relq 1.0.0 → 1.0.2

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 (159) 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 +30 -1
  6. package/dist/cjs/cli/commands/branch.cjs +141 -0
  7. package/dist/cjs/cli/commands/checkout.cjs +134 -0
  8. package/dist/cjs/cli/commands/cherry-pick.cjs +283 -0
  9. package/dist/cjs/cli/commands/diff.cjs +148 -69
  10. package/dist/cjs/cli/commands/export.cjs +64 -5
  11. package/dist/cjs/cli/commands/fetch.cjs +34 -4
  12. package/dist/cjs/cli/commands/history.cjs +1 -1
  13. package/dist/cjs/cli/commands/import.cjs +283 -12
  14. package/dist/cjs/cli/commands/log.cjs +75 -0
  15. package/dist/cjs/cli/commands/merge.cjs +224 -0
  16. package/dist/cjs/cli/commands/migrate.cjs +1 -1
  17. package/dist/cjs/cli/commands/pull.cjs +123 -7
  18. package/dist/cjs/cli/commands/push.cjs +245 -29
  19. package/dist/cjs/cli/commands/remote.cjs +16 -0
  20. package/dist/cjs/cli/commands/reset.cjs +169 -0
  21. package/dist/cjs/cli/commands/resolve.cjs +193 -0
  22. package/dist/cjs/cli/commands/rollback.cjs +1 -1
  23. package/dist/cjs/cli/commands/stash.cjs +154 -0
  24. package/dist/cjs/cli/commands/status.cjs +48 -0
  25. package/dist/cjs/cli/commands/tag.cjs +147 -0
  26. package/dist/cjs/cli/index.cjs +46 -2
  27. package/dist/cjs/cli/utils/commit-manager.cjs +3 -3
  28. package/dist/cjs/cli/utils/env-loader.cjs +3 -2
  29. package/dist/cjs/cli/utils/fast-introspect.cjs +1 -1
  30. package/dist/cjs/cli/utils/project-root.cjs +56 -0
  31. package/dist/cjs/cli/utils/relqignore.cjs +296 -38
  32. package/dist/cjs/cli/utils/repo-manager.cjs +45 -3
  33. package/dist/cjs/cli/utils/schema-introspect.cjs +2 -2
  34. package/dist/cjs/cli/utils/sql-generator.cjs +1 -1
  35. package/dist/cjs/cli/utils/sql-parser.cjs +102 -13
  36. package/dist/cjs/condition/array-condition-builder.cjs +1 -1
  37. package/dist/cjs/condition/condition-collector.cjs +1 -1
  38. package/dist/cjs/condition/fulltext-condition-builder.cjs +1 -1
  39. package/dist/cjs/condition/geometric-condition-builder.cjs +1 -1
  40. package/dist/cjs/condition/jsonb-condition-builder.cjs +1 -1
  41. package/dist/cjs/condition/network-condition-builder.cjs +1 -1
  42. package/dist/cjs/condition/range-condition-builder.cjs +1 -1
  43. package/dist/cjs/copy/copy-builder.cjs +1 -1
  44. package/dist/cjs/core/query-builder.cjs +1 -1
  45. package/dist/cjs/core/relq-client.cjs +2 -2
  46. package/dist/cjs/count/count-builder.cjs +1 -1
  47. package/dist/cjs/cte/cte-builder.cjs +1 -1
  48. package/dist/cjs/delete/delete-builder.cjs +1 -1
  49. package/dist/cjs/function/create-function-builder.cjs +1 -1
  50. package/dist/cjs/functions/advanced-functions.cjs +1 -1
  51. package/dist/cjs/functions/case-builder.cjs +1 -1
  52. package/dist/cjs/functions/geometric-functions.cjs +1 -1
  53. package/dist/cjs/functions/network-functions.cjs +1 -1
  54. package/dist/cjs/functions/sql-functions.cjs +1 -1
  55. package/dist/cjs/indexing/create-index-builder.cjs +1 -1
  56. package/dist/cjs/indexing/drop-index-builder.cjs +1 -1
  57. package/dist/cjs/insert/conflict-builder.cjs +1 -1
  58. package/dist/cjs/insert/insert-builder.cjs +1 -1
  59. package/dist/cjs/maintenance/vacuum-builder.cjs +1 -1
  60. package/dist/cjs/pubsub/listen-notify-builder.cjs +1 -1
  61. package/dist/cjs/pubsub/listener-connection.cjs +2 -2
  62. package/dist/cjs/raw/raw-query-builder.cjs +1 -1
  63. package/dist/cjs/schema/schema-builder.cjs +1 -1
  64. package/dist/cjs/schema-definition/table-definition.cjs +1 -1
  65. package/dist/cjs/select/aggregate-builder.cjs +1 -1
  66. package/dist/cjs/select/select-builder.cjs +1 -1
  67. package/dist/cjs/sequence/sequence-builder.cjs +1 -1
  68. package/dist/cjs/table/alter-table-builder.cjs +1 -1
  69. package/dist/cjs/table/constraint-builder.cjs +1 -1
  70. package/dist/cjs/table/create-table-builder.cjs +1 -1
  71. package/dist/cjs/table/partition-builder.cjs +1 -1
  72. package/dist/cjs/table/truncate-builder.cjs +1 -1
  73. package/dist/cjs/transaction/transaction-builder.cjs +1 -1
  74. package/dist/cjs/trigger/create-trigger-builder.cjs +1 -1
  75. package/dist/cjs/update/array-update-builder.cjs +1 -1
  76. package/dist/cjs/update/update-builder.cjs +1 -1
  77. package/dist/cjs/utils/index.cjs +1 -1
  78. package/dist/cjs/view/create-view-builder.cjs +1 -1
  79. package/dist/cjs/window/window-builder.cjs +1 -1
  80. package/dist/esm/cli/commands/add.js +30 -1
  81. package/dist/esm/cli/commands/branch.js +105 -0
  82. package/dist/esm/cli/commands/checkout.js +98 -0
  83. package/dist/esm/cli/commands/cherry-pick.js +247 -0
  84. package/dist/esm/cli/commands/diff.js +148 -69
  85. package/dist/esm/cli/commands/export.js +64 -5
  86. package/dist/esm/cli/commands/fetch.js +35 -5
  87. package/dist/esm/cli/commands/history.js +1 -1
  88. package/dist/esm/cli/commands/import.js +283 -12
  89. package/dist/esm/cli/commands/log.js +74 -0
  90. package/dist/esm/cli/commands/merge.js +188 -0
  91. package/dist/esm/cli/commands/migrate.js +1 -1
  92. package/dist/esm/cli/commands/pull.js +124 -8
  93. package/dist/esm/cli/commands/push.js +246 -30
  94. package/dist/esm/cli/commands/remote.js +13 -0
  95. package/dist/esm/cli/commands/reset.js +133 -0
  96. package/dist/esm/cli/commands/resolve.js +157 -0
  97. package/dist/esm/cli/commands/rollback.js +1 -1
  98. package/dist/esm/cli/commands/stash.js +118 -0
  99. package/dist/esm/cli/commands/status.js +15 -0
  100. package/dist/esm/cli/commands/tag.js +111 -0
  101. package/dist/esm/cli/index.js +47 -3
  102. package/dist/esm/cli/utils/commit-manager.js +3 -3
  103. package/dist/esm/cli/utils/env-loader.js +3 -2
  104. package/dist/esm/cli/utils/fast-introspect.js +1 -1
  105. package/dist/esm/cli/utils/project-root.js +19 -0
  106. package/dist/esm/cli/utils/relqignore.js +277 -37
  107. package/dist/esm/cli/utils/repo-manager.js +41 -3
  108. package/dist/esm/cli/utils/schema-introspect.js +2 -2
  109. package/dist/esm/cli/utils/sql-generator.js +1 -1
  110. package/dist/esm/cli/utils/sql-parser.js +102 -13
  111. package/dist/esm/condition/array-condition-builder.js +1 -1
  112. package/dist/esm/condition/condition-collector.js +1 -1
  113. package/dist/esm/condition/fulltext-condition-builder.js +1 -1
  114. package/dist/esm/condition/geometric-condition-builder.js +1 -1
  115. package/dist/esm/condition/jsonb-condition-builder.js +1 -1
  116. package/dist/esm/condition/network-condition-builder.js +1 -1
  117. package/dist/esm/condition/range-condition-builder.js +1 -1
  118. package/dist/esm/copy/copy-builder.js +1 -1
  119. package/dist/esm/core/query-builder.js +1 -1
  120. package/dist/esm/core/relq-client.js +2 -2
  121. package/dist/esm/count/count-builder.js +1 -1
  122. package/dist/esm/cte/cte-builder.js +1 -1
  123. package/dist/esm/delete/delete-builder.js +1 -1
  124. package/dist/esm/function/create-function-builder.js +1 -1
  125. package/dist/esm/functions/advanced-functions.js +1 -1
  126. package/dist/esm/functions/case-builder.js +1 -1
  127. package/dist/esm/functions/geometric-functions.js +1 -1
  128. package/dist/esm/functions/network-functions.js +1 -1
  129. package/dist/esm/functions/sql-functions.js +1 -1
  130. package/dist/esm/indexing/create-index-builder.js +1 -1
  131. package/dist/esm/indexing/drop-index-builder.js +1 -1
  132. package/dist/esm/insert/conflict-builder.js +1 -1
  133. package/dist/esm/insert/insert-builder.js +1 -1
  134. package/dist/esm/maintenance/vacuum-builder.js +1 -1
  135. package/dist/esm/pubsub/listen-notify-builder.js +1 -1
  136. package/dist/esm/pubsub/listener-connection.js +2 -2
  137. package/dist/esm/raw/raw-query-builder.js +1 -1
  138. package/dist/esm/schema/schema-builder.js +1 -1
  139. package/dist/esm/schema-definition/table-definition.js +1 -1
  140. package/dist/esm/select/aggregate-builder.js +1 -1
  141. package/dist/esm/select/select-builder.js +1 -1
  142. package/dist/esm/sequence/sequence-builder.js +1 -1
  143. package/dist/esm/table/alter-table-builder.js +1 -1
  144. package/dist/esm/table/constraint-builder.js +1 -1
  145. package/dist/esm/table/create-table-builder.js +1 -1
  146. package/dist/esm/table/partition-builder.js +1 -1
  147. package/dist/esm/table/truncate-builder.js +1 -1
  148. package/dist/esm/transaction/transaction-builder.js +1 -1
  149. package/dist/esm/trigger/create-trigger-builder.js +1 -1
  150. package/dist/esm/update/array-update-builder.js +1 -1
  151. package/dist/esm/update/update-builder.js +1 -1
  152. package/dist/esm/utils/index.js +1 -1
  153. package/dist/esm/view/create-view-builder.js +1 -1
  154. package/dist/esm/window/window-builder.js +1 -1
  155. package/package.json +1 -1
  156. /package/dist/{addons/buffer.js → esm/addon/buffer/index.js} +0 -0
  157. /package/dist/{addons/pg.js → esm/addon/pg/index.js} +0 -0
  158. /package/dist/{addons/pg-cursor.js → esm/addon/pg-cursor/index.js} +0 -0
  159. /package/dist/{addons/pg-format.js → esm/addon/pg-format/index.js} +0 -0
@@ -33,31 +33,114 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.parsePattern = parsePattern;
36
37
  exports.loadRelqignore = loadRelqignore;
37
38
  exports.createDefaultRelqignore = createDefaultRelqignore;
38
39
  exports.isIgnored = isIgnored;
39
- exports.filterIgnored = filterIgnored;
40
+ exports.isTableIgnored = isTableIgnored;
41
+ exports.isColumnIgnored = isColumnIgnored;
42
+ exports.isIndexIgnored = isIndexIgnored;
43
+ exports.isConstraintIgnored = isConstraintIgnored;
44
+ exports.isTriggerIgnored = isTriggerIgnored;
45
+ exports.isEnumIgnored = isEnumIgnored;
46
+ exports.isDomainIgnored = isDomainIgnored;
47
+ exports.isSequenceIgnored = isSequenceIgnored;
48
+ exports.isCompositeTypeIgnored = isCompositeTypeIgnored;
49
+ exports.isFunctionIgnored = isFunctionIgnored;
50
+ exports.isViewIgnored = isViewIgnored;
51
+ exports.validateIgnoreDependencies = validateIgnoreDependencies;
52
+ exports.filterTables = filterTables;
53
+ exports.filterColumns = filterColumns;
54
+ exports.filterIndexes = filterIndexes;
55
+ exports.filterEnums = filterEnums;
56
+ exports.filterDomains = filterDomains;
40
57
  exports.getIgnorePatterns = getIgnorePatterns;
58
+ exports.filterIgnored = filterIgnored;
41
59
  const fs = __importStar(require("fs"));
42
60
  const path = __importStar(require("path"));
61
+ const REQUIRES_PARENT = [
62
+ 'COLUMN', 'INDEX', 'CONSTRAINT', 'CHECK', 'PRIMARY_KEY',
63
+ 'FOREIGN_KEY', 'EXCLUSION', 'PARTITION', 'TRIGGER'
64
+ ];
43
65
  const DEFAULT_PATTERNS = [
44
- '_relq_*',
45
- 'pg_*',
46
- '_temp_*',
47
- 'tmp_*',
66
+ 'TABLE:_relq_*',
67
+ 'TABLE:pg_*',
68
+ 'TABLE:_temp_*',
69
+ 'TABLE:tmp_*',
48
70
  ];
71
+ function parsePattern(line) {
72
+ const trimmed = line.trim();
73
+ if (!trimmed || trimmed.startsWith('#')) {
74
+ return null;
75
+ }
76
+ let negated = false;
77
+ let pattern = trimmed;
78
+ if (pattern.startsWith('!')) {
79
+ negated = true;
80
+ pattern = pattern.slice(1);
81
+ }
82
+ const colonIndex = pattern.indexOf(':');
83
+ if (colonIndex > 0) {
84
+ const typeStr = pattern.slice(0, colonIndex).toUpperCase();
85
+ const rest = pattern.slice(colonIndex + 1);
86
+ const validTypes = [
87
+ 'TABLE', 'COLUMN', 'INDEX', 'CONSTRAINT', 'CHECK', 'PRIMARY_KEY',
88
+ 'FOREIGN_KEY', 'EXCLUSION', 'PARTITION', 'ENUM', 'DOMAIN', 'SEQUENCE',
89
+ 'COMPOSITE_TYPE', 'FUNCTION', 'PROCEDURE', 'TRIGGER', 'VIEW',
90
+ 'MATERIALIZED_VIEW', 'FOREIGN_TABLE', 'EXTENSION', 'COLLATION'
91
+ ];
92
+ if (validTypes.includes(typeStr)) {
93
+ const type = typeStr;
94
+ if (REQUIRES_PARENT.includes(type)) {
95
+ const dotIndex = rest.indexOf('.');
96
+ if (dotIndex > 0) {
97
+ return {
98
+ type,
99
+ parent: rest.slice(0, dotIndex),
100
+ pattern: rest.slice(dotIndex + 1),
101
+ negated,
102
+ raw: trimmed,
103
+ };
104
+ }
105
+ else {
106
+ console.warn(`Warning: ${type} pattern requires table name (e.g., ${type}:table_name.pattern)`);
107
+ return null;
108
+ }
109
+ }
110
+ else {
111
+ return {
112
+ type,
113
+ parent: null,
114
+ pattern: rest,
115
+ negated,
116
+ raw: trimmed,
117
+ };
118
+ }
119
+ }
120
+ }
121
+ return {
122
+ type: 'TABLE',
123
+ parent: null,
124
+ pattern,
125
+ negated,
126
+ raw: trimmed,
127
+ };
128
+ }
49
129
  function loadRelqignore(projectRoot = process.cwd()) {
50
130
  const ignorePath = path.join(projectRoot, '.relqignore');
51
- const patterns = [...DEFAULT_PATTERNS];
131
+ const patterns = [];
132
+ for (const defaultPattern of DEFAULT_PATTERNS) {
133
+ const parsed = parsePattern(defaultPattern);
134
+ if (parsed)
135
+ patterns.push(parsed);
136
+ }
52
137
  if (fs.existsSync(ignorePath)) {
53
138
  const content = fs.readFileSync(ignorePath, 'utf-8');
54
139
  const lines = content.split('\n');
55
140
  for (const line of lines) {
56
- const trimmed = line.trim();
57
- if (!trimmed || trimmed.startsWith('#')) {
58
- continue;
59
- }
60
- patterns.push(trimmed);
141
+ const parsed = parsePattern(line);
142
+ if (parsed)
143
+ patterns.push(parsed);
61
144
  }
62
145
  }
63
146
  return patterns;
@@ -68,40 +151,58 @@ function createDefaultRelqignore(projectRoot = process.cwd()) {
68
151
  return;
69
152
  }
70
153
  const content = `# Relq Ignore File
71
- # Tables and functions matching these patterns will be ignored
154
+ # Objects matching these patterns will be ignored in import/export/add/commit
155
+
156
+ # =============================================================================
157
+ # PATTERN FORMAT
158
+ # =============================================================================
159
+ # TYPE:pattern - Match specific object type
160
+ # TYPE:table.pattern - Match sub-objects (columns, indexes, etc.)
161
+ # pattern - Match tables (backward compatible)
162
+ # !pattern - Negate (un-ignore) a pattern
163
+
164
+ # =============================================================================
165
+ # TYPES
166
+ # =============================================================================
167
+ # TABLE, COLUMN, INDEX, CONSTRAINT, CHECK, PRIMARY_KEY, FOREIGN_KEY, EXCLUSION
168
+ # PARTITION, ENUM, DOMAIN, SEQUENCE, COMPOSITE_TYPE, FUNCTION, PROCEDURE
169
+ # TRIGGER, VIEW, MATERIALIZED_VIEW, FOREIGN_TABLE, EXTENSION, COLLATION
170
+
171
+ # =============================================================================
172
+ # DEFAULT PATTERNS (always applied)
173
+ # =============================================================================
174
+ # TABLE:_relq_* - Relq internal tables
175
+ # TABLE:pg_* - PostgreSQL system tables
176
+ # TABLE:_temp_* - Temporary tables
177
+ # TABLE:tmp_* - Temporary tables
178
+
179
+ # =============================================================================
180
+ # EXAMPLES
181
+ # =============================================================================
72
182
 
73
- # Relq internal tables (always ignored)
74
- _relq_*
183
+ # Ignore specific tables
184
+ # TABLE:debug_*
185
+ # TABLE:test_*
75
186
 
76
- # PostgreSQL system tables
77
- pg_*
187
+ # Ignore sensitive columns (table.column format required)
188
+ # COLUMN:users.password_hash
189
+ # COLUMN:*.api_key
78
190
 
79
- # Temporary tables
80
- _temp_*
81
- tmp_*
191
+ # Ignore temporary indexes
192
+ # INDEX:*.idx_temp_*
82
193
 
83
- # Add your tables/functions to ignore below:
84
- # analytics_raw
85
- # debug_*
86
- # test_*
194
+ # Ignore debug functions
195
+ # FUNCTION:debug_*
196
+
197
+ # Ignore internal triggers
198
+ # TRIGGER:audit_logs.*
199
+
200
+ # Ignore test enums
201
+ # ENUM:test_*
87
202
  `;
88
203
  fs.writeFileSync(ignorePath, content, 'utf-8');
89
204
  }
90
- function isIgnored(name, patterns) {
91
- for (const pattern of patterns) {
92
- if (matchPattern(name, pattern)) {
93
- return true;
94
- }
95
- }
96
- return false;
97
- }
98
- function filterIgnored(items, patterns) {
99
- return items.filter(item => !isIgnored(item.name, patterns));
100
- }
101
- function matchPattern(name, pattern) {
102
- if (pattern.startsWith('!')) {
103
- return !matchPattern(name, pattern.slice(1));
104
- }
205
+ function matchGlob(name, pattern) {
105
206
  const regexPattern = pattern
106
207
  .replace(/[.+^${}()|[\]\\]/g, '\\$&')
107
208
  .replace(/\*/g, '.*')
@@ -109,6 +210,163 @@ function matchPattern(name, pattern) {
109
210
  const regex = new RegExp(`^${regexPattern}$`, 'i');
110
211
  return regex.test(name);
111
212
  }
213
+ function isIgnored(objectType, objectName, parentName, patterns) {
214
+ let isIgnored = false;
215
+ let matchedPattern;
216
+ for (const pattern of patterns) {
217
+ if (pattern.type !== null && pattern.type !== objectType) {
218
+ continue;
219
+ }
220
+ if (pattern.parent !== null) {
221
+ if (parentName === null || !matchGlob(parentName, pattern.parent)) {
222
+ continue;
223
+ }
224
+ }
225
+ if (matchGlob(objectName, pattern.pattern)) {
226
+ if (pattern.negated) {
227
+ isIgnored = false;
228
+ matchedPattern = pattern;
229
+ }
230
+ else {
231
+ isIgnored = true;
232
+ matchedPattern = pattern;
233
+ }
234
+ }
235
+ }
236
+ return {
237
+ ignored: isIgnored,
238
+ pattern: matchedPattern,
239
+ reason: matchedPattern ? `Matched pattern: ${matchedPattern.raw}` : undefined,
240
+ };
241
+ }
242
+ function isTableIgnored(tableName, patterns) {
243
+ return isIgnored('TABLE', tableName, null, patterns);
244
+ }
245
+ function isColumnIgnored(tableName, columnName, patterns) {
246
+ return isIgnored('COLUMN', columnName, tableName, patterns);
247
+ }
248
+ function isIndexIgnored(tableName, indexName, patterns) {
249
+ return isIgnored('INDEX', indexName, tableName, patterns);
250
+ }
251
+ function isConstraintIgnored(tableName, constraintName, patterns) {
252
+ return isIgnored('CONSTRAINT', constraintName, tableName, patterns);
253
+ }
254
+ function isTriggerIgnored(tableName, triggerName, patterns) {
255
+ return isIgnored('TRIGGER', triggerName, tableName, patterns);
256
+ }
257
+ function isEnumIgnored(enumName, patterns) {
258
+ return isIgnored('ENUM', enumName, null, patterns);
259
+ }
260
+ function isDomainIgnored(domainName, patterns) {
261
+ return isIgnored('DOMAIN', domainName, null, patterns);
262
+ }
263
+ function isSequenceIgnored(sequenceName, patterns) {
264
+ return isIgnored('SEQUENCE', sequenceName, null, patterns);
265
+ }
266
+ function isCompositeTypeIgnored(typeName, patterns) {
267
+ return isIgnored('COMPOSITE_TYPE', typeName, null, patterns);
268
+ }
269
+ function isFunctionIgnored(functionName, patterns) {
270
+ return isIgnored('FUNCTION', functionName, null, patterns);
271
+ }
272
+ function isViewIgnored(viewName, patterns) {
273
+ return isIgnored('VIEW', viewName, null, patterns);
274
+ }
275
+ function validateIgnoreDependencies(schema, patterns) {
276
+ const errors = [];
277
+ const ignoredEnums = new Set();
278
+ const ignoredDomains = new Set();
279
+ const ignoredSequences = new Set();
280
+ const ignoredComposites = new Set();
281
+ for (const e of schema.enums) {
282
+ if (isEnumIgnored(e.name, patterns).ignored) {
283
+ ignoredEnums.add(e.name.toLowerCase());
284
+ }
285
+ }
286
+ for (const d of schema.domains) {
287
+ if (isDomainIgnored(d.name, patterns).ignored) {
288
+ ignoredDomains.add(d.name.toLowerCase());
289
+ }
290
+ }
291
+ for (const s of schema.sequences) {
292
+ if (isSequenceIgnored(s.name, patterns).ignored) {
293
+ ignoredSequences.add(s.name.toLowerCase());
294
+ }
295
+ }
296
+ for (const c of schema.compositeTypes) {
297
+ if (isCompositeTypeIgnored(c.name, patterns).ignored) {
298
+ ignoredComposites.add(c.name.toLowerCase());
299
+ }
300
+ }
301
+ for (const table of schema.tables) {
302
+ if (isTableIgnored(table.name, patterns).ignored) {
303
+ continue;
304
+ }
305
+ for (const column of table.columns) {
306
+ if (isColumnIgnored(table.name, column.name, patterns).ignored) {
307
+ continue;
308
+ }
309
+ const typeLower = column.type.toLowerCase().replace(/\[\]$/, '');
310
+ if (ignoredEnums.has(typeLower)) {
311
+ errors.push({
312
+ type: 'ENUM',
313
+ name: column.type,
314
+ usedBy: { table: table.name, column: column.name },
315
+ message: `Column "${table.name}.${column.name}" uses ignored ENUM "${column.type}". Either un-ignore the ENUM or ignore this column.`,
316
+ });
317
+ }
318
+ if (ignoredDomains.has(typeLower)) {
319
+ errors.push({
320
+ type: 'DOMAIN',
321
+ name: column.type,
322
+ usedBy: { table: table.name, column: column.name },
323
+ message: `Column "${table.name}.${column.name}" uses ignored DOMAIN "${column.type}". Either un-ignore the DOMAIN or ignore this column.`,
324
+ });
325
+ }
326
+ if (ignoredComposites.has(typeLower)) {
327
+ errors.push({
328
+ type: 'COMPOSITE_TYPE',
329
+ name: column.type,
330
+ usedBy: { table: table.name, column: column.name },
331
+ message: `Column "${table.name}.${column.name}" uses ignored COMPOSITE_TYPE "${column.type}". Either un-ignore the type or ignore this column.`,
332
+ });
333
+ }
334
+ if (column.default) {
335
+ const seqMatch = column.default.match(/nextval\(['"]?([^'"()]+)['"]?/i);
336
+ if (seqMatch) {
337
+ const seqName = seqMatch[1].toLowerCase().replace(/::regclass$/, '');
338
+ if (ignoredSequences.has(seqName)) {
339
+ errors.push({
340
+ type: 'SEQUENCE',
341
+ name: seqMatch[1],
342
+ usedBy: { table: table.name, column: column.name },
343
+ message: `Column "${table.name}.${column.name}" uses ignored SEQUENCE "${seqMatch[1]}". Either un-ignore the SEQUENCE or ignore this column.`,
344
+ });
345
+ }
346
+ }
347
+ }
348
+ }
349
+ }
350
+ return errors;
351
+ }
352
+ function filterTables(tables, patterns) {
353
+ return tables.filter(t => !isTableIgnored(t.name, patterns).ignored);
354
+ }
355
+ function filterColumns(tableName, columns, patterns) {
356
+ return columns.filter(c => !isColumnIgnored(tableName, c.name, patterns).ignored);
357
+ }
358
+ function filterIndexes(tableName, indexes, patterns) {
359
+ return indexes.filter(i => !isIndexIgnored(tableName, i.name, patterns).ignored);
360
+ }
361
+ function filterEnums(enums, patterns) {
362
+ return enums.filter(e => !isEnumIgnored(e.name, patterns).ignored);
363
+ }
364
+ function filterDomains(domains, patterns) {
365
+ return domains.filter(d => !isDomainIgnored(d.name, patterns).ignored);
366
+ }
112
367
  function getIgnorePatterns(projectRoot = process.cwd()) {
113
368
  return loadRelqignore(projectRoot);
114
369
  }
370
+ function filterIgnored(items, patterns) {
371
+ return items.filter(item => !isTableIgnored(item.name, patterns).ignored);
372
+ }
@@ -69,6 +69,10 @@ exports.pushCommit = pushCommit;
69
69
  exports.getRepoStatus = getRepoStatus;
70
70
  exports.createEmptySchema = createEmptySchema;
71
71
  exports.migrateSnapshot = migrateSnapshot;
72
+ exports.loadTags = loadTags;
73
+ exports.saveTags = saveTags;
74
+ exports.resolveRef = resolveRef;
75
+ exports.loadParentCommit = loadParentCommit;
72
76
  const fs = __importStar(require("fs"));
73
77
  const path = __importStar(require("path"));
74
78
  const crypto = __importStar(require("crypto"));
@@ -350,7 +354,7 @@ function hasUncommittedChanges(projectRoot = process.cwd()) {
350
354
  return state.staged.length > 0 || state.unstaged.length > 0;
351
355
  }
352
356
  async function ensureRemoteTable(connection) {
353
- const { Pool } = await Promise.resolve().then(() => __importStar(require("../../../addons/pg.js")));
357
+ const { Pool } = await Promise.resolve().then(() => __importStar(require("../../addon/pg/index.cjs")));
354
358
  const pool = new Pool({
355
359
  host: connection.host,
356
360
  port: connection.port || 5432,
@@ -382,7 +386,7 @@ async function ensureRemoteTable(connection) {
382
386
  }
383
387
  }
384
388
  async function fetchRemoteCommits(connection, limit = 100) {
385
- const { Pool } = await Promise.resolve().then(() => __importStar(require("../../../addons/pg.js")));
389
+ const { Pool } = await Promise.resolve().then(() => __importStar(require("../../addon/pg/index.cjs")));
386
390
  const pool = new Pool({
387
391
  host: connection.host,
388
392
  port: connection.port || 5432,
@@ -418,7 +422,7 @@ async function getRemoteHead(connection) {
418
422
  return commits.length > 0 ? commits[0].hash : null;
419
423
  }
420
424
  async function pushCommit(connection, commit) {
421
- const { Pool } = await Promise.resolve().then(() => __importStar(require("../../../addons/pg.js")));
425
+ const { Pool } = await Promise.resolve().then(() => __importStar(require("../../addon/pg/index.cjs")));
422
426
  const pool = new Pool({
423
427
  host: connection.host,
424
428
  port: connection.port || 5432,
@@ -513,3 +517,41 @@ function migrateSnapshot(snapshot) {
513
517
  foreignTables: snapshot.foreignTables || [],
514
518
  };
515
519
  }
520
+ function loadTags(projectRoot = process.cwd()) {
521
+ const tagPath = path.join(projectRoot, '.relq', 'tags.json');
522
+ if (fs.existsSync(tagPath)) {
523
+ return JSON.parse(fs.readFileSync(tagPath, 'utf-8'));
524
+ }
525
+ return {};
526
+ }
527
+ function saveTags(tags, projectRoot = process.cwd()) {
528
+ const tagPath = path.join(projectRoot, '.relq', 'tags.json');
529
+ fs.writeFileSync(tagPath, JSON.stringify(tags, null, 2));
530
+ }
531
+ function resolveRef(ref, projectRoot = process.cwd()) {
532
+ const commit = loadCommit(ref, projectRoot);
533
+ if (commit)
534
+ return commit.hash;
535
+ const tags = loadTags(projectRoot);
536
+ if (tags[ref])
537
+ return tags[ref].hash;
538
+ const headMatch = ref.match(/^HEAD~(\d+)$/);
539
+ if (headMatch) {
540
+ const offset = parseInt(headMatch[1]);
541
+ let current = getHead(projectRoot);
542
+ for (let i = 0; i < offset && current; i++) {
543
+ const c = loadCommit(current, projectRoot);
544
+ if (!c || !c.parentHash)
545
+ return null;
546
+ current = c.parentHash;
547
+ }
548
+ return current;
549
+ }
550
+ return null;
551
+ }
552
+ function loadParentCommit(hash, projectRoot = process.cwd()) {
553
+ const commit = loadCommit(hash, projectRoot);
554
+ if (!commit || !commit.parentHash)
555
+ return null;
556
+ return loadCommit(commit.parentHash, projectRoot);
557
+ }
@@ -37,7 +37,7 @@ exports.introspectDatabase = introspectDatabase;
37
37
  exports.tableHasData = tableHasData;
38
38
  async function introspectDatabase(connection, onProgress, options) {
39
39
  const { includeFunctions = false, includeTriggers = false } = options || {};
40
- const { Pool } = await Promise.resolve().then(() => __importStar(require("../../../addons/pg.js")));
40
+ const { Pool } = await Promise.resolve().then(() => __importStar(require("../../addon/pg/index.cjs")));
41
41
  onProgress?.('connecting', connection.database);
42
42
  const pool = new Pool({
43
43
  host: connection.host,
@@ -433,7 +433,7 @@ function parseOptions(options) {
433
433
  return result;
434
434
  }
435
435
  async function tableHasData(connection, tableName) {
436
- const { Pool } = await Promise.resolve().then(() => __importStar(require("../../../addons/pg.js")));
436
+ const { Pool } = await Promise.resolve().then(() => __importStar(require("../../addon/pg/index.cjs")));
437
437
  const pool = new Pool({
438
438
  host: connection.host,
439
439
  port: connection.port || 5432,
@@ -222,7 +222,7 @@ function generateColumnSQL(col) {
222
222
  if (col.identityGeneration) {
223
223
  parts.push(`GENERATED ${col.identityGeneration} AS IDENTITY`);
224
224
  }
225
- if (!col.isNullable && !col.isPrimaryKey) {
225
+ if (!col.isNullable && !col.isPrimaryKey && !col.identityGeneration) {
226
226
  parts.push('NOT NULL');
227
227
  }
228
228
  if (col.defaultValue !== null && col.defaultValue !== undefined && !col.isGenerated) {
@@ -13,6 +13,9 @@ function parseSqlFile(sqlContent) {
13
13
  const sequences = [];
14
14
  const collations = [];
15
15
  const foreignTables = [];
16
+ const views = [];
17
+ const materializedViews = [];
18
+ const foreignServers = [];
16
19
  const extensions = [];
17
20
  const partitions = [];
18
21
  const cleanedSql = removeComments(sqlContent);
@@ -25,7 +28,14 @@ function parseSqlFile(sqlContent) {
25
28
  parseTables(cleanedSql, tables, partitions, enums, domains);
26
29
  parseIndexes(cleanedSql, tables);
27
30
  parseForeignTables(cleanedSql, foreignTables);
28
- return { tables, enums, domains, compositeTypes, sequences, collations, foreignTables, extensions, partitions };
31
+ parseViews(cleanedSql, views);
32
+ parseMaterializedViews(cleanedSql, materializedViews);
33
+ parseForeignServers(cleanedSql, foreignServers);
34
+ return {
35
+ tables, enums, domains, compositeTypes, sequences, collations,
36
+ foreignTables, views, materializedViews, foreignServers,
37
+ extensions, partitions
38
+ };
29
39
  }
30
40
  function removeComments(sql) {
31
41
  let result = sql.replace(/\/\*[\s\S]*?\*\//g, '');
@@ -117,11 +127,11 @@ function parseCompositeTypeBody(body) {
117
127
  const trimmed = line.trim();
118
128
  if (!trimmed)
119
129
  continue;
120
- const attrMatch = trimmed.match(/^(\w+)\s+(.+)$/);
130
+ const attrMatch = trimmed.match(/^(?:"([^"]+)"|(\w+))\s+(.+)$/);
121
131
  if (attrMatch) {
122
132
  attributes.push({
123
- name: attrMatch[1],
124
- type: attrMatch[2].trim().replace(/,\s*$/, ''),
133
+ name: attrMatch[1] || attrMatch[2],
134
+ type: attrMatch[3].trim().replace(/,\s*$/, ''),
125
135
  });
126
136
  }
127
137
  }
@@ -366,12 +376,14 @@ function parseTableBody(body, enums, domains) {
366
376
  const trimmed = part.trim();
367
377
  if (!trimmed)
368
378
  continue;
369
- if (trimmed.toUpperCase().startsWith('CONSTRAINT') ||
370
- trimmed.toUpperCase().startsWith('PRIMARY KEY') ||
371
- trimmed.toUpperCase().startsWith('FOREIGN KEY') ||
372
- trimmed.toUpperCase().startsWith('UNIQUE') ||
373
- trimmed.toUpperCase().startsWith('CHECK') ||
374
- trimmed.toUpperCase().startsWith('EXCLUDE')) {
379
+ const upper = trimmed.toUpperCase();
380
+ const isConstraint = upper.startsWith('CONSTRAINT ') ||
381
+ /^PRIMARY\s+KEY\s*\(/i.test(trimmed) ||
382
+ /^FOREIGN\s+KEY\s*\(/i.test(trimmed) ||
383
+ /^UNIQUE\s*\(/i.test(trimmed) ||
384
+ /^CHECK\s*\(/i.test(trimmed) ||
385
+ /^EXCLUDE\s+(?:USING\s+|ON\s+|\()/i.test(trimmed);
386
+ if (isConstraint) {
375
387
  const constraint = parseConstraint(trimmed);
376
388
  if (constraint) {
377
389
  constraints.push(constraint);
@@ -618,9 +630,9 @@ function extractMaxLength(type) {
618
630
  }
619
631
  function parseConstraint(def) {
620
632
  const upper = def.toUpperCase();
621
- const namedMatch = def.match(/CONSTRAINT\s+(\w+)\s+(.+)/i);
622
- const constraintDef = namedMatch ? namedMatch[2] : def;
623
- const constraintName = namedMatch ? namedMatch[1] : '';
633
+ const namedMatch = def.match(/CONSTRAINT\s+(?:"([^"]+)"|(\w+))\s+(.+)/is);
634
+ const constraintDef = namedMatch ? namedMatch[3] : def;
635
+ const constraintName = namedMatch ? (namedMatch[1] || namedMatch[2]) : '';
624
636
  const constraintUpper = constraintDef.toUpperCase();
625
637
  if (constraintUpper.startsWith('PRIMARY KEY')) {
626
638
  const colsMatch = constraintDef.match(/PRIMARY\s+KEY\s*\(\s*([^)]+)\s*\)/i);
@@ -996,4 +1008,81 @@ function parseComments(sql) {
996
1008
  }
997
1009
  return comments;
998
1010
  }
1011
+ function parseViews(sql, views) {
1012
+ const viewRegex = /CREATE\s+(?:OR\s+REPLACE\s+)?VIEW\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:(?:"?(\w+)"?\.)?"?(\w+)"?)\s*(?:\(([^)]+)\))?\s+AS\s+([\s\S]+?)(?:;|\s+WITH\s+(?:CASCADED|LOCAL)\s+CHECK\s+OPTION\s*;)/gi;
1013
+ let match;
1014
+ while ((match = viewRegex.exec(sql)) !== null) {
1015
+ const schema = match[1] || 'public';
1016
+ const name = match[2];
1017
+ const columnsStr = match[3];
1018
+ const definition = match[4].trim();
1019
+ const columns = columnsStr
1020
+ ? columnsStr.split(',').map(c => c.trim().replace(/"/g, ''))
1021
+ : undefined;
1022
+ views.push({
1023
+ name,
1024
+ schema,
1025
+ definition,
1026
+ columns,
1027
+ });
1028
+ }
1029
+ const simpleViewRegex = /CREATE\s+(?:OR\s+REPLACE\s+)?VIEW\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:(?:"?(\w+)"?\.)?"?(\w+)"?)\s*AS\s+(SELECT[\s\S]+?);/gi;
1030
+ while ((match = simpleViewRegex.exec(sql)) !== null) {
1031
+ const schema = match[1] || 'public';
1032
+ const name = match[2];
1033
+ const definition = match[3].trim();
1034
+ if (views.some(v => v.name === name))
1035
+ continue;
1036
+ views.push({
1037
+ name,
1038
+ schema,
1039
+ definition,
1040
+ });
1041
+ }
1042
+ }
1043
+ function parseMaterializedViews(sql, materializedViews) {
1044
+ const mviewRegex = /CREATE\s+MATERIALIZED\s+VIEW\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:(?:"?(\w+)"?\.)?"?(\w+)"?)\s*(?:\(([^)]+)\))?\s+AS\s+([\s\S]+?)(?:WITH\s+(NO\s+)?DATA\s*)?;/gi;
1045
+ let match;
1046
+ while ((match = mviewRegex.exec(sql)) !== null) {
1047
+ const schema = match[1] || 'public';
1048
+ const name = match[2];
1049
+ const columnsStr = match[3];
1050
+ const definition = match[4].trim();
1051
+ const withNoData = match[5] !== undefined;
1052
+ const columns = columnsStr
1053
+ ? columnsStr.split(',').map(c => c.trim().replace(/"/g, ''))
1054
+ : undefined;
1055
+ materializedViews.push({
1056
+ name,
1057
+ schema,
1058
+ definition,
1059
+ columns,
1060
+ withData: !withNoData,
1061
+ });
1062
+ }
1063
+ }
1064
+ function parseForeignServers(sql, foreignServers) {
1065
+ const serverRegex = /CREATE\s+SERVER\s+(?:IF\s+NOT\s+EXISTS\s+)?"?(\w+)"?\s+FOREIGN\s+DATA\s+WRAPPER\s+"?(\w+)"?\s*(?:OPTIONS\s*\(([^)]+)\))?;/gi;
1066
+ let match;
1067
+ while ((match = serverRegex.exec(sql)) !== null) {
1068
+ const name = match[1];
1069
+ const fdwName = match[2];
1070
+ const optionsStr = match[3];
1071
+ const options = {};
1072
+ if (optionsStr) {
1073
+ const optParts = optionsStr.split(',');
1074
+ for (const part of optParts) {
1075
+ const optMatch = part.trim().match(/(\w+)\s+'([^']+)'/);
1076
+ if (optMatch) {
1077
+ options[optMatch[1]] = optMatch[2];
1078
+ }
1079
+ }
1080
+ }
1081
+ foreignServers.push({
1082
+ name,
1083
+ fdwName,
1084
+ options: Object.keys(options).length > 0 ? options : undefined,
1085
+ });
1086
+ }
1087
+ }
999
1088
  exports.default = parseSqlFile;
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ArrayConditionCollector = void 0;
7
7
  exports.buildArrayConditionSQL = buildArrayConditionSQL;
8
- const pg_format_1 = __importDefault(require("../../addons/pg-format.js"));
8
+ const pg_format_1 = __importDefault(require("../addon/pg-format/index.cjs"));
9
9
  const array_string_condition_builder_1 = require("./array-string-condition-builder.cjs");
10
10
  const array_numeric_condition_builder_1 = require("./array-numeric-condition-builder.cjs");
11
11
  const array_specialized_condition_builder_1 = require("./array-specialized-condition-builder.cjs");
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ConditionCollector = void 0;
7
7
  exports.buildConditionSQL = buildConditionSQL;
8
8
  exports.buildConditionsSQL = buildConditionsSQL;
9
- const pg_format_1 = __importDefault(require("../../addons/pg-format.js"));
9
+ const pg_format_1 = __importDefault(require("../addon/pg-format/index.cjs"));
10
10
  const jsonb_condition_builder_1 = require("./jsonb-condition-builder.cjs");
11
11
  const array_condition_builder_1 = require("./array-condition-builder.cjs");
12
12
  const fulltext_condition_builder_1 = require("./fulltext-condition-builder.cjs");
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.FulltextConditionCollector = void 0;
7
7
  exports.buildFulltextConditionSQL = buildFulltextConditionSQL;
8
- const pg_format_1 = __importDefault(require("../../addons/pg-format.js"));
8
+ const pg_format_1 = __importDefault(require("../addon/pg-format/index.cjs"));
9
9
  class FulltextConditionCollector {
10
10
  parent;
11
11
  constructor(parent) {
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.GeometricConditionCollector = void 0;
7
7
  exports.buildGeometricConditionSQL = buildGeometricConditionSQL;
8
- const pg_format_1 = __importDefault(require("../../addons/pg-format.js"));
8
+ const pg_format_1 = __importDefault(require("../addon/pg-format/index.cjs"));
9
9
  class GeometricConditionCollector {
10
10
  parent;
11
11
  constructor(parent) {