@juit/pgproxy-utils 1.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 +119 -0
- package/dist/database.cjs +60 -0
- package/dist/database.cjs.map +6 -0
- package/dist/database.d.ts +17 -0
- package/dist/database.mjs +33 -0
- package/dist/database.mjs.map +6 -0
- package/dist/extract.cjs +119 -0
- package/dist/extract.cjs.map +6 -0
- package/dist/extract.d.ts +18 -0
- package/dist/extract.mjs +94 -0
- package/dist/extract.mjs.map +6 -0
- package/dist/helpers.cjs +65 -0
- package/dist/helpers.cjs.map +6 -0
- package/dist/helpers.d.ts +10 -0
- package/dist/helpers.mjs +29 -0
- package/dist/helpers.mjs.map +6 -0
- package/dist/index.cjs +53 -0
- package/dist/index.cjs.map +6 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.mjs +12 -0
- package/dist/index.mjs.map +6 -0
- package/dist/migrate.cjs +138 -0
- package/dist/migrate.cjs.map +6 -0
- package/dist/migrate.d.ts +14 -0
- package/dist/migrate.mjs +103 -0
- package/dist/migrate.mjs.map +6 -0
- package/dist/serialize.cjs +279 -0
- package/dist/serialize.cjs.map +6 -0
- package/dist/serialize.d.ts +9 -0
- package/dist/serialize.mjs +244 -0
- package/dist/serialize.mjs.map +6 -0
- package/dist/types.cjs +130 -0
- package/dist/types.cjs.map +6 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.mjs +66 -0
- package/dist/types.mjs.map +6 -0
- package/package.json +50 -0
- package/src/database.ts +48 -0
- package/src/extract.ts +137 -0
- package/src/helpers.ts +30 -0
- package/src/index.ts +22 -0
- package/src/migrate.ts +177 -0
- package/src/serialize.ts +217 -0
- package/src/types.ts +51 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// index.ts
|
|
32
|
+
var src_exports = {};
|
|
33
|
+
__export(src_exports, {
|
|
34
|
+
helpers: () => helpers,
|
|
35
|
+
types: () => types
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(src_exports);
|
|
38
|
+
__reExport(src_exports, require("./database.cjs"), module.exports);
|
|
39
|
+
__reExport(src_exports, require("./extract.cjs"), module.exports);
|
|
40
|
+
__reExport(src_exports, require("./migrate.cjs"), module.exports);
|
|
41
|
+
__reExport(src_exports, require("./serialize.cjs"), module.exports);
|
|
42
|
+
var helpers = __toESM(require("./helpers.cjs"));
|
|
43
|
+
var types = __toESM(require("./types.cjs"));
|
|
44
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
45
|
+
0 && (module.exports = {
|
|
46
|
+
helpers,
|
|
47
|
+
types,
|
|
48
|
+
...require("./database.cjs"),
|
|
49
|
+
...require("./extract.cjs"),
|
|
50
|
+
...require("./migrate.cjs"),
|
|
51
|
+
...require("./serialize.cjs")
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Schema definition extracted from PostgreSQL */
|
|
2
|
+
export interface Schema {
|
|
3
|
+
[table: string]: {
|
|
4
|
+
[column: string]: {
|
|
5
|
+
oid: number;
|
|
6
|
+
isNullable?: boolean;
|
|
7
|
+
hasDefault?: boolean;
|
|
8
|
+
description?: string;
|
|
9
|
+
enumValues?: readonly [string, ...string[]];
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export * from './database';
|
|
14
|
+
export * from './extract';
|
|
15
|
+
export * from './migrate';
|
|
16
|
+
export * from './serialize';
|
|
17
|
+
/** Helper functions for serializing schemas */
|
|
18
|
+
export * as helpers from './helpers';
|
|
19
|
+
/** Known/basic types for serializing schemas */
|
|
20
|
+
export * as types from './types';
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// index.ts
|
|
2
|
+
export * from "./database.mjs";
|
|
3
|
+
export * from "./extract.mjs";
|
|
4
|
+
export * from "./migrate.mjs";
|
|
5
|
+
export * from "./serialize.mjs";
|
|
6
|
+
import * as helpers from "./helpers.mjs";
|
|
7
|
+
import * as types from "./types.mjs";
|
|
8
|
+
export {
|
|
9
|
+
helpers,
|
|
10
|
+
types
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=index.mjs.map
|
package/dist/migrate.cjs
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// migrate.ts
|
|
31
|
+
var migrate_exports = {};
|
|
32
|
+
__export(migrate_exports, {
|
|
33
|
+
migrate: () => migrate
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(migrate_exports);
|
|
36
|
+
var import_node_crypto = __toESM(require("node:crypto"));
|
|
37
|
+
var import_node_path = require("node:path");
|
|
38
|
+
var import_pgproxy_persister = require("@juit/pgproxy-persister");
|
|
39
|
+
var import_plug = require("@plugjs/plug");
|
|
40
|
+
var migrationsExpression = /^([0-9]+)[^\w](.*)\.(sql)$/i;
|
|
41
|
+
async function migrate(url, options) {
|
|
42
|
+
const {
|
|
43
|
+
/* Default to our "../sql" migrations directory */
|
|
44
|
+
migrations: migrationsDirectory = (0, import_plug.resolve)("sql"),
|
|
45
|
+
/* Our default group name is "default" */
|
|
46
|
+
group = "default",
|
|
47
|
+
/* Optional additional directory for migrations */
|
|
48
|
+
additional
|
|
49
|
+
} = { ...options };
|
|
50
|
+
let entries = await (0, import_plug.find)("*.sql", { directory: migrationsDirectory });
|
|
51
|
+
if (additional) {
|
|
52
|
+
for (const addition of [additional].flat()) {
|
|
53
|
+
const additional2 = await (0, import_plug.find)("*.sql", { directory: addition });
|
|
54
|
+
entries = await (0, import_plug.merge)([entries, additional2]);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const promises = [...entries.absolutePaths()].map(async (file) => {
|
|
58
|
+
const match = migrationsExpression.exec((0, import_node_path.basename)(file));
|
|
59
|
+
if (!match)
|
|
60
|
+
return;
|
|
61
|
+
const [, number, name] = match;
|
|
62
|
+
const contents = await import_plug.fs.readFile(file);
|
|
63
|
+
return {
|
|
64
|
+
sha256sum: import_node_crypto.default.createHash("sha256").update(contents).digest(),
|
|
65
|
+
contents: contents.toString("utf8"),
|
|
66
|
+
number: parseInt(number),
|
|
67
|
+
name
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
const migrationFiles = (await Promise.all(promises)).filter((migration) => !!migration).sort((a, b) => a.number - b.number);
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
const persister = new import_pgproxy_persister.Persister(url);
|
|
73
|
+
return await persister.connect(async (connection) => {
|
|
74
|
+
const info = await connection.query("SELECT current_database() AS name");
|
|
75
|
+
import_plug.log.notice(`Migrating database ${(0, import_plug.$ylw)(info.rows[0].name)}`);
|
|
76
|
+
const model = connection.in("$migrations");
|
|
77
|
+
import_plug.log.info("Beginning migrations transaction");
|
|
78
|
+
await connection.begin();
|
|
79
|
+
import_plug.log.info(`Ensuring presence of ${(0, import_plug.$blu)("$migrations")} table`);
|
|
80
|
+
await connection.query(`
|
|
81
|
+
SET LOCAL client_min_messages TO WARNING;
|
|
82
|
+
CREATE TABLE IF NOT EXISTS "$migrations" (
|
|
83
|
+
"group" VARCHAR(32) NOT NULL DEFAULT 'default',
|
|
84
|
+
"number" INTEGER NOT NULL,
|
|
85
|
+
"name" TEXT NOT NULL,
|
|
86
|
+
"timestamp" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
87
|
+
"sha256sum" BYTEA NOT NULL,
|
|
88
|
+
PRIMARY KEY ("group", "number")
|
|
89
|
+
);`);
|
|
90
|
+
import_plug.log.info(`Lock exclusive use of ${(0, import_plug.$blu)("$migrations")} table`);
|
|
91
|
+
await connection.query('LOCK TABLE "$migrations"');
|
|
92
|
+
import_plug.log.info(`Looking for entries in ${(0, import_plug.$blu)("$migrations")} table`);
|
|
93
|
+
const result = await model.read({ group });
|
|
94
|
+
const applied = result.reduce((applied2, row) => {
|
|
95
|
+
const { group: group2, number, name, timestamp, sha256sum } = row;
|
|
96
|
+
applied2[number] = { group: group2, number, name, timestamp, sha256sum };
|
|
97
|
+
return applied2;
|
|
98
|
+
}, {});
|
|
99
|
+
let count = 0;
|
|
100
|
+
for (const { number, name, contents, sha256sum } of migrationFiles) {
|
|
101
|
+
const num = `${number}`.padStart(3, "0");
|
|
102
|
+
const prev = applied[number];
|
|
103
|
+
if (prev) {
|
|
104
|
+
if (sha256sum.equals(prev.sha256sum)) {
|
|
105
|
+
const timestamp = prev.timestamp.toISOString().substring(0, 19).replace("T", " ");
|
|
106
|
+
import_plug.log.notice(`Skipping migration ${(0, import_plug.$gry)(`${group}@`)}${(0, import_plug.$grn)(num)}: ${(0, import_plug.$blu)(name)}`, (0, import_plug.$gry)(`applied on ${(0, import_plug.$und)(timestamp)}`));
|
|
107
|
+
} else {
|
|
108
|
+
import_plug.log.error(`Failed migration ${(0, import_plug.$gry)(`${group}@`)}${(0, import_plug.$grn)(num)}: ${(0, import_plug.$ylw)(name)}`);
|
|
109
|
+
const currHash = sha256sum.toString("hex").substring(0, 6);
|
|
110
|
+
const prevHash = Buffer.from(prev.sha256sum).toString("hex").substring(0, 6);
|
|
111
|
+
throw new Error(`Migration ${group}@${num} (${name}) has checksum "${currHash}" but was recorded as "${prevHash}"`);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
try {
|
|
115
|
+
import_plug.log.notice(`Applying migration ${(0, import_plug.$gry)(`${group}@`)}${(0, import_plug.$grn)(num)}: ${(0, import_plug.$blu)(name)}`);
|
|
116
|
+
await connection.query(contents);
|
|
117
|
+
await model.create({ group, number, name, sha256sum });
|
|
118
|
+
count++;
|
|
119
|
+
} catch (error) {
|
|
120
|
+
import_plug.log.error(`Failed migration ${(0, import_plug.$gry)(`${group}@`)}${(0, import_plug.$grn)(num)}: ${(0, import_plug.$ylw)(name)}`);
|
|
121
|
+
const message = error.message.split("\n").map((s) => ` ${s}`).join("\n");
|
|
122
|
+
error.message = `Failed migration ${group}@${num} (${name}):
|
|
123
|
+
${message}`;
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
import_plug.log.info("Committing migrations transaction");
|
|
129
|
+
await connection.commit();
|
|
130
|
+
import_plug.log.notice(`Applied ${(0, import_plug.$ylw)(count)} migrations ${(0, import_plug.$ms)(Date.now() - now)}`);
|
|
131
|
+
return count;
|
|
132
|
+
}).finally(() => persister.destroy());
|
|
133
|
+
}
|
|
134
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
135
|
+
0 && (module.exports = {
|
|
136
|
+
migrate
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=migrate.cjs.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/migrate.ts"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": ["additional", "crypto", "applied", "group"]
|
|
6
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
export type MigrationOptions = {
|
|
3
|
+
/** The directory where migrations SQL files reside (default: `./sql`) */
|
|
4
|
+
migrations?: string;
|
|
5
|
+
/**
|
|
6
|
+
* The directory (or directories) where _additional_ migrations SQL files
|
|
7
|
+
* reside (default: _undefined_).
|
|
8
|
+
*/
|
|
9
|
+
additional?: string | string[];
|
|
10
|
+
/** The group identifier for this migrations (default: `default`) */
|
|
11
|
+
group?: string;
|
|
12
|
+
};
|
|
13
|
+
/** Migrate a database, applying all changes from a set of SQL files */
|
|
14
|
+
export declare function migrate(url: string | URL, options?: MigrationOptions): Promise<number>;
|
package/dist/migrate.mjs
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// migrate.ts
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
|
+
import { basename } from "node:path";
|
|
4
|
+
import { Persister } from "@juit/pgproxy-persister";
|
|
5
|
+
import { $blu, $grn, $gry, $ms, $und, $ylw, find, fs, log, merge, resolve } from "@plugjs/plug";
|
|
6
|
+
var migrationsExpression = /^([0-9]+)[^\w](.*)\.(sql)$/i;
|
|
7
|
+
async function migrate(url, options) {
|
|
8
|
+
const {
|
|
9
|
+
/* Default to our "../sql" migrations directory */
|
|
10
|
+
migrations: migrationsDirectory = resolve("sql"),
|
|
11
|
+
/* Our default group name is "default" */
|
|
12
|
+
group = "default",
|
|
13
|
+
/* Optional additional directory for migrations */
|
|
14
|
+
additional
|
|
15
|
+
} = { ...options };
|
|
16
|
+
let entries = await find("*.sql", { directory: migrationsDirectory });
|
|
17
|
+
if (additional) {
|
|
18
|
+
for (const addition of [additional].flat()) {
|
|
19
|
+
const additional2 = await find("*.sql", { directory: addition });
|
|
20
|
+
entries = await merge([entries, additional2]);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const promises = [...entries.absolutePaths()].map(async (file) => {
|
|
24
|
+
const match = migrationsExpression.exec(basename(file));
|
|
25
|
+
if (!match)
|
|
26
|
+
return;
|
|
27
|
+
const [, number, name] = match;
|
|
28
|
+
const contents = await fs.readFile(file);
|
|
29
|
+
return {
|
|
30
|
+
sha256sum: crypto.createHash("sha256").update(contents).digest(),
|
|
31
|
+
contents: contents.toString("utf8"),
|
|
32
|
+
number: parseInt(number),
|
|
33
|
+
name
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
const migrationFiles = (await Promise.all(promises)).filter((migration) => !!migration).sort((a, b) => a.number - b.number);
|
|
37
|
+
const now = Date.now();
|
|
38
|
+
const persister = new Persister(url);
|
|
39
|
+
return await persister.connect(async (connection) => {
|
|
40
|
+
const info = await connection.query("SELECT current_database() AS name");
|
|
41
|
+
log.notice(`Migrating database ${$ylw(info.rows[0].name)}`);
|
|
42
|
+
const model = connection.in("$migrations");
|
|
43
|
+
log.info("Beginning migrations transaction");
|
|
44
|
+
await connection.begin();
|
|
45
|
+
log.info(`Ensuring presence of ${$blu("$migrations")} table`);
|
|
46
|
+
await connection.query(`
|
|
47
|
+
SET LOCAL client_min_messages TO WARNING;
|
|
48
|
+
CREATE TABLE IF NOT EXISTS "$migrations" (
|
|
49
|
+
"group" VARCHAR(32) NOT NULL DEFAULT 'default',
|
|
50
|
+
"number" INTEGER NOT NULL,
|
|
51
|
+
"name" TEXT NOT NULL,
|
|
52
|
+
"timestamp" TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
53
|
+
"sha256sum" BYTEA NOT NULL,
|
|
54
|
+
PRIMARY KEY ("group", "number")
|
|
55
|
+
);`);
|
|
56
|
+
log.info(`Lock exclusive use of ${$blu("$migrations")} table`);
|
|
57
|
+
await connection.query('LOCK TABLE "$migrations"');
|
|
58
|
+
log.info(`Looking for entries in ${$blu("$migrations")} table`);
|
|
59
|
+
const result = await model.read({ group });
|
|
60
|
+
const applied = result.reduce((applied2, row) => {
|
|
61
|
+
const { group: group2, number, name, timestamp, sha256sum } = row;
|
|
62
|
+
applied2[number] = { group: group2, number, name, timestamp, sha256sum };
|
|
63
|
+
return applied2;
|
|
64
|
+
}, {});
|
|
65
|
+
let count = 0;
|
|
66
|
+
for (const { number, name, contents, sha256sum } of migrationFiles) {
|
|
67
|
+
const num = `${number}`.padStart(3, "0");
|
|
68
|
+
const prev = applied[number];
|
|
69
|
+
if (prev) {
|
|
70
|
+
if (sha256sum.equals(prev.sha256sum)) {
|
|
71
|
+
const timestamp = prev.timestamp.toISOString().substring(0, 19).replace("T", " ");
|
|
72
|
+
log.notice(`Skipping migration ${$gry(`${group}@`)}${$grn(num)}: ${$blu(name)}`, $gry(`applied on ${$und(timestamp)}`));
|
|
73
|
+
} else {
|
|
74
|
+
log.error(`Failed migration ${$gry(`${group}@`)}${$grn(num)}: ${$ylw(name)}`);
|
|
75
|
+
const currHash = sha256sum.toString("hex").substring(0, 6);
|
|
76
|
+
const prevHash = Buffer.from(prev.sha256sum).toString("hex").substring(0, 6);
|
|
77
|
+
throw new Error(`Migration ${group}@${num} (${name}) has checksum "${currHash}" but was recorded as "${prevHash}"`);
|
|
78
|
+
}
|
|
79
|
+
} else {
|
|
80
|
+
try {
|
|
81
|
+
log.notice(`Applying migration ${$gry(`${group}@`)}${$grn(num)}: ${$blu(name)}`);
|
|
82
|
+
await connection.query(contents);
|
|
83
|
+
await model.create({ group, number, name, sha256sum });
|
|
84
|
+
count++;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
log.error(`Failed migration ${$gry(`${group}@`)}${$grn(num)}: ${$ylw(name)}`);
|
|
87
|
+
const message = error.message.split("\n").map((s) => ` ${s}`).join("\n");
|
|
88
|
+
error.message = `Failed migration ${group}@${num} (${name}):
|
|
89
|
+
${message}`;
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
log.info("Committing migrations transaction");
|
|
95
|
+
await connection.commit();
|
|
96
|
+
log.notice(`Applied ${$ylw(count)} migrations ${$ms(Date.now() - now)}`);
|
|
97
|
+
return count;
|
|
98
|
+
}).finally(() => persister.destroy());
|
|
99
|
+
}
|
|
100
|
+
export {
|
|
101
|
+
migrate
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=migrate.mjs.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/migrate.ts"],
|
|
4
|
+
"mappings": ";AAAA,OAAO,YAAY;AACnB,SAAS,gBAAgB;AAEzB,SAAS,iBAAiB;AAC1B,SAAS,MAAM,MAAM,MAAM,KAAK,MAAM,MAAM,MAAM,IAAI,KAAK,OAAO,eAAe;AAQjF,IAAM,uBAAuB;AAoC7B,eAAsB,QAClB,KACA,SACe;AACjB,QAAM;AAAA;AAAA,IAEJ,YAAY,sBAAsB,QAAQ,KAAK;AAAA;AAAA,IAE/C,QAAQ;AAAA;AAAA,IAER;AAAA,EACF,IAAI,EAAE,GAAG,QAAQ;AAGjB,MAAI,UAAU,MAAM,KAAK,SAAS,EAAE,WAAW,oBAAoB,CAAC;AAGpE,MAAI,YAAY;AACd,eAAW,YAAY,CAAE,UAAW,EAAE,KAAK,GAAG;AAC5C,YAAMA,cAAa,MAAM,KAAK,SAAS,EAAE,WAAW,SAAS,CAAC;AAC9D,gBAAU,MAAM,MAAM,CAAE,SAASA,WAAW,CAAC;AAAA,IAC/C;AAAA,EACF;AAGA,QAAM,WAAW,CAAE,GAAG,QAAQ,cAAc,CAAE,EAAE,IAAI,OAAO,SAAS;AAElE,UAAM,QAAQ,qBAAqB,KAAK,SAAS,IAAI,CAAC;AACtD,QAAI,CAAE;AAAO;AAGb,UAAM,CAAE,EAAE,QAAQ,IAAK,IAAI;AAG3B,UAAM,WAAW,MAAM,GAAG,SAAS,IAAI;AAGvC,WAAO;AAAA,MACL,WAAW,OAAO,WAAW,QAAQ,EAAE,OAAO,QAAQ,EAAE,OAAO;AAAA,MAC/D,UAAU,SAAS,SAAS,MAAM;AAAA,MAClC,QAAQ,SAAS,MAAO;AAAA,MACxB;AAAA,IACF;AAAA,EACF,CAAC;AAGD,QAAM,kBAAkB,MAAM,QAAQ,IAAI,QAAQ,GAC7C,OAAO,CAAC,cAAsC,CAAC,CAAE,SAAS,EAC1D,KAAK,CAAC,GAAG,MAAM,EAAG,SAAS,EAAG,MAAM;AAGzC,QAAM,MAAM,KAAK,IAAI;AACrB,QAAM,YAAY,IAAI,UAA2B,GAAG;AACpD,SAAO,MAAM,UAAU,QAAQ,OAAO,eAAe;AACnD,UAAM,OAAO,MAAM,WAAW,MAAwB,mCAAmC;AACzF,QAAI,OAAO,sBAAsB,KAAM,KAAK,KAAK,CAAC,EAAG,IAAK,CAAC,EAAE;AAE7D,UAAM,QAAQ,WAAW,GAAG,aAAa;AAEzC,QAAI,KAAK,kCAAkC;AAC3C,UAAM,WAAW,MAAM;AAGvB,QAAI,KAAK,wBAAwB,KAAK,aAAa,CAAC,QAAQ;AAC5D,UAAM,WAAW,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SASlB;AAGL,QAAI,KAAK,yBAAyB,KAAK,aAAa,CAAC,QAAQ;AAC7D,UAAM,WAAW,MAAM,0BAA0B;AAGjD,QAAI,KAAK,0BAA0B,KAAK,aAAa,CAAC,QAAQ;AAC9D,UAAM,SAAS,MAAM,MAAM,KAAK,EAAE,MAAM,CAAC;AAGzC,UAAM,UAAU,OAAO,OAAO,CAACC,UAAS,QAAQ;AAC9C,YAAM,EAAE,OAAAC,QAAO,QAAQ,MAAM,WAAW,UAAU,IAAI;AACtD,MAAAD,SAAQ,MAAM,IAAI,EAAE,OAAAC,QAAO,QAAQ,MAAM,WAAW,UAAU;AAC9D,aAAOD;AAAA,IACT,GAAG,CAAC,CAAoE;AAGxE,QAAI,QAAQ;AACZ,eAAW,EAAE,QAAQ,MAAM,UAAU,UAAU,KAAK,gBAAgB;AAClE,YAAM,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,GAAG;AACvC,YAAM,OAAO,QAAQ,MAAM;AAC3B,UAAI,MAAM;AACR,YAAI,UAAU,OAAO,KAAK,SAAS,GAAG;AACpC,gBAAM,YAAY,KAAK,UAAU,YAAY,EAAE,UAAU,GAAG,EAAE,EAAE,QAAQ,KAAK,GAAG;AAChF,cAAI,OAAO,sBAAsB,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,KAAK,cAAc,KAAK,SAAS,CAAC,EAAE,CAAC;AAAA,QACxH,OAAO;AACL,cAAI,MAAM,oBAAoB,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,EAAE;AAC5E,gBAAM,WAAW,UAAU,SAAS,KAAK,EAAE,UAAU,GAAG,CAAC;AACzD,gBAAM,WAAW,OAAO,KAAK,KAAK,SAAS,EAAE,SAAS,KAAK,EAAE,UAAU,GAAG,CAAC;AAC3E,gBAAM,IAAI,MAAM,aAAa,KAAK,IAAI,GAAG,KAAK,IAAI,mBAAmB,QAAQ,0BAA0B,QAAQ,GAAG;AAAA,QACpH;AAAA,MACF,OAAO;AACL,YAAI;AACF,cAAI,OAAO,sBAAsB,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,EAAE;AAC/E,gBAAM,WAAW,MAAM,QAAQ;AAC/B,gBAAM,MAAM,OAAO,EAAE,OAAO,QAAQ,MAAM,UAAU,CAAC;AACrD;AAAA,QACF,SAAS,OAAY;AACnB,cAAI,MAAM,oBAAoB,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,EAAE;AAC5E,gBAAM,UAAU,MAAM,QAAQ,MAAM,IAAI,EAAE,IAAI,CAAC,MAAc,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AAChF,gBAAM,UAAU,oBAAoB,KAAK,IAAI,GAAG,KAAK,IAAI;AAAA,EAAO,OAAO;AACvE,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAGA,QAAI,KAAK,mCAAmC;AAC5C,UAAM,WAAW,OAAO;AAGxB,QAAI,OAAO,WAAW,KAAK,KAAK,CAAC,eAAe,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE;AACvE,WAAO;AAAA,EACT,CAAC,EAAE,QAAQ,MAAM,UAAU,QAAQ,CAAC;AACtC;",
|
|
5
|
+
"names": ["additional", "applied", "group"]
|
|
6
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// serialize.ts
|
|
31
|
+
var serialize_exports = {};
|
|
32
|
+
__export(serialize_exports, {
|
|
33
|
+
serializeSchema: () => serializeSchema
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(serialize_exports);
|
|
36
|
+
var import_pgproxy_client_psql = require("@juit/pgproxy-client-psql");
|
|
37
|
+
var import_pgproxy_types = require("@juit/pgproxy-types");
|
|
38
|
+
var import_typescript = __toESM(require("typescript"));
|
|
39
|
+
var types = __toESM(require("./types.cjs"));
|
|
40
|
+
var exportModifier = import_typescript.default.factory.createModifier(import_typescript.default.SyntaxKind.ExportKeyword);
|
|
41
|
+
var endOfFileToken = import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.EndOfFileToken);
|
|
42
|
+
var oidTypes = {
|
|
43
|
+
/* Basic known types |_oid__|_typname______| */
|
|
44
|
+
[import_pgproxy_types.PGOIDs.bool]: types.booleanType,
|
|
45
|
+
/* | 16 | bool | */
|
|
46
|
+
[import_pgproxy_types.PGOIDs.bytea]: types.uint8ArrayType,
|
|
47
|
+
/* | 17 | bytea | */
|
|
48
|
+
[import_pgproxy_types.PGOIDs.int8]: types.bigintType,
|
|
49
|
+
/* | 20 | int8 | */
|
|
50
|
+
[import_pgproxy_types.PGOIDs.int2]: types.numberType,
|
|
51
|
+
/* | 21 | int2 | */
|
|
52
|
+
[import_pgproxy_types.PGOIDs.int4]: types.numberType,
|
|
53
|
+
/* | 23 | int4 | */
|
|
54
|
+
[import_pgproxy_types.PGOIDs.oid]: types.numberType,
|
|
55
|
+
/* | 26 | oid | */
|
|
56
|
+
[import_pgproxy_types.PGOIDs.json]: types.anyType,
|
|
57
|
+
/* | 114 | json | */
|
|
58
|
+
[import_pgproxy_types.PGOIDs.point]: types.pgPointType,
|
|
59
|
+
/* | 600 | point | */
|
|
60
|
+
[import_pgproxy_types.PGOIDs.float4]: types.numberType,
|
|
61
|
+
/* | 700 | float4 | */
|
|
62
|
+
[import_pgproxy_types.PGOIDs.float8]: types.numberType,
|
|
63
|
+
/* | 701 | float8 | */
|
|
64
|
+
[import_pgproxy_types.PGOIDs.circle]: types.pgCircleType,
|
|
65
|
+
/* | 718 | circle | */
|
|
66
|
+
[import_pgproxy_types.PGOIDs.varchar]: types.stringType,
|
|
67
|
+
/* | 1043 | varchar | */
|
|
68
|
+
[import_pgproxy_types.PGOIDs.timestamp]: types.dateType,
|
|
69
|
+
/* | 1114 | timestamp | */
|
|
70
|
+
[import_pgproxy_types.PGOIDs.timestamptz]: types.dateType,
|
|
71
|
+
/* | 1184 | timestamptz | */
|
|
72
|
+
[import_pgproxy_types.PGOIDs.interval]: types.pgIntervalType,
|
|
73
|
+
/* | 1186 | interval | */
|
|
74
|
+
[import_pgproxy_types.PGOIDs.numeric]: types.stringType,
|
|
75
|
+
/* | 1700 | numeric | */
|
|
76
|
+
[import_pgproxy_types.PGOIDs.jsonb]: types.anyType,
|
|
77
|
+
/* | 3802 | jsonb | */
|
|
78
|
+
/* Special types |_oid__|_typname______| */
|
|
79
|
+
[import_pgproxy_types.PGOIDs.void]: types.voidType,
|
|
80
|
+
/* | 2278 | void | */
|
|
81
|
+
[import_pgproxy_types.PGOIDs.xid]: types.numberType,
|
|
82
|
+
/* | 28 | xid | */
|
|
83
|
+
[import_pgproxy_types.PGOIDs.xid8]: types.bigintType,
|
|
84
|
+
/* | 5069 | xid8 | */
|
|
85
|
+
[import_pgproxy_types.PGOIDs._xid]: types.numberArrayType,
|
|
86
|
+
/* | 1011 | _xid | */
|
|
87
|
+
[import_pgproxy_types.PGOIDs._xid8]: types.bigintArrayType,
|
|
88
|
+
/* | 271 | _xid8 | */
|
|
89
|
+
/* Native array types of the above |_oid__|_typname______| */
|
|
90
|
+
[import_pgproxy_types.PGOIDs._bool]: types.booleanArrayType,
|
|
91
|
+
/* | 1000 | _bool | */
|
|
92
|
+
[import_pgproxy_types.PGOIDs._bytea]: types.uint8ArrayArrayType,
|
|
93
|
+
/* | 1001 | _bytea | */
|
|
94
|
+
[import_pgproxy_types.PGOIDs._int8]: types.bigintArrayType,
|
|
95
|
+
/* | 1016 | _int8 | */
|
|
96
|
+
[import_pgproxy_types.PGOIDs._int2]: types.numberArrayType,
|
|
97
|
+
/* | 1005 | _int2 | */
|
|
98
|
+
[import_pgproxy_types.PGOIDs._int4]: types.numberArrayType,
|
|
99
|
+
/* | 1007 | _int4 | */
|
|
100
|
+
[import_pgproxy_types.PGOIDs._oid]: types.numberArrayType,
|
|
101
|
+
/* | 1028 | _oid | */
|
|
102
|
+
[import_pgproxy_types.PGOIDs._json]: types.anyArrayType,
|
|
103
|
+
/* | 199 | _json | */
|
|
104
|
+
[import_pgproxy_types.PGOIDs._point]: types.pgPointArrayType,
|
|
105
|
+
/* | 1017 | _point | */
|
|
106
|
+
[import_pgproxy_types.PGOIDs._float4]: types.numberArrayType,
|
|
107
|
+
/* | 1021 | _float4 | */
|
|
108
|
+
[import_pgproxy_types.PGOIDs._float8]: types.numberArrayType,
|
|
109
|
+
/* | 1022 | _float8 | */
|
|
110
|
+
[import_pgproxy_types.PGOIDs._circle]: types.pgCircleArrayType,
|
|
111
|
+
/* | 719 | _circle | */
|
|
112
|
+
[import_pgproxy_types.PGOIDs._timestamp]: types.dateArrayType,
|
|
113
|
+
/* | 1115 | _timestamp | */
|
|
114
|
+
[import_pgproxy_types.PGOIDs._timestamptz]: types.dateArrayType,
|
|
115
|
+
/* | 1185 | _timestamptz | */
|
|
116
|
+
[import_pgproxy_types.PGOIDs._interval]: types.pgIntervalArrayType,
|
|
117
|
+
/* | 1187 | _interval | */
|
|
118
|
+
[import_pgproxy_types.PGOIDs._numeric]: types.stringArrayType,
|
|
119
|
+
/* | 1231 | _numeric | */
|
|
120
|
+
[import_pgproxy_types.PGOIDs._jsonb]: types.anyArrayType,
|
|
121
|
+
/* | 3807 | _jsonb | */
|
|
122
|
+
/* Other known array types |_oid__|_typname______| */
|
|
123
|
+
[import_pgproxy_types.PGOIDs._cidr]: types.stringArrayType,
|
|
124
|
+
/* | 651 | _cidr | */
|
|
125
|
+
[import_pgproxy_types.PGOIDs._money]: types.stringArrayType,
|
|
126
|
+
/* | 791 | _money | */
|
|
127
|
+
[import_pgproxy_types.PGOIDs._regproc]: types.stringArrayType,
|
|
128
|
+
/* | 1008 | _regproc | */
|
|
129
|
+
[import_pgproxy_types.PGOIDs._text]: types.stringArrayType,
|
|
130
|
+
/* | 1009 | _text | */
|
|
131
|
+
[import_pgproxy_types.PGOIDs._bpchar]: types.stringArrayType,
|
|
132
|
+
/* | 1014 | _bpchar | */
|
|
133
|
+
[import_pgproxy_types.PGOIDs._varchar]: types.stringArrayType,
|
|
134
|
+
/* | 1015 | _varchar | */
|
|
135
|
+
[import_pgproxy_types.PGOIDs._macaddr]: types.stringArrayType,
|
|
136
|
+
/* | 1040 | _macaddr | */
|
|
137
|
+
[import_pgproxy_types.PGOIDs._inet]: types.stringArrayType,
|
|
138
|
+
/* | 1041 | _inet | */
|
|
139
|
+
[import_pgproxy_types.PGOIDs._date]: types.stringArrayType,
|
|
140
|
+
/* | 1182 | _date | */
|
|
141
|
+
[import_pgproxy_types.PGOIDs._time]: types.stringArrayType,
|
|
142
|
+
/* | 1183 | _time | */
|
|
143
|
+
[import_pgproxy_types.PGOIDs._timetz]: types.stringArrayType,
|
|
144
|
+
/* | 1270 | _timetz | */
|
|
145
|
+
[import_pgproxy_types.PGOIDs._uuid]: types.stringArrayType,
|
|
146
|
+
/* | 2951 | _uuid | */
|
|
147
|
+
/* Range types |_oid__|_typname______| */
|
|
148
|
+
[import_pgproxy_types.PGOIDs.int4range]: types.numberRangeType,
|
|
149
|
+
/* | 3904 | int4range | */
|
|
150
|
+
[import_pgproxy_types.PGOIDs.numrange]: types.numberRangeType,
|
|
151
|
+
/* | 3906 | numrange | */
|
|
152
|
+
[import_pgproxy_types.PGOIDs.tsrange]: types.dateRangeType,
|
|
153
|
+
/* | 3908 | tsrange | */
|
|
154
|
+
[import_pgproxy_types.PGOIDs.tstzrange]: types.dateRangeType,
|
|
155
|
+
/* | 3910 | tstzrange | */
|
|
156
|
+
[import_pgproxy_types.PGOIDs.daterange]: types.stringRangeType,
|
|
157
|
+
/* | 3912 | daterange | */
|
|
158
|
+
[import_pgproxy_types.PGOIDs.int8range]: types.bigintRangeType,
|
|
159
|
+
/* | 3926 | int8range | */
|
|
160
|
+
/* Array of range types |_oid__|_typname______| */
|
|
161
|
+
[import_pgproxy_types.PGOIDs._int4range]: types.numberRangeArrayType,
|
|
162
|
+
/* | 3905 | _int4range | */
|
|
163
|
+
[import_pgproxy_types.PGOIDs._numrange]: types.numberRangeArrayType,
|
|
164
|
+
/* | 3907 | _numrange | */
|
|
165
|
+
[import_pgproxy_types.PGOIDs._tsrange]: types.dateRangeArrayType,
|
|
166
|
+
/* | 3909 | _tsrange | */
|
|
167
|
+
[import_pgproxy_types.PGOIDs._tstzrange]: types.dateRangeArrayType,
|
|
168
|
+
/* | 3911 | _tstzrange | */
|
|
169
|
+
[import_pgproxy_types.PGOIDs._daterange]: types.stringRangeArrayType,
|
|
170
|
+
/* | 3913 | _daterange | */
|
|
171
|
+
[import_pgproxy_types.PGOIDs._int8range]: types.bigintRangeArrayType
|
|
172
|
+
/* | 3927 | _int8range | */
|
|
173
|
+
};
|
|
174
|
+
var trueLiteralTypeNode = import_typescript.default.factory.createLiteralTypeNode(
|
|
175
|
+
import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.TrueKeyword)
|
|
176
|
+
);
|
|
177
|
+
var isNullableSignature = import_typescript.default.factory.createPropertySignature(
|
|
178
|
+
void 0,
|
|
179
|
+
// no modifiers
|
|
180
|
+
"isNullable",
|
|
181
|
+
void 0,
|
|
182
|
+
// no question mark
|
|
183
|
+
trueLiteralTypeNode
|
|
184
|
+
);
|
|
185
|
+
var hasDefaultSignature = import_typescript.default.factory.createPropertySignature(
|
|
186
|
+
void 0,
|
|
187
|
+
// no modifiers
|
|
188
|
+
"hasDefault",
|
|
189
|
+
void 0,
|
|
190
|
+
// no question mark
|
|
191
|
+
trueLiteralTypeNode
|
|
192
|
+
);
|
|
193
|
+
function serializeSchema(schema, id = "Schema", overrides = {}) {
|
|
194
|
+
const tables = [];
|
|
195
|
+
for (const [tableName, table] of Object.entries(schema)) {
|
|
196
|
+
const columns = [];
|
|
197
|
+
for (const [columnName, column] of Object.entries(table)) {
|
|
198
|
+
let typeNode;
|
|
199
|
+
if (column.oid in overrides) {
|
|
200
|
+
typeNode = overrides[column.oid];
|
|
201
|
+
} else if (column.oid in oidTypes) {
|
|
202
|
+
typeNode = oidTypes[column.oid];
|
|
203
|
+
} else if (column.enumValues) {
|
|
204
|
+
typeNode = import_typescript.default.factory.createUnionTypeNode(
|
|
205
|
+
column.enumValues.map((value) => import_typescript.default.factory.createLiteralTypeNode(
|
|
206
|
+
import_typescript.default.factory.createStringLiteral(value)
|
|
207
|
+
))
|
|
208
|
+
);
|
|
209
|
+
} else {
|
|
210
|
+
typeNode = types.stringType;
|
|
211
|
+
}
|
|
212
|
+
const typeSignature = import_typescript.default.factory.createPropertySignature(
|
|
213
|
+
void 0,
|
|
214
|
+
// no modifiers
|
|
215
|
+
"type",
|
|
216
|
+
void 0,
|
|
217
|
+
// no question mark
|
|
218
|
+
typeNode
|
|
219
|
+
);
|
|
220
|
+
const definition = [typeSignature];
|
|
221
|
+
if (column.hasDefault)
|
|
222
|
+
definition.push(hasDefaultSignature);
|
|
223
|
+
if (column.isNullable)
|
|
224
|
+
definition.push(isNullableSignature);
|
|
225
|
+
const columnSignature = import_typescript.default.factory.createPropertySignature(
|
|
226
|
+
void 0,
|
|
227
|
+
// no modifiers
|
|
228
|
+
import_typescript.default.factory.createStringLiteral(columnName),
|
|
229
|
+
void 0,
|
|
230
|
+
// no question mark
|
|
231
|
+
import_typescript.default.factory.createTypeLiteralNode(definition)
|
|
232
|
+
);
|
|
233
|
+
if (column.description) {
|
|
234
|
+
import_typescript.default.addSyntheticLeadingComment(
|
|
235
|
+
columnSignature,
|
|
236
|
+
import_typescript.default.SyntaxKind.MultiLineCommentTrivia,
|
|
237
|
+
`* ${column.description} `,
|
|
238
|
+
true
|
|
239
|
+
// trailing newline!
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
columns.push(columnSignature);
|
|
243
|
+
}
|
|
244
|
+
const tableSignature = import_typescript.default.factory.createPropertySignature(
|
|
245
|
+
void 0,
|
|
246
|
+
// modifiers
|
|
247
|
+
import_typescript.default.factory.createStringLiteral(tableName),
|
|
248
|
+
void 0,
|
|
249
|
+
// question mark
|
|
250
|
+
import_typescript.default.factory.createTypeLiteralNode(columns)
|
|
251
|
+
// as any,
|
|
252
|
+
);
|
|
253
|
+
tables.push(tableSignature);
|
|
254
|
+
}
|
|
255
|
+
const declaration = import_typescript.default.factory.createInterfaceDeclaration(
|
|
256
|
+
[exportModifier],
|
|
257
|
+
// export modifier
|
|
258
|
+
id,
|
|
259
|
+
// the name of the schema, "Schema" or whatever we were given
|
|
260
|
+
void 0,
|
|
261
|
+
// no type parameters
|
|
262
|
+
void 0,
|
|
263
|
+
// no heritage clause
|
|
264
|
+
tables
|
|
265
|
+
// all our tables signatures
|
|
266
|
+
);
|
|
267
|
+
const source = import_typescript.default.factory.createSourceFile(
|
|
268
|
+
[declaration],
|
|
269
|
+
endOfFileToken,
|
|
270
|
+
import_typescript.default.NodeFlags.None
|
|
271
|
+
);
|
|
272
|
+
const content = import_typescript.default.createPrinter().printFile(source);
|
|
273
|
+
return content;
|
|
274
|
+
}
|
|
275
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
276
|
+
0 && (module.exports = {
|
|
277
|
+
serializeSchema
|
|
278
|
+
});
|
|
279
|
+
//# sourceMappingURL=serialize.cjs.map
|