@lunora/cli 1.0.0-alpha.10 → 1.0.0-alpha.100
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 +345 -320
- package/dist/index.d.ts +345 -320
- package/dist/index.mjs +8 -9
- package/dist/packem_chunks/handler.mjs +15 -5
- package/dist/packem_chunks/handler10.mjs +8 -14
- package/dist/packem_chunks/handler11.mjs +20 -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 +27 -6
- package/dist/packem_chunks/handler16.mjs +3 -2
- package/dist/packem_chunks/handler17.mjs +1 -1
- package/dist/packem_chunks/handler18.mjs +3 -3
- package/dist/packem_chunks/handler19.mjs +44 -5
- package/dist/packem_chunks/handler2.mjs +6 -4
- package/dist/packem_chunks/handler20.mjs +2 -2
- package/dist/packem_chunks/handler21.mjs +158 -267
- package/dist/packem_chunks/handler3.mjs +8 -4
- 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 +330 -12
- package/dist/packem_chunks/planDevCommand.mjs +762 -81
- package/dist/packem_chunks/runCodegenCommand.mjs +5 -4
- package/dist/packem_chunks/runDeployCommand.mjs +137 -22
- package/dist/packem_chunks/runInitCommand.mjs +1193 -98
- package/dist/packem_chunks/runMigrateGenerateCommand.mjs +94 -47
- package/dist/packem_chunks/runResetCommand.mjs +2 -2
- package/dist/packem_chunks/runRpcCommand.mjs +3 -2
- package/dist/packem_shared/{COMMANDS-D3h9Iwvl.mjs → COMMANDS-BOJIDoVY.mjs} +112 -25
- package/dist/packem_shared/{DEFAULT_IMPORT_BATCH_SIZE-Ck-2bU08.mjs → DEFAULT_IMPORT_BATCH_SIZE-D0VOTerB.mjs} +7 -2
- package/dist/packem_shared/{api-spec-CtA6ilu4.mjs → api-spec-Bx0iKbxA.mjs} +3 -1
- package/dist/packem_shared/{buildRegistryIndex-BcYe607_.mjs → buildRegistryIndex-BS5ig822.mjs} +1 -1
- package/dist/packem_shared/codegen-error-DJG-ghs_.mjs +31 -0
- package/dist/packem_shared/{command-BC30oSBW.mjs → command-lYnl4QyF.mjs} +6 -1
- package/dist/packem_shared/{commands-DPKWlqqX.mjs → commands-D5Yxt9VY.mjs} +199 -20
- package/dist/packem_shared/{createLogger-B40gPzQo.mjs → createLogger-CIWSHrTL.mjs} +33 -6
- package/dist/packem_shared/{createRecordingSpawner-DxI3mebw.mjs → createRecordingSpawner-WuSn20kb.mjs} +23 -2
- package/dist/packem_shared/detect-package-manager-v4hHpQd0.mjs +62 -0
- 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-wUvAN6AL.mjs → output-format-B4642rjE.mjs} +1 -1
- package/dist/packem_shared/{parseManifest--vZf2FY1.mjs → parseManifest-Dbp-Q2q3.mjs} +36 -9
- package/dist/packem_shared/prompt-cancelled-APzX1Im-.mjs +9 -0
- package/dist/packem_shared/runAddCommand-D1hgfqFQ.mjs +4 -0
- package/dist/packem_shared/{storage-2RJBhUC4.mjs → storage-BXU4ax4O.mjs} +1 -1
- package/dist/packem_shared/{tui-prompts-DEiPCKV-.mjs → tui-prompts-BjEN8XgP.mjs} +9 -12
- package/dist/packem_shared/wrangler-secrets-Coni-mER.mjs +49 -0
- package/package.json +19 -14
- package/skills/lunora-quickstart/SKILL.md +26 -5
- package/dist/packem_shared/detect-package-manager-DYp7n3mJ.mjs +0 -61
- package/dist/packem_shared/parseArgs-YXFuKdEk.mjs +0 -56
- package/dist/packem_shared/runAddCommand-CTRA_JlL.mjs +0 -4
|
@@ -1,311 +1,202 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { readLinkedProject } from '@lunora/config';
|
|
2
|
+
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
3
|
+
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-v4hHpQd0.mjs';
|
|
4
|
+
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-WuSn20kb.mjs';
|
|
5
|
+
import { createR2Sql } from '@lunora/bindings/r2sql';
|
|
6
|
+
import { createPipelineLogReader } from '@lunora/runtime';
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return typeof error.code === "number" ? error.code : 1;
|
|
13
|
-
};
|
|
14
|
-
const defaultRunner = (command, args, cwd) => new Promise((resolve) => {
|
|
15
|
-
execFile(command, [...args], { cwd }, (error, stdout, stderr) => {
|
|
16
|
-
resolve({ code: execCode(error), stderr, stdout });
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
const parseSecretNames = (stdout) => {
|
|
20
|
-
let parsed;
|
|
21
|
-
try {
|
|
22
|
-
parsed = JSON.parse(stdout);
|
|
23
|
-
} catch {
|
|
8
|
+
const LOG_LEVELS = /* @__PURE__ */ new Set(["debug", "error", "fatal", "info", "log", "trace", "warn"]);
|
|
9
|
+
const EPOCH_MILLIS_RE = /^\d+$/;
|
|
10
|
+
const parseTimestamp = (value, flag) => {
|
|
11
|
+
if (value === void 0) {
|
|
24
12
|
return void 0;
|
|
25
13
|
}
|
|
26
|
-
|
|
27
|
-
|
|
14
|
+
const trimmed = value.trim();
|
|
15
|
+
if (EPOCH_MILLIS_RE.test(trimmed)) {
|
|
16
|
+
return Number(trimmed);
|
|
28
17
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
};
|
|
32
|
-
const listRemoteSecrets = async (inputs) => {
|
|
33
|
-
const args = ["exec", "wrangler", "secret", "list", "--format", "json"];
|
|
34
|
-
if (inputs.env !== void 0) {
|
|
35
|
-
args.push("--env", inputs.env);
|
|
36
|
-
}
|
|
37
|
-
if (inputs.temporary) {
|
|
38
|
-
args.push("--temporary");
|
|
39
|
-
}
|
|
40
|
-
const runner = inputs.runner ?? defaultRunner;
|
|
41
|
-
const result = await runner("pnpm", args, inputs.cwd);
|
|
42
|
-
if (result.code !== 0) {
|
|
43
|
-
return { error: result.stderr.trim() || `wrangler secret list exited ${String(result.code)}`, names: [], ok: false };
|
|
44
|
-
}
|
|
45
|
-
const names = parseSecretNames(result.stdout);
|
|
46
|
-
if (names === void 0) {
|
|
47
|
-
return { error: "could not parse `wrangler secret list --format json` output", names: [], ok: false };
|
|
48
|
-
}
|
|
49
|
-
return { names, ok: true };
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
const NEWLINE_PRESENT = /[\r\n]/u;
|
|
53
|
-
const UNREPRESENTABLE_PRESENT = /["\\]/u;
|
|
54
|
-
const parseDevVariables = (content) => {
|
|
55
|
-
const map = /* @__PURE__ */ new Map();
|
|
56
|
-
for (const entry of parseDevVariableEntries(content)) {
|
|
57
|
-
map.set(entry.key, entry);
|
|
18
|
+
const parsed = Date.parse(trimmed);
|
|
19
|
+
if (Number.isNaN(parsed)) {
|
|
20
|
+
throw new TypeError(`logs: invalid ${flag} "${value}" — pass epoch-millis or an ISO 8601 date`);
|
|
58
21
|
}
|
|
59
|
-
return
|
|
22
|
+
return parsed;
|
|
60
23
|
};
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
lines.push(`${entry.key}="${entry.value}"`);
|
|
24
|
+
const parseLevel = (value, flag) => {
|
|
25
|
+
if (value === void 0) {
|
|
26
|
+
return void 0;
|
|
65
27
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
};
|
|
69
|
-
const redact = (value) => {
|
|
70
|
-
if (value.length <= 4) {
|
|
71
|
-
return "****";
|
|
28
|
+
if (!LOG_LEVELS.has(value)) {
|
|
29
|
+
throw new TypeError(`logs: invalid ${flag} "${value}" — expected one of trace, debug, log, info, warn, error, fatal`);
|
|
72
30
|
}
|
|
73
|
-
return
|
|
31
|
+
return value;
|
|
74
32
|
};
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
33
|
+
const buildQuery = (options) => {
|
|
34
|
+
const query = {};
|
|
35
|
+
const sinceTs = parseTimestamp(options.since, "--since");
|
|
36
|
+
if (sinceTs !== void 0) {
|
|
37
|
+
query.sinceTs = sinceTs;
|
|
78
38
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const map = loadDevVariables(context.devVariablesPath);
|
|
83
|
-
if (map.size === 0) {
|
|
84
|
-
context.logger.info(`${DEV_VARS_FILE}: (empty)`);
|
|
85
|
-
return { code: 0, descriptors: [] };
|
|
39
|
+
const untilTs = parseTimestamp(options.until, "--until");
|
|
40
|
+
if (untilTs !== void 0) {
|
|
41
|
+
query.untilTs = untilTs;
|
|
86
42
|
}
|
|
87
|
-
|
|
88
|
-
|
|
43
|
+
const level = parseLevel(options.level, "--level");
|
|
44
|
+
if (level !== void 0) {
|
|
45
|
+
query.level = level;
|
|
89
46
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const { devVariablesPath, logger, options } = context;
|
|
94
|
-
if (!options.key) {
|
|
95
|
-
logger.error("env get requires a key. Usage: lunora env get <KEY>");
|
|
96
|
-
return { code: 1, descriptors: [] };
|
|
47
|
+
const minLevel = parseLevel(options.minLevel, "--min-level");
|
|
48
|
+
if (minLevel !== void 0) {
|
|
49
|
+
query.minLevel = minLevel;
|
|
97
50
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
logger.error(`env: ${options.key} is not set in ${DEV_VARS_FILE}`);
|
|
101
|
-
return { code: 1, descriptors: [] };
|
|
51
|
+
if (options.functionPrefix !== void 0) {
|
|
52
|
+
query.functionPathPrefix = options.functionPrefix;
|
|
102
53
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return { code: 0, descriptors: [] };
|
|
106
|
-
};
|
|
107
|
-
const runEnvSet = (context) => {
|
|
108
|
-
const { devVariablesPath, logger, options } = context;
|
|
109
|
-
if (!options.key) {
|
|
110
|
-
logger.error("env set requires a key. Usage: lunora env set <KEY> <VALUE>");
|
|
111
|
-
return { code: 1, descriptors: [] };
|
|
54
|
+
if (options.traceId !== void 0) {
|
|
55
|
+
query.traceId = options.traceId;
|
|
112
56
|
}
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
return { code: 1, descriptors: [] };
|
|
57
|
+
if (options.shardKey !== void 0) {
|
|
58
|
+
query.shardKey = options.shardKey;
|
|
116
59
|
}
|
|
117
|
-
if (options.
|
|
118
|
-
|
|
119
|
-
return { code: 1, descriptors: [] };
|
|
60
|
+
if (options.userId !== void 0) {
|
|
61
|
+
query.userId = options.userId;
|
|
120
62
|
}
|
|
121
|
-
if (
|
|
122
|
-
|
|
123
|
-
|
|
63
|
+
if (options.limit !== void 0) {
|
|
64
|
+
const limit = Number(options.limit);
|
|
65
|
+
if (!Number.isFinite(limit)) {
|
|
66
|
+
throw new TypeError(`logs: invalid --limit "${options.limit}" — expected a number`);
|
|
67
|
+
}
|
|
68
|
+
query.limit = limit;
|
|
124
69
|
}
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
70
|
+
if (options.cursor !== void 0) {
|
|
71
|
+
const cursorTs = Number(options.cursor);
|
|
72
|
+
if (!Number.isFinite(cursorTs)) {
|
|
73
|
+
throw new TypeError(`logs: invalid --cursor "${options.cursor}" — expected the epoch-millis ts from a prior page's nextCursor`);
|
|
74
|
+
}
|
|
75
|
+
query.cursor = { ts: cursorTs };
|
|
128
76
|
}
|
|
129
|
-
|
|
130
|
-
map.set(options.key, { key: options.key, value: options.value });
|
|
131
|
-
writeFileSync(devVariablesPath, serializeDevVariables(map), "utf8");
|
|
132
|
-
logger.success(`env: set ${options.key} (${redact(options.value)}) in ${DEV_VARS_FILE}`);
|
|
133
|
-
return { code: 0, descriptors: [] };
|
|
77
|
+
return query;
|
|
134
78
|
};
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return { code: 1, descriptors: [] };
|
|
140
|
-
}
|
|
141
|
-
const map = loadDevVariables(devVariablesPath);
|
|
142
|
-
if (!map.delete(options.key)) {
|
|
143
|
-
logger.warn(`env: ${options.key} was not set in ${DEV_VARS_FILE}`);
|
|
144
|
-
return { code: 0, descriptors: [] };
|
|
145
|
-
}
|
|
146
|
-
writeFileSync(devVariablesPath, serializeDevVariables(map), "utf8");
|
|
147
|
-
logger.success(`env: unset ${options.key} in ${DEV_VARS_FILE}`);
|
|
148
|
-
return { code: 0, descriptors: [] };
|
|
79
|
+
const formatRow = (row) => {
|
|
80
|
+
const time = new Date(row.ts).toISOString();
|
|
81
|
+
const level = row.level.toUpperCase().padEnd(5);
|
|
82
|
+
return `${time} ${level} ${row.functionPath} ${row.message}`;
|
|
149
83
|
};
|
|
150
|
-
const
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
84
|
+
const runDurableLogsCommand = async (options) => {
|
|
85
|
+
const environment = options.environment ?? process.env;
|
|
86
|
+
const accountId = environment.R2_SQL_ACCOUNT_ID;
|
|
87
|
+
const apiToken = environment.R2_SQL_TOKEN;
|
|
88
|
+
const bucket = environment.R2_SQL_BUCKET;
|
|
89
|
+
const missing = [];
|
|
90
|
+
if (accountId === void 0 || accountId.length === 0) {
|
|
91
|
+
missing.push("R2_SQL_ACCOUNT_ID");
|
|
155
92
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
logger.warn(`${DEV_VARS_FILE}: nothing to push (empty)`);
|
|
159
|
-
return { code: 0, descriptors: [] };
|
|
93
|
+
if (apiToken === void 0 || apiToken.length === 0) {
|
|
94
|
+
missing.push("R2_SQL_TOKEN");
|
|
160
95
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
for (const entry of map.values()) {
|
|
164
|
-
const args = ["exec", "wrangler", "secret", "put", entry.key];
|
|
165
|
-
if (options.prod) {
|
|
166
|
-
args.push("--env", "production");
|
|
167
|
-
}
|
|
168
|
-
if (options.temporary) {
|
|
169
|
-
args.push("--temporary");
|
|
170
|
-
}
|
|
171
|
-
const descriptor = {
|
|
172
|
-
args,
|
|
173
|
-
command: "pnpm",
|
|
174
|
-
cwd: options.cwd ?? process.cwd(),
|
|
175
|
-
// `wrangler secret put <name>` reads the value from stdin. We
|
|
176
|
-
// pipe it through the spawner's `input` channel so the secret
|
|
177
|
-
// never lands on the command line, in env, or in shell history.
|
|
178
|
-
input: entry.value
|
|
179
|
-
};
|
|
180
|
-
descriptors.push(descriptor);
|
|
181
|
-
logger.info(`pushing ${entry.key} -> wrangler secret${options.prod ? " (production)" : ""}`);
|
|
182
|
-
const result = await spawner(descriptor);
|
|
183
|
-
if (result.code !== 0) {
|
|
184
|
-
logger.error(`env push: failed at ${entry.key} (exit ${String(result.code)})`);
|
|
185
|
-
return { code: result.code, descriptors };
|
|
186
|
-
}
|
|
96
|
+
if (bucket === void 0 || bucket.length === 0) {
|
|
97
|
+
missing.push("R2_SQL_BUCKET");
|
|
187
98
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
};
|
|
191
|
-
const fetchRemoteSecretNames = (context) => {
|
|
192
|
-
const lister = context.options.secretLister ?? listRemoteSecrets;
|
|
193
|
-
return lister({
|
|
194
|
-
cwd: context.cwd,
|
|
195
|
-
env: context.options.prod ? "production" : void 0,
|
|
196
|
-
temporary: context.options.temporary
|
|
197
|
-
});
|
|
198
|
-
};
|
|
199
|
-
const runEnvDiff = async (context) => {
|
|
200
|
-
const { devVariablesPath, logger } = context;
|
|
201
|
-
const remote = await fetchRemoteSecretNames(context);
|
|
202
|
-
if (!remote.ok) {
|
|
203
|
-
logger.error(`env diff: ${remote.error ?? "failed to list remote secrets"}`);
|
|
204
|
-
return { code: 1, descriptors: [] };
|
|
99
|
+
if (options.table === void 0 || options.table.length === 0) {
|
|
100
|
+
missing.push("--table");
|
|
205
101
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
for (const key of localOnly) {
|
|
212
|
-
logger.info(`local only (run \`lunora env push\`): ${key}`);
|
|
102
|
+
if (missing.length > 0) {
|
|
103
|
+
options.logger.error(
|
|
104
|
+
`logs --durable: R2 SQL not configured (missing ${missing.join(", ")}). The Pipeline must write to an R2 Data Catalog (Iceberg) table, and you must supply R2_SQL_ACCOUNT_ID / R2_SQL_TOKEN / R2_SQL_BUCKET plus --table — see the observability docs.`
|
|
105
|
+
);
|
|
106
|
+
return { code: 1, error: "not configured" };
|
|
213
107
|
}
|
|
214
|
-
|
|
215
|
-
|
|
108
|
+
let query;
|
|
109
|
+
try {
|
|
110
|
+
query = buildQuery(options);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
options.logger.error(error instanceof Error ? error.message : String(error));
|
|
113
|
+
return { code: 1, error: "invalid option" };
|
|
114
|
+
}
|
|
115
|
+
const client = createR2Sql({ accountId, apiToken, bucket, fetch: options.fetch });
|
|
116
|
+
const reader = createPipelineLogReader(client, { namespace: options.namespace, table: options.table });
|
|
117
|
+
const page = await reader.query(query);
|
|
118
|
+
for (const row of page.rows) {
|
|
119
|
+
process.stdout.write(`${options.ndjson === true ? JSON.stringify(row) : formatRow(row)}
|
|
120
|
+
`);
|
|
216
121
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
122
|
+
if (page.rows.length === 0) {
|
|
123
|
+
options.logger.info("logs --durable: no matching log records");
|
|
124
|
+
} else if (page.nextCursor !== void 0) {
|
|
125
|
+
options.logger.info(`logs --durable: more rows available — pass --cursor ${String(page.nextCursor.ts)} for the next page`);
|
|
220
126
|
}
|
|
221
|
-
return { code: 0,
|
|
127
|
+
return { code: 0, rows: page.rows };
|
|
222
128
|
};
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
129
|
+
|
|
130
|
+
const LOG_FORMATS = /* @__PURE__ */ new Set(["json", "pretty"]);
|
|
131
|
+
const runLogsCommand = async (options) => {
|
|
132
|
+
const cwd = options.cwd ?? process.cwd();
|
|
133
|
+
if (options.format !== void 0 && !LOG_FORMATS.has(options.format)) {
|
|
134
|
+
options.logger.error(`logs: unknown --format "${options.format}" — expected pretty | json`);
|
|
135
|
+
return { code: 1, descriptor: void 0, error: "invalid format" };
|
|
229
136
|
}
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
logger.error(`env doctor: ${DEV_VARS_FILE} is missing. Run \`lunora dev\` to scaffold it, or \`lunora env set <KEY> <VALUE>\`.`);
|
|
234
|
-
logger.info(`expected (from ${DEV_VARS_EXAMPLE_FILE}): ${exampleKeys.join(", ")}`);
|
|
235
|
-
return { code: 1, descriptors: [] };
|
|
137
|
+
const args = ["tail"];
|
|
138
|
+
if (options.worker !== void 0) {
|
|
139
|
+
args.push(options.worker);
|
|
236
140
|
}
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
const extra = [...current.keys()].filter((key) => !exampleKeySet.has(key));
|
|
241
|
-
for (const key of missing) {
|
|
242
|
-
logger.error(`missing: ${key} is in ${DEV_VARS_EXAMPLE_FILE} but not ${DEV_VARS_FILE}`);
|
|
141
|
+
const env = options.env ?? readLinkedProject(cwd)?.env;
|
|
142
|
+
if (env !== void 0) {
|
|
143
|
+
args.push("--env", env);
|
|
243
144
|
}
|
|
244
|
-
|
|
245
|
-
|
|
145
|
+
if (options.format !== void 0) {
|
|
146
|
+
args.push("--format", options.format);
|
|
246
147
|
}
|
|
247
|
-
|
|
248
|
-
|
|
148
|
+
if (options.status !== void 0) {
|
|
149
|
+
args.push("--status", options.status);
|
|
249
150
|
}
|
|
250
|
-
if (
|
|
251
|
-
|
|
252
|
-
return { code: 0, descriptors: [] };
|
|
151
|
+
if (options.search !== void 0) {
|
|
152
|
+
args.push("--search", options.search);
|
|
253
153
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const runEnvCommand = async (options) => {
|
|
257
|
-
const cwd = options.cwd ?? process.cwd();
|
|
258
|
-
const context = {
|
|
259
|
-
cwd,
|
|
260
|
-
devVariablesPath: join(cwd, DEV_VARS_FILE),
|
|
261
|
-
logger: options.logger,
|
|
262
|
-
options
|
|
263
|
-
};
|
|
264
|
-
switch (options.subcommand) {
|
|
265
|
-
case "diff": {
|
|
266
|
-
return runEnvDiff(context);
|
|
267
|
-
}
|
|
268
|
-
case "doctor": {
|
|
269
|
-
return runEnvDoctor(context);
|
|
270
|
-
}
|
|
271
|
-
case "get": {
|
|
272
|
-
return runEnvGet(context);
|
|
273
|
-
}
|
|
274
|
-
case "list": {
|
|
275
|
-
return runEnvList(context);
|
|
276
|
-
}
|
|
277
|
-
case "push": {
|
|
278
|
-
return runEnvPush(context);
|
|
279
|
-
}
|
|
280
|
-
case "set": {
|
|
281
|
-
return runEnvSet(context);
|
|
282
|
-
}
|
|
283
|
-
case "unset": {
|
|
284
|
-
return runEnvUnset(context);
|
|
285
|
-
}
|
|
286
|
-
default: {
|
|
287
|
-
options.logger.error(`env: unknown subcommand "${options.subcommand}"`);
|
|
288
|
-
return { code: 1, descriptors: [] };
|
|
289
|
-
}
|
|
154
|
+
if (options.temporary) {
|
|
155
|
+
args.push("--temporary");
|
|
290
156
|
}
|
|
157
|
+
const exec = execArgsFor(detectPackageManager(cwd), "wrangler", args);
|
|
158
|
+
const descriptor = {
|
|
159
|
+
args: exec.args,
|
|
160
|
+
command: exec.command,
|
|
161
|
+
cwd
|
|
162
|
+
};
|
|
163
|
+
options.logger.info(`tailing logs via ${descriptor.command} ${descriptor.args.join(" ")}`);
|
|
164
|
+
const spawner = options.spawner ?? defaultSpawner;
|
|
165
|
+
const result = await spawner(descriptor);
|
|
166
|
+
return {
|
|
167
|
+
code: result.code,
|
|
168
|
+
descriptor
|
|
169
|
+
};
|
|
291
170
|
};
|
|
292
|
-
const isEnvSubcommand = (value) => value === "list" || value === "get" || value === "set" || value === "unset" || value === "push" || value === "diff" || value === "doctor";
|
|
293
171
|
const execute = defineHandler(({ argument, cwd, logger, options }) => {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
172
|
+
if (options.durable === true) {
|
|
173
|
+
return runDurableLogsCommand({
|
|
174
|
+
cursor: options.cursor,
|
|
175
|
+
functionPrefix: options.functionPrefix,
|
|
176
|
+
level: options.level,
|
|
177
|
+
limit: options.limit,
|
|
178
|
+
logger,
|
|
179
|
+
minLevel: options.minLevel,
|
|
180
|
+
namespace: options.namespace,
|
|
181
|
+
ndjson: options.ndjson === true,
|
|
182
|
+
shardKey: options.shardKey,
|
|
183
|
+
since: options.since,
|
|
184
|
+
table: options.table,
|
|
185
|
+
traceId: options.traceId,
|
|
186
|
+
until: options.until,
|
|
187
|
+
userId: options.userId
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
return runLogsCommand({
|
|
300
191
|
cwd,
|
|
301
|
-
|
|
192
|
+
env: options.env,
|
|
193
|
+
format: options.format,
|
|
302
194
|
logger,
|
|
303
|
-
|
|
304
|
-
|
|
195
|
+
search: options.search,
|
|
196
|
+
status: options.status,
|
|
305
197
|
temporary: options.temporary === true,
|
|
306
|
-
|
|
307
|
-
yes: options.yes === true
|
|
198
|
+
worker: argument[0]
|
|
308
199
|
});
|
|
309
200
|
});
|
|
310
201
|
|
|
311
|
-
export { execute,
|
|
202
|
+
export { execute, runLogsCommand };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
+
import { LunoraError } from '@lunora/errors';
|
|
4
5
|
import { r as resolveAdminBaseUrl } from '../packem_shared/admin-url-4UzT-CI4.mjs';
|
|
5
|
-
import { d as defineHandler } from '../packem_shared/command-
|
|
6
|
+
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
6
7
|
import { a as resolveProductionWorkerUrl } from '../packem_shared/resolve-target-qbsJ_5sF.mjs';
|
|
7
|
-
import { runExportCommand, runImportCommand } from '../packem_shared/DEFAULT_IMPORT_BATCH_SIZE-
|
|
8
|
+
import { runExportCommand, runImportCommand } from '../packem_shared/DEFAULT_IMPORT_BATCH_SIZE-D0VOTerB.mjs';
|
|
8
9
|
|
|
9
10
|
const DEFAULT_BACKUP_DIR = ".lunora-backups";
|
|
10
11
|
const MANIFEST_FILE = "manifest.json";
|
|
@@ -22,7 +23,9 @@ const readManifest = async (directory) => {
|
|
|
22
23
|
parsed = JSON.parse(await readFile(path, "utf8"));
|
|
23
24
|
} catch (error) {
|
|
24
25
|
const message = error instanceof Error ? error.message : String(error);
|
|
25
|
-
throw new
|
|
26
|
+
throw new LunoraError("INTERNAL", `backup: ${path} exists but is not valid JSON (${message}) — refusing to overwrite it; fix or remove it manually`, {
|
|
27
|
+
cause: error
|
|
28
|
+
});
|
|
26
29
|
}
|
|
27
30
|
if (!Array.isArray(parsed)) {
|
|
28
31
|
throw new TypeError(`backup: ${path} exists but is not a JSON array — refusing to overwrite it; fix or remove it manually`);
|
|
@@ -86,7 +89,8 @@ const runBackupRestore = async (options, directory) => {
|
|
|
86
89
|
logger: options.logger,
|
|
87
90
|
prod: options.prod,
|
|
88
91
|
token: options.token,
|
|
89
|
-
url: options.url
|
|
92
|
+
url: options.url,
|
|
93
|
+
yes: options.yes
|
|
90
94
|
});
|
|
91
95
|
return { code: result.code };
|
|
92
96
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { p as parseApiSpec } from '../packem_shared/api-spec-
|
|
2
|
-
import { d as defineHandler } from '../packem_shared/command-
|
|
1
|
+
import { p as parseApiSpec } from '../packem_shared/api-spec-Bx0iKbxA.mjs';
|
|
2
|
+
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
3
3
|
import { runDeployCommand } from './runDeployCommand.mjs';
|
|
4
4
|
|
|
5
5
|
const DEFAULT_OUT_DIR = ".lunora/build";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { d as defineHandler } from '../packem_shared/command-
|
|
1
|
+
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
2
|
+
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-v4hHpQd0.mjs';
|
|
2
3
|
import { i as isDockerAvailable } from '../packem_shared/docker-hMQ97KSQ.mjs';
|
|
3
|
-
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-
|
|
4
|
+
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-WuSn20kb.mjs';
|
|
4
5
|
|
|
5
6
|
const SUBCOMMANDS = /* @__PURE__ */ new Set(["build", "delete", "images", "info", "list", "push"]);
|
|
6
7
|
const NEEDS_DOCKER = /* @__PURE__ */ new Set(["build", "push"]);
|
|
@@ -18,7 +19,7 @@ const runContainersCommand = async (options) => {
|
|
|
18
19
|
);
|
|
19
20
|
return { code: 1 };
|
|
20
21
|
}
|
|
21
|
-
const args = ["
|
|
22
|
+
const args = ["containers", subcommand, ...rest];
|
|
22
23
|
if (options.tag !== void 0) {
|
|
23
24
|
args.push("--tag", options.tag);
|
|
24
25
|
}
|
|
@@ -28,7 +29,9 @@ const runContainersCommand = async (options) => {
|
|
|
28
29
|
if (options.env !== void 0) {
|
|
29
30
|
args.push("--env", options.env);
|
|
30
31
|
}
|
|
31
|
-
const
|
|
32
|
+
const cwd = options.cwd ?? process.cwd();
|
|
33
|
+
const exec = execArgsFor(detectPackageManager(cwd), "wrangler", args);
|
|
34
|
+
const descriptor = { args: exec.args, command: exec.command, cwd };
|
|
32
35
|
options.logger.info(`running ${descriptor.command} ${descriptor.args.join(" ")}`);
|
|
33
36
|
const spawner = options.spawner ?? defaultSpawner;
|
|
34
37
|
const result = await spawner(descriptor);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { d as defineHandler } from '../packem_shared/command-
|
|
2
|
-
import {
|
|
1
|
+
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
2
|
+
import { e as execArgsFor, d as detectPackageManager } from '../packem_shared/detect-package-manager-v4hHpQd0.mjs';
|
|
3
|
+
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-WuSn20kb.mjs';
|
|
3
4
|
|
|
4
5
|
const withEnv = (args, env) => {
|
|
5
6
|
if (env !== void 0) {
|
|
@@ -8,7 +9,7 @@ const withEnv = (args, env) => {
|
|
|
8
9
|
return args;
|
|
9
10
|
};
|
|
10
11
|
const buildListArgs = (options) => {
|
|
11
|
-
const args = withEnv(["
|
|
12
|
+
const args = withEnv(["deployments", "list"], options.env);
|
|
12
13
|
if (options.json) {
|
|
13
14
|
args.push("--json");
|
|
14
15
|
}
|
|
@@ -20,7 +21,7 @@ const buildArgs = (options) => {
|
|
|
20
21
|
if (options.versionId === void 0) {
|
|
21
22
|
return { error: "deployments inspect requires a version id. Usage: lunora deployments inspect <version-id>" };
|
|
22
23
|
}
|
|
23
|
-
return { args: withEnv(["
|
|
24
|
+
return { args: withEnv(["versions", "view", options.versionId], options.env) };
|
|
24
25
|
}
|
|
25
26
|
case "list": {
|
|
26
27
|
return { args: buildListArgs(options) };
|
|
@@ -32,7 +33,7 @@ const buildArgs = (options) => {
|
|
|
32
33
|
if (!options.yes) {
|
|
33
34
|
return { error: "deployments promote shifts 100% of live traffic. Re-run with --yes to confirm." };
|
|
34
35
|
}
|
|
35
|
-
const args = withEnv(["
|
|
36
|
+
const args = withEnv(["versions", "deploy", `${options.versionId}@100%`, "--yes"], options.env);
|
|
36
37
|
if (options.message !== void 0) {
|
|
37
38
|
args.push("--message", options.message);
|
|
38
39
|
}
|
|
@@ -42,7 +43,7 @@ const buildArgs = (options) => {
|
|
|
42
43
|
if (!options.yes) {
|
|
43
44
|
return { error: "deployments rollback changes the live version. Re-run with --yes to confirm." };
|
|
44
45
|
}
|
|
45
|
-
const args = withEnv(["
|
|
46
|
+
const args = withEnv(["rollback"], options.env);
|
|
46
47
|
if (options.versionId !== void 0) {
|
|
47
48
|
args.push(options.versionId);
|
|
48
49
|
}
|
|
@@ -63,7 +64,9 @@ const runDeploymentsCommand = async (options) => {
|
|
|
63
64
|
options.logger.error(error ?? "deployments: nothing to run");
|
|
64
65
|
return { code: 1, descriptor: void 0, error };
|
|
65
66
|
}
|
|
66
|
-
const
|
|
67
|
+
const cwd = options.cwd ?? process.cwd();
|
|
68
|
+
const exec = execArgsFor(detectPackageManager(cwd), "wrangler", args);
|
|
69
|
+
const descriptor = { args: exec.args, command: exec.command, cwd };
|
|
67
70
|
options.logger.info(`${descriptor.command} ${descriptor.args.join(" ")}`);
|
|
68
71
|
const spawner = options.spawner ?? defaultSpawner;
|
|
69
72
|
const result = await spawner(descriptor);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as defineHandler } from '../packem_shared/command-
|
|
2
|
-
import { o as openUrl } from '../packem_shared/open-url-
|
|
1
|
+
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
2
|
+
import { o as openUrl } from '../packem_shared/open-url-4PBLY9X0.mjs';
|
|
3
3
|
|
|
4
4
|
const DEFAULT_DOCS_URL = "https://lunora.anolilab.dev/docs";
|
|
5
5
|
const trimSlashes = (value) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { findWranglerFile, readWranglerJsonc, validateWranglerConfig, isPlaceholderValue, DEV_VARS_FILE, parseDevVariableEntries, inferLunoraBindings } from '@lunora/config';
|
|
4
|
-
import { d as defineHandler } from '../packem_shared/command-
|
|
4
|
+
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
5
5
|
|
|
6
6
|
const SECRET_KEY_PATTERN = /(?:KEY|PASSWORD|SECRET|TOKEN)$/u;
|
|
7
7
|
const isD1PlaceholderId = (databaseId) => {
|