@lotics/cli 0.52.0 → 0.53.0
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.
|
@@ -8,9 +8,11 @@
|
|
|
8
8
|
* wrapper (different port), so the app gets its own real origin (and Web
|
|
9
9
|
* Storage) without being able to reach the wrapper. `allow-downloads` lets
|
|
10
10
|
* apps trigger file downloads (generated xlsx / pdf etc.) — Chrome blocks
|
|
11
|
-
* every download path from sandboxed iframes without it. `allow="...; geolocation
|
|
12
|
-
* delegates the host's location permission
|
|
13
|
-
*
|
|
11
|
+
* every download path from sandboxed iframes without it. `allow="...; geolocation;
|
|
12
|
+
* web-share"` delegates the host's location permission (geofenced actions read the
|
|
13
|
+
* device position) and grants the Web Share API (apps call `navigator.share({ files })`
|
|
14
|
+
* to push e.g. container photos to the OS share sheet / gallery) — matching
|
|
15
|
+
* production. The iframe sends postMessage RPCs to
|
|
14
16
|
* this wrapper, which forwards them to the local /_rpc endpoint, which
|
|
15
17
|
* dispatches to api.lotics.ai with the CLI's API key.
|
|
16
18
|
*
|
package/dist/dev/wrapper_page.js
CHANGED
|
@@ -8,9 +8,11 @@
|
|
|
8
8
|
* wrapper (different port), so the app gets its own real origin (and Web
|
|
9
9
|
* Storage) without being able to reach the wrapper. `allow-downloads` lets
|
|
10
10
|
* apps trigger file downloads (generated xlsx / pdf etc.) — Chrome blocks
|
|
11
|
-
* every download path from sandboxed iframes without it. `allow="...; geolocation
|
|
12
|
-
* delegates the host's location permission
|
|
13
|
-
*
|
|
11
|
+
* every download path from sandboxed iframes without it. `allow="...; geolocation;
|
|
12
|
+
* web-share"` delegates the host's location permission (geofenced actions read the
|
|
13
|
+
* device position) and grants the Web Share API (apps call `navigator.share({ files })`
|
|
14
|
+
* to push e.g. container photos to the OS share sheet / gallery) — matching
|
|
15
|
+
* production. The iframe sends postMessage RPCs to
|
|
14
16
|
* this wrapper, which forwards them to the local /_rpc endpoint, which
|
|
15
17
|
* dispatches to api.lotics.ai with the CLI's API key.
|
|
16
18
|
*
|
|
@@ -64,7 +66,7 @@ export function buildWrapperPage(args) {
|
|
|
64
66
|
<span>workspace <code>${escapeHtml(workspace_id)}</code></span>
|
|
65
67
|
<span>RPC → <code>${escapeHtml(api_url)}</code></span>
|
|
66
68
|
</header>
|
|
67
|
-
<iframe id="app" sandbox="allow-scripts allow-same-origin allow-downloads" allow="clipboard-write; geolocation"></iframe>
|
|
69
|
+
<iframe id="app" sandbox="allow-scripts allow-same-origin allow-downloads" allow="clipboard-write; geolocation; web-share"></iframe>
|
|
68
70
|
<script>
|
|
69
71
|
(function () {
|
|
70
72
|
const APP_ID = ${JSON.stringify(app_id)};
|
|
@@ -123,6 +123,18 @@ function inputDeclToTsType(decl) {
|
|
|
123
123
|
return "{ start: string; end: string }";
|
|
124
124
|
case "file":
|
|
125
125
|
return "string";
|
|
126
|
+
case "object": {
|
|
127
|
+
const fields = decl.fields !== null && typeof decl.fields === "object"
|
|
128
|
+
? decl.fields
|
|
129
|
+
: {};
|
|
130
|
+
return inputsToType(fields);
|
|
131
|
+
}
|
|
132
|
+
case "array": {
|
|
133
|
+
const items = decl.items !== null && typeof decl.items === "object"
|
|
134
|
+
? decl.items
|
|
135
|
+
: null;
|
|
136
|
+
return items ? `ReadonlyArray<${inputDeclToTsType(items)}>` : "ReadonlyArray<unknown>";
|
|
137
|
+
}
|
|
126
138
|
case "json":
|
|
127
139
|
return "unknown";
|
|
128
140
|
default:
|
|
@@ -32,6 +32,32 @@ describe("generateAppWorkflowsDts", () => {
|
|
|
32
32
|
// No declared inputs → untyped callable in AppWorkflows.
|
|
33
33
|
expect(dts).toContain("computeQuote: Record<string, unknown>;");
|
|
34
34
|
});
|
|
35
|
+
it("types an array-of-objects INPUT as ReadonlyArray<{…}>", () => {
|
|
36
|
+
const dts = generateAppWorkflowsDts({
|
|
37
|
+
importLines: {
|
|
38
|
+
workflow_id: "wfl_4",
|
|
39
|
+
inputs: {
|
|
40
|
+
lines: {
|
|
41
|
+
type: "array",
|
|
42
|
+
items: {
|
|
43
|
+
type: "object",
|
|
44
|
+
fields: {
|
|
45
|
+
sku: { type: "text" },
|
|
46
|
+
qty: { type: "number" },
|
|
47
|
+
note: { type: "text", required: false },
|
|
48
|
+
ref: { type: "record_link", table_id: "tbl_x" },
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
expect(dts).toContain("lines: ReadonlyArray<{");
|
|
56
|
+
expect(dts).toContain("sku: string;");
|
|
57
|
+
expect(dts).toContain("qty: number;");
|
|
58
|
+
expect(dts).toContain("note?: string;");
|
|
59
|
+
expect(dts).toContain("ref: string;");
|
|
60
|
+
});
|
|
35
61
|
it("maps record_link/select outputs the same way as inputs", () => {
|
|
36
62
|
const dts = generateAppWorkflowsDts({
|
|
37
63
|
lookup: {
|
package/dist/src/cli.js
CHANGED
|
@@ -30954,7 +30954,7 @@ function buildWrapperPage(args) {
|
|
|
30954
30954
|
<span>workspace <code>${escapeHtml2(workspace_id)}</code></span>
|
|
30955
30955
|
<span>RPC \u2192 <code>${escapeHtml2(api_url)}</code></span>
|
|
30956
30956
|
</header>
|
|
30957
|
-
<iframe id="app" sandbox="allow-scripts allow-same-origin allow-downloads" allow="clipboard-write; geolocation"></iframe>
|
|
30957
|
+
<iframe id="app" sandbox="allow-scripts allow-same-origin allow-downloads" allow="clipboard-write; geolocation; web-share"></iframe>
|
|
30958
30958
|
<script>
|
|
30959
30959
|
(function () {
|
|
30960
30960
|
const APP_ID = ${JSON.stringify(app_id)};
|
|
@@ -31439,6 +31439,14 @@ function inputDeclToTsType(decl) {
|
|
|
31439
31439
|
return "{ start: string; end: string }";
|
|
31440
31440
|
case "file":
|
|
31441
31441
|
return "string";
|
|
31442
|
+
case "object": {
|
|
31443
|
+
const fields = decl.fields !== null && typeof decl.fields === "object" ? decl.fields : {};
|
|
31444
|
+
return inputsToType(fields);
|
|
31445
|
+
}
|
|
31446
|
+
case "array": {
|
|
31447
|
+
const items = decl.items !== null && typeof decl.items === "object" ? decl.items : null;
|
|
31448
|
+
return items ? `ReadonlyArray<${inputDeclToTsType(items)}>` : "ReadonlyArray<unknown>";
|
|
31449
|
+
}
|
|
31442
31450
|
case "json":
|
|
31443
31451
|
return "unknown";
|
|
31444
31452
|
default:
|