@zitadel/cli 1.0.0-alpha.21 → 1.0.0-alpha.22
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/SKILLS.md +20 -4
- package/dist/box-B_mwKole.mjs +35 -0
- package/dist/box-B_mwKole.mjs.map +1 -0
- package/dist/{branding-cygSBPkV.mjs → branding-DvoH8e0D.mjs} +2 -2
- package/dist/{branding-cygSBPkV.mjs.map → branding-DvoH8e0D.mjs.map} +1 -1
- package/dist/claim-state-B6ZSKmhW.mjs +125 -0
- package/dist/claim-state-B6ZSKmhW.mjs.map +1 -0
- package/dist/commands/apply.mjs +4 -4
- package/dist/commands/branding/eject.mjs +3 -3
- package/dist/commands/claim.mjs +34 -4
- package/dist/commands/claim.mjs.map +1 -1
- package/dist/commands/doctor.mjs +33 -17
- package/dist/commands/doctor.mjs.map +1 -1
- package/dist/commands/eject.mjs +3 -3
- package/dist/commands/logs.mjs +2 -2
- package/dist/commands/plan.mjs +4 -4
- package/dist/commands/reset.mjs +2 -2
- package/dist/commands/schemas/list.mjs +3 -3
- package/dist/commands/setup.mjs +56 -18
- package/dist/commands/setup.mjs.map +1 -1
- package/dist/commands/start.mjs +3 -3
- package/dist/commands/status.mjs +6 -6
- package/dist/commands/status.mjs.map +1 -1
- package/dist/commands/stop.mjs +3 -3
- package/dist/{docker-Ev1Ggt9l.mjs → docker-B1MjOMFo.mjs} +2 -2
- package/dist/{docker-Ev1Ggt9l.mjs.map → docker-B1MjOMFo.mjs.map} +1 -1
- package/dist/{environment-rjRVkJjW.mjs → environment-fibXmzM8.mjs} +1 -1
- package/dist/{environment-rjRVkJjW.mjs.map → environment-fibXmzM8.mjs.map} +1 -1
- package/dist/{journey-guidance-BGrOX_gT.mjs → journey-guidance-C9MxJNTg.mjs} +2 -2
- package/dist/{journey-guidance-BGrOX_gT.mjs.map → journey-guidance-C9MxJNTg.mjs.map} +1 -1
- package/dist/{oclif-CanO3zdt.mjs → oclif-JlsN1lfO.mjs} +1 -1
- package/dist/{oclif-CanO3zdt.mjs.map → oclif-JlsN1lfO.mjs.map} +1 -1
- package/dist/{orca-66vAxeIe.mjs → orca-CPMHzmg3.mjs} +2 -2
- package/dist/{orca-66vAxeIe.mjs.map → orca-CPMHzmg3.mjs.map} +1 -1
- package/dist/{package-manager-DFdLcDx1.mjs → package-manager-CDUsoGBy.mjs} +3 -3
- package/dist/{package-manager-DFdLcDx1.mjs.map → package-manager-CDUsoGBy.mjs.map} +1 -1
- package/dist/{ports-BM20XIZb.mjs → ports-hidBnSW-.mjs} +2 -2
- package/dist/{ports-BM20XIZb.mjs.map → ports-hidBnSW-.mjs.map} +1 -1
- package/dist/{processes-DKHPkU8O.mjs → processes-Cv19mJ2I.mjs} +1 -1
- package/dist/{processes-DKHPkU8O.mjs.map → processes-Cv19mJ2I.mjs.map} +1 -1
- package/dist/{project-CHhot85s.mjs → project-Ba0nriNm.mjs} +2 -2
- package/dist/{project-CHhot85s.mjs.map → project-Ba0nriNm.mjs.map} +1 -1
- package/dist/{sync-BBlACKzT.mjs → sync-ChlLQ4vZ.mjs} +4 -4
- package/dist/{sync-BBlACKzT.mjs.map → sync-ChlLQ4vZ.mjs.map} +1 -1
- package/dist/{user-schema-DTuOsdKE.mjs → user-schema-C2mC-JTN.mjs} +1 -1
- package/dist/{user-schema-DTuOsdKE.mjs.map → user-schema-C2mC-JTN.mjs.map} +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +7 -5
- package/dist/claim-state-DlfD6Res.mjs +0 -66
- package/dist/claim-state-DlfD6Res.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.mjs","names":[],"sources":["../../src/commands/status.ts"],"sourcesContent":["import { createZitadelClient } from \"@zitadel/api/client\";\n\nimport { claimAction, claimCommand, claimState, type ClaimState } from \"../lib/claim-state\";\nimport { isProcessRunning } from \"../lib/local-server/binary\";\nimport { inspectContainer } from \"../lib/local-server/docker\";\nimport { customizeAndPublishActions, verifyLoginAction } from \"../lib/journey-guidance\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n checkLocalServerHealth,\n readRuntimeMetadata,\n runtimeSummary,\n} from \"../lib/local-server/runtime\";\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\nimport {\n hasZitadelConfig,\n hasZitadelSecret,\n readDevelopmentIssuer,\n readProjectServer,\n readZitadelConfig,\n readZitadelSecret,\n} from \"../lib/project\";\nimport { publicCliCommand } from \"../lib/public-cli\";\n\n/**\n * `zitadel status` — summarize the local server and project state.\n *\n * This is intentionally informational: a missing `zitadel.json`, stopped\n * local server, or orphaned config should be visible without making `status`\n * itself fail.\n */\nexport default class Status extends BaseCommand {\n static override description = \"Summarize the local Zitadel server and project state.\";\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Status);\n const cwd = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n const runtime = await readRuntimeMetadata(cwd);\n if (flags.server === \"local\") {\n await this.toMeta(flags, {\n resolveServer: false,\n source: runtime?.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n } else {\n await this.toMeta(flags);\n }\n let docker: Awaited<ReturnType<typeof inspectContainer>> | undefined;\n let dockerError: string | undefined;\n if (runtime?.backend === \"docker\") {\n try {\n docker = await inspectContainer(runtime.container_name);\n } catch (error) {\n dockerError = error instanceof Error ? error.message : String(error);\n }\n }\n const healthy = runtime ? await checkLocalServerHealth(runtime.server_url) : false;\n const processRunning = runtime?.backend === \"binary\" ? isProcessRunning(runtime.pid) : false;\n const serverLifecycle = lifecycleForRuntime({ docker, healthy, processRunning, runtime });\n\n const project = await projectStatus(this.meta.cwd);\n const users =\n project.lifecycle === \"configured\"\n ? await detectUserPresence(this.meta.cwd, this.meta.source)\n : \"unknown\";\n const nextCommands = nextCommandsFor(serverLifecycle, project, users, this.meta.cliVersion);\n const nextActions = nextActionsFor(project, users, this.meta.cliVersion);\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Zitadel status.\",\n server: {\n lifecycle: serverLifecycle,\n runtime: runtimeSummary(runtime),\n docker: {\n available: dockerError === undefined,\n error: dockerError,\n container_exists: docker?.exists ?? false,\n container_running: docker?.running ?? false,\n },\n process:\n runtime?.backend === \"binary\"\n ? {\n pid: runtime.pid,\n running: processRunning,\n }\n : undefined,\n health: {\n healthy,\n url: runtime?.server_url,\n },\n },\n project,\n next_actions: nextActions,\n next_commands: nextCommands,\n },\n });\n }\n}\n\nfunction lifecycleForRuntime(input: {\n docker: Awaited<ReturnType<typeof inspectContainer>> | undefined;\n healthy: boolean;\n processRunning: boolean;\n runtime: Awaited<ReturnType<typeof readRuntimeMetadata>>;\n}): string {\n if (!input.runtime) {\n return \"missing\";\n }\n if (input.runtime.backend === \"binary\") {\n if (input.processRunning && input.healthy) {\n return \"running\";\n }\n return input.processRunning ? \"unhealthy\" : \"stopped\";\n }\n if (input.docker?.running && input.healthy) {\n return \"running\";\n }\n if (input.docker?.exists) {\n return \"unhealthy\";\n }\n return \"stopped\";\n}\n\ntype ProjectStatus =\n | {\n lifecycle: \"not-configured\";\n message: string;\n }\n | {\n lifecycle: \"orphaned-config\";\n project_id?: string;\n message: string;\n }\n | {\n lifecycle: \"configured\";\n project_id: string;\n issuer?: string;\n /**\n * Whether the project is attached to a team, from the local\n * `.zitadel/secret`. Omitted entirely off the cloud, where there is\n * nothing to attach and the field would only invite agents to act on it.\n */\n claim?: ClaimState;\n };\n\nasync function projectStatus(cwd: string): Promise<ProjectStatus> {\n if (!(await hasZitadelConfig(cwd))) {\n return {\n lifecycle: \"not-configured\",\n message: \"zitadel.json has not been created yet.\",\n };\n }\n\n const config = await readZitadelConfig(cwd);\n if (!(await hasZitadelSecret(cwd))) {\n return {\n lifecycle: \"orphaned-config\",\n project_id: typeof config.project === \"string\" ? config.project : undefined,\n message: \"zitadel.json exists but .zitadel/secret is missing.\",\n };\n }\n\n const secret = await readZitadelSecret(cwd);\n // Gated on the server recorded in `zitadel.json`, not `this.meta.source`:\n // `status --server local` rewrites the source for the health probe, but it\n // does not move the project, so the source would answer the wrong question.\n const claim = claimState({ secret, server: readProjectServer(config) });\n return {\n lifecycle: \"configured\",\n project_id: String(config.project ?? secret.project_id ?? \"\"),\n issuer: readDevelopmentIssuer(config),\n ...(claim.kind === \"not-applicable\" ? {} : { claim }),\n };\n}\n\ntype UserPresence = \"none\" | \"some\" | \"unknown\";\n\nconst PRESENCE_PROBE_TIMEOUT_MS = 1500;\n\n/**\n * Whether the project has any users yet — the journey signal that stages the\n * guidance: before the first successful registration the next step is\n * verifying login, afterwards it is customizing and publishing config. Best\n * effort by design: any failure (server unreachable, stale secret, timeout)\n * reads as `unknown` and the caller keeps the lifecycle-only output.\n */\nasync function detectUserPresence(cwd: string, source: string): Promise<UserPresence> {\n try {\n const secret = await readZitadelSecret(cwd);\n const client = createZitadelClient({\n baseUrl: source,\n token: secret.project_secret,\n });\n const probe = client\n .queryUsers({ limit: 1 }, { signal: AbortSignal.timeout(PRESENCE_PROBE_TIMEOUT_MS) })\n .then(({ users }): UserPresence => (users.length > 0 ? \"some\" : \"none\"))\n .catch((): UserPresence => \"unknown\");\n // The abort signal alone is not enough: DNS resolution can outlive it\n // (getaddrinfo runs on the threadpool and some environments take many\n // seconds to fail), and `status` must stay snappy. Race a detached timer\n // so the answer degrades to \"unknown\" at the deadline no matter what the\n // socket layer does; unref'd so it never keeps the CLI process alive.\n return await Promise.race([\n probe,\n new Promise<UserPresence>((resolve) => {\n setTimeout(() => resolve(\"unknown\"), PRESENCE_PROBE_TIMEOUT_MS + 250).unref();\n }),\n ]);\n } catch {\n return \"unknown\";\n }\n}\n\nfunction nextActionsFor(project: ProjectStatus, users: UserPresence, cliVersion: string): string[] {\n if (project.lifecycle === \"not-configured\") {\n return [\n \"From your app directory, run setup; the CLI will detect the framework or ask in an empty directory.\",\n ];\n }\n if (project.lifecycle !== \"configured\") {\n return [];\n }\n // Additive to the journey staging rather than a stage of its own: attaching a\n // team is orthogonal to whether login works yet, so it appends to whichever\n // stage the user is in instead of displacing it.\n const claim = project.claim?.kind === \"detached\" ? [claimAction(cliVersion)] : [];\n if (users === \"none\") {\n return [verifyLoginAction(project.issuer), ...claim];\n }\n if (users === \"some\") {\n return [...customizeAndPublishActions(cliVersion), ...claim];\n }\n return claim;\n}\n\nfunction nextCommandsFor(\n serverLifecycle: string,\n project: ProjectStatus,\n users: UserPresence,\n cliVersion: string,\n): string[] {\n const commands: string[] = [];\n if (serverLifecycle !== \"running\") {\n commands.push(publicCliCommand(\"start\", cliVersion));\n }\n if (project.lifecycle === \"not-configured\") {\n commands.push(publicCliCommand(\"setup --server local\", cliVersion));\n } else if (project.lifecycle === \"orphaned-config\") {\n commands.push(\n publicCliCommand(\"setup --force\", cliVersion),\n publicCliCommand(\"doctor --fix\", cliVersion),\n );\n } else {\n commands.push(publicCliCommand(\"doctor\", cliVersion));\n if (project.claim?.kind === \"detached\") {\n commands.push(claimCommand(cliVersion));\n }\n if (users === \"none\") {\n // Staged like next_actions: before the first login is proven in a\n // browser, publishing is premature — `plan` previews safely and the\n // verify mission lives in next_actions. `apply` joins once users\n // exist (\"some\") or when the probe can't tell (\"unknown\" keeps the\n // lifecycle-only behavior rather than withholding on no signal).\n commands.push(publicCliCommand(\"plan\", cliVersion));\n } else {\n commands.push(publicCliCommand(\"apply\", cliVersion));\n }\n }\n return commands;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"status.mjs","names":[],"sources":["../../src/commands/status.ts"],"sourcesContent":["import { createZitadelClient } from \"@zitadel/api/client\";\n\nimport {\n claimAction,\n claimCommand,\n claimState,\n claimWindowClosedAction,\n type ClaimState,\n} from \"../lib/claim-state\";\nimport { isProcessRunning } from \"../lib/local-server/binary\";\nimport { inspectContainer } from \"../lib/local-server/docker\";\nimport { customizeAndPublishActions, verifyLoginAction } from \"../lib/journey-guidance\";\nimport {\n DEFAULT_LOCAL_SERVER_URL,\n checkLocalServerHealth,\n readRuntimeMetadata,\n runtimeSummary,\n} from \"../lib/local-server/runtime\";\nimport { BaseCommand, type JsonEnvelope } from \"../lib/oclif\";\nimport { resolveCwd } from \"../lib/paths\";\nimport {\n hasZitadelConfig,\n hasZitadelSecret,\n readDevelopmentIssuer,\n readProjectServer,\n readZitadelConfig,\n readZitadelSecret,\n} from \"../lib/project\";\nimport { publicCliCommand } from \"../lib/public-cli\";\n\n/**\n * `zitadel status` — summarize the local server and project state.\n *\n * This is intentionally informational: a missing `zitadel.json`, stopped\n * local server, or orphaned config should be visible without making `status`\n * itself fail.\n */\nexport default class Status extends BaseCommand {\n static override description = \"Summarize the local Zitadel server and project state.\";\n\n async run(): Promise<JsonEnvelope> {\n const { flags } = await this.parse(Status);\n const cwd = resolveCwd(typeof flags.cwd === \"string\" ? flags.cwd : undefined);\n const runtime = await readRuntimeMetadata(cwd);\n if (flags.server === \"local\") {\n await this.toMeta(flags, {\n resolveServer: false,\n source: runtime?.server_url ?? DEFAULT_LOCAL_SERVER_URL,\n });\n } else {\n await this.toMeta(flags);\n }\n let docker: Awaited<ReturnType<typeof inspectContainer>> | undefined;\n let dockerError: string | undefined;\n if (runtime?.backend === \"docker\") {\n try {\n docker = await inspectContainer(runtime.container_name);\n } catch (error) {\n dockerError = error instanceof Error ? error.message : String(error);\n }\n }\n const healthy = runtime ? await checkLocalServerHealth(runtime.server_url) : false;\n const processRunning = runtime?.backend === \"binary\" ? isProcessRunning(runtime.pid) : false;\n const serverLifecycle = lifecycleForRuntime({ docker, healthy, processRunning, runtime });\n\n const project = await projectStatus(this.meta.cwd);\n const users =\n project.lifecycle === \"configured\"\n ? await detectUserPresence(this.meta.cwd, this.meta.source)\n : \"unknown\";\n const nextCommands = nextCommandsFor(serverLifecycle, project, users, this.meta.cliVersion);\n const nextActions = nextActionsFor(project, users, this.meta.cliVersion);\n\n return this.emit({\n status: \"ok\",\n data: {\n title: \"Zitadel status.\",\n server: {\n lifecycle: serverLifecycle,\n runtime: runtimeSummary(runtime),\n docker: {\n available: dockerError === undefined,\n error: dockerError,\n container_exists: docker?.exists ?? false,\n container_running: docker?.running ?? false,\n },\n process:\n runtime?.backend === \"binary\"\n ? {\n pid: runtime.pid,\n running: processRunning,\n }\n : undefined,\n health: {\n healthy,\n url: runtime?.server_url,\n },\n },\n project,\n next_actions: nextActions,\n next_commands: nextCommands,\n },\n });\n }\n}\n\nfunction lifecycleForRuntime(input: {\n docker: Awaited<ReturnType<typeof inspectContainer>> | undefined;\n healthy: boolean;\n processRunning: boolean;\n runtime: Awaited<ReturnType<typeof readRuntimeMetadata>>;\n}): string {\n if (!input.runtime) {\n return \"missing\";\n }\n if (input.runtime.backend === \"binary\") {\n if (input.processRunning && input.healthy) {\n return \"running\";\n }\n return input.processRunning ? \"unhealthy\" : \"stopped\";\n }\n if (input.docker?.running && input.healthy) {\n return \"running\";\n }\n if (input.docker?.exists) {\n return \"unhealthy\";\n }\n return \"stopped\";\n}\n\ntype ProjectStatus =\n | {\n lifecycle: \"not-configured\";\n message: string;\n }\n | {\n lifecycle: \"orphaned-config\";\n project_id?: string;\n message: string;\n }\n | {\n lifecycle: \"configured\";\n project_id: string;\n issuer?: string;\n /**\n * Whether the project is attached to a team, from the local\n * `.zitadel/secret`. Omitted entirely off the cloud, where there is\n * nothing to attach and the field would only invite agents to act on it.\n */\n claim?: ClaimState;\n };\n\nasync function projectStatus(cwd: string): Promise<ProjectStatus> {\n if (!(await hasZitadelConfig(cwd))) {\n return {\n lifecycle: \"not-configured\",\n message: \"zitadel.json has not been created yet.\",\n };\n }\n\n const config = await readZitadelConfig(cwd);\n if (!(await hasZitadelSecret(cwd))) {\n return {\n lifecycle: \"orphaned-config\",\n project_id: typeof config.project === \"string\" ? config.project : undefined,\n message: \"zitadel.json exists but .zitadel/secret is missing.\",\n };\n }\n\n const secret = await readZitadelSecret(cwd);\n // Gated on the server recorded in `zitadel.json`, not `this.meta.source`:\n // `status --server local` rewrites the source for the health probe, but it\n // does not move the project, so the source would answer the wrong question.\n const claim = claimState({ secret, server: readProjectServer(config) });\n return {\n lifecycle: \"configured\",\n project_id: String(config.project ?? secret.project_id ?? \"\"),\n issuer: readDevelopmentIssuer(config),\n ...(claim.kind === \"not-applicable\" ? {} : { claim }),\n };\n}\n\ntype UserPresence = \"none\" | \"some\" | \"unknown\";\n\nconst PRESENCE_PROBE_TIMEOUT_MS = 1500;\n\n/**\n * Whether the project has any users yet — the journey signal that stages the\n * guidance: before the first successful registration the next step is\n * verifying login, afterwards it is customizing and publishing config. Best\n * effort by design: any failure (server unreachable, stale secret, timeout)\n * reads as `unknown` and the caller keeps the lifecycle-only output.\n */\nasync function detectUserPresence(cwd: string, source: string): Promise<UserPresence> {\n try {\n const secret = await readZitadelSecret(cwd);\n const client = createZitadelClient({\n baseUrl: source,\n token: secret.project_secret,\n });\n const probe = client\n .queryUsers({ limit: 1 }, { signal: AbortSignal.timeout(PRESENCE_PROBE_TIMEOUT_MS) })\n .then(({ users }): UserPresence => (users.length > 0 ? \"some\" : \"none\"))\n .catch((): UserPresence => \"unknown\");\n // The abort signal alone is not enough: DNS resolution can outlive it\n // (getaddrinfo runs on the threadpool and some environments take many\n // seconds to fail), and `status` must stay snappy. Race a detached timer\n // so the answer degrades to \"unknown\" at the deadline no matter what the\n // socket layer does; unref'd so it never keeps the CLI process alive.\n return await Promise.race([\n probe,\n new Promise<UserPresence>((resolve) => {\n setTimeout(() => resolve(\"unknown\"), PRESENCE_PROBE_TIMEOUT_MS + 250).unref();\n }),\n ]);\n } catch {\n return \"unknown\";\n }\n}\n\nfunction nextActionsFor(project: ProjectStatus, users: UserPresence, cliVersion: string): string[] {\n if (project.lifecycle === \"not-configured\") {\n return [\n \"From your app directory, run setup; the CLI will detect the framework or ask in an empty directory.\",\n ];\n }\n if (project.lifecycle !== \"configured\") {\n return [];\n }\n // Additive to the journey staging rather than a stage of its own: attaching a\n // team is orthogonal to whether login works yet, so it appends to whichever\n // stage the user is in instead of displacing it. A closed window flips the\n // nudge to reconciliation wording, which still tells the user to run\n // `claim`: the local record may be stale (claimed from another machine\n // reads detached), and the server resolves the grant before the window,\n // so the command is the authoritative check, never a guaranteed failure.\n const claim =\n project.claim?.kind === \"detached\"\n ? project.claim.claimable\n ? [\n claimAction(\n cliVersion,\n project.claim.deadline === undefined ? undefined : new Date(project.claim.deadline),\n ),\n ]\n : [claimWindowClosedAction(cliVersion)]\n : [];\n if (users === \"none\") {\n return [verifyLoginAction(project.issuer), ...claim];\n }\n if (users === \"some\") {\n return [...customizeAndPublishActions(cliVersion), ...claim];\n }\n return claim;\n}\n\nfunction nextCommandsFor(\n serverLifecycle: string,\n project: ProjectStatus,\n users: UserPresence,\n cliVersion: string,\n): string[] {\n const commands: string[] = [];\n if (serverLifecycle !== \"running\") {\n commands.push(publicCliCommand(\"start\", cliVersion));\n }\n if (project.lifecycle === \"not-configured\") {\n commands.push(publicCliCommand(\"setup --server local\", cliVersion));\n } else if (project.lifecycle === \"orphaned-config\") {\n commands.push(\n publicCliCommand(\"setup --force\", cliVersion),\n publicCliCommand(\"doctor --fix\", cliVersion),\n );\n } else {\n commands.push(publicCliCommand(\"doctor\", cliVersion));\n // Suggested even when the local record says the window has closed: the\n // record can be stale (claimed from another machine reads detached), and\n // `claim` is the safe reconciliation — the server checks the grant\n // before the window, so an attached project answers with a clean skip.\n if (project.claim?.kind === \"detached\") {\n commands.push(claimCommand(cliVersion));\n }\n if (users === \"none\") {\n // Staged like next_actions: before the first login is proven in a\n // browser, publishing is premature — `plan` previews safely and the\n // verify mission lives in next_actions. `apply` joins once users\n // exist (\"some\") or when the probe can't tell (\"unknown\" keeps the\n // lifecycle-only behavior rather than withholding on no signal).\n commands.push(publicCliCommand(\"plan\", cliVersion));\n } else {\n commands.push(publicCliCommand(\"apply\", cliVersion));\n }\n }\n return commands;\n}\n"],"mappings":"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"}
|
package/dist/commands/stop.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { E as ZitadelError, h as readRuntimeMetadata, j as publicCliCommand, p as localContainerName, t as BaseCommand, x as resolveCwd } from "../oclif-
|
|
2
|
-
import { g as stopBinaryRuntime, u as stopAndRemoveContainer } from "../docker-
|
|
3
|
-
import { t as discoverManagedRuntimeProcesses } from "../processes-
|
|
1
|
+
import { E as ZitadelError, h as readRuntimeMetadata, j as publicCliCommand, p as localContainerName, t as BaseCommand, x as resolveCwd } from "../oclif-JlsN1lfO.mjs";
|
|
2
|
+
import { g as stopBinaryRuntime, u as stopAndRemoveContainer } from "../docker-B1MjOMFo.mjs";
|
|
3
|
+
import { t as discoverManagedRuntimeProcesses } from "../processes-Cv19mJ2I.mjs";
|
|
4
4
|
import { Flags } from "@oclif/core";
|
|
5
5
|
//#region src/commands/stop.ts
|
|
6
6
|
var Stop = class Stop extends BaseCommand {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as ZitadelError, i as CONTAINER_HTTP_PORT, r as CONTAINER_DATA_DIR } from "./oclif-
|
|
1
|
+
import { E as ZitadelError, i as CONTAINER_HTTP_PORT, r as CONTAINER_DATA_DIR } from "./oclif-JlsN1lfO.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { mkdir, open, readFile, stat } from "node:fs/promises";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
@@ -433,4 +433,4 @@ function dockerError(action, args, cause) {
|
|
|
433
433
|
//#endregion
|
|
434
434
|
export { followContainerLogs as a, metadataFromStart as c, assertServerPackageAvailable as d, binaryLogs as f, stopBinaryRuntime as g, startBinaryRuntime as h, ensureImage as i, startContainer as l, isProcessRunning as m, currentUser as n, imageAvailable as o, followBinaryLogs as p, dockerAvailable as r, inspectContainer as s, containerLogs as t, stopAndRemoveContainer as u };
|
|
435
435
|
|
|
436
|
-
//# sourceMappingURL=docker-
|
|
436
|
+
//# sourceMappingURL=docker-B1MjOMFo.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docker-Ev1Ggt9l.mjs","names":[],"sources":["../src/lib/local-server/binary.ts","../src/lib/local-server/docker.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { createReadStream } from \"node:fs\";\nimport { mkdir, open, readFile, stat } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\n\nimport { ZitadelError } from \"../errors\";\nimport {\n type BinaryRuntimeMetadata,\n type RuntimeMetadata,\n checkLocalServerHealth,\n} from \"./runtime\";\n\nexport const SERVER_NPM_PACKAGE = \"@zitadel/server\";\nconst START_COMMAND_ENV = \"ZITADEL_SERVER_BINARY\";\nconst START_COMMAND_VERSION_ENV = \"ZITADEL_SERVER_BINARY_VERSION\";\nconst STOP_TIMEOUT_MS = 10_000;\nconst STOP_KILL_TIMEOUT_MS = 2_000;\n\nconst require = createRequire(import.meta.url);\n\nexport type BinaryRunSpec = {\n cliVersion: string;\n dataDir: string;\n logPath: string;\n port: number;\n serverUrl: string;\n};\n\nexport type StopBinaryRuntimeResult = Readonly<{\n pid: number;\n signal?: NodeJS.Signals;\n status: \"failed\" | \"stale\" | \"stopped\";\n target: \"process\" | \"process-group\";\n}>;\n\nexport function resolveServerCommand(env: NodeJS.ProcessEnv = process.env): {\n command: string;\n args: string[];\n serverPackage: string;\n serverVersion: string;\n} {\n if (env[START_COMMAND_ENV]) {\n return {\n command: env[START_COMMAND_ENV],\n args: [],\n serverPackage: SERVER_NPM_PACKAGE,\n serverVersion: env[START_COMMAND_VERSION_ENV]?.trim() || \"override\",\n };\n }\n\n const manifestPath = resolveServerPackageManifest();\n const manifest = require(manifestPath) as { version?: unknown };\n return {\n command: process.execPath,\n args: [join(dirname(manifestPath), \"bin\", \"zitadel-server.js\")],\n serverPackage: SERVER_NPM_PACKAGE,\n serverVersion: typeof manifest.version === \"string\" ? manifest.version : \"unknown\",\n };\n}\n\nexport async function startBinaryRuntime(spec: BinaryRunSpec): Promise<BinaryRuntimeMetadata> {\n const command = resolveServerCommand();\n await mkdir(dirname(spec.logPath), { recursive: true, mode: 0o700 });\n const log = await open(spec.logPath, \"a\", 0o600);\n try {\n const child = spawn(command.command, command.args, {\n detached: true,\n env: {\n ...process.env,\n NEXTGEN_SERVER_ADDRESS: `:${String(spec.port)}`,\n NEXTGEN_SERVER_DATA_DIR: spec.dataDir,\n // Browser-facing URLs (claim, dashboard) must point at this local\n // server, not the cloud default the server config falls back to.\n NEXTGEN_SERVER_PUBLIC_BASE: spec.serverUrl,\n },\n stdio: [\"ignore\", log.fd, log.fd],\n });\n child.unref();\n if (!child.pid) {\n throw new Error(\"server process did not expose a pid\");\n }\n return {\n schema_version: 1,\n backend: \"binary\",\n pid: child.pid,\n command: [command.command, ...command.args].join(\" \"),\n log_path: spec.logPath,\n server_package: command.serverPackage,\n server_version: command.serverVersion,\n port: spec.port,\n server_url: spec.serverUrl,\n data_dir: spec.dataDir,\n created_at: new Date().toISOString(),\n cli_version: spec.cliVersion,\n };\n } finally {\n await log.close();\n }\n}\n\nexport async function stopBinaryRuntime(pid: number): Promise<StopBinaryRuntimeResult> {\n if (!isProcessRunning(pid)) {\n return { pid, status: \"stale\", target: \"process\" };\n }\n const term = signalRuntime(pid, \"SIGTERM\");\n if (!term.sent) {\n return { pid, status: \"stale\", target: term.target };\n }\n if (await waitForExit(pid, STOP_TIMEOUT_MS)) {\n return { pid, status: \"stopped\", target: term.target, signal: \"SIGTERM\" };\n }\n\n if (isProcessRunning(pid)) {\n const kill = signalRuntime(pid, \"SIGKILL\");\n if (kill.sent && (await waitForExit(pid, STOP_KILL_TIMEOUT_MS))) {\n return { pid, status: \"stopped\", target: kill.target, signal: \"SIGKILL\" };\n }\n }\n return { pid, status: \"failed\", target: term.target, signal: \"SIGKILL\" };\n}\n\nexport function isProcessRunning(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return isErrno(error, \"EPERM\");\n }\n}\n\nexport async function binaryLogs(logPath: string, tail: number): Promise<string> {\n let content = \"\";\n try {\n content = await readFile(logPath, \"utf8\");\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return \"\";\n }\n throw error;\n }\n const lines = content.split(/\\r?\\n/);\n const hasTrailingNewline = lines.at(-1) === \"\";\n const body = hasTrailingNewline ? lines.slice(0, -1) : lines;\n const selected = body.slice(-tail).join(\"\\n\");\n return selected.length === 0 ? \"\" : `${selected}${hasTrailingNewline ? \"\\n\" : \"\"}`;\n}\n\nexport async function followBinaryLogs(logPath: string, tail: number): Promise<void> {\n process.stdout.write(await binaryLogs(logPath, tail));\n let offset = await fileSize(logPath);\n await new Promise<void>((resolveFollow, reject) => {\n const interval = setInterval(() => {\n void (async () => {\n try {\n const size = await fileSize(logPath);\n if (size > offset) {\n const stream = createReadStream(logPath, { start: offset, end: size - 1 });\n stream.pipe(process.stdout, { end: false });\n offset = size;\n }\n } catch (error) {\n reject(error);\n }\n })();\n }, 1000);\n const stop = () => {\n clearInterval(interval);\n resolveFollow();\n };\n process.once(\"SIGINT\", stop);\n process.once(\"SIGTERM\", stop);\n });\n}\n\nexport async function assertServerPackageAvailable(): Promise<string> {\n try {\n const command = resolveServerCommand();\n return command.serverVersion;\n } catch (error) {\n throw new ZitadelError(\"E_VALIDATION\", \"Zitadel server npm package is not available\", {\n hint: \"Reinstall @zitadel/cli so npm can install @zitadel/server and its platform package.\",\n nextCommands: [\"npm install @zitadel/cli@alpha\"],\n details: { package: SERVER_NPM_PACKAGE, message: errorMessage(error) },\n });\n }\n}\n\nexport async function binaryRuntimeHealthy(runtime: RuntimeMetadata): Promise<boolean> {\n return (\n runtime.backend === \"binary\" &&\n isProcessRunning(runtime.pid) &&\n (await checkLocalServerHealth(runtime.server_url))\n );\n}\n\nfunction resolveServerPackageManifest(): string {\n try {\n return require.resolve(`${SERVER_NPM_PACKAGE}/package.json`);\n } catch (error) {\n throw new Error(`Missing ${SERVER_NPM_PACKAGE}. Reinstall @zitadel/cli.`, { cause: error });\n }\n}\n\nasync function fileSize(path: string): Promise<number> {\n try {\n return (await stat(path)).size;\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return 0;\n }\n throw error;\n }\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\nfunction signalProcess(pid: number, signal: NodeJS.Signals): boolean {\n try {\n process.kill(pid, signal);\n return true;\n } catch (error) {\n if (isErrno(error, \"ESRCH\")) {\n return false;\n }\n throw error;\n }\n}\n\nfunction signalRuntime(\n pid: number,\n signal: NodeJS.Signals,\n): { sent: boolean; target: \"process\" | \"process-group\" } {\n if (process.platform !== \"win32\") {\n try {\n process.kill(-pid, signal);\n return { sent: true, target: \"process-group\" };\n } catch (error) {\n if (!isErrno(error, \"ESRCH\")) {\n throw error;\n }\n }\n }\n return { sent: signalProcess(pid, signal), target: \"process\" };\n}\n\nasync function waitForExit(pid: number, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (!isProcessRunning(pid)) {\n return true;\n }\n await delay(200);\n }\n return !isProcessRunning(pid);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolveDelay) => setTimeout(resolveDelay, ms));\n}\n","import { spawn } from \"node:child_process\";\n\nimport { ZitadelError } from \"../errors\";\nimport {\n CONTAINER_DATA_DIR,\n CONTAINER_HTTP_PORT,\n type ContainerIdentity,\n type RuntimeMetadata,\n} from \"./runtime\";\n\nexport type DockerResult = {\n status: number;\n stdout: string;\n stderr: string;\n};\n\nexport type DockerRunSpec = {\n containerName: string;\n image: string;\n port: number;\n dataDir: string;\n identity?: ContainerIdentity;\n};\n\nexport function dockerRunArgs(spec: DockerRunSpec): string[] {\n const args = [\n \"run\",\n \"--detach\",\n \"--name\",\n spec.containerName,\n \"--publish\",\n `127.0.0.1:${spec.port}:${CONTAINER_HTTP_PORT}`,\n \"--volume\",\n `${spec.dataDir}:${CONTAINER_DATA_DIR}`,\n \"--env\",\n `NEXTGEN_SERVER_ADDRESS=:${CONTAINER_HTTP_PORT}`,\n \"--env\",\n `NEXTGEN_SERVER_DATA_DIR=${CONTAINER_DATA_DIR}`,\n // Browser-facing URLs (claim, dashboard) must use the host-visible port\n // published above, not the cloud default the server config falls back to.\n \"--env\",\n `NEXTGEN_SERVER_PUBLIC_BASE=http://localhost:${spec.port}`,\n ];\n\n if (spec.identity) {\n args.push(\n \"--volume\",\n `${spec.identity.passwdFile}:/etc/passwd:ro`,\n \"--volume\",\n `${spec.identity.groupFile}:/etc/group:ro`,\n \"--user\",\n `${spec.identity.uid}:${spec.identity.gid}`,\n );\n }\n\n args.push(spec.image);\n return args;\n}\n\nexport async function runDocker(args: string[]): Promise<DockerResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"docker\", args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: process.env,\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout?.setEncoding(\"utf8\");\n child.stderr?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", (chunk: string) => {\n stdout += chunk;\n });\n child.stderr?.on(\"data\", (chunk: string) => {\n stderr += chunk;\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n resolve({ status: code ?? 1, stdout, stderr });\n });\n });\n}\n\nexport async function streamDocker(args: string[]): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"docker\", args, {\n stdio: \"inherit\",\n env: process.env,\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`docker ${args.join(\" \")} exited with status ${code ?? 1}`));\n }\n });\n });\n}\n\nexport async function dockerAvailable(): Promise<DockerResult> {\n return runDocker([\"version\", \"--format\", \"{{.Server.Version}}\"]);\n}\n\nexport async function pullImage(image: string): Promise<void> {\n await requireDocker([\"pull\", \"--quiet\", image], `Pull Docker image ${image}`);\n}\n\nexport async function imageExists(image: string): Promise<boolean> {\n let result: DockerResult;\n const args = [\"image\", \"inspect\", image];\n try {\n result = await runDocker(args);\n } catch (error) {\n throw dockerError(`Inspect Docker image ${image}`, args, error);\n }\n return result.status === 0;\n}\n\nexport async function imageAvailable(image: string): Promise<\"local\" | \"remote\"> {\n if (await imageExists(image)) {\n return \"local\";\n }\n\n const args = [\"manifest\", \"inspect\", image];\n let result: DockerResult;\n try {\n result = await runDocker(args);\n } catch (error) {\n throw dockerError(`Inspect Docker image ${image}`, args, error);\n }\n if (result.status === 0) {\n return \"remote\";\n }\n throw dockerError(`Inspect Docker image ${image}`, args, result);\n}\n\nexport async function ensureImage(image: string): Promise<\"local\" | \"pulled\"> {\n if (await imageExists(image)) {\n return \"local\";\n }\n await pullImage(image);\n return \"pulled\";\n}\n\nexport async function inspectContainer(containerName: string): Promise<{\n exists: boolean;\n running: boolean;\n id?: string;\n image?: string;\n}> {\n const result = await runDocker([\n \"inspect\",\n \"--format\",\n \"{{.Id}} {{.State.Running}} {{.Config.Image}}\",\n containerName,\n ]);\n if (result.status !== 0) {\n return { exists: false, running: false };\n }\n const [id, running, ...imageParts] = result.stdout.trim().split(/\\s+/);\n return { exists: true, running: running === \"true\", id, image: imageParts.join(\" \") };\n}\n\nexport async function startContainer(spec: DockerRunSpec): Promise<string> {\n const args = dockerRunArgs(spec);\n const result = await requireDocker(args, \"Start local Zitadel container\");\n return result.stdout.trim();\n}\n\nexport async function stopAndRemoveContainer(containerName: string): Promise<void> {\n const inspect = await inspectContainer(containerName);\n if (!inspect.exists) {\n return;\n }\n if (inspect.running) {\n await requireDocker([\"stop\", containerName], `Stop ${containerName}`);\n }\n await requireDocker([\"rm\", containerName], `Remove ${containerName}`);\n}\n\nexport async function containerLogs(containerName: string, tail: number): Promise<string> {\n const result = await requireDocker([\"logs\", \"--tail\", String(tail), containerName], \"Read logs\");\n return result.stdout;\n}\n\nexport async function followContainerLogs(containerName: string, tail: number): Promise<void> {\n await streamDocker([\"logs\", \"--tail\", String(tail), \"--follow\", containerName]);\n}\n\nexport function currentUser(): { uid?: number; gid?: number } {\n const getuid = process.getuid;\n const getgid = process.getgid;\n if (typeof getuid !== \"function\") {\n return {};\n }\n const uid = getuid();\n const gid = typeof getgid === \"function\" ? getgid() : uid;\n return { uid, gid };\n}\n\nexport function metadataFromStart(input: {\n cwdDataDir: string;\n cliVersion: string;\n containerName: string;\n containerId: string;\n image: string;\n port: number;\n serverUrl: string;\n}): RuntimeMetadata {\n return {\n schema_version: 1,\n backend: \"docker\",\n container_name: input.containerName,\n container_id: input.containerId,\n image: input.image,\n port: input.port,\n server_url: input.serverUrl,\n data_dir: input.cwdDataDir,\n created_at: new Date().toISOString(),\n cli_version: input.cliVersion,\n };\n}\n\nexport async function requireDocker(args: string[], action: string): Promise<DockerResult> {\n let result: DockerResult;\n try {\n result = await runDocker(args);\n } catch (error) {\n throw dockerError(action, args, error);\n }\n if (result.status !== 0) {\n throw dockerError(action, args, result);\n }\n return result;\n}\n\nfunction dockerError(action: string, args: string[], cause: unknown): ZitadelError {\n const details =\n cause && typeof cause === \"object\" && \"stderr\" in cause\n ? { command: [\"docker\", ...args], stderr: String((cause as { stderr?: unknown }).stderr) }\n : { command: [\"docker\", ...args], cause };\n return new ZitadelError(\"E_VALIDATION\", `${action} failed`, {\n hint: \"Check that Docker is installed, running, and reachable from this shell.\",\n nextCommands: [\"zitadel doctor\"],\n details,\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"docker-B1MjOMFo.mjs","names":[],"sources":["../src/lib/local-server/binary.ts","../src/lib/local-server/docker.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { createReadStream } from \"node:fs\";\nimport { mkdir, open, readFile, stat } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\n\nimport { ZitadelError } from \"../errors\";\nimport {\n type BinaryRuntimeMetadata,\n type RuntimeMetadata,\n checkLocalServerHealth,\n} from \"./runtime\";\n\nexport const SERVER_NPM_PACKAGE = \"@zitadel/server\";\nconst START_COMMAND_ENV = \"ZITADEL_SERVER_BINARY\";\nconst START_COMMAND_VERSION_ENV = \"ZITADEL_SERVER_BINARY_VERSION\";\nconst STOP_TIMEOUT_MS = 10_000;\nconst STOP_KILL_TIMEOUT_MS = 2_000;\n\nconst require = createRequire(import.meta.url);\n\nexport type BinaryRunSpec = {\n cliVersion: string;\n dataDir: string;\n logPath: string;\n port: number;\n serverUrl: string;\n};\n\nexport type StopBinaryRuntimeResult = Readonly<{\n pid: number;\n signal?: NodeJS.Signals;\n status: \"failed\" | \"stale\" | \"stopped\";\n target: \"process\" | \"process-group\";\n}>;\n\nexport function resolveServerCommand(env: NodeJS.ProcessEnv = process.env): {\n command: string;\n args: string[];\n serverPackage: string;\n serverVersion: string;\n} {\n if (env[START_COMMAND_ENV]) {\n return {\n command: env[START_COMMAND_ENV],\n args: [],\n serverPackage: SERVER_NPM_PACKAGE,\n serverVersion: env[START_COMMAND_VERSION_ENV]?.trim() || \"override\",\n };\n }\n\n const manifestPath = resolveServerPackageManifest();\n const manifest = require(manifestPath) as { version?: unknown };\n return {\n command: process.execPath,\n args: [join(dirname(manifestPath), \"bin\", \"zitadel-server.js\")],\n serverPackage: SERVER_NPM_PACKAGE,\n serverVersion: typeof manifest.version === \"string\" ? manifest.version : \"unknown\",\n };\n}\n\nexport async function startBinaryRuntime(spec: BinaryRunSpec): Promise<BinaryRuntimeMetadata> {\n const command = resolveServerCommand();\n await mkdir(dirname(spec.logPath), { recursive: true, mode: 0o700 });\n const log = await open(spec.logPath, \"a\", 0o600);\n try {\n const child = spawn(command.command, command.args, {\n detached: true,\n env: {\n ...process.env,\n NEXTGEN_SERVER_ADDRESS: `:${String(spec.port)}`,\n NEXTGEN_SERVER_DATA_DIR: spec.dataDir,\n // Browser-facing URLs (claim, dashboard) must point at this local\n // server, not the cloud default the server config falls back to.\n NEXTGEN_SERVER_PUBLIC_BASE: spec.serverUrl,\n },\n stdio: [\"ignore\", log.fd, log.fd],\n });\n child.unref();\n if (!child.pid) {\n throw new Error(\"server process did not expose a pid\");\n }\n return {\n schema_version: 1,\n backend: \"binary\",\n pid: child.pid,\n command: [command.command, ...command.args].join(\" \"),\n log_path: spec.logPath,\n server_package: command.serverPackage,\n server_version: command.serverVersion,\n port: spec.port,\n server_url: spec.serverUrl,\n data_dir: spec.dataDir,\n created_at: new Date().toISOString(),\n cli_version: spec.cliVersion,\n };\n } finally {\n await log.close();\n }\n}\n\nexport async function stopBinaryRuntime(pid: number): Promise<StopBinaryRuntimeResult> {\n if (!isProcessRunning(pid)) {\n return { pid, status: \"stale\", target: \"process\" };\n }\n const term = signalRuntime(pid, \"SIGTERM\");\n if (!term.sent) {\n return { pid, status: \"stale\", target: term.target };\n }\n if (await waitForExit(pid, STOP_TIMEOUT_MS)) {\n return { pid, status: \"stopped\", target: term.target, signal: \"SIGTERM\" };\n }\n\n if (isProcessRunning(pid)) {\n const kill = signalRuntime(pid, \"SIGKILL\");\n if (kill.sent && (await waitForExit(pid, STOP_KILL_TIMEOUT_MS))) {\n return { pid, status: \"stopped\", target: kill.target, signal: \"SIGKILL\" };\n }\n }\n return { pid, status: \"failed\", target: term.target, signal: \"SIGKILL\" };\n}\n\nexport function isProcessRunning(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return isErrno(error, \"EPERM\");\n }\n}\n\nexport async function binaryLogs(logPath: string, tail: number): Promise<string> {\n let content = \"\";\n try {\n content = await readFile(logPath, \"utf8\");\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return \"\";\n }\n throw error;\n }\n const lines = content.split(/\\r?\\n/);\n const hasTrailingNewline = lines.at(-1) === \"\";\n const body = hasTrailingNewline ? lines.slice(0, -1) : lines;\n const selected = body.slice(-tail).join(\"\\n\");\n return selected.length === 0 ? \"\" : `${selected}${hasTrailingNewline ? \"\\n\" : \"\"}`;\n}\n\nexport async function followBinaryLogs(logPath: string, tail: number): Promise<void> {\n process.stdout.write(await binaryLogs(logPath, tail));\n let offset = await fileSize(logPath);\n await new Promise<void>((resolveFollow, reject) => {\n const interval = setInterval(() => {\n void (async () => {\n try {\n const size = await fileSize(logPath);\n if (size > offset) {\n const stream = createReadStream(logPath, { start: offset, end: size - 1 });\n stream.pipe(process.stdout, { end: false });\n offset = size;\n }\n } catch (error) {\n reject(error);\n }\n })();\n }, 1000);\n const stop = () => {\n clearInterval(interval);\n resolveFollow();\n };\n process.once(\"SIGINT\", stop);\n process.once(\"SIGTERM\", stop);\n });\n}\n\nexport async function assertServerPackageAvailable(): Promise<string> {\n try {\n const command = resolveServerCommand();\n return command.serverVersion;\n } catch (error) {\n throw new ZitadelError(\"E_VALIDATION\", \"Zitadel server npm package is not available\", {\n hint: \"Reinstall @zitadel/cli so npm can install @zitadel/server and its platform package.\",\n nextCommands: [\"npm install @zitadel/cli@alpha\"],\n details: { package: SERVER_NPM_PACKAGE, message: errorMessage(error) },\n });\n }\n}\n\nexport async function binaryRuntimeHealthy(runtime: RuntimeMetadata): Promise<boolean> {\n return (\n runtime.backend === \"binary\" &&\n isProcessRunning(runtime.pid) &&\n (await checkLocalServerHealth(runtime.server_url))\n );\n}\n\nfunction resolveServerPackageManifest(): string {\n try {\n return require.resolve(`${SERVER_NPM_PACKAGE}/package.json`);\n } catch (error) {\n throw new Error(`Missing ${SERVER_NPM_PACKAGE}. Reinstall @zitadel/cli.`, { cause: error });\n }\n}\n\nasync function fileSize(path: string): Promise<number> {\n try {\n return (await stat(path)).size;\n } catch (error) {\n if (isErrno(error, \"ENOENT\")) {\n return 0;\n }\n throw error;\n }\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\nfunction signalProcess(pid: number, signal: NodeJS.Signals): boolean {\n try {\n process.kill(pid, signal);\n return true;\n } catch (error) {\n if (isErrno(error, \"ESRCH\")) {\n return false;\n }\n throw error;\n }\n}\n\nfunction signalRuntime(\n pid: number,\n signal: NodeJS.Signals,\n): { sent: boolean; target: \"process\" | \"process-group\" } {\n if (process.platform !== \"win32\") {\n try {\n process.kill(-pid, signal);\n return { sent: true, target: \"process-group\" };\n } catch (error) {\n if (!isErrno(error, \"ESRCH\")) {\n throw error;\n }\n }\n }\n return { sent: signalProcess(pid, signal), target: \"process\" };\n}\n\nasync function waitForExit(pid: number, timeoutMs: number): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n if (!isProcessRunning(pid)) {\n return true;\n }\n await delay(200);\n }\n return !isProcessRunning(pid);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolveDelay) => setTimeout(resolveDelay, ms));\n}\n","import { spawn } from \"node:child_process\";\n\nimport { ZitadelError } from \"../errors\";\nimport {\n CONTAINER_DATA_DIR,\n CONTAINER_HTTP_PORT,\n type ContainerIdentity,\n type RuntimeMetadata,\n} from \"./runtime\";\n\nexport type DockerResult = {\n status: number;\n stdout: string;\n stderr: string;\n};\n\nexport type DockerRunSpec = {\n containerName: string;\n image: string;\n port: number;\n dataDir: string;\n identity?: ContainerIdentity;\n};\n\nexport function dockerRunArgs(spec: DockerRunSpec): string[] {\n const args = [\n \"run\",\n \"--detach\",\n \"--name\",\n spec.containerName,\n \"--publish\",\n `127.0.0.1:${spec.port}:${CONTAINER_HTTP_PORT}`,\n \"--volume\",\n `${spec.dataDir}:${CONTAINER_DATA_DIR}`,\n \"--env\",\n `NEXTGEN_SERVER_ADDRESS=:${CONTAINER_HTTP_PORT}`,\n \"--env\",\n `NEXTGEN_SERVER_DATA_DIR=${CONTAINER_DATA_DIR}`,\n // Browser-facing URLs (claim, dashboard) must use the host-visible port\n // published above, not the cloud default the server config falls back to.\n \"--env\",\n `NEXTGEN_SERVER_PUBLIC_BASE=http://localhost:${spec.port}`,\n ];\n\n if (spec.identity) {\n args.push(\n \"--volume\",\n `${spec.identity.passwdFile}:/etc/passwd:ro`,\n \"--volume\",\n `${spec.identity.groupFile}:/etc/group:ro`,\n \"--user\",\n `${spec.identity.uid}:${spec.identity.gid}`,\n );\n }\n\n args.push(spec.image);\n return args;\n}\n\nexport async function runDocker(args: string[]): Promise<DockerResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(\"docker\", args, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n env: process.env,\n });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout?.setEncoding(\"utf8\");\n child.stderr?.setEncoding(\"utf8\");\n child.stdout?.on(\"data\", (chunk: string) => {\n stdout += chunk;\n });\n child.stderr?.on(\"data\", (chunk: string) => {\n stderr += chunk;\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n resolve({ status: code ?? 1, stdout, stderr });\n });\n });\n}\n\nexport async function streamDocker(args: string[]): Promise<void> {\n await new Promise<void>((resolve, reject) => {\n const child = spawn(\"docker\", args, {\n stdio: \"inherit\",\n env: process.env,\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`docker ${args.join(\" \")} exited with status ${code ?? 1}`));\n }\n });\n });\n}\n\nexport async function dockerAvailable(): Promise<DockerResult> {\n return runDocker([\"version\", \"--format\", \"{{.Server.Version}}\"]);\n}\n\nexport async function pullImage(image: string): Promise<void> {\n await requireDocker([\"pull\", \"--quiet\", image], `Pull Docker image ${image}`);\n}\n\nexport async function imageExists(image: string): Promise<boolean> {\n let result: DockerResult;\n const args = [\"image\", \"inspect\", image];\n try {\n result = await runDocker(args);\n } catch (error) {\n throw dockerError(`Inspect Docker image ${image}`, args, error);\n }\n return result.status === 0;\n}\n\nexport async function imageAvailable(image: string): Promise<\"local\" | \"remote\"> {\n if (await imageExists(image)) {\n return \"local\";\n }\n\n const args = [\"manifest\", \"inspect\", image];\n let result: DockerResult;\n try {\n result = await runDocker(args);\n } catch (error) {\n throw dockerError(`Inspect Docker image ${image}`, args, error);\n }\n if (result.status === 0) {\n return \"remote\";\n }\n throw dockerError(`Inspect Docker image ${image}`, args, result);\n}\n\nexport async function ensureImage(image: string): Promise<\"local\" | \"pulled\"> {\n if (await imageExists(image)) {\n return \"local\";\n }\n await pullImage(image);\n return \"pulled\";\n}\n\nexport async function inspectContainer(containerName: string): Promise<{\n exists: boolean;\n running: boolean;\n id?: string;\n image?: string;\n}> {\n const result = await runDocker([\n \"inspect\",\n \"--format\",\n \"{{.Id}} {{.State.Running}} {{.Config.Image}}\",\n containerName,\n ]);\n if (result.status !== 0) {\n return { exists: false, running: false };\n }\n const [id, running, ...imageParts] = result.stdout.trim().split(/\\s+/);\n return { exists: true, running: running === \"true\", id, image: imageParts.join(\" \") };\n}\n\nexport async function startContainer(spec: DockerRunSpec): Promise<string> {\n const args = dockerRunArgs(spec);\n const result = await requireDocker(args, \"Start local Zitadel container\");\n return result.stdout.trim();\n}\n\nexport async function stopAndRemoveContainer(containerName: string): Promise<void> {\n const inspect = await inspectContainer(containerName);\n if (!inspect.exists) {\n return;\n }\n if (inspect.running) {\n await requireDocker([\"stop\", containerName], `Stop ${containerName}`);\n }\n await requireDocker([\"rm\", containerName], `Remove ${containerName}`);\n}\n\nexport async function containerLogs(containerName: string, tail: number): Promise<string> {\n const result = await requireDocker([\"logs\", \"--tail\", String(tail), containerName], \"Read logs\");\n return result.stdout;\n}\n\nexport async function followContainerLogs(containerName: string, tail: number): Promise<void> {\n await streamDocker([\"logs\", \"--tail\", String(tail), \"--follow\", containerName]);\n}\n\nexport function currentUser(): { uid?: number; gid?: number } {\n const getuid = process.getuid;\n const getgid = process.getgid;\n if (typeof getuid !== \"function\") {\n return {};\n }\n const uid = getuid();\n const gid = typeof getgid === \"function\" ? getgid() : uid;\n return { uid, gid };\n}\n\nexport function metadataFromStart(input: {\n cwdDataDir: string;\n cliVersion: string;\n containerName: string;\n containerId: string;\n image: string;\n port: number;\n serverUrl: string;\n}): RuntimeMetadata {\n return {\n schema_version: 1,\n backend: \"docker\",\n container_name: input.containerName,\n container_id: input.containerId,\n image: input.image,\n port: input.port,\n server_url: input.serverUrl,\n data_dir: input.cwdDataDir,\n created_at: new Date().toISOString(),\n cli_version: input.cliVersion,\n };\n}\n\nexport async function requireDocker(args: string[], action: string): Promise<DockerResult> {\n let result: DockerResult;\n try {\n result = await runDocker(args);\n } catch (error) {\n throw dockerError(action, args, error);\n }\n if (result.status !== 0) {\n throw dockerError(action, args, result);\n }\n return result;\n}\n\nfunction dockerError(action: string, args: string[], cause: unknown): ZitadelError {\n const details =\n cause && typeof cause === \"object\" && \"stderr\" in cause\n ? { command: [\"docker\", ...args], stderr: String((cause as { stderr?: unknown }).stderr) }\n : { command: [\"docker\", ...args], cause };\n return new ZitadelError(\"E_VALIDATION\", `${action} failed`, {\n hint: \"Check that Docker is installed, running, and reachable from this shell.\",\n nextCommands: [\"zitadel doctor\"],\n details,\n });\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"environment-
|
|
1
|
+
{"version":3,"file":"environment-fibXmzM8.mjs","names":[],"sources":["../src/lib/environment.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * CLI-side deployment environment. Not an API model — it gates which\n * `zitadel.json` environment block and server the commands target.\n * Project request/response shapes live in `@zitadel/api`\n * (generated from the OpenAPI spec).\n */\nexport const environmentSchema = z.enum([\"development\", \"preview\", \"production\"]);\n"],"mappings":";;;;;;;;AAQA,MAAa,oBAAoB,EAAE,KAAK;CAAC;CAAe;CAAW;CAAa,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { j as publicCliCommand } from "./oclif-
|
|
1
|
+
import { j as publicCliCommand } from "./oclif-JlsN1lfO.mjs";
|
|
2
2
|
//#region src/lib/journey-guidance.ts
|
|
3
3
|
/**
|
|
4
4
|
* Journey-staged guidance copy shared by `setup` and `status`.
|
|
@@ -37,4 +37,4 @@ function brandingGuidanceAction(design, cliVersion) {
|
|
|
37
37
|
//#endregion
|
|
38
38
|
export { customizeAndPublishActions as n, verifyLoginAction as r, brandingGuidanceAction as t };
|
|
39
39
|
|
|
40
|
-
//# sourceMappingURL=journey-guidance-
|
|
40
|
+
//# sourceMappingURL=journey-guidance-C9MxJNTg.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"journey-guidance-
|
|
1
|
+
{"version":3,"file":"journey-guidance-C9MxJNTg.mjs","names":[],"sources":["../src/lib/journey-guidance.ts"],"sourcesContent":["import { publicCliCommand } from \"./public-cli\";\n\n/**\n * Journey-staged guidance copy shared by `setup` and `status`.\n *\n * The staging exists because of alpha tester feedback (Elina, alpha.15):\n * printing customize/publish steps before the user has logged in once reads\n * as noise, but dropping them entirely recreates the round-1 dead end where\n * nothing pointed to the next step. So the guidance tracks journey position —\n * verify first, customize/publish once login demonstrably works — and both\n * commands quote the same copy so the story doesn't fork.\n */\n\n/**\n * The verify mission: prove the scaffolded auth round-trips before touching\n * config. `openUrl` prefixes the browser destination for callers that have\n * not already narrated it (setup's box has a separate \"Start your project\"\n * line; status has only the issuer).\n */\nexport function verifyLoginAction(openUrl?: string): string {\n const open = openUrl ? `open ${openUrl}, ` : \"\";\n return (\n `Verify auth in the browser: ${open}register a user, log out, ` +\n \"log in again with the same user, and confirm /profile shows Signed in.\"\n );\n}\n\n/** The customize/publish pair, in Elina's tested wording. */\nexport function customizeAndPublishActions(cliVersion: string): string[] {\n return [\n \"Customize what you ask for and how people sign in: edit .zitadel/schemas/ to change \" +\n \"the information you collect, and .zitadel/flows/ to change the sign-up/sign-in \" +\n \"experience. Each folder has a README with examples.\",\n `See your changes before they go live: ${publicCliCommand(\"plan\", cliVersion)} to preview, ` +\n `then ${publicCliCommand(\"apply\", cliVersion)} to publish.`,\n ];\n}\n\n/**\n * How to change the login's look, depending on whether setup already ejected\n * a starter design. With a design, revision 1 is already live and the\n * template is repo-owned — point at the files and the plan/apply loop.\n * Without one, point at `branding eject` so the built-in template's\n * customization path stays discoverable after setup.\n */\nexport function brandingGuidanceAction(\n design: string | undefined,\n cliVersion: string,\n): string {\n if (design) {\n return (\n `Make the login yours: the ${design} design is live as branding revision 1. ` +\n \"Edit .zitadel/branding/login.liquid (logo and hero image URLs live in \" +\n `branding.json), then ${publicCliCommand(\"plan\", cliVersion)} and ` +\n `${publicCliCommand(\"apply\", cliVersion)} to publish the next revision.`\n );\n }\n return (\n \"Change how the login looks: \" +\n `${publicCliCommand(\"branding eject\", cliVersion)} scaffolds .zitadel/branding/ ` +\n \"from a starter design (centered, split, split-right, hero, minimal) for you to edit.\"\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,SAAgB,kBAAkB,SAA0B;AAE1D,QACE,+BAFW,UAAU,QAAQ,QAAQ,MAAM,GAEP;;;AAMxC,SAAgB,2BAA2B,YAA8B;AACvE,QAAO,CACL,0NAGA,yCAAyC,iBAAiB,QAAQ,WAAW,CAAC,oBACpE,iBAAiB,SAAS,WAAW,CAAC,cACjD;;;;;;;;;AAUH,SAAgB,uBACd,QACA,YACQ;AACR,KAAI,OACF,QACE,6BAA6B,OAAO,qIAEZ,iBAAiB,QAAQ,WAAW,CAAC,OAC1D,iBAAiB,SAAS,WAAW,CAAC;AAG7C,QACE,+BACG,iBAAiB,kBAAkB,WAAW,CAAC"}
|
|
@@ -1766,4 +1766,4 @@ function suffixBlock(opts) {
|
|
|
1766
1766
|
//#endregion
|
|
1767
1767
|
export { npmDistTagForCliVersion as A, parseJsonObject as C, toZitadelError as D, ZitadelError as E, serverKind as M, normalizePublicCliJson as O, isObject as S, stableStringify as T, removeRuntimeMetadata as _, DEFAULT_LOCAL_SERVER_PORT as a, MANAGED_MARKER as b, checkLocalServerHealth as c, ensureContainerIdentity as d, ensureLocalState as f, removeLocalData as g, readRuntimeMetadata as h, CONTAINER_HTTP_PORT as i, publicCliCommand as j, normalizePublicCliProse as k, defaultLocalServerImageForCliVersion as l, localServerUrl as m, DEFAULT_SERVER as n, DEFAULT_LOCAL_SERVER_URL as o, localContainerName as p, CONTAINER_DATA_DIR as r, assertLocalStateWritable as s, BaseCommand as t, detectHealthyLocalServer as u, runtimeSummary as v, setTopLevelJsonKey as w, resolveCwd as x, writeRuntimeMetadata as y };
|
|
1768
1768
|
|
|
1769
|
-
//# sourceMappingURL=oclif-
|
|
1769
|
+
//# sourceMappingURL=oclif-JlsN1lfO.mjs.map
|