@andymic/pigeon 1.0.1 → 1.1.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/package.json +2 -2
- package/src/index.js +82 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@andymic/pigeon",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.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": [
|
|
@@ -35,5 +35,5 @@
|
|
|
35
35
|
"pg": "^8.13.1",
|
|
36
36
|
"prompt-sync": "^4.2.0"
|
|
37
37
|
},
|
|
38
|
-
"gitHead": "
|
|
38
|
+
"gitHead": "6da3fed7416ff254af875d4efbb5fc0f66e1f553"
|
|
39
39
|
}
|
package/src/index.js
CHANGED
|
@@ -98,6 +98,38 @@ export async function runPigeon(dir, host, port, db, user, pass) {
|
|
|
98
98
|
}
|
|
99
99
|
for (const schema of schemas)
|
|
100
100
|
createDir(path.join(dir, schema));
|
|
101
|
+
const customTypeQuery = await runQuery(`SELECT t.oid, t.typname
|
|
102
|
+
FROM pg_type t
|
|
103
|
+
WHERE (t.typrelid = 0 OR t.typrelid IN (SELECT oid FROM pg_class WHERE relkind = 'c'))
|
|
104
|
+
AND t.typelem = 0
|
|
105
|
+
AND t.typnamespace NOT IN
|
|
106
|
+
(SELECT oid FROM pg_namespace WHERE nspname IN ('pg_catalog', 'information_schema'));`, [], host, port, db, user, pass);
|
|
107
|
+
if (typeof customTypeQuery === "undefined")
|
|
108
|
+
return {
|
|
109
|
+
exitCode: 1,
|
|
110
|
+
message: null,
|
|
111
|
+
error: new Error("An SQL error has occurred.")
|
|
112
|
+
};
|
|
113
|
+
const customTypes = [];
|
|
114
|
+
for (const type of customTypeQuery.rows) {
|
|
115
|
+
const enumQuery = await runQuery(`SELECT enumlabel
|
|
116
|
+
FROM pg_enum
|
|
117
|
+
WHERE enumtypid = $1::oid
|
|
118
|
+
ORDER BY enumsortorder;`, [type.oid], host, port, db, user, pass);
|
|
119
|
+
if (typeof enumQuery === "undefined")
|
|
120
|
+
return {
|
|
121
|
+
exitCode: 1,
|
|
122
|
+
message: null,
|
|
123
|
+
error: new Error("An SQL error has occurred.")
|
|
124
|
+
};
|
|
125
|
+
let labels = [];
|
|
126
|
+
for (const enumLabel of enumQuery.rows)
|
|
127
|
+
labels.push(enumLabel.enumlabel);
|
|
128
|
+
customTypes.push({
|
|
129
|
+
name: type.typname,
|
|
130
|
+
labels: labels
|
|
131
|
+
});
|
|
132
|
+
}
|
|
101
133
|
for (const table of tableQuery.rows) {
|
|
102
134
|
const columnQuery = await runQuery(`SELECT *
|
|
103
135
|
FROM information_schema.columns
|
|
@@ -152,6 +184,24 @@ export async function runPigeon(dir, host, port, db, user, pass) {
|
|
|
152
184
|
};
|
|
153
185
|
let ts = clientMaker(0, host, port, db, user, pass);
|
|
154
186
|
ts += "\n\n";
|
|
187
|
+
for (const customType of customTypes) {
|
|
188
|
+
for (const column of columnQuery.rows) {
|
|
189
|
+
if (customType.name === column.udt_name) {
|
|
190
|
+
const enumName = nameBeautifier(customType.name).replaceAll(" ", "");
|
|
191
|
+
ts += "/**\n An Enum representing the " + nameBeautifier(customType.name).toLowerCase() + ".\n * @readonly\n * @enum {string}\n */\n";
|
|
192
|
+
ts += "class " + enumName + "{\n";
|
|
193
|
+
let longestLabel = 0;
|
|
194
|
+
for (const label of customType.labels)
|
|
195
|
+
if (label.length > longestLabel)
|
|
196
|
+
longestLabel = label.length;
|
|
197
|
+
for (const label of customType.labels)
|
|
198
|
+
ts += "\tstatic " + label.toUpperCase().replaceAll(/[^a-zA-Z0-9$]/g, "_") + ": string" + " ".repeat(longestLabel - label.length + 1) + "= \"" + label + "\";\n";
|
|
199
|
+
ts += "}\n";
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (ts.slice(-2) !== "\n\n")
|
|
204
|
+
ts += "\n";
|
|
155
205
|
ts += createClass(table.table_name, columnQuery.rows, pKeys, fKeyQuery.rows);
|
|
156
206
|
ts += "\n\n";
|
|
157
207
|
ts += createGetAll(table.table_schema, table.table_name, columnQuery.rows);
|
|
@@ -174,9 +224,9 @@ export async function runPigeon(dir, host, port, db, user, pass) {
|
|
|
174
224
|
if ((column.column_default !== null && column.column_default.includes("nextval")) || (column.is_identity === "YES" && column.identity_generation === "ALWAYS"))
|
|
175
225
|
hardDefaults.push(column);
|
|
176
226
|
}
|
|
177
|
-
ts += createAdd(table.table_schema, table.table_name, nonDefaults, [], hardDefaults, fKeyQuery.rows) + "\n\n";
|
|
227
|
+
ts += createAdd(table.table_schema, table.table_name, nonDefaults, [], hardDefaults.concat(softDefaults), fKeyQuery.rows) + "\n\n";
|
|
178
228
|
for (const softCombination of getCombinations(softDefaults))
|
|
179
|
-
ts += createAdd(table.table_schema, table.table_name, nonDefaults, softCombination, hardDefaults, fKeyQuery.rows) + "\n\n";
|
|
229
|
+
ts += createAdd(table.table_schema, table.table_name, nonDefaults, softCombination, hardDefaults.concat(softDefaults.filter(n => !getCombinations(softDefaults).includes(n))), fKeyQuery.rows) + "\n\n";
|
|
180
230
|
const regex = /import ({?.*?}?) from "(.*?)";\n/g;
|
|
181
231
|
let match;
|
|
182
232
|
let importObjects = [];
|
|
@@ -200,6 +250,7 @@ export async function runPigeon(dir, host, port, db, user, pass) {
|
|
|
200
250
|
}
|
|
201
251
|
let importString = "";
|
|
202
252
|
for (const object of importObjects) {
|
|
253
|
+
object.functions = [...new Set(object.functions)];
|
|
203
254
|
importString += "import ";
|
|
204
255
|
if (object.brackets)
|
|
205
256
|
importString += "{";
|
|
@@ -230,6 +281,8 @@ function createClass(tableName, columns, primaryKeys, foreignKeys) {
|
|
|
230
281
|
text += "export class " + singularize(nameBeautifier(tableName)).replaceAll(" ", "") + " {\n";
|
|
231
282
|
for (const column of columns) {
|
|
232
283
|
let dataType = types.get(column.data_type);
|
|
284
|
+
if (dataType === undefined)
|
|
285
|
+
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
233
286
|
if (column.is_nullable == "YES")
|
|
234
287
|
dataType += " | undefined";
|
|
235
288
|
let isPrimaryKey = false;
|
|
@@ -252,13 +305,13 @@ function createClass(tableName, columns, primaryKeys, foreignKeys) {
|
|
|
252
305
|
text += "\t" + column.column_name + ": " + dataType;
|
|
253
306
|
if (column.column_default !== null) {
|
|
254
307
|
if (!column.column_default.includes("nextval")) {
|
|
255
|
-
if (
|
|
308
|
+
if (dataType === "Date") {
|
|
256
309
|
if (column.column_default)
|
|
257
310
|
text += " = new Date()";
|
|
258
311
|
else
|
|
259
312
|
text += " = new Date(" + column.column_default.replace(' ', 'T') + ")";
|
|
260
313
|
}
|
|
261
|
-
else if (
|
|
314
|
+
else if (dataType === "number")
|
|
262
315
|
text += " = " + column.column_default;
|
|
263
316
|
else
|
|
264
317
|
text += " = \"" + column.column_default + "\"";
|
|
@@ -271,8 +324,11 @@ function createClass(tableName, columns, primaryKeys, foreignKeys) {
|
|
|
271
324
|
text += "\t * Creates a new object for the " + nameBeautifier(tableName) + " table.\n";
|
|
272
325
|
text += "\t * \n";
|
|
273
326
|
for (const column of columns) {
|
|
327
|
+
let dataType = types.get(column.data_type);
|
|
328
|
+
if (dataType === undefined)
|
|
329
|
+
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
274
330
|
text += "\t * ";
|
|
275
|
-
text += "@param {" +
|
|
331
|
+
text += "@param {" + dataType;
|
|
276
332
|
if (column.is_nullable == "YES")
|
|
277
333
|
text += " | undefined";
|
|
278
334
|
text += "} " + column.column_name;
|
|
@@ -281,7 +337,10 @@ function createClass(tableName, columns, primaryKeys, foreignKeys) {
|
|
|
281
337
|
text += "\t */\n";
|
|
282
338
|
text += "\tconstructor(";
|
|
283
339
|
for (const column of columns) {
|
|
284
|
-
|
|
340
|
+
let dataType = types.get(column.data_type);
|
|
341
|
+
if (dataType === undefined)
|
|
342
|
+
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
343
|
+
text += column.column_name + ": " + dataType;
|
|
285
344
|
if (column.is_nullable == "YES")
|
|
286
345
|
text += " | undefined";
|
|
287
346
|
text += ", ";
|
|
@@ -334,8 +393,11 @@ function createGet(tableSchema, tableName, columns, keys) {
|
|
|
334
393
|
text += " *\n";
|
|
335
394
|
for (const key of keys) {
|
|
336
395
|
const column = columns.find(column => column.column_name == key);
|
|
396
|
+
let dataType = types.get(column.data_type);
|
|
397
|
+
if (dataType === undefined)
|
|
398
|
+
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
337
399
|
text += " * ";
|
|
338
|
-
text += "@param {" +
|
|
400
|
+
text += "@param {" + dataType;
|
|
339
401
|
text += "} " + column.column_name;
|
|
340
402
|
text += " - The " + nameBeautifier(column.column_name) + " of the " + nameBeautifier(tableName) + " table.\n";
|
|
341
403
|
}
|
|
@@ -385,8 +447,11 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
|
|
|
385
447
|
let columns = nonDefaults.concat(softDefaults);
|
|
386
448
|
columns.sort((a, b) => a.ordinal_position - b.ordinal_position);
|
|
387
449
|
for (const column of columns) {
|
|
450
|
+
let dataType = types.get(column.data_type);
|
|
451
|
+
if (dataType === undefined)
|
|
452
|
+
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
388
453
|
text += " * ";
|
|
389
|
-
text += "@param {" +
|
|
454
|
+
text += "@param {" + dataType;
|
|
390
455
|
if (column.is_nullable === "YES")
|
|
391
456
|
text += " | undefined";
|
|
392
457
|
text += "} " + column.column_name;
|
|
@@ -410,7 +475,10 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
|
|
|
410
475
|
}
|
|
411
476
|
text += "(";
|
|
412
477
|
for (const column of columns) {
|
|
413
|
-
|
|
478
|
+
let dataType = types.get(column.data_type);
|
|
479
|
+
if (dataType === undefined)
|
|
480
|
+
dataType = nameBeautifier(column.udt_name).replaceAll(" ", "");
|
|
481
|
+
text += column.column_name + ": " + dataType;
|
|
414
482
|
if (column.is_nullable === "YES")
|
|
415
483
|
text += " | undefined";
|
|
416
484
|
text += ", ";
|
|
@@ -429,7 +497,10 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
|
|
|
429
497
|
query += ") VALUES (";
|
|
430
498
|
let parameters = "";
|
|
431
499
|
for (let i = 0; i < columns.length; i++) {
|
|
432
|
-
|
|
500
|
+
let dataType = columns[i].data_type;
|
|
501
|
+
if (dataType === "USER-DEFINED")
|
|
502
|
+
dataType = "character varying";
|
|
503
|
+
query += "$" + (i + 1) + "::" + dataType + ", ";
|
|
433
504
|
parameters += columns[i].column_name + ", ";
|
|
434
505
|
}
|
|
435
506
|
query = query.slice(0, -2);
|
|
@@ -439,6 +510,7 @@ function createAdd(tableSchema, tableName, nonDefaults, softDefaults, hardDefaul
|
|
|
439
510
|
text += "\n\n";
|
|
440
511
|
text += "\treturn new " + className + "(\n";
|
|
441
512
|
columns = columns.concat(hardDefaults);
|
|
513
|
+
columns = [...new Set(columns)];
|
|
442
514
|
columns.sort((a, b) => a.ordinal_position - b.ordinal_position);
|
|
443
515
|
for (const column of columns)
|
|
444
516
|
text += "\t\tinsertQuery.rows[0]." + column.column_name + ",\n";
|