relq 1.0.2 → 1.0.3
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/cjs/cli/commands/add.cjs +403 -27
- package/dist/cjs/cli/commands/branch.cjs +13 -23
- package/dist/cjs/cli/commands/checkout.cjs +16 -29
- package/dist/cjs/cli/commands/cherry-pick.cjs +3 -4
- package/dist/cjs/cli/commands/commit.cjs +21 -29
- package/dist/cjs/cli/commands/diff.cjs +28 -32
- package/dist/cjs/cli/commands/export.cjs +7 -7
- package/dist/cjs/cli/commands/fetch.cjs +15 -21
- package/dist/cjs/cli/commands/generate.cjs +28 -54
- package/dist/cjs/cli/commands/history.cjs +19 -40
- package/dist/cjs/cli/commands/import.cjs +34 -41
- package/dist/cjs/cli/commands/init.cjs +69 -59
- package/dist/cjs/cli/commands/introspect.cjs +4 -8
- package/dist/cjs/cli/commands/log.cjs +26 -32
- package/dist/cjs/cli/commands/merge.cjs +24 -41
- package/dist/cjs/cli/commands/migrate.cjs +12 -25
- package/dist/cjs/cli/commands/pull.cjs +216 -106
- package/dist/cjs/cli/commands/push.cjs +35 -75
- package/dist/cjs/cli/commands/remote.cjs +2 -1
- package/dist/cjs/cli/commands/reset.cjs +22 -43
- package/dist/cjs/cli/commands/resolve.cjs +12 -14
- package/dist/cjs/cli/commands/rollback.cjs +16 -38
- package/dist/cjs/cli/commands/stash.cjs +5 -7
- package/dist/cjs/cli/commands/status.cjs +5 -10
- package/dist/cjs/cli/commands/sync.cjs +30 -50
- package/dist/cjs/cli/commands/tag.cjs +3 -4
- package/dist/cjs/cli/index.cjs +72 -9
- package/dist/cjs/cli/utils/change-tracker.cjs +107 -3
- package/dist/cjs/cli/utils/cli-utils.cjs +217 -0
- package/dist/cjs/cli/utils/config-loader.cjs +34 -8
- package/dist/cjs/cli/utils/fast-introspect.cjs +109 -3
- package/dist/cjs/cli/utils/git-utils.cjs +42 -161
- package/dist/cjs/cli/utils/pool-manager.cjs +156 -0
- package/dist/cjs/cli/utils/project-root.cjs +56 -5
- package/dist/cjs/cli/utils/relqignore.cjs +1 -0
- package/dist/cjs/cli/utils/repo-manager.cjs +47 -0
- package/dist/cjs/cli/utils/schema-comparator.cjs +301 -11
- package/dist/cjs/cli/utils/schema-diff.cjs +202 -1
- package/dist/cjs/cli/utils/schema-hash.cjs +2 -1
- package/dist/cjs/cli/utils/schema-introspect.cjs +7 -3
- package/dist/cjs/cli/utils/snapshot-manager.cjs +1 -0
- package/dist/cjs/cli/utils/spinner.cjs +14 -106
- package/dist/cjs/cli/utils/sql-generator.cjs +1 -1
- package/dist/cjs/cli/utils/type-generator.cjs +28 -16
- package/dist/config.d.ts +16 -25
- package/dist/esm/cli/commands/add.js +372 -29
- package/dist/esm/cli/commands/branch.js +14 -24
- package/dist/esm/cli/commands/checkout.js +16 -29
- package/dist/esm/cli/commands/cherry-pick.js +3 -4
- package/dist/esm/cli/commands/commit.js +22 -30
- package/dist/esm/cli/commands/diff.js +6 -10
- package/dist/esm/cli/commands/export.js +8 -8
- package/dist/esm/cli/commands/fetch.js +14 -20
- package/dist/esm/cli/commands/generate.js +28 -54
- package/dist/esm/cli/commands/history.js +11 -32
- package/dist/esm/cli/commands/import.js +35 -42
- package/dist/esm/cli/commands/init.js +65 -55
- package/dist/esm/cli/commands/introspect.js +4 -8
- package/dist/esm/cli/commands/log.js +6 -12
- package/dist/esm/cli/commands/merge.js +20 -37
- package/dist/esm/cli/commands/migrate.js +12 -25
- package/dist/esm/cli/commands/pull.js +204 -94
- package/dist/esm/cli/commands/push.js +21 -61
- package/dist/esm/cli/commands/remote.js +2 -1
- package/dist/esm/cli/commands/reset.js +16 -37
- package/dist/esm/cli/commands/resolve.js +13 -15
- package/dist/esm/cli/commands/rollback.js +16 -38
- package/dist/esm/cli/commands/stash.js +6 -8
- package/dist/esm/cli/commands/status.js +6 -11
- package/dist/esm/cli/commands/sync.js +30 -50
- package/dist/esm/cli/commands/tag.js +3 -4
- package/dist/esm/cli/index.js +72 -9
- package/dist/esm/cli/utils/change-tracker.js +107 -3
- package/dist/esm/cli/utils/cli-utils.js +169 -0
- package/dist/esm/cli/utils/config-loader.js +34 -8
- package/dist/esm/cli/utils/fast-introspect.js +109 -3
- package/dist/esm/cli/utils/git-utils.js +2 -124
- package/dist/esm/cli/utils/pool-manager.js +114 -0
- package/dist/esm/cli/utils/project-root.js +55 -5
- package/dist/esm/cli/utils/relqignore.js +1 -0
- package/dist/esm/cli/utils/repo-manager.js +42 -0
- package/dist/esm/cli/utils/schema-comparator.js +301 -11
- package/dist/esm/cli/utils/schema-diff.js +202 -1
- package/dist/esm/cli/utils/schema-hash.js +2 -1
- package/dist/esm/cli/utils/schema-introspect.js +7 -3
- package/dist/esm/cli/utils/snapshot-manager.js +1 -0
- package/dist/esm/cli/utils/spinner.js +1 -101
- package/dist/esm/cli/utils/sql-generator.js +1 -1
- package/dist/esm/cli/utils/type-generator.js +28 -16
- package/dist/index.d.ts +25 -8
- package/dist/schema-builder.d.ts +16 -6
- package/package.json +1 -1
|
@@ -1,101 +1 @@
|
|
|
1
|
-
|
|
2
|
-
const SPINNER_INTERVAL = 80;
|
|
3
|
-
export function createSpinner() {
|
|
4
|
-
let intervalId = null;
|
|
5
|
-
let frameIndex = 0;
|
|
6
|
-
let currentMessage = '';
|
|
7
|
-
let isSpinning = false;
|
|
8
|
-
const clearLine = () => {
|
|
9
|
-
process.stdout.write('\r\x1b[K');
|
|
10
|
-
};
|
|
11
|
-
const render = () => {
|
|
12
|
-
if (!isSpinning)
|
|
13
|
-
return;
|
|
14
|
-
clearLine();
|
|
15
|
-
const frame = SPINNER_FRAMES[frameIndex];
|
|
16
|
-
process.stdout.write(`\x1b[36m${frame}\x1b[0m ${currentMessage}`);
|
|
17
|
-
frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;
|
|
18
|
-
};
|
|
19
|
-
return {
|
|
20
|
-
start(message) {
|
|
21
|
-
if (isSpinning)
|
|
22
|
-
this.stop();
|
|
23
|
-
currentMessage = message;
|
|
24
|
-
isSpinning = true;
|
|
25
|
-
frameIndex = 0;
|
|
26
|
-
intervalId = setInterval(render, SPINNER_INTERVAL);
|
|
27
|
-
render();
|
|
28
|
-
},
|
|
29
|
-
update(message) {
|
|
30
|
-
currentMessage = message;
|
|
31
|
-
},
|
|
32
|
-
succeed(message) {
|
|
33
|
-
this.stop();
|
|
34
|
-
console.log(`\x1b[32m✓\x1b[0m ${message || currentMessage}`);
|
|
35
|
-
},
|
|
36
|
-
fail(message) {
|
|
37
|
-
this.stop();
|
|
38
|
-
console.log(`\x1b[31m✗\x1b[0m ${message || currentMessage}`);
|
|
39
|
-
},
|
|
40
|
-
info(message) {
|
|
41
|
-
this.stop();
|
|
42
|
-
console.log(`\x1b[34mℹ\x1b[0m ${message || currentMessage}`);
|
|
43
|
-
},
|
|
44
|
-
warn(message) {
|
|
45
|
-
this.stop();
|
|
46
|
-
console.log(`\x1b[33m⚠\x1b[0m ${message || currentMessage}`);
|
|
47
|
-
},
|
|
48
|
-
stop() {
|
|
49
|
-
if (intervalId) {
|
|
50
|
-
clearInterval(intervalId);
|
|
51
|
-
intervalId = null;
|
|
52
|
-
}
|
|
53
|
-
if (isSpinning) {
|
|
54
|
-
clearLine();
|
|
55
|
-
isSpinning = false;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
export const colors = {
|
|
61
|
-
reset: '\x1b[0m',
|
|
62
|
-
bold: (text) => `\x1b[1m${text}\x1b[0m`,
|
|
63
|
-
dim: (text) => `\x1b[2m${text}\x1b[0m`,
|
|
64
|
-
red: (text) => `\x1b[31m${text}\x1b[0m`,
|
|
65
|
-
green: (text) => `\x1b[32m${text}\x1b[0m`,
|
|
66
|
-
yellow: (text) => `\x1b[33m${text}\x1b[0m`,
|
|
67
|
-
blue: (text) => `\x1b[34m${text}\x1b[0m`,
|
|
68
|
-
magenta: (text) => `\x1b[35m${text}\x1b[0m`,
|
|
69
|
-
cyan: (text) => `\x1b[36m${text}\x1b[0m`,
|
|
70
|
-
gray: (text) => `\x1b[90m${text}\x1b[0m`,
|
|
71
|
-
white: (text) => `\x1b[37m${text}\x1b[0m`,
|
|
72
|
-
success: (text) => `\x1b[32m${text}\x1b[0m`,
|
|
73
|
-
error: (text) => `\x1b[31m${text}\x1b[0m`,
|
|
74
|
-
warning: (text) => `\x1b[33m${text}\x1b[0m`,
|
|
75
|
-
info: (text) => `\x1b[34m${text}\x1b[0m`,
|
|
76
|
-
muted: (text) => `\x1b[90m${text}\x1b[0m`,
|
|
77
|
-
};
|
|
78
|
-
export function progressBar(current, total, width = 30) {
|
|
79
|
-
const percentage = Math.min(100, Math.round((current / total) * 100));
|
|
80
|
-
const filled = Math.round((percentage / 100) * width);
|
|
81
|
-
const empty = width - filled;
|
|
82
|
-
const bar = '█'.repeat(filled) + '░'.repeat(empty);
|
|
83
|
-
return `\x1b[36m${bar}\x1b[0m ${percentage}%`;
|
|
84
|
-
}
|
|
85
|
-
export function formatBytes(bytes) {
|
|
86
|
-
if (bytes === 0)
|
|
87
|
-
return '0 B';
|
|
88
|
-
const k = 1024;
|
|
89
|
-
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
90
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
91
|
-
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
|
|
92
|
-
}
|
|
93
|
-
export function formatDuration(ms) {
|
|
94
|
-
if (ms < 1000)
|
|
95
|
-
return `${ms}ms`;
|
|
96
|
-
if (ms < 60000)
|
|
97
|
-
return `${(ms / 1000).toFixed(1)}s`;
|
|
98
|
-
const minutes = Math.floor(ms / 60000);
|
|
99
|
-
const seconds = Math.round((ms % 60000) / 1000);
|
|
100
|
-
return `${minutes}m ${seconds}s`;
|
|
101
|
-
}
|
|
1
|
+
export { colors, createSpinner, progressBar, formatBytes, formatDuration, fatal, error, warning, hint, requireInit, confirm, success, } from "./cli-utils.js";
|
|
@@ -324,7 +324,7 @@ export function generateIndexSQL(index, tableName) {
|
|
|
324
324
|
if (index.expression) {
|
|
325
325
|
parts.push(`(${index.expression})`);
|
|
326
326
|
}
|
|
327
|
-
else if (index.columns && index.columns.length > 0) {
|
|
327
|
+
else if (index.columns && Array.isArray(index.columns) && index.columns.length > 0) {
|
|
328
328
|
const cols = index.columns.map(c => quoteColumnRef(c)).join(', ');
|
|
329
329
|
parts.push(`(${cols})`);
|
|
330
330
|
}
|
|
@@ -700,8 +700,18 @@ function formatDefaultValue(val, col, domainMap) {
|
|
|
700
700
|
}
|
|
701
701
|
if (cleaned === "'[]'" || cleaned === 'ARRAY[]')
|
|
702
702
|
return 'emptyArray()';
|
|
703
|
+
const isJsonColumn = col.dataType.toLowerCase().includes('json');
|
|
704
|
+
if (isJsonColumn && cleaned.startsWith("'") && cleaned.endsWith("'")) {
|
|
705
|
+
const jsonStr = cleaned.slice(1, -1).replace(/''/g, "'");
|
|
706
|
+
try {
|
|
707
|
+
const parsed = JSON.parse(jsonStr);
|
|
708
|
+
return JSON.stringify(parsed);
|
|
709
|
+
}
|
|
710
|
+
catch {
|
|
711
|
+
}
|
|
712
|
+
}
|
|
703
713
|
const pgArrayMatch = cleaned.match(/^'?\{([^}]*)\}'?$/);
|
|
704
|
-
if (pgArrayMatch) {
|
|
714
|
+
if (pgArrayMatch && !isJsonColumn) {
|
|
705
715
|
const contents = pgArrayMatch[1];
|
|
706
716
|
if (contents === '') {
|
|
707
717
|
return 'emptyArray()';
|
|
@@ -736,16 +746,6 @@ function formatDefaultValue(val, col, domainMap) {
|
|
|
736
746
|
}
|
|
737
747
|
return 'emptyArray()';
|
|
738
748
|
}
|
|
739
|
-
const isJsonColumn = col.dataType.toLowerCase().includes('json');
|
|
740
|
-
if (isJsonColumn && cleaned.startsWith("'") && cleaned.endsWith("'")) {
|
|
741
|
-
const jsonStr = cleaned.slice(1, -1).replace(/''/g, "'");
|
|
742
|
-
try {
|
|
743
|
-
const parsed = JSON.parse(jsonStr);
|
|
744
|
-
return JSON.stringify(parsed);
|
|
745
|
-
}
|
|
746
|
-
catch {
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
749
|
if (cleaned.startsWith("'") && cleaned.endsWith("'")) {
|
|
750
750
|
const str = cleaned.slice(1, -1).replace(/'/g, "\\'");
|
|
751
751
|
return `'${str}'`;
|
|
@@ -1429,6 +1429,17 @@ function parseCheckValue(value, camelCase) {
|
|
|
1429
1429
|
if (/^-?\d+(\.\d+)?$/.test(value)) {
|
|
1430
1430
|
return value;
|
|
1431
1431
|
}
|
|
1432
|
+
const castMatch = value.match(/^\(?(.+?)\)?::[a-z_][a-z0-9_]*(\[\])?$/i);
|
|
1433
|
+
if (castMatch) {
|
|
1434
|
+
const innerValue = castMatch[1].trim();
|
|
1435
|
+
if (/^-?\d+(\.\d+)?$/.test(innerValue)) {
|
|
1436
|
+
return innerValue;
|
|
1437
|
+
}
|
|
1438
|
+
if (/^'.*'$/.test(innerValue)) {
|
|
1439
|
+
return innerValue;
|
|
1440
|
+
}
|
|
1441
|
+
return parseCheckValue(innerValue, camelCase);
|
|
1442
|
+
}
|
|
1432
1443
|
if (/^TRUE$/i.test(value))
|
|
1433
1444
|
return 'true';
|
|
1434
1445
|
if (/^FALSE$/i.test(value))
|
|
@@ -1550,16 +1561,17 @@ function generateDefineTable(table, camelCase = true, childPartitions, enumNames
|
|
|
1550
1561
|
if (enumMatch) {
|
|
1551
1562
|
const colName = enumMatch[1];
|
|
1552
1563
|
const valuesStr = enumMatch[2];
|
|
1553
|
-
const values = valuesStr
|
|
1554
|
-
.match(/'([^']+)'/g)
|
|
1555
|
-
?.map(v => v.replace(/'/g, '')) || [];
|
|
1564
|
+
const values = valuesStr.match(/'([^']+)'/g)?.map(v => v.replace(/'/g, '')) || [];
|
|
1556
1565
|
if (values.length > 0) {
|
|
1557
|
-
columnChecks.set(colName
|
|
1566
|
+
columnChecks.set(colName, values);
|
|
1558
1567
|
}
|
|
1559
1568
|
}
|
|
1560
1569
|
}
|
|
1561
1570
|
const columns = table.columns
|
|
1562
|
-
.map(col =>
|
|
1571
|
+
.map(col => {
|
|
1572
|
+
const checkValues = columnChecks.get(col.name);
|
|
1573
|
+
return generateColumnDef(col, seenColumns, camelCase, checkValues, enumNames, domainNames, compositeNames, domainMap);
|
|
1574
|
+
})
|
|
1563
1575
|
.filter(Boolean);
|
|
1564
1576
|
const columnNames = Array.from(seenColumns);
|
|
1565
1577
|
const indexesFn = table.indexes ? generateIndexes(table.indexes, columnNames, camelCase) : null;
|
package/dist/index.d.ts
CHANGED
|
@@ -325,13 +325,23 @@ export type BuildSelectType<T extends Record<string, ColumnConfig>> = {
|
|
|
325
325
|
} & {
|
|
326
326
|
[K in keyof T as IsRequiredForSelect<T[K]> extends true ? never : K]?: T[K] extends ColumnConfig<infer U> ? U | null : unknown;
|
|
327
327
|
};
|
|
328
|
-
export type
|
|
329
|
-
[K in keyof T
|
|
328
|
+
export type RequiredInsertKeys<T extends Record<string, ColumnConfig>> = {
|
|
329
|
+
[K in keyof T]: IsRequiredForInsert<T[K]> extends true ? K : never;
|
|
330
|
+
}[keyof T];
|
|
331
|
+
export type OptionalInsertKeys<T extends Record<string, ColumnConfig>> = {
|
|
332
|
+
[K in keyof T]: IsRequiredForInsert<T[K]> extends true ? never : K;
|
|
333
|
+
}[keyof T];
|
|
334
|
+
export type InferInsertValue<C extends ColumnConfig> = C extends ColumnConfig<infer U> ? C extends {
|
|
335
|
+
$nullable: true;
|
|
336
|
+
} ? U | null : U : unknown;
|
|
337
|
+
export type Simplify<T> = {
|
|
338
|
+
[K in keyof T]: T[K];
|
|
339
|
+
} & {};
|
|
340
|
+
export type BuildInsertType<T extends Record<string, ColumnConfig>> = Simplify<{
|
|
341
|
+
[K in RequiredInsertKeys<T>]: InferInsertValue<T[K]>;
|
|
330
342
|
} & {
|
|
331
|
-
[K in
|
|
332
|
-
|
|
333
|
-
} ? U | null : U : unknown;
|
|
334
|
-
};
|
|
343
|
+
[K in OptionalInsertKeys<T>]?: InferInsertValue<T[K]>;
|
|
344
|
+
}>;
|
|
335
345
|
export interface TableDefinition<T extends Record<string, ColumnConfig>> {
|
|
336
346
|
$name: string;
|
|
337
347
|
$schema?: string;
|
|
@@ -4497,6 +4507,13 @@ export declare class TypedSelectBuilder<TTable = any, TColumns extends readonly
|
|
|
4497
4507
|
*/
|
|
4498
4508
|
getBuilder(): SelectBuilder;
|
|
4499
4509
|
}
|
|
4510
|
+
/**
|
|
4511
|
+
* Extract insert type directly from TableDefinition or use InsertData fallback
|
|
4512
|
+
* This helps TypeScript eagerly evaluate the type for better autocomplete
|
|
4513
|
+
*/
|
|
4514
|
+
export type ExtractInsertType<T> = T extends {
|
|
4515
|
+
$inferInsert: infer I;
|
|
4516
|
+
} ? I : InsertData<T>;
|
|
4500
4517
|
/**
|
|
4501
4518
|
* Type-safe INSERT builder wrapper
|
|
4502
4519
|
*/
|
|
@@ -4507,12 +4524,12 @@ export declare class TypedInsertBuilder<TTable = any> {
|
|
|
4507
4524
|
* Add another row to insert
|
|
4508
4525
|
* Enforces required fields based on schema (notNull/primaryKey without defaults)
|
|
4509
4526
|
*/
|
|
4510
|
-
addRow(row:
|
|
4527
|
+
addRow(row: ExtractInsertType<TTable>): this;
|
|
4511
4528
|
/**
|
|
4512
4529
|
* Add multiple rows to insert
|
|
4513
4530
|
* Enforces required fields based on schema (notNull/primaryKey without defaults)
|
|
4514
4531
|
*/
|
|
4515
|
-
addRows(rows:
|
|
4532
|
+
addRows(rows: ExtractInsertType<TTable>[]): this;
|
|
4516
4533
|
/**
|
|
4517
4534
|
* Clear all rows
|
|
4518
4535
|
*/
|
package/dist/schema-builder.d.ts
CHANGED
|
@@ -1618,13 +1618,23 @@ export type BuildSelectType<T extends Record<string, ColumnConfig>> = {
|
|
|
1618
1618
|
} & {
|
|
1619
1619
|
[K in keyof T as IsRequiredForSelect<T[K]> extends true ? never : K]?: T[K] extends ColumnConfig<infer U> ? U | null : unknown;
|
|
1620
1620
|
};
|
|
1621
|
-
export type
|
|
1622
|
-
[K in keyof T
|
|
1621
|
+
export type RequiredInsertKeys<T extends Record<string, ColumnConfig>> = {
|
|
1622
|
+
[K in keyof T]: IsRequiredForInsert<T[K]> extends true ? K : never;
|
|
1623
|
+
}[keyof T];
|
|
1624
|
+
export type OptionalInsertKeys<T extends Record<string, ColumnConfig>> = {
|
|
1625
|
+
[K in keyof T]: IsRequiredForInsert<T[K]> extends true ? never : K;
|
|
1626
|
+
}[keyof T];
|
|
1627
|
+
export type InferInsertValue<C extends ColumnConfig> = C extends ColumnConfig<infer U> ? C extends {
|
|
1628
|
+
$nullable: true;
|
|
1629
|
+
} ? U | null : U : unknown;
|
|
1630
|
+
export type Simplify<T> = {
|
|
1631
|
+
[K in keyof T]: T[K];
|
|
1632
|
+
} & {};
|
|
1633
|
+
export type BuildInsertType<T extends Record<string, ColumnConfig>> = Simplify<{
|
|
1634
|
+
[K in RequiredInsertKeys<T>]: InferInsertValue<T[K]>;
|
|
1623
1635
|
} & {
|
|
1624
|
-
[K in
|
|
1625
|
-
|
|
1626
|
-
} ? U | null : U : unknown;
|
|
1627
|
-
};
|
|
1636
|
+
[K in OptionalInsertKeys<T>]?: InferInsertValue<T[K]>;
|
|
1637
|
+
}>;
|
|
1628
1638
|
export interface TableDefinition<T extends Record<string, ColumnConfig>> {
|
|
1629
1639
|
$name: string;
|
|
1630
1640
|
$schema?: string;
|