@sentry/wizard 3.12.0 → 3.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 (71) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/lib/Steps/ChooseIntegration.js +1 -0
  3. package/dist/lib/Steps/ChooseIntegration.js.map +1 -1
  4. package/dist/package.json +1 -1
  5. package/dist/src/android/android-wizard.js +6 -4
  6. package/dist/src/android/android-wizard.js.map +1 -1
  7. package/dist/src/nextjs/nextjs-wizard.js +5 -2
  8. package/dist/src/nextjs/nextjs-wizard.js.map +1 -1
  9. package/dist/src/nextjs/templates.d.ts +1 -1
  10. package/dist/src/nextjs/templates.js +2 -2
  11. package/dist/src/nextjs/templates.js.map +1 -1
  12. package/dist/src/remix/remix-wizard.js +8 -4
  13. package/dist/src/remix/remix-wizard.js.map +1 -1
  14. package/dist/src/remix/sdk-setup.d.ts +5 -1
  15. package/dist/src/remix/sdk-setup.js +3 -2
  16. package/dist/src/remix/sdk-setup.js.map +1 -1
  17. package/dist/src/sourcemaps/tools/sentry-cli.d.ts +9 -0
  18. package/dist/src/sourcemaps/tools/sentry-cli.js +26 -22
  19. package/dist/src/sourcemaps/tools/sentry-cli.js.map +1 -1
  20. package/dist/src/sourcemaps/tools/tsc.d.ts +6 -0
  21. package/dist/src/sourcemaps/tools/tsc.js +98 -17
  22. package/dist/src/sourcemaps/tools/tsc.js.map +1 -1
  23. package/dist/src/sourcemaps/tools/vite.js +3 -13
  24. package/dist/src/sourcemaps/tools/vite.js.map +1 -1
  25. package/dist/src/sourcemaps/tools/webpack.js +3 -13
  26. package/dist/src/sourcemaps/tools/webpack.js.map +1 -1
  27. package/dist/src/sveltekit/sdk-setup.js +122 -48
  28. package/dist/src/sveltekit/sdk-setup.js.map +1 -1
  29. package/dist/src/sveltekit/sveltekit-wizard.d.ts +1 -0
  30. package/dist/src/sveltekit/sveltekit-wizard.js +119 -44
  31. package/dist/src/sveltekit/sveltekit-wizard.js.map +1 -1
  32. package/dist/src/sveltekit/utils.d.ts +2 -0
  33. package/dist/src/sveltekit/utils.js +48 -0
  34. package/dist/src/sveltekit/utils.js.map +1 -0
  35. package/dist/src/utils/ast-utils.d.ts +70 -0
  36. package/dist/src/utils/ast-utils.js +152 -1
  37. package/dist/src/utils/ast-utils.js.map +1 -1
  38. package/dist/src/utils/clack-utils.d.ts +38 -6
  39. package/dist/src/utils/clack-utils.js +57 -51
  40. package/dist/src/utils/clack-utils.js.map +1 -1
  41. package/dist/src/utils/package-manager.d.ts +5 -0
  42. package/dist/src/utils/package-manager.js +11 -7
  43. package/dist/src/utils/package-manager.js.map +1 -1
  44. package/dist/test/sourcemaps/tools/sentry-cli.test.d.ts +1 -0
  45. package/dist/test/sourcemaps/tools/sentry-cli.test.js +112 -0
  46. package/dist/test/sourcemaps/tools/sentry-cli.test.js.map +1 -0
  47. package/dist/test/sourcemaps/tools/tsc.test.d.ts +1 -0
  48. package/dist/test/sourcemaps/tools/tsc.test.js +121 -0
  49. package/dist/test/sourcemaps/tools/tsc.test.js.map +1 -0
  50. package/dist/test/utils/ast-utils.test.js +157 -26
  51. package/dist/test/utils/ast-utils.test.js.map +1 -1
  52. package/lib/Steps/ChooseIntegration.ts +1 -0
  53. package/package.json +1 -1
  54. package/src/android/android-wizard.ts +8 -5
  55. package/src/nextjs/nextjs-wizard.ts +15 -3
  56. package/src/nextjs/templates.ts +3 -2
  57. package/src/remix/remix-wizard.ts +8 -11
  58. package/src/remix/sdk-setup.ts +8 -2
  59. package/src/sourcemaps/tools/sentry-cli.ts +16 -9
  60. package/src/sourcemaps/tools/tsc.ts +133 -28
  61. package/src/sourcemaps/tools/vite.ts +15 -39
  62. package/src/sourcemaps/tools/webpack.ts +16 -39
  63. package/src/sveltekit/sdk-setup.ts +109 -37
  64. package/src/sveltekit/sveltekit-wizard.ts +93 -25
  65. package/src/sveltekit/utils.ts +50 -0
  66. package/src/utils/ast-utils.ts +180 -0
  67. package/src/utils/clack-utils.ts +68 -49
  68. package/src/utils/package-manager.ts +12 -6
  69. package/test/sourcemaps/tools/sentry-cli.test.ts +51 -0
  70. package/test/sourcemaps/tools/tsc.test.ts +181 -0
  71. package/test/utils/ast-utils.test.ts +233 -32
@@ -1,4 +1,27 @@
1
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
+ };
2
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
27
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -39,102 +62,154 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
39
62
  return (mod && mod.__esModule) ? mod : { "default": mod };
40
63
  };
41
64
  Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.runSvelteKitWizard = void 0;
65
+ exports.runSvelteKitWizardWithTelemetry = exports.runSvelteKitWizard = void 0;
43
66
  // @ts-ignore - clack is ESM and TS complains about that. It works though
44
- var prompts_1 = __importDefault(require("@clack/prompts"));
67
+ var clack = __importStar(require("@clack/prompts"));
45
68
  var chalk_1 = __importDefault(require("chalk"));
69
+ var Sentry = __importStar(require("@sentry/node"));
46
70
  var clack_utils_1 = require("../utils/clack-utils");
47
71
  var package_json_1 = require("../utils/package-json");
48
72
  var sdk_example_1 = require("./sdk-example");
49
73
  var sdk_setup_1 = require("./sdk-setup");
74
+ var telemetry_1 = require("../telemetry");
75
+ var utils_1 = require("./utils");
50
76
  function runSvelteKitWizard(options) {
51
77
  return __awaiter(this, void 0, void 0, function () {
52
- var packageJson, _a, selectedProject, selfHosted, sentryUrl, authToken, svelteConfig, e_1, e_2;
78
+ return __generator(this, function (_a) {
79
+ return [2 /*return*/, (0, telemetry_1.withTelemetry)({
80
+ enabled: options.telemetryEnabled,
81
+ integration: 'sveltekit',
82
+ }, function () { return runSvelteKitWizardWithTelemetry(options); })];
83
+ });
84
+ });
85
+ }
86
+ exports.runSvelteKitWizard = runSvelteKitWizard;
87
+ function runSvelteKitWizardWithTelemetry(options) {
88
+ return __awaiter(this, void 0, void 0, function () {
89
+ var packageJson, kitVersion, kitVersionBucket, shouldContinue, _a, selectedProject, selfHosted, sentryUrl, authToken, sdkAlreadyInstalled, svelteConfig, e_1, e_2;
53
90
  return __generator(this, function (_b) {
54
91
  switch (_b.label) {
55
92
  case 0:
56
93
  (0, clack_utils_1.printWelcome)({
57
94
  wizardName: 'Sentry SvelteKit Wizard',
58
95
  promoCode: options.promoCode,
96
+ telemetryEnabled: options.telemetryEnabled,
59
97
  });
60
- return [4 /*yield*/, (0, clack_utils_1.confirmContinueEvenThoughNoGitRepo)()];
98
+ return [4 /*yield*/, (0, telemetry_1.traceStep)('detect-git', clack_utils_1.confirmContinueEvenThoughNoGitRepo)];
61
99
  case 1:
62
100
  _b.sent();
63
101
  return [4 /*yield*/, (0, clack_utils_1.getPackageDotJson)()];
64
102
  case 2:
65
103
  packageJson = _b.sent();
66
- return [4 /*yield*/, (0, clack_utils_1.ensurePackageIsInstalled)(packageJson, '@sveltejs/kit', 'Sveltekit')];
104
+ return [4 /*yield*/, (0, telemetry_1.traceStep)('detect-framework-version', function () {
105
+ return (0, clack_utils_1.ensurePackageIsInstalled)(packageJson, '@sveltejs/kit', 'Sveltekit');
106
+ })];
67
107
  case 3:
68
108
  _b.sent();
69
- return [4 /*yield*/, (0, clack_utils_1.getOrAskForProjectData)(options, 'javascript-sveltekit')];
109
+ kitVersion = (0, package_json_1.getPackageVersion)('@sveltejs/kit', packageJson);
110
+ kitVersionBucket = (0, utils_1.getKitVersionBucket)(kitVersion);
111
+ Sentry.setTag('sveltekit-version', kitVersionBucket);
112
+ if (!(kitVersionBucket === '0.x')) return [3 /*break*/, 6];
113
+ clack.log.warn("It seems you're using a SvelteKit version <1.0.0 which is not supported by Sentry.\nWe recommend upgrading to the latest 1.x version before you continue.");
114
+ return [4 /*yield*/, (0, clack_utils_1.abortIfCancelled)(clack.select({
115
+ message: 'Do you want to continue anyway?',
116
+ options: [
117
+ {
118
+ label: 'Yes, continue',
119
+ hint: 'The SDK might not work correctly',
120
+ value: true,
121
+ },
122
+ { label: "No, I'll upgrade first", value: false },
123
+ ],
124
+ }))];
70
125
  case 4:
71
- _a = _b.sent(), selectedProject = _a.selectedProject, selfHosted = _a.selfHosted, sentryUrl = _a.sentryUrl, authToken = _a.authToken;
72
- return [4 /*yield*/, (0, clack_utils_1.installPackage)({
73
- packageName: '@sentry/sveltekit',
74
- alreadyInstalled: (0, package_json_1.hasPackageInstalled)('@sentry/sveltekit', packageJson),
75
- })];
126
+ shouldContinue = _b.sent();
127
+ if (!!shouldContinue) return [3 /*break*/, 6];
128
+ return [4 /*yield*/, (0, clack_utils_1.abort)('Exiting Wizard', 0)];
76
129
  case 5:
77
130
  _b.sent();
78
- return [4 /*yield*/, (0, clack_utils_1.addSentryCliConfig)(authToken)];
131
+ return [2 /*return*/];
79
132
  case 6:
80
- _b.sent();
81
- return [4 /*yield*/, (0, sdk_setup_1.loadSvelteConfig)()];
133
+ Sentry.setTag('svelte-version', (0, utils_1.getSvelteVersionBucket)((0, package_json_1.getPackageVersion)('svelte', packageJson)));
134
+ return [4 /*yield*/, (0, clack_utils_1.getOrAskForProjectData)(options, 'javascript-sveltekit')];
82
135
  case 7:
83
- svelteConfig = _b.sent();
84
- _b.label = 8;
136
+ _a = _b.sent(), selectedProject = _a.selectedProject, selfHosted = _a.selfHosted, sentryUrl = _a.sentryUrl, authToken = _a.authToken;
137
+ sdkAlreadyInstalled = (0, package_json_1.hasPackageInstalled)('@sentry/sveltekit', packageJson);
138
+ Sentry.setTag('sdk-already-installed', sdkAlreadyInstalled);
139
+ return [4 /*yield*/, (0, telemetry_1.traceStep)('install-sdk', function () {
140
+ return (0, clack_utils_1.installPackage)({
141
+ packageName: '@sentry/sveltekit',
142
+ alreadyInstalled: sdkAlreadyInstalled,
143
+ });
144
+ })];
85
145
  case 8:
86
- _b.trys.push([8, 10, , 12]);
87
- return [4 /*yield*/, (0, sdk_setup_1.createOrMergeSvelteKitFiles)({
88
- dsn: selectedProject.keys[0].dsn.public,
89
- org: selectedProject.organization.slug,
90
- project: selectedProject.slug,
91
- selfHosted: selfHosted,
92
- url: sentryUrl,
93
- }, svelteConfig)];
146
+ _b.sent();
147
+ return [4 /*yield*/, (0, telemetry_1.traceStep)('add-cli-config', function () { return (0, clack_utils_1.addSentryCliConfig)(authToken); })];
94
148
  case 9:
95
149
  _b.sent();
96
- return [3 /*break*/, 12];
150
+ return [4 /*yield*/, (0, telemetry_1.traceStep)('load-svelte-config', sdk_setup_1.loadSvelteConfig)];
97
151
  case 10:
152
+ svelteConfig = _b.sent();
153
+ _b.label = 11;
154
+ case 11:
155
+ _b.trys.push([11, 13, , 15]);
156
+ return [4 /*yield*/, (0, telemetry_1.traceStep)('configure-sdk', function () {
157
+ return (0, sdk_setup_1.createOrMergeSvelteKitFiles)({
158
+ dsn: selectedProject.keys[0].dsn.public,
159
+ org: selectedProject.organization.slug,
160
+ project: selectedProject.slug,
161
+ selfHosted: selfHosted,
162
+ url: sentryUrl,
163
+ }, svelteConfig);
164
+ })];
165
+ case 12:
166
+ _b.sent();
167
+ return [3 /*break*/, 15];
168
+ case 13:
98
169
  e_1 = _b.sent();
99
- prompts_1.default.log.error('Error while setting up the SvelteKit SDK:');
100
- prompts_1.default.log.info(chalk_1.default.dim(typeof e_1 === 'object' && e_1 != null && 'toString' in e_1
170
+ clack.log.error('Error while setting up the SvelteKit SDK:');
171
+ clack.log.info(chalk_1.default.dim(typeof e_1 === 'object' && e_1 != null && 'toString' in e_1
101
172
  ? e_1.toString()
102
173
  : typeof e_1 === 'string'
103
174
  ? e_1
104
175
  : 'Unknown error'));
176
+ Sentry.captureException('Error while setting up the SvelteKit SDK');
105
177
  return [4 /*yield*/, (0, clack_utils_1.abort)('Exiting Wizard')];
106
- case 11:
178
+ case 14:
107
179
  _b.sent();
108
180
  return [2 /*return*/];
109
- case 12:
110
- _b.trys.push([12, 14, , 16]);
111
- return [4 /*yield*/, (0, sdk_example_1.createExamplePage)(svelteConfig, {
112
- selfHosted: selfHosted,
113
- url: sentryUrl,
114
- orgSlug: selectedProject.organization.slug,
115
- projectId: selectedProject.id,
181
+ case 15:
182
+ _b.trys.push([15, 17, , 19]);
183
+ return [4 /*yield*/, (0, telemetry_1.traceStep)('create-example-page', function () {
184
+ return (0, sdk_example_1.createExamplePage)(svelteConfig, {
185
+ selfHosted: selfHosted,
186
+ url: sentryUrl,
187
+ orgSlug: selectedProject.organization.slug,
188
+ projectId: selectedProject.id,
189
+ });
116
190
  })];
117
- case 13:
191
+ case 16:
118
192
  _b.sent();
119
- return [3 /*break*/, 16];
120
- case 14:
193
+ return [3 /*break*/, 19];
194
+ case 17:
121
195
  e_2 = _b.sent();
122
- prompts_1.default.log.error('Error while creating an example page to test Sentry:');
123
- prompts_1.default.log.info(chalk_1.default.dim(typeof e_2 === 'object' && e_2 != null && 'toString' in e_2
196
+ clack.log.error('Error while creating an example page to test Sentry:');
197
+ clack.log.info(chalk_1.default.dim(typeof e_2 === 'object' && e_2 != null && 'toString' in e_2
124
198
  ? e_2.toString()
125
199
  : typeof e_2 === 'string'
126
200
  ? e_2
127
201
  : 'Unknown error'));
202
+ Sentry.captureException('Error while creating an example Svelte page to test Sentry');
128
203
  return [4 /*yield*/, (0, clack_utils_1.abort)('Exiting Wizard')];
129
- case 15:
204
+ case 18:
130
205
  _b.sent();
131
206
  return [2 /*return*/];
132
- case 16:
133
- prompts_1.default.outro("\n".concat(chalk_1.default.green('Successfully installed the Sentry SvelteKit SDK!'), "\n\n").concat(chalk_1.default.cyan('You can validate your setup by starting your dev environment (`npm run dev`) and visiting "/sentry-example".'), "\n\nCheck out the SDK documentation for further configuration:\nhttps://docs.sentry.io/platforms/javascript/guides/sveltekit/\n "));
207
+ case 19:
208
+ clack.outro("\n".concat(chalk_1.default.green('Successfully installed the Sentry SvelteKit SDK!'), "\n\n").concat(chalk_1.default.cyan('You can validate your setup by starting your dev environment (`npm run dev`) and visiting "/sentry-example".'), "\n\nCheck out the SDK documentation for further configuration:\nhttps://docs.sentry.io/platforms/javascript/guides/sveltekit/\n "));
134
209
  return [2 /*return*/];
135
210
  }
136
211
  });
137
212
  });
138
213
  }
139
- exports.runSvelteKitWizard = runSvelteKitWizard;
214
+ exports.runSvelteKitWizardWithTelemetry = runSvelteKitWizardWithTelemetry;
140
215
  //# sourceMappingURL=sveltekit-wizard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sveltekit-wizard.js","sourceRoot":"","sources":["../../../src/sveltekit/sveltekit-wizard.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,yEAAyE;AACzE,2DAAmC;AACnC,gDAA0B;AAE1B,oDAS8B;AAC9B,sDAA4D;AAE5D,6CAAkD;AAClD,yCAA4E;AAE5E,SAAsB,kBAAkB,CACtC,OAAsB;;;;;;oBAEtB,IAAA,0BAAY,EAAC;wBACX,UAAU,EAAE,yBAAyB;wBACrC,SAAS,EAAE,OAAO,CAAC,SAAS;qBAC7B,CAAC,CAAC;oBAEH,qBAAM,IAAA,gDAAkC,GAAE,EAAA;;oBAA1C,SAA0C,CAAC;oBAEvB,qBAAM,IAAA,+BAAiB,GAAE,EAAA;;oBAAvC,WAAW,GAAG,SAAyB;oBAC7C,qBAAM,IAAA,sCAAwB,EAAC,WAAW,EAAE,eAAe,EAAE,WAAW,CAAC,EAAA;;oBAAzE,SAAyE,CAAC;oBAGxE,qBAAM,IAAA,oCAAsB,EAAC,OAAO,EAAE,sBAAsB,CAAC,EAAA;;oBADzD,KACJ,SAA6D,EADvD,eAAe,qBAAA,EAAE,UAAU,gBAAA,EAAE,SAAS,eAAA,EAAE,SAAS,eAAA;oBAGzD,qBAAM,IAAA,4BAAc,EAAC;4BACnB,WAAW,EAAE,mBAAmB;4BAChC,gBAAgB,EAAE,IAAA,kCAAmB,EAAC,mBAAmB,EAAE,WAAW,CAAC;yBACxE,CAAC,EAAA;;oBAHF,SAGE,CAAC;oBAEH,qBAAM,IAAA,gCAAkB,EAAC,SAAS,CAAC,EAAA;;oBAAnC,SAAmC,CAAC;oBAEf,qBAAM,IAAA,4BAAgB,GAAE,EAAA;;oBAAvC,YAAY,GAAG,SAAwB;;;;oBAG3C,qBAAM,IAAA,uCAA2B,EAC/B;4BACE,GAAG,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM;4BACvC,GAAG,EAAE,eAAe,CAAC,YAAY,CAAC,IAAI;4BACtC,OAAO,EAAE,eAAe,CAAC,IAAI;4BAC7B,UAAU,YAAA;4BACV,GAAG,EAAE,SAAS;yBACf,EACD,YAAY,CACb,EAAA;;oBATD,SASC,CAAC;;;;oBAEF,iBAAK,CAAC,GAAG,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;oBAC7D,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,eAAK,CAAC,GAAG,CACP,OAAO,GAAC,KAAK,QAAQ,IAAI,GAAC,IAAI,IAAI,IAAI,UAAU,IAAI,GAAC;wBACnD,CAAC,CAAC,GAAC,CAAC,QAAQ,EAAE;wBACd,CAAC,CAAC,OAAO,GAAC,KAAK,QAAQ;4BACvB,CAAC,CAAC,GAAC;4BACH,CAAC,CAAC,eAAe,CACpB,CACF,CAAC;oBACF,qBAAM,IAAA,mBAAK,EAAC,gBAAgB,CAAC,EAAA;;oBAA7B,SAA6B,CAAC;oBAC9B,sBAAO;;;oBAIP,qBAAM,IAAA,+BAAiB,EAAC,YAAY,EAAE;4BACpC,UAAU,YAAA;4BACV,GAAG,EAAE,SAAS;4BACd,OAAO,EAAE,eAAe,CAAC,YAAY,CAAC,IAAI;4BAC1C,SAAS,EAAE,eAAe,CAAC,EAAE;yBAC9B,CAAC,EAAA;;oBALF,SAKE,CAAC;;;;oBAEH,iBAAK,CAAC,GAAG,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;oBACxE,iBAAK,CAAC,GAAG,CAAC,IAAI,CACZ,eAAK,CAAC,GAAG,CACP,OAAO,GAAC,KAAK,QAAQ,IAAI,GAAC,IAAI,IAAI,IAAI,UAAU,IAAI,GAAC;wBACnD,CAAC,CAAC,GAAC,CAAC,QAAQ,EAAE;wBACd,CAAC,CAAC,OAAO,GAAC,KAAK,QAAQ;4BACvB,CAAC,CAAC,GAAC;4BACH,CAAC,CAAC,eAAe,CACpB,CACF,CAAC;oBACF,qBAAM,IAAA,mBAAK,EAAC,gBAAgB,CAAC,EAAA;;oBAA7B,SAA6B,CAAC;oBAC9B,sBAAO;;oBAGT,iBAAK,CAAC,KAAK,CAAC,YACZ,eAAK,CAAC,KAAK,CAAC,kDAAkD,CAAC,iBAE/D,eAAK,CAAC,IAAI,CACV,8GAA8G,CAC/G,sIAIE,CAAC,CAAC;;;;;CACJ;AAnFD,gDAmFC","sourcesContent":["// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport clack from '@clack/prompts';\nimport chalk from 'chalk';\n\nimport {\n abort,\n addSentryCliConfig,\n confirmContinueEvenThoughNoGitRepo,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n installPackage,\n printWelcome,\n} from '../utils/clack-utils';\nimport { hasPackageInstalled } from '../utils/package-json';\nimport { WizardOptions } from '../utils/types';\nimport { createExamplePage } from './sdk-example';\nimport { createOrMergeSvelteKitFiles, loadSvelteConfig } from './sdk-setup';\n\nexport async function runSvelteKitWizard(\n options: WizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'Sentry SvelteKit Wizard',\n promoCode: options.promoCode,\n });\n\n await confirmContinueEvenThoughNoGitRepo();\n\n const packageJson = await getPackageDotJson();\n await ensurePackageIsInstalled(packageJson, '@sveltejs/kit', 'Sveltekit');\n\n const { selectedProject, selfHosted, sentryUrl, authToken } =\n await getOrAskForProjectData(options, 'javascript-sveltekit');\n\n await installPackage({\n packageName: '@sentry/sveltekit',\n alreadyInstalled: hasPackageInstalled('@sentry/sveltekit', packageJson),\n });\n\n await addSentryCliConfig(authToken);\n\n const svelteConfig = await loadSvelteConfig();\n\n try {\n await createOrMergeSvelteKitFiles(\n {\n dsn: selectedProject.keys[0].dsn.public,\n org: selectedProject.organization.slug,\n project: selectedProject.slug,\n selfHosted,\n url: sentryUrl,\n },\n svelteConfig,\n );\n } catch (e: unknown) {\n clack.log.error('Error while setting up the SvelteKit SDK:');\n clack.log.info(\n chalk.dim(\n typeof e === 'object' && e != null && 'toString' in e\n ? e.toString()\n : typeof e === 'string'\n ? e\n : 'Unknown error',\n ),\n );\n await abort('Exiting Wizard');\n return;\n }\n\n try {\n await createExamplePage(svelteConfig, {\n selfHosted,\n url: sentryUrl,\n orgSlug: selectedProject.organization.slug,\n projectId: selectedProject.id,\n });\n } catch (e: unknown) {\n clack.log.error('Error while creating an example page to test Sentry:');\n clack.log.info(\n chalk.dim(\n typeof e === 'object' && e != null && 'toString' in e\n ? e.toString()\n : typeof e === 'string'\n ? e\n : 'Unknown error',\n ),\n );\n await abort('Exiting Wizard');\n return;\n }\n\n clack.outro(`\n${chalk.green('Successfully installed the Sentry SvelteKit SDK!')}\n\n${chalk.cyan(\n 'You can validate your setup by starting your dev environment (`npm run dev`) and visiting \"/sentry-example\".',\n)}\n\nCheck out the SDK documentation for further configuration:\nhttps://docs.sentry.io/platforms/javascript/guides/sveltekit/\n `);\n}\n"]}
1
+ {"version":3,"file":"sveltekit-wizard.js","sourceRoot":"","sources":["../../../src/sveltekit/sveltekit-wizard.ts"],"names":[],"mappings":"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","sourcesContent":["// @ts-ignore - clack is ESM and TS complains about that. It works though\nimport * as clack from '@clack/prompts';\nimport chalk from 'chalk';\n\nimport * as Sentry from '@sentry/node';\n\nimport {\n abort,\n abortIfCancelled,\n addSentryCliConfig,\n confirmContinueEvenThoughNoGitRepo,\n ensurePackageIsInstalled,\n getOrAskForProjectData,\n getPackageDotJson,\n installPackage,\n printWelcome,\n} from '../utils/clack-utils';\nimport { getPackageVersion, hasPackageInstalled } from '../utils/package-json';\nimport { WizardOptions } from '../utils/types';\nimport { createExamplePage } from './sdk-example';\nimport { createOrMergeSvelteKitFiles, loadSvelteConfig } from './sdk-setup';\nimport { traceStep, withTelemetry } from '../telemetry';\nimport { getKitVersionBucket, getSvelteVersionBucket } from './utils';\n\nexport async function runSvelteKitWizard(\n options: WizardOptions,\n): Promise<void> {\n return withTelemetry(\n {\n enabled: options.telemetryEnabled,\n integration: 'sveltekit',\n },\n () => runSvelteKitWizardWithTelemetry(options),\n );\n}\n\nexport async function runSvelteKitWizardWithTelemetry(\n options: WizardOptions,\n): Promise<void> {\n printWelcome({\n wizardName: 'Sentry SvelteKit Wizard',\n promoCode: options.promoCode,\n telemetryEnabled: options.telemetryEnabled,\n });\n\n await traceStep('detect-git', confirmContinueEvenThoughNoGitRepo);\n\n const packageJson = await getPackageDotJson();\n await traceStep('detect-framework-version', () =>\n ensurePackageIsInstalled(packageJson, '@sveltejs/kit', 'Sveltekit'),\n );\n\n const kitVersion = getPackageVersion('@sveltejs/kit', packageJson);\n const kitVersionBucket = getKitVersionBucket(kitVersion);\n Sentry.setTag('sveltekit-version', kitVersionBucket);\n\n if (kitVersionBucket === '0.x') {\n clack.log.warn(\n \"It seems you're using a SvelteKit version <1.0.0 which is not supported by Sentry.\\nWe recommend upgrading to the latest 1.x version before you continue.\",\n );\n const shouldContinue = await abortIfCancelled(\n clack.select({\n message: 'Do you want to continue anyway?',\n options: [\n {\n label: 'Yes, continue',\n hint: 'The SDK might not work correctly',\n value: true,\n },\n { label: \"No, I'll upgrade first\", value: false },\n ],\n }),\n );\n if (!shouldContinue) {\n await abort('Exiting Wizard', 0);\n return;\n }\n }\n\n Sentry.setTag(\n 'svelte-version',\n getSvelteVersionBucket(getPackageVersion('svelte', packageJson)),\n );\n\n const { selectedProject, selfHosted, sentryUrl, authToken } =\n await getOrAskForProjectData(options, 'javascript-sveltekit');\n\n const sdkAlreadyInstalled = hasPackageInstalled(\n '@sentry/sveltekit',\n packageJson,\n );\n Sentry.setTag('sdk-already-installed', sdkAlreadyInstalled);\n\n await traceStep('install-sdk', () =>\n installPackage({\n packageName: '@sentry/sveltekit',\n alreadyInstalled: sdkAlreadyInstalled,\n }),\n );\n\n await traceStep('add-cli-config', () => addSentryCliConfig(authToken));\n\n const svelteConfig = await traceStep('load-svelte-config', loadSvelteConfig);\n\n try {\n await traceStep('configure-sdk', () =>\n createOrMergeSvelteKitFiles(\n {\n dsn: selectedProject.keys[0].dsn.public,\n org: selectedProject.organization.slug,\n project: selectedProject.slug,\n selfHosted,\n url: sentryUrl,\n },\n svelteConfig,\n ),\n );\n } catch (e: unknown) {\n clack.log.error('Error while setting up the SvelteKit SDK:');\n clack.log.info(\n chalk.dim(\n typeof e === 'object' && e != null && 'toString' in e\n ? e.toString()\n : typeof e === 'string'\n ? e\n : 'Unknown error',\n ),\n );\n Sentry.captureException('Error while setting up the SvelteKit SDK');\n await abort('Exiting Wizard');\n return;\n }\n\n try {\n await traceStep('create-example-page', () =>\n createExamplePage(svelteConfig, {\n selfHosted,\n url: sentryUrl,\n orgSlug: selectedProject.organization.slug,\n projectId: selectedProject.id,\n }),\n );\n } catch (e: unknown) {\n clack.log.error('Error while creating an example page to test Sentry:');\n clack.log.info(\n chalk.dim(\n typeof e === 'object' && e != null && 'toString' in e\n ? e.toString()\n : typeof e === 'string'\n ? e\n : 'Unknown error',\n ),\n );\n Sentry.captureException(\n 'Error while creating an example Svelte page to test Sentry',\n );\n await abort('Exiting Wizard');\n return;\n }\n\n clack.outro(`\n${chalk.green('Successfully installed the Sentry SvelteKit SDK!')}\n\n${chalk.cyan(\n 'You can validate your setup by starting your dev environment (`npm run dev`) and visiting \"/sentry-example\".',\n)}\n\nCheck out the SDK documentation for further configuration:\nhttps://docs.sentry.io/platforms/javascript/guides/sveltekit/\n `);\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function getKitVersionBucket(version: string | undefined): 'none' | 'invalid' | '0.x' | '>=1.0.0 <1.24.0' | '>=1.24.0';
2
+ export declare function getSvelteVersionBucket(version: string | undefined): 'none' | 'invalid' | '<3.0.0' | '3.x' | '4.x' | '>4.x';
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSvelteVersionBucket = exports.getKitVersionBucket = void 0;
4
+ var semver_1 = require("semver");
5
+ function getKitVersionBucket(version) {
6
+ if (!version) {
7
+ return 'none';
8
+ }
9
+ var minVer = (0, semver_1.minVersion)(version);
10
+ if (!minVer) {
11
+ return 'invalid';
12
+ }
13
+ if ((0, semver_1.lt)(minVer, '1.0.0')) {
14
+ return '0.x';
15
+ }
16
+ else if ((0, semver_1.lt)(minVer, '1.24.0')) {
17
+ return '>=1.0.0 <1.24.0';
18
+ }
19
+ else {
20
+ // This is the version when the client-side invalidation fix was released
21
+ // https://github.com/sveltejs/kit/releases/tag/%40sveltejs%2Fkit%401.24.0
22
+ // https://github.com/sveltejs/kit/pull/10576
23
+ return '>=1.24.0';
24
+ }
25
+ }
26
+ exports.getKitVersionBucket = getKitVersionBucket;
27
+ function getSvelteVersionBucket(version) {
28
+ if (!version) {
29
+ return 'none';
30
+ }
31
+ var minVer = (0, semver_1.minVersion)(version);
32
+ if (!minVer) {
33
+ return 'invalid';
34
+ }
35
+ if ((0, semver_1.lt)(minVer, '3.0.0')) {
36
+ return '<3.0.0';
37
+ }
38
+ if ((0, semver_1.lt)(minVer, '4.0.0')) {
39
+ return '3.x';
40
+ }
41
+ if ((0, semver_1.lt)(minVer, '5.0.0')) {
42
+ return '4.x';
43
+ }
44
+ // Svelte 5 isn't released yet but it's being worked on
45
+ return '>4.x';
46
+ }
47
+ exports.getSvelteVersionBucket = getSvelteVersionBucket;
48
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/sveltekit/utils.ts"],"names":[],"mappings":";;;AAAA,iCAAwC;AAExC,SAAgB,mBAAmB,CACjC,OAA2B;IAE3B,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,MAAM,CAAC;KACf;IAED,IAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,EAAE;QACX,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,IAAA,WAAE,EAAC,MAAM,EAAE,OAAO,CAAC,EAAE;QACvB,OAAO,KAAK,CAAC;KACd;SAAM,IAAI,IAAA,WAAE,EAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;QAC/B,OAAO,iBAAiB,CAAC;KAC1B;SAAM;QACL,yEAAyE;QACzE,0EAA0E;QAC1E,6CAA6C;QAC7C,OAAO,UAAU,CAAC;KACnB;AACH,CAAC;AAtBD,kDAsBC;AAED,SAAgB,sBAAsB,CACpC,OAA2B;IAE3B,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,MAAM,CAAC;KACf;IAED,IAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,OAAO,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,EAAE;QACX,OAAO,SAAS,CAAC;KAClB;IAED,IAAI,IAAA,WAAE,EAAC,MAAM,EAAE,OAAO,CAAC,EAAE;QACvB,OAAO,QAAQ,CAAC;KACjB;IACD,IAAI,IAAA,WAAE,EAAC,MAAM,EAAE,OAAO,CAAC,EAAE;QACvB,OAAO,KAAK,CAAC;KACd;IACD,IAAI,IAAA,WAAE,EAAC,MAAM,EAAE,OAAO,CAAC,EAAE;QACvB,OAAO,KAAK,CAAC;KACd;IACD,uDAAuD;IACvD,OAAO,MAAM,CAAC;AAChB,CAAC;AAvBD,wDAuBC","sourcesContent":["import { lt, minVersion } from 'semver';\n\nexport function getKitVersionBucket(\n version: string | undefined,\n): 'none' | 'invalid' | '0.x' | '>=1.0.0 <1.24.0' | '>=1.24.0' {\n if (!version) {\n return 'none';\n }\n\n const minVer = minVersion(version);\n if (!minVer) {\n return 'invalid';\n }\n\n if (lt(minVer, '1.0.0')) {\n return '0.x';\n } else if (lt(minVer, '1.24.0')) {\n return '>=1.0.0 <1.24.0';\n } else {\n // This is the version when the client-side invalidation fix was released\n // https://github.com/sveltejs/kit/releases/tag/%40sveltejs%2Fkit%401.24.0\n // https://github.com/sveltejs/kit/pull/10576\n return '>=1.24.0';\n }\n}\n\nexport function getSvelteVersionBucket(\n version: string | undefined,\n): 'none' | 'invalid' | '<3.0.0' | '3.x' | '4.x' | '>4.x' {\n if (!version) {\n return 'none';\n }\n\n const minVer = minVersion(version);\n if (!minVer) {\n return 'invalid';\n }\n\n if (lt(minVer, '3.0.0')) {\n return '<3.0.0';\n }\n if (lt(minVer, '4.0.0')) {\n return '3.x';\n }\n if (lt(minVer, '5.0.0')) {\n return '4.x';\n }\n // Svelte 5 isn't released yet but it's being worked on\n return '>4.x';\n}\n"]}
@@ -10,3 +10,73 @@ export declare function findFile(filePath: string, fileTypes?: string[]): string
10
10
  * checks for require('@sentry/*') syntax
11
11
  */
12
12
  export declare function hasSentryContent(program: t.Program): boolean;
13
+ /**
14
+ * Searches for a property of an ObjectExpression by name
15
+ *
16
+ * @param object the ObjectExpression to search in
17
+ * @param name the name of the property to search for
18
+ *
19
+ * @returns the property if it exists
20
+ */
21
+ export declare function getObjectProperty(object: t.ObjectExpression, name: string): t.Property | undefined;
22
+ /**
23
+ * Attempts to find a property of an ObjectExpression by name. If it doesn't exist,
24
+ * the property will be added to the ObjectExpression with the provided default value.
25
+ *
26
+ * @param object the parent object expression to search in
27
+ * @param name the name of the property to search for
28
+ * @param defaultValue the default value to set if the property doesn't exist
29
+ *
30
+ * @returns the
31
+ */
32
+ export declare function getOrSetObjectProperty(object: t.ObjectExpression, name: string, defaultValue: t.Literal | t.BooleanLiteral | t.StringLiteral | t.ObjectExpression): t.Property;
33
+ /**
34
+ * Sets a property of an ObjectExpression if it exists, otherwise adds it
35
+ * to the ObjectExpression. Optionally, a comment can be added to the
36
+ * property.
37
+ *
38
+ * @param object the ObjectExpression to set the property on
39
+ * @param name the name of the property to set
40
+ * @param value the value of the property to set
41
+ * @param comment (optional) a comment to add to the property
42
+ */
43
+ export declare function setOrUpdateObjectProperty(object: t.ObjectExpression, name: string, value: t.Literal | t.BooleanLiteral | t.StringLiteral | t.ObjectExpression, comment?: string): void;
44
+ type JsonCParseResult = {
45
+ jsonObject: t.ObjectExpression;
46
+ ast: t.Program;
47
+ } | {
48
+ jsonObject: undefined;
49
+ ast: undefined;
50
+ };
51
+ /**
52
+ * Parses a JSON string with (potential) comments (JSON-C) and returns the JS AST
53
+ * that can be walked and modified with recast like a normal JS AST.
54
+ *
55
+ * This is done by wrapping the JSON-C string in parentheses, thereby making it
56
+ * a JS `Program` with an `ExpressionStatement` as its body. The expression is then
57
+ * extracted from the AST and returned alongside the AST.
58
+ *
59
+ * To preserve as much original formatting as possible, the returned `ast`
60
+ * property should be passed to {@link `printJsonC`} to get the JSON-C string back.
61
+ *
62
+ * If the input is not valid JSON-C, the result will be undefined.
63
+ *
64
+ * @see {@link JsonCParseResult}
65
+ *
66
+ * @param jsonString a JSON-C string
67
+ *
68
+ * @returns a {@link JsonCParseResult}, containing either the JSON-C object and the AST or undefined in both cases
69
+ */
70
+ export declare function parseJsonC(jsonString: string): JsonCParseResult;
71
+ /**
72
+ * Takes the AST of a parsed JSON-C "program" and returns the JSON-C string without
73
+ * any of the temporary JS wrapper code that was previously applied.
74
+ *
75
+ * Only use this in conjunction with {@link `parseJsonC`}
76
+ *
77
+ * @param ast the `ast` returned from {@link `parseJsonC`}
78
+ *
79
+ * @returns the JSON-C string
80
+ */
81
+ export declare function printJsonC(ast: t.Program): string;
82
+ export {};
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
14
  if (k2 === undefined) k2 = k;
4
15
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -22,10 +33,20 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
33
  __setModuleDefault(result, mod);
23
34
  return result;
24
35
  };
36
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
37
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
38
+ if (ar || !(i in from)) {
39
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
40
+ ar[i] = from[i];
41
+ }
42
+ }
43
+ return to.concat(ar || Array.prototype.slice.call(from));
44
+ };
25
45
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.hasSentryContent = exports.findFile = void 0;
46
+ exports.printJsonC = exports.parseJsonC = exports.setOrUpdateObjectProperty = exports.getOrSetObjectProperty = exports.getObjectProperty = exports.hasSentryContent = exports.findFile = void 0;
27
47
  var fs = __importStar(require("fs"));
28
48
  var recast = __importStar(require("recast"));
49
+ var b = recast.types.builders;
29
50
  /**
30
51
  * Checks if a file where we don't know its concrete file type yet exists
31
52
  * and returns the full path to the file with the correct file type.
@@ -57,4 +78,134 @@ function hasSentryContent(program) {
57
78
  return !!foundSentry;
58
79
  }
59
80
  exports.hasSentryContent = hasSentryContent;
81
+ /**
82
+ * Searches for a property of an ObjectExpression by name
83
+ *
84
+ * @param object the ObjectExpression to search in
85
+ * @param name the name of the property to search for
86
+ *
87
+ * @returns the property if it exists
88
+ */
89
+ function getObjectProperty(object, name) {
90
+ return object.properties.find(function (p) {
91
+ var isObjectProp = p.type === 'Property' || p.type === 'ObjectProperty';
92
+ if (!isObjectProp) {
93
+ return false;
94
+ }
95
+ var hasMatchingLiteralKey = isObjectProp &&
96
+ (p.key.type === 'Literal' || p.key.type === 'StringLiteral') &&
97
+ p.key.value === name;
98
+ if (hasMatchingLiteralKey) {
99
+ return true;
100
+ }
101
+ // has matching identifier key
102
+ return isObjectProp && p.key.type === 'Identifier' && p.key.name === name;
103
+ });
104
+ }
105
+ exports.getObjectProperty = getObjectProperty;
106
+ /**
107
+ * Attempts to find a property of an ObjectExpression by name. If it doesn't exist,
108
+ * the property will be added to the ObjectExpression with the provided default value.
109
+ *
110
+ * @param object the parent object expression to search in
111
+ * @param name the name of the property to search for
112
+ * @param defaultValue the default value to set if the property doesn't exist
113
+ *
114
+ * @returns the
115
+ */
116
+ function getOrSetObjectProperty(object, name, defaultValue) {
117
+ var existingProperty = getObjectProperty(object, name);
118
+ if (existingProperty) {
119
+ return existingProperty;
120
+ }
121
+ var newProperty = b.property.from({
122
+ kind: 'init',
123
+ key: b.stringLiteral(name),
124
+ value: defaultValue,
125
+ });
126
+ object.properties.push(newProperty);
127
+ return newProperty;
128
+ }
129
+ exports.getOrSetObjectProperty = getOrSetObjectProperty;
130
+ /**
131
+ * Sets a property of an ObjectExpression if it exists, otherwise adds it
132
+ * to the ObjectExpression. Optionally, a comment can be added to the
133
+ * property.
134
+ *
135
+ * @param object the ObjectExpression to set the property on
136
+ * @param name the name of the property to set
137
+ * @param value the value of the property to set
138
+ * @param comment (optional) a comment to add to the property
139
+ */
140
+ function setOrUpdateObjectProperty(object, name, value, comment) {
141
+ var newComments = comment &&
142
+ comment.split('\n').map(function (c) { return b.commentLine(" ".concat(c), true, false); });
143
+ var existingProperty = getObjectProperty(object, name);
144
+ if (existingProperty) {
145
+ existingProperty.value = value;
146
+ if (newComments) {
147
+ existingProperty.comments = __spreadArray(__spreadArray([], ((existingProperty === null || existingProperty === void 0 ? void 0 : existingProperty.comments) || []), true), newComments, true);
148
+ }
149
+ }
150
+ else {
151
+ object.properties.push(b.objectProperty.from(__assign({ key: b.stringLiteral(name), value: value }, (newComments && {
152
+ comments: newComments,
153
+ }))));
154
+ }
155
+ }
156
+ exports.setOrUpdateObjectProperty = setOrUpdateObjectProperty;
157
+ /**
158
+ * Parses a JSON string with (potential) comments (JSON-C) and returns the JS AST
159
+ * that can be walked and modified with recast like a normal JS AST.
160
+ *
161
+ * This is done by wrapping the JSON-C string in parentheses, thereby making it
162
+ * a JS `Program` with an `ExpressionStatement` as its body. The expression is then
163
+ * extracted from the AST and returned alongside the AST.
164
+ *
165
+ * To preserve as much original formatting as possible, the returned `ast`
166
+ * property should be passed to {@link `printJsonC`} to get the JSON-C string back.
167
+ *
168
+ * If the input is not valid JSON-C, the result will be undefined.
169
+ *
170
+ * @see {@link JsonCParseResult}
171
+ *
172
+ * @param jsonString a JSON-C string
173
+ *
174
+ * @returns a {@link JsonCParseResult}, containing either the JSON-C object and the AST or undefined in both cases
175
+ */
176
+ function parseJsonC(jsonString) {
177
+ try {
178
+ var jsTsConfig = "(".concat(jsonString, ")");
179
+ // no idea why recast returns any here, this is dumb :/
180
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
181
+ var ast = recast.parse(jsTsConfig.toString()).program;
182
+ var jsonObject = (ast.body[0].type === 'ExpressionStatement' &&
183
+ ast.body[0].expression.type === 'ObjectExpression' &&
184
+ ast.body[0].expression) ||
185
+ undefined;
186
+ if (jsonObject) {
187
+ return { jsonObject: jsonObject, ast: ast };
188
+ }
189
+ }
190
+ catch (_a) {
191
+ /* empty */
192
+ }
193
+ return { jsonObject: undefined, ast: undefined };
194
+ }
195
+ exports.parseJsonC = parseJsonC;
196
+ /**
197
+ * Takes the AST of a parsed JSON-C "program" and returns the JSON-C string without
198
+ * any of the temporary JS wrapper code that was previously applied.
199
+ *
200
+ * Only use this in conjunction with {@link `parseJsonC`}
201
+ *
202
+ * @param ast the `ast` returned from {@link `parseJsonC`}
203
+ *
204
+ * @returns the JSON-C string
205
+ */
206
+ function printJsonC(ast) {
207
+ var js = recast.print(ast).code;
208
+ return js.substring(1, js.length - 1);
209
+ }
210
+ exports.printJsonC = printJsonC;
60
211
  //# sourceMappingURL=ast-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../../../src/utils/ast-utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAyB;AAEzB,6CAAiC;AAIjC;;;GAGG;AACH,SAAgB,QAAQ,CACtB,QAAgB,EAChB,SAAoD;IAApD,0BAAA,EAAA,aAAuB,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC;IAEpD,OAAO,SAAS;SACb,GAAG,CAAC,UAAC,IAAI,IAAK,OAAA,UAAG,QAAQ,SAAG,IAAI,CAAE,EAApB,CAAoB,CAAC;SACnC,IAAI,CAAC,UAAC,IAAI,IAAK,OAAA,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAnB,CAAmB,CAAC,CAAC;AACzC,CAAC;AAPD,4BAOC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,OAAkB;IACjD,IAAI,WAAW,GAAwB,KAAK,CAAC;IAC7C,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE;QACpB,kBAAkB,YAAC,IAAI;YACrB,WAAW,GAAG,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YACpE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QACD,YAAY,YAAC,IAAI;;YACf,WAAW;gBACT,WAAW,KAAI,MAAA,IAAI,CAAC,IAAI,CAAC,KAAK,0CAAE,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA,CAAC;YACpE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,CAAC,CAAC,WAAW,CAAC;AACvB,CAAC;AAfD,4CAeC","sourcesContent":["import * as fs from 'fs';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\n\n/**\n * Checks if a file where we don't know its concrete file type yet exists\n * and returns the full path to the file with the correct file type.\n */\nexport function findFile(\n filePath: string,\n fileTypes: string[] = ['.js', '.ts', '.mjs', '.cjs'],\n): string | undefined {\n return fileTypes\n .map((type) => `${filePath}${type}`)\n .find((file) => fs.existsSync(file));\n}\n\n/**\n * checks for require('@sentry/*') syntax\n */\nexport function hasSentryContent(program: t.Program): boolean {\n let foundSentry: boolean | undefined = false;\n recast.visit(program, {\n visitStringLiteral(path) {\n foundSentry = foundSentry || path.node.value.startsWith('@sentry/');\n this.traverse(path);\n },\n visitLiteral(path) {\n foundSentry =\n foundSentry || path.node.value?.toString().startsWith('@sentry/');\n this.traverse(path);\n },\n });\n\n return !!foundSentry;\n}\n"]}
1
+ {"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../../../src/utils/ast-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs';\n\nimport * as recast from 'recast';\nimport x = recast.types;\nimport t = x.namedTypes;\n\nconst b = recast.types.builders;\n\n/**\n * Checks if a file where we don't know its concrete file type yet exists\n * and returns the full path to the file with the correct file type.\n */\nexport function findFile(\n filePath: string,\n fileTypes: string[] = ['.js', '.ts', '.mjs', '.cjs'],\n): string | undefined {\n return fileTypes\n .map((type) => `${filePath}${type}`)\n .find((file) => fs.existsSync(file));\n}\n\n/**\n * checks for require('@sentry/*') syntax\n */\nexport function hasSentryContent(program: t.Program): boolean {\n let foundSentry: boolean | undefined = false;\n recast.visit(program, {\n visitStringLiteral(path) {\n foundSentry = foundSentry || path.node.value.startsWith('@sentry/');\n this.traverse(path);\n },\n visitLiteral(path) {\n foundSentry =\n foundSentry || path.node.value?.toString().startsWith('@sentry/');\n this.traverse(path);\n },\n });\n\n return !!foundSentry;\n}\n\n/**\n * Searches for a property of an ObjectExpression by name\n *\n * @param object the ObjectExpression to search in\n * @param name the name of the property to search for\n *\n * @returns the property if it exists\n */\nexport function getObjectProperty(\n object: t.ObjectExpression,\n name: string,\n): t.Property | undefined {\n return object.properties.find((p): p is t.Property => {\n const isObjectProp = p.type === 'Property' || p.type === 'ObjectProperty';\n\n if (!isObjectProp) {\n return false;\n }\n\n const hasMatchingLiteralKey =\n isObjectProp &&\n (p.key.type === 'Literal' || p.key.type === 'StringLiteral') &&\n p.key.value === name;\n\n if (hasMatchingLiteralKey) {\n return true;\n }\n\n // has matching identifier key\n return isObjectProp && p.key.type === 'Identifier' && p.key.name === name;\n });\n}\n\n/**\n * Attempts to find a property of an ObjectExpression by name. If it doesn't exist,\n * the property will be added to the ObjectExpression with the provided default value.\n *\n * @param object the parent object expression to search in\n * @param name the name of the property to search for\n * @param defaultValue the default value to set if the property doesn't exist\n *\n * @returns the\n */\nexport function getOrSetObjectProperty(\n object: t.ObjectExpression,\n name: string,\n defaultValue:\n | t.Literal\n | t.BooleanLiteral\n | t.StringLiteral\n | t.ObjectExpression,\n): t.Property {\n const existingProperty = getObjectProperty(object, name);\n\n if (existingProperty) {\n return existingProperty;\n }\n\n const newProperty = b.property.from({\n kind: 'init',\n key: b.stringLiteral(name),\n value: defaultValue,\n });\n\n object.properties.push(newProperty);\n\n return newProperty;\n}\n\n/**\n * Sets a property of an ObjectExpression if it exists, otherwise adds it\n * to the ObjectExpression. Optionally, a comment can be added to the\n * property.\n *\n * @param object the ObjectExpression to set the property on\n * @param name the name of the property to set\n * @param value the value of the property to set\n * @param comment (optional) a comment to add to the property\n */\nexport function setOrUpdateObjectProperty(\n object: t.ObjectExpression,\n name: string,\n value: t.Literal | t.BooleanLiteral | t.StringLiteral | t.ObjectExpression,\n comment?: string,\n) {\n const newComments =\n comment &&\n comment.split('\\n').map((c) => b.commentLine(` ${c}`, true, false));\n\n const existingProperty = getObjectProperty(object, name);\n\n if (existingProperty) {\n existingProperty.value = value;\n if (newComments) {\n existingProperty.comments = [\n ...(existingProperty?.comments || []),\n ...newComments,\n ];\n }\n } else {\n object.properties.push(\n b.objectProperty.from({\n key: b.stringLiteral(name),\n value,\n ...(newComments && {\n comments: newComments,\n }),\n }),\n );\n }\n}\n\ntype JsonCParseResult =\n | {\n jsonObject: t.ObjectExpression;\n ast: t.Program;\n }\n | {\n jsonObject: undefined;\n ast: undefined;\n };\n\n/**\n * Parses a JSON string with (potential) comments (JSON-C) and returns the JS AST\n * that can be walked and modified with recast like a normal JS AST.\n *\n * This is done by wrapping the JSON-C string in parentheses, thereby making it\n * a JS `Program` with an `ExpressionStatement` as its body. The expression is then\n * extracted from the AST and returned alongside the AST.\n *\n * To preserve as much original formatting as possible, the returned `ast`\n * property should be passed to {@link `printJsonC`} to get the JSON-C string back.\n *\n * If the input is not valid JSON-C, the result will be undefined.\n *\n * @see {@link JsonCParseResult}\n *\n * @param jsonString a JSON-C string\n *\n * @returns a {@link JsonCParseResult}, containing either the JSON-C object and the AST or undefined in both cases\n */\nexport function parseJsonC(jsonString: string): JsonCParseResult {\n try {\n const jsTsConfig = `(${jsonString})`;\n // no idea why recast returns any here, this is dumb :/\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n const ast = recast.parse(jsTsConfig.toString()).program as t.Program;\n\n const jsonObject =\n (ast.body[0].type === 'ExpressionStatement' &&\n ast.body[0].expression.type === 'ObjectExpression' &&\n ast.body[0].expression) ||\n undefined;\n\n if (jsonObject) {\n return { jsonObject, ast };\n }\n } catch {\n /* empty */\n }\n return { jsonObject: undefined, ast: undefined };\n}\n\n/**\n * Takes the AST of a parsed JSON-C \"program\" and returns the JSON-C string without\n * any of the temporary JS wrapper code that was previously applied.\n *\n * Only use this in conjunction with {@link `parseJsonC`}\n *\n * @param ast the `ast` returned from {@link `parseJsonC`}\n *\n * @returns the JSON-C string\n */\nexport function printJsonC(ast: t.Program): string {\n const js = recast.print(ast).code;\n return js.substring(1, js.length - 1);\n}\n"]}