@appixar/xpg 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 (54) hide show
  1. package/dist/__tests__/core.test.d.ts +2 -0
  2. package/dist/__tests__/core.test.d.ts.map +1 -0
  3. package/dist/__tests__/core.test.js +228 -0
  4. package/dist/__tests__/core.test.js.map +1 -0
  5. package/dist/builder.d.ts +23 -0
  6. package/dist/builder.d.ts.map +1 -0
  7. package/dist/builder.js +262 -0
  8. package/dist/builder.js.map +1 -0
  9. package/dist/cli.d.ts +3 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +119 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/configLoader.d.ts +22 -0
  14. package/dist/configLoader.d.ts.map +1 -0
  15. package/dist/configLoader.js +97 -0
  16. package/dist/configLoader.js.map +1 -0
  17. package/dist/defaultNormalizer.d.ts +29 -0
  18. package/dist/defaultNormalizer.d.ts.map +1 -0
  19. package/dist/defaultNormalizer.js +124 -0
  20. package/dist/defaultNormalizer.js.map +1 -0
  21. package/dist/diffEngine.d.ts +21 -0
  22. package/dist/diffEngine.d.ts.map +1 -0
  23. package/dist/diffEngine.js +233 -0
  24. package/dist/diffEngine.js.map +1 -0
  25. package/dist/index.d.ts +11 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +15 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/logger.d.ts +22 -0
  30. package/dist/logger.d.ts.map +1 -0
  31. package/dist/logger.js +63 -0
  32. package/dist/logger.js.map +1 -0
  33. package/dist/pgService.d.ts +42 -0
  34. package/dist/pgService.d.ts.map +1 -0
  35. package/dist/pgService.js +219 -0
  36. package/dist/pgService.js.map +1 -0
  37. package/dist/schemaParser.d.ts +10 -0
  38. package/dist/schemaParser.d.ts.map +1 -0
  39. package/dist/schemaParser.js +118 -0
  40. package/dist/schemaParser.js.map +1 -0
  41. package/dist/sqlGenerator.d.ts +18 -0
  42. package/dist/sqlGenerator.d.ts.map +1 -0
  43. package/dist/sqlGenerator.js +104 -0
  44. package/dist/sqlGenerator.js.map +1 -0
  45. package/dist/typeDictionary.d.ts +2 -0
  46. package/dist/typeDictionary.d.ts.map +1 -0
  47. package/dist/typeDictionary.js +27 -0
  48. package/dist/typeDictionary.js.map +1 -0
  49. package/dist/types.d.ts +72 -0
  50. package/dist/types.d.ts.map +1 -0
  51. package/dist/types.js +5 -0
  52. package/dist/types.js.map +1 -0
  53. package/package.json +43 -0
  54. package/xpg.config.yml-sample +42 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=core.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/core.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,228 @@
1
+ // ─────────────────────────────────────────────
2
+ // x-postgres — Unit tests
3
+ // ─────────────────────────────────────────────
4
+ // Uses Node.js built-in test runner (node --test)
5
+ import { describe, it } from 'node:test';
6
+ import assert from 'node:assert/strict';
7
+ import { parseSchema } from '../schemaParser.js';
8
+ import { normalizeDefaultSql, buildDefaultClause, normalizeDbDefaultForCompare } from '../defaultNormalizer.js';
9
+ import { generateCreateTable, generateDropTable } from '../sqlGenerator.js';
10
+ import { POSTGRES_TYPE_DICTIONARY } from '../typeDictionary.js';
11
+ // ──────────────────────────────────────────
12
+ // Schema Parser Tests
13
+ // ──────────────────────────────────────────
14
+ const CUSTOM_FIELDS = {
15
+ id: { Type: 'serial', Key: 'PRI' },
16
+ str: { Type: 'varchar(64)' },
17
+ text: { Type: 'text' },
18
+ int: { Type: 'integer' },
19
+ now: { Type: 'timestamp', Default: 'now()' },
20
+ pid: { Type: 'varchar(12)', Key: 'UNI', Default: '"left"(md5((random())::text), 12)' },
21
+ email: { Type: 'varchar(128)' },
22
+ };
23
+ describe('schemaParser', () => {
24
+ it('parses a simple id field', () => {
25
+ const result = parseSchema({ user_id: 'id' }, CUSTOM_FIELDS);
26
+ const f = result.fields['user_id'];
27
+ assert.ok(f, 'field should exist');
28
+ assert.equal(f.type, 'SERIAL');
29
+ assert.equal(f.key, 'PRI');
30
+ assert.equal(f.nullable, ''); // SERIAL = implicit NOT NULL
31
+ });
32
+ it('parses str with length override', () => {
33
+ const result = parseSchema({ name: 'str/128' }, CUSTOM_FIELDS);
34
+ const f = result.fields['name'];
35
+ assert.equal(f.type, 'VARCHAR(128)');
36
+ });
37
+ it('parses required modifier → NOT NULL', () => {
38
+ const result = parseSchema({ name: 'str required' }, CUSTOM_FIELDS);
39
+ const f = result.fields['name'];
40
+ assert.equal(f.nullable, 'NOT NULL');
41
+ });
42
+ it('default: NULL when not required', () => {
43
+ const result = parseSchema({ name: 'str' }, CUSTOM_FIELDS);
44
+ const f = result.fields['name'];
45
+ assert.equal(f.nullable, 'NULL');
46
+ });
47
+ it('parses unique modifier', () => {
48
+ const result = parseSchema({ email: 'email unique' }, CUSTOM_FIELDS);
49
+ const f = result.fields['email'];
50
+ assert.equal(f.key, 'UNI');
51
+ });
52
+ it('parses custom field defaults', () => {
53
+ const result = parseSchema({ created: 'now' }, CUSTOM_FIELDS);
54
+ const f = result.fields['created'];
55
+ assert.equal(f.type, 'TIMESTAMP');
56
+ assert.equal(f.defaultValue, 'now()');
57
+ });
58
+ it('parses explicit default/value', () => {
59
+ const result = parseSchema({ status: 'str/32 default/active' }, CUSTOM_FIELDS);
60
+ const f = result.fields['status'];
61
+ assert.equal(f.defaultValue, 'active');
62
+ });
63
+ it('parses individual index', () => {
64
+ const result = parseSchema({ email: 'email index' }, CUSTOM_FIELDS);
65
+ assert.ok(result.individualIndexes.includes('email'));
66
+ });
67
+ it('parses composite index', () => {
68
+ const result = parseSchema({
69
+ user_id: 'int index/user_date',
70
+ log_date: 'now index/user_date',
71
+ }, CUSTOM_FIELDS);
72
+ assert.deepEqual(result.compositeIndexes['user_date'], ['user_id', 'log_date']);
73
+ });
74
+ it('parses composite unique index', () => {
75
+ const result = parseSchema({
76
+ ticker: 'str unique/ticker_ex',
77
+ exchange: 'str unique/ticker_ex',
78
+ }, CUSTOM_FIELDS);
79
+ assert.deepEqual(result.compositeUniqueIndexes['ticker_ex'], ['ticker', 'exchange']);
80
+ });
81
+ it('skips ~ meta keys', () => {
82
+ const result = parseSchema({
83
+ '~ignore': 'true',
84
+ name: 'str',
85
+ }, CUSTOM_FIELDS);
86
+ assert.ok(!result.fields['~ignore']);
87
+ assert.ok(result.fields['name']);
88
+ });
89
+ it('handles null/undefined input', () => {
90
+ const result = parseSchema(null, CUSTOM_FIELDS);
91
+ assert.deepEqual(result.fields, {});
92
+ });
93
+ });
94
+ // ──────────────────────────────────────────
95
+ // Default Normalizer Tests
96
+ // ──────────────────────────────────────────
97
+ describe('normalizeDefaultSql', () => {
98
+ it('returns null for null/empty/undefined', () => {
99
+ assert.equal(normalizeDefaultSql(null, 'TEXT'), null);
100
+ assert.equal(normalizeDefaultSql(undefined, 'TEXT'), null);
101
+ assert.equal(normalizeDefaultSql('', 'TEXT'), null);
102
+ });
103
+ it('returns null for "null" string', () => {
104
+ assert.equal(normalizeDefaultSql('null', 'TEXT'), null);
105
+ assert.equal(normalizeDefaultSql('NULL', 'TEXT'), null);
106
+ });
107
+ it('keeps SQL functions as-is', () => {
108
+ assert.equal(normalizeDefaultSql('now()', 'TIMESTAMP'), 'now()');
109
+ assert.equal(normalizeDefaultSql('random()', 'REAL'), 'random()');
110
+ });
111
+ it('handles CURRENT_TIMESTAMP keyword', () => {
112
+ assert.equal(normalizeDefaultSql('CURRENT_TIMESTAMP', 'TIMESTAMP'), 'CURRENT_TIMESTAMP');
113
+ });
114
+ it('normalizes booleans', () => {
115
+ assert.equal(normalizeDefaultSql('true', 'BOOLEAN'), 'TRUE');
116
+ assert.equal(normalizeDefaultSql('false', 'BOOLEAN'), 'FALSE');
117
+ });
118
+ it('keeps numeric values as-is', () => {
119
+ assert.equal(normalizeDefaultSql('0', 'INTEGER'), '0');
120
+ assert.equal(normalizeDefaultSql('3.14', 'REAL'), '3.14');
121
+ assert.equal(normalizeDefaultSql('-1', 'INTEGER'), '-1');
122
+ });
123
+ it('casts JSON/JSONB objects', () => {
124
+ assert.equal(normalizeDefaultSql('{}', 'JSONB'), "'{}'::jsonb");
125
+ assert.equal(normalizeDefaultSql('[]', 'JSON'), "'[]'::json");
126
+ });
127
+ it('quotes UUID literals', () => {
128
+ assert.equal(normalizeDefaultSql('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', 'UUID'), "'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'");
129
+ });
130
+ it('wraps plain strings in single quotes', () => {
131
+ assert.equal(normalizeDefaultSql('active', 'VARCHAR(32)'), "'active'");
132
+ });
133
+ it('keeps already single-quoted strings', () => {
134
+ assert.equal(normalizeDefaultSql("'hello'", 'TEXT'), "'hello'");
135
+ });
136
+ it('converts double-quoted to single-quoted', () => {
137
+ assert.equal(normalizeDefaultSql('"world"', 'TEXT'), "'world'");
138
+ });
139
+ it('strips DEFAULT prefix if present', () => {
140
+ assert.equal(normalizeDefaultSql('DEFAULT 42', 'INTEGER'), '42');
141
+ });
142
+ });
143
+ describe('buildDefaultClause', () => {
144
+ it('returns empty string for null', () => {
145
+ assert.equal(buildDefaultClause(null, 'TEXT'), '');
146
+ });
147
+ it('builds DEFAULT clause', () => {
148
+ assert.equal(buildDefaultClause('0', 'INTEGER'), 'DEFAULT 0');
149
+ assert.equal(buildDefaultClause('now()', 'TIMESTAMP'), 'DEFAULT now()');
150
+ assert.equal(buildDefaultClause('active', 'VARCHAR(32)'), "DEFAULT 'active'");
151
+ });
152
+ });
153
+ describe('normalizeDbDefaultForCompare', () => {
154
+ it('strips ::type casts', () => {
155
+ assert.equal(normalizeDbDefaultForCompare("'0'::integer"), '0');
156
+ assert.equal(normalizeDbDefaultForCompare("'active'::character varying"), 'active');
157
+ });
158
+ it('strips multiword type casts', () => {
159
+ assert.equal(normalizeDbDefaultForCompare("'2024-01-01'::timestamp without time zone"), '2024-01-01');
160
+ });
161
+ it('keeps nextval untouched', () => {
162
+ const val = "nextval('users_id_seq'::regclass)";
163
+ assert.equal(normalizeDbDefaultForCompare(val), val);
164
+ });
165
+ it('normalizes booleans', () => {
166
+ assert.equal(normalizeDbDefaultForCompare('TRUE'), 'true');
167
+ assert.equal(normalizeDbDefaultForCompare('false::boolean'), 'false');
168
+ });
169
+ it('handles null/empty', () => {
170
+ assert.equal(normalizeDbDefaultForCompare(null), '');
171
+ assert.equal(normalizeDbDefaultForCompare(''), '');
172
+ });
173
+ it('unescapes double single-quotes', () => {
174
+ assert.equal(normalizeDbDefaultForCompare("'it''s'::text"), "it's");
175
+ });
176
+ });
177
+ // ──────────────────────────────────────────
178
+ // SQL Generator Tests
179
+ // ──────────────────────────────────────────
180
+ describe('generateCreateTable', () => {
181
+ it('generates CREATE TABLE with correct structure', () => {
182
+ const schema = parseSchema({
183
+ user_id: 'id',
184
+ user_name: 'str required',
185
+ user_email: 'email unique index',
186
+ created: 'now',
187
+ }, CUSTOM_FIELDS);
188
+ const queries = generateCreateTable('users', schema, true);
189
+ assert.ok(queries.length > 0);
190
+ const createQ = queries[0];
191
+ assert.ok(createQ.sql.includes('CREATE TABLE "users"'));
192
+ assert.ok(createQ.sql.includes('"user_id" SERIAL'));
193
+ assert.ok(createQ.sql.includes('PRIMARY KEY'));
194
+ assert.ok(createQ.sql.includes('"user_name" VARCHAR(64) NOT NULL'));
195
+ assert.ok(createQ.sql.includes('DEFAULT now()'));
196
+ // Should have UNIQUE constraint
197
+ const uniqueQ = queries.find(q => q.sql.includes('UNIQUE'));
198
+ assert.ok(uniqueQ, 'should have UNIQUE constraint for email');
199
+ // Should have INDEX
200
+ const indexQ = queries.find(q => q.sql.includes('CREATE INDEX'));
201
+ assert.ok(indexQ, 'should have INDEX for email');
202
+ });
203
+ });
204
+ describe('generateDropTable', () => {
205
+ it('generates DROP TABLE CASCADE', () => {
206
+ const q = generateDropTable('old_table', true);
207
+ assert.equal(q.sql, 'DROP TABLE IF EXISTS "old_table" CASCADE;');
208
+ assert.equal(q.color, 'yellow');
209
+ });
210
+ });
211
+ // ──────────────────────────────────────────
212
+ // Type Dictionary Tests
213
+ // ──────────────────────────────────────────
214
+ describe('typeDictionary', () => {
215
+ it('maps SERIAL to integer', () => {
216
+ assert.equal(POSTGRES_TYPE_DICTIONARY['SERIAL'], 'integer');
217
+ });
218
+ it('maps VARCHAR to character varying', () => {
219
+ assert.equal(POSTGRES_TYPE_DICTIONARY['VARCHAR'], 'character varying');
220
+ });
221
+ it('maps TIMESTAMP to timestamp without time zone', () => {
222
+ assert.equal(POSTGRES_TYPE_DICTIONARY['TIMESTAMP'], 'timestamp without time zone');
223
+ });
224
+ it('maps TEXT to text', () => {
225
+ assert.equal(POSTGRES_TYPE_DICTIONARY['TEXT'], 'text');
226
+ });
227
+ });
228
+ //# sourceMappingURL=core.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.test.js","sourceRoot":"","sources":["../../src/__tests__/core.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export interface BuilderOptions {
2
+ mute?: boolean;
3
+ create?: boolean;
4
+ name?: string;
5
+ tenant?: string;
6
+ dry?: boolean;
7
+ config?: string;
8
+ /** If true, DROP tables that exist in DB but not in YAML. Default: false (safe). */
9
+ dropOrphans?: boolean;
10
+ }
11
+ export interface MigrationResult {
12
+ executed: number;
13
+ failed: {
14
+ sql: string;
15
+ error: string;
16
+ }[];
17
+ total: number;
18
+ }
19
+ /**
20
+ * Run the full database migration flow.
21
+ */
22
+ export declare function up(options?: BuilderOptions): Promise<MigrationResult>;
23
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,cAAc;IAC3B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oFAAoF;IACpF,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;CACjB;AAeD;;GAEG;AACH,wBAAsB,EAAE,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,eAAe,CAAC,CAsP/E"}
@@ -0,0 +1,262 @@
1
+ // ─────────────────────────────────────────────
2
+ // x-postgres — Builder (orchestrator)
3
+ // ─────────────────────────────────────────────
4
+ // Port of PgBuilder.up() — loads config, scans YAML,
5
+ // diffs against live DB, and executes migration queries.
6
+ import { readFileSync, readdirSync, existsSync, statSync } from 'node:fs';
7
+ import { resolve, join } from 'node:path';
8
+ import YAML from 'yaml';
9
+ import * as readline from 'node:readline';
10
+ import { loadConfig, resolveSchemaPath } from './configLoader.js';
11
+ import { parseSchema } from './schemaParser.js';
12
+ import { generateCreateTable, generateDropTable, generateCreateDatabase } from './sqlGenerator.js';
13
+ import { generateUpdateTable } from './diffEngine.js';
14
+ import { PgService } from './pgService.js';
15
+ import * as log from './logger.js';
16
+ /**
17
+ * Prompt the user for yes/no confirmation.
18
+ */
19
+ async function promptConfirm(message) {
20
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
21
+ return new Promise(resolve => {
22
+ rl.question(message, answer => {
23
+ rl.close();
24
+ resolve(answer.trim() === '1' || answer.trim().toLowerCase() === 'y');
25
+ });
26
+ });
27
+ }
28
+ /**
29
+ * Run the full database migration flow.
30
+ */
31
+ export async function up(options = {}) {
32
+ const mute = options.mute ?? false;
33
+ const dryRun = options.dry ?? false;
34
+ const result = { executed: 0, failed: [], total: 0 };
35
+ // Load config
36
+ let cfg;
37
+ try {
38
+ cfg = loadConfig(options.config);
39
+ }
40
+ catch (err) {
41
+ const msg = err.message;
42
+ throw new Error(`Config error: ${msg}. Please verify your xpg.config.yml or config/postgres.yml`);
43
+ }
44
+ const { postgres, customFields, configDir } = cfg;
45
+ // Iterate database clusters
46
+ for (const [dbId, dbConf] of Object.entries(postgres.DB)) {
47
+ // Normalize: could be array (multi-node) or single object
48
+ const nodes = Array.isArray(dbConf) ? dbConf : [dbConf];
49
+ const writeNode = nodes.find(n => n.TYPE === 'write') ?? nodes[0];
50
+ // Filter by --tenant
51
+ if (options.tenant && !writeNode.TENANT_KEYS)
52
+ continue;
53
+ // Filter by --name
54
+ if (options.name) {
55
+ if (options.name !== writeNode.NAME && !writeNode.TENANT_KEYS)
56
+ continue;
57
+ }
58
+ if (!mute)
59
+ log.say(`\n► PostgreSQL '${dbId}' ...`, 'cyan');
60
+ // Resolve schema paths
61
+ let databasePaths = [];
62
+ if (writeNode.PATH) {
63
+ const paths = Array.isArray(writeNode.PATH) ? writeNode.PATH : [writeNode.PATH];
64
+ databasePaths = paths.map(p => resolveSchemaPath(p, configDir));
65
+ }
66
+ else {
67
+ // Default: database/ dir in configDir
68
+ const defaultPath = resolve(configDir, 'database');
69
+ if (existsSync(defaultPath))
70
+ databasePaths = [defaultPath];
71
+ }
72
+ // Connect
73
+ const pg = new PgService(dbConf, dbId);
74
+ const allQueries = [];
75
+ let createDbCount = 0;
76
+ // --create: check if database exists
77
+ if (options.create) {
78
+ try {
79
+ const adminPool = pg.getAdminPool();
80
+ const res = await adminPool.query('SELECT datname FROM pg_database WHERE datname = $1', [writeNode.NAME]);
81
+ if (res.rows.length === 0) {
82
+ const q = generateCreateDatabase(writeNode.NAME);
83
+ allQueries.push(q);
84
+ if (!mute)
85
+ log.say(`→ ${q.sql}`, 'green');
86
+ createDbCount++;
87
+ }
88
+ }
89
+ catch (err) {
90
+ log.error(`Failed to check database existence: ${err.message}`);
91
+ }
92
+ }
93
+ // Skip schema processing if we're only creating the database
94
+ if (createDbCount > 0 && allQueries.length > 0) {
95
+ // Execute create database first, then re-run
96
+ if (!dryRun) {
97
+ if (!mute) {
98
+ console.log('');
99
+ const ok = await promptConfirm('Create database first? (1: Yes, 0: No): ');
100
+ if (!ok) {
101
+ log.warn('Aborting!');
102
+ continue;
103
+ }
104
+ }
105
+ const adminPool = pg.getAdminPool();
106
+ for (const q of allQueries) {
107
+ await adminPool.query(q.sql);
108
+ }
109
+ if (!mute)
110
+ log.success(`Database created. Re-running schema migration...`);
111
+ allQueries.length = 0;
112
+ }
113
+ }
114
+ // Get existing tables
115
+ let tablesReal = [];
116
+ try {
117
+ const t = await pg.query("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'");
118
+ tablesReal = t.map(r => r.table_name);
119
+ }
120
+ catch {
121
+ if (!mute)
122
+ log.warn('Could not fetch existing tables (database may not exist yet)');
123
+ }
124
+ // Process YAML schema files
125
+ const tablesNew = [];
126
+ for (const schemaDir of databasePaths) {
127
+ if (!existsSync(schemaDir) || !statSync(schemaDir).isDirectory())
128
+ continue;
129
+ const files = readdirSync(schemaDir).filter(f => f.endsWith('.yml') || f.endsWith('.yaml'));
130
+ for (const fn of files) {
131
+ const fp = join(schemaDir, fn);
132
+ if (!mute)
133
+ log.say(`❍ Processing: ${fp}`, 'magenta');
134
+ let data;
135
+ try {
136
+ data = YAML.parse(readFileSync(fp, 'utf-8'));
137
+ if (!data || typeof data !== 'object') {
138
+ if (!mute)
139
+ log.warn('⚠ Invalid file format. Ignored.');
140
+ continue;
141
+ }
142
+ }
143
+ catch {
144
+ if (!mute)
145
+ log.warn('⚠ Failed to parse YAML. Ignored.');
146
+ continue;
147
+ }
148
+ for (let [tableName, tableCols] of Object.entries(data)) {
149
+ if (!tableCols || typeof tableCols !== 'object')
150
+ continue;
151
+ // Tenant prefix: ~tablename → PREF + tablename
152
+ if (tableName.startsWith('~') && writeNode.PREF) {
153
+ tableName = writeNode.PREF + tableName.substring(1);
154
+ }
155
+ tablesNew.push(tableName);
156
+ // Check for ~ignore
157
+ if (tableCols['~ignore'])
158
+ continue;
159
+ const schema = parseSchema(tableCols, customFields);
160
+ if (Object.keys(schema.fields).length === 0)
161
+ continue;
162
+ if (tablesReal.includes(tableName)) {
163
+ // ─── UPDATE existing table ───
164
+ try {
165
+ const columns = await pg.query(`SELECT column_name, data_type, is_nullable, character_maximum_length, column_default, numeric_precision, numeric_scale FROM information_schema.columns WHERE table_name = :_tbl`, { _tbl: tableName });
166
+ if (columns.length > 0) {
167
+ const currentCols = {};
168
+ for (const col of columns) {
169
+ currentCols[col.column_name] = col;
170
+ }
171
+ const indexes = await pg.query(`SELECT indexname FROM pg_indexes WHERE tablename = :_tbl`, { _tbl: tableName });
172
+ const uniques = await pg.query(`SELECT conname FROM pg_constraint WHERE conrelid = :_tbl::regclass AND contype = 'u'`, { _tbl: tableName });
173
+ const diffCtx = {
174
+ table: tableName,
175
+ schema,
176
+ currentColumns: currentCols,
177
+ existingIndexes: indexes,
178
+ existingUniques: uniques,
179
+ mute,
180
+ };
181
+ allQueries.push(...generateUpdateTable(diffCtx));
182
+ }
183
+ else {
184
+ if (!mute) {
185
+ log.header(`∴ ${tableName}`, 'blue');
186
+ log.say('✓ Table is up to date');
187
+ }
188
+ }
189
+ }
190
+ catch (err) {
191
+ log.error(`Error reading table ${tableName}: ${err.message}`);
192
+ }
193
+ }
194
+ else {
195
+ // ─── CREATE new table ───
196
+ allQueries.push(...generateCreateTable(tableName, schema, mute));
197
+ }
198
+ }
199
+ }
200
+ }
201
+ // ─── DROP tables not in YAML (opt-in via --drop-orphans) ───
202
+ if (options.dropOrphans) {
203
+ for (const existingTable of tablesReal) {
204
+ if (!tablesNew.includes(existingTable)) {
205
+ allQueries.push(generateDropTable(existingTable, mute));
206
+ }
207
+ }
208
+ }
209
+ else if (!mute) {
210
+ const orphans = tablesReal.filter(t => !tablesNew.includes(t));
211
+ if (orphans.length > 0) {
212
+ log.warn(`⚠ ${orphans.length} table(s) in DB but not in YAML: ${orphans.join(', ')}`);
213
+ log.warn(' Use --drop-orphans to drop them.');
214
+ }
215
+ }
216
+ // ─── Execute or show ───
217
+ if (allQueries.length > 0) {
218
+ if (!mute) {
219
+ log.say(`\n→ ${allQueries.length} requested actions for: ${dbId}`);
220
+ log.say('→ Please verify:');
221
+ for (const q of allQueries) {
222
+ log.say(` → ${q.mini}`, q.color);
223
+ }
224
+ }
225
+ if (dryRun) {
226
+ if (!mute) {
227
+ log.header('🔍 Dry run — no changes applied', 'yellow');
228
+ for (const q of allQueries) {
229
+ log.say(q.sql, 'gray');
230
+ }
231
+ }
232
+ }
233
+ else {
234
+ console.log('');
235
+ console.log('Are you sure you want to do this? ☝');
236
+ console.log('0: No');
237
+ console.log('1: Yes');
238
+ const ok = await promptConfirm('Choose an option: ');
239
+ if (!ok) {
240
+ log.warn('Aborting!');
241
+ continue;
242
+ }
243
+ for (const q of allQueries) {
244
+ try {
245
+ await pg.query(q.sql);
246
+ result.executed++;
247
+ }
248
+ catch (err) {
249
+ const errMsg = err.message;
250
+ result.failed.push({ sql: q.sql, error: errMsg });
251
+ log.error(`Failed: ${q.mini} — ${errMsg}`);
252
+ }
253
+ }
254
+ }
255
+ }
256
+ result.total += allQueries.length;
257
+ log.header(`❤ Finished ${dbId}. Changes: ${allQueries.length}`);
258
+ }
259
+ await PgService.closeAll();
260
+ return result;
261
+ }
262
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}