@technicity/data-service-generator 0.23.0-next.0 → 0.23.0-next.2
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/generation/generate.js +342 -172
- package/dist/runtime/IRuntime.d.ts +2 -1
- package/dist/runtime/lib/getSqlAst.js +8 -6
- package/dist/runtime/lib/shared.js +51 -11
- package/dist/runtime/lib/stringifyWhere.js +7 -0
- package/package.json +1 -1
- package/dist/src/generation/generate.d.ts +0 -21
- package/dist/src/generation/generate.js +0 -2349
- package/dist/src/index.d.ts +0 -4
- package/dist/src/index.js +0 -11
- package/dist/src/lib/CustomError.d.ts +0 -3
- package/dist/src/lib/CustomError.js +0 -10
- package/dist/src/lib/capitalizeFirstLetter.d.ts +0 -1
- package/dist/src/lib/capitalizeFirstLetter.js +0 -6
- package/dist/src/lib/getDuplicates.d.ts +0 -1
- package/dist/src/lib/getDuplicates.js +0 -9
- package/dist/src/lib/isNotNullOrUndefined.d.ts +0 -1
- package/dist/src/lib/isNotNullOrUndefined.js +0 -7
- package/dist/src/runtime/Cache.d.ts +0 -28
- package/dist/src/runtime/Cache.js +0 -142
- package/dist/src/runtime/IRuntime.d.ts +0 -209
- package/dist/src/runtime/IRuntime.js +0 -12
- package/dist/src/runtime/RuntimeMySQL.d.ts +0 -26
- package/dist/src/runtime/RuntimeMySQL.js +0 -132
- package/dist/src/runtime/RuntimeSQLite.d.ts +0 -42
- package/dist/src/runtime/RuntimeSQLite.js +0 -150
- package/dist/src/runtime/Stats.d.ts +0 -8
- package/dist/src/runtime/Stats.js +0 -31
- package/dist/src/runtime/lib/MySQL.d.ts +0 -13
- package/dist/src/runtime/lib/MySQL.js +0 -116
- package/dist/src/runtime/lib/SDKBadWhereError.d.ts +0 -4
- package/dist/src/runtime/lib/SDKBadWhereError.js +0 -10
- package/dist/src/runtime/lib/SDKNotFoundError.d.ts +0 -4
- package/dist/src/runtime/lib/SDKNotFoundError.js +0 -10
- package/dist/src/runtime/lib/addNullFallbacks.d.ts +0 -1
- package/dist/src/runtime/lib/addNullFallbacks.js +0 -32
- package/dist/src/runtime/lib/addNullFallbacks.test.d.ts +0 -1
- package/dist/src/runtime/lib/addNullFallbacks.test.js +0 -206
- package/dist/src/runtime/lib/cursor.d.ts +0 -2
- package/dist/src/runtime/lib/cursor.js +0 -10
- package/dist/src/runtime/lib/getDateTimeStringMySQL.d.ts +0 -1
- package/dist/src/runtime/lib/getDateTimeStringMySQL.js +0 -7
- package/dist/src/runtime/lib/getOrderBy.d.ts +0 -5
- package/dist/src/runtime/lib/getOrderBy.js +0 -52
- package/dist/src/runtime/lib/getSqlAst.d.ts +0 -2
- package/dist/src/runtime/lib/getSqlAst.js +0 -245
- package/dist/src/runtime/lib/getWhere.d.ts +0 -2
- package/dist/src/runtime/lib/getWhere.js +0 -20
- package/dist/src/runtime/lib/shared.d.ts +0 -13
- package/dist/src/runtime/lib/shared.js +0 -1118
- package/dist/src/runtime/lib/stringifyWhere.d.ts +0 -18
- package/dist/src/runtime/lib/stringifyWhere.js +0 -257
- package/dist/src/runtime/lib/stringifyWhere.test.d.ts +0 -1
- package/dist/src/runtime/lib/stringifyWhere.test.js +0 -245
- package/dist/src/runtime/lib/utility.d.ts +0 -5
- package/dist/src/runtime/lib/utility.js +0 -14
- package/dist/src/traverseFieldArgs.d.ts +0 -2
- package/dist/src/traverseFieldArgs.js +0 -17
- package/dist/src/traverseFieldArgs.test.d.ts +0 -1
- package/dist/src/traverseFieldArgs.test.js +0 -56
- package/dist/test/addWhereValidTrue.d.ts +0 -1
- package/dist/test/addWhereValidTrue.js +0 -39
- package/dist/test/globalSetup.d.ts +0 -13
- package/dist/test/globalSetup.js +0 -436
- package/dist/test/postgres/__generated__/sdk-ts/artifacts.d.ts +0 -8425
- package/dist/test/postgres/__generated__/sdk-ts/artifacts.js +0 -10469
- package/dist/test/postgres/__generated__/sdk-ts/index.js +0 -12162
- /package/dist/{src/runtime → runtime}/RuntimePostgreSQL.d.ts +0 -0
- /package/dist/{src/runtime → runtime}/RuntimePostgreSQL.js +0 -0
- /package/dist/{src/runtime → runtime}/lib/PostgreSQL.d.ts +0 -0
- /package/dist/{src/runtime → runtime}/lib/PostgreSQL.js +0 -0
|
@@ -30,24 +30,27 @@ exports.generate = generate;
|
|
|
30
30
|
const path = __importStar(require("node:path"));
|
|
31
31
|
const fs = __importStar(require("node:fs"));
|
|
32
32
|
const os = __importStar(require("node:os"));
|
|
33
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
33
34
|
const child_process = __importStar(require("node:child_process"));
|
|
34
35
|
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
35
36
|
const prettier = __importStar(require("prettier"));
|
|
36
37
|
const changeCase = __importStar(require("change-case"));
|
|
37
38
|
const fse = __importStar(require("fs-extra"));
|
|
38
39
|
const _ = __importStar(require("lodash/fp"));
|
|
40
|
+
const memoize_1 = __importDefault(require("lodash/memoize"));
|
|
39
41
|
const json_schema_to_typescript_1 = require("json-schema-to-typescript");
|
|
40
42
|
const getDuplicates_1 = require("../lib/getDuplicates");
|
|
41
43
|
const isNotNullOrUndefined_1 = require("../lib/isNotNullOrUndefined");
|
|
44
|
+
const pg_1 = require("pg");
|
|
42
45
|
const MySQL_1 = require("../runtime/lib/MySQL");
|
|
43
46
|
const capitalizeFirstLetter_1 = require("../lib/capitalizeFirstLetter");
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
const ctxStorage = new node_async_hooks_1.AsyncLocalStorage();
|
|
48
|
+
function getCtx() {
|
|
49
|
+
const c = ctxStorage.getStore();
|
|
50
|
+
if (!c)
|
|
51
|
+
throw new Error("generate() context missing");
|
|
52
|
+
return c;
|
|
53
|
+
}
|
|
51
54
|
const json2TsOpts = {
|
|
52
55
|
bannerComment: ""
|
|
53
56
|
};
|
|
@@ -62,159 +65,178 @@ async function generate(input) {
|
|
|
62
65
|
const specialCaseUuidColumn = input.specialCaseUuidColumn ?? true;
|
|
63
66
|
const includeMappedFields = input.includeMappedFields ?? true;
|
|
64
67
|
const supplementClientOpts = input.supplementClientOpts ?? true;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
throw new Error("No tables found");
|
|
70
|
-
}
|
|
71
|
-
if (input.tables != null) {
|
|
72
|
-
tables = tables.filter((x) => input.tables?.includes(x));
|
|
73
|
-
}
|
|
74
|
-
if (input.excludeTables != null) {
|
|
75
|
-
tables = tables.filter((x) => !input.excludeTables?.includes(x));
|
|
76
|
-
}
|
|
77
|
-
const data = await Promise.all(tables.flatMap((x) => [
|
|
78
|
-
getGetOneData(x, includeMappedFields),
|
|
79
|
-
getGetListData(x),
|
|
80
|
-
getGetListPaginatedData(x),
|
|
81
|
-
getPostOneData(x, specialCaseUuidColumn, includeMappedFields),
|
|
82
|
-
getPatchOneData(x, specialCaseUuidColumn, includeMappedFields),
|
|
83
|
-
getPatchListData(x),
|
|
84
|
-
getDeleteOneData(x),
|
|
85
|
-
getDeleteListData(x)
|
|
86
|
-
]));
|
|
87
|
-
const artifacts = await getArtifacts(tables, includeMappedFields, specialCaseUuidColumn);
|
|
88
|
-
const artifactsSource = getArtifactsSource(artifacts);
|
|
89
|
-
const sdkSource = await getSDKSource(data, specialCaseUuidColumn, supplementClientOpts, artifacts, input.outputSqliteSchema);
|
|
90
|
-
const sdkFilename = "index.ts";
|
|
91
|
-
const sourceIRuntimeFilePath = fs.existsSync(path.join(__dirname, "../runtime", "IRuntime.ts"))
|
|
92
|
-
? path.join(__dirname, "../runtime", "IRuntime.ts")
|
|
93
|
-
: path.join(__dirname, "../runtime", "IRuntime.js");
|
|
94
|
-
const IRuntimeFilename = path.basename(sourceIRuntimeFilePath);
|
|
95
|
-
const artifactsFilename = "artifacts.ts";
|
|
96
|
-
const tsConfigJSON = {
|
|
97
|
-
compilerOptions: {
|
|
98
|
-
module: "commonjs",
|
|
99
|
-
moduleResolution: "node",
|
|
100
|
-
target: "es2020",
|
|
101
|
-
declaration: true,
|
|
102
|
-
outDir: "./sdk-ts"
|
|
103
|
-
},
|
|
104
|
-
include: [sdkFilename, artifactsFilename, IRuntimeFilename]
|
|
105
|
-
};
|
|
106
|
-
const packageJSON = {
|
|
107
|
-
name: "temp",
|
|
108
|
-
version: "1.0.0",
|
|
109
|
-
// Deps need to be included so that they're inlined by ncc
|
|
110
|
-
dependencies: require("../../package.json").dependencies,
|
|
111
|
-
devDependencies: {
|
|
112
|
-
"@types/node": require("../../package.json").devDependencies["@types/node"],
|
|
113
|
-
typescript: require("../../package.json").devDependencies.typescript
|
|
114
|
-
},
|
|
115
|
-
// Not `resolutions` because npm used for install
|
|
116
|
-
overrides: {
|
|
117
|
-
// Fix for: `Cannot find type definition file for 'glob'`
|
|
118
|
-
glob: ">9.0.0"
|
|
119
|
-
}
|
|
68
|
+
const ctx = {
|
|
69
|
+
runId: node_crypto_1.default.randomUUID(),
|
|
70
|
+
dialect: input.dialect,
|
|
71
|
+
query: undefined
|
|
120
72
|
};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
fs.writeFileSync(path.join(tmpDirPath, artifactsFilename), artifactsSource);
|
|
127
|
-
fse.copyFileSync(sourceIRuntimeFilePath, path.join(tmpDirPath, IRuntimeFilename));
|
|
128
|
-
const typesDirPath = path.join(tmpDirPath, "types");
|
|
129
|
-
fse.mkdirpSync(typesDirPath);
|
|
130
|
-
fs.writeFileSync(path.join(typesDirPath, "_shared.ts"), getTypeShared());
|
|
131
|
-
for (let x of data) {
|
|
132
|
-
if (x.kind === "getOne") {
|
|
133
|
-
fs.writeFileSync(path.join(typesDirPath, x.typeFieldsName + ".ts"), x.typeFields);
|
|
134
|
-
fs.writeFileSync(path.join(typesDirPath, x.typeReturnBaseName + ".ts"), x.typeReturnBase);
|
|
73
|
+
return ctxStorage.run(ctx, async () => {
|
|
74
|
+
init(input);
|
|
75
|
+
let tables = await getTableNames();
|
|
76
|
+
if (tables.length === 0) {
|
|
77
|
+
throw new Error("No tables found");
|
|
135
78
|
}
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
fs.writeFileSync(path.join(typesDirPath, x.typeOrderByName + ".ts"), x.typeOrderBy);
|
|
79
|
+
if (input.tables != null) {
|
|
80
|
+
tables = tables.filter((x) => input.tables?.includes(x));
|
|
139
81
|
}
|
|
140
|
-
if (
|
|
141
|
-
|
|
82
|
+
if (input.excludeTables != null) {
|
|
83
|
+
tables = tables.filter((x) => !input.excludeTables?.includes(x));
|
|
142
84
|
}
|
|
143
|
-
|
|
144
|
-
|
|
85
|
+
const data = await Promise.all(tables.flatMap((x) => [
|
|
86
|
+
getGetOneData(x, includeMappedFields),
|
|
87
|
+
getGetListData(x),
|
|
88
|
+
getGetListPaginatedData(x),
|
|
89
|
+
getPostOneData(x, specialCaseUuidColumn, includeMappedFields),
|
|
90
|
+
getPatchOneData(x, specialCaseUuidColumn, includeMappedFields),
|
|
91
|
+
getPatchListData(x),
|
|
92
|
+
getDeleteOneData(x),
|
|
93
|
+
getDeleteListData(x)
|
|
94
|
+
]));
|
|
95
|
+
const artifacts = await getArtifacts(tables, includeMappedFields, specialCaseUuidColumn);
|
|
96
|
+
const artifactsSource = getArtifactsSource(artifacts);
|
|
97
|
+
const sdkSource = await getSDKSource(data, specialCaseUuidColumn, supplementClientOpts, artifacts, input.outputSqliteSchema);
|
|
98
|
+
const sdkFilename = "index.ts";
|
|
99
|
+
const sourceIRuntimeFilePath = fs.existsSync(path.join(__dirname, "../runtime", "IRuntime.ts"))
|
|
100
|
+
? path.join(__dirname, "../runtime", "IRuntime.ts")
|
|
101
|
+
: path.join(__dirname, "../runtime", "IRuntime.js");
|
|
102
|
+
const IRuntimeFilename = path.basename(sourceIRuntimeFilePath);
|
|
103
|
+
const artifactsFilename = "artifacts.ts";
|
|
104
|
+
const tsConfigJSON = {
|
|
105
|
+
compilerOptions: {
|
|
106
|
+
module: "commonjs",
|
|
107
|
+
moduleResolution: "node",
|
|
108
|
+
target: "es2020",
|
|
109
|
+
declaration: true,
|
|
110
|
+
outDir: "./sdk-ts"
|
|
111
|
+
},
|
|
112
|
+
include: [sdkFilename, artifactsFilename, IRuntimeFilename]
|
|
113
|
+
};
|
|
114
|
+
const packageJSON = {
|
|
115
|
+
name: "temp",
|
|
116
|
+
version: "1.0.0",
|
|
117
|
+
// Deps need to be included so that they're inlined by ncc
|
|
118
|
+
dependencies: require("../../package.json").dependencies,
|
|
119
|
+
devDependencies: {
|
|
120
|
+
"@types/node": require("../../package.json").devDependencies["@types/node"],
|
|
121
|
+
typescript: require("../../package.json").devDependencies.typescript
|
|
122
|
+
},
|
|
123
|
+
// Not `resolutions` because npm used for install
|
|
124
|
+
overrides: {
|
|
125
|
+
// Fix for: `Cannot find type definition file for 'glob'`
|
|
126
|
+
glob: ">9.0.0"
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const tmpDirPath = path.join(os.tmpdir(),
|
|
130
|
+
// _ because - in filename is not supported by mysql2sqlite
|
|
131
|
+
`dsg_${node_crypto_1.default.randomUUID()}`.replace(/-/g, "_"));
|
|
132
|
+
fse.mkdirpSync(tmpDirPath);
|
|
133
|
+
fs.writeFileSync(path.join(tmpDirPath, sdkFilename), sdkSource);
|
|
134
|
+
fs.writeFileSync(path.join(tmpDirPath, artifactsFilename), artifactsSource);
|
|
135
|
+
fse.copyFileSync(sourceIRuntimeFilePath, path.join(tmpDirPath, IRuntimeFilename));
|
|
136
|
+
const typesDirPath = path.join(tmpDirPath, "types");
|
|
137
|
+
fse.mkdirpSync(typesDirPath);
|
|
138
|
+
fs.writeFileSync(path.join(typesDirPath, "_shared.ts"), getTypeShared());
|
|
139
|
+
for (let x of data) {
|
|
140
|
+
if (x.kind === "getOne") {
|
|
141
|
+
fs.writeFileSync(path.join(typesDirPath, x.typeFieldsName + ".ts"), x.typeFields);
|
|
142
|
+
fs.writeFileSync(path.join(typesDirPath, x.typeReturnBaseName + ".ts"), x.typeReturnBase);
|
|
143
|
+
}
|
|
144
|
+
if (x.kind === "getList") {
|
|
145
|
+
fs.writeFileSync(path.join(typesDirPath, x.typeWhereName + ".ts"), x.typeWhere);
|
|
146
|
+
fs.writeFileSync(path.join(typesDirPath, x.typeOrderByName + ".ts"), x.typeOrderBy);
|
|
147
|
+
}
|
|
148
|
+
if (x.kind === "postOne") {
|
|
149
|
+
fs.writeFileSync(path.join(typesDirPath, x.typeDataName + ".ts"), x.typeData);
|
|
150
|
+
}
|
|
151
|
+
if (x.kind === "patchOne") {
|
|
152
|
+
fs.writeFileSync(path.join(typesDirPath, x.typeDataName + ".ts"), x.typeData);
|
|
153
|
+
}
|
|
145
154
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
155
|
+
fs.writeFileSync(path.join(typesDirPath, "index.ts"), getTypeTypesIndex(data));
|
|
156
|
+
fs.writeFileSync(path.join(tmpDirPath, "package.json"), JSON.stringify(packageJSON, null, 2));
|
|
157
|
+
fs.writeFileSync(path.join(tmpDirPath, "tsconfig.json"), JSON.stringify(tsConfigJSON, null, 2));
|
|
158
|
+
fse.copySync(__dirname, path.join(tmpDirPath, "src"));
|
|
159
|
+
const tmpBuildOutputPath = path.join(tmpDirPath, "sdk-ts");
|
|
160
|
+
const outdir = path.resolve(input.outdir);
|
|
161
|
+
const sdkOutputPath = path.join(outdir, "sdk-ts");
|
|
162
|
+
const nccVersion = "^0.33.0";
|
|
163
|
+
child_process.execSync("npm i", { cwd: tmpDirPath, stdio: "inherit" });
|
|
164
|
+
child_process.execSync(`npm_config_yes=true npx -p @vercel/ncc@${nccVersion} ncc build ./${sdkFilename} -o ${tmpBuildOutputPath} -e ./artifacts`, { cwd: tmpDirPath, stdio: "inherit" });
|
|
165
|
+
// TODO: workaround for artifacts.js not being output by ncc
|
|
166
|
+
fs.writeFileSync(path.join(tmpBuildOutputPath, "artifacts.js"), artifactsSource
|
|
167
|
+
.replace("export const artifacts: IArtifacts = ", "module.exports.artifacts = ")
|
|
168
|
+
.split("\n")
|
|
169
|
+
// Remove import
|
|
170
|
+
.slice(2)
|
|
171
|
+
.join("\n"));
|
|
172
|
+
// TODO: workaround for IRuntime.d.ts not being included
|
|
173
|
+
// copyFileSync hangs for some reason, so use writeFileSync + readFileSync instead
|
|
174
|
+
fs.writeFileSync(path.join(tmpBuildOutputPath, "IRuntime.d.ts"), fs.existsSync(path.join(__dirname, "../runtime", "IRuntime.d.ts"))
|
|
175
|
+
? fs.readFileSync(path.join(__dirname, "../runtime", "IRuntime.d.ts"), "utf-8")
|
|
176
|
+
: fs.readFileSync(sourceIRuntimeFilePath, "utf-8"));
|
|
177
|
+
if (getCtx().dialect === "mysql" && input.outputSqliteSchema) {
|
|
178
|
+
// Since mysql2sqlite outputs a malformed string if a column
|
|
179
|
+
// has the name `enum`, temporarily change the name to something else,
|
|
180
|
+
// then change it back.
|
|
181
|
+
const enumMarker = "`" + node_crypto_1.default.randomUUID() + "`";
|
|
182
|
+
const schemaMySql = Object.values(artifacts)
|
|
183
|
+
.reduce((acc, x) => {
|
|
184
|
+
let d = x.dump?.schema;
|
|
185
|
+
if (!d) {
|
|
186
|
+
return acc;
|
|
187
|
+
}
|
|
188
|
+
d = d.replace(/`enum`/g, enumMarker);
|
|
189
|
+
d += ";";
|
|
190
|
+
acc.push(d);
|
|
178
191
|
return acc;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
.
|
|
195
|
-
.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
fse.
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
fse.copySync(tmpBuildOutputPath, sdkOutputPath);
|
|
205
|
-
fse.removeSync(tmpDirPath);
|
|
192
|
+
}, [])
|
|
193
|
+
.join("\n\n");
|
|
194
|
+
const mysql2SqliteSrc = getMysql2sqliteSrc();
|
|
195
|
+
const mysql2SqlitePath = path.join(tmpDirPath, "mysql2sqlite");
|
|
196
|
+
fs.writeFileSync(mysql2SqlitePath, mysql2SqliteSrc);
|
|
197
|
+
fs.chmodSync(mysql2SqlitePath, 0o755);
|
|
198
|
+
const tmpMySqlSchemaFilename = "tmp.sql";
|
|
199
|
+
const tmpMySqlSchemaPath = path.join(tmpDirPath, tmpMySqlSchemaFilename);
|
|
200
|
+
fs.writeFileSync(tmpMySqlSchemaPath, schemaMySql);
|
|
201
|
+
let schemaSqlite = child_process
|
|
202
|
+
.execFileSync(mysql2SqlitePath, [tmpMySqlSchemaFilename], {
|
|
203
|
+
cwd: tmpDirPath
|
|
204
|
+
})
|
|
205
|
+
.toString();
|
|
206
|
+
schemaSqlite = schemaSqlite.replace(new RegExp(enumMarker, "g"), "`enum`");
|
|
207
|
+
const src = prettier.format(`module.exports = { schema: \`${schemaSqlite.replace(/`/g, "\\`")}\` }`, { parser: "babel" });
|
|
208
|
+
fs.writeFileSync(path.join(tmpBuildOutputPath, "artifacts.sqlite.js"), src);
|
|
209
|
+
}
|
|
210
|
+
if (!fs.existsSync(outdir)) {
|
|
211
|
+
fse.mkdirpSync(outdir);
|
|
212
|
+
}
|
|
213
|
+
fse.emptyDirSync(sdkOutputPath);
|
|
214
|
+
fse.copySync(tmpBuildOutputPath, sdkOutputPath);
|
|
215
|
+
fse.removeSync(tmpDirPath);
|
|
216
|
+
});
|
|
206
217
|
}
|
|
207
218
|
function init(input) {
|
|
219
|
+
const ctx = getCtx();
|
|
208
220
|
const { database, user, password, host, port, server } = input;
|
|
209
|
-
if (dialect === "mysql") {
|
|
210
|
-
|
|
221
|
+
if (ctx.dialect === "mysql") {
|
|
222
|
+
const mysql = new MySQL_1.MySQL({
|
|
211
223
|
user,
|
|
212
224
|
password,
|
|
213
225
|
host,
|
|
214
226
|
port,
|
|
215
227
|
database
|
|
216
228
|
});
|
|
217
|
-
query = mysql.query.bind(mysql);
|
|
229
|
+
ctx.query = mysql.query.bind(mysql);
|
|
230
|
+
}
|
|
231
|
+
if (ctx.dialect === "postgresql") {
|
|
232
|
+
const pool = new pg_1.Pool({
|
|
233
|
+
host: host ?? "localhost",
|
|
234
|
+
port: port ?? 5432,
|
|
235
|
+
user,
|
|
236
|
+
password,
|
|
237
|
+
database
|
|
238
|
+
});
|
|
239
|
+
ctx.query = (q, values) => pool.query(q, values ?? []).then((r) => r.rows);
|
|
218
240
|
}
|
|
219
241
|
}
|
|
220
242
|
// It's a bit awkward to put __whereNeedsProcessing, __prepareWhere on the class,
|
|
@@ -258,7 +280,7 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts,
|
|
|
258
280
|
runtime: any;
|
|
259
281
|
clientOpts: { [k: string]: any; },
|
|
260
282
|
otherOpts?: { [k: string]: any; },
|
|
261
|
-
passBeforeValueToAfterCallback
|
|
283
|
+
passBeforeValueToAfterCallback?: boolean,
|
|
262
284
|
}) {
|
|
263
285
|
let otherOpts = opts.otherOpts ?? {};
|
|
264
286
|
if (opts.clientOpts.filename === ":memory:") {
|
|
@@ -271,7 +293,7 @@ async function getSDKSource(input, specialCaseUuidColumn, supplementClientOpts,
|
|
|
271
293
|
: "otherOpts"}, artifacts);
|
|
272
294
|
this.onHandlerMap = new Map();
|
|
273
295
|
this.eventTarget = new EventTarget();
|
|
274
|
-
this.passBeforeValueToAfterCallback = opts.passBeforeValueToAfterCallback;
|
|
296
|
+
this.passBeforeValueToAfterCallback = opts.passBeforeValueToAfterCallback ?? false;
|
|
275
297
|
}
|
|
276
298
|
|
|
277
299
|
$use(middleware: TMiddleware) {
|
|
@@ -1068,7 +1090,7 @@ async function getMappedFields(table) {
|
|
|
1068
1090
|
name: "uuid",
|
|
1069
1091
|
// Replace `Id` with `Uuid`
|
|
1070
1092
|
as: x.foreignKey.slice(0, -2) + "Uuid",
|
|
1071
|
-
type: getBaseJSONType(uuidColumn.Type)
|
|
1093
|
+
type: getBaseJSONType(uuidColumn.Type, getCtx().dialect)
|
|
1072
1094
|
});
|
|
1073
1095
|
}
|
|
1074
1096
|
return out;
|
|
@@ -1489,7 +1511,7 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
|
|
|
1489
1511
|
}
|
|
1490
1512
|
return {
|
|
1491
1513
|
kind: "scalar",
|
|
1492
|
-
type: getBaseJSONType(t.Type),
|
|
1514
|
+
type: getBaseJSONType(t.Type, getCtx().dialect),
|
|
1493
1515
|
name: t.Field,
|
|
1494
1516
|
nullable,
|
|
1495
1517
|
hasDefaultValue: !!t.Default
|
|
@@ -1534,7 +1556,7 @@ async function getArtifacts(tables, includeMappedFields, specialCaseUuidColumn)
|
|
|
1534
1556
|
}, {});
|
|
1535
1557
|
return artifacts;
|
|
1536
1558
|
}
|
|
1537
|
-
const getRelationInfo =
|
|
1559
|
+
const getRelationInfo = (0, memoize_1.default)(async function getRelationInfo(table) {
|
|
1538
1560
|
const relationsManyToOne = await getRelationsManyToOne(table);
|
|
1539
1561
|
const relationsOneToMany = await getRelationsOneToMany(table);
|
|
1540
1562
|
let out = [];
|
|
@@ -1604,7 +1626,7 @@ const getRelationInfo = _.memoize(async function getRelationInfo(table) {
|
|
|
1604
1626
|
out = out.concat(relationsManyToMany);
|
|
1605
1627
|
out = _.sortBy((x) => x.table, out);
|
|
1606
1628
|
return out;
|
|
1607
|
-
});
|
|
1629
|
+
}, (table) => getCtx().runId + ":" + table);
|
|
1608
1630
|
function getRelationManyToOneFieldName(x) {
|
|
1609
1631
|
return changeCase.camelCase(x.foreignKey.replace(new RegExp(x.referencedKey + "$", "i"), ""));
|
|
1610
1632
|
}
|
|
@@ -1627,11 +1649,12 @@ async function getJunctionTables() {
|
|
|
1627
1649
|
}
|
|
1628
1650
|
// `from` relations
|
|
1629
1651
|
// https://stackoverflow.com/a/54732547
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1652
|
+
const getRelationsManyToOne = (0, memoize_1.default)(async function getRelationsManyToOne(table) {
|
|
1653
|
+
const { dialect, query } = getCtx();
|
|
1654
|
+
const tableMeta = await getTableMeta(table);
|
|
1655
|
+
let rs;
|
|
1656
|
+
if (dialect === "mysql") {
|
|
1657
|
+
const sql = `
|
|
1635
1658
|
SELECT
|
|
1636
1659
|
TABLE_SCHEMA as db,
|
|
1637
1660
|
TABLE_NAME as t1,
|
|
@@ -1646,8 +1669,18 @@ const getRelationsManyToOne = _.memoize(async function getRelationsManyToOne(tab
|
|
|
1646
1669
|
AND REFERENCED_TABLE_NAME IS NOT NULL
|
|
1647
1670
|
AND (TABLE_NAME = ?);
|
|
1648
1671
|
`;
|
|
1649
|
-
|
|
1650
|
-
|
|
1672
|
+
rs = await query(sql, [table]);
|
|
1673
|
+
}
|
|
1674
|
+
else if (dialect === "postgresql") {
|
|
1675
|
+
rs = await query(`SELECT kcu.column_name AS "t1Field", ccu.table_name AS t2, ccu.column_name AS "t2Field"
|
|
1676
|
+
FROM information_schema.key_column_usage kcu
|
|
1677
|
+
JOIN information_schema.referential_constraints rc ON kcu.constraint_name = rc.constraint_name AND kcu.table_schema = rc.constraint_schema
|
|
1678
|
+
JOIN information_schema.constraint_column_usage ccu ON rc.unique_constraint_name = ccu.constraint_name AND rc.unique_constraint_schema = ccu.table_schema
|
|
1679
|
+
WHERE kcu.table_schema = 'public' AND kcu.table_name = $1`, [table]);
|
|
1680
|
+
}
|
|
1681
|
+
else {
|
|
1682
|
+
throw new Error("Unsupported dialect: " + dialect);
|
|
1683
|
+
}
|
|
1651
1684
|
const xs = await Promise.all(_.uniqWith(_.isEqual, rs.map(async (v) => {
|
|
1652
1685
|
return {
|
|
1653
1686
|
table: table,
|
|
@@ -1658,10 +1691,13 @@ const getRelationsManyToOne = _.memoize(async function getRelationsManyToOne(tab
|
|
|
1658
1691
|
};
|
|
1659
1692
|
})));
|
|
1660
1693
|
return _.sortBy((x) => x.referencedTable, xs);
|
|
1661
|
-
});
|
|
1694
|
+
}, (table) => getCtx().runId + ":" + table);
|
|
1662
1695
|
// `to` relations
|
|
1663
|
-
const getRelationsOneToMany =
|
|
1664
|
-
const
|
|
1696
|
+
const getRelationsOneToMany = (0, memoize_1.default)(async function getRelationsOneToMany(table) {
|
|
1697
|
+
const { dialect, query } = getCtx();
|
|
1698
|
+
let rs;
|
|
1699
|
+
if (dialect === "mysql") {
|
|
1700
|
+
const sql = `
|
|
1665
1701
|
SELECT
|
|
1666
1702
|
TABLE_SCHEMA as db,
|
|
1667
1703
|
TABLE_NAME as t1,
|
|
@@ -1676,19 +1712,29 @@ const getRelationsOneToMany = _.memoize(async function getRelationsOneToMany(tab
|
|
|
1676
1712
|
AND REFERENCED_TABLE_NAME IS NOT NULL
|
|
1677
1713
|
AND (REFERENCED_TABLE_NAME = ?);
|
|
1678
1714
|
`;
|
|
1679
|
-
|
|
1715
|
+
rs = await query(sql, [table]);
|
|
1716
|
+
}
|
|
1717
|
+
else if (dialect === "postgresql") {
|
|
1718
|
+
rs = await query(`SELECT kcu.table_name AS t1, kcu.column_name AS "t1Field", ccu.column_name AS "t2Field"
|
|
1719
|
+
FROM information_schema.key_column_usage kcu
|
|
1720
|
+
JOIN information_schema.referential_constraints rc ON kcu.constraint_name = rc.constraint_name AND kcu.table_schema = rc.constraint_schema
|
|
1721
|
+
JOIN information_schema.constraint_column_usage ccu ON rc.unique_constraint_name = ccu.constraint_name AND rc.unique_constraint_schema = ccu.table_schema
|
|
1722
|
+
WHERE kcu.table_schema = 'public' AND ccu.table_name = $1`, [table]);
|
|
1723
|
+
}
|
|
1724
|
+
else {
|
|
1725
|
+
throw new Error("Unsupported dialect: " + dialect);
|
|
1726
|
+
}
|
|
1680
1727
|
const xs = await Promise.all(_.uniqWith(_.isEqual, rs.map(async (v) => {
|
|
1681
1728
|
return {
|
|
1682
1729
|
table: table,
|
|
1683
1730
|
foreignKey: v.t2Field,
|
|
1684
1731
|
referencedTable: v.t1,
|
|
1685
1732
|
referencedKey: v.t1Field,
|
|
1686
|
-
// TODO? I think this is right, since it's one-to-many, so a list
|
|
1687
1733
|
nullable: false
|
|
1688
1734
|
};
|
|
1689
1735
|
})));
|
|
1690
1736
|
return _.sortBy((x) => x.referencedKey, _.sortBy((x) => x.referencedTable, xs));
|
|
1691
|
-
});
|
|
1737
|
+
}, (table) => getCtx().runId + ":" + table);
|
|
1692
1738
|
async function getPrimaryColumn(table) {
|
|
1693
1739
|
const tableMeta = await getTableMeta(table);
|
|
1694
1740
|
const columns = tableMeta.filter((x) => x.Key === "PRI");
|
|
@@ -1698,7 +1744,7 @@ async function getPrimaryColumn(table) {
|
|
|
1698
1744
|
const column = columns[0];
|
|
1699
1745
|
return {
|
|
1700
1746
|
name: column.Field,
|
|
1701
|
-
type: getBaseJSONType(column.Type),
|
|
1747
|
+
type: getBaseJSONType(column.Type, getCtx().dialect),
|
|
1702
1748
|
nullable: column.Null === "YES"
|
|
1703
1749
|
};
|
|
1704
1750
|
}
|
|
@@ -1710,7 +1756,7 @@ async function getUniqueColumns(table, specialCaseUuidColumn) {
|
|
|
1710
1756
|
(specialCaseUuidColumn && x.Field === "uuid"))
|
|
1711
1757
|
.map((x) => ({
|
|
1712
1758
|
name: x.Field,
|
|
1713
|
-
type: getBaseJSONType(x.Type),
|
|
1759
|
+
type: getBaseJSONType(x.Type, getCtx().dialect),
|
|
1714
1760
|
nullable: x.Null === "YES"
|
|
1715
1761
|
}));
|
|
1716
1762
|
}
|
|
@@ -1726,23 +1772,116 @@ async function getUuidColumn(table) {
|
|
|
1726
1772
|
nullable: column.Null === "YES"
|
|
1727
1773
|
};
|
|
1728
1774
|
}
|
|
1729
|
-
const
|
|
1775
|
+
const getPgEnumDefinition = (0, memoize_1.default)(async function getPgEnumDefinition(udtName) {
|
|
1776
|
+
const { dialect, query } = getCtx();
|
|
1777
|
+
if (dialect !== "postgresql")
|
|
1778
|
+
return null;
|
|
1779
|
+
const rows = await query(`SELECT e.enumlabel FROM pg_enum e
|
|
1780
|
+
JOIN pg_type t ON e.enumtypid = t.oid
|
|
1781
|
+
JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid
|
|
1782
|
+
WHERE t.typname = $1 AND n.nspname = 'public'
|
|
1783
|
+
ORDER BY e.enumsortorder`, [udtName]);
|
|
1784
|
+
if (rows.length === 0)
|
|
1785
|
+
return null;
|
|
1786
|
+
const labels = rows.map((r) => String(r.enumlabel).replace(/'/g, "''"));
|
|
1787
|
+
return "enum('" + labels.join("', '") + "')";
|
|
1788
|
+
}, (udtName) => getCtx().runId + ":" + udtName);
|
|
1789
|
+
const getTableMeta = (0, memoize_1.default)(async function getTableMeta(table) {
|
|
1790
|
+
const { dialect, query } = getCtx();
|
|
1730
1791
|
if (dialect === "mysql") {
|
|
1731
1792
|
return query("DESCRIBE ??", [table]).then((xs) => _.sortBy((x) => x.Field, xs));
|
|
1732
1793
|
}
|
|
1794
|
+
if (dialect === "postgresql") {
|
|
1795
|
+
const columns = await query(`SELECT column_name AS "Field", data_type, udt_name, character_maximum_length AS char_max, is_nullable, column_default AS "Default"
|
|
1796
|
+
FROM information_schema.columns
|
|
1797
|
+
WHERE table_schema = 'public' AND table_name = $1
|
|
1798
|
+
ORDER BY ordinal_position`, [table]);
|
|
1799
|
+
const keyInfo = await query(`SELECT a.attname AS col, 'PRI' AS key_type
|
|
1800
|
+
FROM pg_index i
|
|
1801
|
+
JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) AND NOT a.attisdropped AND a.attnum > 0
|
|
1802
|
+
JOIN pg_class c ON c.oid = i.indrelid
|
|
1803
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
1804
|
+
WHERE n.nspname = 'public' AND c.relname = $1 AND i.indisprimary
|
|
1805
|
+
UNION ALL
|
|
1806
|
+
SELECT kcu.column_name AS col, 'UNI' AS key_type
|
|
1807
|
+
FROM information_schema.table_constraints tc
|
|
1808
|
+
JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
|
|
1809
|
+
WHERE tc.table_schema = 'public' AND tc.table_name = $1 AND tc.constraint_type = 'UNIQUE'
|
|
1810
|
+
UNION ALL
|
|
1811
|
+
SELECT kcu.column_name AS col, 'MUL' AS key_type
|
|
1812
|
+
FROM information_schema.table_constraints tc
|
|
1813
|
+
JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name AND tc.table_schema = kcu.table_schema
|
|
1814
|
+
WHERE tc.table_schema = 'public' AND tc.table_name = $1 AND tc.constraint_type = 'FOREIGN KEY'`, [table]);
|
|
1815
|
+
const keyMap = new Map();
|
|
1816
|
+
for (const k of keyInfo) {
|
|
1817
|
+
if (!keyMap.has(k.col) || k.key_type === "PRI")
|
|
1818
|
+
keyMap.set(k.col, k.key_type);
|
|
1819
|
+
}
|
|
1820
|
+
const udtNames = [
|
|
1821
|
+
...new Set(columns
|
|
1822
|
+
.filter((c) => c.data_type === "USER-DEFINED" && c.udt_name != null)
|
|
1823
|
+
.map((c) => c.udt_name))
|
|
1824
|
+
];
|
|
1825
|
+
const enumDefs = await Promise.all(udtNames.map((udt) => getPgEnumDefinition(udt)));
|
|
1826
|
+
const enumMap = new Map(udtNames.map((udt, i) => [udt, enumDefs[i] ?? "varchar(255)"]));
|
|
1827
|
+
return columns.map((c) => {
|
|
1828
|
+
let type;
|
|
1829
|
+
if (c.data_type === "USER-DEFINED" && c.udt_name != null) {
|
|
1830
|
+
type = enumMap.get(c.udt_name) ?? "character varying(255)";
|
|
1831
|
+
}
|
|
1832
|
+
else {
|
|
1833
|
+
type = c.data_type;
|
|
1834
|
+
if ((c.data_type === "character varying" || c.data_type === "character") &&
|
|
1835
|
+
c.char_max != null) {
|
|
1836
|
+
type += "(" + c.char_max + ")";
|
|
1837
|
+
}
|
|
1838
|
+
}
|
|
1839
|
+
return {
|
|
1840
|
+
Field: c.Field,
|
|
1841
|
+
Type: type,
|
|
1842
|
+
Null: c.is_nullable === "YES" ? "YES" : "NO",
|
|
1843
|
+
Key: keyMap.get(c.Field) ?? "",
|
|
1844
|
+
Default: c.Default ?? ""
|
|
1845
|
+
};
|
|
1846
|
+
});
|
|
1847
|
+
}
|
|
1733
1848
|
throw new Error("Unsupported dialect: " + dialect);
|
|
1734
|
-
});
|
|
1735
|
-
function getShowCreateTable(table) {
|
|
1849
|
+
}, (table) => getCtx().runId + ":" + table);
|
|
1850
|
+
async function getShowCreateTable(table) {
|
|
1851
|
+
const { dialect, query } = getCtx();
|
|
1736
1852
|
if (dialect === "mysql") {
|
|
1737
1853
|
return query("SHOW CREATE TABLE ??", [table]).then((xs) => xs[0]["Create Table"]
|
|
1738
1854
|
// https://github.com/bradzacher/mysqldump/blob/66839a57e572a07c046b0ba98753f30a7026cbd8/src/getSchemaDump.ts#L65
|
|
1739
1855
|
.replace(/AUTO_INCREMENT\s*=\s*\d+ /g, ""));
|
|
1740
1856
|
}
|
|
1857
|
+
if (dialect === "postgresql") {
|
|
1858
|
+
const [tableMeta, relations] = await Promise.all([
|
|
1859
|
+
getTableMeta(table),
|
|
1860
|
+
getRelationsManyToOne(table)
|
|
1861
|
+
]);
|
|
1862
|
+
const refByFk = new Map(relations.map((r) => [r.foreignKey, r]));
|
|
1863
|
+
const columnDefs = tableMeta.map((c) => {
|
|
1864
|
+
let def = `"${c.Field.replace(/"/g, '""')}" ${c.Type} ${c.Null === "YES" ? "NULL" : "NOT NULL"}`;
|
|
1865
|
+
if (c.Default != null && c.Default !== "") {
|
|
1866
|
+
def += ` DEFAULT ${c.Default}`;
|
|
1867
|
+
}
|
|
1868
|
+
if (c.Key === "PRI")
|
|
1869
|
+
def += " PRIMARY KEY";
|
|
1870
|
+
if (c.Key === "UNI")
|
|
1871
|
+
def += " UNIQUE";
|
|
1872
|
+
const ref = refByFk.get(c.Field);
|
|
1873
|
+
if (ref != null) {
|
|
1874
|
+
def += ` REFERENCES "${ref.referencedTable.replace(/"/g, '""')}" ("${ref.referencedKey.replace(/"/g, '""')}")`;
|
|
1875
|
+
}
|
|
1876
|
+
return def;
|
|
1877
|
+
});
|
|
1878
|
+
return `CREATE TABLE "${table.replace(/"/g, '""')}" (\n ${columnDefs.join(",\n ")}\n)`;
|
|
1879
|
+
}
|
|
1741
1880
|
return Promise.resolve(null);
|
|
1742
1881
|
}
|
|
1743
1882
|
function getJSONSchemaObjProperties(tableMeta) {
|
|
1744
1883
|
return tableMeta.reduce((acc, m) => {
|
|
1745
|
-
const baseType = getBaseJSONType(m.Type);
|
|
1884
|
+
const baseType = getBaseJSONType(m.Type, getCtx().dialect);
|
|
1746
1885
|
const format = getPropertyFormat(m.Type);
|
|
1747
1886
|
const nullable = m.Null === "YES";
|
|
1748
1887
|
const isEnum = m.Type.startsWith("enum");
|
|
@@ -1778,7 +1917,29 @@ function getJSONTypes(baseType, nullable) {
|
|
|
1778
1917
|
return baseType;
|
|
1779
1918
|
}
|
|
1780
1919
|
// https://github.com/mysqljs/mysql#type-casting
|
|
1781
|
-
function getBaseJSONType(sqlType) {
|
|
1920
|
+
function getBaseJSONType(sqlType, dialect) {
|
|
1921
|
+
if (dialect === "postgresql") {
|
|
1922
|
+
if (sqlType === "boolean" || sqlType === "bool")
|
|
1923
|
+
return "boolean";
|
|
1924
|
+
if (["smallint", "int2", "integer", "int4", "bigint", "int8"].includes(sqlType)) {
|
|
1925
|
+
return "integer";
|
|
1926
|
+
}
|
|
1927
|
+
if (["real", "float4", "double precision", "float8"].includes(sqlType) ||
|
|
1928
|
+
sqlType.startsWith("numeric") ||
|
|
1929
|
+
sqlType.startsWith("decimal")) {
|
|
1930
|
+
return "number";
|
|
1931
|
+
}
|
|
1932
|
+
if (["text", "uuid", "json", "jsonb"].includes(sqlType) ||
|
|
1933
|
+
sqlType === "date" ||
|
|
1934
|
+
sqlType === "time" ||
|
|
1935
|
+
sqlType.startsWith("timestamp") ||
|
|
1936
|
+
sqlType.startsWith("character varying") ||
|
|
1937
|
+
sqlType.startsWith("character") ||
|
|
1938
|
+
sqlType.startsWith("enum")) {
|
|
1939
|
+
return "string";
|
|
1940
|
+
}
|
|
1941
|
+
throw new Error("Unable to map to JSON type: " + sqlType);
|
|
1942
|
+
}
|
|
1782
1943
|
if (
|
|
1783
1944
|
// TODO?
|
|
1784
1945
|
sqlType === "tinyint(1)" ||
|
|
@@ -1863,7 +2024,10 @@ function getPropertyEnum(sqlType) {
|
|
|
1863
2024
|
return c;
|
|
1864
2025
|
}
|
|
1865
2026
|
function getPropertyFormat(sqlType) {
|
|
1866
|
-
if (sqlType === "datetime" ||
|
|
2027
|
+
if (sqlType === "datetime" ||
|
|
2028
|
+
sqlType === "datetime2" ||
|
|
2029
|
+
sqlType === "timestamp" ||
|
|
2030
|
+
sqlType.startsWith("timestamp")) {
|
|
1867
2031
|
// TODO: not sure this is correct for `timestamp`
|
|
1868
2032
|
return "date-time";
|
|
1869
2033
|
}
|
|
@@ -1882,9 +2046,15 @@ function getPropertyFormat(sqlType) {
|
|
|
1882
2046
|
return undefined;
|
|
1883
2047
|
}
|
|
1884
2048
|
async function getTableNames() {
|
|
2049
|
+
const { dialect, query } = getCtx();
|
|
1885
2050
|
if (dialect === "mysql") {
|
|
1886
2051
|
return query("SHOW TABLES").then((xs) => xs.flatMap((x) => Object.values(x)).sort());
|
|
1887
2052
|
}
|
|
2053
|
+
if (dialect === "postgresql") {
|
|
2054
|
+
return query(`SELECT table_name FROM information_schema.tables
|
|
2055
|
+
WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
|
|
2056
|
+
ORDER BY table_name`).then((rows) => rows.map((r) => r.table_name));
|
|
2057
|
+
}
|
|
1888
2058
|
throw new Error("Unsupported dialect: " + dialect);
|
|
1889
2059
|
}
|
|
1890
2060
|
function getMysql2sqliteSrc() {
|