@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.
- package/dist/executors/SqlExecutor.d.ts +7 -0
- package/dist/index.cjs.js +230 -20
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +230 -20
- package/dist/index.esm.js.map +1 -1
- package/dist/types/ormInterfaces.d.ts +1 -0
- package/dist/utils/cacheManager.d.ts +3 -2
- package/dist/utils/logSql.d.ts +1 -1
- package/package.json +1 -1
- package/src/__tests__/cacheManager.test.ts +55 -1
- package/src/__tests__/logSql.test.ts +16 -0
- package/src/__tests__/sakila-db/C6.js +1 -1
- package/src/__tests__/sakila-db/C6.mysqldump.json +1 -1
- package/src/__tests__/sakila-db/C6.mysqldump.sql +1 -1
- package/src/__tests__/sakila-db/C6.ts +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +11 -4
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +18 -6
- package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +9 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +10 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +9 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +18 -6
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +5 -5
- package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +18 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +9 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +9 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +13 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +2 -2
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +14 -4
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +3 -3
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +3 -3
- package/src/__tests__/sqlExecutorPostUuid.test.ts +185 -0
- package/src/executors/HttpExecutor.ts +33 -5
- package/src/executors/SqlExecutor.ts +207 -3
- package/src/types/ormInterfaces.ts +1 -0
- package/src/utils/cacheManager.ts +22 -5
- 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.
|
|
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
|
-
|
|
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
|
-
|
|
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 */
|
|
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
|
-
(
|
|
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), (
|
|
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)), (
|
|
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
|
};
|