@lumerahq/cli 0.19.9-dev.3 → 0.19.10-dev.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.
|
@@ -89,7 +89,7 @@ async function isFreshProject(projectRoot) {
|
|
|
89
89
|
}
|
|
90
90
|
function runApply(projectRoot) {
|
|
91
91
|
try {
|
|
92
|
-
execFileSync(process.execPath, [...process.execArgv, process.argv[1], "apply"], {
|
|
92
|
+
execFileSync(process.execPath, [...process.execArgv, process.argv[1], "apply", "--yes"], {
|
|
93
93
|
cwd: projectRoot,
|
|
94
94
|
stdio: "inherit",
|
|
95
95
|
env: process.env
|
package/dist/index.js
CHANGED
|
@@ -219,29 +219,29 @@ async function main() {
|
|
|
219
219
|
switch (command) {
|
|
220
220
|
// Resource commands
|
|
221
221
|
case "plan":
|
|
222
|
-
await import("./resources-
|
|
222
|
+
await import("./resources-TGVI6SYA.js").then((m) => m.plan(args.slice(1)));
|
|
223
223
|
break;
|
|
224
224
|
case "apply":
|
|
225
|
-
await import("./resources-
|
|
225
|
+
await import("./resources-TGVI6SYA.js").then((m) => m.apply(args.slice(1)));
|
|
226
226
|
break;
|
|
227
227
|
case "pull":
|
|
228
|
-
await import("./resources-
|
|
228
|
+
await import("./resources-TGVI6SYA.js").then((m) => m.pull(args.slice(1)));
|
|
229
229
|
break;
|
|
230
230
|
case "destroy":
|
|
231
|
-
await import("./resources-
|
|
231
|
+
await import("./resources-TGVI6SYA.js").then((m) => m.destroy(args.slice(1)));
|
|
232
232
|
break;
|
|
233
233
|
case "list":
|
|
234
|
-
await import("./resources-
|
|
234
|
+
await import("./resources-TGVI6SYA.js").then((m) => m.list(args.slice(1)));
|
|
235
235
|
break;
|
|
236
236
|
case "show":
|
|
237
|
-
await import("./resources-
|
|
237
|
+
await import("./resources-TGVI6SYA.js").then((m) => m.show(args.slice(1)));
|
|
238
238
|
break;
|
|
239
239
|
case "diff":
|
|
240
|
-
await import("./resources-
|
|
240
|
+
await import("./resources-TGVI6SYA.js").then((m) => m.diff(args.slice(1)));
|
|
241
241
|
break;
|
|
242
242
|
// Development
|
|
243
243
|
case "dev":
|
|
244
|
-
await import("./dev-
|
|
244
|
+
await import("./dev-35XSSGOG.js").then((m) => m.dev(args.slice(1)));
|
|
245
245
|
break;
|
|
246
246
|
case "run":
|
|
247
247
|
await import("./run-YUL73K5O.js").then((m) => m.run(args.slice(1)));
|
|
@@ -197,14 +197,16 @@ function parseHookFile(content) {
|
|
|
197
197
|
configFound: false,
|
|
198
198
|
configKeys: [],
|
|
199
199
|
configIssues: [],
|
|
200
|
-
defaultHandlerFound: false
|
|
200
|
+
defaultHandlerFound: false,
|
|
201
|
+
legacyHandlerPattern: false
|
|
201
202
|
};
|
|
202
203
|
let ast;
|
|
203
204
|
try {
|
|
204
205
|
ast = Parser.parse(content, {
|
|
205
206
|
ecmaVersion: "latest",
|
|
206
207
|
sourceType: "module",
|
|
207
|
-
locations: true
|
|
208
|
+
locations: true,
|
|
209
|
+
allowReturnOutsideFunction: true
|
|
208
210
|
});
|
|
209
211
|
} catch (err) {
|
|
210
212
|
const e = err;
|
|
@@ -216,7 +218,9 @@ function parseHookFile(content) {
|
|
|
216
218
|
return finding;
|
|
217
219
|
}
|
|
218
220
|
let configNode;
|
|
221
|
+
let configExportNode;
|
|
219
222
|
let handlerNode;
|
|
223
|
+
let topLevelReturnFound = false;
|
|
220
224
|
for (const node of ast.body) {
|
|
221
225
|
if (node.type === "ExportNamedDeclaration") {
|
|
222
226
|
const decl = node.declaration;
|
|
@@ -224,6 +228,7 @@ function parseHookFile(content) {
|
|
|
224
228
|
for (const d of decl.declarations) {
|
|
225
229
|
if (d.id?.type === "Identifier" && d.id.name === "config" && d.init?.type === "ObjectExpression") {
|
|
226
230
|
configNode = d.init;
|
|
231
|
+
configExportNode = node;
|
|
227
232
|
}
|
|
228
233
|
}
|
|
229
234
|
}
|
|
@@ -232,6 +237,8 @@ function parseHookFile(content) {
|
|
|
232
237
|
if (d.type === "FunctionDeclaration" || d.type === "FunctionExpression" || d.type === "ArrowFunctionExpression") {
|
|
233
238
|
handlerNode = d;
|
|
234
239
|
}
|
|
240
|
+
} else if (node.type === "ReturnStatement") {
|
|
241
|
+
topLevelReturnFound = true;
|
|
235
242
|
}
|
|
236
243
|
}
|
|
237
244
|
if (configNode) {
|
|
@@ -321,6 +328,13 @@ function parseHookFile(content) {
|
|
|
321
328
|
finding.scriptBody = `return ${content.slice(body.start, body.end)};`;
|
|
322
329
|
}
|
|
323
330
|
}
|
|
331
|
+
} else if (topLevelReturnFound) {
|
|
332
|
+
finding.legacyHandlerPattern = true;
|
|
333
|
+
if (configExportNode) {
|
|
334
|
+
finding.scriptBody = (content.slice(0, configExportNode.start) + content.slice(configExportNode.end)).trim();
|
|
335
|
+
} else {
|
|
336
|
+
finding.scriptBody = content.trim();
|
|
337
|
+
}
|
|
324
338
|
}
|
|
325
339
|
return finding;
|
|
326
340
|
}
|
|
@@ -343,6 +357,16 @@ function error2(target, message, line) {
|
|
|
343
357
|
...line !== void 0 ? { line } : {}
|
|
344
358
|
};
|
|
345
359
|
}
|
|
360
|
+
function warning(target, message, line) {
|
|
361
|
+
return {
|
|
362
|
+
ruleId: "hook-verify",
|
|
363
|
+
target,
|
|
364
|
+
severity: "warning",
|
|
365
|
+
message,
|
|
366
|
+
...line !== void 0 ? { line } : {}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
var LEGACY_HANDLER_MIGRATION_HINT = "Hook uses the legacy `async function main(ctx) { \u2026 } return main(ctx);` pattern. This still works, but please migrate to `export default async function handler(ctx) { \u2026 }` \u2014 the legacy pattern is invalid ES module syntax and will be removed in a future CLI release.";
|
|
346
370
|
function messageForIssue(issue) {
|
|
347
371
|
switch (issue.kind) {
|
|
348
372
|
case "missing-required-field":
|
|
@@ -364,6 +388,14 @@ var hookVerifyRule = {
|
|
|
364
388
|
description: "Validates hook file structure (config export, trigger, known keys, default handler) and verifies the script compiles via the backend.",
|
|
365
389
|
appliesTo: ["hook"],
|
|
366
390
|
async check(target, ctx) {
|
|
391
|
+
if (target.filePath.endsWith(".ts")) {
|
|
392
|
+
return [
|
|
393
|
+
error2(
|
|
394
|
+
target,
|
|
395
|
+
"TypeScript hook files are not yet supported. Rename to `.js` and remove any TypeScript-specific syntax (type annotations, `as` casts, etc.)."
|
|
396
|
+
)
|
|
397
|
+
];
|
|
398
|
+
}
|
|
367
399
|
const finding = parseHookFile(target.source);
|
|
368
400
|
if (finding.syntaxError) {
|
|
369
401
|
return [
|
|
@@ -383,7 +415,7 @@ var hookVerifyRule = {
|
|
|
383
415
|
];
|
|
384
416
|
}
|
|
385
417
|
const errors = [];
|
|
386
|
-
if (!finding.hook
|
|
418
|
+
if (finding.hook !== void 0 && !finding.hook.external_id && !ctx.appName) {
|
|
387
419
|
errors.push(
|
|
388
420
|
error2(
|
|
389
421
|
target,
|
|
@@ -391,7 +423,7 @@ var hookVerifyRule = {
|
|
|
391
423
|
)
|
|
392
424
|
);
|
|
393
425
|
}
|
|
394
|
-
if (!finding.defaultHandlerFound) {
|
|
426
|
+
if (!finding.defaultHandlerFound && !finding.legacyHandlerPattern) {
|
|
395
427
|
errors.push(
|
|
396
428
|
error2(
|
|
397
429
|
target,
|
|
@@ -403,20 +435,24 @@ var hookVerifyRule = {
|
|
|
403
435
|
errors.push(error2(target, messageForIssue(issue)));
|
|
404
436
|
}
|
|
405
437
|
if (errors.length > 0) return errors;
|
|
438
|
+
const advisories = [];
|
|
439
|
+
if (finding.legacyHandlerPattern) {
|
|
440
|
+
advisories.push(warning(target, LEGACY_HANDLER_MIGRATION_HINT));
|
|
441
|
+
}
|
|
406
442
|
let script = finding.scriptBody ?? "";
|
|
407
443
|
if (ctx.appName) {
|
|
408
444
|
script = script.replaceAll("{{app}}", ctx.appName);
|
|
409
445
|
}
|
|
410
446
|
if (!ctx.api) {
|
|
411
|
-
return
|
|
447
|
+
return advisories;
|
|
412
448
|
}
|
|
413
449
|
try {
|
|
414
450
|
await ctx.api.compileHook(script);
|
|
415
451
|
} catch (err) {
|
|
416
452
|
const detail = err instanceof ApiError ? err.body.trim() : err instanceof Error ? err.message : String(err);
|
|
417
|
-
return [error2(target, `Hook failed to compile on the backend: ${detail}`)];
|
|
453
|
+
return [...advisories, error2(target, `Hook failed to compile on the backend: ${detail}`)];
|
|
418
454
|
}
|
|
419
|
-
return
|
|
455
|
+
return advisories;
|
|
420
456
|
}
|
|
421
457
|
};
|
|
422
458
|
|
|
@@ -586,21 +622,34 @@ function safePrintLint(warnings, projectRoot) {
|
|
|
586
622
|
if (process.env.LUMERA_DEBUG) console.error("[lint] print failed:", err);
|
|
587
623
|
}
|
|
588
624
|
}
|
|
625
|
+
async function safeLintPass(label, build) {
|
|
626
|
+
try {
|
|
627
|
+
const issues = await build();
|
|
628
|
+
const errors = issues.filter((issue) => issue.severity === "error");
|
|
629
|
+
return { issues, errors };
|
|
630
|
+
} catch (err) {
|
|
631
|
+
if (process.env.LUMERA_DEBUG) console.error(`[lint] ${label} pass failed:`, err);
|
|
632
|
+
return null;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
589
635
|
async function lintCollectionFiles(projectRoot, platformDir, filterName) {
|
|
590
|
-
const
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
636
|
+
const result = await safeLintPass(
|
|
637
|
+
"collection",
|
|
638
|
+
async () => runLint({ projectRoot, targets: buildCollectionTargets(platformDir, filterName) })
|
|
639
|
+
);
|
|
640
|
+
if (!result || result.errors.length === 0) return;
|
|
641
|
+
safePrintLint(result.issues, projectRoot);
|
|
642
|
+
throw new Error(`Found ${result.errors.length} collection lint error(s)`);
|
|
595
643
|
}
|
|
596
644
|
async function lintHookFiles(api, projectRoot, platformDir, appName, filterName) {
|
|
597
|
-
const
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
645
|
+
const result = await safeLintPass("hook", async () => {
|
|
646
|
+
const targets = buildHookTargets(platformDir, filterName);
|
|
647
|
+
if (targets.length === 0) return [];
|
|
648
|
+
return runLint({ projectRoot, targets, api, appName });
|
|
649
|
+
});
|
|
650
|
+
if (!result || result.errors.length === 0) return;
|
|
651
|
+
safePrintLint(result.issues, projectRoot);
|
|
652
|
+
throw new Error(`Found ${result.errors.length} hook lint error(s)`);
|
|
604
653
|
}
|
|
605
654
|
var PACKAGE_MANAGERS = ["bun", "pnpm", "yarn", "npm"];
|
|
606
655
|
var PACKAGE_MANAGER_VALUE_FLAGS = /* @__PURE__ */ new Set(["--package-manager"]);
|