@carbonorm/carbonnode 6.0.14 → 6.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/dist/executors/SqlExecutor.d.ts +17 -0
  2. package/dist/index.cjs.js +450 -248
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.esm.js +450 -249
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/types/ormInterfaces.d.ts +1 -0
  7. package/dist/utils/cacheManager.d.ts +3 -1
  8. package/dist/utils/logLevel.d.ts +3 -3
  9. package/dist/utils/logSql.d.ts +10 -1
  10. package/package.json +2 -2
  11. package/scripts/assets/handlebars/C6.ts.handlebars +1 -1
  12. package/src/__tests__/fixtures/sqlResponses/sqlAllowList.json +1 -1
  13. package/src/__tests__/httpExecutor.cacheEviction.test.ts +70 -0
  14. package/src/__tests__/logSql.test.ts +54 -2
  15. package/src/__tests__/sakila-db/C6.js +1 -1
  16. package/src/__tests__/sakila-db/C6.mysqldump.json +1 -1
  17. package/src/__tests__/sakila-db/C6.mysqldump.sql +1 -1
  18. package/src/__tests__/sakila-db/C6.sqlAllowList.json +59 -70
  19. package/src/__tests__/sakila-db/C6.ts +2 -2
  20. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +3 -3
  21. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +3 -3
  22. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +1 -1
  23. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +3 -3
  24. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +5 -5
  25. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +5 -5
  26. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +1 -1
  27. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +5 -5
  28. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +2 -2
  29. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +2 -2
  30. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +1 -1
  31. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +2 -2
  32. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +2 -2
  33. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +2 -2
  34. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +1 -1
  35. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +2 -2
  36. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +2 -2
  37. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +2 -2
  38. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +1 -1
  39. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +2 -2
  40. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +5 -5
  41. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +5 -5
  42. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +1 -1
  43. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +5 -5
  44. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +2 -2
  45. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +2 -2
  46. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +1 -1
  47. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +2 -2
  48. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +1 -1
  49. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +1 -1
  50. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +1 -1
  51. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +1 -1
  52. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +2 -2
  53. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +2 -2
  54. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +1 -1
  55. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +2 -2
  56. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +2 -2
  57. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +2 -2
  58. package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +2 -2
  59. package/src/__tests__/sakila-db/sqlResponses/C6.rental.join.json +10 -10
  60. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +3 -3
  61. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +3 -3
  62. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +1 -1
  63. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +3 -3
  64. package/src/__tests__/sqlAllowList.test.ts +100 -0
  65. package/src/__tests__/sqlBuilders.test.ts +3 -4
  66. package/src/__tests__/sqlExecutor.cacheEviction.test.ts +79 -0
  67. package/src/executors/HttpExecutor.ts +20 -4
  68. package/src/executors/SqlExecutor.ts +131 -12
  69. package/src/orm/queries/DeleteQueryBuilder.ts +0 -4
  70. package/src/orm/queries/PostQueryBuilder.ts +0 -4
  71. package/src/orm/queries/SelectQueryBuilder.ts +0 -4
  72. package/src/orm/queries/UpdateQueryBuilder.ts +0 -4
  73. package/src/types/ormInterfaces.ts +4 -1
  74. package/src/utils/cacheManager.ts +26 -9
  75. package/src/utils/logLevel.ts +3 -4
  76. package/src/utils/logSql.ts +51 -6
  77. package/src/utils/sqlAllowList.ts +111 -9
package/dist/index.esm.js CHANGED
@@ -514,8 +514,6 @@ var applyLogLevelDefaults = function (config, request) {
514
514
  };
515
515
  var getLogContext = function (config, request) {
516
516
  var _a, _b;
517
- if (!config && !request)
518
- return undefined;
519
517
  return {
520
518
  logLevel: (_a = config === null || config === void 0 ? void 0 : config.logLevel) !== null && _a !== void 0 ? _a : undefined,
521
519
  verbose: (_b = config === null || config === void 0 ? void 0 : config.verbose) !== null && _b !== void 0 ? _b : undefined,
@@ -862,6 +860,213 @@ function removeInvalidKeys(request, c6Tables) {
862
860
  return intersection;
863
861
  }
864
862
 
863
+ /* eslint-disable no-control-regex */
864
+ var RESET = "\x1b[0m";
865
+ var C$1 = {
866
+ KEYWORD: "\x1b[94m", // blue
867
+ LIMIT: "\x1b[93m", // yellow
868
+ NUMBER: "\x1b[92m", // green
869
+ DIM: "\x1b[90m", // gray
870
+ };
871
+ /* ---------- ANSI helpers ---------- */
872
+ var ansi256 = function (n) { return "\u001B[38;5;".concat(n, "m"); };
873
+ /* ---------- hashing ---------- */
874
+ function hashString$1(str) {
875
+ var hash = 0;
876
+ for (var i = 0; i < str.length; i++) {
877
+ hash = (hash * 31 + str.charCodeAt(i)) | 0;
878
+ }
879
+ return Math.abs(hash);
880
+ }
881
+ /* ---------- table color ---------- */
882
+ function tableRGB(tableName) {
883
+ var name = tableName.replace(/[`"]/g, "").toLowerCase();
884
+ var hash = hashString$1(name);
885
+ // Stable hue bucket by first letter
886
+ var first = name.charCodeAt(0) || 97;
887
+ var hueBase = (first - 97) % 6;
888
+ var r = (hueBase + (hash % 3)) % 6;
889
+ var g = (hash >> 3) % 6;
890
+ var b = (hash >> 6) % 6;
891
+ return [r, g, Math.max(2, b)]; // avoid muddy dark blues
892
+ }
893
+ function tableColor(table) {
894
+ var _a = tableRGB(table), r = _a[0], g = _a[1], b = _a[2];
895
+ return ansi256(16 + 36 * r + 6 * g + b);
896
+ }
897
+ /* ---------- column color (same hue, lighter) ---------- */
898
+ function columnColorFromTable(table) {
899
+ var _a = tableRGB(table), r = _a[0], g = _a[1], b = _a[2];
900
+ // Lift toward white, preserve hue
901
+ var lr = Math.min(5, r + 1);
902
+ var lg = Math.min(5, g + 1);
903
+ var lb = Math.min(5, b + 2);
904
+ return ansi256(16 + 36 * lr + 6 * lg + lb);
905
+ }
906
+ /* ---------- bind collapsing ---------- */
907
+ /**
908
+ * ?, ?, ?, ?, ?, ? → ? ×6
909
+ * triggers at 4+
910
+ */
911
+ function collapseBinds(sql) {
912
+ return sql.replace(/(\?\s*,\s*){3,}\?/g, function (match) {
913
+ var count = match.split("?").length - 1;
914
+ return "".concat(C$1.DIM, "? \u00D7").concat(count).concat(RESET);
915
+ });
916
+ }
917
+ /**
918
+ * ( ? ×9 ), ( ? ×9 ), ( ? ×9 ) -> ( ? ×9 ) ×3
919
+ */
920
+ function collapseRepeatedValueRows(sql) {
921
+ var repeatedRowPattern = /(\((?:\x1b\[[0-9;]*m)?\?\s*×\d+(?:\x1b\[[0-9;]*m)?\)|\(\s*(?:\?\s*,\s*)+\?\s*\))(?:\s*,\s*\1){2,}/g;
922
+ return sql.replace(repeatedRowPattern, function (match, row) {
923
+ var _a, _b;
924
+ var rowMatches = match.match(new RegExp(row.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"));
925
+ var count = (_a = rowMatches === null || rowMatches === void 0 ? void 0 : rowMatches.length) !== null && _a !== void 0 ? _a : 1;
926
+ var normalizedRow = row.includes("×")
927
+ ? row
928
+ : "(".concat(C$1.DIM, "? \u00D7").concat(((_b = row.match(/\?/g)) !== null && _b !== void 0 ? _b : []).length).concat(RESET, ")");
929
+ return "".concat(normalizedRow, " ").concat(C$1.DIM, "\u00D7").concat(count).concat(RESET);
930
+ });
931
+ }
932
+ /* ---------- main formatter ---------- */
933
+ function colorSql(sql) {
934
+ var s = sql.trim();
935
+ /* 1️⃣ collapse bind noise */
936
+ s = collapseBinds(s);
937
+ s = collapseRepeatedValueRows(s);
938
+ /* 2️⃣ table.column coloring (core visual grouping) */
939
+ s = s.replace(/\b(`?\w+`?)\.(\w+)\b/g, function (_, table, column) {
940
+ return "".concat(tableColor(table)).concat(table).concat(RESET, ".") +
941
+ "".concat(columnColorFromTable(table)).concat(column).concat(RESET);
942
+ });
943
+ /* 3️⃣ FROM / JOIN tables */
944
+ s = s.replace(/\b(FROM|JOIN|UPDATE|INTO)\s+(`[^`]+`|\w+)/gi, function (_, kw, table) {
945
+ return "".concat(C$1.KEYWORD).concat(kw).concat(RESET, " ").concat(tableColor(table)).concat(table).concat(RESET);
946
+ });
947
+ /* 4️⃣ SQL keywords */
948
+ s = s.replace(/\b(SELECT|WHERE|AND|OR|ON|IN|BETWEEN|EXISTS|ORDER BY|GROUP BY|HAVING|SET|VALUES|INSERT|REPLACE|DELETE|UPDATE|DUPLICATE|KEY)\b/gi, "".concat(C$1.KEYWORD, "$1").concat(RESET));
949
+ /* 5️⃣ LIMIT */
950
+ s = s.replace(/\bLIMIT\s+(\d+)/gi, "".concat(C$1.LIMIT, "LIMIT").concat(RESET, " ").concat(C$1.NUMBER, "$1").concat(RESET));
951
+ return s;
952
+ }
953
+
954
+ var version = "6.0.18";
955
+
956
+ var DEFAULT_STEP = 8;
957
+ function parseSemver(version) {
958
+ var _a = version.trim().split("-"), core = _a[0], prerelease = _a[1];
959
+ var _b = core.split("."), majorRaw = _b[0], minorRaw = _b[1], patchRaw = _b[2];
960
+ var major = Number.parseInt(majorRaw !== null && majorRaw !== void 0 ? majorRaw : "0", 10);
961
+ var minor = Number.parseInt(minorRaw !== null && minorRaw !== void 0 ? minorRaw : "0", 10);
962
+ var patch = Number.parseInt(patchRaw !== null && patchRaw !== void 0 ? patchRaw : "0", 10);
963
+ var prereleaseParts = prerelease ? prerelease.split(".").filter(Boolean).length : 0;
964
+ return {
965
+ major: Number.isFinite(major) ? major : 0,
966
+ minor: Number.isFinite(minor) ? minor : 0,
967
+ patch: Number.isFinite(patch) ? patch : 0,
968
+ prereleaseParts: prereleaseParts,
969
+ };
970
+ }
971
+ function channelValue(n, step) {
972
+ var value = 255 - ((n * step) % 256);
973
+ return (value + 256) % 256;
974
+ }
975
+ function versionToRgb(version, step) {
976
+ if (step === void 0) { step = DEFAULT_STEP; }
977
+ var safeStep = Number.isFinite(step) && step > 0 ? Math.floor(step) : DEFAULT_STEP;
978
+ var _a = parseSemver(version), major = _a.major, minor = _a.minor, patch = _a.patch, prereleaseParts = _a.prereleaseParts;
979
+ var rotation = (major + minor + patch + prereleaseParts) % 3;
980
+ var base = [major, minor, patch];
981
+ var rotated = rotation === 1
982
+ ? [base[2], base[0], base[1]]
983
+ : rotation === 2
984
+ ? [base[1], base[2], base[0]]
985
+ : base;
986
+ return {
987
+ r: channelValue(rotated[0], safeStep),
988
+ g: channelValue(rotated[1], safeStep),
989
+ b: channelValue(rotated[2], safeStep),
990
+ };
991
+ }
992
+
993
+ var C = {
994
+ SSR: "\x1b[95m", // bright magenta
995
+ HTTP: "\x1b[94m", // bright blue
996
+ WARN: "\x1b[93m", // yellow
997
+ ORANGE: "\x1b[38;2;255;165;0m", // orange (truecolor)
998
+ ERROR: "\x1b[91m", // red
999
+ METHOD_COLORS: {
1000
+ SELECT: "\x1b[92m", // green
1001
+ INSERT: "\x1b[96m", // cyan
1002
+ REPLACE: "\x1b[96m", // cyan
1003
+ UPDATE: "\x1b[95m", // magenta
1004
+ DELETE: "\x1b[38;2;255;179;179m", // very light red (truecolor)
1005
+ },
1006
+ METHOD_FALLBACK: [
1007
+ "\x1b[92m", // green
1008
+ "\x1b[93m", // yellow
1009
+ "\x1b[95m", // magenta
1010
+ "\x1b[96m", // cyan
1011
+ "\x1b[94m", // blue
1012
+ "\x1b[97m", // white
1013
+ ],
1014
+ GREY: "\x1b[90m", // light grey
1015
+ RESET: "\x1b[0m",
1016
+ };
1017
+ var rgbAnsi = function (_a) {
1018
+ var r = _a.r, g = _a.g, b = _a.b;
1019
+ return "\u001B[38;2;".concat(r, ";").concat(g, ";").concat(b, "m");
1020
+ };
1021
+ function hashString(value) {
1022
+ var hash = 0;
1023
+ for (var i = 0; i < value.length; i++) {
1024
+ hash = (hash * 31 + value.charCodeAt(i)) | 0;
1025
+ }
1026
+ return Math.abs(hash);
1027
+ }
1028
+ function methodColor(method) {
1029
+ var key = method.toUpperCase();
1030
+ if (key in C.METHOD_COLORS) {
1031
+ return C.METHOD_COLORS[key];
1032
+ }
1033
+ var idx = hashString(key) % C.METHOD_FALLBACK.length;
1034
+ return C.METHOD_FALLBACK[idx];
1035
+ }
1036
+ var cacheLabel = function (cacheStatus) {
1037
+ switch (cacheStatus) {
1038
+ case "hit":
1039
+ return "".concat(C.METHOD_COLORS.SELECT, "[CACHE HIT]").concat(C.RESET);
1040
+ case "ignored":
1041
+ return "".concat(C.WARN, "[CACHE IGNORED]").concat(C.RESET);
1042
+ default:
1043
+ return "".concat(C.ORANGE, "[CACHE MISS]").concat(C.RESET);
1044
+ }
1045
+ };
1046
+ var allowListLabel = function (status) {
1047
+ switch (status) {
1048
+ case "allowed":
1049
+ return "".concat(C.METHOD_COLORS.SELECT, "[VERIFIED]").concat(C.RESET);
1050
+ case "denied":
1051
+ return "".concat(C.ERROR, "[DENIED]").concat(C.RESET);
1052
+ default:
1053
+ return "".concat(C.GREY, "[NOT VERIFIED]").concat(C.RESET);
1054
+ }
1055
+ };
1056
+ function logSql(options) {
1057
+ var method = options.method.toUpperCase();
1058
+ if (!shouldLog(LogLevel.INFO, options.context))
1059
+ return;
1060
+ var preText = getEnvBool("SSR", false)
1061
+ ? "".concat(C.SSR, "[SSR]").concat(C.RESET, " ")
1062
+ : "".concat(C.HTTP, "[API]").concat(C.RESET, " ");
1063
+ var labelColor = methodColor(method);
1064
+ var versionColor = rgbAnsi(versionToRgb(version));
1065
+ var cacheText = cacheLabel(options.cacheStatus);
1066
+ var allowListText = allowListLabel(options.allowListStatus);
1067
+ console.log("".concat(versionColor, "[").concat(version, "]").concat(C.RESET, " ").concat(cacheText, " ").concat(allowListText, " ").concat(preText).concat(labelColor, "[").concat(method, "]").concat(C.RESET, " ").concat(colorSql(options.sql)));
1068
+ }
1069
+
865
1070
  // -----------------------------------------------------------------------------
866
1071
  // Cache Storage
867
1072
  // -----------------------------------------------------------------------------
@@ -904,15 +1109,24 @@ function clearCache(props) {
904
1109
  // -----------------------------------------------------------------------------
905
1110
  // Check Cache (dedupe via hashed key)
906
1111
  // -----------------------------------------------------------------------------
907
- function checkCache(method, tableName, requestData) {
1112
+ function checkCache(method, tableName, requestData, logContext) {
1113
+ var _a, _b, _c, _d, _e;
908
1114
  var key = makeCacheKey(method, tableName, requestData);
909
1115
  var cached = apiRequestCache.get(key);
910
- if (!cached)
1116
+ if (!cached) {
1117
+ console.log('apiRequestCache.size', apiRequestCache.size);
911
1118
  return false;
912
- if (shouldLog(LogLevel.INFO, undefined)) {
913
- console.groupCollapsed("%c API cache hit for ".concat(method, " ").concat(tableName), "color:#0c0");
914
- console.log("Request Data:", requestData);
915
- console.groupEnd();
1119
+ }
1120
+ if (shouldLog(LogLevel.INFO, logContext)) {
1121
+ var sql = (_d = (_c = (_b = (_a = cached.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.sql) === null || _c === void 0 ? void 0 : _c.sql) !== null && _d !== void 0 ? _d : "";
1122
+ var sqlMethod = ((_e = sql.trim().split(/\s+/, 1)[0]) === null || _e === void 0 ? void 0 : _e.toUpperCase()) || method;
1123
+ logSql({
1124
+ allowListStatus: "not verified",
1125
+ cacheStatus: "hit",
1126
+ context: logContext,
1127
+ method: sqlMethod,
1128
+ sql: sql
1129
+ });
916
1130
  }
917
1131
  return cached.request;
918
1132
  }
@@ -923,6 +1137,10 @@ function setCache(method, tableName, requestData, cacheEntry) {
923
1137
  var key = makeCacheKey(method, tableName, requestData);
924
1138
  apiRequestCache.set(key, cacheEntry);
925
1139
  }
1140
+ function evictCacheEntry(method, tableName, requestData) {
1141
+ var key = makeCacheKey(method, tableName, requestData);
1142
+ return apiRequestCache.delete(key);
1143
+ }
926
1144
 
927
1145
  function sortAndSerializeQueryObject(tables, query) {
928
1146
  var orderedQuery = Object.keys(query).sort().reduce(function (obj, key) {
@@ -1048,7 +1266,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1048
1266
  }
1049
1267
  query = this.request;
1050
1268
  apiRequest = function () { return __awaiter(_this, void 0, void 0, function () {
1051
- var _a, debug, _b, cacheResults, dataInsertMultipleRows, success, _c, fetchDependencies, _d, error, cachingConfirmed, cacheRequestData, querySerialized, cachedRequest, apiResponse, restRequestUri, needsConditionOrPrimaryCheck, TABLES, primaryKeyList, primaryKeyFullyQualified, primaryKey, whereVal, whereIsEmpty, providedPrimary, primaryVal, axiosActiveRequest_1;
1269
+ var _a, debug, _b, cacheResults, dataInsertMultipleRows, success, _c, fetchDependencies, _d, error, cachingConfirmed, cacheRequestData, evictFromCache, querySerialized, cachedRequest, cachedData, apiResponse, restRequestUri, needsConditionOrPrimaryCheck, TABLES, primaryKeyList, primaryKeyFullyQualified, primaryKey, whereVal, whereIsEmpty, providedPrimary, primaryVal, axiosActiveRequest_1;
1052
1270
  var _e;
1053
1271
  var _this = this;
1054
1272
  var _f, _g, _h, _j, _k, _l;
@@ -1078,14 +1296,25 @@ var HttpExecutor = /** @class */ (function (_super) {
1078
1296
  query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
1079
1297
  }
1080
1298
  cacheRequestData = JSON.parse(JSON.stringify(query !== null && query !== void 0 ? query : {}));
1299
+ evictFromCache = requestMethod === GET && cacheResults
1300
+ ? function () { return evictCacheEntry(requestMethod, tableName, cacheRequestData); }
1301
+ : undefined;
1081
1302
  querySerialized = sortAndSerializeQueryObject(tables, cacheRequestData !== null && cacheRequestData !== void 0 ? cacheRequestData : {});
1082
1303
  cachedRequest = false;
1083
1304
  if (cacheResults) {
1084
- cachedRequest = checkCache(requestMethod, tableName, cacheRequestData);
1305
+ cachedRequest = checkCache(requestMethod, tableName, cacheRequestData, logContext);
1085
1306
  }
1086
1307
  if (!cachedRequest) return [3 /*break*/, 2];
1087
1308
  return [4 /*yield*/, cachedRequest];
1088
- case 1: return [2 /*return*/, (_m.sent()).data];
1309
+ case 1:
1310
+ cachedData = (_m.sent()).data;
1311
+ if (evictFromCache
1312
+ && cachedData
1313
+ && typeof cachedData === "object"
1314
+ && Array.isArray(cachedData.rest)) {
1315
+ cachedData.evictFromCache = evictFromCache;
1316
+ }
1317
+ return [2 /*return*/, cachedData];
1089
1318
  case 2:
1090
1319
  if (cacheResults) {
1091
1320
  cachingConfirmed = true;
@@ -1276,7 +1505,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1276
1505
  else {
1277
1506
  callback();
1278
1507
  }
1279
- if (!(C6.GET === requestMethod && this.isRestResponse(response))) return [3 /*break*/, 2];
1508
+ if (!(requestMethod === GET && this.isRestResponse(response))) return [3 /*break*/, 2];
1280
1509
  responseData_1 = response.data;
1281
1510
  pageLimit = (_a = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _a === void 0 ? void 0 : _a[C6.LIMIT];
1282
1511
  got = responseData_1.rest.length;
@@ -1287,6 +1516,9 @@ var HttpExecutor = /** @class */ (function (_super) {
1287
1516
  else {
1288
1517
  responseData_1.next = undefined; // short page => done
1289
1518
  }
1519
+ if (cachingConfirmed && evictFromCache) {
1520
+ responseData_1.evictFromCache = evictFromCache;
1521
+ }
1290
1522
  if (cachingConfirmed) {
1291
1523
  setCache(requestMethod, tableName, cacheRequestData, {
1292
1524
  requestArgumentsSerialized: querySerialized,
@@ -2942,186 +3174,6 @@ var PaginationBuilder = /** @class */ (function (_super) {
2942
3174
  return PaginationBuilder;
2943
3175
  }(JoinBuilder));
2944
3176
 
2945
- /* eslint-disable no-control-regex */
2946
- var RESET = "\x1b[0m";
2947
- var C$1 = {
2948
- KEYWORD: "\x1b[94m", // blue
2949
- LIMIT: "\x1b[93m", // yellow
2950
- NUMBER: "\x1b[92m", // green
2951
- DIM: "\x1b[90m", // gray
2952
- };
2953
- /* ---------- ANSI helpers ---------- */
2954
- var ansi256 = function (n) { return "\u001B[38;5;".concat(n, "m"); };
2955
- /* ---------- hashing ---------- */
2956
- function hashString$1(str) {
2957
- var hash = 0;
2958
- for (var i = 0; i < str.length; i++) {
2959
- hash = (hash * 31 + str.charCodeAt(i)) | 0;
2960
- }
2961
- return Math.abs(hash);
2962
- }
2963
- /* ---------- table color ---------- */
2964
- function tableRGB(tableName) {
2965
- var name = tableName.replace(/[`"]/g, "").toLowerCase();
2966
- var hash = hashString$1(name);
2967
- // Stable hue bucket by first letter
2968
- var first = name.charCodeAt(0) || 97;
2969
- var hueBase = (first - 97) % 6;
2970
- var r = (hueBase + (hash % 3)) % 6;
2971
- var g = (hash >> 3) % 6;
2972
- var b = (hash >> 6) % 6;
2973
- return [r, g, Math.max(2, b)]; // avoid muddy dark blues
2974
- }
2975
- function tableColor(table) {
2976
- var _a = tableRGB(table), r = _a[0], g = _a[1], b = _a[2];
2977
- return ansi256(16 + 36 * r + 6 * g + b);
2978
- }
2979
- /* ---------- column color (same hue, lighter) ---------- */
2980
- function columnColorFromTable(table) {
2981
- var _a = tableRGB(table), r = _a[0], g = _a[1], b = _a[2];
2982
- // Lift toward white, preserve hue
2983
- var lr = Math.min(5, r + 1);
2984
- var lg = Math.min(5, g + 1);
2985
- var lb = Math.min(5, b + 2);
2986
- return ansi256(16 + 36 * lr + 6 * lg + lb);
2987
- }
2988
- /* ---------- bind collapsing ---------- */
2989
- /**
2990
- * ?, ?, ?, ?, ?, ? → ? ×6
2991
- * triggers at 4+
2992
- */
2993
- function collapseBinds(sql) {
2994
- return sql.replace(/(\?\s*,\s*){3,}\?/g, function (match) {
2995
- var count = match.split("?").length - 1;
2996
- return "".concat(C$1.DIM, "? \u00D7").concat(count).concat(RESET);
2997
- });
2998
- }
2999
- /**
3000
- * ( ? ×9 ), ( ? ×9 ), ( ? ×9 ) -> ( ? ×9 ) ×3
3001
- */
3002
- function collapseRepeatedValueRows(sql) {
3003
- var repeatedRowPattern = /(\((?:\x1b\[[0-9;]*m)?\?\s*×\d+(?:\x1b\[[0-9;]*m)?\)|\(\s*(?:\?\s*,\s*)+\?\s*\))(?:\s*,\s*\1){2,}/g;
3004
- return sql.replace(repeatedRowPattern, function (match, row) {
3005
- var _a, _b;
3006
- var rowMatches = match.match(new RegExp(row.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"));
3007
- var count = (_a = rowMatches === null || rowMatches === void 0 ? void 0 : rowMatches.length) !== null && _a !== void 0 ? _a : 1;
3008
- var normalizedRow = row.includes("×")
3009
- ? row
3010
- : "(".concat(C$1.DIM, "? \u00D7").concat(((_b = row.match(/\?/g)) !== null && _b !== void 0 ? _b : []).length).concat(RESET, ")");
3011
- return "".concat(normalizedRow, " ").concat(C$1.DIM, "\u00D7").concat(count).concat(RESET);
3012
- });
3013
- }
3014
- /* ---------- main formatter ---------- */
3015
- function colorSql(sql) {
3016
- var s = sql.trim();
3017
- /* 1️⃣ collapse bind noise */
3018
- s = collapseBinds(s);
3019
- s = collapseRepeatedValueRows(s);
3020
- /* 2️⃣ table.column coloring (core visual grouping) */
3021
- s = s.replace(/\b(`?\w+`?)\.(\w+)\b/g, function (_, table, column) {
3022
- return "".concat(tableColor(table)).concat(table).concat(RESET, ".") +
3023
- "".concat(columnColorFromTable(table)).concat(column).concat(RESET);
3024
- });
3025
- /* 3️⃣ FROM / JOIN tables */
3026
- s = s.replace(/\b(FROM|JOIN|UPDATE|INTO)\s+(`[^`]+`|\w+)/gi, function (_, kw, table) {
3027
- return "".concat(C$1.KEYWORD).concat(kw).concat(RESET, " ").concat(tableColor(table)).concat(table).concat(RESET);
3028
- });
3029
- /* 4️⃣ SQL keywords */
3030
- s = s.replace(/\b(SELECT|WHERE|AND|OR|ON|IN|BETWEEN|EXISTS|ORDER BY|GROUP BY|HAVING|SET|VALUES|INSERT|REPLACE|DELETE|UPDATE|DUPLICATE|KEY)\b/gi, "".concat(C$1.KEYWORD, "$1").concat(RESET));
3031
- /* 5️⃣ LIMIT */
3032
- s = s.replace(/\bLIMIT\s+(\d+)/gi, "".concat(C$1.LIMIT, "LIMIT").concat(RESET, " ").concat(C$1.NUMBER, "$1").concat(RESET));
3033
- return s;
3034
- }
3035
-
3036
- var version = "6.0.14";
3037
-
3038
- var DEFAULT_STEP = 8;
3039
- function parseSemver(version) {
3040
- var _a = version.trim().split("-"), core = _a[0], prerelease = _a[1];
3041
- var _b = core.split("."), majorRaw = _b[0], minorRaw = _b[1], patchRaw = _b[2];
3042
- var major = Number.parseInt(majorRaw !== null && majorRaw !== void 0 ? majorRaw : "0", 10);
3043
- var minor = Number.parseInt(minorRaw !== null && minorRaw !== void 0 ? minorRaw : "0", 10);
3044
- var patch = Number.parseInt(patchRaw !== null && patchRaw !== void 0 ? patchRaw : "0", 10);
3045
- var prereleaseParts = prerelease ? prerelease.split(".").filter(Boolean).length : 0;
3046
- return {
3047
- major: Number.isFinite(major) ? major : 0,
3048
- minor: Number.isFinite(minor) ? minor : 0,
3049
- patch: Number.isFinite(patch) ? patch : 0,
3050
- prereleaseParts: prereleaseParts,
3051
- };
3052
- }
3053
- function channelValue(n, step) {
3054
- var value = 255 - ((n * step) % 256);
3055
- return (value + 256) % 256;
3056
- }
3057
- function versionToRgb(version, step) {
3058
- if (step === void 0) { step = DEFAULT_STEP; }
3059
- var safeStep = Number.isFinite(step) && step > 0 ? Math.floor(step) : DEFAULT_STEP;
3060
- var _a = parseSemver(version), major = _a.major, minor = _a.minor, patch = _a.patch, prereleaseParts = _a.prereleaseParts;
3061
- var rotation = (major + minor + patch + prereleaseParts) % 3;
3062
- var base = [major, minor, patch];
3063
- var rotated = rotation === 1
3064
- ? [base[2], base[0], base[1]]
3065
- : rotation === 2
3066
- ? [base[1], base[2], base[0]]
3067
- : base;
3068
- return {
3069
- r: channelValue(rotated[0], safeStep),
3070
- g: channelValue(rotated[1], safeStep),
3071
- b: channelValue(rotated[2], safeStep),
3072
- };
3073
- }
3074
-
3075
- var C = {
3076
- SSR: "\x1b[95m", // bright magenta
3077
- HTTP: "\x1b[94m", // bright blue
3078
- METHOD_COLORS: {
3079
- SELECT: "\x1b[92m", // green
3080
- INSERT: "\x1b[96m", // cyan
3081
- REPLACE: "\x1b[96m", // cyan
3082
- UPDATE: "\x1b[95m", // magenta
3083
- DELETE: "\x1b[91m", // red
3084
- },
3085
- METHOD_FALLBACK: [
3086
- "\x1b[92m", // green
3087
- "\x1b[93m", // yellow
3088
- "\x1b[95m", // magenta
3089
- "\x1b[96m", // cyan
3090
- "\x1b[94m", // blue
3091
- "\x1b[97m", // white
3092
- ],
3093
- RESET: "\x1b[0m",
3094
- };
3095
- var rgbAnsi = function (_a) {
3096
- var r = _a.r, g = _a.g, b = _a.b;
3097
- return "\u001B[38;2;".concat(r, ";").concat(g, ";").concat(b, "m");
3098
- };
3099
- function hashString(value) {
3100
- var hash = 0;
3101
- for (var i = 0; i < value.length; i++) {
3102
- hash = (hash * 31 + value.charCodeAt(i)) | 0;
3103
- }
3104
- return Math.abs(hash);
3105
- }
3106
- function methodColor(method) {
3107
- var key = method.toUpperCase();
3108
- if (key in C.METHOD_COLORS) {
3109
- return C.METHOD_COLORS[key];
3110
- }
3111
- var idx = hashString(key) % C.METHOD_FALLBACK.length;
3112
- return C.METHOD_FALLBACK[idx];
3113
- }
3114
- function logSql(method, sql, context) {
3115
- if (!shouldLog(LogLevel.INFO, context))
3116
- return;
3117
- var preText = getEnvBool("SSR", false)
3118
- ? "".concat(C.SSR, "[SSR]").concat(C.RESET, " ")
3119
- : "".concat(C.HTTP, "[API]").concat(C.RESET, " ");
3120
- var labelColor = methodColor(method);
3121
- var versionColor = rgbAnsi(versionToRgb(version));
3122
- console.log("".concat(versionColor, "[").concat(version, "]").concat(C.RESET, " ").concat(preText).concat(labelColor, "[").concat(method, "]").concat(C.RESET, " ").concat(colorSql(sql)));
3123
- }
3124
-
3125
3177
  var SelectQueryBuilder = /** @class */ (function (_super) {
3126
3178
  __extends(SelectQueryBuilder, _super);
3127
3179
  function SelectQueryBuilder() {
@@ -3173,7 +3225,6 @@ var SelectQueryBuilder = /** @class */ (function (_super) {
3173
3225
  else if (!isSubSelect) {
3174
3226
  sql += " LIMIT 100";
3175
3227
  }
3176
- logSql("SELECT", sql, getLogContext(this.config, this.request));
3177
3228
  return { sql: sql, params: params };
3178
3229
  };
3179
3230
  return SelectQueryBuilder;
@@ -3198,7 +3249,6 @@ var DeleteQueryBuilder = /** @class */ (function (_super) {
3198
3249
  if (this.request.WHERE) {
3199
3250
  sql += this.buildWhereClause(this.request.WHERE, params);
3200
3251
  }
3201
- logSql("DELETE", sql, getLogContext(this.config, this.request));
3202
3252
  return { sql: sql, params: params };
3203
3253
  };
3204
3254
  return DeleteQueryBuilder;
@@ -3257,7 +3307,6 @@ var PostQueryBuilder = /** @class */ (function (_super) {
3257
3307
  var updateClause = updateData.map(function (k) { return "`".concat(k, "` = VALUES(`").concat(k, "`)"); }).join(', ');
3258
3308
  sql += " ON DUPLICATE KEY UPDATE ".concat(updateClause);
3259
3309
  }
3260
- logSql(verb, sql, getLogContext(this.config, this.request));
3261
3310
  return { sql: sql, params: params };
3262
3311
  };
3263
3312
  return PostQueryBuilder;
@@ -3309,7 +3358,6 @@ var UpdateQueryBuilder = /** @class */ (function (_super) {
3309
3358
  if (args.PAGINATION) {
3310
3359
  sql += this.buildPaginationClause(args.PAGINATION, params);
3311
3360
  }
3312
- logSql("UPDATE", sql, getLogContext(this.config, this.request));
3313
3361
  return { sql: sql, params: params };
3314
3362
  };
3315
3363
  return UpdateQueryBuilder;
@@ -3443,8 +3491,55 @@ function normalizeSingularRequest(requestMethod, request, restModel, removedPrim
3443
3491
  }
3444
3492
 
3445
3493
  var allowListCache = new Map();
3494
+ var ANSI_ESCAPE_REGEX = /\x1b\[[0-9;]*m/g;
3495
+ var COLLAPSED_BIND_ROW_REGEX = /\(\?\s*×\d+\)/g;
3496
+ function collapseBindGroups(sql) {
3497
+ var normalized = sql.replace(/\(\s*(\?(?:\s*,\s*\?)*)\s*\)/g, function (_match, binds) {
3498
+ var _a;
3499
+ var bindCount = ((_a = binds.match(/\?/g)) !== null && _a !== void 0 ? _a : []).length;
3500
+ return "(? \u00D7".concat(bindCount, ")");
3501
+ });
3502
+ normalized = normalized.replace(/(\(\?\s*×\d+\))(?:\s*,\s*\1)+/g, function (_match, row) { return "".concat(row, " \u00D7*"); });
3503
+ normalized = normalized.replace(/\b(VALUES|VALUE)\s+(\(\?\s*×\d+\))(?:\s*×\d+|\s*×\*)?/gi, function (_match, keyword, row) { return "".concat(keyword, " ").concat(row, " \u00D7*"); });
3504
+ normalized = normalized.replace(/\bIN\s*\(\?\s*×\d+\)/gi, "IN (? ×*)");
3505
+ normalized = normalized.replace(/\(\?\s*×\d+\)\s*×\d+/g, function (match) {
3506
+ var _a;
3507
+ var row = (_a = match.match(COLLAPSED_BIND_ROW_REGEX)) === null || _a === void 0 ? void 0 : _a[0];
3508
+ return row ? "".concat(row, " \u00D7*") : match;
3509
+ });
3510
+ return normalized;
3511
+ }
3512
+ function normalizeLimitOffset(sql) {
3513
+ return sql
3514
+ .replace(/\bLIMIT\s+\d+\s*,\s*\d+\b/gi, "LIMIT ?, ?")
3515
+ .replace(/\bLIMIT\s+\d+\s+OFFSET\s+\d+\b/gi, "LIMIT ? OFFSET ?")
3516
+ .replace(/\bLIMIT\s+\d+\b/gi, "LIMIT ?")
3517
+ .replace(/\bOFFSET\s+\d+\b/gi, "OFFSET ?");
3518
+ }
3519
+ function normalizeGeomFromTextLiterals(sql) {
3520
+ var normalized = sql.replace(/ST_GEOMFROMTEXT\(\s*'POINT\([^']*\)'\s*,\s*(?:\d+|\?)\s*\)/gi, "ST_GEOMFROMTEXT('POINT(? ?)', ?)");
3521
+ normalized = normalized.replace(/ST_GEOMFROMTEXT\(\s*'POLYGON\(\([^']*\)\)'\s*,\s*(?:\d+|\?)\s*\)/gi, "ST_GEOMFROMTEXT('POLYGON((?))', ?)");
3522
+ return normalized;
3523
+ }
3524
+ function normalizeGeoFunctionNames(sql) {
3525
+ return sql
3526
+ .replace(/\bST_DISTANCE_SPHERE\b/gi, "ST_DISTANCE_SPHERE")
3527
+ .replace(/\bST_GEOMFROMTEXT\b/gi, "ST_GEOMFROMTEXT")
3528
+ .replace(/\bMBRCONTAINS\b/gi, "MBRCONTAINS");
3529
+ }
3530
+ function normalizeTokenPunctuationSpacing(sql) {
3531
+ return sql.replace(/`,\s*`/g, "`, `");
3532
+ }
3446
3533
  var normalizeSql = function (sql) {
3447
- return sql.replace(/\s+/g, " ").trim();
3534
+ var normalized = sql.replace(ANSI_ESCAPE_REGEX, " ");
3535
+ normalized = normalized.replace(/\s+/g, " ").trim();
3536
+ normalized = normalizeGeoFunctionNames(normalized);
3537
+ normalized = normalizeTokenPunctuationSpacing(normalized);
3538
+ normalized = collapseBindGroups(normalized);
3539
+ normalized = normalizeLimitOffset(normalized);
3540
+ normalized = normalizeGeomFromTextLiterals(normalized);
3541
+ normalized = normalized.replace(/;\s*$/, "");
3542
+ return normalized.replace(/\s+/g, " ").trim();
3448
3543
  };
3449
3544
  var parseAllowList = function (raw, sourcePath) {
3450
3545
  var parsed;
@@ -3467,33 +3562,51 @@ var parseAllowList = function (raw, sourcePath) {
3467
3562
  return sqlEntries;
3468
3563
  };
3469
3564
  var loadSqlAllowList = function (allowListPath) { return __awaiter(void 0, void 0, void 0, function () {
3470
- var readFile, raw, sqlEntries, allowList;
3471
- return __generator(this, function (_a) {
3472
- switch (_a.label) {
3565
+ var _a, readFile, stat, fileStat, cached, raw, sqlEntries, allowList;
3566
+ return __generator(this, function (_b) {
3567
+ switch (_b.label) {
3473
3568
  case 0:
3474
- if (allowListCache.has(allowListPath)) {
3475
- return [2 /*return*/, allowListCache.get(allowListPath)];
3476
- }
3477
3569
  if (!isNode()) {
3478
3570
  throw new Error("SQL allowlist validation requires a Node runtime.");
3479
3571
  }
3480
3572
  return [4 /*yield*/, import('node:fs/promises')];
3481
3573
  case 1:
3482
- readFile = (_a.sent()).readFile;
3483
- _a.label = 2;
3574
+ _a = _b.sent(), readFile = _a.readFile, stat = _a.stat;
3575
+ _b.label = 2;
3484
3576
  case 2:
3485
- _a.trys.push([2, 4, , 5]);
3486
- return [4 /*yield*/, readFile(allowListPath, "utf-8")];
3577
+ _b.trys.push([2, 4, , 5]);
3578
+ return [4 /*yield*/, stat(allowListPath)];
3487
3579
  case 3:
3488
- raw = _a.sent();
3580
+ fileStat = _b.sent();
3489
3581
  return [3 /*break*/, 5];
3490
3582
  case 4:
3491
- _a.sent();
3583
+ _b.sent();
3492
3584
  throw new Error("SQL allowlist file not found at ".concat(allowListPath, "."));
3493
3585
  case 5:
3586
+ cached = allowListCache.get(allowListPath);
3587
+ if (cached &&
3588
+ cached.mtimeMs === fileStat.mtimeMs &&
3589
+ cached.size === fileStat.size) {
3590
+ return [2 /*return*/, cached.allowList];
3591
+ }
3592
+ _b.label = 6;
3593
+ case 6:
3594
+ _b.trys.push([6, 8, , 9]);
3595
+ return [4 /*yield*/, readFile(allowListPath, "utf-8")];
3596
+ case 7:
3597
+ raw = _b.sent();
3598
+ return [3 /*break*/, 9];
3599
+ case 8:
3600
+ _b.sent();
3601
+ throw new Error("SQL allowlist file not found at ".concat(allowListPath, "."));
3602
+ case 9:
3494
3603
  sqlEntries = parseAllowList(raw, allowListPath);
3495
3604
  allowList = new Set(sqlEntries);
3496
- allowListCache.set(allowListPath, allowList);
3605
+ allowListCache.set(allowListPath, {
3606
+ allowList: allowList,
3607
+ mtimeMs: fileStat.mtimeMs,
3608
+ size: fileStat.size,
3609
+ });
3497
3610
  return [2 /*return*/, allowList];
3498
3611
  }
3499
3612
  });
@@ -3556,6 +3669,25 @@ var compileSqlAllowList = function (allowListPath, entries) { return __awaiter(v
3556
3669
  });
3557
3670
  }); };
3558
3671
 
3672
+ var SQL_ALLOWLIST_BLOCKED_CODE = "SQL_ALLOWLIST_BLOCKED";
3673
+ var createSqlAllowListBlockedError = function (args) {
3674
+ var _a, _b;
3675
+ var error = new Error("SQL statement is not permitted by allowlist (".concat(args.allowListPath, ")."));
3676
+ error.name = "SqlAllowListBlockedError";
3677
+ error.code = SQL_ALLOWLIST_BLOCKED_CODE;
3678
+ error.tableName = args.tableName;
3679
+ error.method = args.method;
3680
+ error.normalizedSql = args.normalizedSql;
3681
+ error.allowListPath = args.allowListPath;
3682
+ error.sqlAllowList = {
3683
+ sql: args.normalizedSql,
3684
+ table: (_a = args.tableName) !== null && _a !== void 0 ? _a : null,
3685
+ method: (_b = args.method) !== null && _b !== void 0 ? _b : null,
3686
+ allowListPath: args.allowListPath,
3687
+ canAdd: true,
3688
+ };
3689
+ return error;
3690
+ };
3559
3691
  var SqlExecutor = /** @class */ (function (_super) {
3560
3692
  __extends(SqlExecutor, _super);
3561
3693
  function SqlExecutor() {
@@ -3566,6 +3698,22 @@ var SqlExecutor = /** @class */ (function (_super) {
3566
3698
  })); };
3567
3699
  return _this;
3568
3700
  }
3701
+ SqlExecutor.prototype.resolveSqlLogMethod = function (method, sql) {
3702
+ var _a;
3703
+ var token = (_a = sql.trim().split(/\s+/, 1)[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase();
3704
+ if (token)
3705
+ return token;
3706
+ switch (method) {
3707
+ case C6Constants.GET:
3708
+ return "SELECT";
3709
+ case C6Constants.POST:
3710
+ return "INSERT";
3711
+ case C6Constants.PUT:
3712
+ return "UPDATE";
3713
+ default:
3714
+ return "DELETE";
3715
+ }
3716
+ };
3569
3717
  SqlExecutor.prototype.execute = function () {
3570
3718
  return __awaiter(this, void 0, void 0, function () {
3571
3719
  var TABLE_NAME, method, logContext, response, _a, rest, getResponse, restRows, result, result, result;
@@ -3937,7 +4085,7 @@ var SqlExecutor = /** @class */ (function (_super) {
3937
4085
  };
3938
4086
  SqlExecutor.prototype.runQuery = function () {
3939
4087
  return __awaiter(this, void 0, void 0, function () {
3940
- var method, tableName, logContext, cacheResults, cacheRequestData, requestArgumentsSerialized, cachedRequest, sqlExecution, queryPromise, cacheRequest, cacheResponse;
4088
+ var method, tableName, logContext, cacheResults, cacheRequestData, requestArgumentsSerialized, evictFromCache, cachedRequest, cachedData, sqlExecution, sqlMethod, queryPromise, cacheRequest, cacheResponse;
3941
4089
  var _this = this;
3942
4090
  var _a, _b;
3943
4091
  return __generator(this, function (_c) {
@@ -3947,29 +4095,48 @@ var SqlExecutor = /** @class */ (function (_super) {
3947
4095
  tableName = this.config.restModel.TABLE_NAME;
3948
4096
  logContext = getLogContext(this.config, this.request);
3949
4097
  cacheResults = method === C6Constants.GET
3950
- && !this.config.sqlAllowListPath
3951
- && ((_a = this.request) === null || _a === void 0 ? void 0 : _a.cacheResults) !== false;
4098
+ && ((_a = this.request.cacheResults) !== null && _a !== void 0 ? _a : true);
3952
4099
  cacheRequestData = cacheResults
3953
4100
  ? JSON.parse(JSON.stringify((_b = this.request) !== null && _b !== void 0 ? _b : {}))
3954
4101
  : undefined;
3955
4102
  requestArgumentsSerialized = cacheResults
3956
4103
  ? sortAndSerializeQueryObject(tableName, cacheRequestData !== null && cacheRequestData !== void 0 ? cacheRequestData : {})
3957
4104
  : undefined;
4105
+ evictFromCache = method === C6Constants.GET && cacheResults && cacheRequestData
4106
+ ? function () { return evictCacheEntry(method, tableName, cacheRequestData); }
4107
+ : undefined;
3958
4108
  if (!cacheResults) return [3 /*break*/, 2];
3959
- cachedRequest = checkCache(method, tableName, cacheRequestData);
4109
+ cachedRequest = checkCache(method, tableName, cacheRequestData, logContext);
3960
4110
  if (!cachedRequest) return [3 /*break*/, 2];
3961
4111
  return [4 /*yield*/, cachedRequest];
3962
- case 1: return [2 /*return*/, (_c.sent()).data];
4112
+ case 1:
4113
+ cachedData = (_c.sent()).data;
4114
+ if (evictFromCache
4115
+ && cachedData
4116
+ && typeof cachedData === "object"
4117
+ && Array.isArray(cachedData.rest)) {
4118
+ cachedData.evictFromCache = evictFromCache;
4119
+ }
4120
+ return [2 /*return*/, cachedData];
3963
4121
  case 2:
3964
4122
  sqlExecution = this.buildSqlExecutionContext(method, tableName, logContext);
3965
- queryPromise = this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
3966
- return [2 /*return*/, this.executeQueryWithLifecycle(conn, method, sqlExecution, logContext)];
3967
- }); }); });
4123
+ sqlMethod = this.resolveSqlLogMethod(method, sqlExecution.sql);
4124
+ queryPromise = this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () {
4125
+ return __generator(this, function (_a) {
4126
+ return [2 /*return*/, this.executeQueryWithLifecycle(conn, method, sqlExecution, logContext, sqlMethod)];
4127
+ });
4128
+ }); });
3968
4129
  if (!(!cacheResults || !cacheRequestData || !requestArgumentsSerialized)) return [3 /*break*/, 4];
3969
4130
  return [4 /*yield*/, queryPromise];
3970
4131
  case 3: return [2 /*return*/, _c.sent()];
3971
4132
  case 4:
3972
4133
  cacheRequest = queryPromise.then(function (data) {
4134
+ if (evictFromCache
4135
+ && data
4136
+ && typeof data === "object"
4137
+ && Array.isArray(data.rest)) {
4138
+ data.evictFromCache = evictFromCache;
4139
+ }
3973
4140
  return _this.createCacheResponseEnvelope(method, tableName, data);
3974
4141
  });
3975
4142
  setCache(method, tableName, cacheRequestData, {
@@ -4042,9 +4209,9 @@ var SqlExecutor = /** @class */ (function (_super) {
4042
4209
  },
4043
4210
  };
4044
4211
  };
4045
- SqlExecutor.prototype.executeQueryWithLifecycle = function (conn, method, sqlExecution, logContext) {
4212
+ SqlExecutor.prototype.executeQueryWithLifecycle = function (conn, method, sqlExecution, logContext, sqlMethod) {
4046
4213
  return __awaiter(this, void 0, void 0, function () {
4047
- var useTransaction, committed, result, response, hookResponse, err_1, rollbackErr_1;
4214
+ var useTransaction, committed, allowListStatus, error_2, result, response, hookResponse, err_1, rollbackErr_1;
4048
4215
  return __generator(this, function (_a) {
4049
4216
  switch (_a.label) {
4050
4217
  case 0:
@@ -4052,25 +4219,49 @@ var SqlExecutor = /** @class */ (function (_super) {
4052
4219
  committed = false;
4053
4220
  _a.label = 1;
4054
4221
  case 1:
4055
- _a.trys.push([1, 11, , 16]);
4222
+ _a.trys.push([1, 14, , 19]);
4056
4223
  if (!useTransaction) return [3 /*break*/, 3];
4057
4224
  logWithLevel(LogLevel.DEBUG, logContext, console.log, "[SQL EXECUTOR] \uD83E\uDDFE Beginning transaction");
4058
4225
  return [4 /*yield*/, conn.beginTransaction()];
4059
4226
  case 2:
4060
4227
  _a.sent();
4061
4228
  _a.label = 3;
4062
- case 3: return [4 /*yield*/, this.validateSqlAllowList(sqlExecution.sql)];
4229
+ case 3:
4230
+ allowListStatus = "not verified";
4231
+ _a.label = 4;
4063
4232
  case 4:
4064
- _a.sent();
4233
+ _a.trys.push([4, 6, , 7]);
4234
+ return [4 /*yield*/, this.validateSqlAllowList(sqlExecution.sql)];
4235
+ case 5:
4236
+ allowListStatus = _a.sent();
4237
+ return [3 /*break*/, 7];
4238
+ case 6:
4239
+ error_2 = _a.sent();
4240
+ logSql({
4241
+ method: sqlMethod,
4242
+ sql: sqlExecution.sql,
4243
+ context: logContext,
4244
+ cacheStatus: this.request.cacheResults === false ? "ignored" : "miss",
4245
+ allowListStatus: "denied",
4246
+ });
4247
+ throw error_2;
4248
+ case 7:
4249
+ logSql({
4250
+ method: sqlMethod,
4251
+ sql: sqlExecution.sql,
4252
+ context: logContext,
4253
+ cacheStatus: this.request.cacheResults === false ? "ignored" : "miss",
4254
+ allowListStatus: allowListStatus,
4255
+ });
4065
4256
  return [4 /*yield*/, this.runLifecycleHooks("beforeExecution", {
4066
4257
  config: this.config,
4067
4258
  request: this.request,
4068
4259
  sqlExecution: sqlExecution,
4069
4260
  })];
4070
- case 5:
4261
+ case 8:
4071
4262
  _a.sent();
4072
4263
  return [4 /*yield*/, conn.query(sqlExecution.sql, sqlExecution.values)];
4073
- case 6:
4264
+ case 9:
4074
4265
  result = (_a.sent())[0];
4075
4266
  response = this.createResponseFromQueryResult(method, result, sqlExecution, logContext);
4076
4267
  hookResponse = this.createLifecycleHookResponse(response);
@@ -4079,40 +4270,40 @@ var SqlExecutor = /** @class */ (function (_super) {
4079
4270
  request: this.request,
4080
4271
  response: hookResponse,
4081
4272
  })];
4082
- case 7:
4273
+ case 10:
4083
4274
  _a.sent();
4084
- if (!useTransaction) return [3 /*break*/, 9];
4275
+ if (!useTransaction) return [3 /*break*/, 12];
4085
4276
  return [4 /*yield*/, conn.commit()];
4086
- case 8:
4277
+ case 11:
4087
4278
  _a.sent();
4088
4279
  committed = true;
4089
4280
  logWithLevel(LogLevel.DEBUG, logContext, console.log, "[SQL EXECUTOR] \uD83E\uDDFE Transaction committed");
4090
- _a.label = 9;
4091
- case 9: return [4 /*yield*/, this.runLifecycleHooks("afterCommit", {
4281
+ _a.label = 12;
4282
+ case 12: return [4 /*yield*/, this.runLifecycleHooks("afterCommit", {
4092
4283
  config: this.config,
4093
4284
  request: this.request,
4094
4285
  response: hookResponse,
4095
4286
  })];
4096
- case 10:
4287
+ case 13:
4097
4288
  _a.sent();
4098
4289
  return [2 /*return*/, response];
4099
- case 11:
4290
+ case 14:
4100
4291
  err_1 = _a.sent();
4101
- if (!(useTransaction && !committed)) return [3 /*break*/, 15];
4102
- _a.label = 12;
4103
- case 12:
4104
- _a.trys.push([12, 14, , 15]);
4292
+ if (!(useTransaction && !committed)) return [3 /*break*/, 18];
4293
+ _a.label = 15;
4294
+ case 15:
4295
+ _a.trys.push([15, 17, , 18]);
4105
4296
  return [4 /*yield*/, conn.rollback()];
4106
- case 13:
4297
+ case 16:
4107
4298
  _a.sent();
4108
4299
  logWithLevel(LogLevel.WARN, logContext, console.warn, "[SQL EXECUTOR] \uD83E\uDDFE Transaction rolled back");
4109
- return [3 /*break*/, 15];
4110
- case 14:
4300
+ return [3 /*break*/, 18];
4301
+ case 17:
4111
4302
  rollbackErr_1 = _a.sent();
4112
4303
  logWithLevel(LogLevel.ERROR, logContext, console.error, "[SQL EXECUTOR] Rollback failed", rollbackErr_1);
4113
- return [3 /*break*/, 15];
4114
- case 15: throw err_1;
4115
- case 16: return [2 /*return*/];
4304
+ return [3 /*break*/, 18];
4305
+ case 18: throw err_1;
4306
+ case 19: return [2 /*return*/];
4116
4307
  }
4117
4308
  });
4118
4309
  });
@@ -4120,21 +4311,31 @@ var SqlExecutor = /** @class */ (function (_super) {
4120
4311
  SqlExecutor.prototype.validateSqlAllowList = function (sql) {
4121
4312
  return __awaiter(this, void 0, void 0, function () {
4122
4313
  var allowListPath, allowList, normalized;
4123
- return __generator(this, function (_a) {
4124
- switch (_a.label) {
4314
+ var _a;
4315
+ return __generator(this, function (_b) {
4316
+ switch (_b.label) {
4125
4317
  case 0:
4126
4318
  allowListPath = this.config.sqlAllowListPath;
4127
4319
  if (!allowListPath) {
4128
- return [2 /*return*/];
4320
+ return [2 /*return*/, "not verified"];
4129
4321
  }
4130
4322
  return [4 /*yield*/, loadSqlAllowList(allowListPath)];
4131
4323
  case 1:
4132
- allowList = _a.sent();
4324
+ allowList = _b.sent();
4133
4325
  normalized = normalizeSql(sql);
4134
4326
  if (!allowList.has(normalized)) {
4135
- throw new Error("SQL statement is not permitted by allowlist (".concat(allowListPath, ")."));
4327
+ throw createSqlAllowListBlockedError({
4328
+ tableName: typeof ((_a = this.config.restModel) === null || _a === void 0 ? void 0 : _a.TABLE_NAME) === "string"
4329
+ ? this.config.restModel.TABLE_NAME
4330
+ : undefined,
4331
+ method: typeof this.config.requestMethod === "string"
4332
+ ? this.config.requestMethod
4333
+ : undefined,
4334
+ normalizedSql: normalized,
4335
+ allowListPath: allowListPath,
4336
+ });
4136
4337
  }
4137
- return [2 /*return*/];
4338
+ return [2 /*return*/, "allowed"];
4138
4339
  }
4139
4340
  });
4140
4341
  });
@@ -4369,5 +4570,5 @@ function isVerbose() {
4369
4570
  return resolveLogLevel() >= LogLevel.DEBUG;
4370
4571
  }
4371
4572
 
4372
- export { A, AggregateBuilder, C6C, C6Constants, ConditionBuilder, DELETE, DeleteQueryBuilder, Executor, ExpressHandler, F, GET, HttpExecutor, JoinBuilder, LogLevel, POST, PUT, PaginationBuilder, PostQueryBuilder, SelectQueryBuilder, SqlExecutor, TestRestfulResponse, UpdateQueryBuilder, apiRequestCache, applyLogLevelDefaults, axiosInstance, bbox, carbonNodeQsStringify, checkAllRequestsComplete, checkCache, clearCache, collectSqlAllowListEntries, colorSql, compileSqlAllowList, convertForRequestBody, convertHexIfBinary, derivedTable, determineRuntimeJsType, distSphere, eFetchDependencies, error, extractSqlEntries, fieldEq, getEnv, getEnvBool, getEnvDebug, getEnvLogLevel, getLogContext, getPrimaryKeyTypes, group, info, isDerivedTableKey, isLocal, isNode, isTest, isVerbose, loadSqlAllowList, logSql, logWithLevel, normalizeSingularRequest, normalizeSql, notifyToast, onError, onSuccess, parseLogLevel, removeInvalidKeys, removePrefixIfExists, resolveDerivedTable, resolveLogLevel, restExpressRequest, restOrm, restRequest, setCache, setToastHandler, shouldLog, sortAndSerializeQueryObject, stContains, timeout, toastOptions, toastOptionsDevs, userCustomClearCache, versionToRgb as versionColor, warn };
4573
+ export { A, AggregateBuilder, C6C, C6Constants, ConditionBuilder, DELETE, DeleteQueryBuilder, Executor, ExpressHandler, F, GET, HttpExecutor, JoinBuilder, LogLevel, POST, PUT, PaginationBuilder, PostQueryBuilder, SelectQueryBuilder, SqlExecutor, TestRestfulResponse, UpdateQueryBuilder, apiRequestCache, applyLogLevelDefaults, axiosInstance, bbox, carbonNodeQsStringify, checkAllRequestsComplete, checkCache, clearCache, collectSqlAllowListEntries, colorSql, compileSqlAllowList, convertForRequestBody, convertHexIfBinary, derivedTable, determineRuntimeJsType, distSphere, eFetchDependencies, error, evictCacheEntry, extractSqlEntries, fieldEq, getEnv, getEnvBool, getEnvDebug, getEnvLogLevel, getLogContext, getPrimaryKeyTypes, group, info, isDerivedTableKey, isLocal, isNode, isTest, isVerbose, loadSqlAllowList, logSql, logWithLevel, normalizeSingularRequest, normalizeSql, notifyToast, onError, onSuccess, parseLogLevel, removeInvalidKeys, removePrefixIfExists, resolveDerivedTable, resolveLogLevel, restExpressRequest, restOrm, restRequest, setCache, setToastHandler, shouldLog, sortAndSerializeQueryObject, stContains, timeout, toastOptions, toastOptionsDevs, userCustomClearCache, versionToRgb as versionColor, warn };
4373
4574
  //# sourceMappingURL=index.esm.js.map