@carbonorm/carbonnode 3.0.0 → 3.0.2

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 (47) hide show
  1. package/dist/api/builders/sqlBuilder.d.ts +3 -0
  2. package/dist/api/convertForRequestBody.d.ts +1 -1
  3. package/dist/api/executors/Executor.d.ts +16 -0
  4. package/dist/api/executors/HttpExecutor.d.ts +13 -0
  5. package/dist/api/executors/SqlExecutor.d.ts +19 -0
  6. package/dist/api/restRequest.d.ts +9 -166
  7. package/dist/api/types/dynamicFetching.d.ts +10 -0
  8. package/dist/api/types/modifyTypes.d.ts +9 -0
  9. package/dist/api/types/mysqlTypes.d.ts +4 -0
  10. package/dist/api/types/ormInterfaces.d.ts +219 -0
  11. package/dist/api/utils/apiHelpers.d.ts +9 -0
  12. package/dist/api/utils/cacheManager.d.ts +10 -0
  13. package/dist/api/utils/determineRuntimeJsType.d.ts +5 -0
  14. package/dist/api/utils/logger.d.ts +7 -0
  15. package/dist/api/utils/sortAndSerializeQueryObject.d.ts +1 -0
  16. package/dist/api/utils/testHelpers.d.ts +1 -0
  17. package/dist/api/utils/toastNotifier.d.ts +2 -0
  18. package/dist/index.cjs.js +665 -614
  19. package/dist/index.cjs.js.map +1 -1
  20. package/dist/index.d.ts +15 -2
  21. package/dist/index.esm.js +655 -618
  22. package/dist/index.esm.js.map +1 -1
  23. package/package.json +22 -6
  24. package/scripts/assets/handlebars/C6.ts.handlebars +13 -5
  25. package/scripts/assets/handlebars/Table.ts.handlebars +44 -12
  26. package/scripts/generateRestBindings.cjs +1 -1
  27. package/scripts/generateRestBindings.ts +1 -1
  28. package/src/api/builders/sqlBuilder.ts +173 -0
  29. package/src/api/convertForRequestBody.ts +2 -3
  30. package/src/api/executors/Executor.ts +28 -0
  31. package/src/api/executors/HttpExecutor.ts +794 -0
  32. package/src/api/executors/SqlExecutor.ts +104 -0
  33. package/src/api/restRequest.ts +50 -1287
  34. package/src/api/types/dynamicFetching.ts +10 -0
  35. package/src/api/types/modifyTypes.ts +25 -0
  36. package/src/api/types/mysqlTypes.ts +33 -0
  37. package/src/api/types/ormInterfaces.ts +310 -0
  38. package/src/api/utils/apiHelpers.ts +82 -0
  39. package/src/api/utils/cacheManager.ts +67 -0
  40. package/src/api/utils/determineRuntimeJsType.ts +46 -0
  41. package/src/api/utils/logger.ts +24 -0
  42. package/src/api/utils/sortAndSerializeQueryObject.ts +12 -0
  43. package/src/api/utils/testHelpers.ts +24 -0
  44. package/src/api/utils/toastNotifier.ts +11 -0
  45. package/src/index.ts +15 -2
  46. package/src/api/carbonSqlExecutor.ts +0 -279
  47. package/src/api/interfaces/ormInterfaces.ts +0 -87
package/dist/index.cjs.js CHANGED
@@ -235,366 +235,6 @@ var axiosInstance = (axios.create({
235
235
  */
236
236
  }));
237
237
 
238
- // import { validatePayloadAgainstSchema } from './validator'; // C6 schema validator
239
- var CarbonSqlExecutor = /** @class */ (function () {
240
- function CarbonSqlExecutor(pool, C6) {
241
- this.pool = pool;
242
- this.C6 = C6;
243
- }
244
- CarbonSqlExecutor.prototype.withConnection = function (cb) {
245
- return tslib.__awaiter(this, void 0, void 0, function () {
246
- var conn;
247
- return tslib.__generator(this, function (_a) {
248
- switch (_a.label) {
249
- case 0: return [4 /*yield*/, this.pool.getConnection()];
250
- case 1:
251
- conn = _a.sent();
252
- _a.label = 2;
253
- case 2:
254
- _a.trys.push([2, , 4, 5]);
255
- return [4 /*yield*/, cb(conn)];
256
- case 3: return [2 /*return*/, _a.sent()];
257
- case 4:
258
- conn.release();
259
- return [7 /*endfinally*/];
260
- case 5: return [2 /*return*/];
261
- }
262
- });
263
- });
264
- };
265
- CarbonSqlExecutor.prototype.handle = function (req, res, next) {
266
- return tslib.__awaiter(this, void 0, void 0, function () {
267
- var method, table, primary, payload, result, _a, err_1;
268
- return tslib.__generator(this, function (_b) {
269
- switch (_b.label) {
270
- case 0:
271
- _b.trys.push([0, 11, , 12]);
272
- method = req.method.toUpperCase();
273
- table = req.params.table;
274
- primary = req.params.primary;
275
- payload = method === 'GET' ? req.query : req.body;
276
- if (!(table in this.C6.TABLES)) {
277
- res.status(400).json({ error: "Invalid table: ".concat(table) });
278
- return [2 /*return*/];
279
- }
280
- result = void 0;
281
- _a = method;
282
- switch (_a) {
283
- case 'GET': return [3 /*break*/, 1];
284
- case 'OPTIONS': return [3 /*break*/, 1];
285
- case 'POST': return [3 /*break*/, 3];
286
- case 'PUT': return [3 /*break*/, 5];
287
- case 'DELETE': return [3 /*break*/, 7];
288
- }
289
- return [3 /*break*/, 9];
290
- case 1: return [4 /*yield*/, this.select(table, primary, payload)];
291
- case 2:
292
- result = _b.sent();
293
- return [3 /*break*/, 10];
294
- case 3: return [4 /*yield*/, this.insert(table, payload)];
295
- case 4:
296
- result = _b.sent();
297
- return [3 /*break*/, 10];
298
- case 5: return [4 /*yield*/, this.update(table, primary, payload)];
299
- case 6:
300
- result = _b.sent();
301
- return [3 /*break*/, 10];
302
- case 7: return [4 /*yield*/, this.delete(table, primary, payload)];
303
- case 8:
304
- result = _b.sent();
305
- return [3 /*break*/, 10];
306
- case 9: throw new Error("Unsupported method: ".concat(method));
307
- case 10:
308
- res.status(200).json({ success: true, result: result });
309
- return [3 /*break*/, 12];
310
- case 11:
311
- err_1 = _b.sent();
312
- next(err_1);
313
- return [3 /*break*/, 12];
314
- case 12: return [2 /*return*/];
315
- }
316
- });
317
- });
318
- };
319
- CarbonSqlExecutor.prototype.buildBooleanJoinedConditions = function (set, andMode) {
320
- if (andMode === void 0) { andMode = true; }
321
- var booleanOperator = andMode ? 'AND' : 'OR';
322
- var sql = '';
323
- var OPERATORS = ['=', '!=', '<', '<=', '>', '>=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'IS', 'IS NOT'];
324
- var isAggregateArray = function (value) { return Array.isArray(value) && typeof value[0] === 'string' && OPERATORS.includes(value[0]); };
325
- var isNumericKeyed = function (obj) { return Array.isArray(obj) && Object.keys(obj).every(function (k) { return /^\d+$/.test(k); }); };
326
- // todo - we should be doing something with value no????
327
- var addCondition = function (column, op, _value) {
328
- var paramName = column.replace(/\W+/g, '_');
329
- return "(".concat(column, " ").concat(op, " :").concat(paramName, ")");
330
- };
331
- if (isNumericKeyed(set)) {
332
- switch (set.length) {
333
- case 2:
334
- sql += addCondition(set[0], '=', set[1]);
335
- break;
336
- case 3:
337
- if (!OPERATORS.includes(set[1])) {
338
- throw new Error("Invalid operator: ".concat(set[1]));
339
- }
340
- sql += addCondition(set[0], set[1], set[2]);
341
- break;
342
- default:
343
- throw new Error("Invalid array condition: ".concat(JSON.stringify(set)));
344
- }
345
- }
346
- else {
347
- var parts = [];
348
- for (var _i = 0, _a = Object.entries(set); _i < _a.length; _i++) {
349
- var _b = _a[_i], key = _b[0], value = _b[1];
350
- if (/^\d+$/.test(key)) {
351
- parts.push(this.buildBooleanJoinedConditions(value, !andMode));
352
- continue;
353
- }
354
- if (!Array.isArray(value) || isAggregateArray(value)) {
355
- parts.push(addCondition(key, '='));
356
- continue;
357
- }
358
- if (value.length === 2 && OPERATORS.includes(value[0])) {
359
- parts.push(addCondition(key, value[0], value[1]));
360
- }
361
- else if (value.length === 1 && isAggregateArray(value[0])) {
362
- parts.push(addCondition(key, '=', value[0]));
363
- }
364
- else {
365
- throw new Error("Invalid condition for ".concat(key, ": ").concat(JSON.stringify(value)));
366
- }
367
- }
368
- sql = parts.join(" ".concat(booleanOperator, " "));
369
- }
370
- return "(".concat(sql, ")");
371
- };
372
- CarbonSqlExecutor.prototype.buildAggregateField = function (field) {
373
- if (typeof field === 'string')
374
- return field;
375
- if (!Array.isArray(field))
376
- throw new Error('Invalid SELECT entry: must be string or array');
377
- var agg = field[0], args = field.slice(1);
378
- switch (agg) {
379
- case 'COUNT':
380
- return "COUNT(".concat(args[0] || '*', ")");
381
- case 'SUM':
382
- case 'AVG':
383
- case 'MIN':
384
- case 'MAX':
385
- return "".concat(agg, "(").concat(args[0], ")").concat(args[1] ? " AS ".concat(args[1]) : '');
386
- case 'DISTINCT':
387
- return "DISTINCT(".concat(args[0], ")").concat(args[1] ? " AS ".concat(args[1]) : '');
388
- case 'GROUP_CONCAT': {
389
- var col = args[0], alias = args[1], sortCol = args[2], sortType = args[3];
390
- var order = sortCol ? " ORDER BY ".concat(sortCol, " ").concat(sortType || 'ASC') : '';
391
- return "GROUP_CONCAT(DISTINCT ".concat(col).concat(order, " SEPARATOR ',')").concat(alias ? " AS ".concat(alias) : '');
392
- }
393
- case 'AS': {
394
- var col = args[0], alias = args[1];
395
- return "".concat(col, " AS ").concat(alias);
396
- }
397
- case 'CONVERT_TZ': {
398
- var ts = args[0], fromTz = args[1], toTz = args[2];
399
- return "CONVERT_TZ(".concat(ts, ", ").concat(fromTz, ", ").concat(toTz, ")");
400
- }
401
- case 'NOW':
402
- return 'NOW()';
403
- default:
404
- throw new Error("Unsupported aggregate: ".concat(agg));
405
- }
406
- };
407
- CarbonSqlExecutor.prototype.buildSelectQuery = function (table, primary, args, isSubSelect) {
408
- var _this = this;
409
- var _a, _b, _c, _d;
410
- if (isSubSelect === void 0) { isSubSelect = false; }
411
- var selectList = (_a = args === null || args === void 0 ? void 0 : args[this.C6.SELECT]) !== null && _a !== void 0 ? _a : ['*'];
412
- var selectFields = Array.isArray(selectList)
413
- ? selectList.map(function (f) { return _this.buildAggregateField(f); }).join(', ')
414
- : '*';
415
- var sql = "SELECT ".concat(selectFields, " FROM `").concat(table, "`");
416
- if (args === null || args === void 0 ? void 0 : args[this.C6.JOIN]) {
417
- var joins = args[this.C6.JOIN];
418
- for (var joinType in joins) {
419
- var joinKeyword = joinType.replace('_', ' ').toUpperCase();
420
- for (var joinTable in joins[joinType]) {
421
- var onClause = this.buildBooleanJoinedConditions(joins[joinType][joinTable]);
422
- sql += " ".concat(joinKeyword, " JOIN `").concat(joinTable, "` ON ").concat(onClause);
423
- }
424
- }
425
- }
426
- if (args === null || args === void 0 ? void 0 : args[this.C6.WHERE]) {
427
- sql += " WHERE ".concat(this.buildBooleanJoinedConditions(args[this.C6.WHERE]));
428
- }
429
- if (args === null || args === void 0 ? void 0 : args[this.C6.GROUP_BY]) {
430
- var groupByFields = Array.isArray(args[this.C6.GROUP_BY]) ? args[this.C6.GROUP_BY].join(', ') : args[this.C6.GROUP_BY];
431
- sql += " GROUP BY ".concat(groupByFields);
432
- }
433
- if (args === null || args === void 0 ? void 0 : args[this.C6.HAVING]) {
434
- sql += " HAVING ".concat(this.buildBooleanJoinedConditions(args[this.C6.HAVING]));
435
- }
436
- if (args === null || args === void 0 ? void 0 : args[this.C6.PAGINATION]) {
437
- var p = args[this.C6.PAGINATION];
438
- var limitClause = '';
439
- if (p[this.C6.ORDER]) {
440
- var orderArray = Object.entries(p[this.C6.ORDER]).map(function (_a) {
441
- var col = _a[0], dir = _a[1];
442
- if (!['ASC', 'DESC'].includes(String(dir).toUpperCase())) {
443
- throw new Error("Invalid order direction: ".concat(dir));
444
- }
445
- return "".concat(col, " ").concat(String(dir).toUpperCase());
446
- });
447
- sql += " ORDER BY ".concat(orderArray.join(', '));
448
- }
449
- else if (primary) {
450
- sql += " ORDER BY ".concat(primary, " DESC");
451
- }
452
- else {
453
- // todo this is wrong
454
- 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';
455
- sql += " ORDER BY ".concat(primaryKey, " DESC");
456
- }
457
- if (p[this.C6.LIMIT] != null) {
458
- var limit = parseInt(p[this.C6.LIMIT], 10);
459
- if (isNaN(limit) || limit < 0) {
460
- throw new Error("Invalid LIMIT: ".concat(p[this.C6.LIMIT]));
461
- }
462
- var page = parseInt((_d = p[this.C6.PAGE]) !== null && _d !== void 0 ? _d : 1, 10);
463
- if (isNaN(page) || page < 1) {
464
- throw new Error("PAGE must be >= 1 (got ".concat(p[this.C6.PAGE], ")"));
465
- }
466
- var offset = (page - 1) * limit;
467
- limitClause += " LIMIT ".concat(offset, ", ").concat(limit);
468
- }
469
- sql += limitClause;
470
- }
471
- else if (!isSubSelect && primary) {
472
- sql += " ORDER BY ".concat(primary, " ASC LIMIT 1");
473
- }
474
- else if (!isSubSelect && !primary) {
475
- sql += " ORDER BY id ASC LIMIT 100"; // fallback default limit
476
- }
477
- return sql;
478
- };
479
- CarbonSqlExecutor.prototype.select = function (table, primary, args) {
480
- return tslib.__awaiter(this, void 0, void 0, function () {
481
- var sql;
482
- var _this = this;
483
- return tslib.__generator(this, function (_a) {
484
- switch (_a.label) {
485
- case 0:
486
- sql = this.buildSelectQuery(table, primary, args);
487
- return [4 /*yield*/, this.withConnection(function (conn) { return tslib.__awaiter(_this, void 0, void 0, function () {
488
- var rows;
489
- return tslib.__generator(this, function (_a) {
490
- switch (_a.label) {
491
- case 0:
492
- console.log(sql);
493
- return [4 /*yield*/, conn.query(sql)];
494
- case 1:
495
- rows = (_a.sent())[0];
496
- return [2 /*return*/, rows];
497
- }
498
- });
499
- }); })];
500
- case 1: return [2 /*return*/, _a.sent()];
501
- }
502
- });
503
- });
504
- };
505
- CarbonSqlExecutor.prototype.insert = function (table, data) {
506
- return tslib.__awaiter(this, void 0, void 0, function () {
507
- var keys, values, placeholders, sql;
508
- var _this = this;
509
- return tslib.__generator(this, function (_a) {
510
- switch (_a.label) {
511
- case 0:
512
- keys = Object.keys(data);
513
- values = keys.map(function (k) { return data[k]; });
514
- placeholders = keys.map(function () { return '?'; }).join(', ');
515
- sql = "INSERT INTO `".concat(table, "` (").concat(keys.join(', '), ") VALUES (").concat(placeholders, ")");
516
- return [4 /*yield*/, this.withConnection(function (conn) { return tslib.__awaiter(_this, void 0, void 0, function () {
517
- var result;
518
- return tslib.__generator(this, function (_a) {
519
- switch (_a.label) {
520
- case 0: return [4 /*yield*/, conn.execute(sql, values)];
521
- case 1:
522
- result = (_a.sent())[0];
523
- return [2 /*return*/, result];
524
- }
525
- });
526
- }); })];
527
- case 1: return [2 /*return*/, _a.sent()];
528
- }
529
- });
530
- });
531
- };
532
- CarbonSqlExecutor.prototype.update = function (table, primary, data) {
533
- return tslib.__awaiter(this, void 0, void 0, function () {
534
- var keys, values, updates, sql;
535
- var _this = this;
536
- return tslib.__generator(this, function (_a) {
537
- switch (_a.label) {
538
- case 0:
539
- if (!primary) {
540
- throw new Error('Primary key is required for update');
541
- }
542
- keys = Object.keys(data);
543
- values = keys.map(function (k) { return data[k]; });
544
- updates = keys.map(function (k) { return "`".concat(k, "` = ?"); }).join(', ');
545
- sql = "UPDATE `".concat(table, "` SET ").concat(updates, " WHERE `").concat(primary, "` = ?");
546
- values.push(data[primary]);
547
- return [4 /*yield*/, this.withConnection(function (conn) { return tslib.__awaiter(_this, void 0, void 0, function () {
548
- var result;
549
- return tslib.__generator(this, function (_a) {
550
- switch (_a.label) {
551
- case 0: return [4 /*yield*/, conn.execute(sql, values)];
552
- case 1:
553
- result = (_a.sent())[0];
554
- return [2 /*return*/, result];
555
- }
556
- });
557
- }); })];
558
- case 1: return [2 /*return*/, _a.sent()];
559
- }
560
- });
561
- });
562
- };
563
- CarbonSqlExecutor.prototype.delete = function (table, primary, args) {
564
- return tslib.__awaiter(this, void 0, void 0, function () {
565
- var sql;
566
- var _this = this;
567
- return tslib.__generator(this, function (_a) {
568
- switch (_a.label) {
569
- case 0:
570
- if (!primary || !(args === null || args === void 0 ? void 0 : args[primary])) {
571
- throw new Error('Primary key and value required for delete');
572
- }
573
- sql = "DELETE FROM `".concat(table, "` WHERE `").concat(primary, "` = ?");
574
- return [4 /*yield*/, this.withConnection(function (conn) { return tslib.__awaiter(_this, void 0, void 0, function () {
575
- var result;
576
- return tslib.__generator(this, function (_a) {
577
- switch (_a.label) {
578
- case 0: return [4 /*yield*/, conn.execute(sql, [args[primary]])];
579
- case 1:
580
- result = (_a.sent())[0];
581
- return [2 /*return*/, result];
582
- }
583
- });
584
- }); })];
585
- case 1: return [2 /*return*/, _a.sent()];
586
- }
587
- });
588
- });
589
- };
590
- return CarbonSqlExecutor;
591
- }());
592
-
593
- var carbonSqlExecutor = /*#__PURE__*/Object.freeze({
594
- __proto__: null,
595
- CarbonSqlExecutor: CarbonSqlExecutor
596
- });
597
-
598
238
  function convertForRequestBody (restfulObject, tableName, C6, regexErrorHandler) {
599
239
  if (regexErrorHandler === void 0) { regexErrorHandler = alert; }
600
240
  var payload = {};
@@ -669,6 +309,221 @@ function convertForRequestBody (restfulObject, tableName, C6, regexErrorHandler)
669
309
  var _a;
670
310
  var isNode = typeof process !== 'undefined' && !!((_a = process.versions) === null || _a === void 0 ? void 0 : _a.node);
671
311
 
312
+ /**
313
+ * Facade: routes API calls to SQL or HTTP executors based on runtime context.
314
+ */
315
+ function restRequest(config) {
316
+ var _this = this;
317
+ return function () {
318
+ var args_1 = [];
319
+ for (var _i = 0; _i < arguments.length; _i++) {
320
+ args_1[_i] = arguments[_i];
321
+ }
322
+ return tslib.__awaiter(_this, tslib.__spreadArray([], args_1, true), void 0, function (request) {
323
+ var SqlExecutor, executor, HttpExecutor, http;
324
+ if (request === void 0) { request = {}; }
325
+ return tslib.__generator(this, function (_a) {
326
+ switch (_a.label) {
327
+ case 0:
328
+ if (!(isNode && config.mysqlPool)) return [3 /*break*/, 2];
329
+ return [4 /*yield*/, Promise.resolve().then(function () { return SqlExecutor$1; })];
330
+ case 1:
331
+ SqlExecutor = (_a.sent()).SqlExecutor;
332
+ executor = new SqlExecutor(config, request);
333
+ return [2 /*return*/, executor.execute()];
334
+ case 2: return [4 /*yield*/, Promise.resolve().then(function () { return HttpExecutor$1; })];
335
+ case 3:
336
+ HttpExecutor = (_a.sent()).HttpExecutor;
337
+ http = new HttpExecutor(config, request);
338
+ return [2 /*return*/, http.execute()];
339
+ }
340
+ });
341
+ });
342
+ };
343
+ }
344
+
345
+ function timeout(shouldContinueAfterTimeout, cb, timeoutMs) {
346
+ if (timeoutMs === void 0) { timeoutMs = 3000; }
347
+ var timer = function () { return setTimeout(function () {
348
+ if (false === shouldContinueAfterTimeout()) {
349
+ return;
350
+ }
351
+ cb();
352
+ }, timeoutMs); };
353
+ var timerId = timer();
354
+ return function () {
355
+ clearTimeout(timerId);
356
+ };
357
+ }
358
+
359
+ function buildBooleanJoinedConditions(set, andMode) {
360
+ if (andMode === void 0) { andMode = true; }
361
+ var booleanOperator = andMode ? 'AND' : 'OR';
362
+ var sql = '';
363
+ var OPERATORS = ['=', '!=', '<', '<=', '>', '>=', 'LIKE', 'NOT LIKE', 'IN', 'NOT IN', 'IS', 'IS NOT'];
364
+ var isAggregateArray = function (value) { return Array.isArray(value) && typeof value[0] === 'string' && OPERATORS.includes(value[0]); };
365
+ var isNumericKeyed = function (obj) { return Array.isArray(obj) && Object.keys(obj).every(function (k) { return /^\d+$/.test(k); }); };
366
+ // todo - we should be doing something with value no????
367
+ var addCondition = function (column, op, _value) {
368
+ var paramName = column.replace(/\W+/g, '_');
369
+ return "(".concat(column, " ").concat(op, " :").concat(paramName, ")");
370
+ };
371
+ if (isNumericKeyed(set)) {
372
+ switch (set.length) {
373
+ case 2:
374
+ sql += addCondition(set[0], '=', set[1]);
375
+ break;
376
+ case 3:
377
+ if (!OPERATORS.includes(set[1])) {
378
+ throw new Error("Invalid operator: ".concat(set[1]));
379
+ }
380
+ sql += addCondition(set[0], set[1], set[2]);
381
+ break;
382
+ default:
383
+ throw new Error("Invalid array condition: ".concat(JSON.stringify(set)));
384
+ }
385
+ }
386
+ else {
387
+ var parts = [];
388
+ for (var _i = 0, _a = Object.entries(set); _i < _a.length; _i++) {
389
+ var _b = _a[_i], key = _b[0], value = _b[1];
390
+ if (/^\d+$/.test(key)) {
391
+ parts.push(buildBooleanJoinedConditions(value, !andMode));
392
+ continue;
393
+ }
394
+ if (!Array.isArray(value) || isAggregateArray(value)) {
395
+ parts.push(addCondition(key, '='));
396
+ continue;
397
+ }
398
+ if (value.length === 2 && OPERATORS.includes(value[0])) {
399
+ parts.push(addCondition(key, value[0], value[1]));
400
+ }
401
+ else if (value.length === 1 && isAggregateArray(value[0])) {
402
+ parts.push(addCondition(key, '=', value[0]));
403
+ }
404
+ else {
405
+ throw new Error("Invalid condition for ".concat(key, ": ").concat(JSON.stringify(value)));
406
+ }
407
+ }
408
+ sql = parts.join(" ".concat(booleanOperator, " "));
409
+ }
410
+ return "(".concat(sql, ")");
411
+ }
412
+ function buildAggregateField(field) {
413
+ if (typeof field === 'string')
414
+ return field;
415
+ if (!Array.isArray(field))
416
+ throw new Error('Invalid SELECT entry: must be string or array');
417
+ var agg = field[0], args = field.slice(1);
418
+ switch (agg) {
419
+ case 'COUNT':
420
+ return "COUNT(".concat(args[0] || '*', ")");
421
+ case 'SUM':
422
+ case 'AVG':
423
+ case 'MIN':
424
+ case 'MAX':
425
+ return "".concat(agg, "(").concat(args[0], ")").concat(args[1] ? " AS ".concat(args[1]) : '');
426
+ case 'DISTINCT':
427
+ return "DISTINCT(".concat(args[0], ")").concat(args[1] ? " AS ".concat(args[1]) : '');
428
+ case 'GROUP_CONCAT': {
429
+ var col = args[0], alias = args[1], sortCol = args[2], sortType = args[3];
430
+ var order = sortCol ? " ORDER BY ".concat(sortCol, " ").concat(sortType || 'ASC') : '';
431
+ return "GROUP_CONCAT(DISTINCT ".concat(col).concat(order, " SEPARATOR ',')").concat(alias ? " AS ".concat(alias) : '');
432
+ }
433
+ case 'AS': {
434
+ var col = args[0], alias = args[1];
435
+ return "".concat(col, " AS ").concat(alias);
436
+ }
437
+ case 'CONVERT_TZ': {
438
+ var ts = args[0], fromTz = args[1], toTz = args[2];
439
+ return "CONVERT_TZ(".concat(ts, ", ").concat(fromTz, ", ").concat(toTz, ")");
440
+ }
441
+ case 'NOW':
442
+ return 'NOW()';
443
+ default:
444
+ throw new Error("Unsupported aggregate: ".concat(agg));
445
+ }
446
+ }
447
+ function buildSelectQuery(table, primary, args, isSubSelect) {
448
+ var _a, _b;
449
+ if (isSubSelect === void 0) { isSubSelect = false; }
450
+ var selectList = (_a = args === null || args === void 0 ? void 0 : args[C6Constants.SELECT]) !== null && _a !== void 0 ? _a : ['*'];
451
+ var selectFields = Array.isArray(selectList)
452
+ ? selectList.map(function (f) { return buildAggregateField(f); }).join(', ')
453
+ : '*';
454
+ var sql = "SELECT ".concat(selectFields, " FROM `").concat(table, "`");
455
+ if (args === null || args === void 0 ? void 0 : args[C6Constants.JOIN]) {
456
+ var joins = args[C6Constants.JOIN];
457
+ for (var joinType in joins) {
458
+ var joinKeyword = joinType.replace('_', ' ').toUpperCase();
459
+ for (var joinTable in joins[joinType]) {
460
+ var onClause = buildBooleanJoinedConditions(joins[joinType][joinTable]);
461
+ sql += " ".concat(joinKeyword, " JOIN `").concat(joinTable, "` ON ").concat(onClause);
462
+ }
463
+ }
464
+ }
465
+ if (args === null || args === void 0 ? void 0 : args[C6Constants.WHERE]) {
466
+ sql += " WHERE ".concat(buildBooleanJoinedConditions(args[C6Constants.WHERE]));
467
+ }
468
+ if (args === null || args === void 0 ? void 0 : args[C6Constants.GROUP_BY]) {
469
+ var groupByFields = Array.isArray(args[C6Constants.GROUP_BY]) ? args[C6Constants.GROUP_BY].join(', ') : args[C6Constants.GROUP_BY];
470
+ sql += " GROUP BY ".concat(groupByFields);
471
+ }
472
+ if (args === null || args === void 0 ? void 0 : args[C6Constants.HAVING]) {
473
+ sql += " HAVING ".concat(buildBooleanJoinedConditions(args[C6Constants.HAVING]));
474
+ }
475
+ if (args === null || args === void 0 ? void 0 : args[C6Constants.PAGINATION]) {
476
+ var p = args[C6Constants.PAGINATION];
477
+ var limitClause = '';
478
+ if (p[C6Constants.ORDER]) {
479
+ var orderArray = Object.entries(p[C6Constants.ORDER]).map(function (_a) {
480
+ var col = _a[0], dir = _a[1];
481
+ if (!['ASC', 'DESC'].includes(String(dir).toUpperCase())) {
482
+ throw new Error("Invalid order direction: ".concat(dir));
483
+ }
484
+ return "".concat(col, " ").concat(String(dir).toUpperCase());
485
+ });
486
+ sql += " ORDER BY ".concat(orderArray.join(', '));
487
+ }
488
+ else if (primary) {
489
+ sql += " ORDER BY ".concat(primary, " DESC");
490
+ } /*else {
491
+ // todo - this is wrong
492
+ const primaryKey = C6Constants.TABLES['users'].PRIMARY_SHORT?.[0] ?? 'user_id';
493
+ sql += ` ORDER BY ${primaryKey} DESC`;
494
+ }*/
495
+ if (p[C6Constants.LIMIT] != null) {
496
+ var limit = parseInt(p[C6Constants.LIMIT], 10);
497
+ if (isNaN(limit) || limit < 0) {
498
+ throw new Error("Invalid LIMIT: ".concat(p[C6Constants.LIMIT]));
499
+ }
500
+ var page = parseInt((_b = p[C6Constants.PAGE]) !== null && _b !== void 0 ? _b : 1, 10);
501
+ if (isNaN(page) || page < 1) {
502
+ throw new Error("PAGE must be >= 1 (got ".concat(p[C6Constants.PAGE], ")"));
503
+ }
504
+ var offset = (page - 1) * limit;
505
+ limitClause += " LIMIT ".concat(offset, ", ").concat(limit);
506
+ }
507
+ sql += limitClause;
508
+ }
509
+ else if (!isSubSelect && primary) {
510
+ sql += " ORDER BY ".concat(primary, " ASC LIMIT 1");
511
+ }
512
+ else if (!isSubSelect && !primary) {
513
+ sql += " ORDER BY id ASC LIMIT 100"; // fallback default limit
514
+ }
515
+ return sql;
516
+ }
517
+
518
+ var Executor = /** @class */ (function () {
519
+ function Executor(config, request) {
520
+ if (request === void 0) { request = {}; }
521
+ this.config = config;
522
+ this.request = request;
523
+ }
524
+ return Executor;
525
+ }());
526
+
672
527
  function getEnvVar(key, fallback) {
673
528
  if (fallback === void 0) { fallback = ''; }
674
529
  // Vite-style injection
@@ -693,6 +548,36 @@ var isTest = getEnvVar('JEST_WORKER_ID') || getEnvVar('NODE_ENV') === 'test'
693
548
  var envVerbose = getEnvVar('VERBOSE') || getEnvVar('REACT_APP_VERBOSE') || getEnvVar('VITE_VERBOSE') || '';
694
549
  var isVerbose = ['true', '1', 'yes', 'on'].includes(envVerbose.toLowerCase());
695
550
 
551
+ exports.eFetchDependencies = void 0;
552
+ (function (eFetchDependencies) {
553
+ eFetchDependencies[eFetchDependencies["NONE"] = 0] = "NONE";
554
+ eFetchDependencies[eFetchDependencies["REFERENCED"] = 1] = "REFERENCED";
555
+ eFetchDependencies[eFetchDependencies["CHILDREN"] = 1] = "CHILDREN";
556
+ eFetchDependencies[eFetchDependencies["REFERENCES"] = 2] = "REFERENCES";
557
+ eFetchDependencies[eFetchDependencies["PARENTS"] = 2] = "PARENTS";
558
+ eFetchDependencies[eFetchDependencies["ALL"] = 3] = "ALL";
559
+ eFetchDependencies[eFetchDependencies["C6ENTITY"] = 4] = "C6ENTITY";
560
+ eFetchDependencies[eFetchDependencies["RECURSIVE"] = 8] = "RECURSIVE";
561
+ })(exports.eFetchDependencies || (exports.eFetchDependencies = {}));
562
+
563
+ /**
564
+ * the first argument ....
565
+ *
566
+ * Our api returns a zero argument function iff the method is get and the previous request reached the predefined limit.
567
+ * This function can be aliased as GetNextPageOfResults(). If the end is reached undefined will be returned.
568
+ *
569
+ *
570
+ * For POST, PUT, and DELETE requests one can expect the primary key of the new or modified index, or a boolean success
571
+ * indication if no primary key exists.
572
+ **/
573
+ var POST = 'POST';
574
+ var PUT = 'PUT';
575
+ var GET = 'GET';
576
+ var DELETE = 'DELETE';
577
+ function isPromise(x) {
578
+ return Object(x).constructor === Promise;
579
+ }
580
+
696
581
  var toastOptions = {
697
582
  position: "bottom-left",
698
583
  autoClose: 10000,
@@ -733,6 +618,12 @@ function TestRestfulResponse(response, success, error) {
733
618
  }
734
619
  return false;
735
620
  }
621
+ function removePrefixIfExists(tableName, prefix) {
622
+ if (tableName.startsWith(prefix.toLowerCase())) {
623
+ return tableName.slice(prefix.length);
624
+ }
625
+ return tableName;
626
+ }
736
627
  function removeInvalidKeys(request, c6Tables) {
737
628
  var intersection = {};
738
629
  var restfulObjectKeys = [];
@@ -750,32 +641,17 @@ function removeInvalidKeys(request, c6Tables) {
750
641
  isTest || console.log('intersection', intersection);
751
642
  return intersection;
752
643
  }
753
- exports.eFetchDependencies = void 0;
754
- (function (eFetchDependencies) {
755
- eFetchDependencies[eFetchDependencies["NONE"] = 0] = "NONE";
756
- eFetchDependencies[eFetchDependencies["REFERENCED"] = 1] = "REFERENCED";
757
- eFetchDependencies[eFetchDependencies["CHILDREN"] = 1] = "CHILDREN";
758
- eFetchDependencies[eFetchDependencies["REFERENCES"] = 2] = "REFERENCES";
759
- eFetchDependencies[eFetchDependencies["PARENTS"] = 2] = "PARENTS";
760
- eFetchDependencies[eFetchDependencies["ALL"] = 3] = "ALL";
761
- eFetchDependencies[eFetchDependencies["C6ENTITY"] = 4] = "C6ENTITY";
762
- eFetchDependencies[eFetchDependencies["RECURSIVE"] = 8] = "RECURSIVE";
763
- })(exports.eFetchDependencies || (exports.eFetchDependencies = {}));
644
+
764
645
  // do not remove entries from this array. It is used to track the progress of API requests.
765
646
  // position in array is important. Do not sort. To not add to begging.
766
- var apiRequestCache = [];
767
- var userCustomClearCache = [];
768
- function checkAllRequestsComplete() {
769
- var stillRunning = apiRequestCache.filter(function (cache) { return undefined === cache.response; });
770
- if (stillRunning.length !== 0) {
771
- if (document === null || document === undefined) {
772
- throw new Error('document is undefined while waiting for API requests to complete (' + JSON.stringify(apiRequestCache) + ')');
773
- }
774
- // when requests return emtpy sets in full renders, it may not be possible to track their progress.
775
- console.warn('stillRunning...', stillRunning);
776
- return stillRunning.map(function (cache) { return cache.requestArgumentsSerialized; });
647
+ exports.apiRequestCache = [];
648
+ exports.userCustomClearCache = [];
649
+ function clearCache(props) {
650
+ if (false === (props === null || props === void 0 ? void 0 : props.ignoreWarning)) {
651
+ console.warn('The rest api clearCache should only be used with extreme care! Avoid using this in favor of using `cacheResults : boolean`.');
777
652
  }
778
- return true;
653
+ exports.userCustomClearCache.map(function (f) { return 'function' === typeof f && f(); });
654
+ exports.userCustomClearCache = exports.apiRequestCache = [];
779
655
  }
780
656
  function checkCache(cacheResult, requestMethod, tableName, request) {
781
657
  var _a, _b, _c;
@@ -794,95 +670,92 @@ function checkCache(cacheResult, requestMethod, tableName, request) {
794
670
  console.log('%c Response Data:', 'color: #cc0', ((_b = (_a = cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.rest) || ((_c = cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult.response) === null || _c === void 0 ? void 0 : _c.data) || (cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult.response));
795
671
  console.groupEnd();
796
672
  }
797
- return undefined;
798
- }
799
- return false;
800
- }
801
- function sortAndSerializeQueryObject(tables, query) {
802
- var orderedQuery = Object.keys(query).sort().reduce(function (obj, key) {
803
- obj[key] = query[key];
804
- return obj;
805
- }, {});
806
- return tables + ' ' + JSON.stringify(orderedQuery);
807
- }
808
- function clearCache(props) {
809
- if (false === (props === null || props === void 0 ? void 0 : props.ignoreWarning)) {
810
- console.warn('The rest api clearCache should only be used with extreme care! Avoid using this in favor of using `cacheResults : boolean`.');
811
- }
812
- userCustomClearCache.map(function (f) { return 'function' === typeof f && f(); });
813
- userCustomClearCache = apiRequestCache = [];
814
- }
815
- function removePrefixIfExists(tableName, prefix) {
816
- if (tableName.startsWith(prefix.toLowerCase())) {
817
- return tableName.slice(prefix.length);
673
+ return undefined;
818
674
  }
819
- return tableName;
820
- }
821
- /**
822
- * the first argument ....
823
- *
824
- * Our api returns a zero argument function iff the method is get and the previous request reached the predefined limit.
825
- * This function can be aliased as GetNextPageOfResults(). If the end is reached undefined will be returned.
826
- *
827
- *
828
- * For POST, PUT, and DELETE requests one can expect the primary key of the new or modified index, or a boolean success
829
- * indication if no primary key exists.
830
- **/
831
- var POST = 'POST';
832
- var PUT = 'PUT';
833
- var GET = 'GET';
834
- var DELETE = 'DELETE';
835
- function isPromise(x) {
836
- return Object(x).constructor === Promise;
675
+ return false;
837
676
  }
838
- function extendedTypeHints() {
839
- return function (argv) { return restRequest(argv); };
677
+
678
+ function sortAndSerializeQueryObject(tables, query) {
679
+ var orderedQuery = Object.keys(query).sort().reduce(function (obj, key) {
680
+ obj[key] = query[key];
681
+ return obj;
682
+ }, {});
683
+ return tables + ' ' + JSON.stringify(orderedQuery);
840
684
  }
841
- function restRequest(_a) {
842
- var _this = this;
843
- 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;
844
- var fullTableList = Array.isArray(tableName) ? tableName : [tableName];
845
- var operatingTableFullName = fullTableList[0];
846
- var operatingTable = removePrefixIfExists(operatingTableFullName, C6.PREFIX);
847
- var tables = fullTableList.join(',');
848
- switch (requestMethod) {
849
- case GET:
850
- case POST:
851
- case PUT:
852
- case DELETE:
853
- break;
854
- default:
855
- throw Error('Bad request method passed to getApi');
856
- }
857
- if (null !== clearCache || undefined !== clearCache) {
858
- userCustomClearCache[tables + requestMethod] = clearCache;
685
+
686
+ var HttpExecutor = /** @class */ (function (_super) {
687
+ tslib.__extends(HttpExecutor, _super);
688
+ function HttpExecutor() {
689
+ return _super !== null && _super.apply(this, arguments) || this;
859
690
  }
860
- return function () {
861
- var args_1 = [];
862
- for (var _i = 0; _i < arguments.length; _i++) {
863
- args_1[_i] = arguments[_i];
864
- }
865
- return tslib.__awaiter(_this, tslib.__spreadArray([], args_1, true), void 0, function (request) {
866
- // this could return itself with a new page number, or undefined if the end is reached
867
- function apiRequest() {
868
- return tslib.__awaiter(this, void 0, void 0, function () {
869
- var querySerialized, cacheResult, cachingConfirmed, cacheCheck, cacheCheck, addBackPK, apiResponse, returnGetNextPageFunction, restRequestUri, needsConditionOrPrimaryCheck, TABLES, primaryKey, CarbonSqlExecutor, engine, removedPkValue_1, axiosActiveRequest;
870
- var _this = this;
871
- var _a, _b, _c, _d, _e, _f, _g;
872
- return tslib.__generator(this, function (_h) {
873
- switch (_h.label) {
874
- case 0:
875
- (_a = request.cacheResults) !== null && _a !== void 0 ? _a : (request.cacheResults = C6.GET === requestMethod);
691
+ HttpExecutor.prototype.execute = function () {
692
+ return tslib.__awaiter(this, void 0, void 0, function () {
693
+ var _a, C6, axios, restURL, withCredentials, restModel, requestMethod, queryCallback, responseCallback, skipPrimaryCheck, clearCache, tableName, fullTableList, operatingTableFullName, operatingTable, tables, query, apiRequest;
694
+ var _this = this;
695
+ return tslib.__generator(this, function (_b) {
696
+ switch (_b.label) {
697
+ case 0:
698
+ _a = this.config, C6 = _a.C6, axios = _a.axios, restURL = _a.restURL, withCredentials = _a.withCredentials, restModel = _a.restModel, requestMethod = _a.requestMethod, queryCallback = _a.queryCallback, responseCallback = _a.responseCallback, skipPrimaryCheck = _a.skipPrimaryCheck, clearCache = _a.clearCache;
699
+ tableName = restModel.TABLE_NAME;
700
+ fullTableList = Array.isArray(tableName) ? tableName : [tableName];
701
+ operatingTableFullName = fullTableList[0];
702
+ operatingTable = removePrefixIfExists(operatingTableFullName, C6.PREFIX);
703
+ tables = fullTableList.join(',');
704
+ switch (requestMethod) {
705
+ case GET:
706
+ case POST:
707
+ case PUT:
708
+ case DELETE:
709
+ break;
710
+ default:
711
+ throw Error('Bad request method passed to getApi');
712
+ }
713
+ if (null !== clearCache || undefined !== clearCache) {
714
+ exports.userCustomClearCache[tables + requestMethod] = clearCache;
715
+ }
716
+ console.groupCollapsed('%c API: (' + requestMethod + ') Request for (' + tableName + ')', 'color: #0c0');
717
+ console.log('request', this.request);
718
+ console.groupEnd();
719
+ if ('function' === typeof queryCallback) {
720
+ query = queryCallback(this.request); // obj or obj[]
721
+ }
722
+ else {
723
+ query = queryCallback;
724
+ }
725
+ if (undefined === query || null === query) {
726
+ if (this.request.debug && isDevelopment) {
727
+ reactToastify.toast.warning("DEV: queryCallback returned undefined, signaling in Custom Cache. (returning null)", toastOptionsDevs);
728
+ }
729
+ console.groupCollapsed('%c API: (' + requestMethod + ') Request Query for (' + tableName + ') undefined, returning null (will not fire ajax)!', 'color: #c00');
730
+ 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');
731
+ console.trace();
732
+ console.groupEnd();
733
+ return [2 /*return*/, null];
734
+ }
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
+ 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, addBackPK, apiResponse, returnGetNextPageFunction, restRequestUri, needsConditionOrPrimaryCheck, TABLES, primaryKey, removedPkValue_1, axiosActiveRequest;
744
+ var _e;
745
+ var _this = this;
746
+ var _f, _g, _h, _j, _k, _l;
747
+ return tslib.__generator(this, function (_m) {
748
+ _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;
876
749
  if (C6.GET === requestMethod
877
- && undefined !== ((_b = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _b === void 0 ? void 0 : _b[C6.PAGE])
750
+ && undefined !== ((_f = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _f === void 0 ? void 0 : _f[C6.PAGE])
878
751
  && 1 !== query[C6.PAGINATION][C6.PAGE]) {
879
752
  console.groupCollapsed('Request on table (' + tableName + ') is firing for page (' + query[C6.PAGINATION][C6.PAGE] + '), please wait!');
880
- console.log('Request Data (note you may see the success and/or error prompt):', request);
753
+ console.log('Request Data (note you may see the success and/or error prompt):', this.request);
881
754
  console.trace();
882
755
  console.groupEnd();
883
756
  }
884
757
  querySerialized = sortAndSerializeQueryObject(tables, query !== null && query !== void 0 ? query : {});
885
- cacheResult = apiRequestCache.find(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
758
+ cacheResult = exports.apiRequestCache.find(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
886
759
  cachingConfirmed = false;
887
760
  // determine if we need to paginate.
888
761
  if (requestMethod === C6.GET) {
@@ -895,11 +768,11 @@ function restRequest(_a) {
895
768
  query[C6.PAGINATION][C6.PAGE] = query[C6.PAGINATION][C6.PAGE] || 1;
896
769
  query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
897
770
  // this will evaluate true most the time
898
- if (true === request.cacheResults) {
771
+ if (true === cacheResults) {
899
772
  // just find the next, non-fetched, page and return a function to request it
900
773
  if (undefined !== cacheResult) {
901
774
  do {
902
- cacheCheck = checkCache(cacheResult, requestMethod, tableName, request);
775
+ cacheCheck = checkCache(cacheResult, requestMethod, tableName, this.request);
903
776
  if (false !== cacheCheck) {
904
777
  return [2 /*return*/, cacheCheck];
905
778
  }
@@ -907,10 +780,10 @@ function restRequest(_a) {
907
780
  ++query[C6.PAGINATION][C6.PAGE];
908
781
  // this json stringify is to capture the new page number
909
782
  querySerialized = sortAndSerializeQueryObject(tables, query !== null && query !== void 0 ? query : {});
910
- cacheResult = apiRequestCache.find(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
783
+ cacheResult = exports.apiRequestCache.find(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
911
784
  } while (undefined !== cacheResult);
912
- if (request.debug && isDevelopment) {
913
- reactToastify.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);
785
+ if (debug && isDevelopment) {
786
+ 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);
914
787
  }
915
788
  // @ts-ignore - this is an incorrect warning on TS, it's well typed
916
789
  return [2 /*return*/, apiRequest];
@@ -918,17 +791,17 @@ function restRequest(_a) {
918
791
  cachingConfirmed = true;
919
792
  }
920
793
  else {
921
- if (request.debug && isDevelopment) {
794
+ if (debug && isDevelopment) {
922
795
  reactToastify.toast.info("DEVS: Ignore cache was set to true.", toastOptionsDevs);
923
796
  }
924
797
  }
925
- if (request.debug && isDevelopment) {
798
+ if (debug && isDevelopment) {
926
799
  reactToastify.toast.success("DEVS: Request not in cache." + (requestMethod === C6.GET ? "Page (" + query[C6.PAGINATION][C6.PAGE] + ")." : '') + " Logging cache 2 console.", toastOptionsDevs);
927
800
  }
928
801
  }
929
- else if (request.cacheResults) { // if we are not getting, we are updating, deleting, or inserting
802
+ else if (cacheResults) { // if we are not getting, we are updating, deleting, or inserting
930
803
  if (cacheResult) {
931
- cacheCheck = checkCache(cacheResult, requestMethod, tableName, request);
804
+ cacheCheck = checkCache(cacheResult, requestMethod, tableName, this.request);
932
805
  if (false !== cacheCheck) {
933
806
  return [2 /*return*/, cacheCheck];
934
807
  }
@@ -941,7 +814,7 @@ function restRequest(_a) {
941
814
  needsConditionOrPrimaryCheck = (PUT === requestMethod || DELETE === requestMethod)
942
815
  && false === skipPrimaryCheck;
943
816
  TABLES = C6.TABLES;
944
- 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();
817
+ primaryKey = (_k = (_j = (_h = structuredClone((_g = TABLES[operatingTable]) === null || _g === void 0 ? void 0 : _g.PRIMARY)) === null || _h === void 0 ? void 0 : _h.pop()) === null || _j === void 0 ? void 0 : _j.split('.')) === null || _k === void 0 ? void 0 : _k.pop();
945
818
  if (needsConditionOrPrimaryCheck) {
946
819
  if (undefined === primaryKey) {
947
820
  if (null === query
@@ -951,17 +824,17 @@ function restRequest(_a) {
951
824
  || query[C6.WHERE].length === 0)
952
825
  || (Object.keys(query === null || query === void 0 ? void 0 : query[C6.WHERE]).length === 0)) {
953
826
  console.error(query);
954
- 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 + ').');
827
+ throw Error('Failed to parse primary key information. Query: (' + JSON.stringify(query) + ') Primary Key: (' + JSON.stringify(primaryKey) + ') TABLES[operatingTable]?.PRIMARY: (' + JSON.stringify((_l = TABLES[operatingTable]) === null || _l === void 0 ? void 0 : _l.PRIMARY) + ') for operatingTable (' + operatingTable + ').');
955
828
  }
956
829
  }
957
830
  else {
958
831
  if (undefined === query
959
832
  || null === query
960
833
  || false === primaryKey in query) {
961
- if (true === request.debug && isDevelopment) {
834
+ if (true === debug && isDevelopment) {
962
835
  reactToastify.toast.error('DEVS: The primary key (' + primaryKey + ') was not provided!!');
963
836
  }
964
- throw Error('You must provide the primary key (' + primaryKey + ') for table (' + operatingTable + '). Request (' + JSON.stringify(request, undefined, 4) + ') Query (' + JSON.stringify(query) + ')');
837
+ throw Error('You must provide the primary key (' + primaryKey + ') for table (' + operatingTable + '). Request (' + JSON.stringify(this.request, undefined, 4) + ') Query (' + JSON.stringify(query) + ')');
965
838
  }
966
839
  if (undefined === (query === null || query === void 0 ? void 0 : query[primaryKey])
967
840
  || null === (query === null || query === void 0 ? void 0 : query[primaryKey])) {
@@ -970,55 +843,6 @@ function restRequest(_a) {
970
843
  }
971
844
  }
972
845
  }
973
- if (!(isNode && mysqlPool)) return [3 /*break*/, 2];
974
- return [4 /*yield*/, Promise.resolve().then(function () { return carbonSqlExecutor; })];
975
- case 1:
976
- CarbonSqlExecutor = (_h.sent()).CarbonSqlExecutor;
977
- engine = new CarbonSqlExecutor(mysqlPool, C6);
978
- switch (requestMethod) {
979
- case GET:
980
- return [2 /*return*/, engine
981
- .select(tableName, undefined, request)
982
- .then(function (rows) {
983
- // mirror the front‐end shape
984
- var serverResponse = {
985
- rest: rows,
986
- session: undefined,
987
- sql: true,
988
- };
989
- return serverResponse;
990
- })];
991
- case POST:
992
- return [2 /*return*/, engine
993
- .insert(tableName, request)
994
- .then(function (created) { return ({
995
- rest: created,
996
- }); })];
997
- case PUT:
998
- return [2 /*return*/, engine
999
- .update(tableName, undefined, request)
1000
- .then(function (updatedResult) {
1001
- var _a;
1002
- return ({
1003
- rest: updatedResult,
1004
- rowCount: (_a = updatedResult.affectedRows) !== null && _a !== void 0 ? _a : 0,
1005
- });
1006
- })];
1007
- case DELETE:
1008
- return [2 /*return*/, engine
1009
- .delete(tableName, undefined, request)
1010
- .then(function (deletedResult) {
1011
- var _a;
1012
- return ({
1013
- rest: deletedResult,
1014
- rowCount: (_a = deletedResult.affectedRows) !== null && _a !== void 0 ? _a : 0,
1015
- deleted: true,
1016
- });
1017
- })];
1018
- default:
1019
- throw new Error("Unsupported method: ".concat(requestMethod));
1020
- }
1021
- case 2:
1022
846
  // A part of me exists that wants to remove this, but it's a good feature
1023
847
  // this allows developers the ability to cache requests based on primary key
1024
848
  // for tables like `photos` this can be a huge performance boost
@@ -1040,12 +864,12 @@ function restRequest(_a) {
1040
864
  }
1041
865
  try {
1042
866
  console.groupCollapsed('%c API: (' + requestMethod + ') Request Query for (' + operatingTable + ') is about to fire, will return with promise!', 'color: #A020F0');
1043
- console.log(request);
867
+ console.log(this.request);
1044
868
  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');
1045
869
  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');
1046
870
  console.trace();
1047
871
  console.groupEnd();
1048
- axiosActiveRequest = axios[requestMethod.toLowerCase()].apply(axios, tslib.__spreadArray([restRequestUri], ((function () {
872
+ axiosActiveRequest = (_e = axios)[requestMethod.toLowerCase()].apply(_e, tslib.__spreadArray([restRequestUri], ((function () {
1049
873
  // @link - https://axios-http.com/docs/instance
1050
874
  // How configuration vs data is passed is variable, use documentation above for reference
1051
875
  if (requestMethod === GET) {
@@ -1055,9 +879,9 @@ function restRequest(_a) {
1055
879
  }];
1056
880
  }
1057
881
  else if (requestMethod === POST) {
1058
- if (undefined !== (request === null || request === void 0 ? void 0 : request.dataInsertMultipleRows)) {
882
+ if (undefined !== dataInsertMultipleRows) {
1059
883
  return [
1060
- request.dataInsertMultipleRows.map(function (data) {
884
+ dataInsertMultipleRows.map(function (data) {
1061
885
  return convertForRequestBody(data, fullTableList, C6, function (message) { return reactToastify.toast.error(message, toastOptions); });
1062
886
  }),
1063
887
  {
@@ -1092,7 +916,7 @@ function restRequest(_a) {
1092
916
  })()), false));
1093
917
  if (cachingConfirmed) {
1094
918
  // push to cache so we do not repeat the request
1095
- apiRequestCache.push({
919
+ exports.apiRequestCache.push({
1096
920
  requestArgumentsSerialized: querySerialized,
1097
921
  request: axiosActiveRequest
1098
922
  });
@@ -1103,11 +927,11 @@ function restRequest(_a) {
1103
927
  // returning the promise with this then is important for tests. todo - we could make that optional.
1104
928
  // https://rapidapi.com/guides/axios-async-await
1105
929
  return [2 /*return*/, axiosActiveRequest.then(function (response) { return tslib.__awaiter(_this, void 0, void 0, function () {
1106
- var cacheIndex, responseData_1, fetchDependencies, dependencies_1, fetchReferences_1, apiRequestPromises, _loop_1, _a, _b, _c, _i, tableToFetch;
930
+ var cacheIndex, responseData_1, dependencies_1, fetchReferences_1, apiRequestPromises, _loop_1, _a, _b, _c, _i, tableToFetch;
1107
931
  var _this = this;
1108
- var _d, _e, _f, _g, _h, _j, _k, _l, _m;
1109
- return tslib.__generator(this, function (_o) {
1110
- switch (_o.label) {
932
+ var _d, _e, _f, _g, _h, _j, _k;
933
+ return tslib.__generator(this, function (_l) {
934
+ switch (_l.label) {
1111
935
  case 0:
1112
936
  if (typeof response.data === 'string') {
1113
937
  if (isTest) {
@@ -1117,45 +941,43 @@ function restRequest(_a) {
1117
941
  return [2 /*return*/, Promise.reject(response)];
1118
942
  }
1119
943
  if (cachingConfirmed) {
1120
- cacheIndex = apiRequestCache.findIndex(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
1121
- apiRequestCache[cacheIndex].final = false === returnGetNextPageFunction;
944
+ cacheIndex = exports.apiRequestCache.findIndex(function (cache) { return cache.requestArgumentsSerialized === querySerialized; });
945
+ exports.apiRequestCache[cacheIndex].final = false === returnGetNextPageFunction;
1122
946
  // only cache get method requests
1123
- apiRequestCache[cacheIndex].response = response;
947
+ exports.apiRequestCache[cacheIndex].response = response;
1124
948
  }
1125
- 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!");
949
+ apiResponse = TestRestfulResponse(response, success, error);
1126
950
  if (false === apiResponse) {
1127
- if (request.debug && isDevelopment) {
951
+ if (debug && isDevelopment) {
1128
952
  reactToastify.toast.warning("DEVS: TestRestfulResponse returned false for (" + operatingTable + ").", toastOptionsDevs);
1129
953
  }
1130
954
  return [2 /*return*/, response];
1131
955
  }
1132
956
  // stateful operations are done in the response callback - its leverages rest generated functions
1133
957
  if (responseCallback) {
1134
- responseCallback(response, request, apiResponse);
958
+ responseCallback(response, this.request, apiResponse);
1135
959
  }
1136
960
  if (!(C6.GET === requestMethod)) return [3 /*break*/, 6];
1137
961
  responseData_1 = response.data;
1138
- returnGetNextPageFunction = 1 !== ((_e = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _e === void 0 ? void 0 : _e[C6.LIMIT]) &&
1139
- ((_f = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _f === void 0 ? void 0 : _f[C6.LIMIT]) === responseData_1.rest.length;
962
+ returnGetNextPageFunction = 1 !== ((_d = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _d === void 0 ? void 0 : _d[C6.LIMIT]) &&
963
+ ((_e = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _e === void 0 ? void 0 : _e[C6.LIMIT]) === responseData_1.rest.length;
1140
964
  if (false === isTest || true === isVerbose) {
1141
- 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');
965
+ console.groupCollapsed('%c API: Response (' + requestMethod + ' ' + tableName + ') returned length (' + ((_f = responseData_1.rest) === null || _f === void 0 ? void 0 : _f.length) + ') of possible (' + ((_g = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _g === void 0 ? void 0 : _g[C6.LIMIT]) + ') limit!', 'color: #0c0');
1142
966
  console.log('%c ' + requestMethod + ' ' + tableName, 'color: #0c0');
1143
- console.log('%c Request Data (note you may see the success and/or error prompt):', 'color: #0c0', request);
967
+ console.log('%c Request Data (note you may see the success and/or error prompt):', 'color: #0c0', this.request);
1144
968
  console.log('%c Response Data:', 'color: #0c0', responseData_1.rest);
1145
- 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);
969
+ console.log('%c Will return get next page function:' + (1 !== ((_h = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _h === void 0 ? void 0 : _h[C6.LIMIT]) ? '' : ' (Will not return with explicit limit 1 set)'), 'color: #0c0', true === returnGetNextPageFunction);
1146
970
  console.trace();
1147
971
  console.groupEnd();
1148
972
  }
1149
973
  if (false === returnGetNextPageFunction
1150
- && true === request.debug
974
+ && true === debug
1151
975
  && isDevelopment) {
1152
- reactToastify.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);
976
+ reactToastify.toast.success("DEVS: Response returned length (" + ((_j = responseData_1.rest) === null || _j === void 0 ? void 0 : _j.length) + ") less than limit (" + ((_k = query === null || query === void 0 ? void 0 : query[C6.PAGINATION]) === null || _k === void 0 ? void 0 : _k[C6.LIMIT]) + ").", toastOptionsDevs);
1153
977
  }
1154
- (_m = request.fetchDependencies) !== null && _m !== void 0 ? _m : (request.fetchDependencies = exports.eFetchDependencies.NONE);
1155
- if (!(request.fetchDependencies
1156
- && 'number' === typeof request.fetchDependencies
978
+ if (!(fetchDependencies
979
+ && 'number' === typeof fetchDependencies
1157
980
  && responseData_1.rest.length > 0)) return [3 /*break*/, 6];
1158
- fetchDependencies = request.fetchDependencies;
1159
981
  console.groupCollapsed('%c API: Fetch Dependencies segment (' + requestMethod + ' ' + tableName + ')'
1160
982
  + (fetchDependencies & exports.eFetchDependencies.CHILDREN ? ' | (CHILDREN|REFERENCED) ' : '')
1161
983
  + (fetchDependencies & exports.eFetchDependencies.PARENTS ? ' | (PARENTS|REFERENCED_BY)' : '')
@@ -1226,9 +1048,9 @@ function restRequest(_a) {
1226
1048
  console.log('fetchReferences', fetchReferences_1);
1227
1049
  _loop_1 = function (tableToFetch) {
1228
1050
  var referencesTables, shouldContinue, fetchTable, RestApi, nextFetchDependencies;
1229
- var _p;
1230
- return tslib.__generator(this, function (_q) {
1231
- switch (_q.label) {
1051
+ var _m;
1052
+ return tslib.__generator(this, function (_o) {
1053
+ switch (_o.label) {
1232
1054
  case 0:
1233
1055
  if (fetchDependencies & exports.eFetchDependencies.C6ENTITY
1234
1056
  && 'string' === typeof tableName
@@ -1248,7 +1070,7 @@ function restRequest(_a) {
1248
1070
  }
1249
1071
  return [4 /*yield*/, C6.IMPORT(tableToFetch)];
1250
1072
  case 1:
1251
- fetchTable = _q.sent();
1073
+ fetchTable = _o.sent();
1252
1074
  RestApi = fetchTable.default;
1253
1075
  console.log('%c Fetch Dependencies will select (' + tableToFetch + ') using GET request', 'color: #33ccff');
1254
1076
  nextFetchDependencies = exports.eFetchDependencies.NONE;
@@ -1271,8 +1093,8 @@ function restRequest(_a) {
1271
1093
  // it not certain that they are using carbons' entities either
1272
1094
  // this is a dynamic call to the rest api, any generated table may resolve with (RestApi)
1273
1095
  // todo - using value to avoid joins.... but. maybe this should be a parameterizable option -- think race conditions; its safer to join
1274
- apiRequestPromises.push(RestApi.Get((_p = {},
1275
- _p[C6.WHERE] = {
1096
+ apiRequestPromises.push(RestApi.Get((_m = {},
1097
+ _m[C6.WHERE] = {
1276
1098
  0: Object.keys(fetchReferences_1[tableToFetch]).reduce(function (sum, column) {
1277
1099
  fetchReferences_1[tableToFetch][column] = fetchReferences_1[tableToFetch][column].flat(Infinity);
1278
1100
  if (0 === fetchReferences_1[tableToFetch][column].length) {
@@ -1287,8 +1109,8 @@ function restRequest(_a) {
1287
1109
  return sum;
1288
1110
  }, {})
1289
1111
  },
1290
- _p.fetchDependencies = nextFetchDependencies,
1291
- _p)));
1112
+ _m.fetchDependencies = nextFetchDependencies,
1113
+ _m)));
1292
1114
  return [2 /*return*/];
1293
1115
  }
1294
1116
  });
@@ -1298,7 +1120,7 @@ function restRequest(_a) {
1298
1120
  for (_c in _a)
1299
1121
  _b.push(_c);
1300
1122
  _i = 0;
1301
- _o.label = 1;
1123
+ _l.label = 1;
1302
1124
  case 1:
1303
1125
  if (!(_i < _b.length)) return [3 /*break*/, 4];
1304
1126
  _c = _b[_i];
@@ -1306,8 +1128,8 @@ function restRequest(_a) {
1306
1128
  tableToFetch = _c;
1307
1129
  return [5 /*yield**/, _loop_1(tableToFetch)];
1308
1130
  case 2:
1309
- _o.sent();
1310
- _o.label = 3;
1131
+ _l.sent();
1132
+ _l.label = 3;
1311
1133
  case 3:
1312
1134
  _i++;
1313
1135
  return [3 /*break*/, 1];
@@ -1315,16 +1137,17 @@ function restRequest(_a) {
1315
1137
  console.groupEnd();
1316
1138
  return [4 /*yield*/, Promise.all(apiRequestPromises)];
1317
1139
  case 5:
1318
- _o.sent();
1140
+ _l.sent();
1319
1141
  apiRequestPromises.map(function (promise) { return tslib.__awaiter(_this, void 0, void 0, function () {
1320
1142
  var _a, _b;
1321
1143
  return tslib.__generator(this, function (_c) {
1322
1144
  switch (_c.label) {
1323
1145
  case 0:
1324
- if (!Array.isArray(request.fetchDependencies)) {
1325
- request.fetchDependencies = [];
1146
+ if (!Array.isArray(this.request.fetchDependencies)) {
1147
+ // to reassign value we must ref the root
1148
+ this.request.fetchDependencies = [];
1326
1149
  }
1327
- _b = (_a = request.fetchDependencies).push;
1150
+ _b = (_a = this.request.fetchDependencies).push;
1328
1151
  return [4 /*yield*/, promise];
1329
1152
  case 1:
1330
1153
  _b.apply(_a, [_c.sent()]);
@@ -1332,9 +1155,9 @@ function restRequest(_a) {
1332
1155
  }
1333
1156
  });
1334
1157
  }); });
1335
- _o.label = 6;
1158
+ _l.label = 6;
1336
1159
  case 6:
1337
- if (request.debug && isDevelopment) {
1160
+ if (debug && isDevelopment) {
1338
1161
  reactToastify.toast.success("DEVS: (" + requestMethod + ") request complete.", toastOptionsDevs);
1339
1162
  }
1340
1163
  return [2 /*return*/, response];
@@ -1342,98 +1165,326 @@ function restRequest(_a) {
1342
1165
  });
1343
1166
  }); })];
1344
1167
  }
1345
- catch (error) {
1168
+ catch (throwableError) {
1346
1169
  if (isTest) {
1347
- throw new Error(JSON.stringify(error));
1170
+ throw new Error(JSON.stringify(throwableError));
1348
1171
  }
1349
1172
  console.groupCollapsed('%c API: An error occurred in the try catch block. returning null!', 'color: #ff0000');
1350
1173
  console.log('%c ' + requestMethod + ' ' + tableName, 'color: #A020F0');
1351
- console.warn(error);
1174
+ console.warn(throwableError);
1352
1175
  console.trace();
1353
1176
  console.groupEnd();
1354
- 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!");
1177
+ TestRestfulResponse(throwableError, success, error);
1355
1178
  return [2 /*return*/, null];
1356
1179
  }
1357
1180
  return [2 /*return*/];
1358
- }
1359
- });
1360
- });
1361
- }
1362
- var query;
1363
- if (request === void 0) { request = {}; }
1181
+ });
1182
+ }); };
1183
+ return [4 /*yield*/, apiRequest()];
1184
+ case 1: return [2 /*return*/, _b.sent()];
1185
+ }
1186
+ });
1187
+ });
1188
+ };
1189
+ return HttpExecutor;
1190
+ }(Executor));
1191
+
1192
+ var HttpExecutor$1 = /*#__PURE__*/Object.freeze({
1193
+ __proto__: null,
1194
+ HttpExecutor: HttpExecutor
1195
+ });
1196
+
1197
+ var SqlExecutor = /** @class */ (function (_super) {
1198
+ tslib.__extends(SqlExecutor, _super);
1199
+ function SqlExecutor() {
1200
+ return _super !== null && _super.apply(this, arguments) || this;
1201
+ }
1202
+ SqlExecutor.prototype.execute = function () {
1203
+ switch (this.config.requestMethod) {
1204
+ case 'GET':
1205
+ return this.select(this.config.restModel.TABLE_NAME, undefined, this.request).then(function (rows) { return ({ rest: rows }); });
1206
+ case 'POST':
1207
+ return this.insert(this.config.restModel.TABLE_NAME, this.request);
1208
+ case 'PUT':
1209
+ return this.update(this.config.restModel.TABLE_NAME, undefined, this.request);
1210
+ case 'DELETE':
1211
+ return this.delete(this.config.restModel.TABLE_NAME, undefined, this.request);
1212
+ }
1213
+ };
1214
+ SqlExecutor.prototype.withConnection = function (cb) {
1215
+ return tslib.__awaiter(this, void 0, void 0, function () {
1216
+ var conn;
1217
+ return tslib.__generator(this, function (_a) {
1218
+ switch (_a.label) {
1219
+ case 0: return [4 /*yield*/, this.config.mysqlPool.getConnection()];
1220
+ case 1:
1221
+ conn = _a.sent();
1222
+ _a.label = 2;
1223
+ case 2:
1224
+ _a.trys.push([2, , 4, 5]);
1225
+ return [4 /*yield*/, cb(conn)];
1226
+ case 3: return [2 /*return*/, _a.sent()];
1227
+ case 4:
1228
+ conn.release();
1229
+ return [7 /*endfinally*/];
1230
+ case 5: return [2 /*return*/];
1231
+ }
1232
+ });
1233
+ });
1234
+ };
1235
+ SqlExecutor.prototype.select = function (table, primary, args) {
1236
+ return tslib.__awaiter(this, void 0, void 0, function () {
1237
+ var sql;
1238
+ var _this = this;
1364
1239
  return tslib.__generator(this, function (_a) {
1365
1240
  switch (_a.label) {
1366
1241
  case 0:
1367
- console.groupCollapsed('%c API: (' + requestMethod + ') Request for (' + operatingTable + ')', 'color: #0c0');
1368
- console.log('request', request);
1369
- console.groupEnd();
1370
- if ('function' === typeof queryCallback) {
1371
- query = queryCallback(request); // obj or obj[]
1372
- }
1373
- else {
1374
- query = queryCallback;
1375
- }
1376
- if (undefined === query || null === query) {
1377
- if (request.debug && isDevelopment) {
1378
- reactToastify.toast.warning("DEV: queryCallback returned undefined, signaling in Custom Cache. (returning null)", toastOptionsDevs);
1379
- }
1380
- console.groupCollapsed('%c API: (' + requestMethod + ') Request Query for (' + operatingTable + ') undefined, returning null (will not fire ajax)!', 'color: #c00');
1381
- 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');
1382
- console.trace();
1383
- console.groupEnd();
1384
- return [2 /*return*/, null];
1242
+ sql = buildSelectQuery(table, primary, args);
1243
+ return [4 /*yield*/, this.withConnection(function (conn) { return tslib.__awaiter(_this, void 0, void 0, function () {
1244
+ var rows;
1245
+ return tslib.__generator(this, function (_a) {
1246
+ switch (_a.label) {
1247
+ case 0:
1248
+ console.log(sql);
1249
+ return [4 /*yield*/, conn.query(sql)];
1250
+ case 1:
1251
+ rows = (_a.sent())[0];
1252
+ return [2 /*return*/, rows];
1253
+ }
1254
+ });
1255
+ }); })];
1256
+ case 1: return [2 /*return*/, _a.sent()];
1257
+ }
1258
+ });
1259
+ });
1260
+ };
1261
+ SqlExecutor.prototype.insert = function (table, data) {
1262
+ return tslib.__awaiter(this, void 0, void 0, function () {
1263
+ var keys, values, placeholders, sql;
1264
+ var _this = this;
1265
+ return tslib.__generator(this, function (_a) {
1266
+ switch (_a.label) {
1267
+ case 0:
1268
+ keys = Object.keys(data);
1269
+ values = keys.map(function (k) { return data[k]; });
1270
+ placeholders = keys.map(function () { return '?'; }).join(', ');
1271
+ sql = "INSERT INTO `".concat(table, "` (").concat(keys.join(', '), ") VALUES (").concat(placeholders, ")");
1272
+ return [4 /*yield*/, this.withConnection(function (conn) { return tslib.__awaiter(_this, void 0, void 0, function () {
1273
+ var result;
1274
+ return tslib.__generator(this, function (_a) {
1275
+ switch (_a.label) {
1276
+ case 0: return [4 /*yield*/, conn.execute(sql, values)];
1277
+ case 1:
1278
+ result = (_a.sent())[0];
1279
+ return [2 /*return*/, result];
1280
+ }
1281
+ });
1282
+ }); })];
1283
+ case 1: return [2 /*return*/, _a.sent()];
1284
+ }
1285
+ });
1286
+ });
1287
+ };
1288
+ SqlExecutor.prototype.update = function (table, primary, data) {
1289
+ return tslib.__awaiter(this, void 0, void 0, function () {
1290
+ var keys, values, updates, sql;
1291
+ var _this = this;
1292
+ return tslib.__generator(this, function (_a) {
1293
+ switch (_a.label) {
1294
+ case 0:
1295
+ if (!primary) {
1296
+ throw new Error('Primary key is required for update');
1385
1297
  }
1386
- if (C6.GET === requestMethod) {
1387
- if (undefined === query[C6.PAGINATION]) {
1388
- query[C6.PAGINATION] = {};
1389
- }
1390
- query[C6.PAGINATION][C6.PAGE] = query[C6.PAGINATION][C6.PAGE] || 1;
1391
- query[C6.PAGINATION][C6.LIMIT] = query[C6.PAGINATION][C6.LIMIT] || 100;
1298
+ keys = Object.keys(data);
1299
+ values = keys.map(function (k) { return data[k]; });
1300
+ updates = keys.map(function (k) { return "`".concat(k, "` = ?"); }).join(', ');
1301
+ sql = "UPDATE `".concat(table, "` SET ").concat(updates, " WHERE `").concat(primary, "` = ?");
1302
+ values.push(data[primary]);
1303
+ return [4 /*yield*/, this.withConnection(function (conn) { return tslib.__awaiter(_this, void 0, void 0, function () {
1304
+ var result;
1305
+ return tslib.__generator(this, function (_a) {
1306
+ switch (_a.label) {
1307
+ case 0: return [4 /*yield*/, conn.execute(sql, values)];
1308
+ case 1:
1309
+ result = (_a.sent())[0];
1310
+ return [2 /*return*/, result];
1311
+ }
1312
+ });
1313
+ }); })];
1314
+ case 1: return [2 /*return*/, _a.sent()];
1315
+ }
1316
+ });
1317
+ });
1318
+ };
1319
+ SqlExecutor.prototype.delete = function (table, primary, args) {
1320
+ return tslib.__awaiter(this, void 0, void 0, function () {
1321
+ var sql;
1322
+ var _this = this;
1323
+ return tslib.__generator(this, function (_a) {
1324
+ switch (_a.label) {
1325
+ case 0:
1326
+ if (!primary || !(args === null || args === void 0 ? void 0 : args[primary])) {
1327
+ throw new Error('Primary key and value required for delete');
1392
1328
  }
1393
- return [4 /*yield*/, apiRequest()];
1329
+ sql = "DELETE FROM `".concat(table, "` WHERE `").concat(primary, "` = ?");
1330
+ return [4 /*yield*/, this.withConnection(function (conn) { return tslib.__awaiter(_this, void 0, void 0, function () {
1331
+ var result;
1332
+ return tslib.__generator(this, function (_a) {
1333
+ switch (_a.label) {
1334
+ case 0: return [4 /*yield*/, conn.execute(sql, [args[primary]])];
1335
+ case 1:
1336
+ result = (_a.sent())[0];
1337
+ return [2 /*return*/, result];
1338
+ }
1339
+ });
1340
+ }); })];
1394
1341
  case 1: return [2 /*return*/, _a.sent()];
1395
1342
  }
1396
1343
  });
1397
1344
  });
1398
1345
  };
1399
- }
1346
+ return SqlExecutor;
1347
+ }(Executor));
1400
1348
 
1401
- function timeout(shouldContinueAfterTimeout, cb, timeoutMs) {
1402
- if (timeoutMs === void 0) { timeoutMs = 3000; }
1403
- var timer = function () { return setTimeout(function () {
1404
- if (false === shouldContinueAfterTimeout()) {
1405
- return;
1349
+ var SqlExecutor$1 = /*#__PURE__*/Object.freeze({
1350
+ __proto__: null,
1351
+ SqlExecutor: SqlExecutor
1352
+ });
1353
+
1354
+ function determineRuntimeJsType(mysqlType) {
1355
+ var base = mysqlType.toLowerCase().split('(')[0];
1356
+ if ([
1357
+ 'binary', 'varbinary', 'blob', 'tinyblob', 'mediumblob', 'longblob'
1358
+ ].includes(base))
1359
+ return 'buffer';
1360
+ if ([
1361
+ 'json', 'geometry', 'point', 'polygon', 'multipoint', 'multilinestring', 'multipolygon', 'geometrycollection'
1362
+ ].includes(base))
1363
+ return 'object';
1364
+ if ([
1365
+ 'tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint',
1366
+ 'decimal', 'dec', 'numeric', 'float', 'double', 'real'
1367
+ ].includes(base))
1368
+ return 'number';
1369
+ if ([
1370
+ 'boolean', 'bool'
1371
+ ].includes(base))
1372
+ return 'boolean';
1373
+ return 'string';
1374
+ }
1375
+ function getPrimaryKeyTypes(table) {
1376
+ var _a;
1377
+ var result = {};
1378
+ var _loop_1 = function (key) {
1379
+ var fullKey = (_a = Object.entries(table.COLUMNS).find(function (_a) {
1380
+ _a[0]; var short = _a[1];
1381
+ return short === key;
1382
+ })) === null || _a === void 0 ? void 0 : _a[0];
1383
+ if (typeof fullKey === 'string') {
1384
+ var validation = table.TYPE_VALIDATION[fullKey];
1385
+ if (!validation)
1386
+ return "continue";
1387
+ result[key] = determineRuntimeJsType(validation.MYSQL_TYPE);
1406
1388
  }
1407
- cb();
1408
- }, timeoutMs); };
1409
- var timerId = timer();
1410
- return function () {
1411
- clearTimeout(timerId);
1412
1389
  };
1390
+ for (var _i = 0, _b = table.PRIMARY_SHORT; _i < _b.length; _i++) {
1391
+ var key = _b[_i];
1392
+ _loop_1(key);
1393
+ }
1394
+ return result;
1395
+ }
1396
+
1397
+ /**
1398
+ * Conditionally group a log if verbose.
1399
+ */
1400
+ function group(title, data) {
1401
+ if (!isVerbose)
1402
+ return;
1403
+ console.groupCollapsed("%c".concat(title), "color: #007acc");
1404
+ if (data !== undefined)
1405
+ console.log(data);
1406
+ console.groupEnd();
1407
+ }
1408
+ function info(message) {
1409
+ var optional = [];
1410
+ for (var _i = 1; _i < arguments.length; _i++) {
1411
+ optional[_i - 1] = arguments[_i];
1412
+ }
1413
+ if (!isVerbose)
1414
+ return;
1415
+ console.info.apply(console, tslib.__spreadArray(["%cINFO: ".concat(message), "color: #0a0"], optional, false));
1416
+ }
1417
+ function warn(message) {
1418
+ var optional = [];
1419
+ for (var _i = 1; _i < arguments.length; _i++) {
1420
+ optional[_i - 1] = arguments[_i];
1421
+ }
1422
+ console.warn.apply(console, tslib.__spreadArray(["%cWARN: ".concat(message), "color: #e90"], optional, false));
1423
+ }
1424
+ function error(message) {
1425
+ var optional = [];
1426
+ for (var _i = 1; _i < arguments.length; _i++) {
1427
+ optional[_i - 1] = arguments[_i];
1428
+ }
1429
+ console.error.apply(console, tslib.__spreadArray(["%cERROR: ".concat(message), "color: #c00"], optional, false));
1430
+ }
1431
+
1432
+ function checkAllRequestsComplete() {
1433
+ var stillRunning = exports.apiRequestCache.filter(function (cache) { return undefined === cache.response; });
1434
+ if (stillRunning.length !== 0) {
1435
+ if (document === null || document === undefined) {
1436
+ throw new Error('document is undefined while waiting for API requests to complete (' + JSON.stringify(exports.apiRequestCache) + ')');
1437
+ }
1438
+ // when requests return emtpy sets in full renders, it may not be possible to track their progress.
1439
+ console.warn('stillRunning...', stillRunning);
1440
+ return stillRunning.map(function (cache) { return cache.requestArgumentsSerialized; });
1441
+ }
1442
+ return true;
1443
+ }
1444
+
1445
+ function onSuccess(message) {
1446
+ reactToastify.toast.success(message, isDevelopment ? toastOptionsDevs : toastOptions);
1447
+ }
1448
+ function onError(message) {
1449
+ reactToastify.toast.error(message, isDevelopment ? toastOptionsDevs : toastOptions);
1413
1450
  }
1414
1451
 
1415
1452
  exports.C6Constants = C6Constants;
1416
- exports.CarbonSqlExecutor = CarbonSqlExecutor;
1417
1453
  exports.DELETE = DELETE;
1454
+ exports.Executor = Executor;
1418
1455
  exports.GET = GET;
1456
+ exports.HttpExecutor = HttpExecutor;
1419
1457
  exports.POST = POST;
1420
1458
  exports.PUT = PUT;
1459
+ exports.SqlExecutor = SqlExecutor;
1421
1460
  exports.TestRestfulResponse = TestRestfulResponse;
1422
1461
  exports.axiosInstance = axiosInstance;
1462
+ exports.buildAggregateField = buildAggregateField;
1463
+ exports.buildBooleanJoinedConditions = buildBooleanJoinedConditions;
1464
+ exports.buildSelectQuery = buildSelectQuery;
1423
1465
  exports.checkAllRequestsComplete = checkAllRequestsComplete;
1466
+ exports.checkCache = checkCache;
1424
1467
  exports.clearCache = clearCache;
1425
1468
  exports.convertForRequestBody = convertForRequestBody;
1426
- exports.extendedTypeHints = extendedTypeHints;
1469
+ exports.determineRuntimeJsType = determineRuntimeJsType;
1470
+ exports.error = error;
1427
1471
  exports.getEnvVar = getEnvVar;
1472
+ exports.getPrimaryKeyTypes = getPrimaryKeyTypes;
1473
+ exports.group = group;
1474
+ exports.info = info;
1428
1475
  exports.isLocal = isDevelopment;
1429
1476
  exports.isNode = isNode;
1430
1477
  exports.isPromise = isPromise;
1431
1478
  exports.isTest = isTest;
1432
1479
  exports.isVerbose = isVerbose;
1480
+ exports.onError = onError;
1481
+ exports.onSuccess = onSuccess;
1433
1482
  exports.removeInvalidKeys = removeInvalidKeys;
1434
1483
  exports.removePrefixIfExists = removePrefixIfExists;
1435
1484
  exports.restRequest = restRequest;
1485
+ exports.sortAndSerializeQueryObject = sortAndSerializeQueryObject;
1436
1486
  exports.timeout = timeout;
1437
1487
  exports.toastOptions = toastOptions;
1438
1488
  exports.toastOptionsDevs = toastOptionsDevs;
1489
+ exports.warn = warn;
1439
1490
  //# sourceMappingURL=index.cjs.js.map