@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-4M4LMSSN.js").then((m) => m.plan(args.slice(1)));
222
+ await import("./resources-TGVI6SYA.js").then((m) => m.plan(args.slice(1)));
223
223
  break;
224
224
  case "apply":
225
- await import("./resources-4M4LMSSN.js").then((m) => m.apply(args.slice(1)));
225
+ await import("./resources-TGVI6SYA.js").then((m) => m.apply(args.slice(1)));
226
226
  break;
227
227
  case "pull":
228
- await import("./resources-4M4LMSSN.js").then((m) => m.pull(args.slice(1)));
228
+ await import("./resources-TGVI6SYA.js").then((m) => m.pull(args.slice(1)));
229
229
  break;
230
230
  case "destroy":
231
- await import("./resources-4M4LMSSN.js").then((m) => m.destroy(args.slice(1)));
231
+ await import("./resources-TGVI6SYA.js").then((m) => m.destroy(args.slice(1)));
232
232
  break;
233
233
  case "list":
234
- await import("./resources-4M4LMSSN.js").then((m) => m.list(args.slice(1)));
234
+ await import("./resources-TGVI6SYA.js").then((m) => m.list(args.slice(1)));
235
235
  break;
236
236
  case "show":
237
- await import("./resources-4M4LMSSN.js").then((m) => m.show(args.slice(1)));
237
+ await import("./resources-TGVI6SYA.js").then((m) => m.show(args.slice(1)));
238
238
  break;
239
239
  case "diff":
240
- await import("./resources-4M4LMSSN.js").then((m) => m.diff(args.slice(1)));
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-3SDNIPWA.js").then((m) => m.dev(args.slice(1)));
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?.external_id && !ctx.appName) {
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 issues = await runLint({ projectRoot, targets: buildCollectionTargets(platformDir, filterName) });
591
- const errors = issues.filter((issue) => issue.severity === "error");
592
- if (errors.length === 0) return;
593
- printLintWarnings(issues, projectRoot);
594
- throw new Error(`Found ${errors.length} collection lint error(s)`);
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 targets = buildHookTargets(platformDir, filterName);
598
- if (targets.length === 0) return;
599
- const issues = await runLint({ projectRoot, targets, api, appName });
600
- const errors = issues.filter((issue) => issue.severity === "error");
601
- if (errors.length === 0) return;
602
- printLintWarnings(issues, projectRoot);
603
- throw new Error(`Found ${errors.length} hook lint error(s)`);
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"]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumerahq/cli",
3
- "version": "0.19.9-dev.3",
3
+ "version": "0.19.10-dev.0",
4
4
  "description": "CLI for building and deploying Lumera apps",
5
5
  "type": "module",
6
6
  "engines": {