@matter/tools 0.12.4-alpha.0-20250211-56b2c53a0 → 0.12.4-alpha.0-20250213-1187f81eb

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/cjs/building/builder.js +2 -2
  2. package/dist/cjs/building/builder.js.map +1 -1
  3. package/dist/cjs/building/cli.d.ts.map +1 -1
  4. package/dist/cjs/building/cli.js +88 -10
  5. package/dist/cjs/building/cli.js.map +2 -2
  6. package/dist/cjs/building/cycles.d.ts +9 -0
  7. package/dist/cjs/building/cycles.d.ts.map +1 -0
  8. package/dist/cjs/building/cycles.js +124 -0
  9. package/dist/cjs/building/cycles.js.map +6 -0
  10. package/dist/cjs/building/graph.js +1 -1
  11. package/dist/cjs/building/graph.js.map +1 -1
  12. package/dist/cjs/building/project-builder.js +2 -2
  13. package/dist/cjs/building/project-builder.js.map +1 -1
  14. package/dist/cjs/util/bootstrap.mjs +8 -1
  15. package/dist/cjs/util/import-aliases.d.ts +14 -0
  16. package/dist/cjs/util/import-aliases.d.ts.map +1 -0
  17. package/dist/cjs/util/import-aliases.js +82 -0
  18. package/dist/cjs/util/import-aliases.js.map +6 -0
  19. package/dist/cjs/util/package.d.ts +2 -1
  20. package/dist/cjs/util/package.d.ts.map +1 -1
  21. package/dist/cjs/util/package.js +15 -10
  22. package/dist/cjs/util/package.js.map +1 -1
  23. package/dist/cjs/util/progress.d.ts +2 -1
  24. package/dist/cjs/util/progress.d.ts.map +1 -1
  25. package/dist/cjs/util/progress.js +4 -1
  26. package/dist/cjs/util/progress.js.map +1 -1
  27. package/dist/cjs/versioning/cli.js +1 -1
  28. package/dist/cjs/versioning/cli.js.map +1 -1
  29. package/dist/esm/building/builder.js +3 -3
  30. package/dist/esm/building/builder.js.map +1 -1
  31. package/dist/esm/building/cli.d.ts.map +1 -1
  32. package/dist/esm/building/cli.js +89 -11
  33. package/dist/esm/building/cli.js.map +2 -2
  34. package/dist/esm/building/cycles.d.ts +9 -0
  35. package/dist/esm/building/cycles.d.ts.map +1 -0
  36. package/dist/esm/building/cycles.js +94 -0
  37. package/dist/esm/building/cycles.js.map +6 -0
  38. package/dist/esm/building/graph.js +2 -2
  39. package/dist/esm/building/graph.js.map +1 -1
  40. package/dist/esm/building/project-builder.js +3 -3
  41. package/dist/esm/building/project-builder.js.map +1 -1
  42. package/dist/esm/util/bootstrap.mjs +8 -1
  43. package/dist/esm/util/import-aliases.d.ts +14 -0
  44. package/dist/esm/util/import-aliases.d.ts.map +1 -0
  45. package/dist/esm/util/import-aliases.js +62 -0
  46. package/dist/esm/util/import-aliases.js.map +6 -0
  47. package/dist/esm/util/package.d.ts +2 -1
  48. package/dist/esm/util/package.d.ts.map +1 -1
  49. package/dist/esm/util/package.js +16 -11
  50. package/dist/esm/util/package.js.map +1 -1
  51. package/dist/esm/util/progress.d.ts +2 -1
  52. package/dist/esm/util/progress.d.ts.map +1 -1
  53. package/dist/esm/util/progress.js +5 -2
  54. package/dist/esm/util/progress.js.map +1 -1
  55. package/dist/esm/versioning/cli.js +2 -2
  56. package/dist/esm/versioning/cli.js.map +1 -1
  57. package/package.json +6 -4
  58. package/src/building/builder.ts +2 -2
  59. package/src/building/cli.ts +25 -1
  60. package/src/building/cycles.ts +108 -0
  61. package/src/building/graph.ts +1 -1
  62. package/src/building/project-builder.ts +2 -2
  63. package/src/util/bootstrap.mjs +8 -1
  64. package/src/util/import-aliases.ts +79 -0
  65. package/src/util/package.ts +15 -10
  66. package/src/util/progress.ts +5 -1
  67. package/src/versioning/cli.ts +1 -1
@@ -0,0 +1,108 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Project CHIP Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { readFile } from "fs/promises";
8
+ import { Package } from "../util/package.js";
9
+ import { Progress } from "../util/progress.js";
10
+
11
+ // @ts-expect-error we don't have types for detective-typescript
12
+ import detective from "detective-typescript";
13
+ import { dirname, relative, resolve } from "path";
14
+ import { std } from "../ansi-text/std.js";
15
+ import { ansi } from "../ansi-text/text-builder.js";
16
+
17
+ export async function reportCycles(pkg: Package, progress: Progress) {
18
+ const cycles = await progress.run(pkg.name, () => identifyCycles(pkg, progress));
19
+ if (cycles) {
20
+ printCycles(pkg, cycles);
21
+ }
22
+ }
23
+
24
+ async function identifyCycles(pkg: Package, progress: Progress) {
25
+ const deps = {} as Record<string, string[]>;
26
+ for (const filename of await pkg.glob("{src,test}/**/*.ts")) {
27
+ const contents = await readFile(filename, "utf-8");
28
+ const fileDeps = detective(contents, {
29
+ skipTypeImports: true,
30
+ skipAsyncImports: true,
31
+ });
32
+ deps[filename] = resolveDeps(pkg, filename, fileDeps);
33
+ }
34
+
35
+ const cycles = [] as string[][];
36
+ for (const filename in deps) {
37
+ visit(filename, []);
38
+ }
39
+
40
+ function visit(filename: string, breadcrumb: string[]) {
41
+ progress.refresh();
42
+ const fileDeps = deps[filename] ?? deps[filename.replace(/\.js$/, ".ts")];
43
+ if (fileDeps === undefined) {
44
+ return;
45
+ }
46
+
47
+ const previousIndex = breadcrumb.indexOf(filename);
48
+ if (previousIndex !== -1) {
49
+ const newCycle = breadcrumb.slice(previousIndex);
50
+ for (const cycle of cycles) {
51
+ const filenameOffset = cycle.indexOf(filename);
52
+ if (cycle.length !== newCycle.length) {
53
+ continue;
54
+ }
55
+ if (filenameOffset === -1) {
56
+ continue;
57
+ }
58
+
59
+ let i = 0;
60
+ for (i = 0; i < newCycle.length; i++) {
61
+ if (newCycle[i] !== cycle[(filenameOffset + i) % newCycle.length]) {
62
+ break;
63
+ }
64
+ }
65
+
66
+ if (i === newCycle.length) {
67
+ return;
68
+ }
69
+ }
70
+ cycles.push(newCycle);
71
+ return;
72
+ }
73
+
74
+ breadcrumb = [...breadcrumb, filename];
75
+ for (const dep of fileDeps) {
76
+ visit(dep, breadcrumb);
77
+ }
78
+ }
79
+
80
+ return cycles.length ? cycles : undefined;
81
+ }
82
+
83
+ function printCycles(pkg: Package, cycles: string[][]) {
84
+ std.out(ansi.red("Cycles detected:"), "\n");
85
+ const src = pkg.resolve("src");
86
+ for (const cycle of cycles) {
87
+ std.out(" ", cycle.map(name => ansi.bright.blue(relative(src, name))).join(" → "), " ↩\n");
88
+ }
89
+ }
90
+
91
+ function resolveDeps(pkg: Package, sourceFilename: string, deps: string[]) {
92
+ const dir = dirname(sourceFilename);
93
+ const aliases = pkg.importAliases;
94
+ const resolved = Array<string>();
95
+
96
+ for (let dep of deps) {
97
+ let base = dir;
98
+ if (dep.startsWith("#")) {
99
+ dep = aliases.rewrite(dep);
100
+ base = pkg.path;
101
+ }
102
+ if (dep.startsWith("./")) {
103
+ resolved.push(resolve(base, dep));
104
+ }
105
+ }
106
+
107
+ return resolved;
108
+ }
@@ -134,7 +134,7 @@ export class Graph {
134
134
  progress.info("built", formatTime(node.info.timestamp ?? 0));
135
135
  progress.info("dirty", node.isDirty ? colors.dim.red("yes") : colors.dim.green("no"));
136
136
  progress.info("dependencies", node.dependencies.map(formatDep).join(", "));
137
- progress.shutdown();
137
+ progress.close();
138
138
  }
139
139
  }
140
140
 
@@ -67,12 +67,12 @@ export class ProjectBuilder {
67
67
  try {
68
68
  await this.#doBuild(project, progress);
69
69
  } catch (e: any) {
70
- progress.shutdown();
70
+ progress.close();
71
71
  process.stderr.write(`${e.stack ?? e.message}\n\n`);
72
72
  process.exit(1);
73
73
  }
74
74
 
75
- progress.shutdown();
75
+ progress.close();
76
76
  }
77
77
 
78
78
  async #doBuild(project: Project, progress: Progress) {
@@ -73,7 +73,14 @@ async function bootstrap() {
73
73
  await new Promise(resolve => {
74
74
  const proc = spawn(
75
75
  esbuild,
76
- ["src/**/*.ts", "--outdir=dist/esm", "--format=esm", "--log-level=warning", "--sourcemap=inline"],
76
+ [
77
+ "src/**/*.ts",
78
+ "--outdir=dist/esm",
79
+ "--format=esm",
80
+ "--log-level=warning",
81
+ "--sourcemap=inline",
82
+ "--target=es2022",
83
+ ],
77
84
  options,
78
85
  );
79
86
 
@@ -0,0 +1,79 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2025 Project CHIP Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ /**
8
+ * Parses package.json "imports" fields and rewrites local imports according to the import definitions.
9
+ */
10
+ export class ImportAliases {
11
+ #parent?: ImportAliases;
12
+ #direct: Record<string, string> = {};
13
+ #wildcard = Array<WildcardAlias>();
14
+
15
+ constructor(localAliases?: Record<string, string>, parent?: ImportAliases) {
16
+ for (const path in localAliases) {
17
+ const resolvesTo = localAliases[path];
18
+
19
+ let wildcardAt = path.indexOf("*");
20
+ if (wildcardAt === -1) {
21
+ this.#direct[path] = resolvesTo;
22
+ continue;
23
+ }
24
+
25
+ const inputPrefix = path.substring(0, wildcardAt);
26
+ const inputSuffix = path.substring(wildcardAt + 1);
27
+
28
+ wildcardAt = resolvesTo.indexOf("*");
29
+ if (wildcardAt === -1) {
30
+ this.#wildcard.push({
31
+ inputPrefix,
32
+ inputSuffix,
33
+ includeGlob: false,
34
+ outputPrefix: resolvesTo,
35
+ outputSuffix: "",
36
+ });
37
+ } else {
38
+ this.#wildcard.push({
39
+ inputPrefix,
40
+ inputSuffix,
41
+ includeGlob: true,
42
+ outputPrefix: resolvesTo.substring(0, wildcardAt),
43
+ outputSuffix: resolvesTo.substring(wildcardAt + 1),
44
+ });
45
+ }
46
+ }
47
+ this.#parent = parent;
48
+ }
49
+
50
+ rewrite(path: string): string {
51
+ if (path.startsWith("#")) {
52
+ const direct = this.#direct[path];
53
+ if (direct) {
54
+ return direct;
55
+ }
56
+ for (const alias of this.#wildcard) {
57
+ if (path.startsWith(alias.inputPrefix) && path.endsWith(alias.inputSuffix)) {
58
+ if (alias.includeGlob) {
59
+ return (
60
+ alias.outputPrefix +
61
+ path.substring(alias.inputPrefix.length, path.length - alias.inputSuffix.length) +
62
+ alias.outputSuffix
63
+ );
64
+ }
65
+ return alias.outputPrefix;
66
+ }
67
+ }
68
+ }
69
+ return this.#parent?.rewrite(path) ?? path;
70
+ }
71
+ }
72
+
73
+ interface WildcardAlias {
74
+ inputPrefix: string;
75
+ inputSuffix: string;
76
+ includeGlob: boolean;
77
+ outputPrefix: string;
78
+ outputSuffix: string;
79
+ }
@@ -10,6 +10,7 @@ import { dirname, join, relative, resolve } from "path";
10
10
  import { ignoreError, ignoreErrorSync } from "./errors.js";
11
11
  import { isFile, maybeReadJsonSync, maybeStatSync } from "./file.js";
12
12
  import { globSync } from "./glob.js";
13
+ import { ImportAliases } from "./import-aliases.js";
13
14
  import { Progress } from "./progress.js";
14
15
  import { toolsPath } from "./tools-path.cjs";
15
16
 
@@ -53,7 +54,7 @@ export class Package {
53
54
  hasTests: boolean;
54
55
  hasConfig: boolean;
55
56
  isLibrary: boolean;
56
- #aliases?: Record<string, string>;
57
+ #importAliases?: ImportAliases;
57
58
 
58
59
  constructor({
59
60
  path = ".",
@@ -314,7 +315,11 @@ export class Package {
314
315
  if (existsSync(join(path, "package.json"))) {
315
316
  result = new Package({ path });
316
317
  } else {
317
- result = find(dirname(path));
318
+ const parentDir = dirname(path);
319
+ if (parentDir === path) {
320
+ return null;
321
+ }
322
+ result = find(parentDir);
318
323
  }
319
324
  packageForPath[path] = result;
320
325
  }
@@ -334,17 +339,17 @@ export class Package {
334
339
  throw new Error(`Cannot find package.json for "${path}"`);
335
340
  }
336
341
 
337
- get aliases(): Record<string, string> {
338
- if (this.#aliases !== undefined) {
339
- return this.#aliases;
342
+ get importAliases(): ImportAliases {
343
+ if (this.#importAliases !== undefined) {
344
+ return this.#importAliases;
340
345
  }
341
346
 
342
- this.#aliases = {
343
- ...Package.maybeForPath(dirname(this.path))?.aliases,
344
- ...this.json.imports,
345
- };
347
+ this.#importAliases = new ImportAliases(
348
+ this.json.imports,
349
+ Package.maybeForPath(dirname(this.path))?.importAliases,
350
+ );
346
351
 
347
- return this.#aliases;
352
+ return this.#importAliases;
348
353
  }
349
354
 
350
355
  get modules() {
@@ -155,7 +155,7 @@ export class Progress {
155
155
  std.out.write(` ${ansi.yellow("Warning:")} ${text}\n`);
156
156
  }
157
157
 
158
- shutdown() {
158
+ close() {
159
159
  if (this.#refreshInterval) {
160
160
  clearInterval(this.#refreshInterval);
161
161
  this.#refreshInterval = undefined;
@@ -163,6 +163,10 @@ export class Progress {
163
163
  writeStatus("");
164
164
  }
165
165
 
166
+ [Symbol.dispose]() {
167
+ this.close();
168
+ }
169
+
166
170
  refresh() {
167
171
  if (this.#updateSpinner()) {
168
172
  this.#writeOngoing();
@@ -48,5 +48,5 @@ export async function main(argv = process.argv) {
48
48
  await progress.run(`Tagging version ${progress.emphasize(versioner.version)}`, () => versioner.tag());
49
49
  }
50
50
 
51
- progress.shutdown();
51
+ progress.close();
52
52
  }