@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/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 Generate artifacts from package.json AnQst spec",
29
- " generate <specFile> Generate artifacts from explicit spec file",
30
- " verify <specFile> Verify explicit spec file only",
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 parsed = (0, parser_1.parseSpecFile)(specPath);
51
- const verification = (0, verify_1.verifySpec)(parsed);
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 parsed = (0, parser_1.parseSpecFile)(specPath);
61
- const verification = (0, verify_1.verifySpec)(parsed);
62
- const generationTargets = resolveGenerationTargetsFromCwd(cwd);
63
- const outputs = (0, emit_1.generateOutputs)(parsed, generationTargets);
64
- (0, emit_1.writeGeneratedOutputs)(cwd, outputs);
65
- if (generationTargets.emitAngularService) {
66
- (0, emit_1.installTypeScriptOutputs)(cwd);
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
- if (generationTargets.emitQWidget) {
69
- (0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
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 parsed = (0, parser_1.parseSpecFile)(specPath);
100
- const verification = (0, verify_1.verifySpec)(parsed);
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 runBuild(cwd) {
107
- const specPath = (0, project_1.resolveAnQstSpecPath)(cwd);
108
- const generationTargets = resolveGenerationTargetsFromCwd(cwd, true);
109
- const parsed = (0, parser_1.parseSpecFile)(specPath);
110
- (0, verify_1.verifySpec)(parsed);
111
- const outputs = (0, emit_1.generateOutputs)(parsed, generationTargets);
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
- if (generationTargets.emitQWidget) {
117
- (0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
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
- const hasAngularProject = generationTargets.emitQWidget && node_fs_1.default.existsSync(node_path_1.default.join(cwd, "angular.json"));
120
- if (hasAngularProject && generationTargets.emitQWidget) {
121
- const angularBuild = (0, node_child_process_1.spawnSync)("npx", ["ng", "build", "--configuration", "production"], {
122
- cwd,
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
- if (generationTargets.emitQWidget) {
131
- const embedded = (0, emit_1.installEmbeddedWebBundle)(cwd, parsed.widgetName);
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
- if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
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: "Build completed: no outputs selected by AnQst.generate"
285
+ message: [
286
+ "Build completed.",
287
+ ` anqst version ${buildVersion}`,
288
+ ...detailLines
289
+ ].join("\n")
140
290
  };
141
291
  }
142
- const parts = [];
143
- if (generationTargets.emitAngularService) {
144
- parts.push("TypeScript installed to src/anqst-generated");
292
+ finally {
293
+ delete process.env.ANQST_BUILD_STAMP;
145
294
  }
146
- if (generationTargets.emitQWidget) {
147
- parts.push("Qt integration CMake emitted to anqst-cmake/");
148
- parts.push("C++ widget library refreshed with embedded web assets");
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 (generationTargets.emitNodeExpressWs) {
151
- parts.push(`Node Express WS module emitted to generated_output/${parsed.widgetName}_node_express_ws`);
327
+ if (requireSpec) {
328
+ if (positional.length !== 1) {
329
+ throw new Error(usageFor(commandName));
330
+ }
331
+ return { backendId, specArg: positional[0] };
152
332
  }
153
- return {
154
- success: true,
155
- message: `Build completed: ${parts.join(", ")}`
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, parser_1.parseSpecFile)(specPath);
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
- if (command === "instill") {
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 (command === "test") {
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 (command === "build") {
324
- const res = runBuild(process.cwd());
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 (command === "verify") {
329
- if (!specArg) {
330
- console.error(usageFor("verify"));
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 (command === "generate") {
338
- if (!specArg) {
339
- console.error(usageFor("generate"));
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 (command === "clean") {
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,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifySpec = void 0;
4
+ var verify_1 = require("../../verify");
5
+ Object.defineProperty(exports, "verifySpec", { enumerable: true, get: function () { return verify_1.verifySpec; } });
@@ -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
+ }