@sentry/bundler-plugins 10.64.0 → 10.66.0

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.
Files changed (67) hide show
  1. package/build/cjs/babel-plugin/component-annotation.js +46 -0
  2. package/build/cjs/babel-plugin/component-annotation.js.map +1 -0
  3. package/build/cjs/babel-plugin/index.js +19 -49
  4. package/build/cjs/babel-plugin/index.js.map +1 -1
  5. package/build/cjs/core/component-annotation-vite-ast.js +27 -0
  6. package/build/cjs/core/component-annotation-vite-ast.js.map +1 -0
  7. package/build/cjs/core/component-annotation-vite-fragments.js +91 -0
  8. package/build/cjs/core/component-annotation-vite-fragments.js.map +1 -0
  9. package/build/cjs/core/component-annotation-vite-jsx.js +140 -0
  10. package/build/cjs/core/component-annotation-vite-jsx.js.map +1 -0
  11. package/build/cjs/core/component-annotation-vite-walk.js +121 -0
  12. package/build/cjs/core/component-annotation-vite-walk.js.map +1 -0
  13. package/build/cjs/core/component-annotation-vite.js +101 -0
  14. package/build/cjs/core/component-annotation-vite.js.map +1 -0
  15. package/build/cjs/core/index.js +20 -7
  16. package/build/cjs/core/index.js.map +1 -1
  17. package/build/cjs/core/version.js +1 -1
  18. package/build/cjs/core/version.js.map +1 -1
  19. package/build/cjs/rollup/index.js +52 -3
  20. package/build/cjs/rollup/index.js.map +1 -1
  21. package/build/esm/babel-plugin/component-annotation.js +38 -0
  22. package/build/esm/babel-plugin/component-annotation.js.map +1 -0
  23. package/build/esm/babel-plugin/index.js +20 -50
  24. package/build/esm/babel-plugin/index.js.map +1 -1
  25. package/build/esm/core/component-annotation-vite-ast.js +24 -0
  26. package/build/esm/core/component-annotation-vite-ast.js.map +1 -0
  27. package/build/esm/core/component-annotation-vite-fragments.js +89 -0
  28. package/build/esm/core/component-annotation-vite-fragments.js.map +1 -0
  29. package/build/esm/core/component-annotation-vite-jsx.js +130 -0
  30. package/build/esm/core/component-annotation-vite-jsx.js.map +1 -0
  31. package/build/esm/core/component-annotation-vite-walk.js +119 -0
  32. package/build/esm/core/component-annotation-vite-walk.js.map +1 -0
  33. package/build/esm/core/component-annotation-vite.js +94 -0
  34. package/build/esm/core/component-annotation-vite.js.map +1 -0
  35. package/build/esm/core/index.js +16 -3
  36. package/build/esm/core/index.js.map +1 -1
  37. package/build/esm/core/version.js +1 -1
  38. package/build/esm/core/version.js.map +1 -1
  39. package/build/esm/package.json +1 -1
  40. package/build/esm/rollup/index.js +52 -3
  41. package/build/esm/rollup/index.js.map +1 -1
  42. package/build/types/babel-plugin/component-annotation.d.ts +20 -0
  43. package/build/types/babel-plugin/component-annotation.d.ts.map +1 -0
  44. package/build/types/babel-plugin/index.d.ts.map +1 -1
  45. package/build/types/core/component-annotation-vite-ast.d.ts +57 -0
  46. package/build/types/core/component-annotation-vite-ast.d.ts.map +1 -0
  47. package/build/types/core/component-annotation-vite-fragments.d.ts +3 -0
  48. package/build/types/core/component-annotation-vite-fragments.d.ts.map +1 -0
  49. package/build/types/core/component-annotation-vite-jsx.d.ts +16 -0
  50. package/build/types/core/component-annotation-vite-jsx.d.ts.map +1 -0
  51. package/build/types/core/component-annotation-vite-walk.d.ts +3 -0
  52. package/build/types/core/component-annotation-vite-walk.d.ts.map +1 -0
  53. package/build/types/core/component-annotation-vite.d.ts +6 -0
  54. package/build/types/core/component-annotation-vite.d.ts.map +1 -0
  55. package/build/types/core/index.d.ts.map +1 -1
  56. package/build/types/core/version.d.ts +1 -1
  57. package/build/types/rollup/index.d.ts +7 -1
  58. package/build/types/rollup/index.d.ts.map +1 -1
  59. package/build/types-ts3.8/babel-plugin/component-annotation.d.ts +27 -0
  60. package/build/types-ts3.8/core/component-annotation-vite-ast.d.ts +57 -0
  61. package/build/types-ts3.8/core/component-annotation-vite-fragments.d.ts +3 -0
  62. package/build/types-ts3.8/core/component-annotation-vite-jsx.d.ts +16 -0
  63. package/build/types-ts3.8/core/component-annotation-vite-walk.d.ts +3 -0
  64. package/build/types-ts3.8/core/component-annotation-vite.d.ts +6 -0
  65. package/build/types-ts3.8/core/version.d.ts +1 -1
  66. package/build/types-ts3.8/rollup/index.d.ts +7 -1
  67. package/package.json +3 -3
@@ -0,0 +1,130 @@
1
+ import { getComponentAnnotationAttributes, WEB_COMPONENT_NAME, WEB_ELEMENT_NAME, WEB_SOURCE_FILE_NAME } from '../babel-plugin/component-annotation.js';
2
+ import { isAstNode } from './component-annotation-vite-ast.js';
3
+ import { isObjectLike } from '@sentry/core';
4
+
5
+ const UNKNOWN_ELEMENT_NAME = "unknown";
6
+ const WEB_ATTRIBUTE_NAMES = [WEB_ELEMENT_NAME, WEB_COMPONENT_NAME, WEB_SOURCE_FILE_NAME];
7
+ const WEB_ATTRIBUTE_NAME_SET = new Set(WEB_ATTRIBUTE_NAMES);
8
+ function isJSXElement(value) {
9
+ return isAstNode(value) && value.type === "JSXElement";
10
+ }
11
+ function isJSXFragment(value) {
12
+ return isAstNode(value) && value.type === "JSXFragment";
13
+ }
14
+ function isJSXRoot(value) {
15
+ return isJSXElement(value) || isJSXFragment(value);
16
+ }
17
+ function getStringName(node) {
18
+ return isObjectLike(node) && typeof node.name === "string" ? node.name : null;
19
+ }
20
+ function getJSXName(name) {
21
+ if (!isAstNode(name)) {
22
+ return UNKNOWN_ELEMENT_NAME;
23
+ }
24
+ if (name.type === "JSXIdentifier") {
25
+ return getStringName(name) ?? UNKNOWN_ELEMENT_NAME;
26
+ }
27
+ if (name.type === "JSXNamespacedName") {
28
+ return getStringName(name.name) ?? UNKNOWN_ELEMENT_NAME;
29
+ }
30
+ if (name.type === "JSXMemberExpression") {
31
+ const objectName = getJSXName(name.object);
32
+ const propertyName = getJSXName(name.property);
33
+ return `${objectName}.${propertyName}`;
34
+ }
35
+ return UNKNOWN_ELEMENT_NAME;
36
+ }
37
+ function getInsertionOffset(code, openingElement) {
38
+ if (typeof openingElement.end !== "number") {
39
+ return null;
40
+ }
41
+ if (!openingElement.selfClosing) {
42
+ return openingElement.end - 1;
43
+ }
44
+ let offset = openingElement.end - 2;
45
+ while (offset > 0 && /\s/.test(code[offset] ?? "")) {
46
+ offset -= 1;
47
+ }
48
+ return code[offset] === "/" ? offset : openingElement.end - 1;
49
+ }
50
+ function isReactFragment(openingElement, fragmentContext) {
51
+ const elementName = getJSXName(openingElement.name);
52
+ if (elementName === "Fragment" || elementName === "React.Fragment") {
53
+ return true;
54
+ }
55
+ if (fragmentContext.fragmentAliases.has(elementName)) {
56
+ return true;
57
+ }
58
+ if (isObjectLike(openingElement.name) && openingElement.name.type === "JSXMemberExpression") {
59
+ const objectName = getJSXName(openingElement.name.object);
60
+ const propertyName = getJSXName(openingElement.name.property);
61
+ return propertyName === "Fragment" && (fragmentContext.reactNamespaceAliases.has(objectName) || fragmentContext.fragmentAliases.has(objectName));
62
+ }
63
+ return false;
64
+ }
65
+ function addPendingAttributes(code, openingElement, componentName, ignoredComponents, fragmentContext, sourceFileName, insertionsByOffset) {
66
+ const offset = getInsertionOffset(code, openingElement);
67
+ if (offset === null) {
68
+ return;
69
+ }
70
+ const pendingInsertion = insertionsByOffset.get(offset);
71
+ const existingAttributes = getExistingAttributeNames(openingElement);
72
+ for (const attributeName of pendingInsertion?.attributeValues.keys() ?? []) {
73
+ existingAttributes.add(attributeName);
74
+ }
75
+ const attributes = getComponentAnnotationAttributes({
76
+ attributeNames: [WEB_COMPONENT_NAME, WEB_ELEMENT_NAME, WEB_SOURCE_FILE_NAME],
77
+ componentName,
78
+ elementName: getJSXName(openingElement.name),
79
+ existingAttributes,
80
+ ignoredComponents,
81
+ isFragment: isReactFragment(openingElement, fragmentContext),
82
+ sourceFileName
83
+ });
84
+ if (attributes.length === 0) {
85
+ return;
86
+ }
87
+ const insertion = pendingInsertion ?? insertionsByOffset.set(offset, {
88
+ offset,
89
+ attributeValues: /* @__PURE__ */ new Map()
90
+ }).get(offset);
91
+ for (const [name, value] of attributes) {
92
+ insertion?.attributeValues.set(name, value);
93
+ }
94
+ }
95
+ function toAttributeInsertions(insertionsByOffset) {
96
+ return [...insertionsByOffset.values()].map(({ offset, attributeValues }) => ({
97
+ offset,
98
+ attributes: getOrderedAttributes(attributeValues)
99
+ }));
100
+ }
101
+ function getExistingAttributeNames(openingElement) {
102
+ const names = /* @__PURE__ */ new Set();
103
+ for (const attribute of openingElement.attributes ?? []) {
104
+ if (attribute.type === "JSXAttribute") {
105
+ const name = getStringName(attribute.name);
106
+ if (name) {
107
+ names.add(name);
108
+ }
109
+ }
110
+ }
111
+ return names;
112
+ }
113
+ function getOrderedAttributes(attributeValues) {
114
+ const attributes = [];
115
+ for (const name of WEB_ATTRIBUTE_NAMES) {
116
+ const value = attributeValues.get(name);
117
+ if (value) {
118
+ attributes.push([name, value]);
119
+ }
120
+ }
121
+ for (const [name, value] of attributeValues) {
122
+ if (!WEB_ATTRIBUTE_NAME_SET.has(name)) {
123
+ attributes.push([name, value]);
124
+ }
125
+ }
126
+ return attributes;
127
+ }
128
+
129
+ export { addPendingAttributes, getInsertionOffset, getJSXName, getStringName, isJSXElement, isJSXFragment, isJSXRoot, isReactFragment, toAttributeInsertions };
130
+ //# sourceMappingURL=component-annotation-vite-jsx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-annotation-vite-jsx.js","sources":["../../../src/core/component-annotation-vite-jsx.ts"],"sourcesContent":["import {\n getComponentAnnotationAttributes,\n WEB_COMPONENT_NAME,\n WEB_ELEMENT_NAME,\n WEB_SOURCE_FILE_NAME,\n} from '../babel-plugin/component-annotation';\nimport type { ComponentAnnotationAttribute } from '../babel-plugin/component-annotation';\nimport type {\n AttributeInsertion,\n FragmentContext,\n JSXElementNode,\n JSXFragmentNode,\n JSXOpeningElementNode,\n JSXRootNode,\n} from './component-annotation-vite-ast';\nimport { isAstNode, isObjectLike } from './component-annotation-vite-ast';\n\nconst UNKNOWN_ELEMENT_NAME = 'unknown';\nconst WEB_ATTRIBUTE_NAMES = [WEB_ELEMENT_NAME, WEB_COMPONENT_NAME, WEB_SOURCE_FILE_NAME] as const;\nconst WEB_ATTRIBUTE_NAME_SET = new Set<string>(WEB_ATTRIBUTE_NAMES);\n\ntype PendingInsertion = {\n offset: number;\n attributeValues: Map<string, string>;\n};\n\nexport function isJSXElement(value: unknown): value is JSXElementNode {\n return isAstNode(value) && value.type === 'JSXElement';\n}\n\nexport function isJSXFragment(value: unknown): value is JSXFragmentNode {\n return isAstNode(value) && value.type === 'JSXFragment';\n}\n\nexport function isJSXRoot(value: unknown): value is JSXRootNode {\n return isJSXElement(value) || isJSXFragment(value);\n}\n\nexport function getStringName(node: unknown): string | null {\n return isObjectLike(node) && typeof node.name === 'string' ? node.name : null;\n}\n\nexport function getJSXName(name: unknown): string {\n if (!isAstNode(name)) {\n return UNKNOWN_ELEMENT_NAME;\n }\n\n if (name.type === 'JSXIdentifier') {\n return getStringName(name) ?? UNKNOWN_ELEMENT_NAME;\n }\n\n if (name.type === 'JSXNamespacedName') {\n return getStringName(name.name) ?? UNKNOWN_ELEMENT_NAME;\n }\n\n if (name.type === 'JSXMemberExpression') {\n const objectName = getJSXName(name.object);\n const propertyName = getJSXName(name.property);\n\n return `${objectName}.${propertyName}`;\n }\n\n return UNKNOWN_ELEMENT_NAME;\n}\n\nexport function getInsertionOffset(code: string, openingElement: JSXOpeningElementNode): number | null {\n if (typeof openingElement.end !== 'number') {\n return null;\n }\n\n if (!openingElement.selfClosing) {\n return openingElement.end - 1;\n }\n\n let offset = openingElement.end - 2;\n\n while (offset > 0 && /\\s/.test(code[offset] ?? '')) {\n offset -= 1;\n }\n\n return code[offset] === '/' ? offset : openingElement.end - 1;\n}\n\nexport function isReactFragment(openingElement: JSXOpeningElementNode, fragmentContext: FragmentContext): boolean {\n const elementName = getJSXName(openingElement.name);\n\n if (elementName === 'Fragment' || elementName === 'React.Fragment') {\n return true;\n }\n\n if (fragmentContext.fragmentAliases.has(elementName)) {\n return true;\n }\n\n if (isObjectLike(openingElement.name) && openingElement.name.type === 'JSXMemberExpression') {\n const objectName = getJSXName(openingElement.name.object);\n const propertyName = getJSXName(openingElement.name.property);\n\n return (\n propertyName === 'Fragment' &&\n (fragmentContext.reactNamespaceAliases.has(objectName) || fragmentContext.fragmentAliases.has(objectName))\n );\n }\n\n return false;\n}\n\nexport function addPendingAttributes(\n code: string,\n openingElement: JSXOpeningElementNode,\n componentName: string,\n ignoredComponents: string[],\n fragmentContext: FragmentContext,\n sourceFileName: string,\n insertionsByOffset: Map<number, PendingInsertion>,\n): void {\n const offset = getInsertionOffset(code, openingElement);\n if (offset === null) {\n return;\n }\n\n const pendingInsertion = insertionsByOffset.get(offset);\n const existingAttributes = getExistingAttributeNames(openingElement);\n\n for (const attributeName of pendingInsertion?.attributeValues.keys() ?? []) {\n existingAttributes.add(attributeName);\n }\n\n const attributes = getComponentAnnotationAttributes({\n attributeNames: [WEB_COMPONENT_NAME, WEB_ELEMENT_NAME, WEB_SOURCE_FILE_NAME],\n componentName,\n elementName: getJSXName(openingElement.name),\n existingAttributes,\n ignoredComponents,\n isFragment: isReactFragment(openingElement, fragmentContext),\n sourceFileName,\n });\n\n if (attributes.length === 0) {\n return;\n }\n\n const insertion =\n pendingInsertion ??\n insertionsByOffset\n .set(offset, {\n offset,\n attributeValues: new Map(),\n })\n .get(offset);\n\n for (const [name, value] of attributes) {\n insertion?.attributeValues.set(name, value);\n }\n}\n\nexport function toAttributeInsertions(insertionsByOffset: Map<number, PendingInsertion>): AttributeInsertion[] {\n return [...insertionsByOffset.values()].map(({ offset, attributeValues }) => ({\n offset,\n attributes: getOrderedAttributes(attributeValues),\n }));\n}\n\nfunction getExistingAttributeNames(openingElement: JSXOpeningElementNode): Set<string> {\n const names = new Set<string>();\n\n for (const attribute of openingElement.attributes ?? []) {\n if (attribute.type === 'JSXAttribute') {\n const name = getStringName(attribute.name);\n if (name) {\n names.add(name);\n }\n }\n }\n\n return names;\n}\n\nfunction getOrderedAttributes(attributeValues: ReadonlyMap<string, string>): ComponentAnnotationAttribute[] {\n const attributes: ComponentAnnotationAttribute[] = [];\n\n for (const name of WEB_ATTRIBUTE_NAMES) {\n const value = attributeValues.get(name);\n if (value) {\n attributes.push([name, value]);\n }\n }\n\n for (const [name, value] of attributeValues) {\n if (!WEB_ATTRIBUTE_NAME_SET.has(name)) {\n attributes.push([name, value]);\n }\n }\n\n return attributes;\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ import { toAttributeInsertions, isJSXElement, addPendingAttributes, isJSXRoot, getStringName } from './component-annotation-vite-jsx.js';
2
+ import { walkAst, isAstNode } from './component-annotation-vite-ast.js';
3
+ import { collectFragmentContext } from './component-annotation-vite-fragments.js';
4
+ import { isObjectLike } from '@sentry/core';
5
+
6
+ function collectViteComponentAnnotationInsertions(code, ast, ignoredComponents, sourceFileName) {
7
+ const fragmentContext = collectFragmentContext(ast);
8
+ const components = collectComponentJSXRoots(ast);
9
+ const insertionsByOffset = /* @__PURE__ */ new Map();
10
+ for (const component of components) {
11
+ for (const root of component.roots) {
12
+ processJSX(code, root, component.name, ignoredComponents, fragmentContext, sourceFileName, insertionsByOffset);
13
+ }
14
+ }
15
+ return toAttributeInsertions(insertionsByOffset);
16
+ }
17
+ function getJSXRootsFromReturnArgument(argument) {
18
+ if (isJSXRoot(argument)) {
19
+ return [argument];
20
+ }
21
+ if (isObjectLike(argument) && argument.type === "ConditionalExpression") {
22
+ return [argument.consequent, argument.alternate].filter(isJSXRoot);
23
+ }
24
+ return [];
25
+ }
26
+ function getReturnedJSXFromFunction(functionNode) {
27
+ const body = functionNode.body;
28
+ if (isJSXRoot(body)) {
29
+ return [body];
30
+ }
31
+ if (!isObjectLike(body) || body.type !== "BlockStatement") {
32
+ return [];
33
+ }
34
+ const bodyStatements = Array.isArray(body.body) ? body.body : [];
35
+ const returnStatement = bodyStatements.find((statement) => {
36
+ return isAstNode(statement) && statement.type === "ReturnStatement";
37
+ });
38
+ return isObjectLike(returnStatement) ? getJSXRootsFromReturnArgument(returnStatement.argument) : [];
39
+ }
40
+ function pushFunctionComponent(components, nameNode, functionNode) {
41
+ const name = getStringName(nameNode);
42
+ if (name) {
43
+ components.push({
44
+ name,
45
+ roots: getReturnedJSXFromFunction(functionNode)
46
+ });
47
+ }
48
+ }
49
+ function collectComponentJSXRoots(ast) {
50
+ const components = [];
51
+ walkAst(ast, (node) => {
52
+ if (node.type === "FunctionDeclaration" && isObjectLike(node.id)) {
53
+ pushFunctionComponent(components, node.id, node);
54
+ return;
55
+ }
56
+ if (node.type === "VariableDeclarator" && isObjectLike(node.id)) {
57
+ if (isAstNode(node.init) && node.init.type === "ArrowFunctionExpression") {
58
+ pushFunctionComponent(components, node.id, node.init);
59
+ }
60
+ return;
61
+ }
62
+ if (node.type === "ClassDeclaration") {
63
+ pushClassComponent(components, node);
64
+ }
65
+ });
66
+ return components;
67
+ }
68
+ function pushClassComponent(components, node) {
69
+ const renderMethodBody = getClassRenderMethodBody(node);
70
+ if (!renderMethodBody) {
71
+ return;
72
+ }
73
+ const roots = [];
74
+ walkAst(renderMethodBody, (child) => {
75
+ if (child.type === "ReturnStatement" && isJSXRoot(child.argument)) {
76
+ roots.push(child.argument);
77
+ }
78
+ });
79
+ components.push({
80
+ name: getStringName(node.id) ?? "",
81
+ roots
82
+ });
83
+ }
84
+ function getClassRenderMethodBody(node) {
85
+ if (!isObjectLike(node.body) || !Array.isArray(node.body.body)) {
86
+ return null;
87
+ }
88
+ const renderMethod = node.body.body.find((member) => {
89
+ return isObjectLike(member) && isObjectLike(member.key) && getStringName(member.key) === "render" && (isObjectLike(member.value) || isObjectLike(member.body));
90
+ });
91
+ if (!isObjectLike(renderMethod)) {
92
+ return null;
93
+ }
94
+ if (isAstNode(renderMethod.value)) {
95
+ return renderMethod.value;
96
+ }
97
+ return isAstNode(renderMethod) ? renderMethod : null;
98
+ }
99
+ function processJSX(code, node, componentName, ignoredComponents, fragmentContext, sourceFileName, insertionsByOffset) {
100
+ if (isJSXElement(node)) {
101
+ addPendingAttributes(
102
+ code,
103
+ node.openingElement,
104
+ componentName,
105
+ ignoredComponents,
106
+ fragmentContext,
107
+ sourceFileName,
108
+ insertionsByOffset
109
+ );
110
+ }
111
+ for (const child of node.children ?? []) {
112
+ if (isJSXRoot(child)) {
113
+ processJSX(code, child, "", ignoredComponents, fragmentContext, sourceFileName, insertionsByOffset);
114
+ }
115
+ }
116
+ }
117
+
118
+ export { collectViteComponentAnnotationInsertions };
119
+ //# sourceMappingURL=component-annotation-vite-walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-annotation-vite-walk.js","sources":["../../../src/core/component-annotation-vite-walk.ts"],"sourcesContent":["import type { AstNode, AttributeInsertion, FragmentContext, JSXRootNode } from './component-annotation-vite-ast';\nimport {\n addPendingAttributes,\n getStringName,\n isJSXElement,\n isJSXRoot,\n toAttributeInsertions,\n} from './component-annotation-vite-jsx';\nimport { isAstNode, isObjectLike, walkAst } from './component-annotation-vite-ast';\nimport { collectFragmentContext } from './component-annotation-vite-fragments';\n\ntype ComponentJSXRoots = { name: string; roots: JSXRootNode[] };\n\nexport function collectViteComponentAnnotationInsertions(\n code: string,\n ast: AstNode,\n ignoredComponents: string[],\n sourceFileName: string,\n): AttributeInsertion[] {\n const fragmentContext = collectFragmentContext(ast);\n const components = collectComponentJSXRoots(ast);\n const insertionsByOffset = new Map<number, { offset: number; attributeValues: Map<string, string> }>();\n\n for (const component of components) {\n for (const root of component.roots) {\n processJSX(code, root, component.name, ignoredComponents, fragmentContext, sourceFileName, insertionsByOffset);\n }\n }\n\n return toAttributeInsertions(insertionsByOffset);\n}\n\nfunction getJSXRootsFromReturnArgument(argument: unknown): JSXRootNode[] {\n if (isJSXRoot(argument)) {\n return [argument];\n }\n\n if (isObjectLike(argument) && argument.type === 'ConditionalExpression') {\n return [argument.consequent, argument.alternate].filter(isJSXRoot);\n }\n\n return [];\n}\n\nfunction getReturnedJSXFromFunction(functionNode: AstNode): JSXRootNode[] {\n const body = functionNode.body;\n\n if (isJSXRoot(body)) {\n return [body];\n }\n\n if (!isObjectLike(body) || body.type !== 'BlockStatement') {\n return [];\n }\n\n const bodyStatements = Array.isArray(body.body) ? body.body : [];\n const returnStatement = bodyStatements.find(statement => {\n return isAstNode(statement) && statement.type === 'ReturnStatement';\n });\n\n return isObjectLike(returnStatement) ? getJSXRootsFromReturnArgument(returnStatement.argument) : [];\n}\n\nfunction pushFunctionComponent(components: ComponentJSXRoots[], nameNode: unknown, functionNode: AstNode): void {\n const name = getStringName(nameNode);\n\n if (name) {\n components.push({\n name,\n roots: getReturnedJSXFromFunction(functionNode),\n });\n }\n}\n\nfunction collectComponentJSXRoots(ast: AstNode): ComponentJSXRoots[] {\n const components: ComponentJSXRoots[] = [];\n\n walkAst(ast, node => {\n if (node.type === 'FunctionDeclaration' && isObjectLike(node.id)) {\n pushFunctionComponent(components, node.id, node);\n return;\n }\n\n if (node.type === 'VariableDeclarator' && isObjectLike(node.id)) {\n if (isAstNode(node.init) && node.init.type === 'ArrowFunctionExpression') {\n pushFunctionComponent(components, node.id, node.init);\n }\n\n return;\n }\n\n if (node.type === 'ClassDeclaration') {\n pushClassComponent(components, node);\n }\n });\n\n return components;\n}\n\nfunction pushClassComponent(components: ComponentJSXRoots[], node: AstNode): void {\n const renderMethodBody = getClassRenderMethodBody(node);\n\n if (!renderMethodBody) {\n return;\n }\n\n const roots: JSXRootNode[] = [];\n\n walkAst(renderMethodBody, child => {\n if (child.type === 'ReturnStatement' && isJSXRoot(child.argument)) {\n roots.push(child.argument);\n }\n });\n\n components.push({\n name: getStringName(node.id) ?? '',\n roots,\n });\n}\n\nfunction getClassRenderMethodBody(node: AstNode): AstNode | null {\n if (!isObjectLike(node.body) || !Array.isArray(node.body.body)) {\n return null;\n }\n\n const renderMethod = node.body.body.find(member => {\n return (\n isObjectLike(member) &&\n isObjectLike(member.key) &&\n getStringName(member.key) === 'render' &&\n (isObjectLike(member.value) || isObjectLike(member.body))\n );\n });\n\n if (!isObjectLike(renderMethod)) {\n return null;\n }\n\n if (isAstNode(renderMethod.value)) {\n return renderMethod.value;\n }\n\n return isAstNode(renderMethod) ? renderMethod : null;\n}\n\nfunction processJSX(\n code: string,\n node: JSXRootNode,\n componentName: string,\n ignoredComponents: string[],\n fragmentContext: FragmentContext,\n sourceFileName: string,\n insertionsByOffset: Map<number, { offset: number; attributeValues: Map<string, string> }>,\n): void {\n if (isJSXElement(node)) {\n addPendingAttributes(\n code,\n node.openingElement,\n componentName,\n ignoredComponents,\n fragmentContext,\n sourceFileName,\n insertionsByOffset,\n );\n }\n\n for (const child of node.children ?? []) {\n if (isJSXRoot(child)) {\n processJSX(code, child, '', ignoredComponents, fragmentContext, sourceFileName, insertionsByOffset);\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import path__default from 'node:path';
2
+ import MagicString from 'magic-string';
3
+ import { KNOWN_INCOMPATIBLE_PLUGINS } from '../babel-plugin/constants.js';
4
+ import { stripQueryAndHashFromPath } from './utils.js';
5
+ import { isAstNode } from './component-annotation-vite-ast.js';
6
+ import { collectViteComponentAnnotationInsertions } from './component-annotation-vite-walk.js';
7
+
8
+ const JSX_TAG_START_REGEXP = /<[$_\p{ID_Start}][$_\u200c\u200d\p{ID_Continue}.:-]*|<>/u;
9
+ const JSX_FILE_REGEXP = /\.[jt]sx$/;
10
+ function isViteAnnotationFile(idWithoutQueryAndHash) {
11
+ if (idWithoutQueryAndHash.match(/\\node_modules\\|\/node_modules\//)) {
12
+ return false;
13
+ }
14
+ return JSX_FILE_REGEXP.test(idWithoutQueryAndHash);
15
+ }
16
+ function shouldTryParse(code) {
17
+ return JSX_TAG_START_REGEXP.test(code);
18
+ }
19
+ function shouldSkipIncompatibleFile(idWithoutQueryAndHash) {
20
+ return KNOWN_INCOMPATIBLE_PLUGINS.some((pluginName) => {
21
+ return idWithoutQueryAndHash.includes(`/node_modules/${pluginName}/`) || idWithoutQueryAndHash.includes(`\\node_modules\\${pluginName}\\`);
22
+ });
23
+ }
24
+ function escapeAttributeValue(value) {
25
+ return value.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
26
+ }
27
+ function makeAttributeText(code, insertionOffset, attributes) {
28
+ const previousCharIsWhitespace = insertionOffset > 0 && /\s/.test(code[insertionOffset - 1] ?? "");
29
+ const prefix = previousCharIsWhitespace ? "" : " ";
30
+ const suffix = previousCharIsWhitespace && code[insertionOffset] === "/" ? " " : "";
31
+ const attributeText = attributes.map(([name, value]) => `${name}="${escapeAttributeValue(value)}"`).join(" ");
32
+ return `${prefix}${attributeText}${suffix}`;
33
+ }
34
+ function getMagicString(code, meta) {
35
+ if (meta?.magicString) {
36
+ return { magicString: meta.magicString, isNative: true };
37
+ }
38
+ return { magicString: new MagicString(code), isNative: false };
39
+ }
40
+ async function annotateWithViteParser(code, id, ignoredComponents, parseAstAsync, meta) {
41
+ const idWithoutQueryAndHash = stripQueryAndHashFromPath(id);
42
+ if (!idWithoutQueryAndHash || !isViteAnnotationFile(idWithoutQueryAndHash) || !shouldTryParse(code) || shouldSkipIncompatibleFile(idWithoutQueryAndHash)) {
43
+ return null;
44
+ }
45
+ const ast = await parseAstAsync(code, {
46
+ lang: idWithoutQueryAndHash.endsWith(".jsx") ? "jsx" : "tsx"
47
+ });
48
+ if (!isAstNode(ast)) {
49
+ return void 0;
50
+ }
51
+ const insertions = collectViteComponentAnnotationInsertions(
52
+ code,
53
+ ast,
54
+ ignoredComponents,
55
+ path__default.basename(idWithoutQueryAndHash)
56
+ );
57
+ if (insertions.length === 0) {
58
+ return null;
59
+ }
60
+ const { magicString, isNative } = getMagicString(code, meta);
61
+ for (const insertion of insertions) {
62
+ magicString.appendLeft(insertion.offset, makeAttributeText(code, insertion.offset, insertion.attributes));
63
+ }
64
+ if (isNative) {
65
+ return { code: magicString };
66
+ }
67
+ return {
68
+ code: magicString.toString(),
69
+ map: magicString.generateMap?.({
70
+ file: id,
71
+ source: idWithoutQueryAndHash,
72
+ includeContent: true,
73
+ hires: true
74
+ })
75
+ };
76
+ }
77
+ function createViteComponentNameAnnotateHooks(ignoredComponents, getParseAstAsync) {
78
+ return {
79
+ async transform(code, id, meta) {
80
+ try {
81
+ const parseAstAsync = await getParseAstAsync();
82
+ if (!parseAstAsync) {
83
+ return void 0;
84
+ }
85
+ return await annotateWithViteParser(code, id, ignoredComponents, parseAstAsync, meta);
86
+ } catch {
87
+ return void 0;
88
+ }
89
+ }
90
+ };
91
+ }
92
+
93
+ export { createViteComponentNameAnnotateHooks };
94
+ //# sourceMappingURL=component-annotation-vite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-annotation-vite.js","sources":["../../../src/core/component-annotation-vite.ts"],"sourcesContent":["import path from 'node:path';\n\nimport MagicString from 'magic-string';\n\nimport { KNOWN_INCOMPATIBLE_PLUGINS } from '../babel-plugin/constants';\nimport { stripQueryAndHashFromPath } from './utils';\nimport { isAstNode } from './component-annotation-vite-ast';\nimport { collectViteComponentAnnotationInsertions } from './component-annotation-vite-walk';\nimport type {\n AttributeInsertion,\n ComponentAnnotationTransformMeta,\n ComponentAnnotationTransformResult,\n MagicStringLike,\n ParseAstAsync,\n} from './component-annotation-vite-ast';\n\nexport type {\n ComponentAnnotationTransformMeta,\n ComponentAnnotationTransformResult,\n} from './component-annotation-vite-ast';\n\n// Keep this as a superset of JSX tag starts Babel can annotate, because a miss suppresses Babel fallback.\nconst JSX_TAG_START_REGEXP = /<[$_\\p{ID_Start}][$_\\u200c\\u200d\\p{ID_Continue}.:-]*|<>/u;\nconst JSX_FILE_REGEXP = /\\.[jt]sx$/;\n\nfunction isViteAnnotationFile(idWithoutQueryAndHash: string): boolean {\n if (idWithoutQueryAndHash.match(/\\\\node_modules\\\\|\\/node_modules\\//)) {\n return false;\n }\n\n return JSX_FILE_REGEXP.test(idWithoutQueryAndHash);\n}\n\nfunction shouldTryParse(code: string): boolean {\n return JSX_TAG_START_REGEXP.test(code);\n}\n\nfunction shouldSkipIncompatibleFile(idWithoutQueryAndHash: string): boolean {\n return KNOWN_INCOMPATIBLE_PLUGINS.some(pluginName => {\n return (\n idWithoutQueryAndHash.includes(`/node_modules/${pluginName}/`) ||\n idWithoutQueryAndHash.includes(`\\\\node_modules\\\\${pluginName}\\\\`)\n );\n });\n}\n\nfunction escapeAttributeValue(value: string): string {\n return value.replace(/&/g, '&amp;').replace(/\"/g, '&quot;');\n}\n\nfunction makeAttributeText(\n code: string,\n insertionOffset: number,\n attributes: AttributeInsertion['attributes'],\n): string {\n const previousCharIsWhitespace = insertionOffset > 0 && /\\s/.test(code[insertionOffset - 1] ?? '');\n const prefix = previousCharIsWhitespace ? '' : ' ';\n const suffix = previousCharIsWhitespace && code[insertionOffset] === '/' ? ' ' : '';\n const attributeText = attributes.map(([name, value]) => `${name}=\"${escapeAttributeValue(value)}\"`).join(' ');\n\n return `${prefix}${attributeText}${suffix}`;\n}\n\nfunction getMagicString(\n code: string,\n meta?: ComponentAnnotationTransformMeta,\n): { magicString: MagicStringLike; isNative: boolean } {\n if (meta?.magicString) {\n return { magicString: meta.magicString, isNative: true };\n }\n\n return { magicString: new MagicString(code), isNative: false };\n}\n\nasync function annotateWithViteParser(\n code: string,\n id: string,\n ignoredComponents: string[],\n parseAstAsync: ParseAstAsync,\n meta?: ComponentAnnotationTransformMeta,\n): Promise<ComponentAnnotationTransformResult> {\n const idWithoutQueryAndHash = stripQueryAndHashFromPath(id);\n\n if (\n !idWithoutQueryAndHash ||\n !isViteAnnotationFile(idWithoutQueryAndHash) ||\n !shouldTryParse(code) ||\n shouldSkipIncompatibleFile(idWithoutQueryAndHash)\n ) {\n return null;\n }\n\n const ast = await parseAstAsync(code, {\n lang: idWithoutQueryAndHash.endsWith('.jsx') ? 'jsx' : 'tsx',\n });\n\n // Fall through to the Babel fallback (return undefined, not null) when the parser yields an\n // unexpected result, mirroring the catch path — null would suppress Babel and drop annotations.\n if (!isAstNode(ast)) {\n return undefined;\n }\n\n const insertions = collectViteComponentAnnotationInsertions(\n code,\n ast,\n ignoredComponents,\n path.basename(idWithoutQueryAndHash),\n );\n\n if (insertions.length === 0) {\n return null;\n }\n\n const { magicString, isNative } = getMagicString(code, meta);\n\n for (const insertion of insertions) {\n magicString.appendLeft(insertion.offset, makeAttributeText(code, insertion.offset, insertion.attributes));\n }\n\n if (isNative) {\n return { code: magicString as unknown as string };\n }\n\n return {\n code: magicString.toString(),\n map: magicString.generateMap?.({\n file: id,\n source: idWithoutQueryAndHash,\n includeContent: true,\n hires: true,\n }),\n };\n}\n\nexport function createViteComponentNameAnnotateHooks(\n ignoredComponents: string[],\n getParseAstAsync: () => Promise<ParseAstAsync | null>,\n): {\n transform(\n code: string,\n id: string,\n meta?: ComponentAnnotationTransformMeta,\n ): Promise<ComponentAnnotationTransformResult>;\n} {\n return {\n async transform(code, id, meta) {\n try {\n const parseAstAsync = await getParseAstAsync();\n\n if (!parseAstAsync) {\n return undefined;\n }\n\n return await annotateWithViteParser(code, id, ignoredComponents, parseAstAsync, meta);\n } catch {\n return undefined;\n }\n },\n };\n}\n"],"names":["path"],"mappings":"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"}
@@ -1,5 +1,3 @@
1
- import { transformAsync } from '@babel/core';
2
- import componentNameAnnotatePlugin from '../babel-plugin/index.js';
3
1
  import SentryCli from '@sentry/cli';
4
2
  import { debug } from '@sentry/core';
5
3
  import * as fs from 'fs';
@@ -8,8 +6,22 @@ export { generateModuleMetadataInjectorCode, generateReleaseInjectorCode, replac
8
6
  export { globFiles } from './glob.js';
9
7
  export { createSentryBuildPluginManager } from './build-plugin-manager.js';
10
8
  export { createDebugIdUploadFunction } from './debug-id-upload.js';
11
- import { experimentalComponentNameAnnotatePlugin } from '../babel-plugin/experimental.js';
12
9
 
10
+ let babelAnnotationRuntimePromise;
11
+ function loadBabelAnnotationRuntime() {
12
+ if (!babelAnnotationRuntimePromise) {
13
+ babelAnnotationRuntimePromise = Promise.all([import('@babel/core'), import('../babel-plugin/index.js')]).then(
14
+ ([babel, babelPlugin]) => {
15
+ return {
16
+ transformAsync: babel.transformAsync,
17
+ componentNameAnnotatePlugin: babelPlugin.default,
18
+ experimentalComponentNameAnnotatePlugin: babelPlugin.experimentalComponentNameAnnotatePlugin
19
+ };
20
+ }
21
+ );
22
+ }
23
+ return babelAnnotationRuntimePromise;
24
+ }
13
25
  function sentryCliBinaryExists() {
14
26
  return fs.existsSync(SentryCli.getPath());
15
27
  }
@@ -46,6 +58,7 @@ function createComponentNameAnnotateHooks(ignoredComponents, injectIntoHtml) {
46
58
  } else if (idWithoutQueryAndHash.endsWith(".tsx")) {
47
59
  parserPlugins.push("jsx", "typescript");
48
60
  }
61
+ const { transformAsync, componentNameAnnotatePlugin, experimentalComponentNameAnnotatePlugin } = await loadBabelAnnotationRuntime();
49
62
  const plugin = injectIntoHtml ? experimentalComponentNameAnnotatePlugin : componentNameAnnotatePlugin;
50
63
  try {
51
64
  const result = await transformAsync(code, {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/core/index.ts"],"sourcesContent":["import { transformAsync } from '@babel/core';\nimport componentNameAnnotatePlugin, { experimentalComponentNameAnnotatePlugin } from '../babel-plugin';\nimport SentryCli from '@sentry/cli';\nimport { debug } from '@sentry/core';\nimport * as fs from 'fs';\nimport { CodeInjection, containsOnlyImports, stripQueryAndHashFromPath } from './utils';\n\n/**\n * Determines whether the Sentry CLI binary is in its expected location.\n * This function is useful since `@sentry/cli` installs the binary via a post-install\n * script and post-install scripts may not always run. E.g. with `npm i --ignore-scripts`.\n */\nexport function sentryCliBinaryExists(): boolean {\n return fs.existsSync(SentryCli.getPath());\n}\n\n// We need to be careful not to inject the snippet before any `\"use strict\";`s.\n// As an additional complication `\"use strict\";`s may come after any number of comments.\nexport const COMMENT_USE_STRICT_REGEX =\n // Note: CodeQL complains that this regex potentially has n^2 runtime. This likely won't affect realistic files.\n /^(?:\\s*|\\/\\*(?:.|\\r|\\n)*?\\*\\/|\\/\\/.*[\\n\\r])*(?:\"[^\"]*\";|'[^']*';)?/;\n\n/**\n * Checks if a file is a JavaScript file based on its extension.\n * Handles query strings and hashes in the filename.\n */\nexport function isJsFile(fileName: string): boolean {\n const cleanFileName = stripQueryAndHashFromPath(fileName);\n return ['.js', '.mjs', '.cjs'].some(ext => cleanFileName.endsWith(ext));\n}\n\n/**\n * Checks if a chunk should be skipped for code injection\n *\n * This is necessary to handle Vite's MPA (multi-page application) mode where\n * HTML entry points create \"facade\" chunks that should not contain injected code.\n * See: https://github.com/getsentry/sentry-javascript-bundler-plugins/issues/829\n *\n * However, in SPA mode, the main bundle also has an HTML facade but contains\n * substantial application code. We should NOT skip injection for these bundles.\n *\n * @param code - The chunk's code content\n * @param facadeModuleId - The facade module ID (if any) - HTML files create facade chunks\n * @returns true if the chunk should be skipped\n */\nexport function shouldSkipCodeInjection(code: string, facadeModuleId: string | null | undefined): boolean {\n // Skip empty chunks - these are placeholder chunks that should be optimized away\n if (code.trim().length === 0) {\n return true;\n }\n\n // For HTML facade chunks, only skip if they contain only import statements\n if (facadeModuleId && stripQueryAndHashFromPath(facadeModuleId).endsWith('.html')) {\n return containsOnlyImports(code);\n }\n\n return false;\n}\n\nexport { globFiles } from './glob';\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function createComponentNameAnnotateHooks(ignoredComponents: string[], injectIntoHtml: boolean) {\n type ParserPlugins = NonNullable<NonNullable<Parameters<typeof transformAsync>[1]>['parserOpts']>['plugins'];\n\n return {\n async transform(this: void, code: string, id: string) {\n // id may contain query and hash which will trip up our file extension logic below\n const idWithoutQueryAndHash = stripQueryAndHashFromPath(id);\n\n if (idWithoutQueryAndHash.match(/\\\\node_modules\\\\|\\/node_modules\\//)) {\n return null;\n }\n\n // We will only apply this plugin on jsx and tsx files\n if (!['.jsx', '.tsx'].some(ending => idWithoutQueryAndHash.endsWith(ending))) {\n return null;\n }\n\n const parserPlugins: ParserPlugins = [];\n if (idWithoutQueryAndHash.endsWith('.jsx')) {\n parserPlugins.push('jsx');\n } else if (idWithoutQueryAndHash.endsWith('.tsx')) {\n parserPlugins.push('jsx', 'typescript');\n }\n\n const plugin = injectIntoHtml ? experimentalComponentNameAnnotatePlugin : componentNameAnnotatePlugin;\n\n try {\n const result = await transformAsync(code, {\n plugins: [[plugin, { ignoredComponents }]],\n filename: id,\n parserOpts: {\n sourceType: 'module',\n allowAwaitOutsideFunction: true,\n plugins: parserPlugins,\n },\n generatorOpts: {\n decoratorsBeforeExport: true,\n },\n sourceMaps: true,\n });\n\n return {\n code: result?.code ?? code,\n map: result?.map,\n };\n } catch (e) {\n debug.error(`Failed to apply react annotate plugin`, e);\n }\n\n return { code };\n },\n };\n}\n\nexport function getDebugIdSnippet(debugId: string): CodeInjection {\n return new CodeInjection(\n `var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\"${debugId}\",e._sentryDebugIdIdentifier=\"sentry-dbid-${debugId}\");`,\n );\n}\n\nexport type { Logger } from './logger';\nexport type { Options, SentrySDKBuildFlags } from './types';\nexport {\n CodeInjection,\n replaceBooleanFlagsInCode,\n stringToUUID,\n generateReleaseInjectorCode,\n generateModuleMetadataInjectorCode,\n} from './utils';\nexport { createSentryBuildPluginManager } from './build-plugin-manager';\nexport { createDebugIdUploadFunction } from './debug-id-upload';\n"],"names":[],"mappings":";;;;;;;;;;;;AAYO,SAAS,qBAAA,GAAiC;AAC/C,EAAA,OAAO,EAAA,CAAG,UAAA,CAAW,SAAA,CAAU,OAAA,EAAS,CAAA;AAC1C;AAIO,MAAM,wBAAA;AAAA;AAAA,EAEX;AAAA;AAMK,SAAS,SAAS,QAAA,EAA2B;AAClD,EAAA,MAAM,aAAA,GAAgB,0BAA0B,QAAQ,CAAA;AACxD,EAAA,OAAO,CAAC,KAAA,EAAO,MAAA,EAAQ,MAAM,CAAA,CAAE,KAAK,CAAA,GAAA,KAAO,aAAA,CAAc,QAAA,CAAS,GAAG,CAAC,CAAA;AACxE;AAgBO,SAAS,uBAAA,CAAwB,MAAc,cAAA,EAAoD;AAExG,EAAA,IAAI,IAAA,CAAK,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA,EAAG;AAC5B,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,kBAAkB,yBAAA,CAA0B,cAAc,CAAA,CAAE,QAAA,CAAS,OAAO,CAAA,EAAG;AACjF,IAAA,OAAO,oBAAoB,IAAI,CAAA;AAAA,EACjC;AAEA,EAAA,OAAO,KAAA;AACT;AAKO,SAAS,gCAAA,CAAiC,mBAA6B,cAAA,EAAyB;AAGrG,EAAA,OAAO;AAAA,IACL,MAAM,SAAA,CAAsB,IAAA,EAAc,EAAA,EAAY;AAEpD,MAAA,MAAM,qBAAA,GAAwB,0BAA0B,EAAE,CAAA;AAE1D,MAAA,IAAI,qBAAA,CAAsB,KAAA,CAAM,mCAAmC,CAAA,EAAG;AACpE,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,IAAI,CAAC,CAAC,MAAA,EAAQ,MAAM,CAAA,CAAE,IAAA,CAAK,CAAA,MAAA,KAAU,qBAAA,CAAsB,QAAA,CAAS,MAAM,CAAC,CAAA,EAAG;AAC5E,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAM,gBAA+B,EAAC;AACtC,MAAA,IAAI,qBAAA,CAAsB,QAAA,CAAS,MAAM,CAAA,EAAG;AAC1C,QAAA,aAAA,CAAc,KAAK,KAAK,CAAA;AAAA,MAC1B,CAAA,MAAA,IAAW,qBAAA,CAAsB,QAAA,CAAS,MAAM,CAAA,EAAG;AACjD,QAAA,aAAA,CAAc,IAAA,CAAK,OAAO,YAAY,CAAA;AAAA,MACxC;AAEA,MAAA,MAAM,MAAA,GAAS,iBAAiB,uCAAA,GAA0C,2BAAA;AAE1E,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,IAAA,EAAM;AAAA,UACxC,SAAS,CAAC,CAAC,QAAQ,EAAE,iBAAA,EAAmB,CAAC,CAAA;AAAA,UACzC,QAAA,EAAU,EAAA;AAAA,UACV,UAAA,EAAY;AAAA,YACV,UAAA,EAAY,QAAA;AAAA,YACZ,yBAAA,EAA2B,IAAA;AAAA,YAC3B,OAAA,EAAS;AAAA,WACX;AAAA,UACA,aAAA,EAAe;AAAA,YACb,sBAAA,EAAwB;AAAA,WAC1B;AAAA,UACA,UAAA,EAAY;AAAA,SACb,CAAA;AAED,QAAA,OAAO;AAAA,UACL,IAAA,EAAM,QAAQ,IAAA,IAAQ,IAAA;AAAA,UACtB,KAAK,MAAA,EAAQ;AAAA,SACf;AAAA,MACF,SAAS,CAAA,EAAG;AACV,QAAA,KAAA,CAAM,KAAA,CAAM,yCAAyC,CAAC,CAAA;AAAA,MACxD;AAEA,MAAA,OAAO,EAAE,IAAA,EAAK;AAAA,IAChB;AAAA,GACF;AACF;AAEO,SAAS,kBAAkB,OAAA,EAAgC;AAChE,EAAA,OAAO,IAAI,aAAA;AAAA,IACT,CAAA,4FAAA,EAA+F,OAAO,CAAA,0CAAA,EAA6C,OAAO,CAAA,GAAA;AAAA,GAC5J;AACF;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/core/index.ts"],"sourcesContent":["import SentryCli from '@sentry/cli';\nimport { debug } from '@sentry/core';\nimport * as fs from 'fs';\nimport { CodeInjection, containsOnlyImports, stripQueryAndHashFromPath } from './utils';\nimport type { transformAsync as babelTransformAsync } from '@babel/core';\nimport type componentNameAnnotatePlugin from '../babel-plugin';\nimport type { experimentalComponentNameAnnotatePlugin } from '../babel-plugin';\n\ntype BabelTransformAsync = typeof babelTransformAsync;\ntype BabelParserPlugins = NonNullable<NonNullable<Parameters<BabelTransformAsync>[1]>['parserOpts']>['plugins'];\ntype BabelAnnotationRuntime = {\n transformAsync: BabelTransformAsync;\n componentNameAnnotatePlugin: typeof componentNameAnnotatePlugin;\n experimentalComponentNameAnnotatePlugin: typeof experimentalComponentNameAnnotatePlugin;\n};\n\nlet babelAnnotationRuntimePromise: Promise<BabelAnnotationRuntime> | undefined;\n\nfunction loadBabelAnnotationRuntime(): Promise<BabelAnnotationRuntime> {\n if (!babelAnnotationRuntimePromise) {\n babelAnnotationRuntimePromise = Promise.all([import('@babel/core'), import('../babel-plugin')]).then(\n ([babel, babelPlugin]) => {\n return {\n transformAsync: babel.transformAsync,\n componentNameAnnotatePlugin: babelPlugin.default,\n experimentalComponentNameAnnotatePlugin: babelPlugin.experimentalComponentNameAnnotatePlugin,\n };\n },\n );\n }\n\n return babelAnnotationRuntimePromise;\n}\n\n/**\n * Determines whether the Sentry CLI binary is in its expected location.\n * This function is useful since `@sentry/cli` installs the binary via a post-install\n * script and post-install scripts may not always run. E.g. with `npm i --ignore-scripts`.\n */\nexport function sentryCliBinaryExists(): boolean {\n return fs.existsSync(SentryCli.getPath());\n}\n\n// We need to be careful not to inject the snippet before any `\"use strict\";`s.\n// As an additional complication `\"use strict\";`s may come after any number of comments.\nexport const COMMENT_USE_STRICT_REGEX =\n // Note: CodeQL complains that this regex potentially has n^2 runtime. This likely won't affect realistic files.\n /^(?:\\s*|\\/\\*(?:.|\\r|\\n)*?\\*\\/|\\/\\/.*[\\n\\r])*(?:\"[^\"]*\";|'[^']*';)?/;\n\n/**\n * Checks if a file is a JavaScript file based on its extension.\n * Handles query strings and hashes in the filename.\n */\nexport function isJsFile(fileName: string): boolean {\n const cleanFileName = stripQueryAndHashFromPath(fileName);\n return ['.js', '.mjs', '.cjs'].some(ext => cleanFileName.endsWith(ext));\n}\n\n/**\n * Checks if a chunk should be skipped for code injection\n *\n * This is necessary to handle Vite's MPA (multi-page application) mode where\n * HTML entry points create \"facade\" chunks that should not contain injected code.\n * See: https://github.com/getsentry/sentry-javascript-bundler-plugins/issues/829\n *\n * However, in SPA mode, the main bundle also has an HTML facade but contains\n * substantial application code. We should NOT skip injection for these bundles.\n *\n * @param code - The chunk's code content\n * @param facadeModuleId - The facade module ID (if any) - HTML files create facade chunks\n * @returns true if the chunk should be skipped\n */\nexport function shouldSkipCodeInjection(code: string, facadeModuleId: string | null | undefined): boolean {\n // Skip empty chunks - these are placeholder chunks that should be optimized away\n if (code.trim().length === 0) {\n return true;\n }\n\n // For HTML facade chunks, only skip if they contain only import statements\n if (facadeModuleId && stripQueryAndHashFromPath(facadeModuleId).endsWith('.html')) {\n return containsOnlyImports(code);\n }\n\n return false;\n}\n\nexport { globFiles } from './glob';\n\n// eslint-disable-next-line @typescript-eslint/explicit-function-return-type\nexport function createComponentNameAnnotateHooks(ignoredComponents: string[], injectIntoHtml: boolean) {\n return {\n async transform(this: void, code: string, id: string) {\n // id may contain query and hash which will trip up our file extension logic below\n const idWithoutQueryAndHash = stripQueryAndHashFromPath(id);\n\n if (idWithoutQueryAndHash.match(/\\\\node_modules\\\\|\\/node_modules\\//)) {\n return null;\n }\n\n // We will only apply this plugin on jsx and tsx files\n if (!['.jsx', '.tsx'].some(ending => idWithoutQueryAndHash.endsWith(ending))) {\n return null;\n }\n\n const parserPlugins: BabelParserPlugins = [];\n if (idWithoutQueryAndHash.endsWith('.jsx')) {\n parserPlugins.push('jsx');\n } else if (idWithoutQueryAndHash.endsWith('.tsx')) {\n parserPlugins.push('jsx', 'typescript');\n }\n\n const { transformAsync, componentNameAnnotatePlugin, experimentalComponentNameAnnotatePlugin } =\n await loadBabelAnnotationRuntime();\n const plugin = injectIntoHtml ? experimentalComponentNameAnnotatePlugin : componentNameAnnotatePlugin;\n\n try {\n const result = await transformAsync(code, {\n plugins: [[plugin, { ignoredComponents }]],\n filename: id,\n parserOpts: {\n sourceType: 'module',\n allowAwaitOutsideFunction: true,\n plugins: parserPlugins,\n },\n generatorOpts: {\n decoratorsBeforeExport: true,\n },\n sourceMaps: true,\n });\n\n return {\n code: result?.code ?? code,\n map: result?.map,\n };\n } catch (e) {\n debug.error(`Failed to apply react annotate plugin`, e);\n }\n\n return { code };\n },\n };\n}\n\nexport function getDebugIdSnippet(debugId: string): CodeInjection {\n return new CodeInjection(\n `var n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]=\"${debugId}\",e._sentryDebugIdIdentifier=\"sentry-dbid-${debugId}\");`,\n );\n}\n\nexport type { Logger } from './logger';\nexport type { Options, SentrySDKBuildFlags } from './types';\nexport {\n CodeInjection,\n replaceBooleanFlagsInCode,\n stringToUUID,\n generateReleaseInjectorCode,\n generateModuleMetadataInjectorCode,\n} from './utils';\nexport { createSentryBuildPluginManager } from './build-plugin-manager';\nexport { createDebugIdUploadFunction } from './debug-id-upload';\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- const LIB_VERSION = "10.64.0";
1
+ const LIB_VERSION = "10.66.0";
2
2
 
3
3
  export { LIB_VERSION };
4
4
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sources":["../../../src/core/version.ts"],"sourcesContent":["export const LIB_VERSION = \"10.64.0\";\n"],"names":[],"mappings":"AAAO,MAAM,WAAA,GAAc;;;;"}
1
+ {"version":3,"file":"version.js","sources":["../../../src/core/version.ts"],"sourcesContent":["export const LIB_VERSION = \"10.66.0\";\n"],"names":[],"mappings":"AAAO,MAAM,WAAA,GAAc;;;;"}
@@ -1 +1 @@
1
- {"type":"module","version":"10.64.0","sideEffects":["./sentry-release-injection-file.js","./sentry-esbuild-debugid-injection-file.js"]}
1
+ {"type":"module","version":"10.66.0","sideEffects":["./sentry-release-injection-file.js","./sentry-esbuild-debugid-injection-file.js"]}
@@ -8,6 +8,8 @@ import { CodeInjection, generateReleaseInjectorCode, generateModuleMetadataInjec
8
8
  import { globFiles } from '../core/glob.js';
9
9
  import { createDebugIdUploadFunction } from '../core/debug-id-upload.js';
10
10
 
11
+ let viteParseAstAsyncPromise;
12
+ const JS_MODULE_ID_FILTER = /\.[cm]?[jt]sx?(?:[?#].*)?$/;
11
13
  function hasExistingDebugID(code) {
12
14
  const chunkStartSnippet = code.slice(0, 6e3);
13
15
  const chunkEndSnippet = code.slice(-500);
@@ -25,6 +27,23 @@ function getRollupMajorVersion() {
25
27
  }
26
28
  return void 0;
27
29
  }
30
+ function getViteParseAstAsync() {
31
+ if (!viteParseAstAsyncPromise) {
32
+ viteParseAstAsyncPromise = Promise.resolve().then(async () => {
33
+ const viteModule = createRequire(import.meta.url)("vite");
34
+ if (typeof viteModule.parseAstAsync !== "function") {
35
+ return null;
36
+ }
37
+ try {
38
+ await viteModule.parseAstAsync("const x = <div />;", { lang: "tsx" });
39
+ } catch {
40
+ return null;
41
+ }
42
+ return viteModule.parseAstAsync;
43
+ }).catch(() => null);
44
+ }
45
+ return viteParseAstAsyncPromise;
46
+ }
28
47
  function _rollupPluginInternal(userOptions = {}, buildTool, buildToolMajorVersion) {
29
48
  const sentryBuildPluginManager = createSentryBuildPluginManager(userOptions, {
30
49
  loggerPrefix: userOptions._metaOptions?.loggerPrefixOverride ?? `[sentry-${buildTool}-plugin]`,
@@ -71,14 +90,40 @@ function _rollupPluginInternal(userOptions = {}, buildTool, buildToolMajorVersio
71
90
  options.reactComponentAnnotation?.ignoredComponents || [],
72
91
  !!options.reactComponentAnnotation?._experimentalInjectIntoHtml
73
92
  ) : void 0;
93
+ const transformViteAnnotations = options.reactComponentAnnotation?.enabled && buildTool === "vite" && buildToolMajorVersion === "8" && !options.reactComponentAnnotation?._experimentalInjectIntoHtml ? /* @__PURE__ */ (() => {
94
+ let viteAnnotationHooksPromise;
95
+ return {
96
+ transform(code, id, meta) {
97
+ if (!viteAnnotationHooksPromise) {
98
+ viteAnnotationHooksPromise = import('../core/component-annotation-vite.js').then(
99
+ ({ createViteComponentNameAnnotateHooks }) => createViteComponentNameAnnotateHooks(
100
+ options.reactComponentAnnotation?.ignoredComponents || [],
101
+ getViteParseAstAsync
102
+ )
103
+ );
104
+ }
105
+ return viteAnnotationHooksPromise.then((hooks) => hooks.transform(code, id, meta));
106
+ }
107
+ };
108
+ })() : void 0;
74
109
  const transformReplace = Object.keys(replacementValues).length > 0;
75
110
  const shouldTransform = transformAnnotations || transformReplace;
76
111
  function buildStart() {
77
112
  void sentryBuildPluginManager.telemetry.emitBundlerPluginExecutionSignal().catch(() => {
78
113
  });
79
114
  }
80
- async function transform(code, id) {
81
- if (transformAnnotations?.transform) {
115
+ async function transform(code, id, meta) {
116
+ let shouldRunBabelAnnotations = true;
117
+ if (transformViteAnnotations?.transform) {
118
+ const result = await transformViteAnnotations.transform(code, id, meta);
119
+ if (result) {
120
+ return result;
121
+ }
122
+ if (result === null) {
123
+ shouldRunBabelAnnotations = false;
124
+ }
125
+ }
126
+ if (shouldRunBabelAnnotations && transformAnnotations?.transform) {
82
127
  const result = await transformAnnotations.transform(code, id);
83
128
  if (result) {
84
129
  return result;
@@ -149,10 +194,14 @@ function _rollupPluginInternal(userOptions = {}, buildTool, buildToolMajorVersio
149
194
  }
150
195
  const name = `sentry-${buildTool}-plugin`;
151
196
  if (shouldTransform) {
197
+ const transformHook = buildTool === "vite" ? {
198
+ filter: { id: JS_MODULE_ID_FILTER },
199
+ handler: transform
200
+ } : transform;
152
201
  return {
153
202
  name,
154
203
  buildStart,
155
- transform,
204
+ transform: transformHook,
156
205
  renderChunk,
157
206
  writeBundle
158
207
  };