@datarails-ai/dr-appspace-cli 0.12.37 → 0.12.38
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/README.md +5 -2
- package/dist/cli.js +41 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -287,8 +287,11 @@ It compiles in memory, writes only the ejected file and `contract.json`,
|
|
|
287
287
|
refuses a file already at that path unless it holds exactly what the
|
|
288
288
|
compiler would write, and refuses an eject after which the folder would not
|
|
289
289
|
compile (a page holding the only form a `by` handler is called from, a
|
|
290
|
-
handler a picker needs as a list). `page:` keeps the page's
|
|
291
|
-
`pages[i].role
|
|
290
|
+
handler a picker needs as a list). `page:` keeps the page's `params` and
|
|
291
|
+
`roles` (its nav gate as `pages[i].role` when it states no roles), and the
|
|
292
|
+
sources the page reads keep their handlers and gates: the compiler reads them
|
|
293
|
+
off the contract the owned page embeds. An ejected handler's docstring says
|
|
294
|
+
the file is yours.
|
|
292
295
|
The next `compile` carries the file as yours, and the one after writes
|
|
293
296
|
nothing.
|
|
294
297
|
|
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.38",
|
|
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-26T15:07:50.401Z";
|
|
61
61
|
function formatBuildTime(iso) {
|
|
62
62
|
if (iso === "") return "";
|
|
63
63
|
const d = new Date(iso);
|
|
@@ -9618,7 +9618,7 @@ function rolesLandingNowhere(contract) {
|
|
|
9618
9618
|
}
|
|
9619
9619
|
return out;
|
|
9620
9620
|
}
|
|
9621
|
-
function sourceRoles(contract, name) {
|
|
9621
|
+
function sourceRoles(contract, name, known = /* @__PURE__ */ new Set()) {
|
|
9622
9622
|
const source = contract?.data?.sources?.[name];
|
|
9623
9623
|
const stated2 = gateRoles(source?.requiresRole);
|
|
9624
9624
|
const elements = isPlainObject3(contract?.elements) ? contract.elements : {};
|
|
@@ -9636,7 +9636,7 @@ function sourceRoles(contract, name) {
|
|
|
9636
9636
|
for (const role of roles) if (!union.includes(role)) union.push(role);
|
|
9637
9637
|
}
|
|
9638
9638
|
for (const page of pagesOf(contract)) {
|
|
9639
|
-
if (page.owned !== true || readers === 0) continue;
|
|
9639
|
+
if (page.owned !== true || readers === 0 || known.has(page.path)) continue;
|
|
9640
9640
|
const roles = pageRoles(page);
|
|
9641
9641
|
if (roles.length === 0) open2 = true;
|
|
9642
9642
|
for (const role of roles) if (!union.includes(role)) union.push(role);
|
|
@@ -12593,6 +12593,34 @@ function servedSources(elements, sources) {
|
|
|
12593
12593
|
}
|
|
12594
12594
|
return [...out].sort(natural3);
|
|
12595
12595
|
}
|
|
12596
|
+
function ownedReaders(pages, extra) {
|
|
12597
|
+
const readers = {};
|
|
12598
|
+
const known = /* @__PURE__ */ new Set();
|
|
12599
|
+
for (const page of Array.isArray(pages) ? pages : []) {
|
|
12600
|
+
if (page?.owned !== true || !named5(page.path)) continue;
|
|
12601
|
+
const text3 = extra?.[page.path];
|
|
12602
|
+
if (typeof text3 !== "string" || !isOwnedPage(text3)) continue;
|
|
12603
|
+
const embedded = embeddedContractOf({ text: text3 });
|
|
12604
|
+
if (embedded === null) continue;
|
|
12605
|
+
known.add(page.path);
|
|
12606
|
+
const elements = isPlainObject8(embedded.elements) ? embedded.elements : {};
|
|
12607
|
+
for (const uid of Object.keys(elements).sort(natural3)) {
|
|
12608
|
+
const element = elements[uid];
|
|
12609
|
+
if (!isPlainObject8(element) || element.page !== page.path) continue;
|
|
12610
|
+
const props = isPlainObject8(element.props) ? element.props : {};
|
|
12611
|
+
const kept = {};
|
|
12612
|
+
if (named5(props.source)) kept.source = props.source;
|
|
12613
|
+
if (Array.isArray(props.declares?.reads)) kept.declares = { reads: props.declares.reads.filter(named5) };
|
|
12614
|
+
if (Object.keys(kept).length > 0) readers[`owned:${uid}`] = { page: page.path, props: kept };
|
|
12615
|
+
}
|
|
12616
|
+
}
|
|
12617
|
+
return { readers, known };
|
|
12618
|
+
}
|
|
12619
|
+
function withOwnedReaders(contract, readers) {
|
|
12620
|
+
if (Object.keys(readers).length === 0) return contract;
|
|
12621
|
+
const elements = isPlainObject8(contract?.elements) ? contract.elements : {};
|
|
12622
|
+
return { ...contract, elements: { ...elements, ...readers } };
|
|
12623
|
+
}
|
|
12596
12624
|
function sourceProblems(sources, app, handlers, extra) {
|
|
12597
12625
|
const problems = [];
|
|
12598
12626
|
const names = Object.keys(sources).sort(natural3);
|
|
@@ -13624,7 +13652,8 @@ function compileApp(contract, { kit = null, runtime = RUNTIME, extra = {} } = {}
|
|
|
13624
13652
|
problems.push(...exprProblems(stated2));
|
|
13625
13653
|
const metricFindings = metricProblems(contract?.data?.metrics, stated2);
|
|
13626
13654
|
problems.push(...metricFindings.filter((one) => !one.advisory));
|
|
13627
|
-
|
|
13655
|
+
const owned = ownedReaders(contract.pages, extra);
|
|
13656
|
+
problems.push(...paramProblems(withOwnedReaders(contract, owned.readers), stated2));
|
|
13628
13657
|
problems.push(...themeProblems(app));
|
|
13629
13658
|
problems.push(...shellProblems(contract, typed, handlers, stated2));
|
|
13630
13659
|
const sources = fillFilterable(stated2);
|
|
@@ -13743,10 +13772,10 @@ function compileApp(contract, { kit = null, runtime = RUNTIME, extra = {} } = {}
|
|
|
13743
13772
|
problems.push(...placementProblems(elements, pages, tree, order2));
|
|
13744
13773
|
if (problems.length > 0) return { files: {}, problems, contract, warnings };
|
|
13745
13774
|
const whole = restate(contract, elements, pages, typed, order2);
|
|
13746
|
-
const served = servedSources(elements, sources);
|
|
13775
|
+
const served = servedSources({ ...elements, ...owned.readers }, sources);
|
|
13747
13776
|
const transforms = transformTexts2(sources, extra);
|
|
13748
13777
|
const files = {};
|
|
13749
|
-
files["manifest.json"] = json(manifestOf(contract, manifestApp, handlers, names, model, served));
|
|
13778
|
+
files["manifest.json"] = json(manifestOf(contract, manifestApp, handlers, names, model, served, withOwnedReaders(contract, owned.readers), owned.known));
|
|
13750
13779
|
if (app.data_model) files["data_model.json"] = json(dataModelOf(app.data_model));
|
|
13751
13780
|
for (const name of names) {
|
|
13752
13781
|
const path3 = `handlers/${name}.py`;
|
|
@@ -16559,7 +16588,7 @@ function statusColumn(model, row) {
|
|
|
16559
16588
|
const status = table.columns.status;
|
|
16560
16589
|
return status !== void 0 && status.enum === null ? "status" : null;
|
|
16561
16590
|
}
|
|
16562
|
-
function manifestOf(contract, app, handlers, names, model, served = []) {
|
|
16591
|
+
function manifestOf(contract, app, handlers, names, model, served = [], readers = contract, known = /* @__PURE__ */ new Set()) {
|
|
16563
16592
|
const manifest = {
|
|
16564
16593
|
apiVersion: app.api_version ?? DEFAULT_API_VERSION,
|
|
16565
16594
|
id: app.id ?? null,
|
|
@@ -16585,7 +16614,7 @@ function manifestOf(contract, app, handlers, names, model, served = []) {
|
|
|
16585
16614
|
}
|
|
16586
16615
|
for (const name of served) {
|
|
16587
16616
|
const entry = { http: "POST", entrypoint: `handlers/${name}.py` };
|
|
16588
|
-
const { roles: gate } = sourceRoles(
|
|
16617
|
+
const { roles: gate } = sourceRoles(readers, name, known);
|
|
16589
16618
|
if (gate.length > 0) entry.requiresRole = gate;
|
|
16590
16619
|
manifest.handlers[name] = entry;
|
|
16591
16620
|
}
|
|
@@ -29407,7 +29436,7 @@ function rolesLandingNowhere2(contract) {
|
|
|
29407
29436
|
}
|
|
29408
29437
|
return out;
|
|
29409
29438
|
}
|
|
29410
|
-
function sourceRoles2(contract, name) {
|
|
29439
|
+
function sourceRoles2(contract, name, known = /* @__PURE__ */ new Set()) {
|
|
29411
29440
|
const source = contract?.data?.sources?.[name];
|
|
29412
29441
|
const stated2 = gateRoles2(source?.requiresRole);
|
|
29413
29442
|
const elements = isPlainObject17(contract?.elements) ? contract.elements : {};
|
|
@@ -29425,7 +29454,7 @@ function sourceRoles2(contract, name) {
|
|
|
29425
29454
|
for (const role of roles) if (!union.includes(role)) union.push(role);
|
|
29426
29455
|
}
|
|
29427
29456
|
for (const page of pagesOf2(contract)) {
|
|
29428
|
-
if (page.owned !== true || readers === 0) continue;
|
|
29457
|
+
if (page.owned !== true || readers === 0 || known.has(page.path)) continue;
|
|
29429
29458
|
const roles = pageRoles2(page);
|
|
29430
29459
|
if (roles.length === 0) open2 = true;
|
|
29431
29460
|
for (const role of roles) if (!union.includes(role)) union.push(role);
|
|
@@ -31242,7 +31271,7 @@ function unservedAfter(path3, lost) {
|
|
|
31242
31271
|
const one = lost.length === 1;
|
|
31243
31272
|
const names = lost.map((name) => JSON.stringify(name)).join(", ");
|
|
31244
31273
|
const files = lost.map((name) => `handlers/${name}.py`).join(", ");
|
|
31245
|
-
return
|
|
31274
|
+
return `after this eject the compiler would write no handler for source${one ? "" : "s"} ${names}, which ${path3} reads, so ${files} would go and the page would call ${one ? "a handler" : "handlers"} that ${one ? "is" : "are"} not there. The compiler counts an owned page as a reader of what the contract it embeds reads, and eject keeps that contract on the page, so this is a bug in the compiler or in eject, not in your contract. Meanwhile, keep a card that reads ${one ? "it" : "each"} on a compiled page, or eject ${one ? "the source" : "each source"} first (app-space eject ${lost.map((name) => `source:${name}`).join(", ")}), which makes it a custom handler the compiler always carries, where that eject is allowed: eject source: says when it is not.`;
|
|
31246
31275
|
}
|
|
31247
31276
|
function navGateOf(files, path3) {
|
|
31248
31277
|
const gates = navGates;
|