@gtkx/cli 1.4.0 → 1.5.0
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.
- package/README.md +1 -1
- package/dist/builder.d.ts +1 -0
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +2 -2
- package/dist/builder.js.map +1 -1
- package/dist/codegen/run-codegen.d.ts +2 -0
- package/dist/codegen/run-codegen.d.ts.map +1 -1
- package/dist/codegen/run-codegen.js +30 -6
- package/dist/codegen/run-codegen.js.map +1 -1
- package/dist/commands/codegen.js +1 -1
- package/dist/commands/codegen.js.map +1 -1
- package/dist/deploy/freedesktop/localize.d.ts +6 -0
- package/dist/deploy/freedesktop/localize.d.ts.map +1 -0
- package/dist/deploy/freedesktop/localize.js +107 -0
- package/dist/deploy/freedesktop/localize.js.map +1 -0
- package/dist/deploy/install-hints.d.ts.map +1 -1
- package/dist/deploy/install-hints.js +5 -0
- package/dist/deploy/install-hints.js.map +1 -1
- package/dist/deploy/payload/launcher.d.ts.map +1 -1
- package/dist/deploy/payload/launcher.js +2 -0
- package/dist/deploy/payload/launcher.js.map +1 -1
- package/dist/deploy/payload/stage.d.ts +1 -1
- package/dist/deploy/payload/stage.d.ts.map +1 -1
- package/dist/deploy/payload/stage.js +20 -11
- package/dist/deploy/payload/stage.js.map +1 -1
- package/dist/deploy/run-deploy.d.ts.map +1 -1
- package/dist/deploy/run-deploy.js +87 -15
- package/dist/deploy/run-deploy.js.map +1 -1
- package/dist/deploy/targets/flatpak-source.d.ts.map +1 -1
- package/dist/deploy/targets/flatpak-source.js +21 -10
- package/dist/deploy/targets/flatpak-source.js.map +1 -1
- package/dist/deploy/tools.d.ts +6 -1
- package/dist/deploy/tools.d.ts.map +1 -1
- package/dist/deploy/tools.js +26 -1
- package/dist/deploy/tools.js.map +1 -1
- package/dist/dev/locale-dir.d.ts +3 -0
- package/dist/dev/locale-dir.d.ts.map +1 -0
- package/dist/dev/locale-dir.js +17 -0
- package/dist/dev/locale-dir.js.map +1 -0
- package/dist/dev/runner-main.d.ts.map +1 -1
- package/dist/dev/runner-main.js +2 -0
- package/dist/dev/runner-main.js.map +1 -1
- package/dist/dev/runner.d.ts.map +1 -1
- package/dist/dev/runner.js +6 -0
- package/dist/dev/runner.js.map +1 -1
- package/dist/dev/vite-dev-server.d.ts +1 -0
- package/dist/dev/vite-dev-server.d.ts.map +1 -1
- package/dist/dev/vite-dev-server.js.map +1 -1
- package/dist/i18n/binding-extractor.d.ts +30 -0
- package/dist/i18n/binding-extractor.d.ts.map +1 -0
- package/dist/i18n/binding-extractor.js +1324 -0
- package/dist/i18n/binding-extractor.js.map +1 -0
- package/dist/i18n/catalog-template.d.ts +3 -0
- package/dist/i18n/catalog-template.d.ts.map +1 -0
- package/dist/i18n/catalog-template.js +18 -0
- package/dist/i18n/catalog-template.js.map +1 -0
- package/dist/i18n/catalogs.d.ts +21 -0
- package/dist/i18n/catalogs.d.ts.map +1 -0
- package/dist/i18n/catalogs.js +139 -0
- package/dist/i18n/catalogs.js.map +1 -0
- package/dist/i18n/extractor-plugin.d.ts +8 -0
- package/dist/i18n/extractor-plugin.d.ts.map +1 -0
- package/dist/i18n/extractor-plugin.js +247 -0
- package/dist/i18n/extractor-plugin.js.map +1 -0
- package/dist/i18n/metadata-templates.d.ts +11 -0
- package/dist/i18n/metadata-templates.d.ts.map +1 -0
- package/dist/i18n/metadata-templates.js +11 -0
- package/dist/i18n/metadata-templates.js.map +1 -0
- package/dist/i18n/source-messages.d.ts +23 -0
- package/dist/i18n/source-messages.d.ts.map +1 -0
- package/dist/i18n/source-messages.js +403 -0
- package/dist/i18n/source-messages.js.map +1 -0
- package/dist/i18n/types.d.ts +10 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +108 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/internal/source-imports.d.ts +5 -1
- package/dist/internal/source-imports.d.ts.map +1 -1
- package/dist/internal/source-imports.js +23 -44
- package/dist/internal/source-imports.js.map +1 -1
- package/dist/mcp/client.d.ts +0 -1
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +11 -39
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/handlers.d.ts +2 -1
- package/dist/mcp/handlers.d.ts.map +1 -1
- package/dist/mcp/handlers.js.map +1 -1
- package/dist/settings/render.d.ts +4 -1
- package/dist/settings/render.d.ts.map +1 -1
- package/dist/settings/render.js +11 -2
- package/dist/settings/render.js.map +1 -1
- package/dist/settings/schema.d.ts.map +1 -1
- package/dist/settings/schema.js +3 -1
- package/dist/settings/schema.js.map +1 -1
- package/dist/vite-plugins/asset-imports.d.ts.map +1 -1
- package/dist/vite-plugins/asset-imports.js +2 -12
- package/dist/vite-plugins/asset-imports.js.map +1 -1
- package/dist/vite-plugins/i18n.d.ts +5 -0
- package/dist/vite-plugins/i18n.d.ts.map +1 -0
- package/dist/vite-plugins/i18n.js +88 -0
- package/dist/vite-plugins/i18n.js.map +1 -0
- package/dist/vite-plugins/index.d.ts +1 -1
- package/dist/vite-plugins/index.d.ts.map +1 -1
- package/dist/vite-plugins/index.js +3 -1
- package/dist/vite-plugins/index.js.map +1 -1
- package/dist/vite-plugins/resources.d.ts.map +1 -1
- package/dist/vite-plugins/resources.js +10 -55
- package/dist/vite-plugins/resources.js.map +1 -1
- package/dist/vite-plugins/self-contained.d.ts.map +1 -1
- package/dist/vite-plugins/self-contained.js +128 -135
- package/dist/vite-plugins/self-contained.js.map +1 -1
- package/package.json +10 -9
- package/src/builder.ts +3 -2
- package/src/codegen/run-codegen.ts +53 -7
- package/src/commands/codegen.ts +1 -1
- package/src/deploy/freedesktop/localize.ts +144 -0
- package/src/deploy/install-hints.ts +5 -0
- package/src/deploy/payload/launcher.ts +2 -0
- package/src/deploy/payload/stage.ts +35 -10
- package/src/deploy/run-deploy.ts +128 -13
- package/src/deploy/targets/flatpak-source.ts +33 -10
- package/src/deploy/tools.ts +35 -0
- package/src/dev/locale-dir.ts +22 -0
- package/src/dev/runner-main.ts +2 -0
- package/src/dev/runner.ts +8 -0
- package/src/dev/vite-dev-server.ts +1 -0
- package/src/i18n/binding-extractor.ts +1969 -0
- package/src/i18n/catalog-template.ts +24 -0
- package/src/i18n/catalogs.ts +216 -0
- package/src/i18n/extractor-plugin.ts +413 -0
- package/src/i18n/metadata-templates.ts +29 -0
- package/src/i18n/source-messages.ts +608 -0
- package/src/i18n/types.ts +154 -0
- package/src/internal/source-imports.ts +28 -57
- package/src/mcp/client.ts +17 -44
- package/src/mcp/handlers.ts +7 -6
- package/src/settings/render.ts +16 -2
- package/src/settings/schema.ts +3 -1
- package/src/vite-plugins/asset-imports.ts +3 -15
- package/src/vite-plugins/i18n.ts +146 -0
- package/src/vite-plugins/index.ts +3 -0
- package/src/vite-plugins/resources.ts +10 -72
- package/src/vite-plugins/self-contained.ts +150 -169
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sortStringsBy } from "@gtkx/utils";
|
|
2
2
|
import { readdirSync, readFileSync } from "node:fs";
|
|
3
3
|
import { extname, join } from "node:path";
|
|
4
|
-
import { parseSync } from "vite";
|
|
4
|
+
import { parseSync, Visitor } from "vite";
|
|
5
5
|
const SOURCE_LANGUAGES = new Map([
|
|
6
6
|
[".cjs", "jsx"],
|
|
7
7
|
[".cts", "ts"],
|
|
@@ -51,6 +51,11 @@ const sourceFilesIn = (dir, found) => {
|
|
|
51
51
|
collectSourceEntry(dir, entry, found);
|
|
52
52
|
}
|
|
53
53
|
};
|
|
54
|
+
const discoverSourceFiles = (dir) => {
|
|
55
|
+
const files = [];
|
|
56
|
+
sourceFilesIn(dir, files);
|
|
57
|
+
return sortStringsBy(files, (path) => path);
|
|
58
|
+
};
|
|
54
59
|
const staticImportSources = (module) => [
|
|
55
60
|
...module.staticImports.map((statement) => statement.moduleRequest.value),
|
|
56
61
|
...module.staticExports.flatMap((statement) => statement.entries
|
|
@@ -67,49 +72,24 @@ const staticRuntimeImportSources = (module) => [
|
|
|
67
72
|
.filter((source) => source !== undefined)),
|
|
68
73
|
];
|
|
69
74
|
const templateImportSource = (node) => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
const quasis = node.quasis;
|
|
74
|
-
const first = quasis[0];
|
|
75
|
-
if (!isRecord(first) || !isRecord(first.value)) {
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
return typeof first.value.cooked === "string" ? first.value.cooked : null;
|
|
75
|
+
const [quasi] = node.quasis;
|
|
76
|
+
return quasi === undefined || node.expressions.length > 0 ? null : quasi.value.cooked;
|
|
79
77
|
};
|
|
80
78
|
const literalImportSource = (node) => {
|
|
81
|
-
if (
|
|
82
|
-
return
|
|
83
|
-
}
|
|
84
|
-
if (node.type === "Literal") {
|
|
85
|
-
return typeof node.value === "string" ? node.value : null;
|
|
79
|
+
if (node.type === "TemplateLiteral") {
|
|
80
|
+
return templateImportSource(node);
|
|
86
81
|
}
|
|
87
|
-
return node.type === "
|
|
82
|
+
return node.type === "Literal" && typeof node.value === "string" ? node.value : null;
|
|
88
83
|
};
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
found.push(source);
|
|
99
|
-
}
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
collectDynamicImportArray(Object.values(node), found);
|
|
103
|
-
};
|
|
104
|
-
const collectDynamicImportSources = (node, found) => {
|
|
105
|
-
if (Array.isArray(node)) {
|
|
106
|
-
collectDynamicImportArray(node, found);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
if (!isRecord(node)) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
collectDynamicImportRecord(node, found);
|
|
84
|
+
const collectDynamicImportSources = (program, found) => {
|
|
85
|
+
new Visitor({
|
|
86
|
+
ImportExpression: (node) => {
|
|
87
|
+
const source = literalImportSource(node.source);
|
|
88
|
+
if (source !== null) {
|
|
89
|
+
found.push(source);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
}).visit(program);
|
|
113
93
|
};
|
|
114
94
|
const parseImportsInWith = (path, staticSources) => {
|
|
115
95
|
const lang = sourceLanguage(path);
|
|
@@ -135,10 +115,9 @@ const parseRuntimeImportsIn = (path) => parseImportsInWith(path, staticRuntimeIm
|
|
|
135
115
|
const importsIn = (path) => parseImportsIn(path) ?? [];
|
|
136
116
|
const importKey = (entry) => `${entry.importer}\0${entry.source}`;
|
|
137
117
|
const discoverSourceImports = (dir) => {
|
|
138
|
-
const files =
|
|
139
|
-
sourceFilesIn(dir, files);
|
|
118
|
+
const files = discoverSourceFiles(dir);
|
|
140
119
|
const imports = files.flatMap((path) => importsIn(path));
|
|
141
120
|
return sortStringsBy(imports, importKey);
|
|
142
121
|
};
|
|
143
|
-
export { discoverSourceImports, parseRuntimeImportsIn };
|
|
122
|
+
export { discoverSourceFiles, discoverSourceImports, parseRuntimeImportsIn, sourceLanguage };
|
|
144
123
|
//# sourceMappingURL=source-imports.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-imports.js","sourceRoot":"","sources":["../../src/internal/source-imports.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ParseResult, ParserOptions } from \"vite\";\nimport { isRecord, sortStringsBy } from \"@gtkx/utils\";\nimport { type Dirent, readdirSync, readFileSync } from \"node:fs\";\nimport { extname, join } from \"node:path\";\nimport { parseSync } from \"vite\";\n\ntype SourceImport = {\n importer: string;\n source: string;\n};\n\ntype SourceLanguage = NonNullable<ParserOptions[\"lang\"]>;\ntype ParsedModule = ParseResult[\"module\"];\n\nconst SOURCE_LANGUAGES: Map<string, SourceLanguage> = new Map([\n [\".cjs\", \"jsx\"],\n [\".cts\", \"ts\"],\n [\".js\", \"jsx\"],\n [\".jsx\", \"jsx\"],\n [\".mjs\", \"jsx\"],\n [\".mts\", \"ts\"],\n [\".ts\", \"ts\"],\n [\".tsx\", \"tsx\"],\n]);\n\nconst EXCLUDED_DIRECTORIES: Set<string> = new Set([\n \".git\",\n \".gtkx\",\n \"build\",\n \"coverage\",\n \"dist\",\n \"node_modules\",\n \"out-tsc\",\n]);\n\nconst sourceLanguage = (path: string): SourceLanguage | undefined => {\n if (path.endsWith(\".d.ts\") || path.endsWith(\".d.cts\") || path.endsWith(\".d.mts\")) {\n return undefined;\n }\n\n return SOURCE_LANGUAGES.get(extname(path).toLowerCase());\n};\n\nconst collectSourceEntry = (dir: string, entry: Dirent, found: string[]): void => {\n const path = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (!EXCLUDED_DIRECTORIES.has(entry.name)) {\n sourceFilesIn(path, found);\n }\n\n return;\n }\n\n if (entry.isFile() && sourceLanguage(path) !== undefined) {\n found.push(path);\n }\n};\n\nconst sourceFilesIn = (dir: string, found: string[]): void => {\n let entries: Dirent[];\n\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n collectSourceEntry(dir, entry, found);\n }\n};\n\nconst staticImportSources = (module: ParsedModule): string[] => [\n ...module.staticImports.map((statement) => statement.moduleRequest.value),\n ...module.staticExports.flatMap((statement) =>\n statement.entries\n .map((entry) => entry.moduleRequest?.value)\n .filter((source): source is string => source !== undefined),\n ),\n];\n\nconst staticRuntimeImportSources = (module: ParsedModule): string[] => [\n ...module.staticImports\n .filter((statement) => statement.entries.length === 0 || statement.entries.some((entry) => !entry.isType))\n .map((statement) => statement.moduleRequest.value),\n ...module.staticExports.flatMap((statement) =>\n statement.entries\n .filter((entry) => !entry.isType)\n .map((entry) => entry.moduleRequest?.value)\n .filter((source): source is string => source !== undefined),\n ),\n];\n\nconst templateImportSource = (node: Record<string, unknown>): string | null => {\n if (!Array.isArray(node.expressions) || node.expressions.length > 0 || !Array.isArray(node.quasis)) {\n return null;\n }\n\n const quasis: unknown[] = node.quasis;\n const first: unknown = quasis[0];\n\n if (!isRecord(first) || !isRecord(first.value)) {\n return null;\n }\n\n return typeof first.value.cooked === \"string\" ? first.value.cooked : null;\n};\n\nconst literalImportSource = (node: unknown): string | null => {\n if (!isRecord(node)) {\n return null;\n }\n\n if (node.type === \"Literal\") {\n return typeof node.value === \"string\" ? node.value : null;\n }\n\n return node.type === \"TemplateLiteral\" ? templateImportSource(node) : null;\n};\n\nconst collectDynamicImportArray = (nodes: unknown[], found: string[]): void => {\n for (const child of nodes) {\n collectDynamicImportSources(child, found);\n }\n};\n\nconst collectDynamicImportRecord = (node: Record<string, unknown>, found: string[]): void => {\n if (node.type === \"ImportExpression\") {\n const source = literalImportSource(node.source);\n\n if (source !== null) {\n found.push(source);\n }\n\n return;\n }\n\n collectDynamicImportArray(Object.values(node), found);\n};\n\nconst collectDynamicImportSources = (node: unknown, found: string[]): void => {\n if (Array.isArray(node)) {\n collectDynamicImportArray(node, found);\n\n return;\n }\n\n if (!isRecord(node)) {\n return;\n }\n\n collectDynamicImportRecord(node, found);\n};\n\nconst parseImportsInWith = (\n path: string,\n staticSources: (module: ParsedModule) => string[],\n): SourceImport[] | null => {\n const lang = sourceLanguage(path);\n\n if (lang === undefined) {\n return [];\n }\n\n let parsed: ParseResult;\n\n try {\n parsed = parseSync(path, readFileSync(path, \"utf8\"), { lang });\n } catch {\n return null;\n }\n\n if (parsed.errors.length > 0) {\n return null;\n }\n\n const sources = staticSources(parsed.module);\n collectDynamicImportSources(parsed.program, sources);\n\n return [...new Set(sources)].map((source) => ({ importer: path, source }));\n};\n\nconst parseImportsIn = (path: string): SourceImport[] | null => parseImportsInWith(path, staticImportSources);\n\nconst parseRuntimeImportsIn = (path: string): SourceImport[] | null =>\n parseImportsInWith(path, staticRuntimeImportSources);\n\nconst importsIn = (path: string): SourceImport[] => parseImportsIn(path) ?? [];\nconst importKey = (entry: SourceImport): string => `${entry.importer}\\0${entry.source}`;\n\nconst discoverSourceImports = (dir: string): SourceImport[] => {\n const files: string[] = [];\n sourceFilesIn(dir, files);\n const imports = files.flatMap((path) => importsIn(path));\n\n return sortStringsBy(imports, importKey);\n};\n\nexport { discoverSourceImports, parseRuntimeImportsIn, type SourceImport };\n"]}
|
|
1
|
+
{"version":3,"file":"source-imports.js","sourceRoot":"","sources":["../../src/internal/source-imports.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ESTree, ParseResult, ParserOptions } from \"vite\";\nimport { sortStringsBy } from \"@gtkx/utils\";\nimport { type Dirent, readdirSync, readFileSync } from \"node:fs\";\nimport { extname, join } from \"node:path\";\nimport { parseSync, Visitor } from \"vite\";\n\ntype SourceImport = {\n importer: string;\n source: string;\n};\n\ntype SourceLanguage = NonNullable<ParserOptions[\"lang\"]>;\ntype ParsedModule = ParseResult[\"module\"];\n\nconst SOURCE_LANGUAGES: Map<string, SourceLanguage> = new Map([\n [\".cjs\", \"jsx\"],\n [\".cts\", \"ts\"],\n [\".js\", \"jsx\"],\n [\".jsx\", \"jsx\"],\n [\".mjs\", \"jsx\"],\n [\".mts\", \"ts\"],\n [\".ts\", \"ts\"],\n [\".tsx\", \"tsx\"],\n]);\n\nconst EXCLUDED_DIRECTORIES: Set<string> = new Set([\n \".git\",\n \".gtkx\",\n \"build\",\n \"coverage\",\n \"dist\",\n \"node_modules\",\n \"out-tsc\",\n]);\n\nconst sourceLanguage = (path: string): SourceLanguage | undefined => {\n if (path.endsWith(\".d.ts\") || path.endsWith(\".d.cts\") || path.endsWith(\".d.mts\")) {\n return undefined;\n }\n\n return SOURCE_LANGUAGES.get(extname(path).toLowerCase());\n};\n\nconst collectSourceEntry = (dir: string, entry: Dirent, found: string[]): void => {\n const path = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (!EXCLUDED_DIRECTORIES.has(entry.name)) {\n sourceFilesIn(path, found);\n }\n\n return;\n }\n\n if (entry.isFile() && sourceLanguage(path) !== undefined) {\n found.push(path);\n }\n};\n\nconst sourceFilesIn = (dir: string, found: string[]): void => {\n let entries: Dirent[];\n\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n collectSourceEntry(dir, entry, found);\n }\n};\n\nconst discoverSourceFiles = (dir: string): string[] => {\n const files: string[] = [];\n sourceFilesIn(dir, files);\n\n return sortStringsBy(files, (path) => path);\n};\n\nconst staticImportSources = (module: ParsedModule): string[] => [\n ...module.staticImports.map((statement) => statement.moduleRequest.value),\n ...module.staticExports.flatMap((statement) =>\n statement.entries\n .map((entry) => entry.moduleRequest?.value)\n .filter((source): source is string => source !== undefined),\n ),\n];\n\nconst staticRuntimeImportSources = (module: ParsedModule): string[] => [\n ...module.staticImports\n .filter((statement) => statement.entries.length === 0 || statement.entries.some((entry) => !entry.isType))\n .map((statement) => statement.moduleRequest.value),\n ...module.staticExports.flatMap((statement) =>\n statement.entries\n .filter((entry) => !entry.isType)\n .map((entry) => entry.moduleRequest?.value)\n .filter((source): source is string => source !== undefined),\n ),\n];\n\nconst templateImportSource = (node: ESTree.TemplateLiteral): string | null => {\n const [quasi] = node.quasis;\n\n return quasi === undefined || node.expressions.length > 0 ? null : quasi.value.cooked;\n};\n\nconst literalImportSource = (node: ESTree.Expression): string | null => {\n if (node.type === \"TemplateLiteral\") {\n return templateImportSource(node);\n }\n\n return node.type === \"Literal\" && typeof node.value === \"string\" ? node.value : null;\n};\n\nconst collectDynamicImportSources = (program: ESTree.Program, found: string[]): void => {\n new Visitor({\n ImportExpression: (node) => {\n const source = literalImportSource(node.source);\n\n if (source !== null) {\n found.push(source);\n }\n },\n }).visit(program);\n};\n\nconst parseImportsInWith = (\n path: string,\n staticSources: (module: ParsedModule) => string[],\n): SourceImport[] | null => {\n const lang = sourceLanguage(path);\n\n if (lang === undefined) {\n return [];\n }\n\n let parsed: ParseResult;\n\n try {\n parsed = parseSync(path, readFileSync(path, \"utf8\"), { lang });\n } catch {\n return null;\n }\n\n if (parsed.errors.length > 0) {\n return null;\n }\n\n const sources = staticSources(parsed.module);\n collectDynamicImportSources(parsed.program, sources);\n\n return [...new Set(sources)].map((source) => ({ importer: path, source }));\n};\n\nconst parseImportsIn = (path: string): SourceImport[] | null => parseImportsInWith(path, staticImportSources);\n\nconst parseRuntimeImportsIn = (path: string): SourceImport[] | null =>\n parseImportsInWith(path, staticRuntimeImportSources);\n\nconst importsIn = (path: string): SourceImport[] => parseImportsIn(path) ?? [];\nconst importKey = (entry: SourceImport): string => `${entry.importer}\\0${entry.source}`;\n\nconst discoverSourceImports = (dir: string): SourceImport[] => {\n const files = discoverSourceFiles(dir);\n const imports = files.flatMap((path) => importsIn(path));\n\n return sortStringsBy(imports, importKey);\n};\n\nexport { discoverSourceFiles, discoverSourceImports, parseRuntimeImportsIn, type SourceImport, sourceLanguage };\n"]}
|
package/dist/mcp/client.d.ts
CHANGED
package/dist/mcp/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"AAcA,KAAK,gBAAgB,GAAG;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACzB,CAAC;AAsCF,cAAM,SAAS;IACX,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,oBAAoB,CAAyC;IACrE,OAAO,CAAC,QAAQ,CAAwB;gBAE5B,OAAO,EAAE,gBAAgB;IAKrC,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,iBAAiB;YAUX,kBAAkB;IAWhC,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,aAAa;IAYf,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB9B,UAAU,IAAI,IAAI;CAsBrB;AAED,OAAO,EAAE,SAAS,EAAE,CAAC"}
|
package/dist/mcp/client.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import * as Gio from "@gtkx/gi/gio";
|
|
2
2
|
import * as Gtk from "@gtkx/gi/gtk";
|
|
3
|
-
import { DEFAULT_SOCKET_PATH,
|
|
4
|
-
import { error, errorMessage, info, normalizeError
|
|
3
|
+
import { DEFAULT_SOCKET_PATH, isConnectionClosedError, ProtocolConnection, } from "@gtkx/mcp/internal";
|
|
4
|
+
import { error, errorMessage, info, normalizeError } from "@gtkx/utils";
|
|
5
5
|
import * as net from "node:net";
|
|
6
6
|
import { dispatch } from "./handlers.js";
|
|
7
7
|
import { WidgetRegistry } from "./widget-registry.js";
|
|
8
8
|
const RECONNECT_DELAY_MS = 2000;
|
|
9
9
|
const REGISTER_TIMEOUT_MS = 30_000;
|
|
10
10
|
const DISCONNECT_ERROR_CODES = new Set(["ENOENT", "ECONNREFUSED", "EPIPE", "ECONNRESET"]);
|
|
11
|
-
const toResponseError = (error) => error instanceof ProtocolError
|
|
12
|
-
? error.toErrorObject()
|
|
13
|
-
: { code: ErrorCode.INTERNAL_ERROR, message: errorMessage(error) };
|
|
14
11
|
const connectSettler = (callbacks) => {
|
|
15
12
|
let isSettled = false;
|
|
16
13
|
const settle = (notify) => {
|
|
@@ -54,7 +51,7 @@ class McpClient {
|
|
|
54
51
|
}
|
|
55
52
|
handleSocketError(socketError) {
|
|
56
53
|
const code = socketError.code;
|
|
57
|
-
if (code !== undefined && DISCONNECT_ERROR_CODES.has(code)) {
|
|
54
|
+
if (isConnectionClosedError(socketError) || (code !== undefined && DISCONNECT_ERROR_CODES.has(code))) {
|
|
58
55
|
this.scheduleReconnect();
|
|
59
56
|
}
|
|
60
57
|
else {
|
|
@@ -88,12 +85,7 @@ class McpClient {
|
|
|
88
85
|
settle.fail(socketError);
|
|
89
86
|
},
|
|
90
87
|
});
|
|
91
|
-
connection.
|
|
92
|
-
void this.handleRequest(request);
|
|
93
|
-
});
|
|
94
|
-
connection.on("invalid", ({ error: parseError }) => {
|
|
95
|
-
warn(`Received invalid JSON from MCP server: ${parseError.message}`);
|
|
96
|
-
});
|
|
88
|
+
connection.fallbackRequestHandler = (request) => this.handleRequest(request);
|
|
97
89
|
this.socket = socket;
|
|
98
90
|
this.connection = connection;
|
|
99
91
|
}
|
|
@@ -116,32 +108,13 @@ class McpClient {
|
|
|
116
108
|
projectRoot: process.cwd(),
|
|
117
109
|
}, REGISTER_TIMEOUT_MS);
|
|
118
110
|
}
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
try {
|
|
126
|
-
const defaultApp = Gio.Application.getDefault();
|
|
127
|
-
if (!(defaultApp instanceof Gtk.Application)) {
|
|
128
|
-
throw new TypeError("Application not initialized");
|
|
129
|
-
}
|
|
130
|
-
this.registry.refresh();
|
|
131
|
-
const result = await dispatch(method, params, { app: defaultApp, registry: this.registry });
|
|
132
|
-
connection.write({ id, result });
|
|
133
|
-
}
|
|
134
|
-
catch (dispatchError) {
|
|
135
|
-
connection.write({ id, error: toResponseError(dispatchError) });
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
async handleRequest(request) {
|
|
139
|
-
try {
|
|
140
|
-
await this.respondToRequest(request);
|
|
141
|
-
}
|
|
142
|
-
catch (requestError) {
|
|
143
|
-
error("Error handling request:", requestError);
|
|
111
|
+
handleRequest(request) {
|
|
112
|
+
const defaultApp = Gio.Application.getDefault();
|
|
113
|
+
if (!(defaultApp instanceof Gtk.Application)) {
|
|
114
|
+
throw new TypeError("Application not initialized");
|
|
144
115
|
}
|
|
116
|
+
this.registry.refresh();
|
|
117
|
+
return dispatch(request.method, request.params, { app: defaultApp, registry: this.registry });
|
|
145
118
|
}
|
|
146
119
|
async connect() {
|
|
147
120
|
return new Promise((resolve, reject) => {
|
|
@@ -168,9 +141,8 @@ class McpClient {
|
|
|
168
141
|
clearTimeout(this.reconnectTimer);
|
|
169
142
|
this.reconnectTimer = null;
|
|
170
143
|
}
|
|
171
|
-
this.connection?.rejectPending(new Error("Client disconnected"));
|
|
172
144
|
if (this.socket) {
|
|
173
|
-
this.connection?.
|
|
145
|
+
void Promise.allSettled([this.connection?.send("app.unregister")]);
|
|
174
146
|
this.socket.destroy();
|
|
175
147
|
this.socket = null;
|
|
176
148
|
}
|
package/dist/mcp/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gio from \"@gtkx/gi/gio\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport { DEFAULT_SOCKET_PATH, ErrorCode, ProtocolConnection, ProtocolError, type Request } from \"@gtkx/mcp/internal\";\nimport { error, errorMessage, info, normalizeError, warn } from \"@gtkx/utils\";\nimport * as net from \"node:net\";\nimport { dispatch } from \"./handlers.js\";\nimport { WidgetRegistry } from \"./widget-registry.js\";\n\ntype McpClientOptions = {\n socketPath?: string;\n applicationId: string;\n};\n\ntype ConnectCallbacks = {\n onSuccess?: (() => void) | undefined;\n onError?: ((error: Error) => void) | undefined;\n};\n\ntype ConnectSettler = {\n succeed: () => void;\n fail: (error: Error) => void;\n};\n\nconst RECONNECT_DELAY_MS = 2000;\nconst REGISTER_TIMEOUT_MS = 30_000;\nconst DISCONNECT_ERROR_CODES: Set<string> = new Set([\"ENOENT\", \"ECONNREFUSED\", \"EPIPE\", \"ECONNRESET\"]);\n\nconst toResponseError = (error: unknown): { code: number; message: string; data?: unknown } =>\n error instanceof ProtocolError\n ? error.toErrorObject()\n : { code: ErrorCode.INTERNAL_ERROR, message: errorMessage(error) };\n\nconst connectSettler = (callbacks: ConnectCallbacks): ConnectSettler => {\n let isSettled = false;\n\n const settle = (notify: () => void): void => {\n if (isSettled) {\n return;\n }\n\n isSettled = true;\n notify();\n };\n\n return {\n succeed: () => {\n settle(() => callbacks.onSuccess?.());\n },\n fail: (failure) => {\n settle(() => callbacks.onError?.(failure));\n },\n };\n};\n\nclass McpClient {\n private socket: net.Socket | null = null;\n private connection: ProtocolConnection | null = null;\n private socketPath: string;\n private applicationId: string;\n private reconnectTimer: NodeJS.Timeout | null = null;\n private hasConnected = false;\n private isStopping = false;\n private pendingConnectReject: ((error: Error) => void) | null = null;\n private registry = new WidgetRegistry();\n\n constructor(options: McpClientOptions) {\n this.socketPath = options.socketPath ?? DEFAULT_SOCKET_PATH;\n this.applicationId = options.applicationId;\n }\n\n private handleClose(): void {\n if (this.hasConnected) {\n info(\"Disconnected from MCP server\");\n this.hasConnected = false;\n }\n\n this.socket = null;\n this.connection = null;\n this.scheduleReconnect();\n }\n\n private handleSocketError(socketError: Error): void {\n const code = (socketError as NodeJS.ErrnoException).code;\n\n if (code !== undefined && DISCONNECT_ERROR_CODES.has(code)) {\n this.scheduleReconnect();\n } else {\n error(\"Socket error:\", socketError.message);\n }\n }\n\n private async registerWithServer(settle: ConnectSettler): Promise<void> {\n try {\n await this.register();\n info(\"Registered with MCP server\");\n settle.succeed();\n } catch (registerError) {\n error(\"Failed to register with MCP server:\", errorMessage(registerError));\n settle.fail(normalizeError(registerError));\n }\n }\n\n private attemptConnect(callbacks: ConnectCallbacks = {}): void {\n const settle = connectSettler(callbacks);\n\n const socket = net.createConnection(this.socketPath, () => {\n info(`Connected to MCP server at ${this.socketPath}`);\n this.hasConnected = true;\n void this.registerWithServer(settle);\n });\n\n const connection = ProtocolConnection.fromSocket(socket, {\n onClose: () => {\n this.handleClose();\n },\n onError: (socketError) => {\n this.handleSocketError(socketError);\n settle.fail(socketError);\n },\n });\n\n connection.on(\"request\", (request) => {\n void this.handleRequest(request);\n });\n\n connection.on(\"invalid\", ({ error: parseError }) => {\n warn(`Received invalid JSON from MCP server: ${parseError.message}`);\n });\n\n this.socket = socket;\n this.connection = connection;\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer || this.isStopping) {\n return;\n }\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.attemptConnect();\n }, RECONNECT_DELAY_MS);\n }\n\n private register(): Promise<unknown> {\n if (!this.connection) {\n return Promise.reject(new Error(\"Connection not initialized\"));\n }\n\n return this.connection.send(\n \"app.register\",\n {\n applicationId: this.applicationId,\n pid: process.pid,\n projectRoot: process.cwd(),\n },\n REGISTER_TIMEOUT_MS,\n );\n }\n\n private async respondToRequest(request: Request): Promise<void> {\n const { id, method, params } = request;\n const connection = this.connection;\n\n if (!connection) {\n return;\n }\n\n try {\n const defaultApp = Gio.Application.getDefault();\n\n if (!(defaultApp instanceof Gtk.Application)) {\n throw new TypeError(\"Application not initialized\");\n }\n\n this.registry.refresh();\n const result = await dispatch(method, params, { app: defaultApp, registry: this.registry });\n connection.write({ id, result });\n } catch (dispatchError) {\n connection.write({ id, error: toResponseError(dispatchError) });\n }\n }\n\n private async handleRequest(request: Request): Promise<void> {\n try {\n await this.respondToRequest(request);\n } catch (requestError) {\n error(\"Error handling request:\", requestError);\n }\n }\n\n async connect(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.pendingConnectReject = reject;\n\n this.attemptConnect({\n onSuccess: () => {\n this.pendingConnectReject = null;\n resolve();\n },\n onError: (connectError) => {\n this.pendingConnectReject = null;\n reject(connectError);\n },\n });\n });\n }\n\n disconnect(): void {\n this.isStopping = true;\n\n if (this.pendingConnectReject) {\n this.pendingConnectReject(new Error(\"Client disconnected before connection registered\"));\n this.pendingConnectReject = null;\n }\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n this.connection?.rejectPending(new Error(\"Client disconnected\"));\n\n if (this.socket) {\n this.connection?.write({ id: crypto.randomUUID(), method: \"app.unregister\" });\n this.socket.destroy();\n this.socket = null;\n }\n\n this.connection = null;\n this.hasConnected = false;\n }\n}\n\nexport { McpClient };\n"]}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/mcp/client.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gio from \"@gtkx/gi/gio\";\nimport * as Gtk from \"@gtkx/gi/gtk\";\nimport {\n DEFAULT_SOCKET_PATH,\n isConnectionClosedError,\n type JSONRPCRequest,\n ProtocolConnection,\n type Result,\n} from \"@gtkx/mcp/internal\";\nimport { error, errorMessage, info, normalizeError } from \"@gtkx/utils\";\nimport * as net from \"node:net\";\nimport { dispatch } from \"./handlers.js\";\nimport { WidgetRegistry } from \"./widget-registry.js\";\n\ntype McpClientOptions = {\n socketPath?: string;\n applicationId: string;\n};\n\ntype ConnectCallbacks = {\n onSuccess?: (() => void) | undefined;\n onError?: ((error: Error) => void) | undefined;\n};\n\ntype ConnectSettler = {\n succeed: () => void;\n fail: (error: Error) => void;\n};\n\nconst RECONNECT_DELAY_MS = 2000;\nconst REGISTER_TIMEOUT_MS = 30_000;\nconst DISCONNECT_ERROR_CODES: Set<string> = new Set([\"ENOENT\", \"ECONNREFUSED\", \"EPIPE\", \"ECONNRESET\"]);\n\nconst connectSettler = (callbacks: ConnectCallbacks): ConnectSettler => {\n let isSettled = false;\n\n const settle = (notify: () => void): void => {\n if (isSettled) {\n return;\n }\n\n isSettled = true;\n notify();\n };\n\n return {\n succeed: () => {\n settle(() => callbacks.onSuccess?.());\n },\n fail: (failure) => {\n settle(() => callbacks.onError?.(failure));\n },\n };\n};\n\nclass McpClient {\n private socket: net.Socket | null = null;\n private connection: ProtocolConnection | null = null;\n private socketPath: string;\n private applicationId: string;\n private reconnectTimer: NodeJS.Timeout | null = null;\n private hasConnected = false;\n private isStopping = false;\n private pendingConnectReject: ((error: Error) => void) | null = null;\n private registry = new WidgetRegistry();\n\n constructor(options: McpClientOptions) {\n this.socketPath = options.socketPath ?? DEFAULT_SOCKET_PATH;\n this.applicationId = options.applicationId;\n }\n\n private handleClose(): void {\n if (this.hasConnected) {\n info(\"Disconnected from MCP server\");\n this.hasConnected = false;\n }\n\n this.socket = null;\n this.connection = null;\n this.scheduleReconnect();\n }\n\n private handleSocketError(socketError: Error): void {\n const code = (socketError as NodeJS.ErrnoException).code;\n\n if (isConnectionClosedError(socketError) || (code !== undefined && DISCONNECT_ERROR_CODES.has(code))) {\n this.scheduleReconnect();\n } else {\n error(\"Socket error:\", socketError.message);\n }\n }\n\n private async registerWithServer(settle: ConnectSettler): Promise<void> {\n try {\n await this.register();\n info(\"Registered with MCP server\");\n settle.succeed();\n } catch (registerError) {\n error(\"Failed to register with MCP server:\", errorMessage(registerError));\n settle.fail(normalizeError(registerError));\n }\n }\n\n private attemptConnect(callbacks: ConnectCallbacks = {}): void {\n const settle = connectSettler(callbacks);\n\n const socket = net.createConnection(this.socketPath, () => {\n info(`Connected to MCP server at ${this.socketPath}`);\n this.hasConnected = true;\n void this.registerWithServer(settle);\n });\n\n const connection = ProtocolConnection.fromSocket(socket, {\n onClose: () => {\n this.handleClose();\n },\n onError: (socketError) => {\n this.handleSocketError(socketError);\n settle.fail(socketError);\n },\n });\n\n connection.fallbackRequestHandler = (request) => this.handleRequest(request);\n this.socket = socket;\n this.connection = connection;\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer || this.isStopping) {\n return;\n }\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null;\n this.attemptConnect();\n }, RECONNECT_DELAY_MS);\n }\n\n private register(): Promise<unknown> {\n if (!this.connection) {\n return Promise.reject(new Error(\"Connection not initialized\"));\n }\n\n return this.connection.send(\n \"app.register\",\n {\n applicationId: this.applicationId,\n pid: process.pid,\n projectRoot: process.cwd(),\n },\n REGISTER_TIMEOUT_MS,\n );\n }\n\n private handleRequest(request: JSONRPCRequest): Promise<Result> {\n const defaultApp = Gio.Application.getDefault();\n\n if (!(defaultApp instanceof Gtk.Application)) {\n throw new TypeError(\"Application not initialized\");\n }\n\n this.registry.refresh();\n\n return dispatch(request.method, request.params, { app: defaultApp, registry: this.registry });\n }\n\n async connect(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.pendingConnectReject = reject;\n\n this.attemptConnect({\n onSuccess: () => {\n this.pendingConnectReject = null;\n resolve();\n },\n onError: (connectError) => {\n this.pendingConnectReject = null;\n reject(connectError);\n },\n });\n });\n }\n\n disconnect(): void {\n this.isStopping = true;\n\n if (this.pendingConnectReject) {\n this.pendingConnectReject(new Error(\"Client disconnected before connection registered\"));\n this.pendingConnectReject = null;\n }\n\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = null;\n }\n\n if (this.socket) {\n void Promise.allSettled([this.connection?.send(\"app.unregister\")]);\n this.socket.destroy();\n this.socket = null;\n }\n\n this.connection = null;\n this.hasConnected = false;\n }\n}\n\nexport { McpClient };\n"]}
|
package/dist/mcp/handlers.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as Gtk from "@gtkx/gi/gtk";
|
|
2
|
+
import { type Result } from "@gtkx/mcp/internal";
|
|
2
3
|
import type { WidgetRegistry } from "./widget-registry.js";
|
|
3
4
|
type HandlerContext = {
|
|
4
5
|
app: Gtk.Application;
|
|
5
6
|
registry: WidgetRegistry;
|
|
6
7
|
};
|
|
7
|
-
declare const dispatch: (method: string, params: unknown, ctx: HandlerContext) => Promise<
|
|
8
|
+
declare const dispatch: (method: string, params: unknown, ctx: HandlerContext) => Promise<Result>;
|
|
8
9
|
export { dispatch };
|
|
9
10
|
//# sourceMappingURL=handlers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/mcp/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/mcp/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EAIH,KAAK,MAAM,EAKd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAK3D,KAAK,cAAc,GAAG;IAClB,GAAG,EAAE,GAAG,CAAC,WAAW,CAAC;IACrB,QAAQ,EAAE,cAAc,CAAC;CAC5B,CAAC;AA6PF,QAAA,MAAM,QAAQ,GAAU,QAAQ,MAAM,EAAE,QAAQ,OAAO,EAAE,KAAK,cAAc,KAAG,OAAO,CAAC,MAAM,CAM5F,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/mcp/handlers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/mcp/handlers.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Gtk from \"@gtkx/gi/gtk\";\nimport {\n invalidRequestError,\n methodNotFoundError,\n type ParamsSchema,\n type ServerInitiatedMethod,\n type ServerRequestParams,\n ServerRequestParamsSchemas,\n widgetNotFoundError,\n} from \"@gtkx/mcp/internal\";\nimport type { WidgetRegistry } from \"./widget-registry.js\";\nimport { serializeWidget } from \"./serialize-widget.js\";\nimport { loadTestingModule, type TestingModule } from \"./testing-loader.js\";\nimport { readWidgetProperties } from \"./widget-properties.js\";\n\ntype HandlerContext = {\n app: Gtk.Application;\n registry: WidgetRegistry;\n};\n\ntype ValidatedHandler = (ctx: HandlerContext, params: unknown) => Promise<unknown>;\ntype WidgetTarget = { testing: TestingModule; widget: Gtk.Widget };\ntype WidgetParams = { widgetId?: string | undefined };\ntype TargetedHandler<Params> = (ctx: HandlerContext, target: WidgetTarget, params: Params) => Promise<unknown>;\ntype QueryParams = ServerRequestParams<\"widget.query\">;\ntype QueryBy = QueryParams[\"by\"];\ntype QueryRunner = (testing: TestingModule, app: Gtk.Application, params: QueryParams) => Promise<Gtk.Widget[]>;\n\nconst HANDLERS: Record<ServerInitiatedMethod, ValidatedHandler> = {\n \"app.getWindows\": validated(ServerRequestParamsSchemas[\"app.getWindows\"], ({ registry }) =>\n Promise.resolve({\n windows: registry.toplevels().map((window) => ({\n id: registry.getOrCreateId(window),\n title: window.getTitle(),\n })),\n })),\n \"widget.getTree\": validated(ServerRequestParamsSchemas[\"widget.getTree\"], async ({ app, registry }, params) => {\n const testing = await loadTestingModule();\n const container = params.rootId === undefined ? app : requireWidget(registry, params.rootId);\n\n return {\n tree: testing.prettyWidget(container, {\n getId: (w) => registry.getOrCreateId(w),\n shouldHighlight: false,\n ...((params.maxDepth !== undefined) && { maxDepth: params.maxDepth }),\n }),\n };\n }),\n \"widget.query\": validated(ServerRequestParamsSchemas[\"widget.query\"], handleQuery),\n \"widget.getProps\": targeted(\n ServerRequestParamsSchemas[\"widget.getProps\"],\n ({ registry }, { testing, widget }, params) =>\n Promise.resolve({\n ...(params.properties !== undefined && {\n properties: readWidgetProperties(widget, params.properties, registry),\n }),\n ...serializeWidget(widget, (target) => registry.getOrCreateId(target), testing, params.maxDepth),\n }),\n ),\n \"widget.click\": targeted(ServerRequestParamsSchemas[\"widget.click\"], async (_ctx, { testing, widget }) => {\n await testing.userEvent.click(widget);\n\n return { success: true };\n }),\n \"widget.type\": targeted(ServerRequestParamsSchemas[\"widget.type\"], async (_ctx, { testing, widget }, params) => {\n if (params.clear) {\n await testing.userEvent.clear(widget);\n }\n\n await testing.userEvent.type(widget, params.text);\n\n return { success: true };\n }),\n \"widget.fireEvent\": targeted(\n ServerRequestParamsSchemas[\"widget.fireEvent\"],\n async (_ctx, { testing, widget }, params) => {\n const signalArgs = (params.args ?? []).map((arg) => extractSignalArg(arg));\n const isRealized = widget.getRealized();\n const isMapped = widget.getMapped();\n const isSensitive = widget.getSensitive();\n await testing.fireEvent(widget, params.signal, ...signalArgs);\n\n return {\n signal: params.signal,\n isRealized,\n isMapped,\n isSensitive,\n note: emissionNote(isRealized, isMapped),\n };\n },\n ),\n \"widget.screenshot\": validated(ServerRequestParamsSchemas[\"widget.screenshot\"], handleScreenshot),\n};\n\nconst QUERY_RUNNERS: Record<QueryBy, QueryRunner> = {\n role: runRoleQuery,\n text: runTextQuery,\n name: runNameQuery,\n labelText: runLabelTextQuery,\n};\n\nconst SEARCHED_BY: Record<QueryBy, string> = {\n role: \"the accessible role, narrowed by any options given\",\n text: \"the text the widget renders\",\n name:\n \"the widget name (gtk_widget_get_name, which reports the GType name such as \\\"GtkButton\\\" when no name \" +\n \"was set), the accessible label, and the text the widget renders\",\n labelText: \"the accessible label, the labelled-by relation, and the label whose mnemonic targets the widget\",\n};\n\nfunction validated<Params>(\n schema: ParamsSchema<Params>,\n handler: (ctx: HandlerContext, params: Params) => Promise<unknown>,\n): ValidatedHandler {\n return (ctx, params) => {\n const parsed = schema.safeParse(params ?? {});\n\n if (!parsed.success) {\n throw invalidRequestError(parsed.error.message);\n }\n\n return handler(ctx, parsed.data);\n };\n}\n\nfunction targeted<Params extends WidgetParams>(\n schema: ParamsSchema<Params>,\n handler: TargetedHandler<Params>,\n): ValidatedHandler {\n return validated(schema, async (ctx, params) =>\n handler(ctx, await widgetTarget(ctx.registry, params.widgetId), params));\n}\n\nconst widgetTarget = async (registry: WidgetRegistry, widgetId: string | undefined): Promise<WidgetTarget> => ({\n testing: await loadTestingModule(),\n widget: requireWidget(registry, widgetId),\n});\n\nconst requireWidget = (registry: WidgetRegistry, widgetId: string | undefined): Gtk.Widget => {\n if (widgetId === undefined) {\n throw widgetNotFoundError(\"undefined\");\n }\n\n const widget = registry.get(widgetId);\n\n if (!widget) {\n throw widgetNotFoundError(widgetId);\n }\n\n return widget;\n};\n\nconst extractSignalArg = (arg: unknown): unknown => {\n const isTypedArg = typeof arg === \"object\" && arg !== null && \"type\" in arg && \"value\" in arg;\n\n return isTypedArg ? (arg as { value: unknown }).value : arg;\n};\n\nconst emissionNote = (isRealized: boolean, isMapped: boolean): string => {\n if (isRealized && isMapped) {\n return (\n \"The signal was emitted. Default handlers that animate, such as a button activate, settle \" +\n \"asynchronously, so read the widget again rather than assuming the effect has landed.\"\n );\n }\n\n return (\n \"The signal was emitted on a widget that is not realized and mapped, so a default handler that \" +\n \"requires a drawn widget does nothing. Present the containing window or open the containing \" +\n \"popover first, then fire the signal again.\"\n );\n};\n\nconst resolveRole = (value: string | number): Gtk.AccessibleRole | undefined => {\n if (typeof value === \"number\") {\n return value;\n }\n\n const resolved = Gtk.AccessibleRole[value.toUpperCase() as keyof typeof Gtk.AccessibleRole];\n\n return typeof resolved === \"number\" ? resolved : undefined;\n};\n\nconst matchesOrEmpty = async (find: () => Promise<Gtk.Widget[]>): Promise<Gtk.Widget[]> => {\n try {\n return await find();\n } catch {\n return [];\n }\n};\n\nfunction runRoleQuery(testing: TestingModule, app: Gtk.Application, params: QueryParams): Promise<Gtk.Widget[]> {\n const roleValue = resolveRole(params.value);\n\n if (roleValue === undefined) {\n throw invalidRequestError(\n `Unknown accessible role \"${String(params.value)}\"; use the lowercase role shown in the ` +\n \"widget tree, e.g. \\\"button\\\", \\\"list\\\", \\\"list_item\\\", or \\\"checkbox\\\".\",\n );\n }\n\n return matchesOrEmpty(() => testing.findAllByRole(app, roleValue, params.options));\n}\n\nfunction runTextQuery(testing: TestingModule, app: Gtk.Application, params: QueryParams): Promise<Gtk.Widget[]> {\n return matchesOrEmpty(() => testing.findAllByText(app, String(params.value), params.options));\n}\n\nfunction runLabelTextQuery(testing: TestingModule, app: Gtk.Application, params: QueryParams): Promise<Gtk.Widget[]> {\n return matchesOrEmpty(() => testing.findAllByLabelText(app, String(params.value), params.options));\n}\n\nasync function runNameQuery(\n testing: TestingModule,\n app: Gtk.Application,\n params: QueryParams,\n): Promise<Gtk.Widget[]> {\n const matches = await Promise.all([\n matchesOrEmpty(() => testing.findAllByName(app, String(params.value), params.options)),\n runLabelTextQuery(testing, app, params),\n runTextQuery(testing, app, params),\n ]);\n\n return [...new Set(matches.flat())];\n}\n\nconst emptyQueryHint = (params: QueryParams): string =>\n `Nothing matched by:\"${params.by}\" value:\"${String(params.value)}\", which compared ${SEARCHED_BY[params.by]}. ` +\n \"Call gtkx_get_widget_tree to see what is mounted; by:\\\"name\\\" is the widest match, and by:\\\"role\\\" accepts \" +\n \"options.name to match the accessible name of a known role.\";\n\nasync function handleQuery({ app, registry }: HandlerContext, params: QueryParams): Promise<unknown> {\n const testing = await loadTestingModule();\n const widgets = await QUERY_RUNNERS[params.by](testing, app, params);\n const resolveId = (widget: Gtk.Widget): string => registry.getOrCreateId(widget);\n\n return {\n widgets: widgets.map((widget) => serializeWidget(widget, resolveId, testing, 0)),\n searched: SEARCHED_BY[params.by],\n ...(widgets.length === 0 && { hint: emptyQueryHint(params) }),\n };\n}\n\nconst defaultScreenshotTarget = (registry: WidgetRegistry): Gtk.Widget => {\n const [toplevel] = registry.toplevels();\n\n if (!toplevel) {\n throw new Error(\"No windows available for screenshot\");\n }\n\n return toplevel;\n};\n\nasync function handleScreenshot(\n { registry }: HandlerContext,\n params: ServerRequestParams<\"widget.screenshot\">,\n): Promise<unknown> {\n const testing = await loadTestingModule();\n const target = params.windowId ? requireWidget(registry, params.windowId) : defaultScreenshotTarget(registry);\n const result = await testing.screenshot(target, { path: params.path });\n\n if (params.path) {\n return { data: result.data, mimeType: result.mimeType, savedPath: params.path };\n }\n\n return { data: result.data, mimeType: result.mimeType };\n}\n\nconst isServerInitiatedMethod = (method: string): method is ServerInitiatedMethod =>\n Object.hasOwn(ServerRequestParamsSchemas, method);\n\nconst dispatch = async (method: string, params: unknown, ctx: HandlerContext): Promise<unknown> => {\n if (!isServerInitiatedMethod(method)) {\n throw methodNotFoundError(method);\n }\n\n return HANDLERS[method](ctx, params);\n};\n\nexport { dispatch };\n"]}
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/mcp/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,cAAc,CAAC;AACpC,OAAO,EACH,mBAAmB,EACnB,mBAAmB,EAKnB,0BAA0B,EAC1B,mBAAmB,GACtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAsB,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAe9D,MAAM,QAAQ,GAAoD;IAC9D,gBAAgB,EAAE,SAAS,CAAC,0BAA0B,CAAC,gBAAgB,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CACvF,OAAO,CAAC,OAAO,CAAC;QACZ,OAAO,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC3C,EAAE,EAAE,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC;YAClC,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE;SAC3B,CAAC,CAAC;KACN,CAAC,CAAC;IACP,gBAAgB,EAAE,SAAS,CAAC,0BAA0B,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE;QAC1G,MAAM,OAAO,GAAG,MAAM,iBAAiB,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAE7F,OAAO;YACH,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,SAAS,EAAE;gBAClC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;gBACvC,eAAe,EAAE,KAAK;gBACtB,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;aACxE,CAAC;SACL,CAAC;IACN,CAAC,CAAC;IACF,cAAc,EAAE,SAAS,CAAC,0BAA0B,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC;IAClF,iBAAiB,EAAE,QAAQ,CACvB,0BAA0B,CAAC,iBAAiB,CAAC,EAC7C,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,CAC1C,OAAO,CAAC,OAAO,CAAC;QACZ,GAAG,CAAC,MAAM,CAAC,UAAU,KAAK,SAAS,IAAI;YACnC,UAAU,EAAE,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC;SACxE,CAAC;QACF,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC;KACnG,CAAC,CACT;IACD,cAAc,EAAE,QAAQ,CAAC,0BAA0B,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;QACrG,MAAM,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEtC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC,CAAC;IACF,aAAa,EAAE,QAAQ,CAAC,0BAA0B,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE;QAC3G,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QAElD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC,CAAC;IACF,kBAAkB,EAAE,QAAQ,CACxB,0BAA0B,CAAC,kBAAkB,CAAC,EAC9C,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE;QACxC,MAAM,UAAU,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3E,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;QACpC,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;QAC1C,MAAM,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC;QAE9D,OAAO;YACH,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,UAAU;YACV,QAAQ;YACR,WAAW;YACX,IAAI,EAAE,YAAY,CAAC,UAAU,EAAE,QAAQ,CAAC;SAC3C,CAAC;IACN,CAAC,CACJ;IACD,mBAAmB,EAAE,SAAS,CAAC,0BAA0B,CAAC,mBAAmB,CAAC,EAAE,gBAAgB,CAAC;CACpG,CAAC;AAEF,MAAM,aAAa,GAAiC;IAChD,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,SAAS,EAAE,iBAAiB;CAC/B,CAAC;AAEF,MAAM,WAAW,GAA4B;IACzC,IAAI,EAAE,oDAAoD;IAC1D,IAAI,EAAE,6BAA6B;IACnC,IAAI,EACA,wGAAwG;QACxG,iEAAiE;IACrE,SAAS,EAAE,iGAAiG;CAC/G,CAAC;AAEF,SAAS,SAAS,CACd,MAA4B,EAC5B,OAAiE;IAEjE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;QACnB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAE9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC;QAED,OAAO,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,QAAQ,CACb,MAA4B,EAC5B,OAAgC;IAEhC,OAAO,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,CAC3C,OAAO,CAAC,GAAG,EAAE,MAAM,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,YAAY,GAAG,KAAK,EAAE,QAAwB,EAAE,QAA4B,EAAyB,EAAE,CAAC,CAAC;IAC3G,OAAO,EAAE,MAAM,iBAAiB,EAAE;IAClC,MAAM,EAAE,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC5C,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,CAAC,QAAwB,EAAE,QAA4B,EAAc,EAAE;IACzF,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAEtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,GAAY,EAAW,EAAE;IAC/C,MAAM,UAAU,GAAG,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,IAAI,GAAG,CAAC;IAE9F,OAAO,UAAU,CAAC,CAAC,CAAE,GAA0B,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;AAChE,CAAC,CAAC;AAEF,MAAM,YAAY,GAAG,CAAC,UAAmB,EAAE,QAAiB,EAAU,EAAE;IACpE,IAAI,UAAU,IAAI,QAAQ,EAAE,CAAC;QACzB,OAAO,CACH,2FAA2F;YAC3F,sFAAsF,CACzF,CAAC;IACN,CAAC;IAED,OAAO,CACH,gGAAgG;QAChG,6FAA6F;QAC7F,4CAA4C,CAC/C,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,KAAsB,EAAkC,EAAE;IAC3E,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,MAAM,QAAQ,GAAG,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,WAAW,EAAqC,CAAC,CAAC;IAE5F,OAAO,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/D,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,KAAK,EAAE,IAAiC,EAAyB,EAAE;IACtF,IAAI,CAAC;QACD,OAAO,MAAM,IAAI,EAAE,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC,CAAC;AAEF,SAAS,YAAY,CAAC,OAAsB,EAAE,GAAoB,EAAE,MAAmB;IACnF,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAE5C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,mBAAmB,CACrB,4BAA4B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC;YACzF,yEAAyE,CAC5E,CAAC;IACN,CAAC;IAED,OAAO,cAAc,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AACvF,CAAC;AAED,SAAS,YAAY,CAAC,OAAsB,EAAE,GAAoB,EAAE,MAAmB;IACnF,OAAO,cAAc,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AAClG,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAsB,EAAE,GAAoB,EAAE,MAAmB;IACxF,OAAO,cAAc,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AACvG,CAAC;AAED,KAAK,UAAU,YAAY,CACvB,OAAsB,EACtB,GAAoB,EACpB,MAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC9B,cAAc,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACtF,iBAAiB,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC;QACvC,YAAY,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC;KACrC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,MAAmB,EAAU,EAAE,CACnD,uBAAuB,MAAM,CAAC,EAAE,YAAY,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI;IAC/G,6GAA6G;IAC7G,4DAA4D,CAAC;AAEjE,KAAK,UAAU,WAAW,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAkB,EAAE,MAAmB;IAC7E,MAAM,OAAO,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,CAAC,MAAkB,EAAU,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAEjF,OAAO;QACH,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;QAChF,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;KAChE,CAAC;AACN,CAAC;AAED,MAAM,uBAAuB,GAAG,CAAC,QAAwB,EAAc,EAAE;IACrE,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;IAExC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,QAAQ,CAAC;AACpB,CAAC,CAAC;AAEF,KAAK,UAAU,gBAAgB,CAC3B,EAAE,QAAQ,EAAkB,EAC5B,MAAgD;IAEhD,MAAM,OAAO,GAAG,MAAM,iBAAiB,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IAC9G,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAEvE,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IACpF,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC5D,CAAC;AAED,MAAM,uBAAuB,GAAG,CAAC,MAAc,EAAmC,EAAE,CAChF,MAAM,CAAC,MAAM,CAAC,0BAA0B,EAAE,MAAM,CAAC,CAAC;AAEtD,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAE,MAAe,EAAE,GAAmB,EAAmB,EAAE;IAC7F,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,EAAE,CAAC;QACnC,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC,CAAC;AAEF,OAAO,EAAE,QAAQ,EAAE,CAAC","sourcesContent":["import * as Gtk from \"@gtkx/gi/gtk\";\nimport {\n invalidRequestError,\n methodNotFoundError,\n type ParamsSchema,\n type Result,\n type ServerInitiatedMethod,\n type ServerRequestParams,\n ServerRequestParamsSchemas,\n widgetNotFoundError,\n} from \"@gtkx/mcp/internal\";\nimport type { WidgetRegistry } from \"./widget-registry.js\";\nimport { serializeWidget } from \"./serialize-widget.js\";\nimport { loadTestingModule, type TestingModule } from \"./testing-loader.js\";\nimport { readWidgetProperties } from \"./widget-properties.js\";\n\ntype HandlerContext = {\n app: Gtk.Application;\n registry: WidgetRegistry;\n};\n\ntype ValidatedHandler = (ctx: HandlerContext, params: unknown) => Promise<Result>;\ntype WidgetTarget = { testing: TestingModule; widget: Gtk.Widget };\ntype WidgetParams = { widgetId?: string | undefined };\ntype TargetedHandler<Params> = (ctx: HandlerContext, target: WidgetTarget, params: Params) => Promise<Result>;\ntype QueryParams = ServerRequestParams<\"widget.query\">;\ntype QueryBy = QueryParams[\"by\"];\ntype QueryRunner = (testing: TestingModule, app: Gtk.Application, params: QueryParams) => Promise<Gtk.Widget[]>;\n\nconst HANDLERS: Record<ServerInitiatedMethod, ValidatedHandler> = {\n \"app.getWindows\": validated(ServerRequestParamsSchemas[\"app.getWindows\"], ({ registry }) =>\n Promise.resolve({\n windows: registry.toplevels().map((window) => ({\n id: registry.getOrCreateId(window),\n title: window.getTitle(),\n })),\n })),\n \"widget.getTree\": validated(ServerRequestParamsSchemas[\"widget.getTree\"], async ({ app, registry }, params) => {\n const testing = await loadTestingModule();\n const container = params.rootId === undefined ? app : requireWidget(registry, params.rootId);\n\n return {\n tree: testing.prettyWidget(container, {\n getId: (w) => registry.getOrCreateId(w),\n shouldHighlight: false,\n ...((params.maxDepth !== undefined) && { maxDepth: params.maxDepth }),\n }),\n };\n }),\n \"widget.query\": validated(ServerRequestParamsSchemas[\"widget.query\"], handleQuery),\n \"widget.getProps\": targeted(\n ServerRequestParamsSchemas[\"widget.getProps\"],\n ({ registry }, { testing, widget }, params) =>\n Promise.resolve({\n ...(params.properties !== undefined && {\n properties: readWidgetProperties(widget, params.properties, registry),\n }),\n ...serializeWidget(widget, (target) => registry.getOrCreateId(target), testing, params.maxDepth),\n }),\n ),\n \"widget.click\": targeted(ServerRequestParamsSchemas[\"widget.click\"], async (_ctx, { testing, widget }) => {\n await testing.userEvent.click(widget);\n\n return { success: true };\n }),\n \"widget.type\": targeted(ServerRequestParamsSchemas[\"widget.type\"], async (_ctx, { testing, widget }, params) => {\n if (params.clear) {\n await testing.userEvent.clear(widget);\n }\n\n await testing.userEvent.type(widget, params.text);\n\n return { success: true };\n }),\n \"widget.fireEvent\": targeted(\n ServerRequestParamsSchemas[\"widget.fireEvent\"],\n async (_ctx, { testing, widget }, params) => {\n const signalArgs = (params.args ?? []).map((arg) => extractSignalArg(arg));\n const isRealized = widget.getRealized();\n const isMapped = widget.getMapped();\n const isSensitive = widget.getSensitive();\n await testing.fireEvent(widget, params.signal, ...signalArgs);\n\n return {\n signal: params.signal,\n isRealized,\n isMapped,\n isSensitive,\n note: emissionNote(isRealized, isMapped),\n };\n },\n ),\n \"widget.screenshot\": validated(ServerRequestParamsSchemas[\"widget.screenshot\"], handleScreenshot),\n};\n\nconst QUERY_RUNNERS: Record<QueryBy, QueryRunner> = {\n role: runRoleQuery,\n text: runTextQuery,\n name: runNameQuery,\n labelText: runLabelTextQuery,\n};\n\nconst SEARCHED_BY: Record<QueryBy, string> = {\n role: \"the accessible role, narrowed by any options given\",\n text: \"the text the widget renders\",\n name:\n \"the widget name (gtk_widget_get_name, which reports the GType name such as \\\"GtkButton\\\" when no name \" +\n \"was set), the accessible label, and the text the widget renders\",\n labelText: \"the accessible label, the labelled-by relation, and the label whose mnemonic targets the widget\",\n};\n\nfunction validated<Params>(\n schema: ParamsSchema<Params>,\n handler: (ctx: HandlerContext, params: Params) => Promise<Result>,\n): ValidatedHandler {\n return (ctx, params) => {\n const parsed = schema.safeParse(params ?? {});\n\n if (!parsed.success) {\n throw invalidRequestError(parsed.error.message);\n }\n\n return handler(ctx, parsed.data);\n };\n}\n\nfunction targeted<Params extends WidgetParams>(\n schema: ParamsSchema<Params>,\n handler: TargetedHandler<Params>,\n): ValidatedHandler {\n return validated(schema, async (ctx, params) =>\n handler(ctx, await widgetTarget(ctx.registry, params.widgetId), params));\n}\n\nconst widgetTarget = async (registry: WidgetRegistry, widgetId: string | undefined): Promise<WidgetTarget> => ({\n testing: await loadTestingModule(),\n widget: requireWidget(registry, widgetId),\n});\n\nconst requireWidget = (registry: WidgetRegistry, widgetId: string | undefined): Gtk.Widget => {\n if (widgetId === undefined) {\n throw widgetNotFoundError(\"undefined\");\n }\n\n const widget = registry.get(widgetId);\n\n if (!widget) {\n throw widgetNotFoundError(widgetId);\n }\n\n return widget;\n};\n\nconst extractSignalArg = (arg: unknown): unknown => {\n const isTypedArg = typeof arg === \"object\" && arg !== null && \"type\" in arg && \"value\" in arg;\n\n return isTypedArg ? (arg as { value: unknown }).value : arg;\n};\n\nconst emissionNote = (isRealized: boolean, isMapped: boolean): string => {\n if (isRealized && isMapped) {\n return (\n \"The signal was emitted. Default handlers that animate, such as a button activate, settle \" +\n \"asynchronously, so read the widget again rather than assuming the effect has landed.\"\n );\n }\n\n return (\n \"The signal was emitted on a widget that is not realized and mapped, so a default handler that \" +\n \"requires a drawn widget does nothing. Present the containing window or open the containing \" +\n \"popover first, then fire the signal again.\"\n );\n};\n\nconst resolveRole = (value: string | number): Gtk.AccessibleRole | undefined => {\n if (typeof value === \"number\") {\n return value;\n }\n\n const resolved = Gtk.AccessibleRole[value.toUpperCase() as keyof typeof Gtk.AccessibleRole];\n\n return typeof resolved === \"number\" ? resolved : undefined;\n};\n\nconst matchesOrEmpty = async (find: () => Promise<Gtk.Widget[]>): Promise<Gtk.Widget[]> => {\n try {\n return await find();\n } catch {\n return [];\n }\n};\n\nfunction runRoleQuery(testing: TestingModule, app: Gtk.Application, params: QueryParams): Promise<Gtk.Widget[]> {\n const roleValue = resolveRole(params.value);\n\n if (roleValue === undefined) {\n throw invalidRequestError(\n `Unknown accessible role \"${String(params.value)}\"; use the lowercase role shown in the ` +\n \"widget tree, e.g. \\\"button\\\", \\\"list\\\", \\\"list_item\\\", or \\\"checkbox\\\".\",\n );\n }\n\n return matchesOrEmpty(() => testing.findAllByRole(app, roleValue, params.options));\n}\n\nfunction runTextQuery(testing: TestingModule, app: Gtk.Application, params: QueryParams): Promise<Gtk.Widget[]> {\n return matchesOrEmpty(() => testing.findAllByText(app, String(params.value), params.options));\n}\n\nfunction runLabelTextQuery(testing: TestingModule, app: Gtk.Application, params: QueryParams): Promise<Gtk.Widget[]> {\n return matchesOrEmpty(() => testing.findAllByLabelText(app, String(params.value), params.options));\n}\n\nasync function runNameQuery(\n testing: TestingModule,\n app: Gtk.Application,\n params: QueryParams,\n): Promise<Gtk.Widget[]> {\n const matches = await Promise.all([\n matchesOrEmpty(() => testing.findAllByName(app, String(params.value), params.options)),\n runLabelTextQuery(testing, app, params),\n runTextQuery(testing, app, params),\n ]);\n\n return [...new Set(matches.flat())];\n}\n\nconst emptyQueryHint = (params: QueryParams): string =>\n `Nothing matched by:\"${params.by}\" value:\"${String(params.value)}\", which compared ${SEARCHED_BY[params.by]}. ` +\n \"Call gtkx_get_widget_tree to see what is mounted; by:\\\"name\\\" is the widest match, and by:\\\"role\\\" accepts \" +\n \"options.name to match the accessible name of a known role.\";\n\nasync function handleQuery({ app, registry }: HandlerContext, params: QueryParams): Promise<Result> {\n const testing = await loadTestingModule();\n const widgets = await QUERY_RUNNERS[params.by](testing, app, params);\n const resolveId = (widget: Gtk.Widget): string => registry.getOrCreateId(widget);\n\n return {\n widgets: widgets.map((widget) => serializeWidget(widget, resolveId, testing, 0)),\n searched: SEARCHED_BY[params.by],\n ...(widgets.length === 0 && { hint: emptyQueryHint(params) }),\n };\n}\n\nconst defaultScreenshotTarget = (registry: WidgetRegistry): Gtk.Widget => {\n const [toplevel] = registry.toplevels();\n\n if (!toplevel) {\n throw new Error(\"No windows available for screenshot\");\n }\n\n return toplevel;\n};\n\nasync function handleScreenshot(\n { registry }: HandlerContext,\n params: ServerRequestParams<\"widget.screenshot\">,\n): Promise<Result> {\n const testing = await loadTestingModule();\n const target = params.windowId ? requireWidget(registry, params.windowId) : defaultScreenshotTarget(registry);\n const result = await testing.screenshot(target, { path: params.path });\n\n if (params.path) {\n return { data: result.data, mimeType: result.mimeType, savedPath: params.path };\n }\n\n return { data: result.data, mimeType: result.mimeType };\n}\n\nconst isServerInitiatedMethod = (method: string): method is ServerInitiatedMethod =>\n Object.hasOwn(ServerRequestParamsSchemas, method);\n\nconst dispatch = async (method: string, params: unknown, ctx: HandlerContext): Promise<Result> => {\n if (!isServerInitiatedMethod(method)) {\n throw methodNotFoundError(method);\n }\n\n return HANDLERS[method](ctx, params);\n};\n\nexport { dispatch };\n"]}
|
|
@@ -5,7 +5,10 @@ type EnvAssetDeclarations = {
|
|
|
5
5
|
legacy: string[];
|
|
6
6
|
resources: string[];
|
|
7
7
|
};
|
|
8
|
+
type EnvModuleOptions = {
|
|
9
|
+
references?: string[];
|
|
10
|
+
};
|
|
8
11
|
declare const renderRuntimeModule: (file: ParsedSchemaFile) => string;
|
|
9
|
-
declare const renderEnvModule: (files: ParsedSchemaFile[], assetDeclarations?: EnvAssetDeclarations) => string;
|
|
12
|
+
declare const renderEnvModule: (files: ParsedSchemaFile[], assetDeclarations?: EnvAssetDeclarations, options?: EnvModuleOptions) => string;
|
|
10
13
|
export { renderRuntimeModule, renderEnvModule };
|
|
11
14
|
//# sourceMappingURL=render.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/settings/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA2B,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAO7E,KAAK,oBAAoB,GAAG;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AA6DF,QAAA,MAAM,mBAAmB,GAAI,MAAM,gBAAgB,KAAG,MA0BrD,CAAC;AA6HF,QAAA,MAAM,eAAe,GACjB,OAAO,gBAAgB,EAAE,EACzB,oBAAoB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/settings/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA2B,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAO7E,KAAK,oBAAoB,GAAG;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AA6DF,QAAA,MAAM,mBAAmB,GAAI,MAAM,gBAAgB,KAAG,MA0BrD,CAAC;AA6HF,QAAA,MAAM,eAAe,GACjB,OAAO,gBAAgB,EAAE,EACzB,oBAAoB,oBAAoB,EACxC,UAAS,gBAAqB,KAC/B,MAuBF,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/settings/render.js
CHANGED
|
@@ -155,7 +155,7 @@ const renderBlockedAssetModule = (specifier) => [
|
|
|
155
155
|
" export default assetImportRequiresResourceOrUrlQuery;",
|
|
156
156
|
"}",
|
|
157
157
|
].join("\n");
|
|
158
|
-
const renderEnvModule = (files, assetDeclarations) => {
|
|
158
|
+
const renderEnvModule = (files, assetDeclarations, options = {}) => {
|
|
159
159
|
const assets = assetDeclarations ?? { blocked: [], icons: [], legacy: [], resources: [] };
|
|
160
160
|
const usedNames = new Set();
|
|
161
161
|
const schemas = files
|
|
@@ -165,7 +165,16 @@ const renderEnvModule = (files, assetDeclarations) => {
|
|
|
165
165
|
const icons = assets.icons.map((specifier) => renderIconModule(specifier));
|
|
166
166
|
const legacy = assets.legacy.map((specifier) => renderLegacyAssetModule(specifier));
|
|
167
167
|
const resources = assets.resources.map((specifier) => renderResourceModule(specifier));
|
|
168
|
-
|
|
168
|
+
const references = (options.references ?? []).map((path) => `/// <reference path=${JSON.stringify(path)} />`);
|
|
169
|
+
return `${[
|
|
170
|
+
GTKX_ENV_MODULE_HEADER,
|
|
171
|
+
...references,
|
|
172
|
+
...blocked,
|
|
173
|
+
...icons,
|
|
174
|
+
...legacy,
|
|
175
|
+
...resources,
|
|
176
|
+
...schemas,
|
|
177
|
+
].join("\n\n")}\n`;
|
|
169
178
|
};
|
|
170
179
|
export { renderRuntimeModule, renderEnvModule };
|
|
171
180
|
//# sourceMappingURL=render.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/settings/render.ts"],"names":[],"mappings":"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","sourcesContent":["import { camelCase, sanitizeIdentifier, upperFirst } from \"@gtkx/utils\";\nimport type { ParsedKey, ParsedSchema, ParsedSchemaFile } from \"./parser.js\";\n\ntype NamedSchema = {\n schema: ParsedSchema;\n exportName: string;\n};\n\ntype EnvAssetDeclarations = {\n blocked: string[];\n icons: string[];\n legacy: string[];\n resources: string[];\n};\n\nconst GTKX_ENV_MODULE_HEADER = `/**\n * Project import declarations generated by GTKX. Regenerated by\n * \\`gtkx codegen\\`, \\`gtkx dev\\`, and \\`gtkx build\\`; do not edit.\n */`;\n\nconst ENUM_KIND = \"enum\";\nconst FLAGS_KIND = \"flags\";\nconst ID_SEPARATOR = /[._]/;\nconst NAME_SEPARATOR = \"_\";\n\nconst toJsStringLiteral = (value: string): string =>\n JSON.stringify(value).replaceAll(\"\\u{2028}\", String.raw`\\u2028`).replaceAll(\"\\u{2029}\", String.raw`\\u2029`);\n\nconst getExportName = (schemaId: string): string =>\n sanitizeIdentifier(schemaId.split(ID_SEPARATOR).map((part) => camelCase(part)).join(NAME_SEPARATOR));\n\nconst collisionError = (file: ParsedSchemaFile, taken: string, schemaId: string, name: string): Error =>\n new Error(\n `${file.fileName} declares ${taken} and ${schemaId}, which both export \\`${name}\\`. ` +\n \"Rename one of the schema ids so that every schema in the file gets an export of its own.\",\n );\n\nconst getNamedSchemas = (file: ParsedSchemaFile): NamedSchema[] => {\n const owners: Map<string, string> = new Map();\n\n return file.schemas.map((schema) => {\n const exportName = getExportName(schema.id);\n const taken = owners.get(exportName);\n\n if (taken !== undefined) {\n throw collisionError(file, taken, schema.id, exportName);\n }\n\n owners.set(exportName, schema.id);\n\n return { schema, exportName };\n });\n};\n\nconst runtimeKindForKey = (key: ParsedKey): string => {\n if (key.enumId !== null) {\n return ENUM_KIND;\n }\n\n if (key.flagsId !== null) {\n return FLAGS_KIND;\n }\n\n return key.variantType ?? \"\";\n};\n\nconst getRuntimeKeys = (schema: ParsedSchema): string => {\n const entries = schema.keys.map(\n (key) => `${toJsStringLiteral(key.name)}: ${toJsStringLiteral(runtimeKindForKey(key))}`,\n );\n\n return `{ ${entries.join(\", \")} }`;\n};\n\nconst renderRuntimeModule = (file: ParsedSchemaFile): string => {\n const lines: string[] = [];\n const named = getNamedSchemas(file);\n\n for (const [index, { schema, exportName }] of named.entries()) {\n const keysName = `keys_${String(index)}`;\n const id = toJsStringLiteral(schema.id);\n lines.push(`const ${keysName} = ${getRuntimeKeys(schema)};`);\n\n if (schema.path === null) {\n lines.push(\n `export const ${exportName} = { id: ${id}, keys: ${keysName}, ` +\n `at: (path) => ({ id: ${id}, path, keys: ${keysName} }) };`,\n );\n } else {\n lines.push(`export const ${exportName} = { id: ${id}, path: null, keys: ${keysName} };`);\n }\n }\n\n const first = named[0];\n\n if (first !== undefined) {\n lines.push(`export default ${first.exportName};`);\n }\n\n return lines.join(\"\\n\");\n};\n\nconst sanitizeSummary = (summary: string): string => summary.replaceAll(\"*/\", String.raw`*\\/`);\n\nconst allocateInterfaceName = (schemaId: string, usedNames: Set<string>): string => {\n const base = `${schemaId\n .split(/[^a-zA-Z0-9]+/)\n .filter((part) => part.length > 0)\n .map((part) => upperFirst(part))\n .join(\"\")}Keys`;\n\n let name = base;\n let suffix = 2;\n\n while (usedNames.has(name)) {\n name = `${base}${String(suffix)}`;\n suffix += 1;\n }\n\n usedNames.add(name);\n\n return name;\n};\n\nconst renderKeysType = (name: string, schema: ParsedSchema): string[] => {\n const lines = [` type ${name} = {`];\n\n for (const key of schema.keys) {\n if (key.summary !== null) {\n lines.push(` /** ${sanitizeSummary(key.summary)} */`);\n }\n\n lines.push(` ${toJsStringLiteral(key.name)}: ${toJsStringLiteral(runtimeKindForKey(key))};`);\n }\n\n lines.push(\" };\");\n\n return lines;\n};\n\nconst boundRefTypeLines = (interfaceName: string, indent: string): string[] => [\n `${indent}id: string;`,\n `${indent}path: string | null;`,\n `${indent}keys: ${interfaceName};`,\n];\n\nconst renderSchemaConst = ({ schema, exportName }: NamedSchema, interfaceName: string): string[] => {\n if (schema.path !== null) {\n return [\n ` const ${exportName}: {`,\n ` id: ${toJsStringLiteral(schema.id)};`,\n ...boundRefTypeLines(interfaceName, \" \".repeat(8)).slice(1),\n \" };\",\n ];\n }\n\n return [\n ` const ${exportName}: {`,\n ` id: ${JSON.stringify(schema.id)};`,\n ` keys: ${interfaceName};`,\n \" at(path: string): {\",\n ...boundRefTypeLines(interfaceName, \" \".repeat(12)),\n \" };\",\n \" };\",\n ];\n};\n\nconst renderFileModule = (file: ParsedSchemaFile, usedNames: Set<string>): string[] => {\n const lines = [`declare module ${toJsStringLiteral(file.fileName)} {`];\n const exportNames: string[] = [];\n\n for (const [index, named] of getNamedSchemas(file).entries()) {\n if (index > 0) {\n lines.push(\"\");\n }\n\n const interfaceName = allocateInterfaceName(named.schema.id, usedNames);\n lines.push(...renderKeysType(interfaceName, named.schema), \"\", ...renderSchemaConst(named, interfaceName));\n exportNames.push(named.exportName);\n }\n\n const [firstExport] = exportNames;\n\n if (firstExport !== undefined) {\n lines.push(\"\", ` export { ${exportNames.join(\", \")} };`, ` export default ${firstExport};`);\n }\n\n lines.push(\"}\");\n\n return lines;\n};\n\nconst renderResourceModule = (specifier: string): string => [\n `declare module ${toJsStringLiteral(specifier)} {`,\n \" const path: string;\",\n \" export { path };\",\n \" export default path;\",\n \"}\",\n].join(\"\\n\");\n\nconst renderIconModule = (specifier: string): string => [\n `declare module ${toJsStringLiteral(specifier)} {`,\n \" const iconName: string;\",\n \" export default iconName;\",\n \"}\",\n].join(\"\\n\");\n\nconst renderLegacyAssetModule = (specifier: string): string => [\n `declare module ${toJsStringLiteral(specifier)} {`,\n \" const resourceUri: string;\",\n \" const path: string;\",\n \" export { path };\",\n \" export default resourceUri;\",\n \"}\",\n].join(\"\\n\");\n\nconst renderBlockedAssetModule = (specifier: string): string => [\n `declare module ${toJsStringLiteral(specifier)} {`,\n \" const assetImportRequiresResourceOrUrlQuery: {\",\n \" readonly __gtkxAssetImportRequiresResourceOrUrlQuery: unique symbol;\",\n \" };\",\n \" export default assetImportRequiresResourceOrUrlQuery;\",\n \"}\",\n].join(\"\\n\");\n\nconst renderEnvModule = (\n files: ParsedSchemaFile[],\n assetDeclarations?: EnvAssetDeclarations,\n): string => {\n const assets = assetDeclarations ?? { blocked: [], icons: [], legacy: [], resources: [] };\n const usedNames: Set<string> = new Set();\n\n const schemas = files\n .filter((file) => file.schemas.length > 0)\n .map((file) => renderFileModule(file, usedNames).join(\"\\n\"));\n\n const blocked = assets.blocked.map((specifier) => renderBlockedAssetModule(specifier));\n const icons = assets.icons.map((specifier) => renderIconModule(specifier));\n const legacy = assets.legacy.map((specifier) => renderLegacyAssetModule(specifier));\n const resources = assets.resources.map((specifier) => renderResourceModule(specifier));\n\n return `${[GTKX_ENV_MODULE_HEADER, ...blocked, ...icons, ...legacy, ...resources, ...schemas].join(\"\\n\\n\")}\\n`;\n};\n\nexport { renderRuntimeModule, renderEnvModule };\n"]}
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/settings/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAmBxE,MAAM,sBAAsB,GAAG;;;IAG3B,CAAC;AAEL,MAAM,SAAS,GAAG,MAAM,CAAC;AACzB,MAAM,UAAU,GAAG,OAAO,CAAC;AAC3B,MAAM,YAAY,GAAG,MAAM,CAAC;AAC5B,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B,MAAM,iBAAiB,GAAG,CAAC,KAAa,EAAU,EAAE,CAChD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,CAAA,QAAQ,CAAC,CAAC,UAAU,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG,CAAA,QAAQ,CAAC,CAAC;AAEhH,MAAM,aAAa,GAAG,CAAC,QAAgB,EAAU,EAAE,CAC/C,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;AAEzG,MAAM,cAAc,GAAG,CAAC,IAAsB,EAAE,KAAa,EAAE,QAAgB,EAAE,IAAY,EAAS,EAAE,CACpG,IAAI,KAAK,CACL,GAAG,IAAI,CAAC,QAAQ,aAAa,KAAK,QAAQ,QAAQ,yBAAyB,IAAI,MAAM;IACrF,0FAA0F,CAC7F,CAAC;AAEN,MAAM,eAAe,GAAG,CAAC,IAAsB,EAAiB,EAAE;IAC9D,MAAM,MAAM,GAAwB,IAAI,GAAG,EAAE,CAAC;IAE9C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC/B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAErC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAC7D,CAAC;QAED,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAElC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAClC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,GAAc,EAAU,EAAE;IACjD,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QACtB,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO,UAAU,CAAC;IACtB,CAAC;IAED,OAAO,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,MAAoB,EAAU,EAAE;IACpD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAC3B,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,iBAAiB,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,EAAE,CAC1F,CAAC;IAEF,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACvC,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAAC,IAAsB,EAAU,EAAE;IAC3D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IAEpC,KAAK,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC5D,MAAM,QAAQ,GAAG,QAAQ,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,EAAE,GAAG,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACxC,KAAK,CAAC,IAAI,CAAC,SAAS,QAAQ,MAAM,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAE7D,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CACN,gBAAgB,UAAU,YAAY,EAAE,WAAW,QAAQ,IAAI;gBAC/D,wBAAwB,EAAE,iBAAiB,QAAQ,QAAQ,CAC9D,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,IAAI,CAAC,gBAAgB,UAAU,YAAY,EAAE,uBAAuB,QAAQ,KAAK,CAAC,CAAC;QAC7F,CAAC;IACL,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEvB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,kBAAkB,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,OAAe,EAAU,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,CAAA,KAAK,CAAC,CAAC;AAE/F,MAAM,qBAAqB,GAAG,CAAC,QAAgB,EAAE,SAAsB,EAAU,EAAE;IAC/E,MAAM,IAAI,GAAG,GAAG,QAAQ;SACnB,KAAK,CAAC,eAAe,CAAC;SACtB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;SACjC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;SAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC;IAEpB,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,IAAI,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEpB,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,MAAoB,EAAY,EAAE;IACpE,MAAM,KAAK,GAAG,CAAC,YAAY,IAAI,MAAM,CAAC,CAAC;IAEvC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,eAAe,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjE,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,WAAW,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,iBAAiB,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;IACxG,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAErB,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,aAAqB,EAAE,MAAc,EAAY,EAAE,CAAC;IAC3E,GAAG,MAAM,aAAa;IACtB,GAAG,MAAM,sBAAsB;IAC/B,GAAG,MAAM,SAAS,aAAa,GAAG;CACrC,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,EAAE,MAAM,EAAE,UAAU,EAAe,EAAE,aAAqB,EAAY,EAAE;IAC/F,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QACvB,OAAO;YACH,aAAa,UAAU,KAAK;YAC5B,eAAe,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;YAC9C,GAAG,iBAAiB,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3D,QAAQ;SACX,CAAC;IACN,CAAC;IAED,OAAO;QACH,aAAa,UAAU,KAAK;QAC5B,eAAe,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG;QAC3C,iBAAiB,aAAa,GAAG;QACjC,6BAA6B;QAC7B,GAAG,iBAAiB,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnD,YAAY;QACZ,QAAQ;KACX,CAAC;AACN,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,IAAsB,EAAE,SAAsB,EAAY,EAAE;IAClF,MAAM,KAAK,GAAG,CAAC,kBAAkB,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACvE,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3D,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;QAED,MAAM,aAAa,GAAG,qBAAqB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;QACxE,KAAK,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,aAAa,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,iBAAiB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC;QAC3G,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;IAElC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,gBAAgB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,sBAAsB,WAAW,GAAG,CAAC,CAAC;IACtG,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEhB,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC;IACxD,kBAAkB,iBAAiB,CAAC,SAAS,CAAC,IAAI;IAClD,yBAAyB;IACzB,sBAAsB;IACtB,0BAA0B;IAC1B,GAAG;CACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,gBAAgB,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC;IACpD,kBAAkB,iBAAiB,CAAC,SAAS,CAAC,IAAI;IAClD,6BAA6B;IAC7B,8BAA8B;IAC9B,GAAG;CACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,uBAAuB,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC;IAC3D,kBAAkB,iBAAiB,CAAC,SAAS,CAAC,IAAI;IAClD,gCAAgC;IAChC,yBAAyB;IACzB,sBAAsB;IACtB,iCAAiC;IACjC,GAAG;CACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,wBAAwB,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC;IAC5D,kBAAkB,iBAAiB,CAAC,SAAS,CAAC,IAAI;IAClD,oDAAoD;IACpD,8EAA8E;IAC9E,QAAQ;IACR,2DAA2D;IAC3D,GAAG;CACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,eAAe,GAAG,CACpB,KAAyB,EACzB,iBAAwC,EACxC,UAA4B,EAAE,EACxB,EAAE;IACR,MAAM,MAAM,GAAG,iBAAiB,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAC1F,MAAM,SAAS,GAAgB,IAAI,GAAG,EAAE,CAAC;IAEzC,MAAM,OAAO,GAAG,KAAK;SAChB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;SACzC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC,CAAC;IACvF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;IAC3E,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,uBAAuB,CAAC,SAAS,CAAC,CAAC,CAAC;IACpF,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC;IACvF,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE9G,OAAO,GAAG;QACN,sBAAsB;QACtB,GAAG,UAAU;QACb,GAAG,OAAO;QACV,GAAG,KAAK;QACR,GAAG,MAAM;QACT,GAAG,SAAS;QACZ,GAAG,OAAO;KACb,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;AACvB,CAAC,CAAC;AAEF,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,CAAC","sourcesContent":["import { camelCase, sanitizeIdentifier, upperFirst } from \"@gtkx/utils\";\nimport type { ParsedKey, ParsedSchema, ParsedSchemaFile } from \"./parser.js\";\n\ntype NamedSchema = {\n schema: ParsedSchema;\n exportName: string;\n};\n\ntype EnvAssetDeclarations = {\n blocked: string[];\n icons: string[];\n legacy: string[];\n resources: string[];\n};\n\ntype EnvModuleOptions = {\n references?: string[];\n};\n\nconst GTKX_ENV_MODULE_HEADER = `/**\n * Project import declarations generated by GTKX. Regenerated by\n * \\`gtkx codegen\\`, \\`gtkx dev\\`, and \\`gtkx build\\`; do not edit.\n */`;\n\nconst ENUM_KIND = \"enum\";\nconst FLAGS_KIND = \"flags\";\nconst ID_SEPARATOR = /[._]/;\nconst NAME_SEPARATOR = \"_\";\n\nconst toJsStringLiteral = (value: string): string =>\n JSON.stringify(value).replaceAll(\"\\u{2028}\", String.raw`\\u2028`).replaceAll(\"\\u{2029}\", String.raw`\\u2029`);\n\nconst getExportName = (schemaId: string): string =>\n sanitizeIdentifier(schemaId.split(ID_SEPARATOR).map((part) => camelCase(part)).join(NAME_SEPARATOR));\n\nconst collisionError = (file: ParsedSchemaFile, taken: string, schemaId: string, name: string): Error =>\n new Error(\n `${file.fileName} declares ${taken} and ${schemaId}, which both export \\`${name}\\`. ` +\n \"Rename one of the schema ids so that every schema in the file gets an export of its own.\",\n );\n\nconst getNamedSchemas = (file: ParsedSchemaFile): NamedSchema[] => {\n const owners: Map<string, string> = new Map();\n\n return file.schemas.map((schema) => {\n const exportName = getExportName(schema.id);\n const taken = owners.get(exportName);\n\n if (taken !== undefined) {\n throw collisionError(file, taken, schema.id, exportName);\n }\n\n owners.set(exportName, schema.id);\n\n return { schema, exportName };\n });\n};\n\nconst runtimeKindForKey = (key: ParsedKey): string => {\n if (key.enumId !== null) {\n return ENUM_KIND;\n }\n\n if (key.flagsId !== null) {\n return FLAGS_KIND;\n }\n\n return key.variantType ?? \"\";\n};\n\nconst getRuntimeKeys = (schema: ParsedSchema): string => {\n const entries = schema.keys.map(\n (key) => `${toJsStringLiteral(key.name)}: ${toJsStringLiteral(runtimeKindForKey(key))}`,\n );\n\n return `{ ${entries.join(\", \")} }`;\n};\n\nconst renderRuntimeModule = (file: ParsedSchemaFile): string => {\n const lines: string[] = [];\n const named = getNamedSchemas(file);\n\n for (const [index, { schema, exportName }] of named.entries()) {\n const keysName = `keys_${String(index)}`;\n const id = toJsStringLiteral(schema.id);\n lines.push(`const ${keysName} = ${getRuntimeKeys(schema)};`);\n\n if (schema.path === null) {\n lines.push(\n `export const ${exportName} = { id: ${id}, keys: ${keysName}, ` +\n `at: (path) => ({ id: ${id}, path, keys: ${keysName} }) };`,\n );\n } else {\n lines.push(`export const ${exportName} = { id: ${id}, path: null, keys: ${keysName} };`);\n }\n }\n\n const first = named[0];\n\n if (first !== undefined) {\n lines.push(`export default ${first.exportName};`);\n }\n\n return lines.join(\"\\n\");\n};\n\nconst sanitizeSummary = (summary: string): string => summary.replaceAll(\"*/\", String.raw`*\\/`);\n\nconst allocateInterfaceName = (schemaId: string, usedNames: Set<string>): string => {\n const base = `${schemaId\n .split(/[^a-zA-Z0-9]+/)\n .filter((part) => part.length > 0)\n .map((part) => upperFirst(part))\n .join(\"\")}Keys`;\n\n let name = base;\n let suffix = 2;\n\n while (usedNames.has(name)) {\n name = `${base}${String(suffix)}`;\n suffix += 1;\n }\n\n usedNames.add(name);\n\n return name;\n};\n\nconst renderKeysType = (name: string, schema: ParsedSchema): string[] => {\n const lines = [` type ${name} = {`];\n\n for (const key of schema.keys) {\n if (key.summary !== null) {\n lines.push(` /** ${sanitizeSummary(key.summary)} */`);\n }\n\n lines.push(` ${toJsStringLiteral(key.name)}: ${toJsStringLiteral(runtimeKindForKey(key))};`);\n }\n\n lines.push(\" };\");\n\n return lines;\n};\n\nconst boundRefTypeLines = (interfaceName: string, indent: string): string[] => [\n `${indent}id: string;`,\n `${indent}path: string | null;`,\n `${indent}keys: ${interfaceName};`,\n];\n\nconst renderSchemaConst = ({ schema, exportName }: NamedSchema, interfaceName: string): string[] => {\n if (schema.path !== null) {\n return [\n ` const ${exportName}: {`,\n ` id: ${toJsStringLiteral(schema.id)};`,\n ...boundRefTypeLines(interfaceName, \" \".repeat(8)).slice(1),\n \" };\",\n ];\n }\n\n return [\n ` const ${exportName}: {`,\n ` id: ${JSON.stringify(schema.id)};`,\n ` keys: ${interfaceName};`,\n \" at(path: string): {\",\n ...boundRefTypeLines(interfaceName, \" \".repeat(12)),\n \" };\",\n \" };\",\n ];\n};\n\nconst renderFileModule = (file: ParsedSchemaFile, usedNames: Set<string>): string[] => {\n const lines = [`declare module ${toJsStringLiteral(file.fileName)} {`];\n const exportNames: string[] = [];\n\n for (const [index, named] of getNamedSchemas(file).entries()) {\n if (index > 0) {\n lines.push(\"\");\n }\n\n const interfaceName = allocateInterfaceName(named.schema.id, usedNames);\n lines.push(...renderKeysType(interfaceName, named.schema), \"\", ...renderSchemaConst(named, interfaceName));\n exportNames.push(named.exportName);\n }\n\n const [firstExport] = exportNames;\n\n if (firstExport !== undefined) {\n lines.push(\"\", ` export { ${exportNames.join(\", \")} };`, ` export default ${firstExport};`);\n }\n\n lines.push(\"}\");\n\n return lines;\n};\n\nconst renderResourceModule = (specifier: string): string => [\n `declare module ${toJsStringLiteral(specifier)} {`,\n \" const path: string;\",\n \" export { path };\",\n \" export default path;\",\n \"}\",\n].join(\"\\n\");\n\nconst renderIconModule = (specifier: string): string => [\n `declare module ${toJsStringLiteral(specifier)} {`,\n \" const iconName: string;\",\n \" export default iconName;\",\n \"}\",\n].join(\"\\n\");\n\nconst renderLegacyAssetModule = (specifier: string): string => [\n `declare module ${toJsStringLiteral(specifier)} {`,\n \" const resourceUri: string;\",\n \" const path: string;\",\n \" export { path };\",\n \" export default resourceUri;\",\n \"}\",\n].join(\"\\n\");\n\nconst renderBlockedAssetModule = (specifier: string): string => [\n `declare module ${toJsStringLiteral(specifier)} {`,\n \" const assetImportRequiresResourceOrUrlQuery: {\",\n \" readonly __gtkxAssetImportRequiresResourceOrUrlQuery: unique symbol;\",\n \" };\",\n \" export default assetImportRequiresResourceOrUrlQuery;\",\n \"}\",\n].join(\"\\n\");\n\nconst renderEnvModule = (\n files: ParsedSchemaFile[],\n assetDeclarations?: EnvAssetDeclarations,\n options: EnvModuleOptions = {},\n): string => {\n const assets = assetDeclarations ?? { blocked: [], icons: [], legacy: [], resources: [] };\n const usedNames: Set<string> = new Set();\n\n const schemas = files\n .filter((file) => file.schemas.length > 0)\n .map((file) => renderFileModule(file, usedNames).join(\"\\n\"));\n\n const blocked = assets.blocked.map((specifier) => renderBlockedAssetModule(specifier));\n const icons = assets.icons.map((specifier) => renderIconModule(specifier));\n const legacy = assets.legacy.map((specifier) => renderLegacyAssetModule(specifier));\n const resources = assets.resources.map((specifier) => renderResourceModule(specifier));\n const references = (options.references ?? []).map((path) => `/// <reference path=${JSON.stringify(path)} />`);\n\n return `${[\n GTKX_ENV_MODULE_HEADER,\n ...references,\n ...blocked,\n ...icons,\n ...legacy,\n ...resources,\n ...schemas,\n ].join(\"\\n\\n\")}\\n`;\n};\n\nexport { renderRuntimeModule, renderEnvModule };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/settings/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/settings/schema.ts"],"names":[],"mappings":"AA6BA,KAAK,eAAe,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,QAAA,MAAM,aAAa,iBAAiB,CAAC;AAMrC,QAAA,MAAM,gBAAgB,GAAI,KAAK,MAAM,EAAE,UAAU,MAAM,GAAG,SAAS,KAAG,MAUrE,CAAC;AAKF,QAAA,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,UAAU,MAAM,KAAG,IAEpD,CAAC;AAIF,QAAA,MAAM,yBAAyB,GAAI,MAAM,MAAM,EAAE,UAAU,MAAM,KAAG,MAAM,GAAG,IAc5E,CAAC;AA+GF,QAAA,MAAM,2BAA2B,GAAI,aAAa,MAAM,EAAE,KAAG,IAiB5D,CAAC;AA+BF,QAAA,MAAM,6BAA6B,GAAI,MAAM,MAAM,EAAE,SAAS,MAAM,GAAG,IAAI,KAAG,MAAM,GAAG,IAwBtF,CAAC;AAmDF,QAAA,MAAM,aAAa,GACf,SAAS,MAAM,EACf,SAAS,MAAM,GAAG,IAAI,EACtB,6BAA2B,KAC5B,eAmBF,CAAC;AAEF,OAAO,EACH,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,2BAA2B,EAC3B,yBAAyB,EACzB,6BAA6B,EAC7B,aAAa,GAChB,CAAC"}
|
package/dist/settings/schema.js
CHANGED
|
@@ -3,6 +3,7 @@ import { createHash } from "node:crypto";
|
|
|
3
3
|
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, realpathSync, writeFileSync, } from "node:fs";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
6
|
+
import { I18N_TYPES_FILENAME, i18nTypesPath } from "../i18n/types.js";
|
|
6
7
|
import { DATA_IMPORT_PREFIX } from "../internal/data-dir.js";
|
|
7
8
|
import { discoverSourceImports } from "../internal/source-imports.js";
|
|
8
9
|
import { removeTempDir } from "../internal/staging-dir.js";
|
|
@@ -219,7 +220,8 @@ const emitSchemaEnv = (rootDir, dataDir, isV2ResourceImports = false) => {
|
|
|
219
220
|
assertUniqueSchemaBasenames(importedFiles);
|
|
220
221
|
const imported = parseProjectSchemas(importedFiles, getRelativeModuleSpecifier);
|
|
221
222
|
const assets = findAssetModuleSpecifiers(imports, isV2ResourceImports);
|
|
222
|
-
const
|
|
223
|
+
const references = existsSync(i18nTypesPath(rootDir)) ? [`./${I18N_TYPES_FILENAME}`] : [];
|
|
224
|
+
const content = renderEnvModule([...legacy, ...imported], assets, { references });
|
|
223
225
|
const path = schemaEnvPath(rootDir);
|
|
224
226
|
const isWritten = didWriteChanges(path, content);
|
|
225
227
|
return { path, isWritten };
|