sentry-vir 3.1.0 → 3.2.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.
@@ -0,0 +1,2 @@
1
+ import { type AnyObject } from '@augment-vir/common';
2
+ export declare function replaceObject<T extends AnyObject>(original: T, replacement: T): void;
@@ -0,0 +1,6 @@
1
+ export function replaceObject(original, replacement) {
2
+ Object.keys(original).forEach((key) => delete original[key]);
3
+ Object.entries(replacement).forEach(([key, value,]) => {
4
+ original[key] = value;
5
+ });
6
+ }
package/dist/auto.d.ts CHANGED
@@ -12,4 +12,4 @@ export declare const sentryDepByEnv: Record<SentryExecutionEnvEnum, SentryDepImp
12
12
  *
13
13
  * To override any default sentry-vir settings, include them in the userConfig input.
14
14
  */
15
- export declare function autoInitSentry({ executionEnv, dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, }: InitSentryInput): Promise<SentryDep>;
15
+ export declare function autoInitSentry({ executionEnv, dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, silent, throttleOptions, }: InitSentryInput): Promise<SentryDep>;
package/dist/auto.js CHANGED
@@ -19,7 +19,7 @@ async function getSentryByEnv(executionEnv) {
19
19
  *
20
20
  * To override any default sentry-vir settings, include them in the userConfig input.
21
21
  */
22
- export async function autoInitSentry({ executionEnv, dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, }) {
22
+ export async function autoInitSentry({ executionEnv, dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, silent, throttleOptions, }) {
23
23
  const sentryDep = await getSentryByEnv(executionEnv);
24
24
  await baseInitSentry({
25
25
  dsn,
@@ -30,6 +30,8 @@ export async function autoInitSentry({ executionEnv, dsn, releaseEnv, releaseNam
30
30
  sentryDep,
31
31
  executionEnv,
32
32
  isDev,
33
+ silent,
34
+ throttleOptions,
33
35
  });
34
36
  return sentryDep;
35
37
  }
package/dist/browser.d.ts CHANGED
@@ -7,4 +7,4 @@ export type Sentry = SentryBrowserDep;
7
7
  *
8
8
  * To override any default sentry-vir settings, include them in the userConfig input.
9
9
  */
10
- export declare function initSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, }: Omit<InitSentryInput, 'executionEnv'>): Promise<Sentry>;
10
+ export declare function initSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, silent, throttleOptions, }: Omit<InitSentryInput, 'executionEnv'>): Promise<Sentry>;
package/dist/browser.js CHANGED
@@ -6,7 +6,7 @@ import { baseInitSentry } from './init-sentry/base-sentry-init.js';
6
6
  *
7
7
  * To override any default sentry-vir settings, include them in the userConfig input.
8
8
  */
9
- export async function initSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, }) {
9
+ export async function initSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, silent, throttleOptions, }) {
10
10
  const sentryDep = await import('@sentry/browser');
11
11
  await baseInitSentry({
12
12
  dsn,
@@ -17,6 +17,8 @@ export async function initSentry({ dsn, releaseEnv, releaseName, sentryConfigOve
17
17
  sentryDep,
18
18
  executionEnv: SentryExecutionEnvEnum.Browser,
19
19
  isDev,
20
+ silent,
21
+ throttleOptions,
20
22
  });
21
23
  return sentryDep;
22
24
  }
package/dist/index.d.ts CHANGED
@@ -11,3 +11,4 @@ export * from './logging/send-log.js';
11
11
  export * from './logging/sentry-client-for-logging.js';
12
12
  export * from './processing/event-processor.js';
13
13
  export * from './processing/handle-sentry-send.js';
14
+ export * from './processing/throttling.js';
package/dist/index.js CHANGED
@@ -11,3 +11,4 @@ export * from './logging/send-log.js';
11
11
  export * from './logging/sentry-client-for-logging.js';
12
12
  export * from './processing/event-processor.js';
13
13
  export * from './processing/handle-sentry-send.js';
14
+ export * from './processing/throttling.js';
@@ -1,6 +1,8 @@
1
+ import { type PartialWithUndefined } from '@augment-vir/common';
1
2
  import { type Options } from '@sentry/core';
2
3
  import { type SentryDep, type SentryExecutionEnvEnum } from '../env/execution-env.js';
3
4
  import { type EventExtraContextCreator } from '../event-context/event-context.js';
5
+ import { type ThrottleOptions } from '../processing/throttling.js';
4
6
  import { type UserOverrides } from './sentry-config.js';
5
7
  /** Configuration for initializing Sentry. */
6
8
  export type InitSentryInput = {
@@ -33,6 +35,7 @@ export type InitSentryInput = {
33
35
  createUniversalContext?: EventExtraContextCreator | undefined;
34
36
  /** Optionally override any Sentry config properties that this package sets. */
35
37
  sentryConfigOverrides?: UserOverrides;
38
+ throttleOptions: Readonly<PartialWithUndefined<ThrottleOptions>> | undefined;
36
39
  };
37
40
  /**
38
41
  * Base Sentry init. Requires the Sentry module to already have been imported. Setup a sentry client
@@ -40,6 +43,6 @@ export type InitSentryInput = {
40
43
  *
41
44
  * To override any default sentry-vir settings, include them in the userConfig input.
42
45
  */
43
- export declare function baseInitSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, sentryDep, executionEnv, isDev, silent, }: InitSentryInput & {
46
+ export declare function baseInitSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, sentryDep, executionEnv, isDev, silent, throttleOptions, }: InitSentryInput & {
44
47
  sentryDep: SentryDep;
45
48
  }): Promise<SentryDep>;
@@ -7,14 +7,21 @@ import { createSentryConfig } from './sentry-config.js';
7
7
  *
8
8
  * To override any default sentry-vir settings, include them in the userConfig input.
9
9
  */
10
- export async function baseInitSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, sentryDep, executionEnv, isDev, silent, }) {
11
- const finalSentryConfig = await createSentryConfig(executionEnv, sentryDep, {
12
- dsn,
13
- environment: releaseEnv,
14
- release: releaseName,
15
- }, sentryConfigOverrides, {
16
- isDev,
17
- isSilent: !!silent,
10
+ export async function baseInitSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, sentryDep, executionEnv, isDev, silent, throttleOptions, }) {
11
+ const finalSentryConfig = await createSentryConfig({
12
+ executionEnv,
13
+ sentryDep,
14
+ requiredSentryOptions: {
15
+ dsn,
16
+ environment: releaseEnv,
17
+ release: releaseName,
18
+ },
19
+ userOverrides: sentryConfigOverrides,
20
+ flagParams: {
21
+ isDev,
22
+ isSilent: !!silent,
23
+ throttleOptions,
24
+ },
18
25
  });
19
26
  sentryDep.init(finalSentryConfig);
20
27
  sentryDep.addEventProcessor((event, hint) => processSentryEvent(event, hint, createUniversalContext));
@@ -1,13 +1,22 @@
1
+ import { type PartialWithUndefined } from '@augment-vir/common';
1
2
  import { type BrowserOptions } from '@sentry/browser';
2
3
  import { type Options } from '@sentry/core';
3
4
  import { type NodeOptions } from '@sentry/node';
4
5
  import { type SentryDepByEnv, SentryExecutionEnvEnum } from '../env/execution-env.js';
6
+ import { type ThrottleOptions } from '../processing/throttling.js';
5
7
  /** Optional UserOverrides of Sentry config values. */
6
8
  export type UserOverrides = Omit<Partial<Options>, keyof RequiredSentryOptions> | undefined;
7
9
  /** Sentry config options that are required. */
8
10
  export type RequiredSentryOptions = Pick<Required<Options>, 'dsn' | 'environment' | 'release'>;
9
11
  /** Creates the sentry config used internally by sentry-vir. */
10
- export declare function createSentryConfig<const ExecutionEnv extends SentryExecutionEnvEnum>(executionEnv: ExecutionEnv, sentryDep: SentryDepByEnv<ExecutionEnv>, requiredSentryOptions: RequiredSentryOptions, userOverrides: UserOverrides, flagParams: {
11
- isDev: boolean;
12
- isSilent: boolean;
12
+ export declare function createSentryConfig<const ExecutionEnv extends SentryExecutionEnvEnum>({ executionEnv, sentryDep, requiredSentryOptions, userOverrides, flagParams, }: {
13
+ executionEnv: ExecutionEnv;
14
+ sentryDep: SentryDepByEnv<ExecutionEnv>;
15
+ requiredSentryOptions: RequiredSentryOptions;
16
+ userOverrides: UserOverrides;
17
+ flagParams: {
18
+ isDev: boolean;
19
+ isSilent: boolean;
20
+ throttleOptions: Readonly<PartialWithUndefined<ThrottleOptions>> | undefined;
21
+ };
13
22
  }): Promise<BrowserOptions | NodeOptions>;
@@ -2,7 +2,7 @@ import { mergeDeep } from '@augment-vir/common';
2
2
  import { SentryExecutionEnvEnum, } from '../env/execution-env.js';
3
3
  import { createSentryHandler } from '../processing/handle-sentry-send.js';
4
4
  /** Creates the sentry config used internally by sentry-vir. */
5
- export function createSentryConfig(executionEnv, sentryDep, requiredSentryOptions, userOverrides, flagParams) {
5
+ export function createSentryConfig({ executionEnv, sentryDep, requiredSentryOptions, userOverrides, flagParams, }) {
6
6
  const sharedSentryConfig = {
7
7
  beforeSend: createSentryHandler(flagParams),
8
8
  beforeSendTransaction: createSentryHandler(flagParams),
package/dist/node.d.ts CHANGED
@@ -7,4 +7,4 @@ export type Sentry = SentryNodeDep;
7
7
  *
8
8
  * To override any default sentry-vir settings, include them in the userConfig input.
9
9
  */
10
- export declare function initSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, }: Omit<InitSentryInput, 'executionEnv'>): Promise<SentryNodeDep>;
10
+ export declare function initSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, silent, throttleOptions, }: Omit<InitSentryInput, 'executionEnv'>): Promise<SentryNodeDep>;
package/dist/node.js CHANGED
@@ -6,7 +6,7 @@ import { baseInitSentry } from './init-sentry/base-sentry-init.js';
6
6
  *
7
7
  * To override any default sentry-vir settings, include them in the userConfig input.
8
8
  */
9
- export async function initSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, }) {
9
+ export async function initSentry({ dsn, releaseEnv, releaseName, sentryConfigOverrides, createUniversalContext, isDev, silent, throttleOptions, }) {
10
10
  const sentryDep = await import('@sentry/node');
11
11
  await baseInitSentry({
12
12
  dsn,
@@ -17,6 +17,8 @@ export async function initSentry({ dsn, releaseEnv, releaseName, sentryConfigOve
17
17
  sentryDep,
18
18
  executionEnv: SentryExecutionEnvEnum.Node,
19
19
  isDev,
20
+ silent,
21
+ throttleOptions,
20
22
  });
21
23
  return sentryDep;
22
24
  }
@@ -13,4 +13,4 @@ export declare function extractOriginalMessage(
13
13
  /** Event from Sentry. */
14
14
  event: Pick<TransactionEvent | ErrorEvent, 'message'>,
15
15
  /** EventHint generated by Sentry. */
16
- hint: EventHint | undefined): string;
16
+ hint: Readonly<Pick<EventHint, 'originalException'>> | undefined): string;
@@ -1,9 +1,12 @@
1
+ import { type PartialWithUndefined } from '@augment-vir/common';
1
2
  import { type EventHint } from '@sentry/browser';
2
3
  import { type ErrorEvent, type TransactionEvent } from '@sentry/core';
4
+ import { type ThrottleOptions } from './throttling.js';
3
5
  /** Creates a handler for Sentry events based on the given env. */
4
- export declare function createSentryHandler<T extends TransactionEvent | ErrorEvent>({ isDev, isSilent, }: {
6
+ export declare function createSentryHandler<T extends TransactionEvent | ErrorEvent>({ isDev, isSilent, throttleOptions, }: {
5
7
  /** If in dev, events won't be sent to Sentry. They will only be logged in the console. */
6
8
  isDev: boolean;
7
9
  /** If silent, events won't even get logged to the console. */
8
10
  isSilent: boolean;
11
+ throttleOptions: Readonly<PartialWithUndefined<ThrottleOptions>> | undefined;
9
12
  }): (event: T, hint: EventHint) => T | null;
@@ -1,12 +1,16 @@
1
1
  import { LoggingState, logToConsoleFromSentry } from './log-to-console.js';
2
+ import { shouldThrottleEvent } from './throttling.js';
2
3
  /** Creates a handler for Sentry events based on the given env. */
3
- export function createSentryHandler({ isDev, isSilent, }) {
4
+ export function createSentryHandler({ isDev, isSilent, throttleOptions, }) {
4
5
  /** The actual function that gets called when handling Sentry events. */
5
6
  function handleSentrySend(
6
7
  /** The event from Sentry. */
7
8
  event,
8
9
  /** The EventHint generated by Sentry. */
9
10
  hint) {
11
+ if (shouldThrottleEvent(event, hint, throttleOptions)) {
12
+ return null;
13
+ }
10
14
  if (!event.extra?.wasSentPrematurely) {
11
15
  logToConsoleFromSentry(event, hint, isDev ? LoggingState.Dev : LoggingState.Prod, isSilent);
12
16
  }
@@ -0,0 +1,57 @@
1
+ import { type PartialWithUndefined } from '@augment-vir/common';
2
+ import { type ErrorEvent, type EventHint, type TransactionEvent } from '@sentry/core';
3
+ import { type AnyDuration, type FullDate, type UtcTimezone } from 'date-vir';
4
+ /**
5
+ * Type for entries in {@link throttleCache}.
6
+ *
7
+ * @category Internal
8
+ */
9
+ export type ThrottleCacheEntry = {
10
+ intervalCount: number;
11
+ intervalStartAt: FullDate<UtcTimezone>;
12
+ throttleStartedAt: FullDate<UtcTimezone> | undefined;
13
+ };
14
+ /**
15
+ * The current throttle cache.
16
+ *
17
+ * @category Internal
18
+ */
19
+ export declare const throttleCache: Record<string, ThrottleCacheEntry>;
20
+ /**
21
+ * Throttling options.
22
+ *
23
+ * @category Internal
24
+ */
25
+ export type ThrottleOptions = {
26
+ disableThrottling: boolean;
27
+ /**
28
+ * When throttling begins, this determines how much time must pass before the error will be
29
+ * logged again.
30
+ */
31
+ thresholdInterval: AnyDuration;
32
+ /**
33
+ * In order for throttling to turn off, the throttle threshold must have not been hit for this
34
+ * entire duration.
35
+ */
36
+ throttleCooldown: AnyDuration;
37
+ /** Enable a sentry log that indicates that an error is being throttled. */
38
+ disableThrottleLog: boolean;
39
+ /** If an error is logged this many times within `logInterval`, it starts getting throttled. */
40
+ throttleThreshold: number;
41
+ };
42
+ /**
43
+ * Default values for {@link ThrottleOptions}.
44
+ *
45
+ * @category Internal
46
+ */
47
+ export declare const defaultThrottleOptions: ThrottleOptions;
48
+ /**
49
+ * Determines if an event should be throttled based on previous event counts.
50
+ *
51
+ * @category Internal
52
+ */
53
+ export declare function shouldThrottleEvent(
54
+ /** Event from Sentry. */
55
+ event: Pick<TransactionEvent | ErrorEvent, 'message'>,
56
+ /** EventHint generated by Sentry. */
57
+ hint?: Readonly<Pick<EventHint, 'originalException'>> | undefined, userOptions?: Readonly<PartialWithUndefined<ThrottleOptions>>): boolean;
@@ -0,0 +1,82 @@
1
+ import { getOrSet, mergeDefinedProperties } from '@augment-vir/common';
2
+ import { calculateRelativeDate, getNowInUtcTimezone, isDateAfter, } from 'date-vir';
3
+ import { sendLog } from '../logging/send-log.js';
4
+ import { extractOriginalMessage } from './event-processor.js';
5
+ /**
6
+ * The current throttle cache.
7
+ *
8
+ * @category Internal
9
+ */
10
+ export const throttleCache = {};
11
+ /**
12
+ * Default values for {@link ThrottleOptions}.
13
+ *
14
+ * @category Internal
15
+ */
16
+ export const defaultThrottleOptions = {
17
+ disableThrottling: false,
18
+ thresholdInterval: { hours: 1 },
19
+ disableThrottleLog: false,
20
+ throttleCooldown: { days: 1 },
21
+ throttleThreshold: 50,
22
+ };
23
+ /**
24
+ * Determines if an event should be throttled based on previous event counts.
25
+ *
26
+ * @category Internal
27
+ */
28
+ export function shouldThrottleEvent(
29
+ /** Event from Sentry. */
30
+ event,
31
+ /** EventHint generated by Sentry. */
32
+ hint = undefined, userOptions = defaultThrottleOptions) {
33
+ const options = mergeDefinedProperties(defaultThrottleOptions, userOptions);
34
+ if (options.disableThrottling) {
35
+ return false;
36
+ }
37
+ const errorKey = extractOriginalMessage(event, hint);
38
+ const now = getNowInUtcTimezone();
39
+ const errorThrottleData = getOrSet(throttleCache, errorKey, () => {
40
+ return {
41
+ intervalCount: 0,
42
+ intervalStartAt: now,
43
+ throttleStartedAt: undefined,
44
+ };
45
+ });
46
+ errorThrottleData.intervalCount++;
47
+ const thresholdSurpassed = errorThrottleData.intervalCount > options.throttleThreshold;
48
+ if (thresholdSurpassed && !errorThrottleData.throttleStartedAt) {
49
+ errorThrottleData.throttleStartedAt = now;
50
+ if (options.disableThrottleLog) {
51
+ sendLog.warning(`Error throttled: ${errorKey}`);
52
+ }
53
+ }
54
+ const intervalNeedsRestart = isDateAfter({
55
+ fullDate: now,
56
+ relativeTo: calculateRelativeDate(errorThrottleData.intervalStartAt, options.thresholdInterval),
57
+ });
58
+ if (intervalNeedsRestart) {
59
+ errorThrottleData.intervalStartAt = now;
60
+ if (thresholdSurpassed) {
61
+ /**
62
+ * If an interval surpassed the threshold, always bump the threshold started at up so
63
+ * the cooldown requires all intervals to be below the threshold.
64
+ */
65
+ errorThrottleData.throttleStartedAt = now;
66
+ if (options.disableThrottleLog) {
67
+ sendLog.warning(`Error throttled: ${errorKey}`);
68
+ }
69
+ }
70
+ errorThrottleData.intervalCount = 0;
71
+ }
72
+ if (errorThrottleData.throttleStartedAt) {
73
+ const shouldStopThrottle = isDateAfter({
74
+ fullDate: now,
75
+ relativeTo: calculateRelativeDate(errorThrottleData.throttleStartedAt, options.throttleCooldown),
76
+ });
77
+ if (shouldStopThrottle && !thresholdSurpassed) {
78
+ errorThrottleData.throttleStartedAt = undefined;
79
+ }
80
+ }
81
+ return !!errorThrottleData.throttleStartedAt;
82
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sentry-vir",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "description": "Easily use Sentry.",
5
5
  "keywords": [
6
6
  "config",
@@ -35,7 +35,7 @@
35
35
  "publish": "virmator publish npm run test:all",
36
36
  "start": "virmator frontend",
37
37
  "test": "virmator test web",
38
- "test:all": "npm run compile && concurrently --colors --kill-others-on-fail -c auto --names tests,spelling,format,docs,deps,lint \"npm run test\" \"npm run test:spelling\" \"npm run test:format\" \"npm run test:docs\" \"npm run test:deps\" \"npm run test:lint\"",
38
+ "test:all": "npm run compile && runstorm --names tests,spelling,format,docs,deps,lint \"npm run test\" \"npm run test:spelling\" \"npm run test:format\" \"npm run test:docs\" \"npm run test:deps\" \"npm run test:lint\"",
39
39
  "test:deps": "virmator deps check",
40
40
  "test:docs": "virmator docs check",
41
41
  "test:format": "virmator format check",
@@ -44,53 +44,55 @@
44
44
  "test:update": "npm test update"
45
45
  },
46
46
  "dependencies": {
47
- "@augment-vir/assert": "^31.32.2",
48
- "@augment-vir/common": "^31.32.2",
49
- "@sentry/browser": "^10.5.0",
50
- "@sentry/core": "^10.5.0",
51
- "@sentry/node": "^10.5.0",
52
- "type-fest": "^4.41.0"
47
+ "@augment-vir/assert": "^31.38.0",
48
+ "@augment-vir/common": "^31.38.0",
49
+ "@sentry/browser": "^10.14.0",
50
+ "@sentry/core": "^10.14.0",
51
+ "@sentry/node": "^10.14.0",
52
+ "date-vir": "^7.4.2",
53
+ "type-fest": "^5.0.1"
53
54
  },
54
55
  "devDependencies": {
55
- "@augment-vir/test": "^31.32.2",
56
+ "@augment-vir/test": "^31.38.0",
56
57
  "@eslint/eslintrc": "^3.3.1",
57
- "@eslint/js": "^9.33.0",
58
- "@stylistic/eslint-plugin": "^5.2.3",
58
+ "@eslint/js": "^9.36.0",
59
+ "@stylistic/eslint-plugin": "^5.4.0",
59
60
  "@stylistic/eslint-plugin-ts": "^4.4.1",
60
- "@typescript-eslint/eslint-plugin": "^8.39.1",
61
+ "@typescript-eslint/eslint-plugin": "^8.44.1",
61
62
  "@web/dev-server-esbuild": "^1.0.4",
62
63
  "@web/test-runner": "^0.20.2",
63
64
  "@web/test-runner-commands": "^0.9.0",
64
65
  "@web/test-runner-playwright": "^0.11.1",
65
66
  "@web/test-runner-visual-regression": "^0.10.0",
66
- "cspell": "^9.2.0",
67
+ "cspell": "^9.2.1",
67
68
  "dependency-cruiser": "^17.0.1",
68
- "esbuild": "^0.25.9",
69
- "eslint": "^9.33.0",
69
+ "esbuild": "^0.25.10",
70
+ "eslint": "^9.36.0",
70
71
  "eslint-config-prettier": "^10.1.8",
71
- "eslint-plugin-jsdoc": "^54.1.0",
72
+ "eslint-plugin-jsdoc": "^60.2.0",
72
73
  "eslint-plugin-monorepo-cop": "^1.0.2",
73
74
  "eslint-plugin-playwright": "^2.2.2",
74
75
  "eslint-plugin-prettier": "^5.5.4",
75
76
  "eslint-plugin-require-extensions": "^0.1.3",
76
- "eslint-plugin-sonarjs": "^3.0.4",
77
+ "eslint-plugin-sonarjs": "^3.0.5",
77
78
  "eslint-plugin-unicorn": "^57.0.0",
78
79
  "istanbul-smart-text-reporter": "^1.1.5",
79
80
  "markdown-code-example-inserter": "^3.0.3",
80
- "npm-check-updates": "^18.0.2",
81
+ "npm-check-updates": "^18.3.0",
81
82
  "prettier": "~3.3.3",
82
83
  "prettier-plugin-interpolated-html-tags": "^2.0.1",
83
84
  "prettier-plugin-jsdoc": "^1.3.3",
84
85
  "prettier-plugin-multiline-arrays": "^4.0.3",
85
- "prettier-plugin-organize-imports": "^4.2.0",
86
+ "prettier-plugin-organize-imports": "^4.3.0",
86
87
  "prettier-plugin-packagejson": "^2.5.19",
87
88
  "prettier-plugin-sort-json": "^4.1.1",
88
89
  "prettier-plugin-toml": "^2.0.6",
89
- "typedoc": "^0.28.10",
90
+ "runstorm": "^0.6.2",
91
+ "typedoc": "^0.28.13",
90
92
  "typescript": "^5.9.2",
91
- "typescript-eslint": "^8.39.1",
92
- "virmator": "^13.16.2",
93
- "vite": "^7.1.2"
93
+ "typescript-eslint": "^8.44.1",
94
+ "virmator": "^14.0.4",
95
+ "vite": "^7.1.7"
94
96
  },
95
97
  "engines": {
96
98
  "node": ">=22"