@lokalise/fastify-extras 30.0.0 → 30.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.
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,9 +91,77 @@ Your Fastify app will reply with the status of the app when hitting the `GET /`
89
91
  }
90
92
  ```
91
93
 
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
+ ```json
96
+ {
97
+ "heartbeat": "PARTIALLY_HEALTHY",
98
+ "checks": {
99
+ "check1": "HEALTHY",
100
+ "check2": "HEALTHY",
101
+ "check3": "FAIL"
102
+ }
103
+ }
104
+ ```
92
105
 
106
+ ### Common Sync Healthcheck Plugin
93
107
 
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:
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
+
155
+ ### Startup Healthcheck Plugin
156
+
157
+ Plugin to monitor app startup status, doing potentially more expensive checks than what is reasonable through periodic healthchecks.
158
+
159
+ Add the plugin to your Fastify instance by registering it with the following options:
160
+
161
+ - `healthChecks`, a list of asynchronous healthchecks to run at the app startup;
162
+ - `resultsLogLevel`, at what log level to report healthcheck results - default is INFO;
163
+
164
+ This is the structure of the log:
95
165
  ```json
96
166
  {
97
167
  "heartbeat": "PARTIALLY_HEALTHY",
@@ -103,6 +173,14 @@ Your Fastify app will reply with the status of the app when hitting the `GET /he
103
173
  }
104
174
  ```
105
175
 
176
+ In case a non-optional healthcheck fails, an application startup will throw an error. In order to ensure that the error is thrown correctly, make sure to await the app startup:
177
+
178
+ ```ts
179
+ const app = fastify()
180
+ await app.register(startupHealthcheckPlugin, opts)
181
+ await app.ready()
182
+ ```
183
+
106
184
  ### Split IO Plugin
107
185
 
108
186
  Plugin to handle feature flags in Split IO.
package/dist/index.d.ts CHANGED
@@ -18,9 +18,13 @@ 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 { startupHealthcheckPlugin } from './plugins/healthcheck/startupHealthcheckPlugin.js';
25
+ export type { StartupHealthcheckPluginOptions } from './plugins/healthcheck/startupHealthcheckPlugin.js';
26
+ export { commonSyncHealthcheckPlugin } from './plugins/healthcheck/commonSyncHealthcheckPlugin.ts';
27
+ export type { CommonSyncHealthcheckPluginOptions } from './plugins/healthcheck/commonSyncHealthcheckPlugin.ts';
24
28
  export { amplitudePlugin, type AmplitudeConfig, type CreateApiTrackingEventFn, } from './plugins/amplitude/amplitudePlugin.js';
25
29
  export { Amplitude } from './plugins/amplitude/Amplitude.js';
26
30
  export { AmplitudeAdapter, AMPLITUDE_BASE_MESSAGE_SCHEMA, type AmplitudeMessage, type AmplitudeAdapterDependencies, } from './plugins/amplitude/AmplitudeAdapter.js';
package/dist/index.js CHANGED
@@ -10,6 +10,8 @@ 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 { startupHealthcheckPlugin } from './plugins/healthcheck/startupHealthcheckPlugin.js';
14
+ export { commonSyncHealthcheckPlugin } from "./plugins/healthcheck/commonSyncHealthcheckPlugin.js";
13
15
  export { amplitudePlugin, } from './plugins/amplitude/amplitudePlugin.js';
14
16
  export { Amplitude } from './plugins/amplitude/Amplitude.js';
15
17
  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,wBAAwB,EAAE,MAAM,mDAAmD,CAAA;AAG5F,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"}
@@ -1,3 +1,4 @@
1
+ import type { Either } from '@lokalise/node-core';
1
2
  import type { FastifyPluginCallback } from 'fastify';
2
3
  import type { HealthChecker } from './healthcheckCommons.js';
3
4
  export interface CommonHealthcheckPluginOptions {
@@ -7,6 +8,16 @@ export interface CommonHealthcheckPluginOptions {
7
8
  infoProviders?: readonly InfoProvider[];
8
9
  isRootRouteEnabled?: boolean;
9
10
  }
11
+ type HealthcheckResult = {
12
+ name: string;
13
+ isMandatory: boolean;
14
+ result: Either<Error, true>;
15
+ };
16
+ type ResolvedHealthcheckResponse = {
17
+ isFullyHealthy: boolean;
18
+ isPartiallyHealthy: boolean;
19
+ healthChecks: Record<string, string>;
20
+ };
10
21
  export type InfoProvider = {
11
22
  name: string;
12
23
  dataResolver: () => Record<string, unknown>;
@@ -16,4 +27,6 @@ export type HealthCheck = {
16
27
  isMandatory: boolean;
17
28
  checker: HealthChecker;
18
29
  };
30
+ export declare function resolveHealthcheckResults(results: HealthcheckResult[], opts: CommonHealthcheckPluginOptions): ResolvedHealthcheckResponse;
19
31
  export declare const commonHealthcheckPlugin: FastifyPluginCallback<CommonHealthcheckPluginOptions>;
32
+ export {};
@@ -1,5 +1,5 @@
1
1
  import fp from 'fastify-plugin';
2
- function resolveHealthcheckResults(results, opts) {
2
+ export function resolveHealthcheckResults(results, opts) {
3
3
  const healthChecks = {};
4
4
  let isFullyHealthy = true;
5
5
  let isPartiallyHealthy = false;
@@ -1 +1 @@
1
- {"version":3,"file":"commonHealthcheckPlugin.js","sourceRoot":"","sources":["../../../lib/plugins/healthcheck/commonHealthcheckPlugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commonHealthcheckPlugin.js","sourceRoot":"","sources":["../../../lib/plugins/healthcheck/commonHealthcheckPlugin.ts"],"names":[],"mappings":"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"}
@@ -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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"}
@@ -0,0 +1,7 @@
1
+ import type { FastifyPluginCallback } from 'fastify';
2
+ import { type HealthCheck } from './commonHealthcheckPlugin.js';
3
+ export interface StartupHealthcheckPluginOptions {
4
+ resultsLogLevel?: 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'silent';
5
+ healthChecks: readonly HealthCheck[];
6
+ }
7
+ export declare const startupHealthcheckPlugin: FastifyPluginCallback<StartupHealthcheckPluginOptions>;
@@ -0,0 +1,48 @@
1
+ import fp from 'fastify-plugin';
2
+ import { stdSerializers } from 'pino';
3
+ import { resolveHealthcheckResults } from './commonHealthcheckPlugin.js';
4
+ const plugin = (app, opts, done) => {
5
+ app.addHook('onReady', async () => {
6
+ let isFullyHealthy = true;
7
+ let isPartiallyHealthy = false;
8
+ let healthChecks = {};
9
+ const failedHealthchecks = [];
10
+ if (opts.healthChecks.length) {
11
+ const results = await Promise.all(opts.healthChecks.map(async (healthcheck) => {
12
+ const result = await healthcheck.checker(app);
13
+ if (result.error) {
14
+ app.log.error({
15
+ error: stdSerializers.err(result.error),
16
+ }, `${healthcheck.name} healthcheck has failed`);
17
+ }
18
+ if (result.error) {
19
+ failedHealthchecks.push(healthcheck.name);
20
+ }
21
+ return {
22
+ name: healthcheck.name,
23
+ result,
24
+ isMandatory: healthcheck.isMandatory,
25
+ };
26
+ }));
27
+ const resolvedHealthcheckResponse = resolveHealthcheckResults(results, opts);
28
+ healthChecks = resolvedHealthcheckResponse.healthChecks;
29
+ isFullyHealthy = resolvedHealthcheckResponse.isFullyHealthy;
30
+ isPartiallyHealthy = resolvedHealthcheckResponse.isPartiallyHealthy;
31
+ }
32
+ const heartbeat = isFullyHealthy ? 'HEALTHY' : isPartiallyHealthy ? 'PARTIALLY_HEALTHY' : 'FAIL';
33
+ const resultLog = {
34
+ heartbeat,
35
+ checks: healthChecks,
36
+ };
37
+ app.log[opts.resultsLogLevel ?? 'info'](resultLog, 'Healthcheck finished');
38
+ if (!isPartiallyHealthy && !isFullyHealthy) {
39
+ throw new Error(`Healthchecks failed: ${JSON.stringify(failedHealthchecks)}`);
40
+ }
41
+ });
42
+ done();
43
+ };
44
+ export const startupHealthcheckPlugin = fp(plugin, {
45
+ fastify: '5.x',
46
+ name: 'startup-healthcheck-plugin',
47
+ });
48
+ //# sourceMappingURL=startupHealthcheckPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startupHealthcheckPlugin.js","sourceRoot":"","sources":["../../../lib/plugins/healthcheck/startupHealthcheckPlugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AACrC,OAAO,EAAoB,yBAAyB,EAAE,MAAM,8BAA8B,CAAA;AAO1F,MAAM,MAAM,GAA2D,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IACzF,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;QAChC,IAAI,cAAc,GAAG,IAAI,CAAA;QACzB,IAAI,kBAAkB,GAAG,KAAK,CAAA;QAC9B,IAAI,YAAY,GAA2B,EAAE,CAAA;QAC7C,MAAM,kBAAkB,GAAa,EAAE,CAAA;QAEvC,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,EAAE;gBAC1C,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;gBAC7C,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;oBACjB,GAAG,CAAC,GAAG,CAAC,KAAK,CACX;wBACE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;qBACxC,EACD,GAAG,WAAW,CAAC,IAAI,yBAAyB,CAC7C,CAAA;gBACH,CAAC;gBACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;oBACjB,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;gBAC3C,CAAC;gBACD,OAAO;oBACL,IAAI,EAAE,WAAW,CAAC,IAAI;oBACtB,MAAM;oBACN,WAAW,EAAE,WAAW,CAAC,WAAW;iBACrC,CAAA;YACH,CAAC,CAAC,CACH,CAAA;YAED,MAAM,2BAA2B,GAAG,yBAAyB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;YAC5E,YAAY,GAAG,2BAA2B,CAAC,YAAY,CAAA;YACvD,cAAc,GAAG,2BAA2B,CAAC,cAAc,CAAA;YAC3D,kBAAkB,GAAG,2BAA2B,CAAC,kBAAkB,CAAA;QACrE,CAAC;QAED,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,MAAM,CAAA;QAEhG,MAAM,SAAS,GAAG;YAChB,SAAS;YACT,MAAM,EAAE,YAAY;SACrB,CAAA;QAED,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,MAAM,CAAC,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAA;QAE1E,IAAI,CAAC,kBAAkB,IAAI,CAAC,cAAc,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAA;QAC/E,CAAC;IACH,CAAC,CAAC,CAAA;IACF,IAAI,EAAE,CAAA;AACR,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC,MAAM,EAAE;IACjD,OAAO,EAAE,KAAK;IACd,IAAI,EAAE,4BAA4B;CACnC,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lokalise/fastify-extras",
3
- "version": "30.0.0",
3
+ "version": "30.2.0",
4
4
  "description": "Opinionated set of fastify plugins, commonly used in Lokalise",
5
5
  "author": {
6
6
  "name": "Lokalise",
@@ -65,7 +65,7 @@
65
65
  "@lokalise/background-jobs-common": "^14.0.2",
66
66
  "@lokalise/biome-config": "^2.0.0",
67
67
  "@lokalise/node-core": "^14.4.1",
68
- "@lokalise/tsconfig": "^2.0.0",
68
+ "@lokalise/tsconfig": "^3.0.0",
69
69
  "@types/newrelic": "^9.14.8",
70
70
  "@types/node": "^22.18.0",
71
71
  "@vitest/coverage-v8": "^3.2.4",
@@ -74,7 +74,7 @@
74
74
  "fastify": "^5.5.0",
75
75
  "fastify-type-provider-zod": "^6.0.0",
76
76
  "ioredis": "^5.6.1",
77
- "newrelic": "13.2.1",
77
+ "newrelic": "13.3.2",
78
78
  "pino": "^9.9.0",
79
79
  "pino-pretty": "^13.1.1",
80
80
  "rimraf": "^6.0.1",