@sentry/ember 7.61.0 → 7.62.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.
package/addon/index.ts CHANGED
@@ -1,19 +1,23 @@
1
- import * as Sentry from '@sentry/browser';
2
- import { SDK_VERSION, BrowserOptions } from '@sentry/browser';
3
- import { macroCondition, isDevelopingApp, getOwnConfig } from '@embroider/macros';
4
- import { next } from '@ember/runloop';
5
1
  import { assert, warn } from '@ember/debug';
2
+ import type Route from '@ember/routing/route';
3
+ import { next } from '@ember/runloop';
4
+ import { getOwnConfig, isDevelopingApp, macroCondition } from '@embroider/macros';
5
+ import type { BrowserOptions } from '@sentry/browser';
6
+ import * as Sentry from '@sentry/browser';
7
+ import { SDK_VERSION } from '@sentry/browser';
8
+ import type { Transaction } from '@sentry/types';
9
+ import { GLOBAL_OBJ, timestampInSeconds } from '@sentry/utils';
6
10
  import Ember from 'ember';
7
- import { timestampInSeconds, GLOBAL_OBJ } from '@sentry/utils';
8
- import { GlobalConfig, OwnConfig } from './types';
9
11
 
10
- function _getSentryInitConfig() {
12
+ import type { EmberSentryConfig, GlobalConfig, OwnConfig } from './types';
13
+
14
+ function _getSentryInitConfig(): EmberSentryConfig['sentry'] {
11
15
  const _global = GLOBAL_OBJ as typeof GLOBAL_OBJ & GlobalConfig;
12
16
  _global.__sentryEmberConfig = _global.__sentryEmberConfig ?? {};
13
17
  return _global.__sentryEmberConfig;
14
18
  }
15
19
 
16
- export function InitSentryForEmber(_runtimeConfig?: BrowserOptions) {
20
+ export function InitSentryForEmber(_runtimeConfig?: BrowserOptions): void {
17
21
  const environmentConfig = getOwnConfig<OwnConfig>().sentryConfig;
18
22
 
19
23
  assert('Missing configuration.', environmentConfig);
@@ -21,7 +25,7 @@ export function InitSentryForEmber(_runtimeConfig?: BrowserOptions) {
21
25
 
22
26
  if (!environmentConfig.sentry) {
23
27
  // If environment config is not specified but the above assertion passes, use runtime config.
24
- environmentConfig.sentry = { ..._runtimeConfig } as any;
28
+ environmentConfig.sentry = { ..._runtimeConfig };
25
29
  }
26
30
 
27
31
  // Merge runtime config into environment config, preferring runtime.
@@ -62,12 +66,20 @@ export function InitSentryForEmber(_runtimeConfig?: BrowserOptions) {
62
66
  }
63
67
  }
64
68
 
65
- export const getActiveTransaction = () => {
69
+ export const getActiveTransaction = (): Transaction | undefined => {
66
70
  return Sentry.getCurrentHub().getScope().getTransaction();
67
71
  };
68
72
 
69
- export const instrumentRoutePerformance = (BaseRoute: any) => {
70
- const instrumentFunction = async (op: string, description: string, fn: Function, args: any) => {
73
+ type RouteConstructor = new (...args: ConstructorParameters<typeof Route>) => Route;
74
+
75
+ export const instrumentRoutePerformance = <T extends RouteConstructor>(BaseRoute: T): T => {
76
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
+ const instrumentFunction = async <X extends (...args: unknown[]) => any>(
78
+ op: string,
79
+ description: string,
80
+ fn: X,
81
+ args: Parameters<X>,
82
+ ): Promise<ReturnType<X>> => {
71
83
  const startTimestamp = timestampInSeconds();
72
84
  const result = await fn(...args);
73
85
 
@@ -79,40 +91,38 @@ export const instrumentRoutePerformance = (BaseRoute: any) => {
79
91
  return result;
80
92
  };
81
93
 
94
+ const routeName = BaseRoute.name;
95
+
82
96
  return {
83
- [BaseRoute.name]: class extends BaseRoute {
84
- beforeModel(...args: any[]) {
97
+ // @ts-expect-error TS2545 We do not need to redefine a constructor here
98
+ [routeName]: class extends BaseRoute {
99
+ public beforeModel(...args: unknown[]): void | Promise<unknown> {
85
100
  return instrumentFunction(
86
101
  'ui.ember.route.before_model',
87
- (<any>this).fullRouteName,
102
+ this.fullRouteName,
88
103
  super.beforeModel.bind(this),
89
104
  args,
90
105
  );
91
106
  }
92
107
 
93
- async model(...args: any[]) {
94
- return instrumentFunction('ui.ember.route.model', (<any>this).fullRouteName, super.model.bind(this), args);
108
+ public async model(...args: unknown[]): Promise<unknown> {
109
+ return instrumentFunction('ui.ember.route.model', this.fullRouteName, super.model.bind(this), args);
95
110
  }
96
111
 
97
- async afterModel(...args: any[]) {
98
- return instrumentFunction(
99
- 'ui.ember.route.after_model',
100
- (<any>this).fullRouteName,
101
- super.afterModel.bind(this),
102
- args,
103
- );
112
+ public afterModel(...args: unknown[]): void | Promise<unknown> {
113
+ return instrumentFunction('ui.ember.route.after_model', this.fullRouteName, super.afterModel.bind(this), args);
104
114
  }
105
115
 
106
- async setupController(...args: any[]) {
116
+ public setupController(...args: unknown[]): void | Promise<unknown> {
107
117
  return instrumentFunction(
108
118
  'ui.ember.route.setup_controller',
109
- (<any>this).fullRouteName,
119
+ this.fullRouteName,
110
120
  super.setupController.bind(this),
111
121
  args,
112
122
  );
113
123
  }
114
124
  },
115
- }[BaseRoute.name];
125
+ }[routeName] as T;
116
126
  };
117
127
 
118
128
  export * from '@sentry/browser';
@@ -1,18 +1,26 @@
1
- import ApplicationInstance from '@ember/application/instance';
2
- import { run, _backburner, scheduleOnce } from '@ember/runloop';
1
+ /* eslint-disable max-lines */
2
+ import type ApplicationInstance from '@ember/application/instance';
3
3
  import { subscribe } from '@ember/instrumentation';
4
+ import type Transition from '@ember/routing/-private/transition';
5
+ import type RouterService from '@ember/routing/router-service';
6
+ import { _backburner, run, scheduleOnce } from '@ember/runloop';
7
+ import type { EmberRunQueues } from '@ember/runloop/-private/types';
8
+ import { getOwnConfig, isTesting, macroCondition } from '@embroider/macros';
4
9
  import * as Sentry from '@sentry/browser';
5
- import { ExtendedBackburner } from '@sentry/ember/runloop';
6
- import { Span, Transaction } from '@sentry/types';
7
- import { EmberRunQueues } from '@ember/runloop/-private/types';
8
- import { getActiveTransaction } from '..';
10
+ import type { ExtendedBackburner } from '@sentry/ember/runloop';
11
+ import type { Span, Transaction } from '@sentry/types';
9
12
  import { browserPerformanceTimeOrigin, GLOBAL_OBJ, timestampInSeconds } from '@sentry/utils';
10
- import { macroCondition, isTesting, getOwnConfig } from '@embroider/macros';
11
- import { EmberSentryConfig, GlobalConfig, OwnConfig } from '../types';
12
- import RouterService from '@ember/routing/router-service';
13
- import type { BaseClient } from '@sentry/core';
14
13
 
15
- function getSentryConfig() {
14
+ import type { BrowserClient } from '..';
15
+ import { getActiveTransaction } from '..';
16
+ import type { EmberRouterMain, EmberSentryConfig, GlobalConfig, OwnConfig, StartTransactionFunction } from '../types';
17
+
18
+ type SentryTestRouterService = RouterService & {
19
+ _startTransaction?: StartTransactionFunction;
20
+ _sentryInstrumented?: boolean;
21
+ };
22
+
23
+ function getSentryConfig(): EmberSentryConfig {
16
24
  const _global = GLOBAL_OBJ as typeof GLOBAL_OBJ & GlobalConfig;
17
25
  _global.__sentryEmberConfig = _global.__sentryEmberConfig ?? {};
18
26
  const environmentConfig = getOwnConfig<OwnConfig>().sentryConfig;
@@ -27,7 +35,7 @@ function getSentryConfig() {
27
35
 
28
36
  export function initialize(appInstance: ApplicationInstance): void {
29
37
  // Disable in fastboot - we only want to run Sentry client-side
30
- const fastboot = appInstance.lookup('service:fastboot') as { isFastBoot: boolean } | undefined;
38
+ const fastboot = appInstance.lookup('service:fastboot') as unknown as { isFastBoot: boolean } | undefined;
31
39
  if (fastboot?.isFastBoot) {
32
40
  return;
33
41
  }
@@ -38,35 +46,42 @@ export function initialize(appInstance: ApplicationInstance): void {
38
46
  }
39
47
  const performancePromise = instrumentForPerformance(appInstance);
40
48
  if (macroCondition(isTesting())) {
41
- (<any>window)._sentryPerformanceLoad = performancePromise;
49
+ (window as typeof window & { _sentryPerformanceLoad?: Promise<void> })._sentryPerformanceLoad = performancePromise;
42
50
  }
43
51
  }
44
52
 
45
53
  function getBackburner(): Pick<ExtendedBackburner, 'on' | 'off'> {
46
54
  if (_backburner) {
47
- return _backburner;
55
+ return _backburner as unknown as Pick<ExtendedBackburner, 'on' | 'off'>;
48
56
  }
49
57
 
50
- if (run.backburner) {
51
- return run.backburner;
58
+ if ((run as unknown as { backburner?: Pick<ExtendedBackburner, 'on' | 'off'> }).backburner) {
59
+ return (run as unknown as { backburner: Pick<ExtendedBackburner, 'on' | 'off'> }).backburner;
52
60
  }
53
61
 
54
62
  return {
55
- on() {},
56
- off() {},
63
+ on() {
64
+ // noop
65
+ },
66
+ off() {
67
+ // noop
68
+ },
57
69
  };
58
70
  }
59
71
 
60
- function getTransitionInformation(transition: any, router: any) {
72
+ function getTransitionInformation(
73
+ transition: Transition | undefined,
74
+ router: RouterService,
75
+ ): { fromRoute?: string; toRoute?: string } {
61
76
  const fromRoute = transition?.from?.name;
62
- const toRoute = transition && transition.to ? transition.to.name : router.currentRouteName;
77
+ const toRoute = transition?.to?.name || router.currentRouteName;
63
78
  return {
64
79
  fromRoute,
65
80
  toRoute,
66
81
  };
67
82
  }
68
83
 
69
- function getLocationURL(location: any) {
84
+ function getLocationURL(location: EmberRouterMain['location']): string {
70
85
  if (!location || !location.getURL || !location.formatURL) {
71
86
  return '';
72
87
  }
@@ -79,22 +94,24 @@ function getLocationURL(location: any) {
79
94
  }
80
95
 
81
96
  export function _instrumentEmberRouter(
82
- routerService: any,
83
- routerMain: any,
97
+ routerService: RouterService,
98
+ routerMain: EmberRouterMain,
84
99
  config: EmberSentryConfig,
85
- startTransaction: Function,
100
+ startTransaction: StartTransactionFunction,
86
101
  startTransactionOnPageLoad?: boolean,
87
- ) {
102
+ ): {
103
+ startTransaction: StartTransactionFunction;
104
+ } {
88
105
  const { disableRunloopPerformance } = config;
89
106
  const location = routerMain.location;
90
- let activeTransaction: Transaction;
91
- let transitionSpan: Span;
107
+ let activeTransaction: Transaction | undefined;
108
+ let transitionSpan: Span | undefined;
92
109
 
93
110
  const url = getLocationURL(location);
94
111
 
95
112
  if (macroCondition(isTesting())) {
96
- routerService._sentryInstrumented = true;
97
- routerService._startTransaction = startTransaction;
113
+ (routerService as SentryTestRouterService)._sentryInstrumented = true;
114
+ (routerService as SentryTestRouterService)._startTransaction = startTransaction;
98
115
  }
99
116
 
100
117
  if (startTransactionOnPageLoad && url) {
@@ -110,15 +127,15 @@ export function _instrumentEmberRouter(
110
127
  });
111
128
  }
112
129
 
113
- const finishActiveTransaction = function (_: any, nextInstance: any) {
130
+ const finishActiveTransaction = (_: unknown, nextInstance: unknown): void => {
114
131
  if (nextInstance) {
115
132
  return;
116
133
  }
117
- activeTransaction.finish();
134
+ activeTransaction?.finish();
118
135
  getBackburner().off('end', finishActiveTransaction);
119
136
  };
120
137
 
121
- routerService.on('routeWillChange', (transition: any) => {
138
+ routerService.on('routeWillChange', (transition: Transition) => {
122
139
  const { fromRoute, toRoute } = getTransitionInformation(transition, routerService);
123
140
  activeTransaction?.finish();
124
141
  activeTransaction = startTransaction({
@@ -130,7 +147,7 @@ export function _instrumentEmberRouter(
130
147
  'routing.instrumentation': '@sentry/ember',
131
148
  },
132
149
  });
133
- transitionSpan = activeTransaction.startChild({
150
+ transitionSpan = activeTransaction?.startChild({
134
151
  op: 'ui.ember.transition',
135
152
  description: `route:${fromRoute} -> route:${toRoute}`,
136
153
  });
@@ -155,7 +172,7 @@ export function _instrumentEmberRouter(
155
172
  };
156
173
  }
157
174
 
158
- function _instrumentEmberRunloop(config: EmberSentryConfig) {
175
+ function _instrumentEmberRunloop(config: EmberSentryConfig): void {
159
176
  const { disableRunloopPerformance, minimumRunloopQueueDuration } = config;
160
177
  if (disableRunloopPerformance) {
161
178
  return;
@@ -171,7 +188,7 @@ function _instrumentEmberRunloop(config: EmberSentryConfig) {
171
188
  'destroy',
172
189
  ] as EmberRunQueues[];
173
190
 
174
- getBackburner().on('begin', (_: any, previousInstance: any) => {
191
+ getBackburner().on('begin', (_: unknown, previousInstance: unknown) => {
175
192
  if (previousInstance) {
176
193
  return;
177
194
  }
@@ -184,38 +201,38 @@ function _instrumentEmberRunloop(config: EmberSentryConfig) {
184
201
  }
185
202
  currentQueueStart = timestampInSeconds();
186
203
 
204
+ const processQueue = (queue: EmberRunQueues): void => {
205
+ // Process this queue using the end of the previous queue.
206
+ if (currentQueueStart) {
207
+ const now = timestampInSeconds();
208
+ const minQueueDuration = minimumRunloopQueueDuration ?? 5;
209
+
210
+ if ((now - currentQueueStart) * 1000 >= minQueueDuration) {
211
+ activeTransaction
212
+ ?.startChild({
213
+ op: `ui.ember.runloop.${queue}`,
214
+ startTimestamp: currentQueueStart,
215
+ endTimestamp: now,
216
+ })
217
+ .finish();
218
+ }
219
+ currentQueueStart = undefined;
220
+ }
221
+
222
+ // Setup for next queue
223
+
224
+ const stillActiveTransaction = getActiveTransaction();
225
+ if (!stillActiveTransaction) {
226
+ return;
227
+ }
228
+ currentQueueStart = timestampInSeconds();
229
+ };
230
+
187
231
  instrumentedEmberQueues.forEach(queue => {
188
- scheduleOnce(queue, null, () => {
189
- scheduleOnce(queue, null, () => {
190
- // Process this queue using the end of the previous queue.
191
- if (currentQueueStart) {
192
- const now = timestampInSeconds();
193
- const minQueueDuration = minimumRunloopQueueDuration ?? 5;
194
-
195
- if ((now - currentQueueStart) * 1000 >= minQueueDuration) {
196
- activeTransaction
197
- ?.startChild({
198
- op: `ui.ember.runloop.${queue}`,
199
- startTimestamp: currentQueueStart,
200
- endTimestamp: now,
201
- })
202
- .finish();
203
- }
204
- currentQueueStart = undefined;
205
- }
206
-
207
- // Setup for next queue
208
-
209
- const stillActiveTransaction = getActiveTransaction();
210
- if (!stillActiveTransaction) {
211
- return;
212
- }
213
- currentQueueStart = timestampInSeconds();
214
- });
215
- });
232
+ scheduleOnce(queue, null, processQueue, queue);
216
233
  });
217
234
  });
218
- getBackburner().on('end', (_: any, nextInstance: any) => {
235
+ getBackburner().on('end', (_: unknown, nextInstance: unknown) => {
219
236
  if (nextInstance) {
220
237
  return;
221
238
  }
@@ -241,7 +258,7 @@ interface RenderEntries {
241
258
  [name: string]: RenderEntry;
242
259
  }
243
260
 
244
- function processComponentRenderBefore(payload: Payload, beforeEntries: RenderEntries) {
261
+ function processComponentRenderBefore(payload: Payload, beforeEntries: RenderEntries): void {
245
262
  const info = {
246
263
  payload,
247
264
  now: timestampInSeconds(),
@@ -254,7 +271,7 @@ function processComponentRenderAfter(
254
271
  beforeEntries: RenderEntries,
255
272
  op: string,
256
273
  minComponentDuration: number,
257
- ) {
274
+ ): void {
258
275
  const begin = beforeEntries[payload.object];
259
276
 
260
277
  if (!begin) {
@@ -276,7 +293,7 @@ function processComponentRenderAfter(
276
293
  }
277
294
  }
278
295
 
279
- function _instrumentComponents(config: EmberSentryConfig) {
296
+ function _instrumentComponents(config: EmberSentryConfig): void {
280
297
  const { disableInstrumentComponents, minimumComponentRenderDuration, enableComponentDefinitions } = config;
281
298
  if (disableInstrumentComponents) {
282
299
  return;
@@ -287,13 +304,13 @@ function _instrumentComponents(config: EmberSentryConfig) {
287
304
  const beforeEntries = {} as RenderEntries;
288
305
  const beforeComponentDefinitionEntries = {} as RenderEntries;
289
306
 
290
- function _subscribeToRenderEvents() {
307
+ function _subscribeToRenderEvents(): void {
291
308
  subscribe('render.component', {
292
309
  before(_name: string, _timestamp: number, payload: Payload) {
293
310
  processComponentRenderBefore(payload, beforeEntries);
294
311
  },
295
312
 
296
- after(_name: string, _timestamp: number, payload: any, _beganIndex: number) {
313
+ after(_name: string, _timestamp: number, payload: Payload, _beganIndex: number) {
297
314
  processComponentRenderAfter(payload, beforeEntries, 'ui.ember.component.render', minComponentDuration);
298
315
  },
299
316
  });
@@ -303,7 +320,7 @@ function _instrumentComponents(config: EmberSentryConfig) {
303
320
  processComponentRenderBefore(payload, beforeComponentDefinitionEntries);
304
321
  },
305
322
 
306
- after(_name: string, _timestamp: number, payload: any, _beganIndex: number) {
323
+ after(_name: string, _timestamp: number, payload: Payload, _beganIndex: number) {
307
324
  processComponentRenderAfter(payload, beforeComponentDefinitionEntries, 'ui.ember.component.definition', 0);
308
325
  },
309
326
  });
@@ -312,11 +329,11 @@ function _instrumentComponents(config: EmberSentryConfig) {
312
329
  _subscribeToRenderEvents();
313
330
  }
314
331
 
315
- function _instrumentInitialLoad(config: EmberSentryConfig) {
332
+ function _instrumentInitialLoad(config: EmberSentryConfig): void {
316
333
  const startName = '@sentry/ember:initial-load-start';
317
334
  const endName = '@sentry/ember:initial-load-end';
318
335
 
319
- let { HAS_PERFORMANCE, HAS_PERFORMANCE_TIMING } = _hasPerformanceSupport();
336
+ const { HAS_PERFORMANCE, HAS_PERFORMANCE_TIMING } = _hasPerformanceSupport();
320
337
 
321
338
  if (!HAS_PERFORMANCE) {
322
339
  return;
@@ -331,7 +348,7 @@ function _instrumentInitialLoad(config: EmberSentryConfig) {
331
348
  }
332
349
 
333
350
  // Split performance check in two so clearMarks still happens even if timeOrigin isn't available.
334
- if (!HAS_PERFORMANCE_TIMING) {
351
+ if (!HAS_PERFORMANCE_TIMING || browserPerformanceTimeOrigin === undefined) {
335
352
  return;
336
353
  }
337
354
  const measureName = '@sentry/ember:initial-load';
@@ -344,9 +361,10 @@ function _instrumentInitialLoad(config: EmberSentryConfig) {
344
361
 
345
362
  performance.measure(measureName, startName, endName);
346
363
  const measures = performance.getEntriesByName(measureName);
347
- const measure = measures[0];
364
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
365
+ const measure = measures[0]!;
348
366
 
349
- const startTimestamp = (measure.startTime + browserPerformanceTimeOrigin!) / 1000;
367
+ const startTimestamp = (measure.startTime + browserPerformanceTimeOrigin) / 1000;
350
368
  const endTimestamp = startTimestamp + measure.duration / 1000;
351
369
 
352
370
  const transaction = getActiveTransaction();
@@ -361,7 +379,7 @@ function _instrumentInitialLoad(config: EmberSentryConfig) {
361
379
  performance.clearMeasures(measureName);
362
380
  }
363
381
 
364
- function _hasPerformanceSupport() {
382
+ function _hasPerformanceSupport(): { HAS_PERFORMANCE: boolean; HAS_PERFORMANCE_TIMING: boolean } {
365
383
  // TS says that all of these methods are always available, but some of them may not be supported in older browsers
366
384
  // So we "pretend" they are all optional in order to be able to check this properly without TS complaining
367
385
  const _performance = window.performance as {
@@ -381,9 +399,8 @@ function _hasPerformanceSupport() {
381
399
  };
382
400
  }
383
401
 
384
- export async function instrumentForPerformance(appInstance: ApplicationInstance) {
402
+ export async function instrumentForPerformance(appInstance: ApplicationInstance): Promise<void> {
385
403
  const config = getSentryConfig();
386
- const sentryConfig = config.sentry;
387
404
  // Maintaining backwards compatibility with config.browserTracingOptions, but passing it with Sentry options is preferred.
388
405
  const browserTracingOptions = config.browserTracingOptions || config.sentry.browserTracingOptions || {};
389
406
 
@@ -393,7 +410,8 @@ export async function instrumentForPerformance(appInstance: ApplicationInstance)
393
410
 
394
411
  const browserTracing = new BrowserTracing({
395
412
  routingInstrumentation: (customStartTransaction, startTransactionOnPageLoad) => {
396
- const routerMain = appInstance.lookup('router:main');
413
+ // eslint-disable-next-line ember/no-private-routing-service
414
+ const routerMain = appInstance.lookup('router:main') as EmberRouterMain;
397
415
  let routerService = appInstance.lookup('service:router') as
398
416
  | RouterService & { externalRouter?: RouterService; _hasMountedSentryPerformanceRouting?: boolean };
399
417
 
@@ -421,8 +439,8 @@ export async function instrumentForPerformance(appInstance: ApplicationInstance)
421
439
 
422
440
  if (
423
441
  client &&
424
- (client as BaseClient<any>).getIntegrationById &&
425
- (client as BaseClient<any>).getIntegrationById('BrowserTracing')
442
+ (client as BrowserClient).getIntegrationById &&
443
+ (client as BrowserClient).getIntegrationById('BrowserTracing')
426
444
  ) {
427
445
  // Initializers are called more than once in tests, causing the integrations to not be setup correctly.
428
446
  return;
@@ -1,10 +1,10 @@
1
- import { Backburner } from '@ember/runloop/-private/backburner';
1
+ import type { Backburner } from '@ember/runloop/-private/backburner';
2
2
 
3
3
  /**
4
4
  * Backburner needs to be extended as it's missing the 'off' method.
5
5
  */
6
6
  interface ExtendedBackburner extends Backburner {
7
- off(...args: any[]): void;
7
+ off(...args: unknown[]): void;
8
8
  }
9
9
 
10
10
  /**
package/addon/types.ts CHANGED
@@ -1,7 +1,10 @@
1
- import { BrowserOptions } from '@sentry/browser';
1
+ import type { BrowserOptions, BrowserTracing } from '@sentry/browser';
2
+ import type { Transaction, TransactionContext } from '@sentry/types';
3
+
4
+ type BrowserTracingOptions = ConstructorParameters<typeof BrowserTracing>[0];
2
5
 
3
6
  export type EmberSentryConfig = {
4
- sentry: BrowserOptions & { browserTracingOptions: Object };
7
+ sentry: BrowserOptions & { browserTracingOptions?: BrowserTracingOptions };
5
8
  transitionTimeout: number;
6
9
  ignoreEmberOnErrorWarning: boolean;
7
10
  disableInstrumentComponents: boolean;
@@ -12,13 +15,25 @@ export type EmberSentryConfig = {
12
15
  enableComponentDefinitions: boolean;
13
16
  minimumRunloopQueueDuration: number;
14
17
  minimumComponentRenderDuration: number;
15
- browserTracingOptions: Object;
18
+ browserTracingOptions: BrowserTracingOptions;
16
19
  };
17
20
 
18
21
  export type OwnConfig = {
19
22
  sentryConfig: EmberSentryConfig;
20
23
  };
21
24
 
25
+ // This is private in Ember and not really exported, so we "mock" these types here.
26
+ export interface EmberRouterMain {
27
+ location: {
28
+ getURL?: () => string;
29
+ formatURL?: (url: string) => string;
30
+ implementation: string;
31
+ rootURL: string;
32
+ };
33
+ }
34
+
35
+ export type StartTransactionFunction = (context: TransactionContext) => Transaction | undefined;
36
+
22
37
  export type GlobalConfig = {
23
38
  __sentryEmberConfig: EmberSentryConfig['sentry'];
24
39
  };
package/index.d.ts CHANGED
@@ -1,16 +1,9 @@
1
- import * as Sentry from '@sentry/browser';
2
- import { BrowserOptions } from '@sentry/browser';
1
+ import type Route from '@ember/routing/route';
2
+ import type { BrowserOptions } from '@sentry/browser';
3
+ import type { Transaction } from '@sentry/types';
3
4
  export declare function InitSentryForEmber(_runtimeConfig?: BrowserOptions): void;
4
- export declare const getActiveTransaction: () => Sentry.Transaction | undefined;
5
- export declare const instrumentRoutePerformance: (BaseRoute: any) => {
6
- new (): {
7
- [x: string]: any;
8
- beforeModel(...args: any[]): Promise<any>;
9
- model(...args: any[]): Promise<any>;
10
- afterModel(...args: any[]): Promise<any>;
11
- setupController(...args: any[]): Promise<any>;
12
- };
13
- [x: string]: any;
14
- };
5
+ export declare const getActiveTransaction: () => Transaction | undefined;
6
+ type RouteConstructor = new (...args: ConstructorParameters<typeof Route>) => Route;
7
+ export declare const instrumentRoutePerformance: <T extends RouteConstructor>(BaseRoute: T) => T;
15
8
  export * from '@sentry/browser';
16
9
  export declare const init: typeof InitSentryForEmber;
package/index.js CHANGED
@@ -33,6 +33,7 @@ module.exports = {
33
33
  const addonConfig = config['@sentry/ember'] || {};
34
34
 
35
35
  if (!isSerializable(addonConfig)) {
36
+ // eslint-disable-next-line no-console
36
37
  console.warn(
37
38
  `Warning: You passed a non-serializable config to \`ENV['@sentry/ember'].sentry\`.
38
39
  Non-serializable config (e.g. RegExp, ...) can only be passed directly to \`Sentry.init()\`, which is usually defined in app/app.js.
@@ -73,6 +74,7 @@ function isSerializable(obj) {
73
74
  }
74
75
 
75
76
  if (isPlainObject(obj)) {
77
+ // eslint-disable-next-line guard-for-in
76
78
  for (let property in obj) {
77
79
  let value = obj[property];
78
80
  if (!isSerializable(value)) {
@@ -1,8 +1,9 @@
1
- import ApplicationInstance from '@ember/application/instance';
2
- import { EmberSentryConfig } from '../types';
1
+ import type ApplicationInstance from '@ember/application/instance';
2
+ import type RouterService from '@ember/routing/router-service';
3
+ import type { EmberRouterMain, EmberSentryConfig, StartTransactionFunction } from '../types';
3
4
  export declare function initialize(appInstance: ApplicationInstance): void;
4
- export declare function _instrumentEmberRouter(routerService: any, routerMain: any, config: EmberSentryConfig, startTransaction: Function, startTransactionOnPageLoad?: boolean): {
5
- startTransaction: Function;
5
+ export declare function _instrumentEmberRouter(routerService: RouterService, routerMain: EmberRouterMain, config: EmberSentryConfig, startTransaction: StartTransactionFunction, startTransactionOnPageLoad?: boolean): {
6
+ startTransaction: StartTransactionFunction;
6
7
  };
7
8
  export declare function instrumentForPerformance(appInstance: ApplicationInstance): Promise<void>;
8
9
  declare const _default: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/ember",
3
- "version": "7.61.0",
3
+ "version": "7.62.0",
4
4
  "description": "Official Sentry SDK for Ember.js",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/ember",
@@ -23,15 +23,20 @@
23
23
  "lint:hbs": "ember-template-lint .",
24
24
  "lint:js": "eslint .",
25
25
  "lint:ts": "tsc",
26
+ "fix": "run-s fix:eslint fix:prettier",
27
+ "fix:eslint": "eslint . --format stylish --fix",
28
+ "fix:prettier": "prettier --write \"{addon,app,tests,config}/**/**.{ts,js}\"",
26
29
  "start": "ember serve",
27
30
  "test": "ember test",
28
- "test:all": "ember try:each"
31
+ "test:all": "ember try:each",
32
+ "prepack": "ember ts:precompile",
33
+ "postpack": "ember ts:clean"
29
34
  },
30
35
  "dependencies": {
31
36
  "@embroider/macros": "^1.9.0",
32
- "@sentry/browser": "7.61.0",
33
- "@sentry/types": "7.61.0",
34
- "@sentry/utils": "7.61.0",
37
+ "@sentry/browser": "7.62.0",
38
+ "@sentry/types": "7.62.0",
39
+ "@sentry/utils": "7.62.0",
35
40
  "ember-auto-import": "^1.12.1 || ^2.4.3",
36
41
  "ember-cli-babel": "^7.26.11",
37
42
  "ember-cli-htmlbars": "^6.1.1",
@@ -39,14 +44,14 @@
39
44
  },
40
45
  "devDependencies": {
41
46
  "@ember/optional-features": "~1.3.0",
42
- "@ember/test-helpers": "~2.8.1",
47
+ "@ember/test-helpers": "2.9.4",
43
48
  "@embroider/test-setup": "~1.8.3",
44
49
  "@glimmer/component": "~1.1.2",
45
50
  "@glimmer/tracking": "~1.1.2",
46
51
  "@types/ember": "~3.16.5",
47
52
  "@types/ember-qunit": "~3.4.9",
53
+ "@types/ember-resolver": "5.0.13",
48
54
  "@types/ember__debug": "^3.16.5",
49
- "@types/ember__test-helpers": "~1.7.0",
50
55
  "@types/qunit": "~2.9.1",
51
56
  "@types/rsvp": "~4.0.3",
52
57
  "babel-eslint": "~10.1.0",
@@ -61,20 +66,21 @@
61
66
  "ember-load-initializers": "~2.1.1",
62
67
  "ember-maybe-import-regenerator": "~1.0.0",
63
68
  "ember-qunit": "~6.0.0",
64
- "ember-resolver": "~8.0.3",
65
- "ember-sinon-qunit": "~6.0.0",
69
+ "ember-resolver": "11.0.0",
70
+ "ember-sinon-qunit": "7.1.4",
66
71
  "ember-source": "~4.8.0",
67
72
  "ember-source-channel-url": "~2.0.1",
68
73
  "ember-template-lint": "~4.16.1",
69
74
  "ember-test-selectors": "~6.0.0",
70
75
  "ember-try": "~2.0.0",
71
76
  "ember-window-mock": "~0.8.1",
72
- "eslint-plugin-ember": "~11.1.0",
73
- "eslint-plugin-node": "~11.1.0",
74
- "eslint-plugin-qunit": "~7.3.1",
77
+ "eslint-plugin-ember": "11.9.0",
78
+ "eslint-plugin-n": "16.0.1",
79
+ "eslint-plugin-qunit": "8.0.0",
75
80
  "loader.js": "~4.7.0",
76
81
  "qunit": "~2.19.2",
77
82
  "qunit-dom": "~2.0.0",
83
+ "sinon": "15.2.0",
78
84
  "webpack": "~5.74.0"
79
85
  },
80
86
  "engines": {
package/runloop.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { Backburner } from '@ember/runloop/-private/backburner';
1
+ import type { Backburner } from '@ember/runloop/-private/backburner';
2
2
 
3
3
  /**
4
4
  * Backburner needs to be extended as it's missing the 'off' method.
5
5
  */
6
6
  interface ExtendedBackburner extends Backburner {
7
- off(...args: any[]): void;
7
+ off(...args: unknown[]): void;
8
8
  }
9
9
 
10
10
  /**
package/tsconfig.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "extends": "../../tsconfig.json",
3
3
  "compilerOptions": {
4
- "target": "es2017",
4
+ "target": "es2022",
5
5
  "allowJs": true,
6
6
  "moduleResolution": "node",
7
7
  "allowSyntheticDefaultImports": true,
@@ -24,5 +24,5 @@
24
24
  "*": ["types/*"]
25
25
  }
26
26
  },
27
- "include": ["app/**/*", "addon/**/*", "types/**/*", "addon-test-support/**/*"]
27
+ "include": ["app/**/*", "addon/**/*", "tests/**/*", "types/**/*", "test-support/**/*", "addon-test-support/**/*"]
28
28
  }
package/types.d.ts CHANGED
@@ -1,7 +1,9 @@
1
- import { BrowserOptions } from '@sentry/browser';
1
+ import type { BrowserOptions, BrowserTracing } from '@sentry/browser';
2
+ import type { Transaction, TransactionContext } from '@sentry/types';
3
+ type BrowserTracingOptions = ConstructorParameters<typeof BrowserTracing>[0];
2
4
  export type EmberSentryConfig = {
3
5
  sentry: BrowserOptions & {
4
- browserTracingOptions: Object;
6
+ browserTracingOptions?: BrowserTracingOptions;
5
7
  };
6
8
  transitionTimeout: number;
7
9
  ignoreEmberOnErrorWarning: boolean;
@@ -13,11 +15,21 @@ export type EmberSentryConfig = {
13
15
  enableComponentDefinitions: boolean;
14
16
  minimumRunloopQueueDuration: number;
15
17
  minimumComponentRenderDuration: number;
16
- browserTracingOptions: Object;
18
+ browserTracingOptions: BrowserTracingOptions;
17
19
  };
18
20
  export type OwnConfig = {
19
21
  sentryConfig: EmberSentryConfig;
20
22
  };
23
+ export interface EmberRouterMain {
24
+ location: {
25
+ getURL?: () => string;
26
+ formatURL?: (url: string) => string;
27
+ implementation: string;
28
+ rootURL: string;
29
+ };
30
+ }
31
+ export type StartTransactionFunction = (context: TransactionContext) => Transaction | undefined;
21
32
  export type GlobalConfig = {
22
33
  __sentryEmberConfig: EmberSentryConfig['sentry'];
23
34
  };
35
+ export {};