@datarails-ai/dr-appspace-cli 0.12.12 → 0.12.14

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/cli.js +104 -34
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -13,7 +13,7 @@ import { fileURLToPath as fileURLToPath6 } from "url";
13
13
  // package.json
14
14
  var package_default = {
15
15
  name: "@datarails-ai/dr-appspace-cli",
16
- version: "0.12.12",
16
+ version: "0.12.14",
17
17
  description: "Datarails App Space CLI \u2014 build, try, push and publish App Space apps",
18
18
  type: "module",
19
19
  engines: {
@@ -57,7 +57,7 @@ var package_default = {
57
57
  };
58
58
 
59
59
  // src/buildInfo.ts
60
- var BUILD_TIME = "2026-10-14T20:08:09.415Z";
60
+ var BUILD_TIME = "2026-10-15T09:49:23.103Z";
61
61
  function formatBuildTime(iso) {
62
62
  if (iso === "") return "";
63
63
  const d = new Date(iso);
@@ -6210,7 +6210,7 @@ var CHART_FORMATS = Object.freeze(["currency", "number", "percent"]);
6210
6210
  var PLATFORM_FORMAT = Object.freeze({ "type": "string", "maxLength": 64, "pattern": "^(General|[^\\u0000-\\u001f]*[#0][^\\u0000-\\u001f]*)$" });
6211
6211
  var NEGATIVE_MODES = Object.freeze(["minus", "red_minus", "absolute", "red_absolute"]);
6212
6212
  var FORMAT_PATTERNS = Object.freeze({ "currency": "$#,###", "number": "#,###", "percent": '#,###.#"%"' });
6213
- var PLATFORM_NUMBERS = Object.freeze({ "dr-app-runtime": "1.10.0", "dr-app-widgets": "1.2.0", "dr-components": "1.2.0", "dr-components-controls": "1.1.0" });
6213
+ var PLATFORM_NUMBERS = Object.freeze({ "dr-app-runtime": "1.11.0", "dr-app-widgets": "1.2.0", "dr-components": "1.2.0", "dr-components-controls": "1.1.0" });
6214
6214
  var ROW_ACTION_WHEN = Object.freeze({ "dr-components": "1.2.0" });
6215
6215
  var PROPS_SINCE = Object.freeze({ "select": { "multiple": "1.3.0", "searchable": "1.3.0", "group_by": "1.3.0", "values": "1.3.0", "options[].group": "1.3.0" }, "data_grid": { "theme": "1.3.0", "hierarchy": "1.3.0", "totals": "1.3.0", "pin": "1.3.0", "csv_params": "1.3.0", "columns[].cell": "1.3.0", "columns[].badge_map": "1.3.0", "columns[].status_map": "1.3.0", "columns[].link_field": "1.3.0", "columns[].call": "1.3.0", "selection": "1.4.0", "sticky_header": "1.4.0", "search": "1.4.0", "row_detail": "1.4.0", "columns[].weight": "1.4.0", "columns[].currency_field": "1.4.0", "columns[].cell_secondary": "1.4.0", "columns[].badge_labels": "1.4.0", "detail_fields": "1.4.0", "columns[].compact": "1.5.0", "columns[].truncate": "1.5.0", "columns[].max_width": "1.5.0" }, "filter_bar": { "layout": "1.4.0", "filters[].kind=text": "1.4.0", "filters[].kind=number-range": "1.4.0", "filters[].param_min": "1.4.0", "filters[].param_max": "1.4.0", "filters[].mode": "1.4.0", "filters[].placeholder": "1.4.0", "filters[].placeholder_min": "1.4.0", "filters[].placeholder_max": "1.4.0" } });
6216
6216
  var MODULE_OF = Object.freeze({ "widget": "dr-app-widgets", "form": "dr-app-runtime", "list": "dr-app-runtime", "detail": "dr-app-runtime", "queue": "dr-app-runtime", "action": "dr-app-runtime", "filter": "dr-app-runtime", "stat": "dr-app-runtime", "chart": "dr-app-runtime", "custom": "dr-app-runtime", "field": "dr-app-runtime", "number_input": "dr-components", "tabs": "dr-components", "tab_panel": "dr-components", "select": "dr-components", "date_picker": "dr-components", "data_grid": "dr-components", "dialog": "dr-components", "variance_table": "dr-components", "toggle": "dr-components", "control_group": "dr-components", "callout": "dr-components", "scenario_columns": "dr-components", "slider": "dr-components-controls", "button": "dr-components", "status": "dr-components", "badge": "dr-components", "tag": "dr-components", "empty_state": "dr-components", "stepper": "dr-components", "alert": "dr-components", "checkbox": "dr-components", "radio_group": "dr-components", "file_upload": "dr-components", "skeleton": "dr-components", "progress": "dr-components", "accordion": "dr-components", "tooltip_info": "dr-components", "filter_bar": "dr-components", "filter_chip": "dr-components", "date_range": "dr-components", "fiscal_month": "dr-components", "search_input": "dr-components", "split_pane": "dr-components", "file_viewer": "dr-components", "line_grid": "dr-components", "document": "dr-components", "panel": "dr-app-runtime" });
@@ -10888,12 +10888,12 @@ function badgesCss() {
10888
10888
  }
10889
10889
 
10890
10890
  // ../flows/insights-builder/kit/contract/compileApp.mjs
10891
- var RUNTIME = "dr-app-runtime@1.9.1";
10891
+ var RUNTIME = "dr-app-runtime@1.10.0";
10892
10892
  var UI_KIT2 = "ui-kit/v4";
10893
10893
  var CHARTS = "echarts@5.6.0";
10894
10894
  var FMT = "dr-fmt@2.0.1";
10895
10895
  var TOKENS = "dr-tokens@1.0.0";
10896
- var WIDGETS = "dr-app-widgets@1.2.0";
10896
+ var WIDGETS = "dr-app-widgets@1.3.1";
10897
10897
  var COMPONENTS = "dr-components@1.5.0";
10898
10898
  var CONTROLS = "dr-components-controls@1.2.0";
10899
10899
  var PART_FILES = {
@@ -16373,18 +16373,31 @@ async function writePackage(dir, appId, pkg) {
16373
16373
  ) + "\n"
16374
16374
  );
16375
16375
  }
16376
- async function writeStoredContract(client, appId, dir) {
16376
+ async function readStoredContract(client, appId, codeVersion) {
16377
+ const app = `/apps/${encodeURIComponent(appId)}`;
16378
+ const path3 = typeof codeVersion === "number" ? `${app}/versions/${String(codeVersion)}/contract` : `${app}/contract`;
16377
16379
  let stored;
16378
16380
  try {
16379
- stored = await client.request(`/apps/${encodeURIComponent(appId)}/contract`);
16380
- } catch {
16381
- return false;
16381
+ stored = await client.request(path3);
16382
+ } catch (err) {
16383
+ if (err instanceof AppSpaceHttpError) {
16384
+ const detail = err.body?.detail;
16385
+ return { missing: `${String(err.status)}${typeof detail === "string" ? ` ${detail}` : ""}` };
16386
+ }
16387
+ return { missing: err instanceof Error ? err.message.split("\n")[0] ?? "" : String(err) };
16388
+ }
16389
+ if (typeof stored !== "object" || stored === null || Array.isArray(stored)) {
16390
+ return { missing: "the contract read answered no document" };
16382
16391
  }
16383
- if (typeof stored !== "object" || stored === null || Array.isArray(stored)) return false;
16384
16392
  const held = stored["contract"];
16385
16393
  const document = typeof held === "object" && held !== null && !Array.isArray(held) ? held : stored;
16386
- if (!("v" in document)) return false;
16387
- await writeFile5(join10(dir, "contract.json"), JSON.stringify(document, null, 2) + "\n");
16394
+ if (!("v" in document)) return { missing: "the contract read answered no document" };
16395
+ return { document };
16396
+ }
16397
+ async function writeStoredContract(client, appId, dir, codeVersion) {
16398
+ const read = await readStoredContract(client, appId, codeVersion);
16399
+ if (!("document" in read)) return false;
16400
+ await writeFile5(join10(dir, "contract.json"), JSON.stringify(read.document, null, 2) + "\n");
16388
16401
  return true;
16389
16402
  }
16390
16403
  async function writeOwnedFiles(dir, document, { force = false } = {}) {
@@ -16443,20 +16456,52 @@ async function restoreOwnedFiles(dir, contractWritten, { force }) {
16443
16456
  ];
16444
16457
  return writeOwnedFiles(dir, { owned }, { force });
16445
16458
  }
16446
- async function pullInto(client, appId, dir) {
16447
- let pkg;
16448
- try {
16449
- pkg = await client.request(`/apps/${encodeURIComponent(appId)}/package`);
16450
- } catch (err) {
16451
- if (err instanceof AppSpaceHttpError && err.status === 404) return null;
16452
- throw err;
16459
+ var contractWait = { pulls: 7, baseMs: 250, capMs: 4e3 };
16460
+ function contractWaitMs(pull) {
16461
+ return Math.min(contractWait.capMs, contractWait.baseMs * 2 ** (pull - 1));
16462
+ }
16463
+ var LiveContractMissing = class extends Error {
16464
+ constructor(appId, revision, pulls, last) {
16465
+ super(
16466
+ `${appId} is live at revision ${String(revision)}, and its contract could not be read in ${String(pulls)} pulls (the last answered: ${last}). Without it this landing cannot see the cards already live: it would build the app again from the skeleton and replace every one of them. Nothing was landed. Run the same command again. If it fails the same way, the live version has no contract on record: \`app-space get ${appId} --dir <a new folder>\` and then \`app-space push <that folder>\` push the same package back with one, and the next landing builds on it.`
16467
+ );
16468
+ this.appId = appId;
16469
+ this.revision = revision;
16470
+ this.pulls = pulls;
16471
+ this.last = last;
16472
+ this.name = "LiveContractMissing";
16473
+ }
16474
+ appId;
16475
+ revision;
16476
+ pulls;
16477
+ last;
16478
+ };
16479
+ async function pullInto(client, appId, dir, {
16480
+ onWait,
16481
+ sleep: sleep2 = (ms) => new Promise((done) => setTimeout(done, ms))
16482
+ } = {}) {
16483
+ for (let pull = 1; ; pull += 1) {
16484
+ let pkg;
16485
+ try {
16486
+ pkg = await client.request(`/apps/${encodeURIComponent(appId)}/package`);
16487
+ } catch (err) {
16488
+ if (err instanceof AppSpaceHttpError && err.status === 404) return null;
16489
+ throw err;
16490
+ }
16491
+ await rm2(join10(dir, "contract.json"), { force: true });
16492
+ await writePackage(dir, appId, pkg);
16493
+ const read = await readStoredContract(client, appId, pkg.code_version);
16494
+ if ("document" in read) {
16495
+ await writeFile5(join10(dir, "contract.json"), JSON.stringify(read.document, null, 2) + "\n");
16496
+ await restoreOwnedFiles(dir, true, { force: true });
16497
+ await recordPulled(dir, true);
16498
+ return { revision: pkg.revision, stage: pkg.stage };
16499
+ }
16500
+ if (pull >= contractWait.pulls) throw new LiveContractMissing(appId, pkg.revision, pull, read.missing);
16501
+ const ms = contractWaitMs(pull);
16502
+ onWait?.(pull, ms, read.missing);
16503
+ await sleep2(ms);
16453
16504
  }
16454
- await rm2(join10(dir, "contract.json"), { force: true });
16455
- await writePackage(dir, appId, pkg);
16456
- const contract = await writeStoredContract(client, appId, dir);
16457
- await restoreOwnedFiles(dir, contract, { force: true });
16458
- await recordPulled(dir, contract);
16459
- return { revision: pkg.revision, stage: pkg.stage };
16460
16505
  }
16461
16506
  async function runGet(appId, opts) {
16462
16507
  const client = await connect(opts);
@@ -16473,7 +16518,7 @@ async function runGet(appId, opts) {
16473
16518
  return 1;
16474
16519
  }
16475
16520
  await writePackage(dir, appId, pkg);
16476
- const contract = await writeStoredContract(client, appId, dir);
16521
+ const contract = await writeStoredContract(client, appId, dir, pkg.code_version);
16477
16522
  const restored = await restoreOwnedFiles(dir, contract, { force: opts.force === true });
16478
16523
  await recordPulled(dir, contract);
16479
16524
  if (opts.json === true) {
@@ -21879,7 +21924,7 @@ var CHART_FORMATS4 = Object.freeze(["currency", "number", "percent"]);
21879
21924
  var PLATFORM_FORMAT2 = Object.freeze({ "type": "string", "maxLength": 64, "pattern": "^(General|[^\\u0000-\\u001f]*[#0][^\\u0000-\\u001f]*)$" });
21880
21925
  var NEGATIVE_MODES3 = Object.freeze(["minus", "red_minus", "absolute", "red_absolute"]);
21881
21926
  var FORMAT_PATTERNS3 = Object.freeze({ "currency": "$#,###", "number": "#,###", "percent": '#,###.#"%"' });
21882
- var PLATFORM_NUMBERS3 = Object.freeze({ "dr-app-runtime": "1.10.0", "dr-app-widgets": "1.2.0", "dr-components": "1.2.0", "dr-components-controls": "1.1.0" });
21927
+ var PLATFORM_NUMBERS3 = Object.freeze({ "dr-app-runtime": "1.11.0", "dr-app-widgets": "1.2.0", "dr-components": "1.2.0", "dr-components-controls": "1.1.0" });
21883
21928
  var ROW_ACTION_WHEN3 = Object.freeze({ "dr-components": "1.2.0" });
21884
21929
  var PROPS_SINCE3 = Object.freeze({ "select": { "multiple": "1.3.0", "searchable": "1.3.0", "group_by": "1.3.0", "values": "1.3.0", "options[].group": "1.3.0" }, "data_grid": { "theme": "1.3.0", "hierarchy": "1.3.0", "totals": "1.3.0", "pin": "1.3.0", "csv_params": "1.3.0", "columns[].cell": "1.3.0", "columns[].badge_map": "1.3.0", "columns[].status_map": "1.3.0", "columns[].link_field": "1.3.0", "columns[].call": "1.3.0", "selection": "1.4.0", "sticky_header": "1.4.0", "search": "1.4.0", "row_detail": "1.4.0", "columns[].weight": "1.4.0", "columns[].currency_field": "1.4.0", "columns[].cell_secondary": "1.4.0", "columns[].badge_labels": "1.4.0", "detail_fields": "1.4.0", "columns[].compact": "1.5.0", "columns[].truncate": "1.5.0", "columns[].max_width": "1.5.0" }, "filter_bar": { "layout": "1.4.0", "filters[].kind=text": "1.4.0", "filters[].kind=number-range": "1.4.0", "filters[].param_min": "1.4.0", "filters[].param_max": "1.4.0", "filters[].mode": "1.4.0", "filters[].placeholder": "1.4.0", "filters[].placeholder_min": "1.4.0", "filters[].placeholder_max": "1.4.0" } });
21885
21930
  var MODULE_OF3 = Object.freeze({ "widget": "dr-app-widgets", "form": "dr-app-runtime", "list": "dr-app-runtime", "detail": "dr-app-runtime", "queue": "dr-app-runtime", "action": "dr-app-runtime", "filter": "dr-app-runtime", "stat": "dr-app-runtime", "chart": "dr-app-runtime", "custom": "dr-app-runtime", "field": "dr-app-runtime", "number_input": "dr-components", "tabs": "dr-components", "tab_panel": "dr-components", "select": "dr-components", "date_picker": "dr-components", "data_grid": "dr-components", "dialog": "dr-components", "variance_table": "dr-components", "toggle": "dr-components", "control_group": "dr-components", "callout": "dr-components", "scenario_columns": "dr-components", "slider": "dr-components-controls", "button": "dr-components", "status": "dr-components", "badge": "dr-components", "tag": "dr-components", "empty_state": "dr-components", "stepper": "dr-components", "alert": "dr-components", "checkbox": "dr-components", "radio_group": "dr-components", "file_upload": "dr-components", "skeleton": "dr-components", "progress": "dr-components", "accordion": "dr-components", "tooltip_info": "dr-components", "filter_bar": "dr-components", "filter_chip": "dr-components", "date_range": "dr-components", "fiscal_month": "dr-components", "search_input": "dr-components", "split_pane": "dr-components", "file_viewer": "dr-components", "line_grid": "dr-components", "document": "dr-components", "panel": "dr-app-runtime" });
@@ -27185,7 +27230,7 @@ var kit_default2 = {
27185
27230
  checks: "checks/run.mjs",
27186
27231
  contract: "contract/extract.mjs",
27187
27232
  charts: "echarts@5.6.0",
27188
- appWidgets: "dr-app-widgets@1.2.0",
27233
+ appWidgets: "dr-app-widgets@1.3.1",
27189
27234
  appComponents: "dr-components@1.5.0",
27190
27235
  appControls: "dr-components-controls@1.2.0"
27191
27236
  };
@@ -27392,7 +27437,7 @@ async function runCompile(dir, opts) {
27392
27437
  if (plan.intruders.length > 0 || plan.strays.length > 0 || plan.edited.length > 0) {
27393
27438
  report.failure = "would-overwrite";
27394
27439
  await writeReport(dir, report);
27395
- process.stderr.write(refusalOf(dir, plan));
27440
+ process.stderr.write(refusalOf(dir, plan, opts.ontoLive === true));
27396
27441
  return 1;
27397
27442
  }
27398
27443
  const check5 = opts.check === true;
@@ -27731,12 +27776,13 @@ function customHandlerPaths(contract) {
27731
27776
  }
27732
27777
  return out;
27733
27778
  }
27734
- function refusalOf(dir, plan) {
27779
+ function refusalOf(dir, plan, ontoLive) {
27735
27780
  const list3 = (paths) => `${paths.slice(0, 3).join(", ")}${paths.length > 3 ? "\u2026" : ""}`;
27736
27781
  let out = "";
27737
27782
  if (plan.intruders.length > 0) {
27738
- out += `${dir} already holds ${list3(plan.intruders)}, which this compiler did not write. Move them aside, or pass --force to write over them.
27739
- `;
27783
+ out += `${dir} already holds ${list3(plan.intruders)}, ` + // `ship --onto-live` pulled these: they are the live app, and writing
27784
+ // over them is replacing other landings' cards. Never the way past it.
27785
+ (ontoLive ? "which this compiler did not write: they are the live app as pulled, and this landing could not build on them. Nothing was pushed. Run the same command again.\n" : "which this compiler did not write. Move them aside, or pass --force to write over them.\n");
27740
27786
  }
27741
27787
  const handlers = plan.strays.filter((path3) => path3.startsWith("handlers/"));
27742
27788
  const modules = plan.strays.filter((path3) => !path3.startsWith("handlers/"));
@@ -28049,6 +28095,12 @@ async function loadContract(dir, opts) {
28049
28095
  return { contract, assemble: null, headline: resolveExpectations(opts.expect, contract, {}), overlay: {} };
28050
28096
  }
28051
28097
  const baseRaw = await readIfPresent(join15(dir, "contract.json"));
28098
+ if (opts.ontoLive === true && baseRaw === void 0 && await readIfPresent(join15(dir, "manifest.json")) !== void 0) {
28099
+ process.stderr.write(
28100
+ "ship --onto-live: the folder holds the live package but not its contract.json, so this landing cannot see the cards already live, and would replace them. Nothing was written. Run the same command again.\n"
28101
+ );
28102
+ return { exit: 1 };
28103
+ }
28052
28104
  const assembled = assemble({
28053
28105
  drafts: (await Promise.all(drafts.map(readNamed))).flatMap(pageDrafts),
28054
28106
  ...opts.skeleton === void 0 ? {} : { skeleton: await readNamed(opts.skeleton) },
@@ -28416,7 +28468,7 @@ function registerShipCommand(parent) {
28416
28468
  withJsonOption(
28417
28469
  withServerOptions(
28418
28470
  withAssemblyOptions(
28419
- parent.command("ship [dir]").description("Assemble, compile, push and prove a dashboard pass; print the update block the reply ends with.").option("--seed <file>", "Seed rows, as JSON. Forwarded to the push.").option("--force", "Write over files this compiler did not write (never a custom handler).").option(
28471
+ parent.command("ship [dir]").description("Assemble, compile, push and prove a dashboard pass; print the update block the reply ends with.").option("--seed <file>", "Seed rows, as JSON. Forwarded to the push.").option("--force", "Write over files this compiler did not write (never a custom handler). Refused with --onto-live.").option(
28420
28472
  "--onto-live",
28421
28473
  "Land this pass's cards on the app as it is live now, keeping every card already there: pull it, add them, push against its revision, and start over when another push lands first. Needs --app-id and --skeleton, and a folder of its own."
28422
28474
  )
@@ -28451,6 +28503,11 @@ async function runShipOntoLive(dir, opts) {
28451
28503
  if ((opts.expect ?? []).length > 0) {
28452
28504
  return refuse("--expect holds the headline, which is the build's to confirm; a landing proves its own cards only.");
28453
28505
  }
28506
+ if (opts.force === true) {
28507
+ return refuse(
28508
+ "does not take --force: every landing builds on the cards already live, and --force would let this one replace them. Run the same command without it. If it refuses over files it did not write, the live app could not be read whole: run it again, and report the refusal if it repeats."
28509
+ );
28510
+ }
28454
28511
  const owned = await claimFolder(dir);
28455
28512
  if (owned !== null) return refuse(owned);
28456
28513
  await defaultServerFromSession(opts);
@@ -28462,7 +28519,20 @@ async function runShipOntoLive(dir, opts) {
28462
28519
  const client = await connect(opts);
28463
28520
  let pulled;
28464
28521
  try {
28465
- pulled = await pullInto(client, appId, dir);
28522
+ pulled = await pullInto(client, appId, dir, {
28523
+ onWait: (pull, ms, missing) => {
28524
+ if (opts.json === true) return;
28525
+ process.stdout.write(
28526
+ `onto ${appId}: the live version's contract is not readable yet (${missing}) \u2014 pulling again in ${String(ms)} ms (pull ${String(pull + 1)})
28527
+ `
28528
+ );
28529
+ }
28530
+ });
28531
+ } catch (err) {
28532
+ if (!(err instanceof LiveContractMissing)) throw err;
28533
+ process.stderr.write(`ship --onto-live: ${err.message}
28534
+ `);
28535
+ return { code: 1, lost: null, creating: false };
28466
28536
  } finally {
28467
28537
  client.cleanup();
28468
28538
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datarails-ai/dr-appspace-cli",
3
- "version": "0.12.12",
3
+ "version": "0.12.14",
4
4
  "description": "Datarails App Space CLI — build, try, push and publish App Space apps",
5
5
  "type": "module",
6
6
  "engines": {