@zitadel/cli 0.1.0-alpha.0 → 0.1.0-alpha.1
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/README.md +131 -12
- package/SKILLS.md +18 -3
- package/dist/commands/apply.mjs +3 -2
- package/dist/commands/apply.mjs.map +1 -1
- package/dist/commands/doctor.mjs +123 -13
- package/dist/commands/doctor.mjs.map +1 -1
- package/dist/commands/eject.mjs +3 -2
- package/dist/commands/eject.mjs.map +1 -1
- package/dist/commands/logs.mjs +50 -0
- package/dist/commands/logs.mjs.map +1 -0
- package/dist/commands/plan.mjs +3 -2
- package/dist/commands/plan.mjs.map +1 -1
- package/dist/commands/reset.mjs +63 -0
- package/dist/commands/reset.mjs.map +1 -0
- package/dist/commands/setup.mjs +5 -3
- package/dist/commands/setup.mjs.map +1 -1
- package/dist/commands/start.mjs +132 -0
- package/dist/commands/start.mjs.map +1 -0
- package/dist/commands/status.mjs +68 -27
- package/dist/commands/status.mjs.map +1 -1
- package/dist/commands/stop.mjs +44 -0
- package/dist/commands/stop.mjs.map +1 -0
- package/dist/docker-C0aVpJqm.mjs +209 -0
- package/dist/docker-C0aVpJqm.mjs.map +1 -0
- package/dist/{project-C3pSfbao.mjs → oclif-DSPO9Sck.mjs} +216 -91
- package/dist/oclif-DSPO9Sck.mjs.map +1 -0
- package/dist/{orca-COsUnVoz.mjs → orca-DOxshV9n.mjs} +6 -3
- package/dist/{orca-COsUnVoz.mjs.map → orca-DOxshV9n.mjs.map} +1 -1
- package/dist/project-Dwb9WVAT.mjs +87 -0
- package/dist/project-Dwb9WVAT.mjs.map +1 -0
- package/dist/{sync-Cuyh-X1J.mjs → sync-DmtTYNmq.mjs} +3 -3
- package/dist/{sync-Cuyh-X1J.mjs.map → sync-DmtTYNmq.mjs.map} +1 -1
- package/oclif.manifest.json +351 -3
- package/package.json +1 -1
- package/dist/project-C3pSfbao.mjs.map +0 -1
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { Command, Flags } from "@oclif/core";
|
|
2
2
|
import consola from "consola";
|
|
3
|
-
import { readFile,
|
|
3
|
+
import { access, mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
import { ApiError } from "@zitadel/api/runtime/fetch";
|
|
6
|
+
import { createHash } from "node:crypto";
|
|
7
|
+
import { constants } from "node:fs";
|
|
8
|
+
import { createServer } from "node:net";
|
|
6
9
|
import { stringify } from "safe-stable-stringify";
|
|
7
10
|
//#region src/lib/errors.ts
|
|
8
11
|
/**
|
|
@@ -17,6 +20,7 @@ const EXIT_CODES = {
|
|
|
17
20
|
E_NETWORK: 4,
|
|
18
21
|
E_AUTH: 1,
|
|
19
22
|
E_CONFLICT: 5,
|
|
23
|
+
E_LOCAL_SERVER_NOT_RUNNING: 4,
|
|
20
24
|
E_VALIDATION: 3,
|
|
21
25
|
E_NOT_IMPLEMENTED: 2
|
|
22
26
|
};
|
|
@@ -144,6 +148,201 @@ function isObject(value) {
|
|
|
144
148
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
145
149
|
}
|
|
146
150
|
//#endregion
|
|
151
|
+
//#region src/lib/local-server/runtime.ts
|
|
152
|
+
const DEFAULT_LOCAL_SERVER_IMAGE = "ghcr.io/zitadel/nextgen:latest";
|
|
153
|
+
const DEFAULT_LOCAL_SERVER_PORT = 8080;
|
|
154
|
+
const DEFAULT_LOCAL_SERVER_URL = "http://localhost:8080";
|
|
155
|
+
const LOCAL_RUNTIME_DIR = ".zitadel/local";
|
|
156
|
+
const LOCAL_DATA_DIR = ".zitadel/local/nextgen-data";
|
|
157
|
+
const LOCAL_RUNTIME_FILE = ".zitadel/local/runtime.json";
|
|
158
|
+
const LOCAL_CONTAINER_PASSWD_FILE = ".zitadel/local/container-passwd";
|
|
159
|
+
const LOCAL_CONTAINER_GROUP_FILE = ".zitadel/local/container-group";
|
|
160
|
+
const CONTAINER_DATA_DIR = "/var/lib/zitadel/nextgen-data";
|
|
161
|
+
const CONTAINER_HTTP_PORT = 8080;
|
|
162
|
+
function localRuntimePaths(cwd) {
|
|
163
|
+
return {
|
|
164
|
+
runtimeDir: join(cwd, LOCAL_RUNTIME_DIR),
|
|
165
|
+
dataDir: join(cwd, LOCAL_DATA_DIR),
|
|
166
|
+
runtimeFile: join(cwd, LOCAL_RUNTIME_FILE),
|
|
167
|
+
containerPasswdFile: join(cwd, LOCAL_CONTAINER_PASSWD_FILE),
|
|
168
|
+
containerGroupFile: join(cwd, LOCAL_CONTAINER_GROUP_FILE)
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function localContainerName(cwd) {
|
|
172
|
+
return `zitadel-server-${createHash("sha256").update(resolve(cwd)).digest("hex").slice(0, 12)}`;
|
|
173
|
+
}
|
|
174
|
+
function localServerUrl(port) {
|
|
175
|
+
return `http://localhost:${port}`;
|
|
176
|
+
}
|
|
177
|
+
async function ensureLocalState(cwd) {
|
|
178
|
+
const paths = localRuntimePaths(cwd);
|
|
179
|
+
await mkdir(paths.dataDir, {
|
|
180
|
+
recursive: true,
|
|
181
|
+
mode: 448
|
|
182
|
+
});
|
|
183
|
+
await appendGitignoreEntry(cwd, `${LOCAL_RUNTIME_DIR}/`);
|
|
184
|
+
return paths;
|
|
185
|
+
}
|
|
186
|
+
async function ensureContainerIdentity(cwd, user) {
|
|
187
|
+
if (user.uid === void 0 || user.uid <= 0) return;
|
|
188
|
+
const gid = user.gid ?? user.uid;
|
|
189
|
+
const paths = localRuntimePaths(cwd);
|
|
190
|
+
await mkdir(paths.runtimeDir, {
|
|
191
|
+
recursive: true,
|
|
192
|
+
mode: 448
|
|
193
|
+
});
|
|
194
|
+
await writeFile(paths.containerPasswdFile, [
|
|
195
|
+
"root:x:0:0:root:/root:/bin/sh",
|
|
196
|
+
"nonroot:x:65532:65532:nonroot:/nonexistent:/usr/sbin/nologin",
|
|
197
|
+
`zitadel-local:x:${String(user.uid)}:${String(gid)}:Zitadel local user:/tmp:/usr/sbin/nologin`,
|
|
198
|
+
""
|
|
199
|
+
].join("\n"), { mode: 420 });
|
|
200
|
+
await writeFile(paths.containerGroupFile, [
|
|
201
|
+
"root:x:0:",
|
|
202
|
+
"nonroot:x:65532:",
|
|
203
|
+
`zitadel-local:x:${String(gid)}:`,
|
|
204
|
+
""
|
|
205
|
+
].join("\n"), { mode: 420 });
|
|
206
|
+
return {
|
|
207
|
+
uid: user.uid,
|
|
208
|
+
gid,
|
|
209
|
+
passwdFile: paths.containerPasswdFile,
|
|
210
|
+
groupFile: paths.containerGroupFile
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
async function readRuntimeMetadata(cwd) {
|
|
214
|
+
const paths = localRuntimePaths(cwd);
|
|
215
|
+
let raw;
|
|
216
|
+
try {
|
|
217
|
+
raw = await readFile(paths.runtimeFile, "utf8");
|
|
218
|
+
} catch (error) {
|
|
219
|
+
if (isErrno(error, "ENOENT")) return;
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
return normalizeRuntimeMetadata(parseJsonObject(raw, LOCAL_RUNTIME_FILE));
|
|
223
|
+
}
|
|
224
|
+
async function writeRuntimeMetadata(cwd, metadata) {
|
|
225
|
+
const paths = localRuntimePaths(cwd);
|
|
226
|
+
await mkdir(paths.runtimeDir, {
|
|
227
|
+
recursive: true,
|
|
228
|
+
mode: 448
|
|
229
|
+
});
|
|
230
|
+
await writeFile(paths.runtimeFile, `${JSON.stringify(metadata, null, 2)}\n`, { mode: 384 });
|
|
231
|
+
}
|
|
232
|
+
async function removeRuntimeMetadata(cwd) {
|
|
233
|
+
await rm(localRuntimePaths(cwd).runtimeFile, { force: true });
|
|
234
|
+
}
|
|
235
|
+
async function removeLocalData(cwd) {
|
|
236
|
+
await rm(localRuntimePaths(cwd).dataDir, {
|
|
237
|
+
recursive: true,
|
|
238
|
+
force: true
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
async function checkLocalServerHealth(serverUrl, timeoutMs = 1500) {
|
|
242
|
+
try {
|
|
243
|
+
const healthUrl = new URL("/healthz", serverUrl);
|
|
244
|
+
return (await fetch(healthUrl, { signal: AbortSignal.timeout(timeoutMs) })).ok;
|
|
245
|
+
} catch {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
async function isPortAvailable(port) {
|
|
250
|
+
return new Promise((resolvePort) => {
|
|
251
|
+
const server = createServer();
|
|
252
|
+
server.once("error", () => resolvePort(false));
|
|
253
|
+
server.once("listening", () => {
|
|
254
|
+
server.close(() => resolvePort(true));
|
|
255
|
+
});
|
|
256
|
+
server.listen(port, "127.0.0.1");
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
async function resolveLocalServer(cwd) {
|
|
260
|
+
const runtime = await readRuntimeMetadata(cwd);
|
|
261
|
+
if (runtime) {
|
|
262
|
+
if (await checkLocalServerHealth(runtime.server_url)) return runtime.server_url;
|
|
263
|
+
throw localServerNotRunning(runtime.server_url);
|
|
264
|
+
}
|
|
265
|
+
if (await checkLocalServerHealth("http://localhost:8080")) return DEFAULT_LOCAL_SERVER_URL;
|
|
266
|
+
throw localServerNotRunning(DEFAULT_LOCAL_SERVER_URL);
|
|
267
|
+
}
|
|
268
|
+
function localServerNotRunning(serverUrl) {
|
|
269
|
+
return new ZitadelError("E_LOCAL_SERVER_NOT_RUNNING", "Local Zitadel server is not running", {
|
|
270
|
+
hint: `No healthy local server responded at ${serverUrl}.`,
|
|
271
|
+
nextCommands: ["zitadel start"],
|
|
272
|
+
details: { server_url: serverUrl }
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
async function appendGitignoreEntry(cwd, entry) {
|
|
276
|
+
const path = join(cwd, ".gitignore");
|
|
277
|
+
let existing = "";
|
|
278
|
+
try {
|
|
279
|
+
existing = await readFile(path, "utf8");
|
|
280
|
+
} catch (error) {
|
|
281
|
+
if (!isErrno(error, "ENOENT")) throw error;
|
|
282
|
+
}
|
|
283
|
+
if (existing.split(/\r?\n/).map((line) => line.trim()).includes(entry)) return;
|
|
284
|
+
const prefix = existing.length === 0 || existing.endsWith("\n") ? "" : "\n";
|
|
285
|
+
await writeFile(path, `${existing}${prefix}${entry}\n`);
|
|
286
|
+
}
|
|
287
|
+
function normalizeRuntimeMetadata(input) {
|
|
288
|
+
if (input.schema_version !== 1 || typeof input.container_name !== "string" || typeof input.container_id !== "string" || typeof input.image !== "string" || typeof input.port !== "number" || !isValidPort(input.port) || typeof input.server_url !== "string" || !isValidServerUrl(input.server_url, input.port) || typeof input.data_dir !== "string" || typeof input.created_at !== "string" || typeof input.cli_version !== "string") throw new ZitadelError("E_VALIDATION", `${LOCAL_RUNTIME_FILE} is malformed`, {
|
|
289
|
+
hint: "Run `zitadel reset --force`, then `zitadel start`.",
|
|
290
|
+
nextCommands: ["zitadel reset --force", "zitadel start"],
|
|
291
|
+
details: input
|
|
292
|
+
});
|
|
293
|
+
return {
|
|
294
|
+
schema_version: 1,
|
|
295
|
+
container_name: input.container_name,
|
|
296
|
+
container_id: input.container_id,
|
|
297
|
+
image: input.image,
|
|
298
|
+
port: input.port,
|
|
299
|
+
server_url: input.server_url,
|
|
300
|
+
data_dir: input.data_dir,
|
|
301
|
+
created_at: input.created_at,
|
|
302
|
+
cli_version: input.cli_version
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
async function assertWritableDirectory(path) {
|
|
306
|
+
await mkdir(path, {
|
|
307
|
+
recursive: true,
|
|
308
|
+
mode: 448
|
|
309
|
+
});
|
|
310
|
+
await access(path, constants.W_OK);
|
|
311
|
+
}
|
|
312
|
+
function isErrno(error, code) {
|
|
313
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === code;
|
|
314
|
+
}
|
|
315
|
+
function runtimeSummary(metadata) {
|
|
316
|
+
if (!metadata) return { configured: false };
|
|
317
|
+
return {
|
|
318
|
+
configured: true,
|
|
319
|
+
container_name: metadata.container_name,
|
|
320
|
+
container_id: metadata.container_id,
|
|
321
|
+
image: metadata.image,
|
|
322
|
+
port: metadata.port,
|
|
323
|
+
server_url: metadata.server_url,
|
|
324
|
+
data_dir: metadata.data_dir,
|
|
325
|
+
created_at: metadata.created_at
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
function isValidPort(value) {
|
|
329
|
+
return Number.isInteger(value) && value >= 1 && value <= 65535;
|
|
330
|
+
}
|
|
331
|
+
function isValidServerUrl(value, port) {
|
|
332
|
+
try {
|
|
333
|
+
const url = new URL(value);
|
|
334
|
+
return (url.protocol === "http:" || url.protocol === "https:") && url.hostname.length > 0 && explicitUrlPort(value) === port;
|
|
335
|
+
} catch {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
function explicitUrlPort(value) {
|
|
340
|
+
const match = value.match(/^[a-z][a-z\d+\-.]*:\/\/(?:\[[^\]]+\]|[^/?#:]+):(\d+)(?:[/?#]|$)/i);
|
|
341
|
+
if (!match) return;
|
|
342
|
+
const port = Number(match[1]);
|
|
343
|
+
return isValidPort(port) ? port : void 0;
|
|
344
|
+
}
|
|
345
|
+
//#endregion
|
|
147
346
|
//#region src/lib/server.ts
|
|
148
347
|
/**
|
|
149
348
|
* Server URL used when nothing else resolves. Also surfaced in hints and
|
|
@@ -160,23 +359,23 @@ const DEFAULT_SERVER = "https://api.zitadel.cloud";
|
|
|
160
359
|
* `ZitadelError` rather than silently falling through.
|
|
161
360
|
*/
|
|
162
361
|
async function resolveServer(input) {
|
|
163
|
-
if (input.serverFlag) return validate({
|
|
362
|
+
if (input.serverFlag) return validate(input.cwd, {
|
|
164
363
|
value: input.serverFlag,
|
|
165
364
|
origin: "flag"
|
|
166
365
|
});
|
|
167
366
|
const envValue = input.env.ZITADEL_API_BASE;
|
|
168
|
-
if (envValue) return validate({
|
|
367
|
+
if (envValue) return validate(input.cwd, {
|
|
169
368
|
value: envValue,
|
|
170
369
|
origin: "env"
|
|
171
370
|
});
|
|
172
371
|
const config = await readConfig(input.cwd);
|
|
173
372
|
if (config) {
|
|
174
373
|
const envBranch = readEnvServer(config, input.environment);
|
|
175
|
-
if (envBranch) return validate({
|
|
374
|
+
if (envBranch) return validate(input.cwd, {
|
|
176
375
|
value: envBranch,
|
|
177
376
|
origin: "config-env"
|
|
178
377
|
});
|
|
179
|
-
if (typeof config.server === "string") return validate({
|
|
378
|
+
if (typeof config.server === "string") return validate(input.cwd, {
|
|
180
379
|
value: config.server,
|
|
181
380
|
origin: "config-top"
|
|
182
381
|
});
|
|
@@ -186,7 +385,11 @@ async function resolveServer(input) {
|
|
|
186
385
|
origin: "default"
|
|
187
386
|
};
|
|
188
387
|
}
|
|
189
|
-
function validate(resolved) {
|
|
388
|
+
async function validate(cwd, resolved) {
|
|
389
|
+
if (resolved.value === "local") return {
|
|
390
|
+
value: await resolveLocalServer(cwd),
|
|
391
|
+
origin: "local"
|
|
392
|
+
};
|
|
190
393
|
try {
|
|
191
394
|
const url = new URL(resolved.value);
|
|
192
395
|
if (url.protocol !== "https:" && url.protocol !== "http:") throw new ZitadelError("E_VALIDATION", `Server URL must use http(s): ${resolved.value}`, { hint: `Set "server" in zitadel.json to a URL like ${DEFAULT_SERVER}.` });
|
|
@@ -281,11 +484,14 @@ var BaseCommand = class extends Command {
|
|
|
281
484
|
* `source` by the documented precedence and storing the result on
|
|
282
485
|
* `this.meta` so the error handler can render a complete envelope.
|
|
283
486
|
*/
|
|
284
|
-
async toMeta(flags) {
|
|
487
|
+
async toMeta(flags, options = {}) {
|
|
285
488
|
const cwd = resolveCwd(typeof flags.cwd === "string" ? flags.cwd : void 0);
|
|
286
489
|
const serverFlag = typeof flags.server === "string" ? flags.server : void 0;
|
|
287
490
|
const environment = typeof flags.environment === "string" ? flags.environment : "development";
|
|
288
|
-
const source =
|
|
491
|
+
const source = options.resolveServer === false ? {
|
|
492
|
+
value: options.source ?? "",
|
|
493
|
+
origin: "default"
|
|
494
|
+
} : await resolveServer({
|
|
289
495
|
cwd,
|
|
290
496
|
env: process.env,
|
|
291
497
|
serverFlag,
|
|
@@ -502,87 +708,6 @@ function suffixBlock(opts) {
|
|
|
502
708
|
return suffix ? ` ${suffix}` : "";
|
|
503
709
|
}
|
|
504
710
|
//#endregion
|
|
505
|
-
|
|
506
|
-
/**
|
|
507
|
-
* Reports whether `cwd` has already been initialized, i.e. a committed
|
|
508
|
-
* `zitadel.json` exists. Used to decide whether setup should run or skip.
|
|
509
|
-
*/
|
|
510
|
-
async function hasZitadelConfig(cwd) {
|
|
511
|
-
return exists(join(cwd, "zitadel.json"));
|
|
512
|
-
}
|
|
513
|
-
/**
|
|
514
|
-
* Reports whether local secret material (`.zitadel/secret`) is present. Gates
|
|
515
|
-
* commands that need credentials, and signals that secrets were already pulled.
|
|
516
|
-
*/
|
|
517
|
-
async function hasZitadelSecret(cwd) {
|
|
518
|
-
return exists(join(cwd, ".zitadel/secret"));
|
|
519
|
-
}
|
|
520
|
-
async function exists(path) {
|
|
521
|
-
try {
|
|
522
|
-
await stat(path);
|
|
523
|
-
return true;
|
|
524
|
-
} catch (error) {
|
|
525
|
-
if (isNotFound(error)) return false;
|
|
526
|
-
throw error;
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
* Reads and parses `zitadel.json` into a plain object. Translates a missing
|
|
531
|
-
* file into an actionable `E_VALIDATION` error pointing at `zitadel setup`;
|
|
532
|
-
* other errors (e.g. malformed JSON) propagate unchanged.
|
|
533
|
-
*/
|
|
534
|
-
async function readZitadelConfig(cwd) {
|
|
535
|
-
try {
|
|
536
|
-
return parseJsonObject(await readFile(join(cwd, "zitadel.json"), "utf8"), "zitadel.json");
|
|
537
|
-
} catch (error) {
|
|
538
|
-
if (isNotFound(error)) throw new ZitadelError("E_VALIDATION", "zitadel.json was not found", {
|
|
539
|
-
hint: "Run `zitadel setup` first.",
|
|
540
|
-
nextCommands: ["zitadel setup"]
|
|
541
|
-
});
|
|
542
|
-
throw error;
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Reads, parses, and structurally validates `.zitadel/secret`, returning it
|
|
547
|
-
* as a {@link ZitadelSecret}. A missing file becomes an actionable
|
|
548
|
-
* `E_VALIDATION` error pointing at `zitadel setup` / `zitadel doctor --fix`;
|
|
549
|
-
* a present-but-incomplete file throws so callers never proceed with partial
|
|
550
|
-
* credentials.
|
|
551
|
-
*/
|
|
552
|
-
async function readZitadelSecret(cwd) {
|
|
553
|
-
try {
|
|
554
|
-
const secret = parseJsonObject(await readFile(join(cwd, ".zitadel/secret"), "utf8"), ".zitadel/secret");
|
|
555
|
-
if (typeof secret.project_id !== "string" || typeof secret.project_secret !== "string" || typeof secret.preview_secret !== "string" || !Array.isArray(secret.preview_origins)) throw new Error(".zitadel/secret is missing required fields");
|
|
556
|
-
return secret;
|
|
557
|
-
} catch (error) {
|
|
558
|
-
if (isNotFound(error)) throw new ZitadelError("E_VALIDATION", ".zitadel/secret was not found", {
|
|
559
|
-
hint: "Run `zitadel setup` first, or restore the project secret with `zitadel doctor --fix`.",
|
|
560
|
-
nextCommands: ["zitadel setup", "zitadel doctor --fix"]
|
|
561
|
-
});
|
|
562
|
-
throw error;
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
/**
|
|
566
|
-
* Reads the configured renderer id from a parsed `zitadel.json`, normalising the
|
|
567
|
-
* legacy `default` alias to `react` and falling back to `react` when unset. The
|
|
568
|
-
* value is validated downstream by `getRenderer`, so callers need not re-check.
|
|
569
|
-
*/
|
|
570
|
-
function readRendererId(config) {
|
|
571
|
-
const branding = isObject(config.branding) ? config.branding : void 0;
|
|
572
|
-
const value = branding && typeof branding.renderer === "string" ? branding.renderer : "react";
|
|
573
|
-
return value === "default" ? "react" : value;
|
|
574
|
-
}
|
|
575
|
-
/** Reads `environments.development.issuer` from a parsed `zitadel.json`, if present. */
|
|
576
|
-
function readDevelopmentIssuer(config) {
|
|
577
|
-
if (isObject(config.environments) && isObject(config.environments.development)) {
|
|
578
|
-
const issuer = config.environments.development.issuer;
|
|
579
|
-
return typeof issuer === "string" ? issuer : void 0;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
582
|
-
function isNotFound(error) {
|
|
583
|
-
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
584
|
-
}
|
|
585
|
-
//#endregion
|
|
586
|
-
export { readZitadelConfig as a, MANAGED_MARKER as c, parseJsonObject as d, stableStringify as f, readRendererId as i, DEFAULT_SERVER as l, hasZitadelSecret as n, readZitadelSecret as o, ZitadelError as p, readDevelopmentIssuer as r, BaseCommand as s, hasZitadelConfig as t, isObject as u };
|
|
711
|
+
export { parseJsonObject as C, isObject as S, ZitadelError as T, readRuntimeMetadata as _, CONTAINER_HTTP_PORT as a, runtimeSummary as b, DEFAULT_LOCAL_SERVER_URL as c, ensureContainerIdentity as d, ensureLocalState as f, localServerUrl as g, localRuntimePaths as h, CONTAINER_DATA_DIR as i, assertWritableDirectory as l, localContainerName as m, MANAGED_MARKER as n, DEFAULT_LOCAL_SERVER_IMAGE as o, isPortAvailable as p, DEFAULT_SERVER as r, DEFAULT_LOCAL_SERVER_PORT as s, BaseCommand as t, checkLocalServerHealth as u, removeLocalData as v, stableStringify as w, writeRuntimeMetadata as x, removeRuntimeMetadata as y };
|
|
587
712
|
|
|
588
|
-
//# sourceMappingURL=
|
|
713
|
+
//# sourceMappingURL=oclif-DSPO9Sck.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oclif-DSPO9Sck.mjs","names":[],"sources":["../src/lib/errors.ts","../src/lib/json.ts","../src/lib/local-server/runtime.ts","../src/lib/server.ts","../src/lib/paths.ts","../src/lib/oclif/base.ts"],"sourcesContent":["import { ApiError } from \"@zitadel/api/runtime/fetch\";\n\n/**\n * Closed set of failure categories the CLI can surface. Every error the\n * user sees is funnelled into one of these so messaging, exit codes, and\n * machine-readable output stay consistent regardless of where the failure\n * originated.\n */\nexport type ZitadelErrorCode =\n | \"E_ALREADY_INIT\"\n | \"E_FRAMEWORK_NOT_DETECTED\"\n | \"E_UNSUPPORTED_PROJECT_SHAPE\"\n | \"E_NETWORK\"\n | \"E_AUTH\"\n | \"E_CONFLICT\"\n | \"E_LOCAL_SERVER_NOT_RUNNING\"\n | \"E_VALIDATION\"\n | \"E_NOT_IMPLEMENTED\";\n\n/**\n * Maps each {@link ZitadelErrorCode} to the process exit code the CLI\n * returns. The table is the single source of truth for exit semantics so\n * scripts and CI can branch on stable, documented numbers.\n */\nexport const EXIT_CODES: Record<ZitadelErrorCode, number> = {\n E_ALREADY_INIT: 0,\n E_FRAMEWORK_NOT_DETECTED: 3,\n E_UNSUPPORTED_PROJECT_SHAPE: 3,\n E_NETWORK: 4,\n E_AUTH: 1,\n E_CONFLICT: 5,\n E_LOCAL_SERVER_NOT_RUNNING: 4,\n E_VALIDATION: 3,\n E_NOT_IMPLEMENTED: 2,\n};\n\n/**\n * Optional, user-facing extras attached to a {@link ZitadelError}. Kept\n * separate from the message so the renderer can present a hint, suggested\n * follow-up commands, and structured details independently (e.g. as JSON\n * fields) rather than concatenating everything into one string.\n */\nexport type ZitadelErrorOptions = {\n hint?: string;\n nextCommands?: string[];\n details?: unknown;\n};\n\n/**\n * The CLI's single error type. Carries a {@link ZitadelErrorCode} so the\n * top-level handler can derive an exit code and structured output without\n * pattern-matching on messages. Throwing this anywhere guarantees the user\n * gets a categorised, hint-bearing failure instead of a raw stack trace.\n */\nexport class ZitadelError extends Error {\n readonly code: ZitadelErrorCode;\n readonly hint?: string;\n readonly nextCommands?: string[];\n readonly details?: unknown;\n\n constructor(code: ZitadelErrorCode, message: string, opts: ZitadelErrorOptions = {}) {\n super(message);\n this.name = \"ZitadelError\";\n this.code = code;\n this.hint = opts.hint;\n this.nextCommands = opts.nextCommands;\n this.details = opts.details;\n }\n\n get exitCode(): number {\n return EXIT_CODES[this.code] ?? 1;\n }\n}\n\n/**\n * Normalises any thrown value into a {@link ZitadelError}. Inspection is\n * ordered most-specific-first (already-normalised, then errno/filesystem,\n * network, Zod-like, generic `Error`, then a catch-all) so the most\n * actionable category and hint win. This is the boundary that lets the rest\n * of the CLI `throw` plain errors yet still produce consistent, categorised\n * output. The original error shape is preserved under `details` for\n * debugging without leaking it into the user-facing message.\n */\nexport function toZitadelError(error: unknown): ZitadelError {\n if (error instanceof ZitadelError) {\n return error;\n }\n\n if (error instanceof ApiError) {\n // `401`/`403` → bad or missing project secret; `5xx` → transport or\n // server fault; everything else 4xx → the body the CLI sent was\n // rejected (validation, conflict, not-found, …).\n const code: ZitadelErrorCode =\n error.status === 401 || error.status === 403\n ? \"E_AUTH\"\n : error.status >= 500\n ? \"E_NETWORK\"\n : \"E_VALIDATION\";\n return new ZitadelError(code, error.message, {\n details: { status: error.status, url: error.url, body: error.body },\n });\n }\n\n if (isErrnoException(error)) {\n const details = { original: pickErrorShape(error) };\n if (error.code === \"EACCES\" || error.code === \"EPERM\") {\n return new ZitadelError(\"E_AUTH\", `Permission denied: ${error.message}`, {\n hint: \"Check file permissions or run with the right user.\",\n details,\n });\n }\n if (error.code === \"EEXIST\") {\n return new ZitadelError(\"E_CONFLICT\", error.message, {\n hint: \"A file already exists. Use --force to overwrite or remove it first.\",\n details,\n });\n }\n if (error.code === \"ENOENT\") {\n return new ZitadelError(\"E_VALIDATION\", error.message, {\n hint: \"A required file or directory is missing.\",\n details,\n });\n }\n }\n\n if (isNetworkError(error)) {\n return new ZitadelError(\"E_NETWORK\", errorMessage(error), {\n hint: \"Check your connection, ZITADEL_API_BASE, or the configured server URL.\",\n details: { original: pickErrorShape(error as Error) },\n });\n }\n\n if (isZodLikeError(error)) {\n return new ZitadelError(\"E_VALIDATION\", errorMessage(error), {\n details: { issues: (error as { issues: unknown }).issues },\n });\n }\n\n if (error instanceof Error) {\n return new ZitadelError(\"E_VALIDATION\", error.message, {\n details: { original: pickErrorShape(error) },\n });\n }\n\n return new ZitadelError(\"E_VALIDATION\", \"Unknown error\", { details: error });\n}\n\nfunction isErrnoException(error: unknown): error is NodeJS.ErrnoException {\n return error instanceof Error && typeof (error as NodeJS.ErrnoException).code === \"string\";\n}\n\nfunction isNetworkError(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n if (\n error.name === \"TypeError\" &&\n /fetch failed|network|ECONNREFUSED|ENOTFOUND/i.test(error.message)\n ) {\n return true;\n }\n const cause = (error as { cause?: unknown }).cause;\n if (cause && typeof cause === \"object\" && \"code\" in cause) {\n const code = String((cause as { code: unknown }).code);\n return /^(ECONNREFUSED|ECONNRESET|ENOTFOUND|ETIMEDOUT|EAI_AGAIN|UND_ERR)/i.test(code);\n }\n return false;\n}\n\nfunction isZodLikeError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"issues\" in error &&\n Array.isArray((error as { issues: unknown }).issues)\n );\n}\n\nfunction errorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === \"string\") {\n return error;\n }\n return String(error);\n}\n\nfunction pickErrorShape(error: Error): Record<string, unknown> {\n return {\n name: error.name,\n message: error.message,\n code: (error as NodeJS.ErrnoException).code,\n };\n}\n","import { stringify } from \"safe-stable-stringify\";\n\n/**\n * Serialise a value to pretty-printed JSON with object keys sorted at every\n * depth. Determinism is the point: managed files written by the CLI must be\n * byte-stable across runs so diffs stay clean and content hashes don't churn\n * when only key ordering would otherwise differ. Delegates the deterministic\n * sort to `safe-stable-stringify`, matching `JSON.stringify(value, null, 2)`\n * formatting. The `?? \"null\"` only applies to `undefined`/function inputs,\n * which the CLI never serialises.\n */\nexport function stableStringify(value: unknown): string {\n return stringify(value, null, 2) ?? \"null\";\n}\n\n/**\n * Parse `contents` as JSON and assert the root is a plain object (not an\n * array or scalar). The CLI's config and secret files are always objects, so\n * this guards callers from the `JSON.parse` return type of `any` and produces\n * a `path`-qualified error message pointing at the offending file.\n */\nexport function parseJsonObject(contents: string, path: string): Record<string, unknown> {\n const value = JSON.parse(contents) as unknown;\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new Error(`${path} must contain a JSON object`);\n }\n return value as Record<string, unknown>;\n}\n\n/**\n * Narrows an unknown value to a plain (non-array, non-null) object. Shared by\n * the commands and the file-writer that walk parsed JSON, so the predicate\n * isn't reimplemented per call site.\n */\nexport function isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { createHash } from \"node:crypto\";\nimport { access, mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { constants } from \"node:fs\";\nimport { createServer } from \"node:net\";\nimport { join, resolve } from \"node:path\";\n\nimport { ZitadelError } from \"../errors\";\nimport { isObject, parseJsonObject } from \"../json\";\n\nexport const DEFAULT_LOCAL_SERVER_IMAGE = \"ghcr.io/zitadel/nextgen:latest\";\nexport const DEFAULT_LOCAL_SERVER_PORT = 8080;\nexport const DEFAULT_LOCAL_SERVER_URL = \"http://localhost:8080\";\nexport const LOCAL_RUNTIME_DIR = \".zitadel/local\";\nexport const LOCAL_DATA_DIR = \".zitadel/local/nextgen-data\";\nexport const LOCAL_RUNTIME_FILE = \".zitadel/local/runtime.json\";\nexport const LOCAL_CONTAINER_PASSWD_FILE = \".zitadel/local/container-passwd\";\nexport const LOCAL_CONTAINER_GROUP_FILE = \".zitadel/local/container-group\";\nexport const CONTAINER_DATA_DIR = \"/var/lib/zitadel/nextgen-data\";\nexport const CONTAINER_HTTP_PORT = 8080;\n\nexport type RuntimeMetadata = {\n schema_version: 1;\n container_name: string;\n container_id: string;\n image: string;\n port: number;\n server_url: string;\n data_dir: string;\n created_at: string;\n cli_version: string;\n};\n\nexport type LocalRuntimePaths = {\n runtimeDir: string;\n dataDir: string;\n runtimeFile: string;\n containerPasswdFile: string;\n containerGroupFile: string;\n};\n\nexport type ContainerIdentity = {\n uid: number;\n gid: number;\n passwdFile: string;\n groupFile: string;\n};\n\nexport function localRuntimePaths(cwd: string): LocalRuntimePaths {\n return {\n runtimeDir: join(cwd, LOCAL_RUNTIME_DIR),\n dataDir: join(cwd, LOCAL_DATA_DIR),\n runtimeFile: join(cwd, LOCAL_RUNTIME_FILE),\n containerPasswdFile: join(cwd, LOCAL_CONTAINER_PASSWD_FILE),\n containerGroupFile: join(cwd, LOCAL_CONTAINER_GROUP_FILE),\n };\n}\n\nexport function localContainerName(cwd: string): string {\n const hash = createHash(\"sha256\").update(resolve(cwd)).digest(\"hex\").slice(0, 12);\n return `zitadel-server-${hash}`;\n}\n\nexport function localServerUrl(port: number): string {\n return `http://localhost:${port}`;\n}\n\nexport async function ensureLocalState(cwd: string): Promise<LocalRuntimePaths> {\n const paths = localRuntimePaths(cwd);\n await mkdir(paths.dataDir, { recursive: true, mode: 0o700 });\n await appendGitignoreEntry(cwd, `${LOCAL_RUNTIME_DIR}/`);\n return paths;\n}\n\nexport async function ensureContainerIdentity(\n cwd: string,\n user: { uid?: number; gid?: number },\n): Promise<ContainerIdentity | undefined> {\n if (user.uid === undefined || user.uid <= 0) {\n return undefined;\n }\n const gid = user.gid ?? user.uid;\n const paths = localRuntimePaths(cwd);\n await mkdir(paths.runtimeDir, { recursive: true, mode: 0o700 });\n await writeFile(\n paths.containerPasswdFile,\n [\n \"root:x:0:0:root:/root:/bin/sh\",\n \"nonroot:x:65532:65532:nonroot:/nonexistent:/usr/sbin/nologin\",\n `zitadel-local:x:${String(user.uid)}:${String(gid)}:Zitadel local user:/tmp:/usr/sbin/nologin`,\n \"\",\n ].join(\"\\n\"),\n { mode: 0o644 },\n );\n await writeFile(\n paths.containerGroupFile,\n [\n \"root:x:0:\",\n \"nonroot:x:65532:\",\n `zitadel-local:x:${String(gid)}:`,\n \"\",\n ].join(\"\\n\"),\n { mode: 0o644 },\n );\n return {\n uid: user.uid,\n gid,\n passwdFile: paths.containerPasswdFile,\n groupFile: paths.containerGroupFile,\n };\n}\n\nexport async function readRuntimeMetadata(cwd: string): Promise<RuntimeMetadata | undefined> {\n const paths = localRuntimePaths(cwd);\n let raw: string;\n try {\n raw = await readFile(paths.runtimeFile, \"utf8\");\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return undefined;\n }\n throw error;\n }\n\n const parsed = parseJsonObject(raw, LOCAL_RUNTIME_FILE);\n return normalizeRuntimeMetadata(parsed);\n}\n\nexport async function writeRuntimeMetadata(cwd: string, metadata: RuntimeMetadata): Promise<void> {\n const paths = localRuntimePaths(cwd);\n await mkdir(paths.runtimeDir, { recursive: true, mode: 0o700 });\n await writeFile(paths.runtimeFile, `${JSON.stringify(metadata, null, 2)}\\n`, { mode: 0o600 });\n}\n\nexport async function removeRuntimeMetadata(cwd: string): Promise<void> {\n await rm(localRuntimePaths(cwd).runtimeFile, { force: true });\n}\n\nexport async function removeLocalData(cwd: string): Promise<void> {\n await rm(localRuntimePaths(cwd).dataDir, { recursive: true, force: true });\n}\n\nexport async function checkLocalServerHealth(serverUrl: string, timeoutMs = 1500): Promise<boolean> {\n try {\n const healthUrl = new URL(\"/healthz\", serverUrl);\n const response = await fetch(healthUrl, { signal: AbortSignal.timeout(timeoutMs) });\n return response.ok;\n } catch {\n return false;\n }\n}\n\nexport async function isPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolvePort) => {\n const server = createServer();\n server.once(\"error\", () => resolvePort(false));\n server.once(\"listening\", () => {\n server.close(() => resolvePort(true));\n });\n server.listen(port, \"127.0.0.1\");\n });\n}\n\nexport async function resolveLocalServer(cwd: string): Promise<string> {\n const runtime = await readRuntimeMetadata(cwd);\n if (runtime) {\n if (await checkLocalServerHealth(runtime.server_url)) {\n return runtime.server_url;\n }\n throw localServerNotRunning(runtime.server_url);\n }\n\n if (await checkLocalServerHealth(DEFAULT_LOCAL_SERVER_URL)) {\n return DEFAULT_LOCAL_SERVER_URL;\n }\n throw localServerNotRunning(DEFAULT_LOCAL_SERVER_URL);\n}\n\nexport function localServerNotRunning(serverUrl: string): ZitadelError {\n return new ZitadelError(\"E_LOCAL_SERVER_NOT_RUNNING\", \"Local Zitadel server is not running\", {\n hint: `No healthy local server responded at ${serverUrl}.`,\n nextCommands: [\"zitadel start\"],\n details: { server_url: serverUrl },\n });\n}\n\nasync function appendGitignoreEntry(cwd: string, entry: string): Promise<void> {\n const path = join(cwd, \".gitignore\");\n let existing = \"\";\n try {\n existing = await readFile(path, \"utf8\");\n } catch (error) {\n if (!isErrno(error, \"ENOENT\")) {\n throw error;\n }\n }\n\n const lines = existing.split(/\\r?\\n/).map((line) => line.trim());\n if (lines.includes(entry)) {\n return;\n }\n const prefix = existing.length === 0 || existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n await writeFile(path, `${existing}${prefix}${entry}\\n`);\n}\n\nfunction normalizeRuntimeMetadata(input: Record<string, unknown>): RuntimeMetadata {\n if (\n input.schema_version !== 1 ||\n typeof input.container_name !== \"string\" ||\n typeof input.container_id !== \"string\" ||\n typeof input.image !== \"string\" ||\n typeof input.port !== \"number\" ||\n !isValidPort(input.port) ||\n typeof input.server_url !== \"string\" ||\n !isValidServerUrl(input.server_url, input.port) ||\n typeof input.data_dir !== \"string\" ||\n typeof input.created_at !== \"string\" ||\n typeof input.cli_version !== \"string\"\n ) {\n throw new ZitadelError(\"E_VALIDATION\", `${LOCAL_RUNTIME_FILE} is malformed`, {\n hint: \"Run `zitadel reset --force`, then `zitadel start`.\",\n nextCommands: [\"zitadel reset --force\", \"zitadel start\"],\n details: input,\n });\n }\n return {\n schema_version: 1,\n container_name: input.container_name,\n container_id: input.container_id,\n image: input.image,\n port: input.port,\n server_url: input.server_url,\n data_dir: input.data_dir,\n created_at: input.created_at,\n cli_version: input.cli_version,\n };\n}\n\nexport async function assertWritableDirectory(path: string): Promise<void> {\n await mkdir(path, { recursive: true, mode: 0o700 });\n await access(path, constants.W_OK);\n}\n\nfunction isErrno(error: unknown, code: string): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: unknown }).code === code\n );\n}\n\nexport function runtimeSummary(metadata: RuntimeMetadata | undefined): Record<string, unknown> {\n if (!metadata) {\n return { configured: false };\n }\n return {\n configured: true,\n container_name: metadata.container_name,\n container_id: metadata.container_id,\n image: metadata.image,\n port: metadata.port,\n server_url: metadata.server_url,\n data_dir: metadata.data_dir,\n created_at: metadata.created_at,\n };\n}\n\nexport function isRuntimeObject(value: unknown): value is RuntimeMetadata {\n return isObject(value) && value.schema_version === 1;\n}\n\nfunction isValidPort(value: number): boolean {\n return Number.isInteger(value) && value >= 1 && value <= 65_535;\n}\n\nfunction isValidServerUrl(value: string, port: number): boolean {\n try {\n const url = new URL(value);\n return (\n (url.protocol === \"http:\" || url.protocol === \"https:\") &&\n url.hostname.length > 0 &&\n explicitUrlPort(value) === port\n );\n } catch {\n return false;\n }\n}\n\nfunction explicitUrlPort(value: string): number | undefined {\n const match = value.match(/^[a-z][a-z\\d+\\-.]*:\\/\\/(?:\\[[^\\]]+\\]|[^/?#:]+):(\\d+)(?:[/?#]|$)/i);\n if (!match) {\n return undefined;\n }\n const port = Number(match[1]);\n return isValidPort(port) ? port : undefined;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { ZitadelError } from \"./errors\";\nimport { resolveLocalServer } from \"./local-server/runtime\";\nimport { isObject, parseJsonObject } from \"./json\";\n\n/**\n * Server URL used when nothing else resolves. Also surfaced in hints and\n * the interactive setup prompt as the suggested value, so it is exported\n * rather than kept private.\n */\nexport const DEFAULT_SERVER = \"https://api.zitadel.cloud\";\n\n/**\n * The resolved target server plus the source it came from. `origin` is\n * retained (not just the value) so callers can report *why* a server was\n * chosen and so the precedence order stays auditable.\n */\nexport type ResolvedServer = {\n value: string;\n origin: \"flag\" | \"env\" | \"config-env\" | \"config-top\" | \"default\" | \"local\";\n};\n\n/**\n * Inputs to {@link resolveServer}. Passed explicitly (cwd, env) rather\n * than read from globals so resolution is pure and testable. `serverFlag`\n * and `environment` come from the parsed CLI invocation.\n */\nexport type ResolveServerInput = {\n cwd: string;\n env: NodeJS.ProcessEnv;\n serverFlag?: string;\n environment?: string;\n};\n\n/**\n * Resolves which server the CLI should target, applying a fixed\n * precedence: explicit `--server` flag, then `ZITADEL_API_BASE`, then the\n * selected environment block in `zitadel.json`, then the config's\n * top-level `server`, falling back to {@link DEFAULT_SERVER}. Every\n * candidate is validated to a normalised origin; an invalid URL throws a\n * `ZitadelError` rather than silently falling through.\n */\nexport async function resolveServer(input: ResolveServerInput): Promise<ResolvedServer> {\n if (input.serverFlag) {\n return validate(input.cwd, { value: input.serverFlag, origin: \"flag\" });\n }\n const envValue = input.env.ZITADEL_API_BASE;\n if (envValue) {\n return validate(input.cwd, { value: envValue, origin: \"env\" });\n }\n\n const config = await readConfig(input.cwd);\n if (config) {\n const envBranch = readEnvServer(config, input.environment);\n if (envBranch) {\n return validate(input.cwd, { value: envBranch, origin: \"config-env\" });\n }\n if (typeof config.server === \"string\") {\n return validate(input.cwd, { value: config.server, origin: \"config-top\" });\n }\n }\n\n return { value: DEFAULT_SERVER, origin: \"default\" };\n}\n\nasync function validate(cwd: string, resolved: ResolvedServer): Promise<ResolvedServer> {\n if (resolved.value === \"local\") {\n return { value: await resolveLocalServer(cwd), origin: \"local\" };\n }\n\n try {\n const url = new URL(resolved.value);\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n throw new ZitadelError(\"E_VALIDATION\", `Server URL must use http(s): ${resolved.value}`, {\n hint: `Set \"server\" in zitadel.json to a URL like ${DEFAULT_SERVER}.`,\n });\n }\n return { value: url.origin, origin: resolved.origin };\n } catch (error) {\n if (error instanceof ZitadelError) {\n throw error;\n }\n throw new ZitadelError(\"E_VALIDATION\", `Invalid server \"${resolved.value}\"`, {\n hint: `Use a URL like ${DEFAULT_SERVER}.`,\n details: { origin: resolved.origin },\n });\n }\n}\n\nasync function readConfig(cwd: string): Promise<Record<string, unknown> | undefined> {\n try {\n const contents = await readFile(join(cwd, \"zitadel.json\"), \"utf8\");\n return parseJsonObject(contents, \"zitadel.json\");\n } catch (error) {\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code?: string }).code === \"ENOENT\"\n ) {\n return undefined;\n }\n throw error;\n }\n}\n\nfunction readEnvServer(\n config: Record<string, unknown>,\n environment: string | undefined,\n): string | undefined {\n if (!environment) {\n return undefined;\n }\n const envs = config.environments;\n if (!isObject(envs)) {\n return undefined;\n }\n const branch = envs[environment];\n if (!isObject(branch)) {\n return undefined;\n }\n return typeof branch.server === \"string\" ? branch.server : undefined;\n}\n","import { resolve } from \"node:path\";\n\n/**\n * Resolve the working directory the CLI should operate against, defaulting to\n * the process CWD when no `--cwd` override is given. Always returns an\n * absolute path so downstream `join`/`readFile` calls are unaffected by later\n * `process.chdir` or relative-path ambiguity.\n */\nexport function resolveCwd(cwd?: string): string {\n return resolve(cwd ?? process.cwd());\n}\n\n/**\n * Sentinel comment stamped at the top of every file the CLI generates and\n * owns. Commands like `doctor` and `eject` look for this marker to decide\n * whether a file is safe to touch; the trailing `v1` lets the format evolve\n * without mistaking newer managed files for hand-edited ones.\n */\nexport const MANAGED_MARKER = \"// zitadel-cli: managed-file v1\";\n","import { Command, Flags } from \"@oclif/core\";\nimport consola from \"consola\";\n\nimport { resolveServer } from \"../server\";\nimport { toZitadelError, type ZitadelError } from \"../errors\";\nimport { isObject } from \"../json\";\nimport { resolveCwd } from \"../paths\";\nimport type {\n CommandResult,\n ErrorEnvelope,\n EnvelopeMeta,\n GlobalOptions,\n JsonEnvelope,\n} from \"./types\";\n\n/**\n * Base class for every oclif command. Owns the global flags, builds the\n * {@link GlobalOptions} context (including server `source` resolution) the\n * subclass's `run` reads via `this.meta`, and turns the {@link CommandResult}\n * it returns into the JSON envelope (oclif serialises it natively in `--json`\n * mode) or human-facing text. Errors are translated into the failure envelope\n * and the mapped process exit code. Subclasses stay thin: parse flags, call\n * {@link toMeta}, do their work, and `return this.emit(...)`. The agent\n * contract (ADR 004) is preserved — oclif only replaces parsing, dispatch,\n * help, and JSON emission.\n */\nexport abstract class BaseCommand extends Command {\n /** Opt into oclif's native `--json` flag and JSON serialisation of the result. */\n static override enableJsonFlag = true;\n\n /** Flags shared by every command, inherited via oclif `baseFlags`. */\n static override baseFlags = {\n cwd: Flags.string({ char: \"c\", description: \"Project directory to operate on.\" }),\n server: Flags.string({ char: \"s\", description: \"Override the resolved server URL.\" }),\n \"non-interactive\": Flags.boolean({\n char: \"n\",\n description: \"Disable prompts. Required when scripting or running as an agent.\",\n }),\n force: Flags.boolean({ char: \"f\", description: \"Overwrite protected files on conflict.\" }),\n \"dry-run\": Flags.boolean({ description: \"Preview without mutating files or the platform.\" }),\n verbose: Flags.boolean({ description: \"Verbose logging.\" }),\n debug: Flags.boolean({ description: \"Debug logging.\" }),\n };\n\n /** Resolved context for the current invocation; set by {@link toMeta}. */\n protected meta: GlobalOptions = this.fallbackMeta();\n\n /**\n * Builds {@link GlobalOptions} from parsed flags, resolving the server\n * `source` by the documented precedence and storing the result on\n * `this.meta` so the error handler can render a complete envelope.\n */\n protected async toMeta(\n flags: Record<string, unknown>,\n options: { resolveServer?: boolean; source?: string } = {},\n ): Promise<GlobalOptions> {\n const cwd = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n const serverFlag = typeof flags.server === \"string\" ? flags.server : undefined;\n const environment = typeof flags.environment === \"string\" ? flags.environment : \"development\";\n const source =\n options.resolveServer === false\n ? { value: options.source ?? \"\", origin: \"default\" as const }\n : await resolveServer({ cwd, env: process.env, serverFlag, environment });\n const json = this.jsonEnabled();\n const isTTY = Boolean(process.stdout.isTTY && process.stdin.isTTY);\n const verbose = Boolean(flags.verbose);\n const debug = Boolean(flags.debug);\n // Default to `info` (3) so users see step-by-step narration (start/info/\n // success/box). `--json` silences consola entirely so the structured\n // envelope is the only thing on stdout. `--debug` raises to 4 (debug);\n // `--verbose` is reserved for richer per-step detail and currently maps\n // to the same level as default.\n consola.level = json ? -999 : debug ? 4 : 3;\n // Drop the right-aligned timestamp the FancyReporter adds by default.\n // Timestamps add no value in a one-off CLI run, wrap awkwardly on long\n // lines (e.g. created-schema URL), and clutter the visual rhythm of the\n // ◐/✔/ℹ glyphs that anchor each step.\n consola.options.formatOptions = {\n ...consola.options.formatOptions,\n date: false,\n colors: true,\n compact: true,\n };\n this.meta = {\n cwd,\n nonInteractive: Boolean(flags[\"non-interactive\"]) || !isTTY || json,\n dryRun: Boolean(flags[\"dry-run\"]),\n force: Boolean(flags.force),\n command: this.id ?? \"(default)\",\n cliVersion: this.config.version,\n source: source.value,\n serverFlag,\n verbose,\n debug,\n env: process.env,\n isTTY,\n };\n return this.meta;\n }\n\n /**\n * Final step of every command: in human mode it prints the rendered result\n * (oclif suppresses {@link Command.log} under `--json`); it returns the\n * envelope so oclif's `--json` path serialises it.\n */\n protected emit(result: CommandResult): JsonEnvelope {\n this.log(renderPretty(result, this.meta));\n return toEnvelope(result, this.meta);\n }\n\n /**\n * Renders any thrown error as the failure envelope and exits with its code.\n * A flag-parse error fires before {@link toMeta} runs, so the local `meta`\n * here refreshes `command` from the now-resolved command id to keep the\n * envelope's `command` field accurate.\n */\n protected override async catch(error: unknown): Promise<never> {\n const meta: GlobalOptions = { ...this.meta, command: this.id ?? this.meta.command };\n const zitadelError = toZitadelError(error);\n if (this.jsonEnabled()) {\n this.logJson(toErrorEnvelope(zitadelError, meta));\n } else {\n this.logToStderr(renderError(zitadelError));\n }\n return this.exit(zitadelError.exitCode);\n }\n\n /**\n * Context used before {@link toMeta} runs, so an error thrown during flag\n * parsing still renders a complete envelope. Version comes from oclif's\n * resolved {@link Command.config}.\n */\n private fallbackMeta(): GlobalOptions {\n return {\n cwd: resolveCwd(undefined),\n nonInteractive: false,\n dryRun: false,\n force: false,\n command: \"(default)\",\n cliVersion: this.config.version,\n source: \"\",\n verbose: false,\n debug: false,\n env: process.env,\n isTTY: Boolean(process.stdout.isTTY && process.stdin.isTTY),\n };\n }\n}\n\n/** Wraps a {@link CommandResult} with the invocation metadata into the final envelope. */\nfunction toEnvelope(result: CommandResult, meta: GlobalOptions): JsonEnvelope {\n const base: EnvelopeMeta = {\n cli_version: meta.cliVersion,\n command: meta.command,\n source: meta.source,\n };\n if (result.status === \"ok\") {\n return {\n ...base,\n status: \"ok\",\n data: result.data,\n warnings: result.warnings ? [...result.warnings] : [],\n };\n }\n return {\n ...base,\n status: \"skipped\",\n reason: result.reason,\n data: result.data,\n next_commands: result.nextCommands ? [...result.nextCommands] : undefined,\n };\n}\n\n/** Builds the failure envelope from a {@link ZitadelError} and the invocation metadata. */\nfunction toErrorEnvelope(error: ZitadelError, meta: GlobalOptions): ErrorEnvelope {\n return {\n status: \"error\",\n cli_version: meta.cliVersion,\n command: meta.command,\n source: meta.source,\n code: error.code,\n message: error.message,\n hint: error.hint,\n next_commands: error.nextCommands,\n details: error.details,\n };\n}\n\n/**\n * Renders a {@link CommandResult} as human-facing text for non-JSON mode. A\n * command may supply a bespoke `pretty` string (e.g. the `apply` plan diff);\n * otherwise success payloads are summarised by {@link formatData} and skips are\n * shown with their reason and follow-up commands.\n */\nfunction renderPretty(result: CommandResult, meta: GlobalOptions): string {\n if (result.pretty !== undefined) {\n return result.pretty;\n }\n if (result.status === \"ok\") {\n return formatData(result.data, result.warnings ? [...result.warnings] : [], meta);\n }\n const lines = [`Skipped: ${result.reason}${suffixBlock(meta)}`];\n if (result.nextCommands && result.nextCommands.length > 0) {\n lines.push(\"Next:\");\n for (const cmd of result.nextCommands) {\n lines.push(` $ ${cmd}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Renders a {@link ZitadelError} as a human-readable block for stderr: the\n * coded message, an optional hint, and any suggested next commands.\n */\nfunction renderError(error: ZitadelError): string {\n const lines = [`Error ${error.code}: ${error.message}`];\n if (error.hint) {\n lines.push(error.hint);\n }\n if (error.nextCommands && error.nextCommands.length > 0) {\n lines.push(\"Next:\");\n for (const cmd of error.nextCommands) {\n lines.push(` $ ${cmd}`);\n }\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatData(data: unknown, warnings: string[], opts: GlobalOptions): string {\n if (typeof data === \"string\") {\n const suffix = sourceSuffix(opts);\n return suffix ? `${data}\\n${suffix}` : data;\n }\n\n const lines: string[] = [];\n const titleLine =\n isObject(data) && typeof data.title === \"string\"\n ? String(data.title)\n : \"Zitadel command completed.\";\n lines.push(titleLine);\n const suffix = sourceSuffix(opts);\n if (suffix) {\n lines.push(suffix);\n }\n\n if (isObject(data)) {\n renderKnownSections(lines, data);\n\n if (Array.isArray(data.next_actions) && data.next_actions.length > 0) {\n lines.push(\"\");\n lines.push(\"Next:\");\n for (const action of data.next_actions) {\n lines.push(` ${String(action)}`);\n }\n }\n if (Array.isArray(data.next_commands) && data.next_commands.length > 0) {\n if (!Array.isArray(data.next_actions) || data.next_actions.length === 0) {\n lines.push(\"\");\n lines.push(\"Next:\");\n }\n for (const cmd of data.next_commands) {\n lines.push(` $ ${String(cmd)}`);\n }\n }\n }\n\n for (const warning of warnings) {\n lines.push(`Warning: ${warning}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction renderKnownSections(lines: string[], data: Record<string, unknown>): void {\n if (isObject(data.project)) {\n const project = data.project;\n const segments: string[] = [];\n if (typeof project.project_id === \"string\") {\n segments.push(`project=${project.project_id}`);\n }\n if (typeof project.lifecycle === \"string\") {\n segments.push(`lifecycle=${project.lifecycle}`);\n }\n if (typeof project.issuer === \"string\") {\n segments.push(`issuer=${project.issuer}`);\n }\n if (segments.length > 0) {\n lines.push(`Project: ${segments.join(\" \")}`);\n }\n }\n\n if (typeof data.framework === \"string\") {\n lines.push(`framework=${data.framework}`);\n }\n\n if (Array.isArray(data.files_written) || Array.isArray(data.files_skipped)) {\n const written = Array.isArray(data.files_written) ? data.files_written.length : 0;\n const skippedCount = Array.isArray(data.files_skipped) ? data.files_skipped.length : 0;\n lines.push(`Files: ${written} written, ${skippedCount} unchanged`);\n }\n\n if (isObject(data.apply)) {\n const apply = data.apply;\n const bits: string[] = [];\n if (typeof apply.config_version === \"number\") {\n bits.push(`v${apply.config_version}`);\n }\n if (typeof apply.hash === \"string\") {\n bits.push(`hash=${String(apply.hash).slice(0, 12)}`);\n }\n if (typeof apply.environment === \"string\") {\n bits.push(`env=${apply.environment}`);\n }\n if (bits.length > 0) {\n lines.push(`Apply: ${bits.join(\" \")}`);\n }\n }\n\n if (Array.isArray(data.checks) && data.checks.length > 0) {\n lines.push(\"Checks:\");\n for (const check of data.checks) {\n if (!isObject(check)) {\n continue;\n }\n const status = check.status === \"pass\" ? \"ok\" : \"fail\";\n lines.push(` [${status}] ${String(check.name ?? \"check\")}: ${String(check.message ?? \"\")}`);\n }\n }\n}\n\nfunction sourceSuffix(opts: GlobalOptions): string {\n try {\n const url = new URL(opts.source);\n if (url.host === \"api.zitadel.cloud\") {\n return \"\";\n }\n return `(server: ${url.host})`;\n } catch {\n return \"\";\n }\n}\n\nfunction suffixBlock(opts: GlobalOptions): string {\n const suffix = sourceSuffix(opts);\n return suffix ? ` ${suffix}` : \"\";\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as parseJsonObject, S as isObject, T as ZitadelError, n as MANAGED_MARKER, r as DEFAULT_SERVER, w as stableStringify } from "./oclif-DSPO9Sck.mjs";
|
|
2
2
|
import { chmod, mkdir, readFile, rename, stat, writeFile } from "node:fs/promises";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
@@ -814,10 +814,13 @@ function nextCodeOps(ctx, renderer) {
|
|
|
814
814
|
ops.push({
|
|
815
815
|
kind: "add-dep",
|
|
816
816
|
name: renderer.dependency.name,
|
|
817
|
-
version: renderer.dependency.version
|
|
817
|
+
version: dependencyVersionForCli(ctx.cliVersion, renderer.dependency.version)
|
|
818
818
|
});
|
|
819
819
|
return ops;
|
|
820
820
|
}
|
|
821
|
+
function dependencyVersionForCli(cliVersion, fallback) {
|
|
822
|
+
return cliVersion.match(/^\d+\.\d+\.\d+-([0-9A-Za-z]+)(?:[.-]|$)/)?.[1] ?? fallback;
|
|
823
|
+
}
|
|
821
824
|
//#endregion
|
|
822
825
|
//#region src/lib/orca/patchers/index.ts
|
|
823
826
|
/**
|
|
@@ -1003,4 +1006,4 @@ function createOrca() {
|
|
|
1003
1006
|
//#endregion
|
|
1004
1007
|
export { RENDERER_IDS as n, issuerFromPort as r, createOrca as t };
|
|
1005
1008
|
|
|
1006
|
-
//# sourceMappingURL=orca-
|
|
1009
|
+
//# sourceMappingURL=orca-DOxshV9n.mjs.map
|