@lunora/cli 1.0.0-alpha.5 → 1.0.0-alpha.51
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/__assets__/package-og.svg +1 -1
- package/dist/bin.mjs +1 -1
- package/dist/index.d.mts +243 -114
- package/dist/index.d.ts +243 -114
- package/dist/index.mjs +7 -7
- package/dist/packem_chunks/handler.mjs +87 -6
- package/dist/packem_chunks/handler10.mjs +8 -14
- package/dist/packem_chunks/handler11.mjs +19 -189
- package/dist/packem_chunks/handler12.mjs +176 -115
- package/dist/packem_chunks/handler13.mjs +118 -52
- package/dist/packem_chunks/handler14.mjs +50 -43
- package/dist/packem_chunks/handler15.mjs +46 -67
- package/dist/packem_chunks/handler16.mjs +74 -37
- package/dist/packem_chunks/handler17.mjs +38 -100
- package/dist/packem_chunks/handler18.mjs +87 -152
- package/dist/packem_chunks/handler19.mjs +148 -67
- package/dist/packem_chunks/handler2.mjs +2 -2
- package/dist/packem_chunks/handler20.mjs +75 -75
- package/dist/packem_chunks/handler21.mjs +71 -288
- package/dist/packem_chunks/handler3.mjs +1 -1
- package/dist/packem_chunks/handler4.mjs +1 -1
- package/dist/packem_chunks/handler5.mjs +2 -2
- package/dist/packem_chunks/handler6.mjs +2 -2
- package/dist/packem_chunks/handler7.mjs +1 -1
- package/dist/packem_chunks/handler8.mjs +1 -1
- package/dist/packem_chunks/handler9.mjs +311 -12
- package/dist/packem_chunks/planDevCommand.mjs +47 -50
- package/dist/packem_chunks/runCodegenCommand.mjs +2 -2
- package/dist/packem_chunks/runDeployCommand.mjs +105 -15
- package/dist/packem_chunks/runInitCommand.mjs +1942 -88
- package/dist/packem_chunks/runMigrateGenerateCommand.mjs +5 -5
- package/dist/packem_chunks/runResetCommand.mjs +2 -2
- package/dist/packem_chunks/runRpcCommand.mjs +1 -1
- package/dist/packem_shared/{COMMANDS-DXaq12xm.mjs → COMMANDS-B0ftFD_3.mjs} +47 -21
- package/dist/packem_shared/codegen-error-DJG-ghs_.mjs +31 -0
- package/dist/packem_shared/{command-BDXcJCCJ.mjs → command-D3lB_4Az.mjs} +6 -1
- package/dist/packem_shared/{commands-B9nASOYd.mjs → commands-B-gR09Z_.mjs} +61 -4
- package/dist/packem_shared/{createLogger-CHPNjFw2.mjs → createLogger-B40gPzQo.mjs} +9 -4
- package/dist/packem_shared/detect-package-manager-DYp7n3mJ.mjs +61 -0
- package/dist/packem_shared/{diffSnapshots-RR2ZE8Ya.mjs → diffSnapshots-BeDvvNiF.mjs} +1 -1
- package/dist/packem_shared/{insertSchemaExtension-BuzF6-t2.mjs → insertSchemaExtension-DAqbfr9Z.mjs} +15 -10
- package/dist/packem_shared/{output-format-7gyGR3h8.mjs → output-format-wUvAN6AL.mjs} +1 -1
- package/dist/packem_shared/prompt-cancelled-APzX1Im-.mjs +9 -0
- package/dist/packem_shared/runAddCommand-bnY6-HKb.mjs +4 -0
- package/dist/packem_shared/{schemaIrToSnapshot-aBTo7TM5.mjs → schemaIrToSnapshot-DdsljJT-.mjs} +1 -1
- package/dist/packem_shared/storage-BIsph-Vk.mjs +84 -0
- package/dist/packem_shared/tui-prompts-BjEN8XgP.mjs +658 -0
- package/dist/packem_shared/wrangler-secrets-P2_ZUR-k.mjs +47 -0
- package/package.json +9 -10
- package/skills/lunora-setup-storage/SKILL.md +7 -3
- package/dist/packem_shared/features-ocSSpZtS.mjs +0 -24
- package/dist/packem_shared/runAddCommand-BF7XreDW.mjs +0 -4
- package/dist/packem_shared/tui-prompts-Bm15GPJA.mjs +0 -229
- /package/dist/packem_shared/{defaultSpawner-DxI3mebw.mjs → createRecordingSpawner-DxI3mebw.mjs} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, writeFileSync,
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync, mkdtempSync, rmSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
|
-
import {
|
|
3
|
+
import { discoverSchema, discoverMigrations } from '@lunora/codegen';
|
|
4
4
|
import { join } from '@visulima/path';
|
|
5
5
|
import { Project } from 'ts-morph';
|
|
6
6
|
import { r as resolveAdminBaseUrl } from '../packem_shared/admin-url-4UzT-CI4.mjs';
|
|
7
|
-
import { d as defineHandler } from '../packem_shared/command-
|
|
8
|
-
import { diffSnapshots, renderMigrationFile } from '../packem_shared/diffSnapshots-
|
|
7
|
+
import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
|
|
8
|
+
import { diffSnapshots, renderMigrationFile } from '../packem_shared/diffSnapshots-BeDvvNiF.mjs';
|
|
9
9
|
import { a as resolveProductionWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
|
|
10
|
-
import schemaIrToSnapshot from '../packem_shared/schemaIrToSnapshot-
|
|
10
|
+
import schemaIrToSnapshot from '../packem_shared/schemaIrToSnapshot-DdsljJT-.mjs';
|
|
11
11
|
import { runExportCommand, runImportCommand } from '../packem_shared/DEFAULT_IMPORT_BATCH_SIZE-Ck-2bU08.mjs';
|
|
12
12
|
|
|
13
13
|
const SNAPSHOT_FILENAME = ".snapshot.json";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, rmSync } from 'node:fs';
|
|
2
2
|
import { join } from '@visulima/path';
|
|
3
|
-
import { d as defineHandler } from '../packem_shared/command-
|
|
4
|
-
import {
|
|
3
|
+
import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
|
|
4
|
+
import { b as tuiConfirm } from '../packem_shared/tui-prompts-BjEN8XgP.mjs';
|
|
5
5
|
|
|
6
6
|
const runResetCommand = async (options) => {
|
|
7
7
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as defineHandler } from '../packem_shared/command-
|
|
1
|
+
import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
|
|
2
2
|
import { r as resolveWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
|
|
3
3
|
|
|
4
4
|
const parseArgsJson = (raw) => {
|
|
@@ -3,7 +3,7 @@ import { createCerebro } from '@visulima/cerebro';
|
|
|
3
3
|
import completionCommand from '@visulima/cerebro/command/completion';
|
|
4
4
|
import versionCommand from '@visulima/cerebro/command/version';
|
|
5
5
|
import { A as API_SPEC_HELP } from './api-spec-CtA6ilu4.mjs';
|
|
6
|
-
import { createLogger } from './createLogger-
|
|
6
|
+
import { createLogger } from './createLogger-B40gPzQo.mjs';
|
|
7
7
|
import { tmpdir } from 'node:os';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
9
|
|
|
@@ -14,7 +14,8 @@ const addCommand = {
|
|
|
14
14
|
["lunora add auth", "Add authentication (asks which provider)"],
|
|
15
15
|
["lunora add auth --provider clerk", "Add Clerk auth without prompting"],
|
|
16
16
|
["lunora add email", "Add transactional email (Cloudflare Email Workers + dev mail catcher)"],
|
|
17
|
-
["lunora add storage", "Add the R2 storage registry item"],
|
|
17
|
+
["lunora add storage", "Add the R2 storage registry item (asks for the bucket name)"],
|
|
18
|
+
["lunora add storage --bucket my-app-uploads", "Add storage with a bucket name, no prompt"],
|
|
18
19
|
["lunora add crons", "Add the scheduled-jobs registry item"],
|
|
19
20
|
["lunora add storage --ref alpha", "Add an item from the alpha branch's registry"]
|
|
20
21
|
],
|
|
@@ -25,7 +26,10 @@ const addCommand = {
|
|
|
25
26
|
name: "add",
|
|
26
27
|
options: [
|
|
27
28
|
{ description: "auth: provider to use without prompting (auth | clerk | auth0)", name: "provider", type: String },
|
|
28
|
-
{ description: "
|
|
29
|
+
{ description: "auth: D1 database name to use without prompting (lowercase alphanumeric + hyphens)", name: "db", type: String },
|
|
30
|
+
{ description: "storage: R2 bucket name to use without prompting (lowercase alphanumeric + hyphens)", name: "bucket", type: String },
|
|
31
|
+
{ description: "email: verified destination address to use without prompting", name: "mail-to", type: String },
|
|
32
|
+
{ description: "Skip prompts (auth provider, DB name, bucket name, mail destination) and use the defaults", name: "yes", type: Boolean },
|
|
29
33
|
{ description: "Local registry root (offline; expects <name>/ subdirs)", name: "from", type: String },
|
|
30
34
|
{ description: "Override the remote registry source base (e.g. gh:owner/repo/registry)", name: "source", type: String },
|
|
31
35
|
{
|
|
@@ -33,7 +37,8 @@ const addCommand = {
|
|
|
33
37
|
name: "ref",
|
|
34
38
|
type: String
|
|
35
39
|
},
|
|
36
|
-
{ description: "Permit --source values outside gh:/github:/https://", name: "allow-unsafe-source", type: Boolean }
|
|
40
|
+
{ description: "Permit --source values outside gh:/github:/https://", name: "allow-unsafe-source", type: Boolean },
|
|
41
|
+
{ description: "Output format: pretty (default) or json", name: "format", type: String }
|
|
37
42
|
]
|
|
38
43
|
};
|
|
39
44
|
|
|
@@ -256,21 +261,24 @@ const doctorCommand = {
|
|
|
256
261
|
};
|
|
257
262
|
|
|
258
263
|
const envCommand = {
|
|
259
|
-
argument: { description: "list | get <KEY> | set <KEY> <VALUE> | unset <KEY> | push | diff | doctor", name: "subcommand", type: String },
|
|
260
|
-
description: "Manage .dev.vars and sync secrets via wrangler (list | get | set | unset | push | diff | doctor)",
|
|
264
|
+
argument: { description: "list | get <KEY> | set <KEY> <VALUE> | unset <KEY> | generate [KEY] | push | diff | doctor", name: "subcommand", type: String },
|
|
265
|
+
description: "Manage .dev.vars and sync secrets via wrangler (list | get | set | unset | generate | push | diff | doctor)",
|
|
261
266
|
examples: [
|
|
262
267
|
["lunora env list", "List .dev.vars keys"],
|
|
263
268
|
["lunora env set API_KEY secret", "Set a local variable"],
|
|
269
|
+
["lunora env generate", "Generate strong values for the project's secrets (print KEY=value)"],
|
|
270
|
+
["lunora env generate AUTH_SECRET --set", "Generate one secret and write it to .dev.vars"],
|
|
264
271
|
["lunora env push --yes", "Upload secrets to Cloudflare"],
|
|
265
272
|
["lunora env diff", "Compare local .dev.vars keys against Cloudflare"]
|
|
266
273
|
],
|
|
267
274
|
group: "Data",
|
|
268
|
-
loader: () => import('../packem_chunks/
|
|
275
|
+
loader: () => import('../packem_chunks/handler9.mjs').then((m) => {
|
|
269
276
|
return { default: m.execute };
|
|
270
277
|
}),
|
|
271
278
|
name: "env",
|
|
272
279
|
options: [
|
|
273
280
|
{ description: "Target production for `push` (passes --env production to wrangler)", name: "prod", type: Boolean },
|
|
281
|
+
{ description: "For `generate` — write the generated secrets into .dev.vars instead of printing them", name: "set", type: Boolean },
|
|
274
282
|
{
|
|
275
283
|
description: "Push secrets to a temporary-account deployment when unauthenticated (wrangler secret put --temporary). Errors if you're already authenticated.",
|
|
276
284
|
name: "temporary",
|
|
@@ -288,7 +296,7 @@ const exportCommand = {
|
|
|
288
296
|
["lunora export --tables messages,users", "Export only specific tables"]
|
|
289
297
|
],
|
|
290
298
|
group: "Data",
|
|
291
|
-
loader: () => import('../packem_chunks/
|
|
299
|
+
loader: () => import('../packem_chunks/handler10.mjs').then((m) => {
|
|
292
300
|
return { default: m.execute };
|
|
293
301
|
}),
|
|
294
302
|
name: "export",
|
|
@@ -310,7 +318,7 @@ const importCommand = {
|
|
|
310
318
|
description: "Bulk-insert rows from an NDJSON file via the worker's admin endpoint",
|
|
311
319
|
examples: [["lunora import backup.ndjson", "Bulk-insert rows from an NDJSON file"]],
|
|
312
320
|
group: "Data",
|
|
313
|
-
loader: () => import('../packem_chunks/
|
|
321
|
+
loader: () => import('../packem_chunks/handler11.mjs').then((m) => {
|
|
314
322
|
return { default: m.execute };
|
|
315
323
|
}),
|
|
316
324
|
name: "import",
|
|
@@ -334,7 +342,7 @@ const infoCommand = {
|
|
|
334
342
|
["lunora info --json", "Emit a JSON snapshot"]
|
|
335
343
|
],
|
|
336
344
|
group: "Project",
|
|
337
|
-
loader: () => import('../packem_chunks/
|
|
345
|
+
loader: () => import('../packem_chunks/handler12.mjs').then((m) => {
|
|
338
346
|
return { default: m.execute };
|
|
339
347
|
}),
|
|
340
348
|
name: "info",
|
|
@@ -361,11 +369,19 @@ const initCommand = {
|
|
|
361
369
|
options: [
|
|
362
370
|
{
|
|
363
371
|
alias: "t",
|
|
364
|
-
|
|
365
|
-
|
|
372
|
+
// No default: when omitted, an interactive run shows the framework
|
|
373
|
+
// picker (default React overlay) and a non-interactive run errors.
|
|
374
|
+
// For React/Vue/Solid/Svelte SPAs use `--vite <framework>` (overlay);
|
|
375
|
+
// `-t` selects a bespoke template.
|
|
376
|
+
description: "Bespoke template (standalone | astro | nuxt | sveltekit | tanstack-start-react | tanstack-start-solid). For an SPA use --vite react|vue|solid|svelte.",
|
|
366
377
|
name: "template",
|
|
367
378
|
type: String
|
|
368
379
|
},
|
|
380
|
+
{
|
|
381
|
+
description: "Scaffold via the create-vite overlay for a framework (react | vue | solid | svelte | vanilla) — official create-vite base + Lunora layer",
|
|
382
|
+
name: "vite",
|
|
383
|
+
type: String
|
|
384
|
+
},
|
|
369
385
|
{
|
|
370
386
|
description: "Local templates root to copy from (offline-friendly; expects <type>/ subdirs)",
|
|
371
387
|
name: "from",
|
|
@@ -407,6 +423,16 @@ const initCommand = {
|
|
|
407
423
|
description: "Also scaffold a CI deploy pipeline: github (.github/workflows/deploy.yml) or gitlab (.gitlab-ci.yml)",
|
|
408
424
|
name: "ci",
|
|
409
425
|
type: String
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
description: "Add features non-interactively after scaffolding (comma-separated): auth | email | storage | ratelimit | crons | presence | backup",
|
|
429
|
+
name: "add",
|
|
430
|
+
type: String
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
description: "Walk through every step (prompts + output) without writing files, installing, or running git",
|
|
434
|
+
name: "dry-run",
|
|
435
|
+
type: Boolean
|
|
410
436
|
}
|
|
411
437
|
]
|
|
412
438
|
};
|
|
@@ -420,7 +446,7 @@ const insightsCommand = {
|
|
|
420
446
|
["lunora insights --prod --url https://app.example.com --token $LUNORA_ADMIN_TOKEN", "Report against production"]
|
|
421
447
|
],
|
|
422
448
|
group: "Develop",
|
|
423
|
-
loader: () => import('../packem_chunks/
|
|
449
|
+
loader: () => import('../packem_chunks/handler13.mjs').then((m) => {
|
|
424
450
|
return { default: m.execute };
|
|
425
451
|
}),
|
|
426
452
|
name: "insights",
|
|
@@ -442,7 +468,7 @@ const linkCommand = {
|
|
|
442
468
|
["lunora link --remove", "Remove the link"]
|
|
443
469
|
],
|
|
444
470
|
group: "Deploy",
|
|
445
|
-
loader: () => import('../packem_chunks/
|
|
471
|
+
loader: () => import('../packem_chunks/handler14.mjs').then((m) => {
|
|
446
472
|
return { default: m.execute };
|
|
447
473
|
}),
|
|
448
474
|
name: "link",
|
|
@@ -458,7 +484,7 @@ const logsCommand = {
|
|
|
458
484
|
argument: { description: "Worker name (defaults to the name in wrangler config)", name: "worker", type: String },
|
|
459
485
|
description: "Stream live logs from a deployed Lunora Worker",
|
|
460
486
|
group: "Deploy",
|
|
461
|
-
loader: () => import('../packem_chunks/
|
|
487
|
+
loader: () => import('../packem_chunks/handler15.mjs').then((m) => {
|
|
462
488
|
return { default: m.execute };
|
|
463
489
|
}),
|
|
464
490
|
name: "logs",
|
|
@@ -518,7 +544,7 @@ const prepareCommand = {
|
|
|
518
544
|
description: "Run codegen + binding reconcile + wrangler validation (no Vite) — for CI",
|
|
519
545
|
examples: [["lunora prepare", "Codegen + binding reconcile + validate (CI, before deploy)"]],
|
|
520
546
|
group: "Deploy",
|
|
521
|
-
loader: () => import('../packem_chunks/
|
|
547
|
+
loader: () => import('../packem_chunks/handler16.mjs').then((m) => {
|
|
522
548
|
return { default: m.execute };
|
|
523
549
|
}),
|
|
524
550
|
name: "prepare",
|
|
@@ -542,7 +568,7 @@ const registryCommand = {
|
|
|
542
568
|
["lunora registry build --check", "Verify the committed catalog is current"]
|
|
543
569
|
],
|
|
544
570
|
group: "Project",
|
|
545
|
-
loader: () => import('../packem_chunks/
|
|
571
|
+
loader: () => import('../packem_chunks/handler17.mjs').then((m) => {
|
|
546
572
|
return { default: m.execute };
|
|
547
573
|
}),
|
|
548
574
|
name: "registry",
|
|
@@ -592,7 +618,7 @@ const rulesCommand = {
|
|
|
592
618
|
["lunora rules check --strict", "Exit non-zero when rules are missing (CI gate)"]
|
|
593
619
|
],
|
|
594
620
|
group: "Project",
|
|
595
|
-
loader: () => import('../packem_chunks/
|
|
621
|
+
loader: () => import('../packem_chunks/handler18.mjs').then((m) => {
|
|
596
622
|
return { default: m.execute };
|
|
597
623
|
}),
|
|
598
624
|
name: "rules",
|
|
@@ -630,7 +656,7 @@ const seedCommand = {
|
|
|
630
656
|
["lunora seed --seed 7 --dry-run", "Print the NDJSON for seed 7 without inserting"]
|
|
631
657
|
],
|
|
632
658
|
group: "Data",
|
|
633
|
-
loader: () => import('../packem_chunks/
|
|
659
|
+
loader: () => import('../packem_chunks/handler19.mjs').then((m) => {
|
|
634
660
|
return { default: m.execute };
|
|
635
661
|
}),
|
|
636
662
|
name: "seed",
|
|
@@ -659,7 +685,7 @@ const verifyCommand = {
|
|
|
659
685
|
["lunora verify --no-typecheck", "Skip the TypeScript type-check"]
|
|
660
686
|
],
|
|
661
687
|
group: "Deploy",
|
|
662
|
-
loader: () => import('../packem_chunks/
|
|
688
|
+
loader: () => import('../packem_chunks/handler20.mjs').then((m) => {
|
|
663
689
|
return { default: m.execute };
|
|
664
690
|
}),
|
|
665
691
|
name: "verify",
|
|
@@ -678,7 +704,7 @@ const viewCommand = {
|
|
|
678
704
|
["lunora view --remote", "Open the deployed studio"]
|
|
679
705
|
],
|
|
680
706
|
group: "Project",
|
|
681
|
-
loader: () => import('../packem_chunks/
|
|
707
|
+
loader: () => import('../packem_chunks/handler21.mjs').then((m) => {
|
|
682
708
|
return { default: m.execute };
|
|
683
709
|
}),
|
|
684
710
|
name: "view",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { findLunoraSolution } from '@lunora/codegen';
|
|
2
|
+
import { VisulimaError, renderError } from '@visulima/error';
|
|
3
|
+
|
|
4
|
+
const flattenSolutionBody = (solution) => solution.body.split("\n").filter((line) => !line.startsWith("```")).join("\n").replaceAll(/\*\*(.+?)\*\*/gu, "$1").replaceAll(/`([^`]+)`/gu, "$1");
|
|
5
|
+
const NO_STACK = { filterStacktrace: () => false, hideErrorCodeView: true };
|
|
6
|
+
const renderCodegenFailure = (error, reason) => {
|
|
7
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
8
|
+
const solution = findLunoraSolution(message);
|
|
9
|
+
const rendered = new VisulimaError({
|
|
10
|
+
hint: solution ? [solution.header, "", flattenSolutionBody(solution)] : void 0,
|
|
11
|
+
message: reason === void 0 ? `codegen failed: ${message}` : `codegen failed (${reason}): ${message}`,
|
|
12
|
+
name: "CodegenError"
|
|
13
|
+
});
|
|
14
|
+
rendered.stack = "";
|
|
15
|
+
return renderError(rendered, NO_STACK);
|
|
16
|
+
};
|
|
17
|
+
const renderCodegenHint = (message) => {
|
|
18
|
+
const solution = findLunoraSolution(message);
|
|
19
|
+
if (solution === void 0) {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
const rendered = new VisulimaError({
|
|
23
|
+
hint: [flattenSolutionBody(solution)],
|
|
24
|
+
message: solution.header,
|
|
25
|
+
name: "Hint"
|
|
26
|
+
});
|
|
27
|
+
rendered.stack = "";
|
|
28
|
+
return renderError(rendered, NO_STACK);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export { renderCodegenHint as a, renderCodegenFailure as r };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { createLogger } from './createLogger-
|
|
1
|
+
import { createLogger } from './createLogger-B40gPzQo.mjs';
|
|
2
|
+
import { P as PromptCancelledError, a as PROMPT_CANCEL_EXIT_CODE } from './prompt-cancelled-APzX1Im-.mjs';
|
|
2
3
|
|
|
3
4
|
const defineHandler = (body) => async (toolbox) => {
|
|
4
5
|
const logger = createLogger();
|
|
@@ -6,6 +7,10 @@ const defineHandler = (body) => async (toolbox) => {
|
|
|
6
7
|
const { code } = await body({ argument: toolbox.argument, cwd: toolbox.process.cwd, logger, options: toolbox.options });
|
|
7
8
|
toolbox.process.exit(code);
|
|
8
9
|
} catch (error) {
|
|
10
|
+
if (error instanceof PromptCancelledError) {
|
|
11
|
+
toolbox.process.exit(PROMPT_CANCEL_EXIT_CODE);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
9
14
|
logger.error(error instanceof Error ? error.message : String(error));
|
|
10
15
|
toolbox.process.exit(1);
|
|
11
16
|
}
|
|
@@ -3,9 +3,9 @@ import { dirname, join } from '@visulima/path';
|
|
|
3
3
|
import { DEV_VARS_FILE, parseDevVariableEntries } from '@lunora/config';
|
|
4
4
|
import { modify, applyEdits, parse } from 'jsonc-parser';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import {
|
|
6
|
+
import { b as tuiConfirm } from './tui-prompts-BjEN8XgP.mjs';
|
|
7
7
|
import { collectCatalog, buildRegistryIndex } from './buildRegistryIndex-BcYe607_.mjs';
|
|
8
|
-
import { insertSchemaExtension } from './insertSchemaExtension-
|
|
8
|
+
import { insertSchemaExtension } from './insertSchemaExtension-DAqbfr9Z.mjs';
|
|
9
9
|
import { createHash } from 'node:crypto';
|
|
10
10
|
import { tmpdir } from 'node:os';
|
|
11
11
|
import { downloadTemplate } from 'giget';
|
|
@@ -65,6 +65,39 @@ const resolveDistTag = () => {
|
|
|
65
65
|
const ref = resolveVersionRef(resolveCliVersion());
|
|
66
66
|
return ref === STABLE_BRANCH ? STABLE_DIST_TAG : ref;
|
|
67
67
|
};
|
|
68
|
+
const DEFAULT_REGISTRY = "https://registry.npmjs.org";
|
|
69
|
+
const registryBase = () => {
|
|
70
|
+
const configured = process.env["npm_config_registry"];
|
|
71
|
+
const base = configured !== void 0 && configured.length > 0 ? configured : DEFAULT_REGISTRY;
|
|
72
|
+
return base.endsWith("/") ? base.slice(0, -1) : base;
|
|
73
|
+
};
|
|
74
|
+
const resolveTagVersion = async (packageName, tag) => {
|
|
75
|
+
try {
|
|
76
|
+
const response = await fetch(`${registryBase()}/${packageName.replace("/", "%2F")}`, {
|
|
77
|
+
headers: { accept: "application/vnd.npm.install-v1+json" },
|
|
78
|
+
signal: AbortSignal.timeout(1e4)
|
|
79
|
+
});
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
return void 0;
|
|
82
|
+
}
|
|
83
|
+
const packument = await response.json();
|
|
84
|
+
return packument["dist-tags"]?.[tag];
|
|
85
|
+
} catch {
|
|
86
|
+
return void 0;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const resolveTagVersions = async (names, tag) => {
|
|
90
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
91
|
+
await Promise.all(
|
|
92
|
+
[...new Set(names)].map(async (name) => {
|
|
93
|
+
const version = await resolveTagVersion(name, tag);
|
|
94
|
+
if (version !== void 0) {
|
|
95
|
+
resolved.set(name, version);
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
);
|
|
99
|
+
return resolved;
|
|
100
|
+
};
|
|
68
101
|
|
|
69
102
|
const resolveDepRange = (range) => {
|
|
70
103
|
if (!range.startsWith("workspace:")) {
|
|
@@ -583,6 +616,26 @@ const resolvePlan = async (names, options) => {
|
|
|
583
616
|
const emptyResult = () => {
|
|
584
617
|
return { bindings: [], code: 0, deps: [], skipped: [], written: [] };
|
|
585
618
|
};
|
|
619
|
+
const setBindingField = (manifest, section, match, field, fieldValue) => {
|
|
620
|
+
if (!manifest.bindings) {
|
|
621
|
+
return manifest;
|
|
622
|
+
}
|
|
623
|
+
return {
|
|
624
|
+
...manifest,
|
|
625
|
+
bindings: manifest.bindings.map((binding) => {
|
|
626
|
+
if (binding.path[0] !== section || !Array.isArray(binding.value)) {
|
|
627
|
+
return binding;
|
|
628
|
+
}
|
|
629
|
+
const entries = binding.value;
|
|
630
|
+
return {
|
|
631
|
+
...binding,
|
|
632
|
+
value: entries.map(
|
|
633
|
+
(entry) => typeof entry === "object" && entry !== null && entry[match.key] === match.value ? { ...entry, [field]: fieldValue } : entry
|
|
634
|
+
)
|
|
635
|
+
};
|
|
636
|
+
})
|
|
637
|
+
};
|
|
638
|
+
};
|
|
586
639
|
|
|
587
640
|
const printPlan = (logger, manifest) => {
|
|
588
641
|
const label = manifest.title ?? manifest.description;
|
|
@@ -688,8 +741,12 @@ const runAddCommand = async (options) => {
|
|
|
688
741
|
}
|
|
689
742
|
let cleanups = [];
|
|
690
743
|
try {
|
|
691
|
-
const { cleanups: planCleanups, items } = await resolvePlan(options.names, options);
|
|
744
|
+
const { cleanups: planCleanups, items: resolvedItems } = await resolvePlan(options.names, options);
|
|
692
745
|
cleanups = planCleanups;
|
|
746
|
+
const { transformManifest } = options;
|
|
747
|
+
const items = transformManifest ? resolvedItems.map((item) => {
|
|
748
|
+
return { ...item, manifest: transformManifest(item.manifest) };
|
|
749
|
+
}) : resolvedItems;
|
|
693
750
|
for (const { manifest } of items) {
|
|
694
751
|
printPlan(options.logger, manifest);
|
|
695
752
|
}
|
|
@@ -785,4 +842,4 @@ const runBuildIndexCommand = async (options) => {
|
|
|
785
842
|
return empty;
|
|
786
843
|
};
|
|
787
844
|
|
|
788
|
-
export { runBuildIndexCommand as a, runRegistryViewCommand as b,
|
|
845
|
+
export { runBuildIndexCommand as a, runRegistryViewCommand as b, resolveTagVersions as c, resolveSourceRef as d, resolveDistTag as e, runListCommand as f, runAddCommand as r, setBindingField as s };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { STEP_BADGE_NAMES, LunoraReporter } from '@lunora/config';
|
|
1
2
|
import { JsonReporter } from '@visulima/pail/reporter/json';
|
|
2
|
-
import { PrettyReporter } from '@visulima/pail/reporter/pretty';
|
|
3
3
|
import { createPail } from '@visulima/pail/server';
|
|
4
4
|
|
|
5
5
|
const wantJson = () => {
|
|
@@ -7,16 +7,18 @@ const wantJson = () => {
|
|
|
7
7
|
return flag === "1" || flag === "true";
|
|
8
8
|
};
|
|
9
9
|
const buildReporter = () => {
|
|
10
|
-
const Reporter = wantJson() ? JsonReporter :
|
|
10
|
+
const Reporter = wantJson() ? JsonReporter : LunoraReporter;
|
|
11
11
|
return new Reporter();
|
|
12
12
|
};
|
|
13
|
+
const STEP_LOG_TYPES = Object.fromEntries(STEP_BADGE_NAMES.map((name) => [name, { label: name, logLevel: "informational" }]));
|
|
13
14
|
let sharedPail;
|
|
14
15
|
const getPail = () => {
|
|
15
16
|
sharedPail ??= createPail({
|
|
16
17
|
reporters: [buildReporter()],
|
|
17
18
|
scope: ["lunora"],
|
|
18
19
|
stderr: process.stderr,
|
|
19
|
-
stdout: process.stdout
|
|
20
|
+
stdout: process.stdout,
|
|
21
|
+
types: STEP_LOG_TYPES
|
|
20
22
|
});
|
|
21
23
|
return sharedPail;
|
|
22
24
|
};
|
|
@@ -69,5 +71,8 @@ const pail = /* @__PURE__ */ new Proxy({}, {
|
|
|
69
71
|
return typeof value === "function" ? value.bind(instance) : value;
|
|
70
72
|
}
|
|
71
73
|
});
|
|
74
|
+
const logStep = (type, message) => {
|
|
75
|
+
getPail()[type](message);
|
|
76
|
+
};
|
|
72
77
|
|
|
73
|
-
export { createLogger, createStderrLogger, getPail, pail };
|
|
78
|
+
export { createLogger, createStderrLogger, getPail, logStep, pail };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from '@visulima/path';
|
|
4
|
+
|
|
5
|
+
const FALLBACK = "pnpm";
|
|
6
|
+
const KNOWN_MANAGERS = ["pnpm", "yarn", "npm", "bun"];
|
|
7
|
+
const INSTALL_PREFERENCE = ["pnpm", "bun", "yarn", "npm"];
|
|
8
|
+
const isManagerInstalled = (manager) => {
|
|
9
|
+
try {
|
|
10
|
+
return spawnSync(manager, ["--version"], { stdio: "ignore", timeout: 5e3 }).status === 0;
|
|
11
|
+
} catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
const detectInstalledManagers = (probe = isManagerInstalled) => INSTALL_PREFERENCE.filter((manager) => probe(manager));
|
|
16
|
+
const installArgsFor = (manager) => {
|
|
17
|
+
return { args: ["install"], command: manager };
|
|
18
|
+
};
|
|
19
|
+
const parseDeclaredManager = (declared) => {
|
|
20
|
+
if (typeof declared !== "string") {
|
|
21
|
+
return void 0;
|
|
22
|
+
}
|
|
23
|
+
return KNOWN_MANAGERS.find((manager) => declared.startsWith(`${manager}@`));
|
|
24
|
+
};
|
|
25
|
+
const readDeclaredManager = (directory) => {
|
|
26
|
+
const candidate = join(directory, "package.json");
|
|
27
|
+
if (!existsSync(candidate)) {
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(readFileSync(candidate, "utf8"));
|
|
32
|
+
return parseDeclaredManager(parsed.packageManager);
|
|
33
|
+
} catch {
|
|
34
|
+
return void 0;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const detectPackageManager = (startDirectory) => {
|
|
38
|
+
let directory = startDirectory;
|
|
39
|
+
while (directory && directory !== dirname(directory)) {
|
|
40
|
+
const declared = readDeclaredManager(directory);
|
|
41
|
+
if (declared !== void 0) {
|
|
42
|
+
return declared;
|
|
43
|
+
}
|
|
44
|
+
directory = dirname(directory);
|
|
45
|
+
}
|
|
46
|
+
return FALLBACK;
|
|
47
|
+
};
|
|
48
|
+
const execArgsFor = (manager, command, args) => {
|
|
49
|
+
if (manager === "yarn") {
|
|
50
|
+
return { args: [command, ...args], command: "yarn" };
|
|
51
|
+
}
|
|
52
|
+
if (manager === "bun") {
|
|
53
|
+
return { args: ["x", command, ...args], command: "bun" };
|
|
54
|
+
}
|
|
55
|
+
if (manager === "npm") {
|
|
56
|
+
return { args: ["--", command, ...args], command: "npx" };
|
|
57
|
+
}
|
|
58
|
+
return { args: ["exec", command, ...args], command: "pnpm" };
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export { detectInstalledManagers as a, detectPackageManager as d, execArgsFor as e, installArgsFor as i };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { quoteIdentifier,
|
|
1
|
+
import { quoteIdentifier, sqlAffinityForKind, frameworkColumnDdl, columnRef, physicalIndexName } from '@lunora/d1/dialect';
|
|
2
2
|
|
|
3
3
|
const validatorKindToSqlType = (kind) => sqlAffinityForKind(kind);
|
|
4
4
|
const renderColumnDefinition = (name, column) => {
|
package/dist/packem_shared/{insertSchemaExtension-BuzF6-t2.mjs → insertSchemaExtension-DAqbfr9Z.mjs}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Project, SyntaxKind } from 'ts-morph';
|
|
1
|
+
import { Project, SyntaxKind, Node } from 'ts-morph';
|
|
2
2
|
|
|
3
3
|
const VALID_JS_IDENTIFIER = /^[A-Za-z_$][\w$]*$/u;
|
|
4
4
|
const startMarker = (key) => `// lunora:add:${key}:start`;
|
|
@@ -12,6 +12,19 @@ const findDefineSchemaCall = (callExpressions) => {
|
|
|
12
12
|
}
|
|
13
13
|
return void 0;
|
|
14
14
|
};
|
|
15
|
+
const outermostChainExpression = (defineSchemaCall) => {
|
|
16
|
+
let node = defineSchemaCall;
|
|
17
|
+
for (let parent = node.getParent(); parent !== void 0; parent = node.getParent()) {
|
|
18
|
+
if (Node.isPropertyAccessExpression(parent) && parent.getExpression() === node) {
|
|
19
|
+
node = parent;
|
|
20
|
+
} else if (Node.isCallExpression(parent) && parent.getExpression() === node) {
|
|
21
|
+
node = parent;
|
|
22
|
+
} else {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return node;
|
|
27
|
+
};
|
|
15
28
|
const insertSchemaExtension = (source, key) => {
|
|
16
29
|
if (!VALID_JS_IDENTIFIER.test(key)) {
|
|
17
30
|
return { ok: false, reason: "invalid-identifier" };
|
|
@@ -33,15 +46,7 @@ const insertSchemaExtension = (source, key) => {
|
|
|
33
46
|
if (tablesArgument?.getKind() !== SyntaxKind.ObjectLiteralExpression) {
|
|
34
47
|
return { ok: false, reason: "non-object-argument" };
|
|
35
48
|
}
|
|
36
|
-
const
|
|
37
|
-
if (!variableDeclaration) {
|
|
38
|
-
return { ok: false, reason: "no-define-schema" };
|
|
39
|
-
}
|
|
40
|
-
const initializer = variableDeclaration.getInitializer();
|
|
41
|
-
if (!initializer) {
|
|
42
|
-
return { ok: false, reason: "no-define-schema" };
|
|
43
|
-
}
|
|
44
|
-
const insertAt = initializer.getEnd();
|
|
49
|
+
const insertAt = outermostChainExpression(defineSchemaCall).getEnd();
|
|
45
50
|
const chainText = `
|
|
46
51
|
${startMarker(key)}
|
|
47
52
|
.extend(${key}.extension)
|