summaryrefslogtreecommitdiff
path: root/tools/generate_types_deno.ts
blob: 265b6f53711ed616ce4f6c62ba03da78a3dc29a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/env -S deno run -A
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.

// This script is used to generate the @types/deno package on DefinitelyTyped.

import $ from "jsr:@david/dax@0.42.0";
import { Node, Project } from "jsr:@ts-morph/ts-morph@23.0.0";
import * as semver from "jsr:@std/semver@1.0.3";

const rootDir = $.path(import.meta.dirname!).parentOrThrow();
const definitelyTypedDir = rootDir.join(
  "../DefinitelyTyped/types/deno/",
);

if (!definitelyTypedDir.existsSync()) {
  throw new Error(`Makes sure ${definitelyTypedDir} exists.`);
}

const denoExec = rootDir.join(
  "target/debug/deno" + (Deno.build.os === "windows" ? ".exe" : ""),
);

$.logStep("Building Deno executable...");
await $`cargo build`;

$.logStep("Creating declaration file...");
await createDenoDtsFile();
$.logStep("Updating package.json...");
await updatePkgJson();
$.logStep("Formatting...");
await $`pnpm dprint fmt`.cwd(definitelyTypedDir);

async function createDenoDtsFile() {
  function matchesAny(text: string | undefined, patterns: string[]): boolean {
    if (text == null) {
      return false;
    }
    for (const pattern of patterns) {
      if (text.includes(pattern)) {
        return true;
      }
    }
    return false;
  }

  const text = await $`${denoExec} types`.text();
  const project = new Project();
  const file = project.createSourceFile(
    definitelyTypedDir.join("index.d.ts").toString(),
    text,
    {
      overwrite: true,
    },
  );

  for (const statement of file.getStatementsWithComments()) {
    if (Node.isCommentStatement(statement)) {
      const statementText = statement.getText();
      if (statementText.includes("<reference")) {
        statement.remove();
        continue;
      }
    }
    const shouldKeepKeep = (Node.isModuleDeclaration(statement) ||
      Node.isInterfaceDeclaration(statement) ||
      Node.isTypeAliasDeclaration(statement) ||
      Node.isClassDeclaration(statement)) &&
      (matchesAny(statement.getName(), [
        "Deno",
      ]) || statement.getName()?.startsWith("GPU"));
    if (!shouldKeepKeep) {
      statement.remove();
      continue;
    }
  }

  file.insertStatements(
    0,
    "// Copyright 2018-2024 the Deno authors. MIT license.\n\n",
  );

  file.saveSync();
}

async function updatePkgJson() {
  const pkgJsonFile = definitelyTypedDir.join("package.json");
  const obj = pkgJsonFile.readJsonSync();
  const version = semver.parse(await getDenoVersion());
  version.patch = 9999;
  version.prerelease = undefined;
  version.build = undefined;
  // deno-lint-ignore no-explicit-any
  (obj as any).version = semver.format(version);
  pkgJsonFile.writeTextSync(JSON.stringify(obj, undefined, 4) + "\n"); // 4 spaces indent
}

async function getDenoVersion() {
  const text = await $`${denoExec} -v`.text();
  return text.match(/deno (.*)/)![1];
}