@lotics/cli 0.278.0 → 0.279.1

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 +156 -49
  2. package/package.json +1 -1
package/dist/src/cli.js CHANGED
@@ -36089,6 +36089,12 @@ function appDrawnFields(given, app) {
36089
36089
  ...app.register.roster?.of === void 0 ? [] : [app.register.roster.of],
36090
36090
  ...app.register.gantt === void 0 ? [] : ganttFields(app.register.gantt),
36091
36091
  ...app.register.readings.flatMap(readingFields),
36092
+ // A tab narrows, bounds and orders the rows by columns the read returns.
36093
+ ...app.register.tabs.flatMap((tab) => [
36094
+ ...tab.term === void 0 ? [] : tab.term.kind === "in" ? [tab.term.field] : [tab.term.from, tab.term.to],
36095
+ ...tab.where.map((one) => one.field),
36096
+ ...(tab.sort ?? []).map((key) => key.field)
36097
+ ]),
36092
36098
  ...app.record.sections.flatMap((section) => [...section.fields, ...section.when.map((gate) => gate.field)]),
36093
36099
  ...resolvedBlocks(app.record).flatMap((block) => [
36094
36100
  ...block.kind === "files" ? block.fields : block.kind === "text" ? [block.field] : [],
@@ -36482,6 +36488,50 @@ function evaluateFormulaWithJS(preparedExpression, data, timezone, everyReferenc
36482
36488
  }
36483
36489
  }
36484
36490
 
36491
+ // ../shared/src/field_value.ts
36492
+ function fieldValueInfo(field) {
36493
+ switch (field.type) {
36494
+ case "number":
36495
+ return { type: "number", format: field.format, currency: field.currency ?? void 0, unit: field.unit ?? void 0 };
36496
+ case "text":
36497
+ return { type: "text", format: field.format };
36498
+ case "date":
36499
+ return { type: "date", format: field.format };
36500
+ case "select":
36501
+ return { type: "select", options: field.options };
36502
+ case "formula": {
36503
+ const output = field.formula?.output_type;
36504
+ if (field.formula.options !== void 0) return { type: "select", options: field.formula.options };
36505
+ if (output === "date" || output === "datetime") {
36506
+ return { type: "date", format: output === "datetime" ? "datetime" : "date" };
36507
+ }
36508
+ if (output === "boolean") return { type: "boolean" };
36509
+ if (output === "text") return { type: "text", format: field.formula?.format };
36510
+ return { type: "number", format: field.formula?.format, currency: field.formula?.currency, unit: field.formula?.unit };
36511
+ }
36512
+ case "rollup":
36513
+ return {
36514
+ type: rollupOutputType(field.aggregate_option.operation),
36515
+ format: field.aggregate_field_format,
36516
+ currency: field.aggregate_field_currency,
36517
+ unit: field.aggregate_field_unit
36518
+ };
36519
+ case "lookup":
36520
+ return {
36521
+ type: field.lookup_field_type ?? "text",
36522
+ format: field.lookup_field_format,
36523
+ currency: field.lookup_field_currency,
36524
+ unit: field.lookup_field_unit,
36525
+ options: field.lookup_field_options
36526
+ };
36527
+ // The cell stores the composed DISPLAY string ("KH-001"), never the counter.
36528
+ case "autonumber":
36529
+ return { type: "text" };
36530
+ default:
36531
+ return { type: field.type };
36532
+ }
36533
+ }
36534
+
36485
36535
  // ../shared/src/schemas/contract_filter_binding.ts
36486
36536
  function remapContractFilterGroup(group, entity, resolve) {
36487
36537
  return { ...group, children: group.children.map((child) => remapContractFilter(child, entity, resolve)) };
@@ -36545,7 +36595,33 @@ function tableId(t) {
36545
36595
  }
36546
36596
  function syntheticFields(entities) {
36547
36597
  const binding = bindAliases(entities);
36548
- return entities.map((entity) => entity.fields.map((field) => syntheticField(entity, field, binding)));
36598
+ return withLookedUpValues(entities.map((entity) => entity.fields.map((field) => syntheticField(entity, field, binding))));
36599
+ }
36600
+ function withLookedUpValues(tables) {
36601
+ let current = tables;
36602
+ for (let pass = 0; pass < SURFACE_HOPS; pass++) {
36603
+ const byKey = new Map(current.flat().map((field) => [field.key, field]));
36604
+ let changed = false;
36605
+ current = current.map(
36606
+ (fields) => fields.map((field) => {
36607
+ if (field.type !== "lookup" || field.lookup_field_type !== void 0) return field;
36608
+ const target = byKey.get(field.lookup_field_key);
36609
+ if (target === void 0 || target.type === "lookup" && target.lookup_field_type === void 0) return field;
36610
+ changed = true;
36611
+ const info = fieldValueInfo(target);
36612
+ return {
36613
+ ...field,
36614
+ lookup_field_type: info.type,
36615
+ ...info.format !== void 0 && { lookup_field_format: info.format },
36616
+ ...info.currency !== void 0 && { lookup_field_currency: info.currency },
36617
+ ...info.unit !== void 0 && { lookup_field_unit: info.unit },
36618
+ ...info.options !== void 0 && { lookup_field_options: info.options }
36619
+ };
36620
+ })
36621
+ );
36622
+ if (!changed) return current;
36623
+ }
36624
+ return current;
36549
36625
  }
36550
36626
  function syntheticFormula(entities, entity, expression) {
36551
36627
  const binding = bindAliases(entities);
@@ -36698,21 +36774,12 @@ function syntheticField(entity, field, binding) {
36698
36774
  }
36699
36775
  case "lookup": {
36700
36776
  const target = requireTarget(binding, entity, field.source_field_alias, at2);
36701
- const surfaced = requireDeclared(binding, target.alias, field.lookup_field_alias, at2);
36702
- const resolved = resolvedFieldType(surfaced, target, binding.entities);
36703
- const carried = resolvedFormatOf(surfaced, target, binding.entities);
36777
+ requireDeclared(binding, target.alias, field.lookup_field_alias, at2);
36704
36778
  return {
36705
36779
  ...base,
36706
36780
  type: "lookup",
36707
36781
  source_field_key: requireField(binding, entity.alias, field.source_field_alias, at2),
36708
36782
  lookup_field_key: requireField(binding, target.alias, field.lookup_field_alias, at2),
36709
- ...resolved !== void 0 && { lookup_field_type: resolved },
36710
- ...carried.format !== void 0 && { lookup_field_format: carried.format },
36711
- ...carried.currency !== void 0 && { lookup_field_currency: carried.currency },
36712
- ...carried.unit !== void 0 && { lookup_field_unit: carried.unit },
36713
- ...resolved === "select" && {
36714
- lookup_field_options: surfacedOptions(binding, carried, at2)
36715
- },
36716
36783
  ...field.order_by !== void 0 && {
36717
36784
  order_by: {
36718
36785
  field_key: requireField(binding, target.alias, field.order_by.field_key, `${at2}.order_by`),
@@ -36731,13 +36798,6 @@ function mintedOptions(binding, entity, field, options, at2) {
36731
36798
  ...option.mark === void 0 ? {} : { mark: option.mark }
36732
36799
  }));
36733
36800
  }
36734
- function surfacedOptions(binding, carried, at2) {
36735
- const owner = carried.options;
36736
- if (owner === void 0) {
36737
- fail2(`${at2} surfaces a select, but this model states no options for the column it reaches`);
36738
- }
36739
- return mintedOptions(binding, owner.entity, owner.field, owner.options, at2);
36740
- }
36741
36801
  var SURFACE_HOPS = 8;
36742
36802
  function resolvedFormatOf(field, entity, entities, hops = 0) {
36743
36803
  if (hops >= SURFACE_HOPS) return {};
@@ -36747,10 +36807,7 @@ function resolvedFormatOf(field, entity, entities, hops = 0) {
36747
36807
  case "text":
36748
36808
  case "date":
36749
36809
  return { format: field.format };
36750
- case "select":
36751
- return { options: { entity: entity.alias, field: field.alias, options: field.options } };
36752
36810
  case "formula":
36753
- if (field.formula.options !== void 0) return { options: { entity: entity.alias, field: field.alias, options: field.formula.options } };
36754
36811
  return {
36755
36812
  format: field.formula.output_type === "datetime" ? "datetime" : field.formula.format,
36756
36813
  currency: field.formula.currency,
@@ -37273,18 +37330,17 @@ function assignee(model, entity) {
37273
37330
  return [...display?.subtitle ?? [], ...started].find((name) => fieldOf(entity, name)?.type === "select_member");
37274
37331
  }
37275
37332
 
37276
- // ../shared/src/schemas/app_model_books.ts
37277
- function fieldColumnType(field, entity, entities) {
37333
+ // ../shared/src/app_query_output_schema.ts
37334
+ function fieldTypeToColumnType(field) {
37278
37335
  switch (field.type) {
37279
37336
  case "text":
37280
- case "autonumber":
37281
37337
  return "text";
37282
37338
  case "number":
37283
37339
  return "number";
37284
37340
  case "boolean":
37285
37341
  return "boolean";
37286
37342
  case "date":
37287
- return datetime3(field.format) ? "datetime" : "date";
37343
+ return field.format === "datetime" || field.format === "datetime_range" ? "datetime" : "date";
37288
37344
  case "select":
37289
37345
  return "select";
37290
37346
  case "select_member":
@@ -37293,32 +37349,83 @@ function fieldColumnType(field, entity, entities) {
37293
37349
  return "select_record_link";
37294
37350
  case "files":
37295
37351
  return "files";
37296
- case "formula": {
37297
- if (field.formula.options !== void 0) return "select";
37298
- const stated = field.formula.output_type;
37299
- if (stated !== void 0) return stated;
37300
- return field.formula.format === void 0 ? "json" : field.formula.format === "link" ? "text" : "number";
37301
- }
37302
- case "rollup": {
37303
- if (resolvedFieldType(field, entity, entities) === "number") return "number";
37304
- const target = linkedOf(entity, entities, field.source_field_alias);
37305
- const aggregated = target?.fields.find((one) => one.alias === field.aggregate_option.field_key);
37306
- return aggregated?.type === "date" && datetime3(aggregated.format) ? "datetime" : "date";
37307
- }
37308
- case "lookup": {
37309
- const target = linkedOf(entity, entities, field.source_field_alias);
37310
- const shown = target?.fields.find((one) => one.alias === field.lookup_field_alias);
37311
- if (shown === void 0 || target === void 0 || shown.type === "formula" || shown.type === "rollup" || shown.type === "lookup" || shown.type === "autonumber") return "json";
37312
- return fieldColumnType(shown, target, entities);
37352
+ case "rollup":
37353
+ return rollupColumnType(field);
37354
+ case "lookup":
37355
+ return lookupOutputType(field);
37356
+ case "formula":
37357
+ return formulaOutputType(field);
37358
+ case "button":
37359
+ return "json";
37360
+ case "autonumber":
37361
+ return "text";
37362
+ default: {
37363
+ const _exhaustive = field;
37364
+ void _exhaustive;
37365
+ return "json";
37313
37366
  }
37314
37367
  }
37315
37368
  }
37316
- function datetime3(format2) {
37317
- return format2 === "datetime" || format2 === "datetime_range";
37369
+ function formulaOutputType(field) {
37370
+ switch (field.formula.output_type) {
37371
+ case "number":
37372
+ return "number";
37373
+ case "boolean":
37374
+ return "boolean";
37375
+ case "date":
37376
+ return "date";
37377
+ case "datetime":
37378
+ return "datetime";
37379
+ case "text":
37380
+ return "text";
37381
+ case "select":
37382
+ return "select";
37383
+ default:
37384
+ return "json";
37385
+ }
37386
+ }
37387
+ function rollupColumnType(field) {
37388
+ if (rollupOutputType(field.aggregate_option.operation) === "number") return "number";
37389
+ return field.aggregate_field_format === "datetime" || field.aggregate_field_format === "datetime_range" ? "datetime" : "date";
37390
+ }
37391
+ function lookupOutputType(field) {
37392
+ const t = field.lookup_field_type;
37393
+ if (!t) return "json";
37394
+ switch (t) {
37395
+ case "text":
37396
+ return "text";
37397
+ case "number":
37398
+ return "number";
37399
+ case "boolean":
37400
+ return "boolean";
37401
+ case "date":
37402
+ return field.lookup_field_format === "datetime" || field.lookup_field_format === "datetime_range" ? "datetime" : "date";
37403
+ case "select":
37404
+ return "select";
37405
+ case "select_member":
37406
+ return "select_member";
37407
+ case "select_record_link":
37408
+ return "select_record_link";
37409
+ case "files":
37410
+ return "files";
37411
+ default:
37412
+ return "json";
37413
+ }
37318
37414
  }
37319
- function linkedOf(entity, entities, link) {
37320
- const field = entity.fields.find((one) => one.alias === link);
37321
- return field?.type === "select_record_link" ? entities.find((one) => one.alias === field.target_entity) : void 0;
37415
+
37416
+ // ../shared/src/schemas/app_model_books.ts
37417
+ function fieldColumnType(field, entity, entities) {
37418
+ const index = entities.findIndex((one) => one.alias === entity.alias);
37419
+ const synthesized = synthesizedOf(entities)[index]?.[entity.fields.findIndex((one) => one.alias === field.alias)];
37420
+ return synthesized === void 0 ? fail2(`fieldColumnType: "${entity.alias}.${field.alias}" is not a field of the model.`) : fieldTypeToColumnType(synthesized);
37421
+ }
37422
+ var SYNTHESIZED = /* @__PURE__ */ new WeakMap();
37423
+ function synthesizedOf(entities) {
37424
+ const held = SYNTHESIZED.get(entities);
37425
+ if (held !== void 0) return held;
37426
+ const minted = syntheticFields(entities);
37427
+ SYNTHESIZED.set(entities, minted);
37428
+ return minted;
37322
37429
  }
37323
37430
  function holdsSeveral(field) {
37324
37431
  return fieldHoldsSeveral(field) || field.type === "select_member" && field.multi === true;
@@ -40125,8 +40232,8 @@ function resultSideEffects(result) {
40125
40232
  }
40126
40233
 
40127
40234
  // src/version.ts
40128
- var VERSION = "0.278.0";
40129
- var APP_SDK_VERSION = "0.106.1";
40235
+ var VERSION = "0.279.1";
40236
+ var APP_SDK_VERSION = "0.107.0";
40130
40237
 
40131
40238
  // src/timezone.ts
40132
40239
  function machineTimezone() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/cli",
3
- "version": "0.278.0",
3
+ "version": "0.279.1",
4
4
  "description": "Lotics SDK and CLI for AI agents",
5
5
  "type": "module",
6
6
  "bin": {