relq 1.0.1 → 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 (194) hide show
  1. package/dist/cjs/addon/buffer/index.cjs +1881 -0
  2. package/dist/cjs/addon/pg/index.cjs +4812 -0
  3. package/dist/cjs/addon/pg-cursor/index.cjs +1451 -0
  4. package/dist/cjs/addon/pg-format/index.cjs +2270 -0
  5. package/dist/cjs/cli/commands/add.cjs +430 -25
  6. package/dist/cjs/cli/commands/branch.cjs +131 -0
  7. package/dist/cjs/cli/commands/checkout.cjs +121 -0
  8. package/dist/cjs/cli/commands/cherry-pick.cjs +282 -0
  9. package/dist/cjs/cli/commands/commit.cjs +21 -29
  10. package/dist/cjs/cli/commands/diff.cjs +144 -69
  11. package/dist/cjs/cli/commands/export.cjs +70 -11
  12. package/dist/cjs/cli/commands/fetch.cjs +42 -18
  13. package/dist/cjs/cli/commands/generate.cjs +28 -54
  14. package/dist/cjs/cli/commands/history.cjs +19 -40
  15. package/dist/cjs/cli/commands/import.cjs +305 -41
  16. package/dist/cjs/cli/commands/init.cjs +69 -59
  17. package/dist/cjs/cli/commands/introspect.cjs +4 -8
  18. package/dist/cjs/cli/commands/log.cjs +84 -15
  19. package/dist/cjs/cli/commands/merge.cjs +207 -0
  20. package/dist/cjs/cli/commands/migrate.cjs +13 -26
  21. package/dist/cjs/cli/commands/pull.cjs +321 -95
  22. package/dist/cjs/cli/commands/push.cjs +228 -52
  23. package/dist/cjs/cli/commands/remote.cjs +17 -0
  24. package/dist/cjs/cli/commands/reset.cjs +148 -0
  25. package/dist/cjs/cli/commands/resolve.cjs +191 -0
  26. package/dist/cjs/cli/commands/rollback.cjs +17 -39
  27. package/dist/cjs/cli/commands/stash.cjs +152 -0
  28. package/dist/cjs/cli/commands/status.cjs +52 -9
  29. package/dist/cjs/cli/commands/sync.cjs +30 -50
  30. package/dist/cjs/cli/commands/tag.cjs +146 -0
  31. package/dist/cjs/cli/index.cjs +117 -10
  32. package/dist/cjs/cli/utils/change-tracker.cjs +107 -3
  33. package/dist/cjs/cli/utils/cli-utils.cjs +217 -0
  34. package/dist/cjs/cli/utils/commit-manager.cjs +3 -3
  35. package/dist/cjs/cli/utils/config-loader.cjs +34 -8
  36. package/dist/cjs/cli/utils/env-loader.cjs +3 -2
  37. package/dist/cjs/cli/utils/fast-introspect.cjs +110 -4
  38. package/dist/cjs/cli/utils/git-utils.cjs +42 -161
  39. package/dist/cjs/cli/utils/pool-manager.cjs +156 -0
  40. package/dist/cjs/cli/utils/project-root.cjs +107 -0
  41. package/dist/cjs/cli/utils/relqignore.cjs +297 -38
  42. package/dist/cjs/cli/utils/repo-manager.cjs +92 -3
  43. package/dist/cjs/cli/utils/schema-comparator.cjs +301 -11
  44. package/dist/cjs/cli/utils/schema-diff.cjs +202 -1
  45. package/dist/cjs/cli/utils/schema-hash.cjs +2 -1
  46. package/dist/cjs/cli/utils/schema-introspect.cjs +9 -5
  47. package/dist/cjs/cli/utils/snapshot-manager.cjs +1 -0
  48. package/dist/cjs/cli/utils/spinner.cjs +14 -106
  49. package/dist/cjs/cli/utils/sql-generator.cjs +2 -2
  50. package/dist/cjs/cli/utils/sql-parser.cjs +94 -7
  51. package/dist/cjs/cli/utils/type-generator.cjs +28 -16
  52. package/dist/cjs/condition/array-condition-builder.cjs +1 -1
  53. package/dist/cjs/condition/condition-collector.cjs +1 -1
  54. package/dist/cjs/condition/fulltext-condition-builder.cjs +1 -1
  55. package/dist/cjs/condition/geometric-condition-builder.cjs +1 -1
  56. package/dist/cjs/condition/jsonb-condition-builder.cjs +1 -1
  57. package/dist/cjs/condition/network-condition-builder.cjs +1 -1
  58. package/dist/cjs/condition/range-condition-builder.cjs +1 -1
  59. package/dist/cjs/copy/copy-builder.cjs +1 -1
  60. package/dist/cjs/core/query-builder.cjs +1 -1
  61. package/dist/cjs/core/relq-client.cjs +2 -2
  62. package/dist/cjs/count/count-builder.cjs +1 -1
  63. package/dist/cjs/cte/cte-builder.cjs +1 -1
  64. package/dist/cjs/delete/delete-builder.cjs +1 -1
  65. package/dist/cjs/function/create-function-builder.cjs +1 -1
  66. package/dist/cjs/functions/advanced-functions.cjs +1 -1
  67. package/dist/cjs/functions/case-builder.cjs +1 -1
  68. package/dist/cjs/functions/geometric-functions.cjs +1 -1
  69. package/dist/cjs/functions/network-functions.cjs +1 -1
  70. package/dist/cjs/functions/sql-functions.cjs +1 -1
  71. package/dist/cjs/indexing/create-index-builder.cjs +1 -1
  72. package/dist/cjs/indexing/drop-index-builder.cjs +1 -1
  73. package/dist/cjs/insert/conflict-builder.cjs +1 -1
  74. package/dist/cjs/insert/insert-builder.cjs +1 -1
  75. package/dist/cjs/maintenance/vacuum-builder.cjs +1 -1
  76. package/dist/cjs/pubsub/listen-notify-builder.cjs +1 -1
  77. package/dist/cjs/pubsub/listener-connection.cjs +2 -2
  78. package/dist/cjs/raw/raw-query-builder.cjs +1 -1
  79. package/dist/cjs/schema/schema-builder.cjs +1 -1
  80. package/dist/cjs/schema-definition/table-definition.cjs +1 -1
  81. package/dist/cjs/select/aggregate-builder.cjs +1 -1
  82. package/dist/cjs/select/select-builder.cjs +1 -1
  83. package/dist/cjs/sequence/sequence-builder.cjs +1 -1
  84. package/dist/cjs/table/alter-table-builder.cjs +1 -1
  85. package/dist/cjs/table/constraint-builder.cjs +1 -1
  86. package/dist/cjs/table/create-table-builder.cjs +1 -1
  87. package/dist/cjs/table/partition-builder.cjs +1 -1
  88. package/dist/cjs/table/truncate-builder.cjs +1 -1
  89. package/dist/cjs/transaction/transaction-builder.cjs +1 -1
  90. package/dist/cjs/trigger/create-trigger-builder.cjs +1 -1
  91. package/dist/cjs/update/array-update-builder.cjs +1 -1
  92. package/dist/cjs/update/update-builder.cjs +1 -1
  93. package/dist/cjs/utils/index.cjs +1 -1
  94. package/dist/cjs/view/create-view-builder.cjs +1 -1
  95. package/dist/cjs/window/window-builder.cjs +1 -1
  96. package/dist/config.d.ts +16 -25
  97. package/dist/esm/cli/commands/add.js +399 -27
  98. package/dist/esm/cli/commands/branch.js +95 -0
  99. package/dist/esm/cli/commands/checkout.js +85 -0
  100. package/dist/esm/cli/commands/cherry-pick.js +246 -0
  101. package/dist/esm/cli/commands/commit.js +22 -30
  102. package/dist/esm/cli/commands/diff.js +144 -69
  103. package/dist/esm/cli/commands/export.js +71 -12
  104. package/dist/esm/cli/commands/fetch.js +42 -18
  105. package/dist/esm/cli/commands/generate.js +28 -54
  106. package/dist/esm/cli/commands/history.js +11 -32
  107. package/dist/esm/cli/commands/import.js +306 -42
  108. package/dist/esm/cli/commands/init.js +65 -55
  109. package/dist/esm/cli/commands/introspect.js +4 -8
  110. package/dist/esm/cli/commands/log.js +78 -10
  111. package/dist/esm/cli/commands/merge.js +171 -0
  112. package/dist/esm/cli/commands/migrate.js +13 -26
  113. package/dist/esm/cli/commands/pull.js +313 -87
  114. package/dist/esm/cli/commands/push.js +223 -47
  115. package/dist/esm/cli/commands/remote.js +14 -0
  116. package/dist/esm/cli/commands/reset.js +112 -0
  117. package/dist/esm/cli/commands/resolve.js +155 -0
  118. package/dist/esm/cli/commands/rollback.js +17 -39
  119. package/dist/esm/cli/commands/stash.js +116 -0
  120. package/dist/esm/cli/commands/status.js +20 -10
  121. package/dist/esm/cli/commands/sync.js +30 -50
  122. package/dist/esm/cli/commands/tag.js +110 -0
  123. package/dist/esm/cli/index.js +118 -11
  124. package/dist/esm/cli/utils/change-tracker.js +107 -3
  125. package/dist/esm/cli/utils/cli-utils.js +169 -0
  126. package/dist/esm/cli/utils/commit-manager.js +3 -3
  127. package/dist/esm/cli/utils/config-loader.js +34 -8
  128. package/dist/esm/cli/utils/env-loader.js +3 -2
  129. package/dist/esm/cli/utils/fast-introspect.js +110 -4
  130. package/dist/esm/cli/utils/git-utils.js +2 -124
  131. package/dist/esm/cli/utils/pool-manager.js +114 -0
  132. package/dist/esm/cli/utils/project-root.js +69 -0
  133. package/dist/esm/cli/utils/relqignore.js +278 -37
  134. package/dist/esm/cli/utils/repo-manager.js +83 -3
  135. package/dist/esm/cli/utils/schema-comparator.js +301 -11
  136. package/dist/esm/cli/utils/schema-diff.js +202 -1
  137. package/dist/esm/cli/utils/schema-hash.js +2 -1
  138. package/dist/esm/cli/utils/schema-introspect.js +9 -5
  139. package/dist/esm/cli/utils/snapshot-manager.js +1 -0
  140. package/dist/esm/cli/utils/spinner.js +1 -101
  141. package/dist/esm/cli/utils/sql-generator.js +2 -2
  142. package/dist/esm/cli/utils/sql-parser.js +94 -7
  143. package/dist/esm/cli/utils/type-generator.js +28 -16
  144. package/dist/esm/condition/array-condition-builder.js +1 -1
  145. package/dist/esm/condition/condition-collector.js +1 -1
  146. package/dist/esm/condition/fulltext-condition-builder.js +1 -1
  147. package/dist/esm/condition/geometric-condition-builder.js +1 -1
  148. package/dist/esm/condition/jsonb-condition-builder.js +1 -1
  149. package/dist/esm/condition/network-condition-builder.js +1 -1
  150. package/dist/esm/condition/range-condition-builder.js +1 -1
  151. package/dist/esm/copy/copy-builder.js +1 -1
  152. package/dist/esm/core/query-builder.js +1 -1
  153. package/dist/esm/core/relq-client.js +2 -2
  154. package/dist/esm/count/count-builder.js +1 -1
  155. package/dist/esm/cte/cte-builder.js +1 -1
  156. package/dist/esm/delete/delete-builder.js +1 -1
  157. package/dist/esm/function/create-function-builder.js +1 -1
  158. package/dist/esm/functions/advanced-functions.js +1 -1
  159. package/dist/esm/functions/case-builder.js +1 -1
  160. package/dist/esm/functions/geometric-functions.js +1 -1
  161. package/dist/esm/functions/network-functions.js +1 -1
  162. package/dist/esm/functions/sql-functions.js +1 -1
  163. package/dist/esm/indexing/create-index-builder.js +1 -1
  164. package/dist/esm/indexing/drop-index-builder.js +1 -1
  165. package/dist/esm/insert/conflict-builder.js +1 -1
  166. package/dist/esm/insert/insert-builder.js +1 -1
  167. package/dist/esm/maintenance/vacuum-builder.js +1 -1
  168. package/dist/esm/pubsub/listen-notify-builder.js +1 -1
  169. package/dist/esm/pubsub/listener-connection.js +2 -2
  170. package/dist/esm/raw/raw-query-builder.js +1 -1
  171. package/dist/esm/schema/schema-builder.js +1 -1
  172. package/dist/esm/schema-definition/table-definition.js +1 -1
  173. package/dist/esm/select/aggregate-builder.js +1 -1
  174. package/dist/esm/select/select-builder.js +1 -1
  175. package/dist/esm/sequence/sequence-builder.js +1 -1
  176. package/dist/esm/table/alter-table-builder.js +1 -1
  177. package/dist/esm/table/constraint-builder.js +1 -1
  178. package/dist/esm/table/create-table-builder.js +1 -1
  179. package/dist/esm/table/partition-builder.js +1 -1
  180. package/dist/esm/table/truncate-builder.js +1 -1
  181. package/dist/esm/transaction/transaction-builder.js +1 -1
  182. package/dist/esm/trigger/create-trigger-builder.js +1 -1
  183. package/dist/esm/update/array-update-builder.js +1 -1
  184. package/dist/esm/update/update-builder.js +1 -1
  185. package/dist/esm/utils/index.js +1 -1
  186. package/dist/esm/view/create-view-builder.js +1 -1
  187. package/dist/esm/window/window-builder.js +1 -1
  188. package/dist/index.d.ts +25 -8
  189. package/dist/schema-builder.d.ts +16 -6
  190. package/package.json +1 -1
  191. /package/dist/{addons/buffer.js → esm/addon/buffer/index.js} +0 -0
  192. /package/dist/{addons/pg.js → esm/addon/pg/index.js} +0 -0
  193. /package/dist/{addons/pg-cursor.js → esm/addon/pg-cursor/index.js} +0 -0
  194. /package/dist/{addons/pg-format.js → esm/addon/pg-format/index.js} +0 -0
@@ -1,55 +1,460 @@
1
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
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.addCommand = addCommand;
4
37
  exports.getRelatedChanges = getRelatedChanges;
38
+ const fs = __importStar(require("fs"));
5
39
  const spinner_1 = require("../utils/spinner.cjs");
40
+ const relqignore_1 = require("../utils/relqignore.cjs");
41
+ const config_1 = require("../../config/config.cjs");
42
+ const path = __importStar(require("path"));
6
43
  const repo_manager_1 = require("../utils/repo-manager.cjs");
7
44
  const change_tracker_1 = require("../utils/change-tracker.cjs");
45
+ const schema_comparator_1 = require("../utils/schema-comparator.cjs");
46
+ function parseSchemaFileForComparison(schemaPath) {
47
+ if (!fs.existsSync(schemaPath)) {
48
+ return null;
49
+ }
50
+ const content = fs.readFileSync(schemaPath, 'utf-8');
51
+ const tables = [];
52
+ const tableStartRegex = /defineTable\s*\(\s*['"]([^'"]+)['"],\s*\{/g;
53
+ let tableStartMatch;
54
+ while ((tableStartMatch = tableStartRegex.exec(content)) !== null) {
55
+ const tableName = tableStartMatch[1];
56
+ const startIdx = tableStartMatch.index + tableStartMatch[0].length;
57
+ let braceCount = 1;
58
+ let endIdx = startIdx;
59
+ while (braceCount > 0 && endIdx < content.length) {
60
+ const char = content[endIdx];
61
+ if (char === '{')
62
+ braceCount++;
63
+ else if (char === '}')
64
+ braceCount--;
65
+ endIdx++;
66
+ }
67
+ const columnsBlock = content.substring(startIdx, endIdx - 1);
68
+ let optionsBlock = '';
69
+ const afterColumns = content.substring(endIdx);
70
+ const optionsMatch = afterColumns.match(/^\s*,\s*\{/);
71
+ if (optionsMatch) {
72
+ const optStart = endIdx + optionsMatch[0].length;
73
+ braceCount = 1;
74
+ let optEnd = optStart;
75
+ while (braceCount > 0 && optEnd < content.length) {
76
+ const char = content[optEnd];
77
+ if (char === '{')
78
+ braceCount++;
79
+ else if (char === '}')
80
+ braceCount--;
81
+ optEnd++;
82
+ }
83
+ optionsBlock = content.substring(optStart, optEnd - 1);
84
+ }
85
+ const columns = [];
86
+ const constraints = [];
87
+ const tsToDbNameMap = new Map();
88
+ const lines = columnsBlock.split('\n');
89
+ let currentColDef = '';
90
+ for (const line of lines) {
91
+ const trimmed = line.trim();
92
+ if (trimmed.startsWith('//') || trimmed.startsWith('/*') || trimmed.startsWith('*'))
93
+ continue;
94
+ currentColDef += ' ' + trimmed;
95
+ if (trimmed.endsWith(',') || trimmed.endsWith(')')) {
96
+ const colDef = currentColDef.trim();
97
+ currentColDef = '';
98
+ const typePattern = 'varchar|text|uuid|integer|bigint|boolean|timestamp|date|jsonb|json|numeric|serial|bigserial|smallserial|tsvector|smallint|real|doublePrecision|char|inet|cidr|macaddr|macaddr8|interval|time|point|line|lseg|box|path|polygon|circle|bytea|bit|varbit|money|xml|oid';
99
+ const colMatch = colDef.match(new RegExp(`^(\\w+):\\s*(${typePattern})`));
100
+ if (!colMatch)
101
+ continue;
102
+ const tsName = colMatch[1];
103
+ const type = colMatch[2];
104
+ const explicitNameMatch = colDef.match(new RegExp(`${type}\\s*\\(['\"]([^'"]+)['\"]`));
105
+ const dbColName = explicitNameMatch ? explicitNameMatch[1] : tsName;
106
+ tsToDbNameMap.set(tsName, dbColName);
107
+ let defaultValue = null;
108
+ const isJsonbColumn = type === 'jsonb' || type === 'json';
109
+ const isArrayColumn = colDef.includes('.array()');
110
+ const bigintMatch = colDef.match(/\.default\(\s*BigInt\(\s*(-?\d+)\s*\)\s*\)/);
111
+ if (bigintMatch) {
112
+ defaultValue = bigintMatch[1];
113
+ }
114
+ const funcDefaultMatch = !defaultValue && colDef.match(/\.default\(\s*(genRandomUuid|now|currentDate|currentTimestamp|emptyArray|emptyObject)\s*\(\s*\)\s*\)/);
115
+ if (funcDefaultMatch) {
116
+ const funcName = funcDefaultMatch[1];
117
+ if (funcName === 'emptyArray') {
118
+ defaultValue = isJsonbColumn ? "'[]'::jsonb" : "'{}'::text[]";
119
+ }
120
+ else if (funcName === 'emptyObject') {
121
+ defaultValue = "'{}'::jsonb";
122
+ }
123
+ else {
124
+ const funcToSql = {
125
+ 'genRandomUuid': 'gen_random_uuid()',
126
+ 'now': 'now()',
127
+ 'currentDate': 'CURRENT_DATE',
128
+ 'currentTimestamp': 'CURRENT_TIMESTAMP',
129
+ };
130
+ defaultValue = funcToSql[funcName] || `${funcName}()`;
131
+ }
132
+ }
133
+ else {
134
+ const strDefaultMatch = colDef.match(/\.default\(\s*(['"])([^'"]*)\1\s*\)/);
135
+ if (strDefaultMatch) {
136
+ defaultValue = strDefaultMatch[2];
137
+ }
138
+ else {
139
+ const boolDefaultMatch = colDef.match(/\.default\(\s*(true|false)\s*\)/);
140
+ if (boolDefaultMatch) {
141
+ defaultValue = boolDefaultMatch[1];
142
+ }
143
+ else {
144
+ const numDefaultMatch = colDef.match(/\.default\(\s*(-?\d+(?:\.\d+)?)\s*\)/);
145
+ if (numDefaultMatch) {
146
+ defaultValue = numDefaultMatch[1];
147
+ }
148
+ else {
149
+ const jsonObjMatch = colDef.match(/\.default\(\s*(\{[^}]+\})\s*\)/);
150
+ if (jsonObjMatch) {
151
+ defaultValue = `'${jsonObjMatch[1]}'::jsonb`;
152
+ }
153
+ else {
154
+ const arrayLiteralMatch = colDef.match(/\.default\(\s*(\[[^\]]+\])\s*\)/);
155
+ if (arrayLiteralMatch) {
156
+ const arrayStr = arrayLiteralMatch[1];
157
+ defaultValue = `'${arrayStr}'::jsonb`;
158
+ }
159
+ }
160
+ }
161
+ }
162
+ }
163
+ }
164
+ if (colDef.includes('.check(')) {
165
+ const checkValuesMatch = colDef.match(/\.check\(([^)]+)\)/);
166
+ if (checkValuesMatch) {
167
+ const valuesStr = checkValuesMatch[1];
168
+ const values = valuesStr.match(/['"]([^'"]+)['"]/g)?.map(v => v.replace(/['"]/g, '')) || [];
169
+ if (values.length > 0) {
170
+ const constraintName = `${tableName}_${dbColName}_check`;
171
+ constraints.push({
172
+ name: constraintName,
173
+ type: 'CHECK',
174
+ columns: [dbColName],
175
+ definition: '',
176
+ });
177
+ }
178
+ }
179
+ }
180
+ let comment = null;
181
+ const commentMatch = colDef.match(/\.comment\(\s*(['"])([^'"]*)\1\s*\)/);
182
+ if (commentMatch) {
183
+ comment = commentMatch[2];
184
+ }
185
+ if (colDef.includes('.identity()')) {
186
+ defaultValue = defaultValue || 'GENERATED BY DEFAULT AS IDENTITY';
187
+ }
188
+ const isArray = colDef.includes('.array()');
189
+ columns.push({
190
+ name: dbColName,
191
+ dataType: isArray ? `${type}[]` : type,
192
+ isNullable: !colDef.includes('.notNull()') && !colDef.includes('.primaryKey()'),
193
+ defaultValue,
194
+ isPrimaryKey: colDef.includes('.primaryKey()'),
195
+ isUnique: colDef.includes('.unique()'),
196
+ maxLength: null,
197
+ precision: null,
198
+ scale: null,
199
+ references: null,
200
+ comment,
201
+ });
202
+ }
203
+ }
204
+ const indexes = [];
205
+ const indexRegex = /index\s*\(\s*['"]([^'"]+)['"]\s*\)\.on\(([^)]+)\)/g;
206
+ let idxMatch;
207
+ while ((idxMatch = indexRegex.exec(optionsBlock)) !== null) {
208
+ const indexName = idxMatch[1];
209
+ const indexCols = idxMatch[2].split(',').map(c => {
210
+ const tsColName = c.trim().replace(/table\.\s*/, '');
211
+ return tsToDbNameMap.get(tsColName) || tsColName;
212
+ });
213
+ const isUnique = optionsBlock.includes(`index('${indexName}')`) &&
214
+ optionsBlock.substring(optionsBlock.indexOf(`index('${indexName}')`)).split('\n')[0].includes('.unique()');
215
+ indexes.push({
216
+ name: indexName,
217
+ columns: indexCols,
218
+ isUnique: isUnique,
219
+ isPrimary: false,
220
+ type: 'btree',
221
+ definition: '',
222
+ whereClause: null,
223
+ expression: null,
224
+ });
225
+ }
226
+ const checkRegexLegacy = /check\s*\(\s*['"]([^'"]+)['"]\s*,\s*sql`([^`]+)`\s*\)/g;
227
+ let tableCheckMatch;
228
+ while ((tableCheckMatch = checkRegexLegacy.exec(optionsBlock)) !== null) {
229
+ constraints.push({
230
+ name: tableCheckMatch[1],
231
+ type: 'CHECK',
232
+ columns: [],
233
+ definition: tableCheckMatch[2].trim(),
234
+ });
235
+ }
236
+ const checkRegexNew = /check\.constraint\s*\(\s*['"]([^'"]+)['"]/g;
237
+ let newCheckMatch;
238
+ while ((newCheckMatch = checkRegexNew.exec(optionsBlock)) !== null) {
239
+ const constraintName = newCheckMatch[1];
240
+ if (!constraints.some(c => c.name === constraintName)) {
241
+ constraints.push({
242
+ name: constraintName,
243
+ type: 'CHECK',
244
+ columns: [],
245
+ definition: '',
246
+ });
247
+ }
248
+ }
249
+ const checkConstraintsBlockMatch = optionsBlock.match(/checkConstraints:\s*\([^)]+\)\s*=>\s*\[([^\]]+)\]/s);
250
+ if (checkConstraintsBlockMatch) {
251
+ const checkBlock = checkConstraintsBlockMatch[1];
252
+ const constraintNameMatches = checkBlock.matchAll(/check\.constraint\s*\(\s*['"]([^'"]+)['"]/g);
253
+ for (const match of constraintNameMatches) {
254
+ const constraintName = match[1];
255
+ if (!constraints.some(c => c.name === constraintName)) {
256
+ constraints.push({
257
+ name: constraintName,
258
+ type: 'CHECK',
259
+ columns: [],
260
+ definition: '',
261
+ });
262
+ }
263
+ }
264
+ }
265
+ let partitionType;
266
+ let partitionKey;
267
+ const partitionByMatch = optionsBlock.match(/partitionBy:\s*\([^)]+\)\s*=>\s*\w+\.(list|range|hash)\(([^)]+)\)/i);
268
+ if (partitionByMatch) {
269
+ partitionType = partitionByMatch[1].toUpperCase();
270
+ const tsPartitionKey = partitionByMatch[2].replace(/table\./, '').trim();
271
+ const dbPartitionKey = tsToDbNameMap.get(tsPartitionKey) || tsPartitionKey;
272
+ partitionKey = [dbPartitionKey];
273
+ }
274
+ tables.push({
275
+ name: tableName,
276
+ schema: 'public',
277
+ columns,
278
+ indexes,
279
+ constraints,
280
+ rowCount: 0,
281
+ isPartitioned: !!partitionType,
282
+ partitionType,
283
+ partitionKey,
284
+ });
285
+ }
286
+ const enums = [];
287
+ const enumRegex = /defineEnum\s*\(\s*['"]([^'"]+)['"]\s*,\s*\[([^\]]+)\]/g;
288
+ let enumMatch;
289
+ while ((enumMatch = enumRegex.exec(content)) !== null) {
290
+ const enumName = enumMatch[1];
291
+ const valuesStr = enumMatch[2];
292
+ const values = valuesStr.match(/['"]([^'"]+)['"]/g)?.map(v => v.replace(/['"]/g, '')) || [];
293
+ enums.push({ name: enumName, values });
294
+ }
295
+ const extensions = [];
296
+ const singleExtMatch = content.match(/pgExtensions\s*\(\s*['"]([^'"]+)['"]\s*\)/);
297
+ if (singleExtMatch) {
298
+ extensions.push(singleExtMatch[1]);
299
+ }
300
+ else {
301
+ const arrayExtMatch = content.match(/pgExtensions\s*\(\s*\[([^\]]+)\]/);
302
+ if (arrayExtMatch) {
303
+ const extList = arrayExtMatch[1].match(/['"]([^'"]+)['"]/g);
304
+ if (extList) {
305
+ extList.forEach(e => extensions.push(e.replace(/['"]/g, '')));
306
+ }
307
+ }
308
+ }
309
+ return {
310
+ tables,
311
+ enums,
312
+ domains: [],
313
+ compositeTypes: [],
314
+ sequences: [],
315
+ collations: [],
316
+ functions: [],
317
+ triggers: [],
318
+ policies: [],
319
+ partitions: [],
320
+ foreignServers: [],
321
+ foreignTables: [],
322
+ extensions,
323
+ };
324
+ }
325
+ function snapshotToDatabaseSchema(snapshot) {
326
+ const tables = (snapshot.tables || []).map(t => ({
327
+ name: t.name,
328
+ schema: t.schema || 'public',
329
+ columns: (t.columns || []).map(c => ({
330
+ name: c.name,
331
+ dataType: c.type || 'text',
332
+ isNullable: c.nullable !== false,
333
+ defaultValue: c.default || null,
334
+ isPrimaryKey: c.primaryKey || false,
335
+ isUnique: c.unique || false,
336
+ maxLength: null,
337
+ precision: null,
338
+ scale: null,
339
+ references: null,
340
+ comment: c.comment || null,
341
+ })),
342
+ indexes: (t.indexes || []).map(i => ({
343
+ name: i.name,
344
+ columns: Array.isArray(i.columns) ? i.columns : [i.columns],
345
+ isUnique: i.unique || false,
346
+ isPrimary: false,
347
+ type: i.type || 'btree',
348
+ definition: i.definition || '',
349
+ whereClause: i.whereClause || null,
350
+ expression: null,
351
+ })),
352
+ constraints: (t.constraints || []).map(c => ({
353
+ name: c.name,
354
+ type: c.type,
355
+ columns: c.columns || [],
356
+ definition: c.definition || '',
357
+ })),
358
+ rowCount: 0,
359
+ isPartitioned: t.isPartitioned || false,
360
+ partitionType: t.partitionType,
361
+ partitionKey: t.partitionKey ? (Array.isArray(t.partitionKey) ? t.partitionKey : [t.partitionKey]) : undefined,
362
+ }));
363
+ return {
364
+ tables,
365
+ enums: (snapshot.enums || []).map(e => ({ name: e.name, values: e.values })),
366
+ domains: [],
367
+ compositeTypes: [],
368
+ sequences: [],
369
+ collations: [],
370
+ functions: [],
371
+ triggers: [],
372
+ policies: [],
373
+ partitions: [],
374
+ foreignServers: [],
375
+ foreignTables: [],
376
+ extensions: (snapshot.extensions || []).map(e => typeof e === 'string' ? e : e.name),
377
+ };
378
+ }
8
379
  async function addCommand(context) {
9
- const { args } = context;
10
- const projectRoot = process.cwd();
380
+ const { args, projectRoot } = context;
11
381
  console.log('');
12
382
  if (!(0, repo_manager_1.isInitialized)(projectRoot)) {
13
- console.log(`${spinner_1.colors.red('error:')} relq not initialized`);
14
- console.log('');
15
- console.log(`${spinner_1.colors.muted('Run')} ${spinner_1.colors.cyan('relq init')} ${spinner_1.colors.muted('first.')}`);
16
- return;
383
+ (0, spinner_1.fatal)('not a relq repository (or any parent directories): .relq', `Run ${spinner_1.colors.cyan('relq init')} to initialize.`);
384
+ }
385
+ const ignorePatterns = (0, relqignore_1.loadRelqignore)(projectRoot);
386
+ const config = await (0, config_1.loadConfig)();
387
+ const schemaPathRaw = typeof config.schema === 'string' ? config.schema : './db/schema.ts';
388
+ const schemaPath = path.resolve(projectRoot, schemaPathRaw);
389
+ const fileChange = (0, repo_manager_1.detectFileChanges)(schemaPath, projectRoot);
390
+ if (fileChange) {
391
+ const currentSchema = parseSchemaFileForComparison(schemaPath);
392
+ const snapshot = (0, repo_manager_1.loadSnapshot)(projectRoot);
393
+ if (currentSchema && snapshot) {
394
+ const snapshotAsDbSchema = snapshotToDatabaseSchema(snapshot);
395
+ const schemaChanges = (0, schema_comparator_1.compareSchemas)(snapshotAsDbSchema, currentSchema);
396
+ if (schemaChanges.length > 0) {
397
+ (0, repo_manager_1.clearUnstagedChanges)(projectRoot);
398
+ (0, repo_manager_1.addUnstagedChanges)(schemaChanges, projectRoot);
399
+ }
400
+ else {
401
+ const existingUnstaged = (0, repo_manager_1.getUnstagedChanges)(projectRoot);
402
+ const hasFileChange = existingUnstaged.some(c => c.objectType === 'SCHEMA_FILE');
403
+ if (!hasFileChange) {
404
+ (0, repo_manager_1.addUnstagedChanges)([fileChange], projectRoot);
405
+ }
406
+ }
407
+ }
17
408
  }
18
- const unstaged = (0, repo_manager_1.getUnstagedChanges)(projectRoot);
409
+ const allUnstaged = (0, repo_manager_1.getUnstagedChanges)(projectRoot);
19
410
  const staged = (0, repo_manager_1.getStagedChanges)(projectRoot);
411
+ const unstaged = allUnstaged.filter(change => {
412
+ const objectType = change.objectType;
413
+ const result = (0, relqignore_1.isIgnored)(objectType, change.objectName, change.parentName || null, ignorePatterns);
414
+ if (result.ignored) {
415
+ return false;
416
+ }
417
+ if (['FUNCTION', 'PROCEDURE'].includes(change.objectType) && !config.includeFunctions) {
418
+ return false;
419
+ }
420
+ if (change.objectType === 'TRIGGER' && !config.includeTriggers) {
421
+ return false;
422
+ }
423
+ if (['VIEW', 'MATERIALIZED_VIEW'].includes(change.objectType) && !config.includeViews) {
424
+ return false;
425
+ }
426
+ if (change.objectType === 'FOREIGN_TABLE' && !config.includeFDW) {
427
+ return false;
428
+ }
429
+ return true;
430
+ });
431
+ const filteredCount = allUnstaged.length - unstaged.length;
20
432
  if (unstaged.length === 0) {
21
433
  if (staged.length > 0) {
22
- console.log(`${spinner_1.colors.green('✓')} All changes are already staged`);
434
+ console.log('All changes are already staged');
23
435
  console.log(`${spinner_1.colors.muted(`${staged.length} change(s) ready to commit`)}`);
24
436
  console.log('');
25
- console.log(`${spinner_1.colors.muted('Run')} ${spinner_1.colors.cyan('relq commit -m "message"')} ${spinner_1.colors.muted('to commit.')}`);
437
+ console.log(`hint: run 'relq commit -m "message"' to commit`);
438
+ }
439
+ else if (filteredCount > 0) {
440
+ console.log('No stageable changes');
441
+ console.log(`${spinner_1.colors.muted(`${filteredCount} change(s) filtered by .relqignore or config`)}`);
26
442
  }
27
443
  else {
28
- console.log(`${spinner_1.colors.green('✓')} No changes to stage`);
29
- console.log(`${spinner_1.colors.muted('Run')} ${spinner_1.colors.cyan('relq pull')} ${spinner_1.colors.muted('or')} ${spinner_1.colors.cyan('relq import')} ${spinner_1.colors.muted('to detect changes.')}`);
444
+ console.log('No changes to stage');
445
+ console.log(`hint: run 'relq pull' or 'relq import' to detect changes`);
30
446
  }
31
447
  console.log('');
32
448
  return;
33
449
  }
34
450
  const patterns = args.length > 0 ? args : ['.'];
35
- const addAll = patterns.includes('.') || patterns.includes('*');
36
- console.log(`${spinner_1.colors.cyan('Unstaged changes:')} ${unstaged.length}`);
37
- console.log('');
38
- for (const change of unstaged) {
39
- const display = (0, change_tracker_1.getChangeDisplayName)(change);
40
- const color = change.type === 'CREATE' ? spinner_1.colors.green :
41
- change.type === 'DROP' ? spinner_1.colors.red :
42
- spinner_1.colors.yellow;
43
- console.log(` ${color(display)}`);
44
- }
45
- console.log('');
46
451
  const stagedNow = (0, repo_manager_1.stageChanges)(patterns, projectRoot);
47
452
  if (stagedNow.length === 0) {
48
- console.log(`${spinner_1.colors.yellow('⚠')} No changes matched the pattern(s): ${patterns.join(', ')}`);
453
+ (0, spinner_1.warning)(`No changes matched the pattern(s): ${patterns.join(', ')}`);
49
454
  console.log('');
50
455
  return;
51
456
  }
52
- console.log(`${spinner_1.colors.green('✓')} Staged ${stagedNow.length} change(s):`);
457
+ console.log(`Staged ${stagedNow.length} change(s):`);
53
458
  console.log('');
54
459
  for (const change of stagedNow) {
55
460
  const display = (0, change_tracker_1.getChangeDisplayName)(change);
@@ -64,7 +469,7 @@ async function addCommand(context) {
64
469
  console.log(`${spinner_1.colors.muted(`${remainingUnstaged.length} change(s) still unstaged`)}`);
65
470
  console.log('');
66
471
  }
67
- console.log(`${spinner_1.colors.muted('Run')} ${spinner_1.colors.cyan('relq commit -m "message"')} ${spinner_1.colors.muted('to commit.')}`);
472
+ console.log(`hint: run 'relq commit -m "message"' to commit`);
68
473
  console.log('');
69
474
  }
70
475
  function getRelatedChanges(tableName, changes) {
@@ -0,0 +1,131 @@
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.branchCommand = branchCommand;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const spinner_1 = require("../utils/spinner.cjs");
40
+ const repo_manager_1 = require("../utils/repo-manager.cjs");
41
+ function loadBranchState(projectRoot) {
42
+ const branchPath = path.join(projectRoot, '.relq', 'branches.json');
43
+ if (fs.existsSync(branchPath)) {
44
+ return JSON.parse(fs.readFileSync(branchPath, 'utf-8'));
45
+ }
46
+ const head = (0, repo_manager_1.getHead)(projectRoot);
47
+ return {
48
+ current: 'main',
49
+ branches: { main: head || '' }
50
+ };
51
+ }
52
+ function saveBranchState(state, projectRoot) {
53
+ const branchPath = path.join(projectRoot, '.relq', 'branches.json');
54
+ fs.writeFileSync(branchPath, JSON.stringify(state, null, 2));
55
+ }
56
+ async function branchCommand(context) {
57
+ const { args, flags, projectRoot } = context;
58
+ console.log('');
59
+ if (!(0, repo_manager_1.isInitialized)(projectRoot)) {
60
+ (0, spinner_1.fatal)('not a relq repository (or any parent directories): .relq', `Run ${spinner_1.colors.cyan('relq init')} to initialize.`);
61
+ }
62
+ const state = loadBranchState(projectRoot);
63
+ const deleteFlag = flags['d'] === true || flags['delete'] === true;
64
+ const renameFlag = flags['m'] === true || flags['move'] === true;
65
+ if (deleteFlag) {
66
+ const branchName = args[0];
67
+ if (!branchName) {
68
+ (0, spinner_1.fatal)('Please specify branch name', `Usage: ${spinner_1.colors.cyan('relq branch -d <name>')}`);
69
+ }
70
+ if (branchName === state.current) {
71
+ (0, spinner_1.fatal)(`Cannot delete the branch '${branchName}' which you are currently on`);
72
+ }
73
+ if (!state.branches[branchName]) {
74
+ (0, spinner_1.fatal)(`Branch '${branchName}' not found`, `Use ${spinner_1.colors.cyan('relq branch')} to list available branches.`);
75
+ }
76
+ delete state.branches[branchName];
77
+ saveBranchState(state, projectRoot);
78
+ console.log(`Deleted branch '${branchName}'`);
79
+ console.log('');
80
+ return;
81
+ }
82
+ if (renameFlag) {
83
+ const oldName = args[0];
84
+ const newName = args[1];
85
+ if (!oldName || !newName) {
86
+ (0, spinner_1.fatal)('Missing arguments', `Usage: ${spinner_1.colors.cyan('relq branch -m <old> <new>')}`);
87
+ }
88
+ if (!state.branches[oldName]) {
89
+ (0, spinner_1.fatal)(`Branch '${oldName}' not found`, `Use ${spinner_1.colors.cyan('relq branch')} to list available branches.`);
90
+ }
91
+ if (state.branches[newName]) {
92
+ (0, spinner_1.fatal)(`A branch named '${newName}' already exists`);
93
+ }
94
+ state.branches[newName] = state.branches[oldName];
95
+ delete state.branches[oldName];
96
+ if (state.current === oldName)
97
+ state.current = newName;
98
+ saveBranchState(state, projectRoot);
99
+ console.log(`Renamed '${oldName}' to '${newName}'`);
100
+ console.log('');
101
+ return;
102
+ }
103
+ if (args[0]) {
104
+ const branchName = args[0];
105
+ if (state.branches[branchName]) {
106
+ (0, spinner_1.fatal)(`A branch named '${branchName}' already exists`);
107
+ }
108
+ const head = (0, repo_manager_1.getHead)(projectRoot);
109
+ if (!head) {
110
+ (0, spinner_1.fatal)('No commits yet', `Run ${spinner_1.colors.cyan('relq pull')} or ${spinner_1.colors.cyan('relq import')} first.`);
111
+ }
112
+ state.branches[branchName] = head;
113
+ saveBranchState(state, projectRoot);
114
+ console.log(`Created branch '${branchName}'`);
115
+ console.log('');
116
+ return;
117
+ }
118
+ const branches = Object.keys(state.branches).sort();
119
+ if (branches.length === 0) {
120
+ console.log(`${spinner_1.colors.muted('No branches.')}`);
121
+ return;
122
+ }
123
+ for (const name of branches) {
124
+ const isCurrent = name === state.current;
125
+ const prefix = isCurrent ? spinner_1.colors.green('* ') : ' ';
126
+ const branchName = isCurrent ? spinner_1.colors.green(name) : name;
127
+ console.log(`${prefix}${branchName}`);
128
+ }
129
+ console.log('');
130
+ }
131
+ exports.default = branchCommand;