@carbonorm/carbonnode 3.7.23 → 3.8.1

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.
@@ -1,2 +1 @@
1
- declare const _default: import("axios").AxiosInstance;
2
- export default _default;
1
+ export declare const carbonNodeQsStringify: (params: any) => string;
@@ -3,6 +3,7 @@ import { OrmGenerics } from "../types/ormGenerics";
3
3
  import { DetermineResponseDataType, RequestQueryBody } from "../types/ormInterfaces";
4
4
  import { Executor } from "./Executor";
5
5
  export declare class HttpExecutor<G extends OrmGenerics> extends Executor<G> {
6
+ private isRestResponse;
6
7
  private stripTableNameFromKeys;
7
8
  putState(response: AxiosResponse<DetermineResponseDataType<G['RequestMethod'], G['RestTableInterface']>>, request: RequestQueryBody<G['RequestMethod'], G['RestTableInterface'], G['CustomAndRequiredFields'], G['RequestTableOverrides']>, callback: () => void): void;
8
9
  postState(response: AxiosResponse<DetermineResponseDataType<G['RequestMethod'], G['RestTableInterface']>>, request: RequestQueryBody<G['RequestMethod'], G['RestTableInterface'], G['CustomAndRequiredFields'], G['RequestTableOverrides']>, callback: () => void): void;
package/dist/index.cjs.js CHANGED
@@ -170,6 +170,14 @@ var C6Constants = {
170
170
  var C6C = C6Constants;
171
171
 
172
172
  // @link https://www.npmjs.com/package/axios-cache-adapter
173
+ var carbonNodeQsStringify = function (params) {
174
+ return Qs.stringify(params, {
175
+ arrayFormat: "indices",
176
+ indices: true,
177
+ skipNulls: false,
178
+ strictNullHandling: true,
179
+ });
180
+ };
173
181
  // updating these values
174
182
  // @link https://github.com/axios/axios/issues/209
175
183
  //
@@ -178,7 +186,7 @@ var C6C = C6Constants;
178
186
  //
179
187
  // immediately affects this instance
180
188
  // axiosInstance.defaults.headers['Auth-Token'] = 'foo bar';
181
- var axiosInstance = (axios.create({
189
+ var carbonAxiosInstance = (axios.create({
182
190
  // `baseURL` will be prepended to `url` unless `url` is absolute.
183
191
  // It can be convenient to set `baseURL` for an instance of axios to pass relative URLs
184
192
  // to methods of that instance.
@@ -200,7 +208,7 @@ var axiosInstance = (axios.create({
200
208
  // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
201
209
  paramsSerializer: function (params) {
202
210
  // Nested get params [][][,,,] do not serialize correctly without Qs
203
- return Qs.stringify(params, { arrayFormat: 'indices', indices: true, skipNulls: false, strictNullHandling: true });
211
+ return carbonNodeQsStringify(params);
204
212
  },
205
213
  // `data` is the data to be sent as the request body
206
214
  // Only applicable for request methods 'PUT', 'POST', and 'PATCH'
@@ -271,6 +279,20 @@ var axiosInstance = (axios.create({
271
279
  httpsAgent: new https.Agent({ keepAlive: true }),
272
280
  */
273
281
  }));
282
+ carbonAxiosInstance.interceptors.request.use(function (config) {
283
+ if (config.params) {
284
+ var serialized = carbonNodeQsStringify(config.params);
285
+ if (serialized.length > 2000) {
286
+ // Move params into body but keep track of intended method
287
+ config.method = "post";
288
+ config.data = config.params;
289
+ config.params = {
290
+ METHOD: "GET", // 👈 explicit signal for your REST parser
291
+ };
292
+ }
293
+ }
294
+ return config;
295
+ });
274
296
 
275
297
  function convertForRequestBody (restfulObject, tableName, C6, regexErrorHandler) {
276
298
  if (regexErrorHandler === void 0) { regexErrorHandler = alert; }
@@ -628,13 +650,20 @@ var HttpExecutor = /** @class */ (function (_super) {
628
650
  function HttpExecutor() {
629
651
  return _super !== null && _super.apply(this, arguments) || this;
630
652
  }
653
+ HttpExecutor.prototype.isRestResponse = function (r) {
654
+ return !!r && r.data != null && typeof r.data === 'object' && 'rest' in r.data;
655
+ };
631
656
  HttpExecutor.prototype.stripTableNameFromKeys = function (obj) {
632
- var columns = this.config.restModel.COLUMNS || {};
633
- return Object.keys(obj || {}).reduce(function (acc, key) {
634
- var shortKey = columns[key] || key.split('.').pop();
635
- acc[shortKey] = obj[key];
636
- return acc;
637
- }, {});
657
+ var _a;
658
+ var columns = this.config.restModel.COLUMNS;
659
+ var source = (obj !== null && obj !== void 0 ? obj : {});
660
+ var out = {};
661
+ for (var _i = 0, _b = Object.entries(source); _i < _b.length; _i++) {
662
+ var _c = _b[_i], key = _c[0], value = _c[1];
663
+ var short = (_a = columns[key]) !== null && _a !== void 0 ? _a : (key.includes('.') ? key.split('.').pop() : key);
664
+ out[short] = value;
665
+ }
666
+ return out;
638
667
  };
639
668
  HttpExecutor.prototype.putState = function (response, request, callback) {
640
669
  var _a, _b;
@@ -651,14 +680,15 @@ var HttpExecutor = /** @class */ (function (_super) {
651
680
  HttpExecutor.prototype.postState = function (response, request, callback) {
652
681
  var _this = this;
653
682
  var _a, _b, _c;
654
- if (1 !== this.config.restModel.PRIMARY_SHORT.length) {
655
- console.error("C6 received unexpected result's given the primary key length");
656
- }
657
- else {
683
+ if (this.config.restModel.PRIMARY_SHORT.length === 1) {
658
684
  var pk = this.config.restModel.PRIMARY_SHORT[0];
659
- // TODO - should overrides be handled differently? Why override: (react/php), driver missmatches, aux data..
660
- // @ts-ignore - this is technically a correct error, but we allow it anyway...
661
- request[pk] = (_a = response.data) === null || _a === void 0 ? void 0 : _a.created;
685
+ try {
686
+ request[pk] = (_a = response.data) === null || _a === void 0 ? void 0 : _a.created;
687
+ }
688
+ catch ( /* best-effort */_d) { /* best-effort */ }
689
+ }
690
+ else if (isLocal()) {
691
+ console.error("C6 received unexpected results given the primary key length");
662
692
  }
663
693
  (_b = this.config.reactBootstrap) === null || _b === void 0 ? void 0 : _b.updateRestfulObjectArrays({
664
694
  callback: callback,
@@ -691,8 +721,9 @@ var HttpExecutor = /** @class */ (function (_super) {
691
721
  return tslib.__awaiter(this, void 0, void 0, function () {
692
722
  var _a, C6, axios, restURL, withCredentials, restModel, reactBootstrap, requestMethod, skipPrimaryCheck, clearCache, tableName, fullTableList, operatingTableFullName, operatingTable, tables, query, apiRequest;
693
723
  var _this = this;
694
- return tslib.__generator(this, function (_b) {
695
- switch (_b.label) {
724
+ var _b;
725
+ return tslib.__generator(this, function (_c) {
726
+ switch (_c.label) {
696
727
  case 0:
697
728
  _a = this.config, C6 = _a.C6, axios = _a.axios, restURL = _a.restURL, withCredentials = _a.withCredentials, restModel = _a.restModel, reactBootstrap = _a.reactBootstrap, requestMethod = _a.requestMethod, skipPrimaryCheck = _a.skipPrimaryCheck, clearCache = _a.clearCache;
698
729
  return [4 /*yield*/, this.runLifecycleHooks("beforeProcessing", {
@@ -700,7 +731,7 @@ var HttpExecutor = /** @class */ (function (_super) {
700
731
  request: this.request,
701
732
  })];
702
733
  case 1:
703
- _b.sent();
734
+ _c.sent();
704
735
  tableName = restModel.TABLE_NAME;
705
736
  fullTableList = Array.isArray(tableName) ? tableName : [tableName];
706
737
  operatingTableFullName = fullTableList[0];
@@ -715,45 +746,40 @@ var HttpExecutor = /** @class */ (function (_super) {
715
746
  default:
716
747
  throw Error('Bad request method passed to getApi');
717
748
  }
718
- if (null !== clearCache || undefined !== clearCache) {
719
- exports.userCustomClearCache[tables + requestMethod] = clearCache;
749
+ if (clearCache != null) {
750
+ exports.userCustomClearCache.push(clearCache);
751
+ }
752
+ if (isLocal() && (this.config.verbose || ((_b = this.request) === null || _b === void 0 ? void 0 : _b.debug))) {
753
+ console.groupCollapsed('%c API:', 'color: #0c0', "(".concat(requestMethod, ") Request for (").concat(tableName, ")"));
754
+ console.log('request', this.request);
755
+ console.groupEnd();
720
756
  }
721
- console.groupCollapsed('%c API: (' + requestMethod + ') Request for (' + tableName + ')', 'color: #0c0');
722
- console.log('request', this.request);
723
- console.groupEnd();
724
757
  // an undefined query would indicate queryCallback returned undefined,
725
758
  // thus the request shouldn't fire as is in custom cache
726
759
  if (undefined === this.request || null === this.request) {
727
- console.groupCollapsed('%c API: (' + requestMethod + ') Request Query for (' + tableName + ') undefined, returning null (will not fire)!', 'color: #c00');
728
- console.log('request', this.request);
729
- console.log('%c Returning (undefined|null) for a query would indicate a custom cache hit (outside API.tsx), thus the request should not fire.', 'color: #c00');
730
- console.trace();
731
- console.groupEnd();
760
+ if (isLocal()) {
761
+ console.groupCollapsed("API: (".concat(requestMethod, ") (").concat(tableName, ") query undefined/null \u2192 returning null"));
762
+ console.log('request', this.request);
763
+ console.groupEnd();
764
+ }
732
765
  return [2 /*return*/, null];
733
766
  }
734
767
  query = this.request;
735
- if (C6.GET === requestMethod) {
736
- if (undefined === query[C6.PAGINATION]) {
737
- query[C6.PAGINATION] = {};
738
- }
739
- query[C6.PAGINATION][C6.PAGE] = query[C6.PAGINATION][C6.PAGE] || 1;
740
- query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
741
- }
742
768
  apiRequest = function () { return tslib.__awaiter(_this, void 0, void 0, function () {
743
- 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;
769
+ var _a, debug, _b, cacheResults, dataInsertMultipleRows, success, _c, fetchDependencies, _d, error, querySerialized, cacheResult, cachingConfirmed, cacheCheck, cacheCheck, apiResponse, returnGetNextPageFunction, restRequestUri, needsConditionOrPrimaryCheck, TABLES, primaryKeyList, primaryKeyFullyQualified, primaryKey, whereVal, whereIsEmpty, providedPrimary, primaryVal, axiosActiveRequest;
744
770
  var _e;
745
771
  var _this = this;
746
- var _f, _g, _h, _j, _k, _l;
747
- return tslib.__generator(this, function (_m) {
748
- switch (_m.label) {
772
+ var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
773
+ return tslib.__generator(this, function (_r) {
774
+ switch (_r.label) {
749
775
  case 0:
750
776
  _a = this.request, debug = _a.debug, _b = _a.cacheResults, cacheResults = _b === void 0 ? (C6.GET === requestMethod) : _b, dataInsertMultipleRows = _a.dataInsertMultipleRows, success = _a.success, _c = _a.fetchDependencies, fetchDependencies = _c === void 0 ? exports.eFetchDependencies.NONE : _c, _d = _a.error, error = _d === void 0 ? "An unexpected API error occurred!" : _d;
751
777
  if (C6.GET === requestMethod
752
778
  && undefined !== ((_f = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _f === void 0 ? void 0 : _f[C6.PAGE])
753
- && 1 !== query[C6.PAGINATION][C6.PAGE]) {
754
- console.groupCollapsed('Request on table (' + tableName + ') is firing for page (' + query[C6.PAGINATION][C6.PAGE] + '), please wait!');
755
- console.log('Request Data (note you may see the success and/or error prompt):', this.request);
756
- console.trace();
779
+ && 1 !== query[C6.PAGINATION][C6.PAGE]
780
+ && isLocal()) {
781
+ console.groupCollapsed("Request (".concat(tableName, ") page (").concat(query[C6.PAGINATION][C6.PAGE], ")"));
782
+ console.log('request', this.request);
757
783
  console.groupEnd();
758
784
  }
759
785
  querySerialized = sortAndSerializeQueryObject(tables, query !== null && query !== void 0 ? query : {});
@@ -770,39 +796,35 @@ var HttpExecutor = /** @class */ (function (_super) {
770
796
  query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
771
797
  if (!(true === cacheResults)) return [3 /*break*/, 7];
772
798
  if (!(undefined !== cacheResult)) return [3 /*break*/, 6];
773
- _m.label = 1;
799
+ _r.label = 1;
774
800
  case 1:
775
801
  cacheCheck = checkCache(cacheResult, requestMethod, tableName, this.request);
776
802
  if (!(false !== cacheCheck)) return [3 /*break*/, 3];
777
803
  return [4 /*yield*/, cacheCheck];
778
- case 2: return [2 /*return*/, (_m.sent()).data];
804
+ case 2: return [2 /*return*/, (_r.sent()).data];
779
805
  case 3:
780
- // this line incrementing page is why we return recursively
781
806
  ++query[C6.PAGINATION][C6.PAGE];
782
- // this json stringify is to capture the new page number
783
807
  querySerialized = sortAndSerializeQueryObject(tables, query !== null && query !== void 0 ? query : {});
784
808
  cacheResult = exports.apiRequestCache.find(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
785
- _m.label = 4;
809
+ _r.label = 4;
786
810
  case 4:
787
811
  if (undefined !== cacheResult) return [3 /*break*/, 1];
788
- _m.label = 5;
812
+ _r.label = 5;
789
813
  case 5:
790
814
  if (debug && isLocal()) {
791
- reactToastify.toast.warning("DEVS: Request in cache. (" + exports.apiRequestCache.findIndex(function (cache) { return cache.requestArgumentsSerialized === querySerialized; }) + "). Returning function to request page (" + query[C6.PAGINATION][C6.PAGE] + ")", toastOptionsDevs);
815
+ reactToastify.toast.warning("DEVS: Request pages exhausted in cache; firing network.", toastOptionsDevs);
792
816
  }
793
- // @ts-ignore - this is an incorrect warning on TS, it's well typed
794
- return [2 /*return*/, apiRequest];
817
+ _r.label = 6;
795
818
  case 6:
796
819
  cachingConfirmed = true;
797
820
  return [3 /*break*/, 8];
798
821
  case 7:
799
- if (debug && isLocal()) {
822
+ if (debug && isLocal())
800
823
  reactToastify.toast.info("DEVS: Ignore cache was set to true.", toastOptionsDevs);
801
- }
802
- _m.label = 8;
824
+ _r.label = 8;
803
825
  case 8:
804
826
  if (debug && isLocal()) {
805
- reactToastify.toast.success("DEVS: Request not in cache." + (requestMethod === C6.GET ? "Page (" + query[C6.PAGINATION][C6.PAGE] + ")." : '') + " Logging cache 2 console.", toastOptionsDevs);
827
+ reactToastify.toast.success("DEVS: Request not in cache." + (requestMethod === C6.GET ? " Page (" + query[C6.PAGINATION][C6.PAGE] + ")" : ''), toastOptionsDevs);
806
828
  }
807
829
  return [3 /*break*/, 12];
808
830
  case 9:
@@ -811,10 +833,10 @@ var HttpExecutor = /** @class */ (function (_super) {
811
833
  cacheCheck = checkCache(cacheResult, requestMethod, tableName, this.request);
812
834
  if (!(false !== cacheCheck)) return [3 /*break*/, 11];
813
835
  return [4 /*yield*/, cacheCheck];
814
- case 10: return [2 /*return*/, (_m.sent()).data];
836
+ case 10: return [2 /*return*/, (_r.sent()).data];
815
837
  case 11:
816
838
  cachingConfirmed = true;
817
- _m.label = 12;
839
+ _r.label = 12;
818
840
  case 12:
819
841
  returnGetNextPageFunction = false;
820
842
  restRequestUri = restURL + operatingTable + '/';
@@ -826,12 +848,11 @@ var HttpExecutor = /** @class */ (function (_super) {
826
848
  primaryKey = (_h = primaryKeyFullyQualified === null || primaryKeyFullyQualified === void 0 ? void 0 : primaryKeyFullyQualified.split('.')) === null || _h === void 0 ? void 0 : _h.pop();
827
849
  if (needsConditionOrPrimaryCheck) {
828
850
  if (undefined === primaryKey) {
829
- if (null === query
830
- || undefined === query
831
- || undefined === (query === null || query === void 0 ? void 0 : query[C6.WHERE])
832
- || (true === Array.isArray(query[C6.WHERE])
833
- || query[C6.WHERE].length === 0)
834
- || (Object.keys(query === null || query === void 0 ? void 0 : query[C6.WHERE]).length === 0)) {
851
+ whereVal = query === null || query === void 0 ? void 0 : query[C6.WHERE];
852
+ whereIsEmpty = whereVal == null ||
853
+ (Array.isArray(whereVal) && whereVal.length === 0) ||
854
+ (typeof whereVal === 'object' && !Array.isArray(whereVal) && Object.keys(whereVal).length === 0);
855
+ if (whereIsEmpty) {
835
856
  console.error(query);
836
857
  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 + ').');
837
858
  }
@@ -862,22 +883,27 @@ var HttpExecutor = /** @class */ (function (_super) {
862
883
  primaryVal = (_l = query[primaryKey]) !== null && _l !== void 0 ? _l : (primaryKeyFullyQualified ? query[primaryKeyFullyQualified] : undefined);
863
884
  if (undefined !== primaryVal) {
864
885
  restRequestUri += primaryVal + '/';
865
- console.log('query', query, 'primaryKey', primaryKey);
886
+ if (isLocal() && (this.config.verbose || ((_m = this.request) === null || _m === void 0 ? void 0 : _m.debug))) {
887
+ console.log('query', query, 'primaryKey', primaryKey);
888
+ }
866
889
  }
867
890
  else {
868
- console.log('query', query);
891
+ if (isLocal() && (this.config.verbose || ((_o = this.request) === null || _o === void 0 ? void 0 : _o.debug))) {
892
+ console.log('query', query);
893
+ }
869
894
  }
870
895
  }
871
896
  else {
872
- console.log('query', query);
897
+ if (isLocal() && (this.config.verbose || ((_p = this.request) === null || _p === void 0 ? void 0 : _p.debug))) {
898
+ console.log('query', query);
899
+ }
873
900
  }
874
901
  try {
875
- console.groupCollapsed('%c API: (' + requestMethod + ') Request Query for (' + operatingTable + ') is about to fire, will return with promise!', 'color: #A020F0');
876
- console.log(this.request);
877
- console.log('%c If this is the first request for this datatype; thus the value being set is currently undefined, please remember to update the state to null.', 'color: #A020F0');
878
- console.log('%c Remember undefined indicated the request has not fired, null indicates the request is firing, an empty array would signal no data was returned for the sql stmt.', 'color: #A020F0');
879
- console.trace();
880
- console.groupEnd();
902
+ if (isLocal() && (this.config.verbose || ((_q = this.request) === null || _q === void 0 ? void 0 : _q.debug))) {
903
+ console.groupCollapsed('%c API:', 'color: #A020F0', "(".concat(requestMethod, ") (").concat(operatingTable, ") firing"));
904
+ console.log(this.request);
905
+ console.groupEnd();
906
+ }
881
907
  this.runLifecycleHooks("beforeExecution", {
882
908
  config: this.config,
883
909
  request: this.request
@@ -918,11 +944,11 @@ var HttpExecutor = /** @class */ (function (_super) {
918
944
  // returning the promise with this then is important for tests. todo - we could make that optional.
919
945
  // https://rapidapi.com/guides/axios-async-await
920
946
  return [2 /*return*/, axiosActiveRequest.then(function (response) { return tslib.__awaiter(_this, void 0, void 0, function () {
921
- var cacheIndex, callback, responseData_1, dependencies_1, fetchReferences_1, apiRequestPromises, _loop_1, tableToFetch;
947
+ var cacheIndex, callback, responseData_1, pageLimit, got, hasNext, cacheIndex, dependencies_1, fetchReferences_1, apiRequestPromises, _loop_1, tableToFetch;
922
948
  var _this = this;
923
- var _a, _b, _c, _d, _e, _f, _g;
924
- return tslib.__generator(this, function (_h) {
925
- switch (_h.label) {
949
+ var _a, _b, _c, _d;
950
+ return tslib.__generator(this, function (_e) {
951
+ switch (_e.label) {
926
952
  case 0:
927
953
  // noinspection SuspiciousTypeOfGuard
928
954
  if (typeof response.data === 'string') {
@@ -944,13 +970,13 @@ var HttpExecutor = /** @class */ (function (_super) {
944
970
  request: this.request,
945
971
  response: response
946
972
  });
947
- // todo - this feels dumb now, but i digress
948
973
  apiResponse = TestRestfulResponse(response, success, error);
949
974
  if (false === apiResponse) {
950
975
  if (debug && isLocal()) {
951
- reactToastify.toast.warning("DEVS: TestRestfulResponse returned false for (" + operatingTable + ").", toastOptionsDevs);
976
+ reactToastify.toast.warning("DEVS: TestRestfulResponse returned false.", toastOptionsDevs);
952
977
  }
953
- return [2 /*return*/, response];
978
+ // Force a null payload so the final .then(response => response.data) yields null
979
+ return [2 /*return*/, Promise.resolve(tslib.__assign(tslib.__assign({}, response), { data: null }))];
954
980
  }
955
981
  callback = function () { return _this.runLifecycleHooks("afterCommit", {
956
982
  config: _this.config,
@@ -982,28 +1008,29 @@ var HttpExecutor = /** @class */ (function (_super) {
982
1008
  else {
983
1009
  callback();
984
1010
  }
985
- if (!(C6.GET === requestMethod)) return [3 /*break*/, 2];
1011
+ if (!(C6.GET === requestMethod && this.isRestResponse(response))) return [3 /*break*/, 2];
986
1012
  responseData_1 = response.data;
987
- returnGetNextPageFunction = 1 !== ((_a = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _a === void 0 ? void 0 : _a[C6.LIMIT]) &&
988
- ((_b = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _b === void 0 ? void 0 : _b[C6.LIMIT]) === responseData_1.rest.length;
989
- if (false === isTest() || this.config.verbose) {
990
- console.groupCollapsed('%c API: Response (' + requestMethod + ' ' + tableName + ') returned length (' + ((_c = responseData_1.rest) === null || _c === void 0 ? void 0 : _c.length) + ') of possible (' + ((_d = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _d === void 0 ? void 0 : _d[C6.LIMIT]) + ') limit!', 'color: #0c0');
991
- console.log('%c ' + requestMethod + ' ' + tableName, 'color: #0c0');
992
- console.log('%c Request Data (note you may see the success and/or error prompt):', 'color: #0c0', this.request);
993
- console.log('%c Response Data:', 'color: #0c0', responseData_1.rest);
994
- console.log('%c Will return get next page function:' + (returnGetNextPageFunction ? '' : ' (Will not return with explicit limit 1 set)'), 'color: #0c0', true === returnGetNextPageFunction);
995
- console.trace();
996
- console.groupEnd();
997
- }
998
- if (false === returnGetNextPageFunction) {
999
- responseData_1.next = apiRequest;
1013
+ pageLimit = (_a = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _a === void 0 ? void 0 : _a[C6.LIMIT];
1014
+ got = responseData_1.rest.length;
1015
+ hasNext = pageLimit !== 1 && got === pageLimit;
1016
+ if (hasNext) {
1017
+ responseData_1.next = apiRequest; // there might be more
1000
1018
  }
1001
1019
  else {
1002
- responseData_1.next = undefined;
1003
- if (true === debug
1004
- && isLocal()) {
1005
- reactToastify.toast.success("DEVS: Response returned length (" + ((_e = responseData_1.rest) === null || _e === void 0 ? void 0 : _e.length) + ") less than limit (" + ((_f = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _f === void 0 ? void 0 : _f[C6.LIMIT]) + ").", toastOptionsDevs);
1006
- }
1020
+ responseData_1.next = undefined; // short page => done
1021
+ }
1022
+ // If you keep this flag, make it reflect reality:
1023
+ returnGetNextPageFunction = hasNext;
1024
+ // and fix cache ‘final’ flag to match:
1025
+ if (cachingConfirmed) {
1026
+ cacheIndex = exports.apiRequestCache.findIndex(function (c) { return c.requestArgumentsSerialized === querySerialized; });
1027
+ exports.apiRequestCache[cacheIndex].final = !hasNext;
1028
+ }
1029
+ if ((this.config.verbose || debug) && isLocal()) {
1030
+ console.groupCollapsed("API: Response (".concat(requestMethod, " ").concat(tableName, ") len (").concat((_b = responseData_1.rest) === null || _b === void 0 ? void 0 : _b.length, ") of (").concat((_c = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _c === void 0 ? void 0 : _c[C6.LIMIT], ")"));
1031
+ console.log('request', this.request);
1032
+ console.log('response.rest', responseData_1.rest);
1033
+ console.groupEnd();
1007
1034
  }
1008
1035
  if (!(fetchDependencies
1009
1036
  && 'number' === typeof fetchDependencies
@@ -1078,7 +1105,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1078
1105
  }); });
1079
1106
  console.log('fetchReferences', fetchReferences_1);
1080
1107
  _loop_1 = function (tableToFetch) {
1081
- var _j;
1108
+ var _f;
1082
1109
  if (fetchDependencies & exports.eFetchDependencies.C6ENTITY
1083
1110
  && 'string' === typeof tableName
1084
1111
  && tableName.endsWith("carbon_carbons")) {
@@ -1101,7 +1128,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1101
1128
  .split('_')
1102
1129
  .map(function (part) { return part.charAt(0).toUpperCase() + part.slice(1); })
1103
1130
  .join('_');
1104
- var RestApi = (_g = C6.ORM[ormKey]) !== null && _g !== void 0 ? _g : new Error("Fetch Dependencies could not find table (".concat(ormKey, ") in the set \u2209 [ ").concat(Object.keys(C6.ORM).join(', '), " ]"));
1131
+ var RestApi = (_d = C6.ORM[ormKey]) !== null && _d !== void 0 ? _d : new Error("Fetch Dependencies could not find table (".concat(ormKey, ") in the set \u2209 [ ").concat(Object.keys(C6.ORM).join(', '), " ]"));
1105
1132
  console.log('%c Fetch Dependencies will select (' + tableToFetch + ') using GET request', 'color: #33ccff');
1106
1133
  var nextFetchDependencies = exports.eFetchDependencies.NONE;
1107
1134
  if (fetchDependencies & exports.eFetchDependencies.RECURSIVE) {
@@ -1127,8 +1154,8 @@ var HttpExecutor = /** @class */ (function (_super) {
1127
1154
  console.log('RestApi object', RestApi);
1128
1155
  // this is a dynamic call to the rest api, any generated table may resolve with (RestApi)
1129
1156
  // todo - using value to avoid joins.... but. maybe this should be a parameterizable option -- think race conditions; its safer to join
1130
- apiRequestPromises.push(RestApi.Get((_j = {},
1131
- _j[C6.WHERE] = Object.keys(fetchReferences_1[tableToFetch]).reduce(function (sum, column) {
1157
+ apiRequestPromises.push(RestApi.Get((_f = {},
1158
+ _f[C6.WHERE] = Object.keys(fetchReferences_1[tableToFetch]).reduce(function (sum, column) {
1132
1159
  fetchReferences_1[tableToFetch][column] = fetchReferences_1[tableToFetch][column].flat(Infinity);
1133
1160
  if (0 === fetchReferences_1[tableToFetch][column].length) {
1134
1161
  console.warn('The column (' + column + ') was not found in the response data. We will not fetch.', responseData_1);
@@ -1141,8 +1168,8 @@ var HttpExecutor = /** @class */ (function (_super) {
1141
1168
  ];
1142
1169
  return sum;
1143
1170
  }, {}),
1144
- _j.fetchDependencies = nextFetchDependencies,
1145
- _j)));
1171
+ _f.fetchDependencies = nextFetchDependencies,
1172
+ _f)));
1146
1173
  };
1147
1174
  for (tableToFetch in fetchReferences_1) {
1148
1175
  _loop_1(tableToFetch);
@@ -1150,7 +1177,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1150
1177
  console.groupEnd();
1151
1178
  return [4 /*yield*/, Promise.all(apiRequestPromises)];
1152
1179
  case 1:
1153
- _h.sent();
1180
+ _e.sent();
1154
1181
  apiRequestPromises.map(function (promise) { return tslib.__awaiter(_this, void 0, void 0, function () {
1155
1182
  var _a, _b;
1156
1183
  return tslib.__generator(this, function (_c) {
@@ -1168,7 +1195,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1168
1195
  }
1169
1196
  });
1170
1197
  }); });
1171
- _h.label = 2;
1198
+ _e.label = 2;
1172
1199
  case 2:
1173
1200
  if (debug && isLocal()) {
1174
1201
  reactToastify.toast.success("DEVS: (" + requestMethod + ") request complete.", toastOptionsDevs);
@@ -1196,7 +1223,7 @@ var HttpExecutor = /** @class */ (function (_super) {
1196
1223
  });
1197
1224
  }); };
1198
1225
  return [4 /*yield*/, apiRequest()];
1199
- case 2: return [2 /*return*/, _b.sent()];
1226
+ case 2: return [2 /*return*/, _c.sent()];
1200
1227
  }
1201
1228
  });
1202
1229
  });
@@ -2089,16 +2116,31 @@ function ExpressHandler(_a) {
2089
2116
  var _this = this;
2090
2117
  var C6 = _a.C6, mysqlPool = _a.mysqlPool;
2091
2118
  return function (req, res, next) { return tslib.__awaiter(_this, void 0, void 0, function () {
2092
- var method, table, primary, payload, primaryKeys, primaryKeyName, response, err_1;
2093
- var _a, _b;
2094
- return tslib.__generator(this, function (_c) {
2095
- switch (_c.label) {
2119
+ var incomingMethod, table, primary, methodOverrideRaw, methodOverride, treatAsGet, method, payload, primaryKeys, primaryKeyName, response, err_1;
2120
+ var _a, _b, _c, _d, _e;
2121
+ return tslib.__generator(this, function (_f) {
2122
+ switch (_f.label) {
2096
2123
  case 0:
2097
- _c.trys.push([0, 2, , 3]);
2098
- method = req.method.toUpperCase();
2124
+ _f.trys.push([0, 2, , 3]);
2125
+ incomingMethod = req.method.toUpperCase();
2099
2126
  table = req.params.table;
2100
2127
  primary = req.params.primary;
2101
- payload = method === 'GET' ? req.query : req.body;
2128
+ methodOverrideRaw = ((_b = (_a = req.query) === null || _a === void 0 ? void 0 : _a.METHOD) !== null && _b !== void 0 ? _b : (_c = req.query) === null || _c === void 0 ? void 0 : _c.method);
2129
+ methodOverride = typeof methodOverrideRaw === 'string' ? methodOverrideRaw.toUpperCase() : undefined;
2130
+ treatAsGet = incomingMethod === 'POST' && methodOverride === 'GET';
2131
+ method = treatAsGet ? 'GET' : incomingMethod;
2132
+ payload = treatAsGet ? tslib.__assign({}, req.body) : (method === 'GET' ? req.query : req.body);
2133
+ // Remove transport-only METHOD flag so it never leaks into ORM parsing
2134
+ if (treatAsGet && 'METHOD' in payload) {
2135
+ try {
2136
+ delete payload.METHOD;
2137
+ }
2138
+ catch ( /* noop */_g) { /* noop */ }
2139
+ }
2140
+ // Warn for unsupported overrides but continue normally
2141
+ if (incomingMethod !== 'GET' && methodOverride && methodOverride !== 'GET') {
2142
+ console.warn("Ignoring unsupported METHOD override: ".concat(methodOverride));
2143
+ }
2102
2144
  if (!(table in C6.TABLES)) {
2103
2145
  res.status(400).json({ error: "Invalid table: ".concat(table) });
2104
2146
  return [2 /*return*/];
@@ -2121,11 +2163,11 @@ function ExpressHandler(_a) {
2121
2163
  if (primary) {
2122
2164
  if (payload[C6C.WHERE]) {
2123
2165
  payload[C6C.WHERE][primaryKeyName] =
2124
- (_a = payload[C6C.WHERE][primaryKeyName]) !== null && _a !== void 0 ? _a : primary;
2166
+ (_d = payload[C6C.WHERE][primaryKeyName]) !== null && _d !== void 0 ? _d : primary;
2125
2167
  }
2126
2168
  else {
2127
2169
  payload[primaryKeyName] =
2128
- (_b = payload[primaryKeyName]) !== null && _b !== void 0 ? _b : primary;
2170
+ (_e = payload[primaryKeyName]) !== null && _e !== void 0 ? _e : primary;
2129
2171
  }
2130
2172
  }
2131
2173
  return [4 /*yield*/, restRequest({
@@ -2135,11 +2177,11 @@ function ExpressHandler(_a) {
2135
2177
  restModel: C6.TABLES[table]
2136
2178
  })(payload)];
2137
2179
  case 1:
2138
- response = _c.sent();
2180
+ response = _f.sent();
2139
2181
  res.status(200).json(tslib.__assign({ success: true }, response));
2140
2182
  return [3 /*break*/, 3];
2141
2183
  case 2:
2142
- err_1 = _c.sent();
2184
+ err_1 = _f.sent();
2143
2185
  res.status(500).json({ success: false, error: err_1 });
2144
2186
  next(err_1);
2145
2187
  return [3 /*break*/, 3];
@@ -2304,8 +2346,8 @@ exports.SelectQueryBuilder = SelectQueryBuilder;
2304
2346
  exports.SqlExecutor = SqlExecutor;
2305
2347
  exports.TestRestfulResponse = TestRestfulResponse;
2306
2348
  exports.UpdateQueryBuilder = UpdateQueryBuilder;
2307
- exports.axiosInstance = axiosInstance;
2308
2349
  exports.bbox = bbox;
2350
+ exports.carbonNodeQsStringify = carbonNodeQsStringify;
2309
2351
  exports.checkAllRequestsComplete = checkAllRequestsComplete;
2310
2352
  exports.checkCache = checkCache;
2311
2353
  exports.clearCache = clearCache;