@dusted/anqst 0.1.0 → 0.1.1
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 +147 -123
- package/dist/src/app.js +328 -79
- package/dist/src/backend/ast/emit.js +5 -0
- package/dist/src/backend/ast/index.js +13 -0
- package/dist/src/backend/ast/parser.js +5 -0
- package/dist/src/backend/ast/verify.js +5 -0
- package/dist/src/backend/index.js +16 -0
- package/dist/src/backend/tsc/debug-dump.js +39 -0
- package/dist/src/backend/tsc/emit-cpp.js +13 -0
- package/dist/src/backend/tsc/emit-node.js +13 -0
- package/dist/src/backend/tsc/index.js +41 -0
- package/dist/src/backend/tsc/parser.js +19 -0
- package/dist/src/backend/tsc/program.js +120 -0
- package/dist/src/backend/tsc/typegraph.js +172 -0
- package/dist/src/backend/tsc/verify.js +13 -0
- package/dist/src/backend/types.js +2 -0
- package/dist/src/bin/anqst.js +0 -0
- package/dist/src/emit.js +456 -8
- package/dist/src/project.js +110 -40
- package/package.json +7 -4
package/dist/src/app.js
CHANGED
|
@@ -12,11 +12,21 @@ exports.runCommand = runCommand;
|
|
|
12
12
|
const node_path_1 = __importDefault(require("node:path"));
|
|
13
13
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
14
14
|
const node_child_process_1 = require("node:child_process");
|
|
15
|
-
const parser_1 = require("./parser");
|
|
16
|
-
const verify_1 = require("./verify");
|
|
17
15
|
const errors_1 = require("./errors");
|
|
18
16
|
const emit_1 = require("./emit");
|
|
19
17
|
const project_1 = require("./project");
|
|
18
|
+
const backend_1 = require("./backend");
|
|
19
|
+
const ANQSTGEN_ACTIVE_STAMP_FILE = ".anqstgen-version-active.json";
|
|
20
|
+
function generationTargetsForBackend(backendId, targets) {
|
|
21
|
+
if (backendId !== "tsc")
|
|
22
|
+
return targets;
|
|
23
|
+
// tsc backend currently supports QWidget and node_express_ws emitters only.
|
|
24
|
+
return {
|
|
25
|
+
emitQWidget: targets.emitQWidget,
|
|
26
|
+
emitAngularService: false,
|
|
27
|
+
emitNodeExpressWs: targets.emitNodeExpressWs
|
|
28
|
+
};
|
|
29
|
+
}
|
|
20
30
|
function renderHelp() {
|
|
21
31
|
return [
|
|
22
32
|
"Usage:",
|
|
@@ -25,48 +35,64 @@ function renderHelp() {
|
|
|
25
35
|
"Commands:",
|
|
26
36
|
" instill <WidgetName> Initialize AnQst in current npm project",
|
|
27
37
|
" test Verify package.json AnQst spec",
|
|
28
|
-
" build
|
|
29
|
-
" generate <specFile>
|
|
30
|
-
" verify <specFile>
|
|
38
|
+
" build [--backend <id>] [--designerplugin[=true|false]] Generate artifacts from package.json AnQst spec",
|
|
39
|
+
" generate <specFile> [--backend <id>] Generate artifacts from explicit spec file",
|
|
40
|
+
" verify <specFile> [--backend <id>] Verify explicit spec file only",
|
|
31
41
|
" clean <path> [-f|--force] Remove generated artifacts under path",
|
|
32
42
|
"",
|
|
33
43
|
"Options:",
|
|
44
|
+
" --backend <id> Backend for build/generate/verify: ast|tsc",
|
|
45
|
+
" --designerplugin Build Qt Designer plugin (build command only, tsc + QWidget)",
|
|
34
46
|
" -h, --help Show this help output"
|
|
35
47
|
].join("\n");
|
|
36
48
|
}
|
|
37
49
|
function usageFor(command) {
|
|
38
50
|
if (command === "instill")
|
|
39
51
|
return "Usage: anqst instill <WidgetName>";
|
|
52
|
+
if (command === "build")
|
|
53
|
+
return "Usage: anqst build [--backend <id>] [--designerplugin[=true|false]]";
|
|
40
54
|
if (command === "verify")
|
|
41
|
-
return "Usage: anqst verify <specFile>";
|
|
55
|
+
return "Usage: anqst verify <specFile> [--backend <id>]";
|
|
42
56
|
if (command === "generate")
|
|
43
|
-
return "Usage: anqst generate <specFile>";
|
|
57
|
+
return "Usage: anqst generate <specFile> [--backend <id>]";
|
|
44
58
|
if (command === "clean")
|
|
45
59
|
return "Usage: anqst clean <path> [-f|--force]";
|
|
46
60
|
return renderHelp();
|
|
47
61
|
}
|
|
48
|
-
function runVerify(specArg) {
|
|
62
|
+
function runVerify(specArg, backendId = "ast") {
|
|
49
63
|
const specPath = node_path_1.default.resolve(process.cwd(), specArg);
|
|
50
|
-
const
|
|
51
|
-
const
|
|
64
|
+
const backend = (0, backend_1.resolveBackend)(backendId);
|
|
65
|
+
const parsed = backend.parseSpecFile(specPath);
|
|
66
|
+
const verification = backend.verifySpec(parsed);
|
|
52
67
|
return {
|
|
53
68
|
success: true,
|
|
54
69
|
message: verification.message
|
|
55
70
|
};
|
|
56
71
|
}
|
|
57
|
-
function runGenerate(specArg) {
|
|
72
|
+
function runGenerate(specArg, backendId = "ast") {
|
|
58
73
|
const cwd = process.cwd();
|
|
59
74
|
const specPath = node_path_1.default.resolve(cwd, specArg);
|
|
60
|
-
const
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
(0, emit_1.
|
|
75
|
+
const backend = (0, backend_1.resolveBackend)(backendId);
|
|
76
|
+
const parsed = backend.parseSpecFile(specPath);
|
|
77
|
+
const verification = backend.verifySpec(parsed);
|
|
78
|
+
const generationTargets = generationTargetsForBackend(backend.id, resolveGenerationTargetsFromCwd(cwd));
|
|
79
|
+
const outputs = backend.generateOutputs(parsed, generationTargets);
|
|
80
|
+
if (backend.emitsArtifacts) {
|
|
81
|
+
(0, emit_1.writeGeneratedOutputs)(cwd, outputs);
|
|
82
|
+
if (generationTargets.emitAngularService) {
|
|
83
|
+
(0, emit_1.installTypeScriptOutputs)(cwd);
|
|
84
|
+
}
|
|
85
|
+
if (generationTargets.emitQWidget) {
|
|
86
|
+
(0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
|
|
87
|
+
}
|
|
67
88
|
}
|
|
68
|
-
|
|
69
|
-
(
|
|
89
|
+
else {
|
|
90
|
+
const relativeSpecFile = normalizeSlashes(node_path_1.default.relative(cwd, specPath));
|
|
91
|
+
return {
|
|
92
|
+
success: true,
|
|
93
|
+
verificationMessage: verification.message,
|
|
94
|
+
message: `\nAnQst spec ${relativeSpecFile} built.\n Backend '${backend.id}' is a non-emitting skeleton. No artifacts were generated.\n`
|
|
95
|
+
};
|
|
70
96
|
}
|
|
71
97
|
const relativeSpecFile = normalizeSlashes(node_path_1.default.relative(cwd, specPath));
|
|
72
98
|
const relativeTypeScriptInstallPath = normalizeSlashes(node_path_1.default.relative(cwd, node_path_1.default.join(cwd, "src", "anqst-generated")));
|
|
@@ -96,64 +122,271 @@ function runGenerate(specArg) {
|
|
|
96
122
|
}
|
|
97
123
|
function runTest(cwd) {
|
|
98
124
|
const specPath = (0, project_1.resolveAnQstSpecPath)(cwd);
|
|
99
|
-
const
|
|
100
|
-
const
|
|
125
|
+
const backend = (0, backend_1.resolveBackend)("ast");
|
|
126
|
+
const parsed = backend.parseSpecFile(specPath);
|
|
127
|
+
const verification = backend.verifySpec(parsed);
|
|
101
128
|
return {
|
|
102
129
|
success: true,
|
|
103
130
|
message: verification.message
|
|
104
131
|
};
|
|
105
132
|
}
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
(
|
|
111
|
-
|
|
112
|
-
(0, emit_1.writeGeneratedOutputs)(cwd, outputs);
|
|
113
|
-
if (generationTargets.emitAngularService) {
|
|
114
|
-
(0, emit_1.installTypeScriptOutputs)(cwd);
|
|
133
|
+
function resolveAnQstGenRoot() {
|
|
134
|
+
return node_path_1.default.resolve(__dirname, "..", "..");
|
|
135
|
+
}
|
|
136
|
+
function readActiveBuildStamp() {
|
|
137
|
+
if (process.env.ANQST_BUILD_STAMP && process.env.ANQST_BUILD_STAMP.trim().length > 0) {
|
|
138
|
+
return process.env.ANQST_BUILD_STAMP.trim();
|
|
115
139
|
}
|
|
116
|
-
|
|
117
|
-
|
|
140
|
+
const activePath = node_path_1.default.join(resolveAnQstGenRoot(), ANQSTGEN_ACTIVE_STAMP_FILE);
|
|
141
|
+
if (!node_fs_1.default.existsSync(activePath)) {
|
|
142
|
+
return "unknown_build_0";
|
|
118
143
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
stdio: "inherit",
|
|
124
|
-
shell: process.platform === "win32"
|
|
125
|
-
});
|
|
126
|
-
if (angularBuild.status !== 0) {
|
|
127
|
-
throw new errors_1.VerifyError("Angular build failed while preparing embedded widget assets.");
|
|
144
|
+
try {
|
|
145
|
+
const parsed = JSON.parse(node_fs_1.default.readFileSync(activePath, "utf8"));
|
|
146
|
+
if (typeof parsed.active === "string" && parsed.active.trim().length > 0) {
|
|
147
|
+
return parsed.active.trim();
|
|
128
148
|
}
|
|
129
149
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (hasAngularProject && !embedded) {
|
|
133
|
-
throw new errors_1.VerifyError("Unable to embed Angular output. Ensure ng build produced a dist bundle with index.html.");
|
|
134
|
-
}
|
|
150
|
+
catch {
|
|
151
|
+
// Fallback to deterministic unknown stamp.
|
|
135
152
|
}
|
|
136
|
-
|
|
153
|
+
return "unknown_build_0";
|
|
154
|
+
}
|
|
155
|
+
function runDesignerPluginBuild(cwd) {
|
|
156
|
+
const pluginSourceDir = node_path_1.default.join(cwd, "anqst-cmake", "designerplugin");
|
|
157
|
+
const pluginBuildDir = node_path_1.default.join(cwd, "anqst-cmake", "build-designerplugin");
|
|
158
|
+
const webBaseDir = process.env.ANQST_WEBBASE_DIR?.trim();
|
|
159
|
+
if (!webBaseDir) {
|
|
160
|
+
throw new errors_1.VerifyError("Missing ANQST_WEBBASE_DIR environment variable for --designerplugin build.");
|
|
161
|
+
}
|
|
162
|
+
const configureArgs = [
|
|
163
|
+
"-S",
|
|
164
|
+
pluginSourceDir,
|
|
165
|
+
"-B",
|
|
166
|
+
pluginBuildDir,
|
|
167
|
+
"-DCMAKE_BUILD_TYPE=Release",
|
|
168
|
+
`-DANQST_WEBBASE_DIR=${webBaseDir}`
|
|
169
|
+
];
|
|
170
|
+
const configure = (0, node_child_process_1.spawnSync)("cmake", configureArgs, {
|
|
171
|
+
cwd,
|
|
172
|
+
stdio: "inherit",
|
|
173
|
+
shell: process.platform === "win32"
|
|
174
|
+
});
|
|
175
|
+
if (configure.status !== 0) {
|
|
176
|
+
throw new errors_1.VerifyError([
|
|
177
|
+
"CMake configure failed while building Qt Designer plugin.",
|
|
178
|
+
"If CMake reports missing Qt5UiPlugin, install qttools5-dev (Ubuntu/Debian) and re-run install_dependencies.sh."
|
|
179
|
+
].join(" "));
|
|
180
|
+
}
|
|
181
|
+
const build = (0, node_child_process_1.spawnSync)("cmake", ["--build", pluginBuildDir, "--config", "Release"], {
|
|
182
|
+
cwd,
|
|
183
|
+
stdio: "inherit",
|
|
184
|
+
shell: process.platform === "win32"
|
|
185
|
+
});
|
|
186
|
+
if (build.status !== 0) {
|
|
187
|
+
throw new errors_1.VerifyError("CMake build failed while compiling Qt Designer plugin.");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function runBuild(cwd, backendId = "ast", designerPlugin = false) {
|
|
191
|
+
const buildVersion = readActiveBuildStamp();
|
|
192
|
+
process.env.ANQST_BUILD_STAMP = buildVersion;
|
|
193
|
+
try {
|
|
194
|
+
const backend = (0, backend_1.resolveBackend)(backendId);
|
|
195
|
+
const specPath = (0, project_1.resolveAnQstSpecPath)(cwd);
|
|
196
|
+
const generationTargets = generationTargetsForBackend(backend.id, resolveGenerationTargetsFromCwd(cwd, true));
|
|
197
|
+
const parsed = backend.parseSpecFile(specPath);
|
|
198
|
+
backend.verifySpec(parsed);
|
|
199
|
+
const outputs = backend.generateOutputs(parsed, generationTargets);
|
|
200
|
+
if (backend.emitsArtifacts) {
|
|
201
|
+
(0, emit_1.writeGeneratedOutputs)(cwd, outputs);
|
|
202
|
+
if (generationTargets.emitAngularService) {
|
|
203
|
+
(0, emit_1.installTypeScriptOutputs)(cwd);
|
|
204
|
+
}
|
|
205
|
+
if (generationTargets.emitQWidget) {
|
|
206
|
+
(0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
return {
|
|
211
|
+
success: true,
|
|
212
|
+
message: `Build completed: backend '${backend.id}' is a non-emitting skeleton; no artifacts were generated`
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
const hasAngularProject = generationTargets.emitQWidget && node_fs_1.default.existsSync(node_path_1.default.join(cwd, "angular.json"));
|
|
216
|
+
if (hasAngularProject && generationTargets.emitQWidget) {
|
|
217
|
+
const angularBuild = (0, node_child_process_1.spawnSync)("npx", ["ng", "build", "--configuration", "production"], {
|
|
218
|
+
cwd,
|
|
219
|
+
stdio: "inherit",
|
|
220
|
+
shell: process.platform === "win32"
|
|
221
|
+
});
|
|
222
|
+
if (angularBuild.status !== 0) {
|
|
223
|
+
throw new errors_1.VerifyError("Angular build failed while preparing embedded widget assets.");
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (generationTargets.emitQWidget) {
|
|
227
|
+
const embedded = (0, emit_1.installEmbeddedWebBundle)(cwd, parsed.widgetName);
|
|
228
|
+
if (hasAngularProject && !embedded) {
|
|
229
|
+
throw new errors_1.VerifyError("Unable to embed Angular output. Ensure ng build produced a dist bundle with index.html.");
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
let designerPluginBuilt = false;
|
|
233
|
+
if (designerPlugin) {
|
|
234
|
+
if (backend.id !== "tsc") {
|
|
235
|
+
console.warn("[AnQst] --designerplugin is only supported with --backend tsc. Skipping designer plugin build.");
|
|
236
|
+
}
|
|
237
|
+
else if (!generationTargets.emitQWidget) {
|
|
238
|
+
console.warn("[AnQst] --designerplugin requested but QWidget target is not enabled. Skipping designer plugin build.");
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
const widgetCategory = (0, project_1.resolveAnQstWidgetCategory)(cwd);
|
|
242
|
+
(0, emit_1.installQtDesignerPluginCMake)(cwd, parsed.widgetName, { widgetCategory });
|
|
243
|
+
runDesignerPluginBuild(cwd);
|
|
244
|
+
designerPluginBuilt = true;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
|
|
248
|
+
return {
|
|
249
|
+
success: true,
|
|
250
|
+
message: [
|
|
251
|
+
"Build completed.",
|
|
252
|
+
` anqst version ${buildVersion}`,
|
|
253
|
+
" No outputs selected by AnQst.generate."
|
|
254
|
+
].join("\n")
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
const detailLines = [];
|
|
258
|
+
if (generationTargets.emitAngularService) {
|
|
259
|
+
detailLines.push(" Target AngularService:");
|
|
260
|
+
detailLines.push(" - Services output: src/anqst-generated/services");
|
|
261
|
+
detailLines.push(" - Types output: src/anqst-generated/types");
|
|
262
|
+
}
|
|
263
|
+
if (generationTargets.emitQWidget) {
|
|
264
|
+
detailLines.push(" Target QWidget:");
|
|
265
|
+
detailLines.push(" - Qt integration CMake: anqst-cmake/CMakeLists.txt");
|
|
266
|
+
detailLines.push(` - Widget output root: generated_output/${parsed.widgetName}_QtWidget`);
|
|
267
|
+
detailLines.push(" - Embedded web assets refreshed from Angular build");
|
|
268
|
+
}
|
|
269
|
+
if (generationTargets.emitNodeExpressWs) {
|
|
270
|
+
detailLines.push(" Target node_express_ws:");
|
|
271
|
+
detailLines.push(` - Module output root: generated_output/${parsed.widgetName}_node_express_ws`);
|
|
272
|
+
}
|
|
273
|
+
if (designerPluginBuilt) {
|
|
274
|
+
const pluginBinaryPath = normalizeSlashes(node_path_1.default.join("anqst-cmake", "build-designerplugin", designerPluginBinaryName(parsed.widgetName)));
|
|
275
|
+
detailLines.push(" Target QtDesignerPlugin:");
|
|
276
|
+
detailLines.push(" - Build output: anqst-cmake/build-designerplugin");
|
|
277
|
+
detailLines.push(` - Plugin binary: ${pluginBinaryPath}`);
|
|
278
|
+
detailLines.push(" - Install target dir: <QT_INSTALL_PLUGINS>/designer");
|
|
279
|
+
detailLines.push(" - Discover QT_INSTALL_PLUGINS: qmake -query QT_INSTALL_PLUGINS");
|
|
280
|
+
detailLines.push(` - Example install: cp ${pluginBinaryPath} "$(qmake -query QT_INSTALL_PLUGINS)/designer/"`);
|
|
281
|
+
detailLines.push(` - User-local install: mkdir -p "$HOME/.local/lib/qt5/plugins/designer" && cp ${pluginBinaryPath} "$HOME/.local/lib/qt5/plugins/designer/"`);
|
|
282
|
+
}
|
|
137
283
|
return {
|
|
138
284
|
success: true,
|
|
139
|
-
message:
|
|
285
|
+
message: [
|
|
286
|
+
"Build completed.",
|
|
287
|
+
` anqst version ${buildVersion}`,
|
|
288
|
+
...detailLines
|
|
289
|
+
].join("\n")
|
|
140
290
|
};
|
|
141
291
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
parts.push("TypeScript installed to src/anqst-generated");
|
|
292
|
+
finally {
|
|
293
|
+
delete process.env.ANQST_BUILD_STAMP;
|
|
145
294
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
295
|
+
}
|
|
296
|
+
function parseBackendCommandArgs(commandName, specArg, extraArgs, requireSpec) {
|
|
297
|
+
const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
|
|
298
|
+
let backendId = "ast";
|
|
299
|
+
const positional = [];
|
|
300
|
+
for (let i = 0; i < allArgs.length; i += 1) {
|
|
301
|
+
const arg = allArgs[i];
|
|
302
|
+
if (arg === "--backend") {
|
|
303
|
+
const value = allArgs[i + 1];
|
|
304
|
+
if (!value || value.startsWith("-")) {
|
|
305
|
+
throw new Error(`Missing value for --backend. ${usageFor(commandName)}`);
|
|
306
|
+
}
|
|
307
|
+
if (!(0, backend_1.isBackendId)(value)) {
|
|
308
|
+
throw new Error(`Unknown backend '${value}'. Allowed backends: ast, tsc.`);
|
|
309
|
+
}
|
|
310
|
+
backendId = value;
|
|
311
|
+
i += 1;
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (arg.startsWith("--backend=")) {
|
|
315
|
+
const value = arg.slice("--backend=".length);
|
|
316
|
+
if (!(0, backend_1.isBackendId)(value)) {
|
|
317
|
+
throw new Error(`Unknown backend '${value}'. Allowed backends: ast, tsc.`);
|
|
318
|
+
}
|
|
319
|
+
backendId = value;
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (arg.startsWith("-")) {
|
|
323
|
+
throw new Error(`Unknown ${commandName} flag '${arg}'. ${usageFor(commandName)}`);
|
|
324
|
+
}
|
|
325
|
+
positional.push(arg);
|
|
149
326
|
}
|
|
150
|
-
if (
|
|
151
|
-
|
|
327
|
+
if (requireSpec) {
|
|
328
|
+
if (positional.length !== 1) {
|
|
329
|
+
throw new Error(usageFor(commandName));
|
|
330
|
+
}
|
|
331
|
+
return { backendId, specArg: positional[0] };
|
|
152
332
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
};
|
|
333
|
+
if (positional.length > 0) {
|
|
334
|
+
throw new Error(`Unexpected extra argument '${positional[0]}'. ${usageFor(commandName)}`);
|
|
335
|
+
}
|
|
336
|
+
return { backendId };
|
|
337
|
+
}
|
|
338
|
+
function parseBuildCommandArgs(specArg, extraArgs) {
|
|
339
|
+
const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
|
|
340
|
+
let backendId = "ast";
|
|
341
|
+
let designerPlugin = false;
|
|
342
|
+
const positional = [];
|
|
343
|
+
for (let i = 0; i < allArgs.length; i += 1) {
|
|
344
|
+
const arg = allArgs[i];
|
|
345
|
+
if (arg === "--backend") {
|
|
346
|
+
const value = allArgs[i + 1];
|
|
347
|
+
if (!value || value.startsWith("-")) {
|
|
348
|
+
throw new Error(`Missing value for --backend. ${usageFor("build")}`);
|
|
349
|
+
}
|
|
350
|
+
if (!(0, backend_1.isBackendId)(value)) {
|
|
351
|
+
throw new Error(`Unknown backend '${value}'. Allowed backends: ast, tsc.`);
|
|
352
|
+
}
|
|
353
|
+
backendId = value;
|
|
354
|
+
i += 1;
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
if (arg.startsWith("--backend=")) {
|
|
358
|
+
const value = arg.slice("--backend=".length);
|
|
359
|
+
if (!(0, backend_1.isBackendId)(value)) {
|
|
360
|
+
throw new Error(`Unknown backend '${value}'. Allowed backends: ast, tsc.`);
|
|
361
|
+
}
|
|
362
|
+
backendId = value;
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
if (arg === "--designerplugin") {
|
|
366
|
+
const value = allArgs[i + 1];
|
|
367
|
+
if (value && !value.startsWith("-")) {
|
|
368
|
+
designerPlugin = value.toLowerCase() === "true";
|
|
369
|
+
i += 1;
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
designerPlugin = true;
|
|
373
|
+
}
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
if (arg.startsWith("--designerplugin=")) {
|
|
377
|
+
const value = arg.slice("--designerplugin=".length);
|
|
378
|
+
designerPlugin = value.toLowerCase() === "true";
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
381
|
+
if (arg.startsWith("-")) {
|
|
382
|
+
throw new Error(`Unknown build flag '${arg}'. ${usageFor("build")}`);
|
|
383
|
+
}
|
|
384
|
+
positional.push(arg);
|
|
385
|
+
}
|
|
386
|
+
if (positional.length > 0) {
|
|
387
|
+
throw new Error(`Unexpected extra argument '${positional[0]}'. ${usageFor("build")}`);
|
|
388
|
+
}
|
|
389
|
+
return { backendId, designerPlugin };
|
|
157
390
|
}
|
|
158
391
|
function parseCleanCommandArgs(specArg, extraArgs) {
|
|
159
392
|
const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
|
|
@@ -279,7 +512,7 @@ function runClean(pathArg, force) {
|
|
|
279
512
|
};
|
|
280
513
|
}
|
|
281
514
|
const specPath = resolveAnQstSpecFromPackage(targetRoot);
|
|
282
|
-
const parsed = (0,
|
|
515
|
+
const parsed = (0, backend_1.resolveBackend)("ast").parseSpecFile(specPath);
|
|
283
516
|
const widgetDirs = [
|
|
284
517
|
node_path_1.default.join("generated_output", `${parsed.widgetName}_QtWidget`),
|
|
285
518
|
node_path_1.default.join("generated_output", `${parsed.widgetName}_node_express_ws`),
|
|
@@ -296,6 +529,23 @@ function runClean(pathArg, force) {
|
|
|
296
529
|
function normalizeSlashes(inputPath) {
|
|
297
530
|
return inputPath.split(node_path_1.default.sep).join("/");
|
|
298
531
|
}
|
|
532
|
+
function designerPluginBinaryName(widgetName) {
|
|
533
|
+
const targetName = `${widgetName}DesignerPlugin`;
|
|
534
|
+
if (process.platform === "win32") {
|
|
535
|
+
return `${targetName}.dll`;
|
|
536
|
+
}
|
|
537
|
+
if (process.platform === "darwin") {
|
|
538
|
+
return `${targetName}.dylib`;
|
|
539
|
+
}
|
|
540
|
+
return `${targetName}.so`;
|
|
541
|
+
}
|
|
542
|
+
function renderInstallAliasMessage() {
|
|
543
|
+
const useColor = process.stdout.isTTY;
|
|
544
|
+
const text = "[AnQst] 'install' spotted. Muscle memory is undefeated - running 'instill' for you.";
|
|
545
|
+
if (!useColor)
|
|
546
|
+
return text;
|
|
547
|
+
return `\x1b[38;5;214m${text}\x1b[0m`;
|
|
548
|
+
}
|
|
299
549
|
function runCommand(command, specArg, extraArgs = []) {
|
|
300
550
|
try {
|
|
301
551
|
if (!command) {
|
|
@@ -306,7 +556,11 @@ function runCommand(command, specArg, extraArgs = []) {
|
|
|
306
556
|
console.log(renderHelp());
|
|
307
557
|
return 0;
|
|
308
558
|
}
|
|
309
|
-
|
|
559
|
+
const normalizedCommand = command === "install" ? "instill" : command;
|
|
560
|
+
if (command === "install") {
|
|
561
|
+
console.log(renderInstallAliasMessage());
|
|
562
|
+
}
|
|
563
|
+
if (normalizedCommand === "instill") {
|
|
310
564
|
if (!specArg) {
|
|
311
565
|
console.error(usageFor("instill"));
|
|
312
566
|
return 1;
|
|
@@ -315,38 +569,33 @@ function runCommand(command, specArg, extraArgs = []) {
|
|
|
315
569
|
console.log(msg);
|
|
316
570
|
return 0;
|
|
317
571
|
}
|
|
318
|
-
if (
|
|
572
|
+
if (normalizedCommand === "test") {
|
|
319
573
|
const res = runTest(process.cwd());
|
|
320
574
|
console.log(res.message);
|
|
321
575
|
return 0;
|
|
322
576
|
}
|
|
323
|
-
if (
|
|
324
|
-
const
|
|
577
|
+
if (normalizedCommand === "build") {
|
|
578
|
+
const parsedArgs = parseBuildCommandArgs(specArg, extraArgs);
|
|
579
|
+
const res = runBuild(process.cwd(), parsedArgs.backendId, parsedArgs.designerPlugin);
|
|
325
580
|
console.log(res.message);
|
|
326
581
|
return 0;
|
|
327
582
|
}
|
|
328
|
-
if (
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
return 1;
|
|
332
|
-
}
|
|
333
|
-
const res = runVerify(specArg);
|
|
583
|
+
if (normalizedCommand === "verify") {
|
|
584
|
+
const parsedArgs = parseBackendCommandArgs("verify", specArg, extraArgs, true);
|
|
585
|
+
const res = runVerify(parsedArgs.specArg, parsedArgs.backendId);
|
|
334
586
|
console.log(res.message);
|
|
335
587
|
return 0;
|
|
336
588
|
}
|
|
337
|
-
if (
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
return 1;
|
|
341
|
-
}
|
|
342
|
-
const res = runGenerate(specArg);
|
|
589
|
+
if (normalizedCommand === "generate") {
|
|
590
|
+
const parsedArgs = parseBackendCommandArgs("generate", specArg, extraArgs, true);
|
|
591
|
+
const res = runGenerate(parsedArgs.specArg, parsedArgs.backendId);
|
|
343
592
|
if (res.verificationMessage) {
|
|
344
593
|
console.log(res.verificationMessage);
|
|
345
594
|
}
|
|
346
595
|
console.log(res.message);
|
|
347
596
|
return 0;
|
|
348
597
|
}
|
|
349
|
-
if (
|
|
598
|
+
if (normalizedCommand === "clean") {
|
|
350
599
|
const parsed = parseCleanCommandArgs(specArg, extraArgs);
|
|
351
600
|
const res = runClean(parsed.targetPathArg, parsed.force);
|
|
352
601
|
console.log(res.message);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateOutputs = void 0;
|
|
4
|
+
var emit_1 = require("../../emit");
|
|
5
|
+
Object.defineProperty(exports, "generateOutputs", { enumerable: true, get: function () { return emit_1.generateOutputs; } });
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.astBackend = void 0;
|
|
4
|
+
const emit_1 = require("./emit");
|
|
5
|
+
const parser_1 = require("./parser");
|
|
6
|
+
const verify_1 = require("./verify");
|
|
7
|
+
exports.astBackend = {
|
|
8
|
+
id: "ast",
|
|
9
|
+
parseSpecFile: parser_1.parseSpecFile,
|
|
10
|
+
verifySpec: verify_1.verifySpec,
|
|
11
|
+
generateOutputs: emit_1.generateOutputs,
|
|
12
|
+
emitsArtifacts: true
|
|
13
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSpecFile = void 0;
|
|
4
|
+
var parser_1 = require("../../parser");
|
|
5
|
+
Object.defineProperty(exports, "parseSpecFile", { enumerable: true, get: function () { return parser_1.parseSpecFile; } });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveBackend = resolveBackend;
|
|
4
|
+
exports.isBackendId = isBackendId;
|
|
5
|
+
const ast_1 = require("./ast");
|
|
6
|
+
const tsc_1 = require("./tsc");
|
|
7
|
+
const backends = {
|
|
8
|
+
ast: ast_1.astBackend,
|
|
9
|
+
tsc: tsc_1.tscBackend
|
|
10
|
+
};
|
|
11
|
+
function resolveBackend(backendId) {
|
|
12
|
+
return backends[backendId];
|
|
13
|
+
}
|
|
14
|
+
function isBackendId(value) {
|
|
15
|
+
return value === "ast" || value === "tsc";
|
|
16
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isDebugEnabled = isDebugEnabled;
|
|
7
|
+
exports.writeDebugFile = writeDebugFile;
|
|
8
|
+
exports.inspectText = inspectText;
|
|
9
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
10
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const node_util_1 = __importDefault(require("node:util"));
|
|
12
|
+
function isDebugEnabled() {
|
|
13
|
+
return process.env.ANQST_DEBUG === "true";
|
|
14
|
+
}
|
|
15
|
+
function baseIntermediateDir(cwd) {
|
|
16
|
+
return node_path_1.default.join(cwd, "generated_output", "intermediate");
|
|
17
|
+
}
|
|
18
|
+
function writeDebugFile(cwd, relativePath, content) {
|
|
19
|
+
if (!isDebugEnabled())
|
|
20
|
+
return;
|
|
21
|
+
try {
|
|
22
|
+
const targetPath = node_path_1.default.join(baseIntermediateDir(cwd), relativePath);
|
|
23
|
+
node_fs_1.default.mkdirSync(node_path_1.default.dirname(targetPath), { recursive: true });
|
|
24
|
+
node_fs_1.default.writeFileSync(targetPath, content, "utf8");
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
28
|
+
console.warn(`[AnQst][debug] Failed writing ${relativePath}: ${message}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function inspectText(value) {
|
|
32
|
+
return node_util_1.default.inspect(value, {
|
|
33
|
+
depth: null,
|
|
34
|
+
maxArrayLength: null,
|
|
35
|
+
maxStringLength: null,
|
|
36
|
+
breakLength: 120,
|
|
37
|
+
compact: false
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitCppQWidget = emitCppQWidget;
|
|
4
|
+
const emit_1 = require("../ast/emit");
|
|
5
|
+
function emitCppQWidget(spec, options) {
|
|
6
|
+
if (!options.emitQWidget)
|
|
7
|
+
return {};
|
|
8
|
+
return (0, emit_1.generateOutputs)(spec, {
|
|
9
|
+
emitQWidget: true,
|
|
10
|
+
emitAngularService: false,
|
|
11
|
+
emitNodeExpressWs: false
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitNodeExpressWs = emitNodeExpressWs;
|
|
4
|
+
const emit_1 = require("../ast/emit");
|
|
5
|
+
function emitNodeExpressWs(spec, options) {
|
|
6
|
+
if (!options.emitNodeExpressWs)
|
|
7
|
+
return {};
|
|
8
|
+
return (0, emit_1.generateOutputs)(spec, {
|
|
9
|
+
emitQWidget: false,
|
|
10
|
+
emitAngularService: false,
|
|
11
|
+
emitNodeExpressWs: true
|
|
12
|
+
});
|
|
13
|
+
}
|