@lunora/cli 1.0.0-alpha.72 → 1.0.0-alpha.74
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/index.d.mts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.mjs +3 -3
- package/dist/packem_chunks/handler.mjs +2 -2
- package/dist/packem_chunks/handler16.mjs +12 -1
- package/dist/packem_chunks/handler17.mjs +1 -1
- package/dist/packem_chunks/runDeployCommand.mjs +12 -1
- package/dist/packem_chunks/runInitCommand.mjs +5 -4
- package/dist/packem_shared/{buildRegistryIndex-CqM5FwGI.mjs → buildRegistryIndex-BS5ig822.mjs} +1 -1
- package/dist/packem_shared/{commands-vnRRkhNE.mjs → commands-CF2YHeFa.mjs} +101 -3
- package/dist/packem_shared/{parseManifest-BBrXCg9V.mjs → parseManifest-Dbp-Q2q3.mjs} +20 -0
- package/dist/packem_shared/runAddCommand-BGvSitq5.mjs +4 -0
- package/dist/packem_shared/{storage-bGfgwOgF.mjs → storage-HRI1N4Ao.mjs} +1 -1
- package/package.json +4 -4
- package/dist/packem_shared/runAddCommand-BCcJzs_k.mjs +0 -4
package/dist/index.d.mts
CHANGED
|
@@ -651,6 +651,13 @@ interface RegistryEnvVariable {
|
|
|
651
651
|
/** A default/example value for non-secret vars. */
|
|
652
652
|
value?: string;
|
|
653
653
|
}
|
|
654
|
+
/** A re-export the item needs injected into the worker entry point (class-B/C only). */
|
|
655
|
+
interface EntrypointReexport {
|
|
656
|
+
/** Optional JS comment placed above the re-export line. */
|
|
657
|
+
comment?: string;
|
|
658
|
+
/** Module specifier (e.g. `"_generated/workflows"` → `export * from "./lunora/_generated/workflows"`). */
|
|
659
|
+
module: string;
|
|
660
|
+
}
|
|
654
661
|
/** The `registry.json` manifest shape. */
|
|
655
662
|
interface RegistryManifest {
|
|
656
663
|
/** wrangler.jsonc additions (best-effort structural edits). */
|
|
@@ -662,6 +669,8 @@ interface RegistryManifest {
|
|
|
662
669
|
devDependencies?: Readonly<Record<string, string>>;
|
|
663
670
|
/** Post-install guidance printed after the item is added (per-item next steps). */
|
|
664
671
|
docs?: string;
|
|
672
|
+
/** Worker-entry re-exports the item needs (class-B/C only). */
|
|
673
|
+
entrypointReexports?: ReadonlyArray<EntrypointReexport>;
|
|
665
674
|
/** Environment variables the item needs; scaffolded into `.dev.vars`. */
|
|
666
675
|
envVars?: ReadonlyArray<RegistryEnvVariable>;
|
|
667
676
|
files: ReadonlyArray<RegistryFile>;
|
package/dist/index.d.ts
CHANGED
|
@@ -651,6 +651,13 @@ interface RegistryEnvVariable {
|
|
|
651
651
|
/** A default/example value for non-secret vars. */
|
|
652
652
|
value?: string;
|
|
653
653
|
}
|
|
654
|
+
/** A re-export the item needs injected into the worker entry point (class-B/C only). */
|
|
655
|
+
interface EntrypointReexport {
|
|
656
|
+
/** Optional JS comment placed above the re-export line. */
|
|
657
|
+
comment?: string;
|
|
658
|
+
/** Module specifier (e.g. `"_generated/workflows"` → `export * from "./lunora/_generated/workflows"`). */
|
|
659
|
+
module: string;
|
|
660
|
+
}
|
|
654
661
|
/** The `registry.json` manifest shape. */
|
|
655
662
|
interface RegistryManifest {
|
|
656
663
|
/** wrangler.jsonc additions (best-effort structural edits). */
|
|
@@ -662,6 +669,8 @@ interface RegistryManifest {
|
|
|
662
669
|
devDependencies?: Readonly<Record<string, string>>;
|
|
663
670
|
/** Post-install guidance printed after the item is added (per-item next steps). */
|
|
664
671
|
docs?: string;
|
|
672
|
+
/** Worker-entry re-exports the item needs (class-B/C only). */
|
|
673
|
+
entrypointReexports?: ReadonlyArray<EntrypointReexport>;
|
|
665
674
|
/** Environment variables the item needs; scaffolded into `.dev.vars`. */
|
|
666
675
|
envVars?: ReadonlyArray<RegistryEnvVariable>;
|
|
667
676
|
files: ReadonlyArray<RegistryFile>;
|
package/dist/index.mjs
CHANGED
|
@@ -13,7 +13,7 @@ export { createLogger, pail } from './packem_shared/createLogger-CIWSHrTL.mjs';
|
|
|
13
13
|
export { diffSnapshots, renderAddColumn, renderCreateIndex, renderCreateTable, renderDropIndex, renderDropTable, renderMigrationFile, validatorKindToSqlType } from './packem_shared/diffSnapshots-BeDvvNiF.mjs';
|
|
14
14
|
export { default as schemaIrToSnapshot } from './packem_shared/schemaIrToSnapshot-DdsljJT-.mjs';
|
|
15
15
|
export { createRecordingSpawner, defaultSpawner } from './packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
|
|
16
|
-
export { default as parseManifest } from './packem_shared/parseManifest-
|
|
16
|
+
export { default as parseManifest } from './packem_shared/parseManifest-Dbp-Q2q3.mjs';
|
|
17
17
|
export { REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, validateWranglerProject as validateWrangler, validateWranglerConfig } from '@lunora/config';
|
|
18
|
-
export { buildRegistryIndex } from './packem_shared/buildRegistryIndex-
|
|
19
|
-
export { r as runAddCommand, a as runBuildIndexCommand, b as runRegistryViewCommand } from './packem_shared/commands-
|
|
18
|
+
export { buildRegistryIndex } from './packem_shared/buildRegistryIndex-BS5ig822.mjs';
|
|
19
|
+
export { r as runAddCommand, a as runBuildIndexCommand, b as runRegistryViewCommand } from './packem_shared/commands-CF2YHeFa.mjs';
|
|
@@ -4,8 +4,8 @@ import { join, basename } from '@visulima/path';
|
|
|
4
4
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
5
5
|
import { v as validateOutputFormat, i as isJsonFormat, p as printJson, l as loggerForFormat } from '../packem_shared/output-format-B4642rjE.mjs';
|
|
6
6
|
import { t as tuiText, a as tuiSelect } from '../packem_shared/tui-prompts-BjEN8XgP.mjs';
|
|
7
|
-
import { n as normalizeFeature, E as EMAIL_ITEM, s as sanitizeBucketName, d as deriveBucketName, p as promptBucketName, r as resolveTypedDestination, M as MAIL_DESTINATION_PROMPT, a as sanitizeDatabaseName, b as deriveDatabaseName, c as promptDatabaseName, D as DEFAULT_AUTH_ITEM, e as promptAuthProvider, A as AUTH_PROVIDER_OPTIONS, w as withStorageBucketName, f as withMailDestination, g as withAuthDatabaseName } from '../packem_shared/storage-
|
|
8
|
-
import { r as runAddCommand } from '../packem_shared/commands-
|
|
7
|
+
import { n as normalizeFeature, E as EMAIL_ITEM, s as sanitizeBucketName, d as deriveBucketName, p as promptBucketName, r as resolveTypedDestination, M as MAIL_DESTINATION_PROMPT, a as sanitizeDatabaseName, b as deriveDatabaseName, c as promptDatabaseName, D as DEFAULT_AUTH_ITEM, e as promptAuthProvider, A as AUTH_PROVIDER_OPTIONS, w as withStorageBucketName, f as withMailDestination, g as withAuthDatabaseName } from '../packem_shared/storage-HRI1N4Ao.mjs';
|
|
8
|
+
import { r as runAddCommand } from '../packem_shared/commands-CF2YHeFa.mjs';
|
|
9
9
|
|
|
10
10
|
const providerToItem = (provider) => {
|
|
11
11
|
const value = provider.trim().toLowerCase();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { runCodegen } from '@lunora/codegen';
|
|
2
|
-
import { validateWranglerProject, inferLunoraBindings, reconcileWranglerBindings } from '@lunora/config';
|
|
2
|
+
import { validateWranglerProject, inferLunoraBindings, reconcileWranglerBindings, reconcileWranglerCompatibilityDate } from '@lunora/config';
|
|
3
3
|
import { p as parseApiSpec } from '../packem_shared/api-spec-Bx0iKbxA.mjs';
|
|
4
4
|
import { r as renderCodegenFailure } from '../packem_shared/codegen-error-DJG-ghs_.mjs';
|
|
5
5
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
@@ -19,6 +19,17 @@ const provisionBindings = async (cwd, logger) => {
|
|
|
19
19
|
const message = error instanceof Error ? error.message : String(error);
|
|
20
20
|
logger.warn(`binding inference skipped: ${message}`);
|
|
21
21
|
}
|
|
22
|
+
try {
|
|
23
|
+
const reconciled = reconcileWranglerCompatibilityDate(cwd);
|
|
24
|
+
if (reconciled.changed) {
|
|
25
|
+
logger.success(
|
|
26
|
+
`bumped compatibility_date to ${reconciled.date ?? "unknown"} (Workers Cache enabled) → ${reconciled.wranglerPath ?? "wrangler.jsonc"}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
} catch (error) {
|
|
30
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
31
|
+
logger.warn(`compatibility date sync skipped: ${message}`);
|
|
32
|
+
}
|
|
22
33
|
};
|
|
23
34
|
const runPrepareCommand = async (options) => {
|
|
24
35
|
const cwd = options.cwd ?? process.cwd();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
2
|
-
import { r as runAddCommand, b as runRegistryViewCommand, a as runBuildIndexCommand } from '../packem_shared/commands-
|
|
2
|
+
import { r as runAddCommand, b as runRegistryViewCommand, a as runBuildIndexCommand } from '../packem_shared/commands-CF2YHeFa.mjs';
|
|
3
3
|
|
|
4
4
|
const execute = defineHandler(({ argument, cwd, logger, options }) => {
|
|
5
5
|
const subcommand = argument[0];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { runCodegen, discoverMigrations } from '@lunora/codegen';
|
|
3
|
-
import { readLinkedProject, writeLinkedProject, validateWranglerProject, inferLunoraBindings, reconcileWranglerBindings, DEV_VARS_FILE, parseDevVariableEntries, isMintableSecretKey, findWranglerFile, readWranglerJsonc, discoverContainerInfo, packageNamesFromBindings, requiredSecrets, generateSecretValue } from '@lunora/config';
|
|
3
|
+
import { readLinkedProject, writeLinkedProject, validateWranglerProject, inferLunoraBindings, reconcileWranglerBindings, reconcileWranglerCompatibilityDate, DEV_VARS_FILE, parseDevVariableEntries, isMintableSecretKey, findWranglerFile, readWranglerJsonc, discoverContainerInfo, packageNamesFromBindings, requiredSecrets, generateSecretValue } from '@lunora/config';
|
|
4
4
|
import { join } from '@visulima/path';
|
|
5
5
|
import { Spinner } from '@visulima/spinner';
|
|
6
6
|
import { Project } from 'ts-morph';
|
|
@@ -195,6 +195,17 @@ const provisionBindings = async (cwd, logger) => {
|
|
|
195
195
|
const message = error instanceof Error ? error.message : String(error);
|
|
196
196
|
logger.warn(`binding inference skipped: ${message}`);
|
|
197
197
|
}
|
|
198
|
+
try {
|
|
199
|
+
const reconciled = reconcileWranglerCompatibilityDate(cwd);
|
|
200
|
+
if (reconciled.changed) {
|
|
201
|
+
logger.success(
|
|
202
|
+
`bumped compatibility_date to ${reconciled.date ?? "unknown"} (Workers Cache enabled) → ${reconciled.wranglerPath ?? "wrangler.jsonc"}`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
} catch (error) {
|
|
206
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
207
|
+
logger.warn(`compatibility date sync skipped: ${message}`);
|
|
208
|
+
}
|
|
198
209
|
};
|
|
199
210
|
const warnDevVariablesNotPushed = (cwd, logger) => {
|
|
200
211
|
const devVariablesPath = join(cwd, DEV_VARS_FILE);
|
|
@@ -11,11 +11,11 @@ import { d as detectPackageManager, a as detectInstalledManagers, i as installAr
|
|
|
11
11
|
import MagicString from 'magic-string';
|
|
12
12
|
import { Project, SyntaxKind } from 'ts-morph';
|
|
13
13
|
import { P as PromptCancelledError } from '../packem_shared/prompt-cancelled-APzX1Im-.mjs';
|
|
14
|
-
import { c as resolveTagVersions, d as resolveSourceRef, e as resolvePinnedSourceRef, f as resolveDistTag, r as runAddCommand } from '../packem_shared/commands-
|
|
14
|
+
import { c as resolveTagVersions, d as resolveSourceRef, e as resolvePinnedSourceRef, f as resolveDistTag, r as runAddCommand } from '../packem_shared/commands-CF2YHeFa.mjs';
|
|
15
15
|
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
|
|
16
16
|
import { d as tuiMascot, e as tuiStep, f as tuiMoonrise, t as tuiText, g as tuiHeadline, h as tuiInfo, a as tuiSelect, b as tuiConfirm, w as withTuiSpinner, i as tuiNextSteps, j as tuiTasks, k as tuiMultiSelect, l as withTuiBadgeProgress } from '../packem_shared/tui-prompts-BjEN8XgP.mjs';
|
|
17
17
|
import { logStep } from '../packem_shared/createLogger-CIWSHrTL.mjs';
|
|
18
|
-
import { E as EMAIL_ITEM, p as promptBucketName, w as withStorageBucketName, M as MAIL_DESTINATION_PROMPT, r as resolveTypedDestination, f as withMailDestination, e as promptAuthProvider, c as promptDatabaseName, g as withAuthDatabaseName } from '../packem_shared/storage-
|
|
18
|
+
import { E as EMAIL_ITEM, p as promptBucketName, w as withStorageBucketName, M as MAIL_DESTINATION_PROMPT, r as resolveTypedDestination, f as withMailDestination, e as promptAuthProvider, c as promptDatabaseName, g as withAuthDatabaseName } from '../packem_shared/storage-HRI1N4Ao.mjs';
|
|
19
19
|
import dns from 'node:dns/promises';
|
|
20
20
|
|
|
21
21
|
const GITHUB_CONTENT = `name: Deploy
|
|
@@ -1819,6 +1819,7 @@ const stampLunoraDeps = (packageJsonText, distTag, versions) => {
|
|
|
1819
1819
|
const PNPM_BUILT_DEPENDENCIES = [
|
|
1820
1820
|
"@parcel/watcher",
|
|
1821
1821
|
"esbuild",
|
|
1822
|
+
"lmdb",
|
|
1822
1823
|
"msgpackr-extract",
|
|
1823
1824
|
"rs-module-lexer",
|
|
1824
1825
|
"sharp",
|
|
@@ -1833,8 +1834,8 @@ const pnpmWorkspaceYaml = () => [
|
|
|
1833
1834
|
"# without the interactive `pnpm approve-builds` step; deny the optional native",
|
|
1834
1835
|
"# builds a scaffold doesn't need (so no C/C++ toolchain is required).",
|
|
1835
1836
|
"allowBuilds:",
|
|
1836
|
-
...PNPM_BUILT_DEPENDENCIES.map((name) => ` ${name}: true`),
|
|
1837
|
-
...PNPM_DENIED_BUILD_DEPENDENCIES.map((name) => ` ${name}: false`),
|
|
1837
|
+
...PNPM_BUILT_DEPENDENCIES.map((name) => ` '${name}': true`),
|
|
1838
|
+
...PNPM_DENIED_BUILD_DEPENDENCIES.map((name) => ` '${name}': false`),
|
|
1838
1839
|
""
|
|
1839
1840
|
].join("\n");
|
|
1840
1841
|
const collectFiles = (directory) => {
|
package/dist/packem_shared/{buildRegistryIndex-CqM5FwGI.mjs → buildRegistryIndex-BS5ig822.mjs}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
2
2
|
import { join } from '@visulima/path';
|
|
3
|
-
import parseManifest from './parseManifest-
|
|
3
|
+
import parseManifest from './parseManifest-Dbp-Q2q3.mjs';
|
|
4
4
|
|
|
5
5
|
const CONTROL_CHARS = /[\u0000-\u001F\u007F-\u009F]/gu;
|
|
6
6
|
const stripControlChars = (value) => value === void 0 ? void 0 : value.replaceAll(CONTROL_CHARS, "");
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync, mkdirSync, mkdtempSync, rmSync } from 'node:fs';
|
|
2
|
-
import { dirname, join } from '@visulima/path';
|
|
2
|
+
import { dirname, join, relative } 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
6
|
import { LunoraError } from '@lunora/errors';
|
|
7
7
|
import { b as tuiConfirm } from './tui-prompts-BjEN8XgP.mjs';
|
|
8
|
-
import { collectCatalog, buildRegistryIndex } from './buildRegistryIndex-
|
|
8
|
+
import { collectCatalog, buildRegistryIndex } from './buildRegistryIndex-BS5ig822.mjs';
|
|
9
9
|
import { insertSchemaExtension } from './insertSchemaExtension-DAqbfr9Z.mjs';
|
|
10
10
|
import { createHash } from 'node:crypto';
|
|
11
11
|
import { tmpdir } from 'node:os';
|
|
12
12
|
import { downloadTemplate } from 'giget';
|
|
13
|
-
import parseManifest from './parseManifest-
|
|
13
|
+
import parseManifest from './parseManifest-Dbp-Q2q3.mjs';
|
|
14
14
|
|
|
15
15
|
const DEFAULT_SOURCE_REF_FALLBACK = "alpha";
|
|
16
16
|
const STABLE_BRANCH = "main";
|
|
@@ -522,6 +522,93 @@ const reconcileFile = (file, itemKey, itemDirectory, projectRoot, logger, lock,
|
|
|
522
522
|
}
|
|
523
523
|
return reconcileWholeFile(file, itemKey, itemDirectory, projectRoot, logger, lock, reconcileOptions, useUmbrella);
|
|
524
524
|
};
|
|
525
|
+
const WORKER_ENTRY_FALLBACKS = ["src/server.ts", "src/server/index.ts", "src/index.ts", "src/worker.ts"];
|
|
526
|
+
const WRANGLER_MAIN_RE = /"main"\s*:\s*"([^"]+)"/u;
|
|
527
|
+
const readWranglerMain = (projectRoot) => {
|
|
528
|
+
for (const file of ["wrangler.jsonc", "wrangler.json"]) {
|
|
529
|
+
const path = join(projectRoot, file);
|
|
530
|
+
if (!existsSync(path)) {
|
|
531
|
+
continue;
|
|
532
|
+
}
|
|
533
|
+
const match = WRANGLER_MAIN_RE.exec(readFileSync(path, "utf8"));
|
|
534
|
+
if (match?.[1]) {
|
|
535
|
+
return match[1];
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return void 0;
|
|
539
|
+
};
|
|
540
|
+
const findWorkerEntry = (projectRoot) => {
|
|
541
|
+
const main = readWranglerMain(projectRoot);
|
|
542
|
+
const candidates = main === void 0 ? WORKER_ENTRY_FALLBACKS : [main, ...WORKER_ENTRY_FALLBACKS];
|
|
543
|
+
for (const candidate of candidates) {
|
|
544
|
+
const absolute = join(projectRoot, candidate);
|
|
545
|
+
if (!existsSync(absolute)) {
|
|
546
|
+
continue;
|
|
547
|
+
}
|
|
548
|
+
const content = readFileSync(absolute, "utf8");
|
|
549
|
+
if (!content.includes("createShardDO(")) {
|
|
550
|
+
break;
|
|
551
|
+
}
|
|
552
|
+
return { entryPath: absolute, main: candidate, source: content };
|
|
553
|
+
}
|
|
554
|
+
return void 0;
|
|
555
|
+
};
|
|
556
|
+
const computeRelativeSpecifier = (entryPath, projectRoot, moduleName) => {
|
|
557
|
+
const importPath = relative(dirname(entryPath), join(projectRoot, "lunora", moduleName)).replaceAll("\\", "/");
|
|
558
|
+
return importPath.startsWith(".") ? importPath : `./${importPath}`;
|
|
559
|
+
};
|
|
560
|
+
const logClassAFallback = (entrypointReexports, logger) => {
|
|
561
|
+
for (const reexport of entrypointReexports) {
|
|
562
|
+
const specifier = `./lunora/${reexport.module}.js`;
|
|
563
|
+
const instruction = `Add \`export * from "${specifier}"\` to your worker entry`;
|
|
564
|
+
const suffix = reexport.comment ? ` (${reexport.comment})` : "";
|
|
565
|
+
logger.warn(`${instruction}${suffix}`);
|
|
566
|
+
}
|
|
567
|
+
return 0;
|
|
568
|
+
};
|
|
569
|
+
const buildReexportLines = (entrypointReexports, entryPath, projectRoot, source) => {
|
|
570
|
+
const lines = [];
|
|
571
|
+
for (const reexport of entrypointReexports) {
|
|
572
|
+
const specifier = computeRelativeSpecifier(entryPath, projectRoot, reexport.module);
|
|
573
|
+
const escapedSpecifier = specifier.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
|
|
574
|
+
const existingRe = new RegExp(String.raw`export\s+\*\s+from\s+["']${escapedSpecifier}\.js["']`, "u");
|
|
575
|
+
if (existingRe.test(source)) {
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
if (reexport.comment) {
|
|
579
|
+
lines.push(`
|
|
580
|
+
// ${reexport.comment}`);
|
|
581
|
+
}
|
|
582
|
+
lines.push(`export * from "${specifier}.js";`);
|
|
583
|
+
}
|
|
584
|
+
return lines;
|
|
585
|
+
};
|
|
586
|
+
const applyEntrypointReexports = (entrypointReexports, projectRoot, logger, diff) => {
|
|
587
|
+
if (entrypointReexports.length === 0) {
|
|
588
|
+
return 0;
|
|
589
|
+
}
|
|
590
|
+
const entry = findWorkerEntry(projectRoot);
|
|
591
|
+
if (entry === void 0) {
|
|
592
|
+
return logClassAFallback(entrypointReexports, logger);
|
|
593
|
+
}
|
|
594
|
+
const linesToAppend = buildReexportLines(entrypointReexports, entry.entryPath, projectRoot, entry.source);
|
|
595
|
+
if (linesToAppend.length === 0) {
|
|
596
|
+
return 0;
|
|
597
|
+
}
|
|
598
|
+
if (diff) {
|
|
599
|
+
for (const line of linesToAppend) {
|
|
600
|
+
if (line !== "") {
|
|
601
|
+
logger.info(`~ entrypoint: ${line}`);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
return linesToAppend.length;
|
|
605
|
+
}
|
|
606
|
+
const separator = entry.source.endsWith("\n") ? "" : "\n";
|
|
607
|
+
writeFileSync(entry.entryPath, `${entry.source}${separator}${linesToAppend.join("\n")}
|
|
608
|
+
`, "utf8");
|
|
609
|
+
logger.success(`wrote ${String(linesToAppend.length)} entrypoint re-export(s) to ${relative(projectRoot, entry.entryPath)}`);
|
|
610
|
+
return linesToAppend.length;
|
|
611
|
+
};
|
|
525
612
|
const reconcileItems = (items, cwd, logger, reconcileOptions = {}) => {
|
|
526
613
|
const written = [];
|
|
527
614
|
const skipped = [];
|
|
@@ -534,6 +621,9 @@ const reconcileItems = (items, cwd, logger, reconcileOptions = {}) => {
|
|
|
534
621
|
const outcome = reconcileFile(file, manifest.name, directory, cwd, logger, lock, reconcileOptions, useUmbrella);
|
|
535
622
|
(outcome.kind === "written" ? written : skipped).push(outcome.path);
|
|
536
623
|
}
|
|
624
|
+
if (manifest.entrypointReexports !== void 0) {
|
|
625
|
+
applyEntrypointReexports(manifest.entrypointReexports, cwd, logger, reconcileOptions.diff === true);
|
|
626
|
+
}
|
|
537
627
|
if (reconcileOptions.diff) {
|
|
538
628
|
continue;
|
|
539
629
|
}
|
|
@@ -707,6 +797,11 @@ const printPlan = (logger, manifest) => {
|
|
|
707
797
|
const valueSuffix = variable.secret ? " (secret)" : ` = ${JSON.stringify(variable.value ?? "")}`;
|
|
708
798
|
logger.info(` env ${variable.name}${valueSuffix}`);
|
|
709
799
|
}
|
|
800
|
+
for (const reexport of manifest.entrypointReexports ?? []) {
|
|
801
|
+
const specifier = `./lunora/${reexport.module}`;
|
|
802
|
+
const suffix = reexport.comment ? ` // ${reexport.comment}` : "";
|
|
803
|
+
logger.info(` entry ${specifier}${suffix}`);
|
|
804
|
+
}
|
|
710
805
|
};
|
|
711
806
|
const printJsonPlan = (items) => {
|
|
712
807
|
const planSnapshot = items.map(({ manifest }) => {
|
|
@@ -718,6 +813,9 @@ const printJsonPlan = (items) => {
|
|
|
718
813
|
}),
|
|
719
814
|
deps: Object.keys(manifest.deps ?? {}),
|
|
720
815
|
devDependencies: Object.keys(manifest.devDependencies ?? {}),
|
|
816
|
+
entrypointReexports: (manifest.entrypointReexports ?? []).map((reexport) => {
|
|
817
|
+
return { module: reexport.module, ...reexport.comment ? { comment: reexport.comment } : {} };
|
|
818
|
+
}),
|
|
721
819
|
envVars: (manifest.envVars ?? []).map((variable) => {
|
|
722
820
|
return { name: variable.name, ...variable.secret ? { secret: true } : { value: variable.value ?? "" } };
|
|
723
821
|
}),
|
|
@@ -3,6 +3,7 @@ import { LunoraError } from '@lunora/errors';
|
|
|
3
3
|
const NEWLINE_PRESENT = /[\r\n]/u;
|
|
4
4
|
const VALID_ENV_NAME = /^[A-Za-z_]\w*$/u;
|
|
5
5
|
const VALID_ITEM_NAME = /^[A-Za-z0-9][\w-]*$/u;
|
|
6
|
+
const VALID_MODULE_PATH = /^[\w.-]+(?:\/[\w.-]+)*$/u;
|
|
6
7
|
const parseManifest = (raw, itemName) => {
|
|
7
8
|
if (typeof raw !== "object" || raw === null) {
|
|
8
9
|
throw new LunoraError("INTERNAL", `registry.json for "${itemName}" is not an object`);
|
|
@@ -60,6 +61,24 @@ const parseManifest = (raw, itemName) => {
|
|
|
60
61
|
const bindingRecord = value;
|
|
61
62
|
return Array.isArray(bindingRecord.path) && bindingRecord.path.every((segment) => typeof segment === "string");
|
|
62
63
|
}) : void 0;
|
|
64
|
+
const entrypointReexports = Array.isArray(record.entrypointReexports) ? record.entrypointReexports.filter(
|
|
65
|
+
(value) => typeof value === "object" && value !== null && typeof value.module === "string"
|
|
66
|
+
).map((entry) => {
|
|
67
|
+
if (entry.module.includes("..") || entry.module.startsWith("/") || !VALID_MODULE_PATH.test(entry.module)) {
|
|
68
|
+
throw new LunoraError(
|
|
69
|
+
"INTERNAL",
|
|
70
|
+
`registry.json "${itemName}": entrypointReexports[].module "${entry.module}" must be a safe relative module path without path traversal or unsafe characters`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
const reexport = { module: entry.module };
|
|
74
|
+
if (typeof entry.comment === "string") {
|
|
75
|
+
if (NEWLINE_PRESENT.test(entry.comment)) {
|
|
76
|
+
throw new LunoraError("INTERNAL", `registry.json "${itemName}": entrypointReexports[].comment must not contain a newline`);
|
|
77
|
+
}
|
|
78
|
+
reexport.comment = entry.comment;
|
|
79
|
+
}
|
|
80
|
+
return reexport;
|
|
81
|
+
}) : void 0;
|
|
63
82
|
const envVariables = Array.isArray(record.envVars) ? record.envVars.filter(
|
|
64
83
|
(value) => typeof value === "object" && value !== null && typeof value.name === "string"
|
|
65
84
|
).map((entry) => {
|
|
@@ -90,6 +109,7 @@ const parseManifest = (raw, itemName) => {
|
|
|
90
109
|
description: typeof record.description === "string" ? record.description : void 0,
|
|
91
110
|
devDependencies,
|
|
92
111
|
docs: typeof record.docs === "string" ? record.docs : void 0,
|
|
112
|
+
entrypointReexports,
|
|
93
113
|
envVars: envVariables,
|
|
94
114
|
files,
|
|
95
115
|
name,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/cli",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.74",
|
|
4
4
|
"description": "The Lunora CLI: init, dev, deploy, codegen, run, reset, and migrate commands",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
|
@@ -52,12 +52,12 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@bomb.sh/tab": "0.0.16",
|
|
55
|
-
"@lunora/codegen": "1.0.0-alpha.
|
|
56
|
-
"@lunora/config": "1.0.0-alpha.
|
|
55
|
+
"@lunora/codegen": "1.0.0-alpha.36",
|
|
56
|
+
"@lunora/config": "1.0.0-alpha.58",
|
|
57
57
|
"@lunora/container": "1.0.0-alpha.7",
|
|
58
58
|
"@lunora/d1": "1.0.0-alpha.24",
|
|
59
59
|
"@lunora/errors": "1.0.0-alpha.2",
|
|
60
|
-
"@lunora/seed": "1.0.0-alpha.
|
|
60
|
+
"@lunora/seed": "1.0.0-alpha.18",
|
|
61
61
|
"@visulima/cerebro": "3.0.0-alpha.32",
|
|
62
62
|
"@visulima/error": "6.0.0-alpha.34",
|
|
63
63
|
"@visulima/fs": "5.0.0-alpha.32",
|