@dusted/anqst 0.1.0 → 0.1.2
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 +135 -129
- package/dist/src/app.js +287 -113
- package/dist/src/bin/anqst.js +0 -0
- package/dist/src/debug-dump.js +40 -0
- package/dist/src/emit.js +488 -64
- package/dist/src/layout.js +70 -0
- package/dist/src/parser.js +16 -1
- package/dist/src/program.js +120 -0
- package/dist/src/project.js +230 -77
- package/dist/src/typegraph.js +172 -0
- package/dist/src/verify.js +9 -1
- package/index.d.ts +1 -0
- package/package.json +13 -5
- package/spec/AnQst-Spec-DSL.d.ts +2 -2
package/dist/src/app.js
CHANGED
|
@@ -12,11 +12,14 @@ 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");
|
|
16
|
+
const debug_dump_1 = require("./debug-dump");
|
|
18
17
|
const emit_1 = require("./emit");
|
|
19
18
|
const project_1 = require("./project");
|
|
19
|
+
const layout_1 = require("./layout");
|
|
20
|
+
const parser_1 = require("./parser");
|
|
21
|
+
const verify_1 = require("./verify");
|
|
22
|
+
const ANQSTGEN_ACTIVE_STAMP_FILE = ".anqstgen-version-active.json";
|
|
20
23
|
function renderHelp() {
|
|
21
24
|
return [
|
|
22
25
|
"Usage:",
|
|
@@ -24,19 +27,22 @@ function renderHelp() {
|
|
|
24
27
|
"",
|
|
25
28
|
"Commands:",
|
|
26
29
|
" instill <WidgetName> Initialize AnQst in current npm project",
|
|
27
|
-
" test Verify
|
|
28
|
-
" build
|
|
30
|
+
" test Verify AnQst spec from package settings",
|
|
31
|
+
" build [--designerplugin[=true|false]] Generate artifacts from package settings",
|
|
29
32
|
" generate <specFile> Generate artifacts from explicit spec file",
|
|
30
33
|
" verify <specFile> Verify explicit spec file only",
|
|
31
34
|
" clean <path> [-f|--force] Remove generated artifacts under path",
|
|
32
35
|
"",
|
|
33
36
|
"Options:",
|
|
37
|
+
" --designerplugin Build Qt Designer plugin (build command only, QWidget target required)",
|
|
34
38
|
" -h, --help Show this help output"
|
|
35
39
|
].join("\n");
|
|
36
40
|
}
|
|
37
41
|
function usageFor(command) {
|
|
38
42
|
if (command === "instill")
|
|
39
43
|
return "Usage: anqst instill <WidgetName>";
|
|
44
|
+
if (command === "build")
|
|
45
|
+
return "Usage: anqst build [--designerplugin[=true|false]]";
|
|
40
46
|
if (command === "verify")
|
|
41
47
|
return "Usage: anqst verify <specFile>";
|
|
42
48
|
if (command === "generate")
|
|
@@ -45,6 +51,50 @@ function usageFor(command) {
|
|
|
45
51
|
return "Usage: anqst clean <path> [-f|--force]";
|
|
46
52
|
return renderHelp();
|
|
47
53
|
}
|
|
54
|
+
function resetGeneratedTargets(cwd, widgetName, targets) {
|
|
55
|
+
const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, widgetName);
|
|
56
|
+
const roots = new Set();
|
|
57
|
+
if (targets.emitAngularService) {
|
|
58
|
+
roots.add(layout.frontendRoot);
|
|
59
|
+
}
|
|
60
|
+
if (targets.emitNodeExpressWs) {
|
|
61
|
+
roots.add(layout.nodeExpressRoot);
|
|
62
|
+
}
|
|
63
|
+
if (targets.emitQWidget) {
|
|
64
|
+
roots.add(layout.cppQtWidgetRoot);
|
|
65
|
+
roots.add(layout.cppCmakeRoot);
|
|
66
|
+
}
|
|
67
|
+
if ((0, debug_dump_1.isDebugEnabled)()) {
|
|
68
|
+
roots.add(layout.debugIntermediateRoot);
|
|
69
|
+
}
|
|
70
|
+
for (const root of roots) {
|
|
71
|
+
node_fs_1.default.rmSync(root, { recursive: true, force: true });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function buildGenerateSummary(cwd, specPath, widgetName, generationTargets) {
|
|
75
|
+
const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, widgetName);
|
|
76
|
+
const relativeSpecFile = (0, layout_1.normalizeSlashes)(node_path_1.default.relative(cwd, specPath));
|
|
77
|
+
const servicePath = (0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "services"));
|
|
78
|
+
const typePath = (0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "types"));
|
|
79
|
+
const widgetRootPath = (0, layout_1.toProjectRelative)(cwd, layout.cppQtWidgetRoot);
|
|
80
|
+
const nodePath = (0, layout_1.toProjectRelative)(cwd, layout.nodeExpressRoot);
|
|
81
|
+
const messageLines = [];
|
|
82
|
+
messageLines.push(`AnQst spec ${relativeSpecFile} built.`);
|
|
83
|
+
if (generationTargets.emitAngularService) {
|
|
84
|
+
messageLines.push(` Services are available from ${servicePath}.`);
|
|
85
|
+
messageLines.push(` Generated types are available from ${typePath}.`);
|
|
86
|
+
}
|
|
87
|
+
if (generationTargets.emitQWidget) {
|
|
88
|
+
messageLines.push(` Widget library available in ${widgetRootPath}.`);
|
|
89
|
+
}
|
|
90
|
+
if (generationTargets.emitNodeExpressWs) {
|
|
91
|
+
messageLines.push(` Node Express WS module available in ${nodePath}.`);
|
|
92
|
+
}
|
|
93
|
+
if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
|
|
94
|
+
messageLines.push(" No outputs selected by AnQst.generate.");
|
|
95
|
+
}
|
|
96
|
+
return `\n${messageLines.join("\n")}\n`;
|
|
97
|
+
}
|
|
48
98
|
function runVerify(specArg) {
|
|
49
99
|
const specPath = node_path_1.default.resolve(process.cwd(), specArg);
|
|
50
100
|
const parsed = (0, parser_1.parseSpecFile)(specPath);
|
|
@@ -60,38 +110,16 @@ function runGenerate(specArg) {
|
|
|
60
110
|
const parsed = (0, parser_1.parseSpecFile)(specPath);
|
|
61
111
|
const verification = (0, verify_1.verifySpec)(parsed);
|
|
62
112
|
const generationTargets = resolveGenerationTargetsFromCwd(cwd);
|
|
113
|
+
resetGeneratedTargets(cwd, parsed.widgetName, generationTargets);
|
|
63
114
|
const outputs = (0, emit_1.generateOutputs)(parsed, generationTargets);
|
|
64
115
|
(0, emit_1.writeGeneratedOutputs)(cwd, outputs);
|
|
65
|
-
if (generationTargets.emitAngularService) {
|
|
66
|
-
(0, emit_1.installTypeScriptOutputs)(cwd);
|
|
67
|
-
}
|
|
68
116
|
if (generationTargets.emitQWidget) {
|
|
69
117
|
(0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
|
|
70
118
|
}
|
|
71
|
-
const relativeSpecFile = normalizeSlashes(node_path_1.default.relative(cwd, specPath));
|
|
72
|
-
const relativeTypeScriptInstallPath = normalizeSlashes(node_path_1.default.relative(cwd, node_path_1.default.join(cwd, "src", "anqst-generated")));
|
|
73
|
-
const relativeCppLibraryPath = normalizeSlashes(node_path_1.default.relative(cwd, node_path_1.default.join(cwd, "generated_output", `${parsed.widgetName}_QtWidget`)));
|
|
74
|
-
const relativeNodeModulePath = normalizeSlashes(node_path_1.default.relative(cwd, node_path_1.default.join(cwd, "generated_output", `${parsed.widgetName}_node_express_ws`)));
|
|
75
|
-
const serviceList = parsed.services.map((s) => s.name).join(", ");
|
|
76
|
-
const messageLines = [];
|
|
77
|
-
messageLines.push(`AnQst spec ${relativeSpecFile} built.`);
|
|
78
|
-
if (generationTargets.emitAngularService) {
|
|
79
|
-
messageLines.push(` Services ${serviceList} are available from ${relativeTypeScriptInstallPath}/services.`);
|
|
80
|
-
messageLines.push(` Generated types are available from ${relativeTypeScriptInstallPath}/types.`);
|
|
81
|
-
}
|
|
82
|
-
if (generationTargets.emitQWidget) {
|
|
83
|
-
messageLines.push(` Widget library available in ${relativeCppLibraryPath}.`);
|
|
84
|
-
}
|
|
85
|
-
if (generationTargets.emitNodeExpressWs) {
|
|
86
|
-
messageLines.push(` Node Express WS module available in ${relativeNodeModulePath}.`);
|
|
87
|
-
}
|
|
88
|
-
if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
|
|
89
|
-
messageLines.push(" No outputs selected by AnQst.generate.");
|
|
90
|
-
}
|
|
91
119
|
return {
|
|
92
120
|
success: true,
|
|
93
121
|
verificationMessage: verification.message,
|
|
94
|
-
message:
|
|
122
|
+
message: buildGenerateSummary(cwd, specPath, parsed.widgetName, generationTargets)
|
|
95
123
|
};
|
|
96
124
|
}
|
|
97
125
|
function runTest(cwd) {
|
|
@@ -103,57 +131,206 @@ function runTest(cwd) {
|
|
|
103
131
|
message: verification.message
|
|
104
132
|
};
|
|
105
133
|
}
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
(
|
|
111
|
-
|
|
112
|
-
(0, emit_1.writeGeneratedOutputs)(cwd, outputs);
|
|
113
|
-
if (generationTargets.emitAngularService) {
|
|
114
|
-
(0, emit_1.installTypeScriptOutputs)(cwd);
|
|
134
|
+
function resolveAnQstGenRoot() {
|
|
135
|
+
return node_path_1.default.resolve(__dirname, "..", "..");
|
|
136
|
+
}
|
|
137
|
+
function readActiveBuildStamp() {
|
|
138
|
+
if (process.env.ANQST_BUILD_STAMP && process.env.ANQST_BUILD_STAMP.trim().length > 0) {
|
|
139
|
+
return process.env.ANQST_BUILD_STAMP.trim();
|
|
115
140
|
}
|
|
116
|
-
|
|
117
|
-
|
|
141
|
+
const activePath = node_path_1.default.join(resolveAnQstGenRoot(), ANQSTGEN_ACTIVE_STAMP_FILE);
|
|
142
|
+
if (!node_fs_1.default.existsSync(activePath)) {
|
|
143
|
+
return "unknown_build_0";
|
|
118
144
|
}
|
|
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.");
|
|
145
|
+
try {
|
|
146
|
+
const parsed = JSON.parse(node_fs_1.default.readFileSync(activePath, "utf8"));
|
|
147
|
+
if (typeof parsed.active === "string" && parsed.active.trim().length > 0) {
|
|
148
|
+
return parsed.active.trim();
|
|
128
149
|
}
|
|
129
150
|
}
|
|
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
|
-
}
|
|
151
|
+
catch {
|
|
152
|
+
// Fallback to deterministic unknown stamp.
|
|
135
153
|
}
|
|
136
|
-
|
|
154
|
+
return "unknown_build_0";
|
|
155
|
+
}
|
|
156
|
+
function runDesignerPluginBuild(cwd, widgetName) {
|
|
157
|
+
const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, widgetName);
|
|
158
|
+
const pluginSourceDir = layout.designerPluginRoot;
|
|
159
|
+
const pluginBuildDir = layout.designerPluginBuildRoot;
|
|
160
|
+
const webBaseDir = process.env.ANQST_WEBBASE_DIR?.trim();
|
|
161
|
+
if (!webBaseDir) {
|
|
162
|
+
throw new errors_1.VerifyError("Missing ANQST_WEBBASE_DIR environment variable for --designerplugin build.");
|
|
163
|
+
}
|
|
164
|
+
const configureArgs = [
|
|
165
|
+
"-S",
|
|
166
|
+
pluginSourceDir,
|
|
167
|
+
"-B",
|
|
168
|
+
pluginBuildDir,
|
|
169
|
+
"-DCMAKE_BUILD_TYPE=Release",
|
|
170
|
+
`-DANQST_WEBBASE_DIR=${webBaseDir}`
|
|
171
|
+
];
|
|
172
|
+
const configure = (0, node_child_process_1.spawnSync)("cmake", configureArgs, {
|
|
173
|
+
cwd,
|
|
174
|
+
stdio: "inherit",
|
|
175
|
+
shell: process.platform === "win32"
|
|
176
|
+
});
|
|
177
|
+
if (configure.status !== 0) {
|
|
178
|
+
throw new errors_1.VerifyError([
|
|
179
|
+
"CMake configure failed while building Qt Designer plugin.",
|
|
180
|
+
"If CMake reports missing Qt5UiPlugin, install qttools5-dev (Ubuntu/Debian) and re-run install_dependencies.sh."
|
|
181
|
+
].join(" "));
|
|
182
|
+
}
|
|
183
|
+
const build = (0, node_child_process_1.spawnSync)("cmake", ["--build", pluginBuildDir, "--config", "Release"], {
|
|
184
|
+
cwd,
|
|
185
|
+
stdio: "inherit",
|
|
186
|
+
shell: process.platform === "win32"
|
|
187
|
+
});
|
|
188
|
+
if (build.status !== 0) {
|
|
189
|
+
throw new errors_1.VerifyError("CMake build failed while compiling Qt Designer plugin.");
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function runBuild(cwd, designerPlugin = false) {
|
|
193
|
+
const buildVersion = readActiveBuildStamp();
|
|
194
|
+
process.env.ANQST_BUILD_STAMP = buildVersion;
|
|
195
|
+
try {
|
|
196
|
+
const specPath = (0, project_1.resolveAnQstSpecPath)(cwd);
|
|
197
|
+
const configuredWidgetName = (0, project_1.resolveAnQstWidgetName)(cwd);
|
|
198
|
+
const generationTargets = resolveGenerationTargetsFromCwd(cwd, true);
|
|
199
|
+
const parsed = (0, parser_1.parseSpecFile)(specPath);
|
|
200
|
+
(0, verify_1.verifySpec)(parsed);
|
|
201
|
+
if (parsed.widgetName !== configuredWidgetName) {
|
|
202
|
+
throw new errors_1.VerifyError(`Settings widgetName '${configuredWidgetName}' does not match spec namespace '${parsed.widgetName}'.`);
|
|
203
|
+
}
|
|
204
|
+
resetGeneratedTargets(cwd, parsed.widgetName, generationTargets);
|
|
205
|
+
const outputs = (0, emit_1.generateOutputs)(parsed, generationTargets);
|
|
206
|
+
(0, emit_1.writeGeneratedOutputs)(cwd, outputs);
|
|
207
|
+
if (generationTargets.emitQWidget) {
|
|
208
|
+
(0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
|
|
209
|
+
}
|
|
210
|
+
const hasAngularProject = generationTargets.emitQWidget && node_fs_1.default.existsSync(node_path_1.default.join(cwd, "angular.json"));
|
|
211
|
+
if (hasAngularProject) {
|
|
212
|
+
const angularBuild = (0, node_child_process_1.spawnSync)("npx", ["ng", "build", "--configuration", "production"], {
|
|
213
|
+
cwd,
|
|
214
|
+
stdio: "inherit",
|
|
215
|
+
shell: process.platform === "win32"
|
|
216
|
+
});
|
|
217
|
+
if (angularBuild.status !== 0) {
|
|
218
|
+
throw new errors_1.VerifyError("Angular build failed while preparing embedded widget assets.");
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (generationTargets.emitQWidget) {
|
|
222
|
+
const embedded = (0, emit_1.installEmbeddedWebBundle)(cwd, parsed.widgetName);
|
|
223
|
+
if (hasAngularProject && !embedded) {
|
|
224
|
+
throw new errors_1.VerifyError("Unable to embed Angular output. Ensure ng build produced a dist bundle with index.html.");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
let designerPluginBuilt = false;
|
|
228
|
+
if (designerPlugin) {
|
|
229
|
+
if (!generationTargets.emitQWidget) {
|
|
230
|
+
console.warn("[AnQst] --designerplugin requested but QWidget target is not enabled. Skipping designer plugin build.");
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
const widgetCategory = (0, project_1.resolveAnQstWidgetCategory)(cwd);
|
|
234
|
+
(0, emit_1.installQtDesignerPluginCMake)(cwd, parsed.widgetName, { widgetCategory });
|
|
235
|
+
runDesignerPluginBuild(cwd, parsed.widgetName);
|
|
236
|
+
designerPluginBuilt = true;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
|
|
240
|
+
return {
|
|
241
|
+
success: true,
|
|
242
|
+
message: [
|
|
243
|
+
"Build completed.",
|
|
244
|
+
` anqst version ${buildVersion}`,
|
|
245
|
+
" No outputs selected by AnQst.generate."
|
|
246
|
+
].join("\n")
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, parsed.widgetName);
|
|
250
|
+
const detailLines = [];
|
|
251
|
+
if (generationTargets.emitAngularService) {
|
|
252
|
+
detailLines.push(" Target AngularService:");
|
|
253
|
+
detailLines.push(` - Services output: ${(0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "services"))}`);
|
|
254
|
+
detailLines.push(` - Types output: ${(0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "types"))}`);
|
|
255
|
+
}
|
|
256
|
+
if (generationTargets.emitQWidget) {
|
|
257
|
+
detailLines.push(" Target QWidget:");
|
|
258
|
+
detailLines.push(` - Qt integration CMake: ${(0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.cppCmakeRoot, "CMakeLists.txt"))}`);
|
|
259
|
+
detailLines.push(` - Widget output root: ${(0, layout_1.toProjectRelative)(cwd, layout.cppQtWidgetRoot)}`);
|
|
260
|
+
detailLines.push(" - Embedded web assets refreshed from Angular build");
|
|
261
|
+
}
|
|
262
|
+
if (generationTargets.emitNodeExpressWs) {
|
|
263
|
+
detailLines.push(" Target node_express_ws:");
|
|
264
|
+
detailLines.push(` - Module output root: ${(0, layout_1.toProjectRelative)(cwd, layout.nodeExpressRoot)}`);
|
|
265
|
+
}
|
|
266
|
+
if (designerPluginBuilt) {
|
|
267
|
+
const pluginBinaryPath = (0, layout_1.normalizeSlashes)(node_path_1.default.join((0, layout_1.toProjectRelative)(cwd, layout.designerPluginBuildRoot), designerPluginBinaryName(parsed.widgetName)));
|
|
268
|
+
detailLines.push(" Target QtDesignerPlugin:");
|
|
269
|
+
detailLines.push(` - Build output: ${(0, layout_1.toProjectRelative)(cwd, layout.designerPluginBuildRoot)}`);
|
|
270
|
+
detailLines.push(` - Plugin binary: ${pluginBinaryPath}`);
|
|
271
|
+
detailLines.push(" - Install target dir: <QT_INSTALL_PLUGINS>/designer");
|
|
272
|
+
detailLines.push(" - Discover QT_INSTALL_PLUGINS: qmake -query QT_INSTALL_PLUGINS");
|
|
273
|
+
detailLines.push(` - Example install: cp ${pluginBinaryPath} \"$(qmake -query QT_INSTALL_PLUGINS)/designer/\"`);
|
|
274
|
+
detailLines.push(` - User-local install: mkdir -p \"$HOME/.local/lib/qt5/plugins/designer\" && cp ${pluginBinaryPath} \"$HOME/.local/lib/qt5/plugins/designer/\"`);
|
|
275
|
+
}
|
|
137
276
|
return {
|
|
138
277
|
success: true,
|
|
139
|
-
message:
|
|
278
|
+
message: [
|
|
279
|
+
"Build completed.",
|
|
280
|
+
` anqst version ${buildVersion}`,
|
|
281
|
+
...detailLines
|
|
282
|
+
].join("\n")
|
|
140
283
|
};
|
|
141
284
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
parts.push("TypeScript installed to src/anqst-generated");
|
|
285
|
+
finally {
|
|
286
|
+
delete process.env.ANQST_BUILD_STAMP;
|
|
145
287
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
288
|
+
}
|
|
289
|
+
function parseSpecCommandArg(commandName, specArg, extraArgs) {
|
|
290
|
+
const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
|
|
291
|
+
const positional = [];
|
|
292
|
+
for (const arg of allArgs) {
|
|
293
|
+
if (arg.startsWith("-")) {
|
|
294
|
+
throw new Error(`Unknown ${commandName} flag '${arg}'. ${usageFor(commandName)}`);
|
|
295
|
+
}
|
|
296
|
+
positional.push(arg);
|
|
149
297
|
}
|
|
150
|
-
if (
|
|
151
|
-
|
|
298
|
+
if (positional.length !== 1) {
|
|
299
|
+
throw new Error(usageFor(commandName));
|
|
152
300
|
}
|
|
153
|
-
return
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
301
|
+
return positional[0];
|
|
302
|
+
}
|
|
303
|
+
function parseBuildCommandArgs(specArg, extraArgs) {
|
|
304
|
+
const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
|
|
305
|
+
let designerPlugin = false;
|
|
306
|
+
const positional = [];
|
|
307
|
+
for (let i = 0; i < allArgs.length; i += 1) {
|
|
308
|
+
const arg = allArgs[i];
|
|
309
|
+
if (arg === "--designerplugin") {
|
|
310
|
+
const value = allArgs[i + 1];
|
|
311
|
+
if (value && !value.startsWith("-")) {
|
|
312
|
+
designerPlugin = value.toLowerCase() === "true";
|
|
313
|
+
i += 1;
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
designerPlugin = true;
|
|
317
|
+
}
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
if (arg.startsWith("--designerplugin=")) {
|
|
321
|
+
const value = arg.slice("--designerplugin=".length);
|
|
322
|
+
designerPlugin = value.toLowerCase() === "true";
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
if (arg.startsWith("-")) {
|
|
326
|
+
throw new Error(`Unknown build flag '${arg}'. ${usageFor("build")}`);
|
|
327
|
+
}
|
|
328
|
+
positional.push(arg);
|
|
329
|
+
}
|
|
330
|
+
if (positional.length > 0) {
|
|
331
|
+
throw new Error(`Unexpected extra argument '${positional[0]}'. ${usageFor("build")}`);
|
|
332
|
+
}
|
|
333
|
+
return { designerPlugin };
|
|
157
334
|
}
|
|
158
335
|
function parseCleanCommandArgs(specArg, extraArgs) {
|
|
159
336
|
const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
|
|
@@ -209,7 +386,7 @@ function formatCleanResult(targetRoot, rows) {
|
|
|
209
386
|
const notFound = rows.filter((row) => row.status === "not_found");
|
|
210
387
|
const failed = rows.filter((row) => row.status === "failed");
|
|
211
388
|
const lines = [];
|
|
212
|
-
lines.push(`[AnQst] Clean summary for ${normalizeSlashes(targetRoot)}`);
|
|
389
|
+
lines.push(`[AnQst] Clean summary for ${(0, layout_1.normalizeSlashes)(targetRoot)}`);
|
|
213
390
|
if (deleted.length > 0) {
|
|
214
391
|
lines.push(` Deleted (${deleted.length})`);
|
|
215
392
|
for (const row of deleted)
|
|
@@ -231,14 +408,14 @@ function resolveGenerationTargetsFromCwd(cwd, requirePackageAnQst = false) {
|
|
|
231
408
|
const packagePath = node_path_1.default.join(cwd, "package.json");
|
|
232
409
|
if (!node_fs_1.default.existsSync(packagePath)) {
|
|
233
410
|
if (requirePackageAnQst) {
|
|
234
|
-
throw new errors_1.VerifyError("No package.json:
|
|
411
|
+
throw new errors_1.VerifyError("No package.json: AnQst commands must run inside an npm project.");
|
|
235
412
|
}
|
|
236
413
|
return toGenerationTargets([...project_1.DEFAULT_ANQST_GENERATE_TARGETS]);
|
|
237
414
|
}
|
|
238
415
|
const packageJson = JSON.parse(node_fs_1.default.readFileSync(packagePath, "utf8"));
|
|
239
416
|
if (packageJson.AnQst === undefined) {
|
|
240
417
|
if (requirePackageAnQst) {
|
|
241
|
-
throw new errors_1.VerifyError("Missing package.json key 'AnQst
|
|
418
|
+
throw new errors_1.VerifyError("Missing package.json key 'AnQst'. Run 'anqst instill <WidgetName>' first.");
|
|
242
419
|
}
|
|
243
420
|
return toGenerationTargets([...project_1.DEFAULT_ANQST_GENERATE_TARGETS]);
|
|
244
421
|
}
|
|
@@ -251,40 +428,24 @@ function toGenerationTargets(targets) {
|
|
|
251
428
|
emitNodeExpressWs: targets.includes("node_express_ws")
|
|
252
429
|
};
|
|
253
430
|
}
|
|
254
|
-
function resolveAnQstSpecFromPackage(targetRoot) {
|
|
255
|
-
const packagePath = node_path_1.default.join(targetRoot, "package.json");
|
|
256
|
-
if (!node_fs_1.default.existsSync(packagePath)) {
|
|
257
|
-
throw new Error(`No package.json with an AnQst key found at '${normalizeSlashes(targetRoot)}'. Use 'anqst clean ${normalizeSlashes(targetRoot)} --force' to clean anyway.`);
|
|
258
|
-
}
|
|
259
|
-
const packageJson = JSON.parse(node_fs_1.default.readFileSync(packagePath, "utf8"));
|
|
260
|
-
const spec = packageJson.AnQst?.spec;
|
|
261
|
-
if (!spec || spec.trim().length === 0) {
|
|
262
|
-
throw new Error(`No package.json with an AnQst key found at '${normalizeSlashes(targetRoot)}'. Use 'anqst clean ${normalizeSlashes(targetRoot)} --force' to clean anyway.`);
|
|
263
|
-
}
|
|
264
|
-
return node_path_1.default.resolve(targetRoot, spec);
|
|
265
|
-
}
|
|
266
431
|
function runClean(pathArg, force) {
|
|
267
432
|
const targetRoot = node_path_1.default.resolve(process.cwd(), pathArg);
|
|
268
|
-
const broadDirs = [
|
|
269
|
-
"generated_output",
|
|
270
|
-
node_path_1.default.join("src", "anqst-generated"),
|
|
271
|
-
"anqst-cmake"
|
|
272
|
-
];
|
|
273
433
|
if (force) {
|
|
274
|
-
const rows = runCleanup(targetRoot,
|
|
434
|
+
const rows = runCleanup(targetRoot, [(0, layout_1.normalizeSlashes)(node_path_1.default.join("AnQst", "generated"))]);
|
|
275
435
|
return {
|
|
276
436
|
success: true,
|
|
277
437
|
message: formatCleanResult(targetRoot, rows),
|
|
278
438
|
hadFailures: rows.some((row) => row.status === "failed")
|
|
279
439
|
};
|
|
280
440
|
}
|
|
281
|
-
const
|
|
282
|
-
const
|
|
441
|
+
const context = (0, project_1.resolveAnQstSettings)(targetRoot);
|
|
442
|
+
const layout = (0, layout_1.resolveGeneratedLayoutPaths)(targetRoot, context.settings.widgetName);
|
|
283
443
|
const widgetDirs = [
|
|
284
|
-
node_path_1.default.
|
|
285
|
-
node_path_1.default.
|
|
286
|
-
node_path_1.default.
|
|
287
|
-
|
|
444
|
+
(0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.frontendRoot)),
|
|
445
|
+
(0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.nodeExpressRoot)),
|
|
446
|
+
(0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.cppQtWidgetRoot)),
|
|
447
|
+
(0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.cppCmakeRoot)),
|
|
448
|
+
(0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.debugIntermediateRoot))
|
|
288
449
|
];
|
|
289
450
|
const rows = runCleanup(targetRoot, widgetDirs);
|
|
290
451
|
return {
|
|
@@ -293,8 +454,22 @@ function runClean(pathArg, force) {
|
|
|
293
454
|
hadFailures: rows.some((row) => row.status === "failed")
|
|
294
455
|
};
|
|
295
456
|
}
|
|
296
|
-
function
|
|
297
|
-
|
|
457
|
+
function designerPluginBinaryName(widgetName) {
|
|
458
|
+
const targetName = `${widgetName}DesignerPlugin`;
|
|
459
|
+
if (process.platform === "win32") {
|
|
460
|
+
return `${targetName}.dll`;
|
|
461
|
+
}
|
|
462
|
+
if (process.platform === "darwin") {
|
|
463
|
+
return `${targetName}.dylib`;
|
|
464
|
+
}
|
|
465
|
+
return `${targetName}.so`;
|
|
466
|
+
}
|
|
467
|
+
function renderInstallAliasMessage() {
|
|
468
|
+
const useColor = process.stdout.isTTY;
|
|
469
|
+
const text = "[AnQst] 'install' spotted. Muscle memory is undefeated - running 'instill' for you.";
|
|
470
|
+
if (!useColor)
|
|
471
|
+
return text;
|
|
472
|
+
return `\x1b[38;5;214m${text}\x1b[0m`;
|
|
298
473
|
}
|
|
299
474
|
function runCommand(command, specArg, extraArgs = []) {
|
|
300
475
|
try {
|
|
@@ -306,7 +481,11 @@ function runCommand(command, specArg, extraArgs = []) {
|
|
|
306
481
|
console.log(renderHelp());
|
|
307
482
|
return 0;
|
|
308
483
|
}
|
|
309
|
-
|
|
484
|
+
const normalizedCommand = command === "install" ? "instill" : command;
|
|
485
|
+
if (command === "install") {
|
|
486
|
+
console.log(renderInstallAliasMessage());
|
|
487
|
+
}
|
|
488
|
+
if (normalizedCommand === "instill") {
|
|
310
489
|
if (!specArg) {
|
|
311
490
|
console.error(usageFor("instill"));
|
|
312
491
|
return 1;
|
|
@@ -315,38 +494,33 @@ function runCommand(command, specArg, extraArgs = []) {
|
|
|
315
494
|
console.log(msg);
|
|
316
495
|
return 0;
|
|
317
496
|
}
|
|
318
|
-
if (
|
|
497
|
+
if (normalizedCommand === "test") {
|
|
319
498
|
const res = runTest(process.cwd());
|
|
320
499
|
console.log(res.message);
|
|
321
500
|
return 0;
|
|
322
501
|
}
|
|
323
|
-
if (
|
|
324
|
-
const
|
|
502
|
+
if (normalizedCommand === "build") {
|
|
503
|
+
const parsedArgs = parseBuildCommandArgs(specArg, extraArgs);
|
|
504
|
+
const res = runBuild(process.cwd(), parsedArgs.designerPlugin);
|
|
325
505
|
console.log(res.message);
|
|
326
506
|
return 0;
|
|
327
507
|
}
|
|
328
|
-
if (
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
return 1;
|
|
332
|
-
}
|
|
333
|
-
const res = runVerify(specArg);
|
|
508
|
+
if (normalizedCommand === "verify") {
|
|
509
|
+
const specArgParsed = parseSpecCommandArg("verify", specArg, extraArgs);
|
|
510
|
+
const res = runVerify(specArgParsed);
|
|
334
511
|
console.log(res.message);
|
|
335
512
|
return 0;
|
|
336
513
|
}
|
|
337
|
-
if (
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
return 1;
|
|
341
|
-
}
|
|
342
|
-
const res = runGenerate(specArg);
|
|
514
|
+
if (normalizedCommand === "generate") {
|
|
515
|
+
const specArgParsed = parseSpecCommandArg("generate", specArg, extraArgs);
|
|
516
|
+
const res = runGenerate(specArgParsed);
|
|
343
517
|
if (res.verificationMessage) {
|
|
344
518
|
console.log(res.verificationMessage);
|
|
345
519
|
}
|
|
346
520
|
console.log(res.message);
|
|
347
521
|
return 0;
|
|
348
522
|
}
|
|
349
|
-
if (
|
|
523
|
+
if (normalizedCommand === "clean") {
|
|
350
524
|
const parsed = parseCleanCommandArgs(specArg, extraArgs);
|
|
351
525
|
const res = runClean(parsed.targetPathArg, parsed.force);
|
|
352
526
|
console.log(res.message);
|
package/dist/src/bin/anqst.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,40 @@
|
|
|
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
|
+
const layout_1 = require("./layout");
|
|
13
|
+
function isDebugEnabled() {
|
|
14
|
+
return process.env.ANQST_DEBUG === "true";
|
|
15
|
+
}
|
|
16
|
+
function baseIntermediateDir(cwd) {
|
|
17
|
+
return (0, layout_1.anqstDebugIntermediateRootDir)(cwd);
|
|
18
|
+
}
|
|
19
|
+
function writeDebugFile(cwd, relativePath, content) {
|
|
20
|
+
if (!isDebugEnabled())
|
|
21
|
+
return;
|
|
22
|
+
try {
|
|
23
|
+
const targetPath = node_path_1.default.join(baseIntermediateDir(cwd), relativePath);
|
|
24
|
+
node_fs_1.default.mkdirSync(node_path_1.default.dirname(targetPath), { recursive: true });
|
|
25
|
+
node_fs_1.default.writeFileSync(targetPath, content, "utf8");
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
29
|
+
console.warn(`[AnQst][debug] Failed writing ${relativePath}: ${message}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function inspectText(value) {
|
|
33
|
+
return node_util_1.default.inspect(value, {
|
|
34
|
+
depth: null,
|
|
35
|
+
maxArrayLength: null,
|
|
36
|
+
maxStringLength: null,
|
|
37
|
+
breakLength: 120,
|
|
38
|
+
compact: false
|
|
39
|
+
});
|
|
40
|
+
}
|