@mxpicture/build-api 0.2.57 → 0.2.58

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.
@@ -27,4 +27,10 @@ export declare const jsonEqual: <T>(a: T, b: T) => boolean;
27
27
  * ```
28
28
  */
29
29
  export declare const jsonClone: <T>(value: T) => T;
30
+ export declare enum JsonStringifyFormat {
31
+ json = "json",
32
+ jsonStringify = "jsonStringify"
33
+ }
34
+ export declare const jsonStringify: (content: unknown, format?: JsonStringifyFormat) => Promise<string>;
35
+ export declare const jsonParse: <T>(content: string) => T;
30
36
  //# sourceMappingURL=common.json.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.json.d.ts","sourceRoot":"","sources":["../../src/common/common.json.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,KAAG,OAAkC,CAAC;AAE7E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,CAA2B,CAAC"}
1
+ {"version":3,"file":"common.json.d.ts","sourceRoot":"","sources":["../../src/common/common.json.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC,KAAG,OAAkC,CAAC;AAE7E;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,CAA2B,CAAC;AAEpE,oBAAY,mBAAmB;IAC7B,IAAI,SAAS;IACb,aAAa,kBAAkB;CAChC;AAED,eAAO,MAAM,aAAa,GACxB,SAAS,OAAO,EAChB,SAAS,mBAAmB,KAC3B,OAAO,CAAC,MAAM,CAQhB,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,SAAS,MAAM,KAAG,CAAyB,CAAC"}
@@ -1,4 +1,6 @@
1
1
  import { isDeepStrictEqual } from "node:util";
2
+ import json5 from "json5";
3
+ import { formatJson, formatJsonStringify } from "../code/code.format.js";
2
4
  /**
3
5
  * Performs a deep-equality comparison of two values.
4
6
  *
@@ -28,4 +30,20 @@ export const jsonEqual = (a, b) => isDeepStrictEqual(a, b);
28
30
  * ```
29
31
  */
30
32
  export const jsonClone = (value) => structuredClone(value);
33
+ export var JsonStringifyFormat;
34
+ (function (JsonStringifyFormat) {
35
+ JsonStringifyFormat["json"] = "json";
36
+ JsonStringifyFormat["jsonStringify"] = "jsonStringify";
37
+ })(JsonStringifyFormat || (JsonStringifyFormat = {}));
38
+ export const jsonStringify = async (content, format) => {
39
+ let result = json5.stringify(content);
40
+ if (format === JsonStringifyFormat.json) {
41
+ result = await formatJson(result);
42
+ }
43
+ else if (format === JsonStringifyFormat.jsonStringify) {
44
+ result = await formatJsonStringify(result);
45
+ }
46
+ return result;
47
+ };
48
+ export const jsonParse = (content) => json5.parse(content);
31
49
  //# sourceMappingURL=common.json.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.json.js","sourceRoot":"","sources":["../../src/common/common.json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAI,CAAI,EAAE,CAAI,EAAW,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAE7E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAI,KAAQ,EAAK,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC","sourcesContent":["import { isDeepStrictEqual } from \"node:util\";\n\n/**\n * Performs a deep-equality comparison of two values.\n *\n * @param a - The first value to compare.\n * @param b - The second value to compare.\n * @returns `true` if `a` and `b` are deeply equal, `false` otherwise.\n *\n * @example\n * ```ts\n * jsonEqual({ x: 1 }, { x: 1 }); // true\n * jsonEqual([1, 2], [1, 3]); // false\n * ```\n */\nexport const jsonEqual = <T>(a: T, b: T): boolean => isDeepStrictEqual(a, b);\n\n/**\n * Creates a deep clone of the given value using the structured clone algorithm.\n *\n * @param value - The value to clone.\n * @returns A deep copy of `value`.\n *\n * @example\n * ```ts\n * const original = { nested: { key: \"value\" } };\n * const copy = jsonClone(original);\n * copy.nested.key = \"changed\";\n * console.log(original.nested.key); // \"value\"\n * ```\n */\nexport const jsonClone = <T>(value: T): T => structuredClone(value);\n"]}
1
+ {"version":3,"file":"common.json.js","sourceRoot":"","sources":["../../src/common/common.json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAEzE;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAI,CAAI,EAAE,CAAI,EAAW,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAE7E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAI,KAAQ,EAAK,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;AAEpE,MAAM,CAAN,IAAY,mBAGX;AAHD,WAAY,mBAAmB;IAC7B,oCAAa,CAAA;IACb,sDAA+B,CAAA;AACjC,CAAC,EAHW,mBAAmB,KAAnB,mBAAmB,QAG9B;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,OAAgB,EAChB,MAA4B,EACX,EAAE;IACnB,IAAI,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,MAAM,KAAK,mBAAmB,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;SAAM,IAAI,MAAM,KAAK,mBAAmB,CAAC,aAAa,EAAE,CAAC;QACxD,MAAM,GAAG,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAI,OAAe,EAAK,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC","sourcesContent":["import { isDeepStrictEqual } from \"node:util\";\nimport json5 from \"json5\";\nimport { formatJson, formatJsonStringify } from \"../code/code.format.js\";\n\n/**\n * Performs a deep-equality comparison of two values.\n *\n * @param a - The first value to compare.\n * @param b - The second value to compare.\n * @returns `true` if `a` and `b` are deeply equal, `false` otherwise.\n *\n * @example\n * ```ts\n * jsonEqual({ x: 1 }, { x: 1 }); // true\n * jsonEqual([1, 2], [1, 3]); // false\n * ```\n */\nexport const jsonEqual = <T>(a: T, b: T): boolean => isDeepStrictEqual(a, b);\n\n/**\n * Creates a deep clone of the given value using the structured clone algorithm.\n *\n * @param value - The value to clone.\n * @returns A deep copy of `value`.\n *\n * @example\n * ```ts\n * const original = { nested: { key: \"value\" } };\n * const copy = jsonClone(original);\n * copy.nested.key = \"changed\";\n * console.log(original.nested.key); // \"value\"\n * ```\n */\nexport const jsonClone = <T>(value: T): T => structuredClone(value);\n\nexport enum JsonStringifyFormat {\n json = \"json\",\n jsonStringify = \"jsonStringify\",\n}\n\nexport const jsonStringify = async (\n content: unknown,\n format?: JsonStringifyFormat,\n): Promise<string> => {\n let result = json5.stringify(content);\n if (format === JsonStringifyFormat.json) {\n result = await formatJson(result);\n } else if (format === JsonStringifyFormat.jsonStringify) {\n result = await formatJsonStringify(result);\n }\n return result;\n};\n\nexport const jsonParse = <T>(content: string): T => json5.parse(content);\n"]}
@@ -0,0 +1,44 @@
1
+ import { EntryPoint, ExportExtractorParams, ExportNode, PackageAPI } from "../types/types.exports.js";
2
+ import { PackageJson } from "../types/types.package.js";
3
+ export declare const runExportExtractor: (params: ExportExtractorParams) => Promise<void>;
4
+ export declare class ExportExtractor {
5
+ readonly pkg: string;
6
+ /**
7
+ * Analyze an installed package and produce
8
+ * a structured API representation.
9
+ *
10
+ * @param pkg package name
11
+ */
12
+ constructor(pkg: string);
13
+ /**
14
+ * Analyze an installed package and build its API model.
15
+ */
16
+ run(): Promise<PackageAPI>;
17
+ writeJson(filePath: string, content: PackageAPI): Promise<void>;
18
+ toJson(content: PackageAPI): Promise<string>;
19
+ /**
20
+ * Resolve the root directory of an installed package.
21
+ */
22
+ protected resolvePackageRoot(pkg: string): string;
23
+ /**
24
+ * Resolve entrypoints using the Node exports algorithm.
25
+ */
26
+ protected resolveEntrypoints(pkg: string, pkgJson: PackageJson): EntryPoint[];
27
+ /**
28
+ * Expand wildcard export patterns.
29
+ */
30
+ protected expandWildcardEntrypoints(root: string, entrypoints: EntryPoint[]): Promise<EntryPoint[]>;
31
+ /**
32
+ * Dynamically import a module supporting ESM and CommonJS.
33
+ */
34
+ protected loadModule(id: string): Promise<Record<string, unknown>>;
35
+ /**
36
+ * Extract runtime exports from entrypoints.
37
+ */
38
+ protected inspectRuntimeExports(entrypoints: EntryPoint[]): Promise<ExportNode[]>;
39
+ /**
40
+ * Parse TypeScript declaration files to extract exported types.
41
+ */
42
+ protected parseTypeExports(root: string): Promise<ExportNode[]>;
43
+ }
44
+ //# sourceMappingURL=ExportExtractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportExtractor.d.ts","sourceRoot":"","sources":["../../src/pkg/ExportExtractor.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,UAAU,EACV,qBAAqB,EACrB,UAAU,EACV,UAAU,EACX,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAOxD,eAAO,MAAM,kBAAkB,GAAU,QAAQ,qBAAqB,kBAWrE,CAAC;AAEF,qBAAa,eAAe;aAOS,GAAG,EAAE,MAAM;IAN9C;;;;;OAKG;gBACgC,GAAG,EAAE,MAAM;IAE9C;;OAEG;IACU,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;IAkB1B,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAIzD;;OAEG;IACH,SAAS,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAKjD;;OAEG;IACH,SAAS,CAAC,kBAAkB,CAC1B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,WAAW,GACnB,UAAU,EAAE;IAmCf;;OAEG;cACa,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,UAAU,EAAE,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC;IAuBxB;;OAEG;cACa,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAQxE;;OAEG;cACa,qBAAqB,CACnC,WAAW,EAAE,UAAU,EAAE,GACxB,OAAO,CAAC,UAAU,EAAE,CAAC;IAiBxB;;OAEG;cACa,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;CA0CtE"}
@@ -0,0 +1,180 @@
1
+ import { dirname, relative } from "node:path";
2
+ import ts from "typescript";
3
+ import { glob } from "glob";
4
+ import { createRequire } from "node:module";
5
+ import { resolve as resolveExports } from "resolve.exports";
6
+ import { readPackageJson } from "./pkg.fs.js";
7
+ import { initWorkspace } from "../workspace/Workspace.js";
8
+ import { createSourceFileMap } from "../code/code.common.js";
9
+ import { writeFile } from "node:fs/promises";
10
+ import { jsonStringify, JsonStringifyFormat } from "../common/common.json.js";
11
+ const require = createRequire(import.meta.url);
12
+ export const runExportExtractor = async (params) => {
13
+ initWorkspace(params.repoRoot);
14
+ const exp = new ExportExtractor(params.package);
15
+ const result = await exp.run();
16
+ if (params.json) {
17
+ await exp.writeJson(params.json, result);
18
+ }
19
+ else {
20
+ const content = await exp.toJson(result);
21
+ console.log(content);
22
+ }
23
+ };
24
+ export class ExportExtractor {
25
+ pkg;
26
+ /**
27
+ * Analyze an installed package and produce
28
+ * a structured API representation.
29
+ *
30
+ * @param pkg package name
31
+ */
32
+ constructor(pkg) {
33
+ this.pkg = pkg;
34
+ }
35
+ /**
36
+ * Analyze an installed package and build its API model.
37
+ */
38
+ async run() {
39
+ const root = this.resolvePackageRoot(this.pkg);
40
+ const pkgJson = await readPackageJson(root);
41
+ let entrypoints = this.resolveEntrypoints(this.pkg, pkgJson);
42
+ entrypoints = await this.expandWildcardEntrypoints(root, entrypoints);
43
+ const runtimeExports = await this.inspectRuntimeExports(entrypoints);
44
+ const typeExports = await this.parseTypeExports(root);
45
+ return {
46
+ packageRoot: root,
47
+ entrypoints,
48
+ runtimeExports,
49
+ typeExports,
50
+ };
51
+ }
52
+ async writeJson(filePath, content) {
53
+ return writeFile(filePath, await this.toJson(content));
54
+ }
55
+ async toJson(content) {
56
+ return jsonStringify(content, JsonStringifyFormat.jsonStringify);
57
+ }
58
+ /**
59
+ * Resolve the root directory of an installed package.
60
+ */
61
+ resolvePackageRoot(pkg) {
62
+ const pkgJson = require.resolve(`${pkg}/package.json`);
63
+ return dirname(pkgJson);
64
+ }
65
+ /**
66
+ * Resolve entrypoints using the Node exports algorithm.
67
+ */
68
+ resolveEntrypoints(pkg, pkgJson) {
69
+ const entrypoints = [];
70
+ if (!pkgJson.exports) {
71
+ entrypoints.push({ id: pkg });
72
+ return entrypoints;
73
+ }
74
+ const keys = Object.keys(pkgJson.exports);
75
+ for (const key of keys) {
76
+ try {
77
+ const resolved = resolveExports(pkgJson, key, {
78
+ conditions: ["node", "import", "require", "default"],
79
+ });
80
+ if (!resolved)
81
+ continue;
82
+ const files = Array.isArray(resolved) ? resolved : [resolved];
83
+ for (const file of files) {
84
+ const specifier = key === "." ? pkg : `${pkg}/${key.replace("./", "")}`;
85
+ entrypoints.push({
86
+ id: specifier,
87
+ file,
88
+ });
89
+ }
90
+ }
91
+ catch { }
92
+ }
93
+ return entrypoints;
94
+ }
95
+ /**
96
+ * Expand wildcard export patterns.
97
+ */
98
+ async expandWildcardEntrypoints(root, entrypoints) {
99
+ return (await Promise.allSettled(entrypoints.map(async (entry) => {
100
+ if (!entry.file?.includes("*"))
101
+ return [entry];
102
+ const pattern = entry.file;
103
+ const files = await glob.glob(pattern, {
104
+ cwd: root,
105
+ absolute: true,
106
+ });
107
+ return files.map((file) => ({
108
+ id: relative(root, file).replace(/\.(js|mjs|cjs)$/, ""),
109
+ file,
110
+ }));
111
+ })))
112
+ .filter((r) => r.status === "fulfilled")
113
+ .flatMap((r) => r.value);
114
+ }
115
+ /**
116
+ * Dynamically import a module supporting ESM and CommonJS.
117
+ */
118
+ async loadModule(id) {
119
+ try {
120
+ return await import(id);
121
+ }
122
+ catch {
123
+ return require(id);
124
+ }
125
+ }
126
+ /**
127
+ * Extract runtime exports from entrypoints.
128
+ */
129
+ async inspectRuntimeExports(entrypoints) {
130
+ return (await Promise.allSettled(entrypoints.map(async (entry) => {
131
+ const mod = await this.loadModule(entry.id);
132
+ return Object.keys(mod).map((name) => ({
133
+ name,
134
+ kind: typeof mod[name],
135
+ source: entry.id,
136
+ }));
137
+ })))
138
+ .filter((r) => r.status === "fulfilled")
139
+ .flatMap((r) => r.value);
140
+ }
141
+ /**
142
+ * Parse TypeScript declaration files to extract exported types.
143
+ */
144
+ async parseTypeExports(root) {
145
+ const nodes = [];
146
+ const filePaths = await glob.glob("**/*.d.ts", {
147
+ cwd: root,
148
+ absolute: true,
149
+ });
150
+ const srcMap = createSourceFileMap(filePaths);
151
+ for (const filePath of filePaths) {
152
+ const file = srcMap.get(filePath);
153
+ if (!file)
154
+ continue;
155
+ ts.forEachChild(file.sourceFile, (node) => {
156
+ if (ts.isInterfaceDeclaration(node) ||
157
+ ts.isTypeAliasDeclaration(node) ||
158
+ ts.isClassDeclaration(node) ||
159
+ ts.isFunctionDeclaration(node)) {
160
+ if (!node.name)
161
+ return;
162
+ nodes.push({
163
+ name: node.name.text,
164
+ kind: ts.SyntaxKind[node.kind],
165
+ source: filePath,
166
+ });
167
+ }
168
+ if (ts.isEnumDeclaration(node)) {
169
+ nodes.push({
170
+ name: node.name.text,
171
+ kind: "enum",
172
+ source: filePath,
173
+ });
174
+ }
175
+ });
176
+ }
177
+ return nodes;
178
+ }
179
+ }
180
+ //# sourceMappingURL=ExportExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportExtractor.js","sourceRoot":"","sources":["../../src/pkg/ExportExtractor.ts"],"names":[],"mappings":"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","sourcesContent":["import { dirname, relative } from \"node:path\";\nimport ts from \"typescript\";\nimport { glob } from \"glob\";\nimport { createRequire } from \"node:module\";\nimport { resolve as resolveExports } from \"resolve.exports\";\nimport { readPackageJson } from \"./pkg.fs.js\";\nimport {\n EntryPoint,\n ExportExtractorParams,\n ExportNode,\n PackageAPI,\n} from \"../types/types.exports.js\";\nimport { initWorkspace } from \"../workspace/Workspace.js\";\nimport { PackageJson } from \"../types/types.package.js\";\nimport { createSourceFileMap } from \"../code/code.common.js\";\nimport { writeFile } from \"node:fs/promises\";\nimport { jsonStringify, JsonStringifyFormat } from \"../common/common.json.js\";\n\nconst require = createRequire(import.meta.url);\n\nexport const runExportExtractor = async (params: ExportExtractorParams) => {\n initWorkspace(params.repoRoot);\n\n const exp = new ExportExtractor(params.package);\n const result = await exp.run();\n if (params.json) {\n await exp.writeJson(params.json, result);\n } else {\n const content = await exp.toJson(result);\n console.log(content);\n }\n};\n\nexport class ExportExtractor {\n /**\n * Analyze an installed package and produce\n * a structured API representation.\n *\n * @param pkg package name\n */\n public constructor(public readonly pkg: string) {}\n\n /**\n * Analyze an installed package and build its API model.\n */\n public async run(): Promise<PackageAPI> {\n const root = this.resolvePackageRoot(this.pkg);\n const pkgJson = await readPackageJson(root);\n\n let entrypoints = this.resolveEntrypoints(this.pkg, pkgJson);\n entrypoints = await this.expandWildcardEntrypoints(root, entrypoints);\n\n const runtimeExports = await this.inspectRuntimeExports(entrypoints);\n const typeExports = await this.parseTypeExports(root);\n\n return {\n packageRoot: root,\n entrypoints,\n runtimeExports,\n typeExports,\n };\n }\n\n public async writeJson(filePath: string, content: PackageAPI): Promise<void> {\n return writeFile(filePath, await this.toJson(content));\n }\n\n public async toJson(content: PackageAPI): Promise<string> {\n return jsonStringify(content, JsonStringifyFormat.jsonStringify);\n }\n\n /**\n * Resolve the root directory of an installed package.\n */\n protected resolvePackageRoot(pkg: string): string {\n const pkgJson = require.resolve(`${pkg}/package.json`);\n return dirname(pkgJson);\n }\n\n /**\n * Resolve entrypoints using the Node exports algorithm.\n */\n protected resolveEntrypoints(\n pkg: string,\n pkgJson: PackageJson,\n ): EntryPoint[] {\n const entrypoints: EntryPoint[] = [];\n\n if (!pkgJson.exports) {\n entrypoints.push({ id: pkg });\n return entrypoints;\n }\n\n const keys = Object.keys(pkgJson.exports);\n\n for (const key of keys) {\n try {\n const resolved = resolveExports(pkgJson, key, {\n conditions: [\"node\", \"import\", \"require\", \"default\"],\n });\n\n if (!resolved) continue;\n\n const files = Array.isArray(resolved) ? resolved : [resolved];\n\n for (const file of files) {\n const specifier =\n key === \".\" ? pkg : `${pkg}/${key.replace(\"./\", \"\")}`;\n\n entrypoints.push({\n id: specifier,\n file,\n });\n }\n } catch {}\n }\n\n return entrypoints;\n }\n\n /**\n * Expand wildcard export patterns.\n */\n protected async expandWildcardEntrypoints(\n root: string,\n entrypoints: EntryPoint[],\n ): Promise<EntryPoint[]> {\n return (\n await Promise.allSettled(\n entrypoints.map(async (entry) => {\n if (!entry.file?.includes(\"*\")) return [entry];\n\n const pattern = entry.file;\n const files = await glob.glob(pattern, {\n cwd: root,\n absolute: true,\n });\n\n return files.map((file) => ({\n id: relative(root, file).replace(/\\.(js|mjs|cjs)$/, \"\"),\n file,\n }));\n }),\n )\n )\n .filter((r) => r.status === \"fulfilled\")\n .flatMap((r) => r.value);\n }\n\n /**\n * Dynamically import a module supporting ESM and CommonJS.\n */\n protected async loadModule(id: string): Promise<Record<string, unknown>> {\n try {\n return await import(id);\n } catch {\n return require(id);\n }\n }\n\n /**\n * Extract runtime exports from entrypoints.\n */\n protected async inspectRuntimeExports(\n entrypoints: EntryPoint[],\n ): Promise<ExportNode[]> {\n return (\n await Promise.allSettled(\n entrypoints.map(async (entry) => {\n const mod = await this.loadModule(entry.id);\n return Object.keys(mod).map((name) => ({\n name,\n kind: typeof mod[name],\n source: entry.id,\n }));\n }),\n )\n )\n .filter((r) => r.status === \"fulfilled\")\n .flatMap((r) => r.value);\n }\n\n /**\n * Parse TypeScript declaration files to extract exported types.\n */\n protected async parseTypeExports(root: string): Promise<ExportNode[]> {\n const nodes: ExportNode[] = [];\n\n const filePaths = await glob.glob(\"**/*.d.ts\", {\n cwd: root,\n absolute: true,\n });\n\n const srcMap = createSourceFileMap(filePaths);\n\n for (const filePath of filePaths) {\n const file = srcMap.get(filePath);\n if (!file) continue;\n\n ts.forEachChild(file.sourceFile, (node) => {\n if (\n ts.isInterfaceDeclaration(node) ||\n ts.isTypeAliasDeclaration(node) ||\n ts.isClassDeclaration(node) ||\n ts.isFunctionDeclaration(node)\n ) {\n if (!node.name) return;\n\n nodes.push({\n name: node.name.text,\n kind: ts.SyntaxKind[node.kind],\n source: filePath,\n });\n }\n\n if (ts.isEnumDeclaration(node)) {\n nodes.push({\n name: node.name.text,\n kind: \"enum\",\n source: filePath,\n });\n }\n });\n }\n\n return nodes;\n }\n}\n"]}
@@ -1,3 +1,4 @@
1
+ export * from "./ExportExtractor.js";
1
2
  export * from "./Pkg.js";
2
3
  export * from "./SyncPkgVersion.js";
3
4
  export * from "./UpdatePackages.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pkg/index.ts"],"names":[],"mappings":"AACA,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pkg/index.ts"],"names":[],"mappings":"AACA,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC"}
package/dist/pkg/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // This file is auto-generated for build-cli. Do not edit manually.
2
+ export * from "./ExportExtractor.js";
2
3
  export * from "./Pkg.js";
3
4
  export * from "./SyncPkgVersion.js";
4
5
  export * from "./UpdatePackages.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pkg/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC","sourcesContent":["// This file is auto-generated for build-cli. Do not edit manually.\nexport * from \"./Pkg.js\";\nexport * from \"./SyncPkgVersion.js\";\nexport * from \"./UpdatePackages.js\";\nexport * from \"./pkg.common.js\";\nexport * from \"./pkg.fs.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pkg/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,cAAc,sBAAsB,CAAC;AACrC,cAAc,UAAU,CAAC;AACzB,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC","sourcesContent":["// This file is auto-generated for build-cli. Do not edit manually.\nexport * from \"./ExportExtractor.js\";\nexport * from \"./Pkg.js\";\nexport * from \"./SyncPkgVersion.js\";\nexport * from \"./UpdatePackages.js\";\nexport * from \"./pkg.common.js\";\nexport * from \"./pkg.fs.js\";\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"pkg.fs.d.ts","sourceRoot":"","sources":["../../src/pkg/pkg.fs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAKxD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,GAC1B,eAAe,MAAM,KACpB,OAAO,CAAC,WAAW,CACiD,CAAC;AAExE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mBAAmB,GAAI,eAAe,MAAM,KAAG,WACS,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,MAAM,EAChB,SAAS,WAAW,KACnB,OAAO,CAAC,IAAI,CAC2D,CAAC;AAE3E;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,eAAe,MAAM,KAAG,MAGjB,CAAC"}
1
+ {"version":3,"file":"pkg.fs.d.ts","sourceRoot":"","sources":["../../src/pkg/pkg.fs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AASxD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,GAC1B,eAAe,MAAM,KACpB,OAAO,CAAC,WAAW,CAC+C,CAAC;AAEtE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mBAAmB,GAAI,eAAe,MAAM,KAAG,WACO,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,GAC3B,UAAU,MAAM,EAChB,SAAS,WAAW,KACnB,OAAO,CAAC,IAAI,CAIZ,CAAC;AAEJ;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,eAAe,MAAM,KAAG,MAGjB,CAAC"}
@@ -1,8 +1,7 @@
1
- import json5 from "json5";
2
1
  import { readFile, writeFile } from "node:fs/promises";
3
2
  import { join } from "node:path";
4
- import { formatJsonStringify } from "../code/code.format.js";
5
3
  import { readFileSync } from "node:fs";
4
+ import { jsonParse, jsonStringify, JsonStringifyFormat, } from "../common/common.json.js";
6
5
  /**
7
6
  * Reads and parses a `package.json` file asynchronously.
8
7
  *
@@ -19,7 +18,7 @@ import { readFileSync } from "node:fs";
19
18
  * console.log(pkg.name);
20
19
  * ```
21
20
  */
22
- export const readPackageJson = async (dirOrFilepath) => json5.parse(await readFile(ensurePkgJsonPath(dirOrFilepath), "utf8"));
21
+ export const readPackageJson = async (dirOrFilepath) => jsonParse(await readFile(ensurePkgJsonPath(dirOrFilepath), "utf8"));
23
22
  /**
24
23
  * Reads and parses a `package.json` file synchronously.
25
24
  *
@@ -36,7 +35,7 @@ export const readPackageJson = async (dirOrFilepath) => json5.parse(await readFi
36
35
  * console.log(pkg.version);
37
36
  * ```
38
37
  */
39
- export const readPackageJsonSync = (dirOrFilepath) => json5.parse(readFileSync(ensurePkgJsonPath(dirOrFilepath), "utf8"));
38
+ export const readPackageJsonSync = (dirOrFilepath) => jsonParse(readFileSync(ensurePkgJsonPath(dirOrFilepath), "utf8"));
40
39
  /**
41
40
  * Writes a {@link PackageJson} object to disk as formatted JSON.
42
41
  *
@@ -48,7 +47,7 @@ export const readPackageJsonSync = (dirOrFilepath) => json5.parse(readFileSync(e
48
47
  * @param content - The package JSON content to serialize and write.
49
48
  * @returns A promise that resolves when the file has been written.
50
49
  */
51
- export const writePackageJson = async (jsonPath, content) => writeFile(jsonPath, await formatJsonStringify(json5.stringify(content)));
50
+ export const writePackageJson = async (jsonPath, content) => writeFile(jsonPath, await jsonStringify(content, JsonStringifyFormat.jsonStringify));
52
51
  /**
53
52
  * Ensures a path ends with `/package.json`.
54
53
  *
@@ -1 +1 @@
1
- {"version":3,"file":"pkg.fs.js","sourceRoot":"","sources":["../../src/pkg/pkg.fs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,aAAqB,EACC,EAAE,CACxB,KAAK,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAExE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,aAAqB,EAAe,EAAE,CACxE,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,QAAgB,EAChB,OAAoB,EACL,EAAE,CACjB,SAAS,CAAC,QAAQ,EAAE,MAAM,mBAAmB,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAE3E;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,aAAqB,EAAU,EAAE,CACjE,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC;IACrC,CAAC,CAAC,aAAa;IACf,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC","sourcesContent":["import json5 from \"json5\";\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { PackageJson } from \"../types/types.package.js\";\nimport { join } from \"node:path\";\nimport { formatJsonStringify } from \"../code/code.format.js\";\nimport { readFileSync } from \"node:fs\";\n\n/**\n * Reads and parses a `package.json` file asynchronously.\n *\n * @remarks\n * Uses JSON5 for parsing, so comments and trailing commas are permitted.\n * If the path is a directory, `/package.json` is automatically appended.\n *\n * @param dirOrFilepath - An absolute path to either a directory containing `package.json` or the file itself.\n * @returns A promise resolving to the parsed {@link PackageJson} contents.\n *\n * @example\n * ```ts\n * const pkg = await readPackageJson(\"/path/to/my-package\");\n * console.log(pkg.name);\n * ```\n */\nexport const readPackageJson = async (\n dirOrFilepath: string,\n): Promise<PackageJson> =>\n json5.parse(await readFile(ensurePkgJsonPath(dirOrFilepath), \"utf8\"));\n\n/**\n * Reads and parses a `package.json` file synchronously.\n *\n * @remarks\n * Uses JSON5 for parsing, so comments and trailing commas are permitted.\n * If the path is a directory, `/package.json` is automatically appended.\n *\n * @param dirOrFilepath - An absolute path to either a directory containing `package.json` or the file itself.\n * @returns The parsed {@link PackageJson} contents.\n *\n * @example\n * ```ts\n * const pkg = readPackageJsonSync(\"/path/to/my-package\");\n * console.log(pkg.version);\n * ```\n */\nexport const readPackageJsonSync = (dirOrFilepath: string): PackageJson =>\n json5.parse(readFileSync(ensurePkgJsonPath(dirOrFilepath), \"utf8\"));\n\n/**\n * Writes a {@link PackageJson} object to disk as formatted JSON.\n *\n * @remarks\n * The output is stringified via JSON5 and then formatted with the project's\n * standard JSON formatter before being written.\n *\n * @param jsonPath - The absolute file path to write the `package.json` to.\n * @param content - The package JSON content to serialize and write.\n * @returns A promise that resolves when the file has been written.\n */\nexport const writePackageJson = async (\n jsonPath: string,\n content: PackageJson,\n): Promise<void> =>\n writeFile(jsonPath, await formatJsonStringify(json5.stringify(content)));\n\n/**\n * Ensures a path ends with `/package.json`.\n *\n * @remarks\n * If the path already ends with `/package.json` it is returned as-is;\n * otherwise `package.json` is appended via `path.join`.\n *\n * @param dirOrFilepath - A directory path or a path already pointing to `package.json`.\n * @returns The path guaranteed to end with `/package.json`.\n */\nexport const ensurePkgJsonPath = (dirOrFilepath: string): string =>\n dirOrFilepath.endsWith(\"/package.json\")\n ? dirOrFilepath\n : join(dirOrFilepath, \"package.json\");\n"]}
1
+ {"version":3,"file":"pkg.fs.js","sourceRoot":"","sources":["../../src/pkg/pkg.fs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EACL,SAAS,EACT,aAAa,EACb,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,aAAqB,EACC,EAAE,CACxB,SAAS,CAAC,MAAM,QAAQ,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAEtE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,aAAqB,EAAe,EAAE,CACxE,SAAS,CAAC,YAAY,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,QAAgB,EAChB,OAAoB,EACL,EAAE,CACjB,SAAS,CACP,QAAQ,EACR,MAAM,aAAa,CAAC,OAAO,EAAE,mBAAmB,CAAC,aAAa,CAAC,CAChE,CAAC;AAEJ;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,aAAqB,EAAU,EAAE,CACjE,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC;IACrC,CAAC,CAAC,aAAa;IACf,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC","sourcesContent":["import { readFile, writeFile } from \"node:fs/promises\";\nimport { PackageJson } from \"../types/types.package.js\";\nimport { join } from \"node:path\";\nimport { readFileSync } from \"node:fs\";\nimport {\n jsonParse,\n jsonStringify,\n JsonStringifyFormat,\n} from \"../common/common.json.js\";\n\n/**\n * Reads and parses a `package.json` file asynchronously.\n *\n * @remarks\n * Uses JSON5 for parsing, so comments and trailing commas are permitted.\n * If the path is a directory, `/package.json` is automatically appended.\n *\n * @param dirOrFilepath - An absolute path to either a directory containing `package.json` or the file itself.\n * @returns A promise resolving to the parsed {@link PackageJson} contents.\n *\n * @example\n * ```ts\n * const pkg = await readPackageJson(\"/path/to/my-package\");\n * console.log(pkg.name);\n * ```\n */\nexport const readPackageJson = async (\n dirOrFilepath: string,\n): Promise<PackageJson> =>\n jsonParse(await readFile(ensurePkgJsonPath(dirOrFilepath), \"utf8\"));\n\n/**\n * Reads and parses a `package.json` file synchronously.\n *\n * @remarks\n * Uses JSON5 for parsing, so comments and trailing commas are permitted.\n * If the path is a directory, `/package.json` is automatically appended.\n *\n * @param dirOrFilepath - An absolute path to either a directory containing `package.json` or the file itself.\n * @returns The parsed {@link PackageJson} contents.\n *\n * @example\n * ```ts\n * const pkg = readPackageJsonSync(\"/path/to/my-package\");\n * console.log(pkg.version);\n * ```\n */\nexport const readPackageJsonSync = (dirOrFilepath: string): PackageJson =>\n jsonParse(readFileSync(ensurePkgJsonPath(dirOrFilepath), \"utf8\"));\n\n/**\n * Writes a {@link PackageJson} object to disk as formatted JSON.\n *\n * @remarks\n * The output is stringified via JSON5 and then formatted with the project's\n * standard JSON formatter before being written.\n *\n * @param jsonPath - The absolute file path to write the `package.json` to.\n * @param content - The package JSON content to serialize and write.\n * @returns A promise that resolves when the file has been written.\n */\nexport const writePackageJson = async (\n jsonPath: string,\n content: PackageJson,\n): Promise<void> =>\n writeFile(\n jsonPath,\n await jsonStringify(content, JsonStringifyFormat.jsonStringify),\n );\n\n/**\n * Ensures a path ends with `/package.json`.\n *\n * @remarks\n * If the path already ends with `/package.json` it is returned as-is;\n * otherwise `package.json` is appended via `path.join`.\n *\n * @param dirOrFilepath - A directory path or a path already pointing to `package.json`.\n * @returns The path guaranteed to end with `/package.json`.\n */\nexport const ensurePkgJsonPath = (dirOrFilepath: string): string =>\n dirOrFilepath.endsWith(\"/package.json\")\n ? dirOrFilepath\n : join(dirOrFilepath, \"package.json\");\n"]}
@@ -4,6 +4,7 @@ export * from "./types.cleanup.js";
4
4
  export * from "./types.code.js";
5
5
  export * from "./types.deps.js";
6
6
  export * from "./types.documents.js";
7
+ export * from "./types.exports.js";
7
8
  export * from "./types.git.js";
8
9
  export * from "./types.npm.js";
9
10
  export * from "./types.os.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC"}
@@ -5,6 +5,7 @@ export * from "./types.cleanup.js";
5
5
  export * from "./types.code.js";
6
6
  export * from "./types.deps.js";
7
7
  export * from "./types.documents.js";
8
+ export * from "./types.exports.js";
8
9
  export * from "./types.git.js";
9
10
  export * from "./types.npm.js";
10
11
  export * from "./types.os.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC","sourcesContent":["// This file is auto-generated for build-cli. Do not edit manually.\nexport * from \"./types.barrel.js\";\nexport * from \"./types.changelog.js\";\nexport * from \"./types.cleanup.js\";\nexport * from \"./types.code.js\";\nexport * from \"./types.deps.js\";\nexport * from \"./types.documents.js\";\nexport * from \"./types.git.js\";\nexport * from \"./types.npm.js\";\nexport * from \"./types.os.js\";\nexport * from \"./types.package.js\";\nexport * from \"./types.run.js\";\nexport * from \"./types.vscode.js\";\nexport * from \"./types.workspace.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC","sourcesContent":["// This file is auto-generated for build-cli. Do not edit manually.\nexport * from \"./types.barrel.js\";\nexport * from \"./types.changelog.js\";\nexport * from \"./types.cleanup.js\";\nexport * from \"./types.code.js\";\nexport * from \"./types.deps.js\";\nexport * from \"./types.documents.js\";\nexport * from \"./types.exports.js\";\nexport * from \"./types.git.js\";\nexport * from \"./types.npm.js\";\nexport * from \"./types.os.js\";\nexport * from \"./types.package.js\";\nexport * from \"./types.run.js\";\nexport * from \"./types.vscode.js\";\nexport * from \"./types.workspace.js\";\n"]}
@@ -0,0 +1,42 @@
1
+ import { RunRepoRootParams } from "./types.run.js";
2
+ /**
3
+ * Represents a discovered export in a package.
4
+ */
5
+ export interface ExportNode {
6
+ /** Export name */
7
+ name: string;
8
+ /** Type of export (function, object, class, etc.) */
9
+ kind: string;
10
+ /** Source entrypoint */
11
+ source: string;
12
+ }
13
+ /**
14
+ * Represents a resolved package entrypoint.
15
+ */
16
+ export interface EntryPoint {
17
+ /** Import specifier used to load the entrypoint */
18
+ id: string;
19
+ /** Absolute path to resolved file */
20
+ file?: string;
21
+ }
22
+ /**
23
+ * Final API analysis result.
24
+ */
25
+ export interface PackageAPI {
26
+ /** Absolute package root */
27
+ packageRoot: string;
28
+ /** All discovered entrypoints */
29
+ entrypoints: EntryPoint[];
30
+ /** Runtime exports discovered via module loading */
31
+ runtimeExports: ExportNode[];
32
+ /** Type exports discovered via `.d.ts` parsing */
33
+ typeExports: ExportNode[];
34
+ }
35
+ /**
36
+ * Parameters for bulk-updating packages that match a pattern.
37
+ */
38
+ export interface ExportExtractorParams extends RunRepoRootParams {
39
+ package: string;
40
+ json?: string;
41
+ }
42
+ //# sourceMappingURL=types.exports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.exports.d.ts","sourceRoot":"","sources":["../../src/types/types.exports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IAEb,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IAEb,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IAEX,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IAEpB,iCAAiC;IACjC,WAAW,EAAE,UAAU,EAAE,CAAC;IAE1B,oDAAoD;IACpD,cAAc,EAAE,UAAU,EAAE,CAAC;IAE7B,kDAAkD;IAClD,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,iBAAiB;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.exports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.exports.js","sourceRoot":"","sources":["../../src/types/types.exports.ts"],"names":[],"mappings":"","sourcesContent":["import { RunRepoRootParams } from \"./types.run.js\";\n\n/**\n * Represents a discovered export in a package.\n */\nexport interface ExportNode {\n /** Export name */\n name: string;\n\n /** Type of export (function, object, class, etc.) */\n kind: string;\n\n /** Source entrypoint */\n source: string;\n}\n\n/**\n * Represents a resolved package entrypoint.\n */\nexport interface EntryPoint {\n /** Import specifier used to load the entrypoint */\n id: string;\n\n /** Absolute path to resolved file */\n file?: string;\n}\n\n/**\n * Final API analysis result.\n */\nexport interface PackageAPI {\n /** Absolute package root */\n packageRoot: string;\n\n /** All discovered entrypoints */\n entrypoints: EntryPoint[];\n\n /** Runtime exports discovered via module loading */\n runtimeExports: ExportNode[];\n\n /** Type exports discovered via `.d.ts` parsing */\n typeExports: ExportNode[];\n}\n\n/**\n * Parameters for bulk-updating packages that match a pattern.\n */\nexport interface ExportExtractorParams extends RunRepoRootParams {\n package: string;\n json?: string;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"vscode.settings.d.ts","sourceRoot":"","sources":["../../src/vscode/vscode.settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAO1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,cAAc,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,cAAc,CAgBzE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,CAKlE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,YAE3B,CAAC"}
1
+ {"version":3,"file":"vscode.settings.d.ts","sourceRoot":"","sources":["../../src/vscode/vscode.settings.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAM1D;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,cAAc,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,cAAc,CAgBzE,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,CAKlE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,YAE3B,CAAC"}
@@ -1,6 +1,6 @@
1
+ import { jsonParse } from "../common/common.json.js";
1
2
  import { activeProfile, defaultSettingsPath } from "./vscode.profiles.js";
2
3
  import { readFile } from "node:fs/promises";
3
- import json5 from "json5";
4
4
  let __settings = null;
5
5
  /**
6
6
  * Reads and returns the VS Code `settings.json` for the active profile.
@@ -26,7 +26,7 @@ export const vscodeSettings = async (dir) => {
26
26
  settingsPath = defaultSettingsPath();
27
27
  }
28
28
  const raw = await readFile(settingsPath, "utf-8");
29
- __settings = json5.parse(raw);
29
+ __settings = jsonParse(raw);
30
30
  if (!__settings)
31
31
  throw new Error("No settings found");
32
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"vscode.settings.js","sourceRoot":"","sources":["../../src/vscode/vscode.settings.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,IAAI,UAAU,GAA0B,IAAI,CAAC;AAE7C;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,GAAY,EAA2B,EAAE;IAC5E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,IAAI,YAAgC,CAAC;QAErC,IAAI,CAAC;YACH,YAAY,GAAG,CAAC,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,GAAG,mBAAmB,EAAE,CAAC;QACvC,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAClD,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;AAC3B,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,GAAW,EAAmB,EAAE;IACrE,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,CAAC,0BAA0B,IAAI,QAAQ,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,OAAO,QAAQ,CAAC,0BAA0B,CAAW,CAAC;AACxD,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC,CAAC","sourcesContent":["import { VSCodeSettings } from \"../types/types.vscode.js\";\nimport { activeProfile, defaultSettingsPath } from \"./vscode.profiles.js\";\nimport { readFile } from \"node:fs/promises\";\nimport json5 from \"json5\";\n\nlet __settings: VSCodeSettings | null = null;\n\n/**\n * Reads and returns the VS Code `settings.json` for the active profile.\n *\n * @remarks\n * The result is cached after the first successful read. If no active profile\n * can be resolved, the default (global) settings file is used as a fallback.\n * A shallow copy is returned so that callers cannot mutate the cached object.\n *\n * @param dir - Optional directory used to resolve the active profile's\n * workspace. Defaults to the current working directory.\n * @returns A promise that resolves to a shallow copy of the parsed\n * {@link VSCodeSettings}.\n * @throws If the settings file cannot be read or parsed.\n */\nexport const vscodeSettings = async (dir?: string): Promise<VSCodeSettings> => {\n if (!__settings) {\n let settingsPath: string | undefined;\n\n try {\n settingsPath = (await activeProfile(dir)).settingsPath;\n } catch {\n settingsPath = defaultSettingsPath();\n }\n\n const raw = await readFile(settingsPath, \"utf-8\");\n __settings = json5.parse(raw);\n if (!__settings) throw new Error(\"No settings found\");\n }\n\n return { ...__settings };\n};\n\n/**\n * Extracts the `C_Cpp.clang_format_style` value from the VS Code settings.\n *\n * @param cwd - The working directory used to locate the active profile's settings.\n * @returns A promise that resolves to the clang-format style string.\n * @throws If the `C_Cpp.clang_format_style` key is missing from the settings.\n */\nexport const clangFormatStyle = async (cwd: string): Promise<string> => {\n const settings = await vscodeSettings(cwd);\n if (!(\"C_Cpp.clang_format_style\" in settings))\n throw new Error(\"C_Cpp.clang_format_style not found in settings.json\");\n return settings[\"C_Cpp.clang_format_style\"] as string;\n};\n\n/**\n * Resets the cached settings so they are re-read on the next call.\n *\n * @internal\n */\nexport const __resetSettings = () => {\n __settings = null;\n};\n"]}
1
+ {"version":3,"file":"vscode.settings.js","sourceRoot":"","sources":["../../src/vscode/vscode.settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,IAAI,UAAU,GAA0B,IAAI,CAAC;AAE7C;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,GAAY,EAA2B,EAAE;IAC5E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,IAAI,YAAgC,CAAC;QAErC,IAAI,CAAC;YACH,YAAY,GAAG,CAAC,MAAM,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,YAAY,GAAG,mBAAmB,EAAE,CAAC;QACvC,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAClD,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,EAAE,GAAG,UAAU,EAAE,CAAC;AAC3B,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,GAAW,EAAmB,EAAE;IACrE,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,CAAC,0BAA0B,IAAI,QAAQ,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;IACzE,OAAO,QAAQ,CAAC,0BAA0B,CAAW,CAAC;AACxD,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,EAAE;IAClC,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC,CAAC","sourcesContent":["import { jsonParse } from \"../common/common.json.js\";\nimport { VSCodeSettings } from \"../types/types.vscode.js\";\nimport { activeProfile, defaultSettingsPath } from \"./vscode.profiles.js\";\nimport { readFile } from \"node:fs/promises\";\n\nlet __settings: VSCodeSettings | null = null;\n\n/**\n * Reads and returns the VS Code `settings.json` for the active profile.\n *\n * @remarks\n * The result is cached after the first successful read. If no active profile\n * can be resolved, the default (global) settings file is used as a fallback.\n * A shallow copy is returned so that callers cannot mutate the cached object.\n *\n * @param dir - Optional directory used to resolve the active profile's\n * workspace. Defaults to the current working directory.\n * @returns A promise that resolves to a shallow copy of the parsed\n * {@link VSCodeSettings}.\n * @throws If the settings file cannot be read or parsed.\n */\nexport const vscodeSettings = async (dir?: string): Promise<VSCodeSettings> => {\n if (!__settings) {\n let settingsPath: string | undefined;\n\n try {\n settingsPath = (await activeProfile(dir)).settingsPath;\n } catch {\n settingsPath = defaultSettingsPath();\n }\n\n const raw = await readFile(settingsPath, \"utf-8\");\n __settings = jsonParse(raw);\n if (!__settings) throw new Error(\"No settings found\");\n }\n\n return { ...__settings };\n};\n\n/**\n * Extracts the `C_Cpp.clang_format_style` value from the VS Code settings.\n *\n * @param cwd - The working directory used to locate the active profile's settings.\n * @returns A promise that resolves to the clang-format style string.\n * @throws If the `C_Cpp.clang_format_style` key is missing from the settings.\n */\nexport const clangFormatStyle = async (cwd: string): Promise<string> => {\n const settings = await vscodeSettings(cwd);\n if (!(\"C_Cpp.clang_format_style\" in settings))\n throw new Error(\"C_Cpp.clang_format_style not found in settings.json\");\n return settings[\"C_Cpp.clang_format_style\"] as string;\n};\n\n/**\n * Resets the cached settings so they are re-read on the next call.\n *\n * @internal\n */\nexport const __resetSettings = () => {\n __settings = null;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"vscode.storage.d.ts","sourceRoot":"","sources":["../../src/vscode/vscode.storage.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAGzD;;;;GAIG;AACH,eAAO,MAAM,WAAW,QAAO,MAC0B,CAAC;AAI1D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,QAAO,aAM1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,YAE1B,CAAC"}
1
+ {"version":3,"file":"vscode.storage.d.ts","sourceRoot":"","sources":["../../src/vscode/vscode.storage.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAIzD;;;;GAIG;AACH,eAAO,MAAM,WAAW,QAAO,MAC0B,CAAC;AAI1D;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,QAAO,aAM1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,YAE1B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import { join } from "node:path";
3
- import json5 from "json5";
4
3
  import { configUserPath } from "./vscode.config.js";
4
+ import { jsonParse } from "../common/common.json.js";
5
5
  /**
6
6
  * Returns the absolute path to the VS Code `storage.json` file.
7
7
  *
@@ -24,7 +24,7 @@ export const storage = () => {
24
24
  if (__storage)
25
25
  return __storage;
26
26
  const content = fs.readFileSync(storagePath()).toString();
27
- __storage = json5.parse(content);
27
+ __storage = jsonParse(content);
28
28
  if (!__storage)
29
29
  throw new Error("VS Code storage.json could not be loaded");
30
30
  return __storage;
@@ -1 +1 @@
1
- {"version":3,"file":"vscode.storage.js","sourceRoot":"","sources":["../../src/vscode/vscode.storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAW,EAAE,CACtC,IAAI,CAAC,cAAc,EAAE,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC;AAE1D,IAAI,SAAoC,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,GAAkB,EAAE;IACzC,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC1D,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC5E,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,SAAS,GAAG,SAAS,CAAC;AACxB,CAAC,CAAC","sourcesContent":["import * as fs from \"node:fs\";\nimport { join } from \"node:path\";\nimport json5 from \"json5\";\nimport { VSCodeStorage } from \"../types/types.vscode.js\";\nimport { configUserPath } from \"./vscode.config.js\";\n\n/**\n * Returns the absolute path to the VS Code `storage.json` file.\n *\n * @returns The path to `storage.json` inside the `globalStorage` directory.\n */\nexport const storagePath = (): string =>\n join(configUserPath(), \"globalStorage\", \"storage.json\");\n\nlet __storage: VSCodeStorage | undefined;\n\n/**\n * Reads and returns the parsed VS Code `storage.json`.\n *\n * @remarks\n * The result is cached after the first successful read. Subsequent calls\n * return the cached {@link VSCodeStorage} instance without re-reading\n * the file from disk.\n *\n * @returns The parsed {@link VSCodeStorage} object.\n * @throws If the file cannot be read or parsed.\n */\nexport const storage = (): VSCodeStorage => {\n if (__storage) return __storage;\n const content = fs.readFileSync(storagePath()).toString();\n __storage = json5.parse(content);\n if (!__storage) throw new Error(\"VS Code storage.json could not be loaded\");\n return __storage;\n};\n\n/**\n * Resets the cached storage so it is re-read on the next call.\n *\n * @internal\n */\nexport const __resetStorage = () => {\n __storage = undefined;\n};\n"]}
1
+ {"version":3,"file":"vscode.storage.js","sourceRoot":"","sources":["../../src/vscode/vscode.storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,GAAW,EAAE,CACtC,IAAI,CAAC,cAAc,EAAE,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC;AAE1D,IAAI,SAAoC,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,GAAkB,EAAE;IACzC,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC1D,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAC/B,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC5E,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,SAAS,GAAG,SAAS,CAAC;AACxB,CAAC,CAAC","sourcesContent":["import * as fs from \"node:fs\";\nimport { join } from \"node:path\";\nimport { VSCodeStorage } from \"../types/types.vscode.js\";\nimport { configUserPath } from \"./vscode.config.js\";\nimport { jsonParse } from \"../common/common.json.js\";\n\n/**\n * Returns the absolute path to the VS Code `storage.json` file.\n *\n * @returns The path to `storage.json` inside the `globalStorage` directory.\n */\nexport const storagePath = (): string =>\n join(configUserPath(), \"globalStorage\", \"storage.json\");\n\nlet __storage: VSCodeStorage | undefined;\n\n/**\n * Reads and returns the parsed VS Code `storage.json`.\n *\n * @remarks\n * The result is cached after the first successful read. Subsequent calls\n * return the cached {@link VSCodeStorage} instance without re-reading\n * the file from disk.\n *\n * @returns The parsed {@link VSCodeStorage} object.\n * @throws If the file cannot be read or parsed.\n */\nexport const storage = (): VSCodeStorage => {\n if (__storage) return __storage;\n const content = fs.readFileSync(storagePath()).toString();\n __storage = jsonParse(content);\n if (!__storage) throw new Error(\"VS Code storage.json could not be loaded\");\n return __storage;\n};\n\n/**\n * Resets the cached storage so it is re-read on the next call.\n *\n * @internal\n */\nexport const __resetStorage = () => {\n __storage = undefined;\n};\n"]}
@@ -1,6 +1,6 @@
1
1
  import { readFile } from "node:fs/promises";
2
- import json5 from "json5";
3
2
  import { dirname } from "node:path";
3
+ import { jsonParse } from "../common/common.json.js";
4
4
  const __workspaces = {};
5
5
  /**
6
6
  * Reads and returns a parsed VS Code `.code-workspace` file.
@@ -17,7 +17,7 @@ export const vscodeWorkspace = async (workspaceFile) => {
17
17
  let found = __workspaces[workspaceFile];
18
18
  if (!found) {
19
19
  const raw = await readFile(workspaceFile, "utf-8");
20
- found = json5.parse(raw);
20
+ found = jsonParse(raw);
21
21
  __workspaces[workspaceFile] = found;
22
22
  }
23
23
  return { ...found };
@@ -1 +1 @@
1
- {"version":3,"file":"vscode.workspace.js","sourceRoot":"","sources":["../../src/vscode/vscode.workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,YAAY,GAAoC,EAAE,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,aAAqB,EACK,EAAE;IAC5B,IAAI,KAAK,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QACnD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzB,YAAY,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;AACtB,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,aAAqB,EAAE,EAAE,CAC3D,OAAO,CAAC,aAAa,CAAC,CAAC","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { VSCodeWorkspace } from \"../types/types.vscode.js\";\nimport json5 from \"json5\";\nimport { dirname } from \"node:path\";\n\nconst __workspaces: Record<string, VSCodeWorkspace> = {};\n\n/**\n * Reads and returns a parsed VS Code `.code-workspace` file.\n *\n * @remarks\n * The result is cached per `workspaceFile` path. A shallow copy is returned\n * so that callers cannot mutate the cached object.\n *\n * @param workspaceFile - Absolute path to the `.code-workspace` file.\n * @returns A promise that resolves to a shallow copy of the parsed\n * {@link VSCodeWorkspace}.\n */\nexport const vscodeWorkspace = async (\n workspaceFile: string,\n): Promise<VSCodeWorkspace> => {\n let found = __workspaces[workspaceFile];\n if (!found) {\n const raw = await readFile(workspaceFile, \"utf-8\");\n found = json5.parse(raw);\n __workspaces[workspaceFile] = found;\n }\n\n return { ...found };\n};\n\n/**\n * Returns the directory that contains the given workspace file.\n *\n * @param workspaceFile - Absolute path to the `.code-workspace` file.\n * @returns The parent directory of the workspace file.\n */\nexport const vscodeWorkspaceRoot = (workspaceFile: string) =>\n dirname(workspaceFile);\n"]}
1
+ {"version":3,"file":"vscode.workspace.js","sourceRoot":"","sources":["../../src/vscode/vscode.workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,MAAM,YAAY,GAAoC,EAAE,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,aAAqB,EACK,EAAE;IAC5B,IAAI,KAAK,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QACnD,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QACvB,YAAY,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;AACtB,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,aAAqB,EAAE,EAAE,CAC3D,OAAO,CAAC,aAAa,CAAC,CAAC","sourcesContent":["import { readFile } from \"node:fs/promises\";\nimport { VSCodeWorkspace } from \"../types/types.vscode.js\";\nimport { dirname } from \"node:path\";\nimport { jsonParse } from \"../common/common.json.js\";\n\nconst __workspaces: Record<string, VSCodeWorkspace> = {};\n\n/**\n * Reads and returns a parsed VS Code `.code-workspace` file.\n *\n * @remarks\n * The result is cached per `workspaceFile` path. A shallow copy is returned\n * so that callers cannot mutate the cached object.\n *\n * @param workspaceFile - Absolute path to the `.code-workspace` file.\n * @returns A promise that resolves to a shallow copy of the parsed\n * {@link VSCodeWorkspace}.\n */\nexport const vscodeWorkspace = async (\n workspaceFile: string,\n): Promise<VSCodeWorkspace> => {\n let found = __workspaces[workspaceFile];\n if (!found) {\n const raw = await readFile(workspaceFile, \"utf-8\");\n found = jsonParse(raw);\n __workspaces[workspaceFile] = found;\n }\n\n return { ...found };\n};\n\n/**\n * Returns the directory that contains the given workspace file.\n *\n * @param workspaceFile - Absolute path to the `.code-workspace` file.\n * @returns The parent directory of the workspace file.\n */\nexport const vscodeWorkspaceRoot = (workspaceFile: string) =>\n dirname(workspaceFile);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mxpicture/build-api",
3
- "version": "0.2.57",
3
+ "version": "0.2.58",
4
4
  "description": "Build utilities API",
5
5
  "type": "module",
6
6
  "author": "MXPicture",
@@ -42,9 +42,11 @@
42
42
  "dependencies": {
43
43
  "@mxpicture/dep-analyzer": "^0.1.0",
44
44
  "@types/micromatch": "^4.0.10",
45
+ "glob": "^13.0.6",
45
46
  "json5": "^2.2.3",
46
47
  "micromatch": "^4.0.8",
47
48
  "prettier": "^3.8.1",
49
+ "resolve.exports": "^2.0.3",
48
50
  "simple-git": "^3.32.3",
49
51
  "typescript": "^5.9.3",
50
52
  "yaml": "^2.8.2"