@vibexdotnew/inspector 0.0.11 → 0.0.13
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/next/element-tagger.cjs +344 -434
- package/package.json +1 -1
package/next/element-tagger.cjs
CHANGED
|
@@ -1,461 +1,371 @@
|
|
|
1
|
-
|
|
2
1
|
"use strict";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* FlexApp Element Tagger - Turbopack/Webpack Loader
|
|
5
|
+
*
|
|
6
|
+
* Transforms JSX to inject location attributes for visual editing.
|
|
7
|
+
* Injects: data-flex-loc="filepath:line:col" data-flex-name="tagName"
|
|
8
|
+
*
|
|
9
|
+
* SAFE: Never throws errors - returns original source on any failure
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
// Safe imports with fallbacks
|
|
14
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
let parse, MagicString, walk;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
parse = require("@babel/parser").parse;
|
|
20
|
+
} catch {
|
|
21
|
+
parse = null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
MagicString = require("magic-string");
|
|
26
|
+
} catch {
|
|
27
|
+
MagicString = null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// estree-walker v3 is ESM-only, try multiple import strategies
|
|
31
|
+
try {
|
|
32
|
+
walk = require("estree-walker").walk;
|
|
33
|
+
} catch {
|
|
34
|
+
try {
|
|
35
|
+
// Try the sync version
|
|
36
|
+
const mod = require("estree-walker/src/sync.js");
|
|
37
|
+
walk = mod.walk || mod.default?.walk;
|
|
38
|
+
} catch {
|
|
39
|
+
walk = null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
8
43
|
const path = require("path");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"scene",
|
|
18
|
-
"
|
|
19
|
-
"lOD",
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"planeGeometry",
|
|
64
|
-
"latheGeometry",
|
|
65
|
-
"shapeGeometry",
|
|
66
|
-
"extrudeGeometry",
|
|
67
|
-
"edgesGeometry",
|
|
68
|
-
"coneGeometry",
|
|
69
|
-
"cylinderGeometry",
|
|
70
|
-
"circleGeometry",
|
|
71
|
-
"boxGeometry",
|
|
72
|
-
"capsuleGeometry",
|
|
73
|
-
"material",
|
|
74
|
-
"shadowMaterial",
|
|
75
|
-
"spriteMaterial",
|
|
76
|
-
"rawShaderMaterial",
|
|
77
|
-
"shaderMaterial",
|
|
78
|
-
"pointsMaterial",
|
|
79
|
-
"meshPhysicalMaterial",
|
|
80
|
-
"meshStandardMaterial",
|
|
81
|
-
"meshPhongMaterial",
|
|
82
|
-
"meshToonMaterial",
|
|
83
|
-
"meshNormalMaterial",
|
|
84
|
-
"meshLambertMaterial",
|
|
85
|
-
"meshDepthMaterial",
|
|
86
|
-
"meshDistanceMaterial",
|
|
87
|
-
"meshBasicMaterial",
|
|
88
|
-
"meshMatcapMaterial",
|
|
89
|
-
"lineDashedMaterial",
|
|
90
|
-
"lineBasicMaterial",
|
|
91
|
-
"primitive",
|
|
92
|
-
"light",
|
|
93
|
-
"spotLightShadow",
|
|
94
|
-
"spotLight",
|
|
95
|
-
"pointLight",
|
|
96
|
-
"rectAreaLight",
|
|
97
|
-
"hemisphereLight",
|
|
98
|
-
"directionalLightShadow",
|
|
99
|
-
"directionalLight",
|
|
100
|
-
"ambientLight",
|
|
101
|
-
"lightShadow",
|
|
102
|
-
"ambientLightProbe",
|
|
103
|
-
"hemisphereLightProbe",
|
|
104
|
-
"lightProbe",
|
|
105
|
-
"spotLightHelper",
|
|
106
|
-
"skeletonHelper",
|
|
107
|
-
"pointLightHelper",
|
|
108
|
-
"hemisphereLightHelper",
|
|
109
|
-
"gridHelper",
|
|
110
|
-
"polarGridHelper",
|
|
111
|
-
"directionalLightHelper",
|
|
112
|
-
"cameraHelper",
|
|
113
|
-
"boxHelper",
|
|
114
|
-
"box3Helper",
|
|
115
|
-
"planeHelper",
|
|
116
|
-
"arrowHelper",
|
|
117
|
-
"axesHelper",
|
|
118
|
-
"texture",
|
|
119
|
-
"videoTexture",
|
|
120
|
-
"dataTexture",
|
|
121
|
-
"dataTexture3D",
|
|
122
|
-
"compressedTexture",
|
|
123
|
-
"cubeTexture",
|
|
124
|
-
"canvasTexture",
|
|
125
|
-
"depthTexture",
|
|
126
|
-
"raycaster",
|
|
127
|
-
"vector2",
|
|
128
|
-
"vector3",
|
|
129
|
-
"vector4",
|
|
130
|
-
"euler",
|
|
131
|
-
"matrix3",
|
|
132
|
-
"matrix4",
|
|
133
|
-
"quaternion",
|
|
134
|
-
"bufferAttribute",
|
|
135
|
-
"float16BufferAttribute",
|
|
136
|
-
"float32BufferAttribute",
|
|
137
|
-
"float64BufferAttribute",
|
|
138
|
-
"int8BufferAttribute",
|
|
139
|
-
"int16BufferAttribute",
|
|
140
|
-
"int32BufferAttribute",
|
|
141
|
-
"uint8BufferAttribute",
|
|
142
|
-
"uint16BufferAttribute",
|
|
143
|
-
"uint32BufferAttribute",
|
|
144
|
-
"instancedBufferAttribute",
|
|
145
|
-
"color",
|
|
146
|
-
"fog",
|
|
147
|
-
"fogExp2",
|
|
148
|
-
"shape",
|
|
149
|
-
"colorShiftMaterial"
|
|
150
|
-
];
|
|
151
|
-
const dreiElems = [
|
|
152
|
-
"AsciiRenderer",
|
|
153
|
-
"Billboard",
|
|
154
|
-
"Clone",
|
|
155
|
-
"ComputedAttribute",
|
|
156
|
-
"Decal",
|
|
157
|
-
"Edges",
|
|
158
|
-
"Effects",
|
|
159
|
-
"GradientTexture",
|
|
160
|
-
"MarchingCubes",
|
|
161
|
-
"Outlines",
|
|
162
|
-
"PositionalAudio",
|
|
163
|
-
"Sampler",
|
|
164
|
-
"ScreenSizer",
|
|
165
|
-
"ScreenSpace",
|
|
166
|
-
"Splat",
|
|
167
|
-
"Svg",
|
|
168
|
-
"Text",
|
|
169
|
-
"Text3D",
|
|
170
|
-
"Trail",
|
|
171
|
-
"CubeCamera",
|
|
172
|
-
"OrthographicCamera",
|
|
173
|
-
"PerspectiveCamera",
|
|
174
|
-
"CameraControls",
|
|
175
|
-
"FaceControls",
|
|
176
|
-
"KeyboardControls",
|
|
177
|
-
"MotionPathControls",
|
|
178
|
-
"PresentationControls",
|
|
179
|
-
"ScrollControls",
|
|
180
|
-
"DragControls",
|
|
181
|
-
"GizmoHelper",
|
|
182
|
-
"Grid",
|
|
183
|
-
"Helper",
|
|
184
|
-
"PivotControls",
|
|
185
|
-
"TransformControls",
|
|
186
|
-
"CubeTexture",
|
|
187
|
-
"Fbx",
|
|
188
|
-
"Gltf",
|
|
189
|
-
"Ktx2",
|
|
190
|
-
"Loader",
|
|
191
|
-
"Progress",
|
|
192
|
-
"ScreenVideoTexture",
|
|
193
|
-
"Texture",
|
|
194
|
-
"TrailTexture",
|
|
195
|
-
"VideoTexture",
|
|
196
|
-
"WebcamVideoTexture",
|
|
197
|
-
"CycleRaycast",
|
|
198
|
-
"DetectGPU",
|
|
199
|
-
"Example",
|
|
200
|
-
"FaceLandmarker",
|
|
201
|
-
"Fbo",
|
|
202
|
-
"Html",
|
|
203
|
-
"Select",
|
|
204
|
-
"SpriteAnimator",
|
|
205
|
-
"StatsGl",
|
|
206
|
-
"Stats",
|
|
207
|
-
"Trail",
|
|
208
|
-
"Wireframe",
|
|
209
|
-
"CurveModifier",
|
|
210
|
-
"AdaptiveDpr",
|
|
211
|
-
"AdaptiveEvents",
|
|
212
|
-
"BakeShadows",
|
|
213
|
-
"Bvh",
|
|
214
|
-
"Detailed",
|
|
215
|
-
"Instances",
|
|
216
|
-
"Merged",
|
|
217
|
-
"meshBounds",
|
|
218
|
-
"PerformanceMonitor",
|
|
219
|
-
"Points",
|
|
220
|
-
"Preload",
|
|
221
|
-
"Segments",
|
|
222
|
-
"Fisheye",
|
|
223
|
-
"Hud",
|
|
224
|
-
"Mask",
|
|
225
|
-
"MeshPortalMaterial",
|
|
226
|
-
"RenderCubeTexture",
|
|
227
|
-
"RenderTexture",
|
|
228
|
-
"View",
|
|
229
|
-
"MeshDiscardMaterial",
|
|
230
|
-
"MeshDistortMaterial",
|
|
231
|
-
"MeshReflectorMaterial",
|
|
232
|
-
"MeshRefractionMaterial",
|
|
233
|
-
"MeshTransmissionMaterial",
|
|
234
|
-
"MeshWobbleMaterial",
|
|
235
|
-
"PointMaterial",
|
|
236
|
-
"shaderMaterial",
|
|
237
|
-
"SoftShadows",
|
|
238
|
-
"CatmullRomLine",
|
|
239
|
-
"CubicBezierLine",
|
|
240
|
-
"Facemesh",
|
|
241
|
-
"Line",
|
|
242
|
-
"Mesh",
|
|
243
|
-
"QuadraticBezierLine",
|
|
244
|
-
"RoundedBox",
|
|
245
|
-
"ScreenQuad",
|
|
246
|
-
"AccumulativeShadows",
|
|
247
|
-
"Backdrop",
|
|
248
|
-
"BBAnchor",
|
|
249
|
-
"Bounds",
|
|
250
|
-
"CameraShake",
|
|
251
|
-
"Caustics",
|
|
252
|
-
"Center",
|
|
253
|
-
"Cloud",
|
|
254
|
-
"ContactShadows",
|
|
255
|
-
"Environment",
|
|
256
|
-
"Float",
|
|
257
|
-
"Lightformer",
|
|
258
|
-
"MatcapTexture",
|
|
259
|
-
"NormalTexture",
|
|
260
|
-
"RandomizedLight",
|
|
261
|
-
"Resize",
|
|
262
|
-
"ShadowAlpha",
|
|
263
|
-
"Shadow",
|
|
264
|
-
"Sky",
|
|
265
|
-
"Sparkles",
|
|
266
|
-
"SpotLightShadow",
|
|
267
|
-
"SpotLight",
|
|
268
|
-
"Stage",
|
|
269
|
-
"Stars",
|
|
270
|
-
"OrbitControls"
|
|
271
|
-
];
|
|
272
|
-
const shouldTag = (name) => !threeFiberElems.includes(name) && !dreiElems.includes(name);
|
|
273
|
-
// ➕ Collect aliases of the Next.js <Image> component so we can reliably tag it even if it was renamed.
|
|
274
|
-
const isNextImageAlias = (aliases, name) => aliases.has(name);
|
|
275
|
-
const extractLiteralValue = (node) => {
|
|
276
|
-
if (!node)
|
|
277
|
-
return undefined;
|
|
278
|
-
switch (node.type) {
|
|
279
|
-
case 'StringLiteral':
|
|
280
|
-
return node.value;
|
|
281
|
-
case 'NumericLiteral':
|
|
282
|
-
return node.value;
|
|
283
|
-
case 'BooleanLiteral':
|
|
284
|
-
return node.value;
|
|
285
|
-
case 'ObjectExpression':
|
|
286
|
-
const obj = {};
|
|
287
|
-
for (const prop of node.properties) {
|
|
288
|
-
if (prop.type === 'ObjectProperty' && !prop.computed) {
|
|
289
|
-
const key = prop.key.type === 'Identifier' ? prop.key.name : prop.key.value;
|
|
290
|
-
obj[key] = extractLiteralValue(prop.value);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
return obj;
|
|
294
|
-
case 'ArrayExpression':
|
|
295
|
-
return node.elements.map((el) => extractLiteralValue(el));
|
|
296
|
-
default:
|
|
297
|
-
return undefined;
|
|
44
|
+
const fs = require("fs");
|
|
45
|
+
|
|
46
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
47
|
+
// Element Exclusion Lists
|
|
48
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
const EXCLUDED_ELEMENTS = new Set([
|
|
51
|
+
// React Three Fiber primitives
|
|
52
|
+
"primitive", "mesh", "group", "scene", "object3D",
|
|
53
|
+
"camera", "perspectiveCamera", "orthographicCamera", "cubeCamera", "arrayCamera",
|
|
54
|
+
"instancedMesh", "batchedMesh", "skinnedMesh", "sprite", "lOD",
|
|
55
|
+
"lineSegments", "lineLoop", "points", "skeleton", "bone",
|
|
56
|
+
"bufferGeometry", "instancedBufferGeometry",
|
|
57
|
+
"boxGeometry", "sphereGeometry", "planeGeometry", "cylinderGeometry",
|
|
58
|
+
"coneGeometry", "torusGeometry", "torusKnotGeometry", "ringGeometry",
|
|
59
|
+
"circleGeometry", "tubeGeometry", "extrudeGeometry", "latheGeometry",
|
|
60
|
+
"shapeGeometry", "polyhedronGeometry", "icosahedronGeometry",
|
|
61
|
+
"octahedronGeometry", "tetrahedronGeometry", "dodecahedronGeometry",
|
|
62
|
+
"capsuleGeometry", "edgesGeometry", "wireframeGeometry",
|
|
63
|
+
"material", "meshBasicMaterial", "meshStandardMaterial", "meshPhongMaterial",
|
|
64
|
+
"meshLambertMaterial", "meshToonMaterial", "meshNormalMaterial",
|
|
65
|
+
"meshPhysicalMaterial", "meshDepthMaterial", "meshDistanceMaterial",
|
|
66
|
+
"meshMatcapMaterial", "shaderMaterial", "rawShaderMaterial",
|
|
67
|
+
"pointsMaterial", "lineBasicMaterial", "lineDashedMaterial",
|
|
68
|
+
"spriteMaterial", "shadowMaterial",
|
|
69
|
+
"light", "ambientLight", "directionalLight", "pointLight", "spotLight",
|
|
70
|
+
"hemisphereLight", "rectAreaLight", "lightProbe",
|
|
71
|
+
"texture", "videoTexture", "canvasTexture", "cubeTexture",
|
|
72
|
+
"dataTexture", "compressedTexture", "depthTexture",
|
|
73
|
+
"vector2", "vector3", "vector4", "euler", "quaternion",
|
|
74
|
+
"matrix3", "matrix4", "color", "raycaster", "fog", "fogExp2",
|
|
75
|
+
// Drei components
|
|
76
|
+
"Billboard", "Text", "Text3D", "Html", "Trail", "Decal", "Edges", "Outlines",
|
|
77
|
+
"PerspectiveCamera", "OrthographicCamera", "CubeCamera",
|
|
78
|
+
"OrbitControls", "CameraControls", "TransformControls", "PivotControls",
|
|
79
|
+
"Environment", "Sky", "Stars", "Cloud", "Sparkles", "Float", "Stage",
|
|
80
|
+
"RoundedBox", "Line", "Points", "Instances", "Merged",
|
|
81
|
+
"MeshReflectorMaterial", "MeshTransmissionMaterial", "shaderMaterial",
|
|
82
|
+
]);
|
|
83
|
+
|
|
84
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
85
|
+
// Simple AST Walker (fallback if estree-walker fails)
|
|
86
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
function simpleWalk(node, callbacks, parent = null) {
|
|
89
|
+
if (!node || typeof node !== "object") return;
|
|
90
|
+
|
|
91
|
+
// Add parent reference
|
|
92
|
+
if (parent && !Object.prototype.hasOwnProperty.call(node, "parent")) {
|
|
93
|
+
Object.defineProperty(node, "parent", {
|
|
94
|
+
value: parent,
|
|
95
|
+
enumerable: false,
|
|
96
|
+
writable: true,
|
|
97
|
+
});
|
|
298
98
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
name: varName,
|
|
313
|
-
type: Array.isArray(value) ? 'array' : typeof value === 'object' ? 'object' : 'primitive',
|
|
314
|
-
value,
|
|
315
|
-
arrayItems: Array.isArray(value) ? value : undefined,
|
|
316
|
-
loc: (_a = declarator.loc) === null || _a === void 0 ? void 0 : _a.start
|
|
317
|
-
});
|
|
318
|
-
}
|
|
99
|
+
|
|
100
|
+
if (callbacks.enter) {
|
|
101
|
+
callbacks.enter(node, parent);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Walk children
|
|
105
|
+
for (const key of Object.keys(node)) {
|
|
106
|
+
if (key === "parent") continue;
|
|
107
|
+
const child = node[key];
|
|
108
|
+
if (Array.isArray(child)) {
|
|
109
|
+
for (const item of child) {
|
|
110
|
+
if (item && typeof item === "object" && item.type) {
|
|
111
|
+
simpleWalk(item, callbacks, node);
|
|
319
112
|
}
|
|
320
113
|
}
|
|
114
|
+
} else if (child && typeof child === "object" && child.type) {
|
|
115
|
+
simpleWalk(child, callbacks, node);
|
|
321
116
|
}
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Use estree-walker if available, otherwise use simple walker
|
|
121
|
+
const walkAst = walk || simpleWalk;
|
|
122
|
+
|
|
123
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
124
|
+
// Helpers
|
|
125
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Quick check if source likely contains JSX
|
|
129
|
+
*/
|
|
130
|
+
function hasJSX(source) {
|
|
131
|
+
// Look for JSX patterns: <Component, <div, etc.
|
|
132
|
+
return /<[A-Za-z]/.test(source);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Check if element should receive location attributes
|
|
137
|
+
*/
|
|
138
|
+
function shouldInjectAttrs(tagName) {
|
|
139
|
+
if (!tagName) return false;
|
|
140
|
+
if (tagName === "Fragment" || tagName === "React.Fragment") return false;
|
|
141
|
+
if (EXCLUDED_ELEMENTS.has(tagName)) return false;
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Extract tag name from JSX opening element
|
|
147
|
+
*/
|
|
148
|
+
function getTagName(node) {
|
|
149
|
+
try {
|
|
150
|
+
const { name } = node;
|
|
151
|
+
if (name.type === "JSXIdentifier") {
|
|
152
|
+
return name.name;
|
|
153
|
+
}
|
|
154
|
+
if (name.type === "JSXMemberExpression") {
|
|
155
|
+
return `${name.object.name}.${name.property.name}`;
|
|
156
|
+
}
|
|
157
|
+
} catch {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Detect if JSX element is inside a .map() call
|
|
165
|
+
*/
|
|
166
|
+
function detectMapContext(node) {
|
|
167
|
+
try {
|
|
168
|
+
let current = node;
|
|
169
|
+
let depth = 0;
|
|
170
|
+
|
|
171
|
+
while (current && depth < 15) {
|
|
172
|
+
if (
|
|
173
|
+
current.type === "CallExpression" &&
|
|
174
|
+
current.callee?.type === "MemberExpression" &&
|
|
175
|
+
current.callee.property?.name === "map"
|
|
176
|
+
) {
|
|
177
|
+
const arrayRef = current.callee.object?.name;
|
|
178
|
+
const callback = current.arguments?.[0];
|
|
179
|
+
|
|
180
|
+
if (arrayRef && callback?.type === "ArrowFunctionExpression") {
|
|
181
|
+
const indexArg = callback.params?.[1];
|
|
343
182
|
return {
|
|
344
|
-
arrayName,
|
|
345
|
-
|
|
346
|
-
arrayItems: varInfo === null || varInfo === void 0 ? void 0 : varInfo.arrayItems,
|
|
347
|
-
arrayLoc: varInfo === null || varInfo === void 0 ? void 0 : varInfo.loc,
|
|
348
|
-
indexVarName: (indexParam === null || indexParam === void 0 ? void 0 : indexParam.type) === 'Identifier' ? indexParam.name : undefined
|
|
183
|
+
arrayName: arrayRef,
|
|
184
|
+
indexName: indexArg?.type === "Identifier" ? indexArg.name : null,
|
|
349
185
|
};
|
|
350
186
|
}
|
|
351
187
|
}
|
|
188
|
+
current = current.parent;
|
|
189
|
+
depth++;
|
|
352
190
|
}
|
|
353
|
-
|
|
354
|
-
|
|
191
|
+
} catch {
|
|
192
|
+
// Ignore errors
|
|
355
193
|
}
|
|
356
194
|
return null;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
};
|
|
366
|
-
const tagName = getName();
|
|
367
|
-
if (!tagName)
|
|
368
|
-
return null;
|
|
369
|
-
// For Next.js Image components, always return 'img' so the name is a valid HTML tag.
|
|
370
|
-
if (isNextImageAlias(imageAliases, tagName)) {
|
|
371
|
-
return 'img';
|
|
372
|
-
}
|
|
373
|
-
return isNextImageAlias(imageAliases, tagName) ? 'img' : tagName;
|
|
374
|
-
};
|
|
375
|
-
/* ───────────────────────────────────────────── Loader */
|
|
376
|
-
function componentTagger(src, map) {
|
|
377
|
-
const done = this.async();
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Collect Next.js Image import aliases
|
|
199
|
+
*/
|
|
200
|
+
function collectImageAliases(ast) {
|
|
201
|
+
const aliases = new Set();
|
|
202
|
+
|
|
378
203
|
try {
|
|
379
|
-
|
|
380
|
-
return done(null, src, map);
|
|
381
|
-
const ast = (0, parser_1.parse)(src, {
|
|
382
|
-
sourceType: 'module',
|
|
383
|
-
plugins: ['jsx', 'typescript'],
|
|
384
|
-
});
|
|
385
|
-
const ms = new magic_string_1.default(src);
|
|
386
|
-
const rel = path.relative(process.cwd(), this.resourcePath);
|
|
387
|
-
let mutated = false;
|
|
388
|
-
// Add parent references to AST nodes for upward traversal (non-enumerable to avoid infinite recursion)
|
|
389
|
-
(0, estree_walker_1.walk)(ast, {
|
|
390
|
-
enter(node, parent) {
|
|
391
|
-
if (parent && !Object.prototype.hasOwnProperty.call(node, 'parent')) {
|
|
392
|
-
Object.defineProperty(node, 'parent', { value: parent, enumerable: false });
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
});
|
|
396
|
-
// 0️⃣ Collect variable declarations first
|
|
397
|
-
const variables = findVariableDeclarations(ast);
|
|
398
|
-
// 1️⃣ Gather local identifiers that reference `next/image`.
|
|
399
|
-
const imageAliases = new Set();
|
|
400
|
-
(0, estree_walker_1.walk)(ast, {
|
|
204
|
+
walkAst(ast, {
|
|
401
205
|
enter(node) {
|
|
402
|
-
if (
|
|
403
|
-
node.
|
|
404
|
-
|
|
405
|
-
|
|
206
|
+
if (
|
|
207
|
+
node.type === "ImportDeclaration" &&
|
|
208
|
+
node.source?.value === "next/image"
|
|
209
|
+
) {
|
|
210
|
+
for (const spec of node.specifiers || []) {
|
|
211
|
+
if (spec.local?.name) {
|
|
212
|
+
aliases.add(spec.local.name);
|
|
213
|
+
}
|
|
406
214
|
}
|
|
407
215
|
}
|
|
408
216
|
},
|
|
409
217
|
});
|
|
410
|
-
|
|
411
|
-
|
|
218
|
+
} catch {
|
|
219
|
+
// Ignore errors
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return aliases;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
226
|
+
// Main Loader
|
|
227
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* FlexApp Element Tagger Loader
|
|
231
|
+
* SAFE: Returns original source on any error
|
|
232
|
+
*/
|
|
233
|
+
function flexElementTagger(source, sourceMap) {
|
|
234
|
+
const callback = this.async();
|
|
235
|
+
// return callback(null, source, sourceMap);
|
|
236
|
+
// Early exit: missing dependencies
|
|
237
|
+
if (!parse || !MagicString) {
|
|
238
|
+
return callback(null, source, sourceMap);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Early exit: no resource path or it's a directory
|
|
242
|
+
if (!this.resourcePath) {
|
|
243
|
+
return callback(null, source, sourceMap);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Early exit: path doesn't look like a file (no extension)
|
|
247
|
+
const ext = path.extname(this.resourcePath);
|
|
248
|
+
if (!ext || !['.tsx', '.jsx', '.ts', '.js'].includes(ext)) {
|
|
249
|
+
return callback(null, source, sourceMap);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Early exit: check if it's actually a file (not a directory)
|
|
253
|
+
try {
|
|
254
|
+
const stat = fs.statSync(this.resourcePath);
|
|
255
|
+
if (!stat.isFile()) {
|
|
256
|
+
return callback(null, source, sourceMap);
|
|
257
|
+
}
|
|
258
|
+
} catch {
|
|
259
|
+
// If stat fails, still try to process (might be virtual file)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Early exit: node_modules
|
|
263
|
+
if (/node_modules/.test(this.resourcePath)) {
|
|
264
|
+
return callback(null, source, sourceMap);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Early exit: no JSX detected
|
|
268
|
+
if (!hasJSX(source)) {
|
|
269
|
+
return callback(null, source, sourceMap);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
try {
|
|
273
|
+
// Parse source
|
|
274
|
+
const ast = parse(source, {
|
|
275
|
+
sourceType: "module",
|
|
276
|
+
plugins: ["jsx", "typescript"],
|
|
277
|
+
errorRecovery: true, // Don't fail on syntax errors
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
if (!ast || !ast.program) {
|
|
281
|
+
return callback(null, source, sourceMap);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const magicStr = new MagicString(source);
|
|
285
|
+
const relativePath = path.relative(process.cwd(), this.resourcePath);
|
|
286
|
+
const imageAliases = collectImageAliases(ast);
|
|
287
|
+
let hasChanges = false;
|
|
288
|
+
|
|
289
|
+
// Add parent references
|
|
290
|
+
walkAst(ast.program, {
|
|
291
|
+
enter() { }, // Just to trigger parent ref addition
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// Process JSX elements
|
|
295
|
+
walkAst(ast.program, {
|
|
412
296
|
enter(node) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
if (
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
297
|
+
try {
|
|
298
|
+
if (node.type !== "JSXOpeningElement") return;
|
|
299
|
+
|
|
300
|
+
let tagName = getTagName(node);
|
|
301
|
+
if (!tagName) return;
|
|
302
|
+
|
|
303
|
+
// Check if already has data-flex-loc
|
|
304
|
+
const hasAttr = node.attributes?.some(
|
|
305
|
+
(attr) =>
|
|
306
|
+
attr.type === "JSXAttribute" &&
|
|
307
|
+
attr.name?.name === "data-flex-loc"
|
|
308
|
+
);
|
|
309
|
+
if (hasAttr) return;
|
|
310
|
+
|
|
311
|
+
// Normalize Next.js Image to img
|
|
312
|
+
const isNextImage = imageAliases.has(tagName.split(".")[0]);
|
|
313
|
+
const displayName = isNextImage ? "img" : tagName;
|
|
314
|
+
|
|
315
|
+
// Check if we should tag this element
|
|
316
|
+
if (!shouldInjectAttrs(tagName) && !isNextImage) return;
|
|
317
|
+
|
|
318
|
+
// Ensure we have location info
|
|
319
|
+
if (!node.loc?.start || !node.name?.end) return;
|
|
320
|
+
|
|
321
|
+
// Build location identifier
|
|
322
|
+
const { line, column } = node.loc.start;
|
|
323
|
+
let locId = `${relativePath}:${line}:${column}`;
|
|
324
|
+
|
|
325
|
+
// Add iteration context if inside .map()
|
|
326
|
+
const mapCtx = detectMapContext(node);
|
|
327
|
+
if (mapCtx?.arrayName) {
|
|
328
|
+
locId += `#${mapCtx.arrayName}`;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Inject data-flex-iter for map index if available
|
|
332
|
+
if (mapCtx?.indexName) {
|
|
333
|
+
magicStr.appendLeft(
|
|
334
|
+
node.name.end,
|
|
335
|
+
` data-flex-iter=${mapCtx.indexName}`
|
|
336
|
+
);
|
|
440
337
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
338
|
+
|
|
339
|
+
// Inject location and name attributes
|
|
340
|
+
magicStr.appendLeft(
|
|
341
|
+
node.name.end,
|
|
342
|
+
` data-flex-loc="${locId}" data-flex-name="${displayName}"`
|
|
343
|
+
);
|
|
344
|
+
|
|
345
|
+
hasChanges = true;
|
|
346
|
+
} catch {
|
|
347
|
+
// Ignore errors for individual nodes
|
|
445
348
|
}
|
|
446
|
-
ms.appendLeft(node.name.end, ` data-orchids-id="${orchidsId}" data-orchids-name="${semanticName}"`);
|
|
447
|
-
mutated = true;
|
|
448
349
|
},
|
|
449
350
|
});
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
351
|
+
|
|
352
|
+
// Return original if no changes
|
|
353
|
+
if (!hasChanges) {
|
|
354
|
+
return callback(null, source, sourceMap);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Generate output
|
|
358
|
+
const output = magicStr.toString();
|
|
359
|
+
|
|
360
|
+
// Return without sourcemap - Turbopack handles it better
|
|
361
|
+
callback(null, output);
|
|
362
|
+
|
|
363
|
+
} catch (error) {
|
|
364
|
+
// On ANY error, return original source unchanged
|
|
365
|
+
console.warn("[flex-element-tagger] Skipping file due to error:", this.resourcePath);
|
|
366
|
+
callback(null, source, sourceMap);
|
|
459
367
|
}
|
|
460
368
|
}
|
|
461
369
|
|
|
370
|
+
module.exports = flexElementTagger;
|
|
371
|
+
module.exports.default = flexElementTagger;
|