@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/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
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,wBAAc,2BAbd;AAcA,wBAAc,0BAdd;AAeA,wBAAc,0BAfd;AAgBA,wBAAc,4BAhBd;AAmBA,cAAyB;AAEzB,YAAuB;",
5
+ "names": []
6
+ }
@@ -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
@@ -0,0 +1,6 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts"],
4
+ "mappings": ";AAaA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,YAAY,aAAa;AAEzB,YAAY,WAAW;",
5
+ "names": []
6
+ }
@@ -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>;
@@ -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": "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",
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