@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
|
@@ -6,43 +6,140 @@ import isVerbose from "../../variables/isVerbose";
|
|
|
6
6
|
import convertForRequestBody from "../convertForRequestBody";
|
|
7
7
|
import {eFetchDependencies} from "../types/dynamicFetching";
|
|
8
8
|
import {Modify} from "../types/modifyTypes";
|
|
9
|
-
import {
|
|
10
|
-
|
|
9
|
+
import {
|
|
10
|
+
apiReturn,
|
|
11
|
+
DELETE, DetermineResponseDataType,
|
|
12
|
+
GET, iAPI,
|
|
13
|
+
iCacheAPI,
|
|
14
|
+
iConstraint,
|
|
15
|
+
iGetC6RestResponse,
|
|
16
|
+
iRestMethods,
|
|
17
|
+
POST,
|
|
18
|
+
PUT,
|
|
19
|
+
RequestQueryBody
|
|
20
|
+
} from "../types/ormInterfaces";
|
|
21
|
+
import {removeInvalidKeys, removePrefixIfExists, TestRestfulResponse} from "../utils/apiHelpers";
|
|
11
22
|
import {apiRequestCache, checkCache, userCustomClearCache} from "../utils/cacheManager";
|
|
12
23
|
import {sortAndSerializeQueryObject} from "../utils/sortAndSerializeQueryObject";
|
|
13
24
|
import {Executor} from "./Executor";
|
|
14
|
-
import {toastOptions, toastOptionsDevs
|
|
25
|
+
import {toastOptions, toastOptionsDevs} from "variables/toastOptions";
|
|
15
26
|
|
|
16
27
|
export class HttpExecutor<
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
RequestMethod extends iRestMethods,
|
|
29
|
+
RestShortTableName extends string = any,
|
|
30
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
31
|
+
PrimaryKey extends Extract<keyof RestTableInterface, string> = Extract<keyof RestTableInterface, string>,
|
|
32
|
+
CustomAndRequiredFields extends { [key: string]: any } = any,
|
|
33
|
+
RequestTableOverrides extends { [key in keyof RestTableInterface]: any } = { [key in keyof RestTableInterface]: any }
|
|
22
34
|
>
|
|
23
35
|
extends Executor<
|
|
36
|
+
RequestMethod,
|
|
37
|
+
RestShortTableName,
|
|
38
|
+
RestTableInterface,
|
|
39
|
+
PrimaryKey,
|
|
24
40
|
CustomAndRequiredFields,
|
|
25
|
-
|
|
26
|
-
RequestTableOverrides,
|
|
27
|
-
ResponseDataType,
|
|
28
|
-
RestShortTableNames
|
|
41
|
+
RequestTableOverrides
|
|
29
42
|
> {
|
|
30
43
|
|
|
31
|
-
public
|
|
44
|
+
public putState(
|
|
45
|
+
response: AxiosResponse<DetermineResponseDataType<RequestMethod, RestTableInterface>>,
|
|
46
|
+
request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields,
|
|
47
|
+
callback: () => void
|
|
48
|
+
) {
|
|
49
|
+
this.config.reactBootstrap?.updateRestfulObjectArrays<RestTableInterface>({
|
|
50
|
+
callback,
|
|
51
|
+
dataOrCallback: [
|
|
52
|
+
removeInvalidKeys<RestTableInterface>({
|
|
53
|
+
...request,
|
|
54
|
+
...response?.data?.rest,
|
|
55
|
+
}, this.config.C6.TABLES)
|
|
56
|
+
],
|
|
57
|
+
stateKey: this.config.restModel.TABLE_NAME,
|
|
58
|
+
uniqueObjectId: this.config.restModel.PRIMARY_SHORT
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public postState(
|
|
63
|
+
response: AxiosResponse<DetermineResponseDataType<RequestMethod, RestTableInterface>>,
|
|
64
|
+
request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields,
|
|
65
|
+
callback: () => void
|
|
66
|
+
) {
|
|
67
|
+
|
|
68
|
+
if (1 !== this.config.restModel.PRIMARY_SHORT.length) {
|
|
69
|
+
|
|
70
|
+
console.error("C6 received unexpected result's given the primary key length");
|
|
71
|
+
|
|
72
|
+
} else {
|
|
73
|
+
|
|
74
|
+
const pk = this.config.restModel.PRIMARY_SHORT[0];
|
|
75
|
+
|
|
76
|
+
// TODO - should overrides be handled differently? Why override: (react/php), driver missmatches, aux data..
|
|
77
|
+
// @ts-ignore - this is technically a correct error, but we allow it anyway...
|
|
78
|
+
request[pk] = response.data?.created as RestTableInterface[PrimaryKey]
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
this.config.reactBootstrap?.updateRestfulObjectArrays<RestTableInterface>({
|
|
83
|
+
callback,
|
|
84
|
+
dataOrCallback: undefined !== request.dataInsertMultipleRows
|
|
85
|
+
? request.dataInsertMultipleRows.map((request, index) => {
|
|
86
|
+
return removeInvalidKeys<RestTableInterface>({
|
|
87
|
+
...request,
|
|
88
|
+
...(index === 0 ? response?.data?.rest : {}),
|
|
89
|
+
}, this.config.C6.TABLES)
|
|
90
|
+
})
|
|
91
|
+
: [
|
|
92
|
+
removeInvalidKeys<RestTableInterface>({
|
|
93
|
+
...request,
|
|
94
|
+
...response?.data?.rest,
|
|
95
|
+
}, this.config.C6.TABLES)
|
|
96
|
+
],
|
|
97
|
+
stateKey: this.config.restModel.TABLE_NAME,
|
|
98
|
+
uniqueObjectId: this.config.restModel.PRIMARY_SHORT as (keyof RestTableInterface)[]
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public deleteState(
|
|
103
|
+
_response: AxiosResponse<DetermineResponseDataType<RequestMethod, RestTableInterface>>,
|
|
104
|
+
request: iAPI<Modify<RestTableInterface, RequestTableOverrides>> & CustomAndRequiredFields,
|
|
105
|
+
callback: () => void
|
|
106
|
+
) {
|
|
107
|
+
this.config.reactBootstrap?.deleteRestfulObjectArrays<RestTableInterface>({
|
|
108
|
+
callback,
|
|
109
|
+
dataOrCallback: [
|
|
110
|
+
request as unknown as RestTableInterface,
|
|
111
|
+
],
|
|
112
|
+
stateKey: this.config.restModel.TABLE_NAME,
|
|
113
|
+
uniqueObjectId: this.config.restModel.PRIMARY_SHORT as (keyof RestTableInterface)[]
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public async execute(): Promise<apiReturn<DetermineResponseDataType<RequestMethod, RestTableInterface>>> {
|
|
118
|
+
|
|
119
|
+
type ResponseDataType = DetermineResponseDataType<RequestMethod, RestTableInterface>;
|
|
32
120
|
|
|
33
121
|
const {
|
|
34
122
|
C6,
|
|
35
123
|
axios,
|
|
36
124
|
restURL,
|
|
37
125
|
withCredentials,
|
|
38
|
-
|
|
126
|
+
restModel,
|
|
127
|
+
reactBootstrap,
|
|
39
128
|
requestMethod,
|
|
40
|
-
queryCallback,
|
|
41
|
-
responseCallback,
|
|
42
129
|
skipPrimaryCheck,
|
|
43
130
|
clearCache,
|
|
44
131
|
} = this.config
|
|
45
132
|
|
|
133
|
+
|
|
134
|
+
await this.runLifecycleHooks<"beforeProcessing">(
|
|
135
|
+
"beforeProcessing", {
|
|
136
|
+
config: this.config,
|
|
137
|
+
request: this.request,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
const tableName = restModel.TABLE_NAME;
|
|
142
|
+
|
|
46
143
|
const fullTableList = Array.isArray(tableName) ? tableName : [tableName];
|
|
47
144
|
|
|
48
145
|
const operatingTableFullName = fullTableList[0];
|
|
@@ -75,17 +172,7 @@ export class HttpExecutor<
|
|
|
75
172
|
|
|
76
173
|
// an undefined query would indicate queryCallback returned undefined,
|
|
77
174
|
// thus the request shouldn't fire as is in custom cache
|
|
78
|
-
let query: RequestQueryBody<Modify<
|
|
79
|
-
|
|
80
|
-
if ('function' === typeof queryCallback) {
|
|
81
|
-
|
|
82
|
-
query = queryCallback(this.request); // obj or obj[]
|
|
83
|
-
|
|
84
|
-
} else {
|
|
85
|
-
|
|
86
|
-
query = queryCallback;
|
|
87
|
-
|
|
88
|
-
}
|
|
175
|
+
let query: RequestQueryBody<Modify<RestTableInterface, RequestTableOverrides>> | undefined | null;
|
|
89
176
|
|
|
90
177
|
if (undefined === query || null === query) {
|
|
91
178
|
|
|
@@ -122,7 +209,7 @@ export class HttpExecutor<
|
|
|
122
209
|
}
|
|
123
210
|
|
|
124
211
|
// this could return itself with a new page number, or undefined if the end is reached
|
|
125
|
-
const apiRequest = async (): Promise<apiReturn<
|
|
212
|
+
const apiRequest = async (): Promise<apiReturn<DetermineResponseDataType<RequestMethod, RestTableInterface>>> => {
|
|
126
213
|
|
|
127
214
|
const {
|
|
128
215
|
debug,
|
|
@@ -130,7 +217,7 @@ export class HttpExecutor<
|
|
|
130
217
|
dataInsertMultipleRows,
|
|
131
218
|
success,
|
|
132
219
|
fetchDependencies = eFetchDependencies.NONE,
|
|
133
|
-
error =
|
|
220
|
+
error = "An unexpected API error occurred!"
|
|
134
221
|
} = this.request
|
|
135
222
|
|
|
136
223
|
if (C6.GET === requestMethod
|
|
@@ -250,7 +337,7 @@ export class HttpExecutor<
|
|
|
250
337
|
|
|
251
338
|
let addBackPK: (() => void) | undefined;
|
|
252
339
|
|
|
253
|
-
let apiResponse: string | boolean | number | undefined;
|
|
340
|
+
let apiResponse: RestTableInterface[PrimaryKey] | string | boolean | number | undefined;
|
|
254
341
|
|
|
255
342
|
let returnGetNextPageFunction = false;
|
|
256
343
|
|
|
@@ -353,6 +440,12 @@ export class HttpExecutor<
|
|
|
353
440
|
|
|
354
441
|
console.groupEnd()
|
|
355
442
|
|
|
443
|
+
this.runLifecycleHooks<"beforeExecution">(
|
|
444
|
+
"beforeExecution", {
|
|
445
|
+
config: this.config,
|
|
446
|
+
request: this.request
|
|
447
|
+
})
|
|
448
|
+
|
|
356
449
|
const axiosActiveRequest: AxiosPromise<ResponseDataType> = axios![requestMethod.toLowerCase()]<ResponseDataType>(
|
|
357
450
|
restRequestUri,
|
|
358
451
|
...((() => {
|
|
@@ -381,7 +474,7 @@ export class HttpExecutor<
|
|
|
381
474
|
}
|
|
382
475
|
|
|
383
476
|
return [
|
|
384
|
-
convertForRequestBody<
|
|
477
|
+
convertForRequestBody<RestTableInterface>(query as RestTableInterface, fullTableList, C6, (message) => toast.error(message, toastOptions)),
|
|
385
478
|
{
|
|
386
479
|
withCredentials: withCredentials,
|
|
387
480
|
}
|
|
@@ -390,7 +483,7 @@ export class HttpExecutor<
|
|
|
390
483
|
} else if (requestMethod === PUT) {
|
|
391
484
|
|
|
392
485
|
return [
|
|
393
|
-
convertForRequestBody<
|
|
486
|
+
convertForRequestBody<RestTableInterface>(query as RestTableInterface, fullTableList, C6, (message) => toast.error(message, toastOptions)),
|
|
394
487
|
{
|
|
395
488
|
withCredentials: withCredentials,
|
|
396
489
|
}
|
|
@@ -399,7 +492,7 @@ export class HttpExecutor<
|
|
|
399
492
|
|
|
400
493
|
return [{
|
|
401
494
|
withCredentials: withCredentials,
|
|
402
|
-
data: convertForRequestBody<
|
|
495
|
+
data: convertForRequestBody<RestTableInterface>(query as RestTableInterface, fullTableList, C6, (message) => toast.error(message, toastOptions))
|
|
403
496
|
}]
|
|
404
497
|
|
|
405
498
|
} else {
|
|
@@ -427,8 +520,9 @@ export class HttpExecutor<
|
|
|
427
520
|
|
|
428
521
|
// returning the promise with this then is important for tests. todo - we could make that optional.
|
|
429
522
|
// https://rapidapi.com/guides/axios-async-await
|
|
430
|
-
return axiosActiveRequest.then(async (response): Promise<AxiosResponse<ResponseDataType, any>> => {
|
|
523
|
+
return axiosActiveRequest.then(async (response: AxiosResponse<ResponseDataType, any>): Promise<AxiosResponse<ResponseDataType, any>> => {
|
|
431
524
|
|
|
525
|
+
// noinspection SuspiciousTypeOfGuard
|
|
432
526
|
if (typeof response.data === 'string') {
|
|
433
527
|
|
|
434
528
|
if (isTest) {
|
|
@@ -454,6 +548,14 @@ export class HttpExecutor<
|
|
|
454
548
|
|
|
455
549
|
}
|
|
456
550
|
|
|
551
|
+
this.runLifecycleHooks<"afterExecution">(
|
|
552
|
+
"afterExecution", {
|
|
553
|
+
config: this.config,
|
|
554
|
+
request: this.request,
|
|
555
|
+
response
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
// todo - this feels dumb now, but i digress
|
|
457
559
|
apiResponse = TestRestfulResponse(response, success, error)
|
|
458
560
|
|
|
459
561
|
if (false === apiResponse) {
|
|
@@ -468,11 +570,36 @@ export class HttpExecutor<
|
|
|
468
570
|
|
|
469
571
|
}
|
|
470
572
|
|
|
471
|
-
// stateful operations are done in the response callback - its leverages rest generated functions
|
|
472
|
-
if (responseCallback) {
|
|
473
|
-
|
|
474
|
-
responseCallback(response, this.request, apiResponse)
|
|
475
573
|
|
|
574
|
+
const callback = () => this.runLifecycleHooks<"afterCommit">(
|
|
575
|
+
"afterCommit", {
|
|
576
|
+
config: this.config,
|
|
577
|
+
request: this.request,
|
|
578
|
+
response
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
if (undefined !== reactBootstrap && response) {
|
|
582
|
+
switch (requestMethod) {
|
|
583
|
+
case GET:
|
|
584
|
+
reactBootstrap.updateRestfulObjectArrays<RestTableInterface>({
|
|
585
|
+
dataOrCallback: Array.isArray(response.data.rest) ? response.data.rest : [response.data.rest],
|
|
586
|
+
stateKey: this.config.restModel.TABLE_NAME,
|
|
587
|
+
uniqueObjectId: this.config.restModel.PRIMARY_SHORT as (keyof RestTableInterface)[],
|
|
588
|
+
callback
|
|
589
|
+
})
|
|
590
|
+
break;
|
|
591
|
+
case POST:
|
|
592
|
+
this.postState(response, this.request, callback);
|
|
593
|
+
break;
|
|
594
|
+
case PUT:
|
|
595
|
+
this.putState(response, this.request, callback);
|
|
596
|
+
break;
|
|
597
|
+
case DELETE:
|
|
598
|
+
this.deleteState(response, this.request, callback);
|
|
599
|
+
break;
|
|
600
|
+
}
|
|
601
|
+
} else {
|
|
602
|
+
callback();
|
|
476
603
|
}
|
|
477
604
|
|
|
478
605
|
if (C6.GET === requestMethod) {
|
|
@@ -1,26 +1,40 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {iRestMethods} from "@carbonorm/carbonnode";
|
|
2
2
|
import { PoolConnection, RowDataPacket } from 'mysql2/promise';
|
|
3
3
|
import {buildSelectQuery} from "../builders/sqlBuilder";
|
|
4
4
|
import {Executor} from "./Executor";
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
export class SqlExecutor<
|
|
8
|
-
extends
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
export class SqlExecutor<
|
|
8
|
+
RequestMethod extends iRestMethods,
|
|
9
|
+
RestShortTableName extends string = any,
|
|
10
|
+
RestTableInterface extends { [key: string]: any } = any,
|
|
11
|
+
PrimaryKey extends Extract<keyof RestTableInterface, string> = Extract<keyof RestTableInterface, string>,
|
|
12
|
+
CustomAndRequiredFields extends { [key: string]: any } = any,
|
|
13
|
+
RequestTableOverrides extends { [key in keyof RestTableInterface]: any } = { [key in keyof RestTableInterface]: any }
|
|
14
|
+
>
|
|
15
|
+
extends Executor<
|
|
16
|
+
RequestMethod,
|
|
17
|
+
RestShortTableName,
|
|
18
|
+
RestTableInterface,
|
|
19
|
+
PrimaryKey,
|
|
20
|
+
CustomAndRequiredFields,
|
|
21
|
+
RequestTableOverrides
|
|
22
|
+
> {
|
|
23
|
+
|
|
24
|
+
public execute() {
|
|
11
25
|
switch (this.config.requestMethod) {
|
|
12
26
|
case 'GET':
|
|
13
27
|
return (this.select(
|
|
14
|
-
this.config.
|
|
28
|
+
this.config.restModel.TABLE_NAME,
|
|
15
29
|
undefined,
|
|
16
30
|
this.request
|
|
17
31
|
) as Promise<any>).then(rows => ({rest: rows})) as any;
|
|
18
32
|
case 'POST':
|
|
19
|
-
return this.insert(this.config.
|
|
33
|
+
return this.insert(this.config.restModel.TABLE_NAME, this.request) as any;
|
|
20
34
|
case 'PUT':
|
|
21
|
-
return this.update(this.config.
|
|
35
|
+
return this.update(this.config.restModel.TABLE_NAME, undefined, this.request) as any;
|
|
22
36
|
case 'DELETE':
|
|
23
|
-
return this.delete(this.config.
|
|
37
|
+
return this.delete(this.config.restModel.TABLE_NAME, undefined, this.request) as any;
|
|
24
38
|
}
|
|
25
39
|
}
|
|
26
40
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { describe, expect, test } from '@jest/globals';
|
|
2
|
+
import { checkAllRequestsComplete } from '@carbonorm/carbonnode';
|
|
3
|
+
import { act, waitFor } from '@testing-library/react';
|
|
4
|
+
import { C6 } from "./C6";
|
|
5
|
+
|
|
6
|
+
const fillString = () => Math.random().toString(36).substring(2, 12);
|
|
7
|
+
const fillNumber = () => Math.floor(Math.random() * 1000000);
|
|
8
|
+
|
|
9
|
+
const RESERVED_COLUMNS = ['created_at', 'updated_at', 'deleted_at'];
|
|
10
|
+
|
|
11
|
+
function buildTestData(tableModel: any): Record<string, any> {
|
|
12
|
+
const data: Record<string, any> = {};
|
|
13
|
+
const validation = tableModel.TYPE_VALIDATION;
|
|
14
|
+
|
|
15
|
+
for (const col of Object.keys(validation)) {
|
|
16
|
+
const { MYSQL_TYPE, SKIP_COLUMN_IN_POST, MAX_LENGTH } = validation[col];
|
|
17
|
+
|
|
18
|
+
if (SKIP_COLUMN_IN_POST || RESERVED_COLUMNS.includes(col)) continue;
|
|
19
|
+
|
|
20
|
+
if (MYSQL_TYPE.startsWith('varchar') || MYSQL_TYPE === 'text') {
|
|
21
|
+
let str = fillString();
|
|
22
|
+
if (MAX_LENGTH) str = str.substring(0, MAX_LENGTH);
|
|
23
|
+
data[col] = str;
|
|
24
|
+
} else if (MYSQL_TYPE.includes('int') || MYSQL_TYPE === 'decimal') {
|
|
25
|
+
data[col] = fillNumber();
|
|
26
|
+
} else if (MYSQL_TYPE === 'json') {
|
|
27
|
+
data[col] = {};
|
|
28
|
+
} else if (MYSQL_TYPE === 'tinyint(1)') {
|
|
29
|
+
data[col] = 1;
|
|
30
|
+
} else {
|
|
31
|
+
data[col] = null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
describe('CarbonORM table API integration tests', () => {
|
|
39
|
+
for (const [shortName, tableModel] of Object.entries(C6.TABLES)) {
|
|
40
|
+
const primaryKeys: string[] = tableModel.PRIMARY_SHORT;
|
|
41
|
+
|
|
42
|
+
// Get restOrm binding
|
|
43
|
+
const restBinding = (C6 as any)[shortName[0].toUpperCase() + shortName.slice(1)];
|
|
44
|
+
if (!restBinding) continue;
|
|
45
|
+
|
|
46
|
+
test(`[${shortName}] GET → POST → GET → PUT → DELETE`, async () => {
|
|
47
|
+
|
|
48
|
+
const testData = buildTestData(tableModel);
|
|
49
|
+
|
|
50
|
+
await act(async () => {
|
|
51
|
+
|
|
52
|
+
// GET all
|
|
53
|
+
const all = await restBinding.Get({});
|
|
54
|
+
expect(all?.data?.rest).toBeDefined();
|
|
55
|
+
|
|
56
|
+
// POST one
|
|
57
|
+
const post = await restBinding.Post(testData);
|
|
58
|
+
expect(post?.data?.created).toBeDefined();
|
|
59
|
+
|
|
60
|
+
const postID = post?.data?.created;
|
|
61
|
+
const pkName = primaryKeys[0];
|
|
62
|
+
testData[pkName] = postID;
|
|
63
|
+
|
|
64
|
+
// GET single
|
|
65
|
+
const select = await restBinding.Get({
|
|
66
|
+
[C6.WHERE]: {
|
|
67
|
+
[tableModel[pkName.toUpperCase()]]: postID
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(select?.data?.rest?.[0]?.[pkName]).toEqual(postID);
|
|
72
|
+
|
|
73
|
+
// PUT update
|
|
74
|
+
const updated = await restBinding.Put(testData);
|
|
75
|
+
expect(updated?.data?.updated).toBeDefined();
|
|
76
|
+
|
|
77
|
+
// DELETE
|
|
78
|
+
const deleted = await restBinding.Delete({ [pkName]: postID });
|
|
79
|
+
expect(deleted?.data?.deleted).toBeDefined();
|
|
80
|
+
|
|
81
|
+
// Wait for all requests to settle
|
|
82
|
+
await waitFor(() => {
|
|
83
|
+
expect(checkAllRequestsComplete()).toEqual(true);
|
|
84
|
+
}, { timeout: 10000, interval: 1000 });
|
|
85
|
+
});
|
|
86
|
+
}, 100000);
|
|
87
|
+
}
|
|
88
|
+
});
|