@keak/sdk 1.0.9 → 2.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 +102 -7
- package/dist/Conversion.d.ts.map +1 -1
- package/dist/index.cjs.js +199 -187
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +55 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +201 -187
- package/dist/index.js.map +1 -1
- package/dist/toolbar/KeakToolbar.d.ts.map +1 -1
- package/dist/toolbar.js +41 -0
- package/dist/toolbar.js.map +1 -1
- package/package.json +2 -1
- package/src/cli/ai-helper.js +117 -39
- package/src/cli/install.js +251 -152
- package/src/plugins/babel-source-inject.cjs +55 -131
- package/src/plugins/next.cjs +48 -221
- package/src/plugins/webpack-loader-babel/index.js +43 -117
|
@@ -1,170 +1,94 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Babel
|
|
3
|
-
*
|
|
2
|
+
* Keak Babel Plugin - Source Location Injector
|
|
3
|
+
* Simplified version inspired by react-source-lens
|
|
4
|
+
* Injects data-keak-file and data-keak-line attributes into JSX elements
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
|
-
console.log('[Keak Babel Plugin] MODULE LOADED - This means Babel is requiring this file');
|
|
7
|
-
|
|
8
7
|
const path = require('path');
|
|
9
8
|
|
|
10
|
-
let processedCount = 0;
|
|
11
|
-
|
|
12
9
|
function keakSourceInjectorPlugin({ types: t }) {
|
|
13
|
-
console.log('[Keak Babel Plugin] Plugin function called - Plugin loaded and initialized');
|
|
14
10
|
return {
|
|
15
11
|
name: 'keak-source-injector',
|
|
16
12
|
visitor: {
|
|
17
13
|
Program: {
|
|
18
|
-
enter(
|
|
19
|
-
//
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
enter(programPath, state) {
|
|
15
|
+
// Skip in production builds
|
|
16
|
+
if (process.env.NODE_ENV === 'production' && !state.opts.forceProduction) {
|
|
17
|
+
state.skipFile = true;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
// Skip next/font files (Babel/SWC conflict)
|
|
22
|
+
state.skipFile = false;
|
|
23
|
+
programPath.traverse({
|
|
24
24
|
ImportDeclaration(importPath) {
|
|
25
25
|
const source = importPath.node.source.value;
|
|
26
26
|
if (source.includes('next/font') || source.includes('@next/font')) {
|
|
27
27
|
state.skipFile = true;
|
|
28
|
-
importPath.stop();
|
|
28
|
+
importPath.stop();
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
});
|
|
32
|
-
},
|
|
33
|
-
exit() {
|
|
34
|
-
if (processedCount > 0) {
|
|
35
|
-
console.log(`[Keak Babel Plugin] Processed ${processedCount} JSX elements`);
|
|
36
|
-
processedCount = 0;
|
|
37
|
-
}
|
|
38
32
|
}
|
|
39
33
|
},
|
|
40
|
-
JSXOpeningElement(nodePath, state) {
|
|
41
|
-
// Skip entire file if it uses next/font (Babel/SWC conflict)
|
|
42
|
-
if (state.skipFile) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
34
|
|
|
46
|
-
|
|
47
|
-
if
|
|
35
|
+
JSXOpeningElement(nodePath, state) {
|
|
36
|
+
// Skip if file should be skipped or no location info
|
|
37
|
+
if (state.skipFile || !nodePath.node.loc) {
|
|
48
38
|
return;
|
|
49
39
|
}
|
|
50
40
|
|
|
51
|
-
// Skip if
|
|
52
|
-
const
|
|
41
|
+
// Skip if already has keak attributes
|
|
42
|
+
const hasKeakAttr = nodePath.node.attributes.some((attr) =>
|
|
53
43
|
t.isJSXAttribute(attr) &&
|
|
54
44
|
t.isJSXIdentifier(attr.name) &&
|
|
55
|
-
attr.name.name === 'data-keak-src'
|
|
45
|
+
(attr.name.name === 'data-keak-file' || attr.name.name === 'data-keak-src')
|
|
56
46
|
);
|
|
57
|
-
|
|
58
|
-
if (existingAttr) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Get source location info
|
|
63
|
-
const loc = nodePath.node.loc;
|
|
64
|
-
if (!loc) return;
|
|
47
|
+
if (hasKeakAttr) return;
|
|
65
48
|
|
|
66
49
|
const filename = state.file.opts.filename;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
tagName = elementName.name;
|
|
90
|
-
} else if (t.isJSXMemberExpression(elementName)) {
|
|
91
|
-
// Handle cases like <motion.div>
|
|
92
|
-
tagName = elementName.property.name;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Only instrument elements we care about
|
|
96
|
-
const targetElements = new Set([
|
|
97
|
-
'div', 'span', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
|
98
|
-
'button', 'a', 'input', 'textarea', 'select', 'form',
|
|
99
|
-
'img', 'svg', 'canvas', 'video', 'audio',
|
|
100
|
-
'section', 'article', 'header', 'footer', 'nav', 'main',
|
|
101
|
-
'ul', 'ol', 'li', 'table', 'tr', 'td', 'th'
|
|
102
|
-
]);
|
|
103
|
-
|
|
104
|
-
// Also instrument custom components (capitalized names)
|
|
105
|
-
const isCustomComponent = tagName && tagName[0] === tagName[0].toUpperCase();
|
|
106
|
-
const isTargetElement = targetElements.has(tagName.toLowerCase());
|
|
107
|
-
|
|
108
|
-
if (!isTargetElement && !isCustomComponent) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Create the data attribute
|
|
113
|
-
const sourceAttr = t.jsxAttribute(
|
|
114
|
-
t.jsxIdentifier('data-keak-src'),
|
|
115
|
-
t.stringLiteral(sourceLocation)
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
// Add component context if available
|
|
119
|
-
let componentName = '';
|
|
120
|
-
let currentPath = nodePath;
|
|
121
|
-
|
|
122
|
-
// Walk up to find the containing component
|
|
123
|
-
while (currentPath) {
|
|
124
|
-
if (currentPath.isFunctionDeclaration() && currentPath.node.id) {
|
|
125
|
-
componentName = currentPath.node.id.name;
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (currentPath.isVariableDeclarator() && t.isIdentifier(currentPath.node.id)) {
|
|
130
|
-
const init = currentPath.node.init;
|
|
131
|
-
if (t.isArrowFunctionExpression(init) || t.isFunctionExpression(init)) {
|
|
132
|
-
componentName = currentPath.node.id.name;
|
|
133
|
-
break;
|
|
50
|
+
if (!filename || typeof filename !== 'string') return;
|
|
51
|
+
|
|
52
|
+
// Smart relative path detection (like react-source-lens)
|
|
53
|
+
let sourceFile;
|
|
54
|
+
|
|
55
|
+
// Try src/ directory first
|
|
56
|
+
const srcParts = filename.split('/src/');
|
|
57
|
+
if (srcParts.length > 1) {
|
|
58
|
+
sourceFile = 'src/' + srcParts[srcParts.length - 1];
|
|
59
|
+
} else {
|
|
60
|
+
// Try app/ directory (Next.js App Router)
|
|
61
|
+
const appParts = filename.split('/app/');
|
|
62
|
+
if (appParts.length > 1) {
|
|
63
|
+
sourceFile = 'app/' + appParts[appParts.length - 1];
|
|
64
|
+
} else {
|
|
65
|
+
// Try components/ directory
|
|
66
|
+
const compParts = filename.split('/components/');
|
|
67
|
+
if (compParts.length > 1) {
|
|
68
|
+
sourceFile = 'components/' + compParts[compParts.length - 1];
|
|
69
|
+
} else {
|
|
70
|
+
// Fallback: relative from cwd
|
|
71
|
+
sourceFile = path.relative(process.cwd(), filename);
|
|
134
72
|
}
|
|
135
73
|
}
|
|
136
|
-
|
|
137
|
-
currentPath = currentPath.parentPath;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Add component context attribute if found
|
|
141
|
-
if (componentName) {
|
|
142
|
-
const componentAttr = t.jsxAttribute(
|
|
143
|
-
t.jsxIdentifier('data-keak-component'),
|
|
144
|
-
t.stringLiteral(componentName)
|
|
145
|
-
);
|
|
146
|
-
nodePath.node.attributes.push(componentAttr);
|
|
147
74
|
}
|
|
148
75
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
t.
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
nodePath.node.attributes.push(indexAttr);
|
|
163
|
-
}
|
|
76
|
+
const { line } = nodePath.node.loc.start;
|
|
77
|
+
|
|
78
|
+
// Add data-keak-file and data-keak-line attributes
|
|
79
|
+
nodePath.node.attributes.push(
|
|
80
|
+
t.jsxAttribute(
|
|
81
|
+
t.jsxIdentifier('data-keak-file'),
|
|
82
|
+
t.stringLiteral(sourceFile)
|
|
83
|
+
),
|
|
84
|
+
t.jsxAttribute(
|
|
85
|
+
t.jsxIdentifier('data-keak-line'),
|
|
86
|
+
t.stringLiteral(String(line))
|
|
87
|
+
)
|
|
88
|
+
);
|
|
164
89
|
}
|
|
165
90
|
}
|
|
166
91
|
};
|
|
167
92
|
}
|
|
168
93
|
|
|
169
94
|
module.exports = keakSourceInjectorPlugin;
|
|
170
|
-
|
package/src/plugins/next.cjs
CHANGED
|
@@ -1,245 +1,73 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Keak Next.js Plugin
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* for use with Keak IDE element selection.
|
|
6
|
-
*
|
|
3
|
+
* Simplified version - injects source location attributes in development only
|
|
4
|
+
*
|
|
7
5
|
* Usage in next.config.js:
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* module.exports = withKeak({
|
|
12
|
-
* // your existing Next.js config
|
|
13
|
-
* });
|
|
14
|
-
*
|
|
15
|
-
* Or for ESM (next.config.mjs):
|
|
16
|
-
*
|
|
17
|
-
* import { withKeak } from '@keak/sdk/plugins/next';
|
|
18
|
-
* export default withKeak({ ... });
|
|
6
|
+
* const { withKeak } = require('@keak/sdk/next');
|
|
7
|
+
* module.exports = withKeak({ ... });
|
|
19
8
|
*/
|
|
20
9
|
|
|
21
10
|
const path = require('path');
|
|
11
|
+
const fs = require('fs');
|
|
22
12
|
|
|
23
13
|
function withKeak(nextConfig = {}) {
|
|
24
|
-
console.log('[Keak] withKeak() called - plugin loaded successfully');
|
|
25
14
|
return {
|
|
26
15
|
...nextConfig,
|
|
27
16
|
webpack(config, options) {
|
|
28
|
-
|
|
29
|
-
const { dev, isServer } = options;
|
|
17
|
+
const { dev } = options;
|
|
30
18
|
|
|
31
|
-
// Only inject in development mode
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
// Only inject loader in development mode
|
|
20
|
+
if (!dev) {
|
|
21
|
+
// Call original webpack config if it exists
|
|
22
|
+
if (typeof nextConfig.webpack === 'function') {
|
|
23
|
+
return nextConfig.webpack(config, options);
|
|
24
|
+
}
|
|
25
|
+
return config;
|
|
26
|
+
}
|
|
36
27
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
paths: [process.cwd()]
|
|
43
|
-
});
|
|
44
|
-
} catch (e) {
|
|
45
|
-
// Fallback to resolving from @keak/sdk's context
|
|
46
|
-
console.warn(`[Keak] Could not resolve ${moduleName} from project, falling back to @keak/sdk`);
|
|
47
|
-
return require.resolve(moduleName);
|
|
48
|
-
}
|
|
49
|
-
};
|
|
28
|
+
// Resolve loader path from project .keak directory or fallback
|
|
29
|
+
const projectKeakLoader = path.resolve(process.cwd(), '.keak/webpack-loader-babel/index.js');
|
|
30
|
+
const keakLoaderPath = fs.existsSync(projectKeakLoader)
|
|
31
|
+
? projectKeakLoader
|
|
32
|
+
: path.resolve(__dirname, 'webpack-loader-babel/index.js');
|
|
50
33
|
|
|
51
|
-
|
|
34
|
+
// Ensure config.module.rules exists
|
|
35
|
+
if (!config.module || !config.module.rules) {
|
|
52
36
|
config.module = config.module || {};
|
|
53
37
|
config.module.rules = config.module.rules || [];
|
|
38
|
+
}
|
|
54
39
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
// Check if loader exists in project .keak directory
|
|
71
|
-
try {
|
|
72
|
-
if (fs.existsSync(projectKeakLoader)) {
|
|
73
|
-
console.log('[Keak] Found loader in project .keak directory');
|
|
74
|
-
keakLoaderPath = projectKeakLoader;
|
|
75
|
-
loaderSource = 'project';
|
|
76
|
-
} else {
|
|
77
|
-
// Fallback to project loader path even if it doesn't exist yet
|
|
78
|
-
console.warn('[Keak] Loader not found, using fallback path:', projectKeakLoader);
|
|
79
|
-
keakLoaderPath = projectKeakLoader;
|
|
80
|
-
loaderSource = 'fallback';
|
|
81
|
-
}
|
|
82
|
-
} catch (pathError) {
|
|
83
|
-
console.error('[Keak] Error resolving loader path:', pathError.message);
|
|
84
|
-
keakLoaderPath = projectKeakLoader;
|
|
85
|
-
loaderSource = 'error';
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
console.log('[Keak] ✅ Loader path resolved:', keakLoaderPath, '(source:', loaderSource, ')');
|
|
89
|
-
console.log('[Keak] About to inspect webpack rules...');
|
|
90
|
-
console.log('[Keak] DEBUG: config exists?', !!config);
|
|
91
|
-
console.log('[Keak] DEBUG: config.module exists?', !!config.module);
|
|
92
|
-
console.log('[Keak] DEBUG: config.module.rules exists?', !!(config.module && config.module.rules));
|
|
93
|
-
console.log('[Keak] DEBUG: config.module.rules is array?', Array.isArray(config.module && config.module.rules));
|
|
94
|
-
|
|
95
|
-
// Wrap everything in try-catch to catch any errors
|
|
96
|
-
try {
|
|
97
|
-
console.log('[Keak] DEBUG: Entering try block');
|
|
98
|
-
console.log('[Keak] DEBUG: config.module exists?', !!config.module);
|
|
99
|
-
console.log('[Keak] DEBUG: config.module.rules exists?', !!(config.module && config.module.rules));
|
|
100
|
-
console.log('[Keak] Total webpack rules:', config.module && config.module.rules ? config.module.rules.length : 'undefined');
|
|
101
|
-
|
|
102
|
-
if (!config.module || !config.module.rules) {
|
|
103
|
-
console.error('[Keak] ❌ ERROR: config.module.rules is undefined!');
|
|
104
|
-
return config;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Log first few rules to understand structure
|
|
108
|
-
try {
|
|
109
|
-
console.log('[Keak] First few rules structure:');
|
|
110
|
-
config.module.rules.slice(0, 5).forEach((r, i) => {
|
|
111
|
-
console.log(`[Keak] Rule ${i}:`, {
|
|
112
|
-
hasOneOf: Array.isArray(r.oneOf),
|
|
113
|
-
oneOfLength: Array.isArray(r.oneOf) ? r.oneOf.length : 'N/A',
|
|
114
|
-
test: r.test ? r.test.toString().substring(0, 50) : 'no test',
|
|
115
|
-
hasUse: !!r.use,
|
|
116
|
-
useType: r.use ? (Array.isArray(r.use) ? 'array' : typeof r.use) : 'none'
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
} catch (e) {
|
|
120
|
-
console.log('[Keak] Error logging rules:', e.message);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Based on Next.js webpack structure: Find the oneOf array and add our loader
|
|
124
|
-
// Next.js uses oneOf arrays to process files - we need to add our loader there
|
|
125
|
-
let loaderAdded = false;
|
|
126
|
-
|
|
127
|
-
console.log('[Keak] Attempting Strategy 1: Finding oneOf rule...');
|
|
128
|
-
// Strategy 1: Find the oneOf rule (recommended approach from web search)
|
|
129
|
-
const oneOfRule = config.module.rules.find((rule) => Array.isArray(rule.oneOf));
|
|
130
|
-
console.log('[Keak] Strategy 1 result:', oneOfRule ? 'Found oneOf rule' : 'No oneOf rule found');
|
|
131
|
-
|
|
132
|
-
if (oneOfRule && oneOfRule.oneOf) {
|
|
133
|
-
console.log(`[Keak] ✅ Found oneOf array with ${oneOfRule.oneOf.length} entries`);
|
|
134
|
-
|
|
135
|
-
// Add our loader to the BEGINNING of oneOf array so it runs BEFORE SWC
|
|
136
|
-
// This transforms raw JSX to inject attributes before compilation
|
|
137
|
-
const preRule = {
|
|
138
|
-
test: /\.[jt]sx?$/,
|
|
139
|
-
exclude: [
|
|
140
|
-
/node_modules/,
|
|
141
|
-
/\.next\//,
|
|
142
|
-
/webpack/,
|
|
143
|
-
/next\/dist/
|
|
144
|
-
// NOTE: Removed /\.server\.[jt]sx?$/ exclusion to process server components
|
|
145
|
-
],
|
|
146
|
-
enforce: 'pre', // Run BEFORE SWC (pre-compilation)
|
|
147
|
-
use: [
|
|
148
|
-
{
|
|
149
|
-
loader: keakLoaderPath,
|
|
150
|
-
options: {
|
|
151
|
-
projectRoot: process.cwd(),
|
|
152
|
-
includeElementIndex: true,
|
|
153
|
-
devWarnings: dev,
|
|
154
|
-
skipPatterns: [
|
|
155
|
-
// NOTE: Removed /(\.server\.[jt]sx?$)/ to process server components
|
|
156
|
-
/webpack/,
|
|
157
|
-
/\.next\//,
|
|
158
|
-
/next\/dist/
|
|
159
|
-
]
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
]
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
// Add to the BEGINNING of oneOf array (runs before SWC processes files)
|
|
166
|
-
oneOfRule.oneOf.unshift(preRule);
|
|
167
|
-
|
|
168
|
-
console.log(`[Keak] ✅ Added pre-compilation loader to oneOf array (now ${oneOfRule.oneOf.length} entries, runs before SWC)`);
|
|
169
|
-
loaderAdded = true;
|
|
170
|
-
} else {
|
|
171
|
-
console.log('[Keak] No oneOf array found, trying alternative approaches...');
|
|
172
|
-
|
|
173
|
-
// Strategy 2: Look for rules with oneOf property (nested)
|
|
174
|
-
for (let i = 0; i < config.module.rules.length; i++) {
|
|
175
|
-
const rule = config.module.rules[i];
|
|
176
|
-
if (rule.oneOf && Array.isArray(rule.oneOf)) {
|
|
177
|
-
console.log(`[Keak] Found oneOf in rule ${i} with ${rule.oneOf.length} entries`);
|
|
178
|
-
|
|
179
|
-
// Add pre-compilation loader to the BEGINNING of this oneOf array
|
|
180
|
-
rule.oneOf.unshift({
|
|
181
|
-
test: /\.[jt]sx?$/,
|
|
182
|
-
exclude: [/node_modules/, /\.next\//, /webpack/, /next\/dist/],
|
|
183
|
-
enforce: 'pre', // Run BEFORE SWC
|
|
184
|
-
use: [
|
|
185
|
-
{
|
|
186
|
-
loader: keakLoaderPath,
|
|
187
|
-
options: {
|
|
188
|
-
projectRoot: process.cwd(),
|
|
189
|
-
includeElementIndex: true,
|
|
190
|
-
devWarnings: dev,
|
|
191
|
-
skipPatterns: [] // Process all files including server components
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
]
|
|
195
|
-
});
|
|
196
|
-
console.log(`[Keak] ✅ Added pre-compilation loader to oneOf array (now ${rule.oneOf.length} entries)`);
|
|
197
|
-
loaderAdded = true;
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
40
|
+
// Create the loader rule
|
|
41
|
+
const keakRule = {
|
|
42
|
+
test: /\.[jt]sx?$/,
|
|
43
|
+
exclude: [
|
|
44
|
+
/node_modules/,
|
|
45
|
+
/\.next\//,
|
|
46
|
+
/webpack/,
|
|
47
|
+
/next\/dist/
|
|
48
|
+
],
|
|
49
|
+
enforce: 'pre', // Run BEFORE SWC compilation
|
|
50
|
+
use: [
|
|
51
|
+
{
|
|
52
|
+
loader: keakLoaderPath,
|
|
53
|
+
options: {
|
|
54
|
+
projectRoot: process.cwd()
|
|
200
55
|
}
|
|
201
56
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
enforce: 'pre', // Run BEFORE SWC
|
|
211
|
-
use: [
|
|
212
|
-
{
|
|
213
|
-
loader: keakLoaderPath,
|
|
214
|
-
options: {
|
|
215
|
-
projectRoot: process.cwd(),
|
|
216
|
-
includeElementIndex: true,
|
|
217
|
-
devWarnings: dev,
|
|
218
|
-
skipPatterns: [] // Process all files including server components
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
]
|
|
222
|
-
});
|
|
223
|
-
console.log('[Keak] ✅ Added pre-compilation loader rule with enforce:pre (fallback)');
|
|
224
|
-
loaderAdded = true;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
if (!loaderAdded) {
|
|
228
|
-
console.error('[Keak] ❌ ERROR: Failed to add loader using any strategy!');
|
|
229
|
-
} else {
|
|
230
|
-
console.log('[Keak] ✅ Loader successfully added to webpack config');
|
|
231
|
-
}
|
|
232
|
-
} catch (error) {
|
|
233
|
-
console.error('[Keak] ❌ ERROR in loader injection block:', error);
|
|
234
|
-
console.error('[Keak] Error message:', error.message);
|
|
235
|
-
console.error('[Keak] Error stack:', error.stack);
|
|
236
|
-
// Don't throw - let webpack continue even if loader injection fails
|
|
237
|
-
}
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
// Try to inject into oneOf array (Next.js standard structure)
|
|
61
|
+
const oneOfRule = config.module.rules.find((rule) => Array.isArray(rule.oneOf));
|
|
62
|
+
if (oneOfRule && oneOfRule.oneOf) {
|
|
63
|
+
// Add to beginning so it runs before SWC
|
|
64
|
+
oneOfRule.oneOf.unshift(keakRule);
|
|
238
65
|
} else {
|
|
239
|
-
|
|
66
|
+
// Fallback: Add as top-level rule with enforce: 'pre'
|
|
67
|
+
config.module.rules.unshift(keakRule);
|
|
240
68
|
}
|
|
241
69
|
|
|
242
|
-
// Call
|
|
70
|
+
// Call original webpack config if it exists
|
|
243
71
|
if (typeof nextConfig.webpack === 'function') {
|
|
244
72
|
return nextConfig.webpack(config, options);
|
|
245
73
|
}
|
|
@@ -250,4 +78,3 @@ function withKeak(nextConfig = {}) {
|
|
|
250
78
|
}
|
|
251
79
|
|
|
252
80
|
module.exports = { withKeak };
|
|
253
|
-
|