relq 1.0.2 → 1.0.4

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 +10 -2
  44. package/dist/cjs/cli/utils/type-generator.cjs +28 -16
  45. package/dist/config.d.ts +16 -6
  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 +10 -2
  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 +18 -7
  92. package/package.json +1 -1
@@ -33,12 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.colors = void 0;
37
- exports.error = error;
38
- exports.fatal = fatal;
39
- exports.warning = warning;
40
- exports.hint = hint;
41
- exports.success = success;
36
+ exports.requireInit = exports.progressBar = exports.formatDuration = exports.formatBytes = exports.select = exports.success = exports.hint = exports.warning = exports.error = exports.fatal = exports.createSpinner = exports.colors = void 0;
42
37
  exports.info = info;
43
38
  exports.getWorkingTreeStatus = getWorkingTreeStatus;
44
39
  exports.requireRepository = requireRepository;
@@ -50,43 +45,24 @@ exports.checkUncommittedChanges = checkUncommittedChanges;
50
45
  exports.printMergeStrategyHelp = printMergeStrategyHelp;
51
46
  exports.validatePostgresSQL = validatePostgresSQL;
52
47
  exports.readSQLFile = readSQLFile;
53
- exports.createSpinner = createSpinner;
54
- exports.confirm = confirm;
55
- exports.select = select;
56
- exports.formatBytes = formatBytes;
57
- exports.formatDuration = formatDuration;
58
48
  const fs = __importStar(require("fs"));
59
49
  const path = __importStar(require("path"));
60
50
  const repo_manager_1 = require("./repo-manager.cjs");
61
- const isColorSupported = process.stdout.isTTY && !process.env.NO_COLOR;
62
- exports.colors = {
63
- red: (s) => isColorSupported ? `\x1b[31m${s}\x1b[0m` : s,
64
- green: (s) => isColorSupported ? `\x1b[32m${s}\x1b[0m` : s,
65
- yellow: (s) => isColorSupported ? `\x1b[33m${s}\x1b[0m` : s,
66
- blue: (s) => isColorSupported ? `\x1b[34m${s}\x1b[0m` : s,
67
- magenta: (s) => isColorSupported ? `\x1b[35m${s}\x1b[0m` : s,
68
- cyan: (s) => isColorSupported ? `\x1b[36m${s}\x1b[0m` : s,
69
- white: (s) => isColorSupported ? `\x1b[37m${s}\x1b[0m` : s,
70
- gray: (s) => isColorSupported ? `\x1b[90m${s}\x1b[0m` : s,
71
- bold: (s) => isColorSupported ? `\x1b[1m${s}\x1b[0m` : s,
72
- dim: (s) => isColorSupported ? `\x1b[2m${s}\x1b[0m` : s,
73
- };
74
- function error(message) {
75
- console.error(`${exports.colors.red('error:')} ${message}`);
76
- }
77
- function fatal(message) {
78
- console.error(`${exports.colors.red('fatal:')} ${message}`);
79
- process.exit(128);
80
- }
81
- function warning(message) {
82
- console.error(`${exports.colors.yellow('warning:')} ${message}`);
83
- }
84
- function hint(message) {
85
- console.log(`${exports.colors.yellow('hint:')} ${message}`);
86
- }
87
- function success(message) {
88
- console.log(`${exports.colors.green('✓')} ${message}`);
89
- }
51
+ var cli_utils_1 = require("./cli-utils.cjs");
52
+ Object.defineProperty(exports, "colors", { enumerable: true, get: function () { return cli_utils_1.colors; } });
53
+ Object.defineProperty(exports, "createSpinner", { enumerable: true, get: function () { return cli_utils_1.createSpinner; } });
54
+ Object.defineProperty(exports, "fatal", { enumerable: true, get: function () { return cli_utils_1.fatal; } });
55
+ Object.defineProperty(exports, "error", { enumerable: true, get: function () { return cli_utils_1.error; } });
56
+ Object.defineProperty(exports, "warning", { enumerable: true, get: function () { return cli_utils_1.warning; } });
57
+ Object.defineProperty(exports, "hint", { enumerable: true, get: function () { return cli_utils_1.hint; } });
58
+ Object.defineProperty(exports, "success", { enumerable: true, get: function () { return cli_utils_1.success; } });
59
+ Object.defineProperty(exports, "confirm", { enumerable: true, get: function () { return cli_utils_1.confirm; } });
60
+ Object.defineProperty(exports, "select", { enumerable: true, get: function () { return cli_utils_1.select; } });
61
+ Object.defineProperty(exports, "formatBytes", { enumerable: true, get: function () { return cli_utils_1.formatBytes; } });
62
+ Object.defineProperty(exports, "formatDuration", { enumerable: true, get: function () { return cli_utils_1.formatDuration; } });
63
+ Object.defineProperty(exports, "progressBar", { enumerable: true, get: function () { return cli_utils_1.progressBar; } });
64
+ Object.defineProperty(exports, "requireInit", { enumerable: true, get: function () { return cli_utils_1.requireInit; } });
65
+ const cli_utils_2 = require("./cli-utils.cjs");
90
66
  function info(message) {
91
67
  console.log(message);
92
68
  }
@@ -110,7 +86,7 @@ function getWorkingTreeStatus(projectRoot = process.cwd()) {
110
86
  }
111
87
  function requireRepository(projectRoot = process.cwd()) {
112
88
  if (!(0, repo_manager_1.isInitialized)(projectRoot)) {
113
- fatal('not a relq repository (or any of the parent directories): .relq');
89
+ (0, cli_utils_2.fatal)('not a relq repository (or any of the parent directories): .relq');
114
90
  }
115
91
  }
116
92
  function requireCleanWorkingTree(projectRoot = process.cwd(), operation = 'operation') {
@@ -136,44 +112,44 @@ function requireCleanWorkingTree(projectRoot = process.cwd(), operation = 'opera
136
112
  function printDirtyWorkingTreeError(status, operation) {
137
113
  console.log('');
138
114
  if (status.hasUnstagedChanges && status.hasUncommittedChanges) {
139
- error(`Your local changes would be overwritten by ${operation}.`);
140
- hint(`Commit your changes or stash them before you ${operation}.`);
115
+ (0, cli_utils_2.error)(`Your local changes would be overwritten by ${operation}.`);
116
+ (0, cli_utils_2.hint)(`Commit your changes or stash them before you ${operation}.`);
141
117
  }
142
118
  else if (status.hasUncommittedChanges) {
143
- error(`You have uncommitted changes.`);
144
- hint(`Please commit your changes before you ${operation}.`);
119
+ (0, cli_utils_2.error)(`You have uncommitted changes.`);
120
+ (0, cli_utils_2.hint)(`Please commit your changes before you ${operation}.`);
145
121
  }
146
122
  else {
147
- error(`You have unstaged changes.`);
148
- hint(`Please stage and commit your changes before you ${operation}.`);
123
+ (0, cli_utils_2.error)(`You have unstaged changes.`);
124
+ (0, cli_utils_2.hint)(`Please stage and commit your changes before you ${operation}.`);
149
125
  }
150
126
  console.log('');
151
127
  if (status.hasUncommittedChanges) {
152
128
  console.log(`Changes to be committed:`);
153
- console.log(` ${exports.colors.gray('(use "relq restore --staged <file>..." to unstage)')}`);
129
+ console.log(` ${cli_utils_2.colors.gray('(use "relq restore --staged <file>..." to unstage)')}`);
154
130
  console.log('');
155
131
  for (const change of status.stagedChanges.slice(0, 10)) {
156
132
  const prefix = change.type === 'CREATE' ? 'new' : change.type === 'DROP' ? 'deleted' : 'modified';
157
- const color = change.type === 'CREATE' ? exports.colors.green : change.type === 'DROP' ? exports.colors.red : exports.colors.yellow;
133
+ const color = change.type === 'CREATE' ? cli_utils_2.colors.green : change.type === 'DROP' ? cli_utils_2.colors.red : cli_utils_2.colors.yellow;
158
134
  console.log(`\t${color(`${prefix}:`.padEnd(12))}${change.objectName}`);
159
135
  }
160
136
  if (status.stagedChanges.length > 10) {
161
- console.log(`\t${exports.colors.gray(`... and ${status.stagedChanges.length - 10} more`)}`);
137
+ console.log(`\t${cli_utils_2.colors.gray(`... and ${status.stagedChanges.length - 10} more`)}`);
162
138
  }
163
139
  console.log('');
164
140
  }
165
141
  if (status.hasUnstagedChanges) {
166
142
  console.log(`Changes not staged for commit:`);
167
- console.log(` ${exports.colors.gray('(use "relq add <file>..." to update what will be committed)')}`);
168
- console.log(` ${exports.colors.gray('(use "relq restore <file>..." to discard changes in working directory)')}`);
143
+ console.log(` ${cli_utils_2.colors.gray('(use "relq add <file>..." to update what will be committed)')}`);
144
+ console.log(` ${cli_utils_2.colors.gray('(use "relq restore <file>..." to discard changes in working directory)')}`);
169
145
  console.log('');
170
146
  for (const change of status.unstagedChanges.slice(0, 10)) {
171
147
  const prefix = change.type === 'CREATE' ? 'new' : change.type === 'DROP' ? 'deleted' : 'modified';
172
- const color = change.type === 'CREATE' ? exports.colors.green : change.type === 'DROP' ? exports.colors.red : exports.colors.yellow;
148
+ const color = change.type === 'CREATE' ? cli_utils_2.colors.green : change.type === 'DROP' ? cli_utils_2.colors.red : cli_utils_2.colors.yellow;
173
149
  console.log(`\t${color(`${prefix}:`.padEnd(12))}${change.objectName}`);
174
150
  }
175
151
  if (status.unstagedChanges.length > 10) {
176
- console.log(`\t${exports.colors.gray(`... and ${status.unstagedChanges.length - 10} more`)}`);
152
+ console.log(`\t${cli_utils_2.colors.gray(`... and ${status.unstagedChanges.length - 10} more`)}`);
177
153
  }
178
154
  console.log('');
179
155
  }
@@ -209,23 +185,23 @@ function detectConflicts(localChanges, incomingChanges) {
209
185
  }
210
186
  function printConflictError(conflictInfo, operation) {
211
187
  console.log('');
212
- error(`Automatic ${operation} failed; fix conflicts and then commit the result.`);
188
+ (0, cli_utils_2.error)(`Automatic ${operation} failed; fix conflicts and then commit the result.`);
213
189
  console.log('');
214
190
  console.log(`CONFLICT (content): Merge conflict in schema`);
215
191
  console.log('');
216
192
  for (const conflict of conflictInfo.conflicts.slice(0, 10)) {
217
- console.log(` ${exports.colors.red('both modified:')} ${conflict.objectType.toLowerCase()} ${conflict.objectName}`);
193
+ console.log(` ${cli_utils_2.colors.red('both modified:')} ${conflict.objectType.toLowerCase()} ${conflict.objectName}`);
218
194
  }
219
195
  if (conflictInfo.conflicts.length > 10) {
220
- console.log(` ${exports.colors.gray(`... and ${conflictInfo.conflicts.length - 10} more conflicts`)}`);
196
+ console.log(` ${cli_utils_2.colors.gray(`... and ${conflictInfo.conflicts.length - 10} more conflicts`)}`);
221
197
  }
222
198
  console.log('');
223
- hint(`Fix conflicts manually and use:`);
224
- hint(` relq add . - to mark resolution`);
225
- hint(` relq commit - to complete the ${operation}`);
199
+ (0, cli_utils_2.hint)(`Fix conflicts manually and use:`);
200
+ (0, cli_utils_2.hint)(` relq add . - to mark resolution`);
201
+ (0, cli_utils_2.hint)(` relq commit - to complete the ${operation}`);
226
202
  console.log('');
227
- hint(`Or abort the ${operation} with:`);
228
- hint(` relq ${operation} --abort`);
203
+ (0, cli_utils_2.hint)(`Or abort the ${operation} with:`);
204
+ (0, cli_utils_2.hint)(` relq ${operation} --abort`);
229
205
  console.log('');
230
206
  }
231
207
  function checkUncommittedChanges(projectRoot = process.cwd()) {
@@ -244,10 +220,10 @@ function checkUncommittedChanges(projectRoot = process.cwd()) {
244
220
  function printMergeStrategyHelp() {
245
221
  console.log('');
246
222
  console.log('Resolution options:');
247
- console.log(` ${exports.colors.cyan('--theirs')} Accept all incoming changes (overwrite local)`);
248
- console.log(` ${exports.colors.cyan('--ours')} Keep all local changes (reject incoming)`);
249
- console.log(` ${exports.colors.cyan('--force')} Force operation, overwrite local changes`);
250
- console.log(` ${exports.colors.cyan('--abort')} Abort and restore previous state`);
223
+ console.log(` ${cli_utils_2.colors.cyan('--theirs')} Accept all incoming changes (overwrite local)`);
224
+ console.log(` ${cli_utils_2.colors.cyan('--ours')} Keep all local changes (reject incoming)`);
225
+ console.log(` ${cli_utils_2.colors.cyan('--force')} Force operation, overwrite local changes`);
226
+ console.log(` ${cli_utils_2.colors.cyan('--abort')} Abort and restore previous state`);
251
227
  console.log('');
252
228
  }
253
229
  function validatePostgresSQL(content) {
@@ -307,98 +283,3 @@ function readSQLFile(filePath) {
307
283
  const validation = validatePostgresSQL(content);
308
284
  return { content, validation };
309
285
  }
310
- function createSpinner() {
311
- const frames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
312
- let frameIndex = 0;
313
- let interval = null;
314
- let currentMessage = '';
315
- return {
316
- start(message) {
317
- currentMessage = message;
318
- if (process.stdout.isTTY) {
319
- interval = setInterval(() => {
320
- process.stdout.write(`\r${frames[frameIndex]} ${currentMessage}`);
321
- frameIndex = (frameIndex + 1) % frames.length;
322
- }, 80);
323
- }
324
- else {
325
- console.log(` ${message}...`);
326
- }
327
- },
328
- stop() {
329
- if (interval) {
330
- clearInterval(interval);
331
- interval = null;
332
- if (process.stdout.isTTY) {
333
- process.stdout.write('\r' + ' '.repeat(currentMessage.length + 4) + '\r');
334
- }
335
- }
336
- },
337
- succeed(message) {
338
- this.stop();
339
- console.log(`${exports.colors.green('✓')} ${message}`);
340
- },
341
- fail(message) {
342
- this.stop();
343
- console.log(`${exports.colors.red('✗')} ${message}`);
344
- },
345
- info(message) {
346
- this.stop();
347
- console.log(`${exports.colors.blue('ℹ')} ${message}`);
348
- },
349
- };
350
- }
351
- const readline = __importStar(require("readline"));
352
- function confirm(question, defaultYes = true) {
353
- const rl = readline.createInterface({
354
- input: process.stdin,
355
- output: process.stdout,
356
- });
357
- const suffix = defaultYes ? '[Y/n]' : '[y/N]';
358
- return new Promise((resolve) => {
359
- rl.question(`${question} ${exports.colors.gray(suffix)} `, (answer) => {
360
- rl.close();
361
- const a = answer.trim().toLowerCase();
362
- if (!a)
363
- resolve(defaultYes);
364
- else
365
- resolve(a === 'y' || a === 'yes');
366
- });
367
- });
368
- }
369
- function select(question, options) {
370
- const rl = readline.createInterface({
371
- input: process.stdin,
372
- output: process.stdout,
373
- });
374
- console.log(question);
375
- options.forEach((opt, i) => {
376
- console.log(` ${i + 1}) ${opt}`);
377
- });
378
- return new Promise((resolve) => {
379
- rl.question(`${exports.colors.gray('Select [1-' + options.length + ']:')} `, (answer) => {
380
- rl.close();
381
- const num = parseInt(answer.trim(), 10);
382
- if (num >= 1 && num <= options.length) {
383
- resolve(num - 1);
384
- }
385
- else {
386
- resolve(0);
387
- }
388
- });
389
- });
390
- }
391
- function formatBytes(bytes) {
392
- if (bytes < 1024)
393
- return `${bytes} B`;
394
- if (bytes < 1024 * 1024)
395
- return `${(bytes / 1024).toFixed(1)} KB`;
396
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
397
- }
398
- function formatDuration(ms) {
399
- if (ms < 1000)
400
- return `${ms}ms`;
401
- if (ms < 60000)
402
- return `${(ms / 1000).toFixed(1)}s`;
403
- return `${Math.floor(ms / 60000)}m ${Math.floor((ms % 60000) / 1000)}s`;
404
- }
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getPool = getPool;
37
+ exports.releasePool = releasePool;
38
+ exports.withPool = withPool;
39
+ exports.withClient = withClient;
40
+ exports.withTransaction = withTransaction;
41
+ exports.closeAllPools = closeAllPools;
42
+ exports.getActivePoolCount = getActivePoolCount;
43
+ const pools = new Map();
44
+ const IDLE_TIMEOUT = 30000;
45
+ let cleanupInterval = null;
46
+ function getPoolKey(config) {
47
+ if (config.url) {
48
+ return config.url;
49
+ }
50
+ return `${config.host || 'localhost'}:${config.port || 5432}/${config.database}@${config.user}`;
51
+ }
52
+ function startCleanupInterval() {
53
+ if (cleanupInterval)
54
+ return;
55
+ cleanupInterval = setInterval(() => {
56
+ const now = Date.now();
57
+ for (const [key, entry] of pools.entries()) {
58
+ if (entry.refCount === 0 && now - entry.lastUsed > IDLE_TIMEOUT) {
59
+ entry.pool.end().catch(() => { });
60
+ pools.delete(key);
61
+ }
62
+ }
63
+ if (pools.size === 0 && cleanupInterval) {
64
+ clearInterval(cleanupInterval);
65
+ cleanupInterval = null;
66
+ }
67
+ }, IDLE_TIMEOUT);
68
+ cleanupInterval.unref();
69
+ }
70
+ async function getPool(config) {
71
+ const key = getPoolKey(config);
72
+ let entry = pools.get(key);
73
+ if (entry) {
74
+ entry.refCount++;
75
+ entry.lastUsed = Date.now();
76
+ return entry.pool;
77
+ }
78
+ const { Pool } = await Promise.resolve().then(() => __importStar(require("../../addon/pg/index.cjs")));
79
+ const pool = new Pool({
80
+ host: config.host,
81
+ port: config.port || 5432,
82
+ database: config.database,
83
+ user: config.user,
84
+ password: config.password,
85
+ connectionString: config.url,
86
+ ssl: config.ssl,
87
+ max: config.max || 10,
88
+ idleTimeoutMillis: config.idleTimeoutMillis || 10000,
89
+ connectionTimeoutMillis: config.connectionTimeoutMillis || 5000,
90
+ });
91
+ entry = {
92
+ pool,
93
+ refCount: 1,
94
+ lastUsed: Date.now(),
95
+ };
96
+ pools.set(key, entry);
97
+ startCleanupInterval();
98
+ return pool;
99
+ }
100
+ function releasePool(config) {
101
+ const key = getPoolKey(config);
102
+ const entry = pools.get(key);
103
+ if (entry && entry.refCount > 0) {
104
+ entry.refCount--;
105
+ entry.lastUsed = Date.now();
106
+ }
107
+ }
108
+ async function withPool(config, fn) {
109
+ const pool = await getPool(config);
110
+ try {
111
+ return await fn(pool);
112
+ }
113
+ finally {
114
+ releasePool(config);
115
+ }
116
+ }
117
+ async function withClient(config, fn) {
118
+ const pool = await getPool(config);
119
+ const client = await pool.connect();
120
+ try {
121
+ return await fn(client);
122
+ }
123
+ finally {
124
+ client.release();
125
+ releasePool(config);
126
+ }
127
+ }
128
+ async function withTransaction(config, fn) {
129
+ return withClient(config, async (client) => {
130
+ await client.query('BEGIN');
131
+ try {
132
+ const result = await fn(client);
133
+ await client.query('COMMIT');
134
+ return result;
135
+ }
136
+ catch (error) {
137
+ await client.query('ROLLBACK');
138
+ throw error;
139
+ }
140
+ });
141
+ }
142
+ async function closeAllPools() {
143
+ if (cleanupInterval) {
144
+ clearInterval(cleanupInterval);
145
+ cleanupInterval = null;
146
+ }
147
+ const closePromises = [];
148
+ for (const [key, entry] of pools.entries()) {
149
+ closePromises.push(entry.pool.end());
150
+ pools.delete(key);
151
+ }
152
+ await Promise.all(closePromises);
153
+ }
154
+ function getActivePoolCount() {
155
+ return pools.size;
156
+ }
@@ -35,22 +35,73 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.findProjectRoot = findProjectRoot;
37
37
  exports.getRelqDir = getRelqDir;
38
+ exports.getProjectRoot = getProjectRoot;
38
39
  const fs = __importStar(require("fs"));
39
40
  const path = __importStar(require("path"));
41
+ const os = __importStar(require("os"));
42
+ const CONFIG_FILENAMES = [
43
+ 'relq.config.ts',
44
+ 'relq.config.js',
45
+ 'relq.config.mjs',
46
+ ];
47
+ function hasProjectMarker(dir) {
48
+ for (const filename of CONFIG_FILENAMES) {
49
+ if (fs.existsSync(path.join(dir, filename))) {
50
+ return true;
51
+ }
52
+ }
53
+ if (fs.existsSync(path.join(dir, 'package.json'))) {
54
+ return true;
55
+ }
56
+ return false;
57
+ }
40
58
  function findProjectRoot(startDir = process.cwd()) {
41
59
  let currentDir = path.resolve(startDir);
42
60
  const root = path.parse(currentDir).root;
61
+ const homeDir = os.homedir();
43
62
  while (currentDir !== root) {
44
- const packageJsonPath = path.join(currentDir, 'package.json');
45
- if (fs.existsSync(packageJsonPath)) {
63
+ if (hasProjectMarker(currentDir)) {
46
64
  return currentDir;
47
65
  }
66
+ if (currentDir === homeDir) {
67
+ return null;
68
+ }
48
69
  currentDir = path.dirname(currentDir);
49
70
  }
50
- return process.cwd();
71
+ return null;
51
72
  }
52
73
  function getRelqDir(startDir = process.cwd()) {
53
- const projectRoot = findProjectRoot(startDir) || process.cwd();
74
+ const projectRoot = findProjectRoot(startDir);
75
+ if (!projectRoot) {
76
+ const colors = {
77
+ red: (s) => `\x1b[31m${s}\x1b[0m`,
78
+ yellow: (s) => `\x1b[33m${s}\x1b[0m`,
79
+ cyan: (s) => `\x1b[36m${s}\x1b[0m`,
80
+ };
81
+ console.error('');
82
+ console.error(colors.red('fatal:') + ' not a relq project (or any of the parent directories)');
83
+ console.error('');
84
+ console.error(colors.yellow('hint:') + ` Run ${colors.cyan('relq init')} in your project directory to initialize relq.`);
85
+ console.error('');
86
+ process.exit(128);
87
+ }
54
88
  return path.join(projectRoot, '.relq');
55
89
  }
56
- exports.default = { findProjectRoot, getRelqDir };
90
+ function getProjectRoot(startDir = process.cwd()) {
91
+ const projectRoot = findProjectRoot(startDir);
92
+ if (!projectRoot) {
93
+ const colors = {
94
+ red: (s) => `\x1b[31m${s}\x1b[0m`,
95
+ yellow: (s) => `\x1b[33m${s}\x1b[0m`,
96
+ cyan: (s) => `\x1b[36m${s}\x1b[0m`,
97
+ };
98
+ console.error('');
99
+ console.error(colors.red('fatal:') + ' not a relq project (or any of the parent directories)');
100
+ console.error('');
101
+ console.error(colors.yellow('hint:') + ` Run ${colors.cyan('relq init')} in your project directory to initialize relq.`);
102
+ console.error('');
103
+ process.exit(128);
104
+ }
105
+ return projectRoot;
106
+ }
107
+ exports.default = { findProjectRoot, getRelqDir, getProjectRoot };
@@ -64,6 +64,7 @@ const REQUIRES_PARENT = [
64
64
  ];
65
65
  const DEFAULT_PATTERNS = [
66
66
  'TABLE:_relq_*',
67
+ 'TABLE:_kuery_*',
67
68
  'TABLE:pg_*',
68
69
  'TABLE:_temp_*',
69
70
  'TABLE:tmp_*',
@@ -52,10 +52,15 @@ exports.clearStaged = clearStaged;
52
52
  exports.hasStaged = hasStaged;
53
53
  exports.loadSnapshot = loadSnapshot;
54
54
  exports.saveSnapshot = saveSnapshot;
55
+ exports.hashFileContent = hashFileContent;
56
+ exports.getSavedFileHash = getSavedFileHash;
57
+ exports.saveFileHash = saveFileHash;
58
+ exports.detectFileChanges = detectFileChanges;
55
59
  exports.loadWorkingState = loadWorkingState;
56
60
  exports.saveWorkingState = saveWorkingState;
57
61
  exports.getOrCreateWorkingState = getOrCreateWorkingState;
58
62
  exports.addUnstagedChanges = addUnstagedChanges;
63
+ exports.clearUnstagedChanges = clearUnstagedChanges;
59
64
  exports.stageChanges = stageChanges;
60
65
  exports.unstageChanges = unstageChanges;
61
66
  exports.clearWorkingState = clearWorkingState;
@@ -83,6 +88,7 @@ const STAGED_FILE = 'staged.json';
83
88
  const WORKING_FILE = 'working.json';
84
89
  const SNAPSHOT_FILE = 'snapshot.json';
85
90
  const COMMITS_DIR = 'commits';
91
+ const FILE_HASH_FILE = 'file_hash';
86
92
  function isInitialized(projectRoot = process.cwd()) {
87
93
  const relqPath = path.join(projectRoot, RELQ_DIR);
88
94
  const headPath = path.join(relqPath, HEAD_FILE);
@@ -247,6 +253,41 @@ function saveSnapshot(schema, projectRoot = process.cwd()) {
247
253
  const snapshotPath = path.join(projectRoot, RELQ_DIR, SNAPSHOT_FILE);
248
254
  fs.writeFileSync(snapshotPath, JSON.stringify(schema, null, 2), 'utf-8');
249
255
  }
256
+ function hashFileContent(content) {
257
+ return crypto.createHash('sha1').update(content, 'utf8').digest('hex');
258
+ }
259
+ function getSavedFileHash(projectRoot = process.cwd()) {
260
+ const hashPath = path.join(projectRoot, RELQ_DIR, FILE_HASH_FILE);
261
+ if (!fs.existsSync(hashPath)) {
262
+ return null;
263
+ }
264
+ return fs.readFileSync(hashPath, 'utf-8').trim() || null;
265
+ }
266
+ function saveFileHash(hash, projectRoot = process.cwd()) {
267
+ const hashPath = path.join(projectRoot, RELQ_DIR, FILE_HASH_FILE);
268
+ fs.writeFileSync(hashPath, hash, 'utf-8');
269
+ }
270
+ function detectFileChanges(schemaPath, projectRoot = process.cwd()) {
271
+ if (!fs.existsSync(schemaPath)) {
272
+ return null;
273
+ }
274
+ const currentContent = fs.readFileSync(schemaPath, 'utf-8');
275
+ const currentHash = hashFileContent(currentContent);
276
+ const savedHash = getSavedFileHash(projectRoot);
277
+ if (!savedHash || currentHash === savedHash) {
278
+ return null;
279
+ }
280
+ return {
281
+ id: `file_${currentHash.substring(0, 8)}`,
282
+ type: 'ALTER',
283
+ objectType: 'SCHEMA_FILE',
284
+ objectName: path.basename(schemaPath),
285
+ before: { hash: savedHash },
286
+ after: { hash: currentHash },
287
+ sql: '-- Schema file modified (comments, formatting, or manual edits)',
288
+ detectedAt: new Date().toISOString(),
289
+ };
290
+ }
250
291
  function loadWorkingState(projectRoot = process.cwd()) {
251
292
  const workingPath = path.join(projectRoot, RELQ_DIR, WORKING_FILE);
252
293
  if (!fs.existsSync(workingPath)) {
@@ -281,6 +322,12 @@ function addUnstagedChanges(changes, projectRoot = process.cwd()) {
281
322
  state.timestamp = new Date().toISOString();
282
323
  saveWorkingState(state, projectRoot);
283
324
  }
325
+ function clearUnstagedChanges(projectRoot = process.cwd()) {
326
+ const state = getOrCreateWorkingState(projectRoot);
327
+ state.unstaged = [];
328
+ state.timestamp = new Date().toISOString();
329
+ saveWorkingState(state, projectRoot);
330
+ }
284
331
  function stageChanges(patterns, projectRoot = process.cwd()) {
285
332
  const state = getOrCreateWorkingState(projectRoot);
286
333
  const staged = [];