@lizard-build/cli 0.1.0 → 0.3.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/.github/workflows/release.yml +90 -0
  2. package/AGENTS.md +113 -0
  3. package/README.md +41 -0
  4. package/dist/commands/add.js +318 -45
  5. package/dist/commands/add.js.map +1 -1
  6. package/dist/commands/config.d.ts +2 -0
  7. package/dist/commands/config.js +68 -0
  8. package/dist/commands/config.js.map +1 -0
  9. package/dist/commands/docs.d.ts +2 -0
  10. package/dist/commands/docs.js +13 -0
  11. package/dist/commands/docs.js.map +1 -0
  12. package/dist/commands/domain.d.ts +9 -0
  13. package/dist/commands/domain.js +195 -0
  14. package/dist/commands/domain.js.map +1 -0
  15. package/dist/commands/git.js +175 -36
  16. package/dist/commands/git.js.map +1 -1
  17. package/dist/commands/init.d.ts +24 -0
  18. package/dist/commands/init.js +128 -86
  19. package/dist/commands/init.js.map +1 -1
  20. package/dist/commands/link.d.ts +7 -0
  21. package/dist/commands/link.js +104 -33
  22. package/dist/commands/link.js.map +1 -1
  23. package/dist/commands/login.js +4 -3
  24. package/dist/commands/login.js.map +1 -1
  25. package/dist/commands/logs.js +223 -30
  26. package/dist/commands/logs.js.map +1 -1
  27. package/dist/commands/open.js +3 -2
  28. package/dist/commands/open.js.map +1 -1
  29. package/dist/commands/port.d.ts +7 -0
  30. package/dist/commands/port.js +49 -0
  31. package/dist/commands/port.js.map +1 -0
  32. package/dist/commands/projects.js +36 -6
  33. package/dist/commands/projects.js.map +1 -1
  34. package/dist/commands/ps.js +32 -39
  35. package/dist/commands/ps.js.map +1 -1
  36. package/dist/commands/redeploy.js +48 -8
  37. package/dist/commands/redeploy.js.map +1 -1
  38. package/dist/commands/regions.js +2 -5
  39. package/dist/commands/regions.js.map +1 -1
  40. package/dist/commands/restart.js +84 -10
  41. package/dist/commands/restart.js.map +1 -1
  42. package/dist/commands/run.d.ts +9 -0
  43. package/dist/commands/run.js +61 -22
  44. package/dist/commands/run.js.map +1 -1
  45. package/dist/commands/scale.d.ts +10 -0
  46. package/dist/commands/scale.js +166 -0
  47. package/dist/commands/scale.js.map +1 -0
  48. package/dist/commands/secrets.js +200 -89
  49. package/dist/commands/secrets.js.map +1 -1
  50. package/dist/commands/service-set.d.ts +49 -0
  51. package/dist/commands/service-set.js +552 -0
  52. package/dist/commands/service-set.js.map +1 -0
  53. package/dist/commands/service-show.d.ts +11 -0
  54. package/dist/commands/service-show.js +44 -0
  55. package/dist/commands/service-show.js.map +1 -0
  56. package/dist/commands/service.d.ts +8 -0
  57. package/dist/commands/service.js +262 -0
  58. package/dist/commands/service.js.map +1 -0
  59. package/dist/commands/skill.d.ts +2 -0
  60. package/dist/commands/skill.js +146 -0
  61. package/dist/commands/skill.js.map +1 -0
  62. package/dist/commands/ssh.d.ts +2 -0
  63. package/dist/commands/ssh.js +161 -0
  64. package/dist/commands/ssh.js.map +1 -0
  65. package/dist/commands/status.d.ts +7 -0
  66. package/dist/commands/status.js +49 -38
  67. package/dist/commands/status.js.map +1 -1
  68. package/dist/commands/unlink.d.ts +5 -0
  69. package/dist/commands/unlink.js +18 -0
  70. package/dist/commands/unlink.js.map +1 -0
  71. package/dist/commands/up.d.ts +9 -0
  72. package/dist/commands/up.js +417 -0
  73. package/dist/commands/up.js.map +1 -0
  74. package/dist/commands/upgrade.d.ts +2 -0
  75. package/dist/commands/upgrade.js +79 -0
  76. package/dist/commands/upgrade.js.map +1 -0
  77. package/dist/commands/whoami.js +26 -6
  78. package/dist/commands/whoami.js.map +1 -1
  79. package/dist/commands/workspace.d.ts +8 -0
  80. package/dist/commands/workspace.js +36 -0
  81. package/dist/commands/workspace.js.map +1 -0
  82. package/dist/index.js +209 -82
  83. package/dist/index.js.map +1 -1
  84. package/dist/lib/api.d.ts +17 -2
  85. package/dist/lib/api.js +85 -51
  86. package/dist/lib/api.js.map +1 -1
  87. package/dist/lib/auth.d.ts +3 -11
  88. package/dist/lib/auth.js +16 -36
  89. package/dist/lib/auth.js.map +1 -1
  90. package/dist/lib/config.d.ts +36 -15
  91. package/dist/lib/config.js +71 -58
  92. package/dist/lib/config.js.map +1 -1
  93. package/dist/lib/format.d.ts +1 -0
  94. package/dist/lib/format.js +17 -4
  95. package/dist/lib/format.js.map +1 -1
  96. package/dist/lib/name.d.ts +11 -0
  97. package/dist/lib/name.js +26 -0
  98. package/dist/lib/name.js.map +1 -0
  99. package/dist/lib/picker.d.ts +32 -0
  100. package/dist/lib/picker.js +91 -0
  101. package/dist/lib/picker.js.map +1 -0
  102. package/dist/lib/resolve.d.ts +85 -0
  103. package/dist/lib/resolve.js +203 -0
  104. package/dist/lib/resolve.js.map +1 -0
  105. package/dist/lib/updater.d.ts +16 -0
  106. package/dist/lib/updater.js +102 -0
  107. package/dist/lib/updater.js.map +1 -0
  108. package/lizard-wrapper.sh +2 -0
  109. package/package.json +11 -3
  110. package/skill-data/core/SKILL.md +239 -0
  111. package/src/commands/add.ts +388 -56
  112. package/src/commands/config.ts +80 -0
  113. package/src/commands/docs.ts +15 -0
  114. package/src/commands/domain.ts +248 -0
  115. package/src/commands/git.ts +201 -40
  116. package/src/commands/init.ts +149 -100
  117. package/src/commands/link.ts +127 -35
  118. package/src/commands/login.ts +4 -3
  119. package/src/commands/logs.ts +283 -27
  120. package/src/commands/open.ts +3 -2
  121. package/src/commands/port.ts +57 -0
  122. package/src/commands/projects.ts +43 -6
  123. package/src/commands/ps.ts +39 -60
  124. package/src/commands/redeploy.ts +51 -10
  125. package/src/commands/regions.ts +2 -6
  126. package/src/commands/restart.ts +84 -10
  127. package/src/commands/run.ts +68 -24
  128. package/src/commands/scale.ts +216 -0
  129. package/src/commands/secrets.ts +277 -100
  130. package/src/commands/service-set.ts +669 -0
  131. package/src/commands/service-show.ts +52 -0
  132. package/src/commands/service.ts +298 -0
  133. package/src/commands/skill.ts +157 -0
  134. package/src/commands/ssh.ts +176 -0
  135. package/src/commands/status.ts +51 -46
  136. package/src/commands/unlink.ts +17 -0
  137. package/src/commands/up.ts +461 -0
  138. package/src/commands/upgrade.ts +87 -0
  139. package/src/commands/whoami.ts +34 -6
  140. package/src/commands/workspace.ts +44 -0
  141. package/src/index.ts +219 -85
  142. package/src/lib/api.ts +114 -51
  143. package/src/lib/auth.ts +22 -46
  144. package/src/lib/config.ts +100 -65
  145. package/src/lib/format.ts +18 -4
  146. package/src/lib/name.ts +27 -0
  147. package/src/lib/picker.ts +133 -0
  148. package/src/lib/resolve.ts +285 -0
  149. package/src/lib/updater.ts +106 -0
  150. package/test/cli.test.ts +491 -0
  151. package/test/fixtures/hello-app/Dockerfile +5 -0
  152. package/test/fixtures/hello-app/index.js +5 -0
  153. package/test/unit/api.test.ts +66 -0
  154. package/test/unit/config.test.ts +94 -0
  155. package/test/unit/init.test.ts +211 -0
  156. package/test/unit/json.test.ts +208 -0
  157. package/test/unit/picker.test.ts +161 -0
  158. package/test/unit/resolve.test.ts +124 -0
  159. package/test/unit/service-set.test.ts +355 -0
  160. package/vitest.config.ts +10 -0
  161. package/dist/commands/connect.d.ts +0 -2
  162. package/dist/commands/connect.js +0 -117
  163. package/dist/commands/connect.js.map +0 -1
  164. package/dist/commands/context.d.ts +0 -2
  165. package/dist/commands/context.js +0 -71
  166. package/dist/commands/context.js.map +0 -1
  167. package/dist/commands/deploy.d.ts +0 -2
  168. package/dist/commands/deploy.js +0 -120
  169. package/dist/commands/deploy.js.map +0 -1
  170. package/dist/commands/destroy.d.ts +0 -2
  171. package/dist/commands/destroy.js +0 -51
  172. package/dist/commands/destroy.js.map +0 -1
  173. package/dist/commands/update.d.ts +0 -2
  174. package/dist/commands/update.js +0 -41
  175. package/dist/commands/update.js.map +0 -1
  176. package/dist/commands/version.d.ts +0 -2
  177. package/dist/commands/version.js +0 -37
  178. package/dist/commands/version.js.map +0 -1
  179. package/src/commands/connect.ts +0 -145
  180. package/src/commands/context.ts +0 -93
  181. package/src/commands/deploy.ts +0 -153
  182. package/src/commands/destroy.ts +0 -51
  183. package/src/commands/update.ts +0 -44
  184. package/src/commands/version.ts +0 -37
@@ -0,0 +1,552 @@
1
+ import chalk from "chalk";
2
+ import * as p from "@clack/prompts";
3
+ import * as fs from "node:fs";
4
+ import { api, withScope } from "../lib/api.js";
5
+ import { resolveProjectScope, resolveService } from "../lib/resolve.js";
6
+ import { success, info, isJSONMode, printJSON, isTTY } from "../lib/format.js";
7
+ /**
8
+ * `lizard service set` — atomic patch of per-service configuration.
9
+ *
10
+ * Input modes (priority):
11
+ * 1. <service> --set <path>=<value> — positional service + repeatable --set pairs
12
+ * 2. -f <file> — read JSON from file (multi-service)
13
+ * 3. piped stdin JSON — auto-detected when stdin has data
14
+ * 4. interactive — TTY prompts when nothing else is given
15
+ *
16
+ * Field names are flat and match the wire schema of `POST /config:apply`
17
+ * exactly. There is no nested {build,deploy,source} grouping anywhere in the
18
+ * system — DB columns, REST schemas, node-agent payloads, and `service show`
19
+ * output are all flat. See SERVICE_FIELDS below for the full list.
20
+ *
21
+ * Namespaces (variables.*, secrets.*, sharedVariables) are kept because they
22
+ * really are separate stores (per-service / project-wide env), not flat
23
+ * service-config fields.
24
+ */
25
+ /**
26
+ * Canonical service-config fields accepted by `--set` and as keys in a `-f`
27
+ * file's cfg blob. Mirrors `configApplySchema.serviceConfigSchema` in
28
+ * dragonlabs-platform/server/src/routes/projects.ts.
29
+ */
30
+ export const SERVICE_FIELDS = [
31
+ "name", // rename target — only sent when it differs from current
32
+ "sourceType",
33
+ "repoUrl",
34
+ "branch",
35
+ "rootDirectory",
36
+ "buildCommand",
37
+ "watchPatterns",
38
+ "dockerfilePath",
39
+ "startCommand",
40
+ "preDeployCommand",
41
+ "healthcheckPath",
42
+ "healthcheckTimeoutMs",
43
+ ];
44
+ const SERVICE_FIELD_SET = new Set(SERVICE_FIELDS);
45
+ const NUMERIC_FIELDS = new Set(["healthcheckTimeoutMs"]);
46
+ const STRING_ARRAY_FIELDS = new Set(["watchPatterns"]);
47
+ /** Per-service "namespace" keys — not flat fields, separate stores. */
48
+ const NAMESPACE_KEYS = new Set(["variables", "envVars"]);
49
+ /** Allowed top-level keys in a `-f` / stdin JSON payload. */
50
+ const TOP_LEVEL_KEYS = new Set([
51
+ "services",
52
+ "apps",
53
+ "sharedVariables",
54
+ "secrets",
55
+ ]);
56
+ /**
57
+ * Service-name rule mirrored from dragonlabs-platform
58
+ * (server/src/services/var-transform.ts::NAME_REGEX).
59
+ * LIZARD-55: 1–40 chars, lowercase a–z / digits / hyphens, can't start or
60
+ * end with a hyphen.
61
+ */
62
+ const NAME_REGEX = /^[a-z0-9]([a-z0-9-]{0,38}[a-z0-9])?$/;
63
+ const NAME_HINT = "1–40 chars, lowercase a–z, digits, hyphens; can't start or end with a hyphen";
64
+ export function validateName(name) {
65
+ if (!name)
66
+ return "name is required";
67
+ if (name.length > 40)
68
+ return "name must be 40 characters or fewer";
69
+ if (!NAME_REGEX.test(name))
70
+ return `invalid name (${NAME_HINT})`;
71
+ return null;
72
+ }
73
+ export function registerServiceSet(svc) {
74
+ svc
75
+ .command("set")
76
+ .description("Apply build/start/health/source/variables/rename changes to a service")
77
+ .argument("[service]", "Service name or ID (required when using --set)")
78
+ .option("--set <pair>", "Set a field: <path>=<value>. Repeatable.", (val, prev) => [...prev, val], [])
79
+ .option("-f, --file <path>", "JSON config file to apply")
80
+ .option("-s, --service <name>", "Service name or ID")
81
+ .option("-p, --project <id>", "Project name, slug, or ID")
82
+ .option("--force", "Overwrite even if the config was changed remotely")
83
+ .addHelpText("after", `
84
+ Supported --set fields (flat — matches the wire schema and \`service show\`):
85
+ name rename the service (lowercase a-z, digits, hyphens; 1-40 chars)
86
+ sourceType github | upload
87
+ repoUrl string (e.g. https://github.com/acme/api)
88
+ branch string
89
+ rootDirectory string (monorepo subpath)
90
+ buildCommand string (e.g. "npm run build")
91
+ watchPatterns string[] — comma-separated or JSON array
92
+ dockerfilePath string (path to Dockerfile, enables docker build)
93
+ startCommand string (e.g. "node dist/index.js")
94
+ preDeployCommand string (runs once before each rollout, e.g. migrations)
95
+ healthcheckPath string (HTTP path, e.g. /health)
96
+ healthcheckTimeoutMs number (milliseconds)
97
+
98
+ variables.<KEY> string (per-service env shortcut)
99
+ variables.<KEY>.value string (supports \${{ <ref>.KEY }} templates)
100
+
101
+ Notes:
102
+ Use -f <file> or pipe JSON on stdin for multi-service patches.
103
+ --set requires a service argument; pairs are repeatable.
104
+ 'variables.*' are stored as per-service secrets (same runtime env as
105
+ 'lizard secrets set --service <name>'). To set project-wide env, use
106
+ 'lizard secrets set --global' or pass JSON with a top-level
107
+ 'sharedVariables' / 'secrets.shared' block via -f / stdin.
108
+
109
+ Examples:
110
+ lizard service set api --set startCommand="node dist/index.js"
111
+ lizard service set api --set buildCommand="npm run build" --set healthcheckPath=/health
112
+ lizard service set api --set name=api-v2
113
+ lizard service set api --set variables.PORT=3000
114
+ lizard service set api --set variables.DB_URL.value='\${{ postgres.DATABASE_URL }}'
115
+ lizard service set -f lizard-config.json`)
116
+ .action(async (serviceArg, opts) => {
117
+ const { projectId, scope } = await resolveProjectScope(opts.project);
118
+ const patch = await buildPatch(serviceArg || opts.service, opts, projectId, scope);
119
+ if (!patch || isPatchEmpty(patch)) {
120
+ if (isJSONMode()) {
121
+ printJSON({ staged: false, committed: false, message: "No changes" });
122
+ }
123
+ else {
124
+ info(chalk.yellow("No changes to apply"));
125
+ }
126
+ return;
127
+ }
128
+ // Resolve current service names for: rename detection, error messages,
129
+ // and per-service-secret keying. One call, reused.
130
+ const nameById = await fetchNameIndex(projectId, scope, Object.keys(patch.services));
131
+ const body = flattenPatch(patch, nameById);
132
+ // Fetch current configRevision for CAS — skipped when --force is set.
133
+ if (!opts.force) {
134
+ try {
135
+ const proj = await api.get(withScope(`/api/projects/${projectId}`, scope));
136
+ if (proj?.configRevision != null) {
137
+ body.revision = proj.configRevision;
138
+ }
139
+ }
140
+ catch {
141
+ // Non-fatal — proceed without CAS if project fetch fails
142
+ }
143
+ }
144
+ const result = await api
145
+ .post(withScope(`/api/projects/${projectId}/config:apply`, scope), body)
146
+ .catch((err) => {
147
+ if (err?.status === 409) {
148
+ throw new Error(`${err.message}\nUse --force to overwrite.`);
149
+ }
150
+ if (err?.status === 400) {
151
+ const msg = err.message ?? String(err);
152
+ const svcName = msg.match(/Service not found: (\S+)/)?.[1];
153
+ if (svcName) {
154
+ throw new Error(`Service '${svcName}' not found in project. To create it, use 'lizard up --service ${svcName}'.`);
155
+ }
156
+ throw new Error(msg);
157
+ }
158
+ throw err;
159
+ });
160
+ if (isJSONMode()) {
161
+ printJSON({
162
+ ok: result?.ok ?? true,
163
+ revision: result?.revision,
164
+ services: result?.services,
165
+ addons: result?.addons,
166
+ });
167
+ return;
168
+ }
169
+ success(`Service configuration applied`);
170
+ });
171
+ }
172
+ // ── pure transforms (exported for tests) ─────────────────────────────────────
173
+ /**
174
+ * Convert a normalised patch (services keyed by id, flat cfg blobs) into the
175
+ * wire body for `POST /api/projects/:id/config:apply`:
176
+ *
177
+ * { services: [{ id, name?, buildCommand?, startCommand?, ... }],
178
+ * secrets?: { shared?, services? } }
179
+ *
180
+ * `nameById` provides the current display name for each service id. Rename
181
+ * fires only when cfg.name is set AND differs from current — equal names
182
+ * are silently dropped so non-rename calls don't bloat the audit log.
183
+ *
184
+ * Unknown fields in cfg throw before any network call.
185
+ */
186
+ export function flattenPatch(patch, nameById) {
187
+ const out = { services: [] };
188
+ if (!patch || typeof patch !== "object")
189
+ return out;
190
+ const services = patch.services ?? {};
191
+ for (const [id, cfgRaw] of Object.entries(services)) {
192
+ const currentName = nameById.get(id);
193
+ if (!currentName) {
194
+ throw new Error(`Service ${id} no longer exists in the project.`);
195
+ }
196
+ const cfg = cfgRaw && typeof cfgRaw === "object" && !Array.isArray(cfgRaw)
197
+ ? cfgRaw
198
+ : {};
199
+ rejectUnknownServiceFields(cfg, currentName);
200
+ const flat = { id };
201
+ if (cfg.name !== undefined && cfg.name !== currentName) {
202
+ const reason = validateName(String(cfg.name));
203
+ if (reason) {
204
+ throw new Error(`Invalid 'name' for service "${currentName}": ${reason}`);
205
+ }
206
+ flat.name = cfg.name;
207
+ }
208
+ for (const f of SERVICE_FIELDS) {
209
+ if (f === "name")
210
+ continue;
211
+ if (cfg[f] !== undefined)
212
+ flat[f] = cfg[f];
213
+ }
214
+ const svcVars = collectKv(cfg.variables);
215
+ if (cfg.envVars && typeof cfg.envVars === "object") {
216
+ for (const [k, v] of Object.entries(cfg.envVars)) {
217
+ svcVars[k] = v == null ? null : String(v);
218
+ }
219
+ }
220
+ if (Object.keys(svcVars).length > 0) {
221
+ mergeServiceSecrets(out, currentName, svcVars);
222
+ }
223
+ out.services.push(flat);
224
+ }
225
+ if (patch.sharedVariables) {
226
+ mergeSharedSecrets(out, collectKv(patch.sharedVariables));
227
+ }
228
+ if (patch.secrets?.services) {
229
+ for (const [svcName, kv] of Object.entries(patch.secrets.services)) {
230
+ mergeServiceSecrets(out, svcName, kv);
231
+ }
232
+ }
233
+ if (patch.secrets?.shared) {
234
+ mergeSharedSecrets(out, patch.secrets.shared);
235
+ }
236
+ return out;
237
+ }
238
+ function rejectUnknownServiceFields(cfg, serviceName) {
239
+ for (const key of Object.keys(cfg)) {
240
+ if (SERVICE_FIELD_SET.has(key))
241
+ continue;
242
+ if (NAMESPACE_KEYS.has(key))
243
+ continue;
244
+ throw new Error(`Unknown field '${key}' in service "${serviceName}". ` +
245
+ `See 'lizard service set --help' for the list of supported fields.`);
246
+ }
247
+ }
248
+ /** Convert `{ KEY: "v" | { value: "v" } | null }` to a flat `{ KEY: "v" | null }`. */
249
+ function collectKv(src) {
250
+ const out = {};
251
+ if (!src || typeof src !== "object")
252
+ return out;
253
+ for (const [k, raw] of Object.entries(src)) {
254
+ if (raw == null) {
255
+ out[k] = null;
256
+ continue;
257
+ }
258
+ out[k] =
259
+ typeof raw === "object" && "value" in raw
260
+ ? String(raw.value)
261
+ : String(raw);
262
+ }
263
+ return out;
264
+ }
265
+ function mergeServiceSecrets(out, serviceName, kv) {
266
+ out.secrets ??= {};
267
+ out.secrets.services ??= {};
268
+ out.secrets.services[serviceName] = {
269
+ ...(out.secrets.services[serviceName] || {}),
270
+ ...kv,
271
+ };
272
+ }
273
+ function mergeSharedSecrets(out, kv) {
274
+ out.secrets ??= {};
275
+ out.secrets.shared = { ...(out.secrets.shared || {}), ...kv };
276
+ }
277
+ // ── input handling ──────────────────────────────────────────────────────────
278
+ async function buildPatch(serviceArg, opts, projectId, scope) {
279
+ // 1. <service> --set <path>=<value> (repeatable)
280
+ if (opts.set?.length) {
281
+ if (!serviceArg) {
282
+ throw new Error("Service name is required when using --set. Usage: lizard service set <service> --set <path>=<value> (or -s <service>)");
283
+ }
284
+ if (opts.file) {
285
+ throw new Error("Cannot combine --set with --file. Use one input mode.");
286
+ }
287
+ return await setPairsToPatch(serviceArg, opts.set, projectId);
288
+ }
289
+ // 2. -f <file> → JSON file
290
+ if (opts.file) {
291
+ const raw = fs.readFileSync(opts.file, "utf-8");
292
+ const parsed = JSON.parse(raw);
293
+ return await normalisePatch(parsed, projectId);
294
+ }
295
+ // 3. Piped stdin → JSON. Only consume when bytes are actually buffered;
296
+ // otherwise the CLI hangs forever in non-interactive shells.
297
+ if (await stdinHasData()) {
298
+ const stdin = await readStdin();
299
+ const trimmed = stdin.trim();
300
+ if (trimmed) {
301
+ const parsed = JSON.parse(trimmed);
302
+ return await normalisePatch(parsed, projectId);
303
+ }
304
+ }
305
+ // 4. Interactive
306
+ if (isTTY()) {
307
+ return await interactivePatch(projectId, scope);
308
+ }
309
+ return null;
310
+ }
311
+ function readStdin() {
312
+ return new Promise((resolve, reject) => {
313
+ const chunks = [];
314
+ process.stdin.on("data", (c) => chunks.push(c));
315
+ process.stdin.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
316
+ process.stdin.on("error", reject);
317
+ });
318
+ }
319
+ /** Returns true only when stdin is a piped/file source with bytes ready. */
320
+ function stdinHasData() {
321
+ return new Promise((resolve) => {
322
+ if (process.stdin.isTTY)
323
+ return resolve(false);
324
+ const stdin = process.stdin;
325
+ let answered = false;
326
+ const finish = (v) => {
327
+ if (answered)
328
+ return;
329
+ answered = true;
330
+ stdin.removeListener("readable", onReadable);
331
+ stdin.removeListener("end", onEnd);
332
+ clearTimeout(timer);
333
+ resolve(v);
334
+ };
335
+ const onReadable = () => {
336
+ const real = stdin.read();
337
+ if (real) {
338
+ stdin.unshift(real);
339
+ finish(true);
340
+ return;
341
+ }
342
+ };
343
+ const onEnd = () => finish(false);
344
+ stdin.on("readable", onReadable);
345
+ stdin.on("end", onEnd);
346
+ const timer = setTimeout(() => finish(false), 50);
347
+ });
348
+ }
349
+ /**
350
+ * Normalise a raw JSON payload (`-f` / stdin):
351
+ * { services: { name|id: { <flat cfg> } } }
352
+ * { apps: { name|id: { <flat cfg> } } } // alias
353
+ * { name|id: { <flat cfg> } } // shortcut (no siblings)
354
+ * plus optional top-level: sharedVariables, secrets
355
+ *
356
+ * Unknown top-level keys throw. Per-service cfg validation happens in
357
+ * `flattenPatch` once we know the current service name.
358
+ */
359
+ async function normalisePatch(raw, projectId) {
360
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
361
+ throw new Error("Config must be a JSON object.");
362
+ }
363
+ const hasExplicitServices = "services" in raw || "apps" in raw;
364
+ const hasSiblings = "sharedVariables" in raw || "secrets" in raw;
365
+ if (!hasExplicitServices && hasSiblings) {
366
+ throw new Error("Cannot use shortcut form alongside 'sharedVariables'/'secrets'. " +
367
+ "Wrap services in a top-level 'services' key.");
368
+ }
369
+ if (hasExplicitServices) {
370
+ for (const k of Object.keys(raw)) {
371
+ if (!TOP_LEVEL_KEYS.has(k)) {
372
+ throw new Error(`Unknown top-level field '${k}'. ` +
373
+ `Allowed: ${Array.from(TOP_LEVEL_KEYS).join(", ")}.`);
374
+ }
375
+ }
376
+ }
377
+ const root = raw.services ?? raw.apps ?? raw;
378
+ if (typeof root !== "object" || Array.isArray(root)) {
379
+ throw new Error("'services' must be an object keyed by service name or ID.");
380
+ }
381
+ const services = {};
382
+ for (const [key, value] of Object.entries(root)) {
383
+ const svc = await resolveService(projectId, key);
384
+ services[svc.id] = value;
385
+ }
386
+ const out = { services };
387
+ if (raw.sharedVariables)
388
+ out.sharedVariables = raw.sharedVariables;
389
+ if (raw.secrets)
390
+ out.secrets = raw.secrets;
391
+ return out;
392
+ }
393
+ /** Convert a list of "<path>=<value>" pairs (for one service) into a nested patch. */
394
+ async function setPairsToPatch(serviceRef, pairs, projectId) {
395
+ const svc = await resolveService(projectId, serviceRef);
396
+ const cfg = {};
397
+ for (const pair of pairs) {
398
+ const eq = pair.indexOf("=");
399
+ if (eq <= 0) {
400
+ throw new Error(`--set expects <path>=<value>, got "${pair}"`);
401
+ }
402
+ const dotPath = pair.slice(0, eq).trim();
403
+ const rawValue = pair.slice(eq + 1);
404
+ validateSetPath(dotPath);
405
+ const value = parseValue(dotPath, rawValue);
406
+ setDeep(cfg, dotPath, value);
407
+ }
408
+ return { services: { [svc.id]: cfg } };
409
+ }
410
+ /** Validate a `--set` dot-path against the canonical (flat) field list and
411
+ * the `variables.*` namespace. Throws on anything else. */
412
+ export function validateSetPath(dotPath) {
413
+ if (SERVICE_FIELD_SET.has(dotPath))
414
+ return;
415
+ if (dotPath.startsWith("variables.")) {
416
+ const parts = dotPath.split(".");
417
+ // variables.KEY or variables.KEY.value
418
+ if (parts.length === 2 && parts[1])
419
+ return;
420
+ if (parts.length === 3 && parts[1] && parts[2] === "value")
421
+ return;
422
+ throw new Error(`Invalid --set path '${dotPath}'. ` +
423
+ `Use 'variables.<KEY>' or 'variables.<KEY>.value'.`);
424
+ }
425
+ throw new Error(`Unknown --set field '${dotPath}'. ` +
426
+ `See 'lizard service set --help' for the list of supported fields.`);
427
+ }
428
+ /** Interactive prompt loop. Pick service → pick field → enter value. */
429
+ async function interactivePatch(projectId, scope) {
430
+ const data = await api.get(withScope(`/api/projects/${projectId}/services`, scope));
431
+ const services = [...(data.apps || []), ...(data.addons || [])];
432
+ if (services.length === 0) {
433
+ throw new Error("No services in project. Use `lizard add` first.");
434
+ }
435
+ const out = {};
436
+ while (true) {
437
+ const svcId = await p.select({
438
+ message: "Configure which service?",
439
+ options: [
440
+ ...services.map((s) => ({
441
+ value: s.id,
442
+ label: s.name,
443
+ hint: s.status,
444
+ })),
445
+ { value: "__done__", label: "Done — apply changes" },
446
+ ],
447
+ });
448
+ if (p.isCancel(svcId) || svcId === "__done__")
449
+ break;
450
+ const field = await p.select({
451
+ message: "What to change?",
452
+ options: [
453
+ { value: "startCommand", label: "Start command" },
454
+ { value: "preDeployCommand", label: "Pre-deploy command" },
455
+ { value: "buildCommand", label: "Build command" },
456
+ { value: "watchPatterns", label: "Watch patterns" },
457
+ { value: "dockerfilePath", label: "Dockerfile path" },
458
+ { value: "healthcheckPath", label: "Healthcheck path" },
459
+ { value: "healthcheckTimeoutMs", label: "Healthcheck timeout (ms)" },
460
+ { value: "sourceType", label: "Source type (github/upload)" },
461
+ { value: "branch", label: "Branch" },
462
+ { value: "rootDirectory", label: "Root directory" },
463
+ { value: "repoUrl", label: "GitHub repo" },
464
+ { value: "name", label: "Rename service" },
465
+ ],
466
+ });
467
+ if (p.isCancel(field))
468
+ break;
469
+ const valueInput = await p.text({
470
+ message: `${field}`,
471
+ placeholder: field === "watchPatterns"
472
+ ? "comma-separated or JSON array"
473
+ : field === "name"
474
+ ? "new-service-name"
475
+ : "value",
476
+ });
477
+ if (p.isCancel(valueInput))
478
+ break;
479
+ const parsed = parseValue(field, String(valueInput));
480
+ out[svcId] = out[svcId] || {};
481
+ setDeep(out[svcId], field, parsed);
482
+ }
483
+ return { services: out };
484
+ }
485
+ // ── value coercion ──────────────────────────────────────────────────────────
486
+ export function parseValue(dotPath, raw) {
487
+ if (NUMERIC_FIELDS.has(dotPath)) {
488
+ const n = Number(raw);
489
+ if (Number.isNaN(n)) {
490
+ throw new Error(`${dotPath} expects a number, got "${raw}"`);
491
+ }
492
+ return n;
493
+ }
494
+ if (STRING_ARRAY_FIELDS.has(dotPath)) {
495
+ const trimmed = raw.trim();
496
+ if (trimmed.startsWith("[")) {
497
+ try {
498
+ return JSON.parse(trimmed);
499
+ }
500
+ catch {
501
+ throw new Error(`Invalid JSON array for ${dotPath}: ${raw}`);
502
+ }
503
+ }
504
+ return trimmed
505
+ .split(",")
506
+ .map((s) => s.trim())
507
+ .filter(Boolean);
508
+ }
509
+ const trimmed = raw.trim();
510
+ if ((trimmed.startsWith("{") && trimmed.endsWith("}")) ||
511
+ (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
512
+ try {
513
+ return JSON.parse(trimmed);
514
+ }
515
+ catch {
516
+ // store as string
517
+ }
518
+ }
519
+ return raw;
520
+ }
521
+ export function setDeep(obj, dotPath, value) {
522
+ const keys = dotPath.split(".");
523
+ let cur = obj;
524
+ for (let i = 0; i < keys.length - 1; i++) {
525
+ const k = keys[i];
526
+ if (typeof cur[k] !== "object" || cur[k] === null)
527
+ cur[k] = {};
528
+ cur = cur[k];
529
+ }
530
+ cur[keys[keys.length - 1]] = value;
531
+ }
532
+ function isPatchEmpty(patch) {
533
+ if (!patch || typeof patch !== "object")
534
+ return true;
535
+ if (patch.services && Object.keys(patch.services).length === 0) {
536
+ return !patch.sharedVariables && !patch.secrets;
537
+ }
538
+ return false;
539
+ }
540
+ // ── network helpers ─────────────────────────────────────────────────────────
541
+ /**
542
+ * Fetch current display names for each service id in the patch. Reused for
543
+ * rename detection (current vs cfg.name) and per-service-secret keying.
544
+ */
545
+ async function fetchNameIndex(projectId, scope, ids) {
546
+ if (ids.length === 0)
547
+ return new Map();
548
+ const data = await api.get(withScope(`/api/projects/${projectId}/services`, scope));
549
+ const all = [...(data.apps || []), ...(data.addons || [])];
550
+ return new Map(all.map((s) => [s.id, s.name]));
551
+ }
552
+ //# sourceMappingURL=service-set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-set.js","sourceRoot":"","sources":["../../src/commands/service-set.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,GAAG,EAAE,SAAS,EAAsB,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAE/E;;;;;;;;;;;;;;;;;GAiBG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,MAAM,EAAE,yDAAyD;IACjE,YAAY;IACZ,SAAS;IACT,QAAQ;IACR,eAAe;IACf,cAAc;IACd,eAAe;IACf,gBAAgB;IAChB,cAAc;IACd,kBAAkB;IAClB,iBAAiB;IACjB,sBAAsB;CACd,CAAC;AAEX,MAAM,iBAAiB,GAAwB,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC;AACvE,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;AAC9E,MAAM,mBAAmB,GAAwB,IAAI,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;AAE5E,uEAAuE;AACvE,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;AAE9E,6DAA6D;AAC7D,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IAClD,UAAU;IACV,MAAM;IACN,iBAAiB;IACjB,SAAS;CACV,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,UAAU,GAAG,sCAAsC,CAAC;AAC1D,MAAM,SAAS,GACb,8EAA8E,CAAC;AAEjF,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC,IAAI;QAAE,OAAO,kBAAkB,CAAC;IACrC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,qCAAqC,CAAC;IACnE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,iBAAiB,SAAS,GAAG,CAAC;IACjE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,GAAG;SACA,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CACV,uEAAuE,CACxE;SACA,QAAQ,CAAC,WAAW,EAAE,gDAAgD,CAAC;SACvE,MAAM,CACL,cAAc,EACd,0CAA0C,EAC1C,CAAC,GAAW,EAAE,IAAc,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,EAC/C,EAAc,CACf;SACA,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,CAAC;SACxD,MAAM,CAAC,sBAAsB,EAAE,oBAAoB,CAAC;SACpD,MAAM,CAAC,oBAAoB,EAAE,2BAA2B,CAAC;SACzD,MAAM,CAAC,SAAS,EAAE,mDAAmD,CAAC;SACtE,WAAW,CAAC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2CAgCiB,CAAC;SACvC,MAAM,CAAC,KAAK,EAAE,UAA8B,EAAE,IAAI,EAAE,EAAE;QACrD,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAErE,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QACnF,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,IAAI,UAAU,EAAE,EAAE,CAAC;gBACjB,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;YACxE,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAC5C,CAAC;YACD,OAAO;QACT,CAAC;QAED,uEAAuE;QACvE,mDAAmD;QACnD,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;QAErF,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAE3C,sEAAsE;QACtE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CACxB,SAAS,CAAC,iBAAiB,SAAS,EAAE,EAAE,KAAK,CAAC,CAC/C,CAAC;gBACF,IAAI,IAAI,EAAE,cAAc,IAAI,IAAI,EAAE,CAAC;oBAChC,IAAY,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC;gBAC/C,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,yDAAyD;YAC3D,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,GAAG;aACrB,IAAI,CAKF,SAAS,CAAC,iBAAiB,SAAS,eAAe,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC;aACpE,KAAK,CAAC,CAAC,GAAQ,EAAE,EAAE;YAClB,IAAI,GAAG,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC;YAC/D,CAAC;YACD,IAAI,GAAG,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;gBACxB,MAAM,GAAG,GAAW,GAAG,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC/C,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC3D,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,IAAI,KAAK,CACb,YAAY,OAAO,kEAAkE,OAAO,IAAI,CACjG,CAAC;gBACJ,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC,CAAC,CAAC;QAEL,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,SAAS,CAAC;gBACR,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,IAAI;gBACtB,QAAQ,EAAE,MAAM,EAAE,QAAQ;gBAC1B,QAAQ,EAAE,MAAM,EAAE,QAAQ;gBAC1B,MAAM,EAAE,MAAM,EAAE,MAAM;aACvB,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,OAAO,CAAC,+BAA+B,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACP,CAAC;AAED,gFAAgF;AAEhF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAU,EACV,QAA6B;IAE7B,MAAM,GAAG,GAAuC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IACjE,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAEpD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEtC,KAAK,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,MAAM,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,mCAAmC,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,GAAG,GACP,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAC5D,CAAC,CAAE,MAAkC;YACrC,CAAC,CAAC,EAAE,CAAC;QAET,0BAA0B,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAE7C,MAAM,IAAI,GAA4B,EAAE,EAAE,EAAE,CAAC;QAE7C,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACvD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,+BAA+B,WAAW,MAAM,MAAM,EAAE,CAAC,CAAC;YAC5E,CAAC;YACD,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACvB,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,MAAM;gBAAE,SAAS;YAC3B,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS;gBAAE,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,GAAG,CAAC,OAAO,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACnD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAkC,CAAC,EAAE,CAAC;gBAC5E,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpC,mBAAmB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QAED,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QAC1B,kBAAkB,CAAC,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnE,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,EAAmC,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAC1B,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,0BAA0B,CACjC,GAA4B,EAC5B,WAAmB;IAEnB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QACzC,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QACtC,MAAM,IAAI,KAAK,CACb,kBAAkB,GAAG,iBAAiB,WAAW,KAAK;YACpD,mEAAmE,CACtE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,sFAAsF;AACtF,SAAS,SAAS,CAAC,GAAY;IAC7B,MAAM,GAAG,GAAkC,EAAE,CAAC;IAC9C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IAChD,KAAK,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAA8B,CAAC,EAAE,CAAC;QACtE,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YAChB,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YACd,SAAS;QACX,CAAC;QACD,GAAG,CAAC,CAAC,CAAC;YACJ,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,IAAK,GAA+B;gBACpE,CAAC,CAAC,MAAM,CAAE,GAA+B,CAAC,KAAK,CAAC;gBAChD,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,mBAAmB,CAC1B,GAAsB,EACtB,WAAmB,EACnB,EAAiC;IAEjC,GAAG,CAAC,OAAO,KAAK,EAAE,CAAC;IACnB,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,EAAE,CAAC;IAC5B,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG;QAClC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;QAC5C,GAAG,EAAE;KACN,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CACzB,GAAsB,EACtB,EAAiC;IAEjC,GAAG,CAAC,OAAO,KAAK,EAAE,CAAC;IACnB,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC;AAChE,CAAC;AAED,+EAA+E;AAE/E,KAAK,UAAU,UAAU,CACvB,UAA8B,EAC9B,IAAS,EACT,SAAiB,EACjB,KAAoB;IAEpB,iDAAiD;IACjD,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC;QACrB,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,wHAAwH,CACzH,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,MAAM,eAAe,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAChE,CAAC;IAED,2BAA2B;IAC3B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,OAAO,MAAM,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;IAED,wEAAwE;IACxE,gEAAgE;IAChE,IAAI,MAAM,YAAY,EAAE,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnC,OAAO,MAAM,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,IAAI,KAAK,EAAE,EAAE,CAAC;QACZ,OAAO,MAAM,gBAAgB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAC3B,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CACjD,CAAC;QACF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,4EAA4E;AAC5E,SAAS,YAAY;IACnB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK;YAAE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;QAE/C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,MAAM,GAAG,CAAC,CAAU,EAAE,EAAE;YAC5B,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,KAAK,CAAC,cAAc,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAC7C,KAAK,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACnC,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,CAAC,CAAC,CAAC;QACb,CAAC,CAAC;QAEF,MAAM,UAAU,GAAG,GAAG,EAAE;YACtB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;YAC1B,IAAI,IAAI,EAAE,CAAC;gBACT,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC,CAAC;gBACb,OAAO;YACT,CAAC;QACH,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAElC,KAAK,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACjC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAEvB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,cAAc,CAAC,GAAQ,EAAE,SAAiB;IACvD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,mBAAmB,GAAG,UAAU,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,CAAC;IAC/D,MAAM,WAAW,GAAG,iBAAiB,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,CAAC;IAEjE,IAAI,CAAC,mBAAmB,IAAI,WAAW,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,kEAAkE;YAChE,8CAA8C,CACjD,CAAC;IACJ,CAAC;IAED,IAAI,mBAAmB,EAAE,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACb,4BAA4B,CAAC,KAAK;oBAChC,YAAY,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACvD,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAQ,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC;IAClD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,QAAQ,GAAwB,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACjD,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED,MAAM,GAAG,GAAQ,EAAE,QAAQ,EAAE,CAAC;IAC9B,IAAI,GAAG,CAAC,eAAe;QAAE,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC;IACnE,IAAI,GAAG,CAAC,OAAO;QAAE,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC3C,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sFAAsF;AACtF,KAAK,UAAU,eAAe,CAC5B,UAAkB,EAClB,KAAe,EACf,SAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,GAAG,GAAwB,EAAE,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,sCAAsC,IAAI,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACpC,eAAe,CAAC,OAAO,CAAC,CAAC;QACzB,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC;AACzC,CAAC;AAED;4DAC4D;AAC5D,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,IAAI,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO;IAC3C,IAAI,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjC,yCAAyC;QACzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO;QAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,OAAO;YAAE,OAAO;QACnE,MAAM,IAAI,KAAK,CACb,uBAAuB,OAAO,KAAK;YACjC,mDAAmD,CACtD,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,KAAK,CACb,wBAAwB,OAAO,KAAK;QAClC,mEAAmE,CACtE,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,KAAK,UAAU,gBAAgB,CAC7B,SAAiB,EACjB,KAAoB;IAEpB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CACxB,SAAS,CAAC,iBAAiB,SAAS,WAAW,EAAE,KAAK,CAAC,CACxD,CAAC;IACF,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;IAChE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,GAAG,GAAwB,EAAE,CAAC;IAEpC,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC;YAC3B,OAAO,EAAE,0BAA0B;YACnC,OAAO,EAAE;gBACP,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;oBAC3B,KAAK,EAAE,CAAC,CAAC,EAAE;oBACX,KAAK,EAAE,CAAC,CAAC,IAAI;oBACb,IAAI,EAAE,CAAC,CAAC,MAAM;iBACf,CAAC,CAAC;gBACH,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,sBAAsB,EAAE;aACrD;SACF,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,UAAU;YAAE,MAAM;QAErD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC;YAC3B,OAAO,EAAE,iBAAiB;YAC1B,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE;gBACjD,EAAE,KAAK,EAAE,kBAAkB,EAAE,KAAK,EAAE,oBAAoB,EAAE;gBAC1D,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,eAAe,EAAE;gBACjD,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,gBAAgB,EAAE;gBACnD,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE;gBACrD,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,kBAAkB,EAAE;gBACvD,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,0BAA0B,EAAE;gBACpE,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,6BAA6B,EAAE;gBAC7D,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;gBACpC,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,gBAAgB,EAAE;gBACnD,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE;gBAC1C,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE;aAC3C;SACF,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM;QAE7B,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC;YAC9B,OAAO,EAAE,GAAG,KAAK,EAAE;YACnB,WAAW,EACT,KAAK,KAAK,eAAe;gBACvB,CAAC,CAAC,+BAA+B;gBACjC,CAAC,CAAC,KAAK,KAAK,MAAM;oBAChB,CAAC,CAAC,kBAAkB;oBACpB,CAAC,CAAC,OAAO;SAChB,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,MAAM;QAElC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAe,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QAC/D,GAAG,CAAC,KAAe,CAAC,GAAG,GAAG,CAAC,KAAe,CAAC,IAAI,EAAE,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,KAAe,CAAC,EAAE,KAAe,EAAE,MAAM,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;AAC3B,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,GAAW;IACrD,IAAI,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,2BAA2B,GAAG,GAAG,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CAAC,0BAA0B,OAAO,KAAK,GAAG,EAAE,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;QACD,OAAO,OAAO;aACX,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IACE,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAClD,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAClD,CAAC;QACD,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACP,kBAAkB;QACpB,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,GAAwB,EACxB,OAAe,EACf,KAAc;IAEd,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;QAC/D,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;IACf,CAAC;IACD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;AACrC,CAAC;AAED,SAAS,YAAY,CAAC,KAAU;IAC9B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACrD,IAAI,KAAK,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/D,OAAO,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;IAClD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+EAA+E;AAE/E;;;GAGG;AACH,KAAK,UAAU,cAAc,CAC3B,SAAiB,EACjB,KAAoB,EACpB,GAAa;IAEb,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CACxB,SAAS,CAAC,iBAAiB,SAAS,WAAW,EAAE,KAAK,CAAC,CACxD,CAAC;IACF,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3D,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Command } from "commander";
2
+ /**
3
+ * `lizard service show` — print the current service configuration as JSON.
4
+ *
5
+ * Works for both apps and addons. Without `-s` shows the whole project
6
+ * (`{ apps, addons }`). With `-s <name>` shows just that service.
7
+ *
8
+ * Useful for diff-ing against a `lizard.config.json`, seeding a new file,
9
+ * or feeding into `lizard service set` to roll back.
10
+ */
11
+ export declare function registerServiceShow(svc: Command): void;
@@ -0,0 +1,44 @@
1
+ import { api, withScope } from "../lib/api.js";
2
+ import { resolveProjectScope, resolveService } from "../lib/resolve.js";
3
+ import { printJSON } from "../lib/format.js";
4
+ /**
5
+ * `lizard service show` — print the current service configuration as JSON.
6
+ *
7
+ * Works for both apps and addons. Without `-s` shows the whole project
8
+ * (`{ apps, addons }`). With `-s <name>` shows just that service.
9
+ *
10
+ * Useful for diff-ing against a `lizard.config.json`, seeding a new file,
11
+ * or feeding into `lizard service set` to roll back.
12
+ */
13
+ export function registerServiceShow(svc) {
14
+ svc
15
+ .command("show")
16
+ .description("Show the current service configuration as JSON")
17
+ .argument("[service]", "Service name or ID (omit for whole project)")
18
+ .option("-s, --service <name>", "Limit output to one service")
19
+ .option("-p, --project <id>", "Project name, slug, or ID")
20
+ .action(async (serviceArg, opts) => {
21
+ const { projectId, scope } = await resolveProjectScope(opts.project);
22
+ const ref = serviceArg || opts.service;
23
+ if (ref) {
24
+ const svcInfo = await resolveService(projectId, ref);
25
+ if (svcInfo.kind === "app") {
26
+ const detail = await api.get(withScope(`/api/apps/${svcInfo.id}`, scope));
27
+ printJSON(detail);
28
+ return;
29
+ }
30
+ // Addons: pluck from the project /services endpoint, which already
31
+ // returns rich addon objects (connection, config, volume, region).
32
+ // There is no per-addon GET route on the backend.
33
+ const data = await api.get(withScope(`/api/projects/${projectId}/services`, scope));
34
+ const addon = (data.addons || []).find((a) => a.id === svcInfo.id);
35
+ if (!addon)
36
+ throw new Error(`Addon ${svcInfo.name} not found`);
37
+ printJSON(addon);
38
+ return;
39
+ }
40
+ const data = await api.get(withScope(`/api/projects/${projectId}/services`, scope));
41
+ printJSON(data);
42
+ });
43
+ }
44
+ //# sourceMappingURL=service-show.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-show.js","sourceRoot":"","sources":["../../src/commands/service-show.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAY;IAC9C,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,gDAAgD,CAAC;SAC7D,QAAQ,CAAC,WAAW,EAAE,6CAA6C,CAAC;SACpE,MAAM,CAAC,sBAAsB,EAAE,6BAA6B,CAAC;SAC7D,MAAM,CAAC,oBAAoB,EAAE,2BAA2B,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,UAA8B,EAAE,IAAI,EAAE,EAAE;QACrD,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAErE,MAAM,GAAG,GAAG,UAAU,IAAI,IAAI,CAAC,OAAO,CAAC;QACvC,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YACrD,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;gBAC3B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAC1B,SAAS,CAAC,aAAa,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,CAC5C,CAAC;gBACF,SAAS,CAAC,MAAM,CAAC,CAAC;gBAClB,OAAO;YACT,CAAC;YACD,mEAAmE;YACnE,mEAAmE;YACnE,kDAAkD;YAClD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CACxB,SAAS,CAAC,iBAAiB,SAAS,WAAW,EAAE,KAAK,CAAC,CACxD,CAAC;YACF,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,EAAE,CAAC,CAAC;YACxE,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,SAAS,OAAO,CAAC,IAAI,YAAY,CAAC,CAAC;YAC/D,SAAS,CAAC,KAAK,CAAC,CAAC;YACjB,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,GAAG,CACxB,SAAS,CAAC,iBAAiB,SAAS,WAAW,EAAE,KAAK,CAAC,CACxD,CAAC;QACF,SAAS,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { Command } from "commander";
2
+ /**
3
+ * `lizard service` — service group:
4
+ * - bare: link a service to cwd
5
+ * - list / link / status / delete / rename / set / show / logs
6
+ * (scale / redeploy / restart live on the top-level commands of the same name)
7
+ */
8
+ export declare function registerService(program: Command): void;