@xubylele/schema-forge-core 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.
Files changed (83) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +254 -0
  3. package/dist/core/diff.d.ts +22 -0
  4. package/dist/core/diff.d.ts.map +1 -0
  5. package/dist/core/diff.js +248 -0
  6. package/dist/core/diff.js.map +1 -0
  7. package/dist/core/errors.d.ts +4 -0
  8. package/dist/core/errors.d.ts.map +1 -0
  9. package/dist/core/errors.js +7 -0
  10. package/dist/core/errors.js.map +1 -0
  11. package/dist/core/fs.d.ts +31 -0
  12. package/dist/core/fs.d.ts.map +1 -0
  13. package/dist/core/fs.js +104 -0
  14. package/dist/core/fs.js.map +1 -0
  15. package/dist/core/normalize.d.ts +10 -0
  16. package/dist/core/normalize.d.ts.map +1 -0
  17. package/dist/core/normalize.js +152 -0
  18. package/dist/core/normalize.js.map +1 -0
  19. package/dist/core/parser.d.ts +25 -0
  20. package/dist/core/parser.d.ts.map +1 -0
  21. package/dist/core/parser.js +210 -0
  22. package/dist/core/parser.js.map +1 -0
  23. package/dist/core/paths.d.ts +29 -0
  24. package/dist/core/paths.d.ts.map +1 -0
  25. package/dist/core/paths.js +41 -0
  26. package/dist/core/paths.js.map +1 -0
  27. package/dist/core/sql/apply-ops.d.ts +3 -0
  28. package/dist/core/sql/apply-ops.d.ts.map +1 -0
  29. package/dist/core/sql/apply-ops.js +174 -0
  30. package/dist/core/sql/apply-ops.js.map +1 -0
  31. package/dist/core/sql/load-migrations.d.ts +6 -0
  32. package/dist/core/sql/load-migrations.d.ts.map +1 -0
  33. package/dist/core/sql/load-migrations.js +26 -0
  34. package/dist/core/sql/load-migrations.js.map +1 -0
  35. package/dist/core/sql/parse-migration.d.ts +11 -0
  36. package/dist/core/sql/parse-migration.d.ts.map +1 -0
  37. package/dist/core/sql/parse-migration.js +509 -0
  38. package/dist/core/sql/parse-migration.js.map +1 -0
  39. package/dist/core/sql/schema-to-dsl.d.ts +3 -0
  40. package/dist/core/sql/schema-to-dsl.d.ts.map +1 -0
  41. package/dist/core/sql/schema-to-dsl.js +33 -0
  42. package/dist/core/sql/schema-to-dsl.js.map +1 -0
  43. package/dist/core/sql/split-statements.d.ts +11 -0
  44. package/dist/core/sql/split-statements.d.ts.map +1 -0
  45. package/dist/core/sql/split-statements.js +111 -0
  46. package/dist/core/sql/split-statements.js.map +1 -0
  47. package/dist/core/state-manager.d.ts +17 -0
  48. package/dist/core/state-manager.d.ts.map +1 -0
  49. package/dist/core/state-manager.js +48 -0
  50. package/dist/core/state-manager.js.map +1 -0
  51. package/dist/core/utils.d.ts +30 -0
  52. package/dist/core/utils.d.ts.map +1 -0
  53. package/dist/core/utils.js +45 -0
  54. package/dist/core/utils.js.map +1 -0
  55. package/dist/core/validate.d.ts +20 -0
  56. package/dist/core/validate.d.ts.map +1 -0
  57. package/dist/core/validate.js +154 -0
  58. package/dist/core/validate.js.map +1 -0
  59. package/dist/core/validator.d.ts +16 -0
  60. package/dist/core/validator.d.ts.map +1 -0
  61. package/dist/core/validator.js +126 -0
  62. package/dist/core/validator.js.map +1 -0
  63. package/dist/diff/diff.d.ts +7 -0
  64. package/dist/diff/diff.d.ts.map +1 -0
  65. package/dist/diff/diff.js +75 -0
  66. package/dist/diff/diff.js.map +1 -0
  67. package/dist/generator/sql-generator.d.ts +8 -0
  68. package/dist/generator/sql-generator.d.ts.map +1 -0
  69. package/dist/generator/sql-generator.js +126 -0
  70. package/dist/generator/sql-generator.js.map +1 -0
  71. package/dist/index.d.ts +22 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +29 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/parser/parser.d.ts +3 -0
  76. package/dist/parser/parser.d.ts.map +1 -0
  77. package/dist/parser/parser.js +135 -0
  78. package/dist/parser/parser.js.map +1 -0
  79. package/dist/state/snapshot.d.ts +3 -0
  80. package/dist/state/snapshot.d.ts.map +1 -0
  81. package/dist/state/snapshot.js +22 -0
  82. package/dist/state/snapshot.js.map +1 -0
  83. package/package.json +33 -0
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2025-2026 Xuby
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,254 @@
1
+ # Schema Forge Core
2
+
3
+ `@xubylele/schema-forge-core` is the deterministic engine behind Schema Forge. It contains the full domain logic for parsing, diffing, validating, and generating SQL from declarative schema definitions.
4
+
5
+ The core is framework-agnostic and built around pure, predictable transformations:
6
+
7
+ * **Parse** the `.sf` DSL format
8
+ * **Normalize** schema into a state model
9
+ * **Diff** schema versions to detect structural changes
10
+ * **Validate** schema definitions and destructive changes
11
+ * **Generate** SQL migration statements
12
+ * **Import** and reconstruct schema from existing SQL migrations
13
+
14
+ Same input → same output.
15
+
16
+ ---
17
+
18
+ ## Philosophy
19
+
20
+ * Declarative schema definition
21
+ * Deterministic transformations
22
+ * Framework agnostic
23
+ * Pure domain layer
24
+ * Explicit state modeling
25
+
26
+ The core contains no hidden side effects. All structural changes are derived from explicit schema input and state.
27
+
28
+ ---
29
+
30
+ ## Module Boundaries
31
+
32
+ ### Core (Pure)
33
+
34
+ Environment-agnostic logic:
35
+
36
+ * Parsing DSL
37
+ * Schema normalization
38
+ * Diff engine
39
+ * Validation rules
40
+ * SQL generation
41
+ * SQL parsing to operations
42
+ * State modeling
43
+
44
+ These modules can run in Node.js or browser environments.
45
+
46
+ ### Node Utilities (I/O Helpers)
47
+
48
+ Node-only helpers for CLI or tooling environments:
49
+
50
+ * File system utilities
51
+ * Project path resolution
52
+ * Migration file loading
53
+
54
+ These require Node.js.
55
+
56
+ ---
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ npm install @xubylele/schema-forge-core
62
+ ```
63
+
64
+ ---
65
+
66
+ ## Basic Usage
67
+
68
+ ### Parse → Diff → Generate SQL
69
+
70
+ ```ts
71
+ import {
72
+ parseSchema,
73
+ schemaToState,
74
+ diffSchemas,
75
+ generateSql
76
+ } from "@xubylele/schema-forge-core"
77
+
78
+ const schemaSource = `
79
+ table users {
80
+ id uuid pk
81
+ email varchar unique
82
+ created_at timestamptz
83
+ }
84
+ `
85
+
86
+ // Parse DSL into schema model
87
+ const schema = parseSchema(schemaSource)
88
+
89
+ // Convert schema into normalized state
90
+ const state = await schemaToState(schema)
91
+
92
+ const nextSchemaSource = `
93
+ table users {
94
+ id uuid pk
95
+ email varchar unique
96
+ name varchar
97
+ created_at timestamptz
98
+ }
99
+ `
100
+
101
+ const nextSchema = parseSchema(nextSchemaSource)
102
+
103
+ // Compute structural diff
104
+ const diff = diffSchemas(state, nextSchema)
105
+
106
+ // Generate SQL for provider
107
+ const sql = generateSql(diff, "postgres")
108
+
109
+ console.log(sql)
110
+ // ALTER TABLE users ADD COLUMN name varchar;
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Schema Validation
116
+
117
+ ```ts
118
+ import {
119
+ validateSchema,
120
+ validateSchemaChanges,
121
+ toValidationReport
122
+ } from "@xubylele/schema-forge-core"
123
+
124
+ const schema = parseSchema(schemaSource)
125
+
126
+ // Structural validation (throws on invalid schema)
127
+ validateSchema(schema)
128
+
129
+ // Destructive change validation
130
+ const findings = validateSchemaChanges(state, nextSchema)
131
+ const report = toValidationReport(findings)
132
+
133
+ report.errors.forEach(f => {
134
+ console.error(`[error] ${f.code}: ${f.message}`)
135
+ })
136
+
137
+ report.warnings.forEach(f => {
138
+ console.warn(`[warning] ${f.code}: ${f.message}`)
139
+ })
140
+ ```
141
+
142
+ ---
143
+
144
+ ## SQL Import (Reverse Engineering)
145
+
146
+ ```ts
147
+ import {
148
+ loadMigrationSqlInput,
149
+ parseMigrationSql,
150
+ applySqlOps,
151
+ schemaToDsl
152
+ } from "@xubylele/schema-forge-core"
153
+
154
+ const inputs = await loadMigrationSqlInput("./migrations")
155
+
156
+ for (const input of inputs) {
157
+ const parseResult = parseMigrationSql(input.sql)
158
+
159
+ if (parseResult.warnings.length > 0) {
160
+ console.warn(parseResult.warnings)
161
+ }
162
+
163
+ const result = applySqlOps(parseResult.ops)
164
+ const dsl = schemaToDsl(result.schema)
165
+
166
+ console.log(dsl)
167
+ }
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Supported Providers
173
+
174
+ * `postgres`
175
+
176
+ Additional providers may be implemented in higher-level packages.
177
+
178
+ ---
179
+
180
+ ## Core API (High-Level)
181
+
182
+ ### Parsing & State
183
+
184
+ * `parseSchema(source: string): DatabaseSchema`
185
+ * `schemaToState(schema: DatabaseSchema): Promise<StateFile>`
186
+ * `loadState(filePath: string): Promise<StateFile>`
187
+ * `saveState(filePath: string, state: StateFile): Promise<void>`
188
+
189
+ ### Diff Engine
190
+
191
+ * `diffSchemas(state: StateFile, schema: DatabaseSchema): DiffResult`
192
+
193
+ ### Validation
194
+
195
+ * `validateSchema(schema: DatabaseSchema): void`
196
+ * `validateSchemaChanges(state: StateFile, schema: DatabaseSchema): Finding[]`
197
+ * `toValidationReport(findings: Finding[]): ValidationReport`
198
+
199
+ ### SQL Generation
200
+
201
+ * `generateSql(diff: DiffResult, provider: Provider, config?: SqlConfig): string`
202
+
203
+ ### SQL Parsing & Reconstruction
204
+
205
+ * `parseMigrationSql(sql: string): ParseResult`
206
+ * `applySqlOps(ops: SqlOp[]): ApplySqlOpsResult`
207
+ * `schemaToDsl(schema: DatabaseSchema): string`
208
+
209
+ Full API surface is available via TypeScript exports.
210
+
211
+ ---
212
+
213
+ ## Type Exports
214
+
215
+ All domain types are exported for integration:
216
+
217
+ * `DatabaseSchema`, `Table`, `Column`, `ForeignKey`
218
+ * `StateFile`, `StateTable`, `StateColumn`
219
+ * `DiffResult`, `Operation`
220
+ * `SqlOp`, `ParseResult`, `ApplySqlOpsResult`
221
+ * `Finding`, `ValidationReport`, `Severity`
222
+ * `Provider`, `SqlConfig`
223
+
224
+ ---
225
+
226
+ ## Architecture
227
+
228
+ ```
229
+ DSL (.sf)
230
+
231
+ Parser → DatabaseSchema
232
+
233
+ State Normalization → StateFile
234
+
235
+ Diff Engine → Operations
236
+
237
+ SQL Generator → Migration SQL
238
+ ```
239
+
240
+ ---
241
+
242
+ ## Development
243
+
244
+ ```bash
245
+ npm install
246
+ npm run build
247
+ npm test
248
+ ```
249
+
250
+ ---
251
+
252
+ ## License
253
+
254
+ ISC
@@ -0,0 +1,22 @@
1
+ import type { Column, DatabaseSchema, DiffResult, StateColumn, StateFile } from '../types/schema';
2
+ /**
3
+ * Extract table names from a stored state file.
4
+ */
5
+ export declare function getTableNamesFromState(state: StateFile): Set<string>;
6
+ /**
7
+ * Extract table names from a database schema.
8
+ */
9
+ export declare function getTableNamesFromSchema(schema: DatabaseSchema): Set<string>;
10
+ /**
11
+ * Extract column names from a state table columns record.
12
+ */
13
+ export declare function getColumnNamesFromState(stateColumns: Record<string, StateColumn>): Set<string>;
14
+ /**
15
+ * Extract column names from a schema table columns array.
16
+ */
17
+ export declare function getColumnNamesFromSchema(dbColumns: Column[]): Set<string>;
18
+ /**
19
+ * Compare a persisted state and a new schema, generating ordered operations.
20
+ */
21
+ export declare function diffSchemas(oldState: StateFile, newSchema: DatabaseSchema): DiffResult;
22
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,cAAc,EACd,UAAU,EAEV,WAAW,EACX,SAAS,EACV,MAAM,iBAAiB,CAAC;AAGzB;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,CAEpE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,CAE3E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACxC,GAAG,CAAC,MAAM,CAAC,CAEb;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAEzE;AA8BD;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,GAAG,UAAU,CA+OtF"}
@@ -0,0 +1,248 @@
1
+ import { normalizeDefault } from './normalize';
2
+ /**
3
+ * Extract table names from a stored state file.
4
+ */
5
+ export function getTableNamesFromState(state) {
6
+ return new Set(Object.keys(state.tables));
7
+ }
8
+ /**
9
+ * Extract table names from a database schema.
10
+ */
11
+ export function getTableNamesFromSchema(schema) {
12
+ return new Set(Object.keys(schema.tables));
13
+ }
14
+ /**
15
+ * Extract column names from a state table columns record.
16
+ */
17
+ export function getColumnNamesFromState(stateColumns) {
18
+ return new Set(Object.keys(stateColumns));
19
+ }
20
+ /**
21
+ * Extract column names from a schema table columns array.
22
+ */
23
+ export function getColumnNamesFromSchema(dbColumns) {
24
+ return new Set(dbColumns.map(column => column.name));
25
+ }
26
+ function getSortedNames(names) {
27
+ return Array.from(names).sort((a, b) => a.localeCompare(b));
28
+ }
29
+ function normalizeColumnType(type) {
30
+ return type
31
+ .toLowerCase()
32
+ .trim()
33
+ .replace(/\s+/g, ' ')
34
+ .replace(/\s*\(\s*/g, '(')
35
+ .replace(/\s*,\s*/g, ',')
36
+ .replace(/\s*\)\s*/g, ')');
37
+ }
38
+ function resolveStatePrimaryKey(table) {
39
+ return table.primaryKey ??
40
+ Object.entries(table.columns).find(([, column]) => column.primaryKey)?.[0] ??
41
+ null;
42
+ }
43
+ function resolveSchemaPrimaryKey(table) {
44
+ return table.primaryKey ?? table.columns.find(column => column.primaryKey)?.name ?? null;
45
+ }
46
+ function normalizeNullable(nullable) {
47
+ return nullable ?? true;
48
+ }
49
+ /**
50
+ * Compare a persisted state and a new schema, generating ordered operations.
51
+ */
52
+ export function diffSchemas(oldState, newSchema) {
53
+ const operations = [];
54
+ const oldTableNames = getTableNamesFromState(oldState);
55
+ const newTableNames = getTableNamesFromSchema(newSchema);
56
+ const sortedNewTableNames = getSortedNames(newTableNames);
57
+ const sortedOldTableNames = getSortedNames(oldTableNames);
58
+ // Phase 1: create tables (A-Z)
59
+ for (const tableName of sortedNewTableNames) {
60
+ if (!oldTableNames.has(tableName)) {
61
+ operations.push({
62
+ kind: 'create_table',
63
+ table: newSchema.tables[tableName],
64
+ });
65
+ }
66
+ }
67
+ const commonTableNames = sortedNewTableNames.filter(tableName => oldTableNames.has(tableName));
68
+ // Phase 2: detect column type changes in schema order
69
+ for (const tableName of commonTableNames) {
70
+ const newTable = newSchema.tables[tableName];
71
+ const oldTable = oldState.tables[tableName];
72
+ if (!newTable || !oldTable) {
73
+ continue;
74
+ }
75
+ for (const column of newTable.columns) {
76
+ const previousColumn = oldTable.columns[column.name];
77
+ if (!previousColumn) {
78
+ continue;
79
+ }
80
+ const previousType = normalizeColumnType(previousColumn.type);
81
+ const currentType = normalizeColumnType(column.type);
82
+ if (previousType !== currentType) {
83
+ operations.push({
84
+ kind: 'column_type_changed',
85
+ tableName,
86
+ columnName: column.name,
87
+ fromType: previousColumn.type,
88
+ toType: column.type,
89
+ });
90
+ }
91
+ }
92
+ }
93
+ // Phase 3: drop PK constraints for changed/removed primary keys
94
+ for (const tableName of commonTableNames) {
95
+ const newTable = newSchema.tables[tableName];
96
+ const oldTable = oldState.tables[tableName];
97
+ if (!newTable || !oldTable) {
98
+ continue;
99
+ }
100
+ const previousPrimaryKey = resolveStatePrimaryKey(oldTable);
101
+ const currentPrimaryKey = resolveSchemaPrimaryKey(newTable);
102
+ if (previousPrimaryKey !== null && previousPrimaryKey !== currentPrimaryKey) {
103
+ operations.push({
104
+ kind: 'drop_primary_key_constraint',
105
+ tableName,
106
+ });
107
+ }
108
+ }
109
+ // Phase 4: detect unique changes for existing columns in schema order
110
+ for (const tableName of commonTableNames) {
111
+ const newTable = newSchema.tables[tableName];
112
+ const oldTable = oldState.tables[tableName];
113
+ if (!newTable || !oldTable) {
114
+ continue;
115
+ }
116
+ for (const column of newTable.columns) {
117
+ const previousColumn = oldTable.columns[column.name];
118
+ if (!previousColumn) {
119
+ continue;
120
+ }
121
+ const previousUnique = previousColumn.unique ?? false;
122
+ const currentUnique = column.unique ?? false;
123
+ if (previousUnique !== currentUnique) {
124
+ operations.push({
125
+ kind: 'column_unique_changed',
126
+ tableName,
127
+ columnName: column.name,
128
+ from: previousUnique,
129
+ to: currentUnique,
130
+ });
131
+ }
132
+ }
133
+ }
134
+ // Phase 5: detect column nullability changes in schema order
135
+ for (const tableName of commonTableNames) {
136
+ const newTable = newSchema.tables[tableName];
137
+ const oldTable = oldState.tables[tableName];
138
+ if (!newTable || !oldTable) {
139
+ continue;
140
+ }
141
+ for (const column of newTable.columns) {
142
+ const previousColumn = oldTable.columns[column.name];
143
+ if (!previousColumn) {
144
+ continue;
145
+ }
146
+ const previousNullable = normalizeNullable(previousColumn.nullable);
147
+ const currentNullable = normalizeNullable(column.nullable);
148
+ if (previousNullable !== currentNullable) {
149
+ operations.push({
150
+ kind: 'column_nullability_changed',
151
+ tableName,
152
+ columnName: column.name,
153
+ from: previousNullable,
154
+ to: currentNullable,
155
+ });
156
+ }
157
+ }
158
+ }
159
+ // Phase 6: detect column default changes in schema order
160
+ for (const tableName of commonTableNames) {
161
+ const newTable = newSchema.tables[tableName];
162
+ const oldTable = oldState.tables[tableName];
163
+ if (!newTable || !oldTable) {
164
+ continue;
165
+ }
166
+ for (const column of newTable.columns) {
167
+ const previousColumn = oldTable.columns[column.name];
168
+ if (!previousColumn) {
169
+ continue;
170
+ }
171
+ const previousDefault = normalizeDefault(previousColumn.default);
172
+ const currentDefault = normalizeDefault(column.default);
173
+ if (previousDefault !== currentDefault) {
174
+ operations.push({
175
+ kind: 'column_default_changed',
176
+ tableName,
177
+ columnName: column.name,
178
+ fromDefault: previousDefault,
179
+ toDefault: currentDefault,
180
+ });
181
+ }
182
+ }
183
+ }
184
+ // Phase 7: add columns in schema order
185
+ for (const tableName of commonTableNames) {
186
+ const newTable = newSchema.tables[tableName];
187
+ const oldTable = oldState.tables[tableName];
188
+ if (!newTable || !oldTable) {
189
+ continue;
190
+ }
191
+ const oldColumnNames = getColumnNamesFromState(oldTable.columns);
192
+ for (const column of newTable.columns) {
193
+ if (!oldColumnNames.has(column.name)) {
194
+ operations.push({
195
+ kind: 'add_column',
196
+ tableName,
197
+ column,
198
+ });
199
+ }
200
+ }
201
+ }
202
+ // Phase 8: add PK constraints for added/changed primary keys
203
+ for (const tableName of commonTableNames) {
204
+ const newTable = newSchema.tables[tableName];
205
+ const oldTable = oldState.tables[tableName];
206
+ if (!newTable || !oldTable) {
207
+ continue;
208
+ }
209
+ const previousPrimaryKey = resolveStatePrimaryKey(oldTable);
210
+ const currentPrimaryKey = resolveSchemaPrimaryKey(newTable);
211
+ if (currentPrimaryKey !== null && previousPrimaryKey !== currentPrimaryKey) {
212
+ operations.push({
213
+ kind: 'add_primary_key_constraint',
214
+ tableName,
215
+ columnName: currentPrimaryKey,
216
+ });
217
+ }
218
+ }
219
+ // Phase 9: drop columns in state key order
220
+ for (const tableName of commonTableNames) {
221
+ const newTable = newSchema.tables[tableName];
222
+ const oldTable = oldState.tables[tableName];
223
+ if (!newTable || !oldTable) {
224
+ continue;
225
+ }
226
+ const newColumnNames = getColumnNamesFromSchema(newTable.columns);
227
+ for (const columnName of Object.keys(oldTable.columns)) {
228
+ if (!newColumnNames.has(columnName)) {
229
+ operations.push({
230
+ kind: 'drop_column',
231
+ tableName,
232
+ columnName,
233
+ });
234
+ }
235
+ }
236
+ }
237
+ // Phase 10: drop tables (A-Z)
238
+ for (const tableName of sortedOldTableNames) {
239
+ if (!newTableNames.has(tableName)) {
240
+ operations.push({
241
+ kind: 'drop_table',
242
+ tableName,
243
+ });
244
+ }
245
+ }
246
+ return { operations };
247
+ }
248
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/core/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare class SchemaValidationError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B"}
@@ -0,0 +1,7 @@
1
+ export class SchemaValidationError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = 'SchemaValidationError';
5
+ }
6
+ }
7
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Ensure a directory exists, creating it if necessary
3
+ */
4
+ export declare function ensureDir(dirPath: string): Promise<void>;
5
+ /**
6
+ * Check if a file exists
7
+ */
8
+ export declare function fileExists(filePath: string): Promise<boolean>;
9
+ /**
10
+ * Read a text file with UTF-8 encoding
11
+ */
12
+ export declare function readTextFile(filePath: string): Promise<string>;
13
+ /**
14
+ * Write a text file with UTF-8 encoding
15
+ */
16
+ export declare function writeTextFile(filePath: string, content: string): Promise<void>;
17
+ /**
18
+ * Read a JSON file with UTF-8 encoding
19
+ * Returns fallback value if file doesn't exist
20
+ */
21
+ export declare function readJsonFile<T>(filePath: string, fallback: T): Promise<T>;
22
+ /**
23
+ * Write a JSON file with UTF-8 encoding
24
+ * Pretty-prints with 2-space indentation
25
+ */
26
+ export declare function writeJsonFile(filePath: string, data: any): Promise<void>;
27
+ /**
28
+ * Find files matching a pattern recursively
29
+ */
30
+ export declare function findFiles(dirPath: string, pattern: RegExp): Promise<string[]>;
31
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/core/fs.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM9D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOnE;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMpE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUpF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAY/E;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAO9E;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqBnF"}