@rex0220/kintone-sql-tools 3.70.0 → 3.71.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/README.md +1 -1
- package/dist-cli/ksql.js +15 -4
- package/dist-engine/index.cjs +9 -9
- package/dist-engine/index.mjs +10 -10
- package/dist-engine/ksql-engine.umd.js +13 -13
- package/dist-engine/meta/bundle-baseline.json +7 -7
- package/dist-engine/meta/cjs.json +3 -3
- package/dist-engine/meta/esm.json +3 -3
- package/dist-engine/meta/umd.json +3 -3
- package/dist-flow/flow-library/index.d.ts +3 -2
- package/dist-flow/flow-library/publicTypes.d.ts +30 -0
- package/dist-flow/index.cjs +11 -11
- package/dist-flow/index.mjs +11 -11
- package/dist-flow/meta/cjs.json +6 -6
- package/dist-flow/meta/esm.json +7 -6
- package/dist-mcp/ksql-mcp.js +16 -5
- package/dist-mcpb/ksql-mcp.mcpb +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -267,7 +267,7 @@ npm パッケージは 2 つのサブパスを **semver 対象の公開 API**
|
|
|
267
267
|
| サブパス | 用途 | 主な export |
|
|
268
268
|
|---|---|---|
|
|
269
269
|
| `@rex0220/kintone-sql-tools/engine` | **read-only** のクエリ実行(ダッシュボード等)。書込 API は構造的に遮断 | `runQuery` / `runBatch` / `explainQuery` / `createReadonlyKintoneClient` / `KsqlEngineError` / `version` |
|
|
270
|
-
| `@rex0220/kintone-sql-tools/flow` | **Flow dialect 1**(→ [言語リファレンス §27](docs/ksql_language_reference.md))のスクリプト解析・検証・**文単位実行**(バッチランナー向け・書込可能) | `parseScript` / `validateScript` / `explainScript`(`asOf`/`timezone` 注入可) / `createExecutionContext`(`onChunkWritten` 書込チャンク通知) / `executeStatement` / `disposeExecutionContext` / `createKintoneClient` / `isDmlResult`(`FlowDmlResult` 型ガード) / `version` |
|
|
270
|
+
| `@rex0220/kintone-sql-tools/flow` | **Flow dialect 1**(→ [言語リファレンス §27](docs/ksql_language_reference.md))のスクリプト解析・検証・**文単位実行**(バッチランナー向け・書込可能) | `parseScript` / `validateScript` / `explainScript`(`asOf`/`timezone` 注入可) / `createExecutionContext`(`onChunkWritten` 書込チャンク通知) / `executeStatement` / `previewStatement`(dry-run 差分プレビュー・書込 0 回) / `disposeExecutionContext` / `createKintoneClient` / `isDmlResult`(`FlowDmlResult` 型ガード) / `version` |
|
|
271
271
|
|
|
272
272
|
`/flow` の典型的な使い方(1 文ずつ実行して結果で継続判断する):
|
|
273
273
|
|
package/dist-cli/ksql.js
CHANGED
|
@@ -22791,11 +22791,16 @@ function lookupUpsertTarget(index, keyParts) {
|
|
|
22791
22791
|
if (!index.numericKey.some(Boolean)) return void 0;
|
|
22792
22792
|
return index.normalized.get(upsertNormalizedKey(keyParts, index.numericKey));
|
|
22793
22793
|
}
|
|
22794
|
-
async function resolveUpsertTargets(appId, keyFields, rowKeyValues, client, options, fieldTypes) {
|
|
22794
|
+
async function resolveUpsertTargets(appId, keyFields, rowKeyValues, client, options, fieldTypes, previewFields) {
|
|
22795
22795
|
const maxRecords = options.maxRecords ?? 1e4;
|
|
22796
22796
|
const parallel = options.fetchParallel ?? 1;
|
|
22797
22797
|
const numericKey = keyFields.map((f) => fieldTypes.get(f) === "NUMBER");
|
|
22798
|
-
const index = {
|
|
22798
|
+
const index = {
|
|
22799
|
+
raw: /* @__PURE__ */ new Map(),
|
|
22800
|
+
normalized: /* @__PURE__ */ new Map(),
|
|
22801
|
+
numericKey,
|
|
22802
|
+
...previewFields ? { snapshots: /* @__PURE__ */ new Map() } : {}
|
|
22803
|
+
};
|
|
22799
22804
|
const setMax = (map, key, id) => {
|
|
22800
22805
|
const cur = map.get(key);
|
|
22801
22806
|
if (cur === void 0 || id > cur) map.set(key, id);
|
|
@@ -22816,20 +22821,26 @@ async function resolveUpsertTargets(appId, keyFields, rowKeyValues, client, opti
|
|
|
22816
22821
|
if (parts.some((p) => p === "")) perRowKeys.push(parts);
|
|
22817
22822
|
else batchFirstKeys.add(parts[0]);
|
|
22818
22823
|
}
|
|
22819
|
-
const fields = ["$id", ...keyFields];
|
|
22824
|
+
const fields = previewFields ? [.../* @__PURE__ */ new Set(["$id", ...keyFields, ...previewFields])] : ["$id", ...keyFields];
|
|
22820
22825
|
for (const chunk3 of splitChunks([...batchFirstKeys], UPSERT_IN_CHUNK_SIZE)) {
|
|
22821
22826
|
const query = `${keyFields[0]} in (${chunk3.map(sqlQuote).join(",")})`;
|
|
22822
22827
|
const records = await fetchAll(client.getRecords, appId, query, fields, { maxRecords, parallel });
|
|
22823
22828
|
for (const rec of records) {
|
|
22824
22829
|
const id = Number(rec["$id"]?.value);
|
|
22825
22830
|
if (!Number.isFinite(id)) continue;
|
|
22831
|
+
index.snapshots?.set(id, rec);
|
|
22826
22832
|
addRecordToIndex(keyFields.map((f) => toScalarText(rec[f]?.value)), id);
|
|
22827
22833
|
}
|
|
22828
22834
|
}
|
|
22829
22835
|
for (const parts of perRowKeys) {
|
|
22830
22836
|
const query = keyFields.map((f, i) => `${f} = ${sqlQuote(parts[i])}`).join(" and ");
|
|
22831
|
-
const
|
|
22837
|
+
const perRowFields = previewFields ? [.../* @__PURE__ */ new Set(["$id", ...previewFields])] : ["$id"];
|
|
22838
|
+
const existing = await fetchAll(client.getRecords, appId, query, perRowFields, { maxRecords, parallel });
|
|
22832
22839
|
if (existing.length === 0) continue;
|
|
22840
|
+
for (const rec of existing) {
|
|
22841
|
+
const id = Number(rec["$id"]?.value);
|
|
22842
|
+
if (Number.isFinite(id)) index.snapshots?.set(id, rec);
|
|
22843
|
+
}
|
|
22833
22844
|
addRecordToIndex(parts, maxRecordId(existing));
|
|
22834
22845
|
}
|
|
22835
22846
|
return index;
|