@stonyx/orm 0.2.1-beta.82 → 0.2.1-beta.84
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/config/environment.js +17 -0
- package/dist/aggregates.d.ts +21 -0
- package/dist/aggregates.js +90 -0
- package/dist/attr.d.ts +2 -0
- package/dist/attr.js +22 -0
- package/dist/belongs-to.d.ts +11 -0
- package/dist/belongs-to.js +58 -0
- package/dist/cli.d.ts +22 -0
- package/dist/cli.js +148 -0
- package/dist/commands.d.ts +7 -0
- package/dist/commands.js +146 -0
- package/dist/db.d.ts +21 -0
- package/dist/db.js +174 -0
- package/dist/exports/db.d.ts +7 -0
- package/{src → dist}/exports/db.js +2 -4
- package/dist/has-many.d.ts +11 -0
- package/dist/has-many.js +57 -0
- package/dist/hooks.d.ts +47 -0
- package/dist/hooks.js +106 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +34 -0
- package/dist/main.d.ts +46 -0
- package/dist/main.js +178 -0
- package/dist/manage-record.d.ts +13 -0
- package/dist/manage-record.js +113 -0
- package/dist/meta-request.d.ts +6 -0
- package/dist/meta-request.js +52 -0
- package/dist/migrate.d.ts +2 -0
- package/dist/migrate.js +57 -0
- package/dist/model-property.d.ts +9 -0
- package/dist/model-property.js +29 -0
- package/dist/model.d.ts +15 -0
- package/dist/model.js +18 -0
- package/dist/mysql/connection.d.ts +14 -0
- package/dist/mysql/connection.js +24 -0
- package/dist/mysql/migration-generator.d.ts +45 -0
- package/dist/mysql/migration-generator.js +245 -0
- package/dist/mysql/migration-runner.d.ts +12 -0
- package/dist/mysql/migration-runner.js +83 -0
- package/dist/mysql/mysql-db.d.ts +100 -0
- package/dist/mysql/mysql-db.js +411 -0
- package/dist/mysql/query-builder.d.ts +10 -0
- package/dist/mysql/query-builder.js +44 -0
- package/dist/mysql/schema-introspector.d.ts +19 -0
- package/dist/mysql/schema-introspector.js +286 -0
- package/dist/mysql/type-map.d.ts +21 -0
- package/dist/mysql/type-map.js +36 -0
- package/dist/orm-request.d.ts +38 -0
- package/dist/orm-request.js +453 -0
- package/dist/plural-registry.d.ts +4 -0
- package/{src → dist}/plural-registry.js +3 -6
- package/dist/postgres/connection.d.ts +15 -0
- package/dist/postgres/connection.js +30 -0
- package/dist/postgres/migration-generator.d.ts +45 -0
- package/dist/postgres/migration-generator.js +257 -0
- package/dist/postgres/migration-runner.d.ts +10 -0
- package/dist/postgres/migration-runner.js +82 -0
- package/dist/postgres/postgres-db.d.ts +119 -0
- package/dist/postgres/postgres-db.js +473 -0
- package/dist/postgres/query-builder.d.ts +27 -0
- package/dist/postgres/query-builder.js +98 -0
- package/dist/postgres/schema-introspector.d.ts +29 -0
- package/dist/postgres/schema-introspector.js +309 -0
- package/dist/postgres/type-map.d.ts +23 -0
- package/dist/postgres/type-map.js +53 -0
- package/dist/record.d.ts +75 -0
- package/dist/record.js +115 -0
- package/dist/relationships.d.ts +10 -0
- package/dist/relationships.js +35 -0
- package/dist/serializer.d.ts +17 -0
- package/dist/serializer.js +130 -0
- package/dist/setup-rest-server.d.ts +1 -0
- package/dist/setup-rest-server.js +54 -0
- package/dist/standalone-db.d.ts +58 -0
- package/dist/standalone-db.js +142 -0
- package/dist/store.d.ts +62 -0
- package/dist/store.js +271 -0
- package/dist/timescale/query-builder.d.ts +41 -0
- package/dist/timescale/query-builder.js +87 -0
- package/dist/timescale/timescale-db.d.ts +44 -0
- package/dist/timescale/timescale-db.js +81 -0
- package/dist/transforms.d.ts +2 -0
- package/dist/transforms.js +17 -0
- package/dist/types/orm-types.d.ts +142 -0
- package/dist/types/orm-types.js +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +13 -0
- package/dist/view-resolver.d.ts +8 -0
- package/dist/view-resolver.js +165 -0
- package/dist/view.d.ts +11 -0
- package/dist/view.js +18 -0
- package/package.json +34 -11
- package/src/{aggregates.js → aggregates.ts} +27 -13
- package/src/{attr.js → attr.ts} +2 -2
- package/src/{belongs-to.js → belongs-to.ts} +36 -17
- package/src/{cli.js → cli.ts} +17 -11
- package/src/{commands.js → commands.ts} +179 -170
- package/src/{db.js → db.ts} +35 -26
- package/src/exports/db.ts +7 -0
- package/src/has-many.ts +91 -0
- package/src/{hooks.js → hooks.ts} +23 -27
- package/src/{index.js → index.ts} +4 -4
- package/src/{main.js → main.ts} +64 -34
- package/src/{manage-record.js → manage-record.ts} +41 -22
- package/src/{meta-request.js → meta-request.ts} +17 -14
- package/src/{migrate.js → migrate.ts} +9 -9
- package/src/{model-property.js → model-property.ts} +12 -6
- package/src/{model.js → model.ts} +5 -4
- package/src/mysql/{connection.js → connection.ts} +43 -28
- package/src/mysql/{migration-generator.js → migration-generator.ts} +332 -286
- package/src/mysql/{migration-runner.js → migration-runner.ts} +116 -110
- package/src/mysql/{mysql-db.js → mysql-db.ts} +533 -473
- package/src/mysql/{query-builder.js → query-builder.ts} +69 -64
- package/src/mysql/{schema-introspector.js → schema-introspector.ts} +355 -325
- package/src/mysql/{type-map.js → type-map.ts} +42 -37
- package/src/{orm-request.js → orm-request.ts} +165 -95
- package/src/plural-registry.ts +12 -0
- package/src/postgres/connection.ts +46 -0
- package/src/postgres/{migration-generator.js → migration-generator.ts} +82 -38
- package/src/postgres/{migration-runner.js → migration-runner.ts} +11 -10
- package/src/postgres/{postgres-db.js → postgres-db.ts} +199 -111
- package/src/postgres/{query-builder.js → query-builder.ts} +27 -28
- package/src/postgres/{schema-introspector.js → schema-introspector.ts} +87 -58
- package/src/postgres/{type-map.js → type-map.ts} +10 -6
- package/src/{record.js → record.ts} +73 -34
- package/src/relationships.ts +48 -0
- package/src/{serializer.js → serializer.ts} +44 -36
- package/src/{setup-rest-server.js → setup-rest-server.ts} +18 -13
- package/src/{standalone-db.js → standalone-db.ts} +33 -24
- package/src/{store.js → store.ts} +90 -68
- package/src/timescale/query-builder.ts +137 -0
- package/src/timescale/timescale-db.ts +107 -0
- package/src/transforms.ts +20 -0
- package/src/types/mysql2.d.ts +30 -0
- package/src/types/orm-types.ts +146 -0
- package/src/types/pg.d.ts +28 -0
- package/src/types/stonyx-cron.d.ts +5 -0
- package/src/types/stonyx-events.d.ts +4 -0
- package/src/types/stonyx-rest-server.d.ts +11 -0
- package/src/types/stonyx-utils.d.ts +33 -0
- package/src/types/stonyx.d.ts +21 -0
- package/src/utils.ts +16 -0
- package/src/{view-resolver.js → view-resolver.ts} +53 -28
- package/src/view.ts +22 -0
- package/src/has-many.js +0 -68
- package/src/postgres/connection.js +0 -30
- package/src/relationships.js +0 -43
- package/src/transforms.js +0 -20
- package/src/utils.js +0 -12
- package/src/view.js +0 -21
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Pool as PgPool } from 'pg';
|
|
2
|
+
|
|
3
|
+
interface PgConfig {
|
|
4
|
+
host: string;
|
|
5
|
+
port: number;
|
|
6
|
+
user: string;
|
|
7
|
+
password: string;
|
|
8
|
+
database: string;
|
|
9
|
+
connectionLimit: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let pool: PgPool | null = null;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Create or return the singleton pg Pool.
|
|
16
|
+
*/
|
|
17
|
+
export async function getPool(pgConfig: PgConfig, extensions: string[] = ['vector']): Promise<PgPool> {
|
|
18
|
+
if (pool) return pool;
|
|
19
|
+
|
|
20
|
+
const { default: pg } = await import('pg');
|
|
21
|
+
|
|
22
|
+
pool = new pg.Pool({
|
|
23
|
+
host: pgConfig.host,
|
|
24
|
+
port: pgConfig.port,
|
|
25
|
+
user: pgConfig.user,
|
|
26
|
+
password: pgConfig.password,
|
|
27
|
+
database: pgConfig.database,
|
|
28
|
+
max: pgConfig.connectionLimit,
|
|
29
|
+
idleTimeoutMillis: 30000,
|
|
30
|
+
connectionTimeoutMillis: 10000,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Enable requested PostgreSQL extensions
|
|
34
|
+
for (const ext of extensions) {
|
|
35
|
+
await pool.query(`CREATE EXTENSION IF NOT EXISTS ${ext}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return pool;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function closePool(): Promise<void> {
|
|
42
|
+
if (!pool) return;
|
|
43
|
+
|
|
44
|
+
await pool.end();
|
|
45
|
+
pool = null;
|
|
46
|
+
}
|
|
@@ -3,9 +3,53 @@ import { readFile, createFile, createDirectory, fileExists } from '@stonyx/utils
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import config from 'stonyx/config';
|
|
5
5
|
import log from 'stonyx/log';
|
|
6
|
+
import type { ForeignKeyDef, SnapshotEntry } from '../types/orm-types.js';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
interface ColumnChange {
|
|
9
|
+
model: string;
|
|
10
|
+
column: string;
|
|
11
|
+
type: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ColumnTypeChange {
|
|
15
|
+
model: string;
|
|
16
|
+
column: string;
|
|
17
|
+
from: string;
|
|
18
|
+
to: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ForeignKeyChange {
|
|
22
|
+
model: string;
|
|
23
|
+
column: string;
|
|
24
|
+
references: ForeignKeyDef;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface DiffResult {
|
|
28
|
+
hasChanges: boolean;
|
|
29
|
+
addedModels: string[];
|
|
30
|
+
removedModels: string[];
|
|
31
|
+
addedColumns: ColumnChange[];
|
|
32
|
+
removedColumns: ColumnChange[];
|
|
33
|
+
changedColumns: ColumnTypeChange[];
|
|
34
|
+
addedForeignKeys: ForeignKeyChange[];
|
|
35
|
+
removedForeignKeys: ForeignKeyChange[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface ViewDiffResult {
|
|
39
|
+
hasChanges: boolean;
|
|
40
|
+
addedViews: string[];
|
|
41
|
+
removedViews: string[];
|
|
42
|
+
changedViews: string[];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface MigrationResult {
|
|
46
|
+
filename: string;
|
|
47
|
+
content: string;
|
|
48
|
+
snapshot: Record<string, unknown>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function generateMigration(description: string = 'migration', configKey: string = 'postgres'): Promise<MigrationResult | null> {
|
|
52
|
+
const { migrationsDir } = config.orm[configKey] as { migrationsDir: string };
|
|
9
53
|
const rootPath = config.rootPath;
|
|
10
54
|
const migrationsPath = path.resolve(rootPath, migrationsDir);
|
|
11
55
|
|
|
@@ -13,10 +57,10 @@ export async function generateMigration(description = 'migration') {
|
|
|
13
57
|
|
|
14
58
|
const schemas = introspectModels();
|
|
15
59
|
const currentSnapshot = schemasToSnapshot(schemas);
|
|
16
|
-
const previousSnapshot = await loadLatestSnapshot(migrationsPath)
|
|
60
|
+
const previousSnapshot = await loadLatestSnapshot(migrationsPath) as Record<string, SnapshotEntry>;
|
|
17
61
|
const diff = diffSnapshots(previousSnapshot, currentSnapshot);
|
|
18
62
|
|
|
19
|
-
// Don't return early
|
|
63
|
+
// Don't return early -- check view changes too before deciding
|
|
20
64
|
if (!diff.hasChanges) {
|
|
21
65
|
const viewSchemasPrelim = introspectViews();
|
|
22
66
|
const currentViewSnapshotPrelim = viewSchemasToSnapshot(viewSchemasPrelim);
|
|
@@ -24,20 +68,20 @@ export async function generateMigration(description = 'migration') {
|
|
|
24
68
|
const viewDiffPrelim = diffViewSnapshots(previousViewSnapshotPrelim, currentViewSnapshotPrelim);
|
|
25
69
|
|
|
26
70
|
if (!viewDiffPrelim.hasChanges) {
|
|
27
|
-
log.db('No schema changes detected.');
|
|
71
|
+
log.db!('No schema changes detected.');
|
|
28
72
|
return null;
|
|
29
73
|
}
|
|
30
74
|
}
|
|
31
75
|
|
|
32
|
-
const upStatements = [];
|
|
33
|
-
const downStatements = [];
|
|
76
|
+
const upStatements: string[] = [];
|
|
77
|
+
const downStatements: string[] = [];
|
|
34
78
|
|
|
35
79
|
// pgvector extension (include in initial migration)
|
|
36
80
|
if (Object.keys(previousSnapshot).length === 0) {
|
|
37
81
|
upStatements.push('CREATE EXTENSION IF NOT EXISTS vector;');
|
|
38
82
|
}
|
|
39
83
|
|
|
40
|
-
// New tables
|
|
84
|
+
// New tables -- in topological order (parents before children)
|
|
41
85
|
const allOrder = getTopologicalOrder(schemas);
|
|
42
86
|
const addedOrdered = allOrder.filter(name => diff.addedModels.includes(name));
|
|
43
87
|
|
|
@@ -74,7 +118,7 @@ export async function generateMigration(description = 'migration') {
|
|
|
74
118
|
|
|
75
119
|
// Removed columns
|
|
76
120
|
for (const { model, column, type } of diff.removedColumns) {
|
|
77
|
-
const table = previousSnapshot[model].table
|
|
121
|
+
const table = previousSnapshot[model].table!;
|
|
78
122
|
upStatements.push(`ALTER TABLE "${table}" DROP COLUMN "${column}";`);
|
|
79
123
|
downStatements.push(`ALTER TABLE "${table}" ADD COLUMN "${column}" ${type};`);
|
|
80
124
|
}
|
|
@@ -100,7 +144,7 @@ export async function generateMigration(description = 'migration') {
|
|
|
100
144
|
|
|
101
145
|
// Removed foreign keys
|
|
102
146
|
for (const { model, column, references } of diff.removedForeignKeys) {
|
|
103
|
-
const table = previousSnapshot[model].table
|
|
147
|
+
const table = previousSnapshot[model].table!;
|
|
104
148
|
const refModel = Object.entries(previousSnapshot).find(([, s]) => s.table === references.references);
|
|
105
149
|
const fkType = refModel && refModel[1].idType === 'string' ? 'VARCHAR(255)' : 'INTEGER';
|
|
106
150
|
const constraintName = `fk_${table}_${column}`;
|
|
@@ -110,7 +154,7 @@ export async function generateMigration(description = 'migration') {
|
|
|
110
154
|
downStatements.push(`ALTER TABLE "${table}" ADD CONSTRAINT "${constraintName}" FOREIGN KEY ("${column}") REFERENCES "${references.references}"("${references.column}") ON DELETE SET NULL;`);
|
|
111
155
|
}
|
|
112
156
|
|
|
113
|
-
// View migrations
|
|
157
|
+
// View migrations -- views are created AFTER tables (dependency order)
|
|
114
158
|
const viewSchemas = introspectViews();
|
|
115
159
|
const currentViewSnapshot = viewSchemasToSnapshot(viewSchemas);
|
|
116
160
|
const previousViewSnapshot = extractViewsFromSnapshot(previousSnapshot);
|
|
@@ -129,7 +173,7 @@ export async function generateMigration(description = 'migration') {
|
|
|
129
173
|
upStatements.push(ddl + ';');
|
|
130
174
|
downStatements.unshift(`DROP VIEW IF EXISTS "${viewSchemas[name].viewName}";`);
|
|
131
175
|
} catch (error) {
|
|
132
|
-
upStatements.push(`-- WARNING: Could not generate DDL for view '${name}': ${error.message}`);
|
|
176
|
+
upStatements.push(`-- WARNING: Could not generate DDL for view '${name}': ${error instanceof Error ? error.message : String(error)}`);
|
|
133
177
|
}
|
|
134
178
|
}
|
|
135
179
|
|
|
@@ -146,7 +190,7 @@ export async function generateMigration(description = 'migration') {
|
|
|
146
190
|
const ddl = buildViewDDL(name, viewSchemas[name], schemas);
|
|
147
191
|
upStatements.push(ddl + ';');
|
|
148
192
|
} catch (error) {
|
|
149
|
-
upStatements.push(`-- WARNING: Could not generate DDL for changed view '${name}': ${error.message}`);
|
|
193
|
+
upStatements.push(`-- WARNING: Could not generate DDL for changed view '${name}': ${error instanceof Error ? error.message : String(error)}`);
|
|
150
194
|
}
|
|
151
195
|
}
|
|
152
196
|
}
|
|
@@ -154,12 +198,12 @@ export async function generateMigration(description = 'migration') {
|
|
|
154
198
|
const combinedHasChanges = diff.hasChanges || viewDiff.hasChanges;
|
|
155
199
|
|
|
156
200
|
if (!combinedHasChanges) {
|
|
157
|
-
log.db('No schema changes detected.');
|
|
201
|
+
log.db!('No schema changes detected.');
|
|
158
202
|
return null;
|
|
159
203
|
}
|
|
160
204
|
|
|
161
205
|
// Merge view snapshot into the main snapshot
|
|
162
|
-
const combinedSnapshot = { ...currentSnapshot };
|
|
206
|
+
const combinedSnapshot: Record<string, unknown> = { ...currentSnapshot };
|
|
163
207
|
for (const [name, viewSnap] of Object.entries(currentViewSnapshot)) {
|
|
164
208
|
combinedSnapshot[name] = viewSnap;
|
|
165
209
|
}
|
|
@@ -172,28 +216,28 @@ export async function generateMigration(description = 'migration') {
|
|
|
172
216
|
await createFile(path.join(migrationsPath, filename), content);
|
|
173
217
|
await createFile(path.join(migrationsPath, '.snapshot.json'), JSON.stringify(combinedSnapshot, null, 2));
|
|
174
218
|
|
|
175
|
-
log.db(`Migration generated: ${filename}`);
|
|
219
|
+
log.db!(`Migration generated: ${filename}`);
|
|
176
220
|
|
|
177
221
|
return { filename, content, snapshot: combinedSnapshot };
|
|
178
222
|
}
|
|
179
223
|
|
|
180
|
-
export async function loadLatestSnapshot(migrationsPath) {
|
|
224
|
+
export async function loadLatestSnapshot(migrationsPath: string): Promise<Record<string, unknown>> {
|
|
181
225
|
const snapshotPath = path.join(migrationsPath, '.snapshot.json');
|
|
182
226
|
const exists = await fileExists(snapshotPath);
|
|
183
227
|
|
|
184
228
|
if (!exists) return {};
|
|
185
229
|
|
|
186
|
-
return readFile(snapshotPath, { json: true })
|
|
230
|
+
return readFile(snapshotPath, { json: true }) as Promise<Record<string, unknown>>;
|
|
187
231
|
}
|
|
188
232
|
|
|
189
|
-
export function diffSnapshots(previous, current) {
|
|
190
|
-
const addedModels = [];
|
|
191
|
-
const removedModels = [];
|
|
192
|
-
const addedColumns = [];
|
|
193
|
-
const removedColumns = [];
|
|
194
|
-
const changedColumns = [];
|
|
195
|
-
const addedForeignKeys = [];
|
|
196
|
-
const removedForeignKeys = [];
|
|
233
|
+
export function diffSnapshots(previous: Record<string, SnapshotEntry>, current: Record<string, SnapshotEntry>): DiffResult {
|
|
234
|
+
const addedModels: string[] = [];
|
|
235
|
+
const removedModels: string[] = [];
|
|
236
|
+
const addedColumns: ColumnChange[] = [];
|
|
237
|
+
const removedColumns: ColumnChange[] = [];
|
|
238
|
+
const changedColumns: ColumnTypeChange[] = [];
|
|
239
|
+
const addedForeignKeys: ForeignKeyChange[] = [];
|
|
240
|
+
const removedForeignKeys: ForeignKeyChange[] = [];
|
|
197
241
|
|
|
198
242
|
// Find added models
|
|
199
243
|
for (const name of Object.keys(current)) {
|
|
@@ -209,8 +253,8 @@ export function diffSnapshots(previous, current) {
|
|
|
209
253
|
for (const name of Object.keys(current)) {
|
|
210
254
|
if (!previous[name]) continue;
|
|
211
255
|
|
|
212
|
-
const
|
|
213
|
-
const
|
|
256
|
+
const prevCols: Record<string, string> = previous[name].columns || {};
|
|
257
|
+
const currCols: Record<string, string> = current[name].columns || {};
|
|
214
258
|
|
|
215
259
|
// Added columns
|
|
216
260
|
for (const [col, type] of Object.entries(currCols)) {
|
|
@@ -229,8 +273,8 @@ export function diffSnapshots(previous, current) {
|
|
|
229
273
|
}
|
|
230
274
|
|
|
231
275
|
// Foreign key changes
|
|
232
|
-
const prevFKs = previous[name].foreignKeys || {};
|
|
233
|
-
const currFKs = current[name].foreignKeys || {};
|
|
276
|
+
const prevFKs: Record<string, ForeignKeyDef> = previous[name].foreignKeys || {};
|
|
277
|
+
const currFKs: Record<string, ForeignKeyDef> = current[name].foreignKeys || {};
|
|
234
278
|
|
|
235
279
|
for (const [col, refs] of Object.entries(currFKs)) {
|
|
236
280
|
if (!prevFKs[col]) {
|
|
@@ -261,23 +305,23 @@ export function diffSnapshots(previous, current) {
|
|
|
261
305
|
};
|
|
262
306
|
}
|
|
263
307
|
|
|
264
|
-
export function detectSchemaDrift(schemas, snapshot) {
|
|
265
|
-
const current = schemasToSnapshot(schemas);
|
|
308
|
+
export function detectSchemaDrift(schemas: Record<string, unknown>, snapshot: Record<string, SnapshotEntry>): DiffResult {
|
|
309
|
+
const current = schemasToSnapshot(schemas as Parameters<typeof schemasToSnapshot>[0]);
|
|
266
310
|
return diffSnapshots(snapshot, current);
|
|
267
311
|
}
|
|
268
312
|
|
|
269
|
-
export function extractViewsFromSnapshot(snapshot) {
|
|
270
|
-
const views = {};
|
|
313
|
+
export function extractViewsFromSnapshot(snapshot: Record<string, SnapshotEntry>): Record<string, SnapshotEntry> {
|
|
314
|
+
const views: Record<string, SnapshotEntry> = {};
|
|
271
315
|
for (const [name, entry] of Object.entries(snapshot)) {
|
|
272
316
|
if (entry.isView) views[name] = entry;
|
|
273
317
|
}
|
|
274
318
|
return views;
|
|
275
319
|
}
|
|
276
320
|
|
|
277
|
-
export function diffViewSnapshots(previous, current) {
|
|
278
|
-
const addedViews = [];
|
|
279
|
-
const removedViews = [];
|
|
280
|
-
const changedViews = [];
|
|
321
|
+
export function diffViewSnapshots(previous: Record<string, SnapshotEntry>, current: Record<string, SnapshotEntry>): ViewDiffResult {
|
|
322
|
+
const addedViews: string[] = [];
|
|
323
|
+
const removedViews: string[] = [];
|
|
324
|
+
const changedViews: string[] = [];
|
|
281
325
|
|
|
282
326
|
for (const name of Object.keys(current)) {
|
|
283
327
|
if (!previous[name]) {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { readFile, fileExists } from '@stonyx/utils/file';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import fs from 'fs/promises';
|
|
4
|
+
import type { Pool, PoolClient } from 'pg';
|
|
4
5
|
|
|
5
|
-
export async function ensureMigrationsTable(pool, tableName = '__migrations') {
|
|
6
|
+
export async function ensureMigrationsTable(pool: Pool, tableName: string = '__migrations'): Promise<void> {
|
|
6
7
|
await pool.query(`
|
|
7
8
|
CREATE TABLE IF NOT EXISTS "${tableName}" (
|
|
8
9
|
id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
@@ -12,15 +13,15 @@ export async function ensureMigrationsTable(pool, tableName = '__migrations') {
|
|
|
12
13
|
`);
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
export async function getAppliedMigrations(pool, tableName = '__migrations') {
|
|
16
|
+
export async function getAppliedMigrations(pool: Pool, tableName: string = '__migrations'): Promise<string[]> {
|
|
16
17
|
const result = await pool.query(
|
|
17
18
|
`SELECT filename FROM "${tableName}" ORDER BY id ASC`
|
|
18
19
|
);
|
|
19
20
|
|
|
20
|
-
return result.rows.map(row => row.filename);
|
|
21
|
+
return result.rows.map(row => row.filename as string);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
export async function getMigrationFiles(migrationsDir) {
|
|
24
|
+
export async function getMigrationFiles(migrationsDir: string): Promise<string[]> {
|
|
24
25
|
const exists = await fileExists(migrationsDir);
|
|
25
26
|
if (!exists) return [];
|
|
26
27
|
|
|
@@ -31,7 +32,7 @@ export async function getMigrationFiles(migrationsDir) {
|
|
|
31
32
|
.sort();
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
export function parseMigrationFile(content) {
|
|
35
|
+
export function parseMigrationFile(content: string): { up: string; down: string } {
|
|
35
36
|
const upMarker = '-- UP';
|
|
36
37
|
const downMarker = '-- DOWN';
|
|
37
38
|
const upIndex = content.indexOf(upMarker);
|
|
@@ -49,8 +50,8 @@ export function parseMigrationFile(content) {
|
|
|
49
50
|
return { up, down };
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
export async function applyMigration(pool, filename, upSql, tableName = '__migrations') {
|
|
53
|
-
const client = await pool.connect();
|
|
53
|
+
export async function applyMigration(pool: Pool, filename: string, upSql: string, tableName: string = '__migrations'): Promise<void> {
|
|
54
|
+
const client: PoolClient = await pool.connect();
|
|
54
55
|
|
|
55
56
|
try {
|
|
56
57
|
await client.query('BEGIN');
|
|
@@ -75,8 +76,8 @@ export async function applyMigration(pool, filename, upSql, tableName = '__migra
|
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
export async function rollbackMigration(pool, filename, downSql, tableName = '__migrations') {
|
|
79
|
-
const client = await pool.connect();
|
|
79
|
+
export async function rollbackMigration(pool: Pool, filename: string, downSql: string, tableName: string = '__migrations'): Promise<void> {
|
|
80
|
+
const client: PoolClient = await pool.connect();
|
|
80
81
|
|
|
81
82
|
try {
|
|
82
83
|
await client.query('BEGIN');
|
|
@@ -101,7 +102,7 @@ export async function rollbackMigration(pool, filename, downSql, tableName = '__
|
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
|
|
104
|
-
function splitStatements(sql) {
|
|
105
|
+
function splitStatements(sql: string): string[] {
|
|
105
106
|
return sql
|
|
106
107
|
.split(';')
|
|
107
108
|
.map(s => s.trim())
|