@carbonorm/carbonnode 1.2.3 → 1.2.5
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/interfaces/ormInterfaces.d.ts +5 -0
- package/package.json +1 -1
- package/scripts/assets/handlebars/C6.tsx.handlebars +9 -8
- package/scripts/assets/handlebars/Table.test.tsx.handlebars +8 -7
- package/scripts/assets/handlebars/Table.tsx.handlebars +5 -5
- package/scripts/generateRestBindings.cjs +17 -11
- package/scripts/generateRestBindings.ts +25 -13
- package/src/api/interfaces/ormInterfaces.ts +2 -0
|
@@ -21,6 +21,11 @@ export interface iConstraint {
|
|
|
21
21
|
COLUMN: string;
|
|
22
22
|
CONSTRAINT: string;
|
|
23
23
|
}
|
|
24
|
+
export type tC6Tables = {
|
|
25
|
+
[key: string]: (C6RestfulModel & {
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
});
|
|
28
|
+
};
|
|
24
29
|
export interface C6RestfulModel<RestShortTableNames extends string = string> {
|
|
25
30
|
TABLE_NAME: RestShortTableNames;
|
|
26
31
|
PRIMARY: string[];
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
C6RestfulModel,
|
|
3
|
-
C6Constants
|
|
3
|
+
C6Constants,
|
|
4
|
+
tC6Tables
|
|
4
5
|
} from "@carbonorm/carbonnode";
|
|
5
6
|
{{#TABLES}}
|
|
6
7
|
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
8
|
{{/TABLES}}
|
|
8
9
|
|
|
9
|
-
|
|
10
10
|
export type RestTableNames = {{{RestTableNames}}};
|
|
11
11
|
|
|
12
12
|
export type RestShortTableNames = {{{RestShortTableNames}}};
|
|
@@ -25,7 +25,7 @@ interface iDefine{{TABLE_NAME_SHORT_PASCAL_CASE}} {
|
|
|
25
25
|
{{/each}}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export const {{TABLE_NAME_SHORT}}: C6RestfulModel & iDefine{{TABLE_NAME_SHORT_PASCAL_CASE}} = {
|
|
28
|
+
export const {{TABLE_NAME_SHORT}}: C6RestfulModel<RestTableNames> & iDefine{{TABLE_NAME_SHORT_PASCAL_CASE}} = {
|
|
29
29
|
TABLE_NAME: '{{TABLE_NAME}}',
|
|
30
30
|
{{#each COLUMNS_UPPERCASE}}
|
|
31
31
|
{{@key}}: '{{this}}',
|
|
@@ -75,20 +75,21 @@ export const {{TABLE_NAME_SHORT}}: C6RestfulModel & iDefine{{TABLE_NAME_SHORT_PA
|
|
|
75
75
|
},{{/this}}],{{/each}}
|
|
76
76
|
},
|
|
77
77
|
REST_STATE_OPERATIONS: {
|
|
78
|
-
PUT:
|
|
79
|
-
POST:
|
|
80
|
-
DELETE:
|
|
78
|
+
PUT: putState{{TABLE_NAME_SHORT_PASCAL_CASE}},
|
|
79
|
+
POST: postState{{TABLE_NAME_SHORT_PASCAL_CASE}},
|
|
80
|
+
DELETE: deleteState{{TABLE_NAME_SHORT_PASCAL_CASE}},
|
|
81
81
|
},
|
|
82
82
|
}
|
|
83
83
|
{{/TABLES}}
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
|
|
86
|
+
export const TABLES: tC6Tables = {
|
|
86
87
|
{{#TABLES}}
|
|
87
88
|
{{TABLE_NAME_SHORT}}: {{TABLE_NAME_SHORT}},
|
|
88
89
|
{{/TABLES}}
|
|
89
90
|
};
|
|
90
91
|
|
|
91
|
-
export const C6 : { TABLES:
|
|
92
|
+
export const C6 : { TABLES: tC6Tables }
|
|
92
93
|
& { [key: string]: any } = {
|
|
93
94
|
...C6Constants,
|
|
94
95
|
TABLES: TABLES,
|
|
@@ -3,6 +3,7 @@ import {CarbonReact} from "@carbonorm/carbonreact";
|
|
|
3
3
|
import {checkAllRequestsComplete} from "@carbonorm/carbonnode";
|
|
4
4
|
import {act, waitFor} from '@testing-library/react';
|
|
5
5
|
import {C6, iRestfulObjectArrayTypes, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, {{TABLE_NAME_SHORT}} } from "{{RELATIVE_OUTPUT_DIR}}/C6";
|
|
6
|
+
import {{TABLE_NAME_SHORT_PASCAL_CASE}} from "./{{TABLE_NAME_SHORT_PASCAL_CASE}}";
|
|
6
7
|
|
|
7
8
|
const randomString = Math.random().toString(36).substring(7);
|
|
8
9
|
const randomInt = Math.floor(Math.random() * 1000000);
|
|
@@ -28,7 +29,7 @@ xdescribe('REST {{TABLE_NAME_SHORT_PASCAL_CASE}} api', () => {
|
|
|
28
29
|
|
|
29
30
|
await act(async () => {
|
|
30
31
|
|
|
31
|
-
let selectAllResponse = await {{
|
|
32
|
+
let selectAllResponse = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Get({})
|
|
32
33
|
|
|
33
34
|
if ('function' === typeof selectAllResponse) {
|
|
34
35
|
throw Error('selectAllResponse is a promise, this typically means this specific get request has already run during test setup.');
|
|
@@ -37,7 +38,7 @@ xdescribe('REST {{TABLE_NAME_SHORT_PASCAL_CASE}} api', () => {
|
|
|
37
38
|
// We don't care if it is filled or not, just that the request can be made.
|
|
38
39
|
expect(selectAllResponse?.data?.rest).not.toBeUndefined();
|
|
39
40
|
|
|
40
|
-
const postResponse = await {{
|
|
41
|
+
const postResponse = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Post(testData);
|
|
41
42
|
|
|
42
43
|
console.log('postResponse', postResponse?.data)
|
|
43
44
|
|
|
@@ -47,7 +48,7 @@ xdescribe('REST {{TABLE_NAME_SHORT_PASCAL_CASE}} api', () => {
|
|
|
47
48
|
|
|
48
49
|
const postID = postResponse?.data?.created
|
|
49
50
|
|
|
50
|
-
const singleRowSelect = await {{
|
|
51
|
+
const singleRowSelect = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Get({
|
|
51
52
|
[C6.WHERE]: {
|
|
52
53
|
[{{TABLE_NAME_SHORT}}[primaryKey.toUpperCase()]]: postID,
|
|
53
54
|
}
|
|
@@ -70,7 +71,7 @@ xdescribe('REST {{TABLE_NAME_SHORT_PASCAL_CASE}} api', () => {
|
|
|
70
71
|
|
|
71
72
|
expect(selectedPostId).toEqual(postID);
|
|
72
73
|
|
|
73
|
-
const multipleRowSelect = await {{
|
|
74
|
+
const multipleRowSelect = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Get({
|
|
74
75
|
[C6.WHERE]: {
|
|
75
76
|
[{{TABLE_NAME_SHORT}}[primaryKey.toUpperCase()]]: [C6.IN, [0, postID]],
|
|
76
77
|
}
|
|
@@ -91,17 +92,17 @@ xdescribe('REST {{TABLE_NAME_SHORT_PASCAL_CASE}} api', () => {
|
|
|
91
92
|
testData[primaryKey] = postID
|
|
92
93
|
|
|
93
94
|
{{#each TYPE_VALIDATION}}
|
|
94
|
-
testData.{{
|
|
95
|
+
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}};
|
|
95
96
|
{{/each}}
|
|
96
97
|
|
|
97
98
|
// wait for the global state to be updated
|
|
98
99
|
expect(CarbonReact.getState<iRestfulObjectArrayTypes>().{{TABLE_NAME_SHORT}}).not.toBeUndefined();
|
|
99
100
|
|
|
100
|
-
const updateResponse = await {{
|
|
101
|
+
const updateResponse = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Put(testData)
|
|
101
102
|
|
|
102
103
|
expect(updateResponse?.data?.updated).not.toBeUndefined();
|
|
103
104
|
|
|
104
|
-
const deleteResponse = await {{
|
|
105
|
+
const deleteResponse = await {{TABLE_NAME_SHORT_PASCAL_CASE}}.Delete({
|
|
105
106
|
[primaryKey]: postID
|
|
106
107
|
})
|
|
107
108
|
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import {AxiosResponse} from "axios";
|
|
14
14
|
import {iAPI, Modify} from "restRequest";
|
|
15
15
|
import {deleteRestfulObjectArrays, updateRestfulObjectArrays} from "@carbonorm/carbonreact";
|
|
16
|
-
import {C6, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, {{TABLE_NAME_SHORT}},
|
|
16
|
+
import {C6, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, {{TABLE_NAME_SHORT}}, RestTableNames} from "./C6";
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
{{{TABLE_DEFINITION}}}
|
|
@@ -24,7 +24,7 @@ type GetCustomAndRequiredFields = {}
|
|
|
24
24
|
type GetRequestTableOverrides = {}
|
|
25
25
|
|
|
26
26
|
// required parameters, optional parameters, parameter type overrides, response, and table names
|
|
27
|
-
export const Get = restRequest<GetCustomAndRequiredFields, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, GetRequestTableOverrides, iGetC6RestResponse<i{{TABLE_NAME_SHORT_PASCAL_CASE}}>,
|
|
27
|
+
export const Get = restRequest<GetCustomAndRequiredFields, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, GetRequestTableOverrides, iGetC6RestResponse<i{{TABLE_NAME_SHORT_PASCAL_CASE}}>, RestTableNames>({
|
|
28
28
|
C6: C6,
|
|
29
29
|
tableName: {{TABLE_NAME_SHORT}}.TABLE_NAME,
|
|
30
30
|
requestMethod: GET,
|
|
@@ -51,7 +51,7 @@ export function putState{{TABLE_NAME_SHORT_PASCAL_CASE}}(response : AxiosRespons
|
|
|
51
51
|
], "{{TABLE_NAME_SHORT}}", {{TABLE_NAME_SHORT}}.PRIMARY_SHORT as (keyof i{{TABLE_NAME_SHORT_PASCAL_CASE}})[])
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
export const Put = restRequest<PutCustomAndRequiredFields, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, PutRequestTableOverrides, iPutC6RestResponse<i{{TABLE_NAME_SHORT_PASCAL_CASE}}>,
|
|
54
|
+
export const Put = restRequest<PutCustomAndRequiredFields, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, PutRequestTableOverrides, iPutC6RestResponse<i{{TABLE_NAME_SHORT_PASCAL_CASE}}>, RestTableNames>({
|
|
55
55
|
C6: C6,
|
|
56
56
|
tableName: {{TABLE_NAME_SHORT}}.TABLE_NAME,
|
|
57
57
|
requestMethod: PUT,
|
|
@@ -94,7 +94,7 @@ export function postState{{TABLE_NAME_SHORT_PASCAL_CASE}}(response : AxiosRespon
|
|
|
94
94
|
)
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
export const Post = restRequest<PostCustomAndRequiredFields, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, PostRequestTableOverrides, iPostC6RestResponse<i{{TABLE_NAME_SHORT_PASCAL_CASE}}>,
|
|
97
|
+
export const Post = restRequest<PostCustomAndRequiredFields, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, PostRequestTableOverrides, iPostC6RestResponse<i{{TABLE_NAME_SHORT_PASCAL_CASE}}>, RestTableNames>({
|
|
98
98
|
C6: C6,
|
|
99
99
|
tableName: {{TABLE_NAME_SHORT}}.TABLE_NAME,
|
|
100
100
|
requestMethod: POST,
|
|
@@ -116,7 +116,7 @@ export function deleteState{{TABLE_NAME_SHORT_PASCAL_CASE}}(_response : AxiosRes
|
|
|
116
116
|
], "{{TABLE_NAME_SHORT}}", {{TABLE_NAME_SHORT}}.PRIMARY_SHORT as (keyof i{{TABLE_NAME_SHORT_PASCAL_CASE}})[])
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
export const Delete = restRequest<DeleteCustomAndRequiredFields, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, DeleteRequestTableOverrides, iDeleteC6RestResponse<i{{TABLE_NAME_SHORT_PASCAL_CASE}}>,
|
|
119
|
+
export const Delete = restRequest<DeleteCustomAndRequiredFields, i{{TABLE_NAME_SHORT_PASCAL_CASE}}, DeleteRequestTableOverrides, iDeleteC6RestResponse<i{{TABLE_NAME_SHORT_PASCAL_CASE}}>, RestTableNames>({
|
|
120
120
|
C6: C6,
|
|
121
121
|
tableName: {{TABLE_NAME_SHORT}}.TABLE_NAME,
|
|
122
122
|
requestMethod: DELETE,
|
|
@@ -140,17 +140,23 @@ var parseSQLToTypeScript = function (sql) {
|
|
|
140
140
|
var tableName = tableMatch[1];
|
|
141
141
|
var columnDefinitions = tableMatch[2];
|
|
142
142
|
var columns = {};
|
|
143
|
-
|
|
144
|
-
var
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
143
|
+
// Improved regular expression to match column definitions
|
|
144
|
+
var columnRegex = /\s*`([^`]*)`\s+(\w+)(?:\(([^)]+)\))?\s*(NOT NULL)?\s*(AUTO_INCREMENT)?\s*(DEFAULT\s+'.*?'|DEFAULT\s+\S+)?/gm;
|
|
145
|
+
var columnMatch;
|
|
146
|
+
var columnDefinitionsLines = columnDefinitions.split('\n');
|
|
147
|
+
columnDefinitionsLines.forEach(function (line) {
|
|
148
|
+
if (!line.match(/(PRIMARY KEY|UNIQUE KEY|CONSTRAINT)/)) {
|
|
149
|
+
while ((columnMatch = columnRegex.exec(line))) {
|
|
150
|
+
columns[columnMatch[1]] = {
|
|
151
|
+
type: columnMatch[2],
|
|
152
|
+
length: columnMatch[3] || '',
|
|
153
|
+
notNull: !!columnMatch[4],
|
|
154
|
+
autoIncrement: !!columnMatch[5],
|
|
155
|
+
defaultValue: columnMatch[6] ? columnMatch[6].replace(/^DEFAULT\s+/i, '') : ''
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
154
160
|
// Extract primary keys
|
|
155
161
|
var primaryKeyMatch = columnDefinitions.match(/PRIMARY KEY \(([^)]+)\)/i);
|
|
156
162
|
var primaryKeys = primaryKeyMatch
|
|
@@ -211,19 +211,30 @@ const parseSQLToTypeScript = (sql: string) => {
|
|
|
211
211
|
const tableName = tableMatch[1];
|
|
212
212
|
const columnDefinitions = tableMatch[2];
|
|
213
213
|
|
|
214
|
-
let columns
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
214
|
+
let columns = {};
|
|
215
|
+
|
|
216
|
+
// Improved regular expression to match column definitions
|
|
217
|
+
const columnRegex = /\s*`([^`]*)`\s+(\w+)(?:\(([^)]+)\))?\s*(NOT NULL)?\s*(AUTO_INCREMENT)?\s*(DEFAULT\s+'.*?'|DEFAULT\s+\S+)?/gm;
|
|
218
|
+
|
|
219
|
+
let columnMatch;
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
const columnDefinitionsLines = columnDefinitions.split('\n');
|
|
224
|
+
|
|
225
|
+
columnDefinitionsLines.forEach(line => {
|
|
226
|
+
if (!line.match(/(PRIMARY KEY|UNIQUE KEY|CONSTRAINT)/)) {
|
|
227
|
+
while ((columnMatch = columnRegex.exec(line))) {
|
|
228
|
+
columns[columnMatch[1]] = {
|
|
229
|
+
type: columnMatch[2],
|
|
230
|
+
length: columnMatch[3] || '',
|
|
231
|
+
notNull: !!columnMatch[4],
|
|
232
|
+
autoIncrement: !!columnMatch[5],
|
|
233
|
+
defaultValue: columnMatch[6] ? columnMatch[6].replace(/^DEFAULT\s+/i, '') : ''
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
});
|
|
227
238
|
|
|
228
239
|
// Extract primary keys
|
|
229
240
|
const primaryKeyMatch = columnDefinitions.match(/PRIMARY KEY \(([^)]+)\)/i);
|
|
@@ -235,6 +246,7 @@ const parseSQLToTypeScript = (sql: string) => {
|
|
|
235
246
|
const foreignKeyRegex: RegExp = /CONSTRAINT `([^`]+)` FOREIGN KEY \(`([^`]+)`\) REFERENCES `([^`]+)` \(`([^`]+)`\)( ON DELETE (\w+))?( ON UPDATE (\w+))?/g;
|
|
236
247
|
let foreignKeyMatch: RegExpExecArray | null;
|
|
237
248
|
|
|
249
|
+
|
|
238
250
|
while ((foreignKeyMatch = foreignKeyRegex.exec(columnDefinitions))) {
|
|
239
251
|
const constraintName = foreignKeyMatch[1];
|
|
240
252
|
const localColumn = foreignKeyMatch[2];
|
|
@@ -28,6 +28,8 @@ export interface iConstraint {
|
|
|
28
28
|
CONSTRAINT: string
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export type tC6Tables = { [key: string]: (C6RestfulModel & { [key: string]: any }) }
|
|
32
|
+
|
|
31
33
|
export interface C6RestfulModel<RestShortTableNames extends string = string> {
|
|
32
34
|
TABLE_NAME: RestShortTableNames,
|
|
33
35
|
PRIMARY: string[],
|