@carbonorm/carbonnode 4.0.1 → 5.0.0
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/README.md +158 -49
- package/dist/api/executors/SqlExecutor.d.ts +6 -0
- package/dist/api/handlers/ExpressHandler.d.ts +2 -1
- package/dist/api/types/ormInterfaces.d.ts +12 -0
- package/dist/api/utils/sqlAllowList.d.ts +2 -0
- package/dist/index.cjs.js +247 -10
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +246 -11
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/scripts/assets/handlebars/C6.test.ts.handlebars +578 -32
- package/scripts/generateRestBindings.cjs +5 -5
- package/scripts/generateRestBindings.ts +5 -5
- package/src/__tests__/fixtures/createTestServer.ts +11 -3
- package/src/__tests__/fixtures/sqlResponses/actor.get.json +13 -0
- package/src/__tests__/fixtures/sqlResponses/sqlAllowList.blocked.json +3 -0
- package/src/__tests__/fixtures/sqlResponses/sqlAllowList.json +3 -0
- package/src/__tests__/sakila-db/C6.js +1 -1
- package/src/__tests__/sakila-db/C6.mysql.cnf +6 -0
- package/src/__tests__/sakila-db/C6.mysqldump.json +1 -0
- package/src/__tests__/sakila-db/C6.mysqldump.sql +720 -0
- package/src/__tests__/sakila-db/C6.sqlAllowList.json +94 -0
- package/src/__tests__/sakila-db/C6.test.ts +578 -32
- package/src/__tests__/sakila-db/C6.ts +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.get.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.join.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +12 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +16 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.seed.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.fk.current.json +358 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.fk.referenced.json +158 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.get.json +22 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +16 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +22 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.seed.json +22 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.get.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.join.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.seed.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.fk.current.json +158 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.fk.referenced.json +133 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.get.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.join.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +12 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +16 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.seed.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.get.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.join.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.seed.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.fk.current.json +283 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.fk.referenced.json +358 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.get.json +19 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.join.json +29 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +19 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +21 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.seed.json +19 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.fk.current.json +383 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.fk.referenced.json +38 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.get.json +23 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +20 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +23 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +25 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.seed.json +23 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.fk.current.json +158 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.fk.referenced.json +20 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.get.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.join.json +25 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +12 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +16 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.seed.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.get.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.seed.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.fk.current.json +233 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.fk.referenced.json +233 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.get.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +19 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.seed.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.fk.current.json +233 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.fk.referenced.json +34 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.get.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +19 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.seed.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.staff.fk.current.json +34 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.staff.fk.referenced.json +20 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.staff.get.json +21 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.staff.join.json +31 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.staff.seed.json +21 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.store.fk.current.json +20 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.store.fk.referenced.json +34 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.store.get.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.store.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.store.seed.json +14 -0
- package/src/__tests__/sakila.generated.test.ts +31 -0
- package/src/__tests__/sqlAllowList.test.ts +135 -0
- package/src/api/executors/SqlExecutor.ts +156 -0
- package/src/api/handlers/ExpressHandler.ts +10 -1
- package/src/api/types/ormInterfaces.ts +15 -0
- package/src/api/utils/sqlAllowList.ts +54 -0
- package/src/index.ts +1 -0
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ export * from "./api/utils/determineRuntimeJsType";
|
|
|
36
36
|
export * from "./api/utils/logger";
|
|
37
37
|
export * from "./api/utils/normalizeSingularRequest";
|
|
38
38
|
export * from "./api/utils/sortAndSerializeQueryObject";
|
|
39
|
+
export * from "./api/utils/sqlAllowList";
|
|
39
40
|
export * from "./api/utils/testHelpers";
|
|
40
41
|
export * from "./api/utils/toastNotifier";
|
|
41
42
|
export * from "./variables/getEnvVar";
|
package/dist/index.esm.js
CHANGED
|
@@ -2960,6 +2960,63 @@ function normalizeSingularRequest(requestMethod, request, restModel, removedPrim
|
|
|
2960
2960
|
return __assign(__assign({}, normalized), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
2961
2961
|
}
|
|
2962
2962
|
|
|
2963
|
+
var allowListCache = new Map();
|
|
2964
|
+
var normalizeSql = function (sql) {
|
|
2965
|
+
return sql.replace(/\s+/g, " ").trim();
|
|
2966
|
+
};
|
|
2967
|
+
var parseAllowList = function (raw, sourcePath) {
|
|
2968
|
+
var parsed;
|
|
2969
|
+
try {
|
|
2970
|
+
parsed = JSON.parse(raw);
|
|
2971
|
+
}
|
|
2972
|
+
catch (error) {
|
|
2973
|
+
throw new Error("SQL allowlist at ".concat(sourcePath, " is not valid JSON."));
|
|
2974
|
+
}
|
|
2975
|
+
if (!Array.isArray(parsed)) {
|
|
2976
|
+
throw new Error("SQL allowlist at ".concat(sourcePath, " must be a JSON array of strings."));
|
|
2977
|
+
}
|
|
2978
|
+
var sqlEntries = parsed
|
|
2979
|
+
.filter(function (entry) { return typeof entry === "string"; })
|
|
2980
|
+
.map(normalizeSql)
|
|
2981
|
+
.filter(function (entry) { return entry.length > 0; });
|
|
2982
|
+
if (sqlEntries.length !== parsed.length) {
|
|
2983
|
+
throw new Error("SQL allowlist at ".concat(sourcePath, " must contain only string entries."));
|
|
2984
|
+
}
|
|
2985
|
+
return sqlEntries;
|
|
2986
|
+
};
|
|
2987
|
+
var loadSqlAllowList = function (allowListPath) { return __awaiter(void 0, void 0, void 0, function () {
|
|
2988
|
+
var readFile, raw, sqlEntries, allowList;
|
|
2989
|
+
return __generator(this, function (_a) {
|
|
2990
|
+
switch (_a.label) {
|
|
2991
|
+
case 0:
|
|
2992
|
+
if (allowListCache.has(allowListPath)) {
|
|
2993
|
+
return [2 /*return*/, allowListCache.get(allowListPath)];
|
|
2994
|
+
}
|
|
2995
|
+
if (!isNode()) {
|
|
2996
|
+
throw new Error("SQL allowlist validation requires a Node runtime.");
|
|
2997
|
+
}
|
|
2998
|
+
return [4 /*yield*/, import('node:fs/promises')];
|
|
2999
|
+
case 1:
|
|
3000
|
+
readFile = (_a.sent()).readFile;
|
|
3001
|
+
_a.label = 2;
|
|
3002
|
+
case 2:
|
|
3003
|
+
_a.trys.push([2, 4, , 5]);
|
|
3004
|
+
return [4 /*yield*/, readFile(allowListPath, "utf-8")];
|
|
3005
|
+
case 3:
|
|
3006
|
+
raw = _a.sent();
|
|
3007
|
+
return [3 /*break*/, 5];
|
|
3008
|
+
case 4:
|
|
3009
|
+
_a.sent();
|
|
3010
|
+
throw new Error("SQL allowlist file not found at ".concat(allowListPath, "."));
|
|
3011
|
+
case 5:
|
|
3012
|
+
sqlEntries = parseAllowList(raw, allowListPath);
|
|
3013
|
+
allowList = new Set(sqlEntries);
|
|
3014
|
+
allowListCache.set(allowListPath, allowList);
|
|
3015
|
+
return [2 /*return*/, allowList];
|
|
3016
|
+
}
|
|
3017
|
+
});
|
|
3018
|
+
}); };
|
|
3019
|
+
|
|
2963
3020
|
var SqlExecutor = /** @class */ (function (_super) {
|
|
2964
3021
|
__extends(SqlExecutor, _super);
|
|
2965
3022
|
function SqlExecutor() {
|
|
@@ -2992,10 +3049,10 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
2992
3049
|
switch (_a) {
|
|
2993
3050
|
case 'GET': return [3 /*break*/, 1];
|
|
2994
3051
|
case 'POST': return [3 /*break*/, 3];
|
|
2995
|
-
case 'PUT': return [3 /*break*/,
|
|
2996
|
-
case 'DELETE': return [3 /*break*/,
|
|
3052
|
+
case 'PUT': return [3 /*break*/, 6];
|
|
3053
|
+
case 'DELETE': return [3 /*break*/, 9];
|
|
2997
3054
|
}
|
|
2998
|
-
return [3 /*break*/,
|
|
3055
|
+
return [3 /*break*/, 12];
|
|
2999
3056
|
case 1: return [4 /*yield*/, this.runQuery()];
|
|
3000
3057
|
case 2:
|
|
3001
3058
|
rest = _b.sent();
|
|
@@ -3003,16 +3060,25 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
3003
3060
|
case 3: return [4 /*yield*/, this.runQuery()];
|
|
3004
3061
|
case 4:
|
|
3005
3062
|
result = _b.sent();
|
|
3063
|
+
return [4 /*yield*/, this.broadcastWebsocketIfConfigured()];
|
|
3064
|
+
case 5:
|
|
3065
|
+
_b.sent();
|
|
3006
3066
|
return [2 /*return*/, result];
|
|
3007
|
-
case
|
|
3008
|
-
case
|
|
3067
|
+
case 6: return [4 /*yield*/, this.runQuery()];
|
|
3068
|
+
case 7:
|
|
3009
3069
|
result = _b.sent();
|
|
3010
|
-
return [
|
|
3011
|
-
case 7: return [4 /*yield*/, this.runQuery()];
|
|
3070
|
+
return [4 /*yield*/, this.broadcastWebsocketIfConfigured()];
|
|
3012
3071
|
case 8:
|
|
3072
|
+
_b.sent();
|
|
3073
|
+
return [2 /*return*/, result];
|
|
3074
|
+
case 9: return [4 /*yield*/, this.runQuery()];
|
|
3075
|
+
case 10:
|
|
3013
3076
|
result = _b.sent();
|
|
3077
|
+
return [4 /*yield*/, this.broadcastWebsocketIfConfigured()];
|
|
3078
|
+
case 11:
|
|
3079
|
+
_b.sent();
|
|
3014
3080
|
return [2 /*return*/, result];
|
|
3015
|
-
case
|
|
3081
|
+
case 12: throw new Error("Unsupported request method: ".concat(method));
|
|
3016
3082
|
}
|
|
3017
3083
|
});
|
|
3018
3084
|
});
|
|
@@ -3073,6 +3139,149 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
3073
3139
|
return "'".concat(val.toISOString().slice(0, 19).replace('T', ' '), "'");
|
|
3074
3140
|
return "'".concat(JSON.stringify(val), "'");
|
|
3075
3141
|
};
|
|
3142
|
+
SqlExecutor.prototype.stripRequestMetadata = function (source) {
|
|
3143
|
+
var ignoredKeys = new Set([
|
|
3144
|
+
C6Constants.SELECT,
|
|
3145
|
+
C6Constants.UPDATE,
|
|
3146
|
+
C6Constants.DELETE,
|
|
3147
|
+
C6Constants.WHERE,
|
|
3148
|
+
C6Constants.JOIN,
|
|
3149
|
+
C6Constants.PAGINATION,
|
|
3150
|
+
C6Constants.INSERT,
|
|
3151
|
+
C6Constants.REPLACE,
|
|
3152
|
+
"dataInsertMultipleRows",
|
|
3153
|
+
"cacheResults",
|
|
3154
|
+
"fetchDependencies",
|
|
3155
|
+
"debug",
|
|
3156
|
+
"success",
|
|
3157
|
+
"error",
|
|
3158
|
+
]);
|
|
3159
|
+
var filtered = {};
|
|
3160
|
+
for (var _i = 0, _a = Object.entries(source); _i < _a.length; _i++) {
|
|
3161
|
+
var _b = _a[_i], key = _b[0], value = _b[1];
|
|
3162
|
+
if (!ignoredKeys.has(key)) {
|
|
3163
|
+
filtered[key] = value;
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
return filtered;
|
|
3167
|
+
};
|
|
3168
|
+
SqlExecutor.prototype.normalizeRequestPayload = function (source) {
|
|
3169
|
+
var _a;
|
|
3170
|
+
var columns = this.config.restModel.COLUMNS;
|
|
3171
|
+
var validColumns = new Set(Object.values(columns));
|
|
3172
|
+
var normalized = {};
|
|
3173
|
+
for (var _i = 0, _b = Object.entries(source); _i < _b.length; _i++) {
|
|
3174
|
+
var _c = _b[_i], key = _c[0], value = _c[1];
|
|
3175
|
+
var shortKey = (_a = columns[key]) !== null && _a !== void 0 ? _a : (key.includes(".") ? key.split(".").pop() : key);
|
|
3176
|
+
if (validColumns.has(shortKey)) {
|
|
3177
|
+
normalized[shortKey] = value;
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
return normalized;
|
|
3181
|
+
};
|
|
3182
|
+
SqlExecutor.prototype.extractRequestBody = function () {
|
|
3183
|
+
var _a, _b;
|
|
3184
|
+
var request = this.request;
|
|
3185
|
+
if (this.config.requestMethod === C6Constants.POST) {
|
|
3186
|
+
if (Array.isArray(request.dataInsertMultipleRows) && request.dataInsertMultipleRows.length > 0) {
|
|
3187
|
+
return request.dataInsertMultipleRows[0];
|
|
3188
|
+
}
|
|
3189
|
+
if (C6Constants.INSERT in request) {
|
|
3190
|
+
return (_a = request[C6Constants.INSERT]) !== null && _a !== void 0 ? _a : {};
|
|
3191
|
+
}
|
|
3192
|
+
if (C6Constants.REPLACE in request) {
|
|
3193
|
+
return (_b = request[C6Constants.REPLACE]) !== null && _b !== void 0 ? _b : {};
|
|
3194
|
+
}
|
|
3195
|
+
return this.stripRequestMetadata(request);
|
|
3196
|
+
}
|
|
3197
|
+
if (this.config.requestMethod === C6Constants.PUT) {
|
|
3198
|
+
if (request[C6Constants.UPDATE] && typeof request[C6Constants.UPDATE] === "object") {
|
|
3199
|
+
return request[C6Constants.UPDATE];
|
|
3200
|
+
}
|
|
3201
|
+
return this.stripRequestMetadata(request);
|
|
3202
|
+
}
|
|
3203
|
+
return {};
|
|
3204
|
+
};
|
|
3205
|
+
SqlExecutor.prototype.extractPrimaryKeyValues = function () {
|
|
3206
|
+
var _a, _b, _c;
|
|
3207
|
+
var request = this.request;
|
|
3208
|
+
var where = request === null || request === void 0 ? void 0 : request[C6Constants.WHERE];
|
|
3209
|
+
var sources = [request, (where && typeof where === "object" && !Array.isArray(where)) ? where : undefined];
|
|
3210
|
+
var columns = this.config.restModel.COLUMNS;
|
|
3211
|
+
var primaryShorts = (_a = this.config.restModel.PRIMARY_SHORT) !== null && _a !== void 0 ? _a : [];
|
|
3212
|
+
var primaryFulls = (_b = this.config.restModel.PRIMARY) !== null && _b !== void 0 ? _b : [];
|
|
3213
|
+
var pkValues = {};
|
|
3214
|
+
var _loop_1 = function (pkShort) {
|
|
3215
|
+
var value = undefined;
|
|
3216
|
+
for (var _d = 0, sources_1 = sources; _d < sources_1.length; _d++) {
|
|
3217
|
+
var source = sources_1[_d];
|
|
3218
|
+
if (source && pkShort in source) {
|
|
3219
|
+
value = source[pkShort];
|
|
3220
|
+
break;
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
if (value === undefined) {
|
|
3224
|
+
var fullKey = (_c = primaryFulls.find(function (key) { return key.endsWith("." + pkShort); })) !== null && _c !== void 0 ? _c : Object.keys(columns).find(function (key) { return columns[key] === pkShort; });
|
|
3225
|
+
if (fullKey) {
|
|
3226
|
+
for (var _e = 0, sources_2 = sources; _e < sources_2.length; _e++) {
|
|
3227
|
+
var source = sources_2[_e];
|
|
3228
|
+
if (source && fullKey in source) {
|
|
3229
|
+
value = source[fullKey];
|
|
3230
|
+
break;
|
|
3231
|
+
}
|
|
3232
|
+
}
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
if (value !== undefined) {
|
|
3236
|
+
pkValues[pkShort] = value;
|
|
3237
|
+
}
|
|
3238
|
+
};
|
|
3239
|
+
for (var _i = 0, primaryShorts_1 = primaryShorts; _i < primaryShorts_1.length; _i++) {
|
|
3240
|
+
var pkShort = primaryShorts_1[_i];
|
|
3241
|
+
_loop_1(pkShort);
|
|
3242
|
+
}
|
|
3243
|
+
if (primaryShorts.length > 0 && Object.keys(pkValues).length < primaryShorts.length) {
|
|
3244
|
+
return null;
|
|
3245
|
+
}
|
|
3246
|
+
return Object.keys(pkValues).length > 0 ? pkValues : null;
|
|
3247
|
+
};
|
|
3248
|
+
SqlExecutor.prototype.broadcastWebsocketIfConfigured = function () {
|
|
3249
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3250
|
+
var broadcast, payload, error_1;
|
|
3251
|
+
var _a, _b;
|
|
3252
|
+
return __generator(this, function (_c) {
|
|
3253
|
+
switch (_c.label) {
|
|
3254
|
+
case 0:
|
|
3255
|
+
broadcast = this.config.websocketBroadcast;
|
|
3256
|
+
if (!broadcast || this.config.requestMethod === C6Constants.GET)
|
|
3257
|
+
return [2 /*return*/];
|
|
3258
|
+
payload = {
|
|
3259
|
+
REST: {
|
|
3260
|
+
TABLE_NAME: this.config.restModel.TABLE_NAME,
|
|
3261
|
+
TABLE_PREFIX: (_b = (_a = this.config.C6) === null || _a === void 0 ? void 0 : _a.PREFIX) !== null && _b !== void 0 ? _b : "",
|
|
3262
|
+
METHOD: this.config.requestMethod,
|
|
3263
|
+
REQUEST: this.normalizeRequestPayload(this.extractRequestBody()),
|
|
3264
|
+
REQUEST_PRIMARY_KEY: this.extractPrimaryKeyValues(),
|
|
3265
|
+
},
|
|
3266
|
+
};
|
|
3267
|
+
_c.label = 1;
|
|
3268
|
+
case 1:
|
|
3269
|
+
_c.trys.push([1, 3, , 4]);
|
|
3270
|
+
return [4 /*yield*/, broadcast(payload)];
|
|
3271
|
+
case 2:
|
|
3272
|
+
_c.sent();
|
|
3273
|
+
return [3 /*break*/, 4];
|
|
3274
|
+
case 3:
|
|
3275
|
+
error_1 = _c.sent();
|
|
3276
|
+
if (this.config.verbose) {
|
|
3277
|
+
console.error("[SQL EXECUTOR] websocketBroadcast failed", error_1);
|
|
3278
|
+
}
|
|
3279
|
+
return [3 /*break*/, 4];
|
|
3280
|
+
case 4: return [2 /*return*/];
|
|
3281
|
+
}
|
|
3282
|
+
});
|
|
3283
|
+
});
|
|
3284
|
+
};
|
|
3076
3285
|
SqlExecutor.prototype.runQuery = function () {
|
|
3077
3286
|
return __awaiter(this, void 0, void 0, function () {
|
|
3078
3287
|
var TABLE_NAME, method, builder, QueryResult, formatted, toUnnamed, _a, sql, values;
|
|
@@ -3104,6 +3313,9 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
3104
3313
|
this.config.verbose && console.log("[SQL EXECUTOR] \uD83E\uDDE0 Formatted ".concat(method.toUpperCase(), " SQL:"), formatted);
|
|
3105
3314
|
toUnnamed = namedPlaceholders();
|
|
3106
3315
|
_a = toUnnamed(QueryResult.sql, QueryResult.params), sql = _a[0], values = _a[1];
|
|
3316
|
+
return [4 /*yield*/, this.validateSqlAllowList(sql)];
|
|
3317
|
+
case 1:
|
|
3318
|
+
_b.sent();
|
|
3107
3319
|
return [4 /*yield*/, this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () {
|
|
3108
3320
|
var result;
|
|
3109
3321
|
return __generator(this, function (_a) {
|
|
@@ -3128,7 +3340,29 @@ var SqlExecutor = /** @class */ (function (_super) {
|
|
|
3128
3340
|
}
|
|
3129
3341
|
});
|
|
3130
3342
|
}); })];
|
|
3131
|
-
case
|
|
3343
|
+
case 2: return [2 /*return*/, _b.sent()];
|
|
3344
|
+
}
|
|
3345
|
+
});
|
|
3346
|
+
});
|
|
3347
|
+
};
|
|
3348
|
+
SqlExecutor.prototype.validateSqlAllowList = function (sql) {
|
|
3349
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3350
|
+
var allowListPath, allowList, normalized;
|
|
3351
|
+
return __generator(this, function (_a) {
|
|
3352
|
+
switch (_a.label) {
|
|
3353
|
+
case 0:
|
|
3354
|
+
allowListPath = this.config.sqlAllowListPath;
|
|
3355
|
+
if (!allowListPath) {
|
|
3356
|
+
return [2 /*return*/];
|
|
3357
|
+
}
|
|
3358
|
+
return [4 /*yield*/, loadSqlAllowList(allowListPath)];
|
|
3359
|
+
case 1:
|
|
3360
|
+
allowList = _a.sent();
|
|
3361
|
+
normalized = normalizeSql(sql);
|
|
3362
|
+
if (!allowList.has(normalized)) {
|
|
3363
|
+
throw new Error("SQL statement is not permitted by allowlist (".concat(allowListPath, ")."));
|
|
3364
|
+
}
|
|
3365
|
+
return [2 /*return*/];
|
|
3132
3366
|
}
|
|
3133
3367
|
});
|
|
3134
3368
|
});
|
|
@@ -3145,7 +3379,7 @@ var SqlExecutor$1 = /*#__PURE__*/Object.freeze({
|
|
|
3145
3379
|
// note sure how it would help anyone actually...
|
|
3146
3380
|
function ExpressHandler(_a) {
|
|
3147
3381
|
var _this = this;
|
|
3148
|
-
var C6 = _a.C6, mysqlPool = _a.mysqlPool;
|
|
3382
|
+
var C6 = _a.C6, mysqlPool = _a.mysqlPool, sqlAllowListPath = _a.sqlAllowListPath;
|
|
3149
3383
|
return function (req, res, next) { return __awaiter(_this, void 0, void 0, function () {
|
|
3150
3384
|
var incomingMethod, table, primary, methodOverrideRaw, methodOverride, treatAsGet, method, payload, restModel, primaryKeys_1, primaryShortKeys_1, columnMap_1, resolveShortKey_1, hasPrimaryKeyValues, primaryKeyName, response, err_1;
|
|
3151
3385
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
@@ -3231,6 +3465,7 @@ function ExpressHandler(_a) {
|
|
|
3231
3465
|
return [4 /*yield*/, restRequest({
|
|
3232
3466
|
C6: C6,
|
|
3233
3467
|
mysqlPool: mysqlPool,
|
|
3468
|
+
sqlAllowListPath: sqlAllowListPath,
|
|
3234
3469
|
requestMethod: method,
|
|
3235
3470
|
restModel: C6.TABLES[table]
|
|
3236
3471
|
})(payload)];
|
|
@@ -3349,5 +3584,5 @@ function isVerbose () {
|
|
|
3349
3584
|
return ['true', '1', 'yes', 'on'].includes(envVerbose.toLowerCase());
|
|
3350
3585
|
}
|
|
3351
3586
|
|
|
3352
|
-
export { A, AggregateBuilder, C6C, C6Constants, ConditionBuilder, DELETE, DeleteQueryBuilder, Executor, ExpressHandler, F, GET, HttpExecutor, JoinBuilder, POST, PUT, PaginationBuilder, PostQueryBuilder, SelectQueryBuilder, SqlExecutor, TestRestfulResponse, UpdateQueryBuilder, apiRequestCache, axiosInstance, bbox, carbonNodeQsStringify, checkAllRequestsComplete, checkCache, clearCache, convertForRequestBody, convertHexIfBinary, derivedTable, determineRuntimeJsType, distSphere, eFetchDependencies, error, fieldEq, getEnvVar, getPrimaryKeyTypes, group, info, isDerivedTableKey, isLocal, isNode, isTest, isVerbose, normalizeSingularRequest, onError, onSuccess, removeInvalidKeys, removePrefixIfExists, resolveDerivedTable, restOrm, restRequest, setCache, sortAndSerializeQueryObject, stContains, timeout, toastOptions, toastOptionsDevs, userCustomClearCache, warn };
|
|
3587
|
+
export { A, AggregateBuilder, C6C, C6Constants, ConditionBuilder, DELETE, DeleteQueryBuilder, Executor, ExpressHandler, F, GET, HttpExecutor, JoinBuilder, POST, PUT, PaginationBuilder, PostQueryBuilder, SelectQueryBuilder, SqlExecutor, TestRestfulResponse, UpdateQueryBuilder, apiRequestCache, axiosInstance, bbox, carbonNodeQsStringify, checkAllRequestsComplete, checkCache, clearCache, convertForRequestBody, convertHexIfBinary, derivedTable, determineRuntimeJsType, distSphere, eFetchDependencies, error, fieldEq, getEnvVar, getPrimaryKeyTypes, group, info, isDerivedTableKey, isLocal, isNode, isTest, isVerbose, loadSqlAllowList, normalizeSingularRequest, normalizeSql, onError, onSuccess, removeInvalidKeys, removePrefixIfExists, resolveDerivedTable, restOrm, restRequest, setCache, sortAndSerializeQueryObject, stContains, timeout, toastOptions, toastOptionsDevs, userCustomClearCache, warn };
|
|
3353
3588
|
//# sourceMappingURL=index.esm.js.map
|