react-code-locator 0.1.14 → 0.1.16

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.
@@ -0,0 +1,278 @@
1
+ // src/unplugin.ts
2
+ import { createUnplugin } from "unplugin";
3
+
4
+ // src/core/transform.ts
5
+ import { parse } from "acorn";
6
+ import { generate } from "astring";
7
+ import { walk } from "estree-walker";
8
+
9
+ // src/constants.ts
10
+ var SOURCE_PROP = "__componentSourceLoc";
11
+ var JSX_SOURCE_PROP = "$componentSourceLoc";
12
+ var JSX_SOURCE_REGISTRY_SYMBOL = "react-code-locator.jsxSourceRegistry";
13
+
14
+ // src/core/transform.ts
15
+ function toRelativeSource(filename, loc, projectRoot) {
16
+ const root = projectRoot || process.cwd();
17
+ const relativePath = filename.startsWith(root) ? filename.slice(root.length + 1) : filename;
18
+ return `${relativePath}:${loc.line}:${loc.column + 1}`;
19
+ }
20
+ function isComponentName(name) {
21
+ return /^[A-Z]/.test(name);
22
+ }
23
+ function isReactElementFactoryCall(node) {
24
+ const callee = node.callee;
25
+ if (callee.type === "Identifier") {
26
+ const name = callee.name;
27
+ return [
28
+ "jsx",
29
+ "jsxs",
30
+ "jsxDEV",
31
+ "_jsx",
32
+ "_jsxs",
33
+ "_jsxDEV",
34
+ "createElement"
35
+ ].includes(name);
36
+ }
37
+ if (callee.type === "MemberExpression") {
38
+ const obj = callee.object;
39
+ const prop = callee.property;
40
+ if (obj.type === "Identifier" && obj.name === "React" && prop.type === "Identifier" && prop.name === "createElement") {
41
+ return true;
42
+ }
43
+ }
44
+ return false;
45
+ }
46
+ function isSupportedComponentInit(node) {
47
+ if (!node) return false;
48
+ if (node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") {
49
+ return true;
50
+ }
51
+ if (node.type !== "CallExpression") return false;
52
+ const callee = node.callee;
53
+ if (callee.type === "Identifier") {
54
+ return ["memo", "forwardRef"].includes(callee.name);
55
+ }
56
+ if (callee.type === "MemberExpression") {
57
+ const obj = callee.object;
58
+ const prop = callee.property;
59
+ if (obj.type === "Identifier" && obj.name === "React" && prop.type === "Identifier") {
60
+ return ["memo", "forwardRef"].includes(prop.name);
61
+ }
62
+ }
63
+ return false;
64
+ }
65
+ function createSourceAssignment(name, sourceValue) {
66
+ return {
67
+ type: "ExpressionStatement",
68
+ expression: {
69
+ type: "AssignmentExpression",
70
+ operator: "=",
71
+ left: {
72
+ type: "MemberExpression",
73
+ object: { type: "Identifier", name },
74
+ property: { type: "Identifier", name: SOURCE_PROP },
75
+ computed: false
76
+ },
77
+ right: { type: "Literal", value: sourceValue }
78
+ }
79
+ };
80
+ }
81
+ function createMarkElementHelper() {
82
+ const code = `
83
+ function _markReactElementSource(element, source) {
84
+ const registryKey = Symbol.for("${JSX_SOURCE_REGISTRY_SYMBOL}");
85
+ let registry = globalThis[registryKey];
86
+ if (!(registry instanceof WeakMap)) {
87
+ registry = globalThis[registryKey] = new WeakMap();
88
+ }
89
+ if (element && typeof element === "object" && typeof element.props === "object") {
90
+ registry.set(element.props, source);
91
+ }
92
+ return element;
93
+ }
94
+ `;
95
+ return parse(code, { ecmaVersion: "latest" }).body[0];
96
+ }
97
+ function wrapWithMarkElement(node, sourceValue) {
98
+ return {
99
+ type: "CallExpression",
100
+ callee: { type: "Identifier", name: "_markReactElementSource" },
101
+ arguments: [node, { type: "Literal", value: sourceValue }],
102
+ optional: false
103
+ };
104
+ }
105
+ function transformSource(code, options) {
106
+ const {
107
+ filename,
108
+ projectRoot = process.cwd(),
109
+ injectJsxSource = true,
110
+ injectComponentSource = true
111
+ } = options;
112
+ let ast;
113
+ try {
114
+ ast = parse(code, {
115
+ ecmaVersion: "latest",
116
+ sourceType: "module",
117
+ ecmaFeatures: { jsx: true },
118
+ locations: true,
119
+ ranges: true
120
+ });
121
+ } catch (err) {
122
+ return null;
123
+ }
124
+ let modified = false;
125
+ let needsHelper = false;
126
+ const seenComponents = /* @__PURE__ */ new Set();
127
+ const assignments = [];
128
+ walk(ast, {
129
+ enter(node, parent, key, index) {
130
+ if (injectJsxSource && node.type === "CallExpression") {
131
+ if (isReactElementFactoryCall(node)) {
132
+ const loc = node.loc;
133
+ if (loc) {
134
+ const sourceValue = toRelativeSource(filename, loc.start, projectRoot);
135
+ const wrapped = wrapWithMarkElement(node, sourceValue);
136
+ this.replace(wrapped);
137
+ needsHelper = true;
138
+ modified = true;
139
+ }
140
+ }
141
+ }
142
+ if (injectJsxSource && node.type === "JSXElement") {
143
+ const opening = node.openingElement;
144
+ const loc = opening.loc;
145
+ if (loc) {
146
+ const sourceValue = toRelativeSource(filename, loc.start, projectRoot);
147
+ const name = opening.name;
148
+ if (name.type === "JSXIdentifier") {
149
+ if (name.name[0] === name.name[0].toLowerCase()) {
150
+ } else {
151
+ const sourceAttr = {
152
+ type: "JSXAttribute",
153
+ name: { type: "JSXIdentifier", name: JSX_SOURCE_PROP },
154
+ value: { type: "Literal", value: sourceValue }
155
+ };
156
+ opening.attributes.push(sourceAttr);
157
+ modified = true;
158
+ }
159
+ }
160
+ }
161
+ }
162
+ if (injectComponentSource && node.type === "FunctionDeclaration") {
163
+ const name = node.id?.name;
164
+ if (name && isComponentName(name) && !seenComponents.has(name)) {
165
+ const loc = node.loc;
166
+ if (loc) {
167
+ const sourceValue = toRelativeSource(filename, loc.start, projectRoot);
168
+ const assignment = createSourceAssignment(name, sourceValue);
169
+ assignments.push({ node, parent, assignment });
170
+ seenComponents.add(name);
171
+ modified = true;
172
+ }
173
+ }
174
+ }
175
+ if (injectComponentSource && node.type === "VariableDeclarator") {
176
+ const id = node.id;
177
+ if (id.type === "Identifier" && isComponentName(id.name) && !seenComponents.has(id.name)) {
178
+ const init = node.init;
179
+ if (init && isSupportedComponentInit(init)) {
180
+ const loc = node.loc || init.loc;
181
+ if (loc) {
182
+ const sourceValue = toRelativeSource(filename, loc.start, projectRoot);
183
+ const assignment = createSourceAssignment(id.name, sourceValue);
184
+ assignments.push({ node, parent, assignment });
185
+ seenComponents.add(id.name);
186
+ modified = true;
187
+ }
188
+ }
189
+ }
190
+ }
191
+ }
192
+ });
193
+ if (!modified) {
194
+ return null;
195
+ }
196
+ if (needsHelper) {
197
+ const helper = createMarkElementHelper();
198
+ const exists = ast.body.some(
199
+ (n) => n.type === "FunctionDeclaration" && n.id?.name === "_markReactElementSource"
200
+ );
201
+ if (!exists) {
202
+ ast.body.unshift(helper);
203
+ }
204
+ }
205
+ for (const { node, parent, assignment } of assignments.reverse()) {
206
+ if (parent && parent.type === "Program") {
207
+ const index = ast.body.indexOf(node);
208
+ if (index !== -1) {
209
+ ast.body.splice(index + 1, 0, assignment);
210
+ }
211
+ } else if (parent && parent.type === "ExportNamedDeclaration") {
212
+ const exportParent = ast.body.find(
213
+ (n) => n.type === "ExportNamedDeclaration" && n.declaration === parent
214
+ );
215
+ if (exportParent) {
216
+ const index = ast.body.indexOf(exportParent);
217
+ ast.body.splice(index + 1, 0, assignment);
218
+ }
219
+ } else if (parent && parent.type === "ExportDefaultDeclaration") {
220
+ const index = ast.body.indexOf(parent);
221
+ ast.body.splice(index + 1, 0, assignment);
222
+ }
223
+ }
224
+ const result = generate(ast, { indent: " " });
225
+ return { code: result };
226
+ }
227
+
228
+ // src/unplugin.ts
229
+ var DEFAULT_INCLUDE = /\.([jt]sx)$/;
230
+ var DEFAULT_EXCLUDE = /node_modules/;
231
+ function shouldTransform(id, include, exclude) {
232
+ const includePatterns = Array.isArray(include) ? include : [include];
233
+ const excludePatterns = Array.isArray(exclude) ? exclude : [exclude];
234
+ if (excludePatterns.some((pattern) => pattern.test(id))) {
235
+ return false;
236
+ }
237
+ return includePatterns.some((pattern) => pattern.test(id));
238
+ }
239
+ var unplugin = createUnplugin((options = {}) => {
240
+ const {
241
+ include = DEFAULT_INCLUDE,
242
+ exclude = DEFAULT_EXCLUDE,
243
+ projectRoot = process.cwd(),
244
+ injectComponentSource = true,
245
+ injectJsxSource = true
246
+ } = options;
247
+ return {
248
+ name: "react-code-locator",
249
+ transform(code, id) {
250
+ if (!shouldTransform(id, include, exclude)) {
251
+ return null;
252
+ }
253
+ const result = transformSource(code, {
254
+ filename: id,
255
+ projectRoot,
256
+ injectComponentSource,
257
+ injectJsxSource
258
+ });
259
+ return result;
260
+ }
261
+ };
262
+ });
263
+ var vitePlugin = unplugin.vite;
264
+ var webpackPlugin = unplugin.webpack;
265
+ var rollupPlugin = unplugin.rollup;
266
+ var esbuildPlugin = unplugin.esbuild;
267
+ var rspackPlugin = unplugin.rspack;
268
+ var unplugin_default = unplugin;
269
+ export {
270
+ unplugin_default as default,
271
+ esbuildPlugin,
272
+ rollupPlugin,
273
+ rspackPlugin,
274
+ unplugin,
275
+ vitePlugin,
276
+ webpackPlugin
277
+ };
278
+ //# sourceMappingURL=unplugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/unplugin.ts","../src/core/transform.ts","../src/constants.ts"],"sourcesContent":["/**\n * Unplugin-based universal adapter for all build tools\n * Supports: Vite, Webpack, Rollup, esbuild, Rspack\n * \n * Zero-dependency transform using acorn instead of Babel\n */\n\nimport { createUnplugin, type UnpluginInstance, type UnpluginOptions } from \"unplugin\";\nimport { transformSource, type TransformOptions } from \"./core/transform\";\n\nexport interface ReactCodeLocatorOptions extends Omit<TransformOptions, 'filename'> {\n /** \n * Enable source transform for component definitions\n * @default true\n */\n injectComponentSource?: boolean;\n \n /** \n * Enable source transform for JSX call sites\n * @default true\n */\n injectJsxSource?: boolean;\n \n /**\n * Project root for relative path calculation\n * @default process.cwd()\n */\n projectRoot?: string;\n \n /**\n * Include filter for file paths\n * @default /\\.[jt]sx$/\n */\n include?: RegExp | RegExp[];\n \n /**\n * Exclude filter for file paths\n * @default /node_modules/\n */\n exclude?: RegExp | RegExp[];\n}\n\nexport type { TransformOptions };\n\nconst DEFAULT_INCLUDE = /\\.([jt]sx)$/;\nconst DEFAULT_EXCLUDE = /node_modules/;\n\nfunction shouldTransform(id: string, include: RegExp | RegExp[], exclude: RegExp | RegExp[]): boolean {\n const includePatterns = Array.isArray(include) ? include : [include];\n const excludePatterns = Array.isArray(exclude) ? exclude : [exclude];\n \n // Check exclude first\n if (excludePatterns.some(pattern => pattern.test(id))) {\n return false;\n }\n \n // Then check include\n return includePatterns.some(pattern => pattern.test(id));\n}\n\nexport const unplugin: UnpluginInstance<ReactCodeLocatorOptions | undefined, false> = \n createUnplugin((options = {}) => {\n const {\n include = DEFAULT_INCLUDE,\n exclude = DEFAULT_EXCLUDE,\n projectRoot = process.cwd(),\n injectComponentSource = true,\n injectJsxSource = true,\n } = options;\n\n return {\n name: \"react-code-locator\",\n \n transform(code, id) {\n // Skip if doesn't match patterns\n if (!shouldTransform(id, include, exclude)) {\n return null;\n }\n\n // Perform transform using acorn (zero-dependency)\n const result = transformSource(code, {\n filename: id,\n projectRoot,\n injectComponentSource,\n injectJsxSource,\n });\n\n return result;\n },\n } as UnpluginOptions;\n });\n\n// Export individual build tool adapters\nexport const vitePlugin = unplugin.vite;\nexport const webpackPlugin = unplugin.webpack;\nexport const rollupPlugin = unplugin.rollup;\nexport const esbuildPlugin = unplugin.esbuild;\nexport const rspackPlugin = unplugin.rspack;\n\n// Default export for direct usage\nexport default unplugin;\n","/**\n * Zero-dependency source transform using acorn\n * No Babel required - pure JavaScript AST manipulation\n */\n\nimport { parse, type Node as AcornNode } from \"acorn\";\nimport { generate } from \"astring\";\nimport { walk } from \"estree-walker\";\nimport type {\n Node,\n Program,\n FunctionDeclaration,\n FunctionExpression,\n ArrowFunctionExpression,\n VariableDeclarator,\n CallExpression,\n MemberExpression,\n Identifier,\n ExpressionStatement,\n AssignmentExpression,\n} from \"estree\";\nimport { SOURCE_PROP, JSX_SOURCE_PROP, JSX_SOURCE_REGISTRY_SYMBOL } from \"../constants\";\n\nexport interface TransformOptions {\n filename: string;\n projectRoot?: string;\n injectJsxSource?: boolean;\n injectComponentSource?: boolean;\n}\n\ninterface Location {\n line: number;\n column: number;\n}\n\nfunction toRelativeSource(filename: string, loc: Location, projectRoot?: string): string {\n const root = projectRoot || process.cwd();\n const relativePath = filename.startsWith(root) \n ? filename.slice(root.length + 1) \n : filename;\n return `${relativePath}:${loc.line}:${loc.column + 1}`;\n}\n\nfunction isComponentName(name: string): boolean {\n return /^[A-Z]/.test(name);\n}\n\nfunction isReactElementFactoryCall(node: CallExpression): boolean {\n const callee = node.callee;\n \n if (callee.type === \"Identifier\") {\n const name = callee.name;\n return [\n \"jsx\", \"jsxs\", \"jsxDEV\",\n \"_jsx\", \"_jsxs\", \"_jsxDEV\",\n \"createElement\"\n ].includes(name);\n }\n \n // React.createElement\n if (callee.type === \"MemberExpression\") {\n const obj = callee.object;\n const prop = callee.property;\n if (obj.type === \"Identifier\" && obj.name === \"React\" && \n prop.type === \"Identifier\" && prop.name === \"createElement\") {\n return true;\n }\n }\n \n return false;\n}\n\nfunction isSupportedComponentInit(\n node: Node | null\n): boolean {\n if (!node) return false;\n \n if (node.type === \"ArrowFunctionExpression\" || \n node.type === \"FunctionExpression\") {\n return true;\n }\n \n if (node.type !== \"CallExpression\") return false;\n \n const callee = node.callee;\n if (callee.type === \"Identifier\") {\n return [\"memo\", \"forwardRef\"].includes(callee.name);\n }\n \n // React.memo, React.forwardRef\n if (callee.type === \"MemberExpression\") {\n const obj = callee.object;\n const prop = callee.property;\n if (obj.type === \"Identifier\" && obj.name === \"React\" && \n prop.type === \"Identifier\") {\n return [\"memo\", \"forwardRef\"].includes(prop.name);\n }\n }\n \n return false;\n}\n\nfunction createSourceAssignment(name: string, sourceValue: string): ExpressionStatement {\n return {\n type: \"ExpressionStatement\",\n expression: {\n type: \"AssignmentExpression\",\n operator: \"=\",\n left: {\n type: \"MemberExpression\",\n object: { type: \"Identifier\", name },\n property: { type: \"Identifier\", name: SOURCE_PROP },\n computed: false,\n } as MemberExpression,\n right: { type: \"Literal\", value: sourceValue },\n } as AssignmentExpression,\n };\n}\n\nfunction createMarkElementHelper(): FunctionDeclaration {\n const code = `\nfunction _markReactElementSource(element, source) {\n const registryKey = Symbol.for(\"${JSX_SOURCE_REGISTRY_SYMBOL}\");\n let registry = globalThis[registryKey];\n if (!(registry instanceof WeakMap)) {\n registry = globalThis[registryKey] = new WeakMap();\n }\n if (element && typeof element === \"object\" && typeof element.props === \"object\") {\n registry.set(element.props, source);\n }\n return element;\n}\n`;\n return parse(code, { ecmaVersion: \"latest\" }).body[0] as FunctionDeclaration;\n}\n\nfunction wrapWithMarkElement(\n node: Node,\n sourceValue: string\n): CallExpression {\n return {\n type: \"CallExpression\",\n callee: { type: \"Identifier\", name: \"_markReactElementSource\" },\n arguments: [node as any, { type: \"Literal\", value: sourceValue }],\n optional: false,\n };\n}\n\nexport function transformSource(\n code: string,\n options: TransformOptions\n): { code: string; map?: any } | null {\n const {\n filename,\n projectRoot = process.cwd(),\n injectJsxSource = true,\n injectComponentSource = true,\n } = options;\n\n // Parse with acorn\n let ast: Program;\n try {\n ast = parse(code, {\n ecmaVersion: \"latest\",\n sourceType: \"module\",\n ecmaFeatures: { jsx: true },\n locations: true,\n ranges: true,\n } as any) as Program;\n } catch (err) {\n // Parse error - return null to skip this file\n return null;\n }\n\n let modified = false;\n let needsHelper = false;\n const seenComponents = new Set<string>();\n const assignments: Array<{ node: Node; parent: Node | null; assignment: ExpressionStatement }> = [];\n\n walk(ast as any, {\n enter(node: any, parent: any, key: any, index: any) {\n // Inject JSX source for element factory calls\n if (injectJsxSource && node.type === \"CallExpression\") {\n if (isReactElementFactoryCall(node)) {\n const loc = node.loc;\n if (loc) {\n const sourceValue = toRelativeSource(filename, loc.start, projectRoot);\n const wrapped = wrapWithMarkElement(node, sourceValue);\n \n // Replace the node\n this.replace(wrapped);\n needsHelper = true;\n modified = true;\n }\n }\n }\n\n // Inject JSX source for JSX elements\n if (injectJsxSource && node.type === \"JSXElement\") {\n const opening = node.openingElement;\n const loc = opening.loc;\n \n if (loc) {\n const sourceValue = toRelativeSource(filename, loc.start, projectRoot);\n \n // Check if intrinsic element (lowercase) or component (uppercase)\n const name = opening.name;\n if (name.type === \"JSXIdentifier\") {\n if (name.name[0] === name.name[0].toLowerCase()) {\n // Intrinsic element - use _markReactElementSource\n // This is handled by the CallExpression visitor for jsx()\n // But for JSX syntax directly, we need different handling\n } else {\n // Component - add $componentSourceLoc prop\n const sourceAttr = {\n type: \"JSXAttribute\",\n name: { type: \"JSXIdentifier\", name: JSX_SOURCE_PROP },\n value: { type: \"Literal\", value: sourceValue },\n };\n opening.attributes.push(sourceAttr);\n modified = true;\n }\n }\n }\n }\n\n // Inject component source for function declarations\n if (injectComponentSource && node.type === \"FunctionDeclaration\") {\n const name = node.id?.name;\n if (name && isComponentName(name) && !seenComponents.has(name)) {\n const loc = node.loc;\n if (loc) {\n const sourceValue = toRelativeSource(filename, loc.start, projectRoot);\n const assignment = createSourceAssignment(name, sourceValue);\n assignments.push({ node, parent, assignment });\n seenComponents.add(name);\n modified = true;\n }\n }\n }\n\n // Inject component source for variable declarations\n if (injectComponentSource && node.type === \"VariableDeclarator\") {\n const id = node.id;\n if (id.type === \"Identifier\" && isComponentName(id.name) && !seenComponents.has(id.name)) {\n const init = node.init;\n if (init && isSupportedComponentInit(init)) {\n const loc = node.loc || init.loc;\n if (loc) {\n const sourceValue = toRelativeSource(filename, loc.start, projectRoot);\n const assignment = createSourceAssignment(id.name, sourceValue);\n assignments.push({ node, parent, assignment });\n seenComponents.add(id.name);\n modified = true;\n }\n }\n }\n }\n },\n });\n\n if (!modified) {\n return null;\n }\n\n // Insert helper function if needed\n if (needsHelper) {\n const helper = createMarkElementHelper();\n // Check if already exists\n const exists = ast.body.some(\n (n) => n.type === \"FunctionDeclaration\" && \n n.id?.name === \"_markReactElementSource\"\n );\n if (!exists) {\n ast.body.unshift(helper);\n }\n }\n\n // Insert component source assignments\n // We need to insert after the declaration, so we process in reverse order\n for (const { node, parent, assignment } of assignments.reverse()) {\n if (parent && parent.type === \"Program\") {\n const index = ast.body.indexOf(node as any);\n if (index !== -1) {\n ast.body.splice(index + 1, 0, assignment as any);\n }\n } else if (parent && parent.type === \"ExportNamedDeclaration\") {\n // For export const Component = ...\n // Insert after the export statement\n const exportParent = (ast as any).body.find((n: any) => \n n.type === \"ExportNamedDeclaration\" && n.declaration === parent\n );\n if (exportParent) {\n const index = ast.body.indexOf(exportParent);\n ast.body.splice(index + 1, 0, assignment as any);\n }\n } else if (parent && parent.type === \"ExportDefaultDeclaration\") {\n // For export default function Component() ...\n const index = ast.body.indexOf(parent as any);\n ast.body.splice(index + 1, 0, assignment as any);\n }\n }\n\n // Generate code\n const result = generate(ast as any, { indent: \" \" });\n\n return { code: result };\n}\n","export const SOURCE_PROP = \"__componentSourceLoc\";\nexport const JSX_SOURCE_PROP = \"$componentSourceLoc\";\nexport const JSX_SOURCE_REGISTRY_SYMBOL = \"react-code-locator.jsxSourceRegistry\";\n"],"mappings":"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","names":[]}
package/dist/vite.cjs CHANGED
@@ -42,7 +42,6 @@ var import_core = require("@babel/core");
42
42
 
43
43
  // src/constants.ts
44
44
  var SOURCE_PROP = "__componentSourceLoc";
45
- var JSX_SOURCE_PROP = "$componentSourceLoc";
46
45
  var JSX_SOURCE_REGISTRY_SYMBOL = "react-code-locator.jsxSourceRegistry";
47
46
 
48
47
  // src/sourceMetadata.ts
@@ -82,43 +81,11 @@ function toRelativeSource(filename, loc, projectRoot) {
82
81
  const relPath = root && normalizedFilename.startsWith(`${root}/`) ? normalizedFilename.slice(root.length + 1) : root ? computeRelativePath(root, normalizedFilename) : normalizedFilename;
83
82
  return `${relPath}:${loc.line}:${loc.column + 1}`;
84
83
  }
85
- function isProjectLocalFile(filename, projectRoot) {
86
- if (!filename) {
87
- return false;
88
- }
89
- const root = normalizeProjectRoot(projectRoot);
90
- const normalizedFilename = normalizeSlashes(filename);
91
- if (!root) {
92
- return !normalizedFilename.startsWith("../") && !normalizedFilename.startsWith("/") && !/^[A-Za-z]:\//.test(normalizedFilename);
93
- }
94
- if (normalizedFilename.startsWith(`${root}/`) || normalizedFilename === root) {
95
- return true;
96
- }
97
- const relativePath = computeRelativePath(root, normalizedFilename);
98
- return !relativePath.startsWith("../");
99
- }
100
- function isExternalToProjectRoot(filename, projectRoot) {
101
- return !isProjectLocalFile(filename, projectRoot);
102
- }
103
84
 
104
85
  // src/babelInjectComponentSource.ts
105
- var SOURCE_PROP_LOCAL = "_componentSourceLoc";
106
- var SOURCE_PROPS_REST = "__reactCodeLocatorProps";
107
86
  function isComponentName(name) {
108
87
  return /^[A-Z]/.test(name);
109
88
  }
110
- function isCustomComponentTag(name) {
111
- if (import_core.types.isJSXIdentifier(name)) {
112
- return isComponentName(name.name);
113
- }
114
- if (import_core.types.isJSXMemberExpression(name)) {
115
- return true;
116
- }
117
- return false;
118
- }
119
- function isIntrinsicElementTag(name) {
120
- return import_core.types.isJSXIdentifier(name) && /^[a-z]/.test(name.name);
121
- }
122
89
  function isElementFactoryIdentifier(name) {
123
90
  return name === "jsx" || name === "jsxs" || name === "jsxDEV" || name === "_jsx" || name === "_jsxs" || name === "_jsxDEV" || name === "createElement";
124
91
  }
@@ -129,29 +96,6 @@ function isReactElementFactoryCall(pathNode) {
129
96
  }
130
97
  return import_core.types.isMemberExpression(callee) && import_core.types.isIdentifier(callee.object, { name: "React" }) && import_core.types.isIdentifier(callee.property, { name: "createElement" });
131
98
  }
132
- function getRootJsxIdentifierName(name) {
133
- if (import_core.types.isJSXIdentifier(name)) {
134
- return name.name;
135
- }
136
- if (import_core.types.isJSXMemberExpression(name)) {
137
- return getRootJsxIdentifierName(name.object);
138
- }
139
- return null;
140
- }
141
- function isStyledModuleImport(binding) {
142
- if (!binding) {
143
- return false;
144
- }
145
- if (!binding.path.isImportSpecifier() && !binding.path.isImportDefaultSpecifier() && !binding.path.isImportNamespaceSpecifier()) {
146
- return false;
147
- }
148
- const source = binding.path.parentPath.isImportDeclaration() ? binding.path.parentPath.node.source.value : null;
149
- if (typeof source !== "string") {
150
- return false;
151
- }
152
- const normalized = source.replace(/\\/g, "/");
153
- return normalized === "./styled" || normalized === "../styled" || normalized.endsWith("/styled");
154
- }
155
99
  function isSupportedComponentInit(node) {
156
100
  if (!node) {
157
101
  return false;
@@ -167,98 +111,6 @@ function isSupportedComponentInit(node) {
167
111
  }
168
112
  return import_core.types.isMemberExpression(node.callee) && import_core.types.isIdentifier(node.callee.object, { name: "React" }) && import_core.types.isIdentifier(node.callee.property) && (node.callee.property.name === "memo" || node.callee.property.name === "forwardRef");
169
113
  }
170
- function hasSourcePropBinding(pattern) {
171
- return pattern.properties.some((property) => {
172
- if (!import_core.types.isObjectProperty(property)) {
173
- return false;
174
- }
175
- return import_core.types.isIdentifier(property.key) && property.key.name === JSX_SOURCE_PROP;
176
- });
177
- }
178
- function injectSourcePropBinding(pattern) {
179
- if (hasSourcePropBinding(pattern)) {
180
- return;
181
- }
182
- const sourceBinding = import_core.types.objectProperty(
183
- import_core.types.identifier(JSX_SOURCE_PROP),
184
- import_core.types.identifier(SOURCE_PROP_LOCAL),
185
- false,
186
- false
187
- );
188
- const restIndex = pattern.properties.findIndex(
189
- (property) => import_core.types.isRestElement(property)
190
- );
191
- if (restIndex === -1) {
192
- pattern.properties.push(sourceBinding);
193
- return;
194
- }
195
- pattern.properties.splice(restIndex, 0, sourceBinding);
196
- }
197
- function injectSourcePropIntoIdentifierParam(node, param) {
198
- if (!import_core.types.isBlockStatement(node.body)) {
199
- node.body = import_core.types.blockStatement([import_core.types.returnStatement(node.body)]);
200
- }
201
- const alreadyInjected = node.body.body.some(
202
- (statement) => import_core.types.isVariableDeclaration(statement) && statement.declarations.some(
203
- (declaration) => import_core.types.isIdentifier(declaration.id) && declaration.id.name === SOURCE_PROPS_REST
204
- )
205
- );
206
- if (alreadyInjected) {
207
- return;
208
- }
209
- node.body.body.unshift(
210
- import_core.types.variableDeclaration("const", [
211
- import_core.types.variableDeclarator(
212
- import_core.types.objectPattern([
213
- import_core.types.objectProperty(
214
- import_core.types.identifier(JSX_SOURCE_PROP),
215
- import_core.types.identifier(SOURCE_PROP_LOCAL),
216
- false,
217
- false
218
- ),
219
- import_core.types.restElement(import_core.types.identifier(SOURCE_PROPS_REST))
220
- ]),
221
- param
222
- )
223
- ]),
224
- import_core.types.expressionStatement(
225
- import_core.types.assignmentExpression(
226
- "=",
227
- import_core.types.identifier(param.name),
228
- import_core.types.identifier(SOURCE_PROPS_REST)
229
- )
230
- )
231
- );
232
- }
233
- function injectSourcePropIntoFunctionParams(node) {
234
- const firstParam = node.params[0];
235
- if (!firstParam) {
236
- return;
237
- }
238
- if (import_core.types.isObjectPattern(firstParam)) {
239
- injectSourcePropBinding(firstParam);
240
- return;
241
- }
242
- if (import_core.types.isIdentifier(firstParam)) {
243
- injectSourcePropIntoIdentifierParam(node, firstParam);
244
- }
245
- }
246
- function injectSourcePropIntoExpression(node) {
247
- if (!node) {
248
- return;
249
- }
250
- if (import_core.types.isFunctionExpression(node) || import_core.types.isArrowFunctionExpression(node)) {
251
- injectSourcePropIntoFunctionParams(node);
252
- return;
253
- }
254
- if (!import_core.types.isCallExpression(node)) {
255
- return;
256
- }
257
- const firstArg = node.arguments[0];
258
- if (firstArg && !import_core.types.isSpreadElement(firstArg) && (import_core.types.isFunctionExpression(firstArg) || import_core.types.isArrowFunctionExpression(firstArg))) {
259
- injectSourcePropIntoFunctionParams(firstArg);
260
- }
261
- }
262
114
  function getSourceValue(state, loc, projectRoot) {
263
115
  const filename = state.file?.opts?.filename;
264
116
  if (!filename || !loc) {
@@ -275,9 +127,9 @@ function buildAssignment(name, sourceValue) {
275
127
  )
276
128
  );
277
129
  }
278
- function buildIntrinsicSourceHelper() {
130
+ function buildElementSourceHelper() {
279
131
  return import_core.types.functionDeclaration(
280
- import_core.types.identifier("_markIntrinsicElementSource"),
132
+ import_core.types.identifier("_markReactElementSource"),
281
133
  [import_core.types.identifier("element"), import_core.types.identifier("source")],
282
134
  import_core.types.blockStatement([
283
135
  import_core.types.variableDeclaration("const", [
@@ -341,15 +193,15 @@ function buildIntrinsicSourceHelper() {
341
193
  ])
342
194
  );
343
195
  }
344
- function ensureIntrinsicSourceHelper(programPath, state) {
196
+ function ensureElementSourceHelper(programPath, state) {
345
197
  if (state.injectedIntrinsicHelper) {
346
198
  return;
347
199
  }
348
200
  const alreadyExists = programPath.node.body.some(
349
- (node) => import_core.types.isFunctionDeclaration(node) && import_core.types.isIdentifier(node.id, { name: "_markIntrinsicElementSource" })
201
+ (node) => import_core.types.isFunctionDeclaration(node) && import_core.types.isIdentifier(node.id, { name: "_markReactElementSource" })
350
202
  );
351
203
  if (!alreadyExists) {
352
- programPath.unshiftContainer("body", buildIntrinsicSourceHelper());
204
+ programPath.unshiftContainer("body", buildElementSourceHelper());
353
205
  }
354
206
  state.injectedIntrinsicHelper = true;
355
207
  }
@@ -359,9 +211,6 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen, project
359
211
  if (!name || !isComponentName(name) || seen.has(name)) {
360
212
  return;
361
213
  }
362
- if (declarationPath.isFunctionDeclaration()) {
363
- injectSourcePropIntoFunctionParams(declarationPath.node);
364
- }
365
214
  const sourceValue = getSourceValue(
366
215
  state,
367
216
  declarationPath.node.loc?.start,
@@ -388,7 +237,6 @@ function visitDeclaration(declarationPath, insertAfterPath, state, seen, project
388
237
  if (!isSupportedComponentInit(declarator.init)) {
389
238
  return [];
390
239
  }
391
- injectSourcePropIntoExpression(declarator.init);
392
240
  const sourceValue = getSourceValue(
393
241
  state,
394
242
  declarator.loc?.start ?? declarator.init.loc?.start,
@@ -422,7 +270,7 @@ function babelInjectComponentSource(options = {}) {
422
270
  return;
423
271
  }
424
272
  if (pathNode.parentPath.isCallExpression() && import_core.types.isIdentifier(pathNode.parentPath.node.callee, {
425
- name: "_markIntrinsicElementSource"
273
+ name: "_markReactElementSource"
426
274
  })) {
427
275
  return;
428
276
  }
@@ -438,9 +286,9 @@ function babelInjectComponentSource(options = {}) {
438
286
  if (!programPath || !programPath.isProgram()) {
439
287
  return;
440
288
  }
441
- ensureIntrinsicSourceHelper(programPath, state);
289
+ ensureElementSourceHelper(programPath, state);
442
290
  pathNode.replaceWith(
443
- import_core.types.callExpression(import_core.types.identifier("_markIntrinsicElementSource"), [
291
+ import_core.types.callExpression(import_core.types.identifier("_markReactElementSource"), [
444
292
  pathNode.node,
445
293
  import_core.types.stringLiteral(sourceValue)
446
294
  ])
@@ -452,10 +300,7 @@ function babelInjectComponentSource(options = {}) {
452
300
  if (!injectJsxSource) {
453
301
  return;
454
302
  }
455
- if (!isIntrinsicElementTag(pathNode.node.openingElement.name)) {
456
- return;
457
- }
458
- if (pathNode.parentPath.isCallExpression() && import_core.types.isIdentifier(pathNode.parentPath.node.callee, { name: "_markIntrinsicElementSource" })) {
303
+ if (pathNode.parentPath.isCallExpression() && import_core.types.isIdentifier(pathNode.parentPath.node.callee, { name: "_markReactElementSource" })) {
459
304
  return;
460
305
  }
461
306
  const sourceValue = getSourceValue(
@@ -470,8 +315,8 @@ function babelInjectComponentSource(options = {}) {
470
315
  if (!programPath || !programPath.isProgram()) {
471
316
  return;
472
317
  }
473
- ensureIntrinsicSourceHelper(programPath, state);
474
- const wrappedNode = import_core.types.callExpression(import_core.types.identifier("_markIntrinsicElementSource"), [
318
+ ensureElementSourceHelper(programPath, state);
319
+ const wrappedNode = import_core.types.callExpression(import_core.types.identifier("_markReactElementSource"), [
475
320
  pathNode.node,
476
321
  import_core.types.stringLiteral(sourceValue)
477
322
  ]);
@@ -486,37 +331,6 @@ function babelInjectComponentSource(options = {}) {
486
331
  pathNode.replaceWith(wrappedNode);
487
332
  }
488
333
  },
489
- JSXOpeningElement(pathNode, state) {
490
- if (!injectJsxSource) {
491
- return;
492
- }
493
- if (!isCustomComponentTag(pathNode.node.name)) {
494
- return;
495
- }
496
- const rootIdentifierName = getRootJsxIdentifierName(pathNode.node.name);
497
- if (rootIdentifierName && isExternalToProjectRoot(state.file?.opts?.filename, projectRoot) && isStyledModuleImport(pathNode.scope.getBinding(rootIdentifierName))) {
498
- return;
499
- }
500
- const hasSourceProp = pathNode.node.attributes.some(
501
- (attr) => import_core.types.isJSXAttribute(attr) && import_core.types.isJSXIdentifier(attr.name) && attr.name.name === JSX_SOURCE_PROP
502
- );
503
- if (hasSourceProp) {
504
- return;
505
- }
506
- const filename = state.file?.opts?.filename;
507
- const loc = pathNode.node.loc?.start;
508
- if (!filename || !loc) {
509
- return;
510
- }
511
- pathNode.node.attributes.push(
512
- import_core.types.jsxAttribute(
513
- import_core.types.jsxIdentifier(JSX_SOURCE_PROP),
514
- import_core.types.stringLiteral(
515
- getSourceValue(state, loc, projectRoot) ?? `${filename.replace(/\\/g, "/")}:${loc.line}:${loc.column + 1}`
516
- )
517
- )
518
- );
519
- },
520
334
  Program(programPath, state) {
521
335
  if (!injectComponentSource) {
522
336
  return;