@carbonorm/carbonnode 6.0.13 → 6.0.17

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 (74) hide show
  1. package/dist/executors/SqlExecutor.d.ts +17 -0
  2. package/dist/index.cjs.js +413 -245
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.esm.js +413 -245
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/utils/cacheManager.d.ts +2 -1
  7. package/dist/utils/logLevel.d.ts +3 -3
  8. package/dist/utils/logSql.d.ts +10 -1
  9. package/package.json +1 -1
  10. package/scripts/assets/handlebars/C6.ts.handlebars +1 -1
  11. package/src/__tests__/fixtures/sqlResponses/sqlAllowList.json +1 -1
  12. package/src/__tests__/httpExecutor.multiRowUpsert.test.ts +50 -0
  13. package/src/__tests__/logSql.test.ts +54 -2
  14. package/src/__tests__/sakila-db/C6.js +1 -1
  15. package/src/__tests__/sakila-db/C6.mysqldump.json +1 -1
  16. package/src/__tests__/sakila-db/C6.mysqldump.sql +1 -1
  17. package/src/__tests__/sakila-db/C6.sqlAllowList.json +59 -70
  18. package/src/__tests__/sakila-db/C6.ts +2 -2
  19. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +3 -3
  20. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +3 -3
  21. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +1 -1
  22. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +3 -3
  23. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +5 -5
  24. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +5 -5
  25. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +1 -1
  26. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +5 -5
  27. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +2 -2
  28. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +2 -2
  29. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +1 -1
  30. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +2 -2
  31. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +2 -2
  32. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +2 -2
  33. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +1 -1
  34. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +2 -2
  35. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +2 -2
  36. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +2 -2
  37. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +1 -1
  38. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +2 -2
  39. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +5 -5
  40. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +5 -5
  41. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +1 -1
  42. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +5 -5
  43. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +2 -2
  44. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +2 -2
  45. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +1 -1
  46. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +2 -2
  47. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +1 -1
  48. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +1 -1
  49. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +1 -1
  50. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +1 -1
  51. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +2 -2
  52. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +2 -2
  53. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +1 -1
  54. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +2 -2
  55. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +2 -2
  56. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +2 -2
  57. package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +2 -2
  58. package/src/__tests__/sakila-db/sqlResponses/C6.rental.join.json +10 -10
  59. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +3 -3
  60. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +3 -3
  61. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +1 -1
  62. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +3 -3
  63. package/src/__tests__/sqlAllowList.test.ts +100 -0
  64. package/src/__tests__/sqlBuilders.test.ts +3 -4
  65. package/src/executors/HttpExecutor.ts +7 -2
  66. package/src/executors/SqlExecutor.ts +108 -7
  67. package/src/orm/queries/DeleteQueryBuilder.ts +0 -4
  68. package/src/orm/queries/PostQueryBuilder.ts +0 -4
  69. package/src/orm/queries/SelectQueryBuilder.ts +0 -4
  70. package/src/orm/queries/UpdateQueryBuilder.ts +0 -4
  71. package/src/utils/cacheManager.ts +17 -9
  72. package/src/utils/logLevel.ts +3 -4
  73. package/src/utils/logSql.ts +51 -6
  74. 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.17";
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
  }
@@ -1081,7 +1295,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1081
1295
  querySerialized = sortAndSerializeQueryObject(tables, cacheRequestData !== null && cacheRequestData !== void 0 ? cacheRequestData : {});
1082
1296
  cachedRequest = false;
1083
1297
  if (cacheResults) {
1084
- cachedRequest = checkCache(requestMethod, tableName, cacheRequestData);
1298
+ cachedRequest = checkCache(requestMethod, tableName, cacheRequestData, logContext);
1085
1299
  }
1086
1300
  if (!cachedRequest) return [3 /*break*/, 2];
1087
1301
  return [4 /*yield*/, cachedRequest];
@@ -1177,8 +1391,10 @@ var HttpExecutor = /** @class */ (function (_super) {
1177
1391
  return [__assign(__assign({}, baseConfig), { params: query })];
1178
1392
  case POST:
1179
1393
  if (dataInsertMultipleRows !== undefined) {
1394
+ var convertedRows = dataInsertMultipleRows.map(convert);
1395
+ var convertedQuery = convert(query);
1180
1396
  return [
1181
- dataInsertMultipleRows.map(convert),
1397
+ __assign(__assign({}, convertedQuery), { dataInsertMultipleRows: convertedRows }),
1182
1398
  baseConfig
1183
1399
  ];
1184
1400
  }
@@ -2940,186 +3156,6 @@ var PaginationBuilder = /** @class */ (function (_super) {
2940
3156
  return PaginationBuilder;
2941
3157
  }(JoinBuilder));
2942
3158
 
2943
- /* eslint-disable no-control-regex */
2944
- var RESET = "\x1b[0m";
2945
- var C$1 = {
2946
- KEYWORD: "\x1b[94m", // blue
2947
- LIMIT: "\x1b[93m", // yellow
2948
- NUMBER: "\x1b[92m", // green
2949
- DIM: "\x1b[90m", // gray
2950
- };
2951
- /* ---------- ANSI helpers ---------- */
2952
- var ansi256 = function (n) { return "\u001B[38;5;".concat(n, "m"); };
2953
- /* ---------- hashing ---------- */
2954
- function hashString$1(str) {
2955
- var hash = 0;
2956
- for (var i = 0; i < str.length; i++) {
2957
- hash = (hash * 31 + str.charCodeAt(i)) | 0;
2958
- }
2959
- return Math.abs(hash);
2960
- }
2961
- /* ---------- table color ---------- */
2962
- function tableRGB(tableName) {
2963
- var name = tableName.replace(/[`"]/g, "").toLowerCase();
2964
- var hash = hashString$1(name);
2965
- // Stable hue bucket by first letter
2966
- var first = name.charCodeAt(0) || 97;
2967
- var hueBase = (first - 97) % 6;
2968
- var r = (hueBase + (hash % 3)) % 6;
2969
- var g = (hash >> 3) % 6;
2970
- var b = (hash >> 6) % 6;
2971
- return [r, g, Math.max(2, b)]; // avoid muddy dark blues
2972
- }
2973
- function tableColor(table) {
2974
- var _a = tableRGB(table), r = _a[0], g = _a[1], b = _a[2];
2975
- return ansi256(16 + 36 * r + 6 * g + b);
2976
- }
2977
- /* ---------- column color (same hue, lighter) ---------- */
2978
- function columnColorFromTable(table) {
2979
- var _a = tableRGB(table), r = _a[0], g = _a[1], b = _a[2];
2980
- // Lift toward white, preserve hue
2981
- var lr = Math.min(5, r + 1);
2982
- var lg = Math.min(5, g + 1);
2983
- var lb = Math.min(5, b + 2);
2984
- return ansi256(16 + 36 * lr + 6 * lg + lb);
2985
- }
2986
- /* ---------- bind collapsing ---------- */
2987
- /**
2988
- * ?, ?, ?, ?, ?, ? → ? ×6
2989
- * triggers at 4+
2990
- */
2991
- function collapseBinds(sql) {
2992
- return sql.replace(/(\?\s*,\s*){3,}\?/g, function (match) {
2993
- var count = match.split("?").length - 1;
2994
- return "".concat(C$1.DIM, "? \u00D7").concat(count).concat(RESET);
2995
- });
2996
- }
2997
- /**
2998
- * ( ? ×9 ), ( ? ×9 ), ( ? ×9 ) -> ( ? ×9 ) ×3
2999
- */
3000
- function collapseRepeatedValueRows(sql) {
3001
- var repeatedRowPattern = /(\((?:\x1b\[[0-9;]*m)?\?\s*×\d+(?:\x1b\[[0-9;]*m)?\)|\(\s*(?:\?\s*,\s*)+\?\s*\))(?:\s*,\s*\1){2,}/g;
3002
- return sql.replace(repeatedRowPattern, function (match, row) {
3003
- var _a, _b;
3004
- var rowMatches = match.match(new RegExp(row.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"));
3005
- var count = (_a = rowMatches === null || rowMatches === void 0 ? void 0 : rowMatches.length) !== null && _a !== void 0 ? _a : 1;
3006
- var normalizedRow = row.includes("×")
3007
- ? row
3008
- : "(".concat(C$1.DIM, "? \u00D7").concat(((_b = row.match(/\?/g)) !== null && _b !== void 0 ? _b : []).length).concat(RESET, ")");
3009
- return "".concat(normalizedRow, " ").concat(C$1.DIM, "\u00D7").concat(count).concat(RESET);
3010
- });
3011
- }
3012
- /* ---------- main formatter ---------- */
3013
- function colorSql(sql) {
3014
- var s = sql.trim();
3015
- /* 1️⃣ collapse bind noise */
3016
- s = collapseBinds(s);
3017
- s = collapseRepeatedValueRows(s);
3018
- /* 2️⃣ table.column coloring (core visual grouping) */
3019
- s = s.replace(/\b(`?\w+`?)\.(\w+)\b/g, function (_, table, column) {
3020
- return "".concat(tableColor(table)).concat(table).concat(RESET, ".") +
3021
- "".concat(columnColorFromTable(table)).concat(column).concat(RESET);
3022
- });
3023
- /* 3️⃣ FROM / JOIN tables */
3024
- s = s.replace(/\b(FROM|JOIN|UPDATE|INTO)\s+(`[^`]+`|\w+)/gi, function (_, kw, table) {
3025
- return "".concat(C$1.KEYWORD).concat(kw).concat(RESET, " ").concat(tableColor(table)).concat(table).concat(RESET);
3026
- });
3027
- /* 4️⃣ SQL keywords */
3028
- 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));
3029
- /* 5️⃣ LIMIT */
3030
- s = s.replace(/\bLIMIT\s+(\d+)/gi, "".concat(C$1.LIMIT, "LIMIT").concat(RESET, " ").concat(C$1.NUMBER, "$1").concat(RESET));
3031
- return s;
3032
- }
3033
-
3034
- var version = "6.0.13";
3035
-
3036
- var DEFAULT_STEP = 8;
3037
- function parseSemver(version) {
3038
- var _a = version.trim().split("-"), core = _a[0], prerelease = _a[1];
3039
- var _b = core.split("."), majorRaw = _b[0], minorRaw = _b[1], patchRaw = _b[2];
3040
- var major = Number.parseInt(majorRaw !== null && majorRaw !== void 0 ? majorRaw : "0", 10);
3041
- var minor = Number.parseInt(minorRaw !== null && minorRaw !== void 0 ? minorRaw : "0", 10);
3042
- var patch = Number.parseInt(patchRaw !== null && patchRaw !== void 0 ? patchRaw : "0", 10);
3043
- var prereleaseParts = prerelease ? prerelease.split(".").filter(Boolean).length : 0;
3044
- return {
3045
- major: Number.isFinite(major) ? major : 0,
3046
- minor: Number.isFinite(minor) ? minor : 0,
3047
- patch: Number.isFinite(patch) ? patch : 0,
3048
- prereleaseParts: prereleaseParts,
3049
- };
3050
- }
3051
- function channelValue(n, step) {
3052
- var value = 255 - ((n * step) % 256);
3053
- return (value + 256) % 256;
3054
- }
3055
- function versionToRgb(version, step) {
3056
- if (step === void 0) { step = DEFAULT_STEP; }
3057
- var safeStep = Number.isFinite(step) && step > 0 ? Math.floor(step) : DEFAULT_STEP;
3058
- var _a = parseSemver(version), major = _a.major, minor = _a.minor, patch = _a.patch, prereleaseParts = _a.prereleaseParts;
3059
- var rotation = (major + minor + patch + prereleaseParts) % 3;
3060
- var base = [major, minor, patch];
3061
- var rotated = rotation === 1
3062
- ? [base[2], base[0], base[1]]
3063
- : rotation === 2
3064
- ? [base[1], base[2], base[0]]
3065
- : base;
3066
- return {
3067
- r: channelValue(rotated[0], safeStep),
3068
- g: channelValue(rotated[1], safeStep),
3069
- b: channelValue(rotated[2], safeStep),
3070
- };
3071
- }
3072
-
3073
- var C = {
3074
- SSR: "\x1b[95m", // bright magenta
3075
- HTTP: "\x1b[94m", // bright blue
3076
- METHOD_COLORS: {
3077
- SELECT: "\x1b[92m", // green
3078
- INSERT: "\x1b[96m", // cyan
3079
- REPLACE: "\x1b[96m", // cyan
3080
- UPDATE: "\x1b[95m", // magenta
3081
- DELETE: "\x1b[91m", // red
3082
- },
3083
- METHOD_FALLBACK: [
3084
- "\x1b[92m", // green
3085
- "\x1b[93m", // yellow
3086
- "\x1b[95m", // magenta
3087
- "\x1b[96m", // cyan
3088
- "\x1b[94m", // blue
3089
- "\x1b[97m", // white
3090
- ],
3091
- RESET: "\x1b[0m",
3092
- };
3093
- var rgbAnsi = function (_a) {
3094
- var r = _a.r, g = _a.g, b = _a.b;
3095
- return "\u001B[38;2;".concat(r, ";").concat(g, ";").concat(b, "m");
3096
- };
3097
- function hashString(value) {
3098
- var hash = 0;
3099
- for (var i = 0; i < value.length; i++) {
3100
- hash = (hash * 31 + value.charCodeAt(i)) | 0;
3101
- }
3102
- return Math.abs(hash);
3103
- }
3104
- function methodColor(method) {
3105
- var key = method.toUpperCase();
3106
- if (key in C.METHOD_COLORS) {
3107
- return C.METHOD_COLORS[key];
3108
- }
3109
- var idx = hashString(key) % C.METHOD_FALLBACK.length;
3110
- return C.METHOD_FALLBACK[idx];
3111
- }
3112
- function logSql(method, sql, context) {
3113
- if (!shouldLog(LogLevel.INFO, context))
3114
- return;
3115
- var preText = getEnvBool("SSR", false)
3116
- ? "".concat(C.SSR, "[SSR]").concat(C.RESET, " ")
3117
- : "".concat(C.HTTP, "[API]").concat(C.RESET, " ");
3118
- var labelColor = methodColor(method);
3119
- var versionColor = rgbAnsi(versionToRgb(version));
3120
- console.log("".concat(versionColor, "[").concat(version, "]").concat(C.RESET, " ").concat(preText).concat(labelColor, "[").concat(method, "]").concat(C.RESET, " ").concat(colorSql(sql)));
3121
- }
3122
-
3123
3159
  var SelectQueryBuilder = /** @class */ (function (_super) {
3124
3160
  __extends(SelectQueryBuilder, _super);
3125
3161
  function SelectQueryBuilder() {
@@ -3171,7 +3207,6 @@ var SelectQueryBuilder = /** @class */ (function (_super) {
3171
3207
  else if (!isSubSelect) {
3172
3208
  sql += " LIMIT 100";
3173
3209
  }
3174
- logSql("SELECT", sql, getLogContext(this.config, this.request));
3175
3210
  return { sql: sql, params: params };
3176
3211
  };
3177
3212
  return SelectQueryBuilder;
@@ -3196,7 +3231,6 @@ var DeleteQueryBuilder = /** @class */ (function (_super) {
3196
3231
  if (this.request.WHERE) {
3197
3232
  sql += this.buildWhereClause(this.request.WHERE, params);
3198
3233
  }
3199
- logSql("DELETE", sql, getLogContext(this.config, this.request));
3200
3234
  return { sql: sql, params: params };
3201
3235
  };
3202
3236
  return DeleteQueryBuilder;
@@ -3255,7 +3289,6 @@ var PostQueryBuilder = /** @class */ (function (_super) {
3255
3289
  var updateClause = updateData.map(function (k) { return "`".concat(k, "` = VALUES(`").concat(k, "`)"); }).join(', ');
3256
3290
  sql += " ON DUPLICATE KEY UPDATE ".concat(updateClause);
3257
3291
  }
3258
- logSql(verb, sql, getLogContext(this.config, this.request));
3259
3292
  return { sql: sql, params: params };
3260
3293
  };
3261
3294
  return PostQueryBuilder;
@@ -3307,7 +3340,6 @@ var UpdateQueryBuilder = /** @class */ (function (_super) {
3307
3340
  if (args.PAGINATION) {
3308
3341
  sql += this.buildPaginationClause(args.PAGINATION, params);
3309
3342
  }
3310
- logSql("UPDATE", sql, getLogContext(this.config, this.request));
3311
3343
  return { sql: sql, params: params };
3312
3344
  };
3313
3345
  return UpdateQueryBuilder;
@@ -3441,8 +3473,55 @@ function normalizeSingularRequest(requestMethod, request, restModel, removedPrim
3441
3473
  }
3442
3474
 
3443
3475
  var allowListCache = new Map();
3476
+ var ANSI_ESCAPE_REGEX = /\x1b\[[0-9;]*m/g;
3477
+ var COLLAPSED_BIND_ROW_REGEX = /\(\?\s*×\d+\)/g;
3478
+ function collapseBindGroups(sql) {
3479
+ var normalized = sql.replace(/\(\s*(\?(?:\s*,\s*\?)*)\s*\)/g, function (_match, binds) {
3480
+ var _a;
3481
+ var bindCount = ((_a = binds.match(/\?/g)) !== null && _a !== void 0 ? _a : []).length;
3482
+ return "(? \u00D7".concat(bindCount, ")");
3483
+ });
3484
+ normalized = normalized.replace(/(\(\?\s*×\d+\))(?:\s*,\s*\1)+/g, function (_match, row) { return "".concat(row, " \u00D7*"); });
3485
+ normalized = normalized.replace(/\b(VALUES|VALUE)\s+(\(\?\s*×\d+\))(?:\s*×\d+|\s*×\*)?/gi, function (_match, keyword, row) { return "".concat(keyword, " ").concat(row, " \u00D7*"); });
3486
+ normalized = normalized.replace(/\bIN\s*\(\?\s*×\d+\)/gi, "IN (? ×*)");
3487
+ normalized = normalized.replace(/\(\?\s*×\d+\)\s*×\d+/g, function (match) {
3488
+ var _a;
3489
+ var row = (_a = match.match(COLLAPSED_BIND_ROW_REGEX)) === null || _a === void 0 ? void 0 : _a[0];
3490
+ return row ? "".concat(row, " \u00D7*") : match;
3491
+ });
3492
+ return normalized;
3493
+ }
3494
+ function normalizeLimitOffset(sql) {
3495
+ return sql
3496
+ .replace(/\bLIMIT\s+\d+\s*,\s*\d+\b/gi, "LIMIT ?, ?")
3497
+ .replace(/\bLIMIT\s+\d+\s+OFFSET\s+\d+\b/gi, "LIMIT ? OFFSET ?")
3498
+ .replace(/\bLIMIT\s+\d+\b/gi, "LIMIT ?")
3499
+ .replace(/\bOFFSET\s+\d+\b/gi, "OFFSET ?");
3500
+ }
3501
+ function normalizeGeomFromTextLiterals(sql) {
3502
+ var normalized = sql.replace(/ST_GEOMFROMTEXT\(\s*'POINT\([^']*\)'\s*,\s*(?:\d+|\?)\s*\)/gi, "ST_GEOMFROMTEXT('POINT(? ?)', ?)");
3503
+ normalized = normalized.replace(/ST_GEOMFROMTEXT\(\s*'POLYGON\(\([^']*\)\)'\s*,\s*(?:\d+|\?)\s*\)/gi, "ST_GEOMFROMTEXT('POLYGON((?))', ?)");
3504
+ return normalized;
3505
+ }
3506
+ function normalizeGeoFunctionNames(sql) {
3507
+ return sql
3508
+ .replace(/\bST_DISTANCE_SPHERE\b/gi, "ST_DISTANCE_SPHERE")
3509
+ .replace(/\bST_GEOMFROMTEXT\b/gi, "ST_GEOMFROMTEXT")
3510
+ .replace(/\bMBRCONTAINS\b/gi, "MBRCONTAINS");
3511
+ }
3512
+ function normalizeTokenPunctuationSpacing(sql) {
3513
+ return sql.replace(/`,\s*`/g, "`, `");
3514
+ }
3444
3515
  var normalizeSql = function (sql) {
3445
- return sql.replace(/\s+/g, " ").trim();
3516
+ var normalized = sql.replace(ANSI_ESCAPE_REGEX, " ");
3517
+ normalized = normalized.replace(/\s+/g, " ").trim();
3518
+ normalized = normalizeGeoFunctionNames(normalized);
3519
+ normalized = normalizeTokenPunctuationSpacing(normalized);
3520
+ normalized = collapseBindGroups(normalized);
3521
+ normalized = normalizeLimitOffset(normalized);
3522
+ normalized = normalizeGeomFromTextLiterals(normalized);
3523
+ normalized = normalized.replace(/;\s*$/, "");
3524
+ return normalized.replace(/\s+/g, " ").trim();
3446
3525
  };
3447
3526
  var parseAllowList = function (raw, sourcePath) {
3448
3527
  var parsed;
@@ -3465,33 +3544,51 @@ var parseAllowList = function (raw, sourcePath) {
3465
3544
  return sqlEntries;
3466
3545
  };
3467
3546
  var loadSqlAllowList = function (allowListPath) { return __awaiter(void 0, void 0, void 0, function () {
3468
- var readFile, raw, sqlEntries, allowList;
3469
- return __generator(this, function (_a) {
3470
- switch (_a.label) {
3547
+ var _a, readFile, stat, fileStat, cached, raw, sqlEntries, allowList;
3548
+ return __generator(this, function (_b) {
3549
+ switch (_b.label) {
3471
3550
  case 0:
3472
- if (allowListCache.has(allowListPath)) {
3473
- return [2 /*return*/, allowListCache.get(allowListPath)];
3474
- }
3475
3551
  if (!isNode()) {
3476
3552
  throw new Error("SQL allowlist validation requires a Node runtime.");
3477
3553
  }
3478
3554
  return [4 /*yield*/, import('node:fs/promises')];
3479
3555
  case 1:
3480
- readFile = (_a.sent()).readFile;
3481
- _a.label = 2;
3556
+ _a = _b.sent(), readFile = _a.readFile, stat = _a.stat;
3557
+ _b.label = 2;
3482
3558
  case 2:
3483
- _a.trys.push([2, 4, , 5]);
3484
- return [4 /*yield*/, readFile(allowListPath, "utf-8")];
3559
+ _b.trys.push([2, 4, , 5]);
3560
+ return [4 /*yield*/, stat(allowListPath)];
3485
3561
  case 3:
3486
- raw = _a.sent();
3562
+ fileStat = _b.sent();
3487
3563
  return [3 /*break*/, 5];
3488
3564
  case 4:
3489
- _a.sent();
3565
+ _b.sent();
3490
3566
  throw new Error("SQL allowlist file not found at ".concat(allowListPath, "."));
3491
3567
  case 5:
3568
+ cached = allowListCache.get(allowListPath);
3569
+ if (cached &&
3570
+ cached.mtimeMs === fileStat.mtimeMs &&
3571
+ cached.size === fileStat.size) {
3572
+ return [2 /*return*/, cached.allowList];
3573
+ }
3574
+ _b.label = 6;
3575
+ case 6:
3576
+ _b.trys.push([6, 8, , 9]);
3577
+ return [4 /*yield*/, readFile(allowListPath, "utf-8")];
3578
+ case 7:
3579
+ raw = _b.sent();
3580
+ return [3 /*break*/, 9];
3581
+ case 8:
3582
+ _b.sent();
3583
+ throw new Error("SQL allowlist file not found at ".concat(allowListPath, "."));
3584
+ case 9:
3492
3585
  sqlEntries = parseAllowList(raw, allowListPath);
3493
3586
  allowList = new Set(sqlEntries);
3494
- allowListCache.set(allowListPath, allowList);
3587
+ allowListCache.set(allowListPath, {
3588
+ allowList: allowList,
3589
+ mtimeMs: fileStat.mtimeMs,
3590
+ size: fileStat.size,
3591
+ });
3495
3592
  return [2 /*return*/, allowList];
3496
3593
  }
3497
3594
  });
@@ -3554,6 +3651,25 @@ var compileSqlAllowList = function (allowListPath, entries) { return __awaiter(v
3554
3651
  });
3555
3652
  }); };
3556
3653
 
3654
+ var SQL_ALLOWLIST_BLOCKED_CODE = "SQL_ALLOWLIST_BLOCKED";
3655
+ var createSqlAllowListBlockedError = function (args) {
3656
+ var _a, _b;
3657
+ var error = new Error("SQL statement is not permitted by allowlist (".concat(args.allowListPath, ")."));
3658
+ error.name = "SqlAllowListBlockedError";
3659
+ error.code = SQL_ALLOWLIST_BLOCKED_CODE;
3660
+ error.tableName = args.tableName;
3661
+ error.method = args.method;
3662
+ error.normalizedSql = args.normalizedSql;
3663
+ error.allowListPath = args.allowListPath;
3664
+ error.sqlAllowList = {
3665
+ sql: args.normalizedSql,
3666
+ table: (_a = args.tableName) !== null && _a !== void 0 ? _a : null,
3667
+ method: (_b = args.method) !== null && _b !== void 0 ? _b : null,
3668
+ allowListPath: args.allowListPath,
3669
+ canAdd: true,
3670
+ };
3671
+ return error;
3672
+ };
3557
3673
  var SqlExecutor = /** @class */ (function (_super) {
3558
3674
  __extends(SqlExecutor, _super);
3559
3675
  function SqlExecutor() {
@@ -3564,6 +3680,22 @@ var SqlExecutor = /** @class */ (function (_super) {
3564
3680
  })); };
3565
3681
  return _this;
3566
3682
  }
3683
+ SqlExecutor.prototype.resolveSqlLogMethod = function (method, sql) {
3684
+ var _a;
3685
+ var token = (_a = sql.trim().split(/\s+/, 1)[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase();
3686
+ if (token)
3687
+ return token;
3688
+ switch (method) {
3689
+ case C6Constants.GET:
3690
+ return "SELECT";
3691
+ case C6Constants.POST:
3692
+ return "INSERT";
3693
+ case C6Constants.PUT:
3694
+ return "UPDATE";
3695
+ default:
3696
+ return "DELETE";
3697
+ }
3698
+ };
3567
3699
  SqlExecutor.prototype.execute = function () {
3568
3700
  return __awaiter(this, void 0, void 0, function () {
3569
3701
  var TABLE_NAME, method, logContext, response, _a, rest, getResponse, restRows, result, result, result;
@@ -3935,7 +4067,7 @@ var SqlExecutor = /** @class */ (function (_super) {
3935
4067
  };
3936
4068
  SqlExecutor.prototype.runQuery = function () {
3937
4069
  return __awaiter(this, void 0, void 0, function () {
3938
- var method, tableName, logContext, cacheResults, cacheRequestData, requestArgumentsSerialized, cachedRequest, sqlExecution, queryPromise, cacheRequest, cacheResponse;
4070
+ var method, tableName, logContext, cacheResults, cacheRequestData, requestArgumentsSerialized, cachedRequest, sqlExecution, sqlMethod, queryPromise, cacheRequest, cacheResponse;
3939
4071
  var _this = this;
3940
4072
  var _a, _b;
3941
4073
  return __generator(this, function (_c) {
@@ -3945,8 +4077,7 @@ var SqlExecutor = /** @class */ (function (_super) {
3945
4077
  tableName = this.config.restModel.TABLE_NAME;
3946
4078
  logContext = getLogContext(this.config, this.request);
3947
4079
  cacheResults = method === C6Constants.GET
3948
- && !this.config.sqlAllowListPath
3949
- && ((_a = this.request) === null || _a === void 0 ? void 0 : _a.cacheResults) !== false;
4080
+ && ((_a = this.request.cacheResults) !== null && _a !== void 0 ? _a : true);
3950
4081
  cacheRequestData = cacheResults
3951
4082
  ? JSON.parse(JSON.stringify((_b = this.request) !== null && _b !== void 0 ? _b : {}))
3952
4083
  : undefined;
@@ -3954,15 +4085,18 @@ var SqlExecutor = /** @class */ (function (_super) {
3954
4085
  ? sortAndSerializeQueryObject(tableName, cacheRequestData !== null && cacheRequestData !== void 0 ? cacheRequestData : {})
3955
4086
  : undefined;
3956
4087
  if (!cacheResults) return [3 /*break*/, 2];
3957
- cachedRequest = checkCache(method, tableName, cacheRequestData);
4088
+ cachedRequest = checkCache(method, tableName, cacheRequestData, logContext);
3958
4089
  if (!cachedRequest) return [3 /*break*/, 2];
3959
4090
  return [4 /*yield*/, cachedRequest];
3960
4091
  case 1: return [2 /*return*/, (_c.sent()).data];
3961
4092
  case 2:
3962
4093
  sqlExecution = this.buildSqlExecutionContext(method, tableName, logContext);
3963
- queryPromise = this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
3964
- return [2 /*return*/, this.executeQueryWithLifecycle(conn, method, sqlExecution, logContext)];
3965
- }); }); });
4094
+ sqlMethod = this.resolveSqlLogMethod(method, sqlExecution.sql);
4095
+ queryPromise = this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () {
4096
+ return __generator(this, function (_a) {
4097
+ return [2 /*return*/, this.executeQueryWithLifecycle(conn, method, sqlExecution, logContext, sqlMethod)];
4098
+ });
4099
+ }); });
3966
4100
  if (!(!cacheResults || !cacheRequestData || !requestArgumentsSerialized)) return [3 /*break*/, 4];
3967
4101
  return [4 /*yield*/, queryPromise];
3968
4102
  case 3: return [2 /*return*/, _c.sent()];
@@ -4040,9 +4174,9 @@ var SqlExecutor = /** @class */ (function (_super) {
4040
4174
  },
4041
4175
  };
4042
4176
  };
4043
- SqlExecutor.prototype.executeQueryWithLifecycle = function (conn, method, sqlExecution, logContext) {
4177
+ SqlExecutor.prototype.executeQueryWithLifecycle = function (conn, method, sqlExecution, logContext, sqlMethod) {
4044
4178
  return __awaiter(this, void 0, void 0, function () {
4045
- var useTransaction, committed, result, response, hookResponse, err_1, rollbackErr_1;
4179
+ var useTransaction, committed, allowListStatus, error_2, result, response, hookResponse, err_1, rollbackErr_1;
4046
4180
  return __generator(this, function (_a) {
4047
4181
  switch (_a.label) {
4048
4182
  case 0:
@@ -4050,25 +4184,49 @@ var SqlExecutor = /** @class */ (function (_super) {
4050
4184
  committed = false;
4051
4185
  _a.label = 1;
4052
4186
  case 1:
4053
- _a.trys.push([1, 11, , 16]);
4187
+ _a.trys.push([1, 14, , 19]);
4054
4188
  if (!useTransaction) return [3 /*break*/, 3];
4055
4189
  logWithLevel(LogLevel.DEBUG, logContext, console.log, "[SQL EXECUTOR] \uD83E\uDDFE Beginning transaction");
4056
4190
  return [4 /*yield*/, conn.beginTransaction()];
4057
4191
  case 2:
4058
4192
  _a.sent();
4059
4193
  _a.label = 3;
4060
- case 3: return [4 /*yield*/, this.validateSqlAllowList(sqlExecution.sql)];
4194
+ case 3:
4195
+ allowListStatus = "not verified";
4196
+ _a.label = 4;
4061
4197
  case 4:
4062
- _a.sent();
4198
+ _a.trys.push([4, 6, , 7]);
4199
+ return [4 /*yield*/, this.validateSqlAllowList(sqlExecution.sql)];
4200
+ case 5:
4201
+ allowListStatus = _a.sent();
4202
+ return [3 /*break*/, 7];
4203
+ case 6:
4204
+ error_2 = _a.sent();
4205
+ logSql({
4206
+ method: sqlMethod,
4207
+ sql: sqlExecution.sql,
4208
+ context: logContext,
4209
+ cacheStatus: this.request.cacheResults === false ? "ignored" : "miss",
4210
+ allowListStatus: "denied",
4211
+ });
4212
+ throw error_2;
4213
+ case 7:
4214
+ logSql({
4215
+ method: sqlMethod,
4216
+ sql: sqlExecution.sql,
4217
+ context: logContext,
4218
+ cacheStatus: this.request.cacheResults === false ? "ignored" : "miss",
4219
+ allowListStatus: allowListStatus,
4220
+ });
4063
4221
  return [4 /*yield*/, this.runLifecycleHooks("beforeExecution", {
4064
4222
  config: this.config,
4065
4223
  request: this.request,
4066
4224
  sqlExecution: sqlExecution,
4067
4225
  })];
4068
- case 5:
4226
+ case 8:
4069
4227
  _a.sent();
4070
4228
  return [4 /*yield*/, conn.query(sqlExecution.sql, sqlExecution.values)];
4071
- case 6:
4229
+ case 9:
4072
4230
  result = (_a.sent())[0];
4073
4231
  response = this.createResponseFromQueryResult(method, result, sqlExecution, logContext);
4074
4232
  hookResponse = this.createLifecycleHookResponse(response);
@@ -4077,40 +4235,40 @@ var SqlExecutor = /** @class */ (function (_super) {
4077
4235
  request: this.request,
4078
4236
  response: hookResponse,
4079
4237
  })];
4080
- case 7:
4238
+ case 10:
4081
4239
  _a.sent();
4082
- if (!useTransaction) return [3 /*break*/, 9];
4240
+ if (!useTransaction) return [3 /*break*/, 12];
4083
4241
  return [4 /*yield*/, conn.commit()];
4084
- case 8:
4242
+ case 11:
4085
4243
  _a.sent();
4086
4244
  committed = true;
4087
4245
  logWithLevel(LogLevel.DEBUG, logContext, console.log, "[SQL EXECUTOR] \uD83E\uDDFE Transaction committed");
4088
- _a.label = 9;
4089
- case 9: return [4 /*yield*/, this.runLifecycleHooks("afterCommit", {
4246
+ _a.label = 12;
4247
+ case 12: return [4 /*yield*/, this.runLifecycleHooks("afterCommit", {
4090
4248
  config: this.config,
4091
4249
  request: this.request,
4092
4250
  response: hookResponse,
4093
4251
  })];
4094
- case 10:
4252
+ case 13:
4095
4253
  _a.sent();
4096
4254
  return [2 /*return*/, response];
4097
- case 11:
4255
+ case 14:
4098
4256
  err_1 = _a.sent();
4099
- if (!(useTransaction && !committed)) return [3 /*break*/, 15];
4100
- _a.label = 12;
4101
- case 12:
4102
- _a.trys.push([12, 14, , 15]);
4257
+ if (!(useTransaction && !committed)) return [3 /*break*/, 18];
4258
+ _a.label = 15;
4259
+ case 15:
4260
+ _a.trys.push([15, 17, , 18]);
4103
4261
  return [4 /*yield*/, conn.rollback()];
4104
- case 13:
4262
+ case 16:
4105
4263
  _a.sent();
4106
4264
  logWithLevel(LogLevel.WARN, logContext, console.warn, "[SQL EXECUTOR] \uD83E\uDDFE Transaction rolled back");
4107
- return [3 /*break*/, 15];
4108
- case 14:
4265
+ return [3 /*break*/, 18];
4266
+ case 17:
4109
4267
  rollbackErr_1 = _a.sent();
4110
4268
  logWithLevel(LogLevel.ERROR, logContext, console.error, "[SQL EXECUTOR] Rollback failed", rollbackErr_1);
4111
- return [3 /*break*/, 15];
4112
- case 15: throw err_1;
4113
- case 16: return [2 /*return*/];
4269
+ return [3 /*break*/, 18];
4270
+ case 18: throw err_1;
4271
+ case 19: return [2 /*return*/];
4114
4272
  }
4115
4273
  });
4116
4274
  });
@@ -4118,21 +4276,31 @@ var SqlExecutor = /** @class */ (function (_super) {
4118
4276
  SqlExecutor.prototype.validateSqlAllowList = function (sql) {
4119
4277
  return __awaiter(this, void 0, void 0, function () {
4120
4278
  var allowListPath, allowList, normalized;
4121
- return __generator(this, function (_a) {
4122
- switch (_a.label) {
4279
+ var _a;
4280
+ return __generator(this, function (_b) {
4281
+ switch (_b.label) {
4123
4282
  case 0:
4124
4283
  allowListPath = this.config.sqlAllowListPath;
4125
4284
  if (!allowListPath) {
4126
- return [2 /*return*/];
4285
+ return [2 /*return*/, "not verified"];
4127
4286
  }
4128
4287
  return [4 /*yield*/, loadSqlAllowList(allowListPath)];
4129
4288
  case 1:
4130
- allowList = _a.sent();
4289
+ allowList = _b.sent();
4131
4290
  normalized = normalizeSql(sql);
4132
4291
  if (!allowList.has(normalized)) {
4133
- throw new Error("SQL statement is not permitted by allowlist (".concat(allowListPath, ")."));
4292
+ throw createSqlAllowListBlockedError({
4293
+ tableName: typeof ((_a = this.config.restModel) === null || _a === void 0 ? void 0 : _a.TABLE_NAME) === "string"
4294
+ ? this.config.restModel.TABLE_NAME
4295
+ : undefined,
4296
+ method: typeof this.config.requestMethod === "string"
4297
+ ? this.config.requestMethod
4298
+ : undefined,
4299
+ normalizedSql: normalized,
4300
+ allowListPath: allowListPath,
4301
+ });
4134
4302
  }
4135
- return [2 /*return*/];
4303
+ return [2 /*return*/, "allowed"];
4136
4304
  }
4137
4305
  });
4138
4306
  });