@carbonorm/carbonnode 3.7.16 → 3.7.18
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/index.cjs.js +167 -174
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +168 -175
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/scripts/assets/handlebars/C6.test.ts.handlebars +27 -0
- package/src/__tests__/httpExecutorSingular.e2e.test.ts +81 -0
- package/src/__tests__/normalizeSingularRequest.test.ts +8 -8
- package/src/__tests__/sakila-db/C6.js +1 -1
- package/src/__tests__/sakila-db/C6.test.ts +27 -0
- package/src/__tests__/sakila-db/C6.ts +1 -1
- package/src/api/convertForRequestBody.ts +2 -2
- package/src/api/executors/HttpExecutor.ts +22 -42
- package/src/api/handlers/ExpressHandler.ts +10 -23
- package/src/api/utils/normalizeSingularRequest.ts +15 -4
package/dist/index.cjs.js
CHANGED
|
@@ -334,8 +334,8 @@ function convertForRequestBody (restfulObject, tableName, C6, regexErrorHandler)
|
|
|
334
334
|
}
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
|
-
else if (Object.
|
|
338
|
-
// Already a fully qualified column name
|
|
337
|
+
else if (Object.keys(tableDefinition.COLUMNS).includes(value)) {
|
|
338
|
+
// Already using a fully qualified column name
|
|
339
339
|
var columnValue = restfulObject[value];
|
|
340
340
|
payload[value] = columnValue;
|
|
341
341
|
var regexValidations = tableDefinition.REGEX_VALIDATION[value];
|
|
@@ -623,122 +623,6 @@ function sortAndSerializeQueryObject(tables, query) {
|
|
|
623
623
|
return tables + ' ' + JSON.stringify(orderedQuery);
|
|
624
624
|
}
|
|
625
625
|
|
|
626
|
-
/**
|
|
627
|
-
* Converts a singular T-shaped request into complex ORM format for GET/PUT/DELETE
|
|
628
|
-
* Enforces that all primary keys are present for singular syntax and that the table has PKs.
|
|
629
|
-
* Optionally accepts a previously removed primary key (key/value) to reconstruct WHERE.
|
|
630
|
-
*/
|
|
631
|
-
function normalizeSingularRequest(requestMethod, request, restModel, removedPrimary) {
|
|
632
|
-
var _a, _b;
|
|
633
|
-
var _c;
|
|
634
|
-
if (request == null || typeof request !== 'object')
|
|
635
|
-
return request;
|
|
636
|
-
var specialKeys = new Set([
|
|
637
|
-
C6Constants.SELECT,
|
|
638
|
-
C6Constants.UPDATE,
|
|
639
|
-
C6Constants.DELETE,
|
|
640
|
-
C6Constants.WHERE,
|
|
641
|
-
C6Constants.JOIN,
|
|
642
|
-
C6Constants.PAGINATION,
|
|
643
|
-
]);
|
|
644
|
-
// Determine if the request is already complex (has any special key besides PAGINATION)
|
|
645
|
-
var keys = Object.keys(request);
|
|
646
|
-
var hasComplexKeys = keys.some(function (k) { return k !== C6Constants.PAGINATION && specialKeys.has(k); });
|
|
647
|
-
if (hasComplexKeys)
|
|
648
|
-
return request; // already complex
|
|
649
|
-
// We treat it as singular when it's not complex.
|
|
650
|
-
// For GET, PUT, DELETE only
|
|
651
|
-
if (!(requestMethod === C6Constants.GET || requestMethod === C6Constants.PUT || requestMethod === C6Constants.DELETE)) {
|
|
652
|
-
return request;
|
|
653
|
-
}
|
|
654
|
-
var pkShorts = Array.isArray(restModel.PRIMARY_SHORT) ? tslib.__spreadArray([], restModel.PRIMARY_SHORT, true) : [];
|
|
655
|
-
var pkFulls = Array.isArray(restModel.PRIMARY) ? tslib.__spreadArray([], restModel.PRIMARY, true) : [];
|
|
656
|
-
var resolveShortKey = function (key) {
|
|
657
|
-
var _a;
|
|
658
|
-
var cols = restModel.COLUMNS || {};
|
|
659
|
-
return (_a = cols[key]) !== null && _a !== void 0 ? _a : key;
|
|
660
|
-
};
|
|
661
|
-
if (!pkShorts.length) {
|
|
662
|
-
// For GET requests, do not enforce primary key presence; treat as a collection query.
|
|
663
|
-
if (requestMethod === C6Constants.GET)
|
|
664
|
-
return request;
|
|
665
|
-
throw new Error("Table (".concat(restModel.TABLE_NAME, ") has no primary key; singular request syntax is not allowed."));
|
|
666
|
-
}
|
|
667
|
-
// Build pk map from request + possibly removed primary key (accept short or fully-qualified keys)
|
|
668
|
-
var pkValues = {};
|
|
669
|
-
var requestObj = request;
|
|
670
|
-
var _loop_1 = function (pkShort) {
|
|
671
|
-
// 1) direct short key
|
|
672
|
-
var value = requestObj[pkShort];
|
|
673
|
-
if (value === undefined) {
|
|
674
|
-
// 2) fully-qualified key matching this short key (from PRIMARY list or by concatenation)
|
|
675
|
-
var fqCandidate_1 = "".concat(restModel.TABLE_NAME, ".").concat(pkShort);
|
|
676
|
-
var fqKey = (_c = pkFulls.find(function (fq) { return fq === fqCandidate_1 || fq.endsWith(".".concat(pkShort)); })) !== null && _c !== void 0 ? _c : fqCandidate_1;
|
|
677
|
-
value = requestObj[fqKey];
|
|
678
|
-
}
|
|
679
|
-
if (value === undefined && removedPrimary) {
|
|
680
|
-
// 3) removedPrimary may provide either short or fully-qualified key
|
|
681
|
-
var removedKeyShort = resolveShortKey(removedPrimary.key);
|
|
682
|
-
if (removedKeyShort === pkShort)
|
|
683
|
-
value = removedPrimary.value;
|
|
684
|
-
}
|
|
685
|
-
if (value !== undefined && value !== null) {
|
|
686
|
-
pkValues[pkShort] = value;
|
|
687
|
-
}
|
|
688
|
-
};
|
|
689
|
-
for (var _i = 0, pkShorts_1 = pkShorts; _i < pkShorts_1.length; _i++) {
|
|
690
|
-
var pkShort = pkShorts_1[_i];
|
|
691
|
-
_loop_1(pkShort);
|
|
692
|
-
}
|
|
693
|
-
var missing = pkShorts.filter(function (pk) { return !(pk in pkValues); });
|
|
694
|
-
if (missing.length) {
|
|
695
|
-
// For GET requests, if not all PKs are provided, treat as a collection query and leave as-is.
|
|
696
|
-
if (requestMethod === C6Constants.GET) {
|
|
697
|
-
return request;
|
|
698
|
-
}
|
|
699
|
-
throw new Error("Singular request requires all primary key(s) [".concat(pkShorts.join(', '), "] for table (").concat(restModel.TABLE_NAME, "). Missing: [").concat(missing.join(', '), "]"));
|
|
700
|
-
}
|
|
701
|
-
// Strip API metadata that should remain at root
|
|
702
|
-
var _d = request, dataInsertMultipleRows = _d.dataInsertMultipleRows, cacheResults = _d.cacheResults, fetchDependencies = _d.fetchDependencies, debug = _d.debug, success = _d.success, error = _d.error, rest = tslib.__rest(_d, ["dataInsertMultipleRows", "cacheResults", "fetchDependencies", "debug", "success", "error"]);
|
|
703
|
-
if (requestMethod === C6Constants.GET) {
|
|
704
|
-
var normalized_1 = {
|
|
705
|
-
WHERE: tslib.__assign({}, pkValues),
|
|
706
|
-
};
|
|
707
|
-
// Preserve pagination if any was added previously
|
|
708
|
-
if (request[C6Constants.PAGINATION]) {
|
|
709
|
-
normalized_1[C6Constants.PAGINATION] = request[C6Constants.PAGINATION];
|
|
710
|
-
}
|
|
711
|
-
return tslib.__assign(tslib.__assign({}, normalized_1), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
712
|
-
}
|
|
713
|
-
if (requestMethod === C6Constants.DELETE) {
|
|
714
|
-
var normalized_2 = (_a = {},
|
|
715
|
-
_a[C6Constants.DELETE] = true,
|
|
716
|
-
_a.WHERE = tslib.__assign({}, pkValues),
|
|
717
|
-
_a);
|
|
718
|
-
return tslib.__assign(tslib.__assign({}, normalized_2), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
719
|
-
}
|
|
720
|
-
// PUT
|
|
721
|
-
var updateBody = {};
|
|
722
|
-
for (var _e = 0, _f = Object.keys(rest); _e < _f.length; _e++) {
|
|
723
|
-
var k = _f[_e];
|
|
724
|
-
// Skip special request keys if any slipped through
|
|
725
|
-
if (specialKeys.has(k))
|
|
726
|
-
continue;
|
|
727
|
-
var shortKey = resolveShortKey(k);
|
|
728
|
-
if (pkShorts.includes(shortKey))
|
|
729
|
-
continue; // don't update PK columns (short or fully qualified)
|
|
730
|
-
updateBody[shortKey] = rest[k];
|
|
731
|
-
}
|
|
732
|
-
if (Object.keys(updateBody).length === 0) {
|
|
733
|
-
throw new Error("Singular PUT request for table (".concat(restModel.TABLE_NAME, ") must include at least one non-primary field to update."));
|
|
734
|
-
}
|
|
735
|
-
var normalized = (_b = {},
|
|
736
|
-
_b[C6Constants.UPDATE] = updateBody,
|
|
737
|
-
_b.WHERE = tslib.__assign({}, pkValues),
|
|
738
|
-
_b);
|
|
739
|
-
return tslib.__assign(tslib.__assign({}, normalized), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
740
|
-
}
|
|
741
|
-
|
|
742
626
|
var HttpExecutor = /** @class */ (function (_super) {
|
|
743
627
|
tslib.__extends(HttpExecutor, _super);
|
|
744
628
|
function HttpExecutor() {
|
|
@@ -845,7 +729,7 @@ var HttpExecutor = /** @class */ (function (_super) {
|
|
|
845
729
|
query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
|
|
846
730
|
}
|
|
847
731
|
apiRequest = function () { return tslib.__awaiter(_this, void 0, void 0, function () {
|
|
848
|
-
var _a, debug, _b, cacheResults, dataInsertMultipleRows, success, _c, fetchDependencies, _d, error, querySerialized, cacheResult, cachingConfirmed, cacheCheck, cacheCheck,
|
|
732
|
+
var _a, debug, _b, cacheResults, dataInsertMultipleRows, success, _c, fetchDependencies, _d, error, querySerialized, cacheResult, cachingConfirmed, cacheCheck, cacheCheck, apiResponse, returnGetNextPageFunction, restRequestUri, needsConditionOrPrimaryCheck, TABLES, primaryKeyList, primaryKeyFullyQualified, primaryKey, providedPrimary, primaryVal, axiosActiveRequest;
|
|
849
733
|
var _e;
|
|
850
734
|
var _this = this;
|
|
851
735
|
var _f, _g, _h, _j, _k, _l;
|
|
@@ -926,7 +810,9 @@ var HttpExecutor = /** @class */ (function (_super) {
|
|
|
926
810
|
needsConditionOrPrimaryCheck = (PUT === requestMethod || DELETE === requestMethod)
|
|
927
811
|
&& false === skipPrimaryCheck;
|
|
928
812
|
TABLES = C6.TABLES;
|
|
929
|
-
|
|
813
|
+
primaryKeyList = structuredClone((_g = TABLES[operatingTable]) === null || _g === void 0 ? void 0 : _g.PRIMARY);
|
|
814
|
+
primaryKeyFullyQualified = primaryKeyList === null || primaryKeyList === void 0 ? void 0 : primaryKeyList.pop();
|
|
815
|
+
primaryKey = (_h = primaryKeyFullyQualified === null || primaryKeyFullyQualified === void 0 ? void 0 : primaryKeyFullyQualified.split('.')) === null || _h === void 0 ? void 0 : _h.pop();
|
|
930
816
|
if (needsConditionOrPrimaryCheck) {
|
|
931
817
|
if (undefined === primaryKey) {
|
|
932
818
|
if (null === query
|
|
@@ -936,20 +822,20 @@ var HttpExecutor = /** @class */ (function (_super) {
|
|
|
936
822
|
|| query[C6.WHERE].length === 0)
|
|
937
823
|
|| (Object.keys(query === null || query === void 0 ? void 0 : query[C6.WHERE]).length === 0)) {
|
|
938
824
|
console.error(query);
|
|
939
|
-
throw Error('Failed to parse primary key information. Query: (' + JSON.stringify(query) + ') Primary Key: (' + JSON.stringify(primaryKey) + ') TABLES[operatingTable]?.PRIMARY: (' + JSON.stringify((
|
|
825
|
+
throw Error('Failed to parse primary key information. Query: (' + JSON.stringify(query) + ') Primary Key: (' + JSON.stringify(primaryKey) + ') TABLES[operatingTable]?.PRIMARY: (' + JSON.stringify((_j = TABLES[operatingTable]) === null || _j === void 0 ? void 0 : _j.PRIMARY) + ') for operatingTable (' + operatingTable + ').');
|
|
940
826
|
}
|
|
941
827
|
}
|
|
942
828
|
else {
|
|
943
829
|
if (undefined === query
|
|
944
830
|
|| null === query
|
|
945
|
-
||
|
|
831
|
+
|| (!(primaryKey in query) && !(primaryKeyFullyQualified && primaryKeyFullyQualified in query))) {
|
|
946
832
|
if (true === debug && isLocal()) {
|
|
947
833
|
reactToastify.toast.error('DEVS: The primary key (' + primaryKey + ') was not provided!!');
|
|
948
834
|
}
|
|
949
835
|
throw Error('You must provide the primary key (' + primaryKey + ') for table (' + operatingTable + '). Request (' + JSON.stringify(this.request, undefined, 4) + ') Query (' + JSON.stringify(query) + ')');
|
|
950
836
|
}
|
|
951
|
-
|
|
952
|
-
|
|
837
|
+
providedPrimary = (_k = query === null || query === void 0 ? void 0 : query[primaryKey]) !== null && _k !== void 0 ? _k : (primaryKeyFullyQualified ? query === null || query === void 0 ? void 0 : query[primaryKeyFullyQualified] : undefined);
|
|
838
|
+
if (undefined === providedPrimary || null === providedPrimary) {
|
|
953
839
|
reactToastify.toast.error('The primary key (' + primaryKey + ') provided is undefined or null explicitly!!');
|
|
954
840
|
throw Error('The primary key (' + primaryKey + ') provided in the request was exactly equal to undefined.');
|
|
955
841
|
}
|
|
@@ -961,17 +847,15 @@ var HttpExecutor = /** @class */ (function (_super) {
|
|
|
961
847
|
if (POST !== requestMethod
|
|
962
848
|
&& undefined !== query
|
|
963
849
|
&& null !== query
|
|
964
|
-
&& undefined !== primaryKey
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
query
|
|
972
|
-
}
|
|
973
|
-
delete query[primaryKey];
|
|
974
|
-
console.log('query', query, 'primaryKey', primaryKey, 'removedPkValue', removedPkValue_1);
|
|
850
|
+
&& undefined !== primaryKey) {
|
|
851
|
+
primaryVal = (_l = query[primaryKey]) !== null && _l !== void 0 ? _l : (primaryKeyFullyQualified ? query[primaryKeyFullyQualified] : undefined);
|
|
852
|
+
if (undefined !== primaryVal) {
|
|
853
|
+
restRequestUri += primaryVal + '/';
|
|
854
|
+
console.log('query', query, 'primaryKey', primaryKey);
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
console.log('query', query);
|
|
858
|
+
}
|
|
975
859
|
}
|
|
976
860
|
else {
|
|
977
861
|
console.log('query', query);
|
|
@@ -994,11 +878,9 @@ var HttpExecutor = /** @class */ (function (_super) {
|
|
|
994
878
|
var baseConfig = {
|
|
995
879
|
withCredentials: withCredentials,
|
|
996
880
|
};
|
|
997
|
-
// Normalize singular request (GET/PUT/DELETE) into complex ORM shape
|
|
998
|
-
var normalizedQuery = normalizeSingularRequest(requestMethod, query, restModel, removedPrimaryKV);
|
|
999
881
|
switch (requestMethod) {
|
|
1000
882
|
case GET:
|
|
1001
|
-
return [tslib.__assign(tslib.__assign({}, baseConfig), { params:
|
|
883
|
+
return [tslib.__assign(tslib.__assign({}, baseConfig), { params: query })];
|
|
1002
884
|
case POST:
|
|
1003
885
|
if (dataInsertMultipleRows !== undefined) {
|
|
1004
886
|
return [
|
|
@@ -1008,9 +890,9 @@ var HttpExecutor = /** @class */ (function (_super) {
|
|
|
1008
890
|
}
|
|
1009
891
|
return [convert(query), baseConfig];
|
|
1010
892
|
case PUT:
|
|
1011
|
-
return [convert(
|
|
893
|
+
return [convert(query), baseConfig];
|
|
1012
894
|
case DELETE:
|
|
1013
|
-
return [tslib.__assign(tslib.__assign({}, baseConfig), { data: convert(
|
|
895
|
+
return [tslib.__assign(tslib.__assign({}, baseConfig), { data: convert(query) })];
|
|
1014
896
|
default:
|
|
1015
897
|
throw new Error("The request method (".concat(requestMethod, ") was not recognized."));
|
|
1016
898
|
}
|
|
@@ -1022,9 +904,6 @@ var HttpExecutor = /** @class */ (function (_super) {
|
|
|
1022
904
|
request: axiosActiveRequest
|
|
1023
905
|
});
|
|
1024
906
|
}
|
|
1025
|
-
// todo - wip verify this works
|
|
1026
|
-
// we had removed the value from the request to add to the URI.
|
|
1027
|
-
addBackPK === null || addBackPK === void 0 ? void 0 : addBackPK(); // adding back so post-processing methods work
|
|
1028
907
|
// returning the promise with this then is important for tests. todo - we could make that optional.
|
|
1029
908
|
// https://rapidapi.com/guides/axios-async-await
|
|
1030
909
|
return [2 /*return*/, axiosActiveRequest.then(function (response) { return tslib.__awaiter(_this, void 0, void 0, function () {
|
|
@@ -1881,6 +1760,133 @@ var UpdateQueryBuilder = /** @class */ (function (_super) {
|
|
|
1881
1760
|
return UpdateQueryBuilder;
|
|
1882
1761
|
}(PaginationBuilder));
|
|
1883
1762
|
|
|
1763
|
+
/**
|
|
1764
|
+
* Converts a singular T-shaped request into complex ORM format for GET/PUT/DELETE
|
|
1765
|
+
* Enforces that all primary keys are present for singular syntax and that the table has PKs.
|
|
1766
|
+
* Optionally accepts a previously removed primary key (key/value) to reconstruct WHERE.
|
|
1767
|
+
*/
|
|
1768
|
+
function normalizeSingularRequest(requestMethod, request, restModel, removedPrimary) {
|
|
1769
|
+
var _a, _b;
|
|
1770
|
+
var _c;
|
|
1771
|
+
if (request == null || typeof request !== 'object')
|
|
1772
|
+
return request;
|
|
1773
|
+
var specialKeys = new Set([
|
|
1774
|
+
C6Constants.SELECT,
|
|
1775
|
+
C6Constants.UPDATE,
|
|
1776
|
+
C6Constants.DELETE,
|
|
1777
|
+
C6Constants.WHERE,
|
|
1778
|
+
C6Constants.JOIN,
|
|
1779
|
+
C6Constants.PAGINATION,
|
|
1780
|
+
]);
|
|
1781
|
+
// Determine if the request is already complex (has any special key besides PAGINATION)
|
|
1782
|
+
var keys = Object.keys(request);
|
|
1783
|
+
var hasComplexKeys = keys.some(function (k) { return k !== C6Constants.PAGINATION && specialKeys.has(k); });
|
|
1784
|
+
if (hasComplexKeys)
|
|
1785
|
+
return request; // already complex
|
|
1786
|
+
// We treat it as singular when it's not complex.
|
|
1787
|
+
// For GET, PUT, DELETE only
|
|
1788
|
+
if (!(requestMethod === C6Constants.GET || requestMethod === C6Constants.PUT || requestMethod === C6Constants.DELETE)) {
|
|
1789
|
+
return request;
|
|
1790
|
+
}
|
|
1791
|
+
var pkShorts = Array.isArray(restModel.PRIMARY_SHORT) ? tslib.__spreadArray([], restModel.PRIMARY_SHORT, true) : [];
|
|
1792
|
+
var pkFulls = Array.isArray(restModel.PRIMARY) ? tslib.__spreadArray([], restModel.PRIMARY, true) : [];
|
|
1793
|
+
var resolveShortKey = function (key) {
|
|
1794
|
+
var _a;
|
|
1795
|
+
var cols = restModel.COLUMNS || {};
|
|
1796
|
+
return (_a = cols[key]) !== null && _a !== void 0 ? _a : key;
|
|
1797
|
+
};
|
|
1798
|
+
if (!pkShorts.length) {
|
|
1799
|
+
// For GET requests, do not enforce primary key presence; treat as a collection query.
|
|
1800
|
+
if (requestMethod === C6Constants.GET)
|
|
1801
|
+
return request;
|
|
1802
|
+
throw new Error("Table (".concat(restModel.TABLE_NAME, ") has no primary key; singular request syntax is not allowed."));
|
|
1803
|
+
}
|
|
1804
|
+
// Build pk map from request + possibly removed primary key (accept short or fully-qualified keys)
|
|
1805
|
+
var pkValues = {};
|
|
1806
|
+
var requestObj = request;
|
|
1807
|
+
var _loop_1 = function (pkShort) {
|
|
1808
|
+
// 1) direct short key
|
|
1809
|
+
var value = requestObj[pkShort];
|
|
1810
|
+
if (value === undefined) {
|
|
1811
|
+
// 2) fully-qualified key matching this short key (from PRIMARY list or by concatenation)
|
|
1812
|
+
var fqCandidate_1 = "".concat(restModel.TABLE_NAME, ".").concat(pkShort);
|
|
1813
|
+
var fqKey = (_c = pkFulls.find(function (fq) { return fq === fqCandidate_1 || fq.endsWith(".".concat(pkShort)); })) !== null && _c !== void 0 ? _c : fqCandidate_1;
|
|
1814
|
+
value = requestObj[fqKey];
|
|
1815
|
+
}
|
|
1816
|
+
if (value === undefined && removedPrimary) {
|
|
1817
|
+
// 3) removedPrimary may provide either short or fully-qualified key
|
|
1818
|
+
var removedKeyShort = resolveShortKey(removedPrimary.key);
|
|
1819
|
+
if (removedKeyShort === pkShort)
|
|
1820
|
+
value = removedPrimary.value;
|
|
1821
|
+
}
|
|
1822
|
+
if (value !== undefined && value !== null) {
|
|
1823
|
+
pkValues[pkShort] = value;
|
|
1824
|
+
}
|
|
1825
|
+
};
|
|
1826
|
+
for (var _i = 0, pkShorts_1 = pkShorts; _i < pkShorts_1.length; _i++) {
|
|
1827
|
+
var pkShort = pkShorts_1[_i];
|
|
1828
|
+
_loop_1(pkShort);
|
|
1829
|
+
}
|
|
1830
|
+
var missing = pkShorts.filter(function (pk) { return !(pk in pkValues); });
|
|
1831
|
+
if (missing.length) {
|
|
1832
|
+
// For GET requests, if not all PKs are provided, treat as a collection query and leave as-is.
|
|
1833
|
+
if (requestMethod === C6Constants.GET) {
|
|
1834
|
+
return request;
|
|
1835
|
+
}
|
|
1836
|
+
throw new Error("Singular request requires all primary key(s) [".concat(pkShorts.join(', '), "] for table (").concat(restModel.TABLE_NAME, "). Missing: [").concat(missing.join(', '), "]"));
|
|
1837
|
+
}
|
|
1838
|
+
// Strip API metadata that should remain at root
|
|
1839
|
+
var _d = request, dataInsertMultipleRows = _d.dataInsertMultipleRows, cacheResults = _d.cacheResults, fetchDependencies = _d.fetchDependencies, debug = _d.debug, success = _d.success, error = _d.error, rest = tslib.__rest(_d, ["dataInsertMultipleRows", "cacheResults", "fetchDependencies", "debug", "success", "error"]);
|
|
1840
|
+
// Map short primary keys to fully-qualified column names
|
|
1841
|
+
var shortToFull = {};
|
|
1842
|
+
for (var _e = 0, _f = Object.entries(restModel.COLUMNS || {}); _e < _f.length; _e++) {
|
|
1843
|
+
var _g = _f[_e], full = _g[0], short = _g[1];
|
|
1844
|
+
shortToFull[short] = full;
|
|
1845
|
+
}
|
|
1846
|
+
var pkFullValues = Object.fromEntries(Object.entries(pkValues).map(function (_a) {
|
|
1847
|
+
var _b;
|
|
1848
|
+
var k = _a[0], v = _a[1];
|
|
1849
|
+
return [(_b = shortToFull[k]) !== null && _b !== void 0 ? _b : k, v];
|
|
1850
|
+
}));
|
|
1851
|
+
if (requestMethod === C6Constants.GET) {
|
|
1852
|
+
var normalized_1 = {
|
|
1853
|
+
WHERE: tslib.__assign({}, pkFullValues),
|
|
1854
|
+
};
|
|
1855
|
+
// Preserve pagination if any was added previously
|
|
1856
|
+
if (request[C6Constants.PAGINATION]) {
|
|
1857
|
+
normalized_1[C6Constants.PAGINATION] = request[C6Constants.PAGINATION];
|
|
1858
|
+
}
|
|
1859
|
+
return tslib.__assign(tslib.__assign({}, normalized_1), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
1860
|
+
}
|
|
1861
|
+
if (requestMethod === C6Constants.DELETE) {
|
|
1862
|
+
var normalized_2 = (_a = {},
|
|
1863
|
+
_a[C6Constants.DELETE] = true,
|
|
1864
|
+
_a.WHERE = tslib.__assign({}, pkFullValues),
|
|
1865
|
+
_a);
|
|
1866
|
+
return tslib.__assign(tslib.__assign({}, normalized_2), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
1867
|
+
}
|
|
1868
|
+
// PUT
|
|
1869
|
+
var updateBody = {};
|
|
1870
|
+
for (var _h = 0, _j = Object.keys(rest); _h < _j.length; _h++) {
|
|
1871
|
+
var k = _j[_h];
|
|
1872
|
+
// Skip special request keys if any slipped through
|
|
1873
|
+
if (specialKeys.has(k))
|
|
1874
|
+
continue;
|
|
1875
|
+
var shortKey = resolveShortKey(k);
|
|
1876
|
+
if (pkShorts.includes(shortKey))
|
|
1877
|
+
continue; // don't update PK columns (short or fully qualified)
|
|
1878
|
+
updateBody[shortKey] = rest[k];
|
|
1879
|
+
}
|
|
1880
|
+
if (Object.keys(updateBody).length === 0) {
|
|
1881
|
+
throw new Error("Singular PUT request for table (".concat(restModel.TABLE_NAME, ") must include at least one non-primary field to update."));
|
|
1882
|
+
}
|
|
1883
|
+
var normalized = (_b = {},
|
|
1884
|
+
_b[C6Constants.UPDATE] = updateBody,
|
|
1885
|
+
_b.WHERE = tslib.__assign({}, pkFullValues),
|
|
1886
|
+
_b);
|
|
1887
|
+
return tslib.__assign(tslib.__assign({}, normalized), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1884
1890
|
var SqlExecutor = /** @class */ (function (_super) {
|
|
1885
1891
|
tslib.__extends(SqlExecutor, _super);
|
|
1886
1892
|
function SqlExecutor() {
|
|
@@ -2068,12 +2074,12 @@ function ExpressHandler(_a) {
|
|
|
2068
2074
|
var _this = this;
|
|
2069
2075
|
var C6 = _a.C6, mysqlPool = _a.mysqlPool;
|
|
2070
2076
|
return function (req, res, next) { return tslib.__awaiter(_this, void 0, void 0, function () {
|
|
2071
|
-
var method, table, primary, payload, primaryKeys, primaryKeyName,
|
|
2072
|
-
var _a, _b
|
|
2073
|
-
return tslib.__generator(this, function (
|
|
2074
|
-
switch (
|
|
2077
|
+
var method, table, primary, payload, primaryKeys, primaryKeyName, response, err_1;
|
|
2078
|
+
var _a, _b;
|
|
2079
|
+
return tslib.__generator(this, function (_c) {
|
|
2080
|
+
switch (_c.label) {
|
|
2075
2081
|
case 0:
|
|
2076
|
-
|
|
2082
|
+
_c.trys.push([0, 2, , 3]);
|
|
2077
2083
|
method = req.method.toUpperCase();
|
|
2078
2084
|
table = req.params.table;
|
|
2079
2085
|
primary = req.params.primary;
|
|
@@ -2094,30 +2100,17 @@ function ExpressHandler(_a) {
|
|
|
2094
2100
|
return [2 /*return*/];
|
|
2095
2101
|
}
|
|
2096
2102
|
primaryKeyName = primaryKeys[0];
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
case 'DELETE':
|
|
2109
|
-
if (primary) {
|
|
2110
|
-
payload[C6C.WHERE][primaryKeyName] = primary;
|
|
2111
|
-
}
|
|
2112
|
-
else {
|
|
2113
|
-
res.status(400).json({ error: "Invalid request: ".concat(method, " requires a primary key (").concat(primaryKeyName, ").") });
|
|
2114
|
-
}
|
|
2115
|
-
break;
|
|
2116
|
-
case 'POST':
|
|
2117
|
-
break;
|
|
2118
|
-
default:
|
|
2119
|
-
res.status(405).json({ error: "Method ".concat(method, " not allowed") });
|
|
2120
|
-
return [2 /*return*/];
|
|
2103
|
+
// If a primary key was provided in the URL, merge it into the payload.
|
|
2104
|
+
// Support both complex requests using WHERE and singular requests
|
|
2105
|
+
// where the primary key lives at the root of the payload.
|
|
2106
|
+
if (primary) {
|
|
2107
|
+
if (payload[C6C.WHERE]) {
|
|
2108
|
+
payload[C6C.WHERE][primaryKeyName] =
|
|
2109
|
+
(_a = payload[C6C.WHERE][primaryKeyName]) !== null && _a !== void 0 ? _a : primary;
|
|
2110
|
+
}
|
|
2111
|
+
else {
|
|
2112
|
+
payload[primaryKeyName] =
|
|
2113
|
+
(_b = payload[primaryKeyName]) !== null && _b !== void 0 ? _b : primary;
|
|
2121
2114
|
}
|
|
2122
2115
|
}
|
|
2123
2116
|
return [4 /*yield*/, restRequest({
|
|
@@ -2127,11 +2120,11 @@ function ExpressHandler(_a) {
|
|
|
2127
2120
|
restModel: C6.TABLES[table]
|
|
2128
2121
|
})(payload)];
|
|
2129
2122
|
case 1:
|
|
2130
|
-
response =
|
|
2123
|
+
response = _c.sent();
|
|
2131
2124
|
res.status(200).json(tslib.__assign({ success: true }, response));
|
|
2132
2125
|
return [3 /*break*/, 3];
|
|
2133
2126
|
case 2:
|
|
2134
|
-
err_1 =
|
|
2127
|
+
err_1 = _c.sent();
|
|
2135
2128
|
res.status(500).json({ success: false, error: err_1 });
|
|
2136
2129
|
next(err_1);
|
|
2137
2130
|
return [3 /*break*/, 3];
|