@carbonorm/carbonnode 3.0.2 → 3.0.4
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/convertForRequestBody.d.ts +7 -3
- package/dist/api/executors/Executor.d.ts +9 -9
- package/dist/api/executors/HttpExecutor.d.ts +9 -5
- package/dist/api/executors/SqlExecutor.d.ts +5 -5
- package/dist/api/restOrm.d.ts +15 -0
- package/dist/api/restRequest.d.ts +4 -5
- package/dist/api/types/ormInterfaces.d.ts +165 -139
- package/dist/index.cjs.js +263 -160
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +264 -161
- package/dist/index.esm.js.map +1 -1
- package/package.json +5 -4
- package/scripts/assets/handlebars/C6.test.ts.handlebars +88 -0
- package/scripts/assets/handlebars/C6.ts.handlebars +45 -12
- package/scripts/generateRestBindings.cjs +3 -7
- package/scripts/generateRestBindings.ts +3 -14
- package/src/api/convertForRequestBody.ts +62 -90
- package/src/api/executors/Executor.ts +67 -13
- package/src/api/executors/HttpExecutor.ts +224 -90
- package/src/api/executors/SqlExecutor.ts +6 -6
- package/src/api/restOrm.ts +61 -0
- package/src/api/restRequest.ts +19 -14
- package/src/api/types/ormInterfaces.ts +208 -246
- package/src/api/utils/apiHelpers.ts +4 -0
- package/src/index.ts +1 -0
- package/scripts/assets/handlebars/Table.test.ts.handlebars +0 -126
- package/scripts/assets/handlebars/Table.ts.handlebars +0 -193
|
@@ -1,199 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
import {Pool} from "mysql2/promise";
|
|
3
|
-
import {eFetchDependencies} from "./dynamicFetching";
|
|
4
|
-
import {Modify} from "./modifyTypes";
|
|
5
|
-
import {JoinType, OrderDirection, SQLComparisonOperator, SQLFunction} from "./mysqlTypes";
|
|
6
|
-
|
|
7
|
-
export interface stringMap {
|
|
8
|
-
[key: string]: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface stringNumberMap {
|
|
12
|
-
[key: string]: string | number;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface RegExpMap {
|
|
16
|
-
[key: string]: RegExp | RegExpMap;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface complexMap {
|
|
20
|
-
[key: string]: stringMap | stringNumberMap | stringMap[] | RegExpMap;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface iTypeValidation {
|
|
24
|
-
MYSQL_TYPE: string,
|
|
25
|
-
MAX_LENGTH: string,
|
|
26
|
-
AUTO_INCREMENT: boolean,
|
|
27
|
-
SKIP_COLUMN_IN_POST: boolean
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export type iRestReactiveLifecycle<T extends RequestGetPutDeleteBody> = {
|
|
31
|
-
beforeProcessing?: (args: { request: T[]; requestMeta?: any }) => void | Promise<void>;
|
|
32
|
-
beforeExecution?: (args: { request: T[]; requestMeta?: any }) => void | Promise<void>;
|
|
33
|
-
afterExecution?: (args: { response: T[]; request: T[]; responseMeta?: any }) => void | Promise<void>;
|
|
34
|
-
afterCommit?: (args: { response: T[]; request: T[]; responseMeta?: any }) => void | Promise<void>;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export interface iConstraint {
|
|
38
|
-
TABLE: string,
|
|
39
|
-
COLUMN: string,
|
|
40
|
-
CONSTRAINT: string
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// This maps full column names to short column keys
|
|
44
|
-
export type tColumns<
|
|
45
|
-
TableName extends string,
|
|
46
|
-
T extends { [key: string]: any }
|
|
47
|
-
> = {
|
|
48
|
-
[K in keyof T & string as `${TableName}.${K}`]: K;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
export type tPrimaryKeys<
|
|
52
|
-
TableName extends string,
|
|
53
|
-
PK extends string
|
|
54
|
-
> = `${TableName}.${PK}`;
|
|
55
|
-
|
|
56
|
-
export interface iC6RestfulModel<
|
|
57
|
-
RestShortTableNames extends string,
|
|
58
|
-
RestTableInterfaces extends { [key: string]: any },
|
|
59
|
-
PK extends keyof RestTableInterfaces & string,
|
|
60
|
-
> {
|
|
61
|
-
TABLE_NAME: RestShortTableNames;
|
|
62
|
-
PRIMARY: tPrimaryKeys<RestShortTableNames, PK>[];
|
|
63
|
-
PRIMARY_SHORT: PK[];
|
|
64
|
-
COLUMNS: tColumns<RestShortTableNames, RestTableInterfaces>;
|
|
65
|
-
TYPE_VALIDATION: { [key: string]: iTypeValidation };
|
|
66
|
-
REGEX_VALIDATION: RegExpMap;
|
|
67
|
-
LIFECYCLE_HOOKS: iRestReactiveLifecycle<RequestGetPutDeleteBody>[];
|
|
68
|
-
TABLE_REFERENCES: { [columnName: string]: iConstraint[] };
|
|
69
|
-
TABLE_REFERENCED_BY: { [columnName: string]: iConstraint[] };
|
|
70
|
-
}
|
|
1
|
+
// Refined TypeScript types for CarbonORM
|
|
71
2
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
3
|
+
import { AxiosInstance, AxiosPromise, AxiosResponse } from "axios";
|
|
4
|
+
import { Pool } from "mysql2/promise";
|
|
5
|
+
import { eFetchDependencies } from "./dynamicFetching";
|
|
6
|
+
import { Modify } from "./modifyTypes";
|
|
7
|
+
import { JoinType, OrderDirection, SQLComparisonOperator, SQLFunction } from "./mysqlTypes";
|
|
8
|
+
import { CarbonReact } from "@carbonorm/carbonreact";
|
|
78
9
|
|
|
79
|
-
export
|
|
80
|
-
default: iRestApiFunctions<RestData>
|
|
81
|
-
// the methods below are optional
|
|
82
|
-
postState?: (response: AxiosResponse<iPostC6RestResponse<RestData>>, request: iAPI<any>, id: string | number | boolean) => void,
|
|
83
|
-
deleteState?: (response: AxiosResponse<iDeleteC6RestResponse<RestData>>, request: iAPI<any>) => void,
|
|
84
|
-
putState?: (response: AxiosResponse<iPutC6RestResponse<RestData>>, request: iAPI<any>) => void
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export interface tC6Tables<
|
|
88
|
-
RestShortTableName extends string = any,
|
|
89
|
-
RestTableInterface extends { [key: string]: any } = any,
|
|
90
|
-
PrimaryKey extends Extract<keyof RestTableInterface, string> = Extract<keyof RestTableInterface, string>
|
|
91
|
-
> {
|
|
92
|
-
[key: string]: iC6RestfulModel<RestShortTableName, RestTableInterface, PrimaryKey> & { [key: string]: any }
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export interface tC6RestApi {
|
|
96
|
-
[key: string]: {
|
|
97
|
-
REST: iRestApiFunctions,
|
|
98
|
-
PUT: Function;
|
|
99
|
-
POST: Function;
|
|
100
|
-
DELETE: Function;
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// todo - I don't like that these essentially become reserved words.
|
|
105
|
-
export type iAPI<RestTableInterfaces extends { [key: string]: any }> = RestTableInterfaces & {
|
|
106
|
-
dataInsertMultipleRows?: RestTableInterfaces[],
|
|
107
|
-
cacheResults?: boolean, // aka ignoreCache
|
|
108
|
-
// todo - this should really only be used for get requests - add this to the Get interface or throw error (im actually inclined to ts ignore the function and add to iGetC6 atm; back later)
|
|
109
|
-
fetchDependencies?: number | eFetchDependencies | Awaited<apiReturn<iGetC6RestResponse<any>>>[],
|
|
110
|
-
debug?: boolean,
|
|
111
|
-
success?: string | ((r: AxiosResponse) => (string | void)),
|
|
112
|
-
error?: string | ((r: AxiosResponse) => (string | void)),
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export interface iCacheAPI<ResponseDataType = any> {
|
|
116
|
-
requestArgumentsSerialized: string,
|
|
117
|
-
request: AxiosPromise<ResponseDataType>,
|
|
118
|
-
response?: AxiosResponse,
|
|
119
|
-
final?: boolean,
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* the first argument ....
|
|
125
|
-
*
|
|
126
|
-
* Our api returns a zero argument function iff the method is get and the previous request reached the predefined limit.
|
|
127
|
-
* This function can be aliased as GetNextPageOfResults(). If the end is reached undefined will be returned.
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* For POST, PUT, and DELETE requests one can expect the primary key of the new or modified index, or a boolean success
|
|
131
|
-
* indication if no primary key exists.
|
|
132
|
-
**/
|
|
10
|
+
export type iRestMethods = 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
133
11
|
export const POST = 'POST';
|
|
134
12
|
export const PUT = 'PUT';
|
|
135
13
|
export const GET = 'GET';
|
|
136
14
|
export const DELETE = 'DELETE';
|
|
137
15
|
|
|
16
|
+
export interface stringMap { [key: string]: string; }
|
|
17
|
+
export interface stringNumberMap { [key: string]: string | number; }
|
|
18
|
+
export interface RegExpMap { [key: string]: RegExp | RegExpMap; }
|
|
19
|
+
export interface complexMap { [key: string]: stringMap | stringNumberMap | stringMap[] | RegExpMap; }
|
|
138
20
|
|
|
139
|
-
export
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
21
|
+
export interface iTypeValidation {
|
|
22
|
+
MYSQL_TYPE: string;
|
|
23
|
+
MAX_LENGTH: string;
|
|
24
|
+
AUTO_INCREMENT: boolean;
|
|
25
|
+
SKIP_COLUMN_IN_POST: boolean;
|
|
26
|
+
}
|
|
144
27
|
|
|
145
|
-
export type SubSelect<T = any> = {
|
|
28
|
+
export type SubSelect<T extends { [key: string]: any } = any> = {
|
|
146
29
|
subSelect: true;
|
|
147
|
-
table: string;
|
|
148
|
-
args:
|
|
30
|
+
table: string;
|
|
31
|
+
args: RequestQueryBody<'GET', T>;
|
|
149
32
|
alias: string;
|
|
150
33
|
};
|
|
151
34
|
|
|
152
|
-
export type SelectField<T = any> =
|
|
35
|
+
export type SelectField<T extends { [key: string]: any } = any> =
|
|
153
36
|
| keyof T
|
|
154
37
|
| [keyof T, 'AS', string]
|
|
155
38
|
| [SQLFunction, keyof T]
|
|
156
|
-
| [SQLFunction, keyof T, string]
|
|
157
|
-
| SubSelect<T>;
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// ========================
|
|
161
|
-
// 🧠 WHERE (Recursive)
|
|
162
|
-
// ========================
|
|
163
|
-
|
|
164
|
-
export type WhereClause<T = any> =
|
|
165
|
-
| Partial<T>
|
|
166
|
-
| LogicalGroup<T>
|
|
167
|
-
| ComparisonClause<T>;
|
|
168
|
-
|
|
169
|
-
export type LogicalGroup<T = any> = {
|
|
170
|
-
[logicalGroup: string]: Array<WhereClause<T>>;
|
|
171
|
-
};
|
|
39
|
+
| [SQLFunction, keyof T, string]
|
|
40
|
+
| SubSelect<T>;
|
|
172
41
|
|
|
42
|
+
export type WhereClause<T = any> = Partial<T> | LogicalGroup<T> | ComparisonClause<T>;
|
|
43
|
+
export type LogicalGroup<T = any> = { [logicalGroup: string]: Array<WhereClause<T>> };
|
|
173
44
|
export type ComparisonClause<T = any> = [keyof T, SQLComparisonOperator, any];
|
|
174
45
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
// ========================
|
|
179
|
-
|
|
180
|
-
export type JoinTableCondition<T = any> =
|
|
181
|
-
| Partial<T>
|
|
182
|
-
| WhereClause<T>[]
|
|
183
|
-
| ComparisonClause<T>[];
|
|
184
|
-
|
|
185
|
-
export type JoinClause<T = any> = {
|
|
186
|
-
[table: string]: JoinTableCondition<T>;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
export type Join<T = any> = {
|
|
190
|
-
[K in JoinType]?: JoinClause<T>;
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
// ========================
|
|
195
|
-
// 📄 PAGINATION
|
|
196
|
-
// ========================
|
|
46
|
+
export type JoinTableCondition<T = any> = Partial<T> | WhereClause<T>[] | ComparisonClause<T>[];
|
|
47
|
+
export type JoinClause<T = any> = { [table: string]: JoinTableCondition<T>; };
|
|
48
|
+
export type Join<T = any> = { [K in JoinType]?: JoinClause<T>; };
|
|
197
49
|
|
|
198
50
|
export type Pagination<T = any> = {
|
|
199
51
|
PAGE?: number;
|
|
@@ -201,12 +53,7 @@ export type Pagination<T = any> = {
|
|
|
201
53
|
ORDER?: Partial<Record<keyof T, OrderDirection>>;
|
|
202
54
|
};
|
|
203
55
|
|
|
204
|
-
|
|
205
|
-
// ========================
|
|
206
|
-
// 🌐 MAIN API TYPE
|
|
207
|
-
// ========================
|
|
208
|
-
|
|
209
|
-
export type RequestGetPutDeleteBody<T = any> = {
|
|
56
|
+
export type RequestGetPutDeleteBody<T extends { [key: string]: any } = any> = {
|
|
210
57
|
SELECT?: SelectField<T>[];
|
|
211
58
|
UPDATE?: Partial<T>;
|
|
212
59
|
DELETE?: boolean;
|
|
@@ -215,96 +62,211 @@ export type RequestGetPutDeleteBody<T = any> = {
|
|
|
215
62
|
PAGINATION?: Pagination<T>;
|
|
216
63
|
};
|
|
217
64
|
|
|
65
|
+
export type iAPI<T extends { [key: string]: any }> = T & {
|
|
66
|
+
dataInsertMultipleRows?: T[];
|
|
67
|
+
cacheResults?: boolean;
|
|
68
|
+
fetchDependencies?: number | eFetchDependencies | Awaited<apiReturn<iGetC6RestResponse<any>>>[];
|
|
69
|
+
debug?: boolean;
|
|
70
|
+
success?: string | ((r: AxiosResponse) => string | void);
|
|
71
|
+
error?: string | ((r: AxiosResponse) => string | void);
|
|
72
|
+
};
|
|
218
73
|
|
|
219
|
-
export type RequestQueryBody<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
74
|
+
export type RequestQueryBody<
|
|
75
|
+
Method extends iRestMethods,
|
|
76
|
+
T extends { [key: string]: any },
|
|
77
|
+
Custom extends { [key: string]: any } = {},
|
|
78
|
+
Overrides extends { [key: string]: any } = {}
|
|
79
|
+
> = Method extends 'GET' | 'PUT' | 'DELETE'
|
|
80
|
+
? iAPI<RequestGetPutDeleteBody<Modify<T, Overrides> & Custom>>
|
|
81
|
+
: iAPI<Modify<T, Overrides> & Custom>;
|
|
226
82
|
|
|
227
|
-
interface
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
83
|
+
export interface iCacheAPI<ResponseDataType = any> {
|
|
84
|
+
requestArgumentsSerialized: string;
|
|
85
|
+
request: AxiosPromise<ResponseDataType>;
|
|
86
|
+
response?: AxiosResponse;
|
|
87
|
+
final?: boolean;
|
|
231
88
|
}
|
|
232
89
|
|
|
233
|
-
|
|
234
|
-
interface iChangeC6Data {
|
|
235
|
-
rowCount: number,
|
|
236
|
-
}
|
|
90
|
+
export interface iChangeC6Data { rowCount: number; }
|
|
237
91
|
|
|
238
92
|
export interface iDeleteC6RestResponse<RestData = any, RequestData = any> extends iChangeC6Data, iC6RestResponse<RestData> {
|
|
239
|
-
deleted: boolean | number | string | RequestData
|
|
93
|
+
deleted: boolean | number | string | RequestData;
|
|
240
94
|
}
|
|
241
95
|
|
|
242
96
|
export interface iPostC6RestResponse<RestData = any> extends iC6RestResponse<RestData> {
|
|
243
|
-
created: boolean | number | string
|
|
97
|
+
created: boolean | number | string;
|
|
244
98
|
}
|
|
245
99
|
|
|
246
100
|
export interface iPutC6RestResponse<RestData = any, RequestData = any> extends iChangeC6Data, iC6RestResponse<RestData> {
|
|
247
|
-
updated: boolean | number | string | RequestData
|
|
101
|
+
updated: boolean | number | string | RequestData;
|
|
248
102
|
}
|
|
249
103
|
|
|
250
|
-
export interface
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
> {
|
|
255
|
-
C6VERSION: string,
|
|
256
|
-
TABLES: {
|
|
257
|
-
[key: string]: iC6RestfulModel<RestShortTableName, RestTableInterface, PrimaryKey>
|
|
258
|
-
& {
|
|
259
|
-
[key: string]: string | number
|
|
260
|
-
}
|
|
261
|
-
},
|
|
262
|
-
PREFIX: string,
|
|
263
|
-
IMPORT: (tableName: string) => Promise<iDynamicApiImport>,
|
|
264
|
-
|
|
265
|
-
[key: string]: any
|
|
104
|
+
export interface iC6RestResponse<RestData> {
|
|
105
|
+
rest: RestData;
|
|
106
|
+
session?: any;
|
|
107
|
+
sql?: any;
|
|
266
108
|
}
|
|
267
109
|
|
|
268
|
-
|
|
269
|
-
|
|
110
|
+
export type iGetC6RestResponse<ResponseDataType, ResponseDataOverrides = {}> = iC6RestResponse<
|
|
111
|
+
Modify<ResponseDataType, ResponseDataOverrides> | Modify<ResponseDataType, ResponseDataOverrides>[]
|
|
112
|
+
>;
|
|
270
113
|
|
|
271
|
-
// returning undefined means no more results are available, thus we've queried everything possible
|
|
272
|
-
// null means the request is currently being executed
|
|
273
|
-
// https://www.typescriptlang.org/docs/handbook/2/conditional-types.html
|
|
274
114
|
export type apiReturn<Response> =
|
|
275
|
-
null
|
|
115
|
+
| null
|
|
276
116
|
| undefined
|
|
277
117
|
| AxiosPromise<Response>
|
|
278
|
-
| (Response extends iPutC6RestResponse | iDeleteC6RestResponse | iPostC6RestResponse ? null : (
|
|
279
|
-
|
|
118
|
+
| (Response extends iPutC6RestResponse | iDeleteC6RestResponse | iPostC6RestResponse ? null : () => apiReturn<Response>);
|
|
119
|
+
|
|
120
|
+
export type DetermineResponseDataType<
|
|
121
|
+
Method extends iRestMethods,
|
|
122
|
+
RestTableInterface extends { [key: string]: any }
|
|
123
|
+
> = Method extends 'POST'
|
|
124
|
+
? iPostC6RestResponse<RestTableInterface>
|
|
125
|
+
: Method extends 'GET'
|
|
126
|
+
? iGetC6RestResponse<RestTableInterface>
|
|
127
|
+
: Method extends 'PUT'
|
|
128
|
+
? iPutC6RestResponse<RestTableInterface>
|
|
129
|
+
: Method extends 'DELETE'
|
|
130
|
+
? iDeleteC6RestResponse<RestTableInterface>
|
|
131
|
+
: never;
|
|
280
132
|
|
|
281
133
|
export interface iRest<
|
|
282
134
|
RestShortTableName extends string = any,
|
|
283
135
|
RestTableInterface extends { [key: string]: any } = any,
|
|
284
|
-
PrimaryKey extends
|
|
285
|
-
CustomAndRequiredFields extends { [key: string]: any } = any,
|
|
286
|
-
RequestTableOverrides = { [key in keyof RestTableInterface]: any },
|
|
287
|
-
ResponseDataType = any
|
|
136
|
+
PrimaryKey extends keyof RestTableInterface & string = any
|
|
288
137
|
> {
|
|
289
|
-
C6: iC6Object
|
|
290
|
-
axios?: AxiosInstance
|
|
291
|
-
restURL?: string
|
|
138
|
+
C6: iC6Object;
|
|
139
|
+
axios?: AxiosInstance;
|
|
140
|
+
restURL?: string;
|
|
292
141
|
mysqlPool?: Pool;
|
|
293
|
-
withCredentials?: boolean
|
|
294
|
-
restModel: iC6RestfulModel<RestShortTableName, RestTableInterface, PrimaryKey
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
responseCallback?: (response: AxiosResponse<ResponseDataType>,
|
|
300
|
-
request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields,
|
|
301
|
-
success: (ResponseDataType extends iPutC6RestResponse | iDeleteC6RestResponse
|
|
302
|
-
? RequestQueryBody<Modify<RestTableInterface, RequestTableOverrides>>
|
|
303
|
-
: string)
|
|
304
|
-
| RestTableInterface[PrimaryKey] // Rest PK
|
|
305
|
-
| string | number | boolean // Toast and validations
|
|
306
|
-
) => any // keep this set to any, it allows easy arrow functions and the results unused here
|
|
142
|
+
withCredentials?: boolean;
|
|
143
|
+
restModel: iC6RestfulModel<RestShortTableName, RestTableInterface, PrimaryKey>;
|
|
144
|
+
reactBootstrap?: CarbonReact<any, any>;
|
|
145
|
+
requestMethod: iRestMethods;
|
|
146
|
+
clearCache?: () => void;
|
|
147
|
+
skipPrimaryCheck?: boolean;
|
|
307
148
|
}
|
|
308
149
|
|
|
150
|
+
export interface iConstraint {
|
|
151
|
+
TABLE: string;
|
|
152
|
+
COLUMN: string;
|
|
153
|
+
CONSTRAINT: string;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export type tColumns<TableName extends string, T extends { [key: string]: any }> = {
|
|
157
|
+
[K in keyof T & string as `${TableName}.${K}`]: K;
|
|
158
|
+
};
|
|
309
159
|
|
|
160
|
+
export type tPrimaryKeys<TableName extends string, PK extends string> = `${TableName}.${PK}`;
|
|
161
|
+
|
|
162
|
+
export interface iC6RestfulModel<RestShortTableNames extends string, RestTableInterfaces extends { [key: string]: any }, PK extends keyof RestTableInterfaces & string> {
|
|
163
|
+
TABLE_NAME: RestShortTableNames;
|
|
164
|
+
PRIMARY: tPrimaryKeys<RestShortTableNames, PK>[];
|
|
165
|
+
PRIMARY_SHORT: PK[];
|
|
166
|
+
COLUMNS: tColumns<RestShortTableNames, RestTableInterfaces>;
|
|
167
|
+
TYPE_VALIDATION: { [key: string]: iTypeValidation };
|
|
168
|
+
REGEX_VALIDATION: RegExpMap;
|
|
169
|
+
LIFECYCLE_HOOKS: iRestHooks<RestShortTableNames, RestTableInterfaces, PK>;
|
|
170
|
+
TABLE_REFERENCES: { [columnName: string]: iConstraint[] };
|
|
171
|
+
TABLE_REFERENCED_BY: { [columnName: string]: iConstraint[] };
|
|
172
|
+
}
|
|
310
173
|
|
|
174
|
+
export type iRestReactiveLifecycle<
|
|
175
|
+
Method extends iRestMethods,
|
|
176
|
+
RestShortTableName extends string,
|
|
177
|
+
RestTableInterface extends { [key: string]: any },
|
|
178
|
+
PrimaryKey extends keyof RestTableInterface & string,
|
|
179
|
+
CustomAndRequiredFields extends { [key: string]: any },
|
|
180
|
+
RequestTableOverrides extends { [key: string]: any }
|
|
181
|
+
> = {
|
|
182
|
+
beforeProcessing?: {
|
|
183
|
+
[key: string]: (args: {
|
|
184
|
+
config: iRest<RestShortTableName, RestTableInterface, PrimaryKey>;
|
|
185
|
+
request: RequestQueryBody<Method, RestTableInterface, CustomAndRequiredFields, RequestTableOverrides>;
|
|
186
|
+
}) => void | Promise<void>;
|
|
187
|
+
};
|
|
188
|
+
beforeExecution?: {
|
|
189
|
+
[key: string]: (args: {
|
|
190
|
+
config: iRest<RestShortTableName, RestTableInterface, PrimaryKey>;
|
|
191
|
+
request: RequestQueryBody<Method, RestTableInterface, CustomAndRequiredFields, RequestTableOverrides>;
|
|
192
|
+
}) => void | Promise<void>;
|
|
193
|
+
};
|
|
194
|
+
afterExecution?: {
|
|
195
|
+
[key: string]: (args: {
|
|
196
|
+
config: iRest<RestShortTableName, RestTableInterface, PrimaryKey>;
|
|
197
|
+
request: RequestQueryBody<Method, RestTableInterface, CustomAndRequiredFields, RequestTableOverrides>;
|
|
198
|
+
response: AxiosResponse<DetermineResponseDataType<Method, RestTableInterface>>;
|
|
199
|
+
}) => void | Promise<void>;
|
|
200
|
+
};
|
|
201
|
+
afterCommit?: {
|
|
202
|
+
[key: string]: (args: {
|
|
203
|
+
config: iRest<RestShortTableName, RestTableInterface, PrimaryKey>;
|
|
204
|
+
request: RequestQueryBody<Method, RestTableInterface, CustomAndRequiredFields, RequestTableOverrides>;
|
|
205
|
+
response: AxiosResponse<DetermineResponseDataType<Method, RestTableInterface>>;
|
|
206
|
+
}) => void | Promise<void>;
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export type iRestHooks<
|
|
211
|
+
RestShortTableName extends string,
|
|
212
|
+
RestTableInterface extends { [key: string]: any },
|
|
213
|
+
PrimaryKey extends keyof RestTableInterface & string,
|
|
214
|
+
CustomAndRequiredFields extends { [key: string]: any } = any,
|
|
215
|
+
RequestTableOverrides extends { [key: string]: any } = { [key in keyof RestTableInterface]: any }
|
|
216
|
+
> = {
|
|
217
|
+
[Method in iRestMethods]: iRestReactiveLifecycle<
|
|
218
|
+
Method,
|
|
219
|
+
RestShortTableName,
|
|
220
|
+
RestTableInterface,
|
|
221
|
+
PrimaryKey,
|
|
222
|
+
CustomAndRequiredFields,
|
|
223
|
+
RequestTableOverrides
|
|
224
|
+
>;
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export interface iDynamicApiImport<RestData extends { [key: string]: any } = any> {
|
|
228
|
+
default: iRestApiFunctions<RestData>;
|
|
229
|
+
postState?: (response: AxiosResponse<iPostC6RestResponse<RestData>>, request: iAPI<any>, id: string | number | boolean) => void;
|
|
230
|
+
deleteState?: (response: AxiosResponse<iDeleteC6RestResponse<RestData>>, request: iAPI<any>) => void;
|
|
231
|
+
putState?: (response: AxiosResponse<iPutC6RestResponse<RestData>>, request: iAPI<any>) => void;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export interface iRestApiFunctions<RestData extends { [key: string]: any } = any> {
|
|
235
|
+
Delete: (request?: RequestQueryBody<'DELETE', RestData>) => apiReturn<iDeleteC6RestResponse<RestData>>;
|
|
236
|
+
Post: (request?: RequestQueryBody<'POST', RestData>) => apiReturn<iPostC6RestResponse<RestData>>;
|
|
237
|
+
Get: (request?: RequestQueryBody<'GET', RestData>) => apiReturn<iGetC6RestResponse<RestData>>;
|
|
238
|
+
Put: (request?: RequestQueryBody<'PUT', RestData>) => apiReturn<iPutC6RestResponse<RestData>>;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export interface iC6Object<
|
|
242
|
+
RestShortTableName extends string = any,
|
|
243
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
244
|
+
PrimaryKey extends Extract<keyof RestTableInterface, string> = Extract<keyof RestTableInterface, string>
|
|
245
|
+
> {
|
|
246
|
+
C6VERSION: string;
|
|
247
|
+
TABLES: {
|
|
248
|
+
[key: string]: iC6RestfulModel<RestShortTableName, RestTableInterface, PrimaryKey> & {
|
|
249
|
+
[key: string]: string | number;
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
PREFIX: string;
|
|
253
|
+
IMPORT: (tableName: string) => Promise<iDynamicApiImport>;
|
|
254
|
+
[key: string]: any;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export interface tC6Tables<
|
|
258
|
+
RestShortTableName extends string = any,
|
|
259
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
260
|
+
PrimaryKey extends Extract<keyof RestTableInterface, string> = Extract<keyof RestTableInterface, string>
|
|
261
|
+
> {
|
|
262
|
+
[key: string]: iC6RestfulModel<RestShortTableName, RestTableInterface, PrimaryKey> & { [key: string]: any };
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export interface tC6RestApi {
|
|
266
|
+
[key: string]: {
|
|
267
|
+
REST: iRestApiFunctions;
|
|
268
|
+
PUT: Function;
|
|
269
|
+
POST: Function;
|
|
270
|
+
DELETE: Function;
|
|
271
|
+
};
|
|
272
|
+
}
|
|
@@ -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']
|
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";
|
|
@@ -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
|
-
|