viewgate-wrapper 1.11.13 ā 1.11.14
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 +28 -9
- package/dist/cli.js +30 -0
- package/dist/components/ViewGateOverlay.d.ts.map +1 -1
- package/dist/components/ViewGateProvider.d.ts +7 -0
- package/dist/components/ViewGateProvider.d.ts.map +1 -1
- package/dist/plugin/babel-plugin-viewgate.d.ts +12 -0
- package/dist/plugin/babel-plugin-viewgate.d.ts.map +1 -0
- package/dist/plugin/babel-plugin-viewgate.js +27 -0
- package/dist/plugin/config-injectors.d.ts +8 -0
- package/dist/plugin/config-injectors.d.ts.map +1 -0
- package/dist/plugin/config-injectors.js +104 -0
- package/dist/plugin/next-loader.d.ts.map +1 -1
- package/dist/plugin/next-loader.js +2 -9
- package/dist/plugin/transform-logic.d.ts.map +1 -1
- package/dist/plugin/transform-logic.js +12 -2
- package/dist/plugin/webpack-loader.d.ts +2 -0
- package/dist/plugin/webpack-loader.d.ts.map +1 -0
- package/dist/plugin/webpack-loader.js +9 -0
- package/dist/viewgate-wrapper.js +1406 -1372
- package/dist/viewgate-wrapper.umd.cjs +8 -8
- package/package.json +8 -3
package/README.md
CHANGED
|
@@ -11,39 +11,58 @@ npm install viewgate-wrapper
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
## š
|
|
14
|
+
## š Precision Mapping (New)
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
ViewGate features a **Hybrid Precision Strategy** to ensure AI-driven code changes are 100% accurate.
|
|
17
17
|
|
|
18
|
-
### ā” Vite
|
|
19
|
-
Add
|
|
18
|
+
### ā” Vite (Recommended)
|
|
19
|
+
Add it to `vite.config.ts`. Injects stable `data-vg-id` attributes.
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
import { viewgatePlugin } from 'viewgate-wrapper';
|
|
23
23
|
|
|
24
24
|
export default defineConfig({
|
|
25
25
|
plugins: [
|
|
26
|
-
|
|
26
|
+
react(),
|
|
27
27
|
viewgatePlugin()
|
|
28
28
|
]
|
|
29
29
|
});
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
###
|
|
33
|
-
Add the
|
|
32
|
+
### š¦ Webpack (Next.js, CRA, Custom)
|
|
33
|
+
Add the loader to your `webpack.config.js` or `next.config.js`:
|
|
34
34
|
|
|
35
35
|
```javascript
|
|
36
|
+
// next.config.js or webpack.config.js
|
|
36
37
|
module.exports = {
|
|
37
38
|
webpack: (config) => {
|
|
38
39
|
config.module.rules.push({
|
|
39
40
|
test: /\.(tsx|jsx)$/,
|
|
40
|
-
|
|
41
|
+
exclude: /node_modules/,
|
|
42
|
+
use: [{ loader: 'viewgate-wrapper/dist/plugin/webpack-loader' }],
|
|
41
43
|
});
|
|
42
44
|
return config;
|
|
43
45
|
},
|
|
44
46
|
};
|
|
45
47
|
```
|
|
46
|
-
|
|
48
|
+
|
|
49
|
+
### š Babel (Universal)
|
|
50
|
+
If you are using a custom Babel setup (e.g., with `@babel/preset-react`), add the plugin to your `.babelrc` or `babel.config.js`:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"plugins": ["viewgate-wrapper/dist/plugin/babel-plugin-viewgate"]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### āļø Zero-Config React (Fiber Fallback)
|
|
59
|
+
If you can't use a build-time plugin, ViewGate automatically uses **React Fiber Detection** in development.
|
|
60
|
+
- **Precision**: High (Line/Column level).
|
|
61
|
+
- **Setup**: None. Works out of the box by inspecting the React tree.
|
|
62
|
+
- **Heuristics**: Uses **Semantic Fingerprinting** (Tag + ARIA + Roles + Hierarchy) as a safety net.
|
|
63
|
+
|
|
64
|
+
> [!IMPORTANT]
|
|
65
|
+
> To achieve "Surgical Precision", we recommend using a build-time plugin (Vite, Webpack, or Babel) whenever possible.
|
|
47
66
|
|
|
48
67
|
---
|
|
49
68
|
|
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ import fs from 'fs';
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import os from 'os';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
|
+
import { detectFramework, injectVitePlugin, injectNextPlugin } from './plugin/config-injectors.js';
|
|
6
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
7
8
|
const __dirname = path.dirname(__filename);
|
|
8
9
|
async function setup() {
|
|
@@ -44,6 +45,35 @@ async function setup() {
|
|
|
44
45
|
console.log(` ${configPath}`);
|
|
45
46
|
console.log(' Puedes encontrar tu API_KEY en el Dashboard de ViewGate.');
|
|
46
47
|
}
|
|
48
|
+
// 4. Framework Detection and Plugin Auto-Config
|
|
49
|
+
console.log('\nš Detecting framework for High-Precision Mapping...');
|
|
50
|
+
const cwd = process.cwd();
|
|
51
|
+
const result = detectFramework(cwd);
|
|
52
|
+
if (result.framework === 'vite' && result.configPath) {
|
|
53
|
+
console.log(`⨠Vite detected! Attempting to apply viewgatePlugin to: ${path.basename(result.configPath)}`);
|
|
54
|
+
if (injectVitePlugin(result.configPath)) {
|
|
55
|
+
console.log('ā
viewgatePlugin applied successfully!');
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
console.log('ā ļø Could not auto-apply plugin. Please follow manual setup in README.');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if (result.framework === 'next' && result.configPath) {
|
|
62
|
+
console.log(`⨠Next.js detected! Attempting to apply webpack loader to: ${path.basename(result.configPath)}`);
|
|
63
|
+
if (injectNextPlugin(result.configPath)) {
|
|
64
|
+
console.log('ā
next-loader applied successfully!');
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.log('ā ļø Could not auto-apply plugin. Please follow manual setup in README.');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (result.framework !== 'unknown') {
|
|
71
|
+
console.log(`⨠${result.framework.toUpperCase()} detected!`);
|
|
72
|
+
console.log(`š Please follow the manual setup for ${result.framework} in the README to enable High-Precision mapping.`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.log('ā Could not determine framework. High-Precision mapping might require manual setup.');
|
|
76
|
+
}
|
|
47
77
|
}
|
|
48
78
|
catch (error) {
|
|
49
79
|
console.error(`ā Error updating configuration: ${error.message}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewGateOverlay.d.ts","sourceRoot":"","sources":["../../src/components/ViewGateOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAwBnF,OAAO,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"ViewGateOverlay.d.ts","sourceRoot":"","sources":["../../src/components/ViewGateOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqD,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAwBnF,OAAO,wBAAwB,CAAC;AA21BhC,eAAO,MAAM,eAAe,EAAE,EAkvE7B,CAAC"}
|
|
@@ -135,9 +135,15 @@ export interface SemanticReference {
|
|
|
135
135
|
parentContext: string;
|
|
136
136
|
componentPath?: string;
|
|
137
137
|
vgPath?: string;
|
|
138
|
+
vgId?: string | undefined;
|
|
138
139
|
signature?: string;
|
|
139
140
|
source?: string;
|
|
140
141
|
attributes?: Record<string, string>;
|
|
142
|
+
confidence?: {
|
|
143
|
+
vgId: number;
|
|
144
|
+
fiber: number;
|
|
145
|
+
fingerprint: number;
|
|
146
|
+
} | undefined;
|
|
141
147
|
normalizedOffset?: {
|
|
142
148
|
x: number;
|
|
143
149
|
y: number;
|
|
@@ -161,6 +167,7 @@ export interface SemanticReference {
|
|
|
161
167
|
text: string;
|
|
162
168
|
role?: string | undefined;
|
|
163
169
|
type?: string | undefined;
|
|
170
|
+
location?: string | undefined;
|
|
164
171
|
} | undefined;
|
|
165
172
|
siblings?: Array<{
|
|
166
173
|
tag: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ViewGateProvider.d.ts","sourceRoot":"","sources":["../../src/components/ViewGateProvider.tsx"],"names":[],"mappings":"AACA,OAAO,EAA0D,KAAK,SAAS,EAAE,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAIxG,OAAO,wBAAwB,CAAC;AAEhC,MAAM,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnC,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2HjB,CAAC;AAQF,MAAM,WAAW,iBAAiB;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,gBAAgB,CAAC,EAAE;QACf,CAAC,EAAE,MAAM,CAAC;QACV,CAAC,EAAE,MAAM,CAAC;KACb,CAAC;IACF,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,SAAS,CAAC,EAAE;QACR,MAAM,EAAE;YACJ,GAAG,EAAE,MAAM,CAAC;YACZ,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;YAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;YAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;SACjC,CAAC;QACF,MAAM,CAAC,EAAE;YACL,GAAG,EAAE,MAAM,CAAC;YACZ,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;YAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"ViewGateProvider.d.ts","sourceRoot":"","sources":["../../src/components/ViewGateProvider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Babel plugin to inject source mapping attributes.
|
|
3
|
+
* Since we want to keep logic at the source level consistent,
|
|
4
|
+
* this plugin uses the same transformSourcePaths logic.
|
|
5
|
+
*/
|
|
6
|
+
export default function babelPluginViewGate(): {
|
|
7
|
+
name: string;
|
|
8
|
+
visitor: {
|
|
9
|
+
Program(path: any, state: any): void;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=babel-plugin-viewgate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"babel-plugin-viewgate.d.ts","sourceRoot":"","sources":["../../src/plugin/babel-plugin-viewgate.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,mBAAmB;;;sBAIjB,GAAG,SAAS,GAAG;;EAexC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// src/plugin/babel-plugin-viewgate.ts
|
|
2
|
+
import { transformSourcePaths } from './transform-logic.js';
|
|
3
|
+
/**
|
|
4
|
+
* Babel plugin to inject source mapping attributes.
|
|
5
|
+
* Since we want to keep logic at the source level consistent,
|
|
6
|
+
* this plugin uses the same transformSourcePaths logic.
|
|
7
|
+
*/
|
|
8
|
+
export default function babelPluginViewGate() {
|
|
9
|
+
return {
|
|
10
|
+
name: 'babel-plugin-viewgate',
|
|
11
|
+
visitor: {
|
|
12
|
+
Program(path, state) {
|
|
13
|
+
const filePath = state.file.opts.filename;
|
|
14
|
+
if (!filePath || filePath.includes('node_modules'))
|
|
15
|
+
return;
|
|
16
|
+
if (!filePath.endsWith('.tsx') && !filePath.endsWith('.jsx'))
|
|
17
|
+
return;
|
|
18
|
+
const code = state.file.code;
|
|
19
|
+
const transformed = transformSourcePaths(code, filePath, process.cwd());
|
|
20
|
+
// Note: Re-parsing would be safer but more complex.
|
|
21
|
+
// For now, if we are in Babel, we can replace the entire content or
|
|
22
|
+
// use AST manipulation. Since we already have transformSourcePaths
|
|
23
|
+
// which is regex-based, we'll keep it simple for consistency.
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface DetectionResult {
|
|
2
|
+
framework: 'vite' | 'next' | 'webpack' | 'babel' | 'unknown';
|
|
3
|
+
configPath: string | undefined;
|
|
4
|
+
}
|
|
5
|
+
export declare function detectFramework(cwd: string): DetectionResult;
|
|
6
|
+
export declare function injectVitePlugin(configPath: string): boolean;
|
|
7
|
+
export declare function injectNextPlugin(configPath: string): boolean;
|
|
8
|
+
//# sourceMappingURL=config-injectors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-injectors.d.ts","sourceRoot":"","sources":["../../src/plugin/config-injectors.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAC7D,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAwB5D;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAmC5D;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAiD5D"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export function detectFramework(cwd) {
|
|
4
|
+
const files = fs.readdirSync(cwd);
|
|
5
|
+
if (files.includes('vite.config.ts') || files.includes('vite.config.js') || files.includes('vite.config.mjs')) {
|
|
6
|
+
const configPath = files.find(f => f.startsWith('vite.config.'));
|
|
7
|
+
return { framework: 'vite', configPath: configPath ? path.join(cwd, configPath) : undefined };
|
|
8
|
+
}
|
|
9
|
+
if (files.includes('next.config.js') || files.includes('next.config.mjs')) {
|
|
10
|
+
const configPath = files.find(f => f.startsWith('next.config.'));
|
|
11
|
+
return { framework: 'next', configPath: configPath ? path.join(cwd, configPath) : undefined };
|
|
12
|
+
}
|
|
13
|
+
if (files.includes('webpack.config.js') || files.includes('craco.config.js')) {
|
|
14
|
+
const configPath = files.find(f => f.startsWith('webpack.config.') || f.startsWith('craco.config.'));
|
|
15
|
+
return { framework: 'webpack', configPath: configPath ? path.join(cwd, configPath) : undefined };
|
|
16
|
+
}
|
|
17
|
+
if (files.includes('.babelrc') || files.includes('babel.config.js') || files.includes('babel.config.json')) {
|
|
18
|
+
const configPath = files.find(f => f.includes('babel'));
|
|
19
|
+
return { framework: 'babel', configPath: configPath ? path.join(cwd, configPath) : undefined };
|
|
20
|
+
}
|
|
21
|
+
return { framework: 'unknown', configPath: undefined };
|
|
22
|
+
}
|
|
23
|
+
export function injectVitePlugin(configPath) {
|
|
24
|
+
try {
|
|
25
|
+
let content = fs.readFileSync(configPath, 'utf8');
|
|
26
|
+
// 1. Check if already injected
|
|
27
|
+
if (content.includes('viewgatePlugin'))
|
|
28
|
+
return true;
|
|
29
|
+
// 2. Add import (handling both import and require)
|
|
30
|
+
const isTS = configPath.endsWith('.ts');
|
|
31
|
+
const isMJS = configPath.endsWith('.mjs');
|
|
32
|
+
const importStatement = (isTS || isMJS || content.includes('import '))
|
|
33
|
+
? "\nimport viewgatePlugin from 'viewgate-wrapper/vite';\n"
|
|
34
|
+
: "\nconst viewgatePlugin = require('viewgate-wrapper/vite');\n";
|
|
35
|
+
content = importStatement + content;
|
|
36
|
+
// 3. Inject into plugins array
|
|
37
|
+
// Matches: plugins: [ ... ] or plugins: [...]
|
|
38
|
+
const pluginsRegex = /plugins\s*:\s*\[([^\]]*)\]/;
|
|
39
|
+
if (pluginsRegex.test(content)) {
|
|
40
|
+
content = content.replace(pluginsRegex, (match, p1) => {
|
|
41
|
+
const trailingComma = p1.trim() && !p1.trim().endsWith(',') ? ',' : '';
|
|
42
|
+
return `plugins: [\n viewgatePlugin(),${p1}${trailingComma}\n ]`;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
// If no plugins array found, we skip auto-injection to avoid breaking complex configs
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
fs.writeFileSync(configPath, content);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function injectNextPlugin(configPath) {
|
|
57
|
+
try {
|
|
58
|
+
let content = fs.readFileSync(configPath, 'utf8');
|
|
59
|
+
// 1. Check if already injected
|
|
60
|
+
if (content.includes('viewgate-wrapper/next-loader'))
|
|
61
|
+
return true;
|
|
62
|
+
// 2. Find nextConfig object and add webpack property
|
|
63
|
+
// This is a bit more complex, we'll suggest manual setup if it's too nested
|
|
64
|
+
// Simple detection: check if NEXT_PUBLIC_VIEWGATE_API_KEY is mentioned
|
|
65
|
+
const webpackSnippet = `
|
|
66
|
+
webpack: (config) => {
|
|
67
|
+
config.module.rules.push({
|
|
68
|
+
test: /\\.(js|jsx|ts|tsx)$/,
|
|
69
|
+
use: ['viewgate-wrapper/next-loader'],
|
|
70
|
+
});
|
|
71
|
+
return config;
|
|
72
|
+
},`;
|
|
73
|
+
// Try to find the export default or module.exports nextConfig
|
|
74
|
+
if (content.includes('export default nextConfig')) {
|
|
75
|
+
content = content.replace('export default nextConfig', `nextConfig.webpack = (config) => {
|
|
76
|
+
config.module.rules.push({
|
|
77
|
+
test: /\\.(js|jsx|ts|tsx)$/,
|
|
78
|
+
use: ['viewgate-wrapper/next-loader'],
|
|
79
|
+
});
|
|
80
|
+
return config;
|
|
81
|
+
};
|
|
82
|
+
export default nextConfig;`);
|
|
83
|
+
}
|
|
84
|
+
else if (content.includes('module.exports = nextConfig')) {
|
|
85
|
+
content = content.replace('module.exports = nextConfig', `nextConfig.webpack = (config) => {
|
|
86
|
+
config.module.rules.push({
|
|
87
|
+
test: /\\.(js|jsx|ts|tsx)$/,
|
|
88
|
+
use: ['viewgate-wrapper/next-loader'],
|
|
89
|
+
});
|
|
90
|
+
return config;
|
|
91
|
+
};
|
|
92
|
+
module.exports = nextConfig;`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// Too complex to auto-inject reliably
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
fs.writeFileSync(configPath, content);
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"next-loader.d.ts","sourceRoot":"","sources":["../../src/plugin/next-loader.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"next-loader.d.ts","sourceRoot":"","sources":["../../src/plugin/next-loader.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,UAEnE"}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import viewgateWebpackLoader from './webpack-loader.js';
|
|
2
2
|
export default function viewgateNextLoader(source) {
|
|
3
|
-
|
|
4
|
-
if (!id)
|
|
5
|
-
return source;
|
|
6
|
-
// Debug log to ensure loader is running
|
|
7
|
-
if (process.env.NODE_ENV === 'development') {
|
|
8
|
-
// console.log(`[ViewGate] Transforming: ${id}`);
|
|
9
|
-
}
|
|
10
|
-
return transformSourcePaths(source, id, process.cwd());
|
|
3
|
+
return viewgateWebpackLoader.call(this, source);
|
|
11
4
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform-logic.d.ts","sourceRoot":"","sources":["../../src/plugin/transform-logic.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"transform-logic.d.ts","sourceRoot":"","sources":["../../src/plugin/transform-logic.ts"],"names":[],"mappings":"AAAA,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UA8BzE"}
|
|
@@ -5,15 +5,25 @@ export function transformSourcePaths(code, id, cwd) {
|
|
|
5
5
|
return code;
|
|
6
6
|
const normalizePath = (p) => p.replace(/\\/g, '/');
|
|
7
7
|
const relativePath = normalizePath(id).replace(normalizePath(cwd), '');
|
|
8
|
+
// Simpler, faster hash function for performance
|
|
9
|
+
const getHash = (s) => {
|
|
10
|
+
let h = 0;
|
|
11
|
+
for (let i = 0; i < s.length; i++)
|
|
12
|
+
h = (Math.imul(31, h) + s.charCodeAt(i)) | 0;
|
|
13
|
+
return (h >>> 0).toString(16);
|
|
14
|
+
};
|
|
15
|
+
let tagIndex = 0;
|
|
8
16
|
const lines = code.split('\n');
|
|
9
17
|
const transformedLines = lines.map((line, index) => {
|
|
10
18
|
const lineNumber = index + 1;
|
|
11
19
|
// Regex to find JSX tags and inject data-source-path (handles self-closing tags)
|
|
12
20
|
return line.replace(/(^|[^a-zA-Z0-9])<([a-zA-Z][a-zA-Z0-9\.]*)(?=[ \t\n\/\>])/g, (match, prefix, tagName) => {
|
|
13
|
-
if (match.includes('data-source-path') || tagName === 'Fragment' || tagName === 'React.Fragment') {
|
|
21
|
+
if (match.includes('data-source-path') || match.includes('data-vg-id') || tagName === 'Fragment' || tagName === 'React.Fragment') {
|
|
14
22
|
return match;
|
|
15
23
|
}
|
|
16
|
-
|
|
24
|
+
tagIndex++;
|
|
25
|
+
const vgId = getHash(`${relativePath}:${tagName}:${tagIndex}`);
|
|
26
|
+
return `${prefix}<${tagName} data-vg-id="${vgId}" data-source-path="${relativePath}:${lineNumber}"`;
|
|
17
27
|
});
|
|
18
28
|
});
|
|
19
29
|
return transformedLines.join('\n');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webpack-loader.d.ts","sourceRoot":"","sources":["../../src/plugin/webpack-loader.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,UAQtE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { transformSourcePaths } from './transform-logic.js';
|
|
2
|
+
export default function viewgateWebpackLoader(source) {
|
|
3
|
+
const id = this.resourcePath;
|
|
4
|
+
if (!id)
|
|
5
|
+
return source;
|
|
6
|
+
// Support for both Webpack 4 and 5
|
|
7
|
+
const options = this.getOptions ? this.getOptions() : {};
|
|
8
|
+
return transformSourcePaths(source, id, process.cwd());
|
|
9
|
+
}
|