@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.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];
@@ -2942,186 +3156,6 @@ var PaginationBuilder = /** @class */ (function (_super) {
2942
3156
  return PaginationBuilder;
2943
3157
  }(JoinBuilder));
2944
3158
 
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
3159
  var SelectQueryBuilder = /** @class */ (function (_super) {
3126
3160
  __extends(SelectQueryBuilder, _super);
3127
3161
  function SelectQueryBuilder() {
@@ -3173,7 +3207,6 @@ var SelectQueryBuilder = /** @class */ (function (_super) {
3173
3207
  else if (!isSubSelect) {
3174
3208
  sql += " LIMIT 100";
3175
3209
  }
3176
- logSql("SELECT", sql, getLogContext(this.config, this.request));
3177
3210
  return { sql: sql, params: params };
3178
3211
  };
3179
3212
  return SelectQueryBuilder;
@@ -3198,7 +3231,6 @@ var DeleteQueryBuilder = /** @class */ (function (_super) {
3198
3231
  if (this.request.WHERE) {
3199
3232
  sql += this.buildWhereClause(this.request.WHERE, params);
3200
3233
  }
3201
- logSql("DELETE", sql, getLogContext(this.config, this.request));
3202
3234
  return { sql: sql, params: params };
3203
3235
  };
3204
3236
  return DeleteQueryBuilder;
@@ -3257,7 +3289,6 @@ var PostQueryBuilder = /** @class */ (function (_super) {
3257
3289
  var updateClause = updateData.map(function (k) { return "`".concat(k, "` = VALUES(`").concat(k, "`)"); }).join(', ');
3258
3290
  sql += " ON DUPLICATE KEY UPDATE ".concat(updateClause);
3259
3291
  }
3260
- logSql(verb, sql, getLogContext(this.config, this.request));
3261
3292
  return { sql: sql, params: params };
3262
3293
  };
3263
3294
  return PostQueryBuilder;
@@ -3309,7 +3340,6 @@ var UpdateQueryBuilder = /** @class */ (function (_super) {
3309
3340
  if (args.PAGINATION) {
3310
3341
  sql += this.buildPaginationClause(args.PAGINATION, params);
3311
3342
  }
3312
- logSql("UPDATE", sql, getLogContext(this.config, this.request));
3313
3343
  return { sql: sql, params: params };
3314
3344
  };
3315
3345
  return UpdateQueryBuilder;
@@ -3443,8 +3473,55 @@ function normalizeSingularRequest(requestMethod, request, restModel, removedPrim
3443
3473
  }
3444
3474
 
3445
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
+ }
3446
3515
  var normalizeSql = function (sql) {
3447
- 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();
3448
3525
  };
3449
3526
  var parseAllowList = function (raw, sourcePath) {
3450
3527
  var parsed;
@@ -3467,33 +3544,51 @@ var parseAllowList = function (raw, sourcePath) {
3467
3544
  return sqlEntries;
3468
3545
  };
3469
3546
  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) {
3547
+ var _a, readFile, stat, fileStat, cached, raw, sqlEntries, allowList;
3548
+ return __generator(this, function (_b) {
3549
+ switch (_b.label) {
3473
3550
  case 0:
3474
- if (allowListCache.has(allowListPath)) {
3475
- return [2 /*return*/, allowListCache.get(allowListPath)];
3476
- }
3477
3551
  if (!isNode()) {
3478
3552
  throw new Error("SQL allowlist validation requires a Node runtime.");
3479
3553
  }
3480
3554
  return [4 /*yield*/, import('node:fs/promises')];
3481
3555
  case 1:
3482
- readFile = (_a.sent()).readFile;
3483
- _a.label = 2;
3556
+ _a = _b.sent(), readFile = _a.readFile, stat = _a.stat;
3557
+ _b.label = 2;
3484
3558
  case 2:
3485
- _a.trys.push([2, 4, , 5]);
3486
- return [4 /*yield*/, readFile(allowListPath, "utf-8")];
3559
+ _b.trys.push([2, 4, , 5]);
3560
+ return [4 /*yield*/, stat(allowListPath)];
3487
3561
  case 3:
3488
- raw = _a.sent();
3562
+ fileStat = _b.sent();
3489
3563
  return [3 /*break*/, 5];
3490
3564
  case 4:
3491
- _a.sent();
3565
+ _b.sent();
3492
3566
  throw new Error("SQL allowlist file not found at ".concat(allowListPath, "."));
3493
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:
3494
3585
  sqlEntries = parseAllowList(raw, allowListPath);
3495
3586
  allowList = new Set(sqlEntries);
3496
- allowListCache.set(allowListPath, allowList);
3587
+ allowListCache.set(allowListPath, {
3588
+ allowList: allowList,
3589
+ mtimeMs: fileStat.mtimeMs,
3590
+ size: fileStat.size,
3591
+ });
3497
3592
  return [2 /*return*/, allowList];
3498
3593
  }
3499
3594
  });
@@ -3556,6 +3651,25 @@ var compileSqlAllowList = function (allowListPath, entries) { return __awaiter(v
3556
3651
  });
3557
3652
  }); };
3558
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
+ };
3559
3673
  var SqlExecutor = /** @class */ (function (_super) {
3560
3674
  __extends(SqlExecutor, _super);
3561
3675
  function SqlExecutor() {
@@ -3566,6 +3680,22 @@ var SqlExecutor = /** @class */ (function (_super) {
3566
3680
  })); };
3567
3681
  return _this;
3568
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
+ };
3569
3699
  SqlExecutor.prototype.execute = function () {
3570
3700
  return __awaiter(this, void 0, void 0, function () {
3571
3701
  var TABLE_NAME, method, logContext, response, _a, rest, getResponse, restRows, result, result, result;
@@ -3937,7 +4067,7 @@ var SqlExecutor = /** @class */ (function (_super) {
3937
4067
  };
3938
4068
  SqlExecutor.prototype.runQuery = function () {
3939
4069
  return __awaiter(this, void 0, void 0, function () {
3940
- 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;
3941
4071
  var _this = this;
3942
4072
  var _a, _b;
3943
4073
  return __generator(this, function (_c) {
@@ -3947,8 +4077,7 @@ var SqlExecutor = /** @class */ (function (_super) {
3947
4077
  tableName = this.config.restModel.TABLE_NAME;
3948
4078
  logContext = getLogContext(this.config, this.request);
3949
4079
  cacheResults = method === C6Constants.GET
3950
- && !this.config.sqlAllowListPath
3951
- && ((_a = this.request) === null || _a === void 0 ? void 0 : _a.cacheResults) !== false;
4080
+ && ((_a = this.request.cacheResults) !== null && _a !== void 0 ? _a : true);
3952
4081
  cacheRequestData = cacheResults
3953
4082
  ? JSON.parse(JSON.stringify((_b = this.request) !== null && _b !== void 0 ? _b : {}))
3954
4083
  : undefined;
@@ -3956,15 +4085,18 @@ var SqlExecutor = /** @class */ (function (_super) {
3956
4085
  ? sortAndSerializeQueryObject(tableName, cacheRequestData !== null && cacheRequestData !== void 0 ? cacheRequestData : {})
3957
4086
  : undefined;
3958
4087
  if (!cacheResults) return [3 /*break*/, 2];
3959
- cachedRequest = checkCache(method, tableName, cacheRequestData);
4088
+ cachedRequest = checkCache(method, tableName, cacheRequestData, logContext);
3960
4089
  if (!cachedRequest) return [3 /*break*/, 2];
3961
4090
  return [4 /*yield*/, cachedRequest];
3962
4091
  case 1: return [2 /*return*/, (_c.sent()).data];
3963
4092
  case 2:
3964
4093
  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
- }); }); });
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
+ }); });
3968
4100
  if (!(!cacheResults || !cacheRequestData || !requestArgumentsSerialized)) return [3 /*break*/, 4];
3969
4101
  return [4 /*yield*/, queryPromise];
3970
4102
  case 3: return [2 /*return*/, _c.sent()];
@@ -4042,9 +4174,9 @@ var SqlExecutor = /** @class */ (function (_super) {
4042
4174
  },
4043
4175
  };
4044
4176
  };
4045
- SqlExecutor.prototype.executeQueryWithLifecycle = function (conn, method, sqlExecution, logContext) {
4177
+ SqlExecutor.prototype.executeQueryWithLifecycle = function (conn, method, sqlExecution, logContext, sqlMethod) {
4046
4178
  return __awaiter(this, void 0, void 0, function () {
4047
- var useTransaction, committed, result, response, hookResponse, err_1, rollbackErr_1;
4179
+ var useTransaction, committed, allowListStatus, error_2, result, response, hookResponse, err_1, rollbackErr_1;
4048
4180
  return __generator(this, function (_a) {
4049
4181
  switch (_a.label) {
4050
4182
  case 0:
@@ -4052,25 +4184,49 @@ var SqlExecutor = /** @class */ (function (_super) {
4052
4184
  committed = false;
4053
4185
  _a.label = 1;
4054
4186
  case 1:
4055
- _a.trys.push([1, 11, , 16]);
4187
+ _a.trys.push([1, 14, , 19]);
4056
4188
  if (!useTransaction) return [3 /*break*/, 3];
4057
4189
  logWithLevel(LogLevel.DEBUG, logContext, console.log, "[SQL EXECUTOR] \uD83E\uDDFE Beginning transaction");
4058
4190
  return [4 /*yield*/, conn.beginTransaction()];
4059
4191
  case 2:
4060
4192
  _a.sent();
4061
4193
  _a.label = 3;
4062
- case 3: return [4 /*yield*/, this.validateSqlAllowList(sqlExecution.sql)];
4194
+ case 3:
4195
+ allowListStatus = "not verified";
4196
+ _a.label = 4;
4063
4197
  case 4:
4064
- _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
+ });
4065
4221
  return [4 /*yield*/, this.runLifecycleHooks("beforeExecution", {
4066
4222
  config: this.config,
4067
4223
  request: this.request,
4068
4224
  sqlExecution: sqlExecution,
4069
4225
  })];
4070
- case 5:
4226
+ case 8:
4071
4227
  _a.sent();
4072
4228
  return [4 /*yield*/, conn.query(sqlExecution.sql, sqlExecution.values)];
4073
- case 6:
4229
+ case 9:
4074
4230
  result = (_a.sent())[0];
4075
4231
  response = this.createResponseFromQueryResult(method, result, sqlExecution, logContext);
4076
4232
  hookResponse = this.createLifecycleHookResponse(response);
@@ -4079,40 +4235,40 @@ var SqlExecutor = /** @class */ (function (_super) {
4079
4235
  request: this.request,
4080
4236
  response: hookResponse,
4081
4237
  })];
4082
- case 7:
4238
+ case 10:
4083
4239
  _a.sent();
4084
- if (!useTransaction) return [3 /*break*/, 9];
4240
+ if (!useTransaction) return [3 /*break*/, 12];
4085
4241
  return [4 /*yield*/, conn.commit()];
4086
- case 8:
4242
+ case 11:
4087
4243
  _a.sent();
4088
4244
  committed = true;
4089
4245
  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", {
4246
+ _a.label = 12;
4247
+ case 12: return [4 /*yield*/, this.runLifecycleHooks("afterCommit", {
4092
4248
  config: this.config,
4093
4249
  request: this.request,
4094
4250
  response: hookResponse,
4095
4251
  })];
4096
- case 10:
4252
+ case 13:
4097
4253
  _a.sent();
4098
4254
  return [2 /*return*/, response];
4099
- case 11:
4255
+ case 14:
4100
4256
  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]);
4257
+ if (!(useTransaction && !committed)) return [3 /*break*/, 18];
4258
+ _a.label = 15;
4259
+ case 15:
4260
+ _a.trys.push([15, 17, , 18]);
4105
4261
  return [4 /*yield*/, conn.rollback()];
4106
- case 13:
4262
+ case 16:
4107
4263
  _a.sent();
4108
4264
  logWithLevel(LogLevel.WARN, logContext, console.warn, "[SQL EXECUTOR] \uD83E\uDDFE Transaction rolled back");
4109
- return [3 /*break*/, 15];
4110
- case 14:
4265
+ return [3 /*break*/, 18];
4266
+ case 17:
4111
4267
  rollbackErr_1 = _a.sent();
4112
4268
  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*/];
4269
+ return [3 /*break*/, 18];
4270
+ case 18: throw err_1;
4271
+ case 19: return [2 /*return*/];
4116
4272
  }
4117
4273
  });
4118
4274
  });
@@ -4120,21 +4276,31 @@ var SqlExecutor = /** @class */ (function (_super) {
4120
4276
  SqlExecutor.prototype.validateSqlAllowList = function (sql) {
4121
4277
  return __awaiter(this, void 0, void 0, function () {
4122
4278
  var allowListPath, allowList, normalized;
4123
- return __generator(this, function (_a) {
4124
- switch (_a.label) {
4279
+ var _a;
4280
+ return __generator(this, function (_b) {
4281
+ switch (_b.label) {
4125
4282
  case 0:
4126
4283
  allowListPath = this.config.sqlAllowListPath;
4127
4284
  if (!allowListPath) {
4128
- return [2 /*return*/];
4285
+ return [2 /*return*/, "not verified"];
4129
4286
  }
4130
4287
  return [4 /*yield*/, loadSqlAllowList(allowListPath)];
4131
4288
  case 1:
4132
- allowList = _a.sent();
4289
+ allowList = _b.sent();
4133
4290
  normalized = normalizeSql(sql);
4134
4291
  if (!allowList.has(normalized)) {
4135
- 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
+ });
4136
4302
  }
4137
- return [2 /*return*/];
4303
+ return [2 /*return*/, "allowed"];
4138
4304
  }
4139
4305
  });
4140
4306
  });