@carbonorm/carbonnode 2.0.33 → 3.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.
Files changed (84) hide show
  1. package/dist/api/carbonSqlExecutor.d.ts +17 -0
  2. package/dist/api/interfaces/ormInterfaces.d.ts +22 -1
  3. package/dist/api/rest/Blog_Categories.d.ts +37 -0
  4. package/dist/api/rest/Blog_Categories.test.d.ts +11 -0
  5. package/dist/api/rest/Blog_Images.d.ts +37 -0
  6. package/dist/api/rest/Blog_Images.test.d.ts +15 -0
  7. package/dist/api/rest/Blog_Post_Categories.d.ts +37 -0
  8. package/dist/api/rest/Blog_Post_Categories.test.d.ts +13 -0
  9. package/dist/api/rest/Blog_Post_Tags.d.ts +37 -0
  10. package/dist/api/rest/Blog_Post_Tags.test.d.ts +13 -0
  11. package/dist/api/rest/Blog_Posts.d.ts +37 -0
  12. package/dist/api/rest/Blog_Posts.test.d.ts +21 -0
  13. package/dist/api/rest/Blog_Tags.d.ts +37 -0
  14. package/dist/api/rest/Blog_Tags.test.d.ts +11 -0
  15. package/dist/api/rest/C6.d.ts +1000 -0
  16. package/dist/api/rest/Cache.d.ts +37 -0
  17. package/dist/api/rest/Cache.test.d.ts +12 -0
  18. package/dist/api/rest/Cities.d.ts +37 -0
  19. package/dist/api/rest/Cities.test.d.ts +17 -0
  20. package/dist/api/rest/Counties.d.ts +37 -0
  21. package/dist/api/rest/Counties.test.d.ts +18 -0
  22. package/dist/api/rest/Countries.d.ts +37 -0
  23. package/dist/api/rest/Countries.test.d.ts +24 -0
  24. package/dist/api/rest/Geometries.d.ts +37 -0
  25. package/dist/api/rest/Geometries.test.d.ts +16 -0
  26. package/dist/api/rest/Images.d.ts +37 -0
  27. package/dist/api/rest/Images.test.d.ts +16 -0
  28. package/dist/api/rest/Land_Section_Info.d.ts +37 -0
  29. package/dist/api/rest/Land_Section_Info.test.d.ts +15 -0
  30. package/dist/api/rest/Neighborhoods.d.ts +37 -0
  31. package/dist/api/rest/Neighborhoods.test.d.ts +12 -0
  32. package/dist/api/rest/Parcel_Building_Details.d.ts +37 -0
  33. package/dist/api/rest/Parcel_Building_Details.test.d.ts +40 -0
  34. package/dist/api/rest/Parcel_Neighborhoods.d.ts +37 -0
  35. package/dist/api/rest/Parcel_Neighborhoods.test.d.ts +15 -0
  36. package/dist/api/rest/Parcel_Owners.d.ts +37 -0
  37. package/dist/api/rest/Parcel_Owners.test.d.ts +23 -0
  38. package/dist/api/rest/Parcel_Sales.d.ts +37 -0
  39. package/dist/api/rest/Parcel_Sales.test.d.ts +19 -0
  40. package/dist/api/rest/Parcel_Tax_History.d.ts +37 -0
  41. package/dist/api/rest/Parcel_Tax_History.test.d.ts +24 -0
  42. package/dist/api/rest/Parcels.d.ts +37 -0
  43. package/dist/api/rest/Parcels.test.d.ts +42 -0
  44. package/dist/api/rest/Payment_Charge_Logs.d.ts +37 -0
  45. package/dist/api/rest/Payment_Charge_Logs.test.d.ts +17 -0
  46. package/dist/api/rest/Payment_Subscriptions.d.ts +37 -0
  47. package/dist/api/rest/Payment_Subscriptions.test.d.ts +20 -0
  48. package/dist/api/rest/Property_Units.d.ts +37 -0
  49. package/dist/api/rest/Property_Units.test.d.ts +55 -0
  50. package/dist/api/rest/Sources.d.ts +37 -0
  51. package/dist/api/rest/Sources.test.d.ts +17 -0
  52. package/dist/api/rest/States.d.ts +37 -0
  53. package/dist/api/rest/States.test.d.ts +20 -0
  54. package/dist/api/rest/Tax_Districts.d.ts +37 -0
  55. package/dist/api/rest/Tax_Districts.test.d.ts +12 -0
  56. package/dist/api/rest/Users.d.ts +37 -0
  57. package/dist/api/rest/Users.test.d.ts +14 -0
  58. package/dist/api/rest/Valuation_Reports.d.ts +37 -0
  59. package/dist/api/rest/Valuation_Reports.test.d.ts +36 -0
  60. package/dist/api/rest/Zip_Codes.d.ts +37 -0
  61. package/dist/api/rest/Zip_Codes.test.d.ts +15 -0
  62. package/dist/api/restRequest.d.ts +44 -21
  63. package/dist/index.cjs.js +903 -558
  64. package/dist/index.cjs.js.map +1 -1
  65. package/dist/index.d.ts +4 -0
  66. package/dist/index.esm.js +899 -557
  67. package/dist/index.esm.js.map +1 -1
  68. package/dist/variables/getEnvVar.d.ts +1 -0
  69. package/dist/variables/isNode.d.ts +2 -0
  70. package/dist/variables/isTest.d.ts +1 -1
  71. package/dist/variables/toastOptions.d.ts +2 -2
  72. package/package.json +23 -12
  73. package/scripts/assets/handlebars/C6.ts.handlebars +5 -1
  74. package/scripts/generateRestBindings.cjs +89 -23
  75. package/scripts/generateRestBindings.ts +100 -27
  76. package/src/api/carbonSqlExecutor.ts +279 -0
  77. package/src/api/interfaces/ormInterfaces.ts +9 -1
  78. package/src/api/restRequest.ts +164 -19
  79. package/src/index.ts +4 -0
  80. package/src/variables/getEnvVar.ts +15 -0
  81. package/src/variables/isLocal.ts +3 -6
  82. package/src/variables/isNode.ts +3 -0
  83. package/src/variables/isTest.ts +4 -16
  84. package/src/variables/isVerbose.ts +2 -6
package/dist/index.esm.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import axios from 'axios';
2
2
  import Qs from 'qs';
3
+ import { __awaiter, __generator, __assign, __spreadArray } from 'tslib';
3
4
  import { toast } from 'react-toastify';
4
5
 
5
6
  var C6Constants = {
@@ -231,86 +232,365 @@ var axiosInstance = (axios.create({
231
232
  */
232
233
  }));
233
234
 
234
- /******************************************************************************
235
- Copyright (c) Microsoft Corporation.
236
-
237
- Permission to use, copy, modify, and/or distribute this software for any
238
- purpose with or without fee is hereby granted.
239
-
240
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
241
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
242
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
243
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
244
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
245
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
246
- PERFORMANCE OF THIS SOFTWARE.
247
- ***************************************************************************** */
248
- /* global Reflect, Promise, SuppressedError, Symbol */
249
-
250
-
251
- var __assign = function() {
252
- __assign = Object.assign || function __assign(t) {
253
- for (var s, i = 1, n = arguments.length; i < n; i++) {
254
- s = arguments[i];
255
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
256
- }
257
- return t;
258
- };
259
- return __assign.apply(this, arguments);
260
- };
261
-
262
- function __awaiter(thisArg, _arguments, P, generator) {
263
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
264
- return new (P || (P = Promise))(function (resolve, reject) {
265
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
266
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
267
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
268
- step((generator = generator.apply(thisArg, _arguments || [])).next());
269
- });
270
- }
271
-
272
- function __generator(thisArg, body) {
273
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
274
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
275
- function verb(n) { return function (v) { return step([n, v]); }; }
276
- function step(op) {
277
- if (f) throw new TypeError("Generator is already executing.");
278
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
279
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
280
- if (y = 0, t) op = [op[0] & 2, t.value];
281
- switch (op[0]) {
282
- case 0: case 1: t = op; break;
283
- case 4: _.label++; return { value: op[1], done: false };
284
- case 5: _.label++; y = op[1]; op = [0]; continue;
285
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
286
- default:
287
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
288
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
289
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
290
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
291
- if (t[2]) _.ops.pop();
292
- _.trys.pop(); continue;
293
- }
294
- op = body.call(thisArg, _);
295
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
296
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
297
- }
298
- }
299
-
300
- function __spreadArray(to, from, pack) {
301
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
302
- if (ar || !(i in from)) {
303
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
304
- ar[i] = from[i];
305
- }
306
- }
307
- return to.concat(ar || Array.prototype.slice.call(from));
308
- }
309
-
310
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
311
- var e = new Error(message);
312
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
313
- };
235
+ // import { validatePayloadAgainstSchema } from './validator'; // C6 schema validator
236
+ var CarbonSqlExecutor = /** @class */ (function () {
237
+ function CarbonSqlExecutor(pool, C6) {
238
+ this.pool = pool;
239
+ this.C6 = C6;
240
+ }
241
+ CarbonSqlExecutor.prototype.withConnection = function (cb) {
242
+ return __awaiter(this, void 0, void 0, function () {
243
+ var conn;
244
+ return __generator(this, function (_a) {
245
+ switch (_a.label) {
246
+ case 0: return [4 /*yield*/, this.pool.getConnection()];
247
+ case 1:
248
+ conn = _a.sent();
249
+ _a.label = 2;
250
+ case 2:
251
+ _a.trys.push([2, , 4, 5]);
252
+ return [4 /*yield*/, cb(conn)];
253
+ case 3: return [2 /*return*/, _a.sent()];
254
+ case 4:
255
+ conn.release();
256
+ return [7 /*endfinally*/];
257
+ case 5: return [2 /*return*/];
258
+ }
259
+ });
260
+ });
261
+ };
262
+ CarbonSqlExecutor.prototype.handle = function (req, res, next) {
263
+ return __awaiter(this, void 0, void 0, function () {
264
+ var method, table, primary, payload, result, _a, err_1;
265
+ return __generator(this, function (_b) {
266
+ switch (_b.label) {
267
+ case 0:
268
+ _b.trys.push([0, 11, , 12]);
269
+ method = req.method.toUpperCase();
270
+ table = req.params.table;
271
+ primary = req.params.primary;
272
+ payload = method === 'GET' ? req.query : req.body;
273
+ if (!(table in this.C6.TABLES)) {
274
+ res.status(400).json({ error: "Invalid table: ".concat(table) });
275
+ return [2 /*return*/];
276
+ }
277
+ result = void 0;
278
+ _a = method;
279
+ switch (_a) {
280
+ case 'GET': return [3 /*break*/, 1];
281
+ case 'OPTIONS': return [3 /*break*/, 1];
282
+ case 'POST': return [3 /*break*/, 3];
283
+ case 'PUT': return [3 /*break*/, 5];
284
+ case 'DELETE': return [3 /*break*/, 7];
285
+ }
286
+ return [3 /*break*/, 9];
287
+ case 1: return [4 /*yield*/, this.select(table, primary, payload)];
288
+ case 2:
289
+ result = _b.sent();
290
+ return [3 /*break*/, 10];
291
+ case 3: return [4 /*yield*/, this.insert(table, payload)];
292
+ case 4:
293
+ result = _b.sent();
294
+ return [3 /*break*/, 10];
295
+ case 5: return [4 /*yield*/, this.update(table, primary, payload)];
296
+ case 6:
297
+ result = _b.sent();
298
+ return [3 /*break*/, 10];
299
+ case 7: return [4 /*yield*/, this.delete(table, primary, payload)];
300
+ case 8:
301
+ result = _b.sent();
302
+ return [3 /*break*/, 10];
303
+ case 9: throw new Error("Unsupported method: ".concat(method));
304
+ case 10:
305
+ res.status(200).json({ success: true, result: result });
306
+ return [3 /*break*/, 12];
307
+ case 11:
308
+ err_1 = _b.sent();
309
+ next(err_1);
310
+ return [3 /*break*/, 12];
311
+ case 12: return [2 /*return*/];
312
+ }
313
+ });
314
+ });
315
+ };
316
+ CarbonSqlExecutor.prototype.buildBooleanJoinedConditions = function (set, andMode) {
317
+ if (andMode === void 0) { andMode = true; }
318
+ var booleanOperator = andMode ? 'AND' : 'OR';
319
+ var sql = '';
320
+ var OPERATORS = ['=', '!=', '<', '<=', '>', '>=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'IS', 'IS NOT'];
321
+ var isAggregateArray = function (value) { return Array.isArray(value) && typeof value[0] === 'string' && OPERATORS.includes(value[0]); };
322
+ var isNumericKeyed = function (obj) { return Array.isArray(obj) && Object.keys(obj).every(function (k) { return /^\d+$/.test(k); }); };
323
+ // todo - we should be doing something with value no????
324
+ var addCondition = function (column, op, _value) {
325
+ var paramName = column.replace(/\W+/g, '_');
326
+ return "(".concat(column, " ").concat(op, " :").concat(paramName, ")");
327
+ };
328
+ if (isNumericKeyed(set)) {
329
+ switch (set.length) {
330
+ case 2:
331
+ sql += addCondition(set[0], '=', set[1]);
332
+ break;
333
+ case 3:
334
+ if (!OPERATORS.includes(set[1])) {
335
+ throw new Error("Invalid operator: ".concat(set[1]));
336
+ }
337
+ sql += addCondition(set[0], set[1], set[2]);
338
+ break;
339
+ default:
340
+ throw new Error("Invalid array condition: ".concat(JSON.stringify(set)));
341
+ }
342
+ }
343
+ else {
344
+ var parts = [];
345
+ for (var _i = 0, _a = Object.entries(set); _i < _a.length; _i++) {
346
+ var _b = _a[_i], key = _b[0], value = _b[1];
347
+ if (/^\d+$/.test(key)) {
348
+ parts.push(this.buildBooleanJoinedConditions(value, !andMode));
349
+ continue;
350
+ }
351
+ if (!Array.isArray(value) || isAggregateArray(value)) {
352
+ parts.push(addCondition(key, '='));
353
+ continue;
354
+ }
355
+ if (value.length === 2 && OPERATORS.includes(value[0])) {
356
+ parts.push(addCondition(key, value[0], value[1]));
357
+ }
358
+ else if (value.length === 1 && isAggregateArray(value[0])) {
359
+ parts.push(addCondition(key, '=', value[0]));
360
+ }
361
+ else {
362
+ throw new Error("Invalid condition for ".concat(key, ": ").concat(JSON.stringify(value)));
363
+ }
364
+ }
365
+ sql = parts.join(" ".concat(booleanOperator, " "));
366
+ }
367
+ return "(".concat(sql, ")");
368
+ };
369
+ CarbonSqlExecutor.prototype.buildAggregateField = function (field) {
370
+ if (typeof field === 'string')
371
+ return field;
372
+ if (!Array.isArray(field))
373
+ throw new Error('Invalid SELECT entry: must be string or array');
374
+ var agg = field[0], args = field.slice(1);
375
+ switch (agg) {
376
+ case 'COUNT':
377
+ return "COUNT(".concat(args[0] || '*', ")");
378
+ case 'SUM':
379
+ case 'AVG':
380
+ case 'MIN':
381
+ case 'MAX':
382
+ return "".concat(agg, "(").concat(args[0], ")").concat(args[1] ? " AS ".concat(args[1]) : '');
383
+ case 'DISTINCT':
384
+ return "DISTINCT(".concat(args[0], ")").concat(args[1] ? " AS ".concat(args[1]) : '');
385
+ case 'GROUP_CONCAT': {
386
+ var col = args[0], alias = args[1], sortCol = args[2], sortType = args[3];
387
+ var order = sortCol ? " ORDER BY ".concat(sortCol, " ").concat(sortType || 'ASC') : '';
388
+ return "GROUP_CONCAT(DISTINCT ".concat(col).concat(order, " SEPARATOR ',')").concat(alias ? " AS ".concat(alias) : '');
389
+ }
390
+ case 'AS': {
391
+ var col = args[0], alias = args[1];
392
+ return "".concat(col, " AS ").concat(alias);
393
+ }
394
+ case 'CONVERT_TZ': {
395
+ var ts = args[0], fromTz = args[1], toTz = args[2];
396
+ return "CONVERT_TZ(".concat(ts, ", ").concat(fromTz, ", ").concat(toTz, ")");
397
+ }
398
+ case 'NOW':
399
+ return 'NOW()';
400
+ default:
401
+ throw new Error("Unsupported aggregate: ".concat(agg));
402
+ }
403
+ };
404
+ CarbonSqlExecutor.prototype.buildSelectQuery = function (table, primary, args, isSubSelect) {
405
+ var _this = this;
406
+ var _a, _b, _c, _d;
407
+ if (isSubSelect === void 0) { isSubSelect = false; }
408
+ var selectList = (_a = args === null || args === void 0 ? void 0 : args[this.C6.SELECT]) !== null && _a !== void 0 ? _a : ['*'];
409
+ var selectFields = Array.isArray(selectList)
410
+ ? selectList.map(function (f) { return _this.buildAggregateField(f); }).join(', ')
411
+ : '*';
412
+ var sql = "SELECT ".concat(selectFields, " FROM `").concat(table, "`");
413
+ if (args === null || args === void 0 ? void 0 : args[this.C6.JOIN]) {
414
+ var joins = args[this.C6.JOIN];
415
+ for (var joinType in joins) {
416
+ var joinKeyword = joinType.replace('_', ' ').toUpperCase();
417
+ for (var joinTable in joins[joinType]) {
418
+ var onClause = this.buildBooleanJoinedConditions(joins[joinType][joinTable]);
419
+ sql += " ".concat(joinKeyword, " JOIN `").concat(joinTable, "` ON ").concat(onClause);
420
+ }
421
+ }
422
+ }
423
+ if (args === null || args === void 0 ? void 0 : args[this.C6.WHERE]) {
424
+ sql += " WHERE ".concat(this.buildBooleanJoinedConditions(args[this.C6.WHERE]));
425
+ }
426
+ if (args === null || args === void 0 ? void 0 : args[this.C6.GROUP_BY]) {
427
+ var groupByFields = Array.isArray(args[this.C6.GROUP_BY]) ? args[this.C6.GROUP_BY].join(', ') : args[this.C6.GROUP_BY];
428
+ sql += " GROUP BY ".concat(groupByFields);
429
+ }
430
+ if (args === null || args === void 0 ? void 0 : args[this.C6.HAVING]) {
431
+ sql += " HAVING ".concat(this.buildBooleanJoinedConditions(args[this.C6.HAVING]));
432
+ }
433
+ if (args === null || args === void 0 ? void 0 : args[this.C6.PAGINATION]) {
434
+ var p = args[this.C6.PAGINATION];
435
+ var limitClause = '';
436
+ if (p[this.C6.ORDER]) {
437
+ var orderArray = Object.entries(p[this.C6.ORDER]).map(function (_a) {
438
+ var col = _a[0], dir = _a[1];
439
+ if (!['ASC', 'DESC'].includes(String(dir).toUpperCase())) {
440
+ throw new Error("Invalid order direction: ".concat(dir));
441
+ }
442
+ return "".concat(col, " ").concat(String(dir).toUpperCase());
443
+ });
444
+ sql += " ORDER BY ".concat(orderArray.join(', '));
445
+ }
446
+ else if (primary) {
447
+ sql += " ORDER BY ".concat(primary, " DESC");
448
+ }
449
+ else {
450
+ // todo this is wrong
451
+ var primaryKey = (_c = (_b = this.C6.TABLES['users'].PRIMARY_SHORT) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : 'user_id';
452
+ sql += " ORDER BY ".concat(primaryKey, " DESC");
453
+ }
454
+ if (p[this.C6.LIMIT] != null) {
455
+ var limit = parseInt(p[this.C6.LIMIT], 10);
456
+ if (isNaN(limit) || limit < 0) {
457
+ throw new Error("Invalid LIMIT: ".concat(p[this.C6.LIMIT]));
458
+ }
459
+ var page = parseInt((_d = p[this.C6.PAGE]) !== null && _d !== void 0 ? _d : 1, 10);
460
+ if (isNaN(page) || page < 1) {
461
+ throw new Error("PAGE must be >= 1 (got ".concat(p[this.C6.PAGE], ")"));
462
+ }
463
+ var offset = (page - 1) * limit;
464
+ limitClause += " LIMIT ".concat(offset, ", ").concat(limit);
465
+ }
466
+ sql += limitClause;
467
+ }
468
+ else if (!isSubSelect && primary) {
469
+ sql += " ORDER BY ".concat(primary, " ASC LIMIT 1");
470
+ }
471
+ else if (!isSubSelect && !primary) {
472
+ sql += " ORDER BY id ASC LIMIT 100"; // fallback default limit
473
+ }
474
+ return sql;
475
+ };
476
+ CarbonSqlExecutor.prototype.select = function (table, primary, args) {
477
+ return __awaiter(this, void 0, void 0, function () {
478
+ var sql;
479
+ var _this = this;
480
+ return __generator(this, function (_a) {
481
+ switch (_a.label) {
482
+ case 0:
483
+ sql = this.buildSelectQuery(table, primary, args);
484
+ return [4 /*yield*/, this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () {
485
+ var rows;
486
+ return __generator(this, function (_a) {
487
+ switch (_a.label) {
488
+ case 0:
489
+ console.log(sql);
490
+ return [4 /*yield*/, conn.query(sql)];
491
+ case 1:
492
+ rows = (_a.sent())[0];
493
+ return [2 /*return*/, rows];
494
+ }
495
+ });
496
+ }); })];
497
+ case 1: return [2 /*return*/, _a.sent()];
498
+ }
499
+ });
500
+ });
501
+ };
502
+ CarbonSqlExecutor.prototype.insert = function (table, data) {
503
+ return __awaiter(this, void 0, void 0, function () {
504
+ var keys, values, placeholders, sql;
505
+ var _this = this;
506
+ return __generator(this, function (_a) {
507
+ switch (_a.label) {
508
+ case 0:
509
+ keys = Object.keys(data);
510
+ values = keys.map(function (k) { return data[k]; });
511
+ placeholders = keys.map(function () { return '?'; }).join(', ');
512
+ sql = "INSERT INTO `".concat(table, "` (").concat(keys.join(', '), ") VALUES (").concat(placeholders, ")");
513
+ return [4 /*yield*/, this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () {
514
+ var result;
515
+ return __generator(this, function (_a) {
516
+ switch (_a.label) {
517
+ case 0: return [4 /*yield*/, conn.execute(sql, values)];
518
+ case 1:
519
+ result = (_a.sent())[0];
520
+ return [2 /*return*/, result];
521
+ }
522
+ });
523
+ }); })];
524
+ case 1: return [2 /*return*/, _a.sent()];
525
+ }
526
+ });
527
+ });
528
+ };
529
+ CarbonSqlExecutor.prototype.update = function (table, primary, data) {
530
+ return __awaiter(this, void 0, void 0, function () {
531
+ var keys, values, updates, sql;
532
+ var _this = this;
533
+ return __generator(this, function (_a) {
534
+ switch (_a.label) {
535
+ case 0:
536
+ if (!primary) {
537
+ throw new Error('Primary key is required for update');
538
+ }
539
+ keys = Object.keys(data);
540
+ values = keys.map(function (k) { return data[k]; });
541
+ updates = keys.map(function (k) { return "`".concat(k, "` = ?"); }).join(', ');
542
+ sql = "UPDATE `".concat(table, "` SET ").concat(updates, " WHERE `").concat(primary, "` = ?");
543
+ values.push(data[primary]);
544
+ return [4 /*yield*/, this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () {
545
+ var result;
546
+ return __generator(this, function (_a) {
547
+ switch (_a.label) {
548
+ case 0: return [4 /*yield*/, conn.execute(sql, values)];
549
+ case 1:
550
+ result = (_a.sent())[0];
551
+ return [2 /*return*/, result];
552
+ }
553
+ });
554
+ }); })];
555
+ case 1: return [2 /*return*/, _a.sent()];
556
+ }
557
+ });
558
+ });
559
+ };
560
+ CarbonSqlExecutor.prototype.delete = function (table, primary, args) {
561
+ return __awaiter(this, void 0, void 0, function () {
562
+ var sql;
563
+ var _this = this;
564
+ return __generator(this, function (_a) {
565
+ switch (_a.label) {
566
+ case 0:
567
+ if (!primary || !(args === null || args === void 0 ? void 0 : args[primary])) {
568
+ throw new Error('Primary key and value required for delete');
569
+ }
570
+ sql = "DELETE FROM `".concat(table, "` WHERE `").concat(primary, "` = ?");
571
+ return [4 /*yield*/, this.withConnection(function (conn) { return __awaiter(_this, void 0, void 0, function () {
572
+ var result;
573
+ return __generator(this, function (_a) {
574
+ switch (_a.label) {
575
+ case 0: return [4 /*yield*/, conn.execute(sql, [args[primary]])];
576
+ case 1:
577
+ result = (_a.sent())[0];
578
+ return [2 /*return*/, result];
579
+ }
580
+ });
581
+ }); })];
582
+ case 1: return [2 /*return*/, _a.sent()];
583
+ }
584
+ });
585
+ });
586
+ };
587
+ return CarbonSqlExecutor;
588
+ }());
589
+
590
+ var carbonSqlExecutor = /*#__PURE__*/Object.freeze({
591
+ __proto__: null,
592
+ CarbonSqlExecutor: CarbonSqlExecutor
593
+ });
314
594
 
315
595
  function convertForRequestBody (restfulObject, tableName, C6, regexErrorHandler) {
316
596
  if (regexErrorHandler === void 0) { regexErrorHandler = alert; }
@@ -383,31 +663,31 @@ function convertForRequestBody (restfulObject, tableName, C6, regexErrorHandler)
383
663
  }, {});
384
664
  }
385
665
 
386
- var _a$2, _b$2, _c$2, _d$2;
387
- var nodeEnv = typeof process !== 'undefined' && process.env && process.env.NODE_ENV
388
- ? process.env.NODE_ENV
389
- : // @ts-ignore
390
- ((_b$2 = (_a$2 = import.meta) === null || _a$2 === void 0 ? void 0 : _a$2.env) === null || _b$2 === void 0 ? void 0 : _b$2.MODE) || ((_d$2 = (_c$2 = import.meta) === null || _c$2 === void 0 ? void 0 : _c$2.env) === null || _d$2 === void 0 ? void 0 : _d$2.NODE_ENV);
391
- var isDevelopment = nodeEnv === 'development';
666
+ var _a;
667
+ var isNode = typeof process !== 'undefined' && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
392
668
 
393
- var _a$1, _b$1, _c$1, _d$1;
394
- var isTest = typeof process !== 'undefined' &&
395
- typeof process.env !== 'undefined' &&
396
- (process.env.JEST_WORKER_ID !== undefined ||
397
- process.env.NODE_ENV === 'test' ||
398
- process.env.REACT_APP_TEST === 'true') ||
399
- // Vite-only branch
400
- typeof import.meta !== 'undefined' &&
401
- (
669
+ function getEnvVar(key, fallback) {
670
+ if (fallback === void 0) { fallback = ''; }
671
+ // Vite-style injection
672
+ // @ts-ignore
673
+ if (typeof import.meta !== 'undefined' && import.meta.env && key in import.meta.env) {
402
674
  // @ts-ignore
403
- ((_b$1 = (_a$1 = import.meta) === null || _a$1 === void 0 ? void 0 : _a$1.env) === null || _b$1 === void 0 ? void 0 : _b$1.MODE) === 'test' ||
404
- // @ts-ignore
405
- ((_d$1 = (_c$1 = import.meta) === null || _c$1 === void 0 ? void 0 : _c$1.env) === null || _d$1 === void 0 ? void 0 : _d$1.VITE_TEST) === 'true');
675
+ return import.meta.env[key];
676
+ }
677
+ // Node or SSR
678
+ if (typeof process !== 'undefined' && process.env && key in process.env) {
679
+ return process.env[key];
680
+ }
681
+ return fallback;
682
+ }
406
683
 
407
- var _a, _b, _c, _d, _e, _f, _g;
408
- var envVerbose =
409
- // @ts-ignore
410
- (_g = (_e = (_c = (_b = (_a = import.meta) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.VITE_VERBOSE) !== null && _c !== void 0 ? _c : (_d = process === null || process === void 0 ? void 0 : process.env) === null || _d === void 0 ? void 0 : _d.REACT_APP_VERBOSE) !== null && _e !== void 0 ? _e : (_f = process === null || process === void 0 ? void 0 : process.env) === null || _f === void 0 ? void 0 : _f.VERBOSE) !== null && _g !== void 0 ? _g : '';
684
+ var isDevelopment = getEnvVar('NODE_ENV', '') === 'development';
685
+
686
+ var isTest = getEnvVar('JEST_WORKER_ID') || getEnvVar('NODE_ENV') === 'test'
687
+ || getEnvVar('REACT_APP_TEST') === 'true' || getEnvVar('VITE_TEST') === 'true'
688
+ || getEnvVar('MODE') === 'test' || getEnvVar('VITE_TEST_MODE') === 'true';
689
+
690
+ var envVerbose = getEnvVar('VERBOSE') || getEnvVar('REACT_APP_VERBOSE') || getEnvVar('VITE_VERBOSE') || '';
411
691
  var isVerbose = ['true', '1', 'yes', 'on'].includes(envVerbose.toLowerCase());
412
692
 
413
693
  var toastOptions = {
@@ -556,7 +836,8 @@ function extendedTypeHints() {
556
836
  return function (argv) { return restRequest(argv); };
557
837
  }
558
838
  function restRequest(_a) {
559
- var C6 = _a.C6, _b = _a.axios, axios = _b === void 0 ? axiosInstance : _b, _c = _a.restURL, restURL = _c === void 0 ? '/rest/' : _c, _d = _a.withCredentials, withCredentials = _d === void 0 ? true : _d, tableName = _a.tableName, _e = _a.requestMethod, requestMethod = _e === void 0 ? GET : _e, _f = _a.queryCallback, queryCallback = _f === void 0 ? {} : _f, responseCallback = _a.responseCallback, _g = _a.skipPrimaryCheck, skipPrimaryCheck = _g === void 0 ? false : _g, _h = _a.clearCache, clearCache = _h === void 0 ? undefined : _h;
839
+ var _this = this;
840
+ var C6 = _a.C6, _b = _a.axios, axios = _b === void 0 ? axiosInstance : _b, _c = _a.restURL, restURL = _c === void 0 ? '/rest/' : _c, mysqlPool = _a.mysqlPool, _d = _a.withCredentials, withCredentials = _d === void 0 ? true : _d, tableName = _a.tableName, _e = _a.requestMethod, requestMethod = _e === void 0 ? GET : _e, _f = _a.queryCallback, queryCallback = _f === void 0 ? {} : _f, responseCallback = _a.responseCallback, _g = _a.skipPrimaryCheck, skipPrimaryCheck = _g === void 0 ? false : _g, _h = _a.clearCache, clearCache = _h === void 0 ? undefined : _h;
560
841
  var fullTableList = Array.isArray(tableName) ? tableName : [tableName];
561
842
  var operatingTableFullName = fullTableList[0];
562
843
  var operatingTable = removePrefixIfExists(operatingTableFullName, C6.PREFIX);
@@ -573,483 +854,544 @@ function restRequest(_a) {
573
854
  if (null !== clearCache || undefined !== clearCache) {
574
855
  userCustomClearCache[tables + requestMethod] = clearCache;
575
856
  }
576
- return function (request) {
577
- if (request === void 0) { request = {}; }
578
- console.groupCollapsed('%c API: (' + requestMethod + ') Request for (' + operatingTable + ')', 'color: #0c0');
579
- console.log('request', request);
580
- console.groupEnd();
581
- // an undefined query would indicate queryCallback returned undefined,
582
- // thus the request shouldn't fire as is in custom cache
583
- var query;
584
- if ('function' === typeof queryCallback) {
585
- query = queryCallback(request); // obj or obj[]
586
- }
587
- else {
588
- query = queryCallback;
589
- }
590
- if (undefined === query || null === query) {
591
- if (request.debug && isDevelopment) {
592
- toast.warning("DEV: queryCallback returned undefined, signaling in Custom Cache. (returning null)", toastOptionsDevs);
593
- }
594
- console.groupCollapsed('%c API: (' + requestMethod + ') Request Query for (' + operatingTable + ') undefined, returning null (will not fire ajax)!', 'color: #c00');
595
- 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');
596
- console.trace();
597
- console.groupEnd();
598
- return null;
599
- }
600
- if (C6.GET === requestMethod) {
601
- if (undefined === query[C6.PAGINATION]) {
602
- query[C6.PAGINATION] = {};
603
- }
604
- query[C6.PAGINATION][C6.PAGE] = query[C6.PAGINATION][C6.PAGE] || 1;
605
- query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
857
+ return function () {
858
+ var args_1 = [];
859
+ for (var _i = 0; _i < arguments.length; _i++) {
860
+ args_1[_i] = arguments[_i];
606
861
  }
607
- // this could return itself with a new page number, or undefined if the end is reached
608
- function apiRequest() {
609
- var _this = this;
610
- var _a, _b, _c, _d, _e, _f, _g;
611
- (_a = request.cacheResults) !== null && _a !== void 0 ? _a : (request.cacheResults = C6.GET === requestMethod);
612
- if (C6.GET === requestMethod
613
- && undefined !== ((_b = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _b === void 0 ? void 0 : _b[C6.PAGE])
614
- && 1 !== query[C6.PAGINATION][C6.PAGE]) {
615
- console.groupCollapsed('Request on table (' + tableName + ') is firing for page (' + query[C6.PAGINATION][C6.PAGE] + '), please wait!');
616
- console.log('Request Data (note you may see the success and/or error prompt):', request);
617
- console.trace();
618
- console.groupEnd();
619
- }
620
- // The problem with creating cache keys with a stringified object is the order of keys matters and it's possible for the same query to be stringified differently.
621
- // Here we ensure the key order will be identical between two of the same requests. https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key
622
- // literally impossible for query to be undefined or null here but the editor is too busy licking windows to understand that
623
- var querySerialized = sortAndSerializeQueryObject(tables, query !== null && query !== void 0 ? query : {});
624
- var cacheResult = apiRequestCache.find(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
625
- var cachingConfirmed = false;
626
- // determine if we need to paginate.
627
- if (requestMethod === C6.GET) {
628
- if (undefined === (query === null || query === void 0 ? void 0 : query[C6.PAGINATION])) {
629
- if (undefined === query || null === query) {
630
- query = {};
631
- }
632
- query[C6.PAGINATION] = {};
633
- }
634
- query[C6.PAGINATION][C6.PAGE] = query[C6.PAGINATION][C6.PAGE] || 1;
635
- query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
636
- // this will evaluate true most the time
637
- if (true === request.cacheResults) {
638
- // just find the next, non-fetched, page and return a function to request it
639
- if (undefined !== cacheResult) {
640
- do {
641
- var cacheCheck = checkCache(cacheResult, requestMethod, tableName, request);
642
- if (false !== cacheCheck) {
643
- return cacheCheck;
644
- }
645
- // this line incrementing page is why we return recursively
646
- ++query[C6.PAGINATION][C6.PAGE];
647
- // this json stringify is to capture the new page number
648
- querySerialized = sortAndSerializeQueryObject(tables, query !== null && query !== void 0 ? query : {});
649
- cacheResult = apiRequestCache.find(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
650
- } while (undefined !== cacheResult);
651
- if (request.debug && isDevelopment) {
652
- toast.warning("DEVS: Request in cache. (" + apiRequestCache.findIndex(function (cache) { return cache.requestArgumentsSerialized === querySerialized; }) + "). Returning function to request page (" + query[C6.PAGINATION][C6.PAGE] + ")", toastOptionsDevs);
653
- }
654
- // @ts-ignore - this is an incorrect warning on TS, it's well typed
655
- return apiRequest;
656
- }
657
- cachingConfirmed = true;
658
- }
659
- else {
660
- if (request.debug && isDevelopment) {
661
- toast.info("DEVS: Ignore cache was set to true.", toastOptionsDevs);
662
- }
663
- }
664
- if (request.debug && isDevelopment) {
665
- toast.success("DEVS: Request not in cache." + (requestMethod === C6.GET ? "Page (" + query[C6.PAGINATION][C6.PAGE] + ")." : '') + " Logging cache 2 console.", toastOptionsDevs);
666
- }
667
- }
668
- else if (request.cacheResults) { // if we are not getting, we are updating, deleting, or inserting
669
- if (cacheResult) {
670
- var cacheCheck = checkCache(cacheResult, requestMethod, tableName, request);
671
- if (false !== cacheCheck) {
672
- return cacheCheck;
673
- }
674
- }
675
- cachingConfirmed = true;
676
- // push to cache so we do not repeat the request
677
- }
678
- var addBackPK;
679
- var apiResponse;
680
- var returnGetNextPageFunction = false;
681
- var restRequestUri = restURL + operatingTable + '/';
682
- var needsConditionOrPrimaryCheck = (PUT === requestMethod || DELETE === requestMethod)
683
- && false === skipPrimaryCheck;
684
- var TABLES = C6.TABLES;
685
- // todo - aggregate primary key check with condition check
686
- // check if PK exists in query, clone so pop does not affect the real data
687
- var primaryKey = (_f = (_e = (_d = structuredClone((_c = TABLES[operatingTable]) === null || _c === void 0 ? void 0 : _c.PRIMARY)) === null || _d === void 0 ? void 0 : _d.pop()) === null || _e === void 0 ? void 0 : _e.split('.')) === null || _f === void 0 ? void 0 : _f.pop();
688
- if (needsConditionOrPrimaryCheck) {
689
- if (undefined === primaryKey) {
690
- if (null === query
691
- || undefined === query
692
- || undefined === (query === null || query === void 0 ? void 0 : query[C6.WHERE])
693
- || (true === Array.isArray(query[C6.WHERE])
694
- || query[C6.WHERE].length === 0)
695
- || (Object.keys(query === null || query === void 0 ? void 0 : query[C6.WHERE]).length === 0)) {
696
- console.error(query);
697
- throw Error('Failed to parse primary key information. Query: (' + JSON.stringify(query) + ') Primary Key: (' + JSON.stringify(primaryKey) + ') TABLES[operatingTable]?.PRIMARY: (' + JSON.stringify((_g = TABLES[operatingTable]) === null || _g === void 0 ? void 0 : _g.PRIMARY) + ') for operatingTable (' + operatingTable + ').');
698
- }
699
- }
700
- else {
701
- if (undefined === query
702
- || null === query
703
- || false === primaryKey in query) {
704
- if (true === request.debug && isDevelopment) {
705
- toast.error('DEVS: The primary key (' + primaryKey + ') was not provided!!');
706
- }
707
- throw Error('You must provide the primary key (' + primaryKey + ') for table (' + operatingTable + '). Request (' + JSON.stringify(request, undefined, 4) + ') Query (' + JSON.stringify(query) + ')');
708
- }
709
- if (undefined === (query === null || query === void 0 ? void 0 : query[primaryKey])
710
- || null === (query === null || query === void 0 ? void 0 : query[primaryKey])) {
711
- toast.error('The primary key (' + primaryKey + ') provided is undefined or null explicitly!!');
712
- throw Error('The primary key (' + primaryKey + ') provided in the request was exactly equal to undefined.');
713
- }
714
- }
715
- }
716
- // A part of me exists that wants to remove this, but it's a good feature
717
- // this allows developers the ability to cache requests based on primary key
718
- // for tables like `photos` this can be a huge performance boost
719
- if (undefined !== query
720
- && null !== query
721
- && undefined !== primaryKey
722
- && primaryKey in query) {
723
- restRequestUri += query[primaryKey] + '/';
724
- var removedPkValue_1 = query[primaryKey];
725
- addBackPK = function () {
726
- query !== null && query !== void 0 ? query : (query = {});
727
- query[primaryKey] = removedPkValue_1;
728
- };
729
- delete query[primaryKey];
730
- console.log('query', query, 'primaryKey', primaryKey, 'removedPkValue', removedPkValue_1);
731
- }
732
- else {
733
- console.log('query', query);
734
- }
735
- try {
736
- console.groupCollapsed('%c API: (' + requestMethod + ') Request Query for (' + operatingTable + ') is about to fire, will return with promise!', 'color: #A020F0');
737
- console.log(request);
738
- 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');
739
- 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');
740
- console.trace();
741
- console.groupEnd();
742
- var axiosActiveRequest = axios[requestMethod.toLowerCase()].apply(axios, __spreadArray([restRequestUri], ((function () {
743
- // @link - https://axios-http.com/docs/instance
744
- // How configuration vs data is passed is variable, use documentation above for reference
745
- if (requestMethod === GET) {
746
- return [{
747
- withCredentials: withCredentials,
748
- params: query
749
- }];
750
- }
751
- else if (requestMethod === POST) {
752
- if (undefined !== (request === null || request === void 0 ? void 0 : request.dataInsertMultipleRows)) {
753
- return [
754
- request.dataInsertMultipleRows.map(function (data) {
755
- return convertForRequestBody(data, fullTableList, C6, function (message) { return toast.error(message, toastOptions); });
756
- }),
757
- {
758
- withCredentials: withCredentials,
759
- }
760
- ];
761
- }
762
- return [
763
- convertForRequestBody(query, fullTableList, C6, function (message) { return toast.error(message, toastOptions); }),
764
- {
765
- withCredentials: withCredentials,
766
- }
767
- ];
768
- }
769
- else if (requestMethod === PUT) {
770
- return [
771
- convertForRequestBody(query, fullTableList, C6, function (message) { return toast.error(message, toastOptions); }),
772
- {
773
- withCredentials: withCredentials,
774
- }
775
- ];
776
- }
777
- else if (requestMethod === DELETE) {
778
- return [{
779
- withCredentials: withCredentials,
780
- data: convertForRequestBody(query, fullTableList, C6, function (message) { return toast.error(message, toastOptions); })
781
- }];
782
- }
783
- else {
784
- throw new Error('The request method (' + requestMethod + ') was not recognized.');
785
- }
786
- })()), false));
787
- if (cachingConfirmed) {
788
- // push to cache so we do not repeat the request
789
- apiRequestCache.push({
790
- requestArgumentsSerialized: querySerialized,
791
- request: axiosActiveRequest
792
- });
793
- }
794
- // todo - wip verify this works
795
- // we had removed the value from the request to add to the URI.
796
- addBackPK === null || addBackPK === void 0 ? void 0 : addBackPK(); // adding back so post-processing methods work
797
- // returning the promise with this then is important for tests. todo - we could make that optional.
798
- // https://rapidapi.com/guides/axios-async-await
799
- return axiosActiveRequest.then(function (response) { return __awaiter(_this, void 0, void 0, function () {
800
- var cacheIndex, responseData_1, fetchDependencies, dependencies_1, fetchReferences_1, apiRequestPromises, _loop_1, _a, _b, _c, _i, tableToFetch;
862
+ return __awaiter(_this, __spreadArray([], args_1, true), void 0, function (request) {
863
+ // this could return itself with a new page number, or undefined if the end is reached
864
+ function apiRequest() {
865
+ return __awaiter(this, void 0, void 0, function () {
866
+ var querySerialized, cacheResult, cachingConfirmed, cacheCheck, cacheCheck, addBackPK, apiResponse, returnGetNextPageFunction, restRequestUri, needsConditionOrPrimaryCheck, TABLES, primaryKey, CarbonSqlExecutor, engine, removedPkValue_1, axiosActiveRequest;
801
867
  var _this = this;
802
- var _d, _e, _f, _g, _h, _j, _k, _l, _m;
803
- return __generator(this, function (_o) {
804
- switch (_o.label) {
868
+ var _a, _b, _c, _d, _e, _f, _g;
869
+ return __generator(this, function (_h) {
870
+ switch (_h.label) {
805
871
  case 0:
806
- if (typeof response.data === 'string') {
807
- if (isTest) {
808
- console.trace();
809
- throw new Error('The response data was a string this typically indicated html was sent. Make sure all cookies (' + JSON.stringify(response.config.headers) + ') needed are present! (' + response.data + ')');
810
- }
811
- return [2 /*return*/, Promise.reject(response)];
812
- }
813
- if (cachingConfirmed) {
814
- cacheIndex = apiRequestCache.findIndex(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
815
- apiRequestCache[cacheIndex].final = false === returnGetNextPageFunction;
816
- // only cache get method requests
817
- apiRequestCache[cacheIndex].response = response;
872
+ (_a = request.cacheResults) !== null && _a !== void 0 ? _a : (request.cacheResults = C6.GET === requestMethod);
873
+ if (C6.GET === requestMethod
874
+ && undefined !== ((_b = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _b === void 0 ? void 0 : _b[C6.PAGE])
875
+ && 1 !== query[C6.PAGINATION][C6.PAGE]) {
876
+ console.groupCollapsed('Request on table (' + tableName + ') is firing for page (' + query[C6.PAGINATION][C6.PAGE] + '), please wait!');
877
+ console.log('Request Data (note you may see the success and/or error prompt):', request);
878
+ console.trace();
879
+ console.groupEnd();
818
880
  }
819
- apiResponse = TestRestfulResponse(response, request === null || request === void 0 ? void 0 : request.success, (_d = request === null || request === void 0 ? void 0 : request.error) !== null && _d !== void 0 ? _d : "An unexpected API error occurred!");
820
- if (false === apiResponse) {
881
+ querySerialized = sortAndSerializeQueryObject(tables, query !== null && query !== void 0 ? query : {});
882
+ cacheResult = apiRequestCache.find(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
883
+ cachingConfirmed = false;
884
+ // determine if we need to paginate.
885
+ if (requestMethod === C6.GET) {
886
+ if (undefined === (query === null || query === void 0 ? void 0 : query[C6.PAGINATION])) {
887
+ if (undefined === query || null === query) {
888
+ query = {};
889
+ }
890
+ query[C6.PAGINATION] = {};
891
+ }
892
+ query[C6.PAGINATION][C6.PAGE] = query[C6.PAGINATION][C6.PAGE] || 1;
893
+ query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
894
+ // this will evaluate true most the time
895
+ if (true === request.cacheResults) {
896
+ // just find the next, non-fetched, page and return a function to request it
897
+ if (undefined !== cacheResult) {
898
+ do {
899
+ cacheCheck = checkCache(cacheResult, requestMethod, tableName, request);
900
+ if (false !== cacheCheck) {
901
+ return [2 /*return*/, cacheCheck];
902
+ }
903
+ // this line incrementing page is why we return recursively
904
+ ++query[C6.PAGINATION][C6.PAGE];
905
+ // this json stringify is to capture the new page number
906
+ querySerialized = sortAndSerializeQueryObject(tables, query !== null && query !== void 0 ? query : {});
907
+ cacheResult = apiRequestCache.find(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
908
+ } while (undefined !== cacheResult);
909
+ if (request.debug && isDevelopment) {
910
+ toast.warning("DEVS: Request in cache. (" + apiRequestCache.findIndex(function (cache) { return cache.requestArgumentsSerialized === querySerialized; }) + "). Returning function to request page (" + query[C6.PAGINATION][C6.PAGE] + ")", toastOptionsDevs);
911
+ }
912
+ // @ts-ignore - this is an incorrect warning on TS, it's well typed
913
+ return [2 /*return*/, apiRequest];
914
+ }
915
+ cachingConfirmed = true;
916
+ }
917
+ else {
918
+ if (request.debug && isDevelopment) {
919
+ toast.info("DEVS: Ignore cache was set to true.", toastOptionsDevs);
920
+ }
921
+ }
821
922
  if (request.debug && isDevelopment) {
822
- toast.warning("DEVS: TestRestfulResponse returned false for (" + operatingTable + ").", toastOptionsDevs);
923
+ toast.success("DEVS: Request not in cache." + (requestMethod === C6.GET ? "Page (" + query[C6.PAGINATION][C6.PAGE] + ")." : '') + " Logging cache 2 console.", toastOptionsDevs);
823
924
  }
824
- return [2 /*return*/, response];
825
925
  }
826
- // stateful operations are done in the response callback - its leverages rest generated functions
827
- if (responseCallback) {
828
- responseCallback(response, request, apiResponse);
926
+ else if (request.cacheResults) { // if we are not getting, we are updating, deleting, or inserting
927
+ if (cacheResult) {
928
+ cacheCheck = checkCache(cacheResult, requestMethod, tableName, request);
929
+ if (false !== cacheCheck) {
930
+ return [2 /*return*/, cacheCheck];
931
+ }
932
+ }
933
+ cachingConfirmed = true;
934
+ // push to cache so we do not repeat the request
829
935
  }
830
- if (!(C6.GET === requestMethod)) return [3 /*break*/, 6];
831
- responseData_1 = response.data;
832
- returnGetNextPageFunction = 1 !== ((_e = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _e === void 0 ? void 0 : _e[C6.LIMIT]) &&
833
- ((_f = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _f === void 0 ? void 0 : _f[C6.LIMIT]) === responseData_1.rest.length;
834
- if (false === isTest || true === isVerbose) {
835
- console.groupCollapsed('%c API: Response (' + requestMethod + ' ' + tableName + ') returned length (' + ((_g = responseData_1.rest) === null || _g === void 0 ? void 0 : _g.length) + ') of possible (' + ((_h = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _h === void 0 ? void 0 : _h[C6.LIMIT]) + ') limit!', 'color: #0c0');
836
- console.log('%c ' + requestMethod + ' ' + tableName, 'color: #0c0');
837
- console.log('%c Request Data (note you may see the success and/or error prompt):', 'color: #0c0', request);
838
- console.log('%c Response Data:', 'color: #0c0', responseData_1.rest);
839
- console.log('%c Will return get next page function:' + (1 !== ((_j = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _j === void 0 ? void 0 : _j[C6.LIMIT]) ? '' : ' (Will not return with explicit limit 1 set)'), 'color: #0c0', true === returnGetNextPageFunction);
840
- console.trace();
841
- console.groupEnd();
936
+ returnGetNextPageFunction = false;
937
+ restRequestUri = restURL + operatingTable + '/';
938
+ needsConditionOrPrimaryCheck = (PUT === requestMethod || DELETE === requestMethod)
939
+ && false === skipPrimaryCheck;
940
+ TABLES = C6.TABLES;
941
+ primaryKey = (_f = (_e = (_d = structuredClone((_c = TABLES[operatingTable]) === null || _c === void 0 ? void 0 : _c.PRIMARY)) === null || _d === void 0 ? void 0 : _d.pop()) === null || _e === void 0 ? void 0 : _e.split('.')) === null || _f === void 0 ? void 0 : _f.pop();
942
+ if (needsConditionOrPrimaryCheck) {
943
+ if (undefined === primaryKey) {
944
+ if (null === query
945
+ || undefined === query
946
+ || undefined === (query === null || query === void 0 ? void 0 : query[C6.WHERE])
947
+ || (true === Array.isArray(query[C6.WHERE])
948
+ || query[C6.WHERE].length === 0)
949
+ || (Object.keys(query === null || query === void 0 ? void 0 : query[C6.WHERE]).length === 0)) {
950
+ console.error(query);
951
+ throw Error('Failed to parse primary key information. Query: (' + JSON.stringify(query) + ') Primary Key: (' + JSON.stringify(primaryKey) + ') TABLES[operatingTable]?.PRIMARY: (' + JSON.stringify((_g = TABLES[operatingTable]) === null || _g === void 0 ? void 0 : _g.PRIMARY) + ') for operatingTable (' + operatingTable + ').');
952
+ }
953
+ }
954
+ else {
955
+ if (undefined === query
956
+ || null === query
957
+ || false === primaryKey in query) {
958
+ if (true === request.debug && isDevelopment) {
959
+ toast.error('DEVS: The primary key (' + primaryKey + ') was not provided!!');
960
+ }
961
+ throw Error('You must provide the primary key (' + primaryKey + ') for table (' + operatingTable + '). Request (' + JSON.stringify(request, undefined, 4) + ') Query (' + JSON.stringify(query) + ')');
962
+ }
963
+ if (undefined === (query === null || query === void 0 ? void 0 : query[primaryKey])
964
+ || null === (query === null || query === void 0 ? void 0 : query[primaryKey])) {
965
+ toast.error('The primary key (' + primaryKey + ') provided is undefined or null explicitly!!');
966
+ throw Error('The primary key (' + primaryKey + ') provided in the request was exactly equal to undefined.');
967
+ }
968
+ }
842
969
  }
843
- if (false === returnGetNextPageFunction
844
- && true === request.debug
845
- && isDevelopment) {
846
- toast.success("DEVS: Response returned length (" + ((_k = responseData_1.rest) === null || _k === void 0 ? void 0 : _k.length) + ") less than limit (" + ((_l = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _l === void 0 ? void 0 : _l[C6.LIMIT]) + ").", toastOptionsDevs);
970
+ if (!(isNode && mysqlPool)) return [3 /*break*/, 2];
971
+ return [4 /*yield*/, Promise.resolve().then(function () { return carbonSqlExecutor; })];
972
+ case 1:
973
+ CarbonSqlExecutor = (_h.sent()).CarbonSqlExecutor;
974
+ engine = new CarbonSqlExecutor(mysqlPool, C6);
975
+ switch (requestMethod) {
976
+ case GET:
977
+ return [2 /*return*/, engine
978
+ .select(tableName, undefined, request)
979
+ .then(function (rows) {
980
+ // mirror the front‐end shape
981
+ var serverResponse = {
982
+ rest: rows,
983
+ session: undefined,
984
+ sql: true,
985
+ };
986
+ return serverResponse;
987
+ })];
988
+ case POST:
989
+ return [2 /*return*/, engine
990
+ .insert(tableName, request)
991
+ .then(function (created) { return ({
992
+ rest: created,
993
+ }); })];
994
+ case PUT:
995
+ return [2 /*return*/, engine
996
+ .update(tableName, undefined, request)
997
+ .then(function (updatedResult) {
998
+ var _a;
999
+ return ({
1000
+ rest: updatedResult,
1001
+ rowCount: (_a = updatedResult.affectedRows) !== null && _a !== void 0 ? _a : 0,
1002
+ });
1003
+ })];
1004
+ case DELETE:
1005
+ return [2 /*return*/, engine
1006
+ .delete(tableName, undefined, request)
1007
+ .then(function (deletedResult) {
1008
+ var _a;
1009
+ return ({
1010
+ rest: deletedResult,
1011
+ rowCount: (_a = deletedResult.affectedRows) !== null && _a !== void 0 ? _a : 0,
1012
+ deleted: true,
1013
+ });
1014
+ })];
1015
+ default:
1016
+ throw new Error("Unsupported method: ".concat(requestMethod));
847
1017
  }
848
- (_m = request.fetchDependencies) !== null && _m !== void 0 ? _m : (request.fetchDependencies = eFetchDependencies.NONE);
849
- if (!(request.fetchDependencies
850
- && 'number' === typeof request.fetchDependencies
851
- && responseData_1.rest.length > 0)) return [3 /*break*/, 6];
852
- fetchDependencies = request.fetchDependencies;
853
- console.groupCollapsed('%c API: Fetch Dependencies segment (' + requestMethod + ' ' + tableName + ')'
854
- + (fetchDependencies & eFetchDependencies.CHILDREN ? ' | (CHILDREN|REFERENCED) ' : '')
855
- + (fetchDependencies & eFetchDependencies.PARENTS ? ' | (PARENTS|REFERENCED_BY)' : '')
856
- + (fetchDependencies & eFetchDependencies.C6ENTITY ? ' | (C6ENTITY)' : '')
857
- + (fetchDependencies & eFetchDependencies.RECURSIVE ? ' | (RECURSIVE)' : ''), 'color: #33ccff');
858
- console.groupCollapsed('Collapsed JS Trace');
859
- console.trace(); // hidden in collapsed group
860
- console.groupEnd();
861
- dependencies_1 = {};
862
- if (fetchDependencies & eFetchDependencies.C6ENTITY) {
863
- dependencies_1 = operatingTable.endsWith("carbon_carbons")
864
- ? __assign(__assign({}, fetchDependencies & eFetchDependencies.CHILDREN // REFERENCED === CHILDREN
865
- ? C6.TABLES[operatingTable].TABLE_REFERENCED_BY
866
- : {}), fetchDependencies & eFetchDependencies.PARENTS // REFERENCES === PARENTS
867
- ? C6.TABLES[operatingTable].TABLE_REFERENCES
868
- : {}) : __assign(__assign({}, fetchDependencies & eFetchDependencies.CHILDREN // REFERENCED === CHILDREN
869
- ? __assign(__assign({}, Object.keys(C6.TABLES[operatingTable].TABLE_REFERENCES).reduce(function (accumulator, columnName) {
870
- if (!C6.TABLES[operatingTable].PRIMARY_SHORT.includes(columnName)) {
871
- accumulator[columnName] = C6.TABLES[operatingTable].TABLE_REFERENCES[columnName];
872
- }
873
- return accumulator;
874
- }, {})), C6.TABLES[operatingTable].TABLE_REFERENCED_BY // it is unlikely that a C6 table will have any TABLE_REFERENCED_BY
875
- ) : {}), fetchDependencies & eFetchDependencies.PARENTS // REFERENCES === PARENTS
876
- ? C6.TABLES[operatingTable].PRIMARY_SHORT.reduce(function (accumulator, primaryKey) {
877
- if (primaryKey in C6.TABLES[operatingTable].TABLE_REFERENCES) {
878
- accumulator[primaryKey] = C6.TABLES[operatingTable].TABLE_REFERENCES[primaryKey];
879
- }
880
- return accumulator;
881
- }, {})
882
- : {});
1018
+ case 2:
1019
+ // A part of me exists that wants to remove this, but it's a good feature
1020
+ // this allows developers the ability to cache requests based on primary key
1021
+ // for tables like `photos` this can be a huge performance boost
1022
+ if (undefined !== query
1023
+ && null !== query
1024
+ && undefined !== primaryKey
1025
+ && primaryKey in query) {
1026
+ restRequestUri += query[primaryKey] + '/';
1027
+ removedPkValue_1 = query[primaryKey];
1028
+ addBackPK = function () {
1029
+ query !== null && query !== void 0 ? query : (query = {});
1030
+ query[primaryKey] = removedPkValue_1;
1031
+ };
1032
+ delete query[primaryKey];
1033
+ console.log('query', query, 'primaryKey', primaryKey, 'removedPkValue', removedPkValue_1);
883
1034
  }
884
1035
  else {
885
- // this is the natural mysql context
886
- dependencies_1 = __assign(__assign({}, fetchDependencies & eFetchDependencies.REFERENCED // REFERENCED === CHILDREN
887
- ? C6.TABLES[operatingTable].TABLE_REFERENCED_BY
888
- : {}), fetchDependencies & eFetchDependencies.REFERENCES // REFERENCES === PARENTS
889
- ? C6.TABLES[operatingTable].TABLE_REFERENCES
890
- : {});
1036
+ console.log('query', query);
891
1037
  }
892
- fetchReferences_1 = {};
893
- apiRequestPromises = [];
894
- console.log('%c Dependencies', 'color: #005555', dependencies_1);
895
- Object.keys(dependencies_1)
896
- .forEach(function (column) { return dependencies_1[column]
897
- .forEach(function (constraint) {
898
- var _a, _b, _c, _d;
899
- var _e, _f, _g;
900
- var columnValues = (_b = (_a = responseData_1.rest[column]) !== null && _a !== void 0 ? _a : responseData_1.rest.map(function (row) {
901
- if (operatingTable.endsWith("carbons")
902
- && 'entity_tag' in row
903
- && !constraint.TABLE.endsWith(row['entity_tag'].split('\\').pop().toLowerCase())) {
904
- return false; // map
905
- }
906
- if (!(column in row)) {
907
- return false;
1038
+ try {
1039
+ console.groupCollapsed('%c API: (' + requestMethod + ') Request Query for (' + operatingTable + ') is about to fire, will return with promise!', 'color: #A020F0');
1040
+ console.log(request);
1041
+ 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');
1042
+ 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');
1043
+ console.trace();
1044
+ console.groupEnd();
1045
+ axiosActiveRequest = axios[requestMethod.toLowerCase()].apply(axios, __spreadArray([restRequestUri], ((function () {
1046
+ // @link - https://axios-http.com/docs/instance
1047
+ // How configuration vs data is passed is variable, use documentation above for reference
1048
+ if (requestMethod === GET) {
1049
+ return [{
1050
+ withCredentials: withCredentials,
1051
+ params: query
1052
+ }];
908
1053
  }
909
- // todo - row[column] is a FK value, we should optionally remove values that are already in state
910
- // this could be any column in the table constraint.TABLE, not just the primary key
911
- return row[column];
912
- }).filter(function (n) { return n; })) !== null && _b !== void 0 ? _b : [];
913
- if (columnValues.length === 0) {
914
- return; // forEach
915
- }
916
- (_c = fetchReferences_1[_e = constraint.TABLE]) !== null && _c !== void 0 ? _c : (fetchReferences_1[_e] = {});
917
- (_d = (_f = fetchReferences_1[constraint.TABLE])[_g = constraint.COLUMN]) !== null && _d !== void 0 ? _d : (_f[_g] = []);
918
- fetchReferences_1[constraint.TABLE][constraint.COLUMN].push(columnValues);
919
- }); });
920
- console.log('fetchReferences', fetchReferences_1);
921
- _loop_1 = function (tableToFetch) {
922
- var referencesTables, shouldContinue, fetchTable, RestApi, nextFetchDependencies;
923
- var _p;
924
- return __generator(this, function (_q) {
925
- switch (_q.label) {
926
- case 0:
927
- if (fetchDependencies & eFetchDependencies.C6ENTITY
928
- && 'string' === typeof tableName
929
- && tableName.endsWith("carbon_carbons")) {
930
- referencesTables = responseData_1.rest.reduce(function (accumulator, row) {
931
- if ('entity_tag' in row && !accumulator.includes(row['entity_tag'])) {
932
- accumulator.push(row['entity_tag']);
933
- }
934
- return accumulator;
935
- }, []).map(function (entityTag) { return entityTag.split('\\').pop().toLowerCase(); });
936
- shouldContinue = referencesTables.find(function (referencesTable) { return tableToFetch.endsWith(referencesTable); });
937
- if (!shouldContinue) {
938
- console.log('%c C6ENTITY: The constraintTableName (' + tableToFetch + ') did not end with any value in referencesTables', 'color: #c00', referencesTables);
939
- return [2 /*return*/, "continue"];
940
- }
941
- console.log('%c C6ENTITY: The constraintTableName (' + tableToFetch + ') will be fetched.', 'color: #0c0');
942
- }
943
- return [4 /*yield*/, C6.IMPORT(tableToFetch)];
944
- case 1:
945
- fetchTable = _q.sent();
946
- RestApi = fetchTable.default;
947
- console.log('%c Fetch Dependencies will select (' + tableToFetch + ') using GET request', 'color: #33ccff');
948
- nextFetchDependencies = eFetchDependencies.NONE;
949
- if (fetchDependencies & eFetchDependencies.RECURSIVE) {
950
- if (fetchDependencies & eFetchDependencies.ALL) {
951
- throw Error('Recursive fetch dependencies with both PARENT and CHILD reference will result in an infin1ite loop. As there is not real ending condition, this is not supported.');
952
- }
953
- nextFetchDependencies = fetchDependencies;
954
- }
955
- else if (fetchDependencies & eFetchDependencies.C6ENTITY) {
956
- if (tableToFetch === "carbon_carbons") {
957
- nextFetchDependencies = fetchDependencies;
958
- }
959
- else {
960
- nextFetchDependencies = fetchDependencies ^ eFetchDependencies.C6ENTITY;
1054
+ else if (requestMethod === POST) {
1055
+ if (undefined !== (request === null || request === void 0 ? void 0 : request.dataInsertMultipleRows)) {
1056
+ return [
1057
+ request.dataInsertMultipleRows.map(function (data) {
1058
+ return convertForRequestBody(data, fullTableList, C6, function (message) { return toast.error(message, toastOptions); });
1059
+ }),
1060
+ {
1061
+ withCredentials: withCredentials,
961
1062
  }
1063
+ ];
1064
+ }
1065
+ return [
1066
+ convertForRequestBody(query, fullTableList, C6, function (message) { return toast.error(message, toastOptions); }),
1067
+ {
1068
+ withCredentials: withCredentials,
962
1069
  }
963
- console.log('fetchReferences', fetchReferences_1[tableToFetch], "Current fetchDependencies for (" + operatingTable + "):", fetchDependencies, "New fetchDependencies for (" + tableToFetch + "): ", nextFetchDependencies);
964
- // todo - filter out ids that exist in state?!? note - remember that this does not necessarily mean the pk, but only known is its an FK to somewhere
965
- // it not certain that they are using carbons' entities either
966
- // this is a dynamic call to the rest api, any generated table may resolve with (RestApi)
967
- // todo - using value to avoid joins.... but. maybe this should be a parameterizable option -- think race conditions; its safer to join
968
- apiRequestPromises.push(RestApi.Get((_p = {},
969
- _p[C6.WHERE] = {
970
- 0: Object.keys(fetchReferences_1[tableToFetch]).reduce(function (sum, column) {
971
- fetchReferences_1[tableToFetch][column] = fetchReferences_1[tableToFetch][column].flat(Infinity);
972
- if (0 === fetchReferences_1[tableToFetch][column].length) {
973
- console.warn('The column (' + column + ') was not found in the response data. We will not fetch.', responseData_1);
974
- return false;
975
- }
976
- sum[column] = fetchReferences_1[tableToFetch][column].length === 1
977
- ? fetchReferences_1[tableToFetch][column][0]
978
- : [
979
- C6.IN, fetchReferences_1[tableToFetch][column]
980
- ];
981
- return sum;
982
- }, {})
983
- },
984
- _p.fetchDependencies = nextFetchDependencies,
985
- _p)));
986
- return [2 /*return*/];
1070
+ ];
987
1071
  }
988
- });
989
- };
990
- _a = fetchReferences_1;
991
- _b = [];
992
- for (_c in _a)
993
- _b.push(_c);
994
- _i = 0;
995
- _o.label = 1;
996
- case 1:
997
- if (!(_i < _b.length)) return [3 /*break*/, 4];
998
- _c = _b[_i];
999
- if (!(_c in _a)) return [3 /*break*/, 3];
1000
- tableToFetch = _c;
1001
- return [5 /*yield**/, _loop_1(tableToFetch)];
1002
- case 2:
1003
- _o.sent();
1004
- _o.label = 3;
1005
- case 3:
1006
- _i++;
1007
- return [3 /*break*/, 1];
1008
- case 4:
1009
- console.groupEnd();
1010
- return [4 /*yield*/, Promise.all(apiRequestPromises)];
1011
- case 5:
1012
- _o.sent();
1013
- apiRequestPromises.map(function (promise) { return __awaiter(_this, void 0, void 0, function () {
1014
- var _a, _b;
1015
- return __generator(this, function (_c) {
1016
- switch (_c.label) {
1017
- case 0:
1018
- if (!Array.isArray(request.fetchDependencies)) {
1019
- request.fetchDependencies = [];
1072
+ else if (requestMethod === PUT) {
1073
+ return [
1074
+ convertForRequestBody(query, fullTableList, C6, function (message) { return toast.error(message, toastOptions); }),
1075
+ {
1076
+ withCredentials: withCredentials,
1020
1077
  }
1021
- _b = (_a = request.fetchDependencies).push;
1022
- return [4 /*yield*/, promise];
1023
- case 1:
1024
- _b.apply(_a, [_c.sent()]);
1025
- return [2 /*return*/];
1078
+ ];
1026
1079
  }
1027
- });
1028
- }); });
1029
- _o.label = 6;
1030
- case 6:
1031
- if (request.debug && isDevelopment) {
1032
- toast.success("DEVS: (" + requestMethod + ") request complete.", toastOptionsDevs);
1080
+ else if (requestMethod === DELETE) {
1081
+ return [{
1082
+ withCredentials: withCredentials,
1083
+ data: convertForRequestBody(query, fullTableList, C6, function (message) { return toast.error(message, toastOptions); })
1084
+ }];
1085
+ }
1086
+ else {
1087
+ throw new Error('The request method (' + requestMethod + ') was not recognized.');
1088
+ }
1089
+ })()), false));
1090
+ if (cachingConfirmed) {
1091
+ // push to cache so we do not repeat the request
1092
+ apiRequestCache.push({
1093
+ requestArgumentsSerialized: querySerialized,
1094
+ request: axiosActiveRequest
1095
+ });
1096
+ }
1097
+ // todo - wip verify this works
1098
+ // we had removed the value from the request to add to the URI.
1099
+ addBackPK === null || addBackPK === void 0 ? void 0 : addBackPK(); // adding back so post-processing methods work
1100
+ // returning the promise with this then is important for tests. todo - we could make that optional.
1101
+ // https://rapidapi.com/guides/axios-async-await
1102
+ return [2 /*return*/, axiosActiveRequest.then(function (response) { return __awaiter(_this, void 0, void 0, function () {
1103
+ var cacheIndex, responseData_1, fetchDependencies, dependencies_1, fetchReferences_1, apiRequestPromises, _loop_1, _a, _b, _c, _i, tableToFetch;
1104
+ var _this = this;
1105
+ var _d, _e, _f, _g, _h, _j, _k, _l, _m;
1106
+ return __generator(this, function (_o) {
1107
+ switch (_o.label) {
1108
+ case 0:
1109
+ if (typeof response.data === 'string') {
1110
+ if (isTest) {
1111
+ console.trace();
1112
+ throw new Error('The response data was a string this typically indicated html was sent. Make sure all cookies (' + JSON.stringify(response.config.headers) + ') needed are present! (' + response.data + ')');
1113
+ }
1114
+ return [2 /*return*/, Promise.reject(response)];
1115
+ }
1116
+ if (cachingConfirmed) {
1117
+ cacheIndex = apiRequestCache.findIndex(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
1118
+ apiRequestCache[cacheIndex].final = false === returnGetNextPageFunction;
1119
+ // only cache get method requests
1120
+ apiRequestCache[cacheIndex].response = response;
1121
+ }
1122
+ apiResponse = TestRestfulResponse(response, request === null || request === void 0 ? void 0 : request.success, (_d = request === null || request === void 0 ? void 0 : request.error) !== null && _d !== void 0 ? _d : "An unexpected API error occurred!");
1123
+ if (false === apiResponse) {
1124
+ if (request.debug && isDevelopment) {
1125
+ toast.warning("DEVS: TestRestfulResponse returned false for (" + operatingTable + ").", toastOptionsDevs);
1126
+ }
1127
+ return [2 /*return*/, response];
1128
+ }
1129
+ // stateful operations are done in the response callback - its leverages rest generated functions
1130
+ if (responseCallback) {
1131
+ responseCallback(response, request, apiResponse);
1132
+ }
1133
+ if (!(C6.GET === requestMethod)) return [3 /*break*/, 6];
1134
+ responseData_1 = response.data;
1135
+ returnGetNextPageFunction = 1 !== ((_e = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _e === void 0 ? void 0 : _e[C6.LIMIT]) &&
1136
+ ((_f = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _f === void 0 ? void 0 : _f[C6.LIMIT]) === responseData_1.rest.length;
1137
+ if (false === isTest || true === isVerbose) {
1138
+ console.groupCollapsed('%c API: Response (' + requestMethod + ' ' + tableName + ') returned length (' + ((_g = responseData_1.rest) === null || _g === void 0 ? void 0 : _g.length) + ') of possible (' + ((_h = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _h === void 0 ? void 0 : _h[C6.LIMIT]) + ') limit!', 'color: #0c0');
1139
+ console.log('%c ' + requestMethod + ' ' + tableName, 'color: #0c0');
1140
+ console.log('%c Request Data (note you may see the success and/or error prompt):', 'color: #0c0', request);
1141
+ console.log('%c Response Data:', 'color: #0c0', responseData_1.rest);
1142
+ console.log('%c Will return get next page function:' + (1 !== ((_j = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _j === void 0 ? void 0 : _j[C6.LIMIT]) ? '' : ' (Will not return with explicit limit 1 set)'), 'color: #0c0', true === returnGetNextPageFunction);
1143
+ console.trace();
1144
+ console.groupEnd();
1145
+ }
1146
+ if (false === returnGetNextPageFunction
1147
+ && true === request.debug
1148
+ && isDevelopment) {
1149
+ toast.success("DEVS: Response returned length (" + ((_k = responseData_1.rest) === null || _k === void 0 ? void 0 : _k.length) + ") less than limit (" + ((_l = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _l === void 0 ? void 0 : _l[C6.LIMIT]) + ").", toastOptionsDevs);
1150
+ }
1151
+ (_m = request.fetchDependencies) !== null && _m !== void 0 ? _m : (request.fetchDependencies = eFetchDependencies.NONE);
1152
+ if (!(request.fetchDependencies
1153
+ && 'number' === typeof request.fetchDependencies
1154
+ && responseData_1.rest.length > 0)) return [3 /*break*/, 6];
1155
+ fetchDependencies = request.fetchDependencies;
1156
+ console.groupCollapsed('%c API: Fetch Dependencies segment (' + requestMethod + ' ' + tableName + ')'
1157
+ + (fetchDependencies & eFetchDependencies.CHILDREN ? ' | (CHILDREN|REFERENCED) ' : '')
1158
+ + (fetchDependencies & eFetchDependencies.PARENTS ? ' | (PARENTS|REFERENCED_BY)' : '')
1159
+ + (fetchDependencies & eFetchDependencies.C6ENTITY ? ' | (C6ENTITY)' : '')
1160
+ + (fetchDependencies & eFetchDependencies.RECURSIVE ? ' | (RECURSIVE)' : ''), 'color: #33ccff');
1161
+ console.groupCollapsed('Collapsed JS Trace');
1162
+ console.trace(); // hidden in collapsed group
1163
+ console.groupEnd();
1164
+ dependencies_1 = {};
1165
+ if (fetchDependencies & eFetchDependencies.C6ENTITY) {
1166
+ dependencies_1 = operatingTable.endsWith("carbon_carbons")
1167
+ ? __assign(__assign({}, fetchDependencies & eFetchDependencies.CHILDREN // REFERENCED === CHILDREN
1168
+ ? C6.TABLES[operatingTable].TABLE_REFERENCED_BY
1169
+ : {}), fetchDependencies & eFetchDependencies.PARENTS // REFERENCES === PARENTS
1170
+ ? C6.TABLES[operatingTable].TABLE_REFERENCES
1171
+ : {}) : __assign(__assign({}, fetchDependencies & eFetchDependencies.CHILDREN // REFERENCED === CHILDREN
1172
+ ? __assign(__assign({}, Object.keys(C6.TABLES[operatingTable].TABLE_REFERENCES).reduce(function (accumulator, columnName) {
1173
+ if (!C6.TABLES[operatingTable].PRIMARY_SHORT.includes(columnName)) {
1174
+ accumulator[columnName] = C6.TABLES[operatingTable].TABLE_REFERENCES[columnName];
1175
+ }
1176
+ return accumulator;
1177
+ }, {})), C6.TABLES[operatingTable].TABLE_REFERENCED_BY // it is unlikely that a C6 table will have any TABLE_REFERENCED_BY
1178
+ ) : {}), fetchDependencies & eFetchDependencies.PARENTS // REFERENCES === PARENTS
1179
+ ? C6.TABLES[operatingTable].PRIMARY_SHORT.reduce(function (accumulator, primaryKey) {
1180
+ if (primaryKey in C6.TABLES[operatingTable].TABLE_REFERENCES) {
1181
+ accumulator[primaryKey] = C6.TABLES[operatingTable].TABLE_REFERENCES[primaryKey];
1182
+ }
1183
+ return accumulator;
1184
+ }, {})
1185
+ : {});
1186
+ }
1187
+ else {
1188
+ // this is the natural mysql context
1189
+ dependencies_1 = __assign(__assign({}, fetchDependencies & eFetchDependencies.REFERENCED // REFERENCED === CHILDREN
1190
+ ? C6.TABLES[operatingTable].TABLE_REFERENCED_BY
1191
+ : {}), fetchDependencies & eFetchDependencies.REFERENCES // REFERENCES === PARENTS
1192
+ ? C6.TABLES[operatingTable].TABLE_REFERENCES
1193
+ : {});
1194
+ }
1195
+ fetchReferences_1 = {};
1196
+ apiRequestPromises = [];
1197
+ console.log('%c Dependencies', 'color: #005555', dependencies_1);
1198
+ Object.keys(dependencies_1)
1199
+ .forEach(function (column) { return dependencies_1[column]
1200
+ .forEach(function (constraint) {
1201
+ var _a, _b, _c, _d;
1202
+ var _e, _f, _g;
1203
+ var columnValues = (_b = (_a = responseData_1.rest[column]) !== null && _a !== void 0 ? _a : responseData_1.rest.map(function (row) {
1204
+ if (operatingTable.endsWith("carbons")
1205
+ && 'entity_tag' in row
1206
+ && !constraint.TABLE.endsWith(row['entity_tag'].split('\\').pop().toLowerCase())) {
1207
+ return false; // map
1208
+ }
1209
+ if (!(column in row)) {
1210
+ return false;
1211
+ }
1212
+ // todo - row[column] is a FK value, we should optionally remove values that are already in state
1213
+ // this could be any column in the table constraint.TABLE, not just the primary key
1214
+ return row[column];
1215
+ }).filter(function (n) { return n; })) !== null && _b !== void 0 ? _b : [];
1216
+ if (columnValues.length === 0) {
1217
+ return; // forEach
1218
+ }
1219
+ (_c = fetchReferences_1[_e = constraint.TABLE]) !== null && _c !== void 0 ? _c : (fetchReferences_1[_e] = {});
1220
+ (_d = (_f = fetchReferences_1[constraint.TABLE])[_g = constraint.COLUMN]) !== null && _d !== void 0 ? _d : (_f[_g] = []);
1221
+ fetchReferences_1[constraint.TABLE][constraint.COLUMN].push(columnValues);
1222
+ }); });
1223
+ console.log('fetchReferences', fetchReferences_1);
1224
+ _loop_1 = function (tableToFetch) {
1225
+ var referencesTables, shouldContinue, fetchTable, RestApi, nextFetchDependencies;
1226
+ var _p;
1227
+ return __generator(this, function (_q) {
1228
+ switch (_q.label) {
1229
+ case 0:
1230
+ if (fetchDependencies & eFetchDependencies.C6ENTITY
1231
+ && 'string' === typeof tableName
1232
+ && tableName.endsWith("carbon_carbons")) {
1233
+ referencesTables = responseData_1.rest.reduce(function (accumulator, row) {
1234
+ if ('entity_tag' in row && !accumulator.includes(row['entity_tag'])) {
1235
+ accumulator.push(row['entity_tag']);
1236
+ }
1237
+ return accumulator;
1238
+ }, []).map(function (entityTag) { return entityTag.split('\\').pop().toLowerCase(); });
1239
+ shouldContinue = referencesTables.find(function (referencesTable) { return tableToFetch.endsWith(referencesTable); });
1240
+ if (!shouldContinue) {
1241
+ console.log('%c C6ENTITY: The constraintTableName (' + tableToFetch + ') did not end with any value in referencesTables', 'color: #c00', referencesTables);
1242
+ return [2 /*return*/, "continue"];
1243
+ }
1244
+ console.log('%c C6ENTITY: The constraintTableName (' + tableToFetch + ') will be fetched.', 'color: #0c0');
1245
+ }
1246
+ return [4 /*yield*/, C6.IMPORT(tableToFetch)];
1247
+ case 1:
1248
+ fetchTable = _q.sent();
1249
+ RestApi = fetchTable.default;
1250
+ console.log('%c Fetch Dependencies will select (' + tableToFetch + ') using GET request', 'color: #33ccff');
1251
+ nextFetchDependencies = eFetchDependencies.NONE;
1252
+ if (fetchDependencies & eFetchDependencies.RECURSIVE) {
1253
+ if (fetchDependencies & eFetchDependencies.ALL) {
1254
+ throw Error('Recursive fetch dependencies with both PARENT and CHILD reference will result in an infin1ite loop. As there is not real ending condition, this is not supported.');
1255
+ }
1256
+ nextFetchDependencies = fetchDependencies;
1257
+ }
1258
+ else if (fetchDependencies & eFetchDependencies.C6ENTITY) {
1259
+ if (tableToFetch === "carbon_carbons") {
1260
+ nextFetchDependencies = fetchDependencies;
1261
+ }
1262
+ else {
1263
+ nextFetchDependencies = fetchDependencies ^ eFetchDependencies.C6ENTITY;
1264
+ }
1265
+ }
1266
+ console.log('fetchReferences', fetchReferences_1[tableToFetch], "Current fetchDependencies for (" + operatingTable + "):", fetchDependencies, "New fetchDependencies for (" + tableToFetch + "): ", nextFetchDependencies);
1267
+ // todo - filter out ids that exist in state?!? note - remember that this does not necessarily mean the pk, but only known is its an FK to somewhere
1268
+ // it not certain that they are using carbons' entities either
1269
+ // this is a dynamic call to the rest api, any generated table may resolve with (RestApi)
1270
+ // todo - using value to avoid joins.... but. maybe this should be a parameterizable option -- think race conditions; its safer to join
1271
+ apiRequestPromises.push(RestApi.Get((_p = {},
1272
+ _p[C6.WHERE] = {
1273
+ 0: Object.keys(fetchReferences_1[tableToFetch]).reduce(function (sum, column) {
1274
+ fetchReferences_1[tableToFetch][column] = fetchReferences_1[tableToFetch][column].flat(Infinity);
1275
+ if (0 === fetchReferences_1[tableToFetch][column].length) {
1276
+ console.warn('The column (' + column + ') was not found in the response data. We will not fetch.', responseData_1);
1277
+ return false;
1278
+ }
1279
+ sum[column] = fetchReferences_1[tableToFetch][column].length === 1
1280
+ ? fetchReferences_1[tableToFetch][column][0]
1281
+ : [
1282
+ C6.IN, fetchReferences_1[tableToFetch][column]
1283
+ ];
1284
+ return sum;
1285
+ }, {})
1286
+ },
1287
+ _p.fetchDependencies = nextFetchDependencies,
1288
+ _p)));
1289
+ return [2 /*return*/];
1290
+ }
1291
+ });
1292
+ };
1293
+ _a = fetchReferences_1;
1294
+ _b = [];
1295
+ for (_c in _a)
1296
+ _b.push(_c);
1297
+ _i = 0;
1298
+ _o.label = 1;
1299
+ case 1:
1300
+ if (!(_i < _b.length)) return [3 /*break*/, 4];
1301
+ _c = _b[_i];
1302
+ if (!(_c in _a)) return [3 /*break*/, 3];
1303
+ tableToFetch = _c;
1304
+ return [5 /*yield**/, _loop_1(tableToFetch)];
1305
+ case 2:
1306
+ _o.sent();
1307
+ _o.label = 3;
1308
+ case 3:
1309
+ _i++;
1310
+ return [3 /*break*/, 1];
1311
+ case 4:
1312
+ console.groupEnd();
1313
+ return [4 /*yield*/, Promise.all(apiRequestPromises)];
1314
+ case 5:
1315
+ _o.sent();
1316
+ apiRequestPromises.map(function (promise) { return __awaiter(_this, void 0, void 0, function () {
1317
+ var _a, _b;
1318
+ return __generator(this, function (_c) {
1319
+ switch (_c.label) {
1320
+ case 0:
1321
+ if (!Array.isArray(request.fetchDependencies)) {
1322
+ request.fetchDependencies = [];
1323
+ }
1324
+ _b = (_a = request.fetchDependencies).push;
1325
+ return [4 /*yield*/, promise];
1326
+ case 1:
1327
+ _b.apply(_a, [_c.sent()]);
1328
+ return [2 /*return*/];
1329
+ }
1330
+ });
1331
+ }); });
1332
+ _o.label = 6;
1333
+ case 6:
1334
+ if (request.debug && isDevelopment) {
1335
+ toast.success("DEVS: (" + requestMethod + ") request complete.", toastOptionsDevs);
1336
+ }
1337
+ return [2 /*return*/, response];
1338
+ }
1339
+ });
1340
+ }); })];
1341
+ }
1342
+ catch (error) {
1343
+ if (isTest) {
1344
+ throw new Error(JSON.stringify(error));
1345
+ }
1346
+ console.groupCollapsed('%c API: An error occurred in the try catch block. returning null!', 'color: #ff0000');
1347
+ console.log('%c ' + requestMethod + ' ' + tableName, 'color: #A020F0');
1348
+ console.warn(error);
1349
+ console.trace();
1350
+ console.groupEnd();
1351
+ TestRestfulResponse(error, request === null || request === void 0 ? void 0 : request.success, (request === null || request === void 0 ? void 0 : request.error) || "An restful API error occurred!");
1352
+ return [2 /*return*/, null];
1033
1353
  }
1034
- return [2 /*return*/, response];
1354
+ return [2 /*return*/];
1035
1355
  }
1036
1356
  });
1037
- }); });
1357
+ });
1038
1358
  }
1039
- catch (error) {
1040
- if (isTest) {
1041
- throw new Error(JSON.stringify(error));
1359
+ var query;
1360
+ if (request === void 0) { request = {}; }
1361
+ return __generator(this, function (_a) {
1362
+ switch (_a.label) {
1363
+ case 0:
1364
+ console.groupCollapsed('%c API: (' + requestMethod + ') Request for (' + operatingTable + ')', 'color: #0c0');
1365
+ console.log('request', request);
1366
+ console.groupEnd();
1367
+ if ('function' === typeof queryCallback) {
1368
+ query = queryCallback(request); // obj or obj[]
1369
+ }
1370
+ else {
1371
+ query = queryCallback;
1372
+ }
1373
+ if (undefined === query || null === query) {
1374
+ if (request.debug && isDevelopment) {
1375
+ toast.warning("DEV: queryCallback returned undefined, signaling in Custom Cache. (returning null)", toastOptionsDevs);
1376
+ }
1377
+ console.groupCollapsed('%c API: (' + requestMethod + ') Request Query for (' + operatingTable + ') undefined, returning null (will not fire ajax)!', 'color: #c00');
1378
+ 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');
1379
+ console.trace();
1380
+ console.groupEnd();
1381
+ return [2 /*return*/, null];
1382
+ }
1383
+ if (C6.GET === requestMethod) {
1384
+ if (undefined === query[C6.PAGINATION]) {
1385
+ query[C6.PAGINATION] = {};
1386
+ }
1387
+ query[C6.PAGINATION][C6.PAGE] = query[C6.PAGINATION][C6.PAGE] || 1;
1388
+ query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
1389
+ }
1390
+ return [4 /*yield*/, apiRequest()];
1391
+ case 1: return [2 /*return*/, _a.sent()];
1042
1392
  }
1043
- console.groupCollapsed('%c API: An error occurred in the try catch block. returning null!', 'color: #ff0000');
1044
- console.log('%c ' + requestMethod + ' ' + tableName, 'color: #A020F0');
1045
- console.warn(error);
1046
- console.trace();
1047
- console.groupEnd();
1048
- TestRestfulResponse(error, request === null || request === void 0 ? void 0 : request.success, (request === null || request === void 0 ? void 0 : request.error) || "An restful API error occurred!");
1049
- return null;
1050
- }
1051
- }
1052
- return apiRequest();
1393
+ });
1394
+ });
1053
1395
  };
1054
1396
  }
1055
1397
 
@@ -1067,5 +1409,5 @@ function timeout(shouldContinueAfterTimeout, cb, timeoutMs) {
1067
1409
  };
1068
1410
  }
1069
1411
 
1070
- export { C6Constants, DELETE, GET, POST, PUT, TestRestfulResponse, axiosInstance, checkAllRequestsComplete, clearCache, convertForRequestBody, eFetchDependencies, extendedTypeHints, isDevelopment as isLocal, isPromise, isTest, isVerbose, removeInvalidKeys, removePrefixIfExists, restRequest, timeout, toastOptions, toastOptionsDevs };
1412
+ export { C6Constants, CarbonSqlExecutor, DELETE, GET, POST, PUT, TestRestfulResponse, axiosInstance, checkAllRequestsComplete, clearCache, convertForRequestBody, eFetchDependencies, extendedTypeHints, getEnvVar, isDevelopment as isLocal, isNode, isPromise, isTest, isVerbose, removeInvalidKeys, removePrefixIfExists, restRequest, timeout, toastOptions, toastOptionsDevs };
1071
1413
  //# sourceMappingURL=index.esm.js.map