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.
Files changed (92) hide show
  1. package/dist/cjs/cli/commands/add.cjs +403 -27
  2. package/dist/cjs/cli/commands/branch.cjs +13 -23
  3. package/dist/cjs/cli/commands/checkout.cjs +16 -29
  4. package/dist/cjs/cli/commands/cherry-pick.cjs +3 -4
  5. package/dist/cjs/cli/commands/commit.cjs +21 -29
  6. package/dist/cjs/cli/commands/diff.cjs +28 -32
  7. package/dist/cjs/cli/commands/export.cjs +7 -7
  8. package/dist/cjs/cli/commands/fetch.cjs +15 -21
  9. package/dist/cjs/cli/commands/generate.cjs +28 -54
  10. package/dist/cjs/cli/commands/history.cjs +19 -40
  11. package/dist/cjs/cli/commands/import.cjs +34 -41
  12. package/dist/cjs/cli/commands/init.cjs +69 -59
  13. package/dist/cjs/cli/commands/introspect.cjs +4 -8
  14. package/dist/cjs/cli/commands/log.cjs +26 -32
  15. package/dist/cjs/cli/commands/merge.cjs +24 -41
  16. package/dist/cjs/cli/commands/migrate.cjs +12 -25
  17. package/dist/cjs/cli/commands/pull.cjs +216 -106
  18. package/dist/cjs/cli/commands/push.cjs +35 -75
  19. package/dist/cjs/cli/commands/remote.cjs +2 -1
  20. package/dist/cjs/cli/commands/reset.cjs +22 -43
  21. package/dist/cjs/cli/commands/resolve.cjs +12 -14
  22. package/dist/cjs/cli/commands/rollback.cjs +16 -38
  23. package/dist/cjs/cli/commands/stash.cjs +5 -7
  24. package/dist/cjs/cli/commands/status.cjs +5 -10
  25. package/dist/cjs/cli/commands/sync.cjs +30 -50
  26. package/dist/cjs/cli/commands/tag.cjs +3 -4
  27. package/dist/cjs/cli/index.cjs +72 -9
  28. package/dist/cjs/cli/utils/change-tracker.cjs +107 -3
  29. package/dist/cjs/cli/utils/cli-utils.cjs +217 -0
  30. package/dist/cjs/cli/utils/config-loader.cjs +34 -8
  31. package/dist/cjs/cli/utils/fast-introspect.cjs +109 -3
  32. package/dist/cjs/cli/utils/git-utils.cjs +42 -161
  33. package/dist/cjs/cli/utils/pool-manager.cjs +156 -0
  34. package/dist/cjs/cli/utils/project-root.cjs +56 -5
  35. package/dist/cjs/cli/utils/relqignore.cjs +1 -0
  36. package/dist/cjs/cli/utils/repo-manager.cjs +47 -0
  37. package/dist/cjs/cli/utils/schema-comparator.cjs +301 -11
  38. package/dist/cjs/cli/utils/schema-diff.cjs +202 -1
  39. package/dist/cjs/cli/utils/schema-hash.cjs +2 -1
  40. package/dist/cjs/cli/utils/schema-introspect.cjs +7 -3
  41. package/dist/cjs/cli/utils/snapshot-manager.cjs +1 -0
  42. package/dist/cjs/cli/utils/spinner.cjs +14 -106
  43. package/dist/cjs/cli/utils/sql-generator.cjs +1 -1
  44. package/dist/cjs/cli/utils/type-generator.cjs +28 -16
  45. package/dist/config.d.ts +16 -25
  46. package/dist/esm/cli/commands/add.js +372 -29
  47. package/dist/esm/cli/commands/branch.js +14 -24
  48. package/dist/esm/cli/commands/checkout.js +16 -29
  49. package/dist/esm/cli/commands/cherry-pick.js +3 -4
  50. package/dist/esm/cli/commands/commit.js +22 -30
  51. package/dist/esm/cli/commands/diff.js +6 -10
  52. package/dist/esm/cli/commands/export.js +8 -8
  53. package/dist/esm/cli/commands/fetch.js +14 -20
  54. package/dist/esm/cli/commands/generate.js +28 -54
  55. package/dist/esm/cli/commands/history.js +11 -32
  56. package/dist/esm/cli/commands/import.js +35 -42
  57. package/dist/esm/cli/commands/init.js +65 -55
  58. package/dist/esm/cli/commands/introspect.js +4 -8
  59. package/dist/esm/cli/commands/log.js +6 -12
  60. package/dist/esm/cli/commands/merge.js +20 -37
  61. package/dist/esm/cli/commands/migrate.js +12 -25
  62. package/dist/esm/cli/commands/pull.js +204 -94
  63. package/dist/esm/cli/commands/push.js +21 -61
  64. package/dist/esm/cli/commands/remote.js +2 -1
  65. package/dist/esm/cli/commands/reset.js +16 -37
  66. package/dist/esm/cli/commands/resolve.js +13 -15
  67. package/dist/esm/cli/commands/rollback.js +16 -38
  68. package/dist/esm/cli/commands/stash.js +6 -8
  69. package/dist/esm/cli/commands/status.js +6 -11
  70. package/dist/esm/cli/commands/sync.js +30 -50
  71. package/dist/esm/cli/commands/tag.js +3 -4
  72. package/dist/esm/cli/index.js +72 -9
  73. package/dist/esm/cli/utils/change-tracker.js +107 -3
  74. package/dist/esm/cli/utils/cli-utils.js +169 -0
  75. package/dist/esm/cli/utils/config-loader.js +34 -8
  76. package/dist/esm/cli/utils/fast-introspect.js +109 -3
  77. package/dist/esm/cli/utils/git-utils.js +2 -124
  78. package/dist/esm/cli/utils/pool-manager.js +114 -0
  79. package/dist/esm/cli/utils/project-root.js +55 -5
  80. package/dist/esm/cli/utils/relqignore.js +1 -0
  81. package/dist/esm/cli/utils/repo-manager.js +42 -0
  82. package/dist/esm/cli/utils/schema-comparator.js +301 -11
  83. package/dist/esm/cli/utils/schema-diff.js +202 -1
  84. package/dist/esm/cli/utils/schema-hash.js +2 -1
  85. package/dist/esm/cli/utils/schema-introspect.js +7 -3
  86. package/dist/esm/cli/utils/snapshot-manager.js +1 -0
  87. package/dist/esm/cli/utils/spinner.js +1 -101
  88. package/dist/esm/cli/utils/sql-generator.js +1 -1
  89. package/dist/esm/cli/utils/type-generator.js +28 -16
  90. package/dist/index.d.ts +25 -8
  91. package/dist/schema-builder.d.ts +16 -6
  92. package/package.json +1 -1
@@ -1,101 +1 @@
1
- const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
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.toLowerCase(), values);
1566
+ columnChecks.set(colName, values);
1558
1567
  }
1559
1568
  }
1560
1569
  }
1561
1570
  const columns = table.columns
1562
- .map(col => generateColumnDef(col, seenColumns, camelCase, columnChecks.get(col.name.toLowerCase()), enumNames, domainNames, compositeNames, domainMap))
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 BuildInsertType<T extends Record<string, ColumnConfig>> = {
329
- [K in keyof T as IsRequiredForInsert<T[K]> extends true ? K : never]: T[K] extends ColumnConfig<infer U> ? U : unknown;
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 keyof T as IsRequiredForInsert<T[K]> extends true ? never : K]?: T[K] extends ColumnConfig<infer U> ? T[K] extends {
332
- $nullable: true;
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: InsertData<TTable>): this;
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: InsertData<TTable>[]): this;
4532
+ addRows(rows: ExtractInsertType<TTable>[]): this;
4516
4533
  /**
4517
4534
  * Clear all rows
4518
4535
  */
@@ -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 BuildInsertType<T extends Record<string, ColumnConfig>> = {
1622
- [K in keyof T as IsRequiredForInsert<T[K]> extends true ? K : never]: T[K] extends ColumnConfig<infer U> ? U : unknown;
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 keyof T as IsRequiredForInsert<T[K]> extends true ? never : K]?: T[K] extends ColumnConfig<infer U> ? T[K] extends {
1625
- $nullable: true;
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "relq",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "The Fully-Typed PostgreSQL ORM for TypeScript",
5
5
  "author": "Olajide Mathew O. <olajide.mathew@yuniq.solutions>",
6
6
  "license": "MIT",