@lotics/cli 0.44.1 → 0.45.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.
- package/dist/client.d.ts +11 -0
- package/dist/client.js +18 -0
- package/dist/dev/rpc_handler.d.ts +1 -1
- package/dist/dev/rpc_handler.js +56 -0
- package/dist/dev/rpc_handler.test.js +30 -0
- package/dist/src/cli.js +135 -24
- package/dist/starter_template.d.ts +1 -1
- package/dist/starter_template.js +29 -9
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -218,6 +218,17 @@ export declare class LoticsClient {
|
|
|
218
218
|
thumbnail_url?: string;
|
|
219
219
|
};
|
|
220
220
|
}>;
|
|
221
|
+
appGetRecordComments(app_id: string, record_id: string): Promise<unknown[]>;
|
|
222
|
+
appCreateRecordComment(app_id: string, record_id: string, body: {
|
|
223
|
+
content: string;
|
|
224
|
+
file_ids?: string[];
|
|
225
|
+
}): Promise<unknown>;
|
|
226
|
+
appUpdateRecordComment(app_id: string, record_id: string, comment_id: string, body: {
|
|
227
|
+
content: string;
|
|
228
|
+
files?: unknown[];
|
|
229
|
+
}): Promise<unknown>;
|
|
230
|
+
appDeleteRecordComment(app_id: string, record_id: string, comment_id: string): Promise<void>;
|
|
231
|
+
appGetTableCommentCounts(app_id: string, table_id: string): Promise<Record<string, number>>;
|
|
221
232
|
deployAppVersion(args: {
|
|
222
233
|
app_id: string;
|
|
223
234
|
source_archive: Buffer;
|
package/dist/client.js
CHANGED
|
@@ -208,6 +208,24 @@ export class LoticsClient {
|
|
|
208
208
|
async appCompleteFileUpload(app_id, body) {
|
|
209
209
|
return this.request("POST", `/v1/apps/${encodeURIComponent(app_id)}/files/complete`, body);
|
|
210
210
|
}
|
|
211
|
+
// App-scoped record comments — the `lotics app dev` loop forwards the iframe's
|
|
212
|
+
// `comments.*` ops to these (production routes them through the iframe host).
|
|
213
|
+
// App authority + tenant floor are enforced server-side; these are thin.
|
|
214
|
+
async appGetRecordComments(app_id, record_id) {
|
|
215
|
+
return this.request("GET", `/v1/apps/${encodeURIComponent(app_id)}/records/${encodeURIComponent(record_id)}/comments`);
|
|
216
|
+
}
|
|
217
|
+
async appCreateRecordComment(app_id, record_id, body) {
|
|
218
|
+
return this.request("POST", `/v1/apps/${encodeURIComponent(app_id)}/records/${encodeURIComponent(record_id)}/comments`, body);
|
|
219
|
+
}
|
|
220
|
+
async appUpdateRecordComment(app_id, record_id, comment_id, body) {
|
|
221
|
+
return this.request("PATCH", `/v1/apps/${encodeURIComponent(app_id)}/records/${encodeURIComponent(record_id)}/comments/${encodeURIComponent(comment_id)}`, body);
|
|
222
|
+
}
|
|
223
|
+
async appDeleteRecordComment(app_id, record_id, comment_id) {
|
|
224
|
+
await this.request("DELETE", `/v1/apps/${encodeURIComponent(app_id)}/records/${encodeURIComponent(record_id)}/comments/${encodeURIComponent(comment_id)}`);
|
|
225
|
+
}
|
|
226
|
+
async appGetTableCommentCounts(app_id, table_id) {
|
|
227
|
+
return this.request("GET", `/v1/apps/${encodeURIComponent(app_id)}/tables/${encodeURIComponent(table_id)}/comment-counts`);
|
|
228
|
+
}
|
|
211
229
|
async deployAppVersion(args) {
|
|
212
230
|
const formData = new FormData();
|
|
213
231
|
// Wrap Buffers as Uint8Array views so the Blob constructor accepts them
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* { message }. Same shape as the production iframe-host's error path.
|
|
7
7
|
*/
|
|
8
8
|
import { LoticsClient } from "../client.js";
|
|
9
|
-
export type RpcOp = "query" | "workflow" | "members" | "context" | "upload_url" | "upload_complete";
|
|
9
|
+
export type RpcOp = "query" | "workflow" | "members" | "context" | "upload_url" | "upload_complete" | "comments.list" | "comments.create" | "comments.update" | "comments.delete" | "comments.counts";
|
|
10
10
|
export interface RpcRequest {
|
|
11
11
|
app_id: string;
|
|
12
12
|
op: RpcOp;
|
package/dist/dev/rpc_handler.js
CHANGED
|
@@ -12,6 +12,11 @@ const SUPPORTED_OPS = new Set([
|
|
|
12
12
|
"context",
|
|
13
13
|
"upload_url",
|
|
14
14
|
"upload_complete",
|
|
15
|
+
"comments.list",
|
|
16
|
+
"comments.create",
|
|
17
|
+
"comments.update",
|
|
18
|
+
"comments.delete",
|
|
19
|
+
"comments.counts",
|
|
15
20
|
]);
|
|
16
21
|
export async function dispatchRpc(client, body, opts) {
|
|
17
22
|
if (!body || typeof body.app_id !== "string" || typeof body.op !== "string") {
|
|
@@ -86,6 +91,57 @@ export async function dispatchRpc(client, body, opts) {
|
|
|
86
91
|
filename: p.filename,
|
|
87
92
|
});
|
|
88
93
|
}
|
|
94
|
+
// Comment ops mirror the production iframe-host's `handleCommentRpc` return
|
|
95
|
+
// shapes so the SDK hooks behave identically in dev. App authority + the
|
|
96
|
+
// `comments` capability + tenant floor are enforced server-side.
|
|
97
|
+
case "comments.list": {
|
|
98
|
+
const p = body.payload;
|
|
99
|
+
if (!p || typeof p.record_id !== "string") {
|
|
100
|
+
throw new Error("comments.list payload must include record_id");
|
|
101
|
+
}
|
|
102
|
+
const comments = await client.appGetRecordComments(body.app_id, p.record_id);
|
|
103
|
+
return { comments };
|
|
104
|
+
}
|
|
105
|
+
case "comments.create": {
|
|
106
|
+
const p = body.payload;
|
|
107
|
+
if (!p || typeof p.record_id !== "string" || typeof p.content !== "string") {
|
|
108
|
+
throw new Error("comments.create payload must include record_id and content");
|
|
109
|
+
}
|
|
110
|
+
const created = await client.appCreateRecordComment(body.app_id, p.record_id, {
|
|
111
|
+
content: p.content,
|
|
112
|
+
file_ids: p.file_ids,
|
|
113
|
+
});
|
|
114
|
+
return { comments: created ? [created] : [] };
|
|
115
|
+
}
|
|
116
|
+
case "comments.update": {
|
|
117
|
+
const p = body.payload;
|
|
118
|
+
if (!p ||
|
|
119
|
+
typeof p.record_id !== "string" ||
|
|
120
|
+
typeof p.comment_id !== "string" ||
|
|
121
|
+
typeof p.content !== "string") {
|
|
122
|
+
throw new Error("comments.update payload must include record_id, comment_id, content");
|
|
123
|
+
}
|
|
124
|
+
const comment = await client.appUpdateRecordComment(body.app_id, p.record_id, p.comment_id, {
|
|
125
|
+
content: p.content,
|
|
126
|
+
files: p.files,
|
|
127
|
+
});
|
|
128
|
+
return { comment };
|
|
129
|
+
}
|
|
130
|
+
case "comments.delete": {
|
|
131
|
+
const p = body.payload;
|
|
132
|
+
if (!p || typeof p.record_id !== "string" || typeof p.comment_id !== "string") {
|
|
133
|
+
throw new Error("comments.delete payload must include record_id and comment_id");
|
|
134
|
+
}
|
|
135
|
+
await client.appDeleteRecordComment(body.app_id, p.record_id, p.comment_id);
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
case "comments.counts": {
|
|
139
|
+
const p = body.payload;
|
|
140
|
+
if (!p || typeof p.table_id !== "string") {
|
|
141
|
+
throw new Error("comments.counts payload must include table_id");
|
|
142
|
+
}
|
|
143
|
+
return client.appGetTableCommentCounts(body.app_id, p.table_id);
|
|
144
|
+
}
|
|
89
145
|
default: {
|
|
90
146
|
// Unreachable — SUPPORTED_OPS gates above.
|
|
91
147
|
throw new Error(`Unhandled RPC op: ${body.op}`);
|
|
@@ -26,3 +26,33 @@ describe("dispatchRpc — context op", () => {
|
|
|
26
26
|
await expect(dispatchRpc(client, { app_id: "app_x", op: "bogus", payload: {} })).rejects.toThrow(/Unknown RPC op/);
|
|
27
27
|
});
|
|
28
28
|
});
|
|
29
|
+
describe("dispatchRpc — comment ops", () => {
|
|
30
|
+
it("comments.list forwards to appGetRecordComments, wrapped as { comments }", async () => {
|
|
31
|
+
const comments = [{ id: "cmt_1", content: "hi" }];
|
|
32
|
+
const client = mockClient({ appGetRecordComments: async () => comments });
|
|
33
|
+
const result = await dispatchRpc(client, {
|
|
34
|
+
app_id: "app_x",
|
|
35
|
+
op: "comments.list",
|
|
36
|
+
payload: { record_id: "rec_1" },
|
|
37
|
+
});
|
|
38
|
+
expect(result).toEqual({ comments });
|
|
39
|
+
});
|
|
40
|
+
it("comments.counts forwards to appGetTableCommentCounts (counts, no content)", async () => {
|
|
41
|
+
const counts = { rec_1: 2, rec_2: 1 };
|
|
42
|
+
const client = mockClient({ appGetTableCommentCounts: async () => counts });
|
|
43
|
+
const result = await dispatchRpc(client, {
|
|
44
|
+
app_id: "app_x",
|
|
45
|
+
op: "comments.counts",
|
|
46
|
+
payload: { table_id: "tbl_1" },
|
|
47
|
+
});
|
|
48
|
+
expect(result).toEqual(counts);
|
|
49
|
+
});
|
|
50
|
+
it("requires the right payload per comment op", async () => {
|
|
51
|
+
const client = mockClient({
|
|
52
|
+
appGetRecordComments: async () => [],
|
|
53
|
+
appGetTableCommentCounts: async () => ({}),
|
|
54
|
+
});
|
|
55
|
+
await expect(dispatchRpc(client, { app_id: "app_x", op: "comments.list", payload: {} })).rejects.toThrow(/record_id/);
|
|
56
|
+
await expect(dispatchRpc(client, { app_id: "app_x", op: "comments.counts", payload: {} })).rejects.toThrow(/table_id/);
|
|
57
|
+
});
|
|
58
|
+
});
|
package/dist/src/cli.js
CHANGED
|
@@ -29801,6 +29801,41 @@ var LoticsClient = class {
|
|
|
29801
29801
|
body
|
|
29802
29802
|
);
|
|
29803
29803
|
}
|
|
29804
|
+
// App-scoped record comments — the `lotics app dev` loop forwards the iframe's
|
|
29805
|
+
// `comments.*` ops to these (production routes them through the iframe host).
|
|
29806
|
+
// App authority + tenant floor are enforced server-side; these are thin.
|
|
29807
|
+
async appGetRecordComments(app_id, record_id) {
|
|
29808
|
+
return this.request(
|
|
29809
|
+
"GET",
|
|
29810
|
+
`/v1/apps/${encodeURIComponent(app_id)}/records/${encodeURIComponent(record_id)}/comments`
|
|
29811
|
+
);
|
|
29812
|
+
}
|
|
29813
|
+
async appCreateRecordComment(app_id, record_id, body) {
|
|
29814
|
+
return this.request(
|
|
29815
|
+
"POST",
|
|
29816
|
+
`/v1/apps/${encodeURIComponent(app_id)}/records/${encodeURIComponent(record_id)}/comments`,
|
|
29817
|
+
body
|
|
29818
|
+
);
|
|
29819
|
+
}
|
|
29820
|
+
async appUpdateRecordComment(app_id, record_id, comment_id, body) {
|
|
29821
|
+
return this.request(
|
|
29822
|
+
"PATCH",
|
|
29823
|
+
`/v1/apps/${encodeURIComponent(app_id)}/records/${encodeURIComponent(record_id)}/comments/${encodeURIComponent(comment_id)}`,
|
|
29824
|
+
body
|
|
29825
|
+
);
|
|
29826
|
+
}
|
|
29827
|
+
async appDeleteRecordComment(app_id, record_id, comment_id) {
|
|
29828
|
+
await this.request(
|
|
29829
|
+
"DELETE",
|
|
29830
|
+
`/v1/apps/${encodeURIComponent(app_id)}/records/${encodeURIComponent(record_id)}/comments/${encodeURIComponent(comment_id)}`
|
|
29831
|
+
);
|
|
29832
|
+
}
|
|
29833
|
+
async appGetTableCommentCounts(app_id, table_id) {
|
|
29834
|
+
return this.request(
|
|
29835
|
+
"GET",
|
|
29836
|
+
`/v1/apps/${encodeURIComponent(app_id)}/tables/${encodeURIComponent(table_id)}/comment-counts`
|
|
29837
|
+
);
|
|
29838
|
+
}
|
|
29804
29839
|
async deployAppVersion(args) {
|
|
29805
29840
|
const formData = new FormData();
|
|
29806
29841
|
formData.append(
|
|
@@ -30179,7 +30214,7 @@ import { spawn as spawn2 } from "node:child_process";
|
|
|
30179
30214
|
import { tmpdir } from "node:os";
|
|
30180
30215
|
|
|
30181
30216
|
// src/starter_template.ts
|
|
30182
|
-
var STARTER_FALLBACK_UI_VERSION = "2.
|
|
30217
|
+
var STARTER_FALLBACK_UI_VERSION = "2.3.0";
|
|
30183
30218
|
var STARTER_FALLBACK_SDK_VERSION = "0.11.0";
|
|
30184
30219
|
var STARTER_REACT_NATIVE_VERSION = "0.85.3";
|
|
30185
30220
|
function buildStarterTemplate(args) {
|
|
@@ -30322,14 +30357,34 @@ export default defineConfig({
|
|
|
30322
30357
|
dedupe: ["react", "react-dom", "react-native-web"],
|
|
30323
30358
|
},
|
|
30324
30359
|
optimizeDeps: {
|
|
30325
|
-
//
|
|
30326
|
-
//
|
|
30327
|
-
//
|
|
30328
|
-
//
|
|
30329
|
-
//
|
|
30330
|
-
//
|
|
30331
|
-
//
|
|
30332
|
-
|
|
30360
|
+
// \`recharts\` (used by @lotics/ui chart_* + sparkline) imports
|
|
30361
|
+
// \`es-toolkit/compat/get\` as a default-export CJS module. Vite's dev
|
|
30362
|
+
// server treats \`compat/*\` as ESM and won't synthesize a default,
|
|
30363
|
+
// so \`import get from "es-toolkit/compat/get"\` fails to resolve.
|
|
30364
|
+
// Pre-bundling forces Vite to convert it to an ESM shim with a default
|
|
30365
|
+
// export. Production build (rollup) handles it correctly without this.
|
|
30366
|
+
//
|
|
30367
|
+
// react-native-web itself is force-prebundled (folds its core CJS deps like
|
|
30368
|
+
// @react-native/normalize-colors into one interop'd chunk), and the deep
|
|
30369
|
+
// subpaths it reaches via *default* imports (e.g. @react-native-picker's web
|
|
30370
|
+
// <select> build) are each pre-bundled into an ESM shim \u2014 Vite's dev optimizer
|
|
30371
|
+
// otherwise serves them without a synthesized default export ("does not
|
|
30372
|
+
// provide an export named 'default'"), blanking the iframe. (Production/rollup
|
|
30373
|
+
// resolves the interop already, so this is dev-only.)
|
|
30374
|
+
include: [
|
|
30375
|
+
"recharts", "es-toolkit", "es-toolkit/compat",
|
|
30376
|
+
"react-native-web", "@react-native/normalize-colors",
|
|
30377
|
+
"inline-style-prefixer/lib/createPrefixer",
|
|
30378
|
+
"inline-style-prefixer/lib/plugins/crossFade",
|
|
30379
|
+
"inline-style-prefixer/lib/plugins/imageSet",
|
|
30380
|
+
"inline-style-prefixer/lib/plugins/logical",
|
|
30381
|
+
"inline-style-prefixer/lib/plugins/position",
|
|
30382
|
+
"inline-style-prefixer/lib/plugins/sizing",
|
|
30383
|
+
"inline-style-prefixer/lib/plugins/transition",
|
|
30384
|
+
"postcss-value-parser", "fbjs/lib/invariant", "fbjs/lib/warning",
|
|
30385
|
+
"styleq", "styleq/transform-localize-style",
|
|
30386
|
+
"react", "react-dom", "react-dom/client", "nullthrows",
|
|
30387
|
+
],
|
|
30333
30388
|
// The dep optimizer pre-bundles deps with a SEPARATE esbuild pass that
|
|
30334
30389
|
// top-level \`define\` doesn't always reach, so a pre-bundled RN dep can
|
|
30335
30390
|
// still hit \`__DEV__ is not defined\` under \`lotics app dev\`. Define it
|
|
@@ -30671,7 +30726,12 @@ var SUPPORTED_OPS = /* @__PURE__ */ new Set([
|
|
|
30671
30726
|
"members",
|
|
30672
30727
|
"context",
|
|
30673
30728
|
"upload_url",
|
|
30674
|
-
"upload_complete"
|
|
30729
|
+
"upload_complete",
|
|
30730
|
+
"comments.list",
|
|
30731
|
+
"comments.create",
|
|
30732
|
+
"comments.update",
|
|
30733
|
+
"comments.delete",
|
|
30734
|
+
"comments.counts"
|
|
30675
30735
|
]);
|
|
30676
30736
|
async function dispatchRpc(client, body, opts) {
|
|
30677
30737
|
if (!body || typeof body.app_id !== "string" || typeof body.op !== "string") {
|
|
@@ -30738,6 +30798,54 @@ async function dispatchRpc(client, body, opts) {
|
|
|
30738
30798
|
filename: p.filename
|
|
30739
30799
|
});
|
|
30740
30800
|
}
|
|
30801
|
+
// Comment ops mirror the production iframe-host's `handleCommentRpc` return
|
|
30802
|
+
// shapes so the SDK hooks behave identically in dev. App authority + the
|
|
30803
|
+
// `comments` capability + tenant floor are enforced server-side.
|
|
30804
|
+
case "comments.list": {
|
|
30805
|
+
const p = body.payload;
|
|
30806
|
+
if (!p || typeof p.record_id !== "string") {
|
|
30807
|
+
throw new Error("comments.list payload must include record_id");
|
|
30808
|
+
}
|
|
30809
|
+
const comments = await client.appGetRecordComments(body.app_id, p.record_id);
|
|
30810
|
+
return { comments };
|
|
30811
|
+
}
|
|
30812
|
+
case "comments.create": {
|
|
30813
|
+
const p = body.payload;
|
|
30814
|
+
if (!p || typeof p.record_id !== "string" || typeof p.content !== "string") {
|
|
30815
|
+
throw new Error("comments.create payload must include record_id and content");
|
|
30816
|
+
}
|
|
30817
|
+
const created = await client.appCreateRecordComment(body.app_id, p.record_id, {
|
|
30818
|
+
content: p.content,
|
|
30819
|
+
file_ids: p.file_ids
|
|
30820
|
+
});
|
|
30821
|
+
return { comments: created ? [created] : [] };
|
|
30822
|
+
}
|
|
30823
|
+
case "comments.update": {
|
|
30824
|
+
const p = body.payload;
|
|
30825
|
+
if (!p || typeof p.record_id !== "string" || typeof p.comment_id !== "string" || typeof p.content !== "string") {
|
|
30826
|
+
throw new Error("comments.update payload must include record_id, comment_id, content");
|
|
30827
|
+
}
|
|
30828
|
+
const comment = await client.appUpdateRecordComment(body.app_id, p.record_id, p.comment_id, {
|
|
30829
|
+
content: p.content,
|
|
30830
|
+
files: p.files
|
|
30831
|
+
});
|
|
30832
|
+
return { comment };
|
|
30833
|
+
}
|
|
30834
|
+
case "comments.delete": {
|
|
30835
|
+
const p = body.payload;
|
|
30836
|
+
if (!p || typeof p.record_id !== "string" || typeof p.comment_id !== "string") {
|
|
30837
|
+
throw new Error("comments.delete payload must include record_id and comment_id");
|
|
30838
|
+
}
|
|
30839
|
+
await client.appDeleteRecordComment(body.app_id, p.record_id, p.comment_id);
|
|
30840
|
+
return void 0;
|
|
30841
|
+
}
|
|
30842
|
+
case "comments.counts": {
|
|
30843
|
+
const p = body.payload;
|
|
30844
|
+
if (!p || typeof p.table_id !== "string") {
|
|
30845
|
+
throw new Error("comments.counts payload must include table_id");
|
|
30846
|
+
}
|
|
30847
|
+
return client.appGetTableCommentCounts(body.app_id, p.table_id);
|
|
30848
|
+
}
|
|
30741
30849
|
default: {
|
|
30742
30850
|
throw new Error(`Unhandled RPC op: ${body.op}`);
|
|
30743
30851
|
}
|
|
@@ -39228,7 +39336,7 @@ var drawingParser = new XMLParser({
|
|
|
39228
39336
|
processEntities: false,
|
|
39229
39337
|
isArray: (tagName) => tagName === "xdr:twoCellAnchor" || tagName === "xdr:oneCellAnchor" || tagName === "Relationship"
|
|
39230
39338
|
});
|
|
39231
|
-
function parseSheet(sheetXml, sheetRelsXml, styles, sharedStrings, theme, indexedColors, zipEntries, date1904) {
|
|
39339
|
+
function parseSheet(sheetXml, sheetRelsXml, styles, sharedStrings, theme, indexedColors, zipEntries, date1904, maxRows = MAX_ROWS_PER_SHEET) {
|
|
39232
39340
|
const doc = xmlParser4.parse(sheetXml);
|
|
39233
39341
|
const worksheet = doc?.["worksheet"];
|
|
39234
39342
|
if (!worksheet) return emptySheet("Sheet");
|
|
@@ -39246,7 +39354,7 @@ function parseSheet(sheetXml, sheetRelsXml, styles, sharedStrings, theme, indexe
|
|
|
39246
39354
|
maxCol,
|
|
39247
39355
|
maxContentWidth,
|
|
39248
39356
|
rowOutlineLevels
|
|
39249
|
-
} = parseSheetData(worksheet, styles, sharedStrings, hyperlinkMap, defaultRowHeight, date1904);
|
|
39357
|
+
} = parseSheetData(worksheet, styles, sharedStrings, hyperlinkMap, defaultRowHeight, date1904, maxRows);
|
|
39250
39358
|
const colCount = Math.max(parsedCols.length > 0 ? parsedCols[parsedCols.length - 1].max : 0, maxCol);
|
|
39251
39359
|
const columns = buildColumns(parsedCols, colHidden, maxContentWidth, colCount, defaultColWidth);
|
|
39252
39360
|
const mergedCells = parseMergedCells(worksheet);
|
|
@@ -39428,7 +39536,7 @@ function buildColumns(colDefs, colHidden, maxContentWidth, colCount, _defaultCol
|
|
|
39428
39536
|
}
|
|
39429
39537
|
return columns;
|
|
39430
39538
|
}
|
|
39431
|
-
function parseSheetData(worksheet, styles, sharedStrings, hyperlinkMap, defaultRowHeight, date1904) {
|
|
39539
|
+
function parseSheetData(worksheet, styles, sharedStrings, hyperlinkMap, defaultRowHeight, date1904, maxRows) {
|
|
39432
39540
|
const sheetData = worksheet["sheetData"];
|
|
39433
39541
|
if (!sheetData) {
|
|
39434
39542
|
return {
|
|
@@ -39464,9 +39572,9 @@ function parseSheetData(worksheet, styles, sharedStrings, hyperlinkMap, defaultR
|
|
|
39464
39572
|
if (outlineLevel > 0) {
|
|
39465
39573
|
rowOutlineLevels.set(rowIndex, outlineLevel);
|
|
39466
39574
|
}
|
|
39467
|
-
|
|
39575
|
+
const rowHidden = rowEl["@_hidden"] === "1" || rowEl["@_hidden"] === "true";
|
|
39468
39576
|
rowCount++;
|
|
39469
|
-
if (rowCount >
|
|
39577
|
+
if (rowCount > maxRows) continue;
|
|
39470
39578
|
const height = rowEl["@_ht"] ? parseFloat(rowEl["@_ht"]) : defaultRowHeight;
|
|
39471
39579
|
const cellArr = rowEl["c"];
|
|
39472
39580
|
const cells = [];
|
|
@@ -39476,7 +39584,7 @@ function parseSheetData(worksheet, styles, sharedStrings, hyperlinkMap, defaultR
|
|
|
39476
39584
|
if (parsed) {
|
|
39477
39585
|
cells.push(parsed);
|
|
39478
39586
|
if (parsed.column > maxCol) maxCol = parsed.column;
|
|
39479
|
-
if (rowCount <= 200) {
|
|
39587
|
+
if (rowCount <= 200 && !rowHidden) {
|
|
39480
39588
|
const currentMax = maxContentWidth.get(parsed.column) ?? 0;
|
|
39481
39589
|
if (parsed.value.length > currentMax) {
|
|
39482
39590
|
maxContentWidth.set(parsed.column, parsed.value.length);
|
|
@@ -39489,13 +39597,13 @@ function parseSheetData(worksheet, styles, sharedStrings, hyperlinkMap, defaultR
|
|
|
39489
39597
|
index: rowIndex,
|
|
39490
39598
|
height,
|
|
39491
39599
|
cells,
|
|
39492
|
-
hidden:
|
|
39600
|
+
hidden: rowHidden
|
|
39493
39601
|
});
|
|
39494
39602
|
}
|
|
39495
39603
|
return {
|
|
39496
39604
|
rows,
|
|
39497
39605
|
totalRowCount,
|
|
39498
|
-
truncated: rowCount >
|
|
39606
|
+
truncated: rowCount > maxRows,
|
|
39499
39607
|
maxCol,
|
|
39500
39608
|
maxContentWidth,
|
|
39501
39609
|
rowOutlineLevels
|
|
@@ -39537,10 +39645,12 @@ function parseCell(cellEl, styles, sharedStrings, hyperlinkMap, date1904) {
|
|
|
39537
39645
|
if (fEl !== void 0 && fEl !== null) {
|
|
39538
39646
|
if (typeof fEl === "object") {
|
|
39539
39647
|
const fObj = fEl;
|
|
39540
|
-
|
|
39648
|
+
const text = fObj["#text"];
|
|
39649
|
+
formula = text == null ? void 0 : String(text);
|
|
39541
39650
|
if (fObj["@_t"] === "array") {
|
|
39542
39651
|
isArrayFormula = true;
|
|
39543
|
-
|
|
39652
|
+
const ref2 = fObj["@_ref"];
|
|
39653
|
+
arrayRange = ref2 == null ? void 0 : String(ref2);
|
|
39544
39654
|
if (formula?.startsWith("{") && formula.endsWith("}")) {
|
|
39545
39655
|
formula = formula.slice(1, -1);
|
|
39546
39656
|
}
|
|
@@ -41109,11 +41219,11 @@ function ensureVmlArray(val) {
|
|
|
41109
41219
|
}
|
|
41110
41220
|
|
|
41111
41221
|
// ../xlsx/src/excel_parser.ts
|
|
41112
|
-
function parseExcelBuffer(arrayBuffer) {
|
|
41222
|
+
function parseExcelBuffer(arrayBuffer, options) {
|
|
41113
41223
|
const zip = unzipXlsx(arrayBuffer);
|
|
41114
|
-
return parseExcelFromZip(zip);
|
|
41224
|
+
return parseExcelFromZip(zip, options);
|
|
41115
41225
|
}
|
|
41116
|
-
function parseExcelFromZip(zip) {
|
|
41226
|
+
function parseExcelFromZip(zip, options) {
|
|
41117
41227
|
const themeEntry = findEntry(zip, "xl/theme/theme1.xml");
|
|
41118
41228
|
const theme = themeEntry ? parseTheme(decodeUtf8(themeEntry)) : { colors: defaultThemeColors(), majorFont: "Calibri", minorFont: "Calibri" };
|
|
41119
41229
|
const stylesEntry = findEntry(zip, "xl/styles.xml");
|
|
@@ -41175,7 +41285,8 @@ function parseExcelFromZip(zip) {
|
|
|
41175
41285
|
theme,
|
|
41176
41286
|
styles.indexedColors,
|
|
41177
41287
|
zip,
|
|
41178
|
-
workbookInfo.date1904
|
|
41288
|
+
workbookInfo.date1904,
|
|
41289
|
+
options?.maxRowsPerSheet
|
|
41179
41290
|
);
|
|
41180
41291
|
parsed.name = sheetInfo.name;
|
|
41181
41292
|
if (isHidden) parsed.hidden = true;
|
|
@@ -39,7 +39,7 @@ export interface StarterFile {
|
|
|
39
39
|
* scaffolds resolve the live version via `fetchLatestNpmVersion` and only
|
|
40
40
|
* fall back here when the lookup fails.
|
|
41
41
|
*/
|
|
42
|
-
export declare const STARTER_FALLBACK_UI_VERSION = "2.
|
|
42
|
+
export declare const STARTER_FALLBACK_UI_VERSION = "2.3.0";
|
|
43
43
|
export declare const STARTER_FALLBACK_SDK_VERSION = "0.11.0";
|
|
44
44
|
/**
|
|
45
45
|
* react-native pin for scaffolded apps. Matches the monorepo frontend's pin so
|
package/dist/starter_template.js
CHANGED
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* scaffolds resolve the live version via `fetchLatestNpmVersion` and only
|
|
36
36
|
* fall back here when the lookup fails.
|
|
37
37
|
*/
|
|
38
|
-
export const STARTER_FALLBACK_UI_VERSION = "2.
|
|
38
|
+
export const STARTER_FALLBACK_UI_VERSION = "2.3.0";
|
|
39
39
|
export const STARTER_FALLBACK_SDK_VERSION = "0.11.0";
|
|
40
40
|
/**
|
|
41
41
|
* react-native pin for scaffolded apps. Matches the monorepo frontend's pin so
|
|
@@ -184,14 +184,34 @@ export default defineConfig({
|
|
|
184
184
|
dedupe: ["react", "react-dom", "react-native-web"],
|
|
185
185
|
},
|
|
186
186
|
optimizeDeps: {
|
|
187
|
-
//
|
|
188
|
-
//
|
|
189
|
-
//
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
//
|
|
193
|
-
//
|
|
194
|
-
|
|
187
|
+
// \`recharts\` (used by @lotics/ui chart_* + sparkline) imports
|
|
188
|
+
// \`es-toolkit/compat/get\` as a default-export CJS module. Vite's dev
|
|
189
|
+
// server treats \`compat/*\` as ESM and won't synthesize a default,
|
|
190
|
+
// so \`import get from "es-toolkit/compat/get"\` fails to resolve.
|
|
191
|
+
// Pre-bundling forces Vite to convert it to an ESM shim with a default
|
|
192
|
+
// export. Production build (rollup) handles it correctly without this.
|
|
193
|
+
//
|
|
194
|
+
// react-native-web itself is force-prebundled (folds its core CJS deps like
|
|
195
|
+
// @react-native/normalize-colors into one interop'd chunk), and the deep
|
|
196
|
+
// subpaths it reaches via *default* imports (e.g. @react-native-picker's web
|
|
197
|
+
// <select> build) are each pre-bundled into an ESM shim — Vite's dev optimizer
|
|
198
|
+
// otherwise serves them without a synthesized default export ("does not
|
|
199
|
+
// provide an export named 'default'"), blanking the iframe. (Production/rollup
|
|
200
|
+
// resolves the interop already, so this is dev-only.)
|
|
201
|
+
include: [
|
|
202
|
+
"recharts", "es-toolkit", "es-toolkit/compat",
|
|
203
|
+
"react-native-web", "@react-native/normalize-colors",
|
|
204
|
+
"inline-style-prefixer/lib/createPrefixer",
|
|
205
|
+
"inline-style-prefixer/lib/plugins/crossFade",
|
|
206
|
+
"inline-style-prefixer/lib/plugins/imageSet",
|
|
207
|
+
"inline-style-prefixer/lib/plugins/logical",
|
|
208
|
+
"inline-style-prefixer/lib/plugins/position",
|
|
209
|
+
"inline-style-prefixer/lib/plugins/sizing",
|
|
210
|
+
"inline-style-prefixer/lib/plugins/transition",
|
|
211
|
+
"postcss-value-parser", "fbjs/lib/invariant", "fbjs/lib/warning",
|
|
212
|
+
"styleq", "styleq/transform-localize-style",
|
|
213
|
+
"react", "react-dom", "react-dom/client", "nullthrows",
|
|
214
|
+
],
|
|
195
215
|
// The dep optimizer pre-bundles deps with a SEPARATE esbuild pass that
|
|
196
216
|
// top-level \`define\` doesn't always reach, so a pre-bundled RN dep can
|
|
197
217
|
// still hit \`__DEV__ is not defined\` under \`lotics app dev\`. Define it
|