@carbonorm/carbonnode 4.0.1 → 5.0.0
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 +158 -49
- package/dist/api/executors/SqlExecutor.d.ts +6 -0
- package/dist/api/handlers/ExpressHandler.d.ts +2 -1
- package/dist/api/types/ormInterfaces.d.ts +12 -0
- package/dist/api/utils/sqlAllowList.d.ts +2 -0
- package/dist/index.cjs.js +247 -10
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +246 -11
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/scripts/assets/handlebars/C6.test.ts.handlebars +578 -32
- package/scripts/generateRestBindings.cjs +5 -5
- package/scripts/generateRestBindings.ts +5 -5
- package/src/__tests__/fixtures/createTestServer.ts +11 -3
- package/src/__tests__/fixtures/sqlResponses/actor.get.json +13 -0
- package/src/__tests__/fixtures/sqlResponses/sqlAllowList.blocked.json +3 -0
- package/src/__tests__/fixtures/sqlResponses/sqlAllowList.json +3 -0
- package/src/__tests__/sakila-db/C6.js +1 -1
- package/src/__tests__/sakila-db/C6.mysql.cnf +6 -0
- package/src/__tests__/sakila-db/C6.mysqldump.json +1 -0
- package/src/__tests__/sakila-db/C6.mysqldump.sql +720 -0
- package/src/__tests__/sakila-db/C6.sqlAllowList.json +94 -0
- package/src/__tests__/sakila-db/C6.test.ts +578 -32
- package/src/__tests__/sakila-db/C6.ts +1 -1
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.get.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.join.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.json +12 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.post.latest.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.put.lookup.json +16 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.actor.seed.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.fk.current.json +358 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.fk.referenced.json +158 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.get.json +22 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.post.json +16 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.post.latest.json +22 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.put.lookup.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.address.seed.json +22 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.get.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.join.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.post.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.post.latest.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.put.lookup.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.category.seed.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.fk.current.json +158 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.fk.referenced.json +133 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.get.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.join.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.post.json +12 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.post.latest.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.put.lookup.json +16 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.city.seed.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.get.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.join.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.post.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.post.latest.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.put.lookup.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.country.seed.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.fk.current.json +283 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.fk.referenced.json +358 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.get.json +19 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.join.json +29 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.post.latest.json +19 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.put.lookup.json +21 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.customer.seed.json +19 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.fk.current.json +383 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.fk.referenced.json +38 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.get.json +23 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.post.json +20 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.post.latest.json +23 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.put.lookup.json +25 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.film.seed.json +23 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.fk.current.json +158 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.fk.referenced.json +20 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.get.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.join.json +25 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.json +12 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.post.latest.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.put.lookup.json +16 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.inventory.seed.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.get.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.post.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.post.latest.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.put.lookup.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.language.seed.json +13 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.fk.current.json +233 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.fk.referenced.json +233 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.get.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.post.latest.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.put.lookup.json +19 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.payment.seed.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.delete.json +10 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.delete.lookup.json +9 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.fk.current.json +233 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.fk.referenced.json +34 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.get.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.json +15 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.post.latest.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.json +11 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.put.lookup.json +19 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.rental.seed.json +17 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.staff.fk.current.json +34 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.staff.fk.referenced.json +20 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.staff.get.json +21 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.staff.join.json +31 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.staff.seed.json +21 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.store.fk.current.json +20 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.store.fk.referenced.json +34 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.store.get.json +14 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.store.join.json +24 -0
- package/src/__tests__/sakila-db/sqlResponses/C6.store.seed.json +14 -0
- package/src/__tests__/sakila.generated.test.ts +31 -0
- package/src/__tests__/sqlAllowList.test.ts +135 -0
- package/src/api/executors/SqlExecutor.ts +156 -0
- package/src/api/handlers/ExpressHandler.ts +10 -1
- package/src/api/types/ormInterfaces.ts +15 -0
- package/src/api/utils/sqlAllowList.ts +54 -0
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import mysql from 'mysql2/promise';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
5
|
import {
|
|
3
6
|
checkAllRequestsComplete,
|
|
7
|
+
normalizeSql,
|
|
8
|
+
type DetermineResponseDataType,
|
|
9
|
+
type OrmGenerics,
|
|
4
10
|
} from '@carbonorm/carbonnode';
|
|
5
11
|
import {
|
|
6
12
|
C6,
|
|
@@ -14,10 +20,139 @@ import {
|
|
|
14
20
|
afterAll,
|
|
15
21
|
} from 'vitest';
|
|
16
22
|
|
|
17
|
-
function toPascalCase(name) {
|
|
23
|
+
function toPascalCase(name: string) {
|
|
18
24
|
return name.replace(/(^|_)([a-z])/g, (_, __, c) => c.toUpperCase());
|
|
19
25
|
}
|
|
20
26
|
|
|
27
|
+
function stripPrefix(name: string) {
|
|
28
|
+
if (!C6.PREFIX) return name;
|
|
29
|
+
return name.startsWith(C6.PREFIX) ? name.slice(C6.PREFIX.length) : name;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getBinding(shortName: string) {
|
|
33
|
+
return C6.ORM?.[toPascalCase(shortName)] ?? C6[toPascalCase(shortName)];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function formatTimestamp() {
|
|
37
|
+
return new Date().toISOString().slice(0, 19).replace('T', ' ');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
type RestResponse<G extends OrmGenerics = OrmGenerics> = DetermineResponseDataType<
|
|
41
|
+
G['RequestMethod'],
|
|
42
|
+
G['RestTableInterface']
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
type RestPromise<G extends OrmGenerics = OrmGenerics> = Promise<RestResponse<G>>;
|
|
46
|
+
|
|
47
|
+
function unwrapResponse<G extends OrmGenerics = OrmGenerics>(
|
|
48
|
+
response: RestResponse<G> | null | undefined
|
|
49
|
+
) {
|
|
50
|
+
return response;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
54
|
+
const __dirname = path.dirname(__filename);
|
|
55
|
+
const sqlResponsesDir = path.join(__dirname, 'sqlResponses');
|
|
56
|
+
const sqlAllowListPath = path.join(__dirname, 'C6.sqlAllowList.json');
|
|
57
|
+
const sqlAllowListEntries = new Set<string>();
|
|
58
|
+
|
|
59
|
+
async function recordSqlResponse<G extends OrmGenerics = OrmGenerics>(
|
|
60
|
+
label: string,
|
|
61
|
+
response: RestResponse<G> | null | undefined
|
|
62
|
+
) {
|
|
63
|
+
if (!response) return;
|
|
64
|
+
const payload = unwrapResponse(response);
|
|
65
|
+
if (!payload) return;
|
|
66
|
+
const sqlValue = payload?.sql?.sql ?? (typeof payload?.sql === 'string' ? payload.sql : undefined);
|
|
67
|
+
if (typeof sqlValue === 'string') {
|
|
68
|
+
sqlAllowListEntries.add(normalizeSql(sqlValue));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
await mkdir(sqlResponsesDir, { recursive: true });
|
|
72
|
+
const filePath = path.join(sqlResponsesDir, `C6.${label}.json`);
|
|
73
|
+
await writeFile(filePath, JSON.stringify(payload, null, 2));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function finalizeSqlAllowList() {
|
|
77
|
+
await mkdir(sqlResponsesDir, { recursive: true });
|
|
78
|
+
const compiled = Array.from(sqlAllowListEntries).sort();
|
|
79
|
+
await writeFile(sqlAllowListPath, JSON.stringify(compiled, null, 2));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function executeAndRecord<G extends OrmGenerics = OrmGenerics>(
|
|
83
|
+
label: string,
|
|
84
|
+
fn: () => RestPromise<G>
|
|
85
|
+
) {
|
|
86
|
+
const result = await fn();
|
|
87
|
+
await recordSqlResponse<G>(label, result);
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function buildScalarValue(meta: any, columnName: string, seedRow: any) {
|
|
92
|
+
const seedValue = seedRow?.[columnName];
|
|
93
|
+
const mysqlType = String(meta?.MYSQL_TYPE ?? '').toLowerCase();
|
|
94
|
+
|
|
95
|
+
if (mysqlType === 'year') return new Date().getFullYear();
|
|
96
|
+
|
|
97
|
+
const geometryTypes = [
|
|
98
|
+
'geometry',
|
|
99
|
+
'point',
|
|
100
|
+
'linestring',
|
|
101
|
+
'polygon',
|
|
102
|
+
'multipoint',
|
|
103
|
+
'multilinestring',
|
|
104
|
+
'multipolygon',
|
|
105
|
+
'geometrycollection',
|
|
106
|
+
];
|
|
107
|
+
if (geometryTypes.some((type) => mysqlType.includes(type))) {
|
|
108
|
+
return "ST_GeomFromText('POINT(0 0)')";
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (mysqlType === 'json') return {};
|
|
112
|
+
if (mysqlType === 'enum' || mysqlType === 'set') {
|
|
113
|
+
return seedValue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const isStringType = ['char', 'varchar', 'text', 'tinytext', 'mediumtext', 'longtext'].some((t) =>
|
|
117
|
+
mysqlType.includes(t)
|
|
118
|
+
);
|
|
119
|
+
if (isStringType) {
|
|
120
|
+
const value = `${columnName}_${Date.now()}`;
|
|
121
|
+
const maxLength = parseInt(meta?.MAX_LENGTH ?? '', 10);
|
|
122
|
+
if (Number.isFinite(maxLength) && maxLength > 0) {
|
|
123
|
+
return value.slice(0, maxLength);
|
|
124
|
+
}
|
|
125
|
+
return value;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const isDateType = ['date', 'time', 'datetime', 'timestamp', 'year'].some((t) => mysqlType.includes(t));
|
|
129
|
+
if (isDateType) return formatTimestamp();
|
|
130
|
+
|
|
131
|
+
const isNumericType = [
|
|
132
|
+
'int',
|
|
133
|
+
'decimal',
|
|
134
|
+
'numeric',
|
|
135
|
+
'float',
|
|
136
|
+
'double',
|
|
137
|
+
'real',
|
|
138
|
+
'bit',
|
|
139
|
+
].some((t) => mysqlType.includes(t));
|
|
140
|
+
if (isNumericType) {
|
|
141
|
+
if (typeof seedValue === 'number') return seedValue + 1;
|
|
142
|
+
return 1;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (mysqlType.includes('bool')) return 1;
|
|
146
|
+
|
|
147
|
+
if (['blob', 'binary', 'varbinary'].some((t) => mysqlType.includes(t))) {
|
|
148
|
+
return Buffer.from('00', 'hex');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (seedValue !== undefined) return seedValue;
|
|
152
|
+
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
21
156
|
async function waitForRequests(timeout = 10000) {
|
|
22
157
|
const start = Date.now();
|
|
23
158
|
while (!checkAllRequestsComplete()) {
|
|
@@ -28,6 +163,302 @@ async function waitForRequests(timeout = 10000) {
|
|
|
28
163
|
}
|
|
29
164
|
}
|
|
30
165
|
|
|
166
|
+
async function fetchSeedRow(binding: any, label: string) {
|
|
167
|
+
const result = await executeAndRecord(label, () =>
|
|
168
|
+
binding.Get({
|
|
169
|
+
[C6.PAGINATION]: { [C6.LIMIT]: 1 },
|
|
170
|
+
} as any)
|
|
171
|
+
);
|
|
172
|
+
const data = unwrapResponse(result);
|
|
173
|
+
return data?.rest?.[0];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async function pickForeignKeyValue({
|
|
177
|
+
columnName,
|
|
178
|
+
referencedTable,
|
|
179
|
+
referencedColumn,
|
|
180
|
+
restBinding,
|
|
181
|
+
label,
|
|
182
|
+
}: {
|
|
183
|
+
columnName: string;
|
|
184
|
+
referencedTable: string;
|
|
185
|
+
referencedColumn: string;
|
|
186
|
+
restBinding: any;
|
|
187
|
+
label: string;
|
|
188
|
+
}) {
|
|
189
|
+
const referencedBinding = getBinding(referencedTable);
|
|
190
|
+
if (!referencedBinding) return undefined;
|
|
191
|
+
|
|
192
|
+
const [currentResult, referencedResult] = await Promise.all([
|
|
193
|
+
executeAndRecord(`${label}.fk.current`, () =>
|
|
194
|
+
restBinding.Get({
|
|
195
|
+
[C6.PAGINATION]: { [C6.LIMIT]: 25 },
|
|
196
|
+
} as any)
|
|
197
|
+
),
|
|
198
|
+
executeAndRecord(`${label}.fk.referenced`, () =>
|
|
199
|
+
referencedBinding.Get({
|
|
200
|
+
[C6.PAGINATION]: { [C6.LIMIT]: 25 },
|
|
201
|
+
} as any)
|
|
202
|
+
),
|
|
203
|
+
]);
|
|
204
|
+
|
|
205
|
+
const currentData = unwrapResponse(currentResult);
|
|
206
|
+
const referencedData = unwrapResponse(referencedResult);
|
|
207
|
+
|
|
208
|
+
const currentRows = currentData?.rest ?? [];
|
|
209
|
+
const currentValues = new Set(
|
|
210
|
+
currentRows
|
|
211
|
+
.map((row) => row?.[columnName])
|
|
212
|
+
.filter((value) => value !== undefined && value !== null)
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
const candidate = (referencedData?.rest ?? [])
|
|
216
|
+
.map((row) => row?.[referencedColumn])
|
|
217
|
+
.find((value) => value !== undefined && value !== null && !currentValues.has(value));
|
|
218
|
+
|
|
219
|
+
if (candidate !== undefined) return candidate;
|
|
220
|
+
|
|
221
|
+
if (currentValues.size < currentRows.length) {
|
|
222
|
+
return referencedData?.rest?.[0]?.[referencedColumn];
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function buildUpdatedValue(meta: any, columnName: string, currentValue: any) {
|
|
229
|
+
const mysqlType = String(meta?.MYSQL_TYPE ?? '').toLowerCase();
|
|
230
|
+
const geometryTypes = [
|
|
231
|
+
'geometry',
|
|
232
|
+
'point',
|
|
233
|
+
'linestring',
|
|
234
|
+
'polygon',
|
|
235
|
+
'multipoint',
|
|
236
|
+
'multilinestring',
|
|
237
|
+
'multipolygon',
|
|
238
|
+
'geometrycollection',
|
|
239
|
+
];
|
|
240
|
+
|
|
241
|
+
if (mysqlType === 'year') return new Date().getFullYear();
|
|
242
|
+
if (geometryTypes.some((type) => mysqlType.includes(type))) {
|
|
243
|
+
return "ST_GeomFromText('POINT(1 1)')";
|
|
244
|
+
}
|
|
245
|
+
if (mysqlType === 'json') return { updated: true };
|
|
246
|
+
|
|
247
|
+
const isDateType = ['date', 'time', 'datetime', 'timestamp'].some((t) => mysqlType.includes(t));
|
|
248
|
+
if (isDateType) return formatTimestamp();
|
|
249
|
+
|
|
250
|
+
const isNumericType = [
|
|
251
|
+
'int',
|
|
252
|
+
'decimal',
|
|
253
|
+
'numeric',
|
|
254
|
+
'float',
|
|
255
|
+
'double',
|
|
256
|
+
'real',
|
|
257
|
+
'bit',
|
|
258
|
+
].some((t) => mysqlType.includes(t));
|
|
259
|
+
if (isNumericType) {
|
|
260
|
+
if (typeof currentValue === 'number') return currentValue + 1;
|
|
261
|
+
return 1;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (mysqlType.includes('bool')) return currentValue ? 0 : 1;
|
|
265
|
+
|
|
266
|
+
const isStringType = ['char', 'varchar', 'text', 'tinytext', 'mediumtext', 'longtext'].some((t) =>
|
|
267
|
+
mysqlType.includes(t)
|
|
268
|
+
);
|
|
269
|
+
if (isStringType) {
|
|
270
|
+
const base = `${columnName}_updated_${Date.now()}`;
|
|
271
|
+
const maxLength = parseInt(meta?.MAX_LENGTH ?? '', 10);
|
|
272
|
+
if (Number.isFinite(maxLength) && maxLength > 0) {
|
|
273
|
+
return base.slice(0, maxLength);
|
|
274
|
+
}
|
|
275
|
+
return base;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (currentValue instanceof Date) {
|
|
279
|
+
return formatTimestamp();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return currentValue ?? null;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
function normalizeForComparison(meta: any, value: any) {
|
|
286
|
+
if (value === undefined || value === null) return value;
|
|
287
|
+
const mysqlType = String(meta?.MYSQL_TYPE ?? '').toLowerCase();
|
|
288
|
+
|
|
289
|
+
const isDateType = ['date', 'time', 'datetime', 'timestamp', 'year'].some((t) => mysqlType.includes(t));
|
|
290
|
+
if (isDateType) {
|
|
291
|
+
const dateValue = value instanceof Date ? value : new Date(value);
|
|
292
|
+
const time = dateValue.getTime();
|
|
293
|
+
if (!Number.isNaN(time)) return time;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const isDecimalType = ['decimal', 'numeric'].some((t) => mysqlType.includes(t));
|
|
297
|
+
if (isDecimalType) {
|
|
298
|
+
const parsed = Number(value);
|
|
299
|
+
if (!Number.isNaN(parsed)) return parsed;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const isNumericType = [
|
|
303
|
+
'int',
|
|
304
|
+
'float',
|
|
305
|
+
'double',
|
|
306
|
+
'real',
|
|
307
|
+
'bit',
|
|
308
|
+
].some((t) => mysqlType.includes(t));
|
|
309
|
+
if (isNumericType) {
|
|
310
|
+
const parsed = Number(value);
|
|
311
|
+
if (!Number.isNaN(parsed)) return parsed;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return value;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
function rowMatches(row: any, fields: Array<{ columnName: string; value: any; meta: any }>) {
|
|
318
|
+
if (!row) return false;
|
|
319
|
+
return fields.every(({ columnName, value, meta }) => {
|
|
320
|
+
const actual = normalizeForComparison(meta ?? {}, row?.[columnName]);
|
|
321
|
+
const expected = normalizeForComparison(meta ?? {}, value);
|
|
322
|
+
return actual === expected;
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async function buildInsertPayload(restModel: any, restBinding: any, label: string) {
|
|
327
|
+
const seedRow = await fetchSeedRow(restBinding, `${label}.seed`);
|
|
328
|
+
if (!seedRow) return null;
|
|
329
|
+
|
|
330
|
+
const payload: Record<string, any> = {};
|
|
331
|
+
const where: Record<string, any> = {};
|
|
332
|
+
const compareFields: Array<{ columnName: string; value: any; meta: any }> = [];
|
|
333
|
+
const references: Record<string, any[]> = restModel.TABLE_REFERENCES ?? {};
|
|
334
|
+
const validations: Record<string, any> = restModel.TYPE_VALIDATION ?? {};
|
|
335
|
+
const columnMap: Record<string, string> = restModel.COLUMNS ?? {};
|
|
336
|
+
const metaByColumnName: Record<string, any> = {};
|
|
337
|
+
let missingRequired = false;
|
|
338
|
+
|
|
339
|
+
for (const [fullColumn, meta] of Object.entries(validations) as [string, any][]) {
|
|
340
|
+
const columnName = columnMap[fullColumn] ?? fullColumn.split('.').pop();
|
|
341
|
+
if (!columnName) continue;
|
|
342
|
+
metaByColumnName[columnName] = meta;
|
|
343
|
+
metaByColumnName[fullColumn] = meta;
|
|
344
|
+
|
|
345
|
+
if (meta.AUTO_INCREMENT) continue;
|
|
346
|
+
if (meta.SKIP_COLUMN_IN_POST) continue;
|
|
347
|
+
|
|
348
|
+
let value;
|
|
349
|
+
const refList = references[columnName];
|
|
350
|
+
if (Array.isArray(refList) && refList.length > 0) {
|
|
351
|
+
const ref = refList[0];
|
|
352
|
+
const referencedTable = stripPrefix(ref.TABLE);
|
|
353
|
+
value = await pickForeignKeyValue({
|
|
354
|
+
columnName,
|
|
355
|
+
referencedTable,
|
|
356
|
+
referencedColumn: ref.COLUMN,
|
|
357
|
+
restBinding,
|
|
358
|
+
label,
|
|
359
|
+
});
|
|
360
|
+
if (value === undefined) {
|
|
361
|
+
missingRequired = true;
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
} else {
|
|
365
|
+
value = buildScalarValue(meta, columnName, seedRow);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (value === undefined) {
|
|
369
|
+
if (seedRow?.[columnName] !== undefined) {
|
|
370
|
+
value = seedRow[columnName];
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
if (value === undefined) {
|
|
375
|
+
missingRequired = true;
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
payload[columnName] = value;
|
|
380
|
+
|
|
381
|
+
const mysqlType = String(meta?.MYSQL_TYPE ?? '').toLowerCase();
|
|
382
|
+
const geometryTypes = [
|
|
383
|
+
'geometry',
|
|
384
|
+
'point',
|
|
385
|
+
'linestring',
|
|
386
|
+
'polygon',
|
|
387
|
+
'multipoint',
|
|
388
|
+
'multilinestring',
|
|
389
|
+
'multipolygon',
|
|
390
|
+
'geometrycollection',
|
|
391
|
+
];
|
|
392
|
+
const isDateType = ['date', 'time', 'datetime', 'timestamp', 'year'].some((t) => mysqlType.includes(t));
|
|
393
|
+
const shouldSkipWhere =
|
|
394
|
+
isDateType
|
|
395
|
+
|| geometryTypes.some((type) => mysqlType.includes(type))
|
|
396
|
+
|| mysqlType === 'json'
|
|
397
|
+
|| Array.isArray(value)
|
|
398
|
+
|| value instanceof Date
|
|
399
|
+
|| (typeof Buffer !== 'undefined' && Buffer.isBuffer && Buffer.isBuffer(value));
|
|
400
|
+
|
|
401
|
+
if (!shouldSkipWhere && fullColumn && value !== undefined && value !== null) {
|
|
402
|
+
where[fullColumn] = value;
|
|
403
|
+
compareFields.push({ columnName, value, meta });
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (missingRequired) return null;
|
|
408
|
+
|
|
409
|
+
if (!Object.keys(payload).length) return null;
|
|
410
|
+
|
|
411
|
+
if (!Object.keys(where).length) return null;
|
|
412
|
+
|
|
413
|
+
return { payload, where, metaByColumnName, compareFields };
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function buildJoinRequest(shortName: string, restModel: any) {
|
|
417
|
+
const baseTable = restModel.TABLE_NAME ?? shortName;
|
|
418
|
+
const references: Record<string, any[]> = restModel.TABLE_REFERENCES ?? {};
|
|
419
|
+
const referencedBy: Record<string, any[]> = restModel.TABLE_REFERENCED_BY ?? {};
|
|
420
|
+
|
|
421
|
+
const referenceEntries = Object.entries(references) as [string, any[]][];
|
|
422
|
+
if (referenceEntries.length > 0) {
|
|
423
|
+
const [localColumn, refs] = referenceEntries[0];
|
|
424
|
+
const ref = refs[0];
|
|
425
|
+
const joinTable = ref.TABLE;
|
|
426
|
+
const joinAlias = `${stripPrefix(ref.TABLE)}_ref`;
|
|
427
|
+
return {
|
|
428
|
+
[C6.SELECT]: ['*'],
|
|
429
|
+
[C6.JOIN]: {
|
|
430
|
+
[C6.INNER]: {
|
|
431
|
+
[`${joinTable} ${joinAlias}`]: {
|
|
432
|
+
[`${joinAlias}.${ref.COLUMN}`]: [C6.EQUAL, `${baseTable}.${localColumn}`],
|
|
433
|
+
},
|
|
434
|
+
},
|
|
435
|
+
},
|
|
436
|
+
[C6.PAGINATION]: { [C6.LIMIT]: 1 },
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const referencedByEntries = Object.entries(referencedBy) as [string, any[]][];
|
|
441
|
+
if (referencedByEntries.length > 0) {
|
|
442
|
+
const [localColumn, refs] = referencedByEntries[0];
|
|
443
|
+
const ref = refs[0];
|
|
444
|
+
const joinTable = ref.TABLE;
|
|
445
|
+
const joinAlias = `${stripPrefix(ref.TABLE)}_ref`;
|
|
446
|
+
return {
|
|
447
|
+
[C6.SELECT]: ['*'],
|
|
448
|
+
[C6.JOIN]: {
|
|
449
|
+
[C6.INNER]: {
|
|
450
|
+
[`${joinTable} ${joinAlias}`]: {
|
|
451
|
+
[`${joinAlias}.${ref.COLUMN}`]: [C6.EQUAL, `${baseTable}.${localColumn}`],
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
},
|
|
455
|
+
[C6.PAGINATION]: { [C6.LIMIT]: 1 },
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return null;
|
|
460
|
+
}
|
|
461
|
+
|
|
31
462
|
describe('sakila-db generated C6 bindings', () => {
|
|
32
463
|
let pool;
|
|
33
464
|
|
|
@@ -43,48 +474,163 @@ describe('sakila-db generated C6 bindings', () => {
|
|
|
43
474
|
|
|
44
475
|
afterAll(async () => {
|
|
45
476
|
await pool.end();
|
|
477
|
+
await finalizeSqlAllowList();
|
|
46
478
|
});
|
|
47
479
|
|
|
48
|
-
for (const [shortName] of Object.entries(C6.TABLES)) {
|
|
49
|
-
const restBinding =
|
|
480
|
+
for (const [shortName, restModel] of Object.entries(C6.TABLES as Record<string, any>)) {
|
|
481
|
+
const restBinding = getBinding(shortName);
|
|
482
|
+
const tableModel = restModel as any;
|
|
50
483
|
if (!restBinding) continue;
|
|
51
484
|
|
|
52
485
|
it(`[${shortName}] GET`, async () => {
|
|
53
|
-
const result = await
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
486
|
+
const result = await executeAndRecord(`${shortName}.get`, () =>
|
|
487
|
+
restBinding.Get({
|
|
488
|
+
[C6.SELECT]: ['*'],
|
|
489
|
+
[C6.PAGINATION]: { [C6.LIMIT]: 1 },
|
|
490
|
+
} as any)
|
|
491
|
+
);
|
|
492
|
+
const data = unwrapResponse(result);
|
|
493
|
+
expect(Array.isArray(data?.rest)).toBe(true);
|
|
494
|
+
await waitForRequests();
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
it(`[${shortName}] JOIN`, async () => {
|
|
498
|
+
const joinRequest = buildJoinRequest(shortName, tableModel);
|
|
499
|
+
if (!joinRequest) return;
|
|
500
|
+
|
|
501
|
+
const result = await executeAndRecord(`${shortName}.join`, () =>
|
|
502
|
+
restBinding.Get(joinRequest as any)
|
|
503
|
+
);
|
|
504
|
+
const data = unwrapResponse(result);
|
|
58
505
|
expect(Array.isArray(data?.rest)).toBe(true);
|
|
59
506
|
await waitForRequests();
|
|
60
507
|
});
|
|
61
|
-
}
|
|
62
508
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
509
|
+
it(`[${shortName}] POST/PUT/DELETE`, async () => {
|
|
510
|
+
const primaryKeys = tableModel.PRIMARY_SHORT ?? [];
|
|
511
|
+
if (primaryKeys.length !== 1) return;
|
|
66
512
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const originalLastName = data?.rest?.[0]?.last_name;
|
|
513
|
+
const payloadSpec = await buildInsertPayload(tableModel, restBinding, shortName);
|
|
514
|
+
if (!payloadSpec) return;
|
|
70
515
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
} as any);
|
|
516
|
+
await executeAndRecord(`${shortName}.post`, () =>
|
|
517
|
+
restBinding.Post(payloadSpec.payload as any)
|
|
518
|
+
);
|
|
75
519
|
|
|
76
|
-
|
|
77
|
-
[
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
data = result?.data ?? result;
|
|
81
|
-
expect(data?.rest?.[0]?.last_name).toBe('Updated');
|
|
520
|
+
const primaryFull = tableModel.PRIMARY?.[0];
|
|
521
|
+
const primaryKey = primaryKeys[0];
|
|
522
|
+
const primaryMeta = payloadSpec.metaByColumnName?.[primaryKey]
|
|
523
|
+
?? payloadSpec.metaByColumnName?.[primaryFull ?? ''];
|
|
82
524
|
|
|
83
|
-
|
|
84
|
-
[Actor.ACTOR_ID]: testId,
|
|
85
|
-
[Actor.LAST_NAME]: originalLastName,
|
|
86
|
-
} as any);
|
|
87
|
-
await waitForRequests();
|
|
88
|
-
});
|
|
89
|
-
});
|
|
525
|
+
let insertedRow: any;
|
|
90
526
|
|
|
527
|
+
if (primaryFull && primaryMeta?.AUTO_INCREMENT) {
|
|
528
|
+
const latestResult = await executeAndRecord(`${shortName}.post.latest`, () =>
|
|
529
|
+
restBinding.Get({
|
|
530
|
+
[C6.PAGINATION]: {
|
|
531
|
+
[C6.LIMIT]: 1,
|
|
532
|
+
[C6.ORDER]: { [primaryFull]: 'DESC' },
|
|
533
|
+
},
|
|
534
|
+
cacheResults: false,
|
|
535
|
+
} as any)
|
|
536
|
+
);
|
|
537
|
+
const latestData = unwrapResponse(latestResult);
|
|
538
|
+
insertedRow = latestData?.rest?.[0];
|
|
539
|
+
} else {
|
|
540
|
+
const lookupResult = await executeAndRecord(`${shortName}.post.lookup`, () =>
|
|
541
|
+
restBinding.Get({
|
|
542
|
+
[C6.WHERE]: payloadSpec.where,
|
|
543
|
+
[C6.PAGINATION]: { [C6.LIMIT]: 1 },
|
|
544
|
+
cacheResults: false,
|
|
545
|
+
} as any)
|
|
546
|
+
);
|
|
547
|
+
const lookupData = unwrapResponse(lookupResult);
|
|
548
|
+
insertedRow = (lookupData?.rest ?? []).find((row: any) =>
|
|
549
|
+
rowMatches(row, payloadSpec.compareFields ?? [])
|
|
550
|
+
);
|
|
551
|
+
|
|
552
|
+
if (!insertedRow && primaryFull) {
|
|
553
|
+
const fallbackResult = await executeAndRecord(`${shortName}.post.fallback`, () =>
|
|
554
|
+
restBinding.Get({
|
|
555
|
+
[C6.PAGINATION]: {
|
|
556
|
+
[C6.LIMIT]: 1,
|
|
557
|
+
[C6.ORDER]: { [primaryFull]: 'DESC' },
|
|
558
|
+
},
|
|
559
|
+
cacheResults: false,
|
|
560
|
+
} as any)
|
|
561
|
+
);
|
|
562
|
+
const fallbackData = unwrapResponse(fallbackResult);
|
|
563
|
+
insertedRow = fallbackData?.rest?.[0];
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
expect(insertedRow).toBeDefined();
|
|
568
|
+
|
|
569
|
+
if (!insertedRow) return;
|
|
570
|
+
|
|
571
|
+
const primaryValue = insertedRow[primaryKey];
|
|
572
|
+
if (primaryValue === undefined || primaryValue === null) return;
|
|
573
|
+
|
|
574
|
+
const foreignKeys = new Set(Object.keys(tableModel.TABLE_REFERENCES ?? {}));
|
|
575
|
+
const updateColumn = Object.keys(payloadSpec.payload)
|
|
576
|
+
.find((key) => {
|
|
577
|
+
if (key === primaryKey || foreignKeys.has(key)) return false;
|
|
578
|
+
const meta = payloadSpec.metaByColumnName?.[key];
|
|
579
|
+
const mysqlType = String(meta?.MYSQL_TYPE ?? '').toLowerCase();
|
|
580
|
+
const geometryTypes = [
|
|
581
|
+
'geometry',
|
|
582
|
+
'point',
|
|
583
|
+
'linestring',
|
|
584
|
+
'polygon',
|
|
585
|
+
'multipoint',
|
|
586
|
+
'multilinestring',
|
|
587
|
+
'multipolygon',
|
|
588
|
+
'geometrycollection',
|
|
589
|
+
];
|
|
590
|
+
return !geometryTypes.some((type) => mysqlType.includes(type));
|
|
591
|
+
})
|
|
592
|
+
?? Object.keys(payloadSpec.payload).find((key) => key !== primaryKey);
|
|
593
|
+
|
|
594
|
+
if (!updateColumn) return;
|
|
595
|
+
|
|
596
|
+
const currentValue = insertedRow[updateColumn];
|
|
597
|
+
const updateMeta = payloadSpec.metaByColumnName?.[updateColumn];
|
|
598
|
+
const updatedValue = buildUpdatedValue(updateMeta ?? {}, updateColumn, currentValue);
|
|
599
|
+
|
|
600
|
+
await executeAndRecord(`${shortName}.put`, () =>
|
|
601
|
+
restBinding.Put({
|
|
602
|
+
[primaryKey]: primaryValue,
|
|
603
|
+
[updateColumn]: updatedValue,
|
|
604
|
+
} as any)
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
const updatedResult = await executeAndRecord(`${shortName}.put.lookup`, () =>
|
|
608
|
+
restBinding.Get({
|
|
609
|
+
[primaryKey]: primaryValue,
|
|
610
|
+
cacheResults: false,
|
|
611
|
+
} as any)
|
|
612
|
+
);
|
|
613
|
+
const updatedData = unwrapResponse(updatedResult);
|
|
614
|
+
const normalizedActual = normalizeForComparison(updateMeta ?? {}, updatedData?.rest?.[0]?.[updateColumn]);
|
|
615
|
+
const normalizedExpected = normalizeForComparison(updateMeta ?? {}, updatedValue);
|
|
616
|
+
expect(normalizedActual).toBe(normalizedExpected);
|
|
617
|
+
|
|
618
|
+
await executeAndRecord(`${shortName}.delete`, () =>
|
|
619
|
+
restBinding.Delete({
|
|
620
|
+
[primaryKey]: primaryValue,
|
|
621
|
+
} as any)
|
|
622
|
+
);
|
|
623
|
+
|
|
624
|
+
const deletedResult = await executeAndRecord(`${shortName}.delete.lookup`, () =>
|
|
625
|
+
restBinding.Get({
|
|
626
|
+
[primaryKey]: primaryValue,
|
|
627
|
+
cacheResults: false,
|
|
628
|
+
} as any)
|
|
629
|
+
);
|
|
630
|
+
const deletedData = unwrapResponse(deletedResult);
|
|
631
|
+
expect(Array.isArray(deletedData?.rest)).toBe(true);
|
|
632
|
+
expect(deletedData?.rest?.length ?? 0).toBe(0);
|
|
633
|
+
await waitForRequests();
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
});
|
|
@@ -59,15 +59,15 @@ var MySQLDump = /** @class */ (function () {
|
|
|
59
59
|
];
|
|
60
60
|
cnf.push("");
|
|
61
61
|
if ('' === cnfFile) {
|
|
62
|
-
cnfFile = path.join(
|
|
62
|
+
cnfFile = path.join(this.OUTPUT_DIR, 'C6.mysql.cnf');
|
|
63
63
|
}
|
|
64
64
|
try {
|
|
65
65
|
fs.writeFileSync(cnfFile, cnf.join('\n'));
|
|
66
66
|
fs.chmodSync(cnfFile, 488);
|
|
67
|
-
console.log("Successfully created mysql.cnf file in (".concat(cnfFile, ")"));
|
|
67
|
+
console.log("Successfully created C6.mysql.cnf file in (".concat(cnfFile, ")"));
|
|
68
68
|
}
|
|
69
69
|
catch (error) {
|
|
70
|
-
console.error("Failed to store file contents of mysql.cnf in (".concat(process.cwd(), ")"), error);
|
|
70
|
+
console.error("Failed to store file contents of C6.mysql.cnf in (".concat(process.cwd(), ")"), error);
|
|
71
71
|
process.exit(1);
|
|
72
72
|
}
|
|
73
73
|
return (this.mysqlcnf = cnfFile);
|
|
@@ -80,7 +80,7 @@ var MySQLDump = /** @class */ (function () {
|
|
|
80
80
|
if (otherOption === void 0) { otherOption = ''; }
|
|
81
81
|
if (specificTable === void 0) { specificTable = ''; }
|
|
82
82
|
if (outputFile === '') {
|
|
83
|
-
outputFile = path.join(
|
|
83
|
+
outputFile = path.join(this.OUTPUT_DIR, 'C6.mysqldump.sql');
|
|
84
84
|
}
|
|
85
85
|
if (!data && !schemas) {
|
|
86
86
|
console.warn("MysqlDump is running with --no-create-info and --no-data. Why?");
|
|
@@ -404,7 +404,7 @@ var parseSQLToTypeScript = function (sql) {
|
|
|
404
404
|
var sql = fs.readFileSync(dumpFileLocation, 'utf-8');
|
|
405
405
|
var tableData = parseSQLToTypeScript(sql);
|
|
406
406
|
// write to file
|
|
407
|
-
fs.writeFileSync(path.join(
|
|
407
|
+
fs.writeFileSync(path.join(MySQLDump.OUTPUT_DIR, 'C6.mysqldump.json'), JSON.stringify(tableData));
|
|
408
408
|
// import this file src/assets/handlebars/C6.tsx.handlebars for a mustache template
|
|
409
409
|
var c6Template = fs.readFileSync(path.resolve(__dirname, 'assets/handlebars/C6.ts.handlebars'), 'utf-8');
|
|
410
410
|
var c6TestTemplate = fs.readFileSync(path.resolve(__dirname, 'assets/handlebars/C6.test.ts.handlebars'), 'utf-8');
|