@lyku/lockstep-pg 0.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.
Files changed (103) hide show
  1. package/LLMs.md +86 -0
  2. package/README.md +93 -0
  3. package/package.json +32 -0
  4. package/src/buildTableIndexCommand.d.ts +3 -0
  5. package/src/buildTableIndexCommand.d.ts.map +1 -0
  6. package/src/buildTableIndexCommand.js +46 -0
  7. package/src/buildTableIndexCommand.js.map +1 -0
  8. package/src/buildTableTriggerCommands.d.ts +3 -0
  9. package/src/buildTableTriggerCommands.d.ts.map +1 -0
  10. package/src/buildTableTriggerCommands.js +23 -0
  11. package/src/buildTableTriggerCommands.js.map +1 -0
  12. package/src/createTable.d.ts +3 -0
  13. package/src/createTable.d.ts.map +1 -0
  14. package/src/createTable.js +46 -0
  15. package/src/createTable.js.map +1 -0
  16. package/src/dateToPostgresString.d.ts +2 -0
  17. package/src/dateToPostgresString.d.ts.map +1 -0
  18. package/src/dateToPostgresString.js +7 -0
  19. package/src/dateToPostgresString.js.map +1 -0
  20. package/src/diff.d.ts +82 -0
  21. package/src/diff.d.ts.map +1 -0
  22. package/src/diff.js +218 -0
  23. package/src/diff.js.map +1 -0
  24. package/src/drift.d.ts +16 -0
  25. package/src/drift.d.ts.map +1 -0
  26. package/src/drift.js +299 -0
  27. package/src/drift.js.map +1 -0
  28. package/src/form.d.ts +3 -0
  29. package/src/form.d.ts.map +1 -0
  30. package/src/form.js +9 -0
  31. package/src/form.js.map +1 -0
  32. package/src/generateSql.d.ts +16 -0
  33. package/src/generateSql.d.ts.map +1 -0
  34. package/src/generateSql.js +306 -0
  35. package/src/generateSql.js.map +1 -0
  36. package/src/index.d.ts +16 -0
  37. package/src/index.d.ts.map +1 -0
  38. package/src/index.js +21 -0
  39. package/src/index.js.map +1 -0
  40. package/src/introspect.d.ts +56 -0
  41. package/src/introspect.d.ts.map +1 -0
  42. package/src/introspect.js +435 -0
  43. package/src/introspect.js.map +1 -0
  44. package/src/mapArrayType.d.ts +3 -0
  45. package/src/mapArrayType.d.ts.map +1 -0
  46. package/src/mapArrayType.js +41 -0
  47. package/src/mapArrayType.js.map +1 -0
  48. package/src/mapBigintType.d.ts +3 -0
  49. package/src/mapBigintType.d.ts.map +1 -0
  50. package/src/mapBigintType.js +17 -0
  51. package/src/mapBigintType.js.map +1 -0
  52. package/src/mapBigserialType.d.ts +3 -0
  53. package/src/mapBigserialType.d.ts.map +1 -0
  54. package/src/mapBigserialType.js +12 -0
  55. package/src/mapBigserialType.js.map +1 -0
  56. package/src/mapCharType.d.ts +3 -0
  57. package/src/mapCharType.d.ts.map +1 -0
  58. package/src/mapCharType.js +22 -0
  59. package/src/mapCharType.js.map +1 -0
  60. package/src/mapColumnType.d.ts +3 -0
  61. package/src/mapColumnType.d.ts.map +1 -0
  62. package/src/mapColumnType.js +63 -0
  63. package/src/mapColumnType.js.map +1 -0
  64. package/src/mapIntegerType.d.ts +3 -0
  65. package/src/mapIntegerType.d.ts.map +1 -0
  66. package/src/mapIntegerType.js +12 -0
  67. package/src/mapIntegerType.js.map +1 -0
  68. package/src/mapSerialType.d.ts +3 -0
  69. package/src/mapSerialType.d.ts.map +1 -0
  70. package/src/mapSerialType.js +12 -0
  71. package/src/mapSerialType.js.map +1 -0
  72. package/src/mapTextType.d.ts +3 -0
  73. package/src/mapTextType.d.ts.map +1 -0
  74. package/src/mapTextType.js +44 -0
  75. package/src/mapTextType.js.map +1 -0
  76. package/src/mapTimestamptzType.d.ts +3 -0
  77. package/src/mapTimestamptzType.d.ts.map +1 -0
  78. package/src/mapTimestamptzType.js +13 -0
  79. package/src/mapTimestamptzType.js.map +1 -0
  80. package/src/mapVarcharType.d.ts +3 -0
  81. package/src/mapVarcharType.d.ts.map +1 -0
  82. package/src/mapVarcharType.js +44 -0
  83. package/src/mapVarcharType.js.map +1 -0
  84. package/src/migrate.d.ts +13 -0
  85. package/src/migrate.d.ts.map +1 -0
  86. package/src/migrate.js +350 -0
  87. package/src/migrate.js.map +1 -0
  88. package/src/numberChecks.d.ts +11 -0
  89. package/src/numberChecks.d.ts.map +1 -0
  90. package/src/numberChecks.js +22 -0
  91. package/src/numberChecks.js.map +1 -0
  92. package/src/seed.d.ts +3 -0
  93. package/src/seed.d.ts.map +1 -0
  94. package/src/seed.js +56 -0
  95. package/src/seed.js.map +1 -0
  96. package/src/setupTable.d.ts +3 -0
  97. package/src/setupTable.d.ts.map +1 -0
  98. package/src/setupTable.js +41 -0
  99. package/src/setupTable.js.map +1 -0
  100. package/src/timestampChecks.d.ts +11 -0
  101. package/src/timestampChecks.d.ts.map +1 -0
  102. package/src/timestampChecks.js +22 -0
  103. package/src/timestampChecks.js.map +1 -0
package/src/diff.js ADDED
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Diff two table models and generate migration operations
3
+ */
4
+ /**
5
+ * Check if two sets of columns match (order-independent)
6
+ */
7
+ function columnsMatch(a, b) {
8
+ if (a.length !== b.length)
9
+ return false;
10
+ const sortedA = [...a].sort();
11
+ const sortedB = [...b].sort();
12
+ // eslint-disable-next-line security/detect-object-injection -- i is a controlled array index
13
+ return sortedA.every((col, i) => col === sortedB[i]);
14
+ }
15
+ /**
16
+ * Check if two enum value arrays are equivalent
17
+ */
18
+ function enumValuesMatch(a, b) {
19
+ if (a === null && b === null)
20
+ return true;
21
+ if (a === null || b === null)
22
+ return false;
23
+ if (a.length !== b.length)
24
+ return false;
25
+ const sortedA = [...a].sort();
26
+ const sortedB = [...b].sort();
27
+ // eslint-disable-next-line security/detect-object-injection -- i is a controlled array index
28
+ return sortedA.every((v, i) => v === sortedB[i]);
29
+ }
30
+ /**
31
+ * Diff a single column
32
+ */
33
+ function diffColumn(tableName, dbCol, codeCol) {
34
+ const ops = [];
35
+ // Column doesn't exist in DB but exists in code -> add
36
+ if (!dbCol && codeCol) {
37
+ ops.push({ type: 'add_column', tableName, column: codeCol });
38
+ return ops;
39
+ }
40
+ // Column exists in DB but not in code -> drop
41
+ if (dbCol && !codeCol) {
42
+ ops.push({ type: 'drop_column', tableName, columnName: dbCol.name });
43
+ return ops;
44
+ }
45
+ // Both exist -> compare properties
46
+ if (dbCol && codeCol) {
47
+ // Type mismatch
48
+ if (dbCol.type !== codeCol.type) {
49
+ ops.push({
50
+ type: 'alter_column_type',
51
+ tableName,
52
+ columnName: dbCol.name,
53
+ fromType: dbCol.type,
54
+ toType: codeCol.type,
55
+ toArrayItemType: codeCol.arrayItemType,
56
+ });
57
+ }
58
+ // Nullable mismatch
59
+ if (dbCol.nullable !== codeCol.nullable) {
60
+ ops.push({
61
+ type: 'alter_column_nullable',
62
+ tableName,
63
+ columnName: dbCol.name,
64
+ nullable: codeCol.nullable,
65
+ });
66
+ }
67
+ // Enum values mismatch (CHECK constraint)
68
+ if (!enumValuesMatch(dbCol.enumValues, codeCol.enumValues)) {
69
+ ops.push({
70
+ type: 'update_check_constraint',
71
+ tableName,
72
+ columnName: dbCol.name,
73
+ oldValues: dbCol.enumValues ?? [],
74
+ newValues: codeCol.enumValues ?? [],
75
+ });
76
+ }
77
+ }
78
+ return ops;
79
+ }
80
+ /**
81
+ * Diff indexes between DB and code
82
+ */
83
+ function diffIndexes(tableName, dbIndexes, codeIndexes) {
84
+ const ops = [];
85
+ // Skip primary key indexes (named like tableName_pkey)
86
+ const dbNonPk = dbIndexes.filter((i) => !i.name.endsWith('_pkey') && !i.name.includes('_pkey'));
87
+ // Find indexes in code that don't exist in DB
88
+ for (const codeIdx of codeIndexes) {
89
+ const found = dbNonPk.some((dbIdx) => columnsMatch(dbIdx.columns, codeIdx.columns));
90
+ if (!found) {
91
+ ops.push({ type: 'add_index', tableName, index: codeIdx });
92
+ }
93
+ }
94
+ // Note: We don't drop extra indexes by default as they may be intentional
95
+ // performance optimizations added manually
96
+ return ops;
97
+ }
98
+ /**
99
+ * Diff unique constraints
100
+ */
101
+ function diffUniqueConstraints(tableName, dbUnique, codeUnique) {
102
+ const ops = [];
103
+ // Find constraints in code that don't exist in DB
104
+ for (const codeCols of codeUnique) {
105
+ const found = dbUnique.some((dbCols) => columnsMatch(dbCols, codeCols));
106
+ if (!found) {
107
+ ops.push({ type: 'add_unique_constraint', tableName, columns: codeCols });
108
+ }
109
+ }
110
+ return ops;
111
+ }
112
+ /**
113
+ * Diff two tables and generate operations needed to migrate DB to match code
114
+ */
115
+ export function diffTable(dbTable, codeTable) {
116
+ const ops = [];
117
+ // Table doesn't exist in DB but exists in code -> create
118
+ if (!dbTable && codeTable) {
119
+ ops.push({ type: 'create_table', table: codeTable });
120
+ return ops;
121
+ }
122
+ // Table exists in DB but not in code -> drop (dangerous!)
123
+ if (dbTable && !codeTable) {
124
+ ops.push({ type: 'drop_table', tableName: dbTable.name });
125
+ return ops;
126
+ }
127
+ // Both exist -> diff columns, indexes, constraints
128
+ if (dbTable && codeTable) {
129
+ const tableName = dbTable.name;
130
+ // Get all column names from both
131
+ const allColumns = new Set([
132
+ ...dbTable.columns.keys(),
133
+ ...codeTable.columns.keys(),
134
+ ]);
135
+ for (const colName of allColumns) {
136
+ const dbCol = dbTable.columns.get(colName);
137
+ const codeCol = codeTable.columns.get(colName);
138
+ ops.push(...diffColumn(tableName, dbCol, codeCol));
139
+ }
140
+ // Diff indexes
141
+ ops.push(...diffIndexes(tableName, dbTable.indexes, codeTable.indexes));
142
+ // Diff unique constraints
143
+ ops.push(...diffUniqueConstraints(tableName, dbTable.uniqueConstraints, codeTable.uniqueConstraints));
144
+ // Diff foreign keys
145
+ const dbFks = dbTable.foreignKeys ?? [];
146
+ const codeFks = codeTable.foreignKeys ?? [];
147
+ // Find FKs to add (in code but not in DB)
148
+ for (const codeFk of codeFks) {
149
+ const existing = dbFks.find((dbFk) => dbFk.column === codeFk.column &&
150
+ dbFk.referencedTable === codeFk.referencedTable &&
151
+ dbFk.referencedColumn === codeFk.referencedColumn);
152
+ if (!existing) {
153
+ ops.push({ type: 'add_foreign_key', tableName, fk: codeFk });
154
+ }
155
+ }
156
+ // Find FKs to drop (in DB but not in code)
157
+ for (const dbFk of dbFks) {
158
+ const existing = codeFks.find((codeFk) => codeFk.column === dbFk.column &&
159
+ codeFk.referencedTable === dbFk.referencedTable &&
160
+ codeFk.referencedColumn === dbFk.referencedColumn);
161
+ if (!existing) {
162
+ ops.push({
163
+ type: 'drop_foreign_key',
164
+ tableName,
165
+ constraintName: dbFk.constraintName,
166
+ });
167
+ }
168
+ }
169
+ }
170
+ return ops;
171
+ }
172
+ /**
173
+ * Diff entire database against code models
174
+ */
175
+ export function diffDatabase(dbTables, codeTables) {
176
+ const ops = [];
177
+ // Get all table names from both
178
+ const allTables = new Set([...dbTables.keys(), ...codeTables.keys()]);
179
+ for (const tableName of allTables) {
180
+ const dbTable = dbTables.get(tableName);
181
+ const codeTable = codeTables.get(tableName);
182
+ ops.push(...diffTable(dbTable, codeTable));
183
+ }
184
+ return ops;
185
+ }
186
+ /**
187
+ * Categorize operations into safe and destructive
188
+ */
189
+ export function categorizeOperations(ops) {
190
+ const safe = [];
191
+ const destructive = [];
192
+ for (const op of ops) {
193
+ switch (op.type) {
194
+ case 'create_table':
195
+ case 'add_column':
196
+ case 'add_index':
197
+ case 'add_unique_constraint':
198
+ case 'update_check_constraint':
199
+ safe.push(op);
200
+ break;
201
+ case 'drop_table':
202
+ case 'drop_column':
203
+ case 'drop_index':
204
+ case 'drop_unique_constraint':
205
+ destructive.push(op);
206
+ break;
207
+ case 'alter_column_type':
208
+ case 'alter_column_nullable':
209
+ case 'alter_column_default':
210
+ // These can be safe or destructive depending on the change
211
+ // For now, treat as safe but with warning
212
+ safe.push(op);
213
+ break;
214
+ }
215
+ }
216
+ return { safe, destructive };
217
+ }
218
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../../libs/lockstep-pg/src/diff.ts"],"names":[],"mappings":"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"}
package/src/drift.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import type { PostgresRecordModel, PostgresTableModel } from '@lyku/lockstep-core';
2
+ export interface Drift {
3
+ type: 'missing_table' | 'extra_table' | 'missing_column' | 'extra_column' | 'column_type_mismatch' | 'nullable_mismatch' | 'missing_index' | 'extra_index' | 'missing_constraint' | 'extra_constraint' | 'check_constraint_mismatch' | 'missing_stock_doc';
4
+ table: string;
5
+ details: string;
6
+ column?: string;
7
+ expected?: string;
8
+ actual?: string;
9
+ constraintName?: string;
10
+ docId?: string | number;
11
+ }
12
+ export interface DataformConfig {
13
+ tables: Record<string, PostgresTableModel<PostgresRecordModel>>;
14
+ }
15
+ export declare function detectDrift(connectionString: string, config: DataformConfig): Promise<Drift[]>;
16
+ //# sourceMappingURL=drift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift.d.ts","sourceRoot":"","sources":["../../../../libs/lockstep-pg/src/drift.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEX,mBAAmB,EACnB,kBAAkB,EAClB,MAAM,qBAAqB,CAAC;AAqB7B,MAAM,WAAW,KAAK;IACrB,IAAI,EACD,eAAe,GACf,aAAa,GACb,gBAAgB,GAChB,cAAc,GACd,sBAAsB,GACtB,mBAAmB,GACnB,eAAe,GACf,aAAa,GACb,oBAAoB,GACpB,kBAAkB,GAClB,2BAA2B,GAC3B,mBAAmB,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AA4CD,MAAM,WAAW,cAAc;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,mBAAmB,CAAC,CAAC,CAAC;CAChE;AAED,wBAAsB,WAAW,CAChC,gBAAgB,EAAE,MAAM,EACxB,MAAM,EAAE,cAAc,GACpB,OAAO,CAAC,KAAK,EAAE,CAAC,CA2SlB"}
package/src/drift.js ADDED
@@ -0,0 +1,299 @@
1
+ import { Client } from 'pg';
2
+ // Normalize postgres type names for comparison
3
+ function normalizeType(pgType) {
4
+ const lower = pgType.toLowerCase();
5
+ if (lower === 'bigint' || lower === 'int8')
6
+ return 'bigint';
7
+ if (lower === 'integer' || lower === 'int' || lower === 'int4')
8
+ return 'integer';
9
+ if (lower === 'smallint' || lower === 'int2')
10
+ return 'smallint';
11
+ if (lower === 'boolean' || lower === 'bool')
12
+ return 'boolean';
13
+ if (lower.startsWith('character varying') || lower === 'varchar')
14
+ return 'text';
15
+ if (lower.startsWith('character(') ||
16
+ lower.startsWith('character') ||
17
+ lower === 'bpchar' ||
18
+ lower === 'char')
19
+ return 'text';
20
+ if (lower === 'text')
21
+ return 'text';
22
+ if (lower === 'double precision' || lower === 'float8')
23
+ return 'double precision';
24
+ if (lower === 'timestamp with time zone' || lower === 'timestamptz')
25
+ return 'timestamptz';
26
+ if (lower === 'timestamp without time zone' || lower === 'timestamp')
27
+ return 'timestamp';
28
+ if (lower === 'jsonb')
29
+ return 'jsonb';
30
+ if (lower === 'numeric' || lower === 'decimal')
31
+ return 'numeric';
32
+ if (lower === 'array' || lower.endsWith('[]'))
33
+ return 'array';
34
+ // user-defined types in Postgres (custom enums) are stored as text with CHECK
35
+ if (lower === 'user-defined')
36
+ return 'text';
37
+ return lower;
38
+ }
39
+ // Get expected type from schema
40
+ function getExpectedType(columnSchema) {
41
+ const t = columnSchema.type;
42
+ if (t === 'bigserial')
43
+ return 'bigint'; // bigserial is stored as bigint
44
+ if (t === 'serial')
45
+ return 'integer'; // serial is stored as integer
46
+ if (t === 'enum')
47
+ return 'text'; // enums are stored as TEXT with CHECK constraint
48
+ if (t === 'char' || t === 'varchar')
49
+ return 'text'; // char/varchar normalize to text
50
+ return normalizeType(t);
51
+ }
52
+ export async function detectDrift(connectionString, config) {
53
+ const client = new Client({
54
+ connectionString,
55
+ ssl: true,
56
+ connectionTimeoutMillis: 30000,
57
+ });
58
+ const drifts = [];
59
+ try {
60
+ await client.connect();
61
+ // Get all tables from database
62
+ const tablesResult = await client.query(`
63
+ SELECT table_name
64
+ FROM information_schema.tables
65
+ WHERE table_schema = 'public'
66
+ AND table_type = 'BASE TABLE'
67
+ `);
68
+ const actualTables = new Set(tablesResult.rows.map((r) => r.table_name));
69
+ const expectedTables = Object.keys(config.tables);
70
+ // Check for missing tables
71
+ for (const tableName of expectedTables) {
72
+ if (!actualTables.has(tableName)) {
73
+ drifts.push({
74
+ type: 'missing_table',
75
+ table: tableName,
76
+ details: `Table "${tableName}" exists in schema but not in database`,
77
+ });
78
+ }
79
+ }
80
+ // Check for extra tables (not in schema)
81
+ for (const tableName of actualTables) {
82
+ if (!expectedTables.includes(tableName)) {
83
+ drifts.push({
84
+ type: 'extra_table',
85
+ table: tableName,
86
+ details: `Table "${tableName}" exists in database but not in schema`,
87
+ });
88
+ }
89
+ }
90
+ // For each expected table that exists, check columns
91
+ for (const [tableName, tableModel] of Object.entries(config.tables)) {
92
+ if (!actualTables.has(tableName))
93
+ continue;
94
+ const schema = tableModel.schema;
95
+ if (!('properties' in schema))
96
+ continue;
97
+ // Get actual columns
98
+ const columnsResult = await client.query(`
99
+ SELECT column_name, data_type, is_nullable, column_default, character_maximum_length
100
+ FROM information_schema.columns
101
+ WHERE table_schema = 'public' AND table_name = $1
102
+ `, [tableName]);
103
+ const actualColumns = new Map(columnsResult.rows.map((r) => [r.column_name, r]));
104
+ const expectedColumns = Object.entries(schema.properties);
105
+ const required = 'required' in schema ? schema.required : [];
106
+ // Check for missing columns
107
+ for (const [columnName, columnSchema] of expectedColumns) {
108
+ const actualCol = actualColumns.get(columnName);
109
+ if (!actualCol) {
110
+ drifts.push({
111
+ type: 'missing_column',
112
+ table: tableName,
113
+ column: columnName,
114
+ details: `Column "${columnName}" missing from table`,
115
+ });
116
+ continue;
117
+ }
118
+ // Check type
119
+ const expectedType = getExpectedType(columnSchema);
120
+ const actualType = normalizeType(actualCol.data_type);
121
+ if (expectedType !== actualType) {
122
+ drifts.push({
123
+ type: 'column_type_mismatch',
124
+ table: tableName,
125
+ column: columnName,
126
+ details: `Column "${columnName}" type mismatch`,
127
+ expected: expectedType,
128
+ actual: actualType,
129
+ });
130
+ }
131
+ // Check nullable
132
+ const expectedNullable = !required.includes(columnName);
133
+ const actualNullable = actualCol.is_nullable === 'YES';
134
+ if (expectedNullable !== actualNullable) {
135
+ drifts.push({
136
+ type: 'nullable_mismatch',
137
+ table: tableName,
138
+ column: columnName,
139
+ details: `Column "${columnName}" nullable mismatch`,
140
+ expected: expectedNullable ? 'nullable' : 'not null',
141
+ actual: actualNullable ? 'nullable' : 'not null',
142
+ });
143
+ }
144
+ actualColumns.delete(columnName);
145
+ }
146
+ // Extra columns (in DB but not schema)
147
+ for (const [columnName] of actualColumns) {
148
+ drifts.push({
149
+ type: 'extra_column',
150
+ table: tableName,
151
+ column: columnName,
152
+ details: `Column "${columnName}" exists in database but not in schema`,
153
+ });
154
+ }
155
+ // Check CHECK constraints for enum columns
156
+ const checkConstraintsResult = await client.query(`
157
+ SELECT
158
+ con.conname AS constraint_name,
159
+ att.attname AS column_name,
160
+ pg_get_constraintdef(con.oid) AS check_clause
161
+ FROM pg_constraint con
162
+ JOIN pg_attribute att ON att.attnum = ANY(con.conkey) AND att.attrelid = con.conrelid
163
+ WHERE con.conrelid = $1::regclass
164
+ AND con.contype = 'c'
165
+ `, [`"${tableName}"`]);
166
+ const actualCheckConstraints = new Map();
167
+ for (const row of checkConstraintsResult.rows) {
168
+ if (row.check_clause.includes(' IN (') ||
169
+ row.check_clause.includes('ANY (ARRAY[') ||
170
+ row.check_clause.includes('ANY(ARRAY[')) {
171
+ actualCheckConstraints.set(row.column_name, row);
172
+ }
173
+ }
174
+ // Compare enum columns with their CHECK constraints
175
+ for (const [columnName, columnSchema] of expectedColumns) {
176
+ const colSchema = columnSchema;
177
+ if (colSchema.type !== 'enum' || !colSchema.enum)
178
+ continue;
179
+ const actualConstraint = actualCheckConstraints.get(columnName);
180
+ if (!actualConstraint) {
181
+ drifts.push({
182
+ type: 'missing_constraint',
183
+ table: tableName,
184
+ column: columnName,
185
+ details: `Missing CHECK constraint for enum column "${columnName}"`,
186
+ expected: colSchema.enum.join(', '),
187
+ });
188
+ continue;
189
+ }
190
+ const checkClause = actualConstraint.check_clause;
191
+ const actualValues = [];
192
+ const valueMatches = checkClause.matchAll(/'([^']+)'/g);
193
+ for (const match of valueMatches) {
194
+ if (!match[1].includes('::')) {
195
+ actualValues.push(match[1]);
196
+ }
197
+ }
198
+ const expectedSet = new Set(colSchema.enum);
199
+ const actualSet = new Set(actualValues);
200
+ const missing = colSchema.enum.filter((v) => !actualSet.has(v));
201
+ const extra = actualValues.filter((v) => !expectedSet.has(v));
202
+ if (missing.length > 0 || extra.length > 0) {
203
+ drifts.push({
204
+ type: 'check_constraint_mismatch',
205
+ table: tableName,
206
+ column: columnName,
207
+ constraintName: actualConstraint.constraint_name,
208
+ details: `CHECK constraint values mismatch for "${columnName}"`,
209
+ expected: colSchema.enum.join(', '),
210
+ actual: actualValues.join(', '),
211
+ });
212
+ }
213
+ }
214
+ // Check for missing stock documents
215
+ const docs = tableModel.docs;
216
+ if (docs && Array.isArray(docs) && docs.length > 0) {
217
+ const primaryKey = tableModel.primaryKey || 'id';
218
+ for (const doc of docs) {
219
+ if (doc &&
220
+ typeof doc === 'object' &&
221
+ !Array.isArray(doc) &&
222
+ 'id' in doc) {
223
+ const docRecord = doc;
224
+ const docId = docRecord['id'];
225
+ const checkResult = await client.query(`SELECT 1 FROM "${tableName}" WHERE "${String(primaryKey)}" = $1 LIMIT 1`, [docId]);
226
+ if (checkResult.rows.length === 0) {
227
+ const docTitle = 'title' in doc
228
+ ? docRecord['title']
229
+ : 'name' in doc
230
+ ? docRecord['name']
231
+ : 'slug' in doc
232
+ ? docRecord['slug']
233
+ : undefined;
234
+ drifts.push({
235
+ type: 'missing_stock_doc',
236
+ table: tableName,
237
+ docId: typeof docId === 'bigint'
238
+ ? docId.toString()
239
+ : docId,
240
+ details: `Stock document ${String(primaryKey)}=${docId}${docTitle ? ` (${docTitle})` : ''} missing from table`,
241
+ });
242
+ }
243
+ }
244
+ }
245
+ }
246
+ // Check indexes
247
+ const indexesResult = await client.query(`
248
+ SELECT indexname, indexdef
249
+ FROM pg_indexes
250
+ WHERE schemaname = 'public' AND tablename = $1
251
+ `, [tableName]);
252
+ const actualIndexes = new Map(indexesResult.rows.map((r) => [r.indexname, r.indexdef]));
253
+ // Expected indexes from model
254
+ const expectedIndexColumns = tableModel.indexes || [];
255
+ for (const indexCol of expectedIndexColumns) {
256
+ let cols;
257
+ if (typeof indexCol === 'string') {
258
+ cols = [indexCol];
259
+ }
260
+ else if (Array.isArray(indexCol)) {
261
+ cols = indexCol;
262
+ }
263
+ else if (typeof indexCol === 'object' && indexCol !== null) {
264
+ const objIndex = indexCol;
265
+ cols = Array.isArray(objIndex.columns)
266
+ ? objIndex.columns
267
+ : [objIndex.columns];
268
+ }
269
+ else {
270
+ continue;
271
+ }
272
+ let found = false;
273
+ for (const [, indexDef] of actualIndexes) {
274
+ const defLower = indexDef.toLowerCase();
275
+ if (cols.every((c) => {
276
+ const colLower = c.toLowerCase().split(' ')[0];
277
+ return (defLower.includes(`"${colLower}"`) ||
278
+ defLower.includes(colLower));
279
+ })) {
280
+ found = true;
281
+ break;
282
+ }
283
+ }
284
+ if (!found) {
285
+ drifts.push({
286
+ type: 'missing_index',
287
+ table: tableName,
288
+ details: `Missing index on column(s): ${cols.join(', ')}`,
289
+ });
290
+ }
291
+ }
292
+ }
293
+ return drifts;
294
+ }
295
+ finally {
296
+ await client.end();
297
+ }
298
+ }
299
+ //# sourceMappingURL=drift.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift.js","sourceRoot":"","sources":["../../../../libs/lockstep-pg/src/drift.ts"],"names":[],"mappings":"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"}
package/src/form.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { DataformConfig } from './drift';
2
+ export declare function generateCreateTablesSql(config: DataformConfig): string;
3
+ //# sourceMappingURL=form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../../../libs/lockstep-pg/src/form.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAQtE"}
package/src/form.js ADDED
@@ -0,0 +1,9 @@
1
+ import { setupTable } from './setupTable';
2
+ export function generateCreateTablesSql(config) {
3
+ const outputs = [];
4
+ for (const [tableName, table] of Object.entries(config.tables)) {
5
+ outputs.push(setupTable(tableName, table));
6
+ }
7
+ return outputs.join('\n\n');
8
+ }
9
+ //# sourceMappingURL=form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.js","sourceRoot":"","sources":["../../../../libs/lockstep-pg/src/form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,MAAM,UAAU,uBAAuB,CAAC,MAAsB;IAC7D,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Generate SQL from diff operations
3
+ */
4
+ import type { DiffOperation } from './diff';
5
+ /**
6
+ * Convert a single diff operation to SQL
7
+ */
8
+ export declare function operationToSql(op: DiffOperation): string[];
9
+ /**
10
+ * Generate full migration SQL from operations
11
+ */
12
+ export declare function generateMigrationSql(ops: DiffOperation[], _includeDestructive?: boolean): {
13
+ safe: string;
14
+ destructive: string;
15
+ };
16
+ //# sourceMappingURL=generateSql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateSql.d.ts","sourceRoot":"","sources":["../../../../libs/lockstep-pg/src/generateSql.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AA4K5C;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,EAAE,CAkI1D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,GAAG,EAAE,aAAa,EAAE,EACpB,mBAAmB,UAAQ,GACzB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAoDvC"}