@lunora/cli 1.0.0-alpha.7 → 1.0.0-alpha.70
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/LICENSE.md +6 -0
- package/__assets__/package-og.svg +1 -1
- package/dist/bin.mjs +1 -1
- package/dist/index.d.mts +248 -115
- package/dist/index.d.ts +248 -115
- package/dist/index.mjs +8 -8
- 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 +48 -67
- package/dist/packem_chunks/handler16.mjs +74 -37
- package/dist/packem_chunks/handler17.mjs +39 -100
- package/dist/packem_chunks/handler18.mjs +87 -152
- package/dist/packem_chunks/handler19.mjs +148 -67
- package/dist/packem_chunks/handler2.mjs +6 -4
- package/dist/packem_chunks/handler20.mjs +77 -75
- package/dist/packem_chunks/handler21.mjs +71 -288
- package/dist/packem_chunks/handler3.mjs +6 -3
- package/dist/packem_chunks/handler4.mjs +2 -2
- package/dist/packem_chunks/handler5.mjs +7 -4
- package/dist/packem_chunks/handler6.mjs +10 -7
- package/dist/packem_chunks/handler7.mjs +2 -2
- package/dist/packem_chunks/handler8.mjs +1 -1
- package/dist/packem_chunks/handler9.mjs +315 -12
- package/dist/packem_chunks/planDevCommand.mjs +653 -37
- package/dist/packem_chunks/runCodegenCommand.mjs +5 -4
- package/dist/packem_chunks/runDeployCommand.mjs +115 -20
- package/dist/packem_chunks/runInitCommand.mjs +1602 -172
- package/dist/packem_chunks/runMigrateGenerateCommand.mjs +5 -4
- package/dist/packem_chunks/runResetCommand.mjs +2 -2
- package/dist/packem_chunks/runRpcCommand.mjs +3 -2
- package/dist/packem_shared/{COMMANDS-Bn8luojF.mjs → COMMANDS-0BD3K1pb.mjs} +79 -21
- package/dist/packem_shared/{DEFAULT_IMPORT_BATCH_SIZE-Ck-2bU08.mjs → DEFAULT_IMPORT_BATCH_SIZE-CRQmmBZM.mjs} +3 -2
- package/dist/packem_shared/{api-spec-CtA6ilu4.mjs → api-spec-Bx0iKbxA.mjs} +3 -1
- package/dist/packem_shared/{buildRegistryIndex-BcYe607_.mjs → buildRegistryIndex-CqM5FwGI.mjs} +1 -1
- package/dist/packem_shared/codegen-error-DJG-ghs_.mjs +31 -0
- package/dist/packem_shared/{command-BDXcJCCJ.mjs → command-lYnl4QyF.mjs} +6 -1
- package/dist/packem_shared/{commands-DqsEzojt.mjs → commands-vnRRkhNE.mjs} +123 -15
- package/dist/packem_shared/{createLogger-CHPNjFw2.mjs → createLogger-CIWSHrTL.mjs} +40 -8
- package/dist/packem_shared/{createRecordingSpawner-DxI3mebw.mjs → createRecordingSpawner-Cw5Iu73G.mjs} +12 -2
- package/dist/packem_shared/{detect-package-manager-DYp7n3mJ.mjs → detect-package-manager-DvEthdCw.mjs} +26 -30
- package/dist/packem_shared/{insertSchemaExtension-BuzF6-t2.mjs → insertSchemaExtension-DAqbfr9Z.mjs} +15 -10
- package/dist/packem_shared/{open-url-Dfq6fAyT.mjs → open-url-4PBLY9X0.mjs} +3 -2
- package/dist/packem_shared/{output-format-7gyGR3h8.mjs → output-format-B4642rjE.mjs} +1 -1
- package/dist/packem_shared/{parseManifest--vZf2FY1.mjs → parseManifest-BBrXCg9V.mjs} +16 -9
- package/dist/packem_shared/prompt-cancelled-APzX1Im-.mjs +9 -0
- package/dist/packem_shared/runAddCommand-BCcJzs_k.mjs +4 -0
- package/dist/packem_shared/storage-bGfgwOgF.mjs +84 -0
- package/dist/packem_shared/tui-prompts-BjEN8XgP.mjs +658 -0
- package/dist/packem_shared/wrangler-secrets-Dq_Fkbm-.mjs +49 -0
- package/package.json +10 -7
- package/skills/lunora-quickstart/SKILL.md +25 -5
- package/skills/lunora-setup-storage/SKILL.md +7 -3
- package/dist/packem_shared/features-ocSSpZtS.mjs +0 -24
- package/dist/packem_shared/runAddCommand-G544_v6e.mjs +0 -4
- package/dist/packem_shared/tui-prompts-XHFxlOg5.mjs +0 -269
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
import { d as defineHandler } from '../packem_shared/command-
|
|
1
|
+
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
2
2
|
import { a as resolveProductionWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
|
|
3
|
-
import {
|
|
3
|
+
import { runExportCommand } from '../packem_shared/DEFAULT_IMPORT_BATCH_SIZE-CRQmmBZM.mjs';
|
|
4
4
|
|
|
5
|
-
const execute = defineHandler(
|
|
6
|
-
|
|
7
|
-
if (!file) {
|
|
8
|
-
logger.error("import requires a file. Usage: lunora import <path> [--table <name>]");
|
|
9
|
-
return { code: 1 };
|
|
10
|
-
}
|
|
11
|
-
return runImportCommand({
|
|
12
|
-
batchSize: options.batchSize,
|
|
13
|
-
file,
|
|
5
|
+
const execute = defineHandler(
|
|
6
|
+
({ argument, cwd, logger, options }) => runExportCommand({
|
|
14
7
|
logger,
|
|
8
|
+
out: argument[0] ?? options.out,
|
|
15
9
|
prod: options.prod === true,
|
|
16
|
-
|
|
10
|
+
tables: options.tables,
|
|
17
11
|
token: options.token,
|
|
18
12
|
url: resolveProductionWorkerUrl({ cwd, prod: options.prod === true, url: options.url })
|
|
19
|
-
})
|
|
20
|
-
|
|
13
|
+
})
|
|
14
|
+
);
|
|
21
15
|
|
|
22
16
|
export { execute };
|
|
@@ -1,192 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { readLinkedProject } from '@lunora/config';
|
|
5
|
-
import { parse } from 'jsonc-parser';
|
|
6
|
-
import { Project } from 'ts-morph';
|
|
7
|
-
import { d as defineHandler } from '../packem_shared/command-BDXcJCCJ.mjs';
|
|
1
|
+
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
2
|
+
import { a as resolveProductionWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
|
|
3
|
+
import { runImportCommand } from '../packem_shared/DEFAULT_IMPORT_BATCH_SIZE-CRQmmBZM.mjs';
|
|
8
4
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
24
|
-
};
|
|
25
|
-
const arrayField = (record, key) => {
|
|
26
|
-
if (record === null || typeof record !== "object") {
|
|
27
|
-
return [];
|
|
28
|
-
}
|
|
29
|
-
const value = record[key];
|
|
30
|
-
return Array.isArray(value) ? value : [];
|
|
31
|
-
};
|
|
32
|
-
const summariseWrangler = (raw) => {
|
|
33
|
-
const durableObjectBindings = arrayField(raw.durable_objects ?? {}, "bindings");
|
|
34
|
-
const d1 = arrayField(raw, "d1_databases");
|
|
35
|
-
const vectorize = arrayField(raw, "vectorize");
|
|
36
|
-
return {
|
|
37
|
-
bindings: {
|
|
38
|
-
d1: d1.map((entry) => stringField(entry, "binding") ?? "<unnamed>"),
|
|
39
|
-
durableObjects: durableObjectBindings.map((entry) => stringField(entry, "name") ?? "<unnamed>"),
|
|
40
|
-
vectorize: vectorize.map((entry) => stringField(entry, "binding") ?? "<unnamed>")
|
|
41
|
-
},
|
|
42
|
-
compatibilityDate: stringField(raw, "compatibility_date"),
|
|
43
|
-
compatibilityFlags: arrayField(raw, "compatibility_flags").filter((entry) => typeof entry === "string"),
|
|
44
|
-
main: stringField(raw, "main"),
|
|
45
|
-
name: stringField(raw, "name")
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
const summariseSchema = (schema) => {
|
|
49
|
-
return {
|
|
50
|
-
tables: schema.tables.map((table) => {
|
|
51
|
-
let shard = "root";
|
|
52
|
-
if (table.shardMode === "global") {
|
|
53
|
-
shard = "global";
|
|
54
|
-
} else if (typeof table.shardMode === "object") {
|
|
55
|
-
shard = `shardBy(${table.shardMode.field})`;
|
|
56
|
-
}
|
|
57
|
-
return {
|
|
58
|
-
indexes: table.indexes.length,
|
|
59
|
-
name: table.name,
|
|
60
|
-
shard
|
|
61
|
-
};
|
|
62
|
-
}),
|
|
63
|
-
vectorIndexes: schema.vectorIndexes.length
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
const collectLunoraPackages = (projectRoot) => {
|
|
67
|
-
const pkgPath = join(projectRoot, "package.json");
|
|
68
|
-
if (!existsSync(pkgPath)) {
|
|
69
|
-
return [];
|
|
70
|
-
}
|
|
71
|
-
let pkg;
|
|
72
|
-
try {
|
|
73
|
-
pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
74
|
-
} catch {
|
|
75
|
-
return [];
|
|
76
|
-
}
|
|
77
|
-
if (pkg === null || typeof pkg !== "object") {
|
|
78
|
-
return [];
|
|
79
|
-
}
|
|
80
|
-
const sections = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
|
81
|
-
const seen = /* @__PURE__ */ new Map();
|
|
82
|
-
for (const section of sections) {
|
|
83
|
-
const block = pkg[section];
|
|
84
|
-
if (block === null || typeof block !== "object") {
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
for (const [name, version] of Object.entries(block)) {
|
|
88
|
-
if (!name.startsWith("@lunora/")) {
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
if (typeof version === "string" && !seen.has(name)) {
|
|
92
|
-
seen.set(name, version);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return [...seen.entries()].toSorted(([a], [b]) => a.localeCompare(b)).map(([name, version]) => {
|
|
97
|
-
return { name, version };
|
|
5
|
+
const execute = defineHandler(({ argument, cwd, logger, options }) => {
|
|
6
|
+
const file = argument[0];
|
|
7
|
+
if (!file) {
|
|
8
|
+
logger.error("import requires a file. Usage: lunora import <path> [--table <name>]");
|
|
9
|
+
return { code: 1 };
|
|
10
|
+
}
|
|
11
|
+
return runImportCommand({
|
|
12
|
+
batchSize: options.batchSize,
|
|
13
|
+
file,
|
|
14
|
+
logger,
|
|
15
|
+
prod: options.prod === true,
|
|
16
|
+
table: options.table,
|
|
17
|
+
token: options.token,
|
|
18
|
+
url: resolveProductionWorkerUrl({ cwd, prod: options.prod === true, url: options.url })
|
|
98
19
|
});
|
|
99
|
-
};
|
|
100
|
-
const collectInfo = (projectRoot) => {
|
|
101
|
-
const lunoraPackages = collectLunoraPackages(projectRoot);
|
|
102
|
-
const wranglerPath = findWranglerFile(projectRoot);
|
|
103
|
-
let wrangler;
|
|
104
|
-
if (wranglerPath) {
|
|
105
|
-
try {
|
|
106
|
-
wrangler = summariseWrangler(parse(readFileSync(wranglerPath, "utf8")));
|
|
107
|
-
} catch {
|
|
108
|
-
wrangler = void 0;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
const schemaPath = join(projectRoot, "lunora", "schema.ts");
|
|
112
|
-
let schema;
|
|
113
|
-
let schemaError;
|
|
114
|
-
if (existsSync(schemaPath)) {
|
|
115
|
-
try {
|
|
116
|
-
const project = new Project({ skipAddingFilesFromTsConfig: true, useInMemoryFileSystem: false });
|
|
117
|
-
schema = summariseSchema(discoverSchema(project, schemaPath));
|
|
118
|
-
} catch (error) {
|
|
119
|
-
schemaError = error instanceof Error ? error.message : String(error);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return {
|
|
123
|
-
link: readLinkedProject(projectRoot),
|
|
124
|
-
lunoraPackages,
|
|
125
|
-
projectRoot,
|
|
126
|
-
schema,
|
|
127
|
-
schemaError,
|
|
128
|
-
wrangler,
|
|
129
|
-
wranglerPath
|
|
130
|
-
};
|
|
131
|
-
};
|
|
132
|
-
const renderText = (snapshot, logger) => {
|
|
133
|
-
logger.info(`project: ${snapshot.projectRoot}`);
|
|
134
|
-
logger.info("");
|
|
135
|
-
logger.info("@lunora/* packages:");
|
|
136
|
-
if (snapshot.lunoraPackages.length === 0) {
|
|
137
|
-
logger.info(" (none found in package.json)");
|
|
138
|
-
} else {
|
|
139
|
-
for (const pkg of snapshot.lunoraPackages) {
|
|
140
|
-
logger.info(` ${pkg.name}@${pkg.version}`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
logger.info("");
|
|
144
|
-
if (snapshot.wrangler) {
|
|
145
|
-
logger.info(`wrangler: ${snapshot.wranglerPath ?? ""}`);
|
|
146
|
-
logger.info(` name: ${snapshot.wrangler.name ?? "<unset>"}`);
|
|
147
|
-
logger.info(` main: ${snapshot.wrangler.main ?? "<unset>"}`);
|
|
148
|
-
logger.info(` compatibility_date: ${snapshot.wrangler.compatibilityDate ?? "<unset>"}`);
|
|
149
|
-
logger.info(` compatibility_flags: ${snapshot.wrangler.compatibilityFlags.join(", ") || "<none>"}`);
|
|
150
|
-
logger.info(` durable objects: ${snapshot.wrangler.bindings.durableObjects.join(", ") || "<none>"}`);
|
|
151
|
-
logger.info(` d1 databases: ${snapshot.wrangler.bindings.d1.join(", ") || "<none>"}`);
|
|
152
|
-
logger.info(` vectorize indexes: ${snapshot.wrangler.bindings.vectorize.join(", ") || "<none>"}`);
|
|
153
|
-
} else {
|
|
154
|
-
logger.info("wrangler: (not found)");
|
|
155
|
-
}
|
|
156
|
-
logger.info("");
|
|
157
|
-
if (snapshot.link) {
|
|
158
|
-
logger.info(`link: ${snapshot.link.workerName ?? "(unnamed)"} -> ${snapshot.link.workerUrl ?? "<no url>"}`);
|
|
159
|
-
if (snapshot.link.env !== void 0) {
|
|
160
|
-
logger.info(` env: ${snapshot.link.env}`);
|
|
161
|
-
}
|
|
162
|
-
} else {
|
|
163
|
-
logger.info("link: (not linked — run `lunora link --url <https://your-worker>`)");
|
|
164
|
-
}
|
|
165
|
-
logger.info("");
|
|
166
|
-
if (snapshot.schemaError !== void 0) {
|
|
167
|
-
logger.warn(`schema: parse error — ${snapshot.schemaError}`);
|
|
168
|
-
} else if (snapshot.schema) {
|
|
169
|
-
logger.info(`schema: ${String(snapshot.schema.tables.length)} table(s), ${String(snapshot.schema.vectorIndexes)} vector index(es)`);
|
|
170
|
-
for (const table of snapshot.schema.tables) {
|
|
171
|
-
logger.info(` ${table.name} [${table.shard}, ${String(table.indexes)} index(es)]`);
|
|
172
|
-
}
|
|
173
|
-
} else {
|
|
174
|
-
logger.info("schema: (no lunora/schema.ts)");
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
const runInfoCommand = (options) => {
|
|
178
|
-
const cwd = options.cwd ?? process.cwd();
|
|
179
|
-
const snapshot = collectInfo(cwd);
|
|
180
|
-
if (options.json) {
|
|
181
|
-
process.stdout.write(`${JSON.stringify(snapshot, void 0, 2)}
|
|
182
|
-
`);
|
|
183
|
-
} else {
|
|
184
|
-
renderText(snapshot, options.logger);
|
|
185
|
-
}
|
|
186
|
-
return { code: 0, snapshot };
|
|
187
|
-
};
|
|
188
|
-
const execute = defineHandler(
|
|
189
|
-
({ cwd, logger, options }) => runInfoCommand({ cwd, json: options.json === true, logger })
|
|
190
|
-
);
|
|
20
|
+
});
|
|
191
21
|
|
|
192
|
-
export {
|
|
22
|
+
export { execute };
|
|
@@ -1,131 +1,192 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { discoverSchema } from '@lunora/codegen';
|
|
4
|
+
import { readLinkedProject } from '@lunora/config';
|
|
5
|
+
import { parse } from 'jsonc-parser';
|
|
6
|
+
import { Project } from 'ts-morph';
|
|
7
|
+
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
4
8
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
+
const findWranglerFile = (projectRoot) => {
|
|
10
|
+
for (const candidate of ["wrangler.jsonc", "wrangler.json"]) {
|
|
11
|
+
const fullPath = join(projectRoot, candidate);
|
|
12
|
+
if (existsSync(fullPath)) {
|
|
13
|
+
return fullPath;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return void 0;
|
|
17
|
+
};
|
|
18
|
+
const stringField = (record, key) => {
|
|
19
|
+
if (record === null || typeof record !== "object") {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
const value = record[key];
|
|
23
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
24
|
+
};
|
|
25
|
+
const arrayField = (record, key) => {
|
|
26
|
+
if (record === null || typeof record !== "object") {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const value = record[key];
|
|
30
|
+
return Array.isArray(value) ? value : [];
|
|
31
|
+
};
|
|
32
|
+
const summariseWrangler = (raw) => {
|
|
33
|
+
const durableObjectBindings = arrayField(raw.durable_objects ?? {}, "bindings");
|
|
34
|
+
const d1 = arrayField(raw, "d1_databases");
|
|
35
|
+
const vectorize = arrayField(raw, "vectorize");
|
|
9
36
|
return {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
37
|
+
bindings: {
|
|
38
|
+
d1: d1.map((entry) => stringField(entry, "binding") ?? "<unnamed>"),
|
|
39
|
+
durableObjects: durableObjectBindings.map((entry) => stringField(entry, "name") ?? "<unnamed>"),
|
|
40
|
+
vectorize: vectorize.map((entry) => stringField(entry, "binding") ?? "<unnamed>")
|
|
41
|
+
},
|
|
42
|
+
compatibilityDate: stringField(raw, "compatibility_date"),
|
|
43
|
+
compatibilityFlags: arrayField(raw, "compatibility_flags").filter((entry) => typeof entry === "string"),
|
|
44
|
+
main: stringField(raw, "main"),
|
|
45
|
+
name: stringField(raw, "name")
|
|
18
46
|
};
|
|
19
47
|
};
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
...formatSection(
|
|
38
|
-
"Write-conflict hot-spots (OCC contention — candidates for sharding):",
|
|
39
|
-
report.writeContention,
|
|
40
|
-
"none — no write conflicts observed",
|
|
41
|
-
(row) => `${row.path} ${row.conflicts.toString()}/${row.calls.toString()} calls (${percent(row.rate)})`
|
|
42
|
-
),
|
|
43
|
-
"",
|
|
44
|
-
...formatSection(
|
|
45
|
-
"Error hot-spots:",
|
|
46
|
-
report.errorHotspots,
|
|
47
|
-
"none — no errors observed",
|
|
48
|
-
(row) => `${row.path} ${row.errors.toString()}/${row.calls.toString()} calls (${percent(row.rate)})${errorTail(row)}`
|
|
49
|
-
),
|
|
50
|
-
"",
|
|
51
|
-
...formatSection(
|
|
52
|
-
"Latency outliers (slowest single call):",
|
|
53
|
-
report.latencyOutliers,
|
|
54
|
-
"none — no functions have run",
|
|
55
|
-
(row) => `${row.path} max ${formatMs(row.maxDurationMs)}, mean ${formatMs(row.meanDurationMs)} over ${row.calls.toString()} calls`
|
|
56
|
-
)
|
|
57
|
-
].join("\n");
|
|
48
|
+
const summariseSchema = (schema) => {
|
|
49
|
+
return {
|
|
50
|
+
tables: schema.tables.map((table) => {
|
|
51
|
+
let shard = "root";
|
|
52
|
+
if (table.shardMode === "global") {
|
|
53
|
+
shard = "global";
|
|
54
|
+
} else if (typeof table.shardMode === "object") {
|
|
55
|
+
shard = `shardBy(${table.shardMode.field})`;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
indexes: table.indexes.length,
|
|
59
|
+
name: table.name,
|
|
60
|
+
shard
|
|
61
|
+
};
|
|
62
|
+
}),
|
|
63
|
+
vectorIndexes: schema.vectorIndexes.length
|
|
64
|
+
};
|
|
58
65
|
};
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
const collectLunoraPackages = (projectRoot) => {
|
|
67
|
+
const pkgPath = join(projectRoot, "package.json");
|
|
68
|
+
if (!existsSync(pkgPath)) {
|
|
69
|
+
return [];
|
|
62
70
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
return { code: 1 };
|
|
71
|
+
let pkg;
|
|
72
|
+
try {
|
|
73
|
+
pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
74
|
+
} catch {
|
|
75
|
+
return [];
|
|
69
76
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
options.logger.error("admin token required — pass --token or set LUNORA_ADMIN_TOKEN");
|
|
73
|
-
return { code: 1 };
|
|
77
|
+
if (pkg === null || typeof pkg !== "object") {
|
|
78
|
+
return [];
|
|
74
79
|
}
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
const sections = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
|
81
|
+
const seen = /* @__PURE__ */ new Map();
|
|
82
|
+
for (const section of sections) {
|
|
83
|
+
const block = pkg[section];
|
|
84
|
+
if (block === null || typeof block !== "object") {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
for (const [name, version] of Object.entries(block)) {
|
|
88
|
+
if (!name.startsWith("@lunora/")) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (typeof version === "string" && !seen.has(name)) {
|
|
92
|
+
seen.set(name, version);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
78
95
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
96
|
+
return [...seen.entries()].toSorted(([a], [b]) => a.localeCompare(b)).map(([name, version]) => {
|
|
97
|
+
return { name, version };
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
const collectInfo = (projectRoot) => {
|
|
101
|
+
const lunoraPackages = collectLunoraPackages(projectRoot);
|
|
102
|
+
const wranglerPath = findWranglerFile(projectRoot);
|
|
103
|
+
let wrangler;
|
|
104
|
+
if (wranglerPath) {
|
|
105
|
+
try {
|
|
106
|
+
wrangler = summariseWrangler(parse(readFileSync(wranglerPath, "utf8")));
|
|
107
|
+
} catch {
|
|
108
|
+
wrangler = void 0;
|
|
109
|
+
}
|
|
83
110
|
}
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
111
|
+
const schemaPath = join(projectRoot, "lunora", "schema.ts");
|
|
112
|
+
let schema;
|
|
113
|
+
let schemaError;
|
|
114
|
+
if (existsSync(schemaPath)) {
|
|
115
|
+
try {
|
|
116
|
+
const project = new Project({ skipAddingFilesFromTsConfig: true, useInMemoryFileSystem: false });
|
|
117
|
+
schema = summariseSchema(discoverSchema(project, schemaPath));
|
|
118
|
+
} catch (error) {
|
|
119
|
+
schemaError = error instanceof Error ? error.message : String(error);
|
|
120
|
+
}
|
|
87
121
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
122
|
+
return {
|
|
123
|
+
link: readLinkedProject(projectRoot),
|
|
124
|
+
lunoraPackages,
|
|
125
|
+
projectRoot,
|
|
126
|
+
schema,
|
|
127
|
+
schemaError,
|
|
128
|
+
wrangler,
|
|
129
|
+
wranglerPath
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
const renderText = (snapshot, logger) => {
|
|
133
|
+
logger.info(`project: ${snapshot.projectRoot}`);
|
|
134
|
+
logger.info("");
|
|
135
|
+
logger.info("@lunora/* packages:");
|
|
136
|
+
if (snapshot.lunoraPackages.length === 0) {
|
|
137
|
+
logger.info(" (none found in package.json)");
|
|
138
|
+
} else {
|
|
139
|
+
for (const pkg of snapshot.lunoraPackages) {
|
|
140
|
+
logger.info(` ${pkg.name}@${pkg.version}`);
|
|
141
|
+
}
|
|
98
142
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
143
|
+
logger.info("");
|
|
144
|
+
if (snapshot.wrangler) {
|
|
145
|
+
logger.info(`wrangler: ${snapshot.wranglerPath ?? ""}`);
|
|
146
|
+
logger.info(` name: ${snapshot.wrangler.name ?? "<unset>"}`);
|
|
147
|
+
logger.info(` main: ${snapshot.wrangler.main ?? "<unset>"}`);
|
|
148
|
+
logger.info(` compatibility_date: ${snapshot.wrangler.compatibilityDate ?? "<unset>"}`);
|
|
149
|
+
logger.info(` compatibility_flags: ${snapshot.wrangler.compatibilityFlags.join(", ") || "<none>"}`);
|
|
150
|
+
logger.info(` durable objects: ${snapshot.wrangler.bindings.durableObjects.join(", ") || "<none>"}`);
|
|
151
|
+
logger.info(` d1 databases: ${snapshot.wrangler.bindings.d1.join(", ") || "<none>"}`);
|
|
152
|
+
logger.info(` vectorize indexes: ${snapshot.wrangler.bindings.vectorize.join(", ") || "<none>"}`);
|
|
153
|
+
} else {
|
|
154
|
+
logger.info("wrangler: (not found)");
|
|
155
|
+
}
|
|
156
|
+
logger.info("");
|
|
157
|
+
if (snapshot.link) {
|
|
158
|
+
logger.info(`link: ${snapshot.link.workerName ?? "(unnamed)"} -> ${snapshot.link.workerUrl ?? "<no url>"}`);
|
|
159
|
+
if (snapshot.link.env !== void 0) {
|
|
160
|
+
logger.info(` env: ${snapshot.link.env}`);
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
logger.info("link: (not linked — run `lunora link --url <https://your-worker>`)");
|
|
105
164
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
165
|
+
logger.info("");
|
|
166
|
+
if (snapshot.schemaError !== void 0) {
|
|
167
|
+
logger.warn(`schema: parse error — ${snapshot.schemaError}`);
|
|
168
|
+
} else if (snapshot.schema) {
|
|
169
|
+
logger.info(`schema: ${String(snapshot.schema.tables.length)} table(s), ${String(snapshot.schema.vectorIndexes)} vector index(es)`);
|
|
170
|
+
for (const table of snapshot.schema.tables) {
|
|
171
|
+
logger.info(` ${table.name} [${table.shard}, ${String(table.indexes)} index(es)]`);
|
|
172
|
+
}
|
|
173
|
+
} else {
|
|
174
|
+
logger.info("schema: (no lunora/schema.ts)");
|
|
111
175
|
}
|
|
112
|
-
const report = buildInsightsReport(functions, resolveLimit(options.limit));
|
|
113
|
-
options.logger.info(options.json ? JSON.stringify(report, void 0, 2) : formatInsightsReport(report));
|
|
114
|
-
return { code: 0, report };
|
|
115
176
|
};
|
|
116
|
-
const
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
})
|
|
129
|
-
|
|
177
|
+
const runInfoCommand = (options) => {
|
|
178
|
+
const cwd = options.cwd ?? process.cwd();
|
|
179
|
+
const snapshot = collectInfo(cwd);
|
|
180
|
+
if (options.json) {
|
|
181
|
+
process.stdout.write(`${JSON.stringify(snapshot, void 0, 2)}
|
|
182
|
+
`);
|
|
183
|
+
} else {
|
|
184
|
+
renderText(snapshot, options.logger);
|
|
185
|
+
}
|
|
186
|
+
return { code: 0, snapshot };
|
|
187
|
+
};
|
|
188
|
+
const execute = defineHandler(
|
|
189
|
+
({ cwd, logger, options }) => runInfoCommand({ cwd, json: options.json === true, logger })
|
|
190
|
+
);
|
|
130
191
|
|
|
131
|
-
export {
|
|
192
|
+
export { collectInfo, execute, runInfoCommand };
|