@rex0220/kintone-sql-tools 1.1.2 → 1.2.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
@@ -34,7 +34,7 @@ __export(index_exports, {
34
34
  shouldExitOnEmpty: () => shouldExitOnEmpty
35
35
  });
36
36
  module.exports = __toCommonJS(index_exports);
37
- var import_fs = require("fs");
37
+ var import_fs2 = require("fs");
38
38
  var import_path = require("path");
39
39
  var import_readline = require("readline");
40
40
  var import_os = require("os");
@@ -5820,6 +5820,241 @@ function detectSortKind(fieldType, calcFormat) {
5820
5820
  return void 0;
5821
5821
  }
5822
5822
 
5823
+ // src/node/appProfiles.ts
5824
+ var import_fs = require("fs");
5825
+ function parseTokenMap(raw) {
5826
+ const out = {};
5827
+ if (!raw.trim()) return out;
5828
+ const pairs = raw.split(",");
5829
+ for (const pair of pairs) {
5830
+ const idx = pair.indexOf("=");
5831
+ if (idx <= 0) throw new Error("ArgumentError: --token-map must be APPxxx=token pairs.");
5832
+ const key = normalizeAppKey(pair.slice(0, idx).trim());
5833
+ const value = pair.slice(idx + 1).trim();
5834
+ if (!value) throw new Error(`ArgumentError: token is empty for ${key}.`);
5835
+ out[key] = value;
5836
+ }
5837
+ return out;
5838
+ }
5839
+ function parseTokenFile(path) {
5840
+ const raw = (0, import_fs.readFileSync)(path, "utf-8");
5841
+ const parsed = JSON.parse(raw);
5842
+ const out = {};
5843
+ for (const [k, v] of Object.entries(parsed)) out[normalizeAppKey(k)] = String(v);
5844
+ return out;
5845
+ }
5846
+ function normalizeAppKey(v) {
5847
+ const m1 = v.match(/^APP(\d+)$/i);
5848
+ if (m1) return `APP${m1[1]}`;
5849
+ const m2 = v.match(/^(\d+)$/);
5850
+ if (m2) return `APP${m2[1]}`;
5851
+ throw new Error(`ArgumentError: invalid app key "${v}"`);
5852
+ }
5853
+ function extractAppIds(sql) {
5854
+ const out = /* @__PURE__ */ new Set();
5855
+ for (const m of sql.matchAll(/\bAPP(\d+)\b/gi)) out.add(Number(m[1]));
5856
+ return [...out];
5857
+ }
5858
+ function isSqlIdentContinue(ch) {
5859
+ if (!ch) return false;
5860
+ const cp = ch.codePointAt(0);
5861
+ return cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp >= 48 && cp <= 57 || cp === 95 || cp === 36 || cp >= 12352 && cp <= 12543 || cp >= 13312 && cp <= 40959 || cp >= 63744 && cp <= 64255 || cp >= 65281 && cp <= 65376;
5862
+ }
5863
+ function isProfileNameChar(ch) {
5864
+ if (!ch) return false;
5865
+ const cp = ch.codePointAt(0);
5866
+ return cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp >= 48 && cp <= 57 || ch === "_" || ch === "-" || ch === "." || ch === "$";
5867
+ }
5868
+ function tryParseAppProfileToken(sql, start) {
5869
+ const head = sql.slice(start, start + 3);
5870
+ if (head.toUpperCase() !== "APP") return null;
5871
+ const prev = start > 0 ? sql[start - 1] : "";
5872
+ if (isSqlIdentContinue(prev)) return null;
5873
+ let i = start + 3;
5874
+ const digitStart = i;
5875
+ while (i < sql.length && /[0-9]/.test(sql[i])) i++;
5876
+ const digitEnd = i;
5877
+ if (digitEnd === digitStart) return null;
5878
+ if (sql[i] === "$") {
5879
+ i++;
5880
+ const subStart = i;
5881
+ while (i < sql.length && isSqlIdentContinue(sql[i])) i++;
5882
+ if (i === subStart) return null;
5883
+ }
5884
+ const appEnd = i;
5885
+ let profile = null;
5886
+ if (sql[i] === "@") {
5887
+ i++;
5888
+ const pStart = i;
5889
+ while (i < sql.length && isProfileNameChar(sql[i])) i++;
5890
+ if (i === pStart) return null;
5891
+ profile = sql.slice(pStart, i);
5892
+ }
5893
+ const next = i < sql.length ? sql[i] : "";
5894
+ if (isSqlIdentContinue(next)) return null;
5895
+ return {
5896
+ appId: Number(sql.slice(digitStart, digitEnd)),
5897
+ profile,
5898
+ start,
5899
+ digitStart,
5900
+ digitEnd,
5901
+ appEnd,
5902
+ fullEnd: i
5903
+ };
5904
+ }
5905
+ function collectAppProfileTokens(sql) {
5906
+ const tokens = [];
5907
+ let i = 0;
5908
+ while (i < sql.length) {
5909
+ const ch = sql[i];
5910
+ if (ch === "'") {
5911
+ i++;
5912
+ while (i < sql.length) {
5913
+ if (sql[i] === "'") {
5914
+ i++;
5915
+ if (i < sql.length && sql[i] === "'") {
5916
+ i++;
5917
+ continue;
5918
+ }
5919
+ break;
5920
+ }
5921
+ i++;
5922
+ }
5923
+ continue;
5924
+ }
5925
+ if (ch === "`") {
5926
+ i++;
5927
+ while (i < sql.length && sql[i] !== "`") i++;
5928
+ if (i < sql.length) i++;
5929
+ continue;
5930
+ }
5931
+ if (ch === "-" && sql[i + 1] === "-") {
5932
+ i += 2;
5933
+ while (i < sql.length && sql[i] !== "\n") i++;
5934
+ continue;
5935
+ }
5936
+ if (ch === "/" && sql[i + 1] === "*") {
5937
+ i += 2;
5938
+ while (i < sql.length) {
5939
+ if (sql[i] === "*" && sql[i + 1] === "/") {
5940
+ i += 2;
5941
+ break;
5942
+ }
5943
+ i++;
5944
+ }
5945
+ continue;
5946
+ }
5947
+ const parsed = tryParseAppProfileToken(sql, i);
5948
+ if (!parsed) {
5949
+ i++;
5950
+ continue;
5951
+ }
5952
+ tokens.push(parsed);
5953
+ i = parsed.fullEnd;
5954
+ }
5955
+ return tokens;
5956
+ }
5957
+ function nextVirtualAppId(used) {
5958
+ let id = 9e8;
5959
+ while (used.has(id)) id++;
5960
+ used.add(id);
5961
+ return id;
5962
+ }
5963
+ function normalizeSqlAppProfiles(sql, defaultProfile = "dev") {
5964
+ const tokens = collectAppProfileTokens(sql);
5965
+ const hasProfileSyntax = tokens.some((t) => t.profile !== null);
5966
+ const profilesByApp = /* @__PURE__ */ new Map();
5967
+ const normalizedProfile = (profile) => profile ?? defaultProfile;
5968
+ for (const t of tokens) {
5969
+ const p = normalizedProfile(t.profile);
5970
+ let set = profilesByApp.get(t.appId);
5971
+ if (!set) {
5972
+ set = /* @__PURE__ */ new Set();
5973
+ profilesByApp.set(t.appId, set);
5974
+ }
5975
+ set.add(p.toLowerCase());
5976
+ }
5977
+ const usedAppIds = new Set(tokens.map((t) => t.appId));
5978
+ const pairToMapped = /* @__PURE__ */ new Map();
5979
+ const appBindingByMappedApp = /* @__PURE__ */ new Map();
5980
+ for (const [appId, pSet] of profilesByApp.entries()) {
5981
+ const profiles = [...pSet].sort();
5982
+ if (profiles.length <= 1) continue;
5983
+ for (const pLower of profiles) {
5984
+ const mapped = nextVirtualAppId(usedAppIds);
5985
+ pairToMapped.set(`${appId}@${pLower}`, mapped);
5986
+ appBindingByMappedApp.set(mapped, { appId, profile: pLower });
5987
+ }
5988
+ }
5989
+ const out = [];
5990
+ let cursor = 0;
5991
+ for (const t of tokens) {
5992
+ const p = normalizedProfile(t.profile);
5993
+ const pLower = p.toLowerCase();
5994
+ const mapped = pairToMapped.get(`${t.appId}@${pLower}`) ?? t.appId;
5995
+ appBindingByMappedApp.set(mapped, { appId: t.appId, profile: pLower });
5996
+ out.push(sql.slice(cursor, t.start));
5997
+ out.push(sql.slice(t.start, t.digitStart));
5998
+ out.push(String(mapped));
5999
+ out.push(sql.slice(t.digitEnd, t.appEnd));
6000
+ cursor = t.fullEnd;
6001
+ }
6002
+ out.push(sql.slice(cursor));
6003
+ return {
6004
+ normalizedSql: out.join(""),
6005
+ hasProfileSyntax,
6006
+ appBindingByMappedApp
6007
+ };
6008
+ }
6009
+ function buildCacheContext(defaultProfile, appBindingByMappedApp) {
6010
+ if (appBindingByMappedApp.size === 0) return `default:${defaultProfile.toLowerCase()}`;
6011
+ const pairs = [...appBindingByMappedApp.entries()].sort((a, b) => a[0] - b[0]).map(([mappedAppId, b]) => `M${mappedAppId}=APP${b.appId}@${b.profile}`);
6012
+ return `apps:${pairs.join(",")}`;
6013
+ }
6014
+ function formatResolvedAppProfiles(sql, defaultProfile) {
6015
+ const parsed = normalizeSqlAppProfiles(sql, defaultProfile);
6016
+ if (parsed.appBindingByMappedApp.size === 0) return "(none)";
6017
+ return [...parsed.appBindingByMappedApp.values()].map((b) => `APP${b.appId}->${b.profile}`).join(", ");
6018
+ }
6019
+
6020
+ // src/node/dmlGuard.ts
6021
+ function getStatementType(stmt) {
6022
+ if (!stmt || typeof stmt !== "object") return "UNKNOWN";
6023
+ const obj = stmt;
6024
+ return typeof obj.type === "string" ? obj.type : "UNKNOWN";
6025
+ }
6026
+ function isDmlType(type) {
6027
+ return type === "INSERT" || type === "INSERT_SELECT" || type === "UPDATE" || type === "DELETE" || type === "UPSERT" || type === "UPSERT_SELECT" || type === "REORDER";
6028
+ }
6029
+ function hasWhereClause(stmt) {
6030
+ if (!stmt || typeof stmt !== "object") return false;
6031
+ const obj = stmt;
6032
+ return obj.where !== null && obj.where !== void 0;
6033
+ }
6034
+ function isNoFromSelectStatement(stmt) {
6035
+ if (!stmt || typeof stmt !== "object") return false;
6036
+ const obj = stmt;
6037
+ return obj.type === "SELECT" && obj.from?.appId === 0 && obj.from?.cteName === "__NO_FROM__";
6038
+ }
6039
+ function getInsertValuesCount(stmt) {
6040
+ if (!stmt || typeof stmt !== "object") return null;
6041
+ const obj = stmt;
6042
+ if (obj.type !== "INSERT") return null;
6043
+ return Array.isArray(obj.values) ? obj.values.length : null;
6044
+ }
6045
+ function collectDmlTargetFields(stmt) {
6046
+ if (!stmt || typeof stmt !== "object") return [];
6047
+ const obj = stmt;
6048
+ if (!obj.type) return [];
6049
+ if (obj.type === "UPDATE") {
6050
+ return (obj.assignments ?? []).map((a) => a.field).filter((f) => Boolean(f));
6051
+ }
6052
+ if (obj.type === "INSERT" || obj.type === "INSERT_SELECT" || obj.type === "UPSERT" || obj.type === "UPSERT_SELECT") {
6053
+ return [...obj.fields ?? [], ...obj.keyFields ?? []];
6054
+ }
6055
+ return [];
6056
+ }
6057
+
5823
6058
  // src/cli/index.ts
5824
6059
  var HELP_TEXT = `ksql - Execute SQL against kintone apps
5825
6060
 
@@ -5863,7 +6098,7 @@ Options:
5863
6098
  --debug-url Show only HTTP request URL debug logs
5864
6099
  --debug-headers Show request headers in debug logs (masked)
5865
6100
  --exit-on-empty Return exit code 1 when rowCount is 0
5866
- --allow-dml Enable UPDATE/DELETE/INSERT/UPSERT execution
6101
+ --allow-dml Enable UPDATE/DELETE/INSERT/UPSERT/REORDER execution
5867
6102
  --yes Skip DML confirmation prompt
5868
6103
  --allow-without-where Allow UPDATE/DELETE without WHERE
5869
6104
  --dml-max-rows <n> Max affected rows for DML guard (default: 100)
@@ -6128,216 +6363,14 @@ function parseArgs(argv) {
6128
6363
  }
6129
6364
  function getVersion() {
6130
6365
  const pkgPath = (0, import_path.resolve)(__dirname, "../package.json");
6131
- const raw = (0, import_fs.readFileSync)(pkgPath, "utf-8");
6366
+ const raw = (0, import_fs2.readFileSync)(pkgPath, "utf-8");
6132
6367
  const pkg = JSON.parse(raw);
6133
6368
  return pkg.version ?? "0.0.0";
6134
6369
  }
6135
6370
  function loadConfig(configPath) {
6136
- const raw = (0, import_fs.readFileSync)(configPath, "utf-8");
6371
+ const raw = (0, import_fs2.readFileSync)(configPath, "utf-8");
6137
6372
  return JSON.parse(raw);
6138
6373
  }
6139
- function parseTokenMap(raw) {
6140
- const out = {};
6141
- if (!raw.trim()) return out;
6142
- const pairs = raw.split(",");
6143
- for (const pair of pairs) {
6144
- const idx = pair.indexOf("=");
6145
- if (idx <= 0) throw new Error("ArgumentError: --token-map must be APPxxx=token pairs.");
6146
- const key = normalizeAppKey(pair.slice(0, idx).trim());
6147
- const value = pair.slice(idx + 1).trim();
6148
- if (!value) throw new Error(`ArgumentError: token is empty for ${key}.`);
6149
- out[key] = value;
6150
- }
6151
- return out;
6152
- }
6153
- function parseTokenFile(path) {
6154
- const raw = (0, import_fs.readFileSync)(path, "utf-8");
6155
- const parsed = JSON.parse(raw);
6156
- const out = {};
6157
- for (const [k, v] of Object.entries(parsed)) out[normalizeAppKey(k)] = String(v);
6158
- return out;
6159
- }
6160
- function normalizeAppKey(v) {
6161
- const m1 = v.match(/^APP(\d+)$/i);
6162
- if (m1) return `APP${m1[1]}`;
6163
- const m2 = v.match(/^(\d+)$/);
6164
- if (m2) return `APP${m2[1]}`;
6165
- throw new Error(`ArgumentError: invalid app key "${v}"`);
6166
- }
6167
- function extractAppIds(sql) {
6168
- const out = /* @__PURE__ */ new Set();
6169
- for (const m of sql.matchAll(/\bAPP(\d+)\b/gi)) out.add(Number(m[1]));
6170
- return [...out];
6171
- }
6172
- function isSqlIdentContinue(ch) {
6173
- if (!ch) return false;
6174
- const cp = ch.codePointAt(0);
6175
- return cp >= 65 && cp <= 90 || // A-Z
6176
- cp >= 97 && cp <= 122 || // a-z
6177
- cp >= 48 && cp <= 57 || // 0-9
6178
- cp === 95 || // _
6179
- cp === 36 || // $
6180
- cp >= 12352 && cp <= 12543 || cp >= 13312 && cp <= 40959 || cp >= 63744 && cp <= 64255 || cp >= 65281 && cp <= 65376;
6181
- }
6182
- function isProfileNameChar(ch) {
6183
- if (!ch) return false;
6184
- const cp = ch.codePointAt(0);
6185
- return cp >= 65 && cp <= 90 || // A-Z
6186
- cp >= 97 && cp <= 122 || // a-z
6187
- cp >= 48 && cp <= 57 || // 0-9
6188
- ch === "_" || ch === "-" || ch === "." || ch === "$";
6189
- }
6190
- function tryParseAppProfileToken(sql, start) {
6191
- const head = sql.slice(start, start + 3);
6192
- if (head.toUpperCase() !== "APP") return null;
6193
- const prev = start > 0 ? sql[start - 1] : "";
6194
- if (isSqlIdentContinue(prev)) return null;
6195
- let i = start + 3;
6196
- const digitStart = i;
6197
- while (i < sql.length && /[0-9]/.test(sql[i])) i++;
6198
- const digitEnd = i;
6199
- if (digitEnd === digitStart) return null;
6200
- if (sql[i] === "$") {
6201
- i++;
6202
- const subStart = i;
6203
- while (i < sql.length && isSqlIdentContinue(sql[i])) i++;
6204
- if (i === subStart) return null;
6205
- }
6206
- const appEnd = i;
6207
- let profile = null;
6208
- if (sql[i] === "@") {
6209
- i++;
6210
- const pStart = i;
6211
- while (i < sql.length && isProfileNameChar(sql[i])) i++;
6212
- if (i === pStart) return null;
6213
- profile = sql.slice(pStart, i);
6214
- }
6215
- const next = i < sql.length ? sql[i] : "";
6216
- if (isSqlIdentContinue(next)) return null;
6217
- return {
6218
- appId: Number(sql.slice(digitStart, digitEnd)),
6219
- profile,
6220
- start,
6221
- digitStart,
6222
- digitEnd,
6223
- appEnd,
6224
- fullEnd: i
6225
- };
6226
- }
6227
- function collectAppProfileTokens(sql) {
6228
- const tokens = [];
6229
- let i = 0;
6230
- while (i < sql.length) {
6231
- const ch = sql[i];
6232
- if (ch === "'") {
6233
- i++;
6234
- while (i < sql.length) {
6235
- if (sql[i] === "'") {
6236
- i++;
6237
- if (i < sql.length && sql[i] === "'") {
6238
- i++;
6239
- continue;
6240
- }
6241
- break;
6242
- }
6243
- i++;
6244
- }
6245
- continue;
6246
- }
6247
- if (ch === "`") {
6248
- i++;
6249
- while (i < sql.length && sql[i] !== "`") i++;
6250
- if (i < sql.length) i++;
6251
- continue;
6252
- }
6253
- if (ch === "-" && sql[i + 1] === "-") {
6254
- i += 2;
6255
- while (i < sql.length && sql[i] !== "\n") i++;
6256
- continue;
6257
- }
6258
- if (ch === "/" && sql[i + 1] === "*") {
6259
- i += 2;
6260
- while (i < sql.length) {
6261
- if (sql[i] === "*" && sql[i + 1] === "/") {
6262
- i += 2;
6263
- break;
6264
- }
6265
- i++;
6266
- }
6267
- continue;
6268
- }
6269
- const parsed = tryParseAppProfileToken(sql, i);
6270
- if (!parsed) {
6271
- i++;
6272
- continue;
6273
- }
6274
- tokens.push(parsed);
6275
- i = parsed.fullEnd;
6276
- }
6277
- return tokens;
6278
- }
6279
- function nextVirtualAppId(used) {
6280
- let id = 9e8;
6281
- while (used.has(id)) id++;
6282
- used.add(id);
6283
- return id;
6284
- }
6285
- function normalizeSqlAppProfiles(sql, defaultProfile = "dev") {
6286
- const tokens = collectAppProfileTokens(sql);
6287
- const hasProfileSyntax = tokens.some((t) => t.profile !== null);
6288
- const profilesByApp = /* @__PURE__ */ new Map();
6289
- const normalizedProfile = (profile) => profile ?? defaultProfile;
6290
- for (const t of tokens) {
6291
- const p = normalizedProfile(t.profile);
6292
- let set = profilesByApp.get(t.appId);
6293
- if (!set) {
6294
- set = /* @__PURE__ */ new Set();
6295
- profilesByApp.set(t.appId, set);
6296
- }
6297
- set.add(p.toLowerCase());
6298
- }
6299
- const usedAppIds = new Set(tokens.map((t) => t.appId));
6300
- const pairToMapped = /* @__PURE__ */ new Map();
6301
- const appBindingByMappedApp = /* @__PURE__ */ new Map();
6302
- for (const [appId, pSet] of profilesByApp.entries()) {
6303
- const profiles = [...pSet].sort();
6304
- if (profiles.length <= 1) continue;
6305
- for (const pLower of profiles) {
6306
- const mapped = nextVirtualAppId(usedAppIds);
6307
- pairToMapped.set(`${appId}@${pLower}`, mapped);
6308
- appBindingByMappedApp.set(mapped, { appId, profile: pLower });
6309
- }
6310
- }
6311
- const out = [];
6312
- let cursor = 0;
6313
- for (const t of tokens) {
6314
- const p = normalizedProfile(t.profile);
6315
- const pLower = p.toLowerCase();
6316
- const mapped = pairToMapped.get(`${t.appId}@${pLower}`) ?? t.appId;
6317
- appBindingByMappedApp.set(mapped, { appId: t.appId, profile: pLower });
6318
- out.push(sql.slice(cursor, t.start));
6319
- out.push(sql.slice(t.start, t.digitStart));
6320
- out.push(String(mapped));
6321
- out.push(sql.slice(t.digitEnd, t.appEnd));
6322
- cursor = t.fullEnd;
6323
- }
6324
- out.push(sql.slice(cursor));
6325
- return {
6326
- normalizedSql: out.join(""),
6327
- hasProfileSyntax,
6328
- appBindingByMappedApp
6329
- };
6330
- }
6331
- function buildCacheContext(defaultProfile, appBindingByMappedApp) {
6332
- if (appBindingByMappedApp.size === 0) return `default:${defaultProfile.toLowerCase()}`;
6333
- const pairs = [...appBindingByMappedApp.entries()].sort((a, b) => a[0] - b[0]).map(([mappedAppId, b]) => `M${mappedAppId}=APP${b.appId}@${b.profile}`);
6334
- return `apps:${pairs.join(",")}`;
6335
- }
6336
- function formatResolvedAppProfiles(sql, defaultProfile) {
6337
- const parsed = normalizeSqlAppProfiles(sql, defaultProfile);
6338
- if (parsed.appBindingByMappedApp.size === 0) return "(none)";
6339
- return [...parsed.appBindingByMappedApp.values()].map((b) => `APP${b.appId}->${b.profile}`).join(", ");
6340
- }
6341
6374
  function resolveTokenValue(raw) {
6342
6375
  if (raw.startsWith("env:")) {
6343
6376
  const envKey = raw.slice(4);
@@ -6379,42 +6412,6 @@ function envAuth(name) {
6379
6412
  if (v === "token" || v === "userpass" || v === "auto") return v;
6380
6413
  return null;
6381
6414
  }
6382
- function isDmlType(type) {
6383
- return type === "INSERT" || type === "INSERT_SELECT" || type === "UPDATE" || type === "DELETE" || type === "UPSERT" || type === "UPSERT_SELECT";
6384
- }
6385
- function hasWhereClause(stmt) {
6386
- if (!stmt || typeof stmt !== "object") return false;
6387
- const obj = stmt;
6388
- return obj.where !== null && obj.where !== void 0;
6389
- }
6390
- function getStatementType(stmt) {
6391
- if (!stmt || typeof stmt !== "object") return "UNKNOWN";
6392
- const obj = stmt;
6393
- return typeof obj.type === "string" ? obj.type : "UNKNOWN";
6394
- }
6395
- function isNoFromSelectStatement(stmt) {
6396
- if (!stmt || typeof stmt !== "object") return false;
6397
- const obj = stmt;
6398
- return obj.type === "SELECT" && obj.from?.appId === 0 && obj.from?.cteName === "__NO_FROM__";
6399
- }
6400
- function getInsertValuesCount(stmt) {
6401
- if (!stmt || typeof stmt !== "object") return null;
6402
- const obj = stmt;
6403
- if (obj.type !== "INSERT") return null;
6404
- return Array.isArray(obj.values) ? obj.values.length : null;
6405
- }
6406
- function collectDmlTargetFields(stmt) {
6407
- if (!stmt || typeof stmt !== "object") return [];
6408
- const obj = stmt;
6409
- if (!obj.type) return [];
6410
- if (obj.type === "UPDATE") {
6411
- return (obj.assignments ?? []).map((a) => a.field).filter((f) => Boolean(f));
6412
- }
6413
- if (obj.type === "INSERT" || obj.type === "INSERT_SELECT" || obj.type === "UPSERT" || obj.type === "UPSERT_SELECT") {
6414
- return [...obj.fields ?? [], ...obj.keyFields ?? []];
6415
- }
6416
- return [];
6417
- }
6418
6415
  function normalizeUnique(values) {
6419
6416
  const out = [];
6420
6417
  const seen = /* @__PURE__ */ new Set();
@@ -6799,9 +6796,9 @@ function getHistoryPath() {
6799
6796
  }
6800
6797
  function loadHistory(maxItems = 200) {
6801
6798
  const p = getHistoryPath();
6802
- if (!(0, import_fs.existsSync)(p)) return [];
6799
+ if (!(0, import_fs2.existsSync)(p)) return [];
6803
6800
  try {
6804
- const raw = (0, import_fs.readFileSync)(p, "utf-8");
6801
+ const raw = (0, import_fs2.readFileSync)(p, "utf-8");
6805
6802
  const lines = raw.split(/\r?\n/).map((s) => s.trim()).filter((s) => s.length > 0);
6806
6803
  return lines.slice(-maxItems);
6807
6804
  } catch {
@@ -6811,26 +6808,26 @@ function loadHistory(maxItems = 200) {
6811
6808
  function appendHistory(sql) {
6812
6809
  const p = getHistoryPath();
6813
6810
  try {
6814
- (0, import_fs.appendFileSync)(p, `${sql.replace(/\s+/g, " ").trim()}
6811
+ (0, import_fs2.appendFileSync)(p, `${sql.replace(/\s+/g, " ").trim()}
6815
6812
  `, "utf-8");
6816
6813
  } catch {
6817
6814
  }
6818
6815
  }
6819
6816
  function editBufferWithExternalEditor(current) {
6820
6817
  const editor = process.env.KSQL_EDITOR ?? process.env.VISUAL ?? process.env.EDITOR ?? (process.platform === "win32" ? "notepad" : "vi");
6821
- const dir = (0, import_fs.mkdtempSync)((0, import_path.join)((0, import_os.tmpdir)(), "ksql-edit-"));
6818
+ const dir = (0, import_fs2.mkdtempSync)((0, import_path.join)((0, import_os.tmpdir)(), "ksql-edit-"));
6822
6819
  const filePath = (0, import_path.join)(dir, "query.sql");
6823
6820
  try {
6824
- (0, import_fs.writeFileSync)(filePath, current, "utf-8");
6821
+ (0, import_fs2.writeFileSync)(filePath, current, "utf-8");
6825
6822
  const cmd = `"${editor}" "${filePath}"`;
6826
6823
  const res = (0, import_child_process.spawnSync)(cmd, { stdio: "inherit", shell: true });
6827
6824
  if (res.error) throw res.error;
6828
6825
  if ((res.status ?? 0) !== 0) {
6829
6826
  throw new Error(`Editor exited with code ${res.status ?? 1}`);
6830
6827
  }
6831
- return (0, import_fs.readFileSync)(filePath, "utf-8").replace(/\r\n/g, "\n");
6828
+ return (0, import_fs2.readFileSync)(filePath, "utf-8").replace(/\r\n/g, "\n");
6832
6829
  } finally {
6833
- (0, import_fs.rmSync)(dir, { recursive: true, force: true });
6830
+ (0, import_fs2.rmSync)(dir, { recursive: true, force: true });
6834
6831
  }
6835
6832
  }
6836
6833
  async function runConsole(base) {
@@ -7012,11 +7009,11 @@ async function runConsole(base) {
7012
7009
  }
7013
7010
  try {
7014
7011
  if (meta.append) {
7015
- (0, import_fs.appendFileSync)(meta.path, lastOutput, "utf-8");
7012
+ (0, import_fs2.appendFileSync)(meta.path, lastOutput, "utf-8");
7016
7013
  process.stdout.write(`saved (append): ${meta.path}
7017
7014
  `);
7018
7015
  } else {
7019
- (0, import_fs.writeFileSync)(meta.path, lastOutput, "utf-8");
7016
+ (0, import_fs2.writeFileSync)(meta.path, lastOutput, "utf-8");
7020
7017
  process.stdout.write(`saved: ${meta.path}
7021
7018
  `);
7022
7019
  }
@@ -7127,7 +7124,7 @@ async function run() {
7127
7124
  let isDmlStatement = false;
7128
7125
  if (args.diagRecordId === null) {
7129
7126
  sql = args.executeSql;
7130
- if (!sql && args.filePath) sql = (0, import_fs.readFileSync)(args.filePath, "utf-8");
7127
+ if (!sql && args.filePath) sql = (0, import_fs2.readFileSync)(args.filePath, "utf-8");
7131
7128
  if (!sql || !sql.trim()) {
7132
7129
  process.stderr.write("ArgumentError: SQL is empty.\n");
7133
7130
  return 2;
@@ -7208,7 +7205,7 @@ async function run() {
7208
7205
  return 2;
7209
7206
  }
7210
7207
  if (!allowDml) {
7211
- process.stderr.write("ArgumentError: DML is disabled. Use --allow-dml to enable UPDATE/DELETE/INSERT/UPSERT.\n");
7208
+ process.stderr.write("ArgumentError: DML is disabled. Use --allow-dml to enable UPDATE/DELETE/INSERT/UPSERT/REORDER.\n");
7212
7209
  return 2;
7213
7210
  }
7214
7211
  if ((stmtType === "UPDATE" || stmtType === "DELETE") && !hasWhere && !allowWithoutWhere) {
@@ -7484,7 +7481,7 @@ query=${label}`);
7484
7481
  });
7485
7482
  if (result.type !== "SELECT") {
7486
7483
  const output2 = buildMutationOutput(result, format, noHeader, pretty);
7487
- if (outputPath) (0, import_fs.writeFileSync)(outputPath, `${output2}
7484
+ if (outputPath) (0, import_fs2.writeFileSync)(outputPath, `${output2}
7488
7485
  `, "utf-8");
7489
7486
  else if (output2) process.stdout.write(`${output2}
7490
7487
  `);
@@ -7493,7 +7490,7 @@ query=${label}`);
7493
7490
  return 0;
7494
7491
  }
7495
7492
  const output = buildOutput(result, format, noHeader, pretty, displayOptions);
7496
- if (outputPath) (0, import_fs.writeFileSync)(outputPath, `${output}
7493
+ if (outputPath) (0, import_fs2.writeFileSync)(outputPath, `${output}
7497
7494
  `, "utf-8");
7498
7495
  else if (output) process.stdout.write(`${output}
7499
7496
  `);