@carbonorm/carbonnode 3.7.11 → 3.7.13
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 +119 -100
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +120 -101
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/normalizeSingularRequest.test.ts +30 -0
- package/src/__tests__/sakila-db/C6.js +1 -1
- package/src/__tests__/sakila-db/C6.ts +1 -1
- package/src/api/executors/HttpExecutor.ts +2 -10
- package/src/api/utils/normalizeSingularRequest.ts +25 -11
package/dist/index.cjs.js
CHANGED
|
@@ -593,102 +593,6 @@ function removeInvalidKeys(request, c6Tables) {
|
|
|
593
593
|
return intersection;
|
|
594
594
|
}
|
|
595
595
|
|
|
596
|
-
/**
|
|
597
|
-
* Converts a singular T-shaped request into complex ORM format for GET/PUT/DELETE
|
|
598
|
-
* Enforces that all primary keys are present for singular syntax and that the table has PKs.
|
|
599
|
-
* Optionally accepts a previously removed primary key (key/value) to reconstruct WHERE.
|
|
600
|
-
*/
|
|
601
|
-
function normalizeSingularRequest(requestMethod, request, restModel, removedPrimary) {
|
|
602
|
-
var _a, _b;
|
|
603
|
-
if (request == null || typeof request !== 'object')
|
|
604
|
-
return request;
|
|
605
|
-
var specialKeys = new Set([
|
|
606
|
-
C6Constants.SELECT,
|
|
607
|
-
C6Constants.UPDATE,
|
|
608
|
-
C6Constants.DELETE,
|
|
609
|
-
C6Constants.WHERE,
|
|
610
|
-
C6Constants.JOIN,
|
|
611
|
-
C6Constants.PAGINATION,
|
|
612
|
-
]);
|
|
613
|
-
// Determine if the request is already complex (has any special key besides PAGINATION)
|
|
614
|
-
var keys = Object.keys(request);
|
|
615
|
-
var hasComplexKeys = keys.some(function (k) { return k !== C6Constants.PAGINATION && specialKeys.has(k); });
|
|
616
|
-
if (hasComplexKeys)
|
|
617
|
-
return request; // already complex
|
|
618
|
-
// We treat it as singular when it's not complex.
|
|
619
|
-
// For GET, PUT, DELETE only
|
|
620
|
-
if (!(requestMethod === C6Constants.GET || requestMethod === C6Constants.PUT || requestMethod === C6Constants.DELETE)) {
|
|
621
|
-
return request;
|
|
622
|
-
}
|
|
623
|
-
var pkShorts = Array.isArray(restModel.PRIMARY_SHORT) ? tslib.__spreadArray([], restModel.PRIMARY_SHORT, true) : [];
|
|
624
|
-
if (!pkShorts.length) {
|
|
625
|
-
// For GET requests, do not enforce primary key presence; treat as a collection query.
|
|
626
|
-
if (requestMethod === C6Constants.GET)
|
|
627
|
-
return request;
|
|
628
|
-
throw new Error("Table (".concat(restModel.TABLE_NAME, ") has no primary key; singular request syntax is not allowed."));
|
|
629
|
-
}
|
|
630
|
-
// Build pk map from request + possibly removed primary key
|
|
631
|
-
var pkValues = {};
|
|
632
|
-
for (var _i = 0, pkShorts_1 = pkShorts; _i < pkShorts_1.length; _i++) {
|
|
633
|
-
var pk = pkShorts_1[_i];
|
|
634
|
-
var fromRequest = request[pk];
|
|
635
|
-
if (fromRequest !== undefined && fromRequest !== null) {
|
|
636
|
-
pkValues[pk] = fromRequest;
|
|
637
|
-
continue;
|
|
638
|
-
}
|
|
639
|
-
if (removedPrimary && removedPrimary.key === pk) {
|
|
640
|
-
pkValues[pk] = removedPrimary.value;
|
|
641
|
-
continue;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
var missing = pkShorts.filter(function (pk) { return !(pk in pkValues); });
|
|
645
|
-
if (missing.length) {
|
|
646
|
-
// For GET requests, if not all PKs are provided, treat as a collection query and leave as-is.
|
|
647
|
-
if (requestMethod === C6Constants.GET) {
|
|
648
|
-
return request;
|
|
649
|
-
}
|
|
650
|
-
throw new Error("Singular request requires all primary key(s) [".concat(pkShorts.join(', '), "] for table (").concat(restModel.TABLE_NAME, "). Missing: [").concat(missing.join(', '), "]"));
|
|
651
|
-
}
|
|
652
|
-
// Strip API metadata that should remain at root
|
|
653
|
-
var _c = request, dataInsertMultipleRows = _c.dataInsertMultipleRows, cacheResults = _c.cacheResults, fetchDependencies = _c.fetchDependencies, debug = _c.debug, success = _c.success, error = _c.error, rest = tslib.__rest(_c, ["dataInsertMultipleRows", "cacheResults", "fetchDependencies", "debug", "success", "error"]);
|
|
654
|
-
if (requestMethod === C6Constants.GET) {
|
|
655
|
-
var normalized_1 = {
|
|
656
|
-
WHERE: tslib.__assign({}, pkValues),
|
|
657
|
-
};
|
|
658
|
-
// Preserve pagination if any was added previously
|
|
659
|
-
if (request[C6Constants.PAGINATION]) {
|
|
660
|
-
normalized_1[C6Constants.PAGINATION] = request[C6Constants.PAGINATION];
|
|
661
|
-
}
|
|
662
|
-
return tslib.__assign(tslib.__assign({}, normalized_1), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
663
|
-
}
|
|
664
|
-
if (requestMethod === C6Constants.DELETE) {
|
|
665
|
-
var normalized_2 = (_a = {},
|
|
666
|
-
_a[C6Constants.DELETE] = true,
|
|
667
|
-
_a.WHERE = tslib.__assign({}, pkValues),
|
|
668
|
-
_a);
|
|
669
|
-
return tslib.__assign(tslib.__assign({}, normalized_2), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
670
|
-
}
|
|
671
|
-
// PUT
|
|
672
|
-
var updateBody = {};
|
|
673
|
-
for (var _d = 0, _e = Object.keys(rest); _d < _e.length; _d++) {
|
|
674
|
-
var k = _e[_d];
|
|
675
|
-
if (pkShorts.includes(k))
|
|
676
|
-
continue; // don't update PK columns
|
|
677
|
-
// Skip special request keys if any slipped through
|
|
678
|
-
if (specialKeys.has(k))
|
|
679
|
-
continue;
|
|
680
|
-
updateBody[k] = rest[k];
|
|
681
|
-
}
|
|
682
|
-
if (Object.keys(updateBody).length === 0) {
|
|
683
|
-
throw new Error("Singular PUT request for table (".concat(restModel.TABLE_NAME, ") must include at least one non-primary field to update."));
|
|
684
|
-
}
|
|
685
|
-
var normalized = (_b = {},
|
|
686
|
-
_b[C6Constants.UPDATE] = updateBody,
|
|
687
|
-
_b.WHERE = tslib.__assign({}, pkValues),
|
|
688
|
-
_b);
|
|
689
|
-
return tslib.__assign(tslib.__assign({}, normalized), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
690
|
-
}
|
|
691
|
-
|
|
692
596
|
// do not remove entries from this array. It is used to track the progress of API requests.
|
|
693
597
|
// position in array is important. Do not sort. To not add to begging.
|
|
694
598
|
exports.apiRequestCache = [];
|
|
@@ -826,7 +730,7 @@ var HttpExecutor = /** @class */ (function (_super) {
|
|
|
826
730
|
query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
|
|
827
731
|
}
|
|
828
732
|
apiRequest = function () { return tslib.__awaiter(_this, void 0, void 0, function () {
|
|
829
|
-
var _a, debug, _b, cacheResults, dataInsertMultipleRows, success, _c, fetchDependencies, _d, error, querySerialized, cacheResult, cachingConfirmed, cacheCheck, cacheCheck, addBackPK,
|
|
733
|
+
var _a, debug, _b, cacheResults, dataInsertMultipleRows, success, _c, fetchDependencies, _d, error, querySerialized, cacheResult, cachingConfirmed, cacheCheck, cacheCheck, addBackPK, apiResponse, returnGetNextPageFunction, restRequestUri, needsConditionOrPrimaryCheck, TABLES, primaryKey, removedPkValue_1, axiosActiveRequest;
|
|
830
734
|
var _e;
|
|
831
735
|
var _this = this;
|
|
832
736
|
var _f, _g, _h, _j, _k, _l;
|
|
@@ -946,7 +850,6 @@ var HttpExecutor = /** @class */ (function (_super) {
|
|
|
946
850
|
&& primaryKey in query) {
|
|
947
851
|
restRequestUri += query[primaryKey] + '/';
|
|
948
852
|
removedPkValue_1 = query[primaryKey];
|
|
949
|
-
removedPrimaryKV = { key: primaryKey, value: removedPkValue_1 };
|
|
950
853
|
addBackPK = function () {
|
|
951
854
|
query !== null && query !== void 0 ? query : (query = {});
|
|
952
855
|
query[primaryKey] = removedPkValue_1;
|
|
@@ -975,8 +878,8 @@ var HttpExecutor = /** @class */ (function (_super) {
|
|
|
975
878
|
var baseConfig = {
|
|
976
879
|
withCredentials: withCredentials,
|
|
977
880
|
};
|
|
978
|
-
//
|
|
979
|
-
var normalizedQuery =
|
|
881
|
+
// Pass-through request; singular normalization occurs on the backend (SqlExecutor)
|
|
882
|
+
var normalizedQuery = query;
|
|
980
883
|
switch (requestMethod) {
|
|
981
884
|
case GET:
|
|
982
885
|
return [tslib.__assign(tslib.__assign({}, baseConfig), { params: normalizedQuery })];
|
|
@@ -1862,6 +1765,122 @@ var UpdateQueryBuilder = /** @class */ (function (_super) {
|
|
|
1862
1765
|
return UpdateQueryBuilder;
|
|
1863
1766
|
}(PaginationBuilder));
|
|
1864
1767
|
|
|
1768
|
+
/**
|
|
1769
|
+
* Converts a singular T-shaped request into complex ORM format for GET/PUT/DELETE
|
|
1770
|
+
* Enforces that all primary keys are present for singular syntax and that the table has PKs.
|
|
1771
|
+
* Optionally accepts a previously removed primary key (key/value) to reconstruct WHERE.
|
|
1772
|
+
*/
|
|
1773
|
+
function normalizeSingularRequest(requestMethod, request, restModel, removedPrimary) {
|
|
1774
|
+
var _a, _b;
|
|
1775
|
+
var _c;
|
|
1776
|
+
if (request == null || typeof request !== 'object')
|
|
1777
|
+
return request;
|
|
1778
|
+
var specialKeys = new Set([
|
|
1779
|
+
C6Constants.SELECT,
|
|
1780
|
+
C6Constants.UPDATE,
|
|
1781
|
+
C6Constants.DELETE,
|
|
1782
|
+
C6Constants.WHERE,
|
|
1783
|
+
C6Constants.JOIN,
|
|
1784
|
+
C6Constants.PAGINATION,
|
|
1785
|
+
]);
|
|
1786
|
+
// Determine if the request is already complex (has any special key besides PAGINATION)
|
|
1787
|
+
var keys = Object.keys(request);
|
|
1788
|
+
var hasComplexKeys = keys.some(function (k) { return k !== C6Constants.PAGINATION && specialKeys.has(k); });
|
|
1789
|
+
if (hasComplexKeys)
|
|
1790
|
+
return request; // already complex
|
|
1791
|
+
// We treat it as singular when it's not complex.
|
|
1792
|
+
// For GET, PUT, DELETE only
|
|
1793
|
+
if (!(requestMethod === C6Constants.GET || requestMethod === C6Constants.PUT || requestMethod === C6Constants.DELETE)) {
|
|
1794
|
+
return request;
|
|
1795
|
+
}
|
|
1796
|
+
var pkShorts = Array.isArray(restModel.PRIMARY_SHORT) ? tslib.__spreadArray([], restModel.PRIMARY_SHORT, true) : [];
|
|
1797
|
+
var pkFulls = Array.isArray(restModel.PRIMARY) ? tslib.__spreadArray([], restModel.PRIMARY, true) : [];
|
|
1798
|
+
var resolveShortKey = function (key) {
|
|
1799
|
+
var _a;
|
|
1800
|
+
var cols = restModel.COLUMNS || {};
|
|
1801
|
+
return (_a = cols[key]) !== null && _a !== void 0 ? _a : key;
|
|
1802
|
+
};
|
|
1803
|
+
if (!pkShorts.length) {
|
|
1804
|
+
// For GET requests, do not enforce primary key presence; treat as a collection query.
|
|
1805
|
+
if (requestMethod === C6Constants.GET)
|
|
1806
|
+
return request;
|
|
1807
|
+
throw new Error("Table (".concat(restModel.TABLE_NAME, ") has no primary key; singular request syntax is not allowed."));
|
|
1808
|
+
}
|
|
1809
|
+
// Build pk map from request + possibly removed primary key (accept short or fully-qualified keys)
|
|
1810
|
+
var pkValues = {};
|
|
1811
|
+
var requestObj = request;
|
|
1812
|
+
var _loop_1 = function (pkShort) {
|
|
1813
|
+
// 1) direct short key
|
|
1814
|
+
var value = requestObj[pkShort];
|
|
1815
|
+
if (value === undefined) {
|
|
1816
|
+
// 2) fully-qualified key matching this short key (from PRIMARY list or by concatenation)
|
|
1817
|
+
var fqCandidate_1 = "".concat(restModel.TABLE_NAME, ".").concat(pkShort);
|
|
1818
|
+
var fqKey = (_c = pkFulls.find(function (fq) { return fq === fqCandidate_1 || fq.endsWith(".".concat(pkShort)); })) !== null && _c !== void 0 ? _c : fqCandidate_1;
|
|
1819
|
+
value = requestObj[fqKey];
|
|
1820
|
+
}
|
|
1821
|
+
if (value === undefined && removedPrimary) {
|
|
1822
|
+
// 3) removedPrimary may provide either short or fully-qualified key
|
|
1823
|
+
var removedKeyShort = resolveShortKey(removedPrimary.key);
|
|
1824
|
+
if (removedKeyShort === pkShort)
|
|
1825
|
+
value = removedPrimary.value;
|
|
1826
|
+
}
|
|
1827
|
+
if (value !== undefined && value !== null) {
|
|
1828
|
+
pkValues[pkShort] = value;
|
|
1829
|
+
}
|
|
1830
|
+
};
|
|
1831
|
+
for (var _i = 0, pkShorts_1 = pkShorts; _i < pkShorts_1.length; _i++) {
|
|
1832
|
+
var pkShort = pkShorts_1[_i];
|
|
1833
|
+
_loop_1(pkShort);
|
|
1834
|
+
}
|
|
1835
|
+
var missing = pkShorts.filter(function (pk) { return !(pk in pkValues); });
|
|
1836
|
+
if (missing.length) {
|
|
1837
|
+
// For GET requests, if not all PKs are provided, treat as a collection query and leave as-is.
|
|
1838
|
+
if (requestMethod === C6Constants.GET) {
|
|
1839
|
+
return request;
|
|
1840
|
+
}
|
|
1841
|
+
throw new Error("Singular request requires all primary key(s) [".concat(pkShorts.join(', '), "] for table (").concat(restModel.TABLE_NAME, "). Missing: [").concat(missing.join(', '), "]"));
|
|
1842
|
+
}
|
|
1843
|
+
// Strip API metadata that should remain at root
|
|
1844
|
+
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"]);
|
|
1845
|
+
if (requestMethod === C6Constants.GET) {
|
|
1846
|
+
var normalized_1 = {
|
|
1847
|
+
WHERE: tslib.__assign({}, pkValues),
|
|
1848
|
+
};
|
|
1849
|
+
// Preserve pagination if any was added previously
|
|
1850
|
+
if (request[C6Constants.PAGINATION]) {
|
|
1851
|
+
normalized_1[C6Constants.PAGINATION] = request[C6Constants.PAGINATION];
|
|
1852
|
+
}
|
|
1853
|
+
return tslib.__assign(tslib.__assign({}, normalized_1), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
1854
|
+
}
|
|
1855
|
+
if (requestMethod === C6Constants.DELETE) {
|
|
1856
|
+
var normalized_2 = (_a = {},
|
|
1857
|
+
_a[C6Constants.DELETE] = true,
|
|
1858
|
+
_a.WHERE = tslib.__assign({}, pkValues),
|
|
1859
|
+
_a);
|
|
1860
|
+
return tslib.__assign(tslib.__assign({}, normalized_2), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
1861
|
+
}
|
|
1862
|
+
// PUT
|
|
1863
|
+
var updateBody = {};
|
|
1864
|
+
for (var _e = 0, _f = Object.keys(rest); _e < _f.length; _e++) {
|
|
1865
|
+
var k = _f[_e];
|
|
1866
|
+
// Skip special request keys if any slipped through
|
|
1867
|
+
if (specialKeys.has(k))
|
|
1868
|
+
continue;
|
|
1869
|
+
var shortKey = resolveShortKey(k);
|
|
1870
|
+
if (pkShorts.includes(shortKey))
|
|
1871
|
+
continue; // don't update PK columns (short or fully qualified)
|
|
1872
|
+
updateBody[shortKey] = rest[k];
|
|
1873
|
+
}
|
|
1874
|
+
if (Object.keys(updateBody).length === 0) {
|
|
1875
|
+
throw new Error("Singular PUT request for table (".concat(restModel.TABLE_NAME, ") must include at least one non-primary field to update."));
|
|
1876
|
+
}
|
|
1877
|
+
var normalized = (_b = {},
|
|
1878
|
+
_b[C6Constants.UPDATE] = updateBody,
|
|
1879
|
+
_b.WHERE = tslib.__assign({}, pkValues),
|
|
1880
|
+
_b);
|
|
1881
|
+
return tslib.__assign(tslib.__assign({}, normalized), { dataInsertMultipleRows: dataInsertMultipleRows, cacheResults: cacheResults, fetchDependencies: fetchDependencies, debug: debug, success: success, error: error });
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1865
1884
|
var SqlExecutor = /** @class */ (function (_super) {
|
|
1866
1885
|
tslib.__extends(SqlExecutor, _super);
|
|
1867
1886
|
function SqlExecutor() {
|