@lunora/cli 1.0.0-alpha.3 → 1.0.0-alpha.30
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 +89 -7
- 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 +73 -37
- package/dist/packem_chunks/handler17.mjs +38 -100
- package/dist/packem_chunks/handler18.mjs +87 -154
- package/dist/packem_chunks/handler19.mjs +148 -67
- package/dist/packem_chunks/handler2.mjs +2 -2
- package/dist/packem_chunks/handler20.mjs +71 -76
- 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 +46 -49
- package/dist/packem_chunks/runCodegenCommand.mjs +2 -2
- package/dist/packem_chunks/runDeployCommand.mjs +105 -15
- package/dist/packem_chunks/runInitCommand.mjs +1980 -77
- package/dist/packem_chunks/runMigrateGenerateCommand.mjs +5 -5
- package/dist/packem_chunks/runResetCommand.mjs +4 -4
- package/dist/packem_chunks/runRpcCommand.mjs +1 -1
- package/dist/packem_shared/{COMMANDS-CHw4zOZ9.mjs → COMMANDS-B0ftFD_3.mjs} +47 -21
- package/dist/packem_shared/{command-BDXcJCCJ.mjs → command-D3lB_4Az.mjs} +6 -1
- package/dist/packem_shared/{commands-DIQ3nf0C.mjs → commands-B-gR09Z_.mjs} +124 -22
- 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 +12 -11
- package/skills/lunora-setup-storage/SKILL.md +7 -3
- package/dist/packem_shared/features-ocSSpZtS.mjs +0 -24
- package/dist/packem_shared/runAddCommand-3I3JFZUG.mjs +0 -4
- /package/dist/packem_shared/{defaultSpawner-DxI3mebw.mjs → createRecordingSpawner-DxI3mebw.mjs} +0 -0
|
@@ -1,65 +1,131 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { d as defineHandler } from '../packem_shared/command-BDXcJCCJ.mjs';
|
|
5
|
-
import { r as readWranglerName } from '../packem_shared/wrangler-name-cy4yhm9j.mjs';
|
|
1
|
+
import { r as resolveAdminBaseUrl } from '../packem_shared/admin-url-4UzT-CI4.mjs';
|
|
2
|
+
import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
|
|
3
|
+
import { a as resolveProductionWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
|
|
6
4
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
5
|
+
const GET_FUNCTION_STATS_OP = "__lunora_admin__:getFunctionStats";
|
|
6
|
+
const DEFAULT_LIMIT = 10;
|
|
7
|
+
const TRAILING_SLASH = /\/$/u;
|
|
8
|
+
const toInsightRow = (stat, rate) => {
|
|
9
|
+
return {
|
|
10
|
+
calls: stat.calls,
|
|
11
|
+
conflicts: stat.conflicts ?? 0,
|
|
12
|
+
errors: stat.errors,
|
|
13
|
+
lastErrorMessage: stat.lastErrorMessage,
|
|
14
|
+
maxDurationMs: stat.maxDurationMs,
|
|
15
|
+
meanDurationMs: stat.calls === 0 ? 0 : stat.totalDurationMs / stat.calls,
|
|
16
|
+
path: stat.path,
|
|
17
|
+
rate
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const buildInsightsReport = (functions, limit) => {
|
|
21
|
+
const writeContention = functions.filter((stat) => (stat.conflicts ?? 0) > 0).map((stat) => toInsightRow(stat, stat.calls === 0 ? 0 : (stat.conflicts ?? 0) / stat.calls)).toSorted((a, b) => b.rate - a.rate || b.conflicts - a.conflicts).slice(0, limit);
|
|
22
|
+
const errorHotspots = functions.filter((stat) => stat.errors > 0).map((stat) => toInsightRow(stat, stat.calls === 0 ? 0 : stat.errors / stat.calls)).toSorted((a, b) => b.rate - a.rate || b.errors - a.errors).slice(0, limit);
|
|
23
|
+
const latencyOutliers = functions.map((stat) => toInsightRow(stat, 0)).toSorted((a, b) => b.maxDurationMs - a.maxDurationMs).slice(0, limit);
|
|
24
|
+
return { errorHotspots, latencyOutliers, totalFunctions: functions.length, writeContention };
|
|
14
25
|
};
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
26
|
+
const percent = (rate) => `${(rate * 100).toFixed(1)}%`;
|
|
27
|
+
const formatMs = (ms) => ms < 1e3 ? `${Math.round(ms).toString()}ms` : `${(ms / 1e3).toFixed(2)}s`;
|
|
28
|
+
const formatSection = (heading, rows, emptyNote, renderRow) => [
|
|
29
|
+
heading,
|
|
30
|
+
...rows.length === 0 ? [` ${emptyNote}`] : rows.map((row) => ` ${renderRow(row)}`)
|
|
31
|
+
];
|
|
32
|
+
const formatInsightsReport = (report) => {
|
|
33
|
+
const errorTail = (row) => row.lastErrorMessage ? ` — ${row.lastErrorMessage}` : "";
|
|
34
|
+
return [
|
|
35
|
+
`Insights over ${report.totalFunctions.toString()} function${report.totalFunctions === 1 ? "" : "s"}`,
|
|
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");
|
|
58
|
+
};
|
|
59
|
+
const resolveLimit = (raw) => {
|
|
60
|
+
if (raw === void 0 || !Number.isFinite(raw) || raw <= 0) {
|
|
61
|
+
return DEFAULT_LIMIT;
|
|
20
62
|
}
|
|
21
|
-
|
|
22
|
-
logger.success(`link: removed ${LINKED_PROJECT_FILE}`);
|
|
23
|
-
return { code: 0 };
|
|
63
|
+
return Math.floor(raw);
|
|
24
64
|
};
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return runLinkRemove(cwd, logger);
|
|
65
|
+
const runInsightsCommand = async (options) => {
|
|
66
|
+
if (options.prod && options.url === void 0) {
|
|
67
|
+
options.logger.error("--prod requires an explicit --url (refusing to report from the implicit localhost worker)");
|
|
68
|
+
return { code: 1 };
|
|
30
69
|
}
|
|
31
|
-
|
|
32
|
-
|
|
70
|
+
const token = options.token ?? process.env.LUNORA_ADMIN_TOKEN;
|
|
71
|
+
if (!token) {
|
|
72
|
+
options.logger.error("admin token required — pass --token or set LUNORA_ADMIN_TOKEN");
|
|
33
73
|
return { code: 1 };
|
|
34
74
|
}
|
|
35
|
-
|
|
36
|
-
|
|
75
|
+
const baseUrl = resolveAdminBaseUrl(options.url, options.logger);
|
|
76
|
+
if (baseUrl === void 0) {
|
|
37
77
|
return { code: 1 };
|
|
38
78
|
}
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
logger.info(`
|
|
49
|
-
|
|
50
|
-
|
|
79
|
+
const requestUrl = `${baseUrl.replace(TRAILING_SLASH, "")}/_lunora/rpc`;
|
|
80
|
+
const fetchImpl = globalThis.fetch;
|
|
81
|
+
if (typeof fetchImpl !== "function") {
|
|
82
|
+
throw new TypeError("no fetch implementation available — pass fetchImpl or run on Node >= 18");
|
|
83
|
+
}
|
|
84
|
+
const payload = { args: {}, functionPath: GET_FUNCTION_STATS_OP };
|
|
85
|
+
if (options.shard !== void 0) {
|
|
86
|
+
payload.shardKey = options.shard;
|
|
87
|
+
}
|
|
88
|
+
options.logger.info(`POST ${requestUrl} -> insights`);
|
|
89
|
+
const response = await fetchImpl(requestUrl, {
|
|
90
|
+
body: JSON.stringify(payload),
|
|
91
|
+
headers: { authorization: `Bearer ${token}`, "content-type": "application/json" },
|
|
92
|
+
method: "POST"
|
|
93
|
+
});
|
|
94
|
+
const text = await response.text();
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
options.logger.error(`insights failed: HTTP ${String(response.status)}: ${text}`);
|
|
97
|
+
return { code: 1 };
|
|
98
|
+
}
|
|
99
|
+
let parsed;
|
|
100
|
+
try {
|
|
101
|
+
parsed = JSON.parse(text);
|
|
102
|
+
} catch {
|
|
103
|
+
options.logger.error(`insights failed: worker returned non-JSON: ${text}`);
|
|
104
|
+
return { code: 1 };
|
|
105
|
+
}
|
|
106
|
+
const result = parsed.result ?? parsed;
|
|
107
|
+
const { functions } = result;
|
|
108
|
+
if (!Array.isArray(functions)) {
|
|
109
|
+
options.logger.error("insights failed: response carried no `functions` array");
|
|
110
|
+
return { code: 1 };
|
|
51
111
|
}
|
|
52
|
-
|
|
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 };
|
|
53
115
|
};
|
|
54
|
-
const execute = defineHandler(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
116
|
+
const execute = defineHandler(({ cwd, logger, options }) => {
|
|
117
|
+
const limit = options.limit === void 0 ? void 0 : Number.parseInt(options.limit, 10);
|
|
118
|
+
return runInsightsCommand({
|
|
119
|
+
json: options.json,
|
|
120
|
+
limit,
|
|
58
121
|
logger,
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
122
|
+
prod: options.prod,
|
|
123
|
+
shard: options.shard,
|
|
124
|
+
token: options.token,
|
|
125
|
+
// Fall back to the `.lunora/project.json` link when `--prod` is set, so a
|
|
126
|
+
// linked checkout doesn't need --url repeated for prod insights.
|
|
127
|
+
url: resolveProductionWorkerUrl({ cwd, prod: options.prod === true, url: options.url })
|
|
128
|
+
});
|
|
129
|
+
});
|
|
64
130
|
|
|
65
|
-
export { execute,
|
|
131
|
+
export { buildInsightsReport, execute, formatInsightsReport, runInsightsCommand };
|
|
@@ -1,58 +1,65 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { existsSync, rmSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { writeLinkedProject, LINKED_PROJECT_FILE } from '@lunora/config';
|
|
4
|
+
import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
|
|
5
|
+
import { r as readWranglerName } from '../packem_shared/wrangler-name-cy4yhm9j.mjs';
|
|
4
6
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return
|
|
11
|
-
}
|
|
12
|
-
const args = ["exec", "wrangler", "tail"];
|
|
13
|
-
if (options.worker !== void 0) {
|
|
14
|
-
args.push(options.worker);
|
|
15
|
-
}
|
|
16
|
-
const env = options.env ?? readLinkedProject(cwd)?.env;
|
|
17
|
-
if (env !== void 0) {
|
|
18
|
-
args.push("--env", env);
|
|
7
|
+
const isValidWorkerUrl = (value) => {
|
|
8
|
+
try {
|
|
9
|
+
const { protocol } = new URL(value);
|
|
10
|
+
return protocol === "http:" || protocol === "https:";
|
|
11
|
+
} catch {
|
|
12
|
+
return false;
|
|
19
13
|
}
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
};
|
|
15
|
+
const runLinkRemove = (cwd, logger) => {
|
|
16
|
+
const path = join(cwd, LINKED_PROJECT_FILE);
|
|
17
|
+
if (!existsSync(path)) {
|
|
18
|
+
logger.warn(`link: no ${LINKED_PROJECT_FILE} to remove`);
|
|
19
|
+
return { code: 0 };
|
|
22
20
|
}
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
rmSync(path);
|
|
22
|
+
logger.success(`link: removed ${LINKED_PROJECT_FILE}`);
|
|
23
|
+
return { code: 0 };
|
|
24
|
+
};
|
|
25
|
+
const runLinkCommand = (options) => {
|
|
26
|
+
const cwd = options.cwd ?? process.cwd();
|
|
27
|
+
const { logger } = options;
|
|
28
|
+
if (options.remove) {
|
|
29
|
+
return runLinkRemove(cwd, logger);
|
|
25
30
|
}
|
|
26
|
-
if (options.
|
|
27
|
-
|
|
31
|
+
if (options.url === void 0 || options.url === "") {
|
|
32
|
+
logger.error("link requires a deployed Worker URL. Usage: lunora link --url <https://your-worker>");
|
|
33
|
+
return { code: 1 };
|
|
28
34
|
}
|
|
29
|
-
if (options.
|
|
30
|
-
|
|
35
|
+
if (!isValidWorkerUrl(options.url)) {
|
|
36
|
+
logger.error(`link: invalid --url "${options.url}" — expected an http(s) URL`);
|
|
37
|
+
return { code: 1 };
|
|
31
38
|
}
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const spawner = options.spawner ?? defaultSpawner;
|
|
39
|
-
const result = await spawner(descriptor);
|
|
40
|
-
return {
|
|
41
|
-
code: result.code,
|
|
42
|
-
descriptor
|
|
39
|
+
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
40
|
+
const link = {
|
|
41
|
+
env: options.env,
|
|
42
|
+
linkedAt: now(),
|
|
43
|
+
workerName: options.name ?? readWranglerName(cwd),
|
|
44
|
+
workerUrl: options.url
|
|
43
45
|
};
|
|
46
|
+
const path = writeLinkedProject(cwd, link);
|
|
47
|
+
logger.success(`link: ${link.workerName ?? "(unnamed worker)"} -> ${options.url}`);
|
|
48
|
+
logger.info(`link: wrote ${path}`);
|
|
49
|
+
if (link.env !== void 0) {
|
|
50
|
+
logger.info(`link: environment "${link.env}"`);
|
|
51
|
+
}
|
|
52
|
+
return { code: 0, link };
|
|
44
53
|
};
|
|
45
54
|
const execute = defineHandler(
|
|
46
|
-
({
|
|
55
|
+
({ cwd, logger, options }) => runLinkCommand({
|
|
47
56
|
cwd,
|
|
48
57
|
env: options.env,
|
|
49
|
-
format: options.format,
|
|
50
58
|
logger,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
worker: argument[0]
|
|
59
|
+
name: options.name,
|
|
60
|
+
remove: options.remove === true,
|
|
61
|
+
url: options.url
|
|
55
62
|
})
|
|
56
63
|
);
|
|
57
64
|
|
|
58
|
-
export { execute,
|
|
65
|
+
export { execute, runLinkCommand };
|
|
@@ -1,79 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { d as defineHandler } from '../packem_shared/command-BDXcJCCJ.mjs';
|
|
5
|
-
import { r as runSchemaDriftGate } from '../packem_shared/schema-drift-gate-BtBt0as0.mjs';
|
|
1
|
+
import { readLinkedProject } from '@lunora/config';
|
|
2
|
+
import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
|
|
3
|
+
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-DxI3mebw.mjs';
|
|
6
4
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const inferred = await inferLunoraBindings({ projectRoot: cwd });
|
|
10
|
-
const reconciled = reconcileWranglerBindings(cwd, inferred);
|
|
11
|
-
if (reconciled.changed) {
|
|
12
|
-
logger.success(`provisioned bindings: ${reconciled.added.join(", ")} → ${reconciled.wranglerPath ?? "wrangler.jsonc"}`);
|
|
13
|
-
}
|
|
14
|
-
for (const warning of reconciled.warnings) {
|
|
15
|
-
logger.warn(warning);
|
|
16
|
-
}
|
|
17
|
-
} catch (error) {
|
|
18
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
19
|
-
logger.warn(`binding inference skipped: ${message}`);
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
const runPrepareCommand = async (options) => {
|
|
5
|
+
const LOG_FORMATS = /* @__PURE__ */ new Set(["json", "pretty"]);
|
|
6
|
+
const runLogsCommand = async (options) => {
|
|
23
7
|
const cwd = options.cwd ?? process.cwd();
|
|
24
|
-
options.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
8
|
+
if (options.format !== void 0 && !LOG_FORMATS.has(options.format)) {
|
|
9
|
+
options.logger.error(`logs: unknown --format "${options.format}" — expected pretty | json`);
|
|
10
|
+
return { code: 1, descriptor: void 0, error: "invalid format" };
|
|
11
|
+
}
|
|
12
|
+
const args = ["exec", "wrangler", "tail"];
|
|
13
|
+
if (options.worker !== void 0) {
|
|
14
|
+
args.push(options.worker);
|
|
15
|
+
}
|
|
16
|
+
const env = options.env ?? readLinkedProject(cwd)?.env;
|
|
17
|
+
if (env !== void 0) {
|
|
18
|
+
args.push("--env", env);
|
|
19
|
+
}
|
|
20
|
+
if (options.format !== void 0) {
|
|
21
|
+
args.push("--format", options.format);
|
|
22
|
+
}
|
|
23
|
+
if (options.status !== void 0) {
|
|
24
|
+
args.push("--status", options.status);
|
|
37
25
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
codegen,
|
|
41
|
-
logger: options.logger,
|
|
42
|
-
updateBaseline: options.updateSchemaBaseline === true
|
|
43
|
-
});
|
|
44
|
-
if (gate.blocked) {
|
|
45
|
-
return {
|
|
46
|
-
code: 1,
|
|
47
|
-
error: "schema drift gate blocked prepare",
|
|
48
|
-
schemaDrift: { blocked: true, reason: gate.reason },
|
|
49
|
-
validation: { problems: [], wranglerPath: void 0 }
|
|
50
|
-
};
|
|
26
|
+
if (options.search !== void 0) {
|
|
27
|
+
args.push("--search", options.search);
|
|
51
28
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (validation.problems.length > 0) {
|
|
55
|
-
options.logger.error("wrangler.jsonc validation failed:");
|
|
56
|
-
for (const problem of validation.problems) {
|
|
57
|
-
options.logger.error(` - ${problem}`);
|
|
58
|
-
}
|
|
59
|
-
return {
|
|
60
|
-
code: 1,
|
|
61
|
-
error: "wrangler validation failed",
|
|
62
|
-
validation
|
|
63
|
-
};
|
|
29
|
+
if (options.temporary) {
|
|
30
|
+
args.push("--temporary");
|
|
64
31
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
32
|
+
const descriptor = {
|
|
33
|
+
args,
|
|
34
|
+
command: "pnpm",
|
|
35
|
+
cwd
|
|
36
|
+
};
|
|
37
|
+
options.logger.info(`tailing logs via ${descriptor.command} ${descriptor.args.join(" ")}`);
|
|
38
|
+
const spawner = options.spawner ?? defaultSpawner;
|
|
39
|
+
const result = await spawner(descriptor);
|
|
40
|
+
return {
|
|
41
|
+
code: result.code,
|
|
42
|
+
descriptor
|
|
43
|
+
};
|
|
68
44
|
};
|
|
69
45
|
const execute = defineHandler(
|
|
70
|
-
({ cwd, logger, options }) =>
|
|
71
|
-
allowSchemaDrift: options.allowSchemaDrift === true,
|
|
72
|
-
apiSpec: parseApiSpec(options.apiSpec),
|
|
46
|
+
({ argument, cwd, logger, options }) => runLogsCommand({
|
|
73
47
|
cwd,
|
|
48
|
+
env: options.env,
|
|
49
|
+
format: options.format,
|
|
74
50
|
logger,
|
|
75
|
-
|
|
51
|
+
search: options.search,
|
|
52
|
+
status: options.status,
|
|
53
|
+
temporary: options.temporary === true,
|
|
54
|
+
worker: argument[0]
|
|
76
55
|
})
|
|
77
56
|
);
|
|
78
57
|
|
|
79
|
-
export { execute,
|
|
58
|
+
export { execute, runLogsCommand };
|
|
@@ -1,43 +1,79 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { runCodegen } from '@lunora/codegen';
|
|
2
|
+
import { validateWranglerProject, inferLunoraBindings, reconcileWranglerBindings } from '@lunora/config';
|
|
3
|
+
import { p as parseApiSpec } from '../packem_shared/api-spec-CtA6ilu4.mjs';
|
|
4
|
+
import { d as defineHandler } from '../packem_shared/command-D3lB_4Az.mjs';
|
|
5
|
+
import { r as runSchemaDriftGate } from '../packem_shared/schema-drift-gate-BtBt0as0.mjs';
|
|
3
6
|
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
overwrite: options.overwrite === true,
|
|
18
|
-
ref: options.ref,
|
|
19
|
-
source: options.source,
|
|
20
|
-
yes: options.yes === true
|
|
21
|
-
});
|
|
7
|
+
const provisionBindings = async (cwd, logger) => {
|
|
8
|
+
try {
|
|
9
|
+
const inferred = await inferLunoraBindings({ projectRoot: cwd });
|
|
10
|
+
const reconciled = reconcileWranglerBindings(cwd, inferred);
|
|
11
|
+
if (reconciled.changed) {
|
|
12
|
+
logger.success(`provisioned bindings: ${reconciled.added.join(", ")} → ${reconciled.wranglerPath ?? "wrangler.jsonc"}`);
|
|
13
|
+
}
|
|
14
|
+
for (const warning of reconciled.warnings) {
|
|
15
|
+
logger.warn(warning);
|
|
16
|
+
}
|
|
17
|
+
} catch (error) {
|
|
18
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
19
|
+
logger.warn(`binding inference skipped: ${message}`);
|
|
22
20
|
}
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
};
|
|
22
|
+
const runPrepareCommand = async (options) => {
|
|
23
|
+
const cwd = options.cwd ?? process.cwd();
|
|
24
|
+
options.logger.info("running codegen");
|
|
25
|
+
let codegen;
|
|
26
|
+
try {
|
|
27
|
+
codegen = runCodegen({ apiSpec: options.apiSpec, projectRoot: cwd });
|
|
28
|
+
options.logger.success("codegen complete");
|
|
29
|
+
} catch (error) {
|
|
30
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
31
|
+
options.logger.error(`codegen failed: ${message}`);
|
|
32
|
+
return {
|
|
33
|
+
code: 1,
|
|
34
|
+
error: `codegen failed: ${message}`,
|
|
35
|
+
validation: { problems: [], wranglerPath: void 0 }
|
|
36
|
+
};
|
|
25
37
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
38
|
+
const gate = runSchemaDriftGate({
|
|
39
|
+
allowDrift: options.allowSchemaDrift === true,
|
|
40
|
+
codegen,
|
|
41
|
+
logger: options.logger,
|
|
42
|
+
updateBaseline: options.updateSchemaBaseline === true
|
|
43
|
+
});
|
|
44
|
+
if (gate.blocked) {
|
|
45
|
+
return {
|
|
46
|
+
code: 1,
|
|
47
|
+
error: "schema drift gate blocked prepare",
|
|
48
|
+
schemaDrift: { blocked: true, reason: gate.reason },
|
|
49
|
+
validation: { problems: [], wranglerPath: void 0 }
|
|
50
|
+
};
|
|
35
51
|
}
|
|
36
|
-
|
|
37
|
-
|
|
52
|
+
await provisionBindings(cwd, options.logger);
|
|
53
|
+
const validation = validateWranglerProject({ projectRoot: cwd });
|
|
54
|
+
if (validation.problems.length > 0) {
|
|
55
|
+
options.logger.error("wrangler.jsonc validation failed:");
|
|
56
|
+
for (const problem of validation.problems) {
|
|
57
|
+
options.logger.error(` - ${problem}`);
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
code: 1,
|
|
61
|
+
error: "wrangler validation failed",
|
|
62
|
+
validation
|
|
63
|
+
};
|
|
38
64
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
65
|
+
gate.rebless?.();
|
|
66
|
+
options.logger.success("project is ready to deploy");
|
|
67
|
+
return { code: 0, validation };
|
|
68
|
+
};
|
|
69
|
+
const execute = defineHandler(
|
|
70
|
+
({ cwd, logger, options }) => runPrepareCommand({
|
|
71
|
+
allowSchemaDrift: options.allowSchemaDrift === true,
|
|
72
|
+
apiSpec: parseApiSpec(options.apiSpec),
|
|
73
|
+
cwd,
|
|
74
|
+
logger,
|
|
75
|
+
updateSchemaBaseline: options.updateSchemaBaseline === true
|
|
76
|
+
})
|
|
77
|
+
);
|
|
42
78
|
|
|
43
|
-
export { execute };
|
|
79
|
+
export { execute, runPrepareCommand };
|