@lokalise/fastify-extras 29.0.1 → 30.1.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/README.md CHANGED
@@ -7,6 +7,8 @@ Reusable plugins for Fastify.
7
7
 
8
8
  - [RequestContext Provider Plugin](#requestcontext-provider-plugin)
9
9
  - [Public Healthcheck Plugin](#public-healthcheck-plugin)
10
+ - [Common Healthcheck Plugin](#common-healthcheck-plugin)
11
+ - [Common Sync Healthcheck Plugin](#common-sync-healthcheck-plugin)
10
12
  - [Split IO Plugin](#split-io-plugin)
11
13
  - [BugSnag Plugin](#bugsnag-plugin)
12
14
  - [Metrics Plugin](#metrics-plugin)
@@ -72,7 +74,7 @@ Your Fastify app will reply with the status of the app when hitting the `GET /`
72
74
 
73
75
  ### Common Healthcheck Plugin
74
76
 
75
- Plugin to monitor app status through public and private healthchecks.
77
+ Plugin to monitor app status through public and private healthchecks using asynchronous checks.
76
78
 
77
79
  Add the plugin to your Fastify instance by registering it with the following options:
78
80
 
@@ -89,8 +91,6 @@ Your Fastify app will reply with the status of the app when hitting the `GET /`
89
91
  }
90
92
  ```
91
93
 
92
-
93
-
94
94
  Your Fastify app will reply with the status of the app when hitting the `GET /health` private route with detailed results from healthchecks provided, example:
95
95
  ```json
96
96
  {
@@ -103,6 +103,55 @@ Your Fastify app will reply with the status of the app when hitting the `GET /he
103
103
  }
104
104
  ```
105
105
 
106
+ ### Common Sync Healthcheck Plugin
107
+
108
+ Plugin to monitor app status through public and private healthchecks using synchronous checks. **This plugin is recommended when you have healthchecks that run synchronously or are executed in the background**, as it provides better performance for such use cases.
109
+
110
+ Add the plugin to your Fastify instance by registering it with the following options:
111
+
112
+ - `healthChecks`, an array of synchronous healthcheck objects, each containing:
113
+ - `name`, the identifier for the healthcheck;
114
+ - `isMandatory`, boolean indicating if this healthcheck is critical for service health;
115
+ - `checker`, a synchronous function that returns `null` on success or an `Error` on failure;
116
+ - `responsePayload` (optional), the response payload that the healthcheck should return;
117
+ - `logLevel` (optional), the log level for the healthcheck routes ('fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent'), defaults to 'info';
118
+ - `infoProviders` (optional), an array of info providers to include additional metadata in the `/health` response;
119
+ - `isRootRouteEnabled` (optional), whether to enable the public `/` route, defaults to `true`.
120
+
121
+ Example usage:
122
+ ```typescript
123
+ import { commonSyncHealthcheckPlugin } from '@lokalise/fastify-extras'
124
+
125
+ app.register(commonSyncHealthcheckPlugin, {
126
+ healthChecks: [
127
+ {
128
+ name: 'database',
129
+ isMandatory: true,
130
+ checker: (app) => {
131
+ // Synchronous check - returns null if healthy, Error if not
132
+ return isDatabaseConnected() ? null : new Error('Database disconnected')
133
+ }
134
+ },
135
+ {
136
+ name: 'cache',
137
+ isMandatory: false, // Optional dependency
138
+ checker: (app) => {
139
+ return isCacheAvailable() ? null : new Error('Cache unavailable')
140
+ }
141
+ }
142
+ ]
143
+ })
144
+ ```
145
+
146
+ The plugin exposes the same routes as the async Common Healthcheck Plugin:
147
+ - `GET /` - Public route returning aggregated health status
148
+ - `GET /health` - Private route with detailed healthcheck results
149
+
150
+ The key differences from the async version:
151
+ - Uses synchronous healthcheck functions instead of promises
152
+ - Better suited for checks that are already running in the background or are inherently synchronous
153
+ - Supports mandatory vs optional healthchecks (optional failures result in `PARTIALLY_HEALTHY` status)
154
+
106
155
  ### Split IO Plugin
107
156
 
108
157
  Plugin to handle feature flags in Split IO.
package/dist/index.d.ts CHANGED
@@ -18,9 +18,11 @@ export type { ErrorObjectResolver, MetricsPluginOptions, } from './plugins/metri
18
18
  export { publicHealthcheckPlugin } from './plugins/healthcheck/publicHealthcheckPlugin.js';
19
19
  export type { PublicHealthcheckPluginOptions, HealthCheck, InfoProvider, } from './plugins/healthcheck/publicHealthcheckPlugin.js';
20
20
  export { wrapHealthCheck } from './plugins/healthcheck/healthcheckCommons.js';
21
- export type { HealthChecker } from './plugins/healthcheck/healthcheckCommons.js';
21
+ export type { HealthChecker, HealthCheckerSync } from './plugins/healthcheck/healthcheckCommons.js';
22
22
  export { commonHealthcheckPlugin } from './plugins/healthcheck/commonHealthcheckPlugin.js';
23
23
  export type { CommonHealthcheckPluginOptions } from './plugins/healthcheck/commonHealthcheckPlugin.js';
24
+ export { commonSyncHealthcheckPlugin } from './plugins/healthcheck/commonSyncHealthcheckPlugin.ts';
25
+ export type { CommonSyncHealthcheckPluginOptions } from './plugins/healthcheck/commonSyncHealthcheckPlugin.ts';
24
26
  export { amplitudePlugin, type AmplitudeConfig, type CreateApiTrackingEventFn, } from './plugins/amplitude/amplitudePlugin.js';
25
27
  export { Amplitude } from './plugins/amplitude/Amplitude.js';
26
28
  export { AmplitudeAdapter, AMPLITUDE_BASE_MESSAGE_SCHEMA, type AmplitudeMessage, type AmplitudeAdapterDependencies, } from './plugins/amplitude/AmplitudeAdapter.js';
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ export { metricsPlugin } from './plugins/metricsPlugin.js';
10
10
  export { publicHealthcheckPlugin } from './plugins/healthcheck/publicHealthcheckPlugin.js';
11
11
  export { wrapHealthCheck } from './plugins/healthcheck/healthcheckCommons.js';
12
12
  export { commonHealthcheckPlugin } from './plugins/healthcheck/commonHealthcheckPlugin.js';
13
+ export { commonSyncHealthcheckPlugin } from "./plugins/healthcheck/commonSyncHealthcheckPlugin.js";
13
14
  export { amplitudePlugin, } from './plugins/amplitude/amplitudePlugin.js';
14
15
  export { Amplitude } from './plugins/amplitude/Amplitude.js';
15
16
  export { AmplitudeAdapter, AMPLITUDE_BASE_MESSAGE_SCHEMA, } from './plugins/amplitude/AmplitudeAdapter.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,GACf,MAAM,4BAA4B,CAAA;AAGnC,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,2CAA2C,CAAA;AAGlD,OAAO,EACL,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,+CAA+C,CAAA;AAGtD,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,0CAA0C,CAAA;AAGjD,OAAO,EACL,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,mDAAmD,CAAA;AAO1D,OAAO,EAAE,mCAAmC,EAAE,MAAM,6DAA6D,CAAA;AAEjH,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAEtE,OAAO,EACL,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,+CAA+C,CAAA;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAM1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AAO1F,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAA;AAG7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AAG1F,OAAO,EACL,eAAe,GAGhB,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAC5D,OAAO,EACL,gBAAgB,EAChB,6BAA6B,GAG9B,MAAM,yCAAyC,CAAA;AAIhD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAA;AAEhF,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,uCAAuC,CAAA;AAG9C,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAA4B,MAAM,0BAA0B,CAAA;AAGnG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAE5E,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,GACf,MAAM,4BAA4B,CAAA;AAGnC,OAAO,EACL,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,2CAA2C,CAAA;AAGlD,OAAO,EACL,gCAAgC,EAChC,0BAA0B,GAC3B,MAAM,+CAA+C,CAAA;AAGtD,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,0CAA0C,CAAA;AAGjD,OAAO,EACL,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,mDAAmD,CAAA;AAO1D,OAAO,EAAE,mCAAmC,EAAE,MAAM,6DAA6D,CAAA;AAEjH,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAEtE,OAAO,EACL,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,+CAA+C,CAAA;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAM1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AAO1F,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAA;AAG7E,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AAG1F,OAAO,EAAE,2BAA2B,EAAE,MAAM,sDAAsD,CAAA;AAGlG,OAAO,EACL,eAAe,GAGhB,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAC5D,OAAO,EACL,gBAAgB,EAChB,6BAA6B,GAG9B,MAAM,yCAAyC,CAAA;AAIhD,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAA;AAEhF,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,uCAAuC,CAAA;AAG9C,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAA4B,MAAM,0BAA0B,CAAA;AAGnG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAE5E,OAAO,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAA"}
@@ -0,0 +1,19 @@
1
+ import type { FastifyPluginCallback } from 'fastify';
2
+ import type { HealthCheckerSync } from './healthcheckCommons.js';
3
+ export interface CommonSyncHealthcheckPluginOptions {
4
+ responsePayload?: Record<string, unknown>;
5
+ logLevel?: 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent';
6
+ healthChecks: readonly HealthCheckSync[];
7
+ infoProviders?: readonly InfoProvider[];
8
+ isRootRouteEnabled?: boolean;
9
+ }
10
+ export type InfoProvider = {
11
+ name: string;
12
+ dataResolver: () => Record<string, unknown>;
13
+ };
14
+ export type HealthCheckSync = {
15
+ name: string;
16
+ isMandatory: boolean;
17
+ checker: HealthCheckerSync;
18
+ };
19
+ export declare const commonSyncHealthcheckPlugin: FastifyPluginCallback<CommonSyncHealthcheckPluginOptions>;
@@ -0,0 +1,97 @@
1
+ import fp from 'fastify-plugin';
2
+ function resolveHealthcheckResults(results, opts) {
3
+ const healthChecks = {};
4
+ let isFullyHealthy = true;
5
+ let isPartiallyHealthy = false;
6
+ // Return detailed healthcheck results
7
+ for (let i = 0; i < results.length; i++) {
8
+ const entry = results[i];
9
+ if (!entry)
10
+ continue;
11
+ healthChecks[entry.name] = entry.healthcheckError ? 'FAIL' : 'HEALTHY';
12
+ if (entry.healthcheckError && opts.healthChecks[i]?.isMandatory) {
13
+ isFullyHealthy = false;
14
+ isPartiallyHealthy = false;
15
+ }
16
+ // Check if we are only partially healthy (only optional dependencies are failing)
17
+ if (isFullyHealthy && entry.healthcheckError && !opts.healthChecks[i]?.isMandatory) {
18
+ isFullyHealthy = false;
19
+ isPartiallyHealthy = true;
20
+ }
21
+ }
22
+ return {
23
+ isFullyHealthy,
24
+ isPartiallyHealthy,
25
+ healthChecks,
26
+ };
27
+ }
28
+ function addRoute(app, opts, routeOpts) {
29
+ const responsePayload = opts.responsePayload ?? {};
30
+ app.route({
31
+ url: routeOpts.url,
32
+ method: 'GET',
33
+ logLevel: opts.logLevel ?? 'info',
34
+ schema: {
35
+ // hide route from swagger plugins
36
+ hide: true,
37
+ },
38
+ handler: (_, reply) => {
39
+ let isFullyHealthy = true;
40
+ let isPartiallyHealthy = false;
41
+ let healthChecks = {};
42
+ if (opts.healthChecks.length) {
43
+ const results = opts.healthChecks.map((healthcheck) => {
44
+ const healthcheckError = healthcheck.checker(app);
45
+ if (healthcheckError) {
46
+ app.log.error(healthcheckError, `${healthcheck.name} healthcheck has failed`);
47
+ }
48
+ return {
49
+ name: healthcheck.name,
50
+ healthcheckError,
51
+ isMandatory: healthcheck.isMandatory,
52
+ };
53
+ });
54
+ const resolvedHealthcheckResponse = resolveHealthcheckResults(results, opts);
55
+ healthChecks = resolvedHealthcheckResponse.healthChecks;
56
+ isFullyHealthy = resolvedHealthcheckResponse.isFullyHealthy;
57
+ isPartiallyHealthy = resolvedHealthcheckResponse.isPartiallyHealthy;
58
+ }
59
+ const extraInfo = opts.infoProviders?.map((infoProvider) => ({
60
+ name: infoProvider.name,
61
+ value: infoProvider.dataResolver(),
62
+ }));
63
+ const heartbeat = isFullyHealthy
64
+ ? 'HEALTHY'
65
+ : isPartiallyHealthy
66
+ ? 'PARTIALLY_HEALTHY'
67
+ : 'FAIL';
68
+ const response = {
69
+ ...responsePayload,
70
+ heartbeat,
71
+ ...(routeOpts.isPublicRoute
72
+ ? {}
73
+ : { checks: healthChecks, ...(extraInfo && { extraInfo }) }),
74
+ };
75
+ return reply.status(isFullyHealthy || isPartiallyHealthy ? 200 : 500).send(response);
76
+ },
77
+ });
78
+ }
79
+ const plugin = (app, opts, done) => {
80
+ const isRootRouteEnabled = opts.isRootRouteEnabled ?? true;
81
+ if (isRootRouteEnabled) {
82
+ addRoute(app, opts, {
83
+ url: '/',
84
+ isPublicRoute: true,
85
+ });
86
+ }
87
+ addRoute(app, opts, {
88
+ url: '/health',
89
+ isPublicRoute: false,
90
+ });
91
+ done();
92
+ };
93
+ export const commonSyncHealthcheckPlugin = fp(plugin, {
94
+ fastify: '5.x',
95
+ name: 'common-sync-healthcheck-plugin',
96
+ });
97
+ //# sourceMappingURL=commonSyncHealthcheckPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commonSyncHealthcheckPlugin.js","sourceRoot":"","sources":["../../../lib/plugins/healthcheck/commonSyncHealthcheckPlugin.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,10 @@
1
1
  import type { Either } from '@lokalise/node-core';
2
2
  import type { AnyFastifyInstance } from '../pluginsCommon.js';
3
3
  export type HealthChecker = (app: AnyFastifyInstance) => Promise<Either<Error, true>>;
4
+ /**
5
+ * Returns error (if fail) or null (if pass)
6
+ */
7
+ export type HealthCheckerSync = (app: AnyFastifyInstance) => Error | null;
4
8
  /**
5
9
  * Return a function which executes healthcheck and throws an error if it fails
6
10
  */
@@ -1 +1 @@
1
- {"version":3,"file":"healthcheckCommons.js","sourceRoot":"","sources":["../../../lib/plugins/healthcheck/healthcheckCommons.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAuB,EAAE,WAA0B,EAAE,EAAE;IACrF,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,QAAQ,CAAC,KAAK,CAAA;QACtB,CAAC;IACH,CAAC,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"healthcheckCommons.js","sourceRoot":"","sources":["../../../lib/plugins/healthcheck/healthcheckCommons.ts"],"names":[],"mappings":"AAUA;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAuB,EAAE,WAA0B,EAAE,EAAE;IACrF,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAA;QACvC,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,QAAQ,CAAC,KAAK,CAAA;QACtB,CAAC;IACH,CAAC,CAAA;AACH,CAAC,CAAA"}
@@ -16,4 +16,7 @@ export type HealthCheck = {
16
16
  isMandatory: boolean;
17
17
  checker: HealthChecker;
18
18
  };
19
+ /**
20
+ * @deprecated use commonSyncHealthcheckPlugin instead
21
+ */
19
22
  export declare const publicHealthcheckPlugin: FastifyPluginCallback<PublicHealthcheckPluginOptions>;
@@ -61,6 +61,9 @@ function plugin(app, opts, done) {
61
61
  });
62
62
  done();
63
63
  }
64
+ /**
65
+ * @deprecated use commonSyncHealthcheckPlugin instead
66
+ */
64
67
  export const publicHealthcheckPlugin = fp(plugin, {
65
68
  fastify: '5.x',
66
69
  name: 'public-healthcheck-plugin',
@@ -1 +1 @@
1
- {"version":3,"file":"publicHealthcheckPlugin.js","sourceRoot":"","sources":["../../../lib/plugins/healthcheck/publicHealthcheckPlugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"publicHealthcheckPlugin.js","sourceRoot":"","sources":["../../../lib/plugins/healthcheck/publicHealthcheckPlugin.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lokalise/fastify-extras",
3
- "version": "29.0.1",
3
+ "version": "30.1.0",
4
4
  "description": "Opinionated set of fastify plugins, commonly used in Lokalise",
5
5
  "author": {
6
6
  "name": "Lokalise",
@@ -35,52 +35,52 @@
35
35
  "version": "auto-changelog -p && git add CHANGELOG.md && biome check --write package.json && git add package.json"
36
36
  },
37
37
  "dependencies": {
38
- "@amplitude/analytics-node": "^1.4.1",
38
+ "@amplitude/analytics-node": "^1.5.7",
39
39
  "@bugsnag/js": "^8.4.0",
40
40
  "@lokalise/error-utils": "^3.0.0",
41
41
  "@splitsoftware/splitio": "^11.4.1",
42
42
  "@supercharge/promise-pool": "^3.2.0",
43
43
  "fastify-metrics": "^12.1.0",
44
44
  "fastify-plugin": "^5.0.1",
45
- "fastify-type-provider-zod": "^5.0.2",
46
45
  "prom-client": "^15.1.3",
47
46
  "toad-cache": "^3.7.0"
48
47
  },
49
48
  "peerDependencies": {
50
49
  "@fastify/jwt": ">=9.1.0",
51
50
  "@lokalise/api-contracts": ">=5.0.0",
52
- "@lokalise/background-jobs-common": ">=8.0.0",
53
- "@lokalise/node-core": ">=13.3.0",
51
+ "@lokalise/background-jobs-common": ">=12.0.0",
52
+ "@lokalise/node-core": ">=14.0.0",
54
53
  "bullmq": "^5.19.0",
55
- "fastify": "^5.0.0",
56
- "ioredis": "^5.6.1",
54
+ "fastify": "^5.5.0",
55
+ "fastify-type-provider-zod": ">=6.0.0",
56
+ "ioredis": "^5.7.0",
57
57
  "newrelic": ">=11.13.0",
58
- "pino": "^9.7.0",
59
- "zod": ">=3.25.76"
58
+ "pino": "^9.9.0",
59
+ "zod": ">=4.1.5"
60
60
  },
61
61
  "devDependencies": {
62
- "@amplitude/analytics-types": "^2.9.2",
62
+ "@amplitude/analytics-types": "^2.10.0",
63
63
  "@biomejs/biome": "^1.9.4",
64
64
  "@lokalise/backend-http-client": "^7.0.0",
65
65
  "@lokalise/background-jobs-common": "^14.0.2",
66
66
  "@lokalise/biome-config": "^2.0.0",
67
- "@lokalise/node-core": "^14.1.0",
68
- "@lokalise/tsconfig": "^2.0.0",
67
+ "@lokalise/node-core": "^14.4.1",
68
+ "@lokalise/tsconfig": "^3.0.0",
69
69
  "@types/newrelic": "^9.14.8",
70
- "@types/node": "^22.16.5",
71
- "@vitest/coverage-v8": "^3.2.3",
70
+ "@types/node": "^22.18.0",
71
+ "@vitest/coverage-v8": "^3.2.4",
72
72
  "auto-changelog": "^2.4.0",
73
- "bullmq": "^5.56.5",
74
- "fastify": "^5.4.0",
75
- "fastify-type-provider-zod": "^5.0.1",
73
+ "bullmq": "^5.58.4",
74
+ "fastify": "^5.5.0",
75
+ "fastify-type-provider-zod": "^6.0.0",
76
76
  "ioredis": "^5.6.1",
77
- "newrelic": "13.2.1",
78
- "pino": "^9.7.0",
79
- "pino-pretty": "^13.0.0",
77
+ "newrelic": "13.3.2",
78
+ "pino": "^9.9.0",
79
+ "pino-pretty": "^13.1.1",
80
80
  "rimraf": "^6.0.1",
81
- "typescript": "^5.8.3",
82
- "vitest": "^3.2.3",
83
- "zod": "^4.0.5"
81
+ "typescript": "^5.9.2",
82
+ "vitest": "^3.2.4",
83
+ "zod": "^4.1.5"
84
84
  },
85
85
  "engines": {
86
86
  "node": ">=20"