@t1mmen/srtd 0.0.0-next-20251227000343

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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +363 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +50 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/apply.d.ts +2 -0
  7. package/dist/commands/apply.js +105 -0
  8. package/dist/commands/apply.js.map +1 -0
  9. package/dist/commands/build.d.ts +2 -0
  10. package/dist/commands/build.js +134 -0
  11. package/dist/commands/build.js.map +1 -0
  12. package/dist/commands/clear.d.ts +2 -0
  13. package/dist/commands/clear.js +161 -0
  14. package/dist/commands/clear.js.map +1 -0
  15. package/dist/commands/init.d.ts +2 -0
  16. package/dist/commands/init.js +91 -0
  17. package/dist/commands/init.js.map +1 -0
  18. package/dist/commands/menu.d.ts +4 -0
  19. package/dist/commands/menu.js +76 -0
  20. package/dist/commands/menu.js.map +1 -0
  21. package/dist/commands/promote.d.ts +2 -0
  22. package/dist/commands/promote.js +181 -0
  23. package/dist/commands/promote.js.map +1 -0
  24. package/dist/commands/register.d.ts +2 -0
  25. package/dist/commands/register.js +192 -0
  26. package/dist/commands/register.js.map +1 -0
  27. package/dist/commands/watch.d.ts +14 -0
  28. package/dist/commands/watch.js +190 -0
  29. package/dist/commands/watch.js.map +1 -0
  30. package/dist/constants.d.ts +1 -0
  31. package/dist/constants.js +2 -0
  32. package/dist/constants.js.map +1 -0
  33. package/dist/services/DatabaseService.d.ts +113 -0
  34. package/dist/services/DatabaseService.js +343 -0
  35. package/dist/services/DatabaseService.js.map +1 -0
  36. package/dist/services/FileSystemService.d.ts +100 -0
  37. package/dist/services/FileSystemService.js +237 -0
  38. package/dist/services/FileSystemService.js.map +1 -0
  39. package/dist/services/MigrationBuilder.d.ts +106 -0
  40. package/dist/services/MigrationBuilder.js +193 -0
  41. package/dist/services/MigrationBuilder.js.map +1 -0
  42. package/dist/services/Orchestrator.d.ts +155 -0
  43. package/dist/services/Orchestrator.js +622 -0
  44. package/dist/services/Orchestrator.js.map +1 -0
  45. package/dist/services/StateService.d.ts +169 -0
  46. package/dist/services/StateService.js +463 -0
  47. package/dist/services/StateService.js.map +1 -0
  48. package/dist/types.d.ts +48 -0
  49. package/dist/types.js +2 -0
  50. package/dist/types.js.map +1 -0
  51. package/dist/ui/badge.d.ts +14 -0
  52. package/dist/ui/badge.js +28 -0
  53. package/dist/ui/badge.js.map +1 -0
  54. package/dist/ui/branding.d.ts +9 -0
  55. package/dist/ui/branding.js +35 -0
  56. package/dist/ui/branding.js.map +1 -0
  57. package/dist/ui/index.d.ts +4 -0
  58. package/dist/ui/index.js +5 -0
  59. package/dist/ui/index.js.map +1 -0
  60. package/dist/ui/results.d.ts +10 -0
  61. package/dist/ui/results.js +62 -0
  62. package/dist/ui/results.js.map +1 -0
  63. package/dist/ui/spinner.d.ts +5 -0
  64. package/dist/ui/spinner.js +8 -0
  65. package/dist/ui/spinner.js.map +1 -0
  66. package/dist/utils/config.d.ts +12 -0
  67. package/dist/utils/config.js +67 -0
  68. package/dist/utils/config.js.map +1 -0
  69. package/dist/utils/createEmptyBuildLog.d.ts +1 -0
  70. package/dist/utils/createEmptyBuildLog.js +10 -0
  71. package/dist/utils/createEmptyBuildLog.js.map +1 -0
  72. package/dist/utils/ensureDirectories.d.ts +4 -0
  73. package/dist/utils/ensureDirectories.js +23 -0
  74. package/dist/utils/ensureDirectories.js.map +1 -0
  75. package/dist/utils/fileExists.d.ts +1 -0
  76. package/dist/utils/fileExists.js +11 -0
  77. package/dist/utils/fileExists.js.map +1 -0
  78. package/dist/utils/findProjectRoot.d.ts +1 -0
  79. package/dist/utils/findProjectRoot.js +25 -0
  80. package/dist/utils/findProjectRoot.js.map +1 -0
  81. package/dist/utils/getErrorMessage.d.ts +9 -0
  82. package/dist/utils/getErrorMessage.js +14 -0
  83. package/dist/utils/getErrorMessage.js.map +1 -0
  84. package/dist/utils/getNextTimestamp.d.ts +2 -0
  85. package/dist/utils/getNextTimestamp.js +12 -0
  86. package/dist/utils/getNextTimestamp.js.map +1 -0
  87. package/dist/utils/isWipTemplate.d.ts +1 -0
  88. package/dist/utils/isWipTemplate.js +6 -0
  89. package/dist/utils/isWipTemplate.js.map +1 -0
  90. package/dist/utils/logger.d.ts +9 -0
  91. package/dist/utils/logger.js +12 -0
  92. package/dist/utils/logger.js.map +1 -0
  93. package/dist/utils/safeCreate.d.ts +1 -0
  94. package/dist/utils/safeCreate.js +16 -0
  95. package/dist/utils/safeCreate.js.map +1 -0
  96. package/package.json +106 -0
@@ -0,0 +1,237 @@
1
+ /**
2
+ * FileSystemService - Handles all file system operations for templates
3
+ * Decoupled from business logic, only handles raw file operations
4
+ */
5
+ import crypto from 'node:crypto';
6
+ import { EventEmitter } from 'node:events';
7
+ import fs from 'node:fs/promises';
8
+ import path from 'node:path';
9
+ import { glob } from 'glob';
10
+ export class FileSystemService extends EventEmitter {
11
+ config;
12
+ watcher = null;
13
+ debouncedHandlers = new Map();
14
+ constructor(config) {
15
+ super();
16
+ this.config = config;
17
+ }
18
+ /**
19
+ * Find all template files matching the configured pattern
20
+ */
21
+ async findTemplates() {
22
+ const templatePath = path.join(this.config.baseDir, this.config.templateDir, this.config.filter);
23
+ const matches = await glob(templatePath);
24
+ return matches.sort(); // Ensure consistent ordering
25
+ }
26
+ /**
27
+ * Read a template file and return its content with metadata
28
+ */
29
+ async readTemplate(templatePath) {
30
+ try {
31
+ const content = await fs.readFile(templatePath, 'utf-8');
32
+ const hash = this.calculateHash(content);
33
+ const name = path.basename(templatePath, '.sql');
34
+ const relativePath = path.relative(this.config.baseDir, templatePath);
35
+ return {
36
+ path: templatePath,
37
+ name,
38
+ content,
39
+ hash,
40
+ relativePath,
41
+ };
42
+ }
43
+ catch (error) {
44
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
45
+ throw new Error(`Template file not found: ${templatePath}`);
46
+ }
47
+ throw error;
48
+ }
49
+ }
50
+ /**
51
+ * Check if a file exists
52
+ */
53
+ async fileExists(filePath) {
54
+ try {
55
+ await fs.stat(filePath);
56
+ return true;
57
+ }
58
+ catch {
59
+ return false;
60
+ }
61
+ }
62
+ /**
63
+ * Write content to a file
64
+ */
65
+ async writeFile(filePath, content) {
66
+ const dir = path.dirname(filePath);
67
+ await fs.mkdir(dir, { recursive: true });
68
+ await fs.writeFile(filePath, content, 'utf-8');
69
+ }
70
+ /**
71
+ * Delete a file
72
+ */
73
+ async deleteFile(filePath) {
74
+ try {
75
+ await fs.unlink(filePath);
76
+ }
77
+ catch (error) {
78
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
79
+ // File doesn't exist, ignore
80
+ return;
81
+ }
82
+ throw error;
83
+ }
84
+ }
85
+ /**
86
+ * Rename a file
87
+ */
88
+ async renameFile(oldPath, newPath) {
89
+ await fs.rename(oldPath, newPath);
90
+ }
91
+ /**
92
+ * Get file stats
93
+ */
94
+ async getFileStats(filePath) {
95
+ return fs.stat(filePath);
96
+ }
97
+ /**
98
+ * Calculate MD5 hash of content
99
+ */
100
+ calculateHash(content) {
101
+ return crypto.createHash('md5').update(content).digest('hex');
102
+ }
103
+ /**
104
+ * Watch templates for changes
105
+ */
106
+ async watchTemplates() {
107
+ if (this.watcher) {
108
+ throw new Error('Already watching templates');
109
+ }
110
+ const chokidar = await import('chokidar');
111
+ const templatePath = path.join(this.config.baseDir, this.config.templateDir);
112
+ const watchOptions = {
113
+ ignoreInitial: this.config.watchOptions?.ignoreInitial ?? false,
114
+ ignored: ['**/!(*.sql)'],
115
+ persistent: true,
116
+ awaitWriteFinish: {
117
+ stabilityThreshold: this.config.watchOptions?.stabilityThreshold ?? 200,
118
+ pollInterval: this.config.watchOptions?.pollInterval ?? 100,
119
+ },
120
+ };
121
+ this.watcher = chokidar.watch(templatePath, watchOptions);
122
+ // Handle initial files if not ignoring
123
+ if (!watchOptions.ignoreInitial) {
124
+ const existingFiles = await this.findTemplates();
125
+ for (const file of existingFiles) {
126
+ this.emitWatchEvent('added', file);
127
+ }
128
+ }
129
+ // Set up event handlers with debouncing
130
+ this.watcher
131
+ .on('add', (filepath) => {
132
+ if (path.extname(filepath) === '.sql') {
133
+ this.debouncedEmit('added', filepath);
134
+ }
135
+ })
136
+ .on('change', (filepath) => {
137
+ if (path.extname(filepath) === '.sql') {
138
+ this.debouncedEmit('changed', filepath);
139
+ }
140
+ })
141
+ .on('unlink', (filepath) => {
142
+ if (path.extname(filepath) === '.sql') {
143
+ this.debouncedEmit('removed', filepath);
144
+ }
145
+ })
146
+ .on('error', (error) => {
147
+ this.emit('error', error instanceof Error ? error : new Error(String(error)));
148
+ });
149
+ }
150
+ /**
151
+ * Stop watching templates
152
+ */
153
+ async stopWatching() {
154
+ // Clear any pending debounced handlers
155
+ for (const timer of this.debouncedHandlers.values()) {
156
+ clearTimeout(timer);
157
+ }
158
+ this.debouncedHandlers.clear();
159
+ if (this.watcher) {
160
+ await this.watcher.close();
161
+ this.watcher = null;
162
+ }
163
+ }
164
+ /**
165
+ * Emit watch event with debouncing
166
+ */
167
+ debouncedEmit(type, filepath) {
168
+ const key = `${type}:${filepath}`;
169
+ // Clear existing timer for this event
170
+ const existingTimer = this.debouncedHandlers.get(key);
171
+ if (existingTimer) {
172
+ clearTimeout(existingTimer);
173
+ }
174
+ // Set new timer
175
+ const timer = setTimeout(() => {
176
+ this.emitWatchEvent(type, filepath);
177
+ this.debouncedHandlers.delete(key);
178
+ }, 100);
179
+ this.debouncedHandlers.set(key, timer);
180
+ }
181
+ /**
182
+ * Emit a watch event
183
+ */
184
+ emitWatchEvent(type, filepath) {
185
+ const relativePath = path.relative(this.config.baseDir, filepath);
186
+ const name = path.basename(filepath, '.sql');
187
+ const event = {
188
+ type,
189
+ path: filepath,
190
+ relativePath,
191
+ name,
192
+ };
193
+ // Emit specific event types
194
+ switch (type) {
195
+ case 'added':
196
+ this.emit('template:added', event);
197
+ break;
198
+ case 'changed':
199
+ this.emit('template:changed', event);
200
+ break;
201
+ case 'removed':
202
+ this.emit('template:removed', event);
203
+ break;
204
+ }
205
+ // Also emit generic event
206
+ this.emit('template:event', event);
207
+ }
208
+ /**
209
+ * Clean up resources
210
+ */
211
+ async dispose() {
212
+ await this.stopWatching();
213
+ this.removeAllListeners();
214
+ }
215
+ /**
216
+ * Get migration file path for a template
217
+ */
218
+ getMigrationPath(templateName, timestamp) {
219
+ const migrationName = `${timestamp}_${templateName}.sql`;
220
+ return path.join(this.config.baseDir, this.config.migrationDir, migrationName);
221
+ }
222
+ /**
223
+ * List all migration files
224
+ */
225
+ async listMigrations() {
226
+ const migrationPath = path.join(this.config.baseDir, this.config.migrationDir, '*.sql');
227
+ const matches = await glob(migrationPath);
228
+ return matches.sort(); // Ensure chronological order
229
+ }
230
+ /**
231
+ * Read a migration file
232
+ */
233
+ async readMigration(migrationPath) {
234
+ return fs.readFile(migrationPath, 'utf-8');
235
+ }
236
+ }
237
+ //# sourceMappingURL=FileSystemService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileSystemService.js","sourceRoot":"","sources":["../../src/services/FileSystemService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * MigrationBuilder Service - Generates Supabase migration files from templates
3
+ * Pure service that takes template content and metadata and produces formatted migration files
4
+ */
5
+ import type { BuildLog, CLIConfig } from '../types.js';
6
+ export interface TemplateMetadata {
7
+ name: string;
8
+ templatePath: string;
9
+ relativePath: string;
10
+ content: string;
11
+ hash: string;
12
+ lastBuildAt?: string;
13
+ }
14
+ export interface MigrationOptions {
15
+ force?: boolean;
16
+ wrapInTransaction?: boolean;
17
+ bundleMode?: boolean;
18
+ templateName?: string;
19
+ }
20
+ export interface MigrationResult {
21
+ fileName: string;
22
+ filePath: string;
23
+ content: string;
24
+ timestamp: string;
25
+ }
26
+ export interface BundleMigrationResult {
27
+ fileName: string;
28
+ filePath: string;
29
+ content: string;
30
+ timestamp: string;
31
+ includedTemplates: string[];
32
+ }
33
+ export interface MigrationBuilderConfig {
34
+ baseDir: string;
35
+ templateDir: string;
36
+ migrationDir: string;
37
+ migrationPrefix?: string;
38
+ banner?: string;
39
+ footer?: string;
40
+ wrapInTransaction?: boolean;
41
+ }
42
+ export declare class MigrationBuilder {
43
+ private config;
44
+ constructor(config: MigrationBuilderConfig);
45
+ /**
46
+ * Generate a migration file from a single template
47
+ */
48
+ generateMigration(template: TemplateMetadata, buildLog: BuildLog, options?: MigrationOptions): Promise<MigrationResult>;
49
+ /**
50
+ * Generate a bundled migration file from multiple templates
51
+ */
52
+ generateBundledMigration(templates: TemplateMetadata[], buildLog: BuildLog, options?: MigrationOptions): Promise<BundleMigrationResult>;
53
+ /**
54
+ * Format migration content with headers, footers, and transaction wrapping
55
+ */
56
+ private formatMigrationContent;
57
+ /**
58
+ * Create MigrationBuilder from CLI config
59
+ */
60
+ static fromConfig(config: CLIConfig, baseDir: string): MigrationBuilder;
61
+ /**
62
+ * Generate migration file path for a template
63
+ */
64
+ getMigrationPath(templateName: string, timestamp: string): string;
65
+ /**
66
+ * Generate absolute migration file path for a template
67
+ */
68
+ getAbsoluteMigrationPath(templateName: string, timestamp: string): string;
69
+ /**
70
+ * Validate migration configuration
71
+ */
72
+ validateConfig(): {
73
+ valid: boolean;
74
+ errors: string[];
75
+ };
76
+ /**
77
+ * Write migration file to disk
78
+ */
79
+ writeMigration(migrationResult: MigrationResult): Promise<string>;
80
+ /**
81
+ * Write bundled migration file to disk
82
+ */
83
+ writeBundledMigration(migrationResult: BundleMigrationResult): Promise<string>;
84
+ /**
85
+ * Generate and write migration file in one operation
86
+ */
87
+ generateAndWriteMigration(template: TemplateMetadata, buildLog: BuildLog, options?: MigrationOptions): Promise<{
88
+ result: MigrationResult;
89
+ filePath: string;
90
+ }>;
91
+ /**
92
+ * Generate and write bundled migration file in one operation
93
+ */
94
+ generateAndWriteBundledMigration(templates: TemplateMetadata[], buildLog: BuildLog, options?: MigrationOptions): Promise<{
95
+ result: BundleMigrationResult;
96
+ filePath: string;
97
+ }>;
98
+ /**
99
+ * Check if migration file already exists
100
+ */
101
+ migrationExists(fileName: string): Promise<boolean>;
102
+ /**
103
+ * Get current configuration
104
+ */
105
+ getConfig(): Readonly<MigrationBuilderConfig>;
106
+ }
@@ -0,0 +1,193 @@
1
+ /**
2
+ * MigrationBuilder Service - Generates Supabase migration files from templates
3
+ * Pure service that takes template content and metadata and produces formatted migration files
4
+ */
5
+ import fs from 'node:fs/promises';
6
+ import path from 'node:path';
7
+ import { getNextTimestamp } from '../utils/getNextTimestamp.js';
8
+ export class MigrationBuilder {
9
+ config;
10
+ constructor(config) {
11
+ this.config = {
12
+ migrationPrefix: '',
13
+ banner: '',
14
+ footer: '',
15
+ wrapInTransaction: true,
16
+ ...config,
17
+ };
18
+ }
19
+ /**
20
+ * Generate a migration file from a single template
21
+ */
22
+ async generateMigration(template, buildLog, options = {}) {
23
+ const timestamp = await getNextTimestamp(buildLog);
24
+ const prefix = this.config.migrationPrefix ? `${this.config.migrationPrefix}-` : '';
25
+ const fileName = `${timestamp}_${prefix}${template.name}.sql`;
26
+ const filePath = path.join(this.config.migrationDir, fileName);
27
+ const content = this.formatMigrationContent(template, {
28
+ isBundled: false,
29
+ ...options,
30
+ });
31
+ return {
32
+ fileName,
33
+ filePath,
34
+ content,
35
+ timestamp,
36
+ };
37
+ }
38
+ /**
39
+ * Generate a bundled migration file from multiple templates
40
+ */
41
+ async generateBundledMigration(templates, buildLog, options = {}) {
42
+ const timestamp = await getNextTimestamp(buildLog);
43
+ const prefix = this.config.migrationPrefix ? `${this.config.migrationPrefix}-` : '';
44
+ const fileName = `${timestamp}_${prefix}bundle.sql`;
45
+ const filePath = path.join(this.config.migrationDir, fileName);
46
+ let content = '';
47
+ const includedTemplates = [];
48
+ for (const template of templates) {
49
+ const templateContent = this.formatMigrationContent(template, {
50
+ isBundled: true,
51
+ ...options,
52
+ });
53
+ content += `${templateContent}\n\n`;
54
+ includedTemplates.push(template.name);
55
+ }
56
+ return {
57
+ fileName,
58
+ filePath,
59
+ content: content.trim(),
60
+ timestamp,
61
+ includedTemplates,
62
+ };
63
+ }
64
+ /**
65
+ * Format migration content with headers, footers, and transaction wrapping
66
+ */
67
+ formatMigrationContent(template, options = {}) {
68
+ const { isBundled = false, wrapInTransaction = this.config.wrapInTransaction } = options;
69
+ // Generate header
70
+ const headerPrefix = isBundled ? 'Template' : 'Generated with srtd from template';
71
+ const header = `-- ${headerPrefix}: ${this.config.templateDir}/${template.name}.sql\n`;
72
+ // Generate banner
73
+ const banner = this.config.banner ? `-- ${this.config.banner}\n` : '\n';
74
+ // Generate footer
75
+ const lastBuildInfo = template.lastBuildAt || 'Never';
76
+ const footerText = this.config.footer ? `${this.config.footer}\n` : '';
77
+ const footer = `${footerText}-- Last built: ${lastBuildInfo}\n-- Built with https://github.com/t1mmen/srtd\n`;
78
+ // Wrap content in transaction if needed
79
+ const safeContent = wrapInTransaction
80
+ ? `BEGIN;\n\n${template.content}\n\nCOMMIT;`
81
+ : template.content;
82
+ // Assemble final content
83
+ return `${header}${banner}\n${safeContent}\n${footer}`;
84
+ }
85
+ /**
86
+ * Create MigrationBuilder from CLI config
87
+ */
88
+ static fromConfig(config, baseDir) {
89
+ return new MigrationBuilder({
90
+ baseDir,
91
+ templateDir: config.templateDir,
92
+ migrationDir: config.migrationDir,
93
+ migrationPrefix: config.migrationPrefix,
94
+ banner: config.banner,
95
+ footer: config.footer,
96
+ wrapInTransaction: config.wrapInTransaction,
97
+ });
98
+ }
99
+ /**
100
+ * Generate migration file path for a template
101
+ */
102
+ getMigrationPath(templateName, timestamp) {
103
+ const prefix = this.config.migrationPrefix ? `${this.config.migrationPrefix}-` : '';
104
+ const fileName = `${timestamp}_${prefix}${templateName}.sql`;
105
+ return path.join(this.config.migrationDir, fileName);
106
+ }
107
+ /**
108
+ * Generate absolute migration file path for a template
109
+ */
110
+ getAbsoluteMigrationPath(templateName, timestamp) {
111
+ const migrationPath = this.getMigrationPath(templateName, timestamp);
112
+ return path.resolve(this.config.baseDir, migrationPath);
113
+ }
114
+ /**
115
+ * Validate migration configuration
116
+ */
117
+ validateConfig() {
118
+ const errors = [];
119
+ if (!this.config.baseDir) {
120
+ errors.push('baseDir is required');
121
+ }
122
+ if (!this.config.templateDir) {
123
+ errors.push('templateDir is required');
124
+ }
125
+ if (!this.config.migrationDir) {
126
+ errors.push('migrationDir is required');
127
+ }
128
+ return {
129
+ valid: errors.length === 0,
130
+ errors,
131
+ };
132
+ }
133
+ /**
134
+ * Write migration file to disk
135
+ */
136
+ async writeMigration(migrationResult) {
137
+ const fullPath = path.resolve(this.config.baseDir, migrationResult.filePath);
138
+ const directory = path.dirname(fullPath);
139
+ // Ensure migration directory exists
140
+ await fs.mkdir(directory, { recursive: true });
141
+ // Write migration file
142
+ await fs.writeFile(fullPath, migrationResult.content, 'utf-8');
143
+ return fullPath;
144
+ }
145
+ /**
146
+ * Write bundled migration file to disk
147
+ */
148
+ async writeBundledMigration(migrationResult) {
149
+ const fullPath = path.resolve(this.config.baseDir, migrationResult.filePath);
150
+ const directory = path.dirname(fullPath);
151
+ // Ensure migration directory exists
152
+ await fs.mkdir(directory, { recursive: true });
153
+ // Write bundled migration file
154
+ await fs.writeFile(fullPath, migrationResult.content, 'utf-8');
155
+ return fullPath;
156
+ }
157
+ /**
158
+ * Generate and write migration file in one operation
159
+ */
160
+ async generateAndWriteMigration(template, buildLog, options = {}) {
161
+ const result = await this.generateMigration(template, buildLog, options);
162
+ const filePath = await this.writeMigration(result);
163
+ return { result, filePath };
164
+ }
165
+ /**
166
+ * Generate and write bundled migration file in one operation
167
+ */
168
+ async generateAndWriteBundledMigration(templates, buildLog, options = {}) {
169
+ const result = await this.generateBundledMigration(templates, buildLog, options);
170
+ const filePath = await this.writeBundledMigration(result);
171
+ return { result, filePath };
172
+ }
173
+ /**
174
+ * Check if migration file already exists
175
+ */
176
+ async migrationExists(fileName) {
177
+ const fullPath = path.resolve(this.config.baseDir, this.config.migrationDir, fileName);
178
+ try {
179
+ await fs.access(fullPath);
180
+ return true;
181
+ }
182
+ catch {
183
+ return false;
184
+ }
185
+ }
186
+ /**
187
+ * Get current configuration
188
+ */
189
+ getConfig() {
190
+ return { ...this.config };
191
+ }
192
+ }
193
+ //# sourceMappingURL=MigrationBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrationBuilder.js","sourceRoot":"","sources":["../../src/services/MigrationBuilder.ts"],"names":[],"mappings":"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"}