@sentry/wizard 4.7.0 → 4.9.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 (175) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +19 -19
  3. package/dist/e2e-tests/tests/angular-17.test.d.ts +1 -0
  4. package/dist/e2e-tests/tests/angular-17.test.js +196 -0
  5. package/dist/e2e-tests/tests/angular-17.test.js.map +1 -0
  6. package/dist/e2e-tests/tests/angular-19.test.d.ts +1 -0
  7. package/dist/e2e-tests/tests/angular-19.test.js +194 -0
  8. package/dist/e2e-tests/tests/angular-19.test.js.map +1 -0
  9. package/dist/e2e-tests/tests/expo.test.d.ts +1 -0
  10. package/dist/e2e-tests/tests/expo.test.js +103 -0
  11. package/dist/e2e-tests/tests/expo.test.js.map +1 -0
  12. package/dist/e2e-tests/tests/help-message.test.js +2 -2
  13. package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
  14. package/dist/e2e-tests/tests/react-native.test.d.ts +1 -0
  15. package/dist/e2e-tests/tests/react-native.test.js +132 -0
  16. package/dist/e2e-tests/tests/react-native.test.js.map +1 -0
  17. package/dist/e2e-tests/tests/remix.test.js +4 -4
  18. package/dist/e2e-tests/tests/remix.test.js.map +1 -1
  19. package/dist/e2e-tests/tests/sveltekit.test.js +2 -2
  20. package/dist/e2e-tests/tests/sveltekit.test.js.map +1 -1
  21. package/dist/e2e-tests/utils/index.d.ts +7 -0
  22. package/dist/e2e-tests/utils/index.js +32 -7
  23. package/dist/e2e-tests/utils/index.js.map +1 -1
  24. package/dist/lib/Constants.d.ts +1 -0
  25. package/dist/lib/Constants.js +3 -0
  26. package/dist/lib/Constants.js.map +1 -1
  27. package/dist/lib/Helper/SentryCli.d.ts +0 -11
  28. package/dist/lib/Helper/SentryCli.js +0 -52
  29. package/dist/lib/Helper/SentryCli.js.map +1 -1
  30. package/dist/src/android/templates.js +2 -0
  31. package/dist/src/android/templates.js.map +1 -1
  32. package/dist/src/angular/angular-wizard.d.ts +3 -0
  33. package/dist/src/angular/angular-wizard.js +186 -0
  34. package/dist/src/angular/angular-wizard.js.map +1 -0
  35. package/dist/src/angular/codemods/app-config.d.ts +3 -0
  36. package/dist/src/angular/codemods/app-config.js +211 -0
  37. package/dist/src/angular/codemods/app-config.js.map +1 -0
  38. package/dist/src/angular/codemods/main.d.ts +20 -0
  39. package/dist/src/angular/codemods/main.js +62 -0
  40. package/dist/src/angular/codemods/main.js.map +1 -0
  41. package/dist/src/angular/codemods/sourcemaps.d.ts +21 -0
  42. package/dist/src/angular/codemods/sourcemaps.js +94 -0
  43. package/dist/src/angular/codemods/sourcemaps.js.map +1 -0
  44. package/dist/src/angular/example-component.d.ts +8 -0
  45. package/dist/src/angular/example-component.js +286 -0
  46. package/dist/src/angular/example-component.js.map +1 -0
  47. package/dist/src/angular/sdk-setup.d.ts +6 -0
  48. package/dist/src/angular/sdk-setup.js +99 -0
  49. package/dist/src/angular/sdk-setup.js.map +1 -0
  50. package/dist/src/apple/code-tools.d.ts +4 -2
  51. package/dist/src/apple/code-tools.js +21 -11
  52. package/dist/src/apple/code-tools.js.map +1 -1
  53. package/dist/src/apple/inject-code-snippet.js +5 -3
  54. package/dist/src/apple/inject-code-snippet.js.map +1 -1
  55. package/dist/src/apple/macos-system-helper.d.ts +5 -0
  56. package/dist/src/apple/macos-system-helper.js +86 -0
  57. package/dist/src/apple/macos-system-helper.js.map +1 -0
  58. package/dist/src/apple/templates.js +10 -0
  59. package/dist/src/apple/templates.js.map +1 -1
  60. package/dist/src/apple/xcode-manager.d.ts +237 -11
  61. package/dist/src/apple/xcode-manager.js +736 -65
  62. package/dist/src/apple/xcode-manager.js.map +1 -1
  63. package/dist/src/apple/xcode-project-object-with-id.d.ts +5 -0
  64. package/dist/src/apple/xcode-project-object-with-id.js +3 -0
  65. package/dist/src/apple/xcode-project-object-with-id.js.map +1 -0
  66. package/dist/src/flutter/flutter-wizard.js +10 -2
  67. package/dist/src/flutter/flutter-wizard.js.map +1 -1
  68. package/dist/src/flutter/templates.js +7 -1
  69. package/dist/src/flutter/templates.js.map +1 -1
  70. package/dist/src/nextjs/nextjs-wizard.js +27 -15
  71. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  72. package/dist/src/nextjs/templates.js +56 -7
  73. package/dist/src/nextjs/templates.js.map +1 -1
  74. package/dist/src/nuxt/nuxt-wizard.js +1 -3
  75. package/dist/src/nuxt/nuxt-wizard.js.map +1 -1
  76. package/dist/src/nuxt/templates.js +30 -0
  77. package/dist/src/nuxt/templates.js.map +1 -1
  78. package/dist/src/react-native/expo-env-file.js +5 -0
  79. package/dist/src/react-native/expo-env-file.js.map +1 -1
  80. package/dist/src/react-native/expo-metro.js +22 -6
  81. package/dist/src/react-native/expo-metro.js.map +1 -1
  82. package/dist/src/react-native/expo.js +11 -1
  83. package/dist/src/react-native/expo.js.map +1 -1
  84. package/dist/src/react-native/glob.js +14 -4
  85. package/dist/src/react-native/glob.js.map +1 -1
  86. package/dist/src/react-native/gradle.js +14 -4
  87. package/dist/src/react-native/gradle.js.map +1 -1
  88. package/dist/src/react-native/javascript.d.ts +9 -4
  89. package/dist/src/react-native/javascript.js +52 -23
  90. package/dist/src/react-native/javascript.js.map +1 -1
  91. package/dist/src/react-native/metro.d.ts +1 -1
  92. package/dist/src/react-native/metro.js +36 -4
  93. package/dist/src/react-native/metro.js.map +1 -1
  94. package/dist/src/react-native/react-native-wizard.d.ts +4 -0
  95. package/dist/src/react-native/react-native-wizard.js +32 -4
  96. package/dist/src/react-native/react-native-wizard.js.map +1 -1
  97. package/dist/src/react-native/xcode.js +29 -10
  98. package/dist/src/react-native/xcode.js.map +1 -1
  99. package/dist/src/remix/remix-wizard.js +1 -3
  100. package/dist/src/remix/remix-wizard.js.map +1 -1
  101. package/dist/src/remix/sdk-example.js +30 -1
  102. package/dist/src/remix/sdk-example.js.map +1 -1
  103. package/dist/src/remix/sdk-setup.js +11 -5
  104. package/dist/src/remix/sdk-setup.js.map +1 -1
  105. package/dist/src/run.d.ts +1 -1
  106. package/dist/src/run.js +5 -0
  107. package/dist/src/run.js.map +1 -1
  108. package/dist/src/sourcemaps/sourcemaps-wizard.d.ts +1 -1
  109. package/dist/src/sourcemaps/sourcemaps-wizard.js +35 -20
  110. package/dist/src/sourcemaps/sourcemaps-wizard.js.map +1 -1
  111. package/dist/src/sourcemaps/tools/angular.d.ts +1 -0
  112. package/dist/src/sourcemaps/tools/angular.js +7 -7
  113. package/dist/src/sourcemaps/tools/angular.js.map +1 -1
  114. package/dist/src/sourcemaps/tools/sentry-cli.d.ts +5 -1
  115. package/dist/src/sourcemaps/tools/sentry-cli.js +6 -3
  116. package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
  117. package/dist/src/sourcemaps/tools/tsc.js +5 -1
  118. package/dist/src/sourcemaps/tools/tsc.js.map +1 -1
  119. package/dist/src/sourcemaps/tools/vite.js +4 -1
  120. package/dist/src/sourcemaps/tools/vite.js.map +1 -1
  121. package/dist/src/sourcemaps/tools/webpack.js +4 -1
  122. package/dist/src/sourcemaps/tools/webpack.js.map +1 -1
  123. package/dist/src/sveltekit/sdk-example.js +1 -1
  124. package/dist/src/sveltekit/sdk-example.js.map +1 -1
  125. package/dist/src/sveltekit/sveltekit-wizard.js +3 -5
  126. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  127. package/dist/src/sveltekit/templates.js +28 -1
  128. package/dist/src/sveltekit/templates.js.map +1 -1
  129. package/dist/src/utils/clack/index.d.ts +13 -15
  130. package/dist/src/utils/clack/index.js +17 -50
  131. package/dist/src/utils/clack/index.js.map +1 -1
  132. package/dist/src/utils/git.d.ts +11 -0
  133. package/dist/src/utils/git.js +69 -0
  134. package/dist/src/utils/git.js.map +1 -0
  135. package/dist/src/utils/sentrycli-utils.js +13 -4
  136. package/dist/src/utils/sentrycli-utils.js.map +1 -1
  137. package/dist/src/version.d.ts +1 -1
  138. package/dist/src/version.js +1 -1
  139. package/dist/src/version.js.map +1 -1
  140. package/dist/test/angular/angular-wizard.test.d.ts +1 -0
  141. package/dist/test/angular/angular-wizard.test.js +27 -0
  142. package/dist/test/angular/angular-wizard.test.js.map +1 -0
  143. package/dist/test/angular/codemods/sourcemaps.test.d.ts +1 -0
  144. package/dist/test/angular/codemods/sourcemaps.test.js +237 -0
  145. package/dist/test/angular/codemods/sourcemaps.test.js.map +1 -0
  146. package/dist/test/angular/example-component.test.d.ts +1 -0
  147. package/dist/test/angular/example-component.test.js +105 -0
  148. package/dist/test/angular/example-component.test.js.map +1 -0
  149. package/dist/test/apple/code-tools.test.js +54 -35
  150. package/dist/test/apple/code-tools.test.js.map +1 -1
  151. package/dist/test/apple/configure-sentry-cli.test.d.ts +1 -0
  152. package/dist/test/apple/configure-sentry-cli.test.js +131 -0
  153. package/dist/test/apple/configure-sentry-cli.test.js.map +1 -0
  154. package/dist/test/apple/macos-system-helper-mocked.test.d.ts +1 -0
  155. package/dist/test/apple/macos-system-helper-mocked.test.js +46 -0
  156. package/dist/test/apple/macos-system-helper-mocked.test.js.map +1 -0
  157. package/dist/test/apple/macos-system-helper.test.d.ts +1 -0
  158. package/dist/test/apple/macos-system-helper.test.js +88 -0
  159. package/dist/test/apple/macos-system-helper.test.js.map +1 -0
  160. package/dist/test/apple/templates.test.js +10 -0
  161. package/dist/test/apple/templates.test.js.map +1 -1
  162. package/dist/test/apple/xcode-manager.test.js +745 -379
  163. package/dist/test/apple/xcode-manager.test.js.map +1 -1
  164. package/dist/test/flutter/templates.test.js +9 -0
  165. package/dist/test/flutter/templates.test.js.map +1 -1
  166. package/dist/test/react-native/javascript.test.js +119 -0
  167. package/dist/test/react-native/javascript.test.js.map +1 -1
  168. package/dist/test/react-native/metro.test.js +113 -0
  169. package/dist/test/react-native/metro.test.js.map +1 -1
  170. package/dist/test/remix/client-entry.test.js +10 -10
  171. package/dist/test/remix/client-entry.test.js.map +1 -1
  172. package/dist/test/utils/git.test.d.ts +1 -0
  173. package/dist/test/utils/git.test.js +70 -0
  174. package/dist/test/utils/git.test.js.map +1 -0
  175. package/package.json +1 -1
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.updateAppConfigMod = void 0;
30
+ // @ts-expect-error - clack is ESM and TS complains about that. It works though
31
+ const clack = __importStar(require("@clack/prompts"));
32
+ const semver_1 = require("semver");
33
+ const recast = __importStar(require("recast"));
34
+ const chalk_1 = __importDefault(require("chalk"));
35
+ function updateAppConfigMod(
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ originalAppConfigMod, angularVersion, isTracingEnabled) {
38
+ const isAboveAngularV19 = (0, semver_1.gte)(angularVersion, '19.0.0');
39
+ addImports(originalAppConfigMod, isAboveAngularV19, isTracingEnabled);
40
+ addProviders(originalAppConfigMod, isAboveAngularV19, isTracingEnabled);
41
+ return originalAppConfigMod;
42
+ }
43
+ exports.updateAppConfigMod = updateAppConfigMod;
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ function addSentryImport(originalAppConfigMod) {
46
+ const imports = originalAppConfigMod.imports;
47
+ const hasSentryImport = imports.$items.some((item) => item.from === '@sentry/angular');
48
+ if (!hasSentryImport) {
49
+ imports.$add({
50
+ from: '@sentry/angular',
51
+ imported: '*',
52
+ local: 'Sentry',
53
+ });
54
+ }
55
+ }
56
+ function addErrorHandlerImport(
57
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
+ originalAppConfigMod) {
59
+ const imports = originalAppConfigMod.imports;
60
+ const hasErrorHandler = imports.$items.some((item) => item.local === 'ErrorHandler' && item.from === '@angular/core');
61
+ if (!hasErrorHandler) {
62
+ imports.$add({
63
+ from: '@angular/core',
64
+ imported: 'ErrorHandler',
65
+ local: 'ErrorHandler',
66
+ });
67
+ }
68
+ }
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ function addRouterImport(originalAppConfigMod) {
71
+ const imports = originalAppConfigMod.imports;
72
+ const hasRouter = imports.$items.some((item) => item.local === 'Router' && item.from === '@angular/router');
73
+ if (!hasRouter) {
74
+ imports.$add({
75
+ from: '@angular/router',
76
+ imported: 'Router',
77
+ local: 'Router',
78
+ });
79
+ }
80
+ }
81
+ function addMissingImportsV19(
82
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
+ originalAppConfigMod) {
84
+ const imports = originalAppConfigMod.imports;
85
+ const hasProvideAppInitializer = imports.$items.some((item) => item.local === 'provideAppInitializer' && item.from === '@angular/core');
86
+ if (!hasProvideAppInitializer) {
87
+ imports.$add({
88
+ from: '@angular/core',
89
+ imported: 'provideAppInitializer',
90
+ local: 'provideAppInitializer',
91
+ });
92
+ }
93
+ const hasInject = imports.$items.some((item) => item.local === 'inject' && item.from === '@angular/core');
94
+ if (!hasInject) {
95
+ imports.$add({
96
+ from: '@angular/core',
97
+ imported: 'inject',
98
+ local: 'inject',
99
+ });
100
+ }
101
+ }
102
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
+ function addAppInitializer(originalAppConfigMod) {
104
+ const imports = originalAppConfigMod.imports;
105
+ const hasAppInitializer = imports.$items.some((item) => item.local === 'APP_INITIALIZER' && item.from === '@angular/core');
106
+ if (!hasAppInitializer) {
107
+ imports.$add({
108
+ from: '@angular/core',
109
+ imported: 'APP_INITIALIZER',
110
+ local: 'APP_INITIALIZER',
111
+ });
112
+ }
113
+ }
114
+ function addImports(
115
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
116
+ originalAppConfigMod, isAboveAngularV19, isTracingEnabled) {
117
+ addSentryImport(originalAppConfigMod);
118
+ addErrorHandlerImport(originalAppConfigMod);
119
+ if (isTracingEnabled) {
120
+ addRouterImport(originalAppConfigMod);
121
+ }
122
+ if (isAboveAngularV19) {
123
+ addMissingImportsV19(originalAppConfigMod);
124
+ }
125
+ else if (isTracingEnabled) {
126
+ addAppInitializer(originalAppConfigMod);
127
+ }
128
+ }
129
+ function addProviders(
130
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
131
+ originalAppConfigMod, isAboveAngularV19, isTracingEnabled) {
132
+ const b = recast.types.builders;
133
+ recast.visit(originalAppConfigMod.exports.$ast, {
134
+ visitExportNamedDeclaration(path) {
135
+ if (path.node.declaration?.type !== 'VariableDeclaration' ||
136
+ path.node.declaration.declarations[0]?.type !== 'VariableDeclarator' ||
137
+ path.node.declaration.declarations[0].id.type !== 'Identifier' ||
138
+ path.node.declaration.declarations[0].id.name !== 'appConfig' ||
139
+ path.node.declaration.declarations[0].init?.type !==
140
+ 'ObjectExpression' ||
141
+ !path.node.declaration.declarations[0].init.properties) {
142
+ return;
143
+ }
144
+ const appConfigProps = path.node.declaration.declarations[0].init.properties;
145
+ const providersProperty = appConfigProps.find((prop) => prop?.type === 'ObjectProperty' &&
146
+ prop.key.type === 'Identifier' &&
147
+ prop.key.name === 'providers');
148
+ const validProviders = providersProperty?.value?.type === 'ArrayExpression'
149
+ ? providersProperty.value
150
+ : undefined;
151
+ if (!validProviders) {
152
+ return;
153
+ }
154
+ // Check if there is already an ErrorHandler provider
155
+ const hasErrorHandlerProvider = validProviders?.elements.some((element) => element &&
156
+ element.type === 'ObjectExpression' &&
157
+ element.properties.some((prop) => prop.type === 'ObjectProperty' &&
158
+ prop.key.type === 'Identifier' &&
159
+ prop.key.name === 'provide' &&
160
+ prop.value.type === 'Identifier' &&
161
+ prop.value.name === 'ErrorHandler'));
162
+ // If there is already an ErrorHandler provider, we skip adding it and log a message
163
+ if (hasErrorHandlerProvider) {
164
+ clack.log.warn(`ErrorHandler provider already exists in your app config.
165
+ Please refer to the Sentry Angular SDK documentation to combine it manually with Sentry's ErrorHandler.
166
+ ${chalk_1.default.underline('https://docs.sentry.io/platforms/javascript/guides/angular/features/error-handler/')}
167
+ `);
168
+ }
169
+ else {
170
+ const errorHandlerObject = b.objectExpression([
171
+ b.objectProperty(b.identifier('provide'), b.identifier('ErrorHandler')),
172
+ b.objectProperty(b.identifier('useValue'), b.identifier('Sentry.createErrorHandler()')),
173
+ ]);
174
+ validProviders.elements.push(
175
+ // @ts-expect-error - errorHandlerObject is an objectExpression
176
+ errorHandlerObject);
177
+ }
178
+ if (isTracingEnabled) {
179
+ const traceServiceObject = b.objectExpression([
180
+ b.objectProperty(b.identifier('provide'), b.identifier('Sentry.TraceService')),
181
+ b.objectProperty(b.identifier('deps'), b.arrayExpression([b.identifier('Router')])),
182
+ ]);
183
+ // @ts-expect-error - errorHandlerObject is an objectExpression
184
+ validProviders.elements.push(traceServiceObject);
185
+ if (isAboveAngularV19) {
186
+ const provideAppInitializerCall = b.callExpression(b.identifier('provideAppInitializer'), [
187
+ b.arrowFunctionExpression([], b.blockStatement([
188
+ b.expressionStatement(b.callExpression(b.identifier('inject'), [
189
+ b.identifier('Sentry.TraceService'),
190
+ ])),
191
+ ])),
192
+ ]);
193
+ // @ts-expect-error - provideAppInitializerCall is an objectExpression
194
+ validProviders.elements.push(provideAppInitializerCall);
195
+ }
196
+ else {
197
+ const provideAppInitializerObject = b.objectExpression([
198
+ b.objectProperty(b.identifier('provide'), b.identifier('APP_INITIALIZER')),
199
+ b.objectProperty(b.identifier('useFactory'), b.arrowFunctionExpression([], b.arrowFunctionExpression([], b.blockStatement([])))),
200
+ b.objectProperty(b.identifier('deps'), b.arrayExpression([b.identifier('Sentry.TraceService')])),
201
+ b.objectProperty(b.identifier('multi'), b.booleanLiteral(true)),
202
+ ]);
203
+ // @ts-expect-error - provideAppInitializerObject is an objectExpression
204
+ validProviders.elements.push(provideAppInitializerObject);
205
+ }
206
+ }
207
+ this.traverse(path);
208
+ },
209
+ });
210
+ }
211
+ //# sourceMappingURL=app-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-config.js","sourceRoot":"","sources":["../../../../src/angular/codemods/app-config.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ObjectProperty } from '@babel/types';\n\n// @ts-expect-error - magicast is ESM and TS complains about that. It works though\nimport type { ProxifiedModule } from 'magicast';\n\n// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport { gte, type SemVer } from 'semver';\nimport * as recast from 'recast';\nimport chalk from 'chalk';\n\nexport function updateAppConfigMod(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppConfigMod: ProxifiedModule<any>,\n angularVersion: SemVer,\n isTracingEnabled: boolean,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ProxifiedModule<any> {\n const isAboveAngularV19 = gte(angularVersion, '19.0.0');\n\n addImports(originalAppConfigMod, isAboveAngularV19, isTracingEnabled);\n addProviders(originalAppConfigMod, isAboveAngularV19, isTracingEnabled);\n\n return originalAppConfigMod;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction addSentryImport(originalAppConfigMod: ProxifiedModule<any>): void {\n const imports = originalAppConfigMod.imports;\n const hasSentryImport = imports.$items.some(\n (item) => item.from === '@sentry/angular',\n );\n\n if (!hasSentryImport) {\n imports.$add({\n from: '@sentry/angular',\n imported: '*',\n local: 'Sentry',\n });\n }\n}\n\nfunction addErrorHandlerImport(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppConfigMod: ProxifiedModule<any>,\n): void {\n const imports = originalAppConfigMod.imports;\n const hasErrorHandler = imports.$items.some(\n (item) => item.local === 'ErrorHandler' && item.from === '@angular/core',\n );\n\n if (!hasErrorHandler) {\n imports.$add({\n from: '@angular/core',\n imported: 'ErrorHandler',\n local: 'ErrorHandler',\n });\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction addRouterImport(originalAppConfigMod: ProxifiedModule<any>): void {\n const imports = originalAppConfigMod.imports;\n const hasRouter = imports.$items.some(\n (item) => item.local === 'Router' && item.from === '@angular/router',\n );\n\n if (!hasRouter) {\n imports.$add({\n from: '@angular/router',\n imported: 'Router',\n local: 'Router',\n });\n }\n}\n\nfunction addMissingImportsV19(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppConfigMod: ProxifiedModule<any>,\n): void {\n const imports = originalAppConfigMod.imports;\n\n const hasProvideAppInitializer = imports.$items.some(\n (item) =>\n item.local === 'provideAppInitializer' && item.from === '@angular/core',\n );\n\n if (!hasProvideAppInitializer) {\n imports.$add({\n from: '@angular/core',\n imported: 'provideAppInitializer',\n local: 'provideAppInitializer',\n });\n }\n\n const hasInject = imports.$items.some(\n (item) => item.local === 'inject' && item.from === '@angular/core',\n );\n\n if (!hasInject) {\n imports.$add({\n from: '@angular/core',\n imported: 'inject',\n local: 'inject',\n });\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction addAppInitializer(originalAppConfigMod: ProxifiedModule<any>): void {\n const imports = originalAppConfigMod.imports;\n\n const hasAppInitializer = imports.$items.some(\n (item) => item.local === 'APP_INITIALIZER' && item.from === '@angular/core',\n );\n\n if (!hasAppInitializer) {\n imports.$add({\n from: '@angular/core',\n imported: 'APP_INITIALIZER',\n local: 'APP_INITIALIZER',\n });\n }\n}\n\nfunction addImports(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppConfigMod: ProxifiedModule<any>,\n isAboveAngularV19: boolean,\n isTracingEnabled: boolean,\n): void {\n addSentryImport(originalAppConfigMod);\n addErrorHandlerImport(originalAppConfigMod);\n\n if (isTracingEnabled) {\n addRouterImport(originalAppConfigMod);\n }\n\n if (isAboveAngularV19) {\n addMissingImportsV19(originalAppConfigMod);\n } else if (isTracingEnabled) {\n addAppInitializer(originalAppConfigMod);\n }\n}\n\nfunction addProviders(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppConfigMod: ProxifiedModule<any>,\n isAboveAngularV19: boolean,\n isTracingEnabled: boolean,\n): void {\n const b = recast.types.builders;\n\n recast.visit(originalAppConfigMod.exports.$ast, {\n visitExportNamedDeclaration(path) {\n if (\n path.node.declaration?.type !== 'VariableDeclaration' ||\n path.node.declaration.declarations[0]?.type !== 'VariableDeclarator' ||\n path.node.declaration.declarations[0].id.type !== 'Identifier' ||\n path.node.declaration.declarations[0].id.name !== 'appConfig' ||\n path.node.declaration.declarations[0].init?.type !==\n 'ObjectExpression' ||\n !path.node.declaration.declarations[0].init.properties\n ) {\n return;\n }\n\n const appConfigProps =\n path.node.declaration.declarations[0].init.properties;\n\n const providersProperty = appConfigProps.find(\n (prop) =>\n prop?.type === 'ObjectProperty' &&\n prop.key.type === 'Identifier' &&\n prop.key.name === 'providers',\n // type cast is safe because we already check the type in the find condition\n ) as ObjectProperty | undefined;\n\n const validProviders =\n providersProperty?.value?.type === 'ArrayExpression'\n ? providersProperty.value\n : undefined;\n\n if (!validProviders) {\n return;\n }\n\n // Check if there is already an ErrorHandler provider\n const hasErrorHandlerProvider = validProviders?.elements.some(\n (element) =>\n element &&\n element.type === 'ObjectExpression' &&\n element.properties.some(\n (prop) =>\n prop.type === 'ObjectProperty' &&\n prop.key.type === 'Identifier' &&\n prop.key.name === 'provide' &&\n prop.value.type === 'Identifier' &&\n prop.value.name === 'ErrorHandler',\n ),\n );\n\n // If there is already an ErrorHandler provider, we skip adding it and log a message\n if (hasErrorHandlerProvider) {\n clack.log.warn(`ErrorHandler provider already exists in your app config.\nPlease refer to the Sentry Angular SDK documentation to combine it manually with Sentry's ErrorHandler.\n${chalk.underline(\n 'https://docs.sentry.io/platforms/javascript/guides/angular/features/error-handler/',\n)}\n`);\n } else {\n const errorHandlerObject = b.objectExpression([\n b.objectProperty(\n b.identifier('provide'),\n b.identifier('ErrorHandler'),\n ),\n b.objectProperty(\n b.identifier('useValue'),\n b.identifier('Sentry.createErrorHandler()'),\n ),\n ]);\n\n validProviders.elements.push(\n // @ts-expect-error - errorHandlerObject is an objectExpression\n errorHandlerObject,\n );\n }\n\n if (isTracingEnabled) {\n const traceServiceObject = b.objectExpression([\n b.objectProperty(\n b.identifier('provide'),\n b.identifier('Sentry.TraceService'),\n ),\n b.objectProperty(\n b.identifier('deps'),\n b.arrayExpression([b.identifier('Router')]),\n ),\n ]);\n\n // @ts-expect-error - errorHandlerObject is an objectExpression\n validProviders.elements.push(traceServiceObject);\n\n if (isAboveAngularV19) {\n const provideAppInitializerCall = b.callExpression(\n b.identifier('provideAppInitializer'),\n [\n b.arrowFunctionExpression(\n [],\n b.blockStatement([\n b.expressionStatement(\n b.callExpression(b.identifier('inject'), [\n b.identifier('Sentry.TraceService'),\n ]),\n ),\n ]),\n ),\n ],\n );\n\n // @ts-expect-error - provideAppInitializerCall is an objectExpression\n validProviders.elements.push(provideAppInitializerCall);\n } else {\n const provideAppInitializerObject = b.objectExpression([\n b.objectProperty(\n b.identifier('provide'),\n b.identifier('APP_INITIALIZER'),\n ),\n b.objectProperty(\n b.identifier('useFactory'),\n b.arrowFunctionExpression(\n [],\n b.arrowFunctionExpression([], b.blockStatement([])),\n ),\n ),\n b.objectProperty(\n b.identifier('deps'),\n b.arrayExpression([b.identifier('Sentry.TraceService')]),\n ),\n b.objectProperty(b.identifier('multi'), b.booleanLiteral(true)),\n ]);\n\n // @ts-expect-error - provideAppInitializerObject is an objectExpression\n validProviders.elements.push(provideAppInitializerObject);\n }\n }\n\n this.traverse(path);\n },\n });\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import type { Program } from '@babel/types';
2
+ import { Proxified, type ProxifiedModule } from 'magicast';
3
+ export declare function updateAppEntryMod(originalAppModuleMod: ProxifiedModule<any>, dsn: string, selectedFeatures: {
4
+ performance: boolean;
5
+ replay: boolean;
6
+ }): ProxifiedModule<any>;
7
+ export declare function insertInitCall(originalAppModuleMod: ProxifiedModule<any>, dsn: string, selectedFeatures: {
8
+ performance: boolean;
9
+ replay: boolean;
10
+ }): void;
11
+ type InitCallArgs = Record<string, string | number | Array<Proxified>>;
12
+ export declare function getInitCallArgs(dsn: string, selectedFeatures: {
13
+ performance: boolean;
14
+ replay: boolean;
15
+ }): InitCallArgs;
16
+ /**
17
+ * We want to insert the handleError function just after all imports
18
+ */
19
+ export declare function getAfterImportsInsertionIndex(originalEntryServerModAST: Program): number;
20
+ export {};
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAfterImportsInsertionIndex = exports.getInitCallArgs = exports.insertInitCall = exports.updateAppEntryMod = void 0;
4
+ const magicast_1 = require("magicast");
5
+ function updateAppEntryMod(
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ originalAppModuleMod, dsn, selectedFeatures) {
8
+ originalAppModuleMod.imports.$add({
9
+ from: '@sentry/angular',
10
+ imported: '*',
11
+ local: 'Sentry',
12
+ });
13
+ insertInitCall(originalAppModuleMod, dsn, selectedFeatures);
14
+ return originalAppModuleMod;
15
+ }
16
+ exports.updateAppEntryMod = updateAppEntryMod;
17
+ function insertInitCall(
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ originalAppModuleMod, dsn, selectedFeatures) {
20
+ const initCallArgs = getInitCallArgs(dsn, selectedFeatures);
21
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- builders return Proxified which defaults to any
22
+ const initCall = magicast_1.builders.functionCall('Sentry.init', initCallArgs);
23
+ const originalAppModuleModAst = originalAppModuleMod.$ast;
24
+ const initCallInsertionIndex = getAfterImportsInsertionIndex(originalAppModuleModAst);
25
+ originalAppModuleModAst.body.splice(initCallInsertionIndex, 0,
26
+ // @ts-expect-error - string works here because the AST is proxified by magicast
27
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- builders return Proxified which defaults to any.
28
+ (0, magicast_1.generateCode)(initCall).code);
29
+ }
30
+ exports.insertInitCall = insertInitCall;
31
+ function getInitCallArgs(dsn, selectedFeatures) {
32
+ const initCallArgs = {
33
+ dsn,
34
+ };
35
+ if (selectedFeatures.replay || selectedFeatures.performance) {
36
+ initCallArgs.integrations = [];
37
+ if (selectedFeatures.performance) {
38
+ initCallArgs.integrations.push(magicast_1.builders.functionCall('Sentry.browserTracingIntegration'));
39
+ initCallArgs.tracesSampleRate = 1.0;
40
+ }
41
+ if (selectedFeatures.replay) {
42
+ initCallArgs.integrations.push(magicast_1.builders.functionCall('Sentry.replayIntegration'));
43
+ initCallArgs.replaysSessionSampleRate = 0.1;
44
+ initCallArgs.replaysOnErrorSampleRate = 1.0;
45
+ }
46
+ }
47
+ return initCallArgs;
48
+ }
49
+ exports.getInitCallArgs = getInitCallArgs;
50
+ /**
51
+ * We want to insert the handleError function just after all imports
52
+ */
53
+ function getAfterImportsInsertionIndex(originalEntryServerModAST) {
54
+ for (let x = originalEntryServerModAST.body.length - 1; x >= 0; x--) {
55
+ if (originalEntryServerModAST.body[x].type === 'ImportDeclaration') {
56
+ return x + 1;
57
+ }
58
+ }
59
+ return 0;
60
+ }
61
+ exports.getAfterImportsInsertionIndex = getAfterImportsInsertionIndex;
62
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../../../src/angular/codemods/main.ts"],"names":[],"mappings":";;;AAEA,uCAMkB;AAElB,SAAgB,iBAAiB;AAC/B,8DAA8D;AAC9D,oBAA0C,EAC1C,GAAW,EACX,gBAGC;IAGD,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC;QAChC,IAAI,EAAE,iBAAiB;QACvB,QAAQ,EAAE,GAAG;QACb,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;IAEH,cAAc,CAAC,oBAAoB,EAAE,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAE5D,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AAnBD,8CAmBC;AAED,SAAgB,cAAc;AAC5B,8DAA8D;AAC9D,oBAA0C,EAC1C,GAAW,EACX,gBAGC;IAED,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAC5D,sHAAsH;IACtH,MAAM,QAAQ,GAAG,mBAAQ,CAAC,YAAY,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACpE,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,IAAe,CAAC;IAErE,MAAM,sBAAsB,GAAG,6BAA6B,CAC1D,uBAAuB,CACxB,CAAC;IAEF,uBAAuB,CAAC,IAAI,CAAC,MAAM,CACjC,sBAAsB,EACtB,CAAC;IACD,gFAAgF;IAChF,qHAAqH;IACrH,IAAA,uBAAY,EAAC,QAAQ,CAAC,CAAC,IAAI,CAC5B,CAAC;AACJ,CAAC;AAzBD,wCAyBC;AAID,SAAgB,eAAe,CAC7B,GAAW,EACX,gBAGC;IAED,MAAM,YAAY,GAAiB;QACjC,GAAG;KACJ,CAAC;IAEF,IAAI,gBAAgB,CAAC,MAAM,IAAI,gBAAgB,CAAC,WAAW,EAAE;QAC3D,YAAY,CAAC,YAAY,GAAG,EAAE,CAAC;QAE/B,IAAI,gBAAgB,CAAC,WAAW,EAAE;YAChC,YAAY,CAAC,YAAY,CAAC,IAAI,CAC5B,mBAAQ,CAAC,YAAY,CAAC,kCAAkC,CAAC,CAC1D,CAAC;YACF,YAAY,CAAC,gBAAgB,GAAG,GAAG,CAAC;SACrC;QAED,IAAI,gBAAgB,CAAC,MAAM,EAAE;YAC3B,YAAY,CAAC,YAAY,CAAC,IAAI,CAC5B,mBAAQ,CAAC,YAAY,CAAC,0BAA0B,CAAC,CAClD,CAAC;YAEF,YAAY,CAAC,wBAAwB,GAAG,GAAG,CAAC;YAC5C,YAAY,CAAC,wBAAwB,GAAG,GAAG,CAAC;SAC7C;KACF;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAhCD,0CAgCC;AAED;;GAEG;AACH,SAAgB,6BAA6B,CAC3C,yBAAkC;IAElC,KAAK,IAAI,CAAC,GAAG,yBAAyB,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;QACnE,IAAI,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,EAAE;YAClE,OAAO,CAAC,GAAG,CAAC,CAAC;SACd;KACF;IAED,OAAO,CAAC,CAAC;AACX,CAAC;AAVD,sEAUC","sourcesContent":["import type { Program } from '@babel/types';\n\nimport {\n builders,\n generateCode,\n Proxified,\n type ProxifiedModule,\n // @ts-expect-error - magicast is ESM and TS complains about that. It works though\n} from 'magicast';\n\nexport function updateAppEntryMod(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppModuleMod: ProxifiedModule<any>,\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n },\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): ProxifiedModule<any> {\n originalAppModuleMod.imports.$add({\n from: '@sentry/angular',\n imported: '*',\n local: 'Sentry',\n });\n\n insertInitCall(originalAppModuleMod, dsn, selectedFeatures);\n\n return originalAppModuleMod;\n}\n\nexport function insertInitCall(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n originalAppModuleMod: ProxifiedModule<any>,\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n },\n): void {\n const initCallArgs = getInitCallArgs(dsn, selectedFeatures);\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- builders return Proxified which defaults to any\n const initCall = builders.functionCall('Sentry.init', initCallArgs);\n const originalAppModuleModAst = originalAppModuleMod.$ast as Program;\n\n const initCallInsertionIndex = getAfterImportsInsertionIndex(\n originalAppModuleModAst,\n );\n\n originalAppModuleModAst.body.splice(\n initCallInsertionIndex,\n 0,\n // @ts-expect-error - string works here because the AST is proxified by magicast\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument -- builders return Proxified which defaults to any.\n generateCode(initCall).code,\n );\n}\n\ntype InitCallArgs = Record<string, string | number | Array<Proxified>>;\n\nexport function getInitCallArgs(\n dsn: string,\n selectedFeatures: {\n performance: boolean;\n replay: boolean;\n },\n): InitCallArgs {\n const initCallArgs: InitCallArgs = {\n dsn,\n };\n\n if (selectedFeatures.replay || selectedFeatures.performance) {\n initCallArgs.integrations = [];\n\n if (selectedFeatures.performance) {\n initCallArgs.integrations.push(\n builders.functionCall('Sentry.browserTracingIntegration'),\n );\n initCallArgs.tracesSampleRate = 1.0;\n }\n\n if (selectedFeatures.replay) {\n initCallArgs.integrations.push(\n builders.functionCall('Sentry.replayIntegration'),\n );\n\n initCallArgs.replaysSessionSampleRate = 0.1;\n initCallArgs.replaysOnErrorSampleRate = 1.0;\n }\n }\n\n return initCallArgs;\n}\n\n/**\n * We want to insert the handleError function just after all imports\n */\nexport function getAfterImportsInsertionIndex(\n originalEntryServerModAST: Program,\n): number {\n for (let x = originalEntryServerModAST.body.length - 1; x >= 0; x--) {\n if (originalEntryServerModAST.body[x].type === 'ImportDeclaration') {\n return x + 1;\n }\n }\n\n return 0;\n}\n"]}
@@ -0,0 +1,21 @@
1
+ interface PartialAngularJson {
2
+ projects?: {
3
+ [key: string]: {
4
+ architect?: {
5
+ build?: {
6
+ configurations?: {
7
+ production?: {
8
+ sourceMap?: boolean;
9
+ } & Record<string, unknown>;
10
+ };
11
+ };
12
+ };
13
+ };
14
+ };
15
+ }
16
+ export declare function addSourcemapEntryToAngularJSON(): Promise<void>;
17
+ /**
18
+ * Extracted from `addSourcemapEntryToAngularJSON` and exported to allow for easier testing.
19
+ */
20
+ export declare function addSourceMapsSetting(angularJson: PartialAngularJson): PartialAngularJson | undefined;
21
+ export {};
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.addSourceMapsSetting = exports.addSourcemapEntryToAngularJSON = void 0;
27
+ // @ts-expect-error - clack is ESM and TS complains about that. It works though
28
+ const clack = __importStar(require("@clack/prompts"));
29
+ const path = __importStar(require("path"));
30
+ const fs = __importStar(require("fs"));
31
+ const angular_1 = require("../../sourcemaps/tools/angular");
32
+ const node_1 = require("@sentry/node");
33
+ async function addSourcemapEntryToAngularJSON() {
34
+ const angularJsonPath = path.join(process.cwd(), 'angular.json');
35
+ const angularJson = getParsedAngularJson(angularJsonPath);
36
+ if (!angularJson || typeof angularJson !== 'object') {
37
+ await (0, angular_1.configureAngularSourcemapGenerationFlow)();
38
+ return;
39
+ }
40
+ const updatedAngularJson = addSourceMapsSetting(angularJson);
41
+ if (!updatedAngularJson) {
42
+ await (0, angular_1.configureAngularSourcemapGenerationFlow)();
43
+ return;
44
+ }
45
+ try {
46
+ fs.writeFileSync(angularJsonPath, JSON.stringify(updatedAngularJson, null, 2));
47
+ }
48
+ catch (error) {
49
+ clack.log.error(`Failed to write sourcemap configuration to angular.json`);
50
+ (0, node_1.captureException)('Failed to write sourcemap configuration to angular.json');
51
+ await (0, angular_1.configureAngularSourcemapGenerationFlow)();
52
+ }
53
+ }
54
+ exports.addSourcemapEntryToAngularJSON = addSourcemapEntryToAngularJSON;
55
+ /**
56
+ * Extracted from `addSourcemapEntryToAngularJSON` and exported to allow for easier testing.
57
+ */
58
+ function addSourceMapsSetting(angularJson) {
59
+ const newAngularJson = { ...angularJson };
60
+ const projectKeys = Object.keys(newAngularJson.projects || {});
61
+ if (!projectKeys.length || !newAngularJson.projects) {
62
+ return undefined;
63
+ }
64
+ // Emit sourcemaps from all projects in angular.json
65
+ for (const projectKey of projectKeys) {
66
+ const projectConfig = newAngularJson.projects[projectKey];
67
+ if (!projectConfig.architect) {
68
+ projectConfig.architect = {};
69
+ }
70
+ if (!projectConfig.architect.build) {
71
+ projectConfig.architect.build = {};
72
+ }
73
+ if (!projectConfig.architect.build.configurations) {
74
+ projectConfig.architect.build.configurations = {};
75
+ }
76
+ projectConfig.architect.build.configurations.production = {
77
+ ...projectConfig.architect.build.configurations.production,
78
+ sourceMap: true,
79
+ };
80
+ }
81
+ return newAngularJson;
82
+ }
83
+ exports.addSourceMapsSetting = addSourceMapsSetting;
84
+ function getParsedAngularJson(path) {
85
+ try {
86
+ const angularJSONFile = fs.readFileSync(path, 'utf-8');
87
+ return JSON.parse(angularJSONFile);
88
+ }
89
+ catch {
90
+ (0, node_1.captureException)('Could not parse `angular.json`');
91
+ return undefined;
92
+ }
93
+ }
94
+ //# sourceMappingURL=sourcemaps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourcemaps.js","sourceRoot":"","sources":["../../../../src/angular/codemods/sourcemaps.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+EAA+E;AAC/E,sDAAwC;AACxC,2CAA6B;AAC7B,uCAAyB;AACzB,4DAAyF;AACzF,uCAAgD;AAkBzC,KAAK,UAAU,8BAA8B;IAClD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAE1D,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE;QACnD,MAAM,IAAA,iDAAuC,GAAE,CAAC;QAChD,OAAO;KACR;IAED,MAAM,kBAAkB,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IAE7D,IAAI,CAAC,kBAAkB,EAAE;QACvB,MAAM,IAAA,iDAAuC,GAAE,CAAC;QAChD,OAAO;KACR;IAED,IAAI;QACF,EAAE,CAAC,aAAa,CACd,eAAe,EACf,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,CAC5C,CAAC;KACH;IAAC,OAAO,KAAK,EAAE;QACd,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;QAC3E,IAAA,uBAAgB,EAAC,yDAAyD,CAAC,CAAC;QAC5E,MAAM,IAAA,iDAAuC,GAAE,CAAC;KACjD;AACH,CAAC;AA1BD,wEA0BC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAClC,WAA+B;IAE/B,MAAM,cAAc,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;IAE1C,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IAE/D,IAAI,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE;QACnD,OAAO,SAAS,CAAC;KAClB;IAED,oDAAoD;IACpD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE;QACpC,MAAM,aAAa,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAE1D,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE;YAC5B,aAAa,CAAC,SAAS,GAAG,EAAE,CAAC;SAC9B;QAED,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,EAAE;YAClC,aAAa,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC;SACpC;QAED,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,EAAE;YACjD,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;SACnD;QAED,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,GAAG;YACxD,GAAG,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU;YAC1D,SAAS,EAAE,IAAI;SAChB,CAAC;KACH;IAED,OAAO,cAAc,CAAC;AACxB,CAAC;AAlCD,oDAkCC;AAED,SAAS,oBAAoB,CAAC,IAAY;IACxC,IAAI;QACF,MAAM,eAAe,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAmC,CAAC;KACtE;IAAC,MAAM;QACN,IAAA,uBAAgB,EAAC,gCAAgC,CAAC,CAAC;QACnD,OAAO,SAAS,CAAC;KAClB;AACH,CAAC","sourcesContent":["// @ts-expect-error - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { configureAngularSourcemapGenerationFlow } from '../../sourcemaps/tools/angular';\nimport { captureException } from '@sentry/node';\n\ninterface PartialAngularJson {\n projects?: {\n [key: string]: {\n architect?: {\n build?: {\n configurations?: {\n production?: {\n sourceMap?: boolean;\n } & Record<string, unknown>;\n };\n };\n };\n };\n };\n}\n\nexport async function addSourcemapEntryToAngularJSON(): Promise<void> {\n const angularJsonPath = path.join(process.cwd(), 'angular.json');\n const angularJson = getParsedAngularJson(angularJsonPath);\n\n if (!angularJson || typeof angularJson !== 'object') {\n await configureAngularSourcemapGenerationFlow();\n return;\n }\n\n const updatedAngularJson = addSourceMapsSetting(angularJson);\n\n if (!updatedAngularJson) {\n await configureAngularSourcemapGenerationFlow();\n return;\n }\n\n try {\n fs.writeFileSync(\n angularJsonPath,\n JSON.stringify(updatedAngularJson, null, 2),\n );\n } catch (error) {\n clack.log.error(`Failed to write sourcemap configuration to angular.json`);\n captureException('Failed to write sourcemap configuration to angular.json');\n await configureAngularSourcemapGenerationFlow();\n }\n}\n\n/**\n * Extracted from `addSourcemapEntryToAngularJSON` and exported to allow for easier testing.\n */\nexport function addSourceMapsSetting(\n angularJson: PartialAngularJson,\n): PartialAngularJson | undefined {\n const newAngularJson = { ...angularJson };\n\n const projectKeys = Object.keys(newAngularJson.projects || {});\n\n if (!projectKeys.length || !newAngularJson.projects) {\n return undefined;\n }\n\n // Emit sourcemaps from all projects in angular.json\n for (const projectKey of projectKeys) {\n const projectConfig = newAngularJson.projects[projectKey];\n\n if (!projectConfig.architect) {\n projectConfig.architect = {};\n }\n\n if (!projectConfig.architect.build) {\n projectConfig.architect.build = {};\n }\n\n if (!projectConfig.architect.build.configurations) {\n projectConfig.architect.build.configurations = {};\n }\n\n projectConfig.architect.build.configurations.production = {\n ...projectConfig.architect.build.configurations.production,\n sourceMap: true,\n };\n }\n\n return newAngularJson;\n}\n\nfunction getParsedAngularJson(path: string): PartialAngularJson | undefined {\n try {\n const angularJSONFile = fs.readFileSync(path, 'utf-8');\n return JSON.parse(angularJSONFile) as PartialAngularJson | undefined;\n } catch {\n captureException('Could not parse `angular.json`');\n return undefined;\n }\n}\n"]}
@@ -0,0 +1,8 @@
1
+ interface ExampleComponentOptions {
2
+ url: string;
3
+ orgSlug: string;
4
+ projectId: string;
5
+ }
6
+ export declare function createExampleComponent(options: ExampleComponentOptions): Promise<void>;
7
+ export declare function getSentryExampleComponentCode(options: ExampleComponentOptions): string;
8
+ export {};