@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.
- package/dist/__tests__/core.test.d.ts +2 -0
- package/dist/__tests__/core.test.d.ts.map +1 -0
- package/dist/__tests__/core.test.js +228 -0
- package/dist/__tests__/core.test.js.map +1 -0
- package/dist/builder.d.ts +23 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +262 -0
- package/dist/builder.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +119 -0
- package/dist/cli.js.map +1 -0
- package/dist/configLoader.d.ts +22 -0
- package/dist/configLoader.d.ts.map +1 -0
- package/dist/configLoader.js +97 -0
- package/dist/configLoader.js.map +1 -0
- package/dist/defaultNormalizer.d.ts +29 -0
- package/dist/defaultNormalizer.d.ts.map +1 -0
- package/dist/defaultNormalizer.js +124 -0
- package/dist/defaultNormalizer.js.map +1 -0
- package/dist/diffEngine.d.ts +21 -0
- package/dist/diffEngine.d.ts.map +1 -0
- package/dist/diffEngine.js +233 -0
- package/dist/diffEngine.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +22 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +63 -0
- package/dist/logger.js.map +1 -0
- package/dist/pgService.d.ts +42 -0
- package/dist/pgService.d.ts.map +1 -0
- package/dist/pgService.js +219 -0
- package/dist/pgService.js.map +1 -0
- package/dist/schemaParser.d.ts +10 -0
- package/dist/schemaParser.d.ts.map +1 -0
- package/dist/schemaParser.js +118 -0
- package/dist/schemaParser.js.map +1 -0
- package/dist/sqlGenerator.d.ts +18 -0
- package/dist/sqlGenerator.d.ts.map +1 -0
- package/dist/sqlGenerator.js +104 -0
- package/dist/sqlGenerator.js.map +1 -0
- package/dist/typeDictionary.d.ts +2 -0
- package/dist/typeDictionary.d.ts.map +1 -0
- package/dist/typeDictionary.js +27 -0
- package/dist/typeDictionary.js.map +1 -0
- package/dist/types.d.ts +72 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
- package/xpg.config.yml-sample +42 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ─────────────────────────────────────────────
|
|
3
|
+
// x-postgres — CLI entry point
|
|
4
|
+
// ─────────────────────────────────────────────
|
|
5
|
+
import { Command } from 'commander';
|
|
6
|
+
import { writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
7
|
+
import { resolve } from 'node:path';
|
|
8
|
+
import { up } from './builder.js';
|
|
9
|
+
import * as log from './logger.js';
|
|
10
|
+
const program = new Command();
|
|
11
|
+
program
|
|
12
|
+
.name('xpg')
|
|
13
|
+
.description('YAML-driven PostgreSQL schema management & migrations')
|
|
14
|
+
.version('1.0.0')
|
|
15
|
+
.option('--no-color', 'Disable colored output');
|
|
16
|
+
// ─── up command ───
|
|
17
|
+
program
|
|
18
|
+
.command('up')
|
|
19
|
+
.description('Run database migrations (create/update/drop tables from YAML schemas)')
|
|
20
|
+
.option('--create', 'Create database if it does not exist')
|
|
21
|
+
.option('--name <db>', 'Target specific database cluster by NAME')
|
|
22
|
+
.option('--tenant <key>', 'Target specific tenant key')
|
|
23
|
+
.option('--mute', 'Suppress all output')
|
|
24
|
+
.option('--dry', 'Dry run — show queries without executing')
|
|
25
|
+
.option('--drop-orphans', 'Drop tables that exist in DB but not in YAML')
|
|
26
|
+
.option('--config <path>', 'Path to config file (default: xpg.config.yml)')
|
|
27
|
+
.action(async (opts) => {
|
|
28
|
+
try {
|
|
29
|
+
await up({
|
|
30
|
+
create: opts.create,
|
|
31
|
+
name: opts.name,
|
|
32
|
+
tenant: opts.tenant,
|
|
33
|
+
mute: opts.mute,
|
|
34
|
+
dry: opts.dry,
|
|
35
|
+
dropOrphans: opts.dropOrphans,
|
|
36
|
+
config: opts.config,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
log.error(err.message);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
// ─── init command ───
|
|
45
|
+
program
|
|
46
|
+
.command('init')
|
|
47
|
+
.description('Generate sample configuration files in the current directory')
|
|
48
|
+
.action(() => {
|
|
49
|
+
const configPath = resolve(process.cwd(), 'xpg.config.yml');
|
|
50
|
+
const dbDir = resolve(process.cwd(), 'database');
|
|
51
|
+
if (existsSync(configPath)) {
|
|
52
|
+
log.warn('xpg.config.yml already exists. Skipping.');
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
writeFileSync(configPath, SAMPLE_CONFIG);
|
|
56
|
+
log.success('✓ Created xpg.config.yml');
|
|
57
|
+
}
|
|
58
|
+
if (!existsSync(dbDir)) {
|
|
59
|
+
mkdirSync(dbDir, { recursive: true });
|
|
60
|
+
writeFileSync(resolve(dbDir, 'example.yml'), SAMPLE_TABLE);
|
|
61
|
+
log.success('✓ Created database/example.yml');
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
log.warn('database/ already exists. Skipping.');
|
|
65
|
+
}
|
|
66
|
+
log.say('\nEdit xpg.config.yml with your PostgreSQL credentials, then run:');
|
|
67
|
+
log.say(' npx xpg up', 'cyan');
|
|
68
|
+
});
|
|
69
|
+
program.parse();
|
|
70
|
+
// ─── Sample templates ───
|
|
71
|
+
const SAMPLE_CONFIG = `#────────────────────────────────────
|
|
72
|
+
# x-postgres configuration
|
|
73
|
+
#────────────────────────────────────
|
|
74
|
+
POSTGRES:
|
|
75
|
+
DB:
|
|
76
|
+
"main":
|
|
77
|
+
NAME: my_database
|
|
78
|
+
HOST: <ENV.DB_HOST>
|
|
79
|
+
USER: <ENV.DB_USER>
|
|
80
|
+
PASS: <ENV.DB_PASS>
|
|
81
|
+
PORT: <ENV.DB_PORT>
|
|
82
|
+
PREF: app_
|
|
83
|
+
PATH: [database]
|
|
84
|
+
|
|
85
|
+
CUSTOM_FIELDS:
|
|
86
|
+
"id":
|
|
87
|
+
Type: serial
|
|
88
|
+
Key: PRI
|
|
89
|
+
"str":
|
|
90
|
+
Type: varchar(64)
|
|
91
|
+
"text":
|
|
92
|
+
Type: text
|
|
93
|
+
"int":
|
|
94
|
+
Type: integer
|
|
95
|
+
"float":
|
|
96
|
+
Type: real
|
|
97
|
+
"date":
|
|
98
|
+
Type: timestamp
|
|
99
|
+
"email":
|
|
100
|
+
Type: varchar(128)
|
|
101
|
+
"phone":
|
|
102
|
+
Type: varchar(11)
|
|
103
|
+
"now":
|
|
104
|
+
Type: timestamp
|
|
105
|
+
Default: now()
|
|
106
|
+
"pid":
|
|
107
|
+
Type: varchar(12)
|
|
108
|
+
Key: UNI
|
|
109
|
+
Default: '"left"(md5((random())::text), 12)'
|
|
110
|
+
`;
|
|
111
|
+
const SAMPLE_TABLE = `# Example table definition
|
|
112
|
+
example_users:
|
|
113
|
+
user_id: id
|
|
114
|
+
user_name: str required
|
|
115
|
+
user_email: email unique index
|
|
116
|
+
user_status: str/32 default/active index
|
|
117
|
+
user_date_insert: now
|
|
118
|
+
`;
|
|
119
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { PostgresConfig, CustomFieldDef } from './types.js';
|
|
2
|
+
export interface LoadedConfig {
|
|
3
|
+
postgres: PostgresConfig['POSTGRES'];
|
|
4
|
+
customFields: Record<string, CustomFieldDef>;
|
|
5
|
+
/** Directory where the config file lives (used to resolve relative paths) */
|
|
6
|
+
configDir: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Load configuration.
|
|
10
|
+
*
|
|
11
|
+
* Resolution order:
|
|
12
|
+
* 1. `--config <path>` CLI argument → single file
|
|
13
|
+
* 2. `xpg.config.yml` in CWD
|
|
14
|
+
* 3. `config/postgres.yml` + `config/custom_fields.yml` (PHP-compatible layout)
|
|
15
|
+
*/
|
|
16
|
+
export declare function loadConfig(configPath?: string): LoadedConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve database schema paths from config.
|
|
19
|
+
* Handles both absolute paths and paths relative to configDir.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveSchemaPath(pathEntry: string, configDir: string): string;
|
|
22
|
+
//# sourceMappingURL=configLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configLoader.d.ts","sourceRoot":"","sources":["../src/configLoader.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA+BjE,MAAM,WAAW,YAAY;IACzB,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC7C,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,YAAY,CA6C5D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG9E"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────
|
|
2
|
+
// x-postgres — Config loader
|
|
3
|
+
// ─────────────────────────────────────────────
|
|
4
|
+
// Loads xpg.config.yml (or separate postgres.yml + custom_fields.yml)
|
|
5
|
+
// with environment variable interpolation: <ENV.VAR> → process.env.VAR
|
|
6
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
7
|
+
import { resolve, dirname } from 'node:path';
|
|
8
|
+
import YAML from 'yaml';
|
|
9
|
+
/**
|
|
10
|
+
* Interpolate <ENV.VAR_NAME> placeholders with process.env values.
|
|
11
|
+
*/
|
|
12
|
+
function interpolateEnv(raw) {
|
|
13
|
+
return raw.replace(/<ENV\.([A-Za-z_][A-Za-z0-9_]*)>/g, (_match, varName) => {
|
|
14
|
+
const val = process.env[varName];
|
|
15
|
+
if (val === undefined) {
|
|
16
|
+
console.warn(`[x-postgres] ⚠ ENV var "${varName}" is not defined — using empty string`);
|
|
17
|
+
}
|
|
18
|
+
return val ?? '';
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Recursively walk a parsed YAML object and interpolate env vars in all string values.
|
|
23
|
+
*/
|
|
24
|
+
function deepInterpolate(obj) {
|
|
25
|
+
if (typeof obj === 'string')
|
|
26
|
+
return interpolateEnv(obj);
|
|
27
|
+
if (Array.isArray(obj))
|
|
28
|
+
return obj.map(deepInterpolate);
|
|
29
|
+
if (obj !== null && typeof obj === 'object') {
|
|
30
|
+
const result = {};
|
|
31
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
32
|
+
result[k] = deepInterpolate(v);
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
return obj;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Load configuration.
|
|
40
|
+
*
|
|
41
|
+
* Resolution order:
|
|
42
|
+
* 1. `--config <path>` CLI argument → single file
|
|
43
|
+
* 2. `xpg.config.yml` in CWD
|
|
44
|
+
* 3. `config/postgres.yml` + `config/custom_fields.yml` (PHP-compatible layout)
|
|
45
|
+
*/
|
|
46
|
+
export function loadConfig(configPath) {
|
|
47
|
+
let raw = {};
|
|
48
|
+
let configDir = process.cwd();
|
|
49
|
+
if (configPath) {
|
|
50
|
+
const abs = resolve(configPath);
|
|
51
|
+
if (!existsSync(abs))
|
|
52
|
+
throw new Error(`Config file not found: ${abs}`);
|
|
53
|
+
raw = YAML.parse(readFileSync(abs, 'utf-8')) ?? {};
|
|
54
|
+
configDir = dirname(abs);
|
|
55
|
+
}
|
|
56
|
+
else if (existsSync(resolve(process.cwd(), 'xpg.config.yml'))) {
|
|
57
|
+
const abs = resolve(process.cwd(), 'xpg.config.yml');
|
|
58
|
+
raw = YAML.parse(readFileSync(abs, 'utf-8')) ?? {};
|
|
59
|
+
configDir = dirname(abs);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
// Try PHP-compatible layout
|
|
63
|
+
const pgPath = resolve(process.cwd(), 'config/postgres.yml');
|
|
64
|
+
const cfPath = resolve(process.cwd(), 'config/custom_fields.yml');
|
|
65
|
+
if (existsSync(pgPath)) {
|
|
66
|
+
raw = YAML.parse(readFileSync(pgPath, 'utf-8')) ?? {};
|
|
67
|
+
}
|
|
68
|
+
if (existsSync(cfPath)) {
|
|
69
|
+
const cfRaw = YAML.parse(readFileSync(cfPath, 'utf-8')) ?? {};
|
|
70
|
+
// Merge custom fields into POSTGRES block
|
|
71
|
+
if (cfRaw?.POSTGRES?.CUSTOM_FIELDS && raw?.POSTGRES) {
|
|
72
|
+
raw.POSTGRES.CUSTOM_FIELDS = cfRaw.POSTGRES.CUSTOM_FIELDS;
|
|
73
|
+
}
|
|
74
|
+
else if (cfRaw?.POSTGRES?.CUSTOM_FIELDS) {
|
|
75
|
+
raw.POSTGRES = { CUSTOM_FIELDS: cfRaw.POSTGRES.CUSTOM_FIELDS };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Interpolate environment variables
|
|
80
|
+
raw = deepInterpolate(raw);
|
|
81
|
+
const postgres = raw.POSTGRES;
|
|
82
|
+
if (!postgres?.DB) {
|
|
83
|
+
throw new Error('Config error: POSTGRES.DB is missing. Please create xpg.config.yml or config/postgres.yml');
|
|
84
|
+
}
|
|
85
|
+
const customFields = postgres.CUSTOM_FIELDS ?? {};
|
|
86
|
+
return { postgres, customFields, configDir };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Resolve database schema paths from config.
|
|
90
|
+
* Handles both absolute paths and paths relative to configDir.
|
|
91
|
+
*/
|
|
92
|
+
export function resolveSchemaPath(pathEntry, configDir) {
|
|
93
|
+
if (pathEntry.startsWith('/'))
|
|
94
|
+
return pathEntry;
|
|
95
|
+
return resolve(configDir, pathEntry);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=configLoader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configLoader.js","sourceRoot":"","sources":["../src/configLoader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a raw default value from YAML into a safe SQL expression.
|
|
3
|
+
*
|
|
4
|
+
* Rules:
|
|
5
|
+
* - null/empty/"null" → null (no DEFAULT clause)
|
|
6
|
+
* - Numbers / booleans → as-is
|
|
7
|
+
* - SQL functions (ending with ")") or keywords (CURRENT_TIMESTAMP, etc.) → as-is
|
|
8
|
+
* - JSON/JSONB with {} or [] → cast with ::jsonb / ::json
|
|
9
|
+
* - UUID literals → single-quoted lowercase
|
|
10
|
+
* - Already single-quoted → as-is
|
|
11
|
+
* - Double-quoted → convert to single-quoted
|
|
12
|
+
* - Everything else → single-quoted string
|
|
13
|
+
*/
|
|
14
|
+
export declare function normalizeDefaultSql(rawDefault: string | null | undefined, typeRealUpper: string): string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Build the full DEFAULT clause for SQL, e.g. "DEFAULT 'value'"
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildDefaultClause(rawDefault: string | null | undefined, typeRealUpper: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Normalize a column_default value from Postgres for safe comparison.
|
|
21
|
+
*
|
|
22
|
+
* Examples:
|
|
23
|
+
* - "'0'::integer" → "0"
|
|
24
|
+
* - "true::boolean" → "true"
|
|
25
|
+
* - "now()" → "now()" (unchanged)
|
|
26
|
+
* - "nextval('tbl_id_seq'::regclass)" → kept as-is
|
|
27
|
+
*/
|
|
28
|
+
export declare function normalizeDbDefaultForCompare(dbDefault: string | null | undefined): string;
|
|
29
|
+
//# sourceMappingURL=defaultNormalizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultNormalizer.d.ts","sourceRoot":"","sources":["../src/defaultNormalizer.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA8D/G;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAIvG;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAkCzF"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// ─────────────────────────────────────────────
|
|
2
|
+
// x-postgres — Default value normalizer
|
|
3
|
+
// ─────────────────────────────────────────────
|
|
4
|
+
// Handles all logic for converting YAML default values to SQL,
|
|
5
|
+
// and normalizing database defaults for diff comparison.
|
|
6
|
+
/**
|
|
7
|
+
* Convert a raw default value from YAML into a safe SQL expression.
|
|
8
|
+
*
|
|
9
|
+
* Rules:
|
|
10
|
+
* - null/empty/"null" → null (no DEFAULT clause)
|
|
11
|
+
* - Numbers / booleans → as-is
|
|
12
|
+
* - SQL functions (ending with ")") or keywords (CURRENT_TIMESTAMP, etc.) → as-is
|
|
13
|
+
* - JSON/JSONB with {} or [] → cast with ::jsonb / ::json
|
|
14
|
+
* - UUID literals → single-quoted lowercase
|
|
15
|
+
* - Already single-quoted → as-is
|
|
16
|
+
* - Double-quoted → convert to single-quoted
|
|
17
|
+
* - Everything else → single-quoted string
|
|
18
|
+
*/
|
|
19
|
+
export function normalizeDefaultSql(rawDefault, typeRealUpper) {
|
|
20
|
+
if (rawDefault === null || rawDefault === undefined)
|
|
21
|
+
return null;
|
|
22
|
+
let raw = String(rawDefault).trim();
|
|
23
|
+
if (raw === '')
|
|
24
|
+
return null;
|
|
25
|
+
// Explicit "null" → no default
|
|
26
|
+
if (raw.toLowerCase() === 'null')
|
|
27
|
+
return null;
|
|
28
|
+
// Strip "DEFAULT " prefix if user typed it
|
|
29
|
+
if (raw.toLowerCase().startsWith('default ')) {
|
|
30
|
+
raw = raw.substring(8).trim();
|
|
31
|
+
}
|
|
32
|
+
const upperRaw = raw.toUpperCase();
|
|
33
|
+
// SQL functions (ends with ")") or SQL keywords
|
|
34
|
+
if (/\)\s*$/.test(raw) || ['CURRENT_TIMESTAMP', 'CURRENT_DATE', 'CURRENT_TIME'].includes(upperRaw)) {
|
|
35
|
+
return raw;
|
|
36
|
+
}
|
|
37
|
+
// Boolean
|
|
38
|
+
if (['true', 'false'].includes(raw.toLowerCase())) {
|
|
39
|
+
return raw.toUpperCase();
|
|
40
|
+
}
|
|
41
|
+
// Numeric
|
|
42
|
+
if (/^-?\d+(\.\d+)?$/.test(raw)) {
|
|
43
|
+
return raw;
|
|
44
|
+
}
|
|
45
|
+
// JSON / JSONB
|
|
46
|
+
if (typeRealUpper.includes('JSONB') || typeRealUpper.includes('JSON')) {
|
|
47
|
+
const first = raw[0];
|
|
48
|
+
if (first === '{' || first === '[') {
|
|
49
|
+
const escaped = raw.replace(/'/g, "''");
|
|
50
|
+
if (typeRealUpper.includes('JSONB'))
|
|
51
|
+
return `'${escaped}'::jsonb`;
|
|
52
|
+
return `'${escaped}'::json`;
|
|
53
|
+
}
|
|
54
|
+
// Already advanced expression
|
|
55
|
+
return raw;
|
|
56
|
+
}
|
|
57
|
+
// UUID literal
|
|
58
|
+
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(raw)) {
|
|
59
|
+
return `'${raw.toLowerCase()}'`;
|
|
60
|
+
}
|
|
61
|
+
// Already single-quoted
|
|
62
|
+
if (/^'(.*)'$/s.test(raw)) {
|
|
63
|
+
return raw;
|
|
64
|
+
}
|
|
65
|
+
// Double-quoted → convert
|
|
66
|
+
const dqMatch = raw.match(/^"(.*)"$/s);
|
|
67
|
+
if (dqMatch) {
|
|
68
|
+
raw = dqMatch[1];
|
|
69
|
+
}
|
|
70
|
+
// Default: wrap as string
|
|
71
|
+
const escaped = raw.replace(/'/g, "''");
|
|
72
|
+
return `'${escaped}'`;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Build the full DEFAULT clause for SQL, e.g. "DEFAULT 'value'"
|
|
76
|
+
*/
|
|
77
|
+
export function buildDefaultClause(rawDefault, typeRealUpper) {
|
|
78
|
+
const sql = normalizeDefaultSql(rawDefault, typeRealUpper);
|
|
79
|
+
if (sql === null)
|
|
80
|
+
return '';
|
|
81
|
+
return `DEFAULT ${sql}`;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Normalize a column_default value from Postgres for safe comparison.
|
|
85
|
+
*
|
|
86
|
+
* Examples:
|
|
87
|
+
* - "'0'::integer" → "0"
|
|
88
|
+
* - "true::boolean" → "true"
|
|
89
|
+
* - "now()" → "now()" (unchanged)
|
|
90
|
+
* - "nextval('tbl_id_seq'::regclass)" → kept as-is
|
|
91
|
+
*/
|
|
92
|
+
export function normalizeDbDefaultForCompare(dbDefault) {
|
|
93
|
+
let d = String(dbDefault ?? '').trim();
|
|
94
|
+
if (d === '')
|
|
95
|
+
return '';
|
|
96
|
+
d = d.replace(/\s+/g, ' ');
|
|
97
|
+
// Don't touch nextval (serial/sequence)
|
|
98
|
+
if (d.toLowerCase().includes('nextval('))
|
|
99
|
+
return d;
|
|
100
|
+
// Strip trailing ::type casts (handles multiword like "timestamp without time zone")
|
|
101
|
+
let prev = '';
|
|
102
|
+
while (prev !== d) {
|
|
103
|
+
prev = d;
|
|
104
|
+
const m = d.match(/^(.*)::[a-zA-Z][a-zA-Z0-9_ ]*$/);
|
|
105
|
+
if (m)
|
|
106
|
+
d = m[1].trim();
|
|
107
|
+
}
|
|
108
|
+
// Strip outer parentheses
|
|
109
|
+
const parenMatch = d.match(/^\((.*)\)$/);
|
|
110
|
+
if (parenMatch)
|
|
111
|
+
d = parenMatch[1].trim();
|
|
112
|
+
// Strip outer single quotes
|
|
113
|
+
const quoteMatch = d.match(/^'(.*)'$/s);
|
|
114
|
+
if (quoteMatch)
|
|
115
|
+
d = quoteMatch[1];
|
|
116
|
+
// Boolean normalize
|
|
117
|
+
if (['true', 'false'].includes(d.toLowerCase())) {
|
|
118
|
+
d = d.toLowerCase();
|
|
119
|
+
}
|
|
120
|
+
// Unescape double single-quotes
|
|
121
|
+
d = d.replace(/''/g, "'");
|
|
122
|
+
return d;
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=defaultNormalizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultNormalizer.js","sourceRoot":"","sources":["../src/defaultNormalizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ParsedSchema, DbColumnInfo, QueuedQuery } from './types.js';
|
|
2
|
+
interface DbIndexRow {
|
|
3
|
+
indexname: string;
|
|
4
|
+
}
|
|
5
|
+
interface DbConstraintRow {
|
|
6
|
+
conname: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DiffContext {
|
|
9
|
+
table: string;
|
|
10
|
+
schema: ParsedSchema;
|
|
11
|
+
currentColumns: Record<string, DbColumnInfo>;
|
|
12
|
+
existingIndexes: DbIndexRow[];
|
|
13
|
+
existingUniques: DbConstraintRow[];
|
|
14
|
+
mute: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate ALTER statements to bring a live table in sync with YAML schema.
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateUpdateTable(ctx: DiffContext): QueuedQuery[];
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=diffEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diffEngine.d.ts","sourceRoot":"","sources":["../src/diffEngine.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK1E,UAAU,UAAU;IAAG,SAAS,EAAE,MAAM,CAAA;CAAE;AAC1C,UAAU,eAAe;IAAG,OAAO,EAAE,MAAM,CAAA;CAAE;AAE7C,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAC7C,eAAe,EAAE,UAAU,EAAE,CAAC;IAC9B,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,IAAI,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,WAAW,GAAG,WAAW,EAAE,CAgOnE"}
|