@gtkx/cli 1.0.0-rc.3 → 1.0.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 +8 -9
- package/dist/builder.d.ts +1 -1
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +2 -1
- package/dist/builder.js.map +1 -1
- package/dist/cli.js +4 -2
- package/dist/cli.js.map +1 -1
- package/dist/codegen/freshness.d.ts.map +1 -1
- package/dist/codegen/freshness.js +3 -6
- package/dist/codegen/freshness.js.map +1 -1
- package/dist/codegen/run-codegen.d.ts +4 -4
- package/dist/codegen/run-codegen.d.ts.map +1 -1
- package/dist/codegen/run-codegen.js +15 -14
- package/dist/codegen/run-codegen.js.map +1 -1
- package/dist/codegen/store-resolver.d.ts +1 -3
- package/dist/codegen/store-resolver.d.ts.map +1 -1
- package/dist/codegen/store-resolver.js +13 -32
- package/dist/codegen/store-resolver.js.map +1 -1
- package/dist/commands/build.js +1 -1
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/codegen.js +1 -1
- package/dist/commands/codegen.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +4 -2
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/docs.js +13 -13
- package/dist/commands/docs.js.map +1 -1
- package/dist/dev/entry-env.d.ts +3 -0
- package/dist/dev/entry-env.d.ts.map +1 -0
- package/dist/dev/entry-env.js +3 -0
- package/dist/dev/entry-env.js.map +1 -0
- package/dist/dev/runner-deps.d.ts.map +1 -1
- package/dist/dev/runner-deps.js +1 -0
- package/dist/dev/runner-deps.js.map +1 -1
- package/dist/dev/runner-main.d.ts.map +1 -1
- package/dist/dev/runner-main.js +3 -3
- package/dist/dev/runner-main.js.map +1 -1
- package/dist/dev/runner.d.ts +1 -0
- package/dist/dev/runner.d.ts.map +1 -1
- package/dist/dev/runner.js +22 -12
- package/dist/dev/runner.js.map +1 -1
- package/dist/dev/supervisor.d.ts +10 -3
- package/dist/dev/supervisor.d.ts.map +1 -1
- package/dist/dev/supervisor.js +37 -18
- package/dist/dev/supervisor.js.map +1 -1
- package/dist/internal/application-args.d.ts +6 -0
- package/dist/internal/application-args.d.ts.map +1 -0
- package/dist/internal/application-args.js +10 -0
- package/dist/internal/application-args.js.map +1 -0
- package/dist/internal/errors.d.ts +1 -2
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +1 -1
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/run-cli-tool.d.ts +10 -0
- package/dist/internal/run-cli-tool.d.ts.map +1 -0
- package/dist/internal/run-cli-tool.js +15 -0
- package/dist/internal/run-cli-tool.js.map +1 -0
- package/dist/internal.d.ts +3 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +3 -0
- package/dist/internal.js.map +1 -0
- package/dist/mcp/client.d.ts +1 -1
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/handlers.d.ts +1 -1
- package/dist/mcp/handlers.d.ts.map +1 -1
- package/dist/mcp/handlers.js +79 -42
- package/dist/mcp/handlers.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +1 -0
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/serialize-widget.d.ts +2 -2
- package/dist/mcp/serialize-widget.d.ts.map +1 -1
- package/dist/mcp/serialize-widget.js +47 -17
- package/dist/mcp/serialize-widget.js.map +1 -1
- package/dist/mcp/widget-properties.d.ts +6 -0
- package/dist/mcp/widget-properties.d.ts.map +1 -0
- package/dist/mcp/widget-properties.js +102 -0
- package/dist/mcp/widget-properties.js.map +1 -0
- package/dist/refresh-runtime.d.ts +0 -10
- package/dist/refresh-runtime.d.ts.map +1 -1
- package/dist/refresh-runtime.js +0 -17
- package/dist/refresh-runtime.js.map +1 -1
- package/dist/settings/compile.d.ts.map +1 -1
- package/dist/settings/compile.js +8 -12
- package/dist/settings/compile.js.map +1 -1
- package/dist/settings/schema.d.ts +1 -1
- package/dist/settings/schema.d.ts.map +1 -1
- package/dist/settings/schema.js +1 -1
- package/dist/settings/schema.js.map +1 -1
- package/dist/vite-plugins/asset-emitter.d.ts +9 -0
- package/dist/vite-plugins/asset-emitter.d.ts.map +1 -0
- package/dist/vite-plugins/asset-emitter.js +2 -0
- package/dist/vite-plugins/asset-emitter.js.map +1 -0
- package/dist/vite-plugins/asset-extensions.d.ts +1 -2
- package/dist/vite-plugins/asset-extensions.d.ts.map +1 -1
- package/dist/vite-plugins/asset-extensions.js +1 -1
- package/dist/vite-plugins/asset-extensions.js.map +1 -1
- package/dist/vite-plugins/built-url.d.ts.map +1 -1
- package/dist/vite-plugins/built-url.js +14 -10
- package/dist/vite-plugins/built-url.js.map +1 -1
- package/dist/vite-plugins/ensure-store.d.ts +4 -0
- package/dist/vite-plugins/ensure-store.d.ts.map +1 -0
- package/dist/vite-plugins/ensure-store.js +10 -0
- package/dist/vite-plugins/ensure-store.js.map +1 -0
- package/dist/vite-plugins/icons.d.ts.map +1 -1
- package/dist/vite-plugins/icons.js.map +1 -1
- package/dist/vite-plugins/react-compiler.d.ts +1 -1
- package/dist/vite-plugins/react-compiler.d.ts.map +1 -1
- package/dist/vite-plugins/react-compiler.js.map +1 -1
- package/dist/vite-plugins/resources.d.ts +1 -1
- package/dist/vite-plugins/resources.d.ts.map +1 -1
- package/dist/vite-plugins/resources.js +6 -15
- package/dist/vite-plugins/resources.js.map +1 -1
- package/dist/vite-plugins/settings.js.map +1 -1
- package/dist/vite-plugins/undeclared-library.d.ts +1 -1
- package/dist/vite-plugins/undeclared-library.d.ts.map +1 -1
- package/dist/vite-plugins/undeclared-library.js.map +1 -1
- package/dist/vite-plugins/worker.d.ts +4 -0
- package/dist/vite-plugins/worker.d.ts.map +1 -0
- package/dist/vite-plugins/worker.js +136 -0
- package/dist/vite-plugins/worker.js.map +1 -0
- package/dist/vitest-plugin.d.ts +4 -3
- package/dist/vitest-plugin.d.ts.map +1 -1
- package/dist/vitest-plugin.js +11 -4
- package/dist/vitest-plugin.js.map +1 -1
- package/env.d.ts +25 -0
- package/package.json +17 -13
- package/src/builder.ts +3 -2
- package/src/cli.ts +4 -2
- package/src/codegen/freshness.ts +3 -8
- package/src/codegen/run-codegen.ts +19 -19
- package/src/codegen/store-resolver.ts +14 -40
- package/src/commands/build.ts +1 -1
- package/src/commands/codegen.ts +1 -1
- package/src/commands/dev.ts +4 -2
- package/src/commands/docs.ts +15 -15
- package/src/dev/entry-env.ts +3 -0
- package/src/dev/runner-deps.ts +1 -0
- package/src/dev/runner-main.ts +3 -4
- package/src/dev/runner.ts +44 -13
- package/src/dev/supervisor.ts +70 -27
- package/src/internal/application-args.ts +13 -0
- package/src/internal/errors.ts +1 -1
- package/src/internal/run-cli-tool.ts +22 -0
- package/src/internal.ts +2 -0
- package/src/mcp/client.ts +1 -1
- package/src/mcp/handlers.ts +124 -57
- package/src/mcp/index.ts +1 -0
- package/src/mcp/serialize-widget.ts +71 -21
- package/src/mcp/widget-properties.ts +153 -0
- package/src/refresh-runtime.ts +0 -17
- package/src/settings/compile.ts +8 -11
- package/src/settings/schema.ts +2 -2
- package/src/vite-plugins/asset-emitter.ts +5 -0
- package/src/vite-plugins/asset-extensions.ts +1 -1
- package/src/vite-plugins/built-url.ts +19 -13
- package/src/vite-plugins/ensure-store.ts +14 -0
- package/src/vite-plugins/icons.ts +2 -5
- package/src/vite-plugins/react-compiler.ts +3 -2
- package/src/vite-plugins/resources.ts +10 -19
- package/src/vite-plugins/settings.ts +2 -2
- package/src/vite-plugins/undeclared-library.ts +1 -1
- package/src/vite-plugins/worker.ts +235 -0
- package/src/vitest-plugin.ts +12 -4
- package/dist/internal/resolve-cli-tool.d.ts +0 -3
- package/dist/internal/resolve-cli-tool.d.ts.map +0 -1
- package/dist/internal/resolve-cli-tool.js +0 -27
- package/dist/internal/resolve-cli-tool.js.map +0 -1
- package/src/internal/resolve-cli-tool.ts +0 -37
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import type { Plugin, Rollup } from "vite";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { basename, extname } from "node:path";
|
|
4
|
+
import { stripQuery } from "./strip-query.js";
|
|
5
|
+
|
|
6
|
+
type WorkerReplacement = {
|
|
7
|
+
start: number;
|
|
8
|
+
end: number;
|
|
9
|
+
fileName: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type EmitContext = {
|
|
13
|
+
context: Rollup.PluginContext;
|
|
14
|
+
emitted: Map<string, string>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type SourceRange = {
|
|
18
|
+
start: number;
|
|
19
|
+
end: number;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type ScanContext = {
|
|
23
|
+
code: string;
|
|
24
|
+
id: string;
|
|
25
|
+
nonCode: SourceRange[];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type HoistedWorkerUrl = {
|
|
29
|
+
name: string;
|
|
30
|
+
specifier: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type TransformResult = {
|
|
34
|
+
code: string;
|
|
35
|
+
map: null;
|
|
36
|
+
} | null;
|
|
37
|
+
|
|
38
|
+
const RELATIVE_SPECIFIER = String.raw`(?<quote>["'])(?<specifier>\.{1,2}\/[^"']+)\k<quote>`;
|
|
39
|
+
const URL_CALL = String.raw`new\s+URL\s*\(\s*${RELATIVE_SPECIFIER}\s*,\s*import\.meta\.url\s*\)`;
|
|
40
|
+
const URL_DECLARATION = String.raw`(?:const|let|var)\s+(?<name>[A-Za-z_$][\w$]*)\s*(?::[^=;\n]+)?=\s*`;
|
|
41
|
+
const BLOCK_COMMENT = String.raw`\/\*[\s\S]*?\*\/`;
|
|
42
|
+
const LINE_COMMENT = String.raw`\/\/[^\n]*`;
|
|
43
|
+
const DOUBLE_QUOTED = String.raw`"(?:[^"\\\n]|\\[\s\S])*"`;
|
|
44
|
+
const SINGLE_QUOTED = String.raw`'(?:[^'\\\n]|\\[\s\S])*'`;
|
|
45
|
+
const TEMPLATE_LITERAL = String.raw`\`(?:[^\`\\]|\\[\s\S])*\``;
|
|
46
|
+
const WORKER_URL = new RegExp(URL_CALL, "g");
|
|
47
|
+
const HOISTED_WORKER_URL = new RegExp(URL_DECLARATION + URL_CALL, "g");
|
|
48
|
+
const WORKER_CONSTRUCTION = /new\s+(?:\w+\.)?Worker\s*\(\s*$/;
|
|
49
|
+
|
|
50
|
+
const NON_CODE = new RegExp(
|
|
51
|
+
[BLOCK_COMMENT, LINE_COMMENT, DOUBLE_QUOTED, SINGLE_QUOTED, TEMPLATE_LITERAL].join("|"),
|
|
52
|
+
"g",
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const SUGGESTED_EXTENSIONS: Record<string, string[]> = {
|
|
56
|
+
".cjs": [".cts"],
|
|
57
|
+
".js": [".ts", ".tsx"],
|
|
58
|
+
".jsx": [".tsx"],
|
|
59
|
+
".mjs": [".mts"],
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const workerFileName = (id: string): string => {
|
|
63
|
+
const path = stripQuery(id);
|
|
64
|
+
const stem = basename(path, extname(path));
|
|
65
|
+
const digest = createHash("sha256").update(id).digest("hex").slice(0, 8);
|
|
66
|
+
|
|
67
|
+
return `workers/${stem}-${digest}.js`;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const nonCodeRanges = (code: string): SourceRange[] =>
|
|
71
|
+
code
|
|
72
|
+
.matchAll(NON_CODE)
|
|
73
|
+
.map((match) => ({ start: match.index, end: match.index + match[0].length }))
|
|
74
|
+
.toArray();
|
|
75
|
+
|
|
76
|
+
const isCodePosition = (scan: ScanContext, index: number): boolean =>
|
|
77
|
+
scan.nonCode.every((range) => index < range.start || index >= range.end);
|
|
78
|
+
|
|
79
|
+
const isWorkerConstruction = (code: string, matchIndex: number): boolean =>
|
|
80
|
+
WORKER_CONSTRUCTION.test(code.slice(0, matchIndex));
|
|
81
|
+
|
|
82
|
+
const hasWorkerCandidate = (code: string): boolean => code.includes("import.meta.url") && code.includes("Worker");
|
|
83
|
+
|
|
84
|
+
const workerUrlExpression = (fileName: string): string => {
|
|
85
|
+
const specifier = JSON.stringify(`./${fileName}`);
|
|
86
|
+
|
|
87
|
+
return `new URL(${specifier}, import.meta.url)`;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const inlineWorkerExample = (specifier: string): string =>
|
|
91
|
+
`new Worker(new URL(${JSON.stringify(specifier)}, import.meta.url))`;
|
|
92
|
+
|
|
93
|
+
const hoistedWorkerError = (scan: ScanContext, hoisted: HoistedWorkerUrl): Error =>
|
|
94
|
+
new Error(
|
|
95
|
+
`${stripQuery(scan.id)}: the worker URL for ${JSON.stringify(hoisted.specifier)} is bound to ` +
|
|
96
|
+
`"${hoisted.name}" before it reaches "new Worker". gtkx build emits a worker chunk only for a URL ` +
|
|
97
|
+
`written inside the construction. Write ${inlineWorkerExample(hoisted.specifier)} instead.`,
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const unresolvedWorkerError = (scan: ScanContext, specifier: string, suggestion: string | null): Error =>
|
|
101
|
+
new Error(
|
|
102
|
+
`${stripQuery(scan.id)}: the worker specifier ${JSON.stringify(specifier)} does not resolve to a module, ` +
|
|
103
|
+
"so no worker chunk can be emitted. " +
|
|
104
|
+
(suggestion === null
|
|
105
|
+
? "Correct the path so it names the worker source file as it exists on disk."
|
|
106
|
+
: `Write ${inlineWorkerExample(suggestion)} instead.`),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const suggestionFor = async (emit: EmitContext, scan: ScanContext, specifier: string): Promise<string | null> => {
|
|
110
|
+
const extension = extname(specifier);
|
|
111
|
+
const stem = specifier.slice(0, specifier.length - extension.length);
|
|
112
|
+
const candidates = SUGGESTED_EXTENSIONS[extension] ?? [];
|
|
113
|
+
|
|
114
|
+
for (const candidate of candidates) {
|
|
115
|
+
const resolved = await emit.context.resolve(stem + candidate, scan.id);
|
|
116
|
+
|
|
117
|
+
if (resolved !== null) {
|
|
118
|
+
return stem + candidate;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return null;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const claimWorker = (emit: EmitContext, resolvedId: string): string => {
|
|
126
|
+
const existing = emit.emitted.get(resolvedId);
|
|
127
|
+
|
|
128
|
+
if (existing !== undefined) {
|
|
129
|
+
return existing;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const fileName = workerFileName(resolvedId);
|
|
133
|
+
emit.emitted.set(resolvedId, fileName);
|
|
134
|
+
emit.context.emitFile({ type: "chunk", id: resolvedId, fileName });
|
|
135
|
+
|
|
136
|
+
return fileName;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const isRewritableUrl = (scan: ScanContext, match: RegExpExecArray): boolean =>
|
|
140
|
+
isCodePosition(scan, match.index) && isWorkerConstruction(scan.code, match.index);
|
|
141
|
+
|
|
142
|
+
const replacementFor = async (
|
|
143
|
+
emit: EmitContext,
|
|
144
|
+
scan: ScanContext,
|
|
145
|
+
match: RegExpExecArray,
|
|
146
|
+
): Promise<WorkerReplacement | null> => {
|
|
147
|
+
const specifier = match.groups?.specifier;
|
|
148
|
+
|
|
149
|
+
if (specifier === undefined || !isRewritableUrl(scan, match)) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const resolved = await emit.context.resolve(specifier, scan.id);
|
|
154
|
+
|
|
155
|
+
if (resolved === null) {
|
|
156
|
+
throw unresolvedWorkerError(scan, specifier, await suggestionFor(emit, scan, specifier));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return { start: match.index, end: match.index + match[0].length, fileName: claimWorker(emit, resolved.id) };
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const collectReplacements = async (emit: EmitContext, scan: ScanContext): Promise<WorkerReplacement[]> => {
|
|
163
|
+
const pending = scan.code.matchAll(WORKER_URL).map((match) => replacementFor(emit, scan, match)).toArray();
|
|
164
|
+
const found = await Promise.all(pending);
|
|
165
|
+
|
|
166
|
+
return found.filter((entry) => entry !== null);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const hasWorkerArgument = (scan: ScanContext, name: string): boolean => {
|
|
170
|
+
const escaped = name.replaceAll("$", String.raw`\$`);
|
|
171
|
+
const pattern = new RegExp(String.raw`new\s+(?:\w+\.)?Worker\s*\(\s*${escaped}\s*[,)]`, "g");
|
|
172
|
+
|
|
173
|
+
return scan.code.matchAll(pattern).some((match) => isCodePosition(scan, match.index));
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const hoistedUrlFor = (scan: ScanContext, match: RegExpExecArray): HoistedWorkerUrl | null => {
|
|
177
|
+
const name = match.groups?.name;
|
|
178
|
+
const specifier = match.groups?.specifier;
|
|
179
|
+
|
|
180
|
+
if (name === undefined || specifier === undefined || !isCodePosition(scan, match.index)) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return { name, specifier };
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const findHoistedWorkerUrl = (scan: ScanContext): HoistedWorkerUrl | null =>
|
|
188
|
+
scan.code
|
|
189
|
+
.matchAll(HOISTED_WORKER_URL)
|
|
190
|
+
.map((match) => hoistedUrlFor(scan, match))
|
|
191
|
+
.find((entry) => entry !== null && hasWorkerArgument(scan, entry.name)) ?? null;
|
|
192
|
+
|
|
193
|
+
const applyReplacements = (code: string, replacements: WorkerReplacement[]): string => {
|
|
194
|
+
let output = "";
|
|
195
|
+
let cursor = 0;
|
|
196
|
+
|
|
197
|
+
for (const { start, end, fileName } of replacements) {
|
|
198
|
+
output += code.slice(cursor, start) + workerUrlExpression(fileName);
|
|
199
|
+
cursor = end;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return output + code.slice(cursor);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const transformWorkerUrls = async (emit: EmitContext, code: string, id: string): Promise<TransformResult> => {
|
|
206
|
+
if (!hasWorkerCandidate(code)) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const scan: ScanContext = { code, id, nonCode: nonCodeRanges(code) };
|
|
211
|
+
const hoisted = findHoistedWorkerUrl(scan);
|
|
212
|
+
|
|
213
|
+
if (hoisted !== null) {
|
|
214
|
+
throw hoistedWorkerError(scan, hoisted);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const replacements = await collectReplacements(emit, scan);
|
|
218
|
+
|
|
219
|
+
return replacements.length === 0 ? null : { code: applyReplacements(code, replacements), map: null };
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
function gtkxWorker(): Plugin {
|
|
223
|
+
const emitted: Map<string, string> = new Map();
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
name: "gtkx:worker",
|
|
227
|
+
apply: "build",
|
|
228
|
+
|
|
229
|
+
transform(code, id) {
|
|
230
|
+
return transformWorkerUrls({ context: this, emitted }, code, id);
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export { gtkxWorker };
|
package/src/vitest-plugin.ts
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
import type { Plugin } from "vite";
|
|
2
2
|
import gtkxVitest from "@gtkx/vitest";
|
|
3
|
+
import { gtkxEnsureStore } from "./vite-plugins/ensure-store.js";
|
|
3
4
|
import { gtkxVitePlugins } from "./vite-plugins/index.js";
|
|
4
5
|
import { gtkxSettingsWorkerEnv } from "./vite-plugins/settings-worker-env.js";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
|
-
* Vite plugin
|
|
8
|
-
*
|
|
8
|
+
* Vite plugin stack for testing a GTKX application: the generated bindings the tests import,
|
|
9
|
+
* the plugins the app is built with, the project's compiled GSettings schemas exposed to every
|
|
10
|
+
* test worker, and a headless display per worker.
|
|
9
11
|
*
|
|
10
|
-
* @returns The
|
|
12
|
+
* @returns The plugins to spread into a Vitest config.
|
|
11
13
|
*/
|
|
12
|
-
const gtkx = (): Plugin[] => [
|
|
14
|
+
const gtkx = (): Plugin[] => [
|
|
15
|
+
gtkxEnsureStore(),
|
|
16
|
+
...gtkxVitePlugins(),
|
|
17
|
+
gtkxSettingsWorkerEnv(),
|
|
18
|
+
gtkxVitest(),
|
|
19
|
+
];
|
|
20
|
+
|
|
13
21
|
export default gtkx;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-cli-tool.d.ts","sourceRoot":"","sources":["../../src/internal/resolve-cli-tool.ts"],"names":[],"mappings":"AAGA,QAAA,MAAM,cAAc,eAGI,MAAM,KAAG,MAY7B,CAAC;AAkBL,OAAO,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { existsSync, statSync } from "node:fs";
|
|
2
|
-
import { delimiter, join } from "node:path";
|
|
3
|
-
const resolveCliTool = (() => {
|
|
4
|
-
const cache = new Map();
|
|
5
|
-
return (executable) => {
|
|
6
|
-
const cached = cache.get(executable);
|
|
7
|
-
if (cached) {
|
|
8
|
-
return cached;
|
|
9
|
-
}
|
|
10
|
-
const resolved = findInPath(executable);
|
|
11
|
-
cache.set(executable, resolved);
|
|
12
|
-
return resolved;
|
|
13
|
-
};
|
|
14
|
-
})();
|
|
15
|
-
const isExecutableFile = (candidate) => existsSync(candidate) && statSync(candidate).isFile();
|
|
16
|
-
const findInPath = (executable) => {
|
|
17
|
-
const dirs = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
|
|
18
|
-
for (const dir of dirs) {
|
|
19
|
-
const candidate = join(dir, executable);
|
|
20
|
-
if (isExecutableFile(candidate)) {
|
|
21
|
-
return candidate;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
throw new Error(`${executable} not found in PATH`);
|
|
25
|
-
};
|
|
26
|
-
export { resolveCliTool };
|
|
27
|
-
//# sourceMappingURL=resolve-cli-tool.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-cli-tool.js","sourceRoot":"","sources":["../../src/internal/resolve-cli-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE;IACzB,MAAM,KAAK,GAAwB,IAAI,GAAG,EAAE,CAAC;IAE7C,OAAO,CAAC,UAAkB,EAAU,EAAE;QAClC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAErC,IAAI,MAAM,EAAE,CAAC;YACT,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;QACxC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAEhC,OAAO,QAAQ,CAAC;IACpB,CAAC,CAAC;AACN,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,gBAAgB,GAAG,CAAC,SAAiB,EAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,CAAC;AAE/G,MAAM,UAAU,GAAG,CAAC,UAAkB,EAAU,EAAE;IAC9C,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEvE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAExC,IAAI,gBAAgB,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,OAAO,SAAS,CAAC;QACrB,CAAC;IACL,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,oBAAoB,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { existsSync, statSync } from \"node:fs\";\nimport { delimiter, join } from \"node:path\";\n\nconst resolveCliTool = (() => {\n const cache: Map<string, string> = new Map();\n\n return (executable: string): string => {\n const cached = cache.get(executable);\n\n if (cached) {\n return cached;\n }\n\n const resolved = findInPath(executable);\n cache.set(executable, resolved);\n\n return resolved;\n };\n})();\n\nconst isExecutableFile = (candidate: string): boolean => existsSync(candidate) && statSync(candidate).isFile();\n\nconst findInPath = (executable: string): string => {\n const dirs = (process.env.PATH ?? \"\").split(delimiter).filter(Boolean);\n\n for (const dir of dirs) {\n const candidate = join(dir, executable);\n\n if (isExecutableFile(candidate)) {\n return candidate;\n }\n }\n\n throw new Error(`${executable} not found in PATH`);\n};\n\nexport { resolveCliTool };\n"]}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { existsSync, statSync } from "node:fs";
|
|
2
|
-
import { delimiter, join } from "node:path";
|
|
3
|
-
|
|
4
|
-
const resolveCliTool = (() => {
|
|
5
|
-
const cache: Map<string, string> = new Map();
|
|
6
|
-
|
|
7
|
-
return (executable: string): string => {
|
|
8
|
-
const cached = cache.get(executable);
|
|
9
|
-
|
|
10
|
-
if (cached) {
|
|
11
|
-
return cached;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const resolved = findInPath(executable);
|
|
15
|
-
cache.set(executable, resolved);
|
|
16
|
-
|
|
17
|
-
return resolved;
|
|
18
|
-
};
|
|
19
|
-
})();
|
|
20
|
-
|
|
21
|
-
const isExecutableFile = (candidate: string): boolean => existsSync(candidate) && statSync(candidate).isFile();
|
|
22
|
-
|
|
23
|
-
const findInPath = (executable: string): string => {
|
|
24
|
-
const dirs = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
|
|
25
|
-
|
|
26
|
-
for (const dir of dirs) {
|
|
27
|
-
const candidate = join(dir, executable);
|
|
28
|
-
|
|
29
|
-
if (isExecutableFile(candidate)) {
|
|
30
|
-
return candidate;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
throw new Error(`${executable} not found in PATH`);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export { resolveCliTool };
|