@lotics/cli 0.111.0 → 0.112.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.
@@ -50248,6 +50248,10 @@ ${e.toString()}`);
50248
50248
  const { row, col } = unpackRowCol(packed);
50249
50249
  return rowColToRef(row, col);
50250
50250
  }
50251
+ function stripNsPrefix(tag) {
50252
+ const colon = tag.indexOf(":");
50253
+ return colon === -1 ? tag : tag.slice(colon + 1);
50254
+ }
50251
50255
 
50252
50256
  // ../xlsx/node_modules/fast-xml-parser/src/util.js
50253
50257
  var nameStartChar2 = ":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
@@ -52246,6 +52250,16 @@ ${e.toString()}`);
52246
52250
  return { type: "plain", text: displayValue };
52247
52251
  }
52248
52252
 
52253
+ // ../xlsx/src/malformed_part_error.ts
52254
+ var MalformedPartError = class extends Error {
52255
+ constructor(reason) {
52256
+ super(
52257
+ `${reason} \u2014 the file is not a readable spreadsheet. If it opens in Excel, the reader is at fault: report the producer that wrote it.`
52258
+ );
52259
+ this.name = "MalformedPartError";
52260
+ }
52261
+ };
52262
+
52249
52263
  // ../../node_modules/fflate/esm/browser.js
52250
52264
  var u8 = Uint8Array;
52251
52265
  var u16 = Uint16Array;
@@ -52846,7 +52860,11 @@ ${e.toString()}`);
52846
52860
  ignoreAttributes: false,
52847
52861
  attributeNamePrefix: "@_",
52848
52862
  processEntities: false,
52849
- isArray: (tagName) => tagName === "row" || tagName === "c" || tagName === "col" || tagName === "mergeCell" || tagName === "conditionalFormatting" || tagName === "cfRule" || tagName === "cfvo" || tagName === "color" || tagName === "hyperlink" || tagName === "Relationship" || tagName === "sheetView" || tagName === "xdr:twoCellAnchor" || tagName === "xdr:oneCellAnchor" || tagName === "dataValidation" || tagName === "filterColumn" || tagName === "filter" || tagName === "brk" || tagName === "ext",
52863
+ // A producer may bind spreadsheetml to a prefix (`<x:worksheet>`) instead of
52864
+ // making it the default namespace. The prefix carries no meaning, so it is
52865
+ // dropped before anything looks a tag up — see `stripNsPrefix`.
52866
+ transformTagName: stripNsPrefix,
52867
+ isArray: (tagName) => tagName === "row" || tagName === "c" || tagName === "col" || tagName === "mergeCell" || tagName === "conditionalFormatting" || tagName === "cfRule" || tagName === "cfvo" || tagName === "color" || tagName === "hyperlink" || tagName === "Relationship" || tagName === "sheetView" || tagName === "dataValidation" || tagName === "filterColumn" || tagName === "filter" || tagName === "brk" || tagName === "ext",
52850
52868
  // Preserve whitespace in cell values
52851
52869
  trimValues: false
52852
52870
  });
@@ -52865,7 +52883,7 @@ ${e.toString()}`);
52865
52883
  function parseSheet(sheetXml, sheetRelsXml, styles, sharedStrings, theme, indexedColors, zipEntries, date1904, maxRows = MAX_ROWS_PER_SHEET) {
52866
52884
  const doc3 = xmlParser2.parse(sheetXml);
52867
52885
  const worksheet = doc3?.["worksheet"];
52868
- if (!worksheet) return emptySheet("Sheet");
52886
+ if (!worksheet) throw new MalformedPartError("A worksheet part has no <worksheet> root");
52869
52887
  const rels = sheetRelsXml ? parseSheetRels(sheetRelsXml) : /* @__PURE__ */ new Map();
52870
52888
  const sheetFormatPr = worksheet["sheetFormatPr"];
52871
52889
  const defaultRowHeight = sheetFormatPr?.["@_defaultRowHeight"] ? parseFloat(sheetFormatPr["@_defaultRowHeight"]) : 15;
@@ -64560,6 +64578,10 @@ ${e.toString()}`);
64560
64578
  var xmlParser3 = new XMLParser2({
64561
64579
  ignoreAttributes: false,
64562
64580
  attributeNamePrefix: "@_",
64581
+ // A producer may bind spreadsheetml to a prefix (`<x:styleSheet>`) rather than
64582
+ // making it the default namespace; the prefix carries no meaning, so it is
64583
+ // dropped before anything looks a tag up — see `stripNsPrefix`.
64584
+ transformTagName: stripNsPrefix,
64563
64585
  processEntities: false,
64564
64586
  isArray: (tagName) => tagName === "numFmt" || tagName === "font" || tagName === "fill" || tagName === "border" || tagName === "xf" || tagName === "rgbColor" || tagName === "stop"
64565
64587
  });
@@ -64893,6 +64915,10 @@ ${e.toString()}`);
64893
64915
  var xmlParser4 = new XMLParser2({
64894
64916
  ignoreAttributes: false,
64895
64917
  attributeNamePrefix: "@_",
64918
+ // A producer may bind spreadsheetml to a prefix (`<x:workbook>`) rather than
64919
+ // making it the default namespace; the prefix carries no meaning, so it is
64920
+ // dropped before anything looks a tag up — see `stripNsPrefix`.
64921
+ transformTagName: stripNsPrefix,
64896
64922
  // Shared-string and workbook text is textual BY DEFINITION (tax IDs, phone
64897
64923
  // numbers, account codes, sheet/defined names). fast-xml-parser's default tag
64898
64924
  // coercion would parse `<t>0312345678</t>` as the number 312345678 — silently
@@ -64906,7 +64932,7 @@ ${e.toString()}`);
64906
64932
  function parseWorkbook(workbookXml) {
64907
64933
  const doc3 = xmlParser4.parse(workbookXml);
64908
64934
  const wb = doc3?.["workbook"];
64909
- if (!wb) return { sheets: [], activeSheetIndex: 0, date1904: false, namedRanges: /* @__PURE__ */ new Map(), printTitlesBySheet: /* @__PURE__ */ new Map(), fullCalcOnLoad: false };
64935
+ if (!wb) throw new MalformedPartError("xl/workbook.xml has no <workbook> root");
64910
64936
  const sheetsEl = wb["sheets"];
64911
64937
  const sheetArr = sheetsEl?.["sheet"];
64912
64938
  const sheets = (sheetArr ?? []).map((s) => ({
@@ -66220,9 +66246,7 @@ ${e.toString()}`);
66220
66246
  const stylesEntry = findEntry(zip, "xl/styles.xml");
66221
66247
  const styles = stylesEntry ? parseStyles(decodeUtf8(stylesEntry), theme) : emptyStyleResolver();
66222
66248
  const wbEntry = findEntry(zip, "xl/workbook.xml");
66223
- if (!wbEntry) {
66224
- return { sheets: [emptySheet("Sheet1")], activeSheetIndex: 0 };
66225
- }
66249
+ if (!wbEntry) throw new MalformedPartError("The package has no xl/workbook.xml");
66226
66250
  const workbookInfo = parseWorkbook(decodeUtf8(wbEntry));
66227
66251
  const wbRelsEntry = findEntry(zip, "xl/_rels/workbook.xml.rels");
66228
66252
  const wbRels = wbRelsEntry ? parseWorkbookRels(decodeUtf8(wbRelsEntry)) : /* @__PURE__ */ new Map();
@@ -66236,22 +66260,20 @@ ${e.toString()}`);
66236
66260
  });
66237
66261
  const parseXmlDoc = (xml) => xmlParser5.parse(xml);
66238
66262
  const pivotCaches = /* @__PURE__ */ new Map();
66239
- if (wbEntry) {
66240
- const wbDoc = parseXmlDoc(decodeUtf8(wbEntry));
66241
- const wbCacheMap = extractWorkbookPivotCaches(wbDoc);
66242
- for (const [cacheId, rId] of wbCacheMap) {
66243
- const cacheTarget = wbRels.get(rId);
66244
- if (!cacheTarget) continue;
66245
- const cachePath = cacheTarget.startsWith("/") ? cacheTarget.slice(1) : `xl/${cacheTarget}`;
66246
- const cacheEntry = findEntry(zip, cachePath);
66247
- if (!cacheEntry) continue;
66248
- try {
66249
- pivotCaches.set(
66250
- cacheId,
66251
- parsePivotCacheDefinitionXml(decodeUtf8(cacheEntry), cacheId, parseXmlDoc)
66252
- );
66253
- } catch {
66254
- }
66263
+ const wbDoc = parseXmlDoc(decodeUtf8(wbEntry));
66264
+ const wbCacheMap = extractWorkbookPivotCaches(wbDoc);
66265
+ for (const [cacheId, rId] of wbCacheMap) {
66266
+ const cacheTarget = wbRels.get(rId);
66267
+ if (!cacheTarget) continue;
66268
+ const cachePath = cacheTarget.startsWith("/") ? cacheTarget.slice(1) : `xl/${cacheTarget}`;
66269
+ const cacheEntry = findEntry(zip, cachePath);
66270
+ if (!cacheEntry) continue;
66271
+ try {
66272
+ pivotCaches.set(
66273
+ cacheId,
66274
+ parsePivotCacheDefinitionXml(decodeUtf8(cacheEntry), cacheId, parseXmlDoc)
66275
+ );
66276
+ } catch {
66255
66277
  }
66256
66278
  }
66257
66279
  const sheets = [];
@@ -66375,6 +66397,11 @@ ${e.toString()}`);
66375
66397
  }
66376
66398
  visibleIndex++;
66377
66399
  }
66400
+ if (sheets.length === 0 && workbookInfo.sheets.length > 0) {
66401
+ throw new MalformedPartError(
66402
+ `xl/workbook.xml declares ${workbookInfo.sheets.length} sheet(s) and none of their parts could be resolved`
66403
+ );
66404
+ }
66378
66405
  if (sheets.length === 0) {
66379
66406
  return { sheets: [emptySheet("Sheet1")], activeSheetIndex: 0 };
66380
66407
  }
package/dist/src/cli.js CHANGED
@@ -62234,353 +62234,6 @@ var templatePartSchema = zod_default.lazy(
62234
62234
  ])
62235
62235
  );
62236
62236
 
62237
- // ../shared/src/schemas/table_filters.ts
62238
- var tableRecordNumberFieldFilterSchema = zod_default.object({
62239
- type: zod_default.literal("number"),
62240
- field_key: zod_default.string(),
62241
- operator: zod_default.enum([
62242
- "equals",
62243
- "not_equals",
62244
- "greater_than",
62245
- "less_than",
62246
- "greater_than_or_equal_to",
62247
- "less_than_or_equal_to",
62248
- "is_empty",
62249
- "is_not_empty"
62250
- ]),
62251
- value: zod_default.number().nullable()
62252
- });
62253
- var tableRecordTextFieldFilterSchema = zod_default.object({
62254
- type: zod_default.literal("text"),
62255
- field_key: zod_default.string(),
62256
- operator: zod_default.enum([
62257
- "equals",
62258
- "not_equals",
62259
- "contains",
62260
- "does_not_contain",
62261
- "starts_with",
62262
- "ends_with",
62263
- "is_empty",
62264
- "is_not_empty",
62265
- "is_any_of",
62266
- "is_none_of"
62267
- ]),
62268
- value: zod_default.union([zod_default.string(), zod_default.array(zod_default.string())]).nullable()
62269
- });
62270
- var dateTimePointExactSchema = zod_default.object({
62271
- type: zod_default.literal("exact"),
62272
- date: zod_default.string().nullable().describe("ISO 8601 date (YYYY-MM-DD)"),
62273
- time: zod_default.string().nullable().optional().describe("Time HH:mm")
62274
- });
62275
- var timeUnitSchema = zod_default.enum(["minutes", "hours", "days", "weeks", "months", "years"]);
62276
- var dateTimePointRelativeSchema = zod_default.object({
62277
- type: zod_default.literal("relative"),
62278
- offset: zod_default.number().describe("Negative=past, positive=future"),
62279
- unit: timeUnitSchema,
62280
- time: zod_default.string().nullable().optional().describe("Fixed time HH:mm")
62281
- });
62282
- var dateTimePointPeriodSchema = zod_default.object({
62283
- type: zod_default.literal("period"),
62284
- period: zod_default.enum(["day", "week", "month", "quarter", "year"]),
62285
- boundary: zod_default.enum(["start", "end"]),
62286
- offset: zod_default.number().optional().describe("0=current, -1=last, 1=next"),
62287
- time: zod_default.string().nullable().optional().describe("Fixed time HH:mm")
62288
- });
62289
- var dateTimePointSchema = zod_default.discriminatedUnion("type", [
62290
- dateTimePointExactSchema,
62291
- dateTimePointRelativeSchema,
62292
- dateTimePointPeriodSchema
62293
- ]);
62294
- var betweenRangeValueSchema = zod_default.object({
62295
- start: dateTimePointSchema.nullable().describe("Null=no lower bound"),
62296
- end: dateTimePointSchema.nullable().describe("Null=no upper bound")
62297
- });
62298
- var timeOnlyValueSchema = zod_default.object({
62299
- start_time: zod_default.string().nullable().describe("HH:mm"),
62300
- end_time: zod_default.string().nullable().describe("HH:mm")
62301
- });
62302
- var durationValueSchema = zod_default.object({
62303
- amount: zod_default.number(),
62304
- unit: zod_default.enum(["minutes", "hours", "days"])
62305
- });
62306
- var tableRecordDateFieldFilterBaseSchema = zod_default.object({
62307
- type: zod_default.literal("date"),
62308
- field_key: zod_default.string()
62309
- });
62310
- var tableRecordDateFieldFilterEmptySchema = tableRecordDateFieldFilterBaseSchema.extend({
62311
- operator: zod_default.literal("is_empty"),
62312
- value: zod_default.null()
62313
- });
62314
- var tableRecordDateFieldFilterNotEmptySchema = tableRecordDateFieldFilterBaseSchema.extend({
62315
- operator: zod_default.literal("is_not_empty"),
62316
- value: zod_default.null()
62317
- });
62318
- var tableRecordDateFieldFilterBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
62319
- operator: zod_default.literal("before"),
62320
- value: dateTimePointSchema.nullable()
62321
- });
62322
- var tableRecordDateFieldFilterAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
62323
- operator: zod_default.literal("after"),
62324
- value: dateTimePointSchema.nullable()
62325
- });
62326
- var tableRecordDateFieldFilterOnOrBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
62327
- operator: zod_default.literal("on_or_before"),
62328
- value: dateTimePointSchema.nullable()
62329
- });
62330
- var tableRecordDateFieldFilterOnOrAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
62331
- operator: zod_default.literal("on_or_after"),
62332
- value: dateTimePointSchema.nullable()
62333
- });
62334
- var tableRecordDateFieldFilterOnSchema = tableRecordDateFieldFilterBaseSchema.extend({
62335
- operator: zod_default.literal("on"),
62336
- value: dateTimePointSchema.nullable()
62337
- });
62338
- var tableRecordDateFieldFilterBetweenSchema = tableRecordDateFieldFilterBaseSchema.extend({
62339
- operator: zod_default.literal("between"),
62340
- value: betweenRangeValueSchema.nullable()
62341
- });
62342
- var tableRecordDateFieldFilterTimeOfDaySchema = tableRecordDateFieldFilterBaseSchema.extend({
62343
- operator: zod_default.literal("time_of_day"),
62344
- value: timeOnlyValueSchema.nullable()
62345
- });
62346
- var tableRecordDateFieldFilterOverlapsSchema = tableRecordDateFieldFilterBaseSchema.extend({
62347
- operator: zod_default.literal("overlaps"),
62348
- value: betweenRangeValueSchema.nullable()
62349
- });
62350
- var tableRecordDateFieldFilterContainsSchema = tableRecordDateFieldFilterBaseSchema.extend({
62351
- operator: zod_default.literal("contains"),
62352
- value: betweenRangeValueSchema.nullable()
62353
- });
62354
- var tableRecordDateFieldFilterWithinSchema = tableRecordDateFieldFilterBaseSchema.extend({
62355
- operator: zod_default.literal("within"),
62356
- value: betweenRangeValueSchema.nullable()
62357
- });
62358
- var tableRecordDateFieldFilterStartsBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
62359
- operator: zod_default.literal("starts_before"),
62360
- value: dateTimePointSchema.nullable()
62361
- });
62362
- var tableRecordDateFieldFilterStartsAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
62363
- operator: zod_default.literal("starts_after"),
62364
- value: dateTimePointSchema.nullable()
62365
- });
62366
- var tableRecordDateFieldFilterEndsBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
62367
- operator: zod_default.literal("ends_before"),
62368
- value: dateTimePointSchema.nullable()
62369
- });
62370
- var tableRecordDateFieldFilterEndsAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
62371
- operator: zod_default.literal("ends_after"),
62372
- value: dateTimePointSchema.nullable()
62373
- });
62374
- var tableRecordDateFieldFilterDurationEqualsSchema = tableRecordDateFieldFilterBaseSchema.extend({
62375
- operator: zod_default.literal("duration_equals"),
62376
- value: durationValueSchema.nullable()
62377
- });
62378
- var tableRecordDateFieldFilterDurationGreaterThanSchema = tableRecordDateFieldFilterBaseSchema.extend({
62379
- operator: zod_default.literal("duration_greater_than"),
62380
- value: durationValueSchema.nullable()
62381
- });
62382
- var tableRecordDateFieldFilterDurationLessThanSchema = tableRecordDateFieldFilterBaseSchema.extend({
62383
- operator: zod_default.literal("duration_less_than"),
62384
- value: durationValueSchema.nullable()
62385
- });
62386
- var tableRecordDateFieldFilterSchema = zod_default.discriminatedUnion("operator", [
62387
- tableRecordDateFieldFilterEmptySchema,
62388
- tableRecordDateFieldFilterNotEmptySchema,
62389
- tableRecordDateFieldFilterBeforeSchema,
62390
- tableRecordDateFieldFilterAfterSchema,
62391
- tableRecordDateFieldFilterOnOrBeforeSchema,
62392
- tableRecordDateFieldFilterOnOrAfterSchema,
62393
- tableRecordDateFieldFilterOnSchema,
62394
- tableRecordDateFieldFilterBetweenSchema,
62395
- tableRecordDateFieldFilterTimeOfDaySchema,
62396
- tableRecordDateFieldFilterOverlapsSchema,
62397
- tableRecordDateFieldFilterContainsSchema,
62398
- tableRecordDateFieldFilterWithinSchema,
62399
- tableRecordDateFieldFilterStartsBeforeSchema,
62400
- tableRecordDateFieldFilterStartsAfterSchema,
62401
- tableRecordDateFieldFilterEndsBeforeSchema,
62402
- tableRecordDateFieldFilterEndsAfterSchema,
62403
- tableRecordDateFieldFilterDurationEqualsSchema,
62404
- tableRecordDateFieldFilterDurationGreaterThanSchema,
62405
- tableRecordDateFieldFilterDurationLessThanSchema
62406
- ]);
62407
- var tableRecordBooleanFieldFilterSchema = zod_default.object({
62408
- type: zod_default.literal("boolean"),
62409
- field_key: zod_default.string(),
62410
- operator: zod_default.enum(["equals"]),
62411
- value: zod_default.boolean().nullable()
62412
- });
62413
- var tableRecordSelectFieldFilterSchema = zod_default.object({
62414
- type: zod_default.literal("select"),
62415
- field_key: zod_default.string(),
62416
- operator: zod_default.enum([
62417
- "has_any_of",
62418
- "has_none_of",
62419
- "is_empty",
62420
- "is_not_empty",
62421
- "has_all_of"
62422
- ]),
62423
- value: zod_default.array(zod_default.string()).nullable()
62424
- });
62425
- var tableRecordSelectMemberFieldFilterSchema = zod_default.object({
62426
- type: zod_default.literal("select_member"),
62427
- field_key: zod_default.string(),
62428
- operator: zod_default.enum([
62429
- "has_any_of",
62430
- "has_none_of",
62431
- "is_empty",
62432
- "is_not_empty",
62433
- "has_all_of",
62434
- "is_current_member",
62435
- "is_not_current_member"
62436
- ]),
62437
- value: zod_default.array(zod_default.string()).nullable()
62438
- });
62439
- var tableRecordSelectRecordLinkFieldFilterSchema = zod_default.object({
62440
- type: zod_default.literal("select_record_link"),
62441
- field_key: zod_default.string(),
62442
- operator: zod_default.enum([
62443
- // Membership operators — match linked record IDs. value: string[].
62444
- "has_any_of",
62445
- "has_none_of",
62446
- "has_all_of",
62447
- // Text operators — match the cached display text. value: string.
62448
- "contains",
62449
- "not_contains",
62450
- "starts_with",
62451
- "ends_with",
62452
- "is_empty",
62453
- "is_not_empty"
62454
- ]),
62455
- value: zod_default.union([zod_default.string(), zod_default.array(zod_default.string())]).nullable()
62456
- });
62457
- var tableRecordFilesFieldFilterSchema = zod_default.object({
62458
- type: zod_default.literal("files"),
62459
- field_key: zod_default.string(),
62460
- operator: zod_default.enum(["has_filename", "has_mime_type", "has_file_count", "is_empty", "is_not_empty"]),
62461
- value: zod_default.string().nullable()
62462
- });
62463
- var tableRecordLockedFilterSchema = zod_default.object({
62464
- type: zod_default.literal("locked"),
62465
- operator: zod_default.enum(["is_locked", "is_not_locked"]),
62466
- value: zod_default.null()
62467
- });
62468
- var tableRecordCurrentMemberFilterSchema = zod_default.object({
62469
- type: zod_default.literal("current_member"),
62470
- operator: zod_default.enum(["in_any_group"]),
62471
- value: zod_default.array(zod_default.string())
62472
- });
62473
- var tableRecordRecordIdFilterSchema = zod_default.object({
62474
- type: zod_default.literal("record_id"),
62475
- operator: zod_default.enum(["is_any_of", "is_none_of"]),
62476
- value: zod_default.array(zod_default.string())
62477
- });
62478
- var tableRecordFieldFilterConditionSchema = zod_default.union([
62479
- tableRecordTextFieldFilterSchema,
62480
- tableRecordNumberFieldFilterSchema,
62481
- tableRecordDateFieldFilterSchema,
62482
- tableRecordBooleanFieldFilterSchema,
62483
- tableRecordSelectMemberFieldFilterSchema,
62484
- tableRecordSelectFieldFilterSchema,
62485
- tableRecordSelectRecordLinkFieldFilterSchema,
62486
- tableRecordFilesFieldFilterSchema
62487
- ]);
62488
- var tableRecordFiltersConditionNodeSchema = zod_default.object({
62489
- node_type: zod_default.literal("condition"),
62490
- field_key: zod_default.string().optional(),
62491
- type: zod_default.string().optional(),
62492
- operator: zod_default.string(),
62493
- value: zod_default.unknown().optional()
62494
- });
62495
- var tableRecordFiltersTraversalNodeSchema = zod_default.object({
62496
- node_type: zod_default.literal("traversal"),
62497
- path: zod_default.array(zod_default.string()),
62498
- condition: tableRecordFiltersConditionNodeSchema
62499
- });
62500
- var tableRecordFiltersGroupNodeSchema = zod_default.lazy(
62501
- () => zod_default.object({
62502
- node_type: zod_default.literal("group"),
62503
- logic: zod_default.enum(["and", "or"]),
62504
- children: zod_default.array(
62505
- zod_default.union([
62506
- tableRecordFiltersConditionNodeSchema,
62507
- tableRecordFiltersTraversalNodeSchema,
62508
- tableRecordFiltersGroupNodeSchema
62509
- ])
62510
- )
62511
- })
62512
- );
62513
- var tableRecordFiltersSchema = zod_default.union([
62514
- tableRecordFiltersConditionNodeSchema,
62515
- tableRecordFiltersTraversalNodeSchema,
62516
- tableRecordFiltersGroupNodeSchema
62517
- ]);
62518
- var optionColorSchema = zod_default.enum([
62519
- "red",
62520
- "orange",
62521
- "amber",
62522
- "yellow",
62523
- "lime",
62524
- "green",
62525
- "emerald",
62526
- "teal",
62527
- "cyan",
62528
- "sky",
62529
- "blue",
62530
- "indigo",
62531
- "violet",
62532
- "purple",
62533
- "fuchsia",
62534
- "pink",
62535
- "rose",
62536
- "slate",
62537
- "gray",
62538
- "zinc",
62539
- "neutral",
62540
- "stone"
62541
- ]);
62542
- var tableRecordColorSchema = zod_default.object({
62543
- filters: tableRecordFiltersGroupNodeSchema.nullable().describe(
62544
- "The filter conditions that determine when this color rule applies. Null means no filtering."
62545
- ),
62546
- color: optionColorSchema.describe(
62547
- "The color to apply to records matching the filters."
62548
- )
62549
- });
62550
- var tableRecordColorsSchema = zod_default.array(tableRecordColorSchema);
62551
- var tableRecordSortSchema = zod_default.array(
62552
- zod_default.object({
62553
- field_key: zod_default.string().describe("Field key to sort by"),
62554
- order: zod_default.enum(["asc", "desc"]).nullable().describe("Sort order: 'asc' for ascending, 'desc' for descending"),
62555
- blank_position: zod_default.enum(["top", "bottom"]).optional().describe("Blank position: 'top' for top, 'bottom' for bottom")
62556
- })
62557
- );
62558
- var TEXT_OPS = tableRecordTextFieldFilterSchema.shape.operator.options;
62559
- var NUMBER_OPS = tableRecordNumberFieldFilterSchema.shape.operator.options;
62560
- var DATE_OPS = tableRecordDateFieldFilterSchema.options.map((s) => s.shape.operator.value);
62561
- var BOOLEAN_OPS = tableRecordBooleanFieldFilterSchema.shape.operator.options;
62562
- var SELECT_OPS = tableRecordSelectFieldFilterSchema.shape.operator.options;
62563
- var SELECT_MEMBER_OPS = tableRecordSelectMemberFieldFilterSchema.shape.operator.options;
62564
- var SELECT_RECORD_LINK_OPS = tableRecordSelectRecordLinkFieldFilterSchema.shape.operator.options;
62565
- var FILES_OPS = tableRecordFilesFieldFilterSchema.shape.operator.options;
62566
- var LOCKED_OPS = tableRecordLockedFilterSchema.shape.operator.options;
62567
- var CURRENT_MEMBER_OPS = tableRecordCurrentMemberFilterSchema.shape.operator.options;
62568
- var RECORD_ID_OPS = tableRecordRecordIdFilterSchema.shape.operator.options;
62569
- var VALID_OPERATORS = {
62570
- text: TEXT_OPS,
62571
- number: NUMBER_OPS,
62572
- date: DATE_OPS,
62573
- boolean: BOOLEAN_OPS,
62574
- select: SELECT_OPS,
62575
- select_member: SELECT_MEMBER_OPS,
62576
- select_record_link: SELECT_RECORD_LINK_OPS,
62577
- files: FILES_OPS,
62578
- locked: LOCKED_OPS,
62579
- current_member: CURRENT_MEMBER_OPS,
62580
- record_id: RECORD_ID_OPS
62581
- };
62582
- var VALID_FILTER_TYPES = Object.keys(VALID_OPERATORS);
62583
-
62584
62237
  // ../../node_modules/date-fns/constants.js
62585
62238
  var daysInYear = 365.2425;
62586
62239
  var maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1e3;
@@ -64461,6 +64114,353 @@ for (const [operation, fieldTypes] of Object.entries(OPERATION_FIELD_TYPES)) {
64461
64114
  }
64462
64115
  var AGGREGATABLE_FIELD_TYPES = new Set(FIELD_TYPE_OPERATIONS.keys());
64463
64116
 
64117
+ // ../shared/src/schemas/table_filters.ts
64118
+ var tableRecordNumberFieldFilterSchema = zod_default.object({
64119
+ type: zod_default.literal("number"),
64120
+ field_key: zod_default.string(),
64121
+ operator: zod_default.enum([
64122
+ "equals",
64123
+ "not_equals",
64124
+ "greater_than",
64125
+ "less_than",
64126
+ "greater_than_or_equal_to",
64127
+ "less_than_or_equal_to",
64128
+ "is_empty",
64129
+ "is_not_empty"
64130
+ ]),
64131
+ value: zod_default.number().nullable()
64132
+ });
64133
+ var tableRecordTextFieldFilterSchema = zod_default.object({
64134
+ type: zod_default.literal("text"),
64135
+ field_key: zod_default.string(),
64136
+ operator: zod_default.enum([
64137
+ "equals",
64138
+ "not_equals",
64139
+ "contains",
64140
+ "does_not_contain",
64141
+ "starts_with",
64142
+ "ends_with",
64143
+ "is_empty",
64144
+ "is_not_empty",
64145
+ "is_any_of",
64146
+ "is_none_of"
64147
+ ]),
64148
+ value: zod_default.union([zod_default.string(), zod_default.array(zod_default.string())]).nullable()
64149
+ });
64150
+ var dateTimePointExactSchema = zod_default.object({
64151
+ type: zod_default.literal("exact"),
64152
+ date: zod_default.string().nullable().describe("ISO 8601 date (YYYY-MM-DD)"),
64153
+ time: zod_default.string().nullable().optional().describe("Time HH:mm")
64154
+ });
64155
+ var timeUnitSchema = zod_default.enum(["minutes", "hours", "days", "weeks", "months", "years"]);
64156
+ var dateTimePointRelativeSchema = zod_default.object({
64157
+ type: zod_default.literal("relative"),
64158
+ offset: zod_default.number().describe("Negative=past, positive=future"),
64159
+ unit: timeUnitSchema,
64160
+ time: zod_default.string().nullable().optional().describe("Fixed time HH:mm")
64161
+ });
64162
+ var dateTimePointPeriodSchema = zod_default.object({
64163
+ type: zod_default.literal("period"),
64164
+ period: zod_default.enum(["day", "week", "month", "quarter", "year"]),
64165
+ boundary: zod_default.enum(["start", "end"]),
64166
+ offset: zod_default.number().optional().describe("0=current, -1=last, 1=next"),
64167
+ time: zod_default.string().nullable().optional().describe("Fixed time HH:mm")
64168
+ });
64169
+ var dateTimePointSchema = zod_default.discriminatedUnion("type", [
64170
+ dateTimePointExactSchema,
64171
+ dateTimePointRelativeSchema,
64172
+ dateTimePointPeriodSchema
64173
+ ]);
64174
+ var betweenRangeValueSchema = zod_default.object({
64175
+ start: dateTimePointSchema.nullable().describe("Null=no lower bound"),
64176
+ end: dateTimePointSchema.nullable().describe("Null=no upper bound")
64177
+ });
64178
+ var timeOnlyValueSchema = zod_default.object({
64179
+ start_time: zod_default.string().nullable().describe("HH:mm"),
64180
+ end_time: zod_default.string().nullable().describe("HH:mm")
64181
+ });
64182
+ var durationValueSchema = zod_default.object({
64183
+ amount: zod_default.number(),
64184
+ unit: zod_default.enum(["minutes", "hours", "days"])
64185
+ });
64186
+ var tableRecordDateFieldFilterBaseSchema = zod_default.object({
64187
+ type: zod_default.literal("date"),
64188
+ field_key: zod_default.string()
64189
+ });
64190
+ var tableRecordDateFieldFilterEmptySchema = tableRecordDateFieldFilterBaseSchema.extend({
64191
+ operator: zod_default.literal("is_empty"),
64192
+ value: zod_default.null()
64193
+ });
64194
+ var tableRecordDateFieldFilterNotEmptySchema = tableRecordDateFieldFilterBaseSchema.extend({
64195
+ operator: zod_default.literal("is_not_empty"),
64196
+ value: zod_default.null()
64197
+ });
64198
+ var tableRecordDateFieldFilterBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
64199
+ operator: zod_default.literal("before"),
64200
+ value: dateTimePointSchema.nullable()
64201
+ });
64202
+ var tableRecordDateFieldFilterAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
64203
+ operator: zod_default.literal("after"),
64204
+ value: dateTimePointSchema.nullable()
64205
+ });
64206
+ var tableRecordDateFieldFilterOnOrBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
64207
+ operator: zod_default.literal("on_or_before"),
64208
+ value: dateTimePointSchema.nullable()
64209
+ });
64210
+ var tableRecordDateFieldFilterOnOrAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
64211
+ operator: zod_default.literal("on_or_after"),
64212
+ value: dateTimePointSchema.nullable()
64213
+ });
64214
+ var tableRecordDateFieldFilterOnSchema = tableRecordDateFieldFilterBaseSchema.extend({
64215
+ operator: zod_default.literal("on"),
64216
+ value: dateTimePointSchema.nullable()
64217
+ });
64218
+ var tableRecordDateFieldFilterBetweenSchema = tableRecordDateFieldFilterBaseSchema.extend({
64219
+ operator: zod_default.literal("between"),
64220
+ value: betweenRangeValueSchema.nullable()
64221
+ });
64222
+ var tableRecordDateFieldFilterTimeOfDaySchema = tableRecordDateFieldFilterBaseSchema.extend({
64223
+ operator: zod_default.literal("time_of_day"),
64224
+ value: timeOnlyValueSchema.nullable()
64225
+ });
64226
+ var tableRecordDateFieldFilterOverlapsSchema = tableRecordDateFieldFilterBaseSchema.extend({
64227
+ operator: zod_default.literal("overlaps"),
64228
+ value: betweenRangeValueSchema.nullable()
64229
+ });
64230
+ var tableRecordDateFieldFilterContainsSchema = tableRecordDateFieldFilterBaseSchema.extend({
64231
+ operator: zod_default.literal("contains"),
64232
+ value: betweenRangeValueSchema.nullable()
64233
+ });
64234
+ var tableRecordDateFieldFilterWithinSchema = tableRecordDateFieldFilterBaseSchema.extend({
64235
+ operator: zod_default.literal("within"),
64236
+ value: betweenRangeValueSchema.nullable()
64237
+ });
64238
+ var tableRecordDateFieldFilterStartsBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
64239
+ operator: zod_default.literal("starts_before"),
64240
+ value: dateTimePointSchema.nullable()
64241
+ });
64242
+ var tableRecordDateFieldFilterStartsAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
64243
+ operator: zod_default.literal("starts_after"),
64244
+ value: dateTimePointSchema.nullable()
64245
+ });
64246
+ var tableRecordDateFieldFilterEndsBeforeSchema = tableRecordDateFieldFilterBaseSchema.extend({
64247
+ operator: zod_default.literal("ends_before"),
64248
+ value: dateTimePointSchema.nullable()
64249
+ });
64250
+ var tableRecordDateFieldFilterEndsAfterSchema = tableRecordDateFieldFilterBaseSchema.extend({
64251
+ operator: zod_default.literal("ends_after"),
64252
+ value: dateTimePointSchema.nullable()
64253
+ });
64254
+ var tableRecordDateFieldFilterDurationEqualsSchema = tableRecordDateFieldFilterBaseSchema.extend({
64255
+ operator: zod_default.literal("duration_equals"),
64256
+ value: durationValueSchema.nullable()
64257
+ });
64258
+ var tableRecordDateFieldFilterDurationGreaterThanSchema = tableRecordDateFieldFilterBaseSchema.extend({
64259
+ operator: zod_default.literal("duration_greater_than"),
64260
+ value: durationValueSchema.nullable()
64261
+ });
64262
+ var tableRecordDateFieldFilterDurationLessThanSchema = tableRecordDateFieldFilterBaseSchema.extend({
64263
+ operator: zod_default.literal("duration_less_than"),
64264
+ value: durationValueSchema.nullable()
64265
+ });
64266
+ var tableRecordDateFieldFilterSchema = zod_default.discriminatedUnion("operator", [
64267
+ tableRecordDateFieldFilterEmptySchema,
64268
+ tableRecordDateFieldFilterNotEmptySchema,
64269
+ tableRecordDateFieldFilterBeforeSchema,
64270
+ tableRecordDateFieldFilterAfterSchema,
64271
+ tableRecordDateFieldFilterOnOrBeforeSchema,
64272
+ tableRecordDateFieldFilterOnOrAfterSchema,
64273
+ tableRecordDateFieldFilterOnSchema,
64274
+ tableRecordDateFieldFilterBetweenSchema,
64275
+ tableRecordDateFieldFilterTimeOfDaySchema,
64276
+ tableRecordDateFieldFilterOverlapsSchema,
64277
+ tableRecordDateFieldFilterContainsSchema,
64278
+ tableRecordDateFieldFilterWithinSchema,
64279
+ tableRecordDateFieldFilterStartsBeforeSchema,
64280
+ tableRecordDateFieldFilterStartsAfterSchema,
64281
+ tableRecordDateFieldFilterEndsBeforeSchema,
64282
+ tableRecordDateFieldFilterEndsAfterSchema,
64283
+ tableRecordDateFieldFilterDurationEqualsSchema,
64284
+ tableRecordDateFieldFilterDurationGreaterThanSchema,
64285
+ tableRecordDateFieldFilterDurationLessThanSchema
64286
+ ]);
64287
+ var tableRecordBooleanFieldFilterSchema = zod_default.object({
64288
+ type: zod_default.literal("boolean"),
64289
+ field_key: zod_default.string(),
64290
+ operator: zod_default.enum(["equals"]),
64291
+ value: zod_default.boolean().nullable()
64292
+ });
64293
+ var tableRecordSelectFieldFilterSchema = zod_default.object({
64294
+ type: zod_default.literal("select"),
64295
+ field_key: zod_default.string(),
64296
+ operator: zod_default.enum([
64297
+ "has_any_of",
64298
+ "has_none_of",
64299
+ "is_empty",
64300
+ "is_not_empty",
64301
+ "has_all_of"
64302
+ ]),
64303
+ value: zod_default.array(zod_default.string()).nullable()
64304
+ });
64305
+ var tableRecordSelectMemberFieldFilterSchema = zod_default.object({
64306
+ type: zod_default.literal("select_member"),
64307
+ field_key: zod_default.string(),
64308
+ operator: zod_default.enum([
64309
+ "has_any_of",
64310
+ "has_none_of",
64311
+ "is_empty",
64312
+ "is_not_empty",
64313
+ "has_all_of",
64314
+ "is_current_member",
64315
+ "is_not_current_member"
64316
+ ]),
64317
+ value: zod_default.array(zod_default.string()).nullable()
64318
+ });
64319
+ var tableRecordSelectRecordLinkFieldFilterSchema = zod_default.object({
64320
+ type: zod_default.literal("select_record_link"),
64321
+ field_key: zod_default.string(),
64322
+ operator: zod_default.enum([
64323
+ // Membership operators — match linked record IDs. value: string[].
64324
+ "has_any_of",
64325
+ "has_none_of",
64326
+ "has_all_of",
64327
+ // Text operators — match the cached display text. value: string.
64328
+ "contains",
64329
+ "not_contains",
64330
+ "starts_with",
64331
+ "ends_with",
64332
+ "is_empty",
64333
+ "is_not_empty"
64334
+ ]),
64335
+ value: zod_default.union([zod_default.string(), zod_default.array(zod_default.string())]).nullable()
64336
+ });
64337
+ var tableRecordFilesFieldFilterSchema = zod_default.object({
64338
+ type: zod_default.literal("files"),
64339
+ field_key: zod_default.string(),
64340
+ operator: zod_default.enum(["has_filename", "has_mime_type", "has_file_count", "is_empty", "is_not_empty"]),
64341
+ value: zod_default.string().nullable()
64342
+ });
64343
+ var tableRecordLockedFilterSchema = zod_default.object({
64344
+ type: zod_default.literal("locked"),
64345
+ operator: zod_default.enum(["is_locked", "is_not_locked"]),
64346
+ value: zod_default.null()
64347
+ });
64348
+ var tableRecordCurrentMemberFilterSchema = zod_default.object({
64349
+ type: zod_default.literal("current_member"),
64350
+ operator: zod_default.enum(["in_any_group"]),
64351
+ value: zod_default.array(zod_default.string())
64352
+ });
64353
+ var tableRecordRecordIdFilterSchema = zod_default.object({
64354
+ type: zod_default.literal("record_id"),
64355
+ operator: zod_default.enum(["is_any_of", "is_none_of"]),
64356
+ value: zod_default.array(zod_default.string())
64357
+ });
64358
+ var tableRecordFieldFilterConditionSchema = zod_default.union([
64359
+ tableRecordTextFieldFilterSchema,
64360
+ tableRecordNumberFieldFilterSchema,
64361
+ tableRecordDateFieldFilterSchema,
64362
+ tableRecordBooleanFieldFilterSchema,
64363
+ tableRecordSelectMemberFieldFilterSchema,
64364
+ tableRecordSelectFieldFilterSchema,
64365
+ tableRecordSelectRecordLinkFieldFilterSchema,
64366
+ tableRecordFilesFieldFilterSchema
64367
+ ]);
64368
+ var tableRecordFiltersConditionNodeSchema = zod_default.object({
64369
+ node_type: zod_default.literal("condition"),
64370
+ field_key: zod_default.string().optional(),
64371
+ type: zod_default.string().optional(),
64372
+ operator: zod_default.string(),
64373
+ value: zod_default.unknown().optional()
64374
+ });
64375
+ var tableRecordFiltersTraversalNodeSchema = zod_default.object({
64376
+ node_type: zod_default.literal("traversal"),
64377
+ path: zod_default.array(zod_default.string()),
64378
+ condition: tableRecordFiltersConditionNodeSchema
64379
+ });
64380
+ var tableRecordFiltersGroupNodeSchema = zod_default.lazy(
64381
+ () => zod_default.object({
64382
+ node_type: zod_default.literal("group"),
64383
+ logic: zod_default.enum(["and", "or"]),
64384
+ children: zod_default.array(
64385
+ zod_default.union([
64386
+ tableRecordFiltersConditionNodeSchema,
64387
+ tableRecordFiltersTraversalNodeSchema,
64388
+ tableRecordFiltersGroupNodeSchema
64389
+ ])
64390
+ )
64391
+ })
64392
+ );
64393
+ var tableRecordFiltersSchema = zod_default.union([
64394
+ tableRecordFiltersConditionNodeSchema,
64395
+ tableRecordFiltersTraversalNodeSchema,
64396
+ tableRecordFiltersGroupNodeSchema
64397
+ ]);
64398
+ var optionColorSchema = zod_default.enum([
64399
+ "red",
64400
+ "orange",
64401
+ "amber",
64402
+ "yellow",
64403
+ "lime",
64404
+ "green",
64405
+ "emerald",
64406
+ "teal",
64407
+ "cyan",
64408
+ "sky",
64409
+ "blue",
64410
+ "indigo",
64411
+ "violet",
64412
+ "purple",
64413
+ "fuchsia",
64414
+ "pink",
64415
+ "rose",
64416
+ "slate",
64417
+ "gray",
64418
+ "zinc",
64419
+ "neutral",
64420
+ "stone"
64421
+ ]);
64422
+ var tableRecordColorSchema = zod_default.object({
64423
+ filters: tableRecordFiltersGroupNodeSchema.nullable().describe(
64424
+ "The filter conditions that determine when this color rule applies. Null means no filtering."
64425
+ ),
64426
+ color: optionColorSchema.describe(
64427
+ "The color to apply to records matching the filters."
64428
+ )
64429
+ });
64430
+ var tableRecordColorsSchema = zod_default.array(tableRecordColorSchema);
64431
+ var tableRecordSortSchema = zod_default.array(
64432
+ zod_default.object({
64433
+ field_key: zod_default.string().describe("Field key to sort by"),
64434
+ order: zod_default.enum(["asc", "desc"]).nullable().describe("Sort order: 'asc' for ascending, 'desc' for descending"),
64435
+ blank_position: zod_default.enum(["top", "bottom"]).optional().describe("Blank position: 'top' for top, 'bottom' for bottom")
64436
+ })
64437
+ );
64438
+ var TEXT_OPS = tableRecordTextFieldFilterSchema.shape.operator.options;
64439
+ var NUMBER_OPS = tableRecordNumberFieldFilterSchema.shape.operator.options;
64440
+ var DATE_OPS = tableRecordDateFieldFilterSchema.options.map((s) => s.shape.operator.value);
64441
+ var BOOLEAN_OPS = tableRecordBooleanFieldFilterSchema.shape.operator.options;
64442
+ var SELECT_OPS = tableRecordSelectFieldFilterSchema.shape.operator.options;
64443
+ var SELECT_MEMBER_OPS = tableRecordSelectMemberFieldFilterSchema.shape.operator.options;
64444
+ var SELECT_RECORD_LINK_OPS = tableRecordSelectRecordLinkFieldFilterSchema.shape.operator.options;
64445
+ var FILES_OPS = tableRecordFilesFieldFilterSchema.shape.operator.options;
64446
+ var LOCKED_OPS = tableRecordLockedFilterSchema.shape.operator.options;
64447
+ var CURRENT_MEMBER_OPS = tableRecordCurrentMemberFilterSchema.shape.operator.options;
64448
+ var RECORD_ID_OPS = tableRecordRecordIdFilterSchema.shape.operator.options;
64449
+ var VALID_OPERATORS = {
64450
+ text: TEXT_OPS,
64451
+ number: NUMBER_OPS,
64452
+ date: DATE_OPS,
64453
+ boolean: BOOLEAN_OPS,
64454
+ select: SELECT_OPS,
64455
+ select_member: SELECT_MEMBER_OPS,
64456
+ select_record_link: SELECT_RECORD_LINK_OPS,
64457
+ files: FILES_OPS,
64458
+ locked: LOCKED_OPS,
64459
+ current_member: CURRENT_MEMBER_OPS,
64460
+ record_id: RECORD_ID_OPS
64461
+ };
64462
+ var VALID_FILTER_TYPES = Object.keys(VALID_OPERATORS);
64463
+
64464
64464
  // ../shared/src/chat_models.ts
64465
64465
  var CHAT_MODEL_IDS = ["claude-haiku-4-5", "claude-sonnet-5", "claude-opus-5"];
64466
64466
  var LEGACY_CHAT_MODEL_IDS = [];
@@ -77943,6 +77943,59 @@ function hueToRgb(p, q, t) {
77943
77943
  return p;
77944
77944
  }
77945
77945
 
77946
+ // ../xlsx/src/excel_utils.ts
77947
+ function colLettersToNum(letters) {
77948
+ let result = 0;
77949
+ for (let i2 = 0; i2 < letters.length; i2++) {
77950
+ result = result * 26 + (letters.charCodeAt(i2) - 64);
77951
+ }
77952
+ return result;
77953
+ }
77954
+ function colNumToLetters(col) {
77955
+ let result = "";
77956
+ let n = col;
77957
+ while (n > 0) {
77958
+ n--;
77959
+ result = String.fromCharCode(65 + n % 26) + result;
77960
+ n = Math.floor(n / 26);
77961
+ }
77962
+ return result;
77963
+ }
77964
+ function refToRowCol(ref2) {
77965
+ const match2 = ref2.match(/^(\$?)([A-Z]+)(\$?)(\d+)$/);
77966
+ if (!match2) return void 0;
77967
+ return { col: colLettersToNum(match2[2]), row: parseInt(match2[4], 10) };
77968
+ }
77969
+ function rowColToRef(row, col) {
77970
+ return colNumToLetters(col) + String(row);
77971
+ }
77972
+ function escapeXml(s) {
77973
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
77974
+ }
77975
+ var PACK_COL_BITS = 14;
77976
+ var PACK_COL_MULT = 1 << PACK_COL_BITS;
77977
+ function packRowCol(row, col) {
77978
+ return row * PACK_COL_MULT + col;
77979
+ }
77980
+ function unpackRowCol(packed) {
77981
+ const row = Math.floor(packed / PACK_COL_MULT);
77982
+ const col = packed - row * PACK_COL_MULT;
77983
+ return { row, col };
77984
+ }
77985
+ function packRef(ref2) {
77986
+ const rc = refToRowCol(ref2);
77987
+ if (!rc) return -1;
77988
+ return packRowCol(rc.row, rc.col);
77989
+ }
77990
+ function unpackRef(packed) {
77991
+ const { row, col } = unpackRowCol(packed);
77992
+ return rowColToRef(row, col);
77993
+ }
77994
+ function stripNsPrefix(tag) {
77995
+ const colon = tag.indexOf(":");
77996
+ return colon === -1 ? tag : tag.slice(colon + 1);
77997
+ }
77998
+
77946
77999
  // ../xlsx/src/excel_pattern_fills.ts
77947
78000
  var PATTERNS = {
77948
78001
  darkVertical: (fg, bg) => `repeating-linear-gradient(90deg, ${fg} 0px, ${fg} 1px, ${bg} 1px, ${bg} 4px)`,
@@ -78010,6 +78063,10 @@ var BUILTIN_NUM_FMTS = {
78010
78063
  var xmlParser2 = new XMLParser({
78011
78064
  ignoreAttributes: false,
78012
78065
  attributeNamePrefix: "@_",
78066
+ // A producer may bind spreadsheetml to a prefix (`<x:styleSheet>`) rather than
78067
+ // making it the default namespace; the prefix carries no meaning, so it is
78068
+ // dropped before anything looks a tag up — see `stripNsPrefix`.
78069
+ transformTagName: stripNsPrefix,
78013
78070
  processEntities: false,
78014
78071
  isArray: (tagName) => tagName === "numFmt" || tagName === "font" || tagName === "fill" || tagName === "border" || tagName === "xf" || tagName === "rgbColor" || tagName === "stop"
78015
78072
  });
@@ -78339,10 +78396,24 @@ function emptyStyleResolver() {
78339
78396
  };
78340
78397
  }
78341
78398
 
78399
+ // ../xlsx/src/malformed_part_error.ts
78400
+ var MalformedPartError = class extends Error {
78401
+ constructor(reason) {
78402
+ super(
78403
+ `${reason} \u2014 the file is not a readable spreadsheet. If it opens in Excel, the reader is at fault: report the producer that wrote it.`
78404
+ );
78405
+ this.name = "MalformedPartError";
78406
+ }
78407
+ };
78408
+
78342
78409
  // ../xlsx/src/ooxml_workbook.ts
78343
78410
  var xmlParser3 = new XMLParser({
78344
78411
  ignoreAttributes: false,
78345
78412
  attributeNamePrefix: "@_",
78413
+ // A producer may bind spreadsheetml to a prefix (`<x:workbook>`) rather than
78414
+ // making it the default namespace; the prefix carries no meaning, so it is
78415
+ // dropped before anything looks a tag up — see `stripNsPrefix`.
78416
+ transformTagName: stripNsPrefix,
78346
78417
  // Shared-string and workbook text is textual BY DEFINITION (tax IDs, phone
78347
78418
  // numbers, account codes, sheet/defined names). fast-xml-parser's default tag
78348
78419
  // coercion would parse `<t>0312345678</t>` as the number 312345678 — silently
@@ -78356,7 +78427,7 @@ var xmlParser3 = new XMLParser({
78356
78427
  function parseWorkbook(workbookXml) {
78357
78428
  const doc = xmlParser3.parse(workbookXml);
78358
78429
  const wb = doc?.["workbook"];
78359
- if (!wb) return { sheets: [], activeSheetIndex: 0, date1904: false, namedRanges: /* @__PURE__ */ new Map(), printTitlesBySheet: /* @__PURE__ */ new Map(), fullCalcOnLoad: false };
78430
+ if (!wb) throw new MalformedPartError("xl/workbook.xml has no <workbook> root");
78360
78431
  const sheetsEl = wb["sheets"];
78361
78432
  const sheetArr = sheetsEl?.["sheet"];
78362
78433
  const sheets = (sheetArr ?? []).map((s) => ({
@@ -79414,55 +79485,6 @@ function buildCellContent(displayValue, sharedString, hyperlink) {
79414
79485
  return { type: "plain", text: displayValue };
79415
79486
  }
79416
79487
 
79417
- // ../xlsx/src/excel_utils.ts
79418
- function colLettersToNum(letters) {
79419
- let result = 0;
79420
- for (let i2 = 0; i2 < letters.length; i2++) {
79421
- result = result * 26 + (letters.charCodeAt(i2) - 64);
79422
- }
79423
- return result;
79424
- }
79425
- function colNumToLetters(col) {
79426
- let result = "";
79427
- let n = col;
79428
- while (n > 0) {
79429
- n--;
79430
- result = String.fromCharCode(65 + n % 26) + result;
79431
- n = Math.floor(n / 26);
79432
- }
79433
- return result;
79434
- }
79435
- function refToRowCol(ref2) {
79436
- const match2 = ref2.match(/^(\$?)([A-Z]+)(\$?)(\d+)$/);
79437
- if (!match2) return void 0;
79438
- return { col: colLettersToNum(match2[2]), row: parseInt(match2[4], 10) };
79439
- }
79440
- function rowColToRef(row, col) {
79441
- return colNumToLetters(col) + String(row);
79442
- }
79443
- function escapeXml(s) {
79444
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
79445
- }
79446
- var PACK_COL_BITS = 14;
79447
- var PACK_COL_MULT = 1 << PACK_COL_BITS;
79448
- function packRowCol(row, col) {
79449
- return row * PACK_COL_MULT + col;
79450
- }
79451
- function unpackRowCol(packed) {
79452
- const row = Math.floor(packed / PACK_COL_MULT);
79453
- const col = packed - row * PACK_COL_MULT;
79454
- return { row, col };
79455
- }
79456
- function packRef(ref2) {
79457
- const rc = refToRowCol(ref2);
79458
- if (!rc) return -1;
79459
- return packRowCol(rc.row, rc.col);
79460
- }
79461
- function unpackRef(packed) {
79462
- const { row, col } = unpackRowCol(packed);
79463
- return rowColToRef(row, col);
79464
- }
79465
-
79466
79488
  // ../xlsx/src/ooxml_sheet.ts
79467
79489
  var MAX_ROWS_PER_SHEET = 1e4;
79468
79490
  var MAX_IMAGES = 50;
@@ -79478,7 +79500,11 @@ var xmlParser4 = new XMLParser({
79478
79500
  ignoreAttributes: false,
79479
79501
  attributeNamePrefix: "@_",
79480
79502
  processEntities: false,
79481
- isArray: (tagName) => tagName === "row" || tagName === "c" || tagName === "col" || tagName === "mergeCell" || tagName === "conditionalFormatting" || tagName === "cfRule" || tagName === "cfvo" || tagName === "color" || tagName === "hyperlink" || tagName === "Relationship" || tagName === "sheetView" || tagName === "xdr:twoCellAnchor" || tagName === "xdr:oneCellAnchor" || tagName === "dataValidation" || tagName === "filterColumn" || tagName === "filter" || tagName === "brk" || tagName === "ext",
79503
+ // A producer may bind spreadsheetml to a prefix (`<x:worksheet>`) instead of
79504
+ // making it the default namespace. The prefix carries no meaning, so it is
79505
+ // dropped before anything looks a tag up — see `stripNsPrefix`.
79506
+ transformTagName: stripNsPrefix,
79507
+ isArray: (tagName) => tagName === "row" || tagName === "c" || tagName === "col" || tagName === "mergeCell" || tagName === "conditionalFormatting" || tagName === "cfRule" || tagName === "cfvo" || tagName === "color" || tagName === "hyperlink" || tagName === "Relationship" || tagName === "sheetView" || tagName === "dataValidation" || tagName === "filterColumn" || tagName === "filter" || tagName === "brk" || tagName === "ext",
79482
79508
  // Preserve whitespace in cell values
79483
79509
  trimValues: false
79484
79510
  });
@@ -79497,7 +79523,7 @@ var drawingParser = new XMLParser({
79497
79523
  function parseSheet(sheetXml, sheetRelsXml, styles, sharedStrings, theme, indexedColors, zipEntries, date1904, maxRows = MAX_ROWS_PER_SHEET) {
79498
79524
  const doc = xmlParser4.parse(sheetXml);
79499
79525
  const worksheet = doc?.["worksheet"];
79500
- if (!worksheet) return emptySheet("Sheet");
79526
+ if (!worksheet) throw new MalformedPartError("A worksheet part has no <worksheet> root");
79501
79527
  const rels = sheetRelsXml ? parseSheetRels(sheetRelsXml) : /* @__PURE__ */ new Map();
79502
79528
  const sheetFormatPr = worksheet["sheetFormatPr"];
79503
79529
  const defaultRowHeight = sheetFormatPr?.["@_defaultRowHeight"] ? parseFloat(sheetFormatPr["@_defaultRowHeight"]) : 15;
@@ -81747,9 +81773,7 @@ function parseExcelFromZip(zip, options) {
81747
81773
  const stylesEntry = findEntry(zip, "xl/styles.xml");
81748
81774
  const styles = stylesEntry ? parseStyles(decodeUtf8(stylesEntry), theme) : emptyStyleResolver();
81749
81775
  const wbEntry = findEntry(zip, "xl/workbook.xml");
81750
- if (!wbEntry) {
81751
- return { sheets: [emptySheet("Sheet1")], activeSheetIndex: 0 };
81752
- }
81776
+ if (!wbEntry) throw new MalformedPartError("The package has no xl/workbook.xml");
81753
81777
  const workbookInfo = parseWorkbook(decodeUtf8(wbEntry));
81754
81778
  const wbRelsEntry = findEntry(zip, "xl/_rels/workbook.xml.rels");
81755
81779
  const wbRels = wbRelsEntry ? parseWorkbookRels(decodeUtf8(wbRelsEntry)) : /* @__PURE__ */ new Map();
@@ -81763,22 +81787,20 @@ function parseExcelFromZip(zip, options) {
81763
81787
  });
81764
81788
  const parseXmlDoc = (xml) => xmlParser5.parse(xml);
81765
81789
  const pivotCaches = /* @__PURE__ */ new Map();
81766
- if (wbEntry) {
81767
- const wbDoc = parseXmlDoc(decodeUtf8(wbEntry));
81768
- const wbCacheMap = extractWorkbookPivotCaches(wbDoc);
81769
- for (const [cacheId, rId] of wbCacheMap) {
81770
- const cacheTarget = wbRels.get(rId);
81771
- if (!cacheTarget) continue;
81772
- const cachePath = cacheTarget.startsWith("/") ? cacheTarget.slice(1) : `xl/${cacheTarget}`;
81773
- const cacheEntry = findEntry(zip, cachePath);
81774
- if (!cacheEntry) continue;
81775
- try {
81776
- pivotCaches.set(
81777
- cacheId,
81778
- parsePivotCacheDefinitionXml(decodeUtf8(cacheEntry), cacheId, parseXmlDoc)
81779
- );
81780
- } catch {
81781
- }
81790
+ const wbDoc = parseXmlDoc(decodeUtf8(wbEntry));
81791
+ const wbCacheMap = extractWorkbookPivotCaches(wbDoc);
81792
+ for (const [cacheId, rId] of wbCacheMap) {
81793
+ const cacheTarget = wbRels.get(rId);
81794
+ if (!cacheTarget) continue;
81795
+ const cachePath = cacheTarget.startsWith("/") ? cacheTarget.slice(1) : `xl/${cacheTarget}`;
81796
+ const cacheEntry = findEntry(zip, cachePath);
81797
+ if (!cacheEntry) continue;
81798
+ try {
81799
+ pivotCaches.set(
81800
+ cacheId,
81801
+ parsePivotCacheDefinitionXml(decodeUtf8(cacheEntry), cacheId, parseXmlDoc)
81802
+ );
81803
+ } catch {
81782
81804
  }
81783
81805
  }
81784
81806
  const sheets = [];
@@ -81902,6 +81924,11 @@ function parseExcelFromZip(zip, options) {
81902
81924
  }
81903
81925
  visibleIndex++;
81904
81926
  }
81927
+ if (sheets.length === 0 && workbookInfo.sheets.length > 0) {
81928
+ throw new MalformedPartError(
81929
+ `xl/workbook.xml declares ${workbookInfo.sheets.length} sheet(s) and none of their parts could be resolved`
81930
+ );
81931
+ }
81905
81932
  if (sheets.length === 0) {
81906
81933
  return { sheets: [emptySheet("Sheet1")], activeSheetIndex: 0 };
81907
81934
  }
@@ -98133,8 +98160,16 @@ async function loadDocxFromBuffer(buffer) {
98133
98160
  const bodyElements = getChildren(bodyEl);
98134
98161
  return { zip, bodyElements, documentAttrs };
98135
98162
  }
98163
+ function withTrailingParagraph(body) {
98164
+ const sectPrAt = body.findIndex((e) => getTagName(e) === "w:sectPr");
98165
+ const lastBlock = sectPrAt >= 0 ? sectPrAt - 1 : body.length - 1;
98166
+ if (lastBlock < 0 || getTagName(body[lastBlock]) !== "w:tbl") return body;
98167
+ const out = [...body];
98168
+ out.splice(lastBlock + 1, 0, { "w:p": [] });
98169
+ return out;
98170
+ }
98136
98171
  async function saveDocxToBuffer(doc) {
98137
- const bodyChildren = [...doc.bodyElements];
98172
+ const bodyChildren = withTrailingParagraph(doc.bodyElements);
98138
98173
  const documentEl = {
98139
98174
  "w:document": [{ "w:body": bodyChildren }],
98140
98175
  ":@": { ...doc.documentAttrs }
@@ -100293,7 +100328,7 @@ Available workspaces:`);
100293
100328
  if (subcommand === "query") {
100294
100329
  const action = toolArgs;
100295
100330
  if (action === "set") {
100296
- if (restArgs.includes("--all")) {
100331
+ if (flags.all) {
100297
100332
  await appQuerySet(client, { all: true });
100298
100333
  return;
100299
100334
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/cli",
3
- "version": "0.111.0",
3
+ "version": "0.112.0",
4
4
  "description": "Lotics SDK and CLI for AI agents",
5
5
  "type": "module",
6
6
  "bin": {