@sentry/wizard 6.12.0 → 6.13.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 (184) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/bin.js +16 -1
  3. package/dist/bin.js.map +1 -1
  4. package/dist/e2e-tests/tests/angular-17.test.js +3 -4
  5. package/dist/e2e-tests/tests/angular-17.test.js.map +1 -1
  6. package/dist/e2e-tests/tests/angular-19.test.js +3 -4
  7. package/dist/e2e-tests/tests/angular-19.test.js.map +1 -1
  8. package/dist/e2e-tests/tests/flutter.test.js +60 -0
  9. package/dist/e2e-tests/tests/flutter.test.js.map +1 -1
  10. package/dist/e2e-tests/tests/help-message.test.js +8 -3
  11. package/dist/e2e-tests/tests/help-message.test.js.map +1 -1
  12. package/dist/e2e-tests/tests/nuxt-3.test.js +12 -6
  13. package/dist/e2e-tests/tests/nuxt-3.test.js.map +1 -1
  14. package/dist/e2e-tests/tests/nuxt-4.test.js +12 -6
  15. package/dist/e2e-tests/tests/nuxt-4.test.js.map +1 -1
  16. package/dist/e2e-tests/tests/pnpm-workspace.test.js +6 -3
  17. package/dist/e2e-tests/tests/pnpm-workspace.test.js.map +1 -1
  18. package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js +4 -4
  19. package/dist/e2e-tests/tests/react-router-instrumentation-api.test.js.map +1 -1
  20. package/dist/e2e-tests/tests/react-router.test.js +3 -6
  21. package/dist/e2e-tests/tests/react-router.test.js.map +1 -1
  22. package/dist/e2e-tests/tests/remix.test.js +2 -4
  23. package/dist/e2e-tests/tests/remix.test.js.map +1 -1
  24. package/dist/e2e-tests/tests/sveltekit-hooks.test.js +24 -8
  25. package/dist/e2e-tests/tests/sveltekit-hooks.test.js.map +1 -1
  26. package/dist/e2e-tests/tests/sveltekit-tracing.test.js +6 -3
  27. package/dist/e2e-tests/tests/sveltekit-tracing.test.js.map +1 -1
  28. package/dist/lib/Constants.d.ts +1 -0
  29. package/dist/lib/Constants.js +5 -0
  30. package/dist/lib/Constants.js.map +1 -1
  31. package/dist/lib/Steps/Integrations/Electron.js +2 -2
  32. package/dist/lib/Steps/Integrations/Electron.js.map +1 -1
  33. package/dist/src/android/android-wizard.js +3 -0
  34. package/dist/src/android/android-wizard.js.map +1 -1
  35. package/dist/src/angular/codemods/main.d.ts +1 -1
  36. package/dist/src/angular/codemods/main.js +0 -1
  37. package/dist/src/angular/codemods/main.js.map +1 -1
  38. package/dist/src/apple/apple-wizard.js +2 -3
  39. package/dist/src/apple/apple-wizard.js.map +1 -1
  40. package/dist/src/apple/check-installed-cli.d.ts +1 -1
  41. package/dist/src/apple/check-installed-cli.js +13 -7
  42. package/dist/src/apple/check-installed-cli.js.map +1 -1
  43. package/dist/src/apple/configure-xcode-project.js +8 -1
  44. package/dist/src/apple/configure-xcode-project.js.map +1 -1
  45. package/dist/src/apple/lookup-xcode-project.d.ts +8 -5
  46. package/dist/src/apple/lookup-xcode-project.js +22 -17
  47. package/dist/src/apple/lookup-xcode-project.js.map +1 -1
  48. package/dist/src/apple/options.d.ts +5 -0
  49. package/dist/src/apple/options.js.map +1 -1
  50. package/dist/src/apple/sentry-swift-package.d.ts +4 -0
  51. package/dist/src/apple/sentry-swift-package.js +17 -0
  52. package/dist/src/apple/sentry-swift-package.js.map +1 -0
  53. package/dist/src/apple/snapshots/apple-snapshots-wizard.d.ts +2 -0
  54. package/dist/src/apple/snapshots/apple-snapshots-wizard.js +251 -0
  55. package/dist/src/apple/snapshots/apple-snapshots-wizard.js.map +1 -0
  56. package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.d.ts +13 -0
  57. package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js +48 -0
  58. package/dist/src/apple/snapshots/configure-snapshotpreviews-xcode-project.js.map +1 -0
  59. package/dist/src/apple/snapshots/snapshot-test-file.d.ts +18 -0
  60. package/dist/src/apple/snapshots/snapshot-test-file.js +122 -0
  61. package/dist/src/apple/snapshots/snapshot-test-file.js.map +1 -0
  62. package/dist/src/apple/snapshots/snapshot-verification-scheme.d.ts +6 -0
  63. package/dist/src/apple/snapshots/snapshot-verification-scheme.js +147 -0
  64. package/dist/src/apple/snapshots/snapshot-verification-scheme.js.map +1 -0
  65. package/dist/src/apple/snapshots/snapshotpreviews-package.d.ts +4 -0
  66. package/dist/src/apple/snapshots/snapshotpreviews-package.js +8 -0
  67. package/dist/src/apple/snapshots/snapshotpreviews-package.js.map +1 -0
  68. package/dist/src/apple/snapshots/snapshots-cli-preflight.d.ts +23 -0
  69. package/dist/src/apple/snapshots/snapshots-cli-preflight.js +136 -0
  70. package/dist/src/apple/snapshots/snapshots-cli-preflight.js.map +1 -0
  71. package/dist/src/apple/xcode-manager.d.ts +59 -1
  72. package/dist/src/apple/xcode-manager.js +507 -106
  73. package/dist/src/apple/xcode-manager.js.map +1 -1
  74. package/dist/src/flutter/flutter-wizard.js +3 -0
  75. package/dist/src/flutter/flutter-wizard.js.map +1 -1
  76. package/dist/src/nextjs/templates.js +12 -6
  77. package/dist/src/nextjs/templates.js.map +1 -1
  78. package/dist/src/nuxt/templates.js +12 -6
  79. package/dist/src/nuxt/templates.js.map +1 -1
  80. package/dist/src/react-router/codemods/client.entry.d.ts +1 -1
  81. package/dist/src/react-router/codemods/client.entry.js +93 -52
  82. package/dist/src/react-router/codemods/client.entry.js.map +1 -1
  83. package/dist/src/react-router/codemods/server-entry.js +8 -7
  84. package/dist/src/react-router/codemods/server-entry.js.map +1 -1
  85. package/dist/src/react-router/react-router-wizard.js +13 -19
  86. package/dist/src/react-router/react-router-wizard.js.map +1 -1
  87. package/dist/src/react-router/sdk-setup.d.ts +2 -2
  88. package/dist/src/react-router/sdk-setup.js +16 -15
  89. package/dist/src/react-router/sdk-setup.js.map +1 -1
  90. package/dist/src/react-router/templates.d.ts +1 -3
  91. package/dist/src/react-router/templates.js +24 -92
  92. package/dist/src/react-router/templates.js.map +1 -1
  93. package/dist/src/remix/sdk-setup.js +1 -2
  94. package/dist/src/remix/sdk-setup.js.map +1 -1
  95. package/dist/src/run.d.ts +4 -1
  96. package/dist/src/run.js +13 -0
  97. package/dist/src/run.js.map +1 -1
  98. package/dist/src/sourcemaps/tools/remix.js +4 -4
  99. package/dist/src/sourcemaps/tools/remix.js.map +1 -1
  100. package/dist/src/sveltekit/sdk-setup/setup.js +17 -4
  101. package/dist/src/sveltekit/sdk-setup/setup.js.map +1 -1
  102. package/dist/src/sveltekit/templates.js +12 -6
  103. package/dist/src/sveltekit/templates.js.map +1 -1
  104. package/dist/src/utils/clack/index.d.ts +2 -1
  105. package/dist/src/utils/clack/index.js +17 -6
  106. package/dist/src/utils/clack/index.js.map +1 -1
  107. package/dist/src/utils/files.d.ts +2 -0
  108. package/dist/src/utils/files.js +58 -0
  109. package/dist/src/utils/files.js.map +1 -0
  110. package/dist/src/utils/git.d.ts +3 -1
  111. package/dist/src/utils/git.js +2 -1
  112. package/dist/src/utils/git.js.map +1 -1
  113. package/dist/src/utils/line-endings.d.ts +1 -0
  114. package/dist/src/utils/line-endings.js +76 -0
  115. package/dist/src/utils/line-endings.js.map +1 -0
  116. package/dist/src/version.d.ts +1 -1
  117. package/dist/src/version.js +1 -1
  118. package/dist/src/version.js.map +1 -1
  119. package/dist/test/angular/angular-wizard.test.js +0 -5
  120. package/dist/test/angular/angular-wizard.test.js.map +1 -1
  121. package/dist/test/apple/lookup-xcode-project.test.js +167 -0
  122. package/dist/test/apple/lookup-xcode-project.test.js.map +1 -0
  123. package/dist/test/apple/snapshots/apple-snapshots-wizard.test.d.ts +1 -0
  124. package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js +487 -0
  125. package/dist/test/apple/snapshots/apple-snapshots-wizard.test.js.map +1 -0
  126. package/dist/test/apple/snapshots/hosted-test-target-fixture.d.ts +24 -0
  127. package/dist/test/apple/snapshots/hosted-test-target-fixture.js +191 -0
  128. package/dist/test/apple/snapshots/hosted-test-target-fixture.js.map +1 -0
  129. package/dist/test/apple/snapshots/snapshot-test-file.test.d.ts +1 -0
  130. package/dist/test/apple/snapshots/snapshot-test-file.test.js +110 -0
  131. package/dist/test/apple/snapshots/snapshot-test-file.test.js.map +1 -0
  132. package/dist/test/apple/snapshots/snapshot-verification-scheme.test.d.ts +1 -0
  133. package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js +146 -0
  134. package/dist/test/apple/snapshots/snapshot-verification-scheme.test.js.map +1 -0
  135. package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.d.ts +1 -0
  136. package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js +186 -0
  137. package/dist/test/apple/snapshots/snapshotpreviews-xcode-smoke.test.js.map +1 -0
  138. package/dist/test/apple/snapshots/snapshots-cli-preflight.test.d.ts +1 -0
  139. package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js +192 -0
  140. package/dist/test/apple/snapshots/snapshots-cli-preflight.test.js.map +1 -0
  141. package/dist/test/apple/snapshots/source-file-insertion.test.d.ts +1 -0
  142. package/dist/test/apple/snapshots/source-file-insertion.test.js +77 -0
  143. package/dist/test/apple/snapshots/source-file-insertion.test.js.map +1 -0
  144. package/dist/test/apple/xcode-manager.test.js +452 -43
  145. package/dist/test/apple/xcode-manager.test.js.map +1 -1
  146. package/dist/test/constants.test.d.ts +1 -0
  147. package/dist/test/constants.test.js +12 -0
  148. package/dist/test/constants.test.js.map +1 -0
  149. package/dist/test/nextjs/templates.test.js +66 -33
  150. package/dist/test/nextjs/templates.test.js.map +1 -1
  151. package/dist/test/nuxt/templates.test.js +66 -36
  152. package/dist/test/nuxt/templates.test.js.map +1 -1
  153. package/dist/test/react-router/codemods/client-entry.test.js +15 -11
  154. package/dist/test/react-router/codemods/client-entry.test.js.map +1 -1
  155. package/dist/test/react-router/codemods/server-entry.test.js +21 -8
  156. package/dist/test/react-router/codemods/server-entry.test.js.map +1 -1
  157. package/dist/test/react-router/sdk-setup.test.js +46 -10
  158. package/dist/test/react-router/sdk-setup.test.js.map +1 -1
  159. package/dist/test/react-router/templates.test.js +26 -64
  160. package/dist/test/react-router/templates.test.js.map +1 -1
  161. package/dist/test/remix/build-script.test.d.ts +1 -0
  162. package/dist/test/remix/build-script.test.js +124 -0
  163. package/dist/test/remix/build-script.test.js.map +1 -0
  164. package/dist/test/remix/client-entry.test.js +4 -10
  165. package/dist/test/remix/client-entry.test.js.map +1 -1
  166. package/dist/test/run.test.d.ts +1 -0
  167. package/dist/test/run.test.js +137 -0
  168. package/dist/test/run.test.js.map +1 -0
  169. package/dist/test/sveltekit/templates.test.js +78 -27
  170. package/dist/test/sveltekit/templates.test.js.map +1 -1
  171. package/dist/test/utils/clack/index.test.js +101 -0
  172. package/dist/test/utils/clack/index.test.js.map +1 -1
  173. package/dist/test/utils/git.test.js +10 -0
  174. package/dist/test/utils/git.test.js.map +1 -1
  175. package/dist/test/utils/line-endings.test.d.ts +1 -0
  176. package/dist/test/utils/line-endings.test.js +103 -0
  177. package/dist/test/utils/line-endings.test.js.map +1 -0
  178. package/package.json +2 -2
  179. package/dist/src/react-router/codemods/root.d.ts +0 -1
  180. package/dist/src/react-router/codemods/root.js +0 -170
  181. package/dist/src/react-router/codemods/root.js.map +0 -1
  182. package/dist/test/react-router/codemods/root.test.js +0 -182
  183. package/dist/test/react-router/codemods/root.test.js.map +0 -1
  184. /package/dist/test/{react-router/codemods/root.test.d.ts → apple/lookup-xcode-project.test.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/utils/git.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4DAA8C;AAC9C,uCAAyB;AAEzB;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,IAAiC;IAC3D,IAAI;QACF,YAAY,CAAC,QAAQ,CAAC,qCAAqC,EAAE;YAC3D,KAAK,EAAE,QAAQ;YACf,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;KACb;IAAC,MAAM;QACN,OAAO,KAAK,CAAC;KACd;AACH,CAAC;AAVD,kCAUC;AAED,SAAgB,8BAA8B;IAC5C,IAAI;QACF,MAAM,SAAS,GAAG,YAAY;aAC3B,QAAQ,CAAC,2BAA2B,EAAE;YACrC,4BAA4B;YAC5B,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC;aACD,QAAQ,EAAE,CAAC;QAEd,MAAM,KAAK,GAAG,SAAS;aACpB,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC;aACb,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aAC1B,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAExC,OAAO,KAAK,CAAC;KACd;IAAC,MAAM;QACN,OAAO,EAAE,CAAC;KACX;AACH,CAAC;AAnBD,wEAmBC","sourcesContent":["import * as childProcess from 'child_process';\nimport * as os from 'os';\n\n/**\n * Checks if the current working directory is a git repository.\n *\n * @param opts.cwd The directory of the project. If undefined, the current process working directory will be used.\n *\n * @returns true if the current working directory is a git repository, false otherwise.\n */\nexport function isInGitRepo(opts: { cwd: string | undefined }) {\n try {\n childProcess.execSync('git rev-parse --is-inside-work-tree', {\n stdio: 'ignore',\n cwd: opts.cwd,\n });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function getUncommittedOrUntrackedFiles(): string[] {\n try {\n const gitStatus = childProcess\n .execSync('git status --porcelain=v1', {\n // we only care about stdout\n stdio: ['ignore', 'pipe', 'ignore'],\n })\n .toString();\n\n const files = gitStatus\n .split(os.EOL)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((f) => `- ${f.split(/\\s+/)[1]}`);\n\n return files;\n } catch {\n return [];\n }\n}\n"]}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/utils/git.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4DAA8C;AAC9C,uCAAyB;AAEzB;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,IAAiC;IAC3D,IAAI;QACF,YAAY,CAAC,QAAQ,CAAC,qCAAqC,EAAE;YAC3D,KAAK,EAAE,QAAQ;YACf,GAAG,EAAE,IAAI,CAAC,GAAG;SACd,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;KACb;IAAC,MAAM;QACN,OAAO,KAAK,CAAC;KACd;AACH,CAAC;AAVD,kCAUC;AAED,SAAgB,8BAA8B,CAAC,IAE9C;IACC,IAAI;QACF,MAAM,SAAS,GAAG,YAAY;aAC3B,QAAQ,CAAC,2BAA2B,EAAE;YACrC,4BAA4B;YAC5B,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;YACnC,GAAG,EAAE,IAAI,EAAE,GAAG;SACf,CAAC;aACD,QAAQ,EAAE,CAAC;QAEd,MAAM,KAAK,GAAG,SAAS;aACpB,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC;aACb,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aAC1B,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAExC,OAAO,KAAK,CAAC;KACd;IAAC,MAAM;QACN,OAAO,EAAE,CAAC;KACX;AACH,CAAC;AAtBD,wEAsBC","sourcesContent":["import * as childProcess from 'child_process';\nimport * as os from 'os';\n\n/**\n * Checks if the current working directory is a git repository.\n *\n * @param opts.cwd The directory of the project. If undefined, the current process working directory will be used.\n *\n * @returns true if the current working directory is a git repository, false otherwise.\n */\nexport function isInGitRepo(opts: { cwd: string | undefined }) {\n try {\n childProcess.execSync('git rev-parse --is-inside-work-tree', {\n stdio: 'ignore',\n cwd: opts.cwd,\n });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function getUncommittedOrUntrackedFiles(opts?: {\n cwd: string | undefined;\n}): string[] {\n try {\n const gitStatus = childProcess\n .execSync('git status --porcelain=v1', {\n // we only care about stdout\n stdio: ['ignore', 'pipe', 'ignore'],\n cwd: opts?.cwd,\n })\n .toString();\n\n const files = gitStatus\n .split(os.EOL)\n .map((line) => line.trim())\n .filter(Boolean)\n .map((f) => `- ${f.split(/\\s+/)[1]}`);\n\n return files;\n } catch {\n return [];\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function fixLineEndings(): void;
@@ -0,0 +1,76 @@
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.fixLineEndings = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ const git_1 = require("./git");
30
+ /**
31
+ * Fixes mixed line endings in files modified by the wizard.
32
+ *
33
+ * When the wizard reads a CRLF file and inserts content with hardcoded \n,
34
+ * the result is mixed line endings. This function detects files with CRLF
35
+ * and normalizes all line endings to CRLF.
36
+ *
37
+ * Call this at the end of a wizard run, similar to runPrettierIfInstalled().
38
+ */
39
+ const TEXT_EXTENSIONS = new Set([
40
+ '.dart',
41
+ '.yaml',
42
+ '.yml',
43
+ '.properties',
44
+ '.java',
45
+ '.kt',
46
+ '.xml',
47
+ '.gradle',
48
+ '.kts',
49
+ '.gitignore',
50
+ '.json',
51
+ ]);
52
+ function fixLineEndings() {
53
+ const files = (0, git_1.getUncommittedOrUntrackedFiles)()
54
+ .map((f) => (f.startsWith('- ') ? f.slice(2) : f))
55
+ .filter(Boolean);
56
+ for (const file of files) {
57
+ const filePath = path.resolve(file);
58
+ if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
59
+ continue;
60
+ }
61
+ const ext = path.extname(filePath).toLowerCase();
62
+ const basename = path.basename(filePath);
63
+ if (!TEXT_EXTENSIONS.has(ext) && !TEXT_EXTENSIONS.has(basename)) {
64
+ continue;
65
+ }
66
+ const content = fs.readFileSync(filePath, 'utf8');
67
+ if (!content.includes('\r\n')) {
68
+ continue;
69
+ }
70
+ // File has CRLF — normalize all line endings to CRLF
71
+ const normalized = content.replace(/\r\n/g, '\n').replace(/\n/g, '\r\n');
72
+ fs.writeFileSync(filePath, normalized, 'utf8');
73
+ }
74
+ }
75
+ exports.fixLineEndings = fixLineEndings;
76
+ //# sourceMappingURL=line-endings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line-endings.js","sourceRoot":"","sources":["../../../src/utils/line-endings.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,+BAAuD;AAEvD;;;;;;;;GAQG;AACH,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,OAAO;IACP,OAAO;IACP,MAAM;IACN,aAAa;IACb,OAAO;IACP,KAAK;IACL,MAAM;IACN,SAAS;IACT,MAAM;IACN,YAAY;IACZ,OAAO;CACR,CAAC,CAAC;AAEH,SAAgB,cAAc;IAC5B,MAAM,KAAK,GAAG,IAAA,oCAA8B,GAAE;SAC3C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;SACjD,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAEpC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE;YAC/D,SAAS;SACV;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;YAC/D,SAAS;SACV;QAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAElD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE;YAC7B,SAAS;SACV;QAED,qDAAqD;QACrD,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACzE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;KAChD;AACH,CAAC;AA5BD,wCA4BC","sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\nimport { getUncommittedOrUntrackedFiles } from './git';\n\n/**\n * Fixes mixed line endings in files modified by the wizard.\n *\n * When the wizard reads a CRLF file and inserts content with hardcoded \\n,\n * the result is mixed line endings. This function detects files with CRLF\n * and normalizes all line endings to CRLF.\n *\n * Call this at the end of a wizard run, similar to runPrettierIfInstalled().\n */\nconst TEXT_EXTENSIONS = new Set([\n '.dart',\n '.yaml',\n '.yml',\n '.properties',\n '.java',\n '.kt',\n '.xml',\n '.gradle',\n '.kts',\n '.gitignore',\n '.json',\n]);\n\nexport function fixLineEndings(): void {\n const files = getUncommittedOrUntrackedFiles()\n .map((f) => (f.startsWith('- ') ? f.slice(2) : f))\n .filter(Boolean);\n\n for (const file of files) {\n const filePath = path.resolve(file);\n\n if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {\n continue;\n }\n\n const ext = path.extname(filePath).toLowerCase();\n const basename = path.basename(filePath);\n if (!TEXT_EXTENSIONS.has(ext) && !TEXT_EXTENSIONS.has(basename)) {\n continue;\n }\n\n const content = fs.readFileSync(filePath, 'utf8');\n\n if (!content.includes('\\r\\n')) {\n continue;\n }\n\n // File has CRLF — normalize all line endings to CRLF\n const normalized = content.replace(/\\r\\n/g, '\\n').replace(/\\n/g, '\\r\\n');\n fs.writeFileSync(filePath, normalized, 'utf8');\n }\n}\n"]}
@@ -1 +1 @@
1
- export declare const WIZARD_VERSION = "6.12.0";
1
+ export declare const WIZARD_VERSION = "6.13.0";
@@ -3,5 +3,5 @@
3
3
  // This is file is updated at release time.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.WIZARD_VERSION = void 0;
6
- exports.WIZARD_VERSION = '6.12.0';
6
+ exports.WIZARD_VERSION = '6.13.0';
7
7
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";AAAA,oCAAoC;AACpC,2CAA2C;;;AAE9B,QAAA,cAAc,GAAG,QAAQ,CAAC","sourcesContent":["// DO NOT modify this file manually!\n// This is file is updated at release time.\n\nexport const WIZARD_VERSION = '6.12.0';\n"]}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";AAAA,oCAAoC;AACpC,2CAA2C;;;AAE9B,QAAA,cAAc,GAAG,QAAQ,CAAC","sourcesContent":["// DO NOT modify this file manually!\n// This is file is updated at release time.\n\nexport const WIZARD_VERSION = '6.13.0';\n"]}
@@ -44,7 +44,6 @@ vitest_1.vi.mock('../../src/utils/clack/mcp-config', () => ({
44
44
  ],
45
45
  "replaysOnErrorSampleRate": 1,
46
46
  "replaysSessionSampleRate": 0.1,
47
- "sendDefaultPii": true,
48
47
  "tracesSampleRate": 1,
49
48
  }
50
49
  `);
@@ -64,7 +63,6 @@ vitest_1.vi.mock('../../src/utils/clack/mcp-config', () => ({
64
63
  ],
65
64
  "replaysOnErrorSampleRate": 1,
66
65
  "replaysSessionSampleRate": 0.1,
67
- "sendDefaultPii": true,
68
66
  }
69
67
  `);
70
68
  });
@@ -81,7 +79,6 @@ vitest_1.vi.mock('../../src/utils/clack/mcp-config', () => ({
81
79
  "integrations": [
82
80
  {},
83
81
  ],
84
- "sendDefaultPii": true,
85
82
  "tracesSampleRate": 1,
86
83
  }
87
84
  `);
@@ -101,7 +98,6 @@ vitest_1.vi.mock('../../src/utils/clack/mcp-config', () => ({
101
98
  ],
102
99
  "replaysOnErrorSampleRate": 1,
103
100
  "replaysSessionSampleRate": 0.1,
104
- "sendDefaultPii": true,
105
101
  "tracesSampleRate": 1,
106
102
  }
107
103
  `);
@@ -115,7 +111,6 @@ vitest_1.vi.mock('../../src/utils/clack/mcp-config', () => ({
115
111
  (0, vitest_1.expect)(args).toMatchInlineSnapshot(`
116
112
  {
117
113
  "dsn": "https://example.com",
118
- "sendDefaultPii": true,
119
114
  }
120
115
  `);
121
116
  });
@@ -1 +1 @@
1
- {"version":3,"file":"angular-wizard.test.js","sourceRoot":"","sources":["../../../test/angular/angular-wizard.test.ts"],"names":[],"mappings":";;AAAA,mCAAkD;AAElD,qEAAqE;AACrE,0DAAkE;AAElE,WAAE,CAAC,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE,CAAC,CAAC;IACjD,2BAA2B,EAAE,WAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;CAClE,CAAC,CAAC,CAAC;AAEJ,IAAA,iBAAQ,EAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,IAAA,WAAE,EAAC,oEAAoE,EAAE,GAAG,EAAE;YAC5E,IAAA,eAAM,EAAC,IAAA,kCAAiB,EAAC,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;OAOrD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAA,WAAE,EAAC,6EAA6E,EAAE,GAAG,EAAE;YACrF,IAAA,eAAM,EAAC,IAAA,kCAAiB,EAAC,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;OAKtD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,IAAA,WAAE,EAAC,uEAAuE,EAAE,GAAG,EAAE;YAC/E,MAAM,IAAI,GAAG,IAAA,sBAAe,EAAC,qBAAqB,EAAE;gBAClD,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YACH,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;;OAalC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,sEAAsE,EAAE,GAAG,EAAE;YAC9E,MAAM,IAAI,GAAG,IAAA,sBAAe,EAAC,qBAAqB,EAAE;gBAClD,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;OAWlC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,iEAAiE,EAAE,GAAG,EAAE;YACzE,MAAM,IAAI,GAAG,IAAA,sBAAe,EAAC,qBAAqB,EAAE;gBAClD,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;OAUlC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,gEAAgE,EAAE,GAAG,EAAE;YACxE,MAAM,IAAI,GAAG,IAAA,sBAAe,EAAC,qBAAqB,EAAE;gBAClD,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;OAYlC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,wEAAwE,EAAE,GAAG,EAAE;YAChF,MAAM,IAAI,GAAG,IAAA,sBAAe,EAAC,qBAAqB,EAAE;gBAClD,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC;;;;;OAKlC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it, vi } from 'vitest';\n\nimport { buildOutroMessage } from '../../src/angular/angular-wizard';\nimport { getInitCallArgs } from '../../src/angular/codemods/main';\n\nvi.mock('../../src/utils/clack/mcp-config', () => ({\n offerProjectScopedMcpConfig: vi.fn().mockResolvedValue(undefined),\n}));\n\ndescribe('angular-wizard', () => {\n describe('buildOutroMessage', () => {\n it('returns the correct outro message if example component was created', () => {\n expect(buildOutroMessage(true)).toMatchInlineSnapshot(`\n \"Successfully installed the Sentry Angular SDK!\n\n You can validate your setup by starting your dev environment (ng serve) and throwing an error in the example component.\n\n Check out the SDK documentation for further configuration:\n https://docs.sentry.io/platforms/javascript/guides/angular/\"\n `);\n });\n it('returns the correct outro message if example component creation was skipped', () => {\n expect(buildOutroMessage(false)).toMatchInlineSnapshot(`\n \"Successfully installed the Sentry Angular SDK!\n\n Check out the SDK documentation for further configuration:\n https://docs.sentry.io/platforms/javascript/guides/angular/\"\n `);\n });\n });\n\n describe('getInitCallArgs', () => {\n it('returns the correct init call arguments when all features are enabled', () => {\n const args = getInitCallArgs('https://example.com', {\n performance: true,\n replay: true,\n logs: true,\n });\n expect(args).toMatchInlineSnapshot(`\n {\n \"dsn\": \"https://example.com\",\n \"enableLogs\": true,\n \"integrations\": [\n {},\n {},\n ],\n \"replaysOnErrorSampleRate\": 1,\n \"replaysSessionSampleRate\": 0.1,\n \"sendDefaultPii\": true,\n \"tracesSampleRate\": 1,\n }\n `);\n });\n\n it('returns the correct init call arguments when performance is disabled', () => {\n const args = getInitCallArgs('https://example.com', {\n performance: false,\n replay: true,\n logs: true,\n });\n\n expect(args).toMatchInlineSnapshot(`\n {\n \"dsn\": \"https://example.com\",\n \"enableLogs\": true,\n \"integrations\": [\n {},\n ],\n \"replaysOnErrorSampleRate\": 1,\n \"replaysSessionSampleRate\": 0.1,\n \"sendDefaultPii\": true,\n }\n `);\n });\n\n it('returns the correct init call arguments when replay is disabled', () => {\n const args = getInitCallArgs('https://example.com', {\n performance: true,\n replay: false,\n logs: true,\n });\n\n expect(args).toMatchInlineSnapshot(`\n {\n \"dsn\": \"https://example.com\",\n \"enableLogs\": true,\n \"integrations\": [\n {},\n ],\n \"sendDefaultPii\": true,\n \"tracesSampleRate\": 1,\n }\n `);\n });\n\n it('returns the correct init call arguments when logs are disabled', () => {\n const args = getInitCallArgs('https://example.com', {\n performance: true,\n replay: true,\n logs: false,\n });\n\n expect(args).toMatchInlineSnapshot(`\n {\n \"dsn\": \"https://example.com\",\n \"integrations\": [\n {},\n {},\n ],\n \"replaysOnErrorSampleRate\": 1,\n \"replaysSessionSampleRate\": 0.1,\n \"sendDefaultPii\": true,\n \"tracesSampleRate\": 1,\n }\n `);\n });\n\n it('returns the correct init call arguments when all features are disabled', () => {\n const args = getInitCallArgs('https://example.com', {\n performance: false,\n replay: false,\n logs: false,\n });\n\n expect(args).toMatchInlineSnapshot(`\n {\n \"dsn\": \"https://example.com\",\n \"sendDefaultPii\": true,\n }\n `);\n });\n });\n});\n"]}
1
+ {"version":3,"file":"angular-wizard.test.js","sourceRoot":"","sources":["../../../test/angular/angular-wizard.test.ts"],"names":[],"mappings":";;AAAA,mCAAkD;AAElD,qEAAqE;AACrE,0DAAkE;AAElE,WAAE,CAAC,IAAI,CAAC,kCAAkC,EAAE,GAAG,EAAE,CAAC,CAAC;IACjD,2BAA2B,EAAE,WAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;CAClE,CAAC,CAAC,CAAC;AAEJ,IAAA,iBAAQ,EAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,IAAA,WAAE,EAAC,oEAAoE,EAAE,GAAG,EAAE;YAC5E,IAAA,eAAM,EAAC,IAAA,kCAAiB,EAAC,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;;;OAOrD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAA,WAAE,EAAC,6EAA6E,EAAE,GAAG,EAAE;YACrF,IAAA,eAAM,EAAC,IAAA,kCAAiB,EAAC,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC;;;;;OAKtD,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,IAAA,WAAE,EAAC,uEAAuE,EAAE,GAAG,EAAE;YAC/E,MAAM,IAAI,GAAG,IAAA,sBAAe,EAAC,qBAAqB,EAAE;gBAClD,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YACH,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;;OAYlC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,sEAAsE,EAAE,GAAG,EAAE;YAC9E,MAAM,IAAI,GAAG,IAAA,sBAAe,EAAC,qBAAqB,EAAE;gBAClD,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;OAUlC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,iEAAiE,EAAE,GAAG,EAAE;YACzE,MAAM,IAAI,GAAG,IAAA,sBAAe,EAAC,qBAAqB,EAAE;gBAClD,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;OASlC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,gEAAgE,EAAE,GAAG,EAAE;YACxE,MAAM,IAAI,GAAG,IAAA,sBAAe,EAAC,qBAAqB,EAAE;gBAClD,WAAW,EAAE,IAAI;gBACjB,MAAM,EAAE,IAAI;gBACZ,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;;;OAWlC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,wEAAwE,EAAE,GAAG,EAAE;YAChF,MAAM,IAAI,GAAG,IAAA,sBAAe,EAAC,qBAAqB,EAAE;gBAClD,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;YAEH,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,qBAAqB,CAAC;;;;OAIlC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { describe, expect, it, vi } from 'vitest';\n\nimport { buildOutroMessage } from '../../src/angular/angular-wizard';\nimport { getInitCallArgs } from '../../src/angular/codemods/main';\n\nvi.mock('../../src/utils/clack/mcp-config', () => ({\n offerProjectScopedMcpConfig: vi.fn().mockResolvedValue(undefined),\n}));\n\ndescribe('angular-wizard', () => {\n describe('buildOutroMessage', () => {\n it('returns the correct outro message if example component was created', () => {\n expect(buildOutroMessage(true)).toMatchInlineSnapshot(`\n \"Successfully installed the Sentry Angular SDK!\n\n You can validate your setup by starting your dev environment (ng serve) and throwing an error in the example component.\n\n Check out the SDK documentation for further configuration:\n https://docs.sentry.io/platforms/javascript/guides/angular/\"\n `);\n });\n it('returns the correct outro message if example component creation was skipped', () => {\n expect(buildOutroMessage(false)).toMatchInlineSnapshot(`\n \"Successfully installed the Sentry Angular SDK!\n\n Check out the SDK documentation for further configuration:\n https://docs.sentry.io/platforms/javascript/guides/angular/\"\n `);\n });\n });\n\n describe('getInitCallArgs', () => {\n it('returns the correct init call arguments when all features are enabled', () => {\n const args = getInitCallArgs('https://example.com', {\n performance: true,\n replay: true,\n logs: true,\n });\n expect(args).toMatchInlineSnapshot(`\n {\n \"dsn\": \"https://example.com\",\n \"enableLogs\": true,\n \"integrations\": [\n {},\n {},\n ],\n \"replaysOnErrorSampleRate\": 1,\n \"replaysSessionSampleRate\": 0.1,\n \"tracesSampleRate\": 1,\n }\n `);\n });\n\n it('returns the correct init call arguments when performance is disabled', () => {\n const args = getInitCallArgs('https://example.com', {\n performance: false,\n replay: true,\n logs: true,\n });\n\n expect(args).toMatchInlineSnapshot(`\n {\n \"dsn\": \"https://example.com\",\n \"enableLogs\": true,\n \"integrations\": [\n {},\n ],\n \"replaysOnErrorSampleRate\": 1,\n \"replaysSessionSampleRate\": 0.1,\n }\n `);\n });\n\n it('returns the correct init call arguments when replay is disabled', () => {\n const args = getInitCallArgs('https://example.com', {\n performance: true,\n replay: false,\n logs: true,\n });\n\n expect(args).toMatchInlineSnapshot(`\n {\n \"dsn\": \"https://example.com\",\n \"enableLogs\": true,\n \"integrations\": [\n {},\n ],\n \"tracesSampleRate\": 1,\n }\n `);\n });\n\n it('returns the correct init call arguments when logs are disabled', () => {\n const args = getInitCallArgs('https://example.com', {\n performance: true,\n replay: true,\n logs: false,\n });\n\n expect(args).toMatchInlineSnapshot(`\n {\n \"dsn\": \"https://example.com\",\n \"integrations\": [\n {},\n {},\n ],\n \"replaysOnErrorSampleRate\": 1,\n \"replaysSessionSampleRate\": 0.1,\n \"tracesSampleRate\": 1,\n }\n `);\n });\n\n it('returns the correct init call arguments when all features are disabled', () => {\n const args = getInitCallArgs('https://example.com', {\n performance: false,\n replay: false,\n logs: false,\n });\n\n expect(args).toMatchInlineSnapshot(`\n {\n \"dsn\": \"https://example.com\",\n }\n `);\n });\n });\n});\n"]}
@@ -0,0 +1,167 @@
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
+ const fs = __importStar(require("node:fs"));
27
+ const os = __importStar(require("node:os"));
28
+ const path = __importStar(require("node:path"));
29
+ const vitest_1 = require("vitest");
30
+ const mocks = vitest_1.vi.hoisted(() => {
31
+ const targetsByProjectPath = new Map();
32
+ return {
33
+ abort: vitest_1.vi.fn(() => {
34
+ throw new Error('abort');
35
+ }),
36
+ askForItemSelection: vitest_1.vi.fn(),
37
+ clackError: vitest_1.vi.fn(),
38
+ debug: vitest_1.vi.fn(),
39
+ searchXcodeProjectAtPath: vitest_1.vi.fn(),
40
+ setTag: vitest_1.vi.fn(),
41
+ targetsByProjectPath,
42
+ traceStep: vitest_1.vi.fn(async (_name, callback) => await callback()),
43
+ XcodeProject: vitest_1.vi.fn(function (projectPath) {
44
+ this.projectPath = projectPath;
45
+ this.xcodeprojPath = path.dirname(projectPath);
46
+ this.getAllTargets = () => targetsByProjectPath.get(projectPath) ?? [];
47
+ }),
48
+ };
49
+ });
50
+ vitest_1.vi.mock('@clack/prompts', () => ({
51
+ default: {
52
+ log: {
53
+ error: mocks.clackError,
54
+ },
55
+ },
56
+ }));
57
+ vitest_1.vi.mock('@sentry/node', () => ({
58
+ setTag: mocks.setTag,
59
+ }));
60
+ vitest_1.vi.mock('../../src/apple/search-xcode-project-at-path', () => ({
61
+ searchXcodeProjectAtPath: mocks.searchXcodeProjectAtPath,
62
+ }));
63
+ vitest_1.vi.mock('../../src/apple/xcode-manager', () => ({
64
+ XcodeProject: mocks.XcodeProject,
65
+ }));
66
+ vitest_1.vi.mock('../../src/telemetry', () => ({
67
+ traceStep: mocks.traceStep,
68
+ }));
69
+ vitest_1.vi.mock('../../src/utils/clack', () => ({
70
+ abort: mocks.abort,
71
+ askForItemSelection: mocks.askForItemSelection,
72
+ }));
73
+ vitest_1.vi.mock('../../src/utils/debug', () => ({
74
+ debug: mocks.debug,
75
+ }));
76
+ const lookup_xcode_project_1 = require("../../src/apple/lookup-xcode-project");
77
+ function createProject(projectDir, projectName) {
78
+ const projectPath = path.join(projectDir, projectName);
79
+ fs.mkdirSync(projectPath, { recursive: true });
80
+ const pbxprojPath = path.join(projectPath, 'project.pbxproj');
81
+ fs.writeFileSync(pbxprojPath, 'mock pbxproj');
82
+ return pbxprojPath;
83
+ }
84
+ function createMockXcodeProject(pbxprojPath) {
85
+ const XcodeProjectConstructor = mocks.XcodeProject;
86
+ return new XcodeProjectConstructor(pbxprojPath);
87
+ }
88
+ (0, vitest_1.describe)('lookup-xcode-project', () => {
89
+ let projectDir;
90
+ (0, vitest_1.beforeEach)(() => {
91
+ projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'lookup-xcode-project-'));
92
+ vitest_1.vi.clearAllMocks();
93
+ mocks.targetsByProjectPath.clear();
94
+ });
95
+ (0, vitest_1.afterEach)(() => {
96
+ fs.rmSync(projectDir, { force: true, recursive: true });
97
+ });
98
+ (0, vitest_1.describe)('lookupXcodeProject', () => {
99
+ (0, vitest_1.it)('returns an Xcode project without selecting a target', async () => {
100
+ const pbxprojPath = createProject(projectDir, 'App.xcodeproj');
101
+ mocks.searchXcodeProjectAtPath.mockReturnValue(['App.xcodeproj']);
102
+ mocks.targetsByProjectPath.set(pbxprojPath, ['App']);
103
+ const result = await (0, lookup_xcode_project_1.lookupXcodeProject)({ projectDir });
104
+ (0, vitest_1.expect)(mocks.searchXcodeProjectAtPath).toHaveBeenCalledWith(projectDir);
105
+ (0, vitest_1.expect)(mocks.XcodeProject).toHaveBeenCalledWith(pbxprojPath);
106
+ (0, vitest_1.expect)(result).toEqual(vitest_1.expect.objectContaining({ projectPath: pbxprojPath }));
107
+ (0, vitest_1.expect)(mocks.askForItemSelection).not.toHaveBeenCalledWith(['App'], 'Which target do you want to add Sentry to?');
108
+ });
109
+ (0, vitest_1.it)('prompts when multiple Xcode projects are found', async () => {
110
+ createProject(projectDir, 'First.xcodeproj');
111
+ const selectedPbxprojPath = createProject(projectDir, 'Second.xcodeproj');
112
+ mocks.searchXcodeProjectAtPath.mockReturnValue([
113
+ 'First.xcodeproj',
114
+ 'Second.xcodeproj',
115
+ ]);
116
+ mocks.askForItemSelection.mockResolvedValue({
117
+ value: 'Second.xcodeproj',
118
+ });
119
+ const result = await (0, lookup_xcode_project_1.lookupXcodeProject)({ projectDir });
120
+ (0, vitest_1.expect)(mocks.askForItemSelection).toHaveBeenCalledWith(['First.xcodeproj', 'Second.xcodeproj'], 'Which project do you want to add Sentry to?');
121
+ (0, vitest_1.expect)(result).toEqual(vitest_1.expect.objectContaining({ projectPath: selectedPbxprojPath }));
122
+ });
123
+ (0, vitest_1.it)('fails instead of prompting when multiple Xcode projects are found in non-interactive mode', async () => {
124
+ createProject(projectDir, 'First.xcodeproj');
125
+ createProject(projectDir, 'Second.xcodeproj');
126
+ mocks.searchXcodeProjectAtPath.mockReturnValue([
127
+ 'First.xcodeproj',
128
+ 'Second.xcodeproj',
129
+ ]);
130
+ await (0, vitest_1.expect)((0, lookup_xcode_project_1.lookupXcodeProject)({ projectDir, nonInteractive: true })).rejects.toThrow('abort');
131
+ (0, vitest_1.expect)(mocks.askForItemSelection).not.toHaveBeenCalled();
132
+ (0, vitest_1.expect)(mocks.clackError).toHaveBeenCalledWith(vitest_1.expect.stringContaining('Multiple Xcode projects found'));
133
+ });
134
+ });
135
+ (0, vitest_1.describe)('selectXcodeTarget', () => {
136
+ (0, vitest_1.it)('returns the only target without prompting', async () => {
137
+ const pbxprojPath = createProject(projectDir, 'App.xcodeproj');
138
+ mocks.targetsByProjectPath.set(pbxprojPath, ['App']);
139
+ const xcProject = createMockXcodeProject(pbxprojPath);
140
+ const result = await (0, lookup_xcode_project_1.selectXcodeTarget)(xcProject);
141
+ (0, vitest_1.expect)(result).toBe('App');
142
+ (0, vitest_1.expect)(mocks.askForItemSelection).not.toHaveBeenCalled();
143
+ });
144
+ (0, vitest_1.it)('prompts when multiple targets are available', async () => {
145
+ const pbxprojPath = createProject(projectDir, 'App.xcodeproj');
146
+ mocks.targetsByProjectPath.set(pbxprojPath, ['App', 'Widget']);
147
+ mocks.askForItemSelection.mockResolvedValue({ value: 'Widget' });
148
+ const xcProject = createMockXcodeProject(pbxprojPath);
149
+ const result = await (0, lookup_xcode_project_1.selectXcodeTarget)(xcProject);
150
+ (0, vitest_1.expect)(mocks.askForItemSelection).toHaveBeenCalledWith(['App', 'Widget'], 'Which target do you want to add Sentry to?');
151
+ (0, vitest_1.expect)(result).toBe('Widget');
152
+ });
153
+ (0, vitest_1.it)('selects from custom target candidates', async () => {
154
+ const pbxprojPath = createProject(projectDir, 'App.xcodeproj');
155
+ mocks.targetsByProjectPath.set(pbxprojPath, ['App']);
156
+ mocks.askForItemSelection.mockResolvedValue({ value: 'AppUITests' });
157
+ const xcProject = createMockXcodeProject(pbxprojPath);
158
+ const result = await (0, lookup_xcode_project_1.selectXcodeTarget)(xcProject, {
159
+ targetNames: ['AppTests', 'AppUITests'],
160
+ promptMessage: 'Which test target should render SnapshotPreviews?',
161
+ });
162
+ (0, vitest_1.expect)(mocks.askForItemSelection).toHaveBeenCalledWith(['AppTests', 'AppUITests'], 'Which test target should render SnapshotPreviews?');
163
+ (0, vitest_1.expect)(result).toBe('AppUITests');
164
+ });
165
+ });
166
+ });
167
+ //# sourceMappingURL=lookup-xcode-project.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lookup-xcode-project.test.js","sourceRoot":"","sources":["../../../test/apple/lookup-xcode-project.test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\n\ntype MockXcodeProject = {\n projectPath: string;\n xcodeprojPath: string;\n getAllTargets: () => string[];\n};\n\nconst mocks = vi.hoisted(() => {\n const targetsByProjectPath = new Map<string, string[]>();\n\n return {\n abort: vi.fn(() => {\n throw new Error('abort');\n }),\n askForItemSelection: vi.fn(),\n clackError: vi.fn(),\n debug: vi.fn(),\n searchXcodeProjectAtPath: vi.fn(),\n setTag: vi.fn(),\n targetsByProjectPath,\n traceStep: vi.fn(\n async <T>(_name: string, callback: () => Promise<T> | T): Promise<T> =>\n await callback(),\n ),\n XcodeProject: vi.fn(function (this: MockXcodeProject, projectPath: string) {\n this.projectPath = projectPath;\n this.xcodeprojPath = path.dirname(projectPath);\n this.getAllTargets = () => targetsByProjectPath.get(projectPath) ?? [];\n }),\n };\n});\n\nvi.mock('@clack/prompts', () => ({\n default: {\n log: {\n error: mocks.clackError,\n },\n },\n}));\n\nvi.mock('@sentry/node', () => ({\n setTag: mocks.setTag,\n}));\n\nvi.mock('../../src/apple/search-xcode-project-at-path', () => ({\n searchXcodeProjectAtPath: mocks.searchXcodeProjectAtPath,\n}));\n\nvi.mock('../../src/apple/xcode-manager', () => ({\n XcodeProject: mocks.XcodeProject,\n}));\n\nvi.mock('../../src/telemetry', () => ({\n traceStep: mocks.traceStep,\n}));\n\nvi.mock('../../src/utils/clack', () => ({\n abort: mocks.abort,\n askForItemSelection: mocks.askForItemSelection,\n}));\n\nvi.mock('../../src/utils/debug', () => ({\n debug: mocks.debug,\n}));\n\nimport {\n lookupXcodeProject,\n selectXcodeTarget,\n} from '../../src/apple/lookup-xcode-project';\n\nfunction createProject(projectDir: string, projectName: string): string {\n const projectPath = path.join(projectDir, projectName);\n fs.mkdirSync(projectPath, { recursive: true });\n const pbxprojPath = path.join(projectPath, 'project.pbxproj');\n fs.writeFileSync(pbxprojPath, 'mock pbxproj');\n\n return pbxprojPath;\n}\n\nfunction createMockXcodeProject(\n pbxprojPath: string,\n): Parameters<typeof selectXcodeTarget>[0] {\n const XcodeProjectConstructor = mocks.XcodeProject as unknown as {\n new (projectPath: string): MockXcodeProject;\n };\n\n return new XcodeProjectConstructor(pbxprojPath) as unknown as Parameters<\n typeof selectXcodeTarget\n >[0];\n}\n\ndescribe('lookup-xcode-project', () => {\n let projectDir: string;\n\n beforeEach(() => {\n projectDir = fs.mkdtempSync(\n path.join(os.tmpdir(), 'lookup-xcode-project-'),\n );\n vi.clearAllMocks();\n mocks.targetsByProjectPath.clear();\n });\n\n afterEach(() => {\n fs.rmSync(projectDir, { force: true, recursive: true });\n });\n\n describe('lookupXcodeProject', () => {\n it('returns an Xcode project without selecting a target', async () => {\n const pbxprojPath = createProject(projectDir, 'App.xcodeproj');\n mocks.searchXcodeProjectAtPath.mockReturnValue(['App.xcodeproj']);\n mocks.targetsByProjectPath.set(pbxprojPath, ['App']);\n\n const result = await lookupXcodeProject({ projectDir });\n\n expect(mocks.searchXcodeProjectAtPath).toHaveBeenCalledWith(projectDir);\n expect(mocks.XcodeProject).toHaveBeenCalledWith(pbxprojPath);\n expect(result).toEqual(\n expect.objectContaining({ projectPath: pbxprojPath }),\n );\n expect(mocks.askForItemSelection).not.toHaveBeenCalledWith(\n ['App'],\n 'Which target do you want to add Sentry to?',\n );\n });\n\n it('prompts when multiple Xcode projects are found', async () => {\n createProject(projectDir, 'First.xcodeproj');\n const selectedPbxprojPath = createProject(projectDir, 'Second.xcodeproj');\n mocks.searchXcodeProjectAtPath.mockReturnValue([\n 'First.xcodeproj',\n 'Second.xcodeproj',\n ]);\n mocks.askForItemSelection.mockResolvedValue({\n value: 'Second.xcodeproj',\n });\n\n const result = await lookupXcodeProject({ projectDir });\n\n expect(mocks.askForItemSelection).toHaveBeenCalledWith(\n ['First.xcodeproj', 'Second.xcodeproj'],\n 'Which project do you want to add Sentry to?',\n );\n expect(result).toEqual(\n expect.objectContaining({ projectPath: selectedPbxprojPath }),\n );\n });\n\n it('fails instead of prompting when multiple Xcode projects are found in non-interactive mode', async () => {\n createProject(projectDir, 'First.xcodeproj');\n createProject(projectDir, 'Second.xcodeproj');\n mocks.searchXcodeProjectAtPath.mockReturnValue([\n 'First.xcodeproj',\n 'Second.xcodeproj',\n ]);\n\n await expect(\n lookupXcodeProject({ projectDir, nonInteractive: true }),\n ).rejects.toThrow('abort');\n\n expect(mocks.askForItemSelection).not.toHaveBeenCalled();\n expect(mocks.clackError).toHaveBeenCalledWith(\n expect.stringContaining('Multiple Xcode projects found'),\n );\n });\n });\n\n describe('selectXcodeTarget', () => {\n it('returns the only target without prompting', async () => {\n const pbxprojPath = createProject(projectDir, 'App.xcodeproj');\n mocks.targetsByProjectPath.set(pbxprojPath, ['App']);\n const xcProject = createMockXcodeProject(pbxprojPath);\n\n const result = await selectXcodeTarget(xcProject);\n\n expect(result).toBe('App');\n expect(mocks.askForItemSelection).not.toHaveBeenCalled();\n });\n\n it('prompts when multiple targets are available', async () => {\n const pbxprojPath = createProject(projectDir, 'App.xcodeproj');\n mocks.targetsByProjectPath.set(pbxprojPath, ['App', 'Widget']);\n mocks.askForItemSelection.mockResolvedValue({ value: 'Widget' });\n const xcProject = createMockXcodeProject(pbxprojPath);\n\n const result = await selectXcodeTarget(xcProject);\n\n expect(mocks.askForItemSelection).toHaveBeenCalledWith(\n ['App', 'Widget'],\n 'Which target do you want to add Sentry to?',\n );\n expect(result).toBe('Widget');\n });\n\n it('selects from custom target candidates', async () => {\n const pbxprojPath = createProject(projectDir, 'App.xcodeproj');\n mocks.targetsByProjectPath.set(pbxprojPath, ['App']);\n mocks.askForItemSelection.mockResolvedValue({ value: 'AppUITests' });\n const xcProject = createMockXcodeProject(pbxprojPath);\n\n const result = await selectXcodeTarget(xcProject, {\n targetNames: ['AppTests', 'AppUITests'],\n promptMessage: 'Which test target should render SnapshotPreviews?',\n });\n\n expect(mocks.askForItemSelection).toHaveBeenCalledWith(\n ['AppTests', 'AppUITests'],\n 'Which test target should render SnapshotPreviews?',\n );\n expect(result).toBe('AppUITests');\n });\n });\n});\n"]}