@lotics/cli 0.285.0 → 0.286.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.
Files changed (2) hide show
  1. package/dist/src/cli.js +241 -50
  2. package/package.json +1 -1
package/dist/src/cli.js CHANGED
@@ -22071,16 +22071,13 @@ var uploadTicketResultSchema = zod_default.object({
22071
22071
  file_name: zod_default.string(),
22072
22072
  mime_type: zod_default.string(),
22073
22073
  size_bytes: zod_default.number(),
22074
- sha256: zod_default.string(),
22075
- /** True when these bytes were already in the workspace and no second copy was
22076
- * stored. Stated rather than left to inference, because the caller then gets
22077
- * back a `file_name` it did not send — the stored file's, not the one it
22078
- * uploaded under — and a silent difference reads as a bug. */
22079
- deduplicated: zod_default.boolean()
22074
+ sha256: zod_default.string().describe("sha256 of the bytes received, so a caller can prove they arrived intact.")
22080
22075
  });
22081
22076
  var fileSizeSchema = zod_default.number().int().positive().max(MAX_UPLOAD_FILE_SIZE);
22077
+ var CLIENT_FILE_ID_REFUSAL = "This page is out of date. Reload it to upload files.";
22078
+ var refusedClientFileIdSchema = zod_default.never({ error: CLIENT_FILE_ID_REFUSAL }).optional().describe("Never sent: the server mints the file id.");
22082
22079
  var directUploadInitRequestSchema = zod_default.object({
22083
- file_id: zod_default.string().optional(),
22080
+ file_id: refusedClientFileIdSchema,
22084
22081
  filename: zod_default.string(),
22085
22082
  mime_type: zod_default.string(),
22086
22083
  file_size: fileSizeSchema
@@ -22100,7 +22097,7 @@ var directUploadCompleteRequestSchema = zod_default.object({
22100
22097
  )
22101
22098
  });
22102
22099
  var multipartInitRequestSchema = zod_default.object({
22103
- file_id: zod_default.string().optional(),
22100
+ file_id: refusedClientFileIdSchema,
22104
22101
  filename: zod_default.string(),
22105
22102
  mime_type: zod_default.string(),
22106
22103
  file_size: fileSizeSchema,
@@ -25053,6 +25050,12 @@ function everyOptionMarked(nameOf) {
25053
25050
  };
25054
25051
  }
25055
25052
 
25053
+ // ../shared/src/diacritics.ts
25054
+ var COMBINING_MARKS = /[̀-ͯ]/g;
25055
+ function foldDiacritics(value) {
25056
+ return value.normalize("NFD").replace(COMBINING_MARKS, "").replace(/[đĐ]/g, (c) => c === "\u0111" ? "d" : "D");
25057
+ }
25058
+
25056
25059
  // ../shared/src/schemas/table_filters.ts
25057
25060
  var tableRecordNumberFieldFilterSchema = zod_default.object({
25058
25061
  type: zod_default.literal("number"),
@@ -25408,6 +25411,7 @@ var VALID_OPERATORS = {
25408
25411
  record_id: RECORD_ID_OPS
25409
25412
  };
25410
25413
  var VALID_FILTER_TYPES = Object.keys(VALID_OPERATORS);
25414
+ var DEFAULT_MAX_DEPTH = 4;
25411
25415
  var MAX_TRAVERSAL_PATH_LENGTH = 3;
25412
25416
  var NO_VALUE_OPERATORS = /* @__PURE__ */ new Set([
25413
25417
  "is_empty",
@@ -25425,10 +25429,10 @@ function listElementIssue(value) {
25425
25429
  const actual = item === null ? "null" : Array.isArray(item) ? "array" : typeof item;
25426
25430
  return `item ${index} is ${actual}`;
25427
25431
  }
25428
- function conditionValueIssue(type, operator, value, fieldKey) {
25432
+ function conditionValueIssue({ type, operator, value, fieldKey }, check2) {
25429
25433
  if (NO_VALUE_OPERATORS.has(operator)) return null;
25430
25434
  if (value === null || value === void 0) return null;
25431
- if (isTemplateExpression(value)) return null;
25435
+ if (check2.templates === "filled" && isTemplateExpression(value)) return null;
25432
25436
  if (type === "date") {
25433
25437
  const parsed = tableRecordDateFieldFilterSchema.safeParse({
25434
25438
  type,
@@ -25486,7 +25490,8 @@ function conditionValueIssue(type, operator, value, fieldKey) {
25486
25490
  return null;
25487
25491
  }
25488
25492
  }
25489
- function conditionIssues(node, path17, fieldMap) {
25493
+ function conditionIssues(node, path17, check2) {
25494
+ const { fieldMap } = check2;
25490
25495
  if (!node || typeof node !== "object") {
25491
25496
  return [`${path17}: expected condition object, got ${typeof node}`];
25492
25497
  }
@@ -25557,11 +25562,14 @@ function conditionIssues(node, path17, fieldMap) {
25557
25562
  filterType === "number" ? `Filter on "${obj.field_key}": unit_option is the key of an option, got ${Array.isArray(obj.unit_option) ? "array" : typeof obj.unit_option}.` : `Filter on "${obj.field_key}": unit_option names the unit a number is compared in, and a ${filterType} condition compares none.`
25558
25563
  ];
25559
25564
  }
25560
- const valueIssue = conditionValueIssue(filterType, obj.operator, obj.value, obj.field_key);
25565
+ const valueIssue = conditionValueIssue(
25566
+ { type: filterType, operator: obj.operator, value: obj.value, fieldKey: obj.field_key },
25567
+ check2
25568
+ );
25561
25569
  return valueIssue ? [valueIssue] : [];
25562
25570
  }
25563
25571
  function validateFilterCondition(condition, path17 = "filter") {
25564
- return conditionIssues(condition, path17, void 0);
25572
+ return conditionIssues(condition, path17, { fieldMap: void 0, maxDepth: DEFAULT_MAX_DEPTH, templates: "filled" });
25565
25573
  }
25566
25574
  function inheritedFilterType(type, format2, fallback) {
25567
25575
  switch (type) {
@@ -27398,6 +27406,106 @@ function sample(arr) {
27398
27406
  return arr[Math.floor(Math.random() * arr.length)];
27399
27407
  }
27400
27408
 
27409
+ // ../shared/src/expression_limits.ts
27410
+ var MAX_RESULT_LENGTH = 1e5;
27411
+ var MAX_STRING_LENGTH = 1e7;
27412
+ var MAX_RANDOM_LENGTH = 1e3;
27413
+ var MAX_RUN_BUILT_BYTES = 512 * 1024 * 1024;
27414
+ var MAX_PERSISTED_JSON_LENGTH = 64 * 1024 * 1024;
27415
+ var ExpressionLimitError = class extends Error {
27416
+ constructor(message2) {
27417
+ super(message2);
27418
+ this.name = "ExpressionLimitError";
27419
+ }
27420
+ };
27421
+ function jsonLengthUpTo(value, max2) {
27422
+ const top = jsonValue(value, "");
27423
+ if (isOmitted(top)) return 0;
27424
+ let length2 = 0;
27425
+ const pending = [top];
27426
+ while (pending.length > 0 && length2 <= max2) {
27427
+ const member = pending.pop();
27428
+ if (typeof member === "string") {
27429
+ length2 += member.length + 2;
27430
+ if (length2 <= max2) length2 += escapedLength(member) - member.length;
27431
+ } else if (typeof member === "number") {
27432
+ length2 += Number.isFinite(member) ? String(member).length : 4;
27433
+ } else if (typeof member === "boolean") {
27434
+ length2 += member ? 4 : 5;
27435
+ } else if (typeof member === "bigint") {
27436
+ length2 += String(member).length;
27437
+ } else if (member === null || typeof member !== "object") {
27438
+ length2 += 4;
27439
+ } else if (Array.isArray(member)) {
27440
+ length2 += member.length === 0 ? 2 : member.length + 1;
27441
+ for (let index = 0; index < member.length && length2 <= max2; index++) {
27442
+ const element = jsonValue(member[index], String(index));
27443
+ if (isOmitted(element)) length2 += 4;
27444
+ else pending.push(element);
27445
+ }
27446
+ } else {
27447
+ length2 += 2;
27448
+ let members = 0;
27449
+ for (const key of Object.keys(member)) {
27450
+ if (length2 > max2) break;
27451
+ const held = jsonValue(Reflect.get(member, key), key);
27452
+ if (isOmitted(held)) continue;
27453
+ length2 += escapedLength(key) + 2 + (members === 0 ? 1 : 2);
27454
+ members += 1;
27455
+ pending.push(held);
27456
+ }
27457
+ }
27458
+ }
27459
+ return length2;
27460
+ }
27461
+ function jsonValue(value, key) {
27462
+ if (typeof value !== "object" || value === null) return value;
27463
+ const toJSON = Reflect.get(value, "toJSON");
27464
+ if (typeof toJSON !== "function") return value;
27465
+ const written = Reflect.apply(toJSON, value, [key]);
27466
+ return written;
27467
+ }
27468
+ function isOmitted(value) {
27469
+ return value === void 0 || typeof value === "function" || typeof value === "symbol";
27470
+ }
27471
+ var ESCAPED = /["\\\u0000-\u001f\ud800-\udfff]/;
27472
+ function escapedLength(text) {
27473
+ if (!ESCAPED.test(text)) return text.length;
27474
+ let length2 = 0;
27475
+ for (let at2 = 0; at2 < text.length; at2++) {
27476
+ const code = text.charCodeAt(at2);
27477
+ if (code === 34 || code === 92 || code === 8 || code === 9 || code === 10 || code === 12 || code === 13) {
27478
+ length2 += 2;
27479
+ } else if (code < 32) {
27480
+ length2 += 6;
27481
+ } else if (code >= 55296 && code <= 56319 && isLowSurrogate(text.charCodeAt(at2 + 1))) {
27482
+ length2 += 2;
27483
+ at2 += 1;
27484
+ } else {
27485
+ length2 += code >= 55296 && code <= 57343 ? 6 : 1;
27486
+ }
27487
+ }
27488
+ return length2;
27489
+ }
27490
+ function isLowSurrogate(code) {
27491
+ return code >= 56320 && code <= 57343;
27492
+ }
27493
+ function textLengthUpTo(value, max2) {
27494
+ return textLength(value, max2, /* @__PURE__ */ new Set());
27495
+ }
27496
+ function textLength(value, max2, joining) {
27497
+ if (!Array.isArray(value)) return String(value).length;
27498
+ if (joining.has(value)) return 0;
27499
+ joining.add(value);
27500
+ let length2 = Math.max(0, value.length - 1);
27501
+ for (let index = 0; index < value.length && length2 <= max2; index++) {
27502
+ const element = value[index];
27503
+ if (element != null) length2 += textLength(element, max2 - length2, joining);
27504
+ }
27505
+ joining.delete(value);
27506
+ return length2;
27507
+ }
27508
+
27401
27509
  // ../shared/src/expression_array.ts
27402
27510
  var expression_array_exports = {};
27403
27511
  __export(expression_array_exports, {
@@ -27461,12 +27569,36 @@ function compareValues(a, b) {
27461
27569
  function isCallback(v) {
27462
27570
  return typeof v === "function";
27463
27571
  }
27572
+ function assertCallbackInput(helper, arr) {
27573
+ if (arr.length > MAX_RESULT_LENGTH) {
27574
+ throw new ExpressionLimitError(`${helper}: too many elements for a callback (max ${MAX_RESULT_LENGTH})`);
27575
+ }
27576
+ }
27577
+ async function callEach(arr, cb) {
27578
+ const results = Array.from({ length: arr.length });
27579
+ let next = 0;
27580
+ let failed = false;
27581
+ const work = async () => {
27582
+ while (!failed && next < arr.length) {
27583
+ const i = next;
27584
+ next += 1;
27585
+ results[i] = await Promise.resolve().then(() => cb(arr[i], i)).catch((error52) => {
27586
+ failed = true;
27587
+ throw error52;
27588
+ });
27589
+ }
27590
+ };
27591
+ const extra = arr.length > 1 ? cb.workers?.claim(arr.length - 1) ?? 0 : 0;
27592
+ await Promise.all(Array.from({ length: 1 + extra }, work)).finally(() => cb.workers?.release(extra));
27593
+ return results;
27594
+ }
27464
27595
  function sumBy(arr, fieldOrCb) {
27465
27596
  if (arr == null) return isCallback(fieldOrCb) ? Promise.resolve(0) : 0;
27466
27597
  if (!Array.isArray(arr)) {
27467
27598
  throw new Error("sumBy: expected array, got " + typeof arr);
27468
27599
  }
27469
27600
  if (isCallback(fieldOrCb)) {
27601
+ assertCallbackInput("sumBy", arr);
27470
27602
  return sumByCallback(arr, fieldOrCb);
27471
27603
  }
27472
27604
  if (typeof fieldOrCb !== "string") {
@@ -27478,7 +27610,7 @@ function sumBy(arr, fieldOrCb) {
27478
27610
  }, 0);
27479
27611
  }
27480
27612
  async function sumByCallback(arr, cb) {
27481
- const values2 = await Promise.all(arr.map((item, idx) => cb(item, idx)));
27613
+ const values2 = await callEach(arr, cb);
27482
27614
  return values2.reduce((sum2, val) => sum2 + (typeof val === "number" ? val : 0), 0);
27483
27615
  }
27484
27616
  function meanBy(arr, fieldOrCb) {
@@ -27489,7 +27621,8 @@ function meanBy(arr, fieldOrCb) {
27489
27621
  throw new Error("meanBy: array cannot be empty");
27490
27622
  }
27491
27623
  if (isCallback(fieldOrCb)) {
27492
- return Promise.all(arr.map((item, idx) => fieldOrCb(item, idx))).then(
27624
+ assertCallbackInput("meanBy", arr);
27625
+ return callEach(arr, fieldOrCb).then(
27493
27626
  (vals) => vals.reduce((acc, v) => acc + (typeof v === "number" ? v : 0), 0) / arr.length
27494
27627
  );
27495
27628
  }
@@ -27511,6 +27644,7 @@ function minBy(arr, fieldOrCb) {
27511
27644
  throw new Error("minBy: array cannot be empty");
27512
27645
  }
27513
27646
  if (isCallback(fieldOrCb)) {
27647
+ assertCallbackInput("minBy", arr);
27514
27648
  return selectByCallback(arr, fieldOrCb, (cmp) => cmp < 0);
27515
27649
  }
27516
27650
  const field = fieldOrCb;
@@ -27537,6 +27671,7 @@ function maxBy(arr, fieldOrCb) {
27537
27671
  throw new Error("maxBy: array cannot be empty");
27538
27672
  }
27539
27673
  if (isCallback(fieldOrCb)) {
27674
+ assertCallbackInput("maxBy", arr);
27540
27675
  return selectByCallback(arr, fieldOrCb, (cmp) => cmp > 0);
27541
27676
  }
27542
27677
  const field = fieldOrCb;
@@ -27556,7 +27691,7 @@ function maxBy(arr, fieldOrCb) {
27556
27691
  return maxItem;
27557
27692
  }
27558
27693
  async function selectByCallback(arr, cb, keep) {
27559
- const keys2 = await Promise.all(arr.map((item, idx) => cb(item, idx)));
27694
+ const keys2 = await callEach(arr, cb);
27560
27695
  let bestItem = arr[0];
27561
27696
  let bestKey = keys2[0];
27562
27697
  for (let i = 1; i < arr.length; i++) {
@@ -27575,7 +27710,8 @@ function countBy(arr, fieldOrCb) {
27575
27710
  throw new Error("countBy: expected array, got " + typeof arr);
27576
27711
  }
27577
27712
  if (isCallback(fieldOrCb)) {
27578
- return Promise.all(arr.map((item, idx) => fieldOrCb(item, idx))).then((keys2) => {
27713
+ assertCallbackInput("countBy", arr);
27714
+ return callEach(arr, fieldOrCb).then((keys2) => {
27579
27715
  const result2 = {};
27580
27716
  for (const val of keys2) {
27581
27717
  const key = val == null ? "null" : String(val);
@@ -27602,7 +27738,8 @@ function pluck(arr, fieldOrCb) {
27602
27738
  throw new Error("pluck: expected array, got " + typeof arr);
27603
27739
  }
27604
27740
  if (isCallback(fieldOrCb)) {
27605
- return Promise.all(arr.map((item, idx) => fieldOrCb(item, idx)));
27741
+ assertCallbackInput("pluck", arr);
27742
+ return callEach(arr, fieldOrCb);
27606
27743
  }
27607
27744
  if (typeof fieldOrCb !== "string") {
27608
27745
  throw new Error("pluck: second arg must be a function or field path string");
@@ -27615,6 +27752,7 @@ function filter(arr, fieldOrCb, value) {
27615
27752
  throw new Error("filter: expected array, got " + typeof arr);
27616
27753
  }
27617
27754
  if (isCallback(fieldOrCb)) {
27755
+ assertCallbackInput("filter", arr);
27618
27756
  return filterByCallback(arr, fieldOrCb);
27619
27757
  }
27620
27758
  if (typeof fieldOrCb !== "string") {
@@ -27626,7 +27764,7 @@ function filter(arr, fieldOrCb, value) {
27626
27764
  });
27627
27765
  }
27628
27766
  async function filterByCallback(arr, cb) {
27629
- const results = await Promise.all(arr.map((item, idx) => cb(item, idx)));
27767
+ const results = await callEach(arr, cb);
27630
27768
  return arr.filter((_, i) => Boolean(results[i]));
27631
27769
  }
27632
27770
  function find(arr, fieldOrCb, value) {
@@ -27635,6 +27773,7 @@ function find(arr, fieldOrCb, value) {
27635
27773
  throw new Error("find: expected array, got " + typeof arr);
27636
27774
  }
27637
27775
  if (isCallback(fieldOrCb)) {
27776
+ assertCallbackInput("find", arr);
27638
27777
  return findByCallback(arr, fieldOrCb);
27639
27778
  }
27640
27779
  if (typeof fieldOrCb !== "string") {
@@ -27662,6 +27801,7 @@ function sortBy(arr, fieldOrCb, order) {
27662
27801
  throw new Error('sortBy: order must be "asc" or "desc"');
27663
27802
  }
27664
27803
  if (isCallback(fieldOrCb)) {
27804
+ assertCallbackInput("sortBy", arr);
27665
27805
  return sortByCallback(arr, fieldOrCb, order);
27666
27806
  }
27667
27807
  if (typeof fieldOrCb !== "string") {
@@ -27670,7 +27810,7 @@ function sortBy(arr, fieldOrCb, order) {
27670
27810
  return sortBySync(arr, fieldOrCb, order);
27671
27811
  }
27672
27812
  async function sortByCallback(arr, cb, order) {
27673
- const keys2 = await Promise.all(arr.map((item, idx) => cb(item, idx)));
27813
+ const keys2 = await callEach(arr, cb);
27674
27814
  const indexed = arr.map((item, i) => ({ item, key: keys2[i] }));
27675
27815
  indexed.sort((a, b) => {
27676
27816
  const cmp = compareValues(a.key, b.key);
@@ -27703,7 +27843,8 @@ function groupBy(arr, fieldOrCb) {
27703
27843
  throw new Error("groupBy: expected array, got " + typeof arr);
27704
27844
  }
27705
27845
  if (isCallback(fieldOrCb)) {
27706
- return Promise.all(arr.map((item, idx) => fieldOrCb(item, idx))).then((keys2) => {
27846
+ assertCallbackInput("groupBy", arr);
27847
+ return callEach(arr, fieldOrCb).then((keys2) => {
27707
27848
  const result2 = {};
27708
27849
  for (let i = 0; i < arr.length; i++) {
27709
27850
  const key = keys2[i] == null ? "null" : String(keys2[i]);
@@ -27752,7 +27893,8 @@ function uniqueBy(arr, fieldOrCb) {
27752
27893
  throw new Error("uniqueBy: expected array, got " + typeof arr);
27753
27894
  }
27754
27895
  if (isCallback(fieldOrCb)) {
27755
- return Promise.all(arr.map((item, idx) => fieldOrCb(item, idx))).then((keys2) => {
27896
+ assertCallbackInput("uniqueBy", arr);
27897
+ return callEach(arr, fieldOrCb).then((keys2) => {
27756
27898
  const seen2 = /* @__PURE__ */ new Set();
27757
27899
  return arr.filter((_, i) => {
27758
27900
  if (seen2.has(keys2[i])) return false;
@@ -27783,7 +27925,7 @@ function flatten(arr) {
27783
27925
  total += Array.isArray(item) ? item.length : 1;
27784
27926
  }
27785
27927
  if (total > MAX_RESULT_LENGTH) {
27786
- throw new Error(`flatten: too large (max ${MAX_RESULT_LENGTH} elements)`);
27928
+ throw new ExpressionLimitError(`flatten: too large (max ${MAX_RESULT_LENGTH} elements)`);
27787
27929
  }
27788
27930
  const result = [];
27789
27931
  for (const item of arr) {
@@ -27882,6 +28024,7 @@ function some(arr, fieldOrCb, value) {
27882
28024
  throw new Error("some: expected array, got " + typeof arr);
27883
28025
  }
27884
28026
  if (isCallback(fieldOrCb)) {
28027
+ assertCallbackInput("some", arr);
27885
28028
  return (async () => {
27886
28029
  for (let i = 0; i < arr.length; i++) {
27887
28030
  if (await fieldOrCb(arr[i], i)) return true;
@@ -27901,6 +28044,7 @@ function every(arr, fieldOrCb, value) {
27901
28044
  throw new Error("every: expected array, got " + typeof arr);
27902
28045
  }
27903
28046
  if (isCallback(fieldOrCb)) {
28047
+ assertCallbackInput("every", arr);
27904
28048
  return (async () => {
27905
28049
  for (let i = 0; i < arr.length; i++) {
27906
28050
  if (!await fieldOrCb(arr[i], i)) return false;
@@ -27936,6 +28080,8 @@ function differenceBy(arr1, arr2, fieldOrCb) {
27936
28080
  throw new Error("differenceBy: second argument expected array, got " + typeof arr2);
27937
28081
  }
27938
28082
  if (isCallback(fieldOrCb)) {
28083
+ assertCallbackInput("differenceBy", arr1);
28084
+ assertCallbackInput("differenceBy", arr2);
27939
28085
  return keyedSetOp(arr1, arr2, fieldOrCb, false);
27940
28086
  }
27941
28087
  const field = fieldOrCb;
@@ -27965,6 +28111,8 @@ function intersectionBy(arr1, arr2, fieldOrCb) {
27965
28111
  throw new Error("intersectionBy: second argument expected array, got " + typeof arr2);
27966
28112
  }
27967
28113
  if (isCallback(fieldOrCb)) {
28114
+ assertCallbackInput("intersectionBy", arr1);
28115
+ assertCallbackInput("intersectionBy", arr2);
27968
28116
  return keyedSetOp(arr1, arr2, fieldOrCb, true);
27969
28117
  }
27970
28118
  const field = fieldOrCb;
@@ -27975,10 +28123,8 @@ function intersectionBy(arr1, arr2, fieldOrCb) {
27975
28123
  return arr1.filter((item) => set2.has(getField(item, field)));
27976
28124
  }
27977
28125
  async function keyedSetOp(arr1, arr2, cb, keepWhenPresent) {
27978
- const [keys1, keys2] = await Promise.all([
27979
- Promise.all(arr1.map((item, idx) => cb(item, idx))),
27980
- Promise.all(arr2.map((item, idx) => cb(item, idx)))
27981
- ]);
28126
+ const keys1 = await callEach(arr1, cb);
28127
+ const keys2 = await callEach(arr2, cb);
27982
28128
  const set2 = new Set(keys2);
27983
28129
  return arr1.filter((_, i) => set2.has(keys1[i]) === keepWhenPresent);
27984
28130
  }
@@ -27993,20 +28139,13 @@ async function reduce(arr, callback, initial) {
27993
28139
  if (arguments.length < 3) {
27994
28140
  throw new Error("reduce: initial value is required \u2014 reduce(arr, (acc, x) => ..., initial)");
27995
28141
  }
27996
- const startedAt2 = Date.now();
28142
+ assertCallbackInput("reduce", arr);
27997
28143
  let acc = initial;
27998
28144
  for (let i = 0; i < arr.length; i++) {
27999
- if (i % 1024 === 0 && Date.now() - startedAt2 > REDUCE_TIME_BUDGET_MS) {
28000
- throw new Error(
28001
- `reduce: exceeded time budget of ${REDUCE_TIME_BUDGET_MS}ms after ${i} iterations`
28002
- );
28003
- }
28004
28145
  acc = await callback(acc, arr[i], i);
28005
28146
  }
28006
28147
  return acc;
28007
28148
  }
28008
- var REDUCE_TIME_BUDGET_MS = 5e3;
28009
- var MAX_RESULT_LENGTH = 1e5;
28010
28149
  function range(startOrEnd, end) {
28011
28150
  const start = end === void 0 ? 0 : startOrEnd;
28012
28151
  const stop = end === void 0 ? startOrEnd : end;
@@ -28016,13 +28155,13 @@ function range(startOrEnd, end) {
28016
28155
  const len = stop - start;
28017
28156
  if (len <= 0) return [];
28018
28157
  if (len > MAX_RESULT_LENGTH) {
28019
- throw new Error(`range: too large (max ${MAX_RESULT_LENGTH} elements)`);
28158
+ throw new ExpressionLimitError(`range: too large (max ${MAX_RESULT_LENGTH} elements)`);
28020
28159
  }
28021
28160
  return Array.from({ length: len }, (_, i) => start + i);
28022
28161
  }
28023
28162
  function list(...items) {
28024
28163
  if (items.length > MAX_RESULT_LENGTH) {
28025
- throw new Error(`list: too large (max ${MAX_RESULT_LENGTH} elements)`);
28164
+ throw new ExpressionLimitError(`list: too large (max ${MAX_RESULT_LENGTH} elements)`);
28026
28165
  }
28027
28166
  return items;
28028
28167
  }
@@ -28058,7 +28197,7 @@ function concatArrays(arrays) {
28058
28197
  total += arr.length;
28059
28198
  }
28060
28199
  if (total > MAX_RESULT_LENGTH) {
28061
- throw new Error(`concat: too large (max ${MAX_RESULT_LENGTH} elements)`);
28200
+ throw new ExpressionLimitError(`concat: too large (max ${MAX_RESULT_LENGTH} elements)`);
28062
28201
  }
28063
28202
  const result = [];
28064
28203
  for (let i = 0; i < arrays.length; i++) {
@@ -28111,7 +28250,10 @@ function join(arr, separator) {
28111
28250
  if (typeof separator !== "string") {
28112
28251
  throw new Error("join: separator must be a string");
28113
28252
  }
28114
- return arr.map(String).join(separator);
28253
+ const parts = arr.map(String);
28254
+ const separatorsLength = Math.max(0, parts.length - 1) * separator.length;
28255
+ assertStringLength("join", parts.reduce((total, part) => total + part.length, separatorsLength));
28256
+ return parts.join(separator);
28115
28257
  }
28116
28258
  function split(str, separator) {
28117
28259
  if (str == null) return [];
@@ -28121,7 +28263,11 @@ function split(str, separator) {
28121
28263
  if (typeof separator !== "string") {
28122
28264
  throw new Error("split: separator must be a string");
28123
28265
  }
28124
- return str.split(separator);
28266
+ const parts = str.split(separator, MAX_RESULT_LENGTH + 1);
28267
+ if (parts.length > MAX_RESULT_LENGTH) {
28268
+ throw new ExpressionLimitError(`split: too many parts (max ${MAX_RESULT_LENGTH})`);
28269
+ }
28270
+ return parts;
28125
28271
  }
28126
28272
  function trim(str) {
28127
28273
  if (str == null) return "";
@@ -28176,8 +28322,26 @@ function replaceAll(str, search, replacement) {
28176
28322
  if (typeof replacement !== "string") {
28177
28323
  throw new Error("replaceAll: replacement must be a string");
28178
28324
  }
28325
+ const matches = matchCount(str, search);
28326
+ if (matches >= MAX_STRING_LENGTH) {
28327
+ throw new ExpressionLimitError(`replaceAll: too many matches (max ${MAX_STRING_LENGTH})`);
28328
+ }
28329
+ assertStringLength("replaceAll", str.length + matches * (replacement.length - search.length));
28179
28330
  return str.split(search).join(replacement);
28180
28331
  }
28332
+ function matchCount(str, search) {
28333
+ if (search === "") return Math.max(0, str.length - 1);
28334
+ let matches = 0;
28335
+ for (let at2 = str.indexOf(search); at2 !== -1; at2 = str.indexOf(search, at2 + search.length)) {
28336
+ matches += 1;
28337
+ }
28338
+ return matches;
28339
+ }
28340
+ function assertStringLength(helper, length2) {
28341
+ if (length2 > MAX_STRING_LENGTH) {
28342
+ throw new ExpressionLimitError(`${helper}: result too long (max ${MAX_STRING_LENGTH} characters)`);
28343
+ }
28344
+ }
28181
28345
  function startsWith(str, prefix) {
28182
28346
  if (str == null) return false;
28183
28347
  if (typeof str !== "string") {
@@ -28222,6 +28386,7 @@ function padStart(str, length2, char) {
28222
28386
  if (typeof char !== "string") {
28223
28387
  throw new Error("padStart: char must be a string");
28224
28388
  }
28389
+ assertStringLength("padStart", length2);
28225
28390
  return str.padStart(length2, char);
28226
28391
  }
28227
28392
  function padEnd(str, length2, char) {
@@ -28235,6 +28400,7 @@ function padEnd(str, length2, char) {
28235
28400
  if (typeof char !== "string") {
28236
28401
  throw new Error("padEnd: char must be a string");
28237
28402
  }
28403
+ assertStringLength("padEnd", length2);
28238
28404
  return str.padEnd(length2, char);
28239
28405
  }
28240
28406
  function length(value) {
@@ -28820,6 +28986,9 @@ function toNumber(val) {
28820
28986
  }
28821
28987
  function toString(val) {
28822
28988
  if (val == null) return "";
28989
+ if (typeof val !== "string" && textLengthUpTo(val, MAX_STRING_LENGTH) > MAX_STRING_LENGTH) {
28990
+ throw new ExpressionLimitError(`toString: result too long (max ${MAX_STRING_LENGTH} characters)`);
28991
+ }
28823
28992
  return String(val);
28824
28993
  }
28825
28994
  function isNull(val) {
@@ -28843,6 +29012,9 @@ function parseJson(value) {
28843
29012
  }
28844
29013
  }
28845
29014
  function toJson(value) {
29015
+ if (jsonLengthUpTo(value, MAX_STRING_LENGTH) > MAX_STRING_LENGTH) {
29016
+ throw new ExpressionLimitError(`toJson: result too long (max ${MAX_STRING_LENGTH} characters)`);
29017
+ }
28846
29018
  return JSON.stringify(value) ?? "null";
28847
29019
  }
28848
29020
  function typeOf(value) {
@@ -31121,9 +31293,15 @@ function getDateExpressionFunctions(defaultTimezone) {
31121
31293
 
31122
31294
  // ../shared/src/js_expression.ts
31123
31295
  var DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
31296
+ var ExpressionNotPermittedError = class extends Error {
31297
+ constructor(message2) {
31298
+ super(message2);
31299
+ this.name = "ExpressionNotPermittedError";
31300
+ }
31301
+ };
31124
31302
  function assertSafeKey(key) {
31125
31303
  if (typeof key === "string" && DANGEROUS_KEYS.has(key)) {
31126
- throw new Error(`Access to "${key}" is not permitted in expressions`);
31304
+ throw new ExpressionNotPermittedError(`Access to "${key}" is not permitted in expressions`);
31127
31305
  }
31128
31306
  }
31129
31307
  function isNothing(value) {
@@ -31149,7 +31327,7 @@ var SafeEvalAstFactory = class extends EvalAstFactory {
31149
31327
  }
31150
31328
  binary(left, op, right) {
31151
31329
  if (op === "=") {
31152
- throw new Error("Assignment is not permitted in expressions");
31330
+ throw new ExpressionNotPermittedError("Assignment is not permitted in expressions");
31153
31331
  }
31154
31332
  const multiplicative = MULTIPLICATIVE_OPERATORS.get(op);
31155
31333
  if (multiplicative) {
@@ -31215,6 +31393,18 @@ var SafeEvalAstFactory = class extends EvalAstFactory {
31215
31393
  }
31216
31394
  };
31217
31395
  }
31396
+ arrowFunction(params, body) {
31397
+ const parsed = super.arrowFunction(params, body);
31398
+ return {
31399
+ type: "ArrowFunction",
31400
+ params,
31401
+ body,
31402
+ evaluate() {
31403
+ throw new ExpressionNotPermittedError("An arrow function cannot run in this expression");
31404
+ },
31405
+ getIds: (idents) => parsed.getIds(idents)
31406
+ };
31407
+ }
31218
31408
  index(receiver, argument) {
31219
31409
  return {
31220
31410
  type: "Index",
@@ -31295,13 +31485,20 @@ function createTimezoneAwareFunctions(defaultTimezone) {
31295
31485
  };
31296
31486
  }
31297
31487
  var numericAlphabet = customAlphabet("0123456789");
31488
+ function assertRandomLength(helper, length2) {
31489
+ if (length2 > MAX_RANDOM_LENGTH) {
31490
+ throw new ExpressionLimitError(`${helper}: length ${length2} is over ${MAX_RANDOM_LENGTH}.`);
31491
+ }
31492
+ }
31298
31493
  function randomNumber(length2) {
31494
+ assertRandomLength("randomNumber", length2);
31299
31495
  return numericAlphabet(length2);
31300
31496
  }
31301
31497
  var alphanumericAlphabet = customAlphabet(
31302
31498
  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
31303
31499
  );
31304
31500
  function randomAlphaNumeric(length2) {
31501
+ assertRandomLength("randomAlphaNumeric", length2);
31305
31502
  return alphanumericAlphabet(length2);
31306
31503
  }
31307
31504
 
@@ -32789,12 +32986,6 @@ var bindingSchema = zod_default.object({
32789
32986
  apps: bindingMapSchema.default({})
32790
32987
  });
32791
32988
 
32792
- // ../shared/src/diacritics.ts
32793
- var COMBINING_MARKS = /[̀-ͯ]/g;
32794
- function foldDiacritics(value) {
32795
- return value.normalize("NFD").replace(COMBINING_MARKS, "").replace(/[đĐ]/g, (c) => c === "\u0111" ? "d" : "D");
32796
- }
32797
-
32798
32989
  // ../shared/src/formula.ts
32799
32990
  function getSyntheticValue(field) {
32800
32991
  switch (field.type) {
@@ -41775,8 +41966,8 @@ function resultSideEffects(result) {
41775
41966
  }
41776
41967
 
41777
41968
  // src/version.ts
41778
- var VERSION = "0.285.0";
41779
- var APP_SDK_VERSION = "0.111.4";
41969
+ var VERSION = "0.286.0";
41970
+ var APP_SDK_VERSION = "0.112.0";
41780
41971
 
41781
41972
  // src/timezone.ts
41782
41973
  function machineTimezone() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/cli",
3
- "version": "0.285.0",
3
+ "version": "0.286.0",
4
4
  "description": "Lotics SDK and CLI for AI agents",
5
5
  "type": "module",
6
6
  "bin": {