@launchmatic/cli 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +102 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -26221,6 +26221,74 @@ function prompt6(question) {
26221
26221
  });
26222
26222
  });
26223
26223
  }
26224
+ function parseIndices(spec, max) {
26225
+ const out = /* @__PURE__ */ new Set();
26226
+ for (const token of spec.split(",").map((s) => s.trim()).filter(Boolean)) {
26227
+ const range = token.match(/^(\d+)-(\d+)$/);
26228
+ if (range) {
26229
+ const lo = parseInt(range[1], 10) - 1;
26230
+ const hi = parseInt(range[2], 10) - 1;
26231
+ if (lo >= 0 && hi < max && lo <= hi) {
26232
+ for (let i = lo; i <= hi; i++) out.add(i);
26233
+ }
26234
+ continue;
26235
+ }
26236
+ const n = parseInt(token, 10);
26237
+ if (Number.isFinite(n) && n >= 1 && n <= max) out.add(n - 1);
26238
+ }
26239
+ return [...out].sort((a, b) => a - b);
26240
+ }
26241
+ async function reviewList(label, items, render, editable) {
26242
+ if (items.length === 0) return items;
26243
+ let current = [...items];
26244
+ for (let round = 0; round < 5; round++) {
26245
+ console.log();
26246
+ console.log(source_default.bold(`Review ${label}:`));
26247
+ current.forEach((item, i) => {
26248
+ console.log(` ${source_default.dim(String(i + 1).padStart(2))}. ${render(item)}`);
26249
+ });
26250
+ const action = (await prompt6(
26251
+ `Action \u2014 [Enter] accept, [r] remove, [e] edit, [a] add? `
26252
+ )).toLowerCase();
26253
+ if (!action || action === "a" && current.length === items.length) {
26254
+ if (!action) break;
26255
+ }
26256
+ if (action === "r") {
26257
+ const spec = await prompt6("Indices to remove (e.g. 1,3-4): ");
26258
+ const drop = new Set(parseIndices(spec, current.length));
26259
+ if (drop.size > 0) {
26260
+ current = current.filter((_, i) => !drop.has(i));
26261
+ console.log(source_default.dim(`Removed ${drop.size} item${drop.size === 1 ? "" : "s"}.`));
26262
+ }
26263
+ continue;
26264
+ }
26265
+ if (action === "e") {
26266
+ const spec = await prompt6("Indices to edit (e.g. 2): ");
26267
+ const editIdx = parseIndices(spec, current.length);
26268
+ for (const idx of editIdx) {
26269
+ const item = { ...current[idx] };
26270
+ console.log(source_default.dim(`
26271
+ Editing ${render(item)}`));
26272
+ for (const field of editable) {
26273
+ const cur = item[field.key];
26274
+ const display = cur === void 0 || cur === null ? source_default.dim("unset") : source_default.cyan(String(cur));
26275
+ const ans = await prompt6(` ${field.label} [${display}]: `);
26276
+ if (ans) {
26277
+ if (field.numeric) {
26278
+ const n = parseInt(ans, 10);
26279
+ if (Number.isFinite(n)) item[field.key] = n;
26280
+ } else {
26281
+ item[field.key] = ans;
26282
+ }
26283
+ }
26284
+ }
26285
+ current[idx] = item;
26286
+ }
26287
+ continue;
26288
+ }
26289
+ }
26290
+ return current;
26291
+ }
26224
26292
  async function initManifest(opts) {
26225
26293
  if (!requireLogin3()) return;
26226
26294
  const repoRoot = findRepoRoot();
@@ -26232,8 +26300,8 @@ async function initManifest(opts) {
26232
26300
  return;
26233
26301
  }
26234
26302
  const spin = ora("Discovering services and infra...").start();
26235
- const discovered = discoverServices(repoRoot);
26236
- const discoveredInfra = discoverInfra(repoRoot);
26303
+ let discovered = discoverServices(repoRoot);
26304
+ let discoveredInfra = discoverInfra(repoRoot);
26237
26305
  spin.stop();
26238
26306
  if (discovered.length === 0) {
26239
26307
  console.error(source_default.red("No services discovered."));
@@ -26256,6 +26324,38 @@ Discovered ${discoveredInfra.length} infra dependenc${discoveredInfra.length ===
26256
26324
  console.log(` ${source_default.magenta(i.name)} ${source_default.dim(i.engine)}${v}`);
26257
26325
  }
26258
26326
  }
26327
+ if (!opts.yes) {
26328
+ discovered = await reviewList(
26329
+ `services`,
26330
+ discovered,
26331
+ (s) => `${source_default.cyan(s.name)} ${source_default.dim(s.rootDir)}${s.framework ? source_default.dim(` [${s.framework}]`) : ""}`,
26332
+ [
26333
+ { key: "name", label: "name" },
26334
+ { key: "rootDir", label: "rootDir" },
26335
+ { key: "framework", label: "framework" },
26336
+ { key: "buildCmd", label: "buildCmd" },
26337
+ { key: "startCmd", label: "startCmd" },
26338
+ { key: "port", label: "port", numeric: true }
26339
+ ]
26340
+ );
26341
+ if (discovered.length === 0) {
26342
+ console.error(source_default.red("All services removed. Nothing to create."));
26343
+ process.exitCode = 1;
26344
+ return;
26345
+ }
26346
+ if (discoveredInfra.length > 0) {
26347
+ discoveredInfra = await reviewList(
26348
+ `infra`,
26349
+ discoveredInfra,
26350
+ (i) => `${source_default.magenta(i.name)} ${source_default.dim(i.engine)}${i.version ? source_default.dim(` ${i.version}`) : ""}`,
26351
+ [
26352
+ { key: "name", label: "name" },
26353
+ { key: "engine", label: "engine (POSTGRESQL/POSTGIS/REDIS/MONGODB/MYSQL)" },
26354
+ { key: "version", label: "version" }
26355
+ ]
26356
+ );
26357
+ }
26358
+ }
26259
26359
  const { data: teams } = await api("/api/teams");
26260
26360
  if (!teams || teams.length === 0) {
26261
26361
  console.error(source_default.red("No teams found on your account."));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@launchmatic/cli",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Launchmatic CLI — deploy from your terminal",
5
5
  "private": false,
6
6
  "type": "module",