@carbonorm/carbonnode 6.0.18 → 6.0.20

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 (64) hide show
  1. package/dist/executors/SqlExecutor.d.ts +7 -0
  2. package/dist/index.cjs.js +230 -20
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.esm.js +230 -20
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/types/ormInterfaces.d.ts +1 -0
  7. package/dist/utils/cacheManager.d.ts +3 -2
  8. package/dist/utils/logSql.d.ts +1 -1
  9. package/package.json +1 -1
  10. package/src/__tests__/cacheManager.test.ts +55 -1
  11. package/src/__tests__/logSql.test.ts +16 -0
  12. package/src/__tests__/sakila-db/C6.js +1 -1
  13. package/src/__tests__/sakila-db/C6.mysqldump.json +1 -1
  14. package/src/__tests__/sakila-db/C6.mysqldump.sql +1 -1
  15. package/src/__tests__/sakila-db/C6.ts +1 -1
  16. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +11 -4
  17. package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +3 -3
  18. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +1 -1
  19. package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +3 -3
  20. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +18 -6
  21. package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +5 -5
  22. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +1 -1
  23. package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +5 -5
  24. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +9 -3
  25. package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +2 -2
  26. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +1 -1
  27. package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +2 -2
  28. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +10 -3
  29. package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +2 -2
  30. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +1 -1
  31. package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +2 -2
  32. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +9 -3
  33. package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +2 -2
  34. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +1 -1
  35. package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +2 -2
  36. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +18 -6
  37. package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +5 -5
  38. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +1 -1
  39. package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +5 -5
  40. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +18 -3
  41. package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +2 -2
  42. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +1 -1
  43. package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +2 -2
  44. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +9 -2
  45. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +1 -1
  46. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +1 -1
  47. package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +1 -1
  48. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +9 -3
  49. package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +2 -2
  50. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +1 -1
  51. package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +2 -2
  52. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +13 -3
  53. package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +2 -2
  54. package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +2 -2
  55. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +14 -4
  56. package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +3 -3
  57. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +1 -1
  58. package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +3 -3
  59. package/src/__tests__/sqlExecutorPostUuid.test.ts +185 -0
  60. package/src/executors/HttpExecutor.ts +33 -5
  61. package/src/executors/SqlExecutor.ts +207 -3
  62. package/src/types/ormInterfaces.ts +1 -0
  63. package/src/utils/cacheManager.ts +22 -5
  64. package/src/utils/logSql.ts +3 -1
@@ -17,6 +17,13 @@ export type SqlAllowListBlockedError = Error & {
17
17
  };
18
18
  };
19
19
  export declare class SqlExecutor<G extends OrmGenerics> extends Executor<G> {
20
+ private getPostRequestRows;
21
+ private getTypeValidationForColumn;
22
+ private isUuidLikePrimaryColumn;
23
+ private hasDefinedValue;
24
+ private generatePrimaryUuidValue;
25
+ private assignMissingPostPrimaryUuids;
26
+ private buildPostResponseRows;
20
27
  private resolveSqlLogMethod;
21
28
  execute(): Promise<DetermineResponseDataType<G['RequestMethod'], G['RestTableInterface']>>;
22
29
  private withConnection;
package/dist/index.cjs.js CHANGED
@@ -954,7 +954,7 @@ function colorSql(sql) {
954
954
  return s;
955
955
  }
956
956
 
957
- var version = "6.0.18";
957
+ var version = "6.0.20";
958
958
 
959
959
  var DEFAULT_STEP = 8;
960
960
  function parseSemver(version) {
@@ -1040,6 +1040,8 @@ var cacheLabel = function (cacheStatus) {
1040
1040
  switch (cacheStatus) {
1041
1041
  case "hit":
1042
1042
  return "".concat(C.METHOD_COLORS.SELECT, "[CACHE HIT]").concat(C.RESET);
1043
+ case "evicted":
1044
+ return "".concat(C.WARN, "[CACHE EVICTED]").concat(C.RESET);
1043
1045
  case "ignored":
1044
1046
  return "".concat(C.WARN, "[CACHE IGNORED]").concat(C.RESET);
1045
1047
  default:
@@ -1112,19 +1114,18 @@ function clearCache(props) {
1112
1114
  // -----------------------------------------------------------------------------
1113
1115
  // Check Cache (dedupe via hashed key)
1114
1116
  // -----------------------------------------------------------------------------
1115
- function checkCache(method, tableName, requestData, logContext) {
1116
- var _a, _b, _c, _d, _e;
1117
+ function checkCache(method, tableName, requestData, logContext, allowListStatus) {
1118
+ var _a, _b, _c, _d, _e, _f, _g;
1117
1119
  var key = makeCacheKey(method, tableName, requestData);
1118
1120
  var cached = apiRequestCache.get(key);
1119
1121
  if (!cached) {
1120
- console.log('apiRequestCache.size', apiRequestCache.size);
1121
1122
  return false;
1122
1123
  }
1123
1124
  if (shouldLog(exports.LogLevel.INFO, logContext)) {
1124
1125
  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
1126
  var sqlMethod = ((_e = sql.trim().split(/\s+/, 1)[0]) === null || _e === void 0 ? void 0 : _e.toUpperCase()) || method;
1126
1127
  logSql({
1127
- allowListStatus: "not verified",
1128
+ allowListStatus: (_g = (_f = cached.allowListStatus) !== null && _f !== void 0 ? _f : allowListStatus) !== null && _g !== void 0 ? _g : "not verified",
1128
1129
  cacheStatus: "hit",
1129
1130
  context: logContext,
1130
1131
  method: sqlMethod,
@@ -1140,9 +1141,23 @@ function setCache(method, tableName, requestData, cacheEntry) {
1140
1141
  var key = makeCacheKey(method, tableName, requestData);
1141
1142
  apiRequestCache.set(key, cacheEntry);
1142
1143
  }
1143
- function evictCacheEntry(method, tableName, requestData) {
1144
+ function evictCacheEntry(method, tableName, requestData, logContext, allowListStatus) {
1145
+ var _a, _b, _c, _d, _e, _f, _g;
1144
1146
  var key = makeCacheKey(method, tableName, requestData);
1145
- return apiRequestCache.delete(key);
1147
+ var cached = apiRequestCache.get(key);
1148
+ var deleted = apiRequestCache.delete(key);
1149
+ if (deleted && shouldLog(exports.LogLevel.INFO, logContext)) {
1150
+ var sql = (_d = (_c = (_b = (_a = cached === null || cached === void 0 ? void 0 : 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 : "";
1151
+ var sqlMethod = ((_e = sql.trim().split(/\s+/, 1)[0]) === null || _e === void 0 ? void 0 : _e.toUpperCase()) || method;
1152
+ logSql({
1153
+ allowListStatus: (_g = (_f = cached === null || cached === void 0 ? void 0 : cached.allowListStatus) !== null && _f !== void 0 ? _f : allowListStatus) !== null && _g !== void 0 ? _g : "not verified",
1154
+ cacheStatus: "evicted",
1155
+ context: logContext,
1156
+ method: sqlMethod,
1157
+ sql: sql,
1158
+ });
1159
+ }
1160
+ return deleted;
1146
1161
  }
1147
1162
 
1148
1163
  function sortAndSerializeQueryObject(tables, query) {
@@ -1190,27 +1205,34 @@ var HttpExecutor = /** @class */ (function (_super) {
1190
1205
  };
1191
1206
  HttpExecutor.prototype.postState = function (response, request, callback) {
1192
1207
  var _this = this;
1193
- var _a, _b, _c;
1208
+ var _a, _b, _c, _d, _e, _f;
1209
+ var responseRestRaw = (_a = response.data) === null || _a === void 0 ? void 0 : _a.rest;
1210
+ var responseRows = Array.isArray(responseRestRaw)
1211
+ ? responseRestRaw
1212
+ : (responseRestRaw ? [responseRestRaw] : []);
1194
1213
  if (this.config.restModel.PRIMARY_SHORT.length === 1) {
1195
1214
  var pk = this.config.restModel.PRIMARY_SHORT[0];
1196
1215
  try {
1197
- request[pk] = (_a = response.data) === null || _a === void 0 ? void 0 : _a.created;
1216
+ var created = (_c = (_b = response.data) === null || _b === void 0 ? void 0 : _b.created) !== null && _c !== void 0 ? _c : (_d = responseRows[0]) === null || _d === void 0 ? void 0 : _d[pk];
1217
+ if (created !== undefined) {
1218
+ request[pk] = created;
1219
+ }
1198
1220
  }
1199
- catch ( /* best-effort */_d) { /* best-effort */ }
1221
+ catch ( /* best-effort */_g) { /* best-effort */ }
1200
1222
  }
1201
1223
  else if (isLocal()) {
1202
1224
  logWithLevel(exports.LogLevel.ERROR, getLogContext(this.config, this.request), console.error, "C6 received unexpected results given the primary key length");
1203
1225
  }
1204
- (_b = this.config.reactBootstrap) === null || _b === void 0 ? void 0 : _b.updateRestfulObjectArrays({
1226
+ (_e = this.config.reactBootstrap) === null || _e === void 0 ? void 0 : _e.updateRestfulObjectArrays({
1205
1227
  callback: callback,
1206
1228
  dataOrCallback: undefined !== request.dataInsertMultipleRows
1207
1229
  ? request.dataInsertMultipleRows.map(function (row, index) {
1208
1230
  var _a;
1209
1231
  var normalizedRow = _this.stripTableNameFromKeys(row);
1210
- return removeInvalidKeys(tslib.__assign(tslib.__assign({}, normalizedRow), (index === 0 ? (_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.rest : {})), _this.config.C6.TABLES);
1232
+ return removeInvalidKeys(tslib.__assign(tslib.__assign({}, normalizedRow), ((_a = responseRows[index]) !== null && _a !== void 0 ? _a : {})), _this.config.C6.TABLES);
1211
1233
  })
1212
1234
  : [
1213
- removeInvalidKeys(tslib.__assign(tslib.__assign({}, this.stripTableNameFromKeys(request)), (_c = response === null || response === void 0 ? void 0 : response.data) === null || _c === void 0 ? void 0 : _c.rest), this.config.C6.TABLES)
1235
+ removeInvalidKeys(tslib.__assign(tslib.__assign({}, this.stripTableNameFromKeys(request)), ((_f = responseRows[0]) !== null && _f !== void 0 ? _f : {})), this.config.C6.TABLES)
1214
1236
  ],
1215
1237
  stateKey: this.config.restModel.TABLE_NAME,
1216
1238
  uniqueObjectId: this.config.restModel.PRIMARY_SHORT
@@ -1269,7 +1291,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1269
1291
  }
1270
1292
  query = this.request;
1271
1293
  apiRequest = function () { return tslib.__awaiter(_this, void 0, void 0, function () {
1272
- var _a, debug, _b, cacheResults, dataInsertMultipleRows, success, _c, fetchDependencies, _d, error, cachingConfirmed, cacheRequestData, evictFromCache, querySerialized, cachedRequest, cachedData, apiResponse, restRequestUri, needsConditionOrPrimaryCheck, TABLES, primaryKeyList, primaryKeyFullyQualified, primaryKey, whereVal, whereIsEmpty, providedPrimary, primaryVal, axiosActiveRequest_1;
1294
+ var _a, debug, _b, cacheResults, dataInsertMultipleRows, success, _c, fetchDependencies, _d, error, cachingConfirmed, cacheRequestData, cacheAllowListStatus, evictFromCache, querySerialized, cachedRequest, cachedData, apiResponse, restRequestUri, needsConditionOrPrimaryCheck, TABLES, primaryKeyList, primaryKeyFullyQualified, primaryKey, whereVal, whereIsEmpty, providedPrimary, primaryVal, axiosActiveRequest_1;
1273
1295
  var _e;
1274
1296
  var _this = this;
1275
1297
  var _f, _g, _h, _j, _k, _l;
@@ -1299,13 +1321,16 @@ var HttpExecutor = /** @class */ (function (_super) {
1299
1321
  query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
1300
1322
  }
1301
1323
  cacheRequestData = JSON.parse(JSON.stringify(query !== null && query !== void 0 ? query : {}));
1324
+ cacheAllowListStatus = this.config.sqlAllowListPath
1325
+ ? "allowed"
1326
+ : "not verified";
1302
1327
  evictFromCache = requestMethod === GET && cacheResults
1303
- ? function () { return evictCacheEntry(requestMethod, tableName, cacheRequestData); }
1328
+ ? function () { return evictCacheEntry(requestMethod, tableName, cacheRequestData, logContext, cacheAllowListStatus); }
1304
1329
  : undefined;
1305
1330
  querySerialized = sortAndSerializeQueryObject(tables, cacheRequestData !== null && cacheRequestData !== void 0 ? cacheRequestData : {});
1306
1331
  cachedRequest = false;
1307
1332
  if (cacheResults) {
1308
- cachedRequest = checkCache(requestMethod, tableName, cacheRequestData, logContext);
1333
+ cachedRequest = checkCache(requestMethod, tableName, cacheRequestData, logContext, cacheAllowListStatus);
1309
1334
  }
1310
1335
  if (!cachedRequest) return [3 /*break*/, 2];
1311
1336
  return [4 /*yield*/, cachedRequest];
@@ -1429,6 +1454,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1429
1454
  setCache(requestMethod, tableName, cacheRequestData, {
1430
1455
  requestArgumentsSerialized: querySerialized,
1431
1456
  request: axiosActiveRequest_1,
1457
+ allowListStatus: cacheAllowListStatus,
1432
1458
  });
1433
1459
  }
1434
1460
  // returning the promise with this then is important for tests. todo - we could make that optional.
@@ -1446,6 +1472,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1446
1472
  setCache(requestMethod, tableName, cacheRequestData, {
1447
1473
  requestArgumentsSerialized: querySerialized,
1448
1474
  request: axiosActiveRequest_1,
1475
+ allowListStatus: cacheAllowListStatus,
1449
1476
  response: response,
1450
1477
  final: true,
1451
1478
  });
@@ -1462,6 +1489,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1462
1489
  setCache(requestMethod, tableName, cacheRequestData, {
1463
1490
  requestArgumentsSerialized: querySerialized,
1464
1491
  request: axiosActiveRequest_1,
1492
+ allowListStatus: cacheAllowListStatus,
1465
1493
  response: response,
1466
1494
  });
1467
1495
  }
@@ -1526,6 +1554,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1526
1554
  setCache(requestMethod, tableName, cacheRequestData, {
1527
1555
  requestArgumentsSerialized: querySerialized,
1528
1556
  request: axiosActiveRequest_1,
1557
+ allowListStatus: cacheAllowListStatus,
1529
1558
  response: response,
1530
1559
  final: !hasNext,
1531
1560
  });
@@ -1725,6 +1754,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1725
1754
  setCache(requestMethod, tableName, cacheRequestData, {
1726
1755
  requestArgumentsSerialized: querySerialized,
1727
1756
  request: axiosActiveRequest_1,
1757
+ allowListStatus: cacheAllowListStatus,
1728
1758
  response: response,
1729
1759
  final: true,
1730
1760
  });
@@ -3673,6 +3703,38 @@ var compileSqlAllowList = function (allowListPath, entries) { return tslib.__awa
3673
3703
  }); };
3674
3704
 
3675
3705
  var SQL_ALLOWLIST_BLOCKED_CODE = "SQL_ALLOWLIST_BLOCKED";
3706
+ var fillRandomBytes = function (bytes) {
3707
+ var cryptoRef = globalThis.crypto;
3708
+ if (!cryptoRef || typeof cryptoRef.getRandomValues !== "function") {
3709
+ throw new Error("Secure random source unavailable: crypto.getRandomValues is required for UUID generation.");
3710
+ }
3711
+ cryptoRef.getRandomValues(bytes);
3712
+ };
3713
+ var generateUuidV7 = function () {
3714
+ var bytes = new Uint8Array(16);
3715
+ var random = new Uint8Array(10);
3716
+ fillRandomBytes(random);
3717
+ var timestampMs = Date.now();
3718
+ bytes[0] = Math.floor(timestampMs / 1099511627776) & 0xff; // 2^40
3719
+ bytes[1] = Math.floor(timestampMs / 4294967296) & 0xff; // 2^32
3720
+ bytes[2] = Math.floor(timestampMs / 16777216) & 0xff; // 2^24
3721
+ bytes[3] = Math.floor(timestampMs / 65536) & 0xff; // 2^16
3722
+ bytes[4] = Math.floor(timestampMs / 256) & 0xff; // 2^8
3723
+ bytes[5] = timestampMs & 0xff;
3724
+ // RFC 9562 UUIDv7 layout
3725
+ bytes[6] = 0x70 | (random[0] & 0x0f); // version 7 + rand_a high bits
3726
+ bytes[7] = random[1]; // rand_a low bits
3727
+ bytes[8] = 0x80 | (random[2] & 0x3f); // variant + rand_b high bits
3728
+ bytes[9] = random[3];
3729
+ bytes[10] = random[4];
3730
+ bytes[11] = random[5];
3731
+ bytes[12] = random[6];
3732
+ bytes[13] = random[7];
3733
+ bytes[14] = random[8];
3734
+ bytes[15] = random[9];
3735
+ var hex = Array.from(bytes, function (byte) { return byte.toString(16).padStart(2, "0"); }).join("");
3736
+ return "".concat(hex.slice(0, 8), "-").concat(hex.slice(8, 12), "-").concat(hex.slice(12, 16), "-").concat(hex.slice(16, 20), "-").concat(hex.slice(20));
3737
+ };
3676
3738
  var createSqlAllowListBlockedError = function (args) {
3677
3739
  var _a, _b;
3678
3740
  var error = new Error("SQL statement is not permitted by allowlist (".concat(args.allowListPath, ")."));
@@ -3701,6 +3763,146 @@ var SqlExecutor = /** @class */ (function (_super) {
3701
3763
  })); };
3702
3764
  return _this;
3703
3765
  }
3766
+ SqlExecutor.prototype.getPostRequestRows = function () {
3767
+ var request = this.request;
3768
+ if (!request)
3769
+ return [];
3770
+ if (Array.isArray(request)) {
3771
+ return request;
3772
+ }
3773
+ if (Array.isArray(request.dataInsertMultipleRows)
3774
+ && request.dataInsertMultipleRows.length > 0) {
3775
+ return request.dataInsertMultipleRows;
3776
+ }
3777
+ var verb = C6Constants.REPLACE in request ? C6Constants.REPLACE : C6Constants.INSERT;
3778
+ if (verb in request && request[verb] && typeof request[verb] === "object") {
3779
+ return [request[verb]];
3780
+ }
3781
+ if (typeof request === "object") {
3782
+ return [request];
3783
+ }
3784
+ return [];
3785
+ };
3786
+ SqlExecutor.prototype.getTypeValidationForColumn = function (shortKey, fullKey) {
3787
+ var _a, _b;
3788
+ var validation = (_a = this.config.restModel) === null || _a === void 0 ? void 0 : _a.TYPE_VALIDATION;
3789
+ if (!validation || typeof validation !== "object")
3790
+ return undefined;
3791
+ return (_b = validation[shortKey]) !== null && _b !== void 0 ? _b : validation[fullKey];
3792
+ };
3793
+ SqlExecutor.prototype.isUuidLikePrimaryColumn = function (columnDef) {
3794
+ var _a, _b;
3795
+ if (!columnDef || typeof columnDef !== "object")
3796
+ return false;
3797
+ if (columnDef.AUTO_INCREMENT === true)
3798
+ return false;
3799
+ var mysqlType = String((_a = columnDef.MYSQL_TYPE) !== null && _a !== void 0 ? _a : "").toLowerCase();
3800
+ var maxLength = String((_b = columnDef.MAX_LENGTH) !== null && _b !== void 0 ? _b : "").trim();
3801
+ if (mysqlType.includes("uuid"))
3802
+ return true;
3803
+ var isBinary16 = mysqlType.includes("binary")
3804
+ && (maxLength === "16" || /\b16\b/.test(mysqlType) || mysqlType === "binary");
3805
+ var isUuidString = (mysqlType.includes("char") || mysqlType.includes("varchar"))
3806
+ && (maxLength === "32" || maxLength === "36");
3807
+ return isBinary16 || isUuidString;
3808
+ };
3809
+ SqlExecutor.prototype.hasDefinedValue = function (value) {
3810
+ if (value === undefined || value === null)
3811
+ return false;
3812
+ if (typeof value === "string" && value.trim() === "")
3813
+ return false;
3814
+ return true;
3815
+ };
3816
+ SqlExecutor.prototype.generatePrimaryUuidValue = function (columnDef) {
3817
+ var _a, _b;
3818
+ var mysqlType = String((_a = columnDef.MYSQL_TYPE) !== null && _a !== void 0 ? _a : "").toLowerCase();
3819
+ var maxLength = String((_b = columnDef.MAX_LENGTH) !== null && _b !== void 0 ? _b : "").trim();
3820
+ var uuid = generateUuidV7();
3821
+ // BINARY(16) and CHAR/VARCHAR(32) commonly persist UUIDs as 32-hex.
3822
+ if (mysqlType.includes("binary") || maxLength === "32") {
3823
+ return uuid.replace(/-/g, "").toUpperCase();
3824
+ }
3825
+ return uuid;
3826
+ };
3827
+ SqlExecutor.prototype.assignMissingPostPrimaryUuids = function () {
3828
+ var _this = this;
3829
+ var _a, _b;
3830
+ if (this.config.requestMethod !== C6Constants.POST)
3831
+ return;
3832
+ var rows = this.getPostRequestRows();
3833
+ if (rows.length === 0)
3834
+ return;
3835
+ var columns = this.config.restModel.COLUMNS;
3836
+ var tableName = this.config.restModel.TABLE_NAME;
3837
+ var primaryShorts = (_a = this.config.restModel.PRIMARY_SHORT) !== null && _a !== void 0 ? _a : [];
3838
+ var primaryColumns = primaryShorts
3839
+ .map(function (shortKey) {
3840
+ var _a;
3841
+ var fullKey = (_a = Object.keys(columns).find(function (key) { return columns[key] === shortKey; })) !== null && _a !== void 0 ? _a : "".concat(tableName, ".").concat(shortKey);
3842
+ var columnDef = _this.getTypeValidationForColumn(shortKey, fullKey);
3843
+ return { shortKey: shortKey, fullKey: fullKey, columnDef: columnDef };
3844
+ })
3845
+ .filter(function (_a) {
3846
+ var columnDef = _a.columnDef;
3847
+ return _this.isUuidLikePrimaryColumn(columnDef);
3848
+ });
3849
+ if (primaryColumns.length === 0)
3850
+ return;
3851
+ for (var _i = 0, rows_1 = rows; _i < rows_1.length; _i++) {
3852
+ var row = rows_1[_i];
3853
+ if (!row || typeof row !== "object")
3854
+ continue;
3855
+ var useQualifiedKeyByDefault = Object.keys(row).some(function (key) { return key.includes("."); });
3856
+ for (var _c = 0, primaryColumns_1 = primaryColumns; _c < primaryColumns_1.length; _c++) {
3857
+ var primaryColumn = primaryColumns_1[_c];
3858
+ var existing = (_b = row[primaryColumn.shortKey]) !== null && _b !== void 0 ? _b : row[primaryColumn.fullKey];
3859
+ if (this.hasDefinedValue(existing))
3860
+ continue;
3861
+ var generated = this.generatePrimaryUuidValue(primaryColumn.columnDef);
3862
+ if (Object.prototype.hasOwnProperty.call(row, primaryColumn.shortKey)) {
3863
+ row[primaryColumn.shortKey] = generated;
3864
+ continue;
3865
+ }
3866
+ if (Object.prototype.hasOwnProperty.call(row, primaryColumn.fullKey)) {
3867
+ row[primaryColumn.fullKey] = generated;
3868
+ continue;
3869
+ }
3870
+ row[useQualifiedKeyByDefault ? primaryColumn.fullKey : primaryColumn.shortKey] = generated;
3871
+ }
3872
+ }
3873
+ };
3874
+ SqlExecutor.prototype.buildPostResponseRows = function (insertId) {
3875
+ var _this = this;
3876
+ var _a;
3877
+ var rows = this.getPostRequestRows();
3878
+ if (rows.length === 0)
3879
+ return [];
3880
+ var columns = this.config.restModel.COLUMNS;
3881
+ var validColumns = new Set(Object.values(columns));
3882
+ var pkShorts = (_a = this.config.restModel.PRIMARY_SHORT) !== null && _a !== void 0 ? _a : [];
3883
+ var now = new Date().toISOString();
3884
+ return rows.map(function (row, index) {
3885
+ var normalized = _this.normalizeRequestPayload(row !== null && row !== void 0 ? row : {});
3886
+ if (validColumns.has("changed_at") && normalized.changed_at === undefined) {
3887
+ normalized.changed_at = now;
3888
+ }
3889
+ if (validColumns.has("created_at") && normalized.created_at === undefined) {
3890
+ normalized.created_at = now;
3891
+ }
3892
+ if (validColumns.has("updated_at") && normalized.updated_at === undefined) {
3893
+ normalized.updated_at = now;
3894
+ }
3895
+ // When DB generated PK is numeric/autoincrement, expose it for the single-row insert.
3896
+ if (index === 0
3897
+ && insertId !== undefined
3898
+ && insertId !== null
3899
+ && pkShorts.length === 1
3900
+ && !_this.hasDefinedValue(normalized[pkShorts[0]])) {
3901
+ normalized[pkShorts[0]] = insertId;
3902
+ }
3903
+ return normalized;
3904
+ });
3905
+ };
3704
3906
  SqlExecutor.prototype.resolveSqlLogMethod = function (method, sql) {
3705
3907
  var _a;
3706
3908
  var token = (_a = sql.trim().split(/\s+/, 1)[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase();
@@ -3739,6 +3941,7 @@ var SqlExecutor = /** @class */ (function (_super) {
3739
3941
  // Surface normalization errors early
3740
3942
  throw e;
3741
3943
  }
3944
+ this.assignMissingPostPrimaryUuids();
3742
3945
  logContext = getLogContext(this.config, this.request);
3743
3946
  logWithLevel(exports.LogLevel.DEBUG, logContext, console.log, "[SQL EXECUTOR] \u25B6\uFE0F Executing ".concat(method, " on table \"").concat(TABLE_NAME, "\""));
3744
3947
  logWithLevel(exports.LogLevel.DEBUG, logContext, console.log, "[SQL EXECUTOR] \uD83E\uDDE9 Request:", this.request);
@@ -4088,7 +4291,7 @@ var SqlExecutor = /** @class */ (function (_super) {
4088
4291
  };
4089
4292
  SqlExecutor.prototype.runQuery = function () {
4090
4293
  return tslib.__awaiter(this, void 0, void 0, function () {
4091
- var method, tableName, logContext, cacheResults, cacheRequestData, requestArgumentsSerialized, evictFromCache, cachedRequest, cachedData, sqlExecution, sqlMethod, queryPromise, cacheRequest, cacheResponse;
4294
+ var method, tableName, logContext, cacheResults, cacheAllowListStatus, cacheRequestData, requestArgumentsSerialized, evictFromCache, cachedRequest, cachedData, sqlExecution, sqlMethod, queryPromise, cacheRequest, cacheResponse;
4092
4295
  var _this = this;
4093
4296
  var _a, _b;
4094
4297
  return tslib.__generator(this, function (_c) {
@@ -4099,6 +4302,9 @@ var SqlExecutor = /** @class */ (function (_super) {
4099
4302
  logContext = getLogContext(this.config, this.request);
4100
4303
  cacheResults = method === C6Constants.GET
4101
4304
  && ((_a = this.request.cacheResults) !== null && _a !== void 0 ? _a : true);
4305
+ cacheAllowListStatus = this.config.sqlAllowListPath
4306
+ ? "allowed"
4307
+ : "not verified";
4102
4308
  cacheRequestData = cacheResults
4103
4309
  ? JSON.parse(JSON.stringify((_b = this.request) !== null && _b !== void 0 ? _b : {}))
4104
4310
  : undefined;
@@ -4106,10 +4312,10 @@ var SqlExecutor = /** @class */ (function (_super) {
4106
4312
  ? sortAndSerializeQueryObject(tableName, cacheRequestData !== null && cacheRequestData !== void 0 ? cacheRequestData : {})
4107
4313
  : undefined;
4108
4314
  evictFromCache = method === C6Constants.GET && cacheResults && cacheRequestData
4109
- ? function () { return evictCacheEntry(method, tableName, cacheRequestData); }
4315
+ ? function () { return evictCacheEntry(method, tableName, cacheRequestData, logContext, cacheAllowListStatus); }
4110
4316
  : undefined;
4111
4317
  if (!cacheResults) return [3 /*break*/, 2];
4112
- cachedRequest = checkCache(method, tableName, cacheRequestData, logContext);
4318
+ cachedRequest = checkCache(method, tableName, cacheRequestData, logContext, cacheAllowListStatus);
4113
4319
  if (!cachedRequest) return [3 /*break*/, 2];
4114
4320
  return [4 /*yield*/, cachedRequest];
4115
4321
  case 1:
@@ -4145,6 +4351,7 @@ var SqlExecutor = /** @class */ (function (_super) {
4145
4351
  setCache(method, tableName, cacheRequestData, {
4146
4352
  requestArgumentsSerialized: requestArgumentsSerialized,
4147
4353
  request: cacheRequest,
4354
+ allowListStatus: cacheAllowListStatus,
4148
4355
  });
4149
4356
  return [4 /*yield*/, cacheRequest];
4150
4357
  case 5:
@@ -4152,6 +4359,7 @@ var SqlExecutor = /** @class */ (function (_super) {
4152
4359
  setCache(method, tableName, cacheRequestData, {
4153
4360
  requestArgumentsSerialized: requestArgumentsSerialized,
4154
4361
  request: cacheRequest,
4362
+ allowListStatus: cacheAllowListStatus,
4155
4363
  response: cacheResponse,
4156
4364
  final: true,
4157
4365
  });
@@ -4195,7 +4403,9 @@ var SqlExecutor = /** @class */ (function (_super) {
4195
4403
  return {
4196
4404
  affected: result.affectedRows,
4197
4405
  insertId: result.insertId,
4198
- rest: [],
4406
+ rest: method === C6Constants.POST
4407
+ ? this.buildPostResponseRows(result.insertId)
4408
+ : [],
4199
4409
  sql: { sql: sqlExecution.sql, values: sqlExecution.values },
4200
4410
  };
4201
4411
  };