@famgia/omnify 1.0.96 → 1.0.99

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@famgia/omnify",
3
- "version": "1.0.96",
3
+ "version": "1.0.99",
4
4
  "description": "Schema-driven database migration system with TypeScript types and Laravel migrations",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -25,14 +25,14 @@
25
25
  "README.md"
26
26
  ],
27
27
  "dependencies": {
28
- "@famgia/omnify-cli": "0.0.92",
29
- "@famgia/omnify-core": "0.0.86",
30
- "@famgia/omnify-laravel": "0.0.95",
31
- "@famgia/omnify-types": "0.0.84",
32
- "@famgia/omnify-atlas": "0.0.80",
33
- "@famgia/omnify-mcp": "0.0.72",
34
- "@famgia/omnify-typescript": "0.0.74",
35
- "@famgia/omnify-japan": "0.0.79"
28
+ "@famgia/omnify-cli": "0.0.95",
29
+ "@famgia/omnify-core": "0.0.89",
30
+ "@famgia/omnify-types": "0.0.87",
31
+ "@famgia/omnify-typescript": "0.0.77",
32
+ "@famgia/omnify-laravel": "0.0.98",
33
+ "@famgia/omnify-atlas": "0.0.83",
34
+ "@famgia/omnify-mcp": "0.0.75",
35
+ "@famgia/omnify-japan": "0.0.82"
36
36
  },
37
37
  "keywords": [
38
38
  "omnify",
@@ -58,6 +58,205 @@ Commands:
58
58
  // Helper Functions
59
59
  // ============================================================================
60
60
 
61
+ /**
62
+ * Reads omnify.config.ts and extracts the TypeScript output path.
63
+ * Returns null if not found or on error.
64
+ */
65
+ function getOmnifyTypescriptPath(projectRoot) {
66
+ const configPaths = [
67
+ path.join(projectRoot, 'omnify.config.ts'),
68
+ path.join(projectRoot, 'omnify.config.js'),
69
+ ];
70
+
71
+ for (const configPath of configPaths) {
72
+ if (!fs.existsSync(configPath)) continue;
73
+
74
+ try {
75
+ const content = fs.readFileSync(configPath, 'utf-8');
76
+ // Simple regex to extract typescript.path
77
+ const match = content.match(/typescript\s*:\s*\{[^}]*path\s*:\s*['"]([^'"]+)['"]/);
78
+ if (match) {
79
+ return match[1].replace(/^\.\//, ''); // Remove leading ./
80
+ }
81
+ } catch { /* ignore */ }
82
+ }
83
+
84
+ return null;
85
+ }
86
+
87
+ /**
88
+ * Parse tsconfig.json content (handling comments)
89
+ */
90
+ function parseTsconfig(content) {
91
+ // Remove single-line comments only (block comments can conflict with paths like @/*)
92
+ const jsonContent = content
93
+ .split('\n')
94
+ .map(line => {
95
+ const commentIdx = line.indexOf('//');
96
+ if (commentIdx === -1) return line;
97
+ // Simple check: if there's an odd number of quotes before //, it's inside a string
98
+ const beforeComment = line.slice(0, commentIdx);
99
+ const quoteCount = (beforeComment.match(/"/g) || []).length;
100
+ return quoteCount % 2 === 0 ? beforeComment : line;
101
+ })
102
+ .join('\n');
103
+ return JSON.parse(jsonContent);
104
+ }
105
+
106
+ /**
107
+ * Update a single tsconfig.json with @omnify alias
108
+ */
109
+ function updateTsconfigWithAlias(tsconfigPath, aliasPath) {
110
+ try {
111
+ const content = fs.readFileSync(tsconfigPath, 'utf-8');
112
+ const tsconfig = parseTsconfig(content);
113
+
114
+ // Initialize compilerOptions if not present
115
+ if (!tsconfig.compilerOptions) {
116
+ tsconfig.compilerOptions = {};
117
+ }
118
+
119
+ // Initialize paths if not present
120
+ if (!tsconfig.compilerOptions.paths) {
121
+ tsconfig.compilerOptions.paths = {};
122
+ }
123
+
124
+ // Check if @omnify alias already exists
125
+ if (tsconfig.compilerOptions.paths['@omnify/*']) {
126
+ return false; // Already configured
127
+ }
128
+
129
+ // Add @omnify alias
130
+ tsconfig.compilerOptions.paths['@omnify/*'] = [`${aliasPath}/*`];
131
+
132
+ // Ensure baseUrl is set (required for paths to work)
133
+ if (!tsconfig.compilerOptions.baseUrl) {
134
+ tsconfig.compilerOptions.baseUrl = '.';
135
+ }
136
+
137
+ // Write back with proper formatting
138
+ fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n');
139
+ return true;
140
+ } catch {
141
+ return false;
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Setup @omnify alias in tsconfig.json files
147
+ * Handles monorepo structures by finding tsconfig in the same directory tree as omnifyPath
148
+ */
149
+ function setupTsconfigAlias(projectRoot, omnifyPath) {
150
+ const updated = [];
151
+
152
+ // Normalize omnify path (e.g., "./frontend/src/omnify" → "frontend/src/omnify")
153
+ const normalizedPath = omnifyPath.replace(/^\.\//, '');
154
+
155
+ // Find the directory containing omnify output
156
+ const omnifyDir = path.dirname(normalizedPath);
157
+
158
+ // Strategy: Look for tsconfig.json in:
159
+ // 1. Same directory as omnify output (e.g., frontend/src/tsconfig.json)
160
+ // 2. Parent directories up to the package root (e.g., frontend/tsconfig.json)
161
+ // 3. Project root (e.g., ./tsconfig.json)
162
+
163
+ const searchDirs = [];
164
+ let currentDir = omnifyDir;
165
+ while (currentDir && currentDir !== '.') {
166
+ searchDirs.push(currentDir);
167
+ currentDir = path.dirname(currentDir);
168
+ }
169
+ searchDirs.push('.'); // Add project root
170
+
171
+ for (const dir of searchDirs) {
172
+ const tsconfigPath = path.join(projectRoot, dir, 'tsconfig.json');
173
+ if (!fs.existsSync(tsconfigPath)) continue;
174
+
175
+ // Calculate relative path from tsconfig location to omnify
176
+ let relativePath;
177
+ if (dir === '.') {
178
+ relativePath = normalizedPath;
179
+ } else {
180
+ // Get relative path from tsconfig dir to omnify dir
181
+ relativePath = path.relative(dir, normalizedPath);
182
+ }
183
+
184
+ if (updateTsconfigWithAlias(tsconfigPath, relativePath)) {
185
+ updated.push(path.join(dir, 'tsconfig.json'));
186
+ }
187
+ }
188
+
189
+ return updated;
190
+ }
191
+
192
+ /**
193
+ * Setup @omnify alias in vite.config.ts
194
+ */
195
+ function setupViteAlias(projectRoot, omnifyPath) {
196
+ const vitePaths = [
197
+ path.join(projectRoot, 'vite.config.ts'),
198
+ path.join(projectRoot, 'vite.config.js'),
199
+ path.join(projectRoot, 'vite.config.mts'),
200
+ ];
201
+
202
+ const viteConfigPath = vitePaths.find(p => fs.existsSync(p));
203
+ if (!viteConfigPath) return false;
204
+
205
+ try {
206
+ let content = fs.readFileSync(viteConfigPath, 'utf-8');
207
+
208
+ // Check if @omnify alias already exists
209
+ if (content.includes('@omnify')) {
210
+ return false; // Already configured
211
+ }
212
+
213
+ // Check if resolve.alias exists
214
+ if (content.includes('resolve:') && content.includes('alias:')) {
215
+ // Add to existing alias object
216
+ const aliasMatch = content.match(/(alias\s*:\s*\{)/);
217
+ if (aliasMatch) {
218
+ const insertPos = content.indexOf(aliasMatch[0]) + aliasMatch[0].length;
219
+ const aliasLine = `\n '@omnify': path.resolve(__dirname, '${omnifyPath}'),`;
220
+ content = content.slice(0, insertPos) + aliasLine + content.slice(insertPos);
221
+ }
222
+ } else if (content.includes('resolve:')) {
223
+ // Add alias to existing resolve object
224
+ const resolveMatch = content.match(/(resolve\s*:\s*\{)/);
225
+ if (resolveMatch) {
226
+ const insertPos = content.indexOf(resolveMatch[0]) + resolveMatch[0].length;
227
+ const aliasBlock = `\n alias: {\n '@omnify': path.resolve(__dirname, '${omnifyPath}'),\n },`;
228
+ content = content.slice(0, insertPos) + aliasBlock + content.slice(insertPos);
229
+ }
230
+ } else {
231
+ // Add resolve.alias to defineConfig
232
+ const defineConfigMatch = content.match(/(defineConfig\s*\(\s*\{)/);
233
+ if (defineConfigMatch) {
234
+ const insertPos = content.indexOf(defineConfigMatch[0]) + defineConfigMatch[0].length;
235
+ const resolveBlock = `\n resolve: {\n alias: {\n '@omnify': path.resolve(__dirname, '${omnifyPath}'),\n },\n },`;
236
+ content = content.slice(0, insertPos) + resolveBlock + content.slice(insertPos);
237
+ }
238
+ }
239
+
240
+ // Add path import if not present
241
+ if (!content.includes("import path from") && !content.includes("import * as path from") && !content.includes("const path = require")) {
242
+ if (content.startsWith('import ')) {
243
+ content = `import path from 'path';\n` + content;
244
+ } else {
245
+ // Find first import and add before it
246
+ const firstImport = content.indexOf('import ');
247
+ if (firstImport !== -1) {
248
+ content = content.slice(0, firstImport) + `import path from 'path';\n` + content.slice(firstImport);
249
+ }
250
+ }
251
+ }
252
+
253
+ fs.writeFileSync(viteConfigPath, content);
254
+ return true;
255
+ } catch {
256
+ return false;
257
+ }
258
+ }
259
+
61
260
  function findProjectRoot() {
62
261
  let dir = process.env.INIT_CWD || process.cwd();
63
262
  const idx = dir.indexOf('node_modules');
@@ -264,6 +463,22 @@ function main() {
264
463
 
265
464
  setupClaudeMcp();
266
465
 
466
+ // Setup @omnify alias in config files
467
+ const omnifyPath = getOmnifyTypescriptPath(projectRoot) || 'src/omnify';
468
+
469
+ try {
470
+ const updatedTsconfigs = setupTsconfigAlias(projectRoot, omnifyPath);
471
+ for (const file of updatedTsconfigs) {
472
+ results.push(`✓ Added @omnify alias to ${file}`);
473
+ }
474
+ } catch { /* ignore */ }
475
+
476
+ try {
477
+ if (setupViteAlias(projectRoot, omnifyPath)) {
478
+ results.push(`✓ Added @omnify alias to vite.config`);
479
+ }
480
+ } catch { /* ignore */ }
481
+
267
482
  for (const r of results) console.log(` ${r}`);
268
483
  console.log('\n✅ Omnify setup complete!\n');
269
484
  }