@pgpmjs/export 1.0.2 → 1.1.1

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.
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Generic, deterministic table-data export.
3
+ *
4
+ * Emits INSERT/DELETE/verify SQL for a set of tables so callers can ship row
5
+ * data inside a pgpm change (replayed under `session_replication_role =
6
+ * replica`). This is the shared data-dump capability behind the meta export
7
+ * flow and downstream scoped-plane data exports — column introspection,
8
+ * non-deterministic-default exclusion, and script assembly live here so
9
+ * consumers do not re-implement them.
10
+ *
11
+ * All emitted SQL is built through @constructive-io/query-builder (pg-ast +
12
+ * pgsql-deparser) — no string concatenation, no manual identifier quoting.
13
+ */
14
+ import { cast, col, div, eq, fn, gte, lit, QueryBuilder } from '@constructive-io/query-builder';
15
+ /**
16
+ * Introspect the exportable columns of a table: name, formatted type,
17
+ * default expression, and whether that default depends on a non-immutable
18
+ * function. Single canonical column introspection for data exports.
19
+ */
20
+ export const getDataExportColumns = async (db, schema, table) => {
21
+ const result = await db.query(`
22
+ SELECT a.attname AS name,
23
+ format_type(a.atttypid, a.atttypmod) AS type,
24
+ pg_get_expr(d.adbin, d.adrelid) AS column_default,
25
+ COALESCE((
26
+ SELECT bool_or(p.provolatile <> 'i')
27
+ FROM regexp_matches(d.adbin::text, ':funcid (\\d+)', 'g') m
28
+ JOIN pg_proc p ON p.oid = m[1]::oid
29
+ ), d.adbin::text ~ 'SQLVALUEFUNCTION', false) AS volatile_default
30
+ FROM pg_attribute a
31
+ JOIN pg_class c ON c.oid = a.attrelid
32
+ JOIN pg_namespace n ON n.oid = c.relnamespace
33
+ LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = a.attnum
34
+ WHERE n.nspname = $1 AND c.relname = $2
35
+ AND a.attnum > 0 AND NOT a.attisdropped
36
+ ORDER BY a.attnum
37
+ `, [schema, table]);
38
+ return result.rows.map((row) => ({
39
+ name: row.name,
40
+ type: row.type,
41
+ columnDefault: row.column_default,
42
+ volatileDefault: row.volatile_default
43
+ }));
44
+ };
45
+ /**
46
+ * True for columns whose value must be omitted from exported rows so the DDL
47
+ * DEFAULT re-supplies it at deploy time: timestamp/timestamptz columns whose
48
+ * default depends on a non-immutable function (wall-clock defaults).
49
+ */
50
+ export const isVolatileTimestampColumn = (column) => column.volatileDefault && /^timestamp/.test(column.type);
51
+ const RAW_ID = '__raw_id';
52
+ /**
53
+ * Export a table's rows as a single deterministic INSERT statement.
54
+ * Values are text-cast server-side, emitted as literals re-cast to the
55
+ * column type; rows are ordered by id when present, otherwise by all
56
+ * exported columns, so output is reproducible.
57
+ */
58
+ export const exportTableData = async (db, spec, options = {}) => {
59
+ const excluded = new Set(options.excludeColumns ?? []);
60
+ const allColumns = await getDataExportColumns(db, spec.schema, spec.table);
61
+ const columns = allColumns.filter(c => !excluded.has(c.name) && !isVolatileTimestampColumn(c));
62
+ const base = {
63
+ schema: spec.schema,
64
+ table: spec.table,
65
+ columns,
66
+ rowCount: 0,
67
+ ids: null,
68
+ insert: null
69
+ };
70
+ if (columns.length === 0)
71
+ return base;
72
+ const hasId = columns.some(c => c.name === 'id');
73
+ const selectQb = new QueryBuilder()
74
+ .schema(spec.schema)
75
+ .table(spec.table)
76
+ .select([]);
77
+ for (const c of columns) {
78
+ selectQb.selectExpr(c.name, cast(col(c.name), 'text'));
79
+ }
80
+ if (hasId) {
81
+ selectQb.selectExpr(RAW_ID, cast(col('id'), 'text'));
82
+ selectQb.orderBy(cast(col('id'), 'text'));
83
+ }
84
+ else {
85
+ for (const c of columns) {
86
+ selectQb.orderBy(col(c.name));
87
+ }
88
+ }
89
+ if (spec.filter) {
90
+ selectQb.where({ [spec.filter.column]: { equalTo: spec.filter.value } });
91
+ }
92
+ const { text: selectSql, values: selectValues } = selectQb.build();
93
+ const rowsRes = await db.query(selectSql, selectValues);
94
+ if (rowsRes.rows.length === 0)
95
+ return base;
96
+ const insertQb = new QueryBuilder()
97
+ .schema(spec.schema)
98
+ .table(spec.table)
99
+ .insert(rowsRes.rows.map((row) => Object.fromEntries(columns.map(c => [c.name, cast(lit(row[c.name]), c.type)]))));
100
+ if (options.conflictDoNothing) {
101
+ insertQb.onConflict({ action: 'nothing' });
102
+ }
103
+ return {
104
+ ...base,
105
+ rowCount: rowsRes.rows.length,
106
+ ids: hasId ? rowsRes.rows.map((r) => r[RAW_ID]) : null,
107
+ insert: `${insertQb.build().text};`
108
+ };
109
+ };
110
+ /**
111
+ * Export multiple tables in the given (FK-dependency) order.
112
+ */
113
+ export const exportTablesData = async (db, specs, options = {}) => {
114
+ const results = [];
115
+ for (const spec of specs) {
116
+ results.push(await exportTableData(db, spec, options));
117
+ }
118
+ return results;
119
+ };
120
+ const REPLICA_HEADER = 'SET session_replication_role TO replica;';
121
+ const REPLICA_FOOTER = 'SET session_replication_role TO DEFAULT;';
122
+ const wrapReplica = (body) => [REPLICA_HEADER, '', ...body, '', REPLICA_FOOTER, ''].join('\n');
123
+ /**
124
+ * Assemble the deploy script body: every table's INSERT in dependency order,
125
+ * replayed with triggers/FKs suppressed. Callers prepend the pgpm change
126
+ * header.
127
+ */
128
+ export const buildDataDeployScript = (exports) => {
129
+ const inserts = exports
130
+ .filter(e => e.insert !== null)
131
+ .map(e => e.insert);
132
+ return wrapReplica([inserts.join('\n\n')]);
133
+ };
134
+ /**
135
+ * Assemble the revert script body: per-table DELETEs of the exported rows in
136
+ * reverse dependency order. Tables exported without an id column cannot be
137
+ * precisely reverted and are skipped with a comment.
138
+ */
139
+ export const buildDataRevertScript = (exports) => {
140
+ const statements = [];
141
+ for (const e of [...exports].reverse()) {
142
+ if (e.rowCount === 0)
143
+ continue;
144
+ if (!e.ids) {
145
+ statements.push(`-- ${e.schema}.${e.table}: exported without an id column; rows not reverted`);
146
+ continue;
147
+ }
148
+ const { text } = new QueryBuilder()
149
+ .schema(e.schema)
150
+ .table(e.table)
151
+ .delete()
152
+ .where({ id: { in: e.ids.map(id => lit(id)) } })
153
+ .build();
154
+ statements.push(`${text};`);
155
+ }
156
+ return wrapReplica([statements.join('\n\n')]);
157
+ };
158
+ /**
159
+ * Assemble the verify script body: per-table checks that the exported rows
160
+ * are present (exact id match when ids were exported, row-count floor
161
+ * otherwise). Divide-by-zero style, per pgpm verify conventions.
162
+ */
163
+ export const buildDataVerifyScript = (exports) => {
164
+ const statements = [];
165
+ for (const e of exports) {
166
+ if (e.rowCount === 0)
167
+ continue;
168
+ const countCheck = e.ids ? eq : gte;
169
+ const qb = new QueryBuilder()
170
+ .schema(e.schema)
171
+ .table(e.table)
172
+ .select([])
173
+ .selectExpr('verified', div(lit(1), cast(countCheck(fn('count', [col('*')]), lit(e.rowCount)), 'int')));
174
+ if (e.ids) {
175
+ qb.where({ id: { in: e.ids.map(id => lit(id)) } });
176
+ }
177
+ statements.push(`${qb.build().text};`);
178
+ }
179
+ return statements.join('\n\n') + '\n';
180
+ };
package/esm/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './export-data';
1
2
  export * from './export-meta';
2
3
  export * from './export-migrations';
3
4
  export * from './export-graphql';
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Minimal query interface satisfied by pg.Pool, pg.Client, and test clients.
3
+ */
4
+ export interface Queryable {
5
+ query(text: string, values?: unknown[]): Promise<{
6
+ rows: any[];
7
+ }>;
8
+ }
9
+ export interface DataExportColumn {
10
+ /** Column name. */
11
+ name: string;
12
+ /** Fully formatted SQL type (format_type), used for value casts. */
13
+ type: string;
14
+ /** The column's default expression, if any (pg_get_expr). */
15
+ columnDefault: string | null;
16
+ /**
17
+ * True when the default expression depends on a non-immutable function
18
+ * (now(), CURRENT_TIMESTAMP, clock_timestamp(), gen_random_uuid(), ...).
19
+ * Detected from the compiled default expression's function references
20
+ * (pg_proc.provolatile), not by pattern-matching the expression text.
21
+ */
22
+ volatileDefault: boolean;
23
+ }
24
+ /**
25
+ * Introspect the exportable columns of a table: name, formatted type,
26
+ * default expression, and whether that default depends on a non-immutable
27
+ * function. Single canonical column introspection for data exports.
28
+ */
29
+ export declare const getDataExportColumns: (db: Queryable, schema: string, table: string) => Promise<DataExportColumn[]>;
30
+ /**
31
+ * True for columns whose value must be omitted from exported rows so the DDL
32
+ * DEFAULT re-supplies it at deploy time: timestamp/timestamptz columns whose
33
+ * default depends on a non-immutable function (wall-clock defaults).
34
+ */
35
+ export declare const isVolatileTimestampColumn: (column: DataExportColumn) => boolean;
36
+ export interface DataExportTableSpec {
37
+ schema: string;
38
+ table: string;
39
+ /** Optional equality filter, e.g. { column: 'database_id', value: id }. */
40
+ filter?: {
41
+ column: string;
42
+ value: string;
43
+ };
44
+ }
45
+ export interface ExportTableDataOptions {
46
+ /**
47
+ * Columns excluded from the export in addition to volatile timestamp
48
+ * defaults (e.g. environment-stamped columns like dbname, or trigger
49
+ * maintained stamps like created_at/updated_at).
50
+ */
51
+ excludeColumns?: string[];
52
+ /** Emit ON CONFLICT DO NOTHING on the INSERT. */
53
+ conflictDoNothing?: boolean;
54
+ }
55
+ export interface TableDataExport {
56
+ schema: string;
57
+ table: string;
58
+ /** Columns included in the INSERT, in table order. */
59
+ columns: DataExportColumn[];
60
+ rowCount: number;
61
+ /** Exported id values (text) when an id column is exported, else null. */
62
+ ids: string[] | null;
63
+ /** The INSERT statement, or null when the table had no exportable rows. */
64
+ insert: string | null;
65
+ }
66
+ /**
67
+ * Export a table's rows as a single deterministic INSERT statement.
68
+ * Values are text-cast server-side, emitted as literals re-cast to the
69
+ * column type; rows are ordered by id when present, otherwise by all
70
+ * exported columns, so output is reproducible.
71
+ */
72
+ export declare const exportTableData: (db: Queryable, spec: DataExportTableSpec, options?: ExportTableDataOptions) => Promise<TableDataExport>;
73
+ /**
74
+ * Export multiple tables in the given (FK-dependency) order.
75
+ */
76
+ export declare const exportTablesData: (db: Queryable, specs: DataExportTableSpec[], options?: ExportTableDataOptions) => Promise<TableDataExport[]>;
77
+ /**
78
+ * Assemble the deploy script body: every table's INSERT in dependency order,
79
+ * replayed with triggers/FKs suppressed. Callers prepend the pgpm change
80
+ * header.
81
+ */
82
+ export declare const buildDataDeployScript: (exports: TableDataExport[]) => string;
83
+ /**
84
+ * Assemble the revert script body: per-table DELETEs of the exported rows in
85
+ * reverse dependency order. Tables exported without an id column cannot be
86
+ * precisely reverted and are skipped with a comment.
87
+ */
88
+ export declare const buildDataRevertScript: (exports: TableDataExport[]) => string;
89
+ /**
90
+ * Assemble the verify script body: per-table checks that the exported rows
91
+ * are present (exact id match when ids were exported, row-count floor
92
+ * otherwise). Divide-by-zero style, per pgpm verify conventions.
93
+ */
94
+ export declare const buildDataVerifyScript: (exports: TableDataExport[]) => string;
package/export-data.js ADDED
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildDataVerifyScript = exports.buildDataRevertScript = exports.buildDataDeployScript = exports.exportTablesData = exports.exportTableData = exports.isVolatileTimestampColumn = exports.getDataExportColumns = void 0;
4
+ /**
5
+ * Generic, deterministic table-data export.
6
+ *
7
+ * Emits INSERT/DELETE/verify SQL for a set of tables so callers can ship row
8
+ * data inside a pgpm change (replayed under `session_replication_role =
9
+ * replica`). This is the shared data-dump capability behind the meta export
10
+ * flow and downstream scoped-plane data exports — column introspection,
11
+ * non-deterministic-default exclusion, and script assembly live here so
12
+ * consumers do not re-implement them.
13
+ *
14
+ * All emitted SQL is built through @constructive-io/query-builder (pg-ast +
15
+ * pgsql-deparser) — no string concatenation, no manual identifier quoting.
16
+ */
17
+ const query_builder_1 = require("@constructive-io/query-builder");
18
+ /**
19
+ * Introspect the exportable columns of a table: name, formatted type,
20
+ * default expression, and whether that default depends on a non-immutable
21
+ * function. Single canonical column introspection for data exports.
22
+ */
23
+ const getDataExportColumns = async (db, schema, table) => {
24
+ const result = await db.query(`
25
+ SELECT a.attname AS name,
26
+ format_type(a.atttypid, a.atttypmod) AS type,
27
+ pg_get_expr(d.adbin, d.adrelid) AS column_default,
28
+ COALESCE((
29
+ SELECT bool_or(p.provolatile <> 'i')
30
+ FROM regexp_matches(d.adbin::text, ':funcid (\\d+)', 'g') m
31
+ JOIN pg_proc p ON p.oid = m[1]::oid
32
+ ), d.adbin::text ~ 'SQLVALUEFUNCTION', false) AS volatile_default
33
+ FROM pg_attribute a
34
+ JOIN pg_class c ON c.oid = a.attrelid
35
+ JOIN pg_namespace n ON n.oid = c.relnamespace
36
+ LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = a.attnum
37
+ WHERE n.nspname = $1 AND c.relname = $2
38
+ AND a.attnum > 0 AND NOT a.attisdropped
39
+ ORDER BY a.attnum
40
+ `, [schema, table]);
41
+ return result.rows.map((row) => ({
42
+ name: row.name,
43
+ type: row.type,
44
+ columnDefault: row.column_default,
45
+ volatileDefault: row.volatile_default
46
+ }));
47
+ };
48
+ exports.getDataExportColumns = getDataExportColumns;
49
+ /**
50
+ * True for columns whose value must be omitted from exported rows so the DDL
51
+ * DEFAULT re-supplies it at deploy time: timestamp/timestamptz columns whose
52
+ * default depends on a non-immutable function (wall-clock defaults).
53
+ */
54
+ const isVolatileTimestampColumn = (column) => column.volatileDefault && /^timestamp/.test(column.type);
55
+ exports.isVolatileTimestampColumn = isVolatileTimestampColumn;
56
+ const RAW_ID = '__raw_id';
57
+ /**
58
+ * Export a table's rows as a single deterministic INSERT statement.
59
+ * Values are text-cast server-side, emitted as literals re-cast to the
60
+ * column type; rows are ordered by id when present, otherwise by all
61
+ * exported columns, so output is reproducible.
62
+ */
63
+ const exportTableData = async (db, spec, options = {}) => {
64
+ const excluded = new Set(options.excludeColumns ?? []);
65
+ const allColumns = await (0, exports.getDataExportColumns)(db, spec.schema, spec.table);
66
+ const columns = allColumns.filter(c => !excluded.has(c.name) && !(0, exports.isVolatileTimestampColumn)(c));
67
+ const base = {
68
+ schema: spec.schema,
69
+ table: spec.table,
70
+ columns,
71
+ rowCount: 0,
72
+ ids: null,
73
+ insert: null
74
+ };
75
+ if (columns.length === 0)
76
+ return base;
77
+ const hasId = columns.some(c => c.name === 'id');
78
+ const selectQb = new query_builder_1.QueryBuilder()
79
+ .schema(spec.schema)
80
+ .table(spec.table)
81
+ .select([]);
82
+ for (const c of columns) {
83
+ selectQb.selectExpr(c.name, (0, query_builder_1.cast)((0, query_builder_1.col)(c.name), 'text'));
84
+ }
85
+ if (hasId) {
86
+ selectQb.selectExpr(RAW_ID, (0, query_builder_1.cast)((0, query_builder_1.col)('id'), 'text'));
87
+ selectQb.orderBy((0, query_builder_1.cast)((0, query_builder_1.col)('id'), 'text'));
88
+ }
89
+ else {
90
+ for (const c of columns) {
91
+ selectQb.orderBy((0, query_builder_1.col)(c.name));
92
+ }
93
+ }
94
+ if (spec.filter) {
95
+ selectQb.where({ [spec.filter.column]: { equalTo: spec.filter.value } });
96
+ }
97
+ const { text: selectSql, values: selectValues } = selectQb.build();
98
+ const rowsRes = await db.query(selectSql, selectValues);
99
+ if (rowsRes.rows.length === 0)
100
+ return base;
101
+ const insertQb = new query_builder_1.QueryBuilder()
102
+ .schema(spec.schema)
103
+ .table(spec.table)
104
+ .insert(rowsRes.rows.map((row) => Object.fromEntries(columns.map(c => [c.name, (0, query_builder_1.cast)((0, query_builder_1.lit)(row[c.name]), c.type)]))));
105
+ if (options.conflictDoNothing) {
106
+ insertQb.onConflict({ action: 'nothing' });
107
+ }
108
+ return {
109
+ ...base,
110
+ rowCount: rowsRes.rows.length,
111
+ ids: hasId ? rowsRes.rows.map((r) => r[RAW_ID]) : null,
112
+ insert: `${insertQb.build().text};`
113
+ };
114
+ };
115
+ exports.exportTableData = exportTableData;
116
+ /**
117
+ * Export multiple tables in the given (FK-dependency) order.
118
+ */
119
+ const exportTablesData = async (db, specs, options = {}) => {
120
+ const results = [];
121
+ for (const spec of specs) {
122
+ results.push(await (0, exports.exportTableData)(db, spec, options));
123
+ }
124
+ return results;
125
+ };
126
+ exports.exportTablesData = exportTablesData;
127
+ const REPLICA_HEADER = 'SET session_replication_role TO replica;';
128
+ const REPLICA_FOOTER = 'SET session_replication_role TO DEFAULT;';
129
+ const wrapReplica = (body) => [REPLICA_HEADER, '', ...body, '', REPLICA_FOOTER, ''].join('\n');
130
+ /**
131
+ * Assemble the deploy script body: every table's INSERT in dependency order,
132
+ * replayed with triggers/FKs suppressed. Callers prepend the pgpm change
133
+ * header.
134
+ */
135
+ const buildDataDeployScript = (exports) => {
136
+ const inserts = exports
137
+ .filter(e => e.insert !== null)
138
+ .map(e => e.insert);
139
+ return wrapReplica([inserts.join('\n\n')]);
140
+ };
141
+ exports.buildDataDeployScript = buildDataDeployScript;
142
+ /**
143
+ * Assemble the revert script body: per-table DELETEs of the exported rows in
144
+ * reverse dependency order. Tables exported without an id column cannot be
145
+ * precisely reverted and are skipped with a comment.
146
+ */
147
+ const buildDataRevertScript = (exports) => {
148
+ const statements = [];
149
+ for (const e of [...exports].reverse()) {
150
+ if (e.rowCount === 0)
151
+ continue;
152
+ if (!e.ids) {
153
+ statements.push(`-- ${e.schema}.${e.table}: exported without an id column; rows not reverted`);
154
+ continue;
155
+ }
156
+ const { text } = new query_builder_1.QueryBuilder()
157
+ .schema(e.schema)
158
+ .table(e.table)
159
+ .delete()
160
+ .where({ id: { in: e.ids.map(id => (0, query_builder_1.lit)(id)) } })
161
+ .build();
162
+ statements.push(`${text};`);
163
+ }
164
+ return wrapReplica([statements.join('\n\n')]);
165
+ };
166
+ exports.buildDataRevertScript = buildDataRevertScript;
167
+ /**
168
+ * Assemble the verify script body: per-table checks that the exported rows
169
+ * are present (exact id match when ids were exported, row-count floor
170
+ * otherwise). Divide-by-zero style, per pgpm verify conventions.
171
+ */
172
+ const buildDataVerifyScript = (exports) => {
173
+ const statements = [];
174
+ for (const e of exports) {
175
+ if (e.rowCount === 0)
176
+ continue;
177
+ const countCheck = e.ids ? query_builder_1.eq : query_builder_1.gte;
178
+ const qb = new query_builder_1.QueryBuilder()
179
+ .schema(e.schema)
180
+ .table(e.table)
181
+ .select([])
182
+ .selectExpr('verified', (0, query_builder_1.div)((0, query_builder_1.lit)(1), (0, query_builder_1.cast)(countCheck((0, query_builder_1.fn)('count', [(0, query_builder_1.col)('*')]), (0, query_builder_1.lit)(e.rowCount)), 'int')));
183
+ if (e.ids) {
184
+ qb.where({ id: { in: e.ids.map(id => (0, query_builder_1.lit)(id)) } });
185
+ }
186
+ statements.push(`${qb.build().text};`);
187
+ }
188
+ return statements.join('\n\n') + '\n';
189
+ };
190
+ exports.buildDataVerifyScript = buildDataVerifyScript;
package/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './export-data';
1
2
  export * from './export-meta';
2
3
  export * from './export-migrations';
3
4
  export * from './export-graphql';
package/index.js CHANGED
@@ -15,6 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.parsePgInterval = exports.intervalToPostgres = exports.lookupByGqlType = exports.lookupByPgUdt = exports.PG_TYPE_MAP = exports.installMissingModules = exports.detectMissingModules = exports.normalizeOutdir = exports.preparePackage = exports.makeReplacer = exports.mapPgTypeToFieldType = exports.META_TABLE_OVERRIDES = exports.META_TABLE_CONFIG = exports.META_TABLE_ORDER = exports.META_COMMON_FOOTER = exports.META_COMMON_HEADER = exports.SERVICE_REQUIRED_EXTENSIONS = exports.DB_REQUIRED_EXTENSIONS = exports.unwrapGraphQLType = exports.mapGraphQLTypeToFieldType = exports.buildFieldsFragment = exports.graphqlRowToPostgresRow = exports.getGraphQLTypeName = exports.getGraphQLQueryName = exports.GraphQLClient = void 0;
18
+ __exportStar(require("./export-data"), exports);
18
19
  __exportStar(require("./export-meta"), exports);
19
20
  __exportStar(require("./export-migrations"), exports);
20
21
  __exportStar(require("./export-graphql"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pgpmjs/export",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "author": "Constructive <developers@constructive.io>",
5
5
  "description": "PGPM export tools for SQL and GraphQL database migration extraction",
6
6
  "main": "index.js",
@@ -41,11 +41,12 @@
41
41
  "@pgsql/types": "^18.0.0",
42
42
  "@types/pg": "^8.20.0",
43
43
  "makage": "^0.3.0",
44
- "pgsql-test": "^5.0.2"
44
+ "pgsql-test": "^5.0.4"
45
45
  },
46
46
  "dependencies": {
47
- "@pgpmjs/core": "^7.2.0",
48
- "@pgpmjs/migrate-client": "^1.0.2",
47
+ "@constructive-io/query-builder": "^3.0.1",
48
+ "@pgpmjs/core": "^7.2.2",
49
+ "@pgpmjs/migrate-client": "^1.0.4",
49
50
  "@pgpmjs/types": "^2.35.1",
50
51
  "csv-to-pg": "^4.0.0",
51
52
  "glob": "^13.0.6",
@@ -55,5 +56,5 @@
55
56
  "pg-cache": "^3.15.2",
56
57
  "pg-env": "^1.18.1"
57
58
  },
58
- "gitHead": "15a831fa029544068ee64e3386e4b08715d2b86d"
59
+ "gitHead": "d48f39ebd4b7dcbab22df7c57438c06efd9e223d"
59
60
  }