@keak/sdk 1.0.1
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/README.md +131 -0
- package/dist/Conversion.d.ts +13 -0
- package/dist/Conversion.d.ts.map +1 -0
- package/dist/KeakToolbarShadow.d.ts +21 -0
- package/dist/KeakToolbarShadow.d.ts.map +1 -0
- package/dist/components/ui/card.d.ts +9 -0
- package/dist/components/ui/card.d.ts.map +1 -0
- package/dist/components/ui/html-preview.d.ts +9 -0
- package/dist/components/ui/html-preview.d.ts.map +1 -0
- package/dist/components/ui/simple-tabs.d.ts +26 -0
- package/dist/components/ui/simple-tabs.d.ts.map +1 -0
- package/dist/components/ui/spinner.d.ts +6 -0
- package/dist/components/ui/spinner.d.ts.map +1 -0
- package/dist/components/ui/tabs.d.ts +13 -0
- package/dist/components/ui/tabs.d.ts.map +1 -0
- package/dist/components/ui/textarea.d.ts +6 -0
- package/dist/components/ui/textarea.d.ts.map +1 -0
- package/dist/index.cjs.js +17407 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17395 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/sourceInjector.d.ts +2 -0
- package/dist/runtime/sourceInjector.d.ts.map +1 -0
- package/dist/scripts/sourcePathInjection.d.ts +11 -0
- package/dist/scripts/sourcePathInjection.d.ts.map +1 -0
- package/dist/services/index.d.ts +7 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/telemetry/index.d.ts +20 -0
- package/dist/services/telemetry/index.d.ts.map +1 -0
- package/dist/services/telemetry/telemetryService.d.ts +66 -0
- package/dist/services/telemetry/telemetryService.d.ts.map +1 -0
- package/dist/services/telemetry/types.d.ts +64 -0
- package/dist/services/telemetry/types.d.ts.map +1 -0
- package/dist/toolbar/AIPromptPanel.d.ts +9 -0
- package/dist/toolbar/AIPromptPanel.d.ts.map +1 -0
- package/dist/toolbar/ElementSelector.d.ts +8 -0
- package/dist/toolbar/ElementSelector.d.ts.map +1 -0
- package/dist/toolbar/ExperimentPanel.d.ts +9 -0
- package/dist/toolbar/ExperimentPanel.d.ts.map +1 -0
- package/dist/toolbar/KeakToolbar.d.ts +10 -0
- package/dist/toolbar/KeakToolbar.d.ts.map +1 -0
- package/dist/toolbar/MetricsPanel.d.ts +7 -0
- package/dist/toolbar/MetricsPanel.d.ts.map +1 -0
- package/dist/toolbar/PageScanPanel.d.ts +15 -0
- package/dist/toolbar/PageScanPanel.d.ts.map +1 -0
- package/dist/toolbar/components/PrimaryButton.d.ts +12 -0
- package/dist/toolbar/components/PrimaryButton.d.ts.map +1 -0
- package/dist/toolbar/components/WarningButton.d.ts +12 -0
- package/dist/toolbar/components/WarningButton.d.ts.map +1 -0
- package/dist/toolbar/components/icons/index.d.ts +13 -0
- package/dist/toolbar/components/icons/index.d.ts.map +1 -0
- package/dist/toolbar/components/ui/Badge.d.ts +10 -0
- package/dist/toolbar/components/ui/Badge.d.ts.map +1 -0
- package/dist/toolbar/components/ui/Button.d.ts +12 -0
- package/dist/toolbar/components/ui/Button.d.ts.map +1 -0
- package/dist/toolbar/components/ui/Progress.d.ts +5 -0
- package/dist/toolbar/components/ui/Progress.d.ts.map +1 -0
- package/dist/toolbar/components/ui/Tabs.d.ts +44 -0
- package/dist/toolbar/components/ui/Tabs.d.ts.map +1 -0
- package/dist/toolbar/components/ui/dropdown-menu.d.ts +28 -0
- package/dist/toolbar/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/toolbar/lib/utils.d.ts +3 -0
- package/dist/toolbar/lib/utils.d.ts.map +1 -0
- package/dist/toolbar/utils/fiberSource.d.ts +64 -0
- package/dist/toolbar/utils/fiberSource.d.ts.map +1 -0
- package/dist/toolbar/utils/keakCodeClient.d.ts +104 -0
- package/dist/toolbar/utils/keakCodeClient.d.ts.map +1 -0
- package/dist/toolbar.css +1 -0
- package/dist/toolbar.js +1257 -0
- package/dist/toolbar.js.map +1 -0
- package/dist/utils/generateElementId.d.ts +44 -0
- package/dist/utils/generateElementId.d.ts.map +1 -0
- package/dist/utils/injectDataId.d.ts +33 -0
- package/dist/utils/injectDataId.d.ts.map +1 -0
- package/package.json +152 -0
- package/src/cli/ai-helper.js +206 -0
- package/src/cli/code-transformer.js +354 -0
- package/src/cli/conversion-detector.js +716 -0
- package/src/cli/framework-config.js +477 -0
- package/src/cli/install.js +618 -0
- package/src/cli/keak-setup.js +43 -0
- package/src/cli/revert-conversions.js +264 -0
- package/src/cli/safe-transformer.js +456 -0
- package/src/cli/simple-transformer.js +339 -0
- package/src/plugins/README.md +131 -0
- package/src/plugins/babel-source-inject.cjs +170 -0
- package/src/plugins/next.cjs +145 -0
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Framework Configuration Manager
|
|
5
|
+
*
|
|
6
|
+
* This module handles framework-specific configurations needed for Keak to work properly.
|
|
7
|
+
* Specifically, it sets up Babel transforms to preserve React source information in Fiber nodes.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import fs from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
|
|
13
|
+
// ANSI color codes
|
|
14
|
+
const colors = {
|
|
15
|
+
reset: '\x1b[0m',
|
|
16
|
+
bright: '\x1b[1m',
|
|
17
|
+
green: '\x1b[32m',
|
|
18
|
+
yellow: '\x1b[33m',
|
|
19
|
+
blue: '\x1b[34m',
|
|
20
|
+
cyan: '\x1b[36m',
|
|
21
|
+
red: '\x1b[31m',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export class FrameworkConfigManager {
|
|
25
|
+
constructor(projectRoot) {
|
|
26
|
+
this.projectRoot = projectRoot;
|
|
27
|
+
this.packageJsonPath = path.join(projectRoot, 'package.json');
|
|
28
|
+
this.framework = null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Detect the framework being used
|
|
33
|
+
*/
|
|
34
|
+
detectFramework() {
|
|
35
|
+
if (!fs.existsSync(this.packageJsonPath)) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const packageJson = JSON.parse(fs.readFileSync(this.packageJsonPath, 'utf-8'));
|
|
40
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
41
|
+
|
|
42
|
+
if (deps['next']) {
|
|
43
|
+
this.framework = 'nextjs';
|
|
44
|
+
return 'nextjs';
|
|
45
|
+
} else if (deps['vite'] && deps['react']) {
|
|
46
|
+
this.framework = 'vite';
|
|
47
|
+
return 'vite';
|
|
48
|
+
} else if (deps['react-scripts']) {
|
|
49
|
+
this.framework = 'cra';
|
|
50
|
+
return 'cra';
|
|
51
|
+
} else if (deps['gatsby']) {
|
|
52
|
+
this.framework = 'gatsby';
|
|
53
|
+
return 'gatsby';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Setup Babel configuration for the detected framework
|
|
61
|
+
*/
|
|
62
|
+
async setupBabelConfig() {
|
|
63
|
+
const framework = this.detectFramework();
|
|
64
|
+
|
|
65
|
+
if (!framework) {
|
|
66
|
+
console.log(`${colors.yellow}⚠️ Could not detect framework, skipping Babel setup${colors.reset}`);
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.log(`${colors.blue}🔧 Setting up Babel configuration for ${framework}...${colors.reset}`);
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
switch (framework) {
|
|
74
|
+
case 'nextjs':
|
|
75
|
+
return await this.setupNextJsConfig();
|
|
76
|
+
case 'vite':
|
|
77
|
+
return await this.setupViteConfig();
|
|
78
|
+
case 'cra':
|
|
79
|
+
return await this.setupCRAConfig();
|
|
80
|
+
case 'gatsby':
|
|
81
|
+
return await this.setupGatsbyConfig();
|
|
82
|
+
default:
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error(`${colors.red}❌ Failed to setup Babel config: ${error.message}${colors.reset}`);
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Check if project is using Turbopack
|
|
93
|
+
*/
|
|
94
|
+
isTurbopackEnabled() {
|
|
95
|
+
const packageJson = JSON.parse(fs.readFileSync(this.packageJsonPath, 'utf-8'));
|
|
96
|
+
const devScript = packageJson.scripts?.dev || '';
|
|
97
|
+
return devScript.includes('--turbopack') || devScript.includes('turbo');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Setup Next.js configuration
|
|
102
|
+
*/
|
|
103
|
+
async setupNextJsConfig() {
|
|
104
|
+
const nextConfigPath = path.join(this.projectRoot, 'next.config.js');
|
|
105
|
+
const babelrcPath = path.join(this.projectRoot, '.babelrc');
|
|
106
|
+
const packageJsonPath = this.packageJsonPath;
|
|
107
|
+
|
|
108
|
+
// Check if using Turbopack
|
|
109
|
+
if (this.isTurbopackEnabled()) {
|
|
110
|
+
console.log(`${colors.yellow}⚠️ Turbopack detected - disabling for Keak compatibility${colors.reset}`);
|
|
111
|
+
|
|
112
|
+
// Update package.json to remove --turbopack flag
|
|
113
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
114
|
+
if (packageJson.scripts?.dev) {
|
|
115
|
+
// Create backup dev:turbo script
|
|
116
|
+
packageJson.scripts['dev:turbo'] = packageJson.scripts.dev;
|
|
117
|
+
// Remove --turbopack flag from dev script
|
|
118
|
+
packageJson.scripts.dev = packageJson.scripts.dev.replace(/--turbopack\s*/g, '').replace(/\s+/g, ' ').trim();
|
|
119
|
+
|
|
120
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
121
|
+
console.log(`${colors.green}✅ Updated package.json (saved turbo script as 'dev:turbo')${colors.reset}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Check if babel dependencies are installed
|
|
126
|
+
const hasRequiredDeps = await this.ensureBabelDependencies([
|
|
127
|
+
'@babel/plugin-transform-react-jsx-source',
|
|
128
|
+
'babel-loader',
|
|
129
|
+
'@babel/runtime'
|
|
130
|
+
]);
|
|
131
|
+
|
|
132
|
+
if (!hasRequiredDeps) {
|
|
133
|
+
console.log(`${colors.yellow}⚠️ Installing required Babel dependencies...${colors.reset}`);
|
|
134
|
+
await this.installBabelDependencies([
|
|
135
|
+
'@babel/plugin-transform-react-jsx-source',
|
|
136
|
+
'babel-loader',
|
|
137
|
+
'@babel/runtime'
|
|
138
|
+
]);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Create or update .babelrc
|
|
142
|
+
const babelConfig = {
|
|
143
|
+
presets: ['next/babel'],
|
|
144
|
+
env: {
|
|
145
|
+
development: {
|
|
146
|
+
plugins: ['@babel/plugin-transform-react-jsx-source']
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
fs.writeFileSync(babelrcPath, JSON.stringify(babelConfig, null, 2));
|
|
152
|
+
console.log(`${colors.green}✅ Created .babelrc${colors.reset}`);
|
|
153
|
+
|
|
154
|
+
// Update next.config.js
|
|
155
|
+
if (fs.existsSync(nextConfigPath)) {
|
|
156
|
+
const content = fs.readFileSync(nextConfigPath, 'utf-8');
|
|
157
|
+
|
|
158
|
+
// Check if already configured
|
|
159
|
+
if (content.includes('babel-loader') && content.includes('react-jsx-source')) {
|
|
160
|
+
console.log(`${colors.green}✅ Next.js already configured${colors.reset}`);
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Backup original config
|
|
165
|
+
fs.writeFileSync(`${nextConfigPath}.backup`, content);
|
|
166
|
+
console.log(`${colors.cyan}📋 Backed up next.config.js${colors.reset}`);
|
|
167
|
+
|
|
168
|
+
// Add webpack configuration
|
|
169
|
+
const updatedConfig = this.injectNextJsWebpackConfig(content);
|
|
170
|
+
fs.writeFileSync(nextConfigPath, updatedConfig);
|
|
171
|
+
console.log(`${colors.green}✅ Updated next.config.js${colors.reset}`);
|
|
172
|
+
} else {
|
|
173
|
+
// Create new next.config.js
|
|
174
|
+
const newConfig = this.generateNextJsConfig();
|
|
175
|
+
fs.writeFileSync(nextConfigPath, newConfig);
|
|
176
|
+
console.log(`${colors.green}✅ Created next.config.js${colors.reset}`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Inject webpack configuration into existing Next.js config
|
|
184
|
+
*/
|
|
185
|
+
injectNextJsWebpackConfig(content) {
|
|
186
|
+
// Check if webpack config already exists
|
|
187
|
+
if (content.includes('webpack:')) {
|
|
188
|
+
console.log(`${colors.yellow}⚠️ Webpack config already exists, please manually add Babel loader${colors.reset}`);
|
|
189
|
+
return content;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Find the nextConfig object
|
|
193
|
+
const configMatch = content.match(/(const\s+nextConfig\s*=\s*{)([\s\S]*?)(}\s*;?\s*(?:module\.exports|export default))/);
|
|
194
|
+
|
|
195
|
+
if (!configMatch) {
|
|
196
|
+
console.log(`${colors.yellow}⚠️ Could not parse next.config.js, please configure manually${colors.reset}`);
|
|
197
|
+
return content;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const webpackConfig = `
|
|
201
|
+
// Configure webpack to preserve React debug information (added by Keak)
|
|
202
|
+
webpack: (config, { dev }) => {
|
|
203
|
+
if (dev) {
|
|
204
|
+
// Disable minification in development
|
|
205
|
+
config.optimization = {
|
|
206
|
+
...config.optimization,
|
|
207
|
+
minimize: false,
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// Enable source maps
|
|
211
|
+
config.devtool = 'cheap-module-source-map';
|
|
212
|
+
|
|
213
|
+
// Add babel-loader for JSX files to inject __source
|
|
214
|
+
config.module.rules.push({
|
|
215
|
+
test: /\\.(jsx|tsx)$/,
|
|
216
|
+
exclude: /node_modules/,
|
|
217
|
+
use: {
|
|
218
|
+
loader: 'babel-loader',
|
|
219
|
+
options: {
|
|
220
|
+
presets: ['next/babel'],
|
|
221
|
+
plugins: ['@babel/plugin-transform-react-jsx-source'],
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
return config;
|
|
227
|
+
},`;
|
|
228
|
+
|
|
229
|
+
// Insert webpack config before the closing brace
|
|
230
|
+
return content.replace(
|
|
231
|
+
configMatch[0],
|
|
232
|
+
`${configMatch[1]}${configMatch[2]}${webpackConfig}\n${configMatch[3]}`
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Generate a new Next.js config file
|
|
238
|
+
*/
|
|
239
|
+
generateNextJsConfig() {
|
|
240
|
+
return `/** @type {import('next').NextConfig} */
|
|
241
|
+
const nextConfig = {
|
|
242
|
+
reactStrictMode: true,
|
|
243
|
+
|
|
244
|
+
// Configure webpack to preserve React debug information (added by Keak)
|
|
245
|
+
webpack: (config, { dev }) => {
|
|
246
|
+
if (dev) {
|
|
247
|
+
// Disable minification in development
|
|
248
|
+
config.optimization = {
|
|
249
|
+
...config.optimization,
|
|
250
|
+
minimize: false,
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
// Enable source maps
|
|
254
|
+
config.devtool = 'cheap-module-source-map';
|
|
255
|
+
|
|
256
|
+
// Add babel-loader for JSX files to inject __source
|
|
257
|
+
config.module.rules.push({
|
|
258
|
+
test: /\\.(jsx|tsx)$/,
|
|
259
|
+
exclude: /node_modules/,
|
|
260
|
+
use: {
|
|
261
|
+
loader: 'babel-loader',
|
|
262
|
+
options: {
|
|
263
|
+
presets: ['next/babel'],
|
|
264
|
+
plugins: ['@babel/plugin-transform-react-jsx-source'],
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
return config;
|
|
270
|
+
},
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
module.exports = nextConfig;
|
|
274
|
+
`;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Setup Vite configuration
|
|
279
|
+
*/
|
|
280
|
+
async setupViteConfig() {
|
|
281
|
+
const viteConfigPaths = [
|
|
282
|
+
path.join(this.projectRoot, 'vite.config.ts'),
|
|
283
|
+
path.join(this.projectRoot, 'vite.config.js'),
|
|
284
|
+
];
|
|
285
|
+
|
|
286
|
+
const existingConfig = viteConfigPaths.find(p => fs.existsSync(p));
|
|
287
|
+
|
|
288
|
+
// Install required dependencies
|
|
289
|
+
await this.installBabelDependencies(['@vitejs/plugin-react']);
|
|
290
|
+
|
|
291
|
+
if (existingConfig) {
|
|
292
|
+
const content = fs.readFileSync(existingConfig, 'utf-8');
|
|
293
|
+
|
|
294
|
+
// Check if already configured
|
|
295
|
+
if (content.includes('jsxDev: true') || content.includes('@vitejs/plugin-react')) {
|
|
296
|
+
console.log(`${colors.green}✅ Vite already configured${colors.reset}`);
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Backup and update
|
|
301
|
+
fs.writeFileSync(`${existingConfig}.backup`, content);
|
|
302
|
+
const updated = this.updateViteConfig(content);
|
|
303
|
+
fs.writeFileSync(existingConfig, updated);
|
|
304
|
+
console.log(`${colors.green}✅ Updated ${path.basename(existingConfig)}${colors.reset}`);
|
|
305
|
+
} else {
|
|
306
|
+
// Create new config
|
|
307
|
+
const newConfig = this.generateViteConfig();
|
|
308
|
+
fs.writeFileSync(viteConfigPaths[0], newConfig);
|
|
309
|
+
console.log(`${colors.green}✅ Created vite.config.ts${colors.reset}`);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Update existing Vite config
|
|
317
|
+
*/
|
|
318
|
+
updateViteConfig(content) {
|
|
319
|
+
// Add React plugin with development mode options
|
|
320
|
+
if (!content.includes('@vitejs/plugin-react')) {
|
|
321
|
+
// Add import
|
|
322
|
+
const importLine = "import react from '@vitejs/plugin-react';\n";
|
|
323
|
+
const importIndex = content.indexOf('import');
|
|
324
|
+
content = importIndex >= 0
|
|
325
|
+
? content.slice(0, importIndex) + importLine + content.slice(importIndex)
|
|
326
|
+
: importLine + content;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Update plugins array
|
|
330
|
+
if (content.includes('plugins:')) {
|
|
331
|
+
content = content.replace(
|
|
332
|
+
/plugins:\s*\[([\s\S]*?)\]/,
|
|
333
|
+
`plugins: [react({ jsxDev: true })$1]`
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return content;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Generate new Vite config
|
|
342
|
+
*/
|
|
343
|
+
generateViteConfig() {
|
|
344
|
+
return `import { defineConfig } from 'vite';
|
|
345
|
+
import react from '@vitejs/plugin-react';
|
|
346
|
+
|
|
347
|
+
export default defineConfig({
|
|
348
|
+
plugins: [
|
|
349
|
+
react({
|
|
350
|
+
// Enable development mode JSX transform (preserves __source)
|
|
351
|
+
jsxDev: true,
|
|
352
|
+
}),
|
|
353
|
+
],
|
|
354
|
+
});
|
|
355
|
+
`;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Setup Create React App configuration
|
|
360
|
+
*/
|
|
361
|
+
async setupCRAConfig() {
|
|
362
|
+
console.log(`${colors.yellow}⚠️ Create React App uses CRACO or react-app-rewired for config overrides${colors.reset}`);
|
|
363
|
+
console.log(`${colors.cyan}ℹ️ React source information is enabled by default in CRA dev mode${colors.reset}`);
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Setup Gatsby configuration
|
|
369
|
+
*/
|
|
370
|
+
async setupGatsbyConfig() {
|
|
371
|
+
const gatsbyConfigPath = path.join(this.projectRoot, 'gatsby-config.js');
|
|
372
|
+
|
|
373
|
+
console.log(`${colors.cyan}ℹ️ Gatsby enables React source information by default in development${colors.reset}`);
|
|
374
|
+
|
|
375
|
+
if (fs.existsSync(gatsbyConfigPath)) {
|
|
376
|
+
console.log(`${colors.green}✅ Gatsby config found${colors.reset}`);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
return true;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Check if Babel dependencies are installed
|
|
384
|
+
*/
|
|
385
|
+
async ensureBabelDependencies(deps) {
|
|
386
|
+
if (!fs.existsSync(this.packageJsonPath)) {
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const packageJson = JSON.parse(fs.readFileSync(this.packageJsonPath, 'utf-8'));
|
|
391
|
+
const allDeps = {
|
|
392
|
+
...packageJson.dependencies,
|
|
393
|
+
...packageJson.devDependencies,
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
return deps.every(dep => dep in allDeps);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Install Babel dependencies
|
|
401
|
+
*/
|
|
402
|
+
async installBabelDependencies(deps) {
|
|
403
|
+
const { execSync } = await import('child_process');
|
|
404
|
+
|
|
405
|
+
console.log(`${colors.blue}📦 Installing: ${deps.join(', ')}...${colors.reset}`);
|
|
406
|
+
|
|
407
|
+
try {
|
|
408
|
+
// Detect package manager
|
|
409
|
+
const hasYarn = fs.existsSync(path.join(this.projectRoot, 'yarn.lock'));
|
|
410
|
+
const hasPnpm = fs.existsSync(path.join(this.projectRoot, 'pnpm-lock.yaml'));
|
|
411
|
+
|
|
412
|
+
let installCmd;
|
|
413
|
+
if (hasPnpm) {
|
|
414
|
+
installCmd = `pnpm add -D ${deps.join(' ')}`;
|
|
415
|
+
} else if (hasYarn) {
|
|
416
|
+
installCmd = `yarn add -D ${deps.join(' ')}`;
|
|
417
|
+
} else {
|
|
418
|
+
installCmd = `npm install --save-dev ${deps.join(' ')}`;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
execSync(installCmd, {
|
|
422
|
+
cwd: this.projectRoot,
|
|
423
|
+
stdio: 'inherit'
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
console.log(`${colors.green}✅ Dependencies installed${colors.reset}`);
|
|
427
|
+
return true;
|
|
428
|
+
} catch (error) {
|
|
429
|
+
console.error(`${colors.red}❌ Failed to install dependencies: ${error.message}${colors.reset}`);
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Show manual configuration instructions
|
|
436
|
+
*/
|
|
437
|
+
showManualInstructions() {
|
|
438
|
+
const instructions = {
|
|
439
|
+
nextjs: `
|
|
440
|
+
${colors.cyan}Next.js Manual Configuration:${colors.reset}
|
|
441
|
+
|
|
442
|
+
1. Install dependencies:
|
|
443
|
+
npm install --save-dev @babel/plugin-transform-react-jsx-source babel-loader
|
|
444
|
+
|
|
445
|
+
2. Create .babelrc:
|
|
446
|
+
{
|
|
447
|
+
"presets": ["next/babel"],
|
|
448
|
+
"env": {
|
|
449
|
+
"development": {
|
|
450
|
+
"plugins": ["@babel/plugin-transform-react-jsx-source"]
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
3. Update next.config.js - add webpack config to preserve React source info
|
|
456
|
+
See: https://docs.keak.dev/setup/nextjs
|
|
457
|
+
`,
|
|
458
|
+
vite: `
|
|
459
|
+
${colors.cyan}Vite Manual Configuration:${colors.reset}
|
|
460
|
+
|
|
461
|
+
1. Install plugin:
|
|
462
|
+
npm install --save-dev @vitejs/plugin-react
|
|
463
|
+
|
|
464
|
+
2. Update vite.config.ts:
|
|
465
|
+
import react from '@vitejs/plugin-react';
|
|
466
|
+
|
|
467
|
+
export default defineConfig({
|
|
468
|
+
plugins: [react({ jsxDev: true })]
|
|
469
|
+
});
|
|
470
|
+
`,
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
console.log(instructions[this.framework] || '');
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
export default FrameworkConfigManager;
|