@carbonorm/carbonnode 1.5.2 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/api/interfaces/ormInterfaces.d.ts +12 -4
- package/dist/api/restRequest.d.ts +15 -3
- package/dist/index.cjs.js +169 -40
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +170 -41
- package/dist/index.esm.js.map +1 -1
- package/package.json +2 -2
- package/scripts/assets/handlebars/C6.ts.handlebars +39 -0
- package/scripts/assets/handlebars/C6RestApi.ts.handlebars +23 -0
- package/scripts/generateRestBindings.cjs +6 -2
- package/scripts/generateRestBindings.ts +6 -5
- package/src/api/interfaces/ormInterfaces.ts +27 -2
- package/src/api/restRequest.ts +129 -30
- package/scripts/assets/handlebars/WsLiveUpdates.ts.handlebars +0 -22
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
2
3
|
var __values = (this && this.__values) || function(o) {
|
|
3
4
|
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
4
5
|
if (m) return m.call(o);
|
|
@@ -10,10 +11,12 @@ var __values = (this && this.__values) || function(o) {
|
|
|
10
11
|
};
|
|
11
12
|
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
12
13
|
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
15
|
var execSync = require('child_process').execSync;
|
|
14
16
|
var fs = require('fs');
|
|
15
17
|
var path = require('path');
|
|
16
18
|
var Handlebars = require('handlebars');
|
|
19
|
+
var package_json_1 = require("../package.json");
|
|
17
20
|
var args = process.argv.slice(2); // Slice the first two elements
|
|
18
21
|
var argMap = {};
|
|
19
22
|
for (var i = 0; i < args.length; i += 2) {
|
|
@@ -284,6 +287,7 @@ var parseSQLToTypeScript = function (sql) {
|
|
|
284
287
|
}
|
|
285
288
|
var tables = Object.values(tableData);
|
|
286
289
|
return {
|
|
290
|
+
C6VERSION: package_json_1.version,
|
|
287
291
|
PREFIX: MySQLDump.DB_PREFIX,
|
|
288
292
|
TABLES: tables,
|
|
289
293
|
RestTableNames: tables.map(function (table) { return "'" + table.TABLE_NAME + "'"; }).join('\n | '),
|
|
@@ -299,8 +303,8 @@ fs.writeFileSync(path.join(process.cwd(), 'C6MySqlDump.json'), JSON.stringify(ta
|
|
|
299
303
|
// import this file src/assets/handlebars/C6.tsx.handlebars for a mustache template
|
|
300
304
|
var c6Template = fs.readFileSync(path.resolve(__dirname, 'assets/handlebars/C6.ts.handlebars'), 'utf-8');
|
|
301
305
|
fs.writeFileSync(path.join(MySQLDump.OUTPUT_DIR, 'C6.ts'), Handlebars.compile(c6Template)(tableData));
|
|
302
|
-
var
|
|
303
|
-
fs.writeFileSync(path.join(MySQLDump.OUTPUT_DIR, '
|
|
306
|
+
var C6RestApiTemplate = fs.readFileSync(path.resolve(__dirname, 'assets/handlebars/C6RestApi.ts.handlebars'), 'utf-8');
|
|
307
|
+
fs.writeFileSync(path.join(MySQLDump.OUTPUT_DIR, 'C6RestApi.ts'), Handlebars.compile(C6RestApiTemplate)(tableData));
|
|
304
308
|
var template = fs.readFileSync(path.resolve(__dirname, 'assets/handlebars/Table.ts.handlebars'), 'utf-8');
|
|
305
309
|
var testTemplate = fs.readFileSync(path.resolve(__dirname, 'assets/handlebars/Table.test.ts.handlebars'), 'utf-8');
|
|
306
310
|
Object.values(tableData.TABLES).forEach(function (tableData) {
|
|
@@ -4,7 +4,7 @@ const {execSync} = require('child_process');
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const Handlebars = require('handlebars');
|
|
7
|
-
|
|
7
|
+
import {version} from '../package.json';
|
|
8
8
|
|
|
9
9
|
const args = process.argv.slice(2); // Slice the first two elements
|
|
10
10
|
const argMap = {};
|
|
@@ -130,13 +130,13 @@ const pathRuntimeReference = MySQLDump.RELATIVE_OUTPUT_DIR.replace(/(^\/(src\/)?
|
|
|
130
130
|
// Usage example
|
|
131
131
|
const dumpFileLocation = MySQLDump.MySQLDump();
|
|
132
132
|
|
|
133
|
-
type ColumnInfo = {
|
|
133
|
+
/*type ColumnInfo = {
|
|
134
134
|
type: string;
|
|
135
135
|
length?: string;
|
|
136
136
|
autoIncrement: boolean;
|
|
137
137
|
notNull: boolean;
|
|
138
138
|
defaultValue?: string;
|
|
139
|
-
}
|
|
139
|
+
};*/
|
|
140
140
|
|
|
141
141
|
type foreignKeyInfo = {
|
|
142
142
|
TABLE: string,
|
|
@@ -367,6 +367,7 @@ const parseSQLToTypeScript = (sql: string) => {
|
|
|
367
367
|
|
|
368
368
|
|
|
369
369
|
return {
|
|
370
|
+
C6VERSION: version,
|
|
370
371
|
PREFIX: MySQLDump.DB_PREFIX,
|
|
371
372
|
TABLES: tables,
|
|
372
373
|
RestTableNames: tables.map(table => "'" + table.TABLE_NAME + "'").join('\n | '),
|
|
@@ -389,9 +390,9 @@ const c6Template = fs.readFileSync(path.resolve(__dirname, 'assets/handlebars/C6
|
|
|
389
390
|
|
|
390
391
|
fs.writeFileSync(path.join(MySQLDump.OUTPUT_DIR, 'C6.ts'), Handlebars.compile(c6Template)(tableData));
|
|
391
392
|
|
|
392
|
-
const
|
|
393
|
+
const C6RestApiTemplate = fs.readFileSync(path.resolve(__dirname, 'assets/handlebars/C6RestApi.ts.handlebars'), 'utf-8');
|
|
393
394
|
|
|
394
|
-
fs.writeFileSync(path.join(MySQLDump.OUTPUT_DIR, '
|
|
395
|
+
fs.writeFileSync(path.join(MySQLDump.OUTPUT_DIR, 'C6RestApi.ts'), Handlebars.compile(C6RestApiTemplate)(tableData));
|
|
395
396
|
|
|
396
397
|
const template = fs.readFileSync(path.resolve(__dirname, 'assets/handlebars/Table.ts.handlebars'), 'utf-8');
|
|
397
398
|
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
apiReturn,
|
|
3
|
+
iAPI,
|
|
4
|
+
iDeleteC6RestResponse,
|
|
5
|
+
iPostC6RestResponse,
|
|
6
|
+
iGetC6RestResponse,
|
|
7
|
+
iPutC6RestResponse
|
|
8
|
+
} from "api/restRequest";
|
|
9
|
+
|
|
10
|
+
|
|
1
11
|
export interface stringMap {
|
|
2
12
|
[key: string]: string;
|
|
3
13
|
}
|
|
@@ -38,8 +48,23 @@ export interface iC6RestfulModel<RestShortTableNames extends string = string> {
|
|
|
38
48
|
TABLE_REFERENCED_BY: { [columnName: string]: iConstraint[] },
|
|
39
49
|
}
|
|
40
50
|
|
|
51
|
+
export interface iRestApiFunctions {
|
|
52
|
+
Delete: (request?: (iAPI<any> & any)) => apiReturn<iDeleteC6RestResponse<any>>;
|
|
53
|
+
Post: (request?: (iAPI<any> & any)) => apiReturn<iPostC6RestResponse<any>>;
|
|
54
|
+
Get: (request?: (iAPI<any> & any)) => apiReturn<iGetC6RestResponse<any>>;
|
|
55
|
+
Put: (request?: (iAPI<any> & any)) => apiReturn<iPutC6RestResponse<any>>
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface tC6Tables { [key: string]: (iC6RestfulModel & { [key: string]: any }) }
|
|
59
|
+
|
|
60
|
+
export interface tC6RestApi {
|
|
61
|
+
[key: string]: {
|
|
62
|
+
REST: iRestApiFunctions,
|
|
63
|
+
PUT: Function;
|
|
64
|
+
POST: Function;
|
|
65
|
+
DELETE: Function;
|
|
66
|
+
};
|
|
67
|
+
}
|
|
41
68
|
|
|
42
|
-
export type tC6Tables = { [key: string]: (iC6RestfulModel & { [key: string]: any }) }
|
|
43
69
|
|
|
44
|
-
export type tWsLiveUpdate = { [key: string]: { PUT: Function, POST: Function, DELETE: Function } };
|
|
45
70
|
|
package/src/api/restRequest.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import axiosInstance from "api/axiosInstance";
|
|
2
2
|
import convertForRequestBody from "api/convertForRequestBody";
|
|
3
|
-
import {iC6RestfulModel} from "api/interfaces/ormInterfaces";
|
|
3
|
+
import {iC6RestfulModel, iConstraint, iRestApiFunctions} from "api/interfaces/ormInterfaces";
|
|
4
4
|
import {AxiosInstance, AxiosPromise, AxiosResponse} from "axios";
|
|
5
5
|
|
|
6
6
|
import {toast} from "react-toastify";
|
|
@@ -105,10 +105,19 @@ type DeepPartialAny<T> = {
|
|
|
105
105
|
[P in keyof T]?: T[P] extends AnyObject ? DeepPartialAny<T[P]> : any
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
export enum eFetchDependencies {
|
|
109
|
+
NONE = 0,
|
|
110
|
+
REFERENCED = 1,
|
|
111
|
+
CHILDREN = 1,
|
|
112
|
+
REFERENCES = 2,
|
|
113
|
+
PARENTS = 2,
|
|
114
|
+
ALL = 3
|
|
115
|
+
}
|
|
116
|
+
|
|
108
117
|
export type iAPI<RestTableInterfaces extends { [key: string]: any }> = RestTableInterfaces & {
|
|
109
118
|
dataInsertMultipleRows?: RestTableInterfaces[],
|
|
110
119
|
cacheResults?: boolean, // aka ignoreCache
|
|
111
|
-
fetchDependencies?:
|
|
120
|
+
fetchDependencies?: eFetchDependencies|Promise<apiReturn<iGetC6RestResponse<any>>>[],
|
|
112
121
|
debug?: boolean,
|
|
113
122
|
success?: string | ((r: AxiosResponse) => (string | void)),
|
|
114
123
|
error?: string | ((r: AxiosResponse) => (string | void)),
|
|
@@ -297,11 +306,15 @@ export interface iPutC6RestResponse<RestData = any, RequestData = any> extends i
|
|
|
297
306
|
}
|
|
298
307
|
|
|
299
308
|
export interface iC6Object {
|
|
309
|
+
C6VERSION: string,
|
|
300
310
|
TABLES: {
|
|
301
311
|
[key: string]: iC6RestfulModel &
|
|
302
312
|
{ [key: string]: string | number }
|
|
303
313
|
},
|
|
304
314
|
PREFIX: string,
|
|
315
|
+
IMPORT: (tableName: string) => Promise<{
|
|
316
|
+
default: iRestApiFunctions
|
|
317
|
+
}>,
|
|
305
318
|
|
|
306
319
|
[key: string]: any
|
|
307
320
|
}
|
|
@@ -751,8 +764,9 @@ export default function restApi<
|
|
|
751
764
|
// we had removed the value from the request to add to the URI.
|
|
752
765
|
addBackPK?.(); // adding back so post-processing methods work
|
|
753
766
|
|
|
767
|
+
// returning the promise with this then is important for tests. todo - we could make that optional.
|
|
754
768
|
// https://rapidapi.com/guides/axios-async-await
|
|
755
|
-
return axiosActiveRequest.then(response => {
|
|
769
|
+
return axiosActiveRequest.then(async (response) => {
|
|
756
770
|
|
|
757
771
|
if (typeof response.data === 'string') {
|
|
758
772
|
|
|
@@ -768,58 +782,143 @@ export default function restApi<
|
|
|
768
782
|
|
|
769
783
|
}
|
|
770
784
|
|
|
785
|
+
if (cachingConfirmed) {
|
|
786
|
+
|
|
787
|
+
const cacheIndex = apiRequestCache.findIndex(cache => cache.requestArgumentsSerialized === querySerialized);
|
|
788
|
+
|
|
789
|
+
apiRequestCache[cacheIndex].final = false === returnGetNextPageFunction
|
|
790
|
+
|
|
791
|
+
// only cache get method requests
|
|
792
|
+
apiRequestCache[cacheIndex].response = response
|
|
793
|
+
|
|
794
|
+
}
|
|
795
|
+
|
|
771
796
|
apiResponse = TestRestfulResponse(response, request?.success, request?.error ?? "An unexpected API error occurred!")
|
|
772
797
|
|
|
773
|
-
if (false
|
|
798
|
+
if (false === apiResponse) {
|
|
774
799
|
|
|
775
|
-
|
|
800
|
+
if (request.debug && isLocal) {
|
|
776
801
|
|
|
777
|
-
|
|
802
|
+
toast.warning("DEVS: TestRestfulResponse returned false for (" + operatingTable + ").", toastOptionsDevs);
|
|
778
803
|
|
|
779
|
-
|
|
804
|
+
}
|
|
780
805
|
|
|
781
|
-
|
|
782
|
-
returnGetNextPageFunction = 1 !== query?.[C6.PAGINATION]?.[C6.LIMIT] &&
|
|
783
|
-
query?.[C6.PAGINATION]?.[C6.LIMIT] === responseData.rest.length
|
|
806
|
+
return response;
|
|
784
807
|
|
|
785
|
-
|
|
808
|
+
}
|
|
786
809
|
|
|
787
|
-
|
|
810
|
+
responseCallback(response, request, apiResponse)
|
|
788
811
|
|
|
789
|
-
|
|
812
|
+
if (C6.GET === requestMethod) {
|
|
790
813
|
|
|
791
|
-
|
|
814
|
+
const responseData = response.data as iGetC6RestResponse<any>;
|
|
792
815
|
|
|
793
|
-
|
|
816
|
+
returnGetNextPageFunction = 1 !== query?.[C6.PAGINATION]?.[C6.LIMIT] &&
|
|
817
|
+
query?.[C6.PAGINATION]?.[C6.LIMIT] === responseData.rest.length
|
|
794
818
|
|
|
795
|
-
|
|
819
|
+
if (false === isTest || true === isVerbose) {
|
|
796
820
|
|
|
797
|
-
|
|
821
|
+
console.groupCollapsed('%c API: Response returned length (' + responseData.rest?.length + ') of possible (' + query?.[C6.PAGINATION]?.[C6.LIMIT] + ') limit!', 'color: #0c0')
|
|
798
822
|
|
|
799
|
-
|
|
823
|
+
console.log('%c ' + requestMethod + ' ' + tableName, 'color: #0c0')
|
|
800
824
|
|
|
801
|
-
|
|
825
|
+
console.log('%c Request Data (note you may see the success and/or error prompt):', 'color: #0c0', request)
|
|
802
826
|
|
|
803
|
-
|
|
804
|
-
&& true === request.debug
|
|
805
|
-
&& isLocal) {
|
|
827
|
+
console.log('%c Response Data:', 'color: #0c0', responseData.rest)
|
|
806
828
|
|
|
807
|
-
|
|
829
|
+
console.log('%c Will return get next page function:' + (1 !== query?.[C6.PAGINATION]?.[C6.LIMIT] ? '' : ' (Will not return with explicit limit 1 set)'), 'color: #0c0', true === returnGetNextPageFunction)
|
|
808
830
|
|
|
809
|
-
|
|
831
|
+
console.trace();
|
|
832
|
+
|
|
833
|
+
console.groupEnd()
|
|
810
834
|
|
|
811
835
|
}
|
|
812
836
|
|
|
813
|
-
|
|
837
|
+
if (false === returnGetNextPageFunction
|
|
838
|
+
&& true === request.debug
|
|
839
|
+
&& isLocal) {
|
|
814
840
|
|
|
815
|
-
|
|
841
|
+
toast.success("DEVS: Response returned length (" + responseData.rest?.length + ") less than limit (" + query?.[C6.PAGINATION]?.[C6.LIMIT] + ").", toastOptionsDevs);
|
|
816
842
|
|
|
817
|
-
|
|
843
|
+
}
|
|
818
844
|
|
|
819
|
-
|
|
845
|
+
if (eFetchDependencies.NONE !== request.fetchDependencies) {
|
|
820
846
|
|
|
821
|
-
|
|
822
|
-
|
|
847
|
+
console.groupCollapsed('%c API: fetchDependencies segment', 'color: #0c0')
|
|
848
|
+
|
|
849
|
+
console.log('%c ' + requestMethod + ' ' + tableName, 'color: #0c0')
|
|
850
|
+
|
|
851
|
+
console.trace();
|
|
852
|
+
|
|
853
|
+
const fetchDependencies = async (fetchData: {
|
|
854
|
+
[key: string]: iConstraint[]
|
|
855
|
+
}) => Object.keys(
|
|
856
|
+
fetchData
|
|
857
|
+
).map((column) => {
|
|
858
|
+
|
|
859
|
+
// check if the column is in the response
|
|
860
|
+
if (undefined === responseData.rest[column]) {
|
|
861
|
+
|
|
862
|
+
return false
|
|
863
|
+
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
return fetchData[column].map(async (constraint) => {
|
|
867
|
+
|
|
868
|
+
console.log(column, constraint.TABLE)
|
|
869
|
+
|
|
870
|
+
const fetchTable = await C6.IMPORT(constraint.TABLE)
|
|
871
|
+
|
|
872
|
+
const RestApi = fetchTable.default
|
|
873
|
+
|
|
874
|
+
return RestApi.Get({
|
|
875
|
+
[C6.WHERE]: {
|
|
876
|
+
[constraint.COLUMN]: responseData.rest[column]
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
});
|
|
883
|
+
|
|
884
|
+
let dependencies: any[] = [];
|
|
885
|
+
|
|
886
|
+
// noinspection FallThroughInSwitchStatementJS
|
|
887
|
+
switch (request.fetchDependencies) {
|
|
888
|
+
case eFetchDependencies.ALL:
|
|
889
|
+
case eFetchDependencies.CHILDREN:
|
|
890
|
+
// @ts-ignore
|
|
891
|
+
case eFetchDependencies.REFERENCED:
|
|
892
|
+
|
|
893
|
+
const referencedBy = C6.TABLES[operatingTable].TABLE_REFERENCED_BY;
|
|
894
|
+
|
|
895
|
+
dependencies = (await fetchDependencies(referencedBy)).flat(Infinity)
|
|
896
|
+
|
|
897
|
+
if (request.fetchDependencies !== eFetchDependencies.ALL) {
|
|
898
|
+
|
|
899
|
+
break;
|
|
900
|
+
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
case eFetchDependencies.PARENTS:
|
|
904
|
+
case eFetchDependencies.REFERENCES:
|
|
905
|
+
|
|
906
|
+
const references = C6.TABLES[operatingTable].TABLE_REFERENCES;
|
|
907
|
+
|
|
908
|
+
dependencies = [...dependencies, (await fetchDependencies(references)).flat(Infinity)]
|
|
909
|
+
|
|
910
|
+
break;
|
|
911
|
+
default:
|
|
912
|
+
throw new Error('The value of fetchDependencies (' + request.fetchDependencies?.toString() + ') was not recognized.')
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
request.fetchDependencies = dependencies;
|
|
916
|
+
|
|
917
|
+
await Promise.all(dependencies)
|
|
918
|
+
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
console.groupEnd()
|
|
823
922
|
|
|
824
923
|
}
|
|
825
924
|
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
tWsLiveUpdate
|
|
3
|
-
} from "@carbonorm/carbonnode";
|
|
4
|
-
|
|
5
|
-
{{#TABLES}}
|
|
6
|
-
import { putState{{TABLE_NAME_SHORT_PASCAL_CASE}}, postState{{TABLE_NAME_SHORT_PASCAL_CASE}}, deleteState{{TABLE_NAME_SHORT_PASCAL_CASE}} } from "./{{TABLE_NAME_SHORT_PASCAL_CASE}}";
|
|
7
|
-
{{/TABLES}}
|
|
8
|
-
|
|
9
|
-
const wsLiveUpdates: tWsLiveUpdate = {
|
|
10
|
-
{{#TABLES}}
|
|
11
|
-
{{TABLE_NAME_SHORT}}: {
|
|
12
|
-
PUT: putState{{TABLE_NAME_SHORT_PASCAL_CASE}},
|
|
13
|
-
POST: postState{{TABLE_NAME_SHORT_PASCAL_CASE}},
|
|
14
|
-
DELETE: deleteState{{TABLE_NAME_SHORT_PASCAL_CASE}},
|
|
15
|
-
},
|
|
16
|
-
{{/TABLES}}
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export default wsLiveUpdates;
|
|
21
|
-
|
|
22
|
-
|