@carbonorm/carbonnode 6.0.14 → 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 (72) hide show
  1. package/dist/executors/SqlExecutor.d.ts +17 -0
  2. package/dist/index.cjs.js +410 -244
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.esm.js +410 -244
  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__/logSql.test.ts +54 -2
  13. package/src/__tests__/sakila-db/C6.js +1 -1
  14. package/src/__tests__/sakila-db/C6.mysqldump.json +1 -1
  15. package/src/__tests__/sakila-db/C6.mysqldump.sql +1 -1
  16. package/src/__tests__/sakila-db/C6.sqlAllowList.json +59 -70
  17. package/src/__tests__/sakila-db/C6.ts +2 -2
  18. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +3 -3
  19. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +3 -3
  20. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +1 -1
  21. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +3 -3
  22. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +5 -5
  23. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +5 -5
  24. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +1 -1
  25. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +5 -5
  26. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +2 -2
  27. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +2 -2
  28. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +1 -1
  29. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +2 -2
  30. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +2 -2
  31. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +2 -2
  32. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +1 -1
  33. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +2 -2
  34. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +2 -2
  35. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +2 -2
  36. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +1 -1
  37. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +2 -2
  38. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +5 -5
  39. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +5 -5
  40. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +1 -1
  41. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +5 -5
  42. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +2 -2
  43. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +2 -2
  44. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +1 -1
  45. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +2 -2
  46. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +1 -1
  47. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +1 -1
  48. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +1 -1
  49. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +1 -1
  50. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +2 -2
  51. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +2 -2
  52. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +1 -1
  53. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +2 -2
  54. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +2 -2
  55. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +2 -2
  56. package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +2 -2
  57. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +3 -3
  58. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +3 -3
  59. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +1 -1
  60. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +3 -3
  61. package/src/__tests__/sqlAllowList.test.ts +100 -0
  62. package/src/__tests__/sqlBuilders.test.ts +3 -4
  63. package/src/executors/HttpExecutor.ts +1 -1
  64. package/src/executors/SqlExecutor.ts +108 -7
  65. package/src/orm/queries/DeleteQueryBuilder.ts +0 -4
  66. package/src/orm/queries/PostQueryBuilder.ts +0 -4
  67. package/src/orm/queries/SelectQueryBuilder.ts +0 -4
  68. package/src/orm/queries/UpdateQueryBuilder.ts +0 -4
  69. package/src/utils/cacheManager.ts +17 -9
  70. package/src/utils/logLevel.ts +3 -4
  71. package/src/utils/logSql.ts +51 -6
  72. package/src/utils/sqlAllowList.ts +111 -9
package/dist/index.cjs.js CHANGED
@@ -517,8 +517,6 @@ var applyLogLevelDefaults = function (config, request) {
517
517
  };
518
518
  var getLogContext = function (config, request) {
519
519
  var _a, _b;
520
- if (!config && !request)
521
- return undefined;
522
520
  return {
523
521
  logLevel: (_a = config === null || config === void 0 ? void 0 : config.logLevel) !== null && _a !== void 0 ? _a : undefined,
524
522
  verbose: (_b = config === null || config === void 0 ? void 0 : config.verbose) !== null && _b !== void 0 ? _b : undefined,
@@ -865,6 +863,213 @@ function removeInvalidKeys(request, c6Tables) {
865
863
  return intersection;
866
864
  }
867
865
 
866
+ /* eslint-disable no-control-regex */
867
+ var RESET = "\x1b[0m";
868
+ var C$1 = {
869
+ KEYWORD: "\x1b[94m", // blue
870
+ LIMIT: "\x1b[93m", // yellow
871
+ NUMBER: "\x1b[92m", // green
872
+ DIM: "\x1b[90m", // gray
873
+ };
874
+ /* ---------- ANSI helpers ---------- */
875
+ var ansi256 = function (n) { return "\u001B[38;5;".concat(n, "m"); };
876
+ /* ---------- hashing ---------- */
877
+ function hashString$1(str) {
878
+ var hash = 0;
879
+ for (var i = 0; i < str.length; i++) {
880
+ hash = (hash * 31 + str.charCodeAt(i)) | 0;
881
+ }
882
+ return Math.abs(hash);
883
+ }
884
+ /* ---------- table color ---------- */
885
+ function tableRGB(tableName) {
886
+ var name = tableName.replace(/[`"]/g, "").toLowerCase();
887
+ var hash = hashString$1(name);
888
+ // Stable hue bucket by first letter
889
+ var first = name.charCodeAt(0) || 97;
890
+ var hueBase = (first - 97) % 6;
891
+ var r = (hueBase + (hash % 3)) % 6;
892
+ var g = (hash >> 3) % 6;
893
+ var b = (hash >> 6) % 6;
894
+ return [r, g, Math.max(2, b)]; // avoid muddy dark blues
895
+ }
896
+ function tableColor(table) {
897
+ var _a = tableRGB(table), r = _a[0], g = _a[1], b = _a[2];
898
+ return ansi256(16 + 36 * r + 6 * g + b);
899
+ }
900
+ /* ---------- column color (same hue, lighter) ---------- */
901
+ function columnColorFromTable(table) {
902
+ var _a = tableRGB(table), r = _a[0], g = _a[1], b = _a[2];
903
+ // Lift toward white, preserve hue
904
+ var lr = Math.min(5, r + 1);
905
+ var lg = Math.min(5, g + 1);
906
+ var lb = Math.min(5, b + 2);
907
+ return ansi256(16 + 36 * lr + 6 * lg + lb);
908
+ }
909
+ /* ---------- bind collapsing ---------- */
910
+ /**
911
+ * ?, ?, ?, ?, ?, ? → ? ×6
912
+ * triggers at 4+
913
+ */
914
+ function collapseBinds(sql) {
915
+ return sql.replace(/(\?\s*,\s*){3,}\?/g, function (match) {
916
+ var count = match.split("?").length - 1;
917
+ return "".concat(C$1.DIM, "? \u00D7").concat(count).concat(RESET);
918
+ });
919
+ }
920
+ /**
921
+ * ( ? ×9 ), ( ? ×9 ), ( ? ×9 ) -> ( ? ×9 ) ×3
922
+ */
923
+ function collapseRepeatedValueRows(sql) {
924
+ var repeatedRowPattern = /(\((?:\x1b\[[0-9;]*m)?\?\s*×\d+(?:\x1b\[[0-9;]*m)?\)|\(\s*(?:\?\s*,\s*)+\?\s*\))(?:\s*,\s*\1){2,}/g;
925
+ return sql.replace(repeatedRowPattern, function (match, row) {
926
+ var _a, _b;
927
+ var rowMatches = match.match(new RegExp(row.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"));
928
+ var count = (_a = rowMatches === null || rowMatches === void 0 ? void 0 : rowMatches.length) !== null && _a !== void 0 ? _a : 1;
929
+ var normalizedRow = row.includes("×")
930
+ ? row
931
+ : "(".concat(C$1.DIM, "? \u00D7").concat(((_b = row.match(/\?/g)) !== null && _b !== void 0 ? _b : []).length).concat(RESET, ")");
932
+ return "".concat(normalizedRow, " ").concat(C$1.DIM, "\u00D7").concat(count).concat(RESET);
933
+ });
934
+ }
935
+ /* ---------- main formatter ---------- */
936
+ function colorSql(sql) {
937
+ var s = sql.trim();
938
+ /* 1️⃣ collapse bind noise */
939
+ s = collapseBinds(s);
940
+ s = collapseRepeatedValueRows(s);
941
+ /* 2️⃣ table.column coloring (core visual grouping) */
942
+ s = s.replace(/\b(`?\w+`?)\.(\w+)\b/g, function (_, table, column) {
943
+ return "".concat(tableColor(table)).concat(table).concat(RESET, ".") +
944
+ "".concat(columnColorFromTable(table)).concat(column).concat(RESET);
945
+ });
946
+ /* 3️⃣ FROM / JOIN tables */
947
+ s = s.replace(/\b(FROM|JOIN|UPDATE|INTO)\s+(`[^`]+`|\w+)/gi, function (_, kw, table) {
948
+ return "".concat(C$1.KEYWORD).concat(kw).concat(RESET, " ").concat(tableColor(table)).concat(table).concat(RESET);
949
+ });
950
+ /* 4️⃣ SQL keywords */
951
+ 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));
952
+ /* 5️⃣ LIMIT */
953
+ s = s.replace(/\bLIMIT\s+(\d+)/gi, "".concat(C$1.LIMIT, "LIMIT").concat(RESET, " ").concat(C$1.NUMBER, "$1").concat(RESET));
954
+ return s;
955
+ }
956
+
957
+ var version = "6.0.17";
958
+
959
+ var DEFAULT_STEP = 8;
960
+ function parseSemver(version) {
961
+ var _a = version.trim().split("-"), core = _a[0], prerelease = _a[1];
962
+ var _b = core.split("."), majorRaw = _b[0], minorRaw = _b[1], patchRaw = _b[2];
963
+ var major = Number.parseInt(majorRaw !== null && majorRaw !== void 0 ? majorRaw : "0", 10);
964
+ var minor = Number.parseInt(minorRaw !== null && minorRaw !== void 0 ? minorRaw : "0", 10);
965
+ var patch = Number.parseInt(patchRaw !== null && patchRaw !== void 0 ? patchRaw : "0", 10);
966
+ var prereleaseParts = prerelease ? prerelease.split(".").filter(Boolean).length : 0;
967
+ return {
968
+ major: Number.isFinite(major) ? major : 0,
969
+ minor: Number.isFinite(minor) ? minor : 0,
970
+ patch: Number.isFinite(patch) ? patch : 0,
971
+ prereleaseParts: prereleaseParts,
972
+ };
973
+ }
974
+ function channelValue(n, step) {
975
+ var value = 255 - ((n * step) % 256);
976
+ return (value + 256) % 256;
977
+ }
978
+ function versionToRgb(version, step) {
979
+ if (step === void 0) { step = DEFAULT_STEP; }
980
+ var safeStep = Number.isFinite(step) && step > 0 ? Math.floor(step) : DEFAULT_STEP;
981
+ var _a = parseSemver(version), major = _a.major, minor = _a.minor, patch = _a.patch, prereleaseParts = _a.prereleaseParts;
982
+ var rotation = (major + minor + patch + prereleaseParts) % 3;
983
+ var base = [major, minor, patch];
984
+ var rotated = rotation === 1
985
+ ? [base[2], base[0], base[1]]
986
+ : rotation === 2
987
+ ? [base[1], base[2], base[0]]
988
+ : base;
989
+ return {
990
+ r: channelValue(rotated[0], safeStep),
991
+ g: channelValue(rotated[1], safeStep),
992
+ b: channelValue(rotated[2], safeStep),
993
+ };
994
+ }
995
+
996
+ var C = {
997
+ SSR: "\x1b[95m", // bright magenta
998
+ HTTP: "\x1b[94m", // bright blue
999
+ WARN: "\x1b[93m", // yellow
1000
+ ORANGE: "\x1b[38;2;255;165;0m", // orange (truecolor)
1001
+ ERROR: "\x1b[91m", // red
1002
+ METHOD_COLORS: {
1003
+ SELECT: "\x1b[92m", // green
1004
+ INSERT: "\x1b[96m", // cyan
1005
+ REPLACE: "\x1b[96m", // cyan
1006
+ UPDATE: "\x1b[95m", // magenta
1007
+ DELETE: "\x1b[38;2;255;179;179m", // very light red (truecolor)
1008
+ },
1009
+ METHOD_FALLBACK: [
1010
+ "\x1b[92m", // green
1011
+ "\x1b[93m", // yellow
1012
+ "\x1b[95m", // magenta
1013
+ "\x1b[96m", // cyan
1014
+ "\x1b[94m", // blue
1015
+ "\x1b[97m", // white
1016
+ ],
1017
+ GREY: "\x1b[90m", // light grey
1018
+ RESET: "\x1b[0m",
1019
+ };
1020
+ var rgbAnsi = function (_a) {
1021
+ var r = _a.r, g = _a.g, b = _a.b;
1022
+ return "\u001B[38;2;".concat(r, ";").concat(g, ";").concat(b, "m");
1023
+ };
1024
+ function hashString(value) {
1025
+ var hash = 0;
1026
+ for (var i = 0; i < value.length; i++) {
1027
+ hash = (hash * 31 + value.charCodeAt(i)) | 0;
1028
+ }
1029
+ return Math.abs(hash);
1030
+ }
1031
+ function methodColor(method) {
1032
+ var key = method.toUpperCase();
1033
+ if (key in C.METHOD_COLORS) {
1034
+ return C.METHOD_COLORS[key];
1035
+ }
1036
+ var idx = hashString(key) % C.METHOD_FALLBACK.length;
1037
+ return C.METHOD_FALLBACK[idx];
1038
+ }
1039
+ var cacheLabel = function (cacheStatus) {
1040
+ switch (cacheStatus) {
1041
+ case "hit":
1042
+ return "".concat(C.METHOD_COLORS.SELECT, "[CACHE HIT]").concat(C.RESET);
1043
+ case "ignored":
1044
+ return "".concat(C.WARN, "[CACHE IGNORED]").concat(C.RESET);
1045
+ default:
1046
+ return "".concat(C.ORANGE, "[CACHE MISS]").concat(C.RESET);
1047
+ }
1048
+ };
1049
+ var allowListLabel = function (status) {
1050
+ switch (status) {
1051
+ case "allowed":
1052
+ return "".concat(C.METHOD_COLORS.SELECT, "[VERIFIED]").concat(C.RESET);
1053
+ case "denied":
1054
+ return "".concat(C.ERROR, "[DENIED]").concat(C.RESET);
1055
+ default:
1056
+ return "".concat(C.GREY, "[NOT VERIFIED]").concat(C.RESET);
1057
+ }
1058
+ };
1059
+ function logSql(options) {
1060
+ var method = options.method.toUpperCase();
1061
+ if (!shouldLog(exports.LogLevel.INFO, options.context))
1062
+ return;
1063
+ var preText = getEnvBool("SSR", false)
1064
+ ? "".concat(C.SSR, "[SSR]").concat(C.RESET, " ")
1065
+ : "".concat(C.HTTP, "[API]").concat(C.RESET, " ");
1066
+ var labelColor = methodColor(method);
1067
+ var versionColor = rgbAnsi(versionToRgb(version));
1068
+ var cacheText = cacheLabel(options.cacheStatus);
1069
+ var allowListText = allowListLabel(options.allowListStatus);
1070
+ 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)));
1071
+ }
1072
+
868
1073
  // -----------------------------------------------------------------------------
869
1074
  // Cache Storage
870
1075
  // -----------------------------------------------------------------------------
@@ -907,15 +1112,24 @@ function clearCache(props) {
907
1112
  // -----------------------------------------------------------------------------
908
1113
  // Check Cache (dedupe via hashed key)
909
1114
  // -----------------------------------------------------------------------------
910
- function checkCache(method, tableName, requestData) {
1115
+ function checkCache(method, tableName, requestData, logContext) {
1116
+ var _a, _b, _c, _d, _e;
911
1117
  var key = makeCacheKey(method, tableName, requestData);
912
1118
  var cached = apiRequestCache.get(key);
913
- if (!cached)
1119
+ if (!cached) {
1120
+ console.log('apiRequestCache.size', apiRequestCache.size);
914
1121
  return false;
915
- if (shouldLog(exports.LogLevel.INFO, undefined)) {
916
- console.groupCollapsed("%c API cache hit for ".concat(method, " ").concat(tableName), "color:#0c0");
917
- console.log("Request Data:", requestData);
918
- console.groupEnd();
1122
+ }
1123
+ if (shouldLog(exports.LogLevel.INFO, logContext)) {
1124
+ 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 : "";
1125
+ var sqlMethod = ((_e = sql.trim().split(/\s+/, 1)[0]) === null || _e === void 0 ? void 0 : _e.toUpperCase()) || method;
1126
+ logSql({
1127
+ allowListStatus: "not verified",
1128
+ cacheStatus: "hit",
1129
+ context: logContext,
1130
+ method: sqlMethod,
1131
+ sql: sql
1132
+ });
919
1133
  }
920
1134
  return cached.request;
921
1135
  }
@@ -1084,7 +1298,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1084
1298
  querySerialized = sortAndSerializeQueryObject(tables, cacheRequestData !== null && cacheRequestData !== void 0 ? cacheRequestData : {});
1085
1299
  cachedRequest = false;
1086
1300
  if (cacheResults) {
1087
- cachedRequest = checkCache(requestMethod, tableName, cacheRequestData);
1301
+ cachedRequest = checkCache(requestMethod, tableName, cacheRequestData, logContext);
1088
1302
  }
1089
1303
  if (!cachedRequest) return [3 /*break*/, 2];
1090
1304
  return [4 /*yield*/, cachedRequest];
@@ -2945,186 +3159,6 @@ var PaginationBuilder = /** @class */ (function (_super) {
2945
3159
  return PaginationBuilder;
2946
3160
  }(JoinBuilder));
2947
3161
 
2948
- /* eslint-disable no-control-regex */
2949
- var RESET = "\x1b[0m";
2950
- var C$1 = {
2951
- KEYWORD: "\x1b[94m", // blue
2952
- LIMIT: "\x1b[93m", // yellow
2953
- NUMBER: "\x1b[92m", // green
2954
- DIM: "\x1b[90m", // gray
2955
- };
2956
- /* ---------- ANSI helpers ---------- */
2957
- var ansi256 = function (n) { return "\u001B[38;5;".concat(n, "m"); };
2958
- /* ---------- hashing ---------- */
2959
- function hashString$1(str) {
2960
- var hash = 0;
2961
- for (var i = 0; i < str.length; i++) {
2962
- hash = (hash * 31 + str.charCodeAt(i)) | 0;
2963
- }
2964
- return Math.abs(hash);
2965
- }
2966
- /* ---------- table color ---------- */
2967
- function tableRGB(tableName) {
2968
- var name = tableName.replace(/[`"]/g, "").toLowerCase();
2969
- var hash = hashString$1(name);
2970
- // Stable hue bucket by first letter
2971
- var first = name.charCodeAt(0) || 97;
2972
- var hueBase = (first - 97) % 6;
2973
- var r = (hueBase + (hash % 3)) % 6;
2974
- var g = (hash >> 3) % 6;
2975
- var b = (hash >> 6) % 6;
2976
- return [r, g, Math.max(2, b)]; // avoid muddy dark blues
2977
- }
2978
- function tableColor(table) {
2979
- var _a = tableRGB(table), r = _a[0], g = _a[1], b = _a[2];
2980
- return ansi256(16 + 36 * r + 6 * g + b);
2981
- }
2982
- /* ---------- column color (same hue, lighter) ---------- */
2983
- function columnColorFromTable(table) {
2984
- var _a = tableRGB(table), r = _a[0], g = _a[1], b = _a[2];
2985
- // Lift toward white, preserve hue
2986
- var lr = Math.min(5, r + 1);
2987
- var lg = Math.min(5, g + 1);
2988
- var lb = Math.min(5, b + 2);
2989
- return ansi256(16 + 36 * lr + 6 * lg + lb);
2990
- }
2991
- /* ---------- bind collapsing ---------- */
2992
- /**
2993
- * ?, ?, ?, ?, ?, ? → ? ×6
2994
- * triggers at 4+
2995
- */
2996
- function collapseBinds(sql) {
2997
- return sql.replace(/(\?\s*,\s*){3,}\?/g, function (match) {
2998
- var count = match.split("?").length - 1;
2999
- return "".concat(C$1.DIM, "? \u00D7").concat(count).concat(RESET);
3000
- });
3001
- }
3002
- /**
3003
- * ( ? ×9 ), ( ? ×9 ), ( ? ×9 ) -> ( ? ×9 ) ×3
3004
- */
3005
- function collapseRepeatedValueRows(sql) {
3006
- var repeatedRowPattern = /(\((?:\x1b\[[0-9;]*m)?\?\s*×\d+(?:\x1b\[[0-9;]*m)?\)|\(\s*(?:\?\s*,\s*)+\?\s*\))(?:\s*,\s*\1){2,}/g;
3007
- return sql.replace(repeatedRowPattern, function (match, row) {
3008
- var _a, _b;
3009
- var rowMatches = match.match(new RegExp(row.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"));
3010
- var count = (_a = rowMatches === null || rowMatches === void 0 ? void 0 : rowMatches.length) !== null && _a !== void 0 ? _a : 1;
3011
- var normalizedRow = row.includes("×")
3012
- ? row
3013
- : "(".concat(C$1.DIM, "? \u00D7").concat(((_b = row.match(/\?/g)) !== null && _b !== void 0 ? _b : []).length).concat(RESET, ")");
3014
- return "".concat(normalizedRow, " ").concat(C$1.DIM, "\u00D7").concat(count).concat(RESET);
3015
- });
3016
- }
3017
- /* ---------- main formatter ---------- */
3018
- function colorSql(sql) {
3019
- var s = sql.trim();
3020
- /* 1️⃣ collapse bind noise */
3021
- s = collapseBinds(s);
3022
- s = collapseRepeatedValueRows(s);
3023
- /* 2️⃣ table.column coloring (core visual grouping) */
3024
- s = s.replace(/\b(`?\w+`?)\.(\w+)\b/g, function (_, table, column) {
3025
- return "".concat(tableColor(table)).concat(table).concat(RESET, ".") +
3026
- "".concat(columnColorFromTable(table)).concat(column).concat(RESET);
3027
- });
3028
- /* 3️⃣ FROM / JOIN tables */
3029
- s = s.replace(/\b(FROM|JOIN|UPDATE|INTO)\s+(`[^`]+`|\w+)/gi, function (_, kw, table) {
3030
- return "".concat(C$1.KEYWORD).concat(kw).concat(RESET, " ").concat(tableColor(table)).concat(table).concat(RESET);
3031
- });
3032
- /* 4️⃣ SQL keywords */
3033
- 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));
3034
- /* 5️⃣ LIMIT */
3035
- s = s.replace(/\bLIMIT\s+(\d+)/gi, "".concat(C$1.LIMIT, "LIMIT").concat(RESET, " ").concat(C$1.NUMBER, "$1").concat(RESET));
3036
- return s;
3037
- }
3038
-
3039
- var version = "6.0.14";
3040
-
3041
- var DEFAULT_STEP = 8;
3042
- function parseSemver(version) {
3043
- var _a = version.trim().split("-"), core = _a[0], prerelease = _a[1];
3044
- var _b = core.split("."), majorRaw = _b[0], minorRaw = _b[1], patchRaw = _b[2];
3045
- var major = Number.parseInt(majorRaw !== null && majorRaw !== void 0 ? majorRaw : "0", 10);
3046
- var minor = Number.parseInt(minorRaw !== null && minorRaw !== void 0 ? minorRaw : "0", 10);
3047
- var patch = Number.parseInt(patchRaw !== null && patchRaw !== void 0 ? patchRaw : "0", 10);
3048
- var prereleaseParts = prerelease ? prerelease.split(".").filter(Boolean).length : 0;
3049
- return {
3050
- major: Number.isFinite(major) ? major : 0,
3051
- minor: Number.isFinite(minor) ? minor : 0,
3052
- patch: Number.isFinite(patch) ? patch : 0,
3053
- prereleaseParts: prereleaseParts,
3054
- };
3055
- }
3056
- function channelValue(n, step) {
3057
- var value = 255 - ((n * step) % 256);
3058
- return (value + 256) % 256;
3059
- }
3060
- function versionToRgb(version, step) {
3061
- if (step === void 0) { step = DEFAULT_STEP; }
3062
- var safeStep = Number.isFinite(step) && step > 0 ? Math.floor(step) : DEFAULT_STEP;
3063
- var _a = parseSemver(version), major = _a.major, minor = _a.minor, patch = _a.patch, prereleaseParts = _a.prereleaseParts;
3064
- var rotation = (major + minor + patch + prereleaseParts) % 3;
3065
- var base = [major, minor, patch];
3066
- var rotated = rotation === 1
3067
- ? [base[2], base[0], base[1]]
3068
- : rotation === 2
3069
- ? [base[1], base[2], base[0]]
3070
- : base;
3071
- return {
3072
- r: channelValue(rotated[0], safeStep),
3073
- g: channelValue(rotated[1], safeStep),
3074
- b: channelValue(rotated[2], safeStep),
3075
- };
3076
- }
3077
-
3078
- var C = {
3079
- SSR: "\x1b[95m", // bright magenta
3080
- HTTP: "\x1b[94m", // bright blue
3081
- METHOD_COLORS: {
3082
- SELECT: "\x1b[92m", // green
3083
- INSERT: "\x1b[96m", // cyan
3084
- REPLACE: "\x1b[96m", // cyan
3085
- UPDATE: "\x1b[95m", // magenta
3086
- DELETE: "\x1b[91m", // red
3087
- },
3088
- METHOD_FALLBACK: [
3089
- "\x1b[92m", // green
3090
- "\x1b[93m", // yellow
3091
- "\x1b[95m", // magenta
3092
- "\x1b[96m", // cyan
3093
- "\x1b[94m", // blue
3094
- "\x1b[97m", // white
3095
- ],
3096
- RESET: "\x1b[0m",
3097
- };
3098
- var rgbAnsi = function (_a) {
3099
- var r = _a.r, g = _a.g, b = _a.b;
3100
- return "\u001B[38;2;".concat(r, ";").concat(g, ";").concat(b, "m");
3101
- };
3102
- function hashString(value) {
3103
- var hash = 0;
3104
- for (var i = 0; i < value.length; i++) {
3105
- hash = (hash * 31 + value.charCodeAt(i)) | 0;
3106
- }
3107
- return Math.abs(hash);
3108
- }
3109
- function methodColor(method) {
3110
- var key = method.toUpperCase();
3111
- if (key in C.METHOD_COLORS) {
3112
- return C.METHOD_COLORS[key];
3113
- }
3114
- var idx = hashString(key) % C.METHOD_FALLBACK.length;
3115
- return C.METHOD_FALLBACK[idx];
3116
- }
3117
- function logSql(method, sql, context) {
3118
- if (!shouldLog(exports.LogLevel.INFO, context))
3119
- return;
3120
- var preText = getEnvBool("SSR", false)
3121
- ? "".concat(C.SSR, "[SSR]").concat(C.RESET, " ")
3122
- : "".concat(C.HTTP, "[API]").concat(C.RESET, " ");
3123
- var labelColor = methodColor(method);
3124
- var versionColor = rgbAnsi(versionToRgb(version));
3125
- console.log("".concat(versionColor, "[").concat(version, "]").concat(C.RESET, " ").concat(preText).concat(labelColor, "[").concat(method, "]").concat(C.RESET, " ").concat(colorSql(sql)));
3126
- }
3127
-
3128
3162
  var SelectQueryBuilder = /** @class */ (function (_super) {
3129
3163
  tslib.__extends(SelectQueryBuilder, _super);
3130
3164
  function SelectQueryBuilder() {
@@ -3176,7 +3210,6 @@ var SelectQueryBuilder = /** @class */ (function (_super) {
3176
3210
  else if (!isSubSelect) {
3177
3211
  sql += " LIMIT 100";
3178
3212
  }
3179
- logSql("SELECT", sql, getLogContext(this.config, this.request));
3180
3213
  return { sql: sql, params: params };
3181
3214
  };
3182
3215
  return SelectQueryBuilder;
@@ -3201,7 +3234,6 @@ var DeleteQueryBuilder = /** @class */ (function (_super) {
3201
3234
  if (this.request.WHERE) {
3202
3235
  sql += this.buildWhereClause(this.request.WHERE, params);
3203
3236
  }
3204
- logSql("DELETE", sql, getLogContext(this.config, this.request));
3205
3237
  return { sql: sql, params: params };
3206
3238
  };
3207
3239
  return DeleteQueryBuilder;
@@ -3260,7 +3292,6 @@ var PostQueryBuilder = /** @class */ (function (_super) {
3260
3292
  var updateClause = updateData.map(function (k) { return "`".concat(k, "` = VALUES(`").concat(k, "`)"); }).join(', ');
3261
3293
  sql += " ON DUPLICATE KEY UPDATE ".concat(updateClause);
3262
3294
  }
3263
- logSql(verb, sql, getLogContext(this.config, this.request));
3264
3295
  return { sql: sql, params: params };
3265
3296
  };
3266
3297
  return PostQueryBuilder;
@@ -3312,7 +3343,6 @@ var UpdateQueryBuilder = /** @class */ (function (_super) {
3312
3343
  if (args.PAGINATION) {
3313
3344
  sql += this.buildPaginationClause(args.PAGINATION, params);
3314
3345
  }
3315
- logSql("UPDATE", sql, getLogContext(this.config, this.request));
3316
3346
  return { sql: sql, params: params };
3317
3347
  };
3318
3348
  return UpdateQueryBuilder;
@@ -3446,8 +3476,55 @@ function normalizeSingularRequest(requestMethod, request, restModel, removedPrim
3446
3476
  }
3447
3477
 
3448
3478
  var allowListCache = new Map();
3479
+ var ANSI_ESCAPE_REGEX = /\x1b\[[0-9;]*m/g;
3480
+ var COLLAPSED_BIND_ROW_REGEX = /\(\?\s*×\d+\)/g;
3481
+ function collapseBindGroups(sql) {
3482
+ var normalized = sql.replace(/\(\s*(\?(?:\s*,\s*\?)*)\s*\)/g, function (_match, binds) {
3483
+ var _a;
3484
+ var bindCount = ((_a = binds.match(/\?/g)) !== null && _a !== void 0 ? _a : []).length;
3485
+ return "(? \u00D7".concat(bindCount, ")");
3486
+ });
3487
+ normalized = normalized.replace(/(\(\?\s*×\d+\))(?:\s*,\s*\1)+/g, function (_match, row) { return "".concat(row, " \u00D7*"); });
3488
+ normalized = normalized.replace(/\b(VALUES|VALUE)\s+(\(\?\s*×\d+\))(?:\s*×\d+|\s*×\*)?/gi, function (_match, keyword, row) { return "".concat(keyword, " ").concat(row, " \u00D7*"); });
3489
+ normalized = normalized.replace(/\bIN\s*\(\?\s*×\d+\)/gi, "IN (? ×*)");
3490
+ normalized = normalized.replace(/\(\?\s*×\d+\)\s*×\d+/g, function (match) {
3491
+ var _a;
3492
+ var row = (_a = match.match(COLLAPSED_BIND_ROW_REGEX)) === null || _a === void 0 ? void 0 : _a[0];
3493
+ return row ? "".concat(row, " \u00D7*") : match;
3494
+ });
3495
+ return normalized;
3496
+ }
3497
+ function normalizeLimitOffset(sql) {
3498
+ return sql
3499
+ .replace(/\bLIMIT\s+\d+\s*,\s*\d+\b/gi, "LIMIT ?, ?")
3500
+ .replace(/\bLIMIT\s+\d+\s+OFFSET\s+\d+\b/gi, "LIMIT ? OFFSET ?")
3501
+ .replace(/\bLIMIT\s+\d+\b/gi, "LIMIT ?")
3502
+ .replace(/\bOFFSET\s+\d+\b/gi, "OFFSET ?");
3503
+ }
3504
+ function normalizeGeomFromTextLiterals(sql) {
3505
+ var normalized = sql.replace(/ST_GEOMFROMTEXT\(\s*'POINT\([^']*\)'\s*,\s*(?:\d+|\?)\s*\)/gi, "ST_GEOMFROMTEXT('POINT(? ?)', ?)");
3506
+ normalized = normalized.replace(/ST_GEOMFROMTEXT\(\s*'POLYGON\(\([^']*\)\)'\s*,\s*(?:\d+|\?)\s*\)/gi, "ST_GEOMFROMTEXT('POLYGON((?))', ?)");
3507
+ return normalized;
3508
+ }
3509
+ function normalizeGeoFunctionNames(sql) {
3510
+ return sql
3511
+ .replace(/\bST_DISTANCE_SPHERE\b/gi, "ST_DISTANCE_SPHERE")
3512
+ .replace(/\bST_GEOMFROMTEXT\b/gi, "ST_GEOMFROMTEXT")
3513
+ .replace(/\bMBRCONTAINS\b/gi, "MBRCONTAINS");
3514
+ }
3515
+ function normalizeTokenPunctuationSpacing(sql) {
3516
+ return sql.replace(/`,\s*`/g, "`, `");
3517
+ }
3449
3518
  var normalizeSql = function (sql) {
3450
- return sql.replace(/\s+/g, " ").trim();
3519
+ var normalized = sql.replace(ANSI_ESCAPE_REGEX, " ");
3520
+ normalized = normalized.replace(/\s+/g, " ").trim();
3521
+ normalized = normalizeGeoFunctionNames(normalized);
3522
+ normalized = normalizeTokenPunctuationSpacing(normalized);
3523
+ normalized = collapseBindGroups(normalized);
3524
+ normalized = normalizeLimitOffset(normalized);
3525
+ normalized = normalizeGeomFromTextLiterals(normalized);
3526
+ normalized = normalized.replace(/;\s*$/, "");
3527
+ return normalized.replace(/\s+/g, " ").trim();
3451
3528
  };
3452
3529
  var parseAllowList = function (raw, sourcePath) {
3453
3530
  var parsed;
@@ -3470,33 +3547,51 @@ var parseAllowList = function (raw, sourcePath) {
3470
3547
  return sqlEntries;
3471
3548
  };
3472
3549
  var loadSqlAllowList = function (allowListPath) { return tslib.__awaiter(void 0, void 0, void 0, function () {
3473
- var readFile, raw, sqlEntries, allowList;
3474
- return tslib.__generator(this, function (_a) {
3475
- switch (_a.label) {
3550
+ var _a, readFile, stat, fileStat, cached, raw, sqlEntries, allowList;
3551
+ return tslib.__generator(this, function (_b) {
3552
+ switch (_b.label) {
3476
3553
  case 0:
3477
- if (allowListCache.has(allowListPath)) {
3478
- return [2 /*return*/, allowListCache.get(allowListPath)];
3479
- }
3480
3554
  if (!isNode()) {
3481
3555
  throw new Error("SQL allowlist validation requires a Node runtime.");
3482
3556
  }
3483
3557
  return [4 /*yield*/, import('node:fs/promises')];
3484
3558
  case 1:
3485
- readFile = (_a.sent()).readFile;
3486
- _a.label = 2;
3559
+ _a = _b.sent(), readFile = _a.readFile, stat = _a.stat;
3560
+ _b.label = 2;
3487
3561
  case 2:
3488
- _a.trys.push([2, 4, , 5]);
3489
- return [4 /*yield*/, readFile(allowListPath, "utf-8")];
3562
+ _b.trys.push([2, 4, , 5]);
3563
+ return [4 /*yield*/, stat(allowListPath)];
3490
3564
  case 3:
3491
- raw = _a.sent();
3565
+ fileStat = _b.sent();
3492
3566
  return [3 /*break*/, 5];
3493
3567
  case 4:
3494
- _a.sent();
3568
+ _b.sent();
3495
3569
  throw new Error("SQL allowlist file not found at ".concat(allowListPath, "."));
3496
3570
  case 5:
3571
+ cached = allowListCache.get(allowListPath);
3572
+ if (cached &&
3573
+ cached.mtimeMs === fileStat.mtimeMs &&
3574
+ cached.size === fileStat.size) {
3575
+ return [2 /*return*/, cached.allowList];
3576
+ }
3577
+ _b.label = 6;
3578
+ case 6:
3579
+ _b.trys.push([6, 8, , 9]);
3580
+ return [4 /*yield*/, readFile(allowListPath, "utf-8")];
3581
+ case 7:
3582
+ raw = _b.sent();
3583
+ return [3 /*break*/, 9];
3584
+ case 8:
3585
+ _b.sent();
3586
+ throw new Error("SQL allowlist file not found at ".concat(allowListPath, "."));
3587
+ case 9:
3497
3588
  sqlEntries = parseAllowList(raw, allowListPath);
3498
3589
  allowList = new Set(sqlEntries);
3499
- allowListCache.set(allowListPath, allowList);
3590
+ allowListCache.set(allowListPath, {
3591
+ allowList: allowList,
3592
+ mtimeMs: fileStat.mtimeMs,
3593
+ size: fileStat.size,
3594
+ });
3500
3595
  return [2 /*return*/, allowList];
3501
3596
  }
3502
3597
  });
@@ -3559,6 +3654,25 @@ var compileSqlAllowList = function (allowListPath, entries) { return tslib.__awa
3559
3654
  });
3560
3655
  }); };
3561
3656
 
3657
+ var SQL_ALLOWLIST_BLOCKED_CODE = "SQL_ALLOWLIST_BLOCKED";
3658
+ var createSqlAllowListBlockedError = function (args) {
3659
+ var _a, _b;
3660
+ var error = new Error("SQL statement is not permitted by allowlist (".concat(args.allowListPath, ")."));
3661
+ error.name = "SqlAllowListBlockedError";
3662
+ error.code = SQL_ALLOWLIST_BLOCKED_CODE;
3663
+ error.tableName = args.tableName;
3664
+ error.method = args.method;
3665
+ error.normalizedSql = args.normalizedSql;
3666
+ error.allowListPath = args.allowListPath;
3667
+ error.sqlAllowList = {
3668
+ sql: args.normalizedSql,
3669
+ table: (_a = args.tableName) !== null && _a !== void 0 ? _a : null,
3670
+ method: (_b = args.method) !== null && _b !== void 0 ? _b : null,
3671
+ allowListPath: args.allowListPath,
3672
+ canAdd: true,
3673
+ };
3674
+ return error;
3675
+ };
3562
3676
  var SqlExecutor = /** @class */ (function (_super) {
3563
3677
  tslib.__extends(SqlExecutor, _super);
3564
3678
  function SqlExecutor() {
@@ -3569,6 +3683,22 @@ var SqlExecutor = /** @class */ (function (_super) {
3569
3683
  })); };
3570
3684
  return _this;
3571
3685
  }
3686
+ SqlExecutor.prototype.resolveSqlLogMethod = function (method, sql) {
3687
+ var _a;
3688
+ var token = (_a = sql.trim().split(/\s+/, 1)[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase();
3689
+ if (token)
3690
+ return token;
3691
+ switch (method) {
3692
+ case C6Constants.GET:
3693
+ return "SELECT";
3694
+ case C6Constants.POST:
3695
+ return "INSERT";
3696
+ case C6Constants.PUT:
3697
+ return "UPDATE";
3698
+ default:
3699
+ return "DELETE";
3700
+ }
3701
+ };
3572
3702
  SqlExecutor.prototype.execute = function () {
3573
3703
  return tslib.__awaiter(this, void 0, void 0, function () {
3574
3704
  var TABLE_NAME, method, logContext, response, _a, rest, getResponse, restRows, result, result, result;
@@ -3940,7 +4070,7 @@ var SqlExecutor = /** @class */ (function (_super) {
3940
4070
  };
3941
4071
  SqlExecutor.prototype.runQuery = function () {
3942
4072
  return tslib.__awaiter(this, void 0, void 0, function () {
3943
- var method, tableName, logContext, cacheResults, cacheRequestData, requestArgumentsSerialized, cachedRequest, sqlExecution, queryPromise, cacheRequest, cacheResponse;
4073
+ var method, tableName, logContext, cacheResults, cacheRequestData, requestArgumentsSerialized, cachedRequest, sqlExecution, sqlMethod, queryPromise, cacheRequest, cacheResponse;
3944
4074
  var _this = this;
3945
4075
  var _a, _b;
3946
4076
  return tslib.__generator(this, function (_c) {
@@ -3950,8 +4080,7 @@ var SqlExecutor = /** @class */ (function (_super) {
3950
4080
  tableName = this.config.restModel.TABLE_NAME;
3951
4081
  logContext = getLogContext(this.config, this.request);
3952
4082
  cacheResults = method === C6Constants.GET
3953
- && !this.config.sqlAllowListPath
3954
- && ((_a = this.request) === null || _a === void 0 ? void 0 : _a.cacheResults) !== false;
4083
+ && ((_a = this.request.cacheResults) !== null && _a !== void 0 ? _a : true);
3955
4084
  cacheRequestData = cacheResults
3956
4085
  ? JSON.parse(JSON.stringify((_b = this.request) !== null && _b !== void 0 ? _b : {}))
3957
4086
  : undefined;
@@ -3959,15 +4088,18 @@ var SqlExecutor = /** @class */ (function (_super) {
3959
4088
  ? sortAndSerializeQueryObject(tableName, cacheRequestData !== null && cacheRequestData !== void 0 ? cacheRequestData : {})
3960
4089
  : undefined;
3961
4090
  if (!cacheResults) return [3 /*break*/, 2];
3962
- cachedRequest = checkCache(method, tableName, cacheRequestData);
4091
+ cachedRequest = checkCache(method, tableName, cacheRequestData, logContext);
3963
4092
  if (!cachedRequest) return [3 /*break*/, 2];
3964
4093
  return [4 /*yield*/, cachedRequest];
3965
4094
  case 1: return [2 /*return*/, (_c.sent()).data];
3966
4095
  case 2:
3967
4096
  sqlExecution = this.buildSqlExecutionContext(method, tableName, logContext);
3968
- queryPromise = this.withConnection(function (conn) { return tslib.__awaiter(_this, void 0, void 0, function () { return tslib.__generator(this, function (_a) {
3969
- return [2 /*return*/, this.executeQueryWithLifecycle(conn, method, sqlExecution, logContext)];
3970
- }); }); });
4097
+ sqlMethod = this.resolveSqlLogMethod(method, sqlExecution.sql);
4098
+ queryPromise = this.withConnection(function (conn) { return tslib.__awaiter(_this, void 0, void 0, function () {
4099
+ return tslib.__generator(this, function (_a) {
4100
+ return [2 /*return*/, this.executeQueryWithLifecycle(conn, method, sqlExecution, logContext, sqlMethod)];
4101
+ });
4102
+ }); });
3971
4103
  if (!(!cacheResults || !cacheRequestData || !requestArgumentsSerialized)) return [3 /*break*/, 4];
3972
4104
  return [4 /*yield*/, queryPromise];
3973
4105
  case 3: return [2 /*return*/, _c.sent()];
@@ -4045,9 +4177,9 @@ var SqlExecutor = /** @class */ (function (_super) {
4045
4177
  },
4046
4178
  };
4047
4179
  };
4048
- SqlExecutor.prototype.executeQueryWithLifecycle = function (conn, method, sqlExecution, logContext) {
4180
+ SqlExecutor.prototype.executeQueryWithLifecycle = function (conn, method, sqlExecution, logContext, sqlMethod) {
4049
4181
  return tslib.__awaiter(this, void 0, void 0, function () {
4050
- var useTransaction, committed, result, response, hookResponse, err_1, rollbackErr_1;
4182
+ var useTransaction, committed, allowListStatus, error_2, result, response, hookResponse, err_1, rollbackErr_1;
4051
4183
  return tslib.__generator(this, function (_a) {
4052
4184
  switch (_a.label) {
4053
4185
  case 0:
@@ -4055,25 +4187,49 @@ var SqlExecutor = /** @class */ (function (_super) {
4055
4187
  committed = false;
4056
4188
  _a.label = 1;
4057
4189
  case 1:
4058
- _a.trys.push([1, 11, , 16]);
4190
+ _a.trys.push([1, 14, , 19]);
4059
4191
  if (!useTransaction) return [3 /*break*/, 3];
4060
4192
  logWithLevel(exports.LogLevel.DEBUG, logContext, console.log, "[SQL EXECUTOR] \uD83E\uDDFE Beginning transaction");
4061
4193
  return [4 /*yield*/, conn.beginTransaction()];
4062
4194
  case 2:
4063
4195
  _a.sent();
4064
4196
  _a.label = 3;
4065
- case 3: return [4 /*yield*/, this.validateSqlAllowList(sqlExecution.sql)];
4197
+ case 3:
4198
+ allowListStatus = "not verified";
4199
+ _a.label = 4;
4066
4200
  case 4:
4067
- _a.sent();
4201
+ _a.trys.push([4, 6, , 7]);
4202
+ return [4 /*yield*/, this.validateSqlAllowList(sqlExecution.sql)];
4203
+ case 5:
4204
+ allowListStatus = _a.sent();
4205
+ return [3 /*break*/, 7];
4206
+ case 6:
4207
+ error_2 = _a.sent();
4208
+ logSql({
4209
+ method: sqlMethod,
4210
+ sql: sqlExecution.sql,
4211
+ context: logContext,
4212
+ cacheStatus: this.request.cacheResults === false ? "ignored" : "miss",
4213
+ allowListStatus: "denied",
4214
+ });
4215
+ throw error_2;
4216
+ case 7:
4217
+ logSql({
4218
+ method: sqlMethod,
4219
+ sql: sqlExecution.sql,
4220
+ context: logContext,
4221
+ cacheStatus: this.request.cacheResults === false ? "ignored" : "miss",
4222
+ allowListStatus: allowListStatus,
4223
+ });
4068
4224
  return [4 /*yield*/, this.runLifecycleHooks("beforeExecution", {
4069
4225
  config: this.config,
4070
4226
  request: this.request,
4071
4227
  sqlExecution: sqlExecution,
4072
4228
  })];
4073
- case 5:
4229
+ case 8:
4074
4230
  _a.sent();
4075
4231
  return [4 /*yield*/, conn.query(sqlExecution.sql, sqlExecution.values)];
4076
- case 6:
4232
+ case 9:
4077
4233
  result = (_a.sent())[0];
4078
4234
  response = this.createResponseFromQueryResult(method, result, sqlExecution, logContext);
4079
4235
  hookResponse = this.createLifecycleHookResponse(response);
@@ -4082,40 +4238,40 @@ var SqlExecutor = /** @class */ (function (_super) {
4082
4238
  request: this.request,
4083
4239
  response: hookResponse,
4084
4240
  })];
4085
- case 7:
4241
+ case 10:
4086
4242
  _a.sent();
4087
- if (!useTransaction) return [3 /*break*/, 9];
4243
+ if (!useTransaction) return [3 /*break*/, 12];
4088
4244
  return [4 /*yield*/, conn.commit()];
4089
- case 8:
4245
+ case 11:
4090
4246
  _a.sent();
4091
4247
  committed = true;
4092
4248
  logWithLevel(exports.LogLevel.DEBUG, logContext, console.log, "[SQL EXECUTOR] \uD83E\uDDFE Transaction committed");
4093
- _a.label = 9;
4094
- case 9: return [4 /*yield*/, this.runLifecycleHooks("afterCommit", {
4249
+ _a.label = 12;
4250
+ case 12: return [4 /*yield*/, this.runLifecycleHooks("afterCommit", {
4095
4251
  config: this.config,
4096
4252
  request: this.request,
4097
4253
  response: hookResponse,
4098
4254
  })];
4099
- case 10:
4255
+ case 13:
4100
4256
  _a.sent();
4101
4257
  return [2 /*return*/, response];
4102
- case 11:
4258
+ case 14:
4103
4259
  err_1 = _a.sent();
4104
- if (!(useTransaction && !committed)) return [3 /*break*/, 15];
4105
- _a.label = 12;
4106
- case 12:
4107
- _a.trys.push([12, 14, , 15]);
4260
+ if (!(useTransaction && !committed)) return [3 /*break*/, 18];
4261
+ _a.label = 15;
4262
+ case 15:
4263
+ _a.trys.push([15, 17, , 18]);
4108
4264
  return [4 /*yield*/, conn.rollback()];
4109
- case 13:
4265
+ case 16:
4110
4266
  _a.sent();
4111
4267
  logWithLevel(exports.LogLevel.WARN, logContext, console.warn, "[SQL EXECUTOR] \uD83E\uDDFE Transaction rolled back");
4112
- return [3 /*break*/, 15];
4113
- case 14:
4268
+ return [3 /*break*/, 18];
4269
+ case 17:
4114
4270
  rollbackErr_1 = _a.sent();
4115
4271
  logWithLevel(exports.LogLevel.ERROR, logContext, console.error, "[SQL EXECUTOR] Rollback failed", rollbackErr_1);
4116
- return [3 /*break*/, 15];
4117
- case 15: throw err_1;
4118
- case 16: return [2 /*return*/];
4272
+ return [3 /*break*/, 18];
4273
+ case 18: throw err_1;
4274
+ case 19: return [2 /*return*/];
4119
4275
  }
4120
4276
  });
4121
4277
  });
@@ -4123,21 +4279,31 @@ var SqlExecutor = /** @class */ (function (_super) {
4123
4279
  SqlExecutor.prototype.validateSqlAllowList = function (sql) {
4124
4280
  return tslib.__awaiter(this, void 0, void 0, function () {
4125
4281
  var allowListPath, allowList, normalized;
4126
- return tslib.__generator(this, function (_a) {
4127
- switch (_a.label) {
4282
+ var _a;
4283
+ return tslib.__generator(this, function (_b) {
4284
+ switch (_b.label) {
4128
4285
  case 0:
4129
4286
  allowListPath = this.config.sqlAllowListPath;
4130
4287
  if (!allowListPath) {
4131
- return [2 /*return*/];
4288
+ return [2 /*return*/, "not verified"];
4132
4289
  }
4133
4290
  return [4 /*yield*/, loadSqlAllowList(allowListPath)];
4134
4291
  case 1:
4135
- allowList = _a.sent();
4292
+ allowList = _b.sent();
4136
4293
  normalized = normalizeSql(sql);
4137
4294
  if (!allowList.has(normalized)) {
4138
- throw new Error("SQL statement is not permitted by allowlist (".concat(allowListPath, ")."));
4295
+ throw createSqlAllowListBlockedError({
4296
+ tableName: typeof ((_a = this.config.restModel) === null || _a === void 0 ? void 0 : _a.TABLE_NAME) === "string"
4297
+ ? this.config.restModel.TABLE_NAME
4298
+ : undefined,
4299
+ method: typeof this.config.requestMethod === "string"
4300
+ ? this.config.requestMethod
4301
+ : undefined,
4302
+ normalizedSql: normalized,
4303
+ allowListPath: allowListPath,
4304
+ });
4139
4305
  }
4140
- return [2 /*return*/];
4306
+ return [2 /*return*/, "allowed"];
4141
4307
  }
4142
4308
  });
4143
4309
  });