@datarails-ai/dr-appspace-cli 0.12.0 → 0.12.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.
- package/dist/cli.js +50 -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.
|
|
16
|
+
version: "0.12.1",
|
|
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-
|
|
60
|
+
var BUILD_TIME = "2026-10-07T21:55:46.945Z";
|
|
61
61
|
function formatBuildTime(iso) {
|
|
62
62
|
if (iso === "") return "";
|
|
63
63
|
const d = new Date(iso);
|
|
@@ -17549,6 +17549,7 @@ function validateContract(contract, catalog) {
|
|
|
17549
17549
|
if (kind === "dashboard") {
|
|
17550
17550
|
checkPeriodOverride(doc, problems);
|
|
17551
17551
|
checkKinds(doc, problems);
|
|
17552
|
+
checkDrillTargets(doc, problems);
|
|
17552
17553
|
checkPairing(doc, problems);
|
|
17553
17554
|
checkTransforms(doc, problems);
|
|
17554
17555
|
} else {
|
|
@@ -18030,6 +18031,19 @@ function checkSources(doc, catalog, problems, skipped) {
|
|
|
18030
18031
|
}
|
|
18031
18032
|
report(held, ["data", "widgets", id, "source", key]);
|
|
18032
18033
|
}
|
|
18034
|
+
{
|
|
18035
|
+
const held = source["period_field"];
|
|
18036
|
+
const field = isObject4(held) ? held["field"] : held;
|
|
18037
|
+
const epoch = isObject4(held) && held["format"] === "epoch";
|
|
18038
|
+
if (typeof field === "string" && dated.has(field.toLowerCase()) && source["period_is_date"] !== true && !epoch) {
|
|
18039
|
+
problems.push({
|
|
18040
|
+
code: "period-needs-date",
|
|
18041
|
+
pointer: pointer("data", "widgets", id, "source", "period_field"),
|
|
18042
|
+
message: `${JSON.stringify(field)} is a date column, and this source does not say so \u2014 its window is not sent to FinanceOS, a drill reads rows from every period, and a clicked chart point matches no row.`,
|
|
18043
|
+
fix: `Add "period_is_date": true to the source (next to period_field ${JSON.stringify(field)}); the page's window is then pushed down as Unix epoch seconds, with no "where" range needed.`
|
|
18044
|
+
});
|
|
18045
|
+
}
|
|
18046
|
+
}
|
|
18033
18047
|
for (const key of ["select", "dimensions", "measures"]) {
|
|
18034
18048
|
for (const [index, name] of list2(source[key]).entries()) {
|
|
18035
18049
|
if (isObject4(name)) {
|
|
@@ -18361,6 +18375,40 @@ function checkKinds(doc, problems) {
|
|
|
18361
18375
|
});
|
|
18362
18376
|
}
|
|
18363
18377
|
}
|
|
18378
|
+
function checkDrillTargets(doc, problems) {
|
|
18379
|
+
const widgets = obj(obj(doc["data"])["widgets"]);
|
|
18380
|
+
for (const [id, raw] of Object.entries(widgets)) {
|
|
18381
|
+
if (id.startsWith("_") || !isObject4(raw)) continue;
|
|
18382
|
+
const row = raw;
|
|
18383
|
+
if (row["data"] !== void 0 && row["data"] !== null) continue;
|
|
18384
|
+
const drill = list2(row["drill"]).filter((name) => typeof name === "string");
|
|
18385
|
+
if (drill.length === 0) continue;
|
|
18386
|
+
const offered = new Set(drill.map((name) => name.toLowerCase()));
|
|
18387
|
+
const listed = JSON.stringify(drill);
|
|
18388
|
+
if (row["kind"] === "breakdown") {
|
|
18389
|
+
const dimension = row["dimension"];
|
|
18390
|
+
if (typeof dimension !== "string" || dimension === "") continue;
|
|
18391
|
+
if (offered.has(dimension.toLowerCase())) continue;
|
|
18392
|
+
problems.push({
|
|
18393
|
+
code: "drill-needs-dimension",
|
|
18394
|
+
pointer: pointer("data", "widgets", id, "drill"),
|
|
18395
|
+
message: `this breakdown is cut by ${JSON.stringify(dimension)} and its drill list ${listed} does not name it, so no legend row answers a click \u2014 the card looks drillable and is not.`,
|
|
18396
|
+
fix: `Put ${JSON.stringify(dimension)} first in drill \u2014 ${JSON.stringify([dimension, ...drill])}: the clicked slice is a value of the card's own dimension, and the levels after it are where the grid goes next.`
|
|
18397
|
+
});
|
|
18398
|
+
continue;
|
|
18399
|
+
}
|
|
18400
|
+
if (row["kind"] !== "table") continue;
|
|
18401
|
+
const declared = list2(row["columns"]).map((column) => isObject4(column) ? column["key"] : void 0).filter((key) => typeof key === "string" && key !== "");
|
|
18402
|
+
const keys2 = declared.length > 0 ? declared : list2(obj(row["source"])["dimensions"]).filter((key) => typeof key === "string");
|
|
18403
|
+
if (keys2.length === 0 || keys2.some((key) => offered.has(key.toLowerCase()))) continue;
|
|
18404
|
+
problems.push({
|
|
18405
|
+
code: "drill-needs-dimension",
|
|
18406
|
+
pointer: pointer("data", "widgets", id, "drill"),
|
|
18407
|
+
message: `this table's drill list ${listed} names none of its columns (${keys2.map((key) => JSON.stringify(key)).join(", ")}), and a cell drills only when its column key is in drill \u2014 so no cell answers a click.`,
|
|
18408
|
+
fix: `Add the column a reader clicks to drill \u2014 e.g. ${JSON.stringify([keys2[0], ...drill])} \u2014 naming the grid's own dimension column first.`
|
|
18409
|
+
});
|
|
18410
|
+
}
|
|
18411
|
+
}
|
|
18364
18412
|
function checkPairing(doc, problems) {
|
|
18365
18413
|
const data = doc["data"];
|
|
18366
18414
|
if (!isObject4(data) || !isObject4(data["widgets"])) return;
|