@lunora/cli 1.0.0-alpha.3 → 1.0.0-alpha.4
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.mjs +1 -1
- package/dist/packem_chunks/handler.mjs +1 -1
- package/dist/packem_chunks/handler16.mjs +1 -1
- package/dist/packem_chunks/runInitCommand.mjs +39 -3
- package/dist/packem_shared/{commands-DIQ3nf0C.mjs → commands-SUPdjsu5.mjs} +61 -17
- package/dist/packem_shared/runAddCommand-Txwh1Xw1.mjs +4 -0
- package/package.json +1 -1
- package/dist/packem_shared/runAddCommand-3I3JFZUG.mjs +0 -4
package/dist/index.mjs
CHANGED
|
@@ -16,4 +16,4 @@ export { createRecordingSpawner, defaultSpawner } from './packem_shared/defaultS
|
|
|
16
16
|
export { default as parseManifest } from './packem_shared/parseManifest--vZf2FY1.mjs';
|
|
17
17
|
export { REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, validateWranglerProject as validateWrangler, validateWranglerConfig } from '@lunora/config';
|
|
18
18
|
export { buildRegistryIndex } from './packem_shared/buildRegistryIndex-BcYe607_.mjs';
|
|
19
|
-
export { r as runAddCommand, a as runBuildIndexCommand, b as runRegistryViewCommand } from './packem_shared/commands-
|
|
19
|
+
export { r as runAddCommand, a as runBuildIndexCommand, b as runRegistryViewCommand } from './packem_shared/commands-SUPdjsu5.mjs';
|
|
@@ -3,7 +3,7 @@ import { findWranglerFile, promptSelect } from '@lunora/config';
|
|
|
3
3
|
import { join } from '@visulima/path';
|
|
4
4
|
import { d as defineHandler } from '../packem_shared/command-BDXcJCCJ.mjs';
|
|
5
5
|
import { n as normalizeFeature, E as EMAIL_ITEM, D as DEFAULT_AUTH_ITEM, p as promptAuthProvider, A as AUTH_PROVIDER_OPTIONS } from '../packem_shared/features-ocSSpZtS.mjs';
|
|
6
|
-
import { r as runAddCommand } from '../packem_shared/commands-
|
|
6
|
+
import { r as runAddCommand } from '../packem_shared/commands-SUPdjsu5.mjs';
|
|
7
7
|
|
|
8
8
|
const providerToItem = (provider) => {
|
|
9
9
|
const value = provider.trim().toLowerCase();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as defineHandler } from '../packem_shared/command-BDXcJCCJ.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-SUPdjsu5.mjs';
|
|
3
3
|
|
|
4
4
|
const execute = defineHandler(({ argument, cwd, logger, options }) => {
|
|
5
5
|
const subcommand = argument[0];
|
|
@@ -2,13 +2,14 @@ import { existsSync, mkdirSync, writeFileSync, readdirSync, mkdtempSync, rmSync,
|
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import { detectFramework as detectFramework$1, isInteractive, promptSelect, promptMultiSelect } from '@lunora/config';
|
|
4
4
|
import { walkSync } from '@visulima/fs';
|
|
5
|
-
import { resolve, join as join$1, relative, dirname as dirname$1 } from '@visulima/path';
|
|
5
|
+
import { resolve, join as join$1, relative, dirname as dirname$1, basename } from '@visulima/path';
|
|
6
6
|
import { downloadTemplate } from 'giget';
|
|
7
|
+
import { modify, applyEdits } from 'jsonc-parser';
|
|
7
8
|
import { join, dirname } from 'node:path';
|
|
8
9
|
import { d as defineHandler } from '../packem_shared/command-BDXcJCCJ.mjs';
|
|
9
10
|
import MagicString from 'magic-string';
|
|
10
11
|
import { Project, SyntaxKind } from 'ts-morph';
|
|
11
|
-
import { c as resolveSourceRef, r as runAddCommand } from '../packem_shared/commands-
|
|
12
|
+
import { c as resolveSourceRef, d as resolveDistTag, r as runAddCommand } from '../packem_shared/commands-SUPdjsu5.mjs';
|
|
12
13
|
import { p as promptAuthProvider, E as EMAIL_ITEM } from '../packem_shared/features-ocSSpZtS.mjs';
|
|
13
14
|
|
|
14
15
|
const GITHUB_CONTENT = `name: Deploy
|
|
@@ -19,6 +20,10 @@ on:
|
|
|
19
20
|
pull_request:
|
|
20
21
|
workflow_dispatch:
|
|
21
22
|
|
|
23
|
+
# Prerequisite: commit your pnpm-lock.yaml. \`pnpm install --frozen-lockfile\`
|
|
24
|
+
# (below) and the pnpm cache both require it — run \`pnpm install\` locally and
|
|
25
|
+
# commit the lockfile before pushing, or the first CI run fails.
|
|
26
|
+
#
|
|
22
27
|
# Set these repository secrets (Settings → Secrets and variables → Actions):
|
|
23
28
|
# CLOUDFLARE_API_TOKEN — a Workers-scoped API token
|
|
24
29
|
# CLOUDFLARE_ACCOUNT_ID — your Cloudflare account id
|
|
@@ -65,6 +70,10 @@ jobs:
|
|
|
65
70
|
const GITLAB_CONTENT = `stages:
|
|
66
71
|
- deploy
|
|
67
72
|
|
|
73
|
+
# Prerequisite: commit your pnpm-lock.yaml. \`pnpm install --frozen-lockfile\`
|
|
74
|
+
# (below) requires it — run \`pnpm install\` locally and commit the lockfile
|
|
75
|
+
# before pushing, or the first pipeline fails.
|
|
76
|
+
#
|
|
68
77
|
# Set these as masked CI/CD variables (Settings → CI/CD → Variables):
|
|
69
78
|
# CLOUDFLARE_API_TOKEN — a Workers-scoped API token
|
|
70
79
|
# CLOUDFLARE_ACCOUNT_ID — your Cloudflare account id
|
|
@@ -126,6 +135,9 @@ const scaffoldCiWorkflow = (projectRoot, provider, logger, options = {}) => {
|
|
|
126
135
|
} else {
|
|
127
136
|
logger.success(`--ci ${provider}: wrote ${spec.file}`);
|
|
128
137
|
logger.info(`--ci ${provider}: set CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID as ${spec.secretsHint} to enable deploys.`);
|
|
138
|
+
logger.info(
|
|
139
|
+
`--ci ${provider}: run \`pnpm install\` and commit pnpm-lock.yaml before pushing — the pipeline runs \`pnpm install --frozen-lockfile\`.`
|
|
140
|
+
);
|
|
129
141
|
}
|
|
130
142
|
return result;
|
|
131
143
|
} catch (error) {
|
|
@@ -331,6 +343,26 @@ const isTextFile = (filePath) => {
|
|
|
331
343
|
return TEXT_EXTENSIONS.has(filePath.slice(lastDot));
|
|
332
344
|
};
|
|
333
345
|
const substitute = (content, name) => content.replaceAll("{{name}}", name);
|
|
346
|
+
const isLunoraDep = (name) => name === "lunorash" || name.startsWith("@lunora/");
|
|
347
|
+
const stampLunoraDeps = (packageJsonText, distTag) => {
|
|
348
|
+
let parsed;
|
|
349
|
+
try {
|
|
350
|
+
parsed = JSON.parse(packageJsonText);
|
|
351
|
+
} catch {
|
|
352
|
+
return packageJsonText;
|
|
353
|
+
}
|
|
354
|
+
let text = packageJsonText;
|
|
355
|
+
for (const section of ["dependencies", "devDependencies"]) {
|
|
356
|
+
for (const name of Object.keys(parsed[section] ?? {})) {
|
|
357
|
+
if (!isLunoraDep(name)) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
const edits = modify(text, [section, name], distTag, { formattingOptions: { insertSpaces: true, tabSize: 4 } });
|
|
361
|
+
text = applyEdits(text, edits);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return text;
|
|
365
|
+
};
|
|
334
366
|
const collectFiles = (directory) => {
|
|
335
367
|
const out = [];
|
|
336
368
|
for (const entry of walkSync(directory, { includeDirs: false, includeFiles: true })) {
|
|
@@ -341,12 +373,16 @@ const collectFiles = (directory) => {
|
|
|
341
373
|
const copyTemplate = (sourceDirectory, target, name) => {
|
|
342
374
|
const files = collectFiles(sourceDirectory);
|
|
343
375
|
const written = [];
|
|
376
|
+
const distTag = resolveDistTag();
|
|
344
377
|
for (const source of files) {
|
|
345
378
|
const relativePath = relative(sourceDirectory, source);
|
|
346
379
|
const destination = join$1(target, relativePath);
|
|
347
380
|
mkdirSync(dirname$1(destination), { recursive: true });
|
|
348
381
|
const raw = readFileSync(source);
|
|
349
|
-
|
|
382
|
+
let text = isTextFile(source) ? substitute(raw.toString("utf8"), name) : void 0;
|
|
383
|
+
if (text !== void 0 && basename(source) === "package.json") {
|
|
384
|
+
text = stampLunoraDeps(text, distTag);
|
|
385
|
+
}
|
|
350
386
|
if (text === void 0) {
|
|
351
387
|
writeFileSync(destination, raw);
|
|
352
388
|
} else {
|
|
@@ -2,12 +2,12 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync, mkdtempSync, rmSync
|
|
|
2
2
|
import { dirname, join } from '@visulima/path';
|
|
3
3
|
import { DEV_VARS_FILE, parseDevVariableEntries, promptYesNo } from '@lunora/config';
|
|
4
4
|
import { modify, applyEdits, parse } from 'jsonc-parser';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
5
6
|
import { collectCatalog, buildRegistryIndex } from './buildRegistryIndex-BcYe607_.mjs';
|
|
6
7
|
import { insertSchemaExtension } from './insertSchemaExtension-BuzF6-t2.mjs';
|
|
7
8
|
import { createHash } from 'node:crypto';
|
|
8
9
|
import { tmpdir } from 'node:os';
|
|
9
10
|
import { downloadTemplate } from 'giget';
|
|
10
|
-
import { fileURLToPath } from 'node:url';
|
|
11
11
|
import parseManifest from './parseManifest--vZf2FY1.mjs';
|
|
12
12
|
|
|
13
13
|
const DEFAULT_SOURCE_REF_FALLBACK = "alpha";
|
|
@@ -59,8 +59,38 @@ const resolveSourceRef = (ref) => {
|
|
|
59
59
|
}
|
|
60
60
|
return resolveVersionRef(resolveCliVersion());
|
|
61
61
|
};
|
|
62
|
+
const STABLE_DIST_TAG = "latest";
|
|
63
|
+
const resolveDistTag = () => {
|
|
64
|
+
const ref = resolveVersionRef(resolveCliVersion());
|
|
65
|
+
return ref === STABLE_BRANCH ? STABLE_DIST_TAG : ref;
|
|
66
|
+
};
|
|
62
67
|
|
|
63
|
-
const
|
|
68
|
+
const resolveDepRange = (range) => {
|
|
69
|
+
if (!range.startsWith("workspace:")) {
|
|
70
|
+
return range;
|
|
71
|
+
}
|
|
72
|
+
const rest = range.slice("workspace:".length);
|
|
73
|
+
if (rest === "" || rest === "*" || rest === "^" || rest === "~") {
|
|
74
|
+
return resolveDistTag();
|
|
75
|
+
}
|
|
76
|
+
return rest;
|
|
77
|
+
};
|
|
78
|
+
const UMBRELLA_REEXPORTED_DEPS = /* @__PURE__ */ new Set(["@lunora/client", "@lunora/do", "@lunora/runtime", "@lunora/server", "@lunora/values"]);
|
|
79
|
+
const UMBRELLA_IMPORT_RE = /(['"])@lunora\/(client|do|runtime|server|values)(\/[^'"]*)?\1/gu;
|
|
80
|
+
const projectUsesUmbrella = (projectRoot) => {
|
|
81
|
+
const packageJsonPath = join(projectRoot, "package.json");
|
|
82
|
+
if (!existsSync(packageJsonPath)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
87
|
+
return parsed.dependencies?.lunorash !== void 0 || parsed.devDependencies?.lunorash !== void 0;
|
|
88
|
+
} catch {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const rewriteUmbrellaImports = (source) => source.replaceAll(UMBRELLA_IMPORT_RE, (_match, quote, base, subpath) => `${quote}lunorash/${base}${subpath ?? ""}${quote}`);
|
|
93
|
+
const applyDeps = (deps, projectRoot, logger, section = "dependencies", useUmbrella = false) => {
|
|
64
94
|
const entries = Object.entries(deps);
|
|
65
95
|
if (entries.length === 0) {
|
|
66
96
|
return [];
|
|
@@ -74,11 +104,15 @@ const applyDeps = (deps, projectRoot, logger, section = "dependencies") => {
|
|
|
74
104
|
const parsed = JSON.parse(text);
|
|
75
105
|
const added = [];
|
|
76
106
|
for (const [name, range] of entries) {
|
|
107
|
+
if (useUmbrella && UMBRELLA_REEXPORTED_DEPS.has(name)) {
|
|
108
|
+
logger.info(`dep provided by the lunorash umbrella, skipping: ${name}`);
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
77
111
|
if (parsed.dependencies?.[name] !== void 0 || parsed.devDependencies?.[name] !== void 0) {
|
|
78
112
|
logger.info(`dep already present: ${name}`);
|
|
79
113
|
continue;
|
|
80
114
|
}
|
|
81
|
-
const edits = modify(text, [section, name], range, {
|
|
115
|
+
const edits = modify(text, [section, name], resolveDepRange(range), {
|
|
82
116
|
formattingOptions: { insertSpaces: true, tabSize: 4 }
|
|
83
117
|
});
|
|
84
118
|
text = applyEdits(text, edits);
|
|
@@ -199,14 +233,14 @@ const applyBindings = (bindings, projectRoot, logger) => {
|
|
|
199
233
|
}
|
|
200
234
|
return applied;
|
|
201
235
|
};
|
|
202
|
-
const applyItemResources = (manifest, cwd, logger) => {
|
|
236
|
+
const applyItemResources = (manifest, cwd, logger, useUmbrella = false) => {
|
|
203
237
|
const deps = [];
|
|
204
238
|
const bindings = [];
|
|
205
239
|
if (manifest.deps) {
|
|
206
|
-
deps.push(...applyDeps(manifest.deps, cwd, logger));
|
|
240
|
+
deps.push(...applyDeps(manifest.deps, cwd, logger, "dependencies", useUmbrella));
|
|
207
241
|
}
|
|
208
242
|
if (manifest.devDependencies) {
|
|
209
|
-
deps.push(...applyDeps(manifest.devDependencies, cwd, logger, "devDependencies"));
|
|
243
|
+
deps.push(...applyDeps(manifest.devDependencies, cwd, logger, "devDependencies", useUmbrella));
|
|
210
244
|
}
|
|
211
245
|
if (manifest.bindings) {
|
|
212
246
|
bindings.push(...applyBindings(manifest.bindings, cwd, logger));
|
|
@@ -318,7 +352,12 @@ const renderDiff = (oldText, newText) => {
|
|
|
318
352
|
return out;
|
|
319
353
|
};
|
|
320
354
|
|
|
321
|
-
const
|
|
355
|
+
const CODE_FILE_RE = /\.[cm]?[jt]sx?$/u;
|
|
356
|
+
const readItemFile = (itemDirectory, file, useUmbrella) => {
|
|
357
|
+
const source = readFileSync(join(itemDirectory, file.from), "utf8");
|
|
358
|
+
return useUmbrella && CODE_FILE_RE.test(file.to) ? rewriteUmbrellaImports(source) : source;
|
|
359
|
+
};
|
|
360
|
+
const reconcileSchemaExtension = (file, itemKey, itemDirectory, projectRoot, logger, diff, useUmbrella) => {
|
|
322
361
|
const schemaPath = join(projectRoot, "lunora", "schema.ts");
|
|
323
362
|
if (diff) {
|
|
324
363
|
logger.info(`~ would merge .extend(${itemKey}.extension) into lunora/schema.ts (and create ${file.to} if absent)`);
|
|
@@ -327,9 +366,13 @@ const reconcileSchemaExtension = (file, itemKey, itemDirectory, projectRoot, log
|
|
|
327
366
|
const destinationPath = join(projectRoot, file.to);
|
|
328
367
|
if (!existsSync(destinationPath)) {
|
|
329
368
|
mkdirSync(dirname(destinationPath), { recursive: true });
|
|
330
|
-
writeFileSync(destinationPath,
|
|
369
|
+
writeFileSync(destinationPath, readItemFile(itemDirectory, file, useUmbrella), "utf8");
|
|
331
370
|
}
|
|
332
|
-
const
|
|
371
|
+
const baseModule = useUmbrella ? "lunorash/server" : "@lunora/server";
|
|
372
|
+
const existingSchema = existsSync(schemaPath) ? readFileSync(schemaPath, "utf8") : `import { defineSchema } from "${baseModule}";
|
|
373
|
+
|
|
374
|
+
export const schema = defineSchema({});
|
|
375
|
+
`;
|
|
333
376
|
const result = insertSchemaExtension(existingSchema, itemKey);
|
|
334
377
|
if (result.ok) {
|
|
335
378
|
mkdirSync(dirname(schemaPath), { recursive: true });
|
|
@@ -359,9 +402,9 @@ const previewWholeFile = (file, current, incoming, exists, logger) => {
|
|
|
359
402
|
logger.info(` ${line}`);
|
|
360
403
|
}
|
|
361
404
|
};
|
|
362
|
-
const reconcileWholeFile = (file, itemKey, itemDirectory, projectRoot, logger, lock, reconcileOptions) => {
|
|
405
|
+
const reconcileWholeFile = (file, itemKey, itemDirectory, projectRoot, logger, lock, reconcileOptions, useUmbrella) => {
|
|
363
406
|
const destinationPath = join(projectRoot, file.to);
|
|
364
|
-
const incoming =
|
|
407
|
+
const incoming = readItemFile(itemDirectory, file, useUmbrella);
|
|
365
408
|
const exists = existsSync(destinationPath);
|
|
366
409
|
const current = exists ? readFileSync(destinationPath, "utf8") : "";
|
|
367
410
|
const write = (message) => {
|
|
@@ -399,11 +442,11 @@ const reconcileWholeFile = (file, itemKey, itemDirectory, projectRoot, logger, l
|
|
|
399
442
|
logger.warn(`conflict: ${file.to} has local edits and an upstream update — wrote ${file.to}.new (use --overwrite to take theirs)`);
|
|
400
443
|
return { kind: "skipped", path: destinationPath };
|
|
401
444
|
};
|
|
402
|
-
const reconcileFile = (file, itemKey, itemDirectory, projectRoot, logger, lock, reconcileOptions = {}) => {
|
|
445
|
+
const reconcileFile = (file, itemKey, itemDirectory, projectRoot, logger, lock, reconcileOptions = {}, useUmbrella = false) => {
|
|
403
446
|
if (file.merge === "schema-extension") {
|
|
404
|
-
return reconcileSchemaExtension(file, itemKey, itemDirectory, projectRoot, logger, reconcileOptions.diff === true);
|
|
447
|
+
return reconcileSchemaExtension(file, itemKey, itemDirectory, projectRoot, logger, reconcileOptions.diff === true, useUmbrella);
|
|
405
448
|
}
|
|
406
|
-
return reconcileWholeFile(file, itemKey, itemDirectory, projectRoot, logger, lock, reconcileOptions);
|
|
449
|
+
return reconcileWholeFile(file, itemKey, itemDirectory, projectRoot, logger, lock, reconcileOptions, useUmbrella);
|
|
407
450
|
};
|
|
408
451
|
const reconcileItems = (items, cwd, logger, reconcileOptions = {}) => {
|
|
409
452
|
const written = [];
|
|
@@ -411,15 +454,16 @@ const reconcileItems = (items, cwd, logger, reconcileOptions = {}) => {
|
|
|
411
454
|
const depsAdded = [];
|
|
412
455
|
const bindingsApplied = [];
|
|
413
456
|
const lock = readLock(cwd);
|
|
457
|
+
const useUmbrella = projectUsesUmbrella(cwd);
|
|
414
458
|
for (const { directory, manifest } of items) {
|
|
415
459
|
for (const file of manifest.files) {
|
|
416
|
-
const outcome = reconcileFile(file, manifest.name, directory, cwd, logger, lock, reconcileOptions);
|
|
460
|
+
const outcome = reconcileFile(file, manifest.name, directory, cwd, logger, lock, reconcileOptions, useUmbrella);
|
|
417
461
|
(outcome.kind === "written" ? written : skipped).push(outcome.path);
|
|
418
462
|
}
|
|
419
463
|
if (reconcileOptions.diff) {
|
|
420
464
|
continue;
|
|
421
465
|
}
|
|
422
|
-
const applied = applyItemResources(manifest, cwd, logger);
|
|
466
|
+
const applied = applyItemResources(manifest, cwd, logger, useUmbrella);
|
|
423
467
|
depsAdded.push(...applied.deps);
|
|
424
468
|
bindingsApplied.push(...applied.bindings);
|
|
425
469
|
}
|
|
@@ -740,4 +784,4 @@ const runBuildIndexCommand = async (options) => {
|
|
|
740
784
|
return empty;
|
|
741
785
|
};
|
|
742
786
|
|
|
743
|
-
export { runBuildIndexCommand as a, runRegistryViewCommand as b, resolveSourceRef as c,
|
|
787
|
+
export { runBuildIndexCommand as a, runRegistryViewCommand as b, resolveSourceRef as c, resolveDistTag as d, runListCommand as e, runAddCommand as r };
|
package/package.json
CHANGED