@datarails-ai/dr-appspace-cli 0.12.4 → 0.12.6
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 +45 -9
- 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.6",
|
|
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-12T20:27:28.392Z";
|
|
61
61
|
function formatBuildTime(iso) {
|
|
62
62
|
if (iso === "") return "";
|
|
63
63
|
const d = new Date(iso);
|
|
@@ -17277,7 +17277,7 @@ var contract_schema_default = {
|
|
|
17277
17277
|
module: { type: "string", description: "dr-widgets, dr-insights, dr-fmt, echarts, ui-kit" },
|
|
17278
17278
|
version: { type: "string", description: "1.1.1 for a vendor module, v3 for the ui-kit" },
|
|
17279
17279
|
file: { type: "string" },
|
|
17280
|
-
path: { type: "string", description: "the platform-root path, e.g. vendor/dr-widgets@1.
|
|
17280
|
+
path: { type: "string", description: "the platform-root path, e.g. vendor/dr-widgets@1.2.1/widgets.js" },
|
|
17281
17281
|
rel: { enum: ["script", "stylesheet"] },
|
|
17282
17282
|
pages: { type: "array", items: { type: "string" } },
|
|
17283
17283
|
order: { type: "integer", minimum: 0, description: "load order: where this module is first reached across the bundle" }
|
|
@@ -18034,6 +18034,7 @@ var LITERAL_OK = /* @__PURE__ */ new Set([
|
|
|
18034
18034
|
]);
|
|
18035
18035
|
function validateContract(contract, catalog) {
|
|
18036
18036
|
const problems = [];
|
|
18037
|
+
const warnings = [];
|
|
18037
18038
|
const doc = isObject4(contract) ? contract : {};
|
|
18038
18039
|
const app = obj(doc["app"]);
|
|
18039
18040
|
const kind = kindOf(doc);
|
|
@@ -18051,6 +18052,7 @@ function validateContract(contract, catalog) {
|
|
|
18051
18052
|
checkPeriodOverride(doc, problems);
|
|
18052
18053
|
checkKinds(doc, problems);
|
|
18053
18054
|
checkDrillTargets(doc, problems);
|
|
18055
|
+
checkAggOrAccountType(doc, warnings);
|
|
18054
18056
|
checkPairing(doc, problems);
|
|
18055
18057
|
checkTransforms(doc, problems);
|
|
18056
18058
|
} else {
|
|
@@ -18063,7 +18065,7 @@ function validateContract(contract, catalog) {
|
|
|
18063
18065
|
checkCustomDeclares(doc, problems);
|
|
18064
18066
|
skipChartColumns(doc, skipped);
|
|
18065
18067
|
}
|
|
18066
|
-
return { problems: dedupe(problems), skipped: dedupeSkipped(skipped) };
|
|
18068
|
+
return { problems: dedupe(problems), skipped: dedupeSkipped(skipped), warnings: dedupe(warnings) };
|
|
18067
18069
|
}
|
|
18068
18070
|
function checkCustomDeclares(doc, problems) {
|
|
18069
18071
|
for (const problem5 of declaresProblems2(doc)) {
|
|
@@ -18883,7 +18885,7 @@ function checkDrillTargets(doc, problems) {
|
|
|
18883
18885
|
const row = raw;
|
|
18884
18886
|
if (row["data"] !== void 0 && row["data"] !== null) continue;
|
|
18885
18887
|
const drill = list2(row["drill"]).filter((name) => typeof name === "string");
|
|
18886
|
-
if (drill.length === 0) continue;
|
|
18888
|
+
if (drill.length === 0 || !menuless(row)) continue;
|
|
18887
18889
|
const offered = new Set(drill.map((name) => name.toLowerCase()));
|
|
18888
18890
|
const listed = JSON.stringify(drill);
|
|
18889
18891
|
if (row["kind"] === "breakdown") {
|
|
@@ -18893,7 +18895,7 @@ function checkDrillTargets(doc, problems) {
|
|
|
18893
18895
|
problems.push({
|
|
18894
18896
|
code: "drill-needs-dimension",
|
|
18895
18897
|
pointer: pointer("data", "widgets", id, "drill"),
|
|
18896
|
-
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.`,
|
|
18898
|
+
message: `this breakdown gets no point menu, so a click on it is the drill itself; it 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.`,
|
|
18897
18899
|
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.`
|
|
18898
18900
|
});
|
|
18899
18901
|
continue;
|
|
@@ -18905,11 +18907,43 @@ function checkDrillTargets(doc, problems) {
|
|
|
18905
18907
|
problems.push({
|
|
18906
18908
|
code: "drill-needs-dimension",
|
|
18907
18909
|
pointer: pointer("data", "widgets", id, "drill"),
|
|
18908
|
-
message: `this table
|
|
18910
|
+
message: `this table gets no point menu, so a click on it is the drill itself; its 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.`,
|
|
18909
18911
|
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.`
|
|
18910
18912
|
});
|
|
18911
18913
|
}
|
|
18912
18914
|
}
|
|
18915
|
+
function menuless(row) {
|
|
18916
|
+
if (row["compute"] || row["transform"] !== void 0 && row["transform"] !== null) return true;
|
|
18917
|
+
const source = row["source"];
|
|
18918
|
+
if (!isObject4(source) || "app_table" in source || "call" in source) return true;
|
|
18919
|
+
if ("metric_id" in source) return Boolean(source["drill_rows"]) && typeof row["value_field"] !== "string";
|
|
18920
|
+
if (!addressesTable(source)) return true;
|
|
18921
|
+
const measures = list2(source["measures"]).length > 0 ? list2(source["measures"]) : source["measure"] ? [source["measure"]] : [];
|
|
18922
|
+
const fields = measures.map((one) => obj(one)["field"]);
|
|
18923
|
+
const named12 = typeof row["value_field"] === "string" && fields.includes(row["value_field"]);
|
|
18924
|
+
return !(named12 || fields.length === 1);
|
|
18925
|
+
}
|
|
18926
|
+
function addressesTable(source) {
|
|
18927
|
+
return source["address"] === "id" || source["address"] === "alias" || Boolean(source["table_alias"]) || source["table_id"] !== void 0 && source["table_id"] !== null;
|
|
18928
|
+
}
|
|
18929
|
+
function checkAggOrAccountType(doc, warnings) {
|
|
18930
|
+
const widgets = obj(obj(doc["data"])["widgets"]);
|
|
18931
|
+
const declared = (value) => typeof value === "string" && value.trim() !== "";
|
|
18932
|
+
for (const [id, raw] of Object.entries(widgets)) {
|
|
18933
|
+
if (id.startsWith("_") || !isObject4(raw)) continue;
|
|
18934
|
+
const row = raw;
|
|
18935
|
+
if (row["kind"] !== "kpi" && row["kind"] !== "series") continue;
|
|
18936
|
+
if (!isObject4(row["source"])) continue;
|
|
18937
|
+
if (["data", "compute", "transform", "shape"].some((key) => row[key] !== void 0 && row[key] !== null)) continue;
|
|
18938
|
+
if (declared(row["agg"]) || declared(row["account_type"])) continue;
|
|
18939
|
+
warnings.push({
|
|
18940
|
+
code: "agg-or-account-type",
|
|
18941
|
+
pointer: pointer("data", "widgets", id),
|
|
18942
|
+
message: `this ${row["kind"]} declares neither "agg" nor "account_type", so its figure sums its months \u2014 a quarter or a year of a balance (cash, assets, liabilities, equity, receivables, payables, inventory) would show three or twelve balances added up.`,
|
|
18943
|
+
fix: 'If it is a balance, add "account_type": "asset" (or "liability", "equity"), or "agg": "last", so a quarter or year shows the closing month; if it is a flow (revenue, expenses), add "account_type": "revenue" (or "expense") to say so and silence this.'
|
|
18944
|
+
});
|
|
18945
|
+
}
|
|
18946
|
+
}
|
|
18913
18947
|
function checkPairing(doc, problems) {
|
|
18914
18948
|
const data = doc["data"];
|
|
18915
18949
|
if (!isObject4(data) || !isObject4(data["widgets"])) return;
|
|
@@ -27102,7 +27136,7 @@ var kit_default = {
|
|
|
27102
27136
|
fmt: "dr-fmt@1.0.0",
|
|
27103
27137
|
markdown: "dr-md@1.0.0",
|
|
27104
27138
|
uiKit: "ui-kit/v3",
|
|
27105
|
-
widgets: "dr-widgets@1.1
|
|
27139
|
+
widgets: "dr-widgets@1.2.1"
|
|
27106
27140
|
};
|
|
27107
27141
|
|
|
27108
27142
|
// ../flows/appspace-builder/kit/kit.json
|
|
@@ -27263,10 +27297,11 @@ async function runCompile(dir, opts) {
|
|
|
27263
27297
|
} finally {
|
|
27264
27298
|
client?.cleanup();
|
|
27265
27299
|
}
|
|
27266
|
-
const { problems, skipped } = validateContract(contract, catalog);
|
|
27300
|
+
const { problems, skipped, warnings } = validateContract(contract, catalog);
|
|
27267
27301
|
report.validate = {
|
|
27268
27302
|
problems,
|
|
27269
27303
|
checks_skipped: skipped,
|
|
27304
|
+
warnings,
|
|
27270
27305
|
catalog: {
|
|
27271
27306
|
source: catalog.source,
|
|
27272
27307
|
server: catalog.server ?? null,
|
|
@@ -27365,6 +27400,7 @@ async function afterWrite(dir, target, kind, contract, built, report, kit, skipp
|
|
|
27365
27400
|
}
|
|
27366
27401
|
report.verify = runVerify(target, kind, report.app_id, kit);
|
|
27367
27402
|
report.verify.warnings = [
|
|
27403
|
+
...(report.validate.warnings ?? []).map((one) => `${one.code} ${one.pointer}: ${one.message} ${one.fix}`),
|
|
27368
27404
|
...(built.warnings ?? []).map((one) => `${one.code} ${one.pointer ?? "/"}: ${one.message}`),
|
|
27369
27405
|
...report.verify.warnings ?? []
|
|
27370
27406
|
];
|