@carbonorm/carbonnode 3.0.1 → 3.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/executors/Executor.d.ts +13 -14
- package/dist/api/executors/HttpExecutor.d.ts +14 -11
- package/dist/api/executors/SqlExecutor.d.ts +11 -3
- package/dist/api/restOrm.d.ts +43 -0
- package/dist/api/restRequest.d.ts +7 -5
- package/dist/api/types/ormInterfaces.d.ts +76 -54
- package/dist/api/utils/apiHelpers.d.ts +1 -1
- package/dist/api/utils/determineRuntimeJsType.d.ts +5 -0
- package/dist/index.cjs.js +175 -481
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +173 -481
- package/dist/index.esm.js.map +1 -1
- package/package.json +6 -5
- package/scripts/assets/handlebars/C6.test.ts.handlebars +88 -0
- package/scripts/assets/handlebars/C6.ts.handlebars +42 -8
- package/scripts/generateRestBindings.cjs +3 -8
- package/scripts/generateRestBindings.ts +3 -15
- package/src/api/convertForRequestBody.ts +1 -1
- package/src/api/executors/Executor.ts +70 -18
- package/src/api/executors/HttpExecutor.ts +165 -38
- package/src/api/executors/SqlExecutor.ts +23 -9
- package/src/api/rest/C6.test.ts +88 -0
- package/src/api/rest/C6.ts +5338 -0
- package/src/api/restOrm.ts +61 -0
- package/src/api/restRequest.ts +35 -17
- package/src/api/types/ormInterfaces.ts +148 -42
- package/src/api/utils/apiHelpers.ts +5 -2
- package/src/api/utils/determineRuntimeJsType.ts +46 -0
- package/src/index.ts +2 -0
- package/scripts/assets/handlebars/Table.test.ts.handlebars +0 -126
- package/scripts/assets/handlebars/Table.ts.handlebars +0 -161
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import restRequest from "./restRequest";
|
|
2
|
+
import {iRest} from "./types/ormInterfaces";
|
|
3
|
+
|
|
4
|
+
export function restOrm<
|
|
5
|
+
RestShortTableName extends string = any,
|
|
6
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
7
|
+
PrimaryKey extends Extract<keyof RestTableInterface, string> = Extract<keyof RestTableInterface, string>,
|
|
8
|
+
CustomAndRequiredFields extends { [key: string]: any } = any,
|
|
9
|
+
RequestTableOverrides extends { [key in keyof RestTableInterface]: any } = { [key in keyof RestTableInterface]: any }
|
|
10
|
+
>(config: Omit<iRest<
|
|
11
|
+
RestShortTableName,
|
|
12
|
+
RestTableInterface,
|
|
13
|
+
PrimaryKey
|
|
14
|
+
>, "requestMethod">) {
|
|
15
|
+
return {
|
|
16
|
+
Get: restRequest<
|
|
17
|
+
"GET",
|
|
18
|
+
RestShortTableName,
|
|
19
|
+
RestTableInterface,
|
|
20
|
+
PrimaryKey,
|
|
21
|
+
CustomAndRequiredFields,
|
|
22
|
+
RequestTableOverrides
|
|
23
|
+
>({
|
|
24
|
+
...config,
|
|
25
|
+
requestMethod: "GET",
|
|
26
|
+
}),
|
|
27
|
+
Put: restRequest<
|
|
28
|
+
"PUT",
|
|
29
|
+
RestShortTableName,
|
|
30
|
+
RestTableInterface,
|
|
31
|
+
PrimaryKey,
|
|
32
|
+
CustomAndRequiredFields,
|
|
33
|
+
RequestTableOverrides
|
|
34
|
+
>({
|
|
35
|
+
...config,
|
|
36
|
+
requestMethod: "PUT",
|
|
37
|
+
}),
|
|
38
|
+
Post: restRequest<
|
|
39
|
+
"POST",
|
|
40
|
+
RestShortTableName,
|
|
41
|
+
RestTableInterface,
|
|
42
|
+
PrimaryKey,
|
|
43
|
+
CustomAndRequiredFields,
|
|
44
|
+
RequestTableOverrides
|
|
45
|
+
>({
|
|
46
|
+
...config,
|
|
47
|
+
requestMethod: "POST",
|
|
48
|
+
}),
|
|
49
|
+
Delete: restRequest<
|
|
50
|
+
"DELETE",
|
|
51
|
+
RestShortTableName,
|
|
52
|
+
RestTableInterface,
|
|
53
|
+
PrimaryKey,
|
|
54
|
+
CustomAndRequiredFields,
|
|
55
|
+
RequestTableOverrides
|
|
56
|
+
>({
|
|
57
|
+
...config,
|
|
58
|
+
requestMethod: "DELETE",
|
|
59
|
+
}),
|
|
60
|
+
}
|
|
61
|
+
}
|
package/src/api/restRequest.ts
CHANGED
|
@@ -1,39 +1,57 @@
|
|
|
1
1
|
import isNode from '../variables/isNode';
|
|
2
2
|
import {Modify} from "./types/modifyTypes";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
apiReturn, DetermineResponseDataType,
|
|
5
|
+
iAPI,
|
|
6
|
+
iRest, iRestMethods
|
|
7
|
+
} from "./types/ormInterfaces";
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Facade: routes API calls to SQL or HTTP executors based on runtime context.
|
|
7
11
|
*/
|
|
8
12
|
export default function restRequest<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} = any,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} = any
|
|
15
|
-
RequestTableOverrides extends {
|
|
16
|
-
[key: string]: any;
|
|
17
|
-
} = any,
|
|
18
|
-
ResponseDataType = any,
|
|
19
|
-
RestShortTableNames extends string = any
|
|
13
|
+
RequestMethod extends iRestMethods,
|
|
14
|
+
RestShortTableName extends string = any,
|
|
15
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
16
|
+
PrimaryKey extends Extract<keyof RestTableInterface, string> = Extract<keyof RestTableInterface, string>,
|
|
17
|
+
CustomAndRequiredFields extends { [key: string]: any } = any,
|
|
18
|
+
RequestTableOverrides extends { [key in keyof RestTableInterface]: any } = { [key in keyof RestTableInterface]: any }
|
|
20
19
|
>(
|
|
21
|
-
config: iRest<
|
|
20
|
+
config: iRest<
|
|
21
|
+
RestShortTableName,
|
|
22
|
+
RestTableInterface,
|
|
23
|
+
PrimaryKey
|
|
24
|
+
>
|
|
22
25
|
) {
|
|
23
26
|
return async (
|
|
24
|
-
request: iAPI<Modify<
|
|
25
|
-
): Promise<apiReturn<
|
|
27
|
+
request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields = {} as iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields
|
|
28
|
+
): Promise<apiReturn<DetermineResponseDataType<RequestMethod, RestTableInterface>>> => {
|
|
26
29
|
|
|
27
30
|
// SQL path if on Node with a provided pool
|
|
28
31
|
if (isNode && config.mysqlPool) {
|
|
29
32
|
const {SqlExecutor} = await import('./executors/SqlExecutor');
|
|
30
|
-
const executor = new SqlExecutor<
|
|
33
|
+
const executor = new SqlExecutor<
|
|
34
|
+
RequestMethod,
|
|
35
|
+
RestShortTableName,
|
|
36
|
+
RestTableInterface,
|
|
37
|
+
PrimaryKey,
|
|
38
|
+
CustomAndRequiredFields,
|
|
39
|
+
RequestTableOverrides
|
|
40
|
+
>(config, request);
|
|
31
41
|
return executor.execute();
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
// HTTP path fallback
|
|
35
45
|
const {HttpExecutor} = await import('./executors/HttpExecutor');
|
|
36
|
-
const http = new HttpExecutor<
|
|
46
|
+
const http = new HttpExecutor<
|
|
47
|
+
RequestMethod,
|
|
48
|
+
RestShortTableName,
|
|
49
|
+
RestTableInterface,
|
|
50
|
+
PrimaryKey,
|
|
51
|
+
CustomAndRequiredFields,
|
|
52
|
+
RequestTableOverrides
|
|
53
|
+
>(config, request);
|
|
37
54
|
return http.execute();
|
|
38
55
|
};
|
|
39
56
|
}
|
|
57
|
+
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import restRequest from "api/restRequest";
|
|
2
1
|
import {AxiosInstance, AxiosPromise, AxiosResponse} from "axios";
|
|
3
2
|
import {Pool} from "mysql2/promise";
|
|
4
3
|
import {eFetchDependencies} from "./dynamicFetching";
|
|
5
4
|
import {Modify} from "./modifyTypes";
|
|
6
5
|
import {JoinType, OrderDirection, SQLComparisonOperator, SQLFunction} from "./mysqlTypes";
|
|
6
|
+
import {CarbonReact} from "@carbonorm/carbonreact";
|
|
7
7
|
|
|
8
8
|
export interface stringMap {
|
|
9
9
|
[key: string]: string;
|
|
@@ -28,29 +28,114 @@ export interface iTypeValidation {
|
|
|
28
28
|
SKIP_COLUMN_IN_POST: boolean
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
|
|
32
|
+
// config, request, response
|
|
33
|
+
export type iRestReactiveLifecycle<
|
|
34
|
+
RequestMethod extends iRestMethods,
|
|
35
|
+
RestShortTableName extends string = any,
|
|
36
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
37
|
+
PrimaryKey extends keyof RestTableInterface & string = any,
|
|
38
|
+
// TODO - do we ever use these last two ever? should we make usage just any?
|
|
39
|
+
CustomAndRequiredFields extends { [key: string]: any } = any,
|
|
40
|
+
RequestTableOverrides extends { [key: string]: any } = { [key in keyof RestTableInterface]: any }
|
|
41
|
+
> = {
|
|
42
|
+
beforeProcessing?: {
|
|
43
|
+
[key: string]: (args: {
|
|
44
|
+
config: iRest<
|
|
45
|
+
RestShortTableName,
|
|
46
|
+
RestTableInterface,
|
|
47
|
+
PrimaryKey
|
|
48
|
+
>,
|
|
49
|
+
request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields;
|
|
50
|
+
}) => void | Promise<void>
|
|
51
|
+
},
|
|
52
|
+
beforeExecution?:
|
|
53
|
+
{
|
|
54
|
+
[key: string]: (args: {
|
|
55
|
+
config: iRest<
|
|
56
|
+
RestShortTableName,
|
|
57
|
+
RestTableInterface,
|
|
58
|
+
PrimaryKey
|
|
59
|
+
>,
|
|
60
|
+
request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields
|
|
61
|
+
}) => void | Promise<void>
|
|
62
|
+
};
|
|
63
|
+
afterExecution?:
|
|
64
|
+
{
|
|
65
|
+
[key: string]: (args: {
|
|
66
|
+
config: iRest<
|
|
67
|
+
RestShortTableName,
|
|
68
|
+
RestTableInterface,
|
|
69
|
+
PrimaryKey
|
|
70
|
+
>,
|
|
71
|
+
request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields;
|
|
72
|
+
response: AxiosResponse<DetermineResponseDataType<RequestMethod, RestTableInterface>>;
|
|
73
|
+
}) => void | Promise<void>
|
|
74
|
+
};
|
|
75
|
+
afterCommit?: {
|
|
76
|
+
[key: string]: (args: {
|
|
77
|
+
config: iRest<
|
|
78
|
+
RestShortTableName,
|
|
79
|
+
RestTableInterface,
|
|
80
|
+
PrimaryKey
|
|
81
|
+
>,
|
|
82
|
+
request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields;
|
|
83
|
+
response: AxiosResponse<DetermineResponseDataType<RequestMethod, RestTableInterface>>;
|
|
84
|
+
}) => void | Promise<void>
|
|
85
|
+
};
|
|
36
86
|
};
|
|
37
87
|
|
|
88
|
+
export type iRestHooks<
|
|
89
|
+
RestShortTableName extends string = any,
|
|
90
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
91
|
+
PrimaryKey extends keyof RestTableInterface & string = any,
|
|
92
|
+
CustomAndRequiredFields extends { [key: string]: any } = any,
|
|
93
|
+
RequestTableOverrides extends { [key: string]: any } = { [key in keyof RestTableInterface]: any }
|
|
94
|
+
> = {
|
|
95
|
+
[Method in iRestMethods]: iRestReactiveLifecycle<
|
|
96
|
+
Method,
|
|
97
|
+
RestShortTableName,
|
|
98
|
+
RestTableInterface,
|
|
99
|
+
PrimaryKey,
|
|
100
|
+
CustomAndRequiredFields,
|
|
101
|
+
RequestTableOverrides
|
|
102
|
+
>
|
|
103
|
+
}
|
|
104
|
+
|
|
38
105
|
export interface iConstraint {
|
|
39
106
|
TABLE: string,
|
|
40
107
|
COLUMN: string,
|
|
41
108
|
CONSTRAINT: string
|
|
42
109
|
}
|
|
43
110
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
111
|
+
// This maps full column names to short column keys
|
|
112
|
+
export type tColumns<
|
|
113
|
+
TableName extends string,
|
|
114
|
+
T extends { [key: string]: any }
|
|
115
|
+
> = {
|
|
116
|
+
[K in keyof T & string as `${TableName}.${K}`]: K;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export type tPrimaryKeys<
|
|
120
|
+
TableName extends string,
|
|
121
|
+
PK extends string
|
|
122
|
+
> = `${TableName}.${PK}`;
|
|
123
|
+
|
|
124
|
+
export interface iC6RestfulModel<
|
|
125
|
+
RestShortTableNames extends string,
|
|
126
|
+
RestTableInterfaces extends { [key: string]: any },
|
|
127
|
+
PK extends keyof RestTableInterfaces & string,
|
|
128
|
+
> {
|
|
129
|
+
TABLE_NAME: RestShortTableNames;
|
|
130
|
+
PRIMARY: tPrimaryKeys<RestShortTableNames, PK>[];
|
|
131
|
+
PRIMARY_SHORT: PK[];
|
|
132
|
+
COLUMNS: tColumns<RestShortTableNames, RestTableInterfaces>;
|
|
133
|
+
TYPE_VALIDATION: { [key: string]: iTypeValidation };
|
|
134
|
+
REGEX_VALIDATION: RegExpMap;
|
|
135
|
+
// TODO - I thon think theres a good way to infer the last two generics (overides)
|
|
136
|
+
LIFECYCLE_HOOKS: iRestHooks<RestShortTableNames, RestTableInterfaces, PK>;
|
|
137
|
+
TABLE_REFERENCES: { [columnName: string]: iConstraint[] };
|
|
138
|
+
TABLE_REFERENCED_BY: { [columnName: string]: iConstraint[] };
|
|
54
139
|
}
|
|
55
140
|
|
|
56
141
|
export interface iRestApiFunctions<RestData = any> {
|
|
@@ -68,7 +153,13 @@ export interface iDynamicApiImport<RestData = any> {
|
|
|
68
153
|
putState?: (response: AxiosResponse<iPutC6RestResponse<RestData>>, request: iAPI<any>) => void
|
|
69
154
|
}
|
|
70
155
|
|
|
71
|
-
export interface tC6Tables
|
|
156
|
+
export interface tC6Tables<
|
|
157
|
+
RestShortTableName extends string = any,
|
|
158
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
159
|
+
PrimaryKey extends Extract<keyof RestTableInterface, string> = Extract<keyof RestTableInterface, string>
|
|
160
|
+
> {
|
|
161
|
+
[key: string]: iC6RestfulModel<RestShortTableName, RestTableInterface, PrimaryKey> & { [key: string]: any }
|
|
162
|
+
}
|
|
72
163
|
|
|
73
164
|
export interface tC6RestApi {
|
|
74
165
|
[key: string]: {
|
|
@@ -98,7 +189,6 @@ export interface iCacheAPI<ResponseDataType = any> {
|
|
|
98
189
|
}
|
|
99
190
|
|
|
100
191
|
|
|
101
|
-
|
|
102
192
|
/**
|
|
103
193
|
* the first argument ....
|
|
104
194
|
*
|
|
@@ -226,11 +316,17 @@ export interface iPutC6RestResponse<RestData = any, RequestData = any> extends i
|
|
|
226
316
|
updated: boolean | number | string | RequestData,
|
|
227
317
|
}
|
|
228
318
|
|
|
229
|
-
export interface iC6Object
|
|
319
|
+
export interface iC6Object<
|
|
320
|
+
RestShortTableName extends string = any,
|
|
321
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
322
|
+
PrimaryKey extends Extract<keyof RestTableInterface, string> = Extract<keyof RestTableInterface, string>
|
|
323
|
+
> {
|
|
230
324
|
C6VERSION: string,
|
|
231
325
|
TABLES: {
|
|
232
|
-
[key: string]: iC6RestfulModel
|
|
233
|
-
{
|
|
326
|
+
[key: string]: iC6RestfulModel<RestShortTableName, RestTableInterface, PrimaryKey>
|
|
327
|
+
& {
|
|
328
|
+
[key: string]: string | number
|
|
329
|
+
}
|
|
234
330
|
},
|
|
235
331
|
PREFIX: string,
|
|
236
332
|
IMPORT: (tableName: string) => Promise<iDynamicApiImport>,
|
|
@@ -251,37 +347,47 @@ export type apiReturn<Response> =
|
|
|
251
347
|
| (Response extends iPutC6RestResponse | iDeleteC6RestResponse | iPostC6RestResponse ? null : (() => apiReturn<Response>))
|
|
252
348
|
|
|
253
349
|
|
|
350
|
+
export type DetermineResponseDataType<
|
|
351
|
+
RequestMethod extends iRestMethods,
|
|
352
|
+
RestTableInterface extends { [key: string]: any }
|
|
353
|
+
> = RequestMethod extends "POST"
|
|
354
|
+
? iPostC6RestResponse<RestTableInterface>
|
|
355
|
+
: RequestMethod extends "GET"
|
|
356
|
+
? iGetC6RestResponse<RestTableInterface>
|
|
357
|
+
: RequestMethod extends "PUT"
|
|
358
|
+
? iPutC6RestResponse<RestTableInterface>
|
|
359
|
+
: RequestMethod extends "DELETE"
|
|
360
|
+
? iDeleteC6RestResponse<RestTableInterface>
|
|
361
|
+
: any;
|
|
362
|
+
|
|
254
363
|
export interface iRest<
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
ResponseDataType = any,
|
|
259
|
-
RestShortTableNames extends string = any
|
|
364
|
+
RestShortTableName extends string = any,
|
|
365
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
366
|
+
PrimaryKey extends keyof RestTableInterface & string = any
|
|
260
367
|
> {
|
|
261
368
|
C6: iC6Object,
|
|
262
369
|
axios?: AxiosInstance,
|
|
263
370
|
restURL?: string,
|
|
264
371
|
mysqlPool?: Pool;
|
|
265
372
|
withCredentials?: boolean,
|
|
266
|
-
|
|
373
|
+
restModel: iC6RestfulModel<RestShortTableName, RestTableInterface, PrimaryKey>,
|
|
374
|
+
reactBootstrap?: CarbonReact<any, any>,
|
|
267
375
|
requestMethod: iRestMethods,
|
|
268
376
|
clearCache?: () => void,
|
|
269
377
|
skipPrimaryCheck?: boolean,
|
|
270
|
-
queryCallback: RequestQueryBody<Modify<
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
378
|
+
/* queryCallback: RequestQueryBody<Modify<RestTableInterface, RequestTableOverrides>> | ((request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields) => (null | undefined | RequestQueryBody<Modify<RestTableInterface, RequestTableOverrides>>)),
|
|
379
|
+
responseCallback?: (
|
|
380
|
+
response: AxiosResponse<DetermineResponseDataType<RequestMethod, RestTableInterface>>,
|
|
381
|
+
request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields,
|
|
382
|
+
success: (
|
|
383
|
+
// TODO - make sure this makes sense, or re-implement with the hooks model
|
|
384
|
+
DetermineResponseDataType<RequestMethod, RestTableInterface> extends iPutC6RestResponse | iDeleteC6RestResponse
|
|
385
|
+
? RequestQueryBody<Modify<RestTableInterface, RequestTableOverrides>>
|
|
386
|
+
: string)
|
|
387
|
+
| RestTableInterface[PrimaryKey] // Rest PK
|
|
388
|
+
| string | number | boolean // Toast and validations
|
|
389
|
+
) => (RestTableInterface | RestTableInterface[] | void) // keep this set to any, it allows easy arrow functions and the results unused here*/
|
|
274
390
|
}
|
|
275
391
|
|
|
276
|
-
|
|
277
|
-
[key: string]: any
|
|
278
|
-
}, RestShortTableNames extends string>() {
|
|
279
|
-
return <CustomAndRequiredFields extends {
|
|
280
|
-
[key: string]: any
|
|
281
|
-
} = any, RequestTableTypes extends RestTableInterfaces = any, RequestTableOverrides extends {
|
|
282
|
-
[key: string]: any
|
|
283
|
-
} = any, ResponseDataType extends {
|
|
284
|
-
[key: string]: any
|
|
285
|
-
} = any>(argv) => restRequest<CustomAndRequiredFields, RequestTableTypes, RequestTableOverrides, ResponseDataType, RestShortTableNames>(argv)
|
|
286
|
-
}
|
|
392
|
+
|
|
287
393
|
|
|
@@ -5,6 +5,10 @@ import { AxiosResponse } from "axios";
|
|
|
5
5
|
import {toastOptions} from "../../variables/toastOptions";
|
|
6
6
|
import {iC6RestfulModel} from "../types/ormInterfaces";
|
|
7
7
|
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
8
12
|
export function TestRestfulResponse(response: AxiosResponse | any, success: ((r: AxiosResponse) => (string | void)) | string | undefined, error: ((r: AxiosResponse) => (string | void)) | string | undefined): string | boolean | number {
|
|
9
13
|
|
|
10
14
|
if (undefined === response.data?.['ERROR TYPE']
|
|
@@ -36,7 +40,6 @@ export function TestRestfulResponse(response: AxiosResponse | any, success: ((r:
|
|
|
36
40
|
|
|
37
41
|
return false;
|
|
38
42
|
|
|
39
|
-
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
export function removePrefixIfExists(tableName: string, prefix: string): string {
|
|
@@ -47,7 +50,7 @@ export function removePrefixIfExists(tableName: string, prefix: string): string
|
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
export function removeInvalidKeys<iRestObject>(request: any, c6Tables: {
|
|
50
|
-
[key: string]: (iC6RestfulModel & { [key: string]: any })
|
|
53
|
+
[key: string]: (iC6RestfulModel<any,any,any> & { [key: string]: any })
|
|
51
54
|
}): iRestObject {
|
|
52
55
|
|
|
53
56
|
let intersection: iRestObject = {} as iRestObject
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {iC6RestfulModel} from "../types/ormInterfaces";
|
|
2
|
+
|
|
3
|
+
type JsPrimitive = 'string' | 'number' | 'boolean' | 'buffer' | 'object';
|
|
4
|
+
|
|
5
|
+
export function determineRuntimeJsType(mysqlType: string): JsPrimitive {
|
|
6
|
+
const base = mysqlType.toLowerCase().split('(')[0];
|
|
7
|
+
|
|
8
|
+
if ([
|
|
9
|
+
'binary', 'varbinary', 'blob', 'tinyblob', 'mediumblob', 'longblob'
|
|
10
|
+
].includes(base)) return 'buffer';
|
|
11
|
+
|
|
12
|
+
if ([
|
|
13
|
+
'json', 'geometry', 'point', 'polygon', 'multipoint', 'multilinestring', 'multipolygon', 'geometrycollection'
|
|
14
|
+
].includes(base)) return 'object';
|
|
15
|
+
|
|
16
|
+
if ([
|
|
17
|
+
'tinyint', 'smallint', 'mediumint', 'int', 'integer', 'bigint',
|
|
18
|
+
'decimal', 'dec', 'numeric', 'float', 'double', 'real'
|
|
19
|
+
].includes(base)) return 'number';
|
|
20
|
+
|
|
21
|
+
if ([
|
|
22
|
+
'boolean', 'bool'
|
|
23
|
+
].includes(base)) return 'boolean';
|
|
24
|
+
|
|
25
|
+
return 'string';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function getPrimaryKeyTypes(
|
|
29
|
+
table: iC6RestfulModel<string, any, any>
|
|
30
|
+
): Record<string, JsPrimitive> {
|
|
31
|
+
const result: Record<string, JsPrimitive> = {};
|
|
32
|
+
|
|
33
|
+
for (const key of table.PRIMARY_SHORT) {
|
|
34
|
+
const fullKey = Object.entries(table.COLUMNS).find(([_, short]) => short === key)?.[0];
|
|
35
|
+
|
|
36
|
+
if (typeof fullKey === 'string') {
|
|
37
|
+
const validation = table.TYPE_VALIDATION[fullKey];
|
|
38
|
+
if (!validation) continue;
|
|
39
|
+
|
|
40
|
+
result[key] = determineRuntimeJsType(validation.MYSQL_TYPE);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { default as axiosInstance } from "./api/axiosInstance";
|
|
|
7
7
|
export * from "./api/axiosInstance";
|
|
8
8
|
export { default as convertForRequestBody } from "./api/convertForRequestBody";
|
|
9
9
|
export * from "./api/convertForRequestBody";
|
|
10
|
+
export * from "./api/restOrm";
|
|
10
11
|
export { default as restRequest } from "./api/restRequest";
|
|
11
12
|
export * from "./api/restRequest";
|
|
12
13
|
export { default as timeout } from "./api/timeout";
|
|
@@ -21,6 +22,7 @@ export * from "./api/types/mysqlTypes";
|
|
|
21
22
|
export * from "./api/types/ormInterfaces";
|
|
22
23
|
export * from "./api/utils/apiHelpers";
|
|
23
24
|
export * from "./api/utils/cacheManager";
|
|
25
|
+
export * from "./api/utils/determineRuntimeJsType";
|
|
24
26
|
export * from "./api/utils/logger";
|
|
25
27
|
export * from "./api/utils/sortAndSerializeQueryObject";
|
|
26
28
|
export * from "./api/utils/testHelpers";
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import {xdescribe, expect, test} from '@jest/globals';
|
|
2
|
-
import {checkAllRequestsComplete} from "@carbonorm/carbonnode";
|
|
3
|
-
import {act, waitFor} from '@testing-library/react';
|
|
4
|
-
import {C6, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, {{TABLE_NAME_SHORT}} } from "{{RELATIVE_OUTPUT_DIR}}/C6";
|
|
5
|
-
import {{TABLE_NAME_SHORT_PASCAL_CASE}} from "./{{TABLE_NAME_SHORT_PASCAL_CASE}}";{{#if REACT_IMPORT}}
|
|
6
|
-
{{{REACT_IMPORT}}};{{/if}}
|
|
7
|
-
|
|
8
|
-
const randomString = Math.random().toString(36).substring(7);
|
|
9
|
-
const randomInt = Math.floor(Math.random() * 1000000);
|
|
10
|
-
const fillString = 'string' + randomString + randomInt;
|
|
11
|
-
|
|
12
|
-
console.log('fillString', fillString);
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
{{{TABLE_DEFINITION}}}
|
|
16
|
-
**/
|
|
17
|
-
|
|
18
|
-
const Test_Data: i{{TABLE_NAME_SHORT_PASCAL_CASE}} = {
|
|
19
|
-
{{#each TYPE_VALIDATION}}{{#SKIP_COLUMN_IN_POST}}
|
|
20
|
-
{{COLUMN_NAME}}: {{#TYPESCRIPT_TYPE_IS_STRING}}fillString{{#MAX_LENGTH}}.substring(0, {{MAX_LENGTH}}){{/MAX_LENGTH}}{{/TYPESCRIPT_TYPE_IS_STRING}}{{#TYPESCRIPT_TYPE_IS_NUMBER}}randomInt{{/TYPESCRIPT_TYPE_IS_NUMBER}},
|
|
21
|
-
{{/SKIP_COLUMN_IN_POST}}{{/each}}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export default Test_Data;
|
|
25
|
-
|
|
26
|
-
xdescribe('REST {{TABLE_NAME_SHORT_PASCAL_CASE}} api', () => {
|
|
27
|
-
|
|
28
|
-
let testData = Test_Data;
|
|
29
|
-
|
|
30
|
-
test('GET POST PUT DELETE', async () => {
|
|
31
|
-
|
|
32
|
-
await act(async () => {
|
|
33
|
-
|
|
34
|
-
let selectAllResponse = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Get({})
|
|
35
|
-
|
|
36
|
-
if ('function' === typeof selectAllResponse) {
|
|
37
|
-
throw Error('selectAllResponse is a promise, this typically means this specific get request has already run during test setup.');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
// We don't care if it is filled or not, just that the request can be made.
|
|
41
|
-
expect(selectAllResponse?.data?.rest).not.toBeUndefined();
|
|
42
|
-
|
|
43
|
-
const postResponse = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Post(testData);
|
|
44
|
-
|
|
45
|
-
console.log('postResponse', postResponse?.data)
|
|
46
|
-
|
|
47
|
-
expect(postResponse?.data?.created).not.toBeUndefined();
|
|
48
|
-
|
|
49
|
-
const primaryKey = {{TABLE_NAME_SHORT}}.PRIMARY_SHORT[0];
|
|
50
|
-
|
|
51
|
-
const postID = postResponse?.data?.created
|
|
52
|
-
|
|
53
|
-
const singleRowSelect = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Get({
|
|
54
|
-
[C6.WHERE]: {
|
|
55
|
-
[{{TABLE_NAME_SHORT}}[primaryKey.toUpperCase()]]: postID,
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
if ('function' === typeof singleRowSelect) {
|
|
60
|
-
throw Error('singleRowSelect is a promise, this is unexpected.');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
console.log('singleRowSelect', singleRowSelect?.data)
|
|
64
|
-
|
|
65
|
-
// Ensure the expected response datastructure is returned
|
|
66
|
-
expect(singleRowSelect?.data?.rest).not.toBeUndefined();
|
|
67
|
-
|
|
68
|
-
// Make sure the previously created post is now returned
|
|
69
|
-
expect(typeof singleRowSelect?.data?.rest).toEqual('object');
|
|
70
|
-
|
|
71
|
-
// todo - make this work correctly with multiple primary keys
|
|
72
|
-
const selectedPostId = singleRowSelect?.data?.rest[0][primaryKey]
|
|
73
|
-
|
|
74
|
-
expect(selectedPostId).toEqual(postID);
|
|
75
|
-
|
|
76
|
-
const multipleRowSelect = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Get({
|
|
77
|
-
[C6.WHERE]: {
|
|
78
|
-
[{{TABLE_NAME_SHORT}}[primaryKey.toUpperCase()]]: [C6.IN, [0, postID]],
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
if ('function' === typeof multipleRowSelect) {
|
|
83
|
-
throw Error('singleRowSelect is a promise, this is unexpected.');
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
console.log('singleRowSelect', multipleRowSelect?.data)
|
|
87
|
-
|
|
88
|
-
// Ensure the expected response datastructure is returned
|
|
89
|
-
expect(multipleRowSelect?.data?.rest).not.toBeUndefined();
|
|
90
|
-
|
|
91
|
-
// Make sure the previously created post is now returned
|
|
92
|
-
expect(typeof multipleRowSelect?.data?.rest).toEqual('object');
|
|
93
|
-
|
|
94
|
-
testData[primaryKey] = postID
|
|
95
|
-
|
|
96
|
-
{{#each TYPE_VALIDATION}}
|
|
97
|
-
testData.{{COLUMN_NAME}} = {{#TYPESCRIPT_TYPE_IS_STRING}}fillString.substring(0, {{MAX_LENGTH}}){{/TYPESCRIPT_TYPE_IS_STRING}}{{#TYPESCRIPT_TYPE_IS_NUMBER}}randomInt{{/TYPESCRIPT_TYPE_IS_NUMBER}};
|
|
98
|
-
{{/each}}
|
|
99
|
-
|
|
100
|
-
{{#if REACT_IMPORT}}
|
|
101
|
-
// wait for the global state to be updated
|
|
102
|
-
expect({{{CARBON_REACT_INSTANCE}}}.state.{{TABLE_NAME_SHORT}}).not.toBeUndefined();
|
|
103
|
-
{{/if}}
|
|
104
|
-
|
|
105
|
-
const updateResponse = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Put(testData)
|
|
106
|
-
|
|
107
|
-
expect(updateResponse?.data?.updated).not.toBeUndefined();
|
|
108
|
-
|
|
109
|
-
const deleteResponse = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Delete({
|
|
110
|
-
[primaryKey]: postID
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
console.log('deleteResponse', deleteResponse?.data)
|
|
114
|
-
|
|
115
|
-
expect(deleteResponse?.data?.deleted).not.toBeUndefined();
|
|
116
|
-
|
|
117
|
-
await waitFor(async () => {
|
|
118
|
-
expect(checkAllRequestsComplete()).toEqual(true);
|
|
119
|
-
}, {timeout: 10000, interval: 1000});
|
|
120
|
-
|
|
121
|
-
})
|
|
122
|
-
|
|
123
|
-
}, 100000);
|
|
124
|
-
|
|
125
|
-
})
|
|
126
|
-
|