@rex0220/kintone-sql-tools 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist-cli/ksql.js CHANGED
@@ -3508,52 +3508,91 @@ function resolveFieldRef(row, field) {
3508
3508
  }
3509
3509
 
3510
3510
  // src/engine/evalWhere.ts
3511
- function evalWhere(expr, row) {
3511
+ function evalWhere(expr, row, resolveFieldType) {
3512
3512
  switch (expr.type) {
3513
3513
  case "BINARY":
3514
- return evalBinary(expr, row);
3514
+ return evalBinary(expr, row, resolveFieldType);
3515
3515
  case "NULL_CHECK":
3516
3516
  return evalNullCheck(expr, row);
3517
3517
  case "LOGICAL":
3518
- return evalLogical(expr, row);
3518
+ return evalLogical(expr, row, resolveFieldType);
3519
3519
  case "NOT":
3520
- return !evalWhere(expr.expr, row);
3520
+ return !evalWhere(expr.expr, row, resolveFieldType);
3521
3521
  case "GROUP":
3522
- return evalWhere(expr.expr, row);
3522
+ return evalWhere(expr.expr, row, resolveFieldType);
3523
3523
  case "EXISTS": {
3524
3524
  const exists = expr.resolved;
3525
3525
  return expr.not ? !exists : exists;
3526
3526
  }
3527
3527
  }
3528
3528
  }
3529
- function evalBinary(expr, row) {
3530
- const left = resolveField(expr.left, row);
3531
- return evalOp(expr.op, left, expr.right, row);
3529
+ function evalBinary(expr, row, resolveFieldType) {
3530
+ const left = resolveField(expr.left, row, resolveFieldType);
3531
+ const fieldType = expr.left.type === "FIELD" ? resolveFieldType?.(expr.left) : void 0;
3532
+ return evalOp(expr.op, left, expr.right, row, fieldType, resolveFieldType);
3532
3533
  }
3533
- function evalOp(op, leftStr, right, row) {
3534
+ function evalOp(op, leftStr, right, row, fieldType, resolveFieldType) {
3534
3535
  if (op === "IN" || op === "NOT_IN") {
3536
+ let values = null;
3535
3537
  if (right.type === "IN_LIST") {
3536
3538
  assertResolvedInListValues2(right.values);
3537
- const contains = right.values.some((v) => leftStr === String(v.value));
3538
- return op === "IN" ? contains : !contains;
3539
+ values = new Set(right.values.map((v) => String(v.value)));
3539
3540
  }
3540
3541
  if (right.type === "SUBQUERY_IN_LIST") {
3541
- const contains = right.resolved.has(leftStr);
3542
- return op === "IN" ? contains : !contains;
3542
+ values = right.resolved;
3543
3543
  }
3544
- return op === "NOT_IN";
3544
+ if (values === null) return op === "NOT_IN";
3545
+ const contains = typedInContains(leftStr, values, fieldType);
3546
+ return op === "IN" ? contains : !contains;
3545
3547
  }
3546
3548
  if (op === "LIKE") {
3547
- const pattern = resolveValue(right, row);
3549
+ const pattern = resolveValue(right, row, resolveFieldType);
3548
3550
  return matchLike(leftStr, pattern);
3549
3551
  }
3550
3552
  if (op === "NOT_LIKE") {
3551
- const pattern = resolveValue(right, row);
3553
+ const pattern = resolveValue(right, row, resolveFieldType);
3552
3554
  return !matchLike(leftStr, pattern);
3553
3555
  }
3554
- const rightStr = resolveValue(right, row);
3556
+ const rightStr = resolveValue(right, row, resolveFieldType);
3555
3557
  return compareScalarValues(op, leftStr, rightStr);
3556
3558
  }
3559
+ var STRING_ARRAY_FIELD_TYPES = /* @__PURE__ */ new Set(["CHECK_BOX", "MULTI_SELECT"]);
3560
+ var OBJECT_ARRAY_FIELD_TYPES = /* @__PURE__ */ new Set([
3561
+ "USER_SELECT",
3562
+ "ORGANIZATION_SELECT",
3563
+ "GROUP_SELECT",
3564
+ "STATUS_ASSIGNEE"
3565
+ ]);
3566
+ var SINGLE_OBJECT_FIELD_TYPES = /* @__PURE__ */ new Set(["CREATOR", "MODIFIER"]);
3567
+ function typedInContains(leftStr, values, fieldType) {
3568
+ const fallback = () => values.has(leftStr);
3569
+ if (fieldType === void 0) return fallback();
3570
+ let parsed;
3571
+ if (STRING_ARRAY_FIELD_TYPES.has(fieldType) || OBJECT_ARRAY_FIELD_TYPES.has(fieldType) || SINGLE_OBJECT_FIELD_TYPES.has(fieldType)) {
3572
+ try {
3573
+ parsed = JSON.parse(leftStr);
3574
+ } catch {
3575
+ return fallback();
3576
+ }
3577
+ } else {
3578
+ return fallback();
3579
+ }
3580
+ if (STRING_ARRAY_FIELD_TYPES.has(fieldType)) {
3581
+ if (!Array.isArray(parsed) || !parsed.every((item) => typeof item === "string")) {
3582
+ return fallback();
3583
+ }
3584
+ return parsed.some((item) => values.has(item));
3585
+ }
3586
+ if (OBJECT_ARRAY_FIELD_TYPES.has(fieldType)) {
3587
+ if (!Array.isArray(parsed) || !parsed.every(hasStringCode)) return fallback();
3588
+ return parsed.some((item) => values.has(item.code));
3589
+ }
3590
+ if (!hasStringCode(parsed)) return fallback();
3591
+ return values.has(parsed.code);
3592
+ }
3593
+ function hasStringCode(value) {
3594
+ return value !== null && typeof value === "object" && !Array.isArray(value) && typeof value.code === "string";
3595
+ }
3557
3596
  function assertResolvedInListValues2(values) {
3558
3597
  const unresolved = values.find((item) => item.type === "VARIABLE");
3559
3598
  if (unresolved?.type === "VARIABLE") {
@@ -3564,20 +3603,20 @@ function evalNullCheck(expr, row) {
3564
3603
  const val = resolveField(expr.field, row);
3565
3604
  return expr.not ? val !== "" : val === "";
3566
3605
  }
3567
- function evalLogical(expr, row) {
3606
+ function evalLogical(expr, row, resolveFieldType) {
3568
3607
  if (expr.op === "AND") {
3569
- return evalWhere(expr.left, row) && evalWhere(expr.right, row);
3608
+ return evalWhere(expr.left, row, resolveFieldType) && evalWhere(expr.right, row, resolveFieldType);
3570
3609
  }
3571
- return evalWhere(expr.left, row) || evalWhere(expr.right, row);
3610
+ return evalWhere(expr.left, row, resolveFieldType) || evalWhere(expr.right, row, resolveFieldType);
3572
3611
  }
3573
- function resolveField(field, row) {
3612
+ function resolveField(field, row, resolveFieldType) {
3574
3613
  if (field.type === "FUNC_FIELD") return evalStringFunc(field.expr, row);
3575
3614
  if (field.type === "ARITH_FIELD") return String(evalArithExpr(field.expr, row));
3576
- if (field.type === "CASE_FIELD") return evalCaseWhen(field.expr, row);
3615
+ if (field.type === "CASE_FIELD") return evalCaseWhen(field.expr, row, resolveFieldType);
3577
3616
  const key = field.tableAlias ? `${field.tableAlias}.${field.field}` : field.field;
3578
3617
  return resolveFieldRef(row, key);
3579
3618
  }
3580
- function resolveValue(value, row) {
3619
+ function resolveValue(value, row, resolveFieldType) {
3581
3620
  switch (value.type) {
3582
3621
  case "VARIABLE":
3583
3622
  throw new Error(`ParseError: unresolved batch variable @${value.name}.`);
@@ -3600,14 +3639,14 @@ function resolveValue(value, row) {
3600
3639
  if (value.expr.type === "STRING_FUNC") return evalStringFunc(value.expr, row);
3601
3640
  return String(evalArithExpr(value.expr, row));
3602
3641
  case "CASE_VALUE":
3603
- return evalCaseWhen(value.expr, row);
3642
+ return evalCaseWhen(value.expr, row, resolveFieldType);
3604
3643
  case "ARRAY":
3605
3644
  return value.elements.map((e) => e.value).join(",");
3606
3645
  }
3607
3646
  }
3608
- function evalCaseWhen(expr, row) {
3647
+ function evalCaseWhen(expr, row, resolveFieldType) {
3609
3648
  for (const branch of expr.branches) {
3610
- if (evalWhere(branch.condition, row)) {
3649
+ if (evalWhere(branch.condition, row, resolveFieldType)) {
3611
3650
  return evalCaseResult(branch.result, row);
3612
3651
  }
3613
3652
  }
@@ -4274,9 +4313,9 @@ function applyJoin(leftRows, rightRows, join2) {
4274
4313
  }
4275
4314
  return result;
4276
4315
  }
4277
- function applyFilter(rows, where) {
4316
+ function applyFilter(rows, where, resolveFieldType) {
4278
4317
  if (where === null) return rows;
4279
- return rows.filter((row) => evalWhere(where, row));
4318
+ return rows.filter((row) => evalWhere(where, row, resolveFieldType));
4280
4319
  }
4281
4320
  function hasAggregateColumns(columns) {
4282
4321
  return columns.some(
@@ -4402,9 +4441,9 @@ function aggregateSyntheticName2(func, distinct, arg) {
4402
4441
  const argStr = aggregateArgLabel(arg);
4403
4442
  return distinct ? `${func}(DISTINCT ${argStr})` : `${func}(${argStr})`;
4404
4443
  }
4405
- function applyHaving(rows, having) {
4444
+ function applyHaving(rows, having, resolveFieldType) {
4406
4445
  if (having === null) return rows;
4407
- return rows.filter((row) => evalWhere(having, row));
4446
+ return rows.filter((row) => evalWhere(having, row, resolveFieldType));
4408
4447
  }
4409
4448
  function applyDistinct(rows, columns) {
4410
4449
  if (rows.length === 0) return rows;
@@ -4529,7 +4568,7 @@ function applyLimit(rows, limit, offset) {
4529
4568
  if (limit === null) return rows.slice(start);
4530
4569
  return rows.slice(start, start + limit);
4531
4570
  }
4532
- function project(rows, columns, scalarCache) {
4571
+ function project(rows, columns, scalarCache, resolveFieldType) {
4533
4572
  if (columns.length === 1 && columns[0].type === "WILDCARD") {
4534
4573
  const projected2 = rows.map((row) => stripParentShortcutColumns(row));
4535
4574
  const cols = projected2.length > 0 ? Object.keys(projected2[0]) : [];
@@ -4590,7 +4629,7 @@ function project(rows, columns, scalarCache) {
4590
4629
  }
4591
4630
  case "CASE_COL": {
4592
4631
  const key = outputKeys?.[colIdx] ?? col.alias ?? "case";
4593
- out[key] = evalCaseWhen(col.expr, row);
4632
+ out[key] = evalCaseWhen(col.expr, row, resolveFieldType);
4594
4633
  if (outputKeys === null && rowIdx === 0) orderedKeys.push(key);
4595
4634
  break;
4596
4635
  }
@@ -4726,7 +4765,15 @@ function resolveAggInStringFuncExpr(expr, rows) {
4726
4765
  };
4727
4766
  }
4728
4767
  function runFullScan(input) {
4729
- const { stmt, tables, scalarCache, optionOrders, sortKinds } = input;
4768
+ const {
4769
+ stmt,
4770
+ tables,
4771
+ scalarCache,
4772
+ optionOrders,
4773
+ sortKinds,
4774
+ fieldTypeResolver,
4775
+ havingFieldTypeResolver
4776
+ } = input;
4730
4777
  let rows = [];
4731
4778
  const mainAlias = stmt.from.alias;
4732
4779
  const mainRecords = tables.get(mainAlias) ?? tables.get(null) ?? [];
@@ -4737,17 +4784,17 @@ function runFullScan(input) {
4737
4784
  const rightRows = rightRecords.map((r) => flatten(r, rightAlias));
4738
4785
  rows = applyJoin(rows, rightRows, join2);
4739
4786
  }
4740
- rows = applyFilter(rows, stmt.where);
4787
+ rows = applyFilter(rows, stmt.where, fieldTypeResolver);
4741
4788
  if (stmt.groupBy.length > 0 || hasAggregateColumns(stmt.columns)) {
4742
4789
  rows = applyGroupBy(rows, stmt.groupBy, stmt.columns);
4743
4790
  }
4744
- rows = applyHaving(rows, stmt.having);
4791
+ rows = applyHaving(rows, stmt.having, havingFieldTypeResolver);
4745
4792
  if (stmt.distinct) {
4746
4793
  rows = applyDistinct(rows, stmt.columns);
4747
4794
  }
4748
4795
  rows = applyOrderBy(rows, stmt.orderBy, optionOrders, sortKinds);
4749
4796
  rows = applyLimit(rows, stmt.limit, stmt.offset);
4750
- return project(rows, stmt.columns, scalarCache);
4797
+ return project(rows, stmt.columns, scalarCache, fieldTypeResolver);
4751
4798
  }
4752
4799
 
4753
4800
  // src/converter/subtableAdapter.ts
@@ -5280,6 +5327,7 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache) {
5280
5327
  if (isNoFromSelect(stmt)) {
5281
5328
  return executeNoFromSelect(stmt);
5282
5329
  }
5330
+ await resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache);
5283
5331
  const mode = resolveSelectMode(stmt);
5284
5332
  await validateSelectFieldCodes(stmt, mode, client, cacheContext);
5285
5333
  if (mode === "SIMPLE") {
@@ -5338,6 +5386,8 @@ function executeNoFromSelect(stmt) {
5338
5386
  }
5339
5387
  async function executeSimpleSelect(stmt, client, options, cacheContext) {
5340
5388
  const params = selectToKintoneParams(stmt);
5389
+ const typedInFieldTypes = await loadTypedInFieldTypes(stmt, client, cacheContext);
5390
+ const fieldTypeResolvers = buildSelectFieldTypeResolvers(stmt, typedInFieldTypes);
5341
5391
  const maxRecords = options.maxRecords ?? 1e4;
5342
5392
  const warnings = /* @__PURE__ */ new Set();
5343
5393
  const onLimit = options.onLimitReached ?? "error";
@@ -5374,7 +5424,12 @@ async function executeSimpleSelect(stmt, client, options, cacheContext) {
5374
5424
  rows = applyOrderBy(rows, stmt.orderBy, optionOrders, sortKinds);
5375
5425
  rows = applyLimit(rows, stmt.limit, stmt.offset);
5376
5426
  }
5377
- const { rows: projected, columns } = project(rows, stmt.columns);
5427
+ const { rows: projected, columns } = project(
5428
+ rows,
5429
+ stmt.columns,
5430
+ void 0,
5431
+ fieldTypeResolvers.row
5432
+ );
5378
5433
  return { type: "SELECT", rows: projected, columns, rowCount: projected.length, warnings: [...warnings] };
5379
5434
  }
5380
5435
  async function validateSelectFieldCodes(stmt, mode, client, cacheContext) {
@@ -5447,6 +5502,108 @@ async function loadNumericPushdownFieldTypes(stmt, client, cacheContext) {
5447
5502
  const entries = await Promise.all([...appIds].map(async (appId) => [appId, await getFieldTypeMap(appId, client, cacheContext)]));
5448
5503
  return new Map(entries);
5449
5504
  }
5505
+ function collectTypedInFieldRefs(expr, out) {
5506
+ if (expr === null) return;
5507
+ switch (expr.type) {
5508
+ case "BINARY":
5509
+ if ((expr.op === "IN" || expr.op === "NOT_IN") && expr.left.type === "FIELD") {
5510
+ out.push(expr.left);
5511
+ }
5512
+ if (expr.left.type === "CASE_FIELD") collectCaseTypedInFieldRefs(expr.left.expr, out);
5513
+ if (expr.right.type === "CASE_VALUE") collectCaseTypedInFieldRefs(expr.right.expr, out);
5514
+ return;
5515
+ case "LOGICAL":
5516
+ collectTypedInFieldRefs(expr.left, out);
5517
+ collectTypedInFieldRefs(expr.right, out);
5518
+ return;
5519
+ case "NOT":
5520
+ case "GROUP":
5521
+ collectTypedInFieldRefs(expr.expr, out);
5522
+ return;
5523
+ case "NULL_CHECK":
5524
+ case "EXISTS":
5525
+ return;
5526
+ }
5527
+ }
5528
+ function collectCaseTypedInFieldRefs(expr, out) {
5529
+ for (const branch of expr.branches) collectTypedInFieldRefs(branch.condition, out);
5530
+ }
5531
+ function collectSelectTypedInFieldRefs(stmt) {
5532
+ const refs = [];
5533
+ collectTypedInFieldRefs(stmt.where, refs);
5534
+ collectTypedInFieldRefs(stmt.having, refs);
5535
+ for (const column of stmt.columns) {
5536
+ if (column.type === "CASE_COL") collectCaseTypedInFieldRefs(column.expr, refs);
5537
+ }
5538
+ return refs;
5539
+ }
5540
+ function findTableForAlias(stmt, alias) {
5541
+ return [stmt.from, ...stmt.joins.map((join2) => join2.table)].find((table) => table.alias === alias);
5542
+ }
5543
+ function physicalSelectTables(stmt) {
5544
+ return [stmt.from, ...stmt.joins.map((join2) => join2.table)].filter((table) => table.cteName === null);
5545
+ }
5546
+ async function loadTypedInFieldTypes(stmt, client, cacheContext) {
5547
+ const refs = collectSelectTypedInFieldRefs(stmt);
5548
+ if (refs.length === 0) return /* @__PURE__ */ new Map();
5549
+ const appIds = /* @__PURE__ */ new Set();
5550
+ const physicalTables = physicalSelectTables(stmt);
5551
+ for (const ref of refs) {
5552
+ if (ref.tableAlias !== null) {
5553
+ if (ref.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
5554
+ appIds.add(stmt.from.appId);
5555
+ continue;
5556
+ }
5557
+ const table = findTableForAlias(stmt, ref.tableAlias);
5558
+ if (table && table.cteName === null) appIds.add(table.appId);
5559
+ continue;
5560
+ }
5561
+ if (stmt.joins.length === 0) {
5562
+ if (stmt.from.cteName === null) appIds.add(stmt.from.appId);
5563
+ continue;
5564
+ }
5565
+ for (const table of physicalTables) appIds.add(table.appId);
5566
+ }
5567
+ const entries = await Promise.all([...appIds].map(async (appId) => [appId, await getFieldTypeMap(appId, client, cacheContext)]));
5568
+ return new Map(entries);
5569
+ }
5570
+ function fieldCodeForTypeLookup(table, field) {
5571
+ if (table.subtableCode && field.startsWith("_p.")) return field.slice(3);
5572
+ return field;
5573
+ }
5574
+ function buildSelectFieldTypeResolvers(stmt, fieldTypesByApp) {
5575
+ const tables = [stmt.from, ...stmt.joins.map((join2) => join2.table)];
5576
+ const physicalTables = tables.filter((table) => table.cteName === null);
5577
+ const outputAliases = new Set(
5578
+ stmt.columns.map((column) => "alias" in column ? column.alias : null).filter((alias) => alias !== null)
5579
+ );
5580
+ const row = (field) => {
5581
+ if (field.tableAlias !== null) {
5582
+ if (field.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
5583
+ return fieldTypesByApp.get(stmt.from.appId)?.get(field.field);
5584
+ }
5585
+ const table2 = tables.find((candidate) => candidate.alias === field.tableAlias);
5586
+ if (!table2 || table2.cteName !== null) return void 0;
5587
+ return fieldTypesByApp.get(table2.appId)?.get(fieldCodeForTypeLookup(table2, field.field));
5588
+ }
5589
+ if (stmt.joins.length === 0) {
5590
+ if (stmt.from.cteName !== null) return void 0;
5591
+ return fieldTypesByApp.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, field.field));
5592
+ }
5593
+ if (tables.some((table2) => table2.cteName !== null)) return void 0;
5594
+ const matches = physicalTables.filter(
5595
+ (table2) => fieldTypesByApp.get(table2.appId)?.has(fieldCodeForTypeLookup(table2, field.field))
5596
+ );
5597
+ if (matches.length !== 1) return void 0;
5598
+ const table = matches[0];
5599
+ return fieldTypesByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, field.field));
5600
+ };
5601
+ const having = (field) => {
5602
+ if (field.tableAlias === null && outputAliases.has(field.field)) return void 0;
5603
+ return row(field);
5604
+ };
5605
+ return { row, having };
5606
+ }
5450
5607
  async function executeFullScanSelect(stmt, client, options, cacheContext, cteCache) {
5451
5608
  const maxRecords = options.maxRecords ?? 1e4;
5452
5609
  const warnings = /* @__PURE__ */ new Set();
@@ -5455,7 +5612,11 @@ async function executeFullScanSelect(stmt, client, options, cacheContext, cteCac
5455
5612
  resolveSubqueries(stmt.where, client, options, cacheContext, cteCache),
5456
5613
  resolveSubqueries(stmt.having, client, options, cacheContext, cteCache)
5457
5614
  ]);
5458
- const pushdownFieldTypes = await loadNumericPushdownFieldTypes(stmt, client, cacheContext);
5615
+ const [pushdownFieldTypes, typedInFieldTypes] = await Promise.all([
5616
+ loadNumericPushdownFieldTypes(stmt, client, cacheContext),
5617
+ loadTypedInFieldTypes(stmt, client, cacheContext)
5618
+ ]);
5619
+ const fieldTypeResolvers = buildSelectFieldTypeResolvers(stmt, typedInFieldTypes);
5459
5620
  const mainPushDown = extractMainSafePushdown(
5460
5621
  stmt,
5461
5622
  pushdownFieldTypes.get(stmt.from.appId)
@@ -5544,7 +5705,15 @@ async function executeFullScanSelect(stmt, client, options, cacheContext, cteCac
5544
5705
  }));
5545
5706
  const scalarCache = await scalarCachePromise;
5546
5707
  const { optionOrders, sortKinds } = await orderByMetaPromise;
5547
- const { rows, columns } = runFullScan({ tables, stmt, scalarCache, optionOrders, sortKinds });
5708
+ const { rows, columns } = runFullScan({
5709
+ tables,
5710
+ stmt,
5711
+ scalarCache,
5712
+ optionOrders,
5713
+ sortKinds,
5714
+ fieldTypeResolver: fieldTypeResolvers.row,
5715
+ havingFieldTypeResolver: fieldTypeResolvers.having
5716
+ });
5548
5717
  return { type: "SELECT", rows, columns, rowCount: rows.length, warnings: [...warnings] };
5549
5718
  }
5550
5719
  async function executeUnion(stmt, client, options, cacheContext) {
@@ -5700,8 +5869,11 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
5700
5869
  const parallel = options.fetchParallel ?? 1;
5701
5870
  await Promise.all([
5702
5871
  resolveSubqueries(stmt.where, client, options, cacheContext, cteCache),
5703
- resolveSubqueries(stmt.having, client, options, cacheContext, cteCache)
5872
+ resolveSubqueries(stmt.having, client, options, cacheContext, cteCache),
5873
+ resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache)
5704
5874
  ]);
5875
+ const typedInFieldTypes = await loadTypedInFieldTypes(stmt, client, cacheContext);
5876
+ const fieldTypeResolvers = buildSelectFieldTypeResolvers(stmt, typedInFieldTypes);
5705
5877
  const scalarCachePromise = resolveScalarColumns(stmt.columns, client, options, cacheContext, cteCache);
5706
5878
  const orderByMetaPromise = buildOrderByMetaForSelect(stmt, client, cacheContext);
5707
5879
  scalarCachePromise.catch(() => {
@@ -5756,7 +5928,15 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
5756
5928
  await Promise.all(joinFetches);
5757
5929
  const scalarCache = await scalarCachePromise;
5758
5930
  const { optionOrders, sortKinds } = await orderByMetaPromise;
5759
- const { rows, columns } = runFullScan({ tables, stmt, scalarCache, optionOrders, sortKinds });
5931
+ const { rows, columns } = runFullScan({
5932
+ tables,
5933
+ stmt,
5934
+ scalarCache,
5935
+ optionOrders,
5936
+ sortKinds,
5937
+ fieldTypeResolver: fieldTypeResolvers.row,
5938
+ havingFieldTypeResolver: fieldTypeResolvers.having
5939
+ });
5760
5940
  return { type: "SELECT", rows, columns, rowCount: rows.length, warnings: [...warnings] };
5761
5941
  }
5762
5942
  function processRowToKintoneRecord(row) {
@@ -6253,6 +6433,16 @@ async function executeUpsert(stmt, client, options, cacheContext) {
6253
6433
  updatedCount: toUpdate.length
6254
6434
  };
6255
6435
  }
6436
+ async function buildSubtableFieldTypeResolver(appId, typedInRefs, client, cacheContext) {
6437
+ if (typedInRefs.length === 0) return void 0;
6438
+ const fieldTypes = await getFieldTypeMap(appId, client, cacheContext);
6439
+ return (field) => {
6440
+ if (field.tableAlias !== null && field.tableAlias !== "_p") return void 0;
6441
+ if (field.tableAlias === "_p") return fieldTypes.get(field.field);
6442
+ const code = field.field.startsWith("_p.") ? field.field.slice(3) : field.field;
6443
+ return fieldTypes.get(code);
6444
+ };
6445
+ }
6256
6446
  async function executeInsertSubtable(stmt, client, options, _cacheContext) {
6257
6447
  const subtableCode = stmt.subtableCode;
6258
6448
  const pidIndex = stmt.fields.indexOf("_pid");
@@ -6293,11 +6483,24 @@ async function executeInsertSubtable(stmt, client, options, _cacheContext) {
6293
6483
  }
6294
6484
  return { type: "INSERT", createdIds: [], insertedCount: stmt.values.length };
6295
6485
  }
6296
- async function executeUpdateSubtable(stmt, client, options, _cacheContext) {
6486
+ async function executeUpdateSubtable(stmt, client, options, cacheContext) {
6297
6487
  const subtableCode = stmt.subtableCode;
6298
6488
  if (!hasRidCondition(stmt.where)) {
6299
6489
  throw new Error("\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB UPDATE \u306B\u306F _rid \u6761\u4EF6\u304C\u5FC5\u9808\u3067\u3059");
6300
6490
  }
6491
+ const typedInRefs = [];
6492
+ collectTypedInFieldRefs(stmt.where, typedInRefs);
6493
+ for (const assignment of stmt.assignments) {
6494
+ if (assignment.value.type === "CASE_VALUE") {
6495
+ collectCaseTypedInFieldRefs(assignment.value.expr, typedInRefs);
6496
+ }
6497
+ }
6498
+ const resolveFieldType = await buildSubtableFieldTypeResolver(
6499
+ stmt.appId,
6500
+ typedInRefs,
6501
+ client,
6502
+ cacheContext
6503
+ );
6301
6504
  const parents = await fetchAll(
6302
6505
  client.getRecords,
6303
6506
  stmt.appId,
@@ -6306,7 +6509,7 @@ async function executeUpdateSubtable(stmt, client, options, _cacheContext) {
6306
6509
  { maxRecords: options.maxRecords ?? 1e4, parallel: options.fetchParallel ?? 1 }
6307
6510
  );
6308
6511
  const expanded = expandRowsForSubtableDml(parents, subtableCode);
6309
- const targets = expanded.filter((r) => evalWhere(stmt.where, r.flat));
6512
+ const targets = expanded.filter((r) => evalWhere(stmt.where, r.flat, resolveFieldType));
6310
6513
  if (options.confirm) {
6311
6514
  const ok = await options.confirm(targets.length, "UPDATE");
6312
6515
  if (!ok) throw new OperationCancelledError("UPDATE", targets.length);
@@ -6326,7 +6529,7 @@ async function executeUpdateSubtable(stmt, client, options, _cacheContext) {
6326
6529
  if (a.field.startsWith("_")) {
6327
6530
  throw new Error(`\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB UPDATE \u3067\u30B7\u30B9\u30C6\u30E0\u5217\u300C${a.field}\u300D\u306F\u66F4\u65B0\u3067\u304D\u307E\u305B\u3093`);
6328
6531
  }
6329
- updates[a.field] = { value: evalAssignmentValueForSubtable(a.value, t.flat) };
6532
+ updates[a.field] = { value: evalAssignmentValueForSubtable(a.value, t.flat, resolveFieldType) };
6330
6533
  }
6331
6534
  byRid.set(t.rowId, updates);
6332
6535
  }
@@ -6348,11 +6551,19 @@ async function executeUpdateSubtable(stmt, client, options, _cacheContext) {
6348
6551
  }
6349
6552
  return { type: "UPDATE", updatedCount: targets.length };
6350
6553
  }
6351
- async function executeDeleteSubtable(stmt, client, options, _cacheContext) {
6554
+ async function executeDeleteSubtable(stmt, client, options, cacheContext) {
6352
6555
  const subtableCode = stmt.subtableCode;
6353
6556
  if (!hasRidCondition(stmt.where)) {
6354
6557
  throw new Error("\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB DELETE \u306B\u306F _rid \u6761\u4EF6\u304C\u5FC5\u9808\u3067\u3059");
6355
6558
  }
6559
+ const typedInRefs = [];
6560
+ collectTypedInFieldRefs(stmt.where, typedInRefs);
6561
+ const resolveFieldType = await buildSubtableFieldTypeResolver(
6562
+ stmt.appId,
6563
+ typedInRefs,
6564
+ client,
6565
+ cacheContext
6566
+ );
6356
6567
  const parents = await fetchAll(
6357
6568
  client.getRecords,
6358
6569
  stmt.appId,
@@ -6361,7 +6572,7 @@ async function executeDeleteSubtable(stmt, client, options, _cacheContext) {
6361
6572
  { maxRecords: options.maxRecords ?? 1e4, parallel: options.fetchParallel ?? 1 }
6362
6573
  );
6363
6574
  const expanded = expandRowsForSubtableDml(parents, subtableCode);
6364
- const targets = expanded.filter((r) => evalWhere(stmt.where, r.flat));
6575
+ const targets = expanded.filter((r) => evalWhere(stmt.where, r.flat, resolveFieldType));
6365
6576
  if (options.confirm) {
6366
6577
  const ok = await options.confirm(targets.length, "DELETE");
6367
6578
  if (!ok) throw new OperationCancelledError("DELETE", targets.length);
@@ -6476,11 +6687,11 @@ function buildSubtableReorderPutParams(appId, parentId, revision, subtableCode,
6476
6687
  ]
6477
6688
  };
6478
6689
  }
6479
- function evalAssignmentValueForSubtable(value, row) {
6690
+ function evalAssignmentValueForSubtable(value, row, resolveFieldType) {
6480
6691
  if (value.type === "STRING") return value.value;
6481
6692
  if (value.type === "NUMBER") return String(value.value);
6482
6693
  if (value.type === "ARITH") return String(evalArithExpr(value, row));
6483
- if (value.type === "CASE_VALUE") return evalCaseWhen(value.expr, row);
6694
+ if (value.type === "CASE_VALUE") return evalCaseWhen(value.expr, row, resolveFieldType);
6484
6695
  throw new Error(`${value.type} \u306F\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB UPDATE \u306E\u5024\u3068\u3057\u3066\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093`);
6485
6696
  }
6486
6697
  function valueToString(value) {
@@ -6512,7 +6723,15 @@ function hasRidCondition(where) {
6512
6723
  return false;
6513
6724
  }
6514
6725
  }
6515
- async function executeReorder(stmt, client, options, _cacheContext) {
6726
+ async function executeReorder(stmt, client, options, cacheContext) {
6727
+ const typedInRefs = [];
6728
+ collectTypedInFieldRefs(stmt.where, typedInRefs);
6729
+ const resolveFieldType = await buildSubtableFieldTypeResolver(
6730
+ stmt.appId,
6731
+ typedInRefs,
6732
+ client,
6733
+ cacheContext
6734
+ );
6516
6735
  const parents = await fetchAll(
6517
6736
  client.getRecords,
6518
6737
  stmt.appId,
@@ -6521,7 +6740,7 @@ async function executeReorder(stmt, client, options, _cacheContext) {
6521
6740
  { maxRecords: options.maxRecords ?? 1e4, parallel: options.fetchParallel ?? 1 }
6522
6741
  );
6523
6742
  const expanded = expandRowsForSubtableDml(parents, stmt.subtableCode);
6524
- const targetParentIds = stmt.all ? new Set(parents.map((p) => String(p["$id"]?.value ?? "")).filter((id) => id !== "")) : new Set(expanded.filter((r) => stmt.where && evalWhere(stmt.where, r.flat)).map((r) => r.parentId));
6743
+ const targetParentIds = stmt.all ? new Set(parents.map((p) => String(p["$id"]?.value ?? "")).filter((id) => id !== "")) : new Set(expanded.filter((r) => stmt.where && evalWhere(stmt.where, r.flat, resolveFieldType)).map((r) => r.parentId));
6525
6744
  if (options.confirm) {
6526
6745
  const ok = await options.confirm(targetParentIds.size, "UPDATE");
6527
6746
  if (!ok) throw new OperationCancelledError("UPDATE", targetParentIds.size);
@@ -6666,6 +6885,16 @@ async function resolveSubqueries(where, client, options, cacheContext, cteCache)
6666
6885
  collectSubqueryTasks(where, client, options, cacheContext, tasks, cteCache);
6667
6886
  await Promise.all(tasks);
6668
6887
  }
6888
+ async function resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache) {
6889
+ const tasks = [];
6890
+ for (const column of stmt.columns) {
6891
+ if (column.type !== "CASE_COL") continue;
6892
+ for (const branch of column.expr.branches) {
6893
+ tasks.push(resolveSubqueries(branch.condition, client, options, cacheContext, cteCache));
6894
+ }
6895
+ }
6896
+ await Promise.all(tasks);
6897
+ }
6669
6898
  function runSubquery(query, client, options, cacheContext, cteCache) {
6670
6899
  if (cteCache !== void 0 && cteCache.size > 0) {
6671
6900
  return executeQueryWithCte(query, client, options, cteCache, cacheContext);
@@ -7595,6 +7824,42 @@ function clampInt(v, min, max) {
7595
7824
  return Math.max(min, Math.min(max, Math.trunc(v)));
7596
7825
  }
7597
7826
 
7827
+ // src/core/formFieldInfo.ts
7828
+ function flattenFormFieldProperties(properties) {
7829
+ const out = [];
7830
+ for (const field of Object.values(properties)) {
7831
+ out.push({
7832
+ code: field.code,
7833
+ label: field.label,
7834
+ fieldType: field.type,
7835
+ optionOrder: toOptionOrderMap(field.options),
7836
+ sortKind: detectSortKind(field.type, field.format)
7837
+ });
7838
+ if (field.fields) out.push(...flattenFormFieldProperties(field.fields));
7839
+ }
7840
+ return out;
7841
+ }
7842
+ function toOptionOrderMap(options) {
7843
+ if (!options || typeof options !== "object") return void 0;
7844
+ const order = {};
7845
+ let hasAny = false;
7846
+ for (const [label, meta] of Object.entries(options)) {
7847
+ const n = Number(meta?.index);
7848
+ if (!Number.isFinite(n)) continue;
7849
+ order[label] = n;
7850
+ hasAny = true;
7851
+ }
7852
+ return hasAny ? order : void 0;
7853
+ }
7854
+ function detectSortKind(fieldType, calcFormat) {
7855
+ if (fieldType === "NUMBER" || fieldType === "RECORD_NUMBER") return "number";
7856
+ if (fieldType === "CALC") {
7857
+ if (calcFormat === "NUMBER" || calcFormat === "NUMBER_DIGIT") return "number";
7858
+ return "string";
7859
+ }
7860
+ return void 0;
7861
+ }
7862
+
7598
7863
  // src/cli/nodeKintoneClient.ts
7599
7864
  function createNodeKintoneClient(baseUrl, tokenResolver) {
7600
7865
  const normalizedBaseUrl = baseUrl.replace(/\/+$/, "");
@@ -7773,36 +8038,10 @@ function createNodeKintoneClient(baseUrl, tokenResolver) {
7773
8038
  { method: "GET" },
7774
8039
  appId
7775
8040
  );
7776
- return Object.values(res.properties).map((f) => ({
7777
- code: f.code,
7778
- label: f.label,
7779
- fieldType: f.type,
7780
- optionOrder: toOptionOrderMap(f.options),
7781
- sortKind: detectSortKind(f.type, f.format)
7782
- }));
8041
+ return flattenFormFieldProperties(res.properties);
7783
8042
  }
7784
8043
  };
7785
8044
  }
7786
- function toOptionOrderMap(options) {
7787
- if (!options || typeof options !== "object") return void 0;
7788
- const order = {};
7789
- let hasAny = false;
7790
- for (const [label, meta] of Object.entries(options)) {
7791
- const n = Number(meta?.index);
7792
- if (!Number.isFinite(n)) continue;
7793
- order[label] = n;
7794
- hasAny = true;
7795
- }
7796
- return hasAny ? order : void 0;
7797
- }
7798
- function detectSortKind(fieldType, calcFormat) {
7799
- if (fieldType === "NUMBER" || fieldType === "RECORD_NUMBER") return "number";
7800
- if (fieldType === "CALC") {
7801
- if (calcFormat === "NUMBER" || calcFormat === "NUMBER_DIGIT") return "number";
7802
- return "string";
7803
- }
7804
- return void 0;
7805
- }
7806
8045
 
7807
8046
  // src/node/appProfiles.ts
7808
8047
  var import_fs = require("fs");
@@ -34409,52 +34409,91 @@ function resolveFieldRef(row, field) {
34409
34409
  }
34410
34410
 
34411
34411
  // src/engine/evalWhere.ts
34412
- function evalWhere(expr, row) {
34412
+ function evalWhere(expr, row, resolveFieldType) {
34413
34413
  switch (expr.type) {
34414
34414
  case "BINARY":
34415
- return evalBinary(expr, row);
34415
+ return evalBinary(expr, row, resolveFieldType);
34416
34416
  case "NULL_CHECK":
34417
34417
  return evalNullCheck(expr, row);
34418
34418
  case "LOGICAL":
34419
- return evalLogical(expr, row);
34419
+ return evalLogical(expr, row, resolveFieldType);
34420
34420
  case "NOT":
34421
- return !evalWhere(expr.expr, row);
34421
+ return !evalWhere(expr.expr, row, resolveFieldType);
34422
34422
  case "GROUP":
34423
- return evalWhere(expr.expr, row);
34423
+ return evalWhere(expr.expr, row, resolveFieldType);
34424
34424
  case "EXISTS": {
34425
34425
  const exists = expr.resolved;
34426
34426
  return expr.not ? !exists : exists;
34427
34427
  }
34428
34428
  }
34429
34429
  }
34430
- function evalBinary(expr, row) {
34431
- const left = resolveField(expr.left, row);
34432
- return evalOp(expr.op, left, expr.right, row);
34430
+ function evalBinary(expr, row, resolveFieldType) {
34431
+ const left = resolveField(expr.left, row, resolveFieldType);
34432
+ const fieldType = expr.left.type === "FIELD" ? resolveFieldType?.(expr.left) : void 0;
34433
+ return evalOp(expr.op, left, expr.right, row, fieldType, resolveFieldType);
34433
34434
  }
34434
- function evalOp(op, leftStr, right, row) {
34435
+ function evalOp(op, leftStr, right, row, fieldType, resolveFieldType) {
34435
34436
  if (op === "IN" || op === "NOT_IN") {
34437
+ let values = null;
34436
34438
  if (right.type === "IN_LIST") {
34437
34439
  assertResolvedInListValues2(right.values);
34438
- const contains = right.values.some((v) => leftStr === String(v.value));
34439
- return op === "IN" ? contains : !contains;
34440
+ values = new Set(right.values.map((v) => String(v.value)));
34440
34441
  }
34441
34442
  if (right.type === "SUBQUERY_IN_LIST") {
34442
- const contains = right.resolved.has(leftStr);
34443
- return op === "IN" ? contains : !contains;
34443
+ values = right.resolved;
34444
34444
  }
34445
- return op === "NOT_IN";
34445
+ if (values === null) return op === "NOT_IN";
34446
+ const contains = typedInContains(leftStr, values, fieldType);
34447
+ return op === "IN" ? contains : !contains;
34446
34448
  }
34447
34449
  if (op === "LIKE") {
34448
- const pattern = resolveValue(right, row);
34450
+ const pattern = resolveValue(right, row, resolveFieldType);
34449
34451
  return matchLike(leftStr, pattern);
34450
34452
  }
34451
34453
  if (op === "NOT_LIKE") {
34452
- const pattern = resolveValue(right, row);
34454
+ const pattern = resolveValue(right, row, resolveFieldType);
34453
34455
  return !matchLike(leftStr, pattern);
34454
34456
  }
34455
- const rightStr = resolveValue(right, row);
34457
+ const rightStr = resolveValue(right, row, resolveFieldType);
34456
34458
  return compareScalarValues(op, leftStr, rightStr);
34457
34459
  }
34460
+ var STRING_ARRAY_FIELD_TYPES = /* @__PURE__ */ new Set(["CHECK_BOX", "MULTI_SELECT"]);
34461
+ var OBJECT_ARRAY_FIELD_TYPES = /* @__PURE__ */ new Set([
34462
+ "USER_SELECT",
34463
+ "ORGANIZATION_SELECT",
34464
+ "GROUP_SELECT",
34465
+ "STATUS_ASSIGNEE"
34466
+ ]);
34467
+ var SINGLE_OBJECT_FIELD_TYPES = /* @__PURE__ */ new Set(["CREATOR", "MODIFIER"]);
34468
+ function typedInContains(leftStr, values, fieldType) {
34469
+ const fallback = () => values.has(leftStr);
34470
+ if (fieldType === void 0) return fallback();
34471
+ let parsed;
34472
+ if (STRING_ARRAY_FIELD_TYPES.has(fieldType) || OBJECT_ARRAY_FIELD_TYPES.has(fieldType) || SINGLE_OBJECT_FIELD_TYPES.has(fieldType)) {
34473
+ try {
34474
+ parsed = JSON.parse(leftStr);
34475
+ } catch {
34476
+ return fallback();
34477
+ }
34478
+ } else {
34479
+ return fallback();
34480
+ }
34481
+ if (STRING_ARRAY_FIELD_TYPES.has(fieldType)) {
34482
+ if (!Array.isArray(parsed) || !parsed.every((item) => typeof item === "string")) {
34483
+ return fallback();
34484
+ }
34485
+ return parsed.some((item) => values.has(item));
34486
+ }
34487
+ if (OBJECT_ARRAY_FIELD_TYPES.has(fieldType)) {
34488
+ if (!Array.isArray(parsed) || !parsed.every(hasStringCode)) return fallback();
34489
+ return parsed.some((item) => values.has(item.code));
34490
+ }
34491
+ if (!hasStringCode(parsed)) return fallback();
34492
+ return values.has(parsed.code);
34493
+ }
34494
+ function hasStringCode(value) {
34495
+ return value !== null && typeof value === "object" && !Array.isArray(value) && typeof value.code === "string";
34496
+ }
34458
34497
  function assertResolvedInListValues2(values) {
34459
34498
  const unresolved = values.find((item) => item.type === "VARIABLE");
34460
34499
  if (unresolved?.type === "VARIABLE") {
@@ -34465,20 +34504,20 @@ function evalNullCheck(expr, row) {
34465
34504
  const val = resolveField(expr.field, row);
34466
34505
  return expr.not ? val !== "" : val === "";
34467
34506
  }
34468
- function evalLogical(expr, row) {
34507
+ function evalLogical(expr, row, resolveFieldType) {
34469
34508
  if (expr.op === "AND") {
34470
- return evalWhere(expr.left, row) && evalWhere(expr.right, row);
34509
+ return evalWhere(expr.left, row, resolveFieldType) && evalWhere(expr.right, row, resolveFieldType);
34471
34510
  }
34472
- return evalWhere(expr.left, row) || evalWhere(expr.right, row);
34511
+ return evalWhere(expr.left, row, resolveFieldType) || evalWhere(expr.right, row, resolveFieldType);
34473
34512
  }
34474
- function resolveField(field, row) {
34513
+ function resolveField(field, row, resolveFieldType) {
34475
34514
  if (field.type === "FUNC_FIELD") return evalStringFunc(field.expr, row);
34476
34515
  if (field.type === "ARITH_FIELD") return String(evalArithExpr(field.expr, row));
34477
- if (field.type === "CASE_FIELD") return evalCaseWhen(field.expr, row);
34516
+ if (field.type === "CASE_FIELD") return evalCaseWhen(field.expr, row, resolveFieldType);
34478
34517
  const key = field.tableAlias ? `${field.tableAlias}.${field.field}` : field.field;
34479
34518
  return resolveFieldRef(row, key);
34480
34519
  }
34481
- function resolveValue(value, row) {
34520
+ function resolveValue(value, row, resolveFieldType) {
34482
34521
  switch (value.type) {
34483
34522
  case "VARIABLE":
34484
34523
  throw new Error(`ParseError: unresolved batch variable @${value.name}.`);
@@ -34501,14 +34540,14 @@ function resolveValue(value, row) {
34501
34540
  if (value.expr.type === "STRING_FUNC") return evalStringFunc(value.expr, row);
34502
34541
  return String(evalArithExpr(value.expr, row));
34503
34542
  case "CASE_VALUE":
34504
- return evalCaseWhen(value.expr, row);
34543
+ return evalCaseWhen(value.expr, row, resolveFieldType);
34505
34544
  case "ARRAY":
34506
34545
  return value.elements.map((e) => e.value).join(",");
34507
34546
  }
34508
34547
  }
34509
- function evalCaseWhen(expr, row) {
34548
+ function evalCaseWhen(expr, row, resolveFieldType) {
34510
34549
  for (const branch of expr.branches) {
34511
- if (evalWhere(branch.condition, row)) {
34550
+ if (evalWhere(branch.condition, row, resolveFieldType)) {
34512
34551
  return evalCaseResult(branch.result, row);
34513
34552
  }
34514
34553
  }
@@ -35175,9 +35214,9 @@ function applyJoin(leftRows, rightRows, join) {
35175
35214
  }
35176
35215
  return result;
35177
35216
  }
35178
- function applyFilter(rows, where) {
35217
+ function applyFilter(rows, where, resolveFieldType) {
35179
35218
  if (where === null) return rows;
35180
- return rows.filter((row) => evalWhere(where, row));
35219
+ return rows.filter((row) => evalWhere(where, row, resolveFieldType));
35181
35220
  }
35182
35221
  function hasAggregateColumns(columns) {
35183
35222
  return columns.some(
@@ -35303,9 +35342,9 @@ function aggregateSyntheticName2(func, distinct, arg) {
35303
35342
  const argStr = aggregateArgLabel(arg);
35304
35343
  return distinct ? `${func}(DISTINCT ${argStr})` : `${func}(${argStr})`;
35305
35344
  }
35306
- function applyHaving(rows, having) {
35345
+ function applyHaving(rows, having, resolveFieldType) {
35307
35346
  if (having === null) return rows;
35308
- return rows.filter((row) => evalWhere(having, row));
35347
+ return rows.filter((row) => evalWhere(having, row, resolveFieldType));
35309
35348
  }
35310
35349
  function applyDistinct(rows, columns) {
35311
35350
  if (rows.length === 0) return rows;
@@ -35430,7 +35469,7 @@ function applyLimit(rows, limit, offset) {
35430
35469
  if (limit === null) return rows.slice(start);
35431
35470
  return rows.slice(start, start + limit);
35432
35471
  }
35433
- function project(rows, columns, scalarCache) {
35472
+ function project(rows, columns, scalarCache, resolveFieldType) {
35434
35473
  if (columns.length === 1 && columns[0].type === "WILDCARD") {
35435
35474
  const projected2 = rows.map((row) => stripParentShortcutColumns(row));
35436
35475
  const cols = projected2.length > 0 ? Object.keys(projected2[0]) : [];
@@ -35491,7 +35530,7 @@ function project(rows, columns, scalarCache) {
35491
35530
  }
35492
35531
  case "CASE_COL": {
35493
35532
  const key = outputKeys?.[colIdx] ?? col.alias ?? "case";
35494
- out[key] = evalCaseWhen(col.expr, row);
35533
+ out[key] = evalCaseWhen(col.expr, row, resolveFieldType);
35495
35534
  if (outputKeys === null && rowIdx === 0) orderedKeys.push(key);
35496
35535
  break;
35497
35536
  }
@@ -35627,7 +35666,15 @@ function resolveAggInStringFuncExpr(expr, rows) {
35627
35666
  };
35628
35667
  }
35629
35668
  function runFullScan(input) {
35630
- const { stmt, tables, scalarCache, optionOrders, sortKinds } = input;
35669
+ const {
35670
+ stmt,
35671
+ tables,
35672
+ scalarCache,
35673
+ optionOrders,
35674
+ sortKinds,
35675
+ fieldTypeResolver,
35676
+ havingFieldTypeResolver
35677
+ } = input;
35631
35678
  let rows = [];
35632
35679
  const mainAlias = stmt.from.alias;
35633
35680
  const mainRecords = tables.get(mainAlias) ?? tables.get(null) ?? [];
@@ -35638,17 +35685,17 @@ function runFullScan(input) {
35638
35685
  const rightRows = rightRecords.map((r) => flatten(r, rightAlias));
35639
35686
  rows = applyJoin(rows, rightRows, join);
35640
35687
  }
35641
- rows = applyFilter(rows, stmt.where);
35688
+ rows = applyFilter(rows, stmt.where, fieldTypeResolver);
35642
35689
  if (stmt.groupBy.length > 0 || hasAggregateColumns(stmt.columns)) {
35643
35690
  rows = applyGroupBy(rows, stmt.groupBy, stmt.columns);
35644
35691
  }
35645
- rows = applyHaving(rows, stmt.having);
35692
+ rows = applyHaving(rows, stmt.having, havingFieldTypeResolver);
35646
35693
  if (stmt.distinct) {
35647
35694
  rows = applyDistinct(rows, stmt.columns);
35648
35695
  }
35649
35696
  rows = applyOrderBy(rows, stmt.orderBy, optionOrders, sortKinds);
35650
35697
  rows = applyLimit(rows, stmt.limit, stmt.offset);
35651
- return project(rows, stmt.columns, scalarCache);
35698
+ return project(rows, stmt.columns, scalarCache, fieldTypeResolver);
35652
35699
  }
35653
35700
 
35654
35701
  // src/converter/subtableAdapter.ts
@@ -36181,6 +36228,7 @@ async function executeSelect(stmt, client, options, cacheContext, cteCache) {
36181
36228
  if (isNoFromSelect(stmt)) {
36182
36229
  return executeNoFromSelect(stmt);
36183
36230
  }
36231
+ await resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache);
36184
36232
  const mode = resolveSelectMode(stmt);
36185
36233
  await validateSelectFieldCodes(stmt, mode, client, cacheContext);
36186
36234
  if (mode === "SIMPLE") {
@@ -36239,6 +36287,8 @@ function executeNoFromSelect(stmt) {
36239
36287
  }
36240
36288
  async function executeSimpleSelect(stmt, client, options, cacheContext) {
36241
36289
  const params = selectToKintoneParams(stmt);
36290
+ const typedInFieldTypes = await loadTypedInFieldTypes(stmt, client, cacheContext);
36291
+ const fieldTypeResolvers = buildSelectFieldTypeResolvers(stmt, typedInFieldTypes);
36242
36292
  const maxRecords2 = options.maxRecords ?? 1e4;
36243
36293
  const warnings = /* @__PURE__ */ new Set();
36244
36294
  const onLimit2 = options.onLimitReached ?? "error";
@@ -36275,7 +36325,12 @@ async function executeSimpleSelect(stmt, client, options, cacheContext) {
36275
36325
  rows = applyOrderBy(rows, stmt.orderBy, optionOrders, sortKinds);
36276
36326
  rows = applyLimit(rows, stmt.limit, stmt.offset);
36277
36327
  }
36278
- const { rows: projected, columns } = project(rows, stmt.columns);
36328
+ const { rows: projected, columns } = project(
36329
+ rows,
36330
+ stmt.columns,
36331
+ void 0,
36332
+ fieldTypeResolvers.row
36333
+ );
36279
36334
  return { type: "SELECT", rows: projected, columns, rowCount: projected.length, warnings: [...warnings] };
36280
36335
  }
36281
36336
  async function validateSelectFieldCodes(stmt, mode, client, cacheContext) {
@@ -36348,6 +36403,108 @@ async function loadNumericPushdownFieldTypes(stmt, client, cacheContext) {
36348
36403
  const entries = await Promise.all([...appIds].map(async (appId) => [appId, await getFieldTypeMap(appId, client, cacheContext)]));
36349
36404
  return new Map(entries);
36350
36405
  }
36406
+ function collectTypedInFieldRefs(expr, out) {
36407
+ if (expr === null) return;
36408
+ switch (expr.type) {
36409
+ case "BINARY":
36410
+ if ((expr.op === "IN" || expr.op === "NOT_IN") && expr.left.type === "FIELD") {
36411
+ out.push(expr.left);
36412
+ }
36413
+ if (expr.left.type === "CASE_FIELD") collectCaseTypedInFieldRefs(expr.left.expr, out);
36414
+ if (expr.right.type === "CASE_VALUE") collectCaseTypedInFieldRefs(expr.right.expr, out);
36415
+ return;
36416
+ case "LOGICAL":
36417
+ collectTypedInFieldRefs(expr.left, out);
36418
+ collectTypedInFieldRefs(expr.right, out);
36419
+ return;
36420
+ case "NOT":
36421
+ case "GROUP":
36422
+ collectTypedInFieldRefs(expr.expr, out);
36423
+ return;
36424
+ case "NULL_CHECK":
36425
+ case "EXISTS":
36426
+ return;
36427
+ }
36428
+ }
36429
+ function collectCaseTypedInFieldRefs(expr, out) {
36430
+ for (const branch of expr.branches) collectTypedInFieldRefs(branch.condition, out);
36431
+ }
36432
+ function collectSelectTypedInFieldRefs(stmt) {
36433
+ const refs = [];
36434
+ collectTypedInFieldRefs(stmt.where, refs);
36435
+ collectTypedInFieldRefs(stmt.having, refs);
36436
+ for (const column of stmt.columns) {
36437
+ if (column.type === "CASE_COL") collectCaseTypedInFieldRefs(column.expr, refs);
36438
+ }
36439
+ return refs;
36440
+ }
36441
+ function findTableForAlias(stmt, alias) {
36442
+ return [stmt.from, ...stmt.joins.map((join) => join.table)].find((table) => table.alias === alias);
36443
+ }
36444
+ function physicalSelectTables(stmt) {
36445
+ return [stmt.from, ...stmt.joins.map((join) => join.table)].filter((table) => table.cteName === null);
36446
+ }
36447
+ async function loadTypedInFieldTypes(stmt, client, cacheContext) {
36448
+ const refs = collectSelectTypedInFieldRefs(stmt);
36449
+ if (refs.length === 0) return /* @__PURE__ */ new Map();
36450
+ const appIds = /* @__PURE__ */ new Set();
36451
+ const physicalTables = physicalSelectTables(stmt);
36452
+ for (const ref of refs) {
36453
+ if (ref.tableAlias !== null) {
36454
+ if (ref.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
36455
+ appIds.add(stmt.from.appId);
36456
+ continue;
36457
+ }
36458
+ const table = findTableForAlias(stmt, ref.tableAlias);
36459
+ if (table && table.cteName === null) appIds.add(table.appId);
36460
+ continue;
36461
+ }
36462
+ if (stmt.joins.length === 0) {
36463
+ if (stmt.from.cteName === null) appIds.add(stmt.from.appId);
36464
+ continue;
36465
+ }
36466
+ for (const table of physicalTables) appIds.add(table.appId);
36467
+ }
36468
+ const entries = await Promise.all([...appIds].map(async (appId) => [appId, await getFieldTypeMap(appId, client, cacheContext)]));
36469
+ return new Map(entries);
36470
+ }
36471
+ function fieldCodeForTypeLookup(table, field) {
36472
+ if (table.subtableCode && field.startsWith("_p.")) return field.slice(3);
36473
+ return field;
36474
+ }
36475
+ function buildSelectFieldTypeResolvers(stmt, fieldTypesByApp) {
36476
+ const tables = [stmt.from, ...stmt.joins.map((join) => join.table)];
36477
+ const physicalTables = tables.filter((table) => table.cteName === null);
36478
+ const outputAliases = new Set(
36479
+ stmt.columns.map((column) => "alias" in column ? column.alias : null).filter((alias) => alias !== null)
36480
+ );
36481
+ const row = (field) => {
36482
+ if (field.tableAlias !== null) {
36483
+ if (field.tableAlias === "_p" && stmt.from.subtableCode && stmt.from.cteName === null) {
36484
+ return fieldTypesByApp.get(stmt.from.appId)?.get(field.field);
36485
+ }
36486
+ const table2 = tables.find((candidate) => candidate.alias === field.tableAlias);
36487
+ if (!table2 || table2.cteName !== null) return void 0;
36488
+ return fieldTypesByApp.get(table2.appId)?.get(fieldCodeForTypeLookup(table2, field.field));
36489
+ }
36490
+ if (stmt.joins.length === 0) {
36491
+ if (stmt.from.cteName !== null) return void 0;
36492
+ return fieldTypesByApp.get(stmt.from.appId)?.get(fieldCodeForTypeLookup(stmt.from, field.field));
36493
+ }
36494
+ if (tables.some((table2) => table2.cteName !== null)) return void 0;
36495
+ const matches = physicalTables.filter(
36496
+ (table2) => fieldTypesByApp.get(table2.appId)?.has(fieldCodeForTypeLookup(table2, field.field))
36497
+ );
36498
+ if (matches.length !== 1) return void 0;
36499
+ const table = matches[0];
36500
+ return fieldTypesByApp.get(table.appId)?.get(fieldCodeForTypeLookup(table, field.field));
36501
+ };
36502
+ const having = (field) => {
36503
+ if (field.tableAlias === null && outputAliases.has(field.field)) return void 0;
36504
+ return row(field);
36505
+ };
36506
+ return { row, having };
36507
+ }
36351
36508
  async function executeFullScanSelect(stmt, client, options, cacheContext, cteCache) {
36352
36509
  const maxRecords2 = options.maxRecords ?? 1e4;
36353
36510
  const warnings = /* @__PURE__ */ new Set();
@@ -36356,7 +36513,11 @@ async function executeFullScanSelect(stmt, client, options, cacheContext, cteCac
36356
36513
  resolveSubqueries(stmt.where, client, options, cacheContext, cteCache),
36357
36514
  resolveSubqueries(stmt.having, client, options, cacheContext, cteCache)
36358
36515
  ]);
36359
- const pushdownFieldTypes = await loadNumericPushdownFieldTypes(stmt, client, cacheContext);
36516
+ const [pushdownFieldTypes, typedInFieldTypes] = await Promise.all([
36517
+ loadNumericPushdownFieldTypes(stmt, client, cacheContext),
36518
+ loadTypedInFieldTypes(stmt, client, cacheContext)
36519
+ ]);
36520
+ const fieldTypeResolvers = buildSelectFieldTypeResolvers(stmt, typedInFieldTypes);
36360
36521
  const mainPushDown = extractMainSafePushdown(
36361
36522
  stmt,
36362
36523
  pushdownFieldTypes.get(stmt.from.appId)
@@ -36445,7 +36606,15 @@ async function executeFullScanSelect(stmt, client, options, cacheContext, cteCac
36445
36606
  }));
36446
36607
  const scalarCache = await scalarCachePromise;
36447
36608
  const { optionOrders, sortKinds } = await orderByMetaPromise;
36448
- const { rows, columns } = runFullScan({ tables, stmt, scalarCache, optionOrders, sortKinds });
36609
+ const { rows, columns } = runFullScan({
36610
+ tables,
36611
+ stmt,
36612
+ scalarCache,
36613
+ optionOrders,
36614
+ sortKinds,
36615
+ fieldTypeResolver: fieldTypeResolvers.row,
36616
+ havingFieldTypeResolver: fieldTypeResolvers.having
36617
+ });
36449
36618
  return { type: "SELECT", rows, columns, rowCount: rows.length, warnings: [...warnings] };
36450
36619
  }
36451
36620
  async function executeUnion(stmt, client, options, cacheContext) {
@@ -36601,8 +36770,11 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
36601
36770
  const parallel = options.fetchParallel ?? 1;
36602
36771
  await Promise.all([
36603
36772
  resolveSubqueries(stmt.where, client, options, cacheContext, cteCache),
36604
- resolveSubqueries(stmt.having, client, options, cacheContext, cteCache)
36773
+ resolveSubqueries(stmt.having, client, options, cacheContext, cteCache),
36774
+ resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache)
36605
36775
  ]);
36776
+ const typedInFieldTypes = await loadTypedInFieldTypes(stmt, client, cacheContext);
36777
+ const fieldTypeResolvers = buildSelectFieldTypeResolvers(stmt, typedInFieldTypes);
36606
36778
  const scalarCachePromise = resolveScalarColumns(stmt.columns, client, options, cacheContext, cteCache);
36607
36779
  const orderByMetaPromise = buildOrderByMetaForSelect(stmt, client, cacheContext);
36608
36780
  scalarCachePromise.catch(() => {
@@ -36657,7 +36829,15 @@ async function executeFullScanWithCte(stmt, client, options, cteCache, cacheCont
36657
36829
  await Promise.all(joinFetches);
36658
36830
  const scalarCache = await scalarCachePromise;
36659
36831
  const { optionOrders, sortKinds } = await orderByMetaPromise;
36660
- const { rows, columns } = runFullScan({ tables, stmt, scalarCache, optionOrders, sortKinds });
36832
+ const { rows, columns } = runFullScan({
36833
+ tables,
36834
+ stmt,
36835
+ scalarCache,
36836
+ optionOrders,
36837
+ sortKinds,
36838
+ fieldTypeResolver: fieldTypeResolvers.row,
36839
+ havingFieldTypeResolver: fieldTypeResolvers.having
36840
+ });
36661
36841
  return { type: "SELECT", rows, columns, rowCount: rows.length, warnings: [...warnings] };
36662
36842
  }
36663
36843
  function processRowToKintoneRecord(row) {
@@ -37154,6 +37334,16 @@ async function executeUpsert(stmt, client, options, cacheContext) {
37154
37334
  updatedCount: toUpdate.length
37155
37335
  };
37156
37336
  }
37337
+ async function buildSubtableFieldTypeResolver(appId, typedInRefs, client, cacheContext) {
37338
+ if (typedInRefs.length === 0) return void 0;
37339
+ const fieldTypes = await getFieldTypeMap(appId, client, cacheContext);
37340
+ return (field) => {
37341
+ if (field.tableAlias !== null && field.tableAlias !== "_p") return void 0;
37342
+ if (field.tableAlias === "_p") return fieldTypes.get(field.field);
37343
+ const code = field.field.startsWith("_p.") ? field.field.slice(3) : field.field;
37344
+ return fieldTypes.get(code);
37345
+ };
37346
+ }
37157
37347
  async function executeInsertSubtable(stmt, client, options, _cacheContext) {
37158
37348
  const subtableCode = stmt.subtableCode;
37159
37349
  const pidIndex = stmt.fields.indexOf("_pid");
@@ -37194,11 +37384,24 @@ async function executeInsertSubtable(stmt, client, options, _cacheContext) {
37194
37384
  }
37195
37385
  return { type: "INSERT", createdIds: [], insertedCount: stmt.values.length };
37196
37386
  }
37197
- async function executeUpdateSubtable(stmt, client, options, _cacheContext) {
37387
+ async function executeUpdateSubtable(stmt, client, options, cacheContext) {
37198
37388
  const subtableCode = stmt.subtableCode;
37199
37389
  if (!hasRidCondition(stmt.where)) {
37200
37390
  throw new Error("\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB UPDATE \u306B\u306F _rid \u6761\u4EF6\u304C\u5FC5\u9808\u3067\u3059");
37201
37391
  }
37392
+ const typedInRefs = [];
37393
+ collectTypedInFieldRefs(stmt.where, typedInRefs);
37394
+ for (const assignment of stmt.assignments) {
37395
+ if (assignment.value.type === "CASE_VALUE") {
37396
+ collectCaseTypedInFieldRefs(assignment.value.expr, typedInRefs);
37397
+ }
37398
+ }
37399
+ const resolveFieldType = await buildSubtableFieldTypeResolver(
37400
+ stmt.appId,
37401
+ typedInRefs,
37402
+ client,
37403
+ cacheContext
37404
+ );
37202
37405
  const parents = await fetchAll(
37203
37406
  client.getRecords,
37204
37407
  stmt.appId,
@@ -37207,7 +37410,7 @@ async function executeUpdateSubtable(stmt, client, options, _cacheContext) {
37207
37410
  { maxRecords: options.maxRecords ?? 1e4, parallel: options.fetchParallel ?? 1 }
37208
37411
  );
37209
37412
  const expanded = expandRowsForSubtableDml(parents, subtableCode);
37210
- const targets = expanded.filter((r) => evalWhere(stmt.where, r.flat));
37413
+ const targets = expanded.filter((r) => evalWhere(stmt.where, r.flat, resolveFieldType));
37211
37414
  if (options.confirm) {
37212
37415
  const ok = await options.confirm(targets.length, "UPDATE");
37213
37416
  if (!ok) throw new OperationCancelledError("UPDATE", targets.length);
@@ -37227,7 +37430,7 @@ async function executeUpdateSubtable(stmt, client, options, _cacheContext) {
37227
37430
  if (a.field.startsWith("_")) {
37228
37431
  throw new Error(`\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB UPDATE \u3067\u30B7\u30B9\u30C6\u30E0\u5217\u300C${a.field}\u300D\u306F\u66F4\u65B0\u3067\u304D\u307E\u305B\u3093`);
37229
37432
  }
37230
- updates[a.field] = { value: evalAssignmentValueForSubtable(a.value, t.flat) };
37433
+ updates[a.field] = { value: evalAssignmentValueForSubtable(a.value, t.flat, resolveFieldType) };
37231
37434
  }
37232
37435
  byRid.set(t.rowId, updates);
37233
37436
  }
@@ -37249,11 +37452,19 @@ async function executeUpdateSubtable(stmt, client, options, _cacheContext) {
37249
37452
  }
37250
37453
  return { type: "UPDATE", updatedCount: targets.length };
37251
37454
  }
37252
- async function executeDeleteSubtable(stmt, client, options, _cacheContext) {
37455
+ async function executeDeleteSubtable(stmt, client, options, cacheContext) {
37253
37456
  const subtableCode = stmt.subtableCode;
37254
37457
  if (!hasRidCondition(stmt.where)) {
37255
37458
  throw new Error("\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB DELETE \u306B\u306F _rid \u6761\u4EF6\u304C\u5FC5\u9808\u3067\u3059");
37256
37459
  }
37460
+ const typedInRefs = [];
37461
+ collectTypedInFieldRefs(stmt.where, typedInRefs);
37462
+ const resolveFieldType = await buildSubtableFieldTypeResolver(
37463
+ stmt.appId,
37464
+ typedInRefs,
37465
+ client,
37466
+ cacheContext
37467
+ );
37257
37468
  const parents = await fetchAll(
37258
37469
  client.getRecords,
37259
37470
  stmt.appId,
@@ -37262,7 +37473,7 @@ async function executeDeleteSubtable(stmt, client, options, _cacheContext) {
37262
37473
  { maxRecords: options.maxRecords ?? 1e4, parallel: options.fetchParallel ?? 1 }
37263
37474
  );
37264
37475
  const expanded = expandRowsForSubtableDml(parents, subtableCode);
37265
- const targets = expanded.filter((r) => evalWhere(stmt.where, r.flat));
37476
+ const targets = expanded.filter((r) => evalWhere(stmt.where, r.flat, resolveFieldType));
37266
37477
  if (options.confirm) {
37267
37478
  const ok = await options.confirm(targets.length, "DELETE");
37268
37479
  if (!ok) throw new OperationCancelledError("DELETE", targets.length);
@@ -37377,11 +37588,11 @@ function buildSubtableReorderPutParams(appId, parentId, revision, subtableCode,
37377
37588
  ]
37378
37589
  };
37379
37590
  }
37380
- function evalAssignmentValueForSubtable(value, row) {
37591
+ function evalAssignmentValueForSubtable(value, row, resolveFieldType) {
37381
37592
  if (value.type === "STRING") return value.value;
37382
37593
  if (value.type === "NUMBER") return String(value.value);
37383
37594
  if (value.type === "ARITH") return String(evalArithExpr(value, row));
37384
- if (value.type === "CASE_VALUE") return evalCaseWhen(value.expr, row);
37595
+ if (value.type === "CASE_VALUE") return evalCaseWhen(value.expr, row, resolveFieldType);
37385
37596
  throw new Error(`${value.type} \u306F\u30B5\u30D6\u30C6\u30FC\u30D6\u30EB UPDATE \u306E\u5024\u3068\u3057\u3066\u4F7F\u7528\u3067\u304D\u307E\u305B\u3093`);
37386
37597
  }
37387
37598
  function valueToString(value) {
@@ -37413,7 +37624,15 @@ function hasRidCondition(where) {
37413
37624
  return false;
37414
37625
  }
37415
37626
  }
37416
- async function executeReorder(stmt, client, options, _cacheContext) {
37627
+ async function executeReorder(stmt, client, options, cacheContext) {
37628
+ const typedInRefs = [];
37629
+ collectTypedInFieldRefs(stmt.where, typedInRefs);
37630
+ const resolveFieldType = await buildSubtableFieldTypeResolver(
37631
+ stmt.appId,
37632
+ typedInRefs,
37633
+ client,
37634
+ cacheContext
37635
+ );
37417
37636
  const parents = await fetchAll(
37418
37637
  client.getRecords,
37419
37638
  stmt.appId,
@@ -37422,7 +37641,7 @@ async function executeReorder(stmt, client, options, _cacheContext) {
37422
37641
  { maxRecords: options.maxRecords ?? 1e4, parallel: options.fetchParallel ?? 1 }
37423
37642
  );
37424
37643
  const expanded = expandRowsForSubtableDml(parents, stmt.subtableCode);
37425
- const targetParentIds = stmt.all ? new Set(parents.map((p) => String(p["$id"]?.value ?? "")).filter((id) => id !== "")) : new Set(expanded.filter((r) => stmt.where && evalWhere(stmt.where, r.flat)).map((r) => r.parentId));
37644
+ const targetParentIds = stmt.all ? new Set(parents.map((p) => String(p["$id"]?.value ?? "")).filter((id) => id !== "")) : new Set(expanded.filter((r) => stmt.where && evalWhere(stmt.where, r.flat, resolveFieldType)).map((r) => r.parentId));
37426
37645
  if (options.confirm) {
37427
37646
  const ok = await options.confirm(targetParentIds.size, "UPDATE");
37428
37647
  if (!ok) throw new OperationCancelledError("UPDATE", targetParentIds.size);
@@ -37567,6 +37786,16 @@ async function resolveSubqueries(where, client, options, cacheContext, cteCache)
37567
37786
  collectSubqueryTasks(where, client, options, cacheContext, tasks, cteCache);
37568
37787
  await Promise.all(tasks);
37569
37788
  }
37789
+ async function resolveSelectCaseSubqueries(stmt, client, options, cacheContext, cteCache) {
37790
+ const tasks = [];
37791
+ for (const column of stmt.columns) {
37792
+ if (column.type !== "CASE_COL") continue;
37793
+ for (const branch of column.expr.branches) {
37794
+ tasks.push(resolveSubqueries(branch.condition, client, options, cacheContext, cteCache));
37795
+ }
37796
+ }
37797
+ await Promise.all(tasks);
37798
+ }
37570
37799
  function runSubquery(query, client, options, cacheContext, cteCache) {
37571
37800
  if (cteCache !== void 0 && cteCache.size > 0) {
37572
37801
  return executeQueryWithCte(query, client, options, cteCache, cacheContext);
@@ -38489,6 +38718,42 @@ function clampInt(v, min, max) {
38489
38718
  return Math.max(min, Math.min(max, Math.trunc(v)));
38490
38719
  }
38491
38720
 
38721
+ // src/core/formFieldInfo.ts
38722
+ function flattenFormFieldProperties(properties) {
38723
+ const out = [];
38724
+ for (const field of Object.values(properties)) {
38725
+ out.push({
38726
+ code: field.code,
38727
+ label: field.label,
38728
+ fieldType: field.type,
38729
+ optionOrder: toOptionOrderMap(field.options),
38730
+ sortKind: detectSortKind(field.type, field.format)
38731
+ });
38732
+ if (field.fields) out.push(...flattenFormFieldProperties(field.fields));
38733
+ }
38734
+ return out;
38735
+ }
38736
+ function toOptionOrderMap(options) {
38737
+ if (!options || typeof options !== "object") return void 0;
38738
+ const order = {};
38739
+ let hasAny = false;
38740
+ for (const [label, meta3] of Object.entries(options)) {
38741
+ const n = Number(meta3?.index);
38742
+ if (!Number.isFinite(n)) continue;
38743
+ order[label] = n;
38744
+ hasAny = true;
38745
+ }
38746
+ return hasAny ? order : void 0;
38747
+ }
38748
+ function detectSortKind(fieldType, calcFormat) {
38749
+ if (fieldType === "NUMBER" || fieldType === "RECORD_NUMBER") return "number";
38750
+ if (fieldType === "CALC") {
38751
+ if (calcFormat === "NUMBER" || calcFormat === "NUMBER_DIGIT") return "number";
38752
+ return "string";
38753
+ }
38754
+ return void 0;
38755
+ }
38756
+
38492
38757
  // src/cli/nodeKintoneClient.ts
38493
38758
  function createNodeKintoneClient(baseUrl, tokenResolver) {
38494
38759
  const normalizedBaseUrl = baseUrl.replace(/\/+$/, "");
@@ -38667,36 +38932,10 @@ function createNodeKintoneClient(baseUrl, tokenResolver) {
38667
38932
  { method: "GET" },
38668
38933
  appId
38669
38934
  );
38670
- return Object.values(res.properties).map((f) => ({
38671
- code: f.code,
38672
- label: f.label,
38673
- fieldType: f.type,
38674
- optionOrder: toOptionOrderMap(f.options),
38675
- sortKind: detectSortKind(f.type, f.format)
38676
- }));
38935
+ return flattenFormFieldProperties(res.properties);
38677
38936
  }
38678
38937
  };
38679
38938
  }
38680
- function toOptionOrderMap(options) {
38681
- if (!options || typeof options !== "object") return void 0;
38682
- const order = {};
38683
- let hasAny = false;
38684
- for (const [label, meta3] of Object.entries(options)) {
38685
- const n = Number(meta3?.index);
38686
- if (!Number.isFinite(n)) continue;
38687
- order[label] = n;
38688
- hasAny = true;
38689
- }
38690
- return hasAny ? order : void 0;
38691
- }
38692
- function detectSortKind(fieldType, calcFormat) {
38693
- if (fieldType === "NUMBER" || fieldType === "RECORD_NUMBER") return "number";
38694
- if (fieldType === "CALC") {
38695
- if (calcFormat === "NUMBER" || calcFormat === "NUMBER_DIGIT") return "number";
38696
- return "string";
38697
- }
38698
- return void 0;
38699
- }
38700
38939
 
38701
38940
  // src/node/appProfiles.ts
38702
38941
  function parseTokenMap(raw) {
@@ -40156,7 +40395,7 @@ Options:
40156
40395
  -h, --help Show help
40157
40396
  `);
40158
40397
  }
40159
- var SERVER_VERSION = true ? "2.4.0" : "0.0.0-dev";
40398
+ var SERVER_VERSION = true ? "2.5.0" : "0.0.0-dev";
40160
40399
  function createServer(args) {
40161
40400
  const server = new McpServer({
40162
40401
  name: "ksql-mcp",
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rex0220/kintone-sql-tools",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "kintone SQL plugin, CLI, and MCP tools (ksql)",
5
5
  "publishConfig": {
6
6
  "access": "public"