@andymic/pigeon 1.2.0 → 1.3.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/bin/pigeon.js +11 -7
- package/package.json +3 -3
- package/src/cli.js +14 -9
- package/src/config.js +5 -13
- package/src/index.js +270 -185
- package/src/utils.js +21 -7
package/bin/pigeon.js
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/*
|
|
3
|
-
* Copyright (c)
|
|
3
|
+
* Copyright (c) 2025 Andreas Michael
|
|
4
4
|
* This software is under the Apache 2.0 License
|
|
5
5
|
*/
|
|
6
6
|
import { cli, run } from "../src/cli.js";
|
|
7
|
+
import { PigeonError } from "../src/index.js";
|
|
7
8
|
try {
|
|
8
|
-
const
|
|
9
|
-
if (
|
|
10
|
-
|
|
9
|
+
const result = await run(cli.flags);
|
|
10
|
+
if (result instanceof PigeonError) {
|
|
11
|
+
if (result.message !== "")
|
|
12
|
+
console.log(result.message);
|
|
13
|
+
console.error(result.error);
|
|
14
|
+
process.exit(result.exitCode);
|
|
11
15
|
}
|
|
12
|
-
|
|
13
|
-
console.
|
|
16
|
+
else {
|
|
17
|
+
console.log("Generation Completed Successfully");
|
|
18
|
+
process.exit(0);
|
|
14
19
|
}
|
|
15
|
-
process.exit(exitCode);
|
|
16
20
|
}
|
|
17
21
|
catch (error) {
|
|
18
22
|
console.error(error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andymic/pigeon",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"author": "Andreas Michael <ateasm03@gmail.com>",
|
|
5
5
|
"description": "Pigeon is a TypeScript-based tool for generating TypeScript classes and methods from PostgreSQL database schemas.",
|
|
6
6
|
"keywords": [
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"meow": "^13.2.0",
|
|
35
|
-
"pg": "^8.
|
|
35
|
+
"pg": "^8.15.6",
|
|
36
36
|
"prompt-sync": "^4.2.0"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "40d793e0267631471bde05ffddc53ba908e07512"
|
|
39
39
|
}
|
package/src/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) 2025 Andreas Michael
|
|
3
3
|
* This software is under the Apache 2.0 License
|
|
4
4
|
*/
|
|
5
5
|
import meow from "meow";
|
|
6
6
|
import { createConfig } from "./config.js";
|
|
7
|
+
import { Database, deleteDir, guided, PigeonError, queryDB, runGeneration } from "./index.js";
|
|
7
8
|
import * as path from "node:path";
|
|
8
|
-
import { deleteDir, guided, runPigeon } from "./index.js";
|
|
9
9
|
import fs from "node:fs";
|
|
10
10
|
export const cli = meow(`
|
|
11
11
|
Usage
|
|
@@ -69,14 +69,19 @@ export async function run(flags) {
|
|
|
69
69
|
deleteDir(flags.output);
|
|
70
70
|
if (flags.guided) {
|
|
71
71
|
const params = guided();
|
|
72
|
-
|
|
72
|
+
const database = new Database(params.host, String(params.port), params.db, params.user, params.pass);
|
|
73
|
+
const result = await queryDB(database);
|
|
74
|
+
if (result instanceof PigeonError)
|
|
75
|
+
return result;
|
|
73
76
|
}
|
|
74
77
|
if (!fs.existsSync(path.join(process.cwd(), ".pigeon.json")))
|
|
75
|
-
return
|
|
76
|
-
exitCode: 1,
|
|
77
|
-
message: null,
|
|
78
|
-
error: new Error("The configuration file does not exist. Generate one using the \"pigeon --init\" command"),
|
|
79
|
-
};
|
|
78
|
+
return new PigeonError(1, "", new Error("The configuration file does not exist. Generate one using the \"pigeon --init\" command"));
|
|
80
79
|
const params = JSON.parse(fs.readFileSync(flags.config).toString());
|
|
81
|
-
|
|
80
|
+
const database = new Database(params.host, params.port, params.database, params.username, params.password);
|
|
81
|
+
const queryResult = await queryDB(database);
|
|
82
|
+
if (queryResult instanceof PigeonError)
|
|
83
|
+
return queryResult;
|
|
84
|
+
const generationResult = runGeneration(flags.output, database, queryResult.tables, queryResult.enums);
|
|
85
|
+
if (generationResult instanceof PigeonError)
|
|
86
|
+
return generationResult;
|
|
82
87
|
}
|
package/src/config.js
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) 2025 Andreas Michael
|
|
3
3
|
* This software is under the Apache 2.0 License
|
|
4
4
|
*/
|
|
5
|
+
import { PigeonError } from "./index.js";
|
|
5
6
|
import fs from "node:fs";
|
|
6
7
|
import * as path from "node:path";
|
|
7
8
|
export function createConfig(dir) {
|
|
8
|
-
if (fs.existsSync(path.join(dir, ".pigeon.json")))
|
|
9
|
-
return
|
|
10
|
-
exitCode: 1,
|
|
11
|
-
message: null,
|
|
12
|
-
error: new Error("A Pigeon configuration file already exists."),
|
|
13
|
-
};
|
|
14
|
-
}
|
|
9
|
+
if (fs.existsSync(path.join(dir, ".pigeon.json")))
|
|
10
|
+
return new PigeonError(1, "", new Error("A Pigeon configuration file already exists."));
|
|
15
11
|
fs.writeFileSync(path.join(dir, ".pigeon.json"), "{\n\t\"host\": \"localhost\",\n\t\"port\": 5432,\n\t\"database\": \"postgres\",\n\t\"username\": \"postgres\",\n\t\"password\": \"xxx\"\n}");
|
|
16
|
-
return
|
|
17
|
-
exitCode: 0,
|
|
18
|
-
message: "Configuration file successfully created!",
|
|
19
|
-
error: null,
|
|
20
|
-
};
|
|
12
|
+
return new PigeonError(0, "Configuration file successfully created!", null);
|
|
21
13
|
}
|
package/src/index.js
CHANGED
|
@@ -1,33 +1,110 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) 2025 Andreas Michael
|
|
3
3
|
* This software is under the Apache 2.0 License
|
|
4
4
|
*/
|
|
5
|
-
import { arrayMaker, getCombinations, nameBeautifier, queryMaker, runQuery, singularize, sleep, tabsInserter } from "./utils.js";
|
|
6
|
-
import
|
|
5
|
+
import { arrayMaker, consoleMessage, getCombinations, getType, nameBeautifier, queryMaker, runQuery, singularize, sleep, tabsInserter } from "./utils.js";
|
|
6
|
+
import prompt from "prompt-sync";
|
|
7
7
|
import fs from "node:fs";
|
|
8
8
|
import * as path from "node:path";
|
|
9
|
-
|
|
9
|
+
export class PigeonError {
|
|
10
|
+
exitCode;
|
|
11
|
+
message;
|
|
12
|
+
error;
|
|
13
|
+
constructor(exitCode, message, error) {
|
|
14
|
+
this.exitCode = exitCode;
|
|
15
|
+
this.message = message;
|
|
16
|
+
this.error = error;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class Database {
|
|
20
|
+
host;
|
|
21
|
+
port;
|
|
22
|
+
db;
|
|
23
|
+
user;
|
|
24
|
+
pass;
|
|
25
|
+
constructor(host, port, db, user, pass) {
|
|
26
|
+
this.host = host;
|
|
27
|
+
this.port = port;
|
|
28
|
+
this.db = db;
|
|
29
|
+
this.user = user;
|
|
30
|
+
this.pass = pass;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
class Table {
|
|
34
|
+
table_schema;
|
|
35
|
+
table_name;
|
|
36
|
+
columns = [];
|
|
37
|
+
primaryKey;
|
|
38
|
+
foreignKeys;
|
|
39
|
+
unique;
|
|
40
|
+
constructor(table_schema, table_name, columns, primaryKey, foreignKeys, unique) {
|
|
41
|
+
this.table_schema = table_schema;
|
|
42
|
+
this.table_name = table_name;
|
|
43
|
+
this.columns = columns;
|
|
44
|
+
this.primaryKey = primaryKey;
|
|
45
|
+
this.foreignKeys = foreignKeys;
|
|
46
|
+
this.unique = unique;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
class Enum {
|
|
50
|
+
name;
|
|
51
|
+
labels;
|
|
52
|
+
constructor(name, labels) {
|
|
53
|
+
this.name = name;
|
|
54
|
+
this.labels = labels;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
class ColumnQueryRow {
|
|
58
|
+
column_name;
|
|
59
|
+
ordinal_position;
|
|
60
|
+
column_default;
|
|
61
|
+
is_nullable;
|
|
62
|
+
data_type;
|
|
63
|
+
udt_name;
|
|
64
|
+
is_identity;
|
|
65
|
+
identity_generation;
|
|
66
|
+
constructor(column_name, ordinal_position, column_default, is_nullable, data_type, udt_name, is_identity, identity_generation) {
|
|
67
|
+
this.column_name = column_name;
|
|
68
|
+
this.ordinal_position = ordinal_position;
|
|
69
|
+
this.column_default = column_default;
|
|
70
|
+
this.is_nullable = is_nullable;
|
|
71
|
+
this.data_type = data_type;
|
|
72
|
+
this.udt_name = udt_name;
|
|
73
|
+
this.is_identity = is_identity;
|
|
74
|
+
this.identity_generation = identity_generation;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
class PrimaryKeyQueryRow {
|
|
78
|
+
column_name;
|
|
79
|
+
constructor(column_name) {
|
|
80
|
+
this.column_name = column_name;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
class ForeignKeyQueryRow {
|
|
84
|
+
local_table;
|
|
85
|
+
local_column;
|
|
86
|
+
foreign_schema;
|
|
87
|
+
foreign_table;
|
|
88
|
+
foreign_column;
|
|
89
|
+
constructor(local_table, local_column, foreign_schema, foreign_table, foreign_column) {
|
|
90
|
+
this.local_table = local_table;
|
|
91
|
+
this.local_column = local_column;
|
|
92
|
+
this.foreign_schema = foreign_schema;
|
|
93
|
+
this.foreign_table = foreign_table;
|
|
94
|
+
this.foreign_column = foreign_column;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
class UniqueQueryRow {
|
|
98
|
+
columns;
|
|
99
|
+
constructor(columns) {
|
|
100
|
+
this.columns = columns;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
10
103
|
function createDir(dirPath) {
|
|
11
104
|
if (fs.existsSync(dirPath))
|
|
12
|
-
return
|
|
13
|
-
exitCode: 1,
|
|
14
|
-
message: null,
|
|
15
|
-
error: new Error("Generation directory already exists. Add the --force flag if you want to overwrite it.")
|
|
16
|
-
};
|
|
105
|
+
return new PigeonError(1, "", new Error("Generation directory already exists. Add the --force flag if you want to overwrite it."));
|
|
17
106
|
else
|
|
18
|
-
fs.
|
|
19
|
-
if (err)
|
|
20
|
-
return {
|
|
21
|
-
exitCode: 1,
|
|
22
|
-
message: null,
|
|
23
|
-
error: err
|
|
24
|
-
};
|
|
25
|
-
});
|
|
26
|
-
return {
|
|
27
|
-
exitCode: 0,
|
|
28
|
-
message: null,
|
|
29
|
-
error: null
|
|
30
|
-
};
|
|
107
|
+
fs.mkdirSync(dirPath);
|
|
31
108
|
}
|
|
32
109
|
export function deleteDir(dirPath) {
|
|
33
110
|
if (fs.existsSync(dirPath)) {
|
|
@@ -75,94 +152,65 @@ export function guided() {
|
|
|
75
152
|
const pass = input("Database Password: ");
|
|
76
153
|
return { host, port, db, user, pass };
|
|
77
154
|
}
|
|
78
|
-
export async function
|
|
79
|
-
const dirResult = createDir(dir);
|
|
80
|
-
if (dirResult.exitCode !== 0)
|
|
81
|
-
return dirResult;
|
|
155
|
+
export async function queryDB(db) {
|
|
82
156
|
const tableQuery = await runQuery(`SELECT table_schema, table_name
|
|
83
157
|
FROM information_schema.tables
|
|
84
158
|
WHERE table_type = 'BASE TABLE'
|
|
85
159
|
AND table_schema NOT IN
|
|
86
|
-
('pg_catalog', 'information_schema');`, [],
|
|
160
|
+
('pg_catalog', 'information_schema');`, [], db);
|
|
87
161
|
if (typeof tableQuery === "undefined")
|
|
88
|
-
return
|
|
89
|
-
exitCode: 1,
|
|
90
|
-
message: null,
|
|
91
|
-
error: new Error("An SQL error has occurred.")
|
|
92
|
-
};
|
|
93
|
-
let schemas = [];
|
|
94
|
-
for (const table of tableQuery.rows) {
|
|
95
|
-
if (schemas.includes(table.table_schema))
|
|
96
|
-
continue;
|
|
97
|
-
schemas.push(table.table_schema);
|
|
98
|
-
}
|
|
99
|
-
for (const schema of schemas)
|
|
100
|
-
createDir(path.join(dir, schema));
|
|
162
|
+
return new PigeonError(1, "", new Error("An SQL error has occurred."));
|
|
101
163
|
const customTypeQuery = await runQuery(`SELECT t.oid, t.typname
|
|
102
164
|
FROM pg_type t
|
|
103
165
|
WHERE (t.typrelid = 0 OR t.typrelid IN (SELECT oid FROM pg_class WHERE relkind = 'c'))
|
|
104
166
|
AND t.typelem = 0
|
|
105
167
|
AND t.typnamespace NOT IN
|
|
106
|
-
(SELECT oid FROM pg_namespace WHERE nspname IN ('pg_catalog', 'information_schema'));`, [],
|
|
168
|
+
(SELECT oid FROM pg_namespace WHERE nspname IN ('pg_catalog', 'information_schema'));`, [], db);
|
|
107
169
|
if (typeof customTypeQuery === "undefined")
|
|
108
|
-
return
|
|
109
|
-
|
|
110
|
-
message: null,
|
|
111
|
-
error: new Error("An SQL error has occurred.")
|
|
112
|
-
};
|
|
113
|
-
const customTypes = [];
|
|
170
|
+
return new PigeonError(1, "", new Error("An SQL error has occurred."));
|
|
171
|
+
const enums = [];
|
|
114
172
|
for (const type of customTypeQuery.rows) {
|
|
115
173
|
const enumQuery = await runQuery(`SELECT enumlabel
|
|
116
174
|
FROM pg_enum
|
|
117
175
|
WHERE enumtypid = $1::oid
|
|
118
|
-
ORDER BY enumsortorder;`, [type.oid],
|
|
176
|
+
ORDER BY enumsortorder;`, [type.oid], db);
|
|
119
177
|
if (typeof enumQuery === "undefined")
|
|
120
|
-
return
|
|
121
|
-
exitCode: 1,
|
|
122
|
-
message: null,
|
|
123
|
-
error: new Error("An SQL error has occurred.")
|
|
124
|
-
};
|
|
178
|
+
return new PigeonError(1, "", new Error("An SQL error has occurred."));
|
|
125
179
|
let labels = [];
|
|
126
180
|
for (const enumLabel of enumQuery.rows)
|
|
127
181
|
labels.push(enumLabel.enumlabel);
|
|
128
|
-
|
|
129
|
-
name: type.typname,
|
|
130
|
-
labels: labels
|
|
131
|
-
});
|
|
182
|
+
enums.push(new Enum(type.typname, labels));
|
|
132
183
|
}
|
|
184
|
+
const tables = [];
|
|
133
185
|
for (const table of tableQuery.rows) {
|
|
134
|
-
const columnQuery = await runQuery(`SELECT
|
|
186
|
+
const columnQuery = await runQuery(`SELECT column_name,
|
|
187
|
+
ordinal_position,
|
|
188
|
+
column_default,
|
|
189
|
+
is_nullable,
|
|
190
|
+
data_type,
|
|
191
|
+
udt_name,
|
|
192
|
+
is_identity,
|
|
193
|
+
identity_generation
|
|
135
194
|
FROM information_schema.columns
|
|
136
195
|
WHERE table_name = $1::varchar
|
|
137
|
-
AND table_schema = $2::varchar;`, [table.table_name, table.table_schema],
|
|
196
|
+
AND table_schema = $2::varchar;`, [table.table_name, table.table_schema], db);
|
|
138
197
|
if (typeof columnQuery === "undefined")
|
|
139
|
-
return
|
|
140
|
-
exitCode: 1,
|
|
141
|
-
message: null,
|
|
142
|
-
error: new Error("An SQL error has occurred.")
|
|
143
|
-
};
|
|
198
|
+
return new PigeonError(1, "", new Error("An SQL error has occurred."));
|
|
144
199
|
const pKeyQuery = await runQuery(`SELECT ku.column_name
|
|
145
200
|
FROM information_schema.table_constraints AS tc
|
|
146
201
|
INNER JOIN information_schema.key_column_usage AS ku
|
|
147
202
|
ON tc.constraint_type = 'PRIMARY KEY'
|
|
148
203
|
AND tc.constraint_name = ku.constraint_name
|
|
149
204
|
WHERE tc.table_schema = $1::varchar
|
|
150
|
-
AND tc.table_name = $2::varchar;`, [table.table_schema, table.table_name],
|
|
205
|
+
AND tc.table_name = $2::varchar;`, [table.table_schema, table.table_name], db);
|
|
151
206
|
if (typeof pKeyQuery === "undefined")
|
|
152
|
-
return
|
|
153
|
-
exitCode: 1,
|
|
154
|
-
message: null,
|
|
155
|
-
error: new Error("An SQL error has occurred.")
|
|
156
|
-
};
|
|
157
|
-
let pKeys = [];
|
|
158
|
-
for (let pKey of pKeyQuery.rows)
|
|
159
|
-
pKeys.push(pKey.column_name);
|
|
207
|
+
return new PigeonError(1, "", new Error("An SQL error has occurred."));
|
|
160
208
|
const fKeyQuery = await runQuery(`SELECT kcu1.table_schema AS local_schema,
|
|
161
209
|
kcu1.table_name AS local_table,
|
|
162
210
|
kcu1.column_name AS local_column,
|
|
163
|
-
kcu2.table_schema AS
|
|
164
|
-
kcu2.table_name AS
|
|
165
|
-
kcu2.column_name AS
|
|
211
|
+
kcu2.table_schema AS foreign_schema,
|
|
212
|
+
kcu2.table_name AS foreign_table,
|
|
213
|
+
kcu2.column_name AS foreign_column
|
|
166
214
|
FROM information_schema.referential_constraints AS rc
|
|
167
215
|
INNER JOIN information_schema.key_column_usage AS kcu1
|
|
168
216
|
ON kcu1.constraint_catalog = rc.constraint_catalog
|
|
@@ -175,13 +223,9 @@ export async function runPigeon(dir, host, port, db, user, pass) {
|
|
|
175
223
|
AND kcu2.constraint_name = rc.unique_constraint_name
|
|
176
224
|
AND kcu2.ordinal_position = kcu1.ordinal_position
|
|
177
225
|
WHERE kcu1.table_schema = $1::varchar
|
|
178
|
-
AND kcu1.table_name = $2::varchar;`, [table.table_schema, table.table_name],
|
|
226
|
+
AND kcu1.table_name = $2::varchar;`, [table.table_schema, table.table_name], db);
|
|
179
227
|
if (typeof fKeyQuery === "undefined")
|
|
180
|
-
return
|
|
181
|
-
exitCode: 1,
|
|
182
|
-
message: null,
|
|
183
|
-
error: new Error("An SQL error has occurred.")
|
|
184
|
-
};
|
|
228
|
+
return new PigeonError(1, "", new Error("An SQL error has occurred."));
|
|
185
229
|
const uniqueQuery = await runQuery(`SELECT array_agg(a.attname) AS columns
|
|
186
230
|
FROM pg_constraint AS c
|
|
187
231
|
CROSS JOIN LATERAL unnest(c.conkey) AS k(c)
|
|
@@ -190,61 +234,88 @@ export async function runPigeon(dir, host, port, db, user, pass) {
|
|
|
190
234
|
AND c.connamespace = $1::regnamespace
|
|
191
235
|
AND c.conrelid = $2::regclass
|
|
192
236
|
GROUP BY c.conrelid;
|
|
193
|
-
`, [table.table_schema, table.table_name],
|
|
237
|
+
`, [table.table_schema, table.table_name], db);
|
|
194
238
|
if (typeof uniqueQuery === "undefined")
|
|
195
|
-
return
|
|
196
|
-
exitCode: 1,
|
|
197
|
-
message: null,
|
|
198
|
-
error: new Error("An SQL error has occurred.")
|
|
199
|
-
};
|
|
239
|
+
return new PigeonError(1, "", new Error("An SQL error has occurred."));
|
|
200
240
|
let uniques = [];
|
|
201
241
|
if (uniqueQuery.rowCount > 0)
|
|
202
242
|
uniques = uniqueQuery.rows[0].columns.slice(1, -1).split(",");
|
|
203
|
-
|
|
243
|
+
tables.push(new Table(table.table_schema, table.table_name, columnQuery.rows, pKeyQuery.rows[0], fKeyQuery.rows, { columns: uniques }));
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
tables: tables,
|
|
247
|
+
enums: enums
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
export function runGeneration(dir, db, tables, enums) {
|
|
251
|
+
if (!tables)
|
|
252
|
+
return new PigeonError(1, "", new Error("No tables were found."));
|
|
253
|
+
const dirResult = createDir(dir);
|
|
254
|
+
if (dirResult instanceof PigeonError)
|
|
255
|
+
return dirResult;
|
|
256
|
+
let schemas = [];
|
|
257
|
+
for (const table of tables) {
|
|
258
|
+
if (schemas.includes(table.table_schema))
|
|
259
|
+
continue;
|
|
260
|
+
schemas.push(table.table_schema);
|
|
261
|
+
}
|
|
262
|
+
for (const schema of schemas) {
|
|
263
|
+
const dirResult = createDir(path.join(dir, schema));
|
|
264
|
+
if (dirResult instanceof PigeonError)
|
|
265
|
+
return dirResult;
|
|
266
|
+
}
|
|
267
|
+
for (const table of tables) {
|
|
268
|
+
let ts = clientMaker(0, db);
|
|
204
269
|
ts += "\n\n";
|
|
205
|
-
|
|
206
|
-
for (const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
270
|
+
if (enums) {
|
|
271
|
+
for (const cEnum of enums) {
|
|
272
|
+
for (const column of table.columns) {
|
|
273
|
+
if (cEnum.name === column.udt_name) {
|
|
274
|
+
const enumName = nameBeautifier(cEnum.name).replaceAll(" ", "");
|
|
275
|
+
ts += "/**\n An Enum representing the " + nameBeautifier(cEnum.name).toLowerCase() + ".\n * @readonly\n * @enum {string}\n */\n";
|
|
276
|
+
ts += "class " + enumName + " {\n";
|
|
277
|
+
let longestLabel = 0;
|
|
278
|
+
for (const label of cEnum.labels)
|
|
279
|
+
if (label.length > longestLabel)
|
|
280
|
+
longestLabel = label.length;
|
|
281
|
+
for (const label of cEnum.labels)
|
|
282
|
+
ts += "\tstatic " + label.toUpperCase().replaceAll(/[^a-zA-Z0-9$]/g, "_") + ": string" + " ".repeat(longestLabel - label.length + 1) + "= \"" + label + "\";\n";
|
|
283
|
+
ts += "}\n\n";
|
|
284
|
+
}
|
|
218
285
|
}
|
|
219
286
|
}
|
|
220
287
|
}
|
|
221
|
-
ts += createClass(table.table_name,
|
|
288
|
+
ts += createClass(table.table_name, table.columns, table.primaryKey?.column_name, table.foreignKeys);
|
|
222
289
|
ts += "\n\n";
|
|
223
|
-
ts += createGetAll(table.table_schema, table.table_name,
|
|
290
|
+
ts += createGetAll(table.table_schema, table.table_name, table.columns);
|
|
224
291
|
ts += "\n\n";
|
|
225
|
-
let keys = [
|
|
226
|
-
|
|
227
|
-
keys.push(
|
|
228
|
-
|
|
292
|
+
let keys = [];
|
|
293
|
+
if (table.primaryKey)
|
|
294
|
+
keys.push(table.primaryKey.column_name);
|
|
295
|
+
if (table.foreignKeys)
|
|
296
|
+
for (const fKey of table.foreignKeys)
|
|
297
|
+
keys.push(fKey.local_column.replaceAll(" ", ""));
|
|
298
|
+
if (table.unique)
|
|
299
|
+
keys = keys.concat(table.unique.columns);
|
|
229
300
|
keys = [...new Set(keys)];
|
|
230
301
|
for (const keyCombination of getCombinations(keys)) {
|
|
231
|
-
ts += createGet(table.table_schema, table.table_name,
|
|
302
|
+
ts += createGet(table.table_schema, table.table_name, table.columns, keyCombination);
|
|
232
303
|
ts += "\n\n";
|
|
233
304
|
}
|
|
234
305
|
let nonDefaults = [];
|
|
235
306
|
let softDefaults = [];
|
|
236
307
|
let hardDefaults = [];
|
|
237
|
-
for (const column of
|
|
308
|
+
for (const column of table.columns) {
|
|
238
309
|
if (column.column_default === null && column.is_identity === "NO")
|
|
239
310
|
nonDefaults.push(column);
|
|
240
|
-
if ((column.column_default !== null && !column.column_default.includes("nextval")) || (column.is_identity === "YES" && column.identity_generation === "BY DEFAULT"))
|
|
311
|
+
else if ((column.column_default !== null && !column.column_default.includes("nextval")) || (column.is_identity === "YES" && column.identity_generation === "BY DEFAULT"))
|
|
241
312
|
softDefaults.push(column);
|
|
242
|
-
if ((column.column_default !== null && column.column_default.includes("nextval")) || (column.is_identity === "YES" && column.identity_generation === "ALWAYS"))
|
|
313
|
+
else if ((column.column_default !== null && column.column_default.includes("nextval")) || (column.is_identity === "YES" && column.identity_generation === "ALWAYS"))
|
|
243
314
|
hardDefaults.push(column);
|
|
244
315
|
}
|
|
245
|
-
ts += createAdd(table.table_schema, table.table_name, nonDefaults, [], hardDefaults.concat(softDefaults),
|
|
316
|
+
ts += createAdd(table.table_schema, table.table_name, nonDefaults, [], hardDefaults.concat(softDefaults), table.foreignKeys) + "\n\n";
|
|
246
317
|
for (const softCombination of getCombinations(softDefaults))
|
|
247
|
-
ts += createAdd(table.table_schema, table.table_name, nonDefaults, softCombination, hardDefaults.concat(softDefaults.filter(n => !getCombinations(softDefaults).includes(n))),
|
|
318
|
+
ts += createAdd(table.table_schema, table.table_name, nonDefaults, softCombination, hardDefaults.concat(softDefaults.filter(n => !getCombinations(softDefaults).includes([n]))), table.foreignKeys) + "\n\n";
|
|
248
319
|
ts = ts.slice(0, -2);
|
|
249
320
|
const regex = /import ({?.*?}?) from "(.*?)";\n/g;
|
|
250
321
|
let importObjects = [];
|
|
@@ -291,34 +362,29 @@ export async function runPigeon(dir, host, port, db, user, pass) {
|
|
|
291
362
|
ts = importString + ts;
|
|
292
363
|
fs.writeFileSync(path.join(dir, table.table_schema, table.table_name + ".ts"), ts);
|
|
293
364
|
}
|
|
294
|
-
return {
|
|
295
|
-
exitCode: 0,
|
|
296
|
-
message: "Generation Completed Successfully",
|
|
297
|
-
error: null
|
|
298
|
-
};
|
|
299
365
|
}
|
|
300
|
-
function createClass(tableName, columns,
|
|
366
|
+
function createClass(tableName, columns, primaryKey, foreignKeys) {
|
|
301
367
|
let text = "";
|
|
302
368
|
text += "export class " + singularize(nameBeautifier(tableName)).replaceAll(" ", "") + " {\n";
|
|
303
369
|
for (const column of columns) {
|
|
304
|
-
let dataType =
|
|
305
|
-
if (
|
|
306
|
-
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
307
|
-
if (column.is_nullable == "YES")
|
|
370
|
+
let dataType = getType(column.data_type, column.udt_name).replaceAll(" ", "");
|
|
371
|
+
if (column.is_nullable === "YES")
|
|
308
372
|
dataType += " | undefined";
|
|
309
373
|
let isPrimaryKey = false;
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
374
|
+
if (column.column_name === primaryKey)
|
|
375
|
+
isPrimaryKey = true;
|
|
376
|
+
let foreignKeyIndex;
|
|
377
|
+
if (foreignKeys)
|
|
378
|
+
for (let i = 0; i < foreignKeys.length; i++)
|
|
379
|
+
if (foreignKeys[i].local_column === column.column_name)
|
|
380
|
+
foreignKeyIndex = i;
|
|
317
381
|
text += "\t/**\n";
|
|
318
382
|
if (isPrimaryKey)
|
|
319
383
|
text += "\t * A primary key representing the " + nameBeautifier(column.column_name) + " for the " + nameBeautifier(tableName) + " table.\n";
|
|
320
|
-
else if (
|
|
321
|
-
text += "\t * A foreign key representing the " + nameBeautifier(column.column_name) + " for the " + nameBeautifier(tableName) + " table and referencing the " + nameBeautifier(foreignKeys[foreignKeyIndex].
|
|
384
|
+
else if (foreignKeys && foreignKeyIndex)
|
|
385
|
+
text += "\t * A foreign key representing the " + nameBeautifier(column.column_name) + " for the " + nameBeautifier(tableName) + " table and referencing the " + nameBeautifier(foreignKeys[foreignKeyIndex].foreign_column) + " in the " + nameBeautifier(foreignKeys[foreignKeyIndex].foreign_table) + " table in the " + nameBeautifier(foreignKeys[foreignKeyIndex].foreign_schema) + " schema.\n";
|
|
386
|
+
else if (column.column_name.toLowerCase().startsWith('is_'))
|
|
387
|
+
text += "\t * Indicates whether this record in the table " + nameBeautifier(tableName) + " is currently " + nameBeautifier(column.column_name.slice(3)).toLowerCase() + ".\n";
|
|
322
388
|
else
|
|
323
389
|
text += "\t * The " + nameBeautifier(column.column_name) + " for the " + nameBeautifier(tableName) + " table.\n";
|
|
324
390
|
text += "\t * @type {" + dataType + "}\n";
|
|
@@ -332,7 +398,7 @@ function createClass(tableName, columns, primaryKeys, foreignKeys) {
|
|
|
332
398
|
else
|
|
333
399
|
text += " = new Date(" + column.column_default.replace(' ', 'T') + ")";
|
|
334
400
|
}
|
|
335
|
-
else if (dataType === "number")
|
|
401
|
+
else if (dataType === "number" || dataType === "boolean")
|
|
336
402
|
text += " = " + column.column_default;
|
|
337
403
|
else
|
|
338
404
|
text += " = \"" + column.column_default + "\"";
|
|
@@ -345,24 +411,23 @@ function createClass(tableName, columns, primaryKeys, foreignKeys) {
|
|
|
345
411
|
text += "\t * Creates a new object for the " + nameBeautifier(tableName) + " table.\n";
|
|
346
412
|
text += "\t * \n";
|
|
347
413
|
for (const column of columns) {
|
|
348
|
-
let dataType =
|
|
349
|
-
if (dataType === undefined)
|
|
350
|
-
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
414
|
+
let dataType = getType(column.data_type, column.udt_name).replaceAll(" ", "");
|
|
351
415
|
text += "\t * ";
|
|
352
416
|
text += "@param {" + dataType;
|
|
353
|
-
if (column.is_nullable
|
|
417
|
+
if (column.is_nullable === "YES")
|
|
354
418
|
text += " | undefined";
|
|
355
419
|
text += "} " + column.column_name;
|
|
356
|
-
|
|
420
|
+
if (!column.column_name.toLowerCase().startsWith('is_'))
|
|
421
|
+
text += " - The " + nameBeautifier(column.column_name) + " of the " + nameBeautifier(tableName) + " table. \n";
|
|
422
|
+
else
|
|
423
|
+
text += " - Indicates whether this record in the table " + nameBeautifier(tableName) + " is currently " + nameBeautifier(column.column_name.slice(3)).toLowerCase() + ".\n";
|
|
357
424
|
}
|
|
358
425
|
text += "\t */\n";
|
|
359
426
|
text += "\tconstructor(";
|
|
360
427
|
for (const column of columns) {
|
|
361
|
-
let dataType =
|
|
362
|
-
if (dataType === undefined)
|
|
363
|
-
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
428
|
+
let dataType = getType(column.data_type, column.udt_name).replaceAll(" ", "");
|
|
364
429
|
text += column.column_name + ": " + dataType;
|
|
365
|
-
if (column.is_nullable
|
|
430
|
+
if (column.is_nullable === "YES")
|
|
366
431
|
text += " | undefined";
|
|
367
432
|
text += ", ";
|
|
368
433
|
}
|
|
@@ -374,14 +439,14 @@ function createClass(tableName, columns, primaryKeys, foreignKeys) {
|
|
|
374
439
|
text += "}";
|
|
375
440
|
return text;
|
|
376
441
|
}
|
|
377
|
-
export function clientMaker(baseTabs,
|
|
442
|
+
export function clientMaker(baseTabs, db) {
|
|
378
443
|
let text = "";
|
|
379
444
|
text += tabsInserter(baseTabs) + "const client = new Client({\n";
|
|
380
|
-
text += tabsInserter(baseTabs + 1) + "host: \"" + host + "\",\n";
|
|
381
|
-
text += tabsInserter(baseTabs + 1) + "port: " + port + ",\n";
|
|
382
|
-
text += tabsInserter(baseTabs + 1) + "database: \"" + db + "\",\n";
|
|
383
|
-
text += tabsInserter(baseTabs + 1) + "user: \"" + user + "\",\n";
|
|
384
|
-
text += tabsInserter(baseTabs + 1) + "password: \"" + pass + "\"\n";
|
|
445
|
+
text += tabsInserter(baseTabs + 1) + "host: \"" + db.host + "\",\n";
|
|
446
|
+
text += tabsInserter(baseTabs + 1) + "port: " + db.port + ",\n";
|
|
447
|
+
text += tabsInserter(baseTabs + 1) + "database: \"" + db.db + "\",\n";
|
|
448
|
+
text += tabsInserter(baseTabs + 1) + "user: \"" + db.user + "\",\n";
|
|
449
|
+
text += tabsInserter(baseTabs + 1) + "password: \"" + db.pass + "\"\n";
|
|
385
450
|
text += tabsInserter(baseTabs) + "});";
|
|
386
451
|
return text;
|
|
387
452
|
}
|
|
@@ -413,10 +478,12 @@ function createGet(tableSchema, tableName, columns, keys) {
|
|
|
413
478
|
text = text.slice(0, -5) + ".\n";
|
|
414
479
|
text += " *\n";
|
|
415
480
|
for (const key of keys) {
|
|
416
|
-
const column = columns.find(column => column.column_name
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
481
|
+
const column = columns.find(column => column.column_name === key);
|
|
482
|
+
if (!column) {
|
|
483
|
+
consoleMessage("WRN", `Key ${key} was not found in the columns of table ${tableName}.`);
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
let dataType = getType(column.data_type, column.udt_name).replaceAll(" ", "");
|
|
420
487
|
text += " * ";
|
|
421
488
|
text += "@param {" + dataType;
|
|
422
489
|
text += "} " + column.column_name;
|
|
@@ -429,8 +496,14 @@ function createGet(tableSchema, tableName, columns, keys) {
|
|
|
429
496
|
text += nameBeautifier(key).replaceAll(" ", "") + "And";
|
|
430
497
|
text = text.slice(0, -3);
|
|
431
498
|
text += "(";
|
|
432
|
-
for (const key of keys)
|
|
433
|
-
|
|
499
|
+
for (const key of keys) {
|
|
500
|
+
const column = columns.find(column => column.column_name === key);
|
|
501
|
+
if (!column) {
|
|
502
|
+
consoleMessage("WRN", `Key ${key} was not found in the columns of table ${tableName}.`);
|
|
503
|
+
continue;
|
|
504
|
+
}
|
|
505
|
+
text += key + ": " + getType(column.data_type, column.udt_name) + ", ";
|
|
506
|
+
}
|
|
434
507
|
text = text.slice(0, -2);
|
|
435
508
|
text += "): Promise<" + className + "[]> {\n";
|
|
436
509
|
text += "\tif (";
|
|
@@ -441,7 +514,12 @@ function createGet(tableSchema, tableName, columns, keys) {
|
|
|
441
514
|
let query = "SELECT * FROM " + tableSchema + "." + tableName + " WHERE ";
|
|
442
515
|
let parameters = "";
|
|
443
516
|
for (let i = 0; i < keys.length; i++) {
|
|
444
|
-
|
|
517
|
+
const column = columns.find(column => column.column_name === keys[i]);
|
|
518
|
+
if (!column) {
|
|
519
|
+
consoleMessage("WRN", `Key ${keys[i]} was not found in the columns of table ${tableName}.`);
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
query += keys[i] + " = " + "$" + (i + 1) + "::" + (column.data_type || column.udt_name) + " AND ";
|
|
445
523
|
parameters += keys[i] + ", ";
|
|
446
524
|
}
|
|
447
525
|
query = query.slice(0, -5) + ";";
|
|
@@ -456,13 +534,15 @@ function createGet(tableSchema, tableName, columns, keys) {
|
|
|
456
534
|
function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaults, foreignKeys) {
|
|
457
535
|
let text = "";
|
|
458
536
|
const className = singularize(nameBeautifier(tableName)).replaceAll(" ", "");
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
537
|
+
if (foreignKeys) {
|
|
538
|
+
for (const foreignKey of foreignKeys) {
|
|
539
|
+
if ((tableSchema === foreignKey.foreign_schema) && (tableName === foreignKey.foreign_table))
|
|
540
|
+
continue;
|
|
541
|
+
text += "import {get" + nameBeautifier(foreignKey.foreign_table).replaceAll(" ", "") + "By" + nameBeautifier(foreignKey.foreign_column).replaceAll(" ", "") + "} from \".";
|
|
542
|
+
if (tableSchema !== foreignKey.foreign_schema)
|
|
543
|
+
text += "./" + foreignKey.foreign_schema;
|
|
544
|
+
text += "/" + foreignKey.foreign_table + ".js\";\n";
|
|
545
|
+
}
|
|
466
546
|
}
|
|
467
547
|
text += "/**\n";
|
|
468
548
|
text += " * Adds the provided " + className + " object to the database.\n";
|
|
@@ -470,9 +550,7 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
|
|
|
470
550
|
let columns = nonDefaults.concat(softDefaults);
|
|
471
551
|
columns.sort((a, b) => a.ordinal_position - b.ordinal_position);
|
|
472
552
|
for (const column of columns) {
|
|
473
|
-
let dataType =
|
|
474
|
-
if (dataType === undefined)
|
|
475
|
-
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
553
|
+
let dataType = getType(column.data_type, column.udt_name).replaceAll(" ", "");
|
|
476
554
|
text += " * ";
|
|
477
555
|
text += "@param {" + dataType;
|
|
478
556
|
if (column.is_nullable === "YES")
|
|
@@ -481,7 +559,7 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
|
|
|
481
559
|
text += " - The " + nameBeautifier(column.column_name) + " to be inserted into the " + nameBeautifier(tableName) + " table.\n";
|
|
482
560
|
}
|
|
483
561
|
text += " * @returns {Promise<" + className + ">} - A Promise object returning the inserted " + nameBeautifier(tableName) + ".\n";
|
|
484
|
-
if (foreignKeys.length > 0) {
|
|
562
|
+
if (foreignKeys && foreignKeys.length > 0) {
|
|
485
563
|
text += " * @throws string An exception in the case of the ";
|
|
486
564
|
for (const foreignKey of foreignKeys)
|
|
487
565
|
text += nameBeautifier(foreignKey.local_column) + " or the ";
|
|
@@ -498,9 +576,7 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
|
|
|
498
576
|
}
|
|
499
577
|
text += "(";
|
|
500
578
|
for (const column of columns) {
|
|
501
|
-
let dataType =
|
|
502
|
-
if (dataType === undefined)
|
|
503
|
-
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
579
|
+
let dataType = getType(column.data_type, column.udt_name);
|
|
504
580
|
text += column.column_name + ": " + dataType;
|
|
505
581
|
if (column.is_nullable === "YES")
|
|
506
582
|
text += " | undefined";
|
|
@@ -508,18 +584,25 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
|
|
|
508
584
|
}
|
|
509
585
|
text = text.slice(0, -2);
|
|
510
586
|
text += "): Promise<" + className + "> {\n";
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
587
|
+
if (foreignKeys) {
|
|
588
|
+
for (const foreignKey of foreignKeys) {
|
|
589
|
+
const column = columns.find(column => column.column_name === foreignKey.local_column);
|
|
590
|
+
if (!column) {
|
|
591
|
+
consoleMessage("WRN", `Key ${foreignKey} was not found in the columns of table ${tableName}.`);
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
if (column.is_nullable === "YES") {
|
|
595
|
+
text += "\tif (" + foreignKey.local_column + ") {\n";
|
|
596
|
+
text += "\t\tconst verify" + nameBeautifier(foreignKey.local_column).replaceAll(" ", "") + " = await get" + nameBeautifier(foreignKey.foreign_table).replaceAll(" ", "") + "By" + nameBeautifier(foreignKey.foreign_column).replaceAll(" ", "") + "(" + foreignKey.local_column + ");\n";
|
|
597
|
+
text += "\t\tif (verify" + nameBeautifier(foreignKey.local_column).replaceAll(" ", "") + ".length === 0)\n";
|
|
598
|
+
text += "\t\t\tthrow \"The " + nameBeautifier(foreignKey.local_column) + " provided does not exist.\";\n";
|
|
599
|
+
text += "\t}\n\n";
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
text += "\tconst verify" + nameBeautifier(foreignKey.local_column).replaceAll(" ", "") + " = await get" + nameBeautifier(foreignKey.foreign_table).replaceAll(" ", "") + "By" + nameBeautifier(foreignKey.foreign_column).replaceAll(" ", "") + "(" + foreignKey.local_column + ");\n";
|
|
603
|
+
text += "\tif (verify" + nameBeautifier(foreignKey.local_column).replaceAll(" ", "") + ".length === 0)\n";
|
|
604
|
+
text += "\t\tthrow \"The " + nameBeautifier(foreignKey.local_column) + " provided does not exist.\";\n\n";
|
|
605
|
+
}
|
|
523
606
|
}
|
|
524
607
|
}
|
|
525
608
|
let query = "INSERT INTO " + tableSchema + "." + tableName + " (";
|
|
@@ -529,9 +612,11 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
|
|
|
529
612
|
query += ") VALUES (";
|
|
530
613
|
let parameters = "";
|
|
531
614
|
for (let i = 0; i < columns.length; i++) {
|
|
532
|
-
let dataType = columns[i].
|
|
533
|
-
if (dataType === "
|
|
534
|
-
dataType =
|
|
615
|
+
let dataType = columns[i].udt_name;
|
|
616
|
+
if (dataType[0] === "_")
|
|
617
|
+
dataType = dataType.slice(1) + "[]";
|
|
618
|
+
else if (columns[i].data_type !== "USER-DEFINED")
|
|
619
|
+
dataType = columns[i].data_type;
|
|
535
620
|
query += "$" + (i + 1) + "::" + dataType + ", ";
|
|
536
621
|
parameters += columns[i].column_name + ", ";
|
|
537
622
|
}
|
package/src/utils.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) 2025 Andreas Michael
|
|
3
3
|
* This software is under the Apache 2.0 License
|
|
4
4
|
*/
|
|
5
5
|
import pg from "pg";
|
|
6
|
+
import { types } from "./maps.js";
|
|
6
7
|
const { Client } = pg;
|
|
7
|
-
export async function runQuery(command, parameters,
|
|
8
|
+
export async function runQuery(command, parameters, db) {
|
|
8
9
|
const client = new Client({
|
|
9
|
-
host: host,
|
|
10
|
-
port: port,
|
|
11
|
-
database: db,
|
|
12
|
-
user:
|
|
13
|
-
password:
|
|
10
|
+
host: db.host,
|
|
11
|
+
port: Number(db.port),
|
|
12
|
+
database: db.db,
|
|
13
|
+
user: db.user,
|
|
14
|
+
password: db.pass,
|
|
14
15
|
});
|
|
15
16
|
try {
|
|
16
17
|
await client.connect();
|
|
@@ -149,3 +150,16 @@ export function getCombinations(valuesArray) {
|
|
|
149
150
|
combinations.sort((a, b) => a.length - b.length);
|
|
150
151
|
return combinations;
|
|
151
152
|
}
|
|
153
|
+
export function getType(dataType, udtName) {
|
|
154
|
+
let isArray = false;
|
|
155
|
+
if (dataType === "ARRAY") {
|
|
156
|
+
dataType = udtName.slice(1);
|
|
157
|
+
isArray = true;
|
|
158
|
+
}
|
|
159
|
+
let foundDataType = types.get(dataType);
|
|
160
|
+
if (foundDataType === undefined)
|
|
161
|
+
foundDataType = nameBeautifier(udtName).replaceAll(" ", "");
|
|
162
|
+
if (isArray)
|
|
163
|
+
foundDataType += "[]";
|
|
164
|
+
return foundDataType;
|
|
165
|
+
}
|