@datarails-ai/dr-appspace-cli 0.10.15 → 0.10.16

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 +67 -4
  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.10.15",
16
+ version: "0.10.16",
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-01T09:50:31.199Z";
60
+ var BUILD_TIME = "2026-10-01T09:59:27.370Z";
61
61
  function formatBuildTime(iso) {
62
62
  if (iso === "") return "";
63
63
  const d = new Date(iso);
@@ -10131,6 +10131,9 @@ var contract_schema_default = {
10131
10131
  where: { type: "object" },
10132
10132
  order_by: { type: "string" },
10133
10133
  limit: { type: "integer" },
10134
+ order: { enum: ["source", "declared"], description: "OPTIONAL, shape breakdown only (this schema has no conditional keyword, so the shape rule is the compiler's: source_shape refuses order on a breakdown source outside this enum). The order the items are answered in: declared is the labels listed in items, over any read; source keeps the rows' own order, which holds only where something promises one: a transform, or an app-table read that states order_by. Absent, the items are sorted by size. A waterfall card over a breakdown source needs one, with top: null." },
10135
+ items: { type: "array", items: { type: "string", minLength: 1 }, minItems: 1, description: `OPTIONAL, shape breakdown with order: declared only; on any other shape the compiler refuses it (source_shape). The breakdown's labels, each once, in the order they are drawn (a bridge's steps: ["Opening ARR", "New", ...]). A label the rows do not carry is left out; one they carry and the list does not name follows, in row order.` },
10136
+ top: { type: ["integer", "null"], minimum: 1, description: "OPTIONAL. On a breakdown source (the only shape whose top the compiler holds), how many items are drawn (default 5; the rest is one Other figure, other_value), or null to draw every one; a waterfall card over a breakdown source needs null. An app-table read is also capped by limit (default 200 rows), so a total over a bigger table needs limit set above its row count." },
10134
10137
  requiresRole: { type: "array", items: { type: "string" }, description: "OPTIONAL. The app roles that may read this source, any of them: written as its handler's requiresRole, so the server refuses anyone else with 403. Absent means the roles of the pages whose components read it (pages[].roles), and every role as soon as one of those pages is open to every role." }
10135
10138
  }
10136
10139
  }
@@ -12493,6 +12496,7 @@ function sourceProblems(sources, app, handlers, extra) {
12493
12496
  message: `source "${name}" states shape ${JSON.stringify(row.shape)}; a source answers ${either3(SOURCE_SHAPES2)}`
12494
12497
  });
12495
12498
  }
12499
+ problems.push(...orderProblems(name, row, at));
12496
12500
  if (row.transform !== void 0 && row.transform !== null) {
12497
12501
  const path3 = String(row.transform);
12498
12502
  if (!TRANSFORM_RE.test(path3)) {
@@ -12512,6 +12516,62 @@ function sourceProblems(sources, app, handlers, extra) {
12512
12516
  }
12513
12517
  return problems;
12514
12518
  }
12519
+ var SOURCE_ORDERS = ["source", "declared"];
12520
+ function orderProblems(name, row, at) {
12521
+ const problems = [];
12522
+ const say = (key, message) => problems.push({ code: "source_shape", pointer: at(name, key), message: `source "${name}" ${message}` });
12523
+ const has = (key) => Object.prototype.hasOwnProperty.call(row, key);
12524
+ if (row.shape !== "breakdown") {
12525
+ if (has("items")) say("items", 'states items, which only a source shaped breakdown reads (with order "declared"); give it shape breakdown, or drop items');
12526
+ return problems;
12527
+ }
12528
+ if (has("order") && !SOURCE_ORDERS.includes(row.order)) {
12529
+ say("order", `states order ${JSON.stringify(row.order)}; a breakdown source keeps ${either3(SOURCE_ORDERS.map((one) => JSON.stringify(one)))} order (the rows' own, or the labels listed in items), and is otherwise sorted by size`);
12530
+ }
12531
+ if (has("items")) {
12532
+ const labels = Array.isArray(row.items) ? row.items : null;
12533
+ if (labels === null || labels.length === 0 || !labels.every(named4) || new Set(labels).size !== labels.length) {
12534
+ say("items", `states items as ${JSON.stringify(row.items)}; items is the breakdown's labels, each once, in the order they are drawn (["Opening ARR", "New", "Churn"])`);
12535
+ } else if (row.order !== "declared") {
12536
+ say("items", 'lists items, which are read only with order "declared"; add "order": "declared", or drop items');
12537
+ }
12538
+ } else if (row.order === "declared") {
12539
+ say("order", `states order "declared" and lists no items; add "items": [the labels, in the order they are drawn], or use "order": "source" to keep the rows' own order`);
12540
+ }
12541
+ if (has("top") && row.top !== null && !(Number.isInteger(row.top) && row.top > 0)) {
12542
+ say("top", `states top ${JSON.stringify(row.top)}; top is how many of the breakdown's items are drawn (a whole number, default 5; the rest is one "Other" figure), or null to draw every one`);
12543
+ }
12544
+ return problems;
12545
+ }
12546
+ function bridgeFixes(row) {
12547
+ const declare = '"order": "declared" with "items": [the step labels, in order]';
12548
+ const transformed = row.transform !== void 0 && row.transform !== null;
12549
+ const origin = originOf(row);
12550
+ const unordered = origin === "financeos" ? "a FinanceOS aggregate" : origin === "call" ? "a call" : "an app-table read with no order_by";
12551
+ const fixes = [];
12552
+ let order2 = null;
12553
+ if (row.order === "declared") {
12554
+ if (!(Array.isArray(row.items) && row.items.length > 0)) {
12555
+ order2 = "unstated";
12556
+ fixes.push('add "items": [the step labels, in order] beside "order": "declared"');
12557
+ }
12558
+ } else if (row.order === "source") {
12559
+ if (!transformed && !(origin === "table" && named4(row.order_by))) {
12560
+ order2 = "unpromised";
12561
+ fixes.push(
12562
+ origin === "table" ? `add "order_by" naming the column the steps sort by (${unordered} comes back in no promised order), or replace "order": "source" with ${declare}` : `replace "order": "source" with ${declare} \u2014 ${unordered} comes back in no promised order, so its steps could be drawn shuffled`
12563
+ );
12564
+ }
12565
+ } else {
12566
+ order2 = "unstated";
12567
+ fixes.push(
12568
+ transformed ? `add ${declare}, or "order": "source" to keep the order your transform returns` : origin === "table" ? `add ${declare}, or "order": "source" with an "order_by" naming the column the steps sort by` : `add ${declare} (${unordered} comes back in no promised order, so "order": "source" would not hold)`
12569
+ );
12570
+ }
12571
+ const cut3 = !(Object.prototype.hasOwnProperty.call(row, "top") && row.top === null);
12572
+ if (cut3) fixes.push('add "top": null (nothing cut, no "Other")');
12573
+ return { fixes, order: order2, cut: cut3 };
12574
+ }
12515
12575
  function carriedFields(row, model) {
12516
12576
  if (row.transform !== void 0 && row.transform !== null) return null;
12517
12577
  const origin = originOf(row);
@@ -14091,9 +14151,12 @@ function widgetProblems(elements, tree, handlers, sources, widgetsPin = WIDGETS)
14091
14151
  shaped(`draws ${props.kind}, and source "${props.source}" answers ${shape} (its shape); give the source the shape ${reads.join(" or ")}`);
14092
14152
  continue;
14093
14153
  }
14094
- if (ORDERED_KINDS.includes(props.kind) && shape === "breakdown") {
14154
+ const bridge = ORDERED_KINDS.includes(props.kind) && shape === "breakdown" ? bridgeFixes(source) : null;
14155
+ if (bridge !== null && bridge.fixes.length > 0) {
14156
+ const otherFigure = 'cuts to its top 5 (the rest is one "Other" figure a waterfall does not draw)';
14157
+ const why = bridge.order === "unpromised" ? `that keeps the order its rows arrive in, which nothing promises${bridge.cut ? `, and the platform ${otherFigure}` : ""}` : bridge.order === "unstated" ? `which the platform sorts by size${bridge.cut ? ` and ${otherFigure}` : ""}` : `which the platform ${otherFigure}`;
14095
14158
  shaped(
14096
- `draws ${props.kind}, and source "${props.source}" is a breakdown, which the platform sorts by size and cuts to its top 5 (the rest is one "Other" figure a waterfall does not draw) \u2014 so the bridge would draw the wrong steps and the wrong total. Give the source the shape series (the periods are the steps, in order), or answer the bridge from a custom handler (data.app.handlers, role custom) that returns {"kind": "breakdown", "items": [...]} in the order the steps go`
14159
+ `draws ${props.kind}, and source "${props.source}" is a breakdown ${why} \u2014 so the bridge would draw the wrong steps${bridge.cut ? " and the wrong total" : ""}. In data.sources.${props.source}: ${bridge.fixes.join("; and ")}; or give the source the shape series (the periods are the steps, in order)`
14097
14160
  );
14098
14161
  }
14099
14162
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datarails-ai/dr-appspace-cli",
3
- "version": "0.10.15",
3
+ "version": "0.10.16",
4
4
  "description": "Datarails App Space CLI — build, try, push and publish App Space apps",
5
5
  "type": "module",
6
6
  "engines": {