@firebreak/vitals 2.0.0 → 2.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 +96 -51
- package/dist/{handler-TZOgZvY7.d.cts → handler-C3eTDuSQ.d.cts} +1 -0
- package/dist/{handler-BvjN4Ot9.d.ts → handler-DaFJivGK.d.ts} +1 -0
- package/dist/index.cjs +7 -5
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +7 -5
- package/dist/integrations/express.cjs +7 -5
- package/dist/integrations/express.d.cts +1 -1
- package/dist/integrations/express.d.ts +1 -1
- package/dist/integrations/express.mjs +7 -5
- package/dist/integrations/next.cjs +7 -5
- package/dist/integrations/next.d.cts +1 -1
- package/dist/integrations/next.d.ts +1 -1
- package/dist/integrations/next.mjs +7 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vitals (Node.js)
|
|
2
2
|
|
|
3
|
-
Structured healthcheck endpoints for Node.js services with shallow and deep response tiers. Register health checks, run them concurrently with timeouts, and expose them via Express or Next.js.
|
|
3
|
+
Structured healthcheck endpoints for Node.js services with shallow and deep response tiers. Register health checks, run them concurrently with timeouts, and expose them via Express or Next.js. A configurable depth policy controls whether callers get a lightweight "alive" response or full diagnostic results.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@ npm install express # for Express integration
|
|
|
19
19
|
## Quick Start (Express)
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
|
-
import { HealthcheckRegistry } from '@firebreak/vitals';
|
|
22
|
+
import { HealthcheckRegistry, extractToken, verifyToken } from '@firebreak/vitals';
|
|
23
23
|
import { createHealthcheckMiddleware } from '@firebreak/vitals/express';
|
|
24
24
|
import { pgPoolCheck } from '@firebreak/vitals/checks/postgres';
|
|
25
25
|
import { ioredisClientCheck } from '@firebreak/vitals/checks/redis';
|
|
@@ -35,7 +35,14 @@ registry.add('api', httpCheck('https://api.example.com/health'));
|
|
|
35
35
|
const app = express();
|
|
36
36
|
app.get('/vitals', createHealthcheckMiddleware({
|
|
37
37
|
registry,
|
|
38
|
-
|
|
38
|
+
resolveDepth: (req) => {
|
|
39
|
+
const token = extractToken({
|
|
40
|
+
queryParams: req.queryParams as Record<string, string>,
|
|
41
|
+
authorizationHeader: req.authorizationHeader as string | null,
|
|
42
|
+
});
|
|
43
|
+
if (token && verifyToken(token, process.env.VITALS_TOKEN!)) return 'deep';
|
|
44
|
+
return 'shallow';
|
|
45
|
+
},
|
|
39
46
|
metadata: {
|
|
40
47
|
build: process.env.BUILD_SHA,
|
|
41
48
|
buildTimestamp: process.env.BUILD_TIMESTAMP,
|
|
@@ -43,19 +50,19 @@ app.get('/vitals', createHealthcheckMiddleware({
|
|
|
43
50
|
}));
|
|
44
51
|
```
|
|
45
52
|
|
|
46
|
-
Hit `/vitals` without a token to get a shallow response:
|
|
53
|
+
Hit `/vitals` without a valid token to get a shallow response:
|
|
47
54
|
|
|
48
55
|
```json
|
|
49
56
|
{ "status": "ok", "timestamp": "...", "build": "stg-45d76e5", "buildTimestamp": "2025-02-25T19:41:56Z" }
|
|
50
57
|
```
|
|
51
58
|
|
|
52
|
-
|
|
59
|
+
When `resolveDepth` returns `'deep'`, the full deep response with check results is returned.
|
|
53
60
|
|
|
54
61
|
## Quick Start (Next.js)
|
|
55
62
|
|
|
56
63
|
```typescript
|
|
57
64
|
// app/vitals/route.ts
|
|
58
|
-
import { HealthcheckRegistry } from '@firebreak/vitals';
|
|
65
|
+
import { HealthcheckRegistry, extractToken, verifyToken } from '@firebreak/vitals';
|
|
59
66
|
import { createNextHandler } from '@firebreak/vitals/next';
|
|
60
67
|
import { pgClientCheck } from '@firebreak/vitals/checks/postgres';
|
|
61
68
|
import { httpCheck } from '@firebreak/vitals/checks/http';
|
|
@@ -69,7 +76,14 @@ registry.add('api', httpCheck(`${process.env.API_BASE_URL}/health`));
|
|
|
69
76
|
|
|
70
77
|
export const GET = createNextHandler({
|
|
71
78
|
registry,
|
|
72
|
-
|
|
79
|
+
resolveDepth: (req) => {
|
|
80
|
+
const token = extractToken({
|
|
81
|
+
queryParams: req.queryParams as Record<string, string>,
|
|
82
|
+
authorizationHeader: req.authorizationHeader as string | null,
|
|
83
|
+
});
|
|
84
|
+
if (token && verifyToken(token, process.env.VITALS_TOKEN!)) return 'deep';
|
|
85
|
+
return 'shallow';
|
|
86
|
+
},
|
|
73
87
|
metadata: {
|
|
74
88
|
build: process.env.BUILD_SHA,
|
|
75
89
|
},
|
|
@@ -207,8 +221,14 @@ import { createHealthcheckMiddleware } from '@firebreak/vitals/express';
|
|
|
207
221
|
|
|
208
222
|
app.get('/vitals', createHealthcheckMiddleware({
|
|
209
223
|
registry,
|
|
210
|
-
|
|
211
|
-
|
|
224
|
+
resolveDepth: (req) => { // optional — omit for always-shallow
|
|
225
|
+
const token = extractToken({
|
|
226
|
+
queryParams: req.queryParams as Record<string, string>,
|
|
227
|
+
authorizationHeader: req.authorizationHeader as string | null,
|
|
228
|
+
});
|
|
229
|
+
if (token && verifyToken(token, 'my-secret-token')) return 'deep';
|
|
230
|
+
return 'shallow';
|
|
231
|
+
},
|
|
212
232
|
metadata: { // optional — included in shallow & deep responses
|
|
213
233
|
build: 'stg-45d76e5',
|
|
214
234
|
},
|
|
@@ -222,7 +242,14 @@ import { createNextHandler } from '@firebreak/vitals/next';
|
|
|
222
242
|
|
|
223
243
|
export const GET = createNextHandler({
|
|
224
244
|
registry,
|
|
225
|
-
|
|
245
|
+
resolveDepth: (req) => {
|
|
246
|
+
const token = extractToken({
|
|
247
|
+
queryParams: req.queryParams as Record<string, string>,
|
|
248
|
+
authorizationHeader: req.authorizationHeader as string | null,
|
|
249
|
+
});
|
|
250
|
+
if (token && verifyToken(token, process.env.VITALS_TOKEN!)) return 'deep';
|
|
251
|
+
return 'shallow';
|
|
252
|
+
},
|
|
226
253
|
metadata: { build: process.env.BUILD_SHA },
|
|
227
254
|
});
|
|
228
255
|
```
|
|
@@ -232,101 +259,120 @@ export const GET = createNextHandler({
|
|
|
232
259
|
For other frameworks, use the generic handler directly:
|
|
233
260
|
|
|
234
261
|
```typescript
|
|
235
|
-
import { createHealthcheckHandler } from '@firebreak/vitals';
|
|
262
|
+
import { createHealthcheckHandler, extractToken, verifyToken } from '@firebreak/vitals';
|
|
236
263
|
|
|
237
264
|
const handle = createHealthcheckHandler({
|
|
238
265
|
registry,
|
|
239
|
-
|
|
266
|
+
resolveDepth: (req) => {
|
|
267
|
+
const token = extractToken({
|
|
268
|
+
queryParams: req.queryParams as Record<string, string>,
|
|
269
|
+
authorizationHeader: req.authorizationHeader as string | null,
|
|
270
|
+
});
|
|
271
|
+
if (token && verifyToken(token, process.env.VITALS_TOKEN!)) return 'deep';
|
|
272
|
+
return 'shallow';
|
|
273
|
+
},
|
|
240
274
|
metadata: { build: 'stg-45d76e5' },
|
|
241
275
|
});
|
|
242
276
|
|
|
243
|
-
//
|
|
277
|
+
// resolveDepth returns 'shallow' → shallow response
|
|
244
278
|
const shallow = await handle({});
|
|
245
279
|
// { status: 200, body: { status: 'ok', timestamp: '...', build: 'stg-45d76e5' } }
|
|
246
280
|
|
|
247
|
-
//
|
|
281
|
+
// resolveDepth returns 'deep' → deep response
|
|
248
282
|
const deep = await handle({ queryParams: { token: '...' } });
|
|
249
283
|
// { status: 200, body: { status: 'healthy', timestamp: '...', build: 'stg-45d76e5', checks: { ... } } }
|
|
250
284
|
```
|
|
251
285
|
|
|
252
286
|
### Shallow / Deep Responses
|
|
253
287
|
|
|
254
|
-
|
|
288
|
+
The endpoint serves two tiers from a single route, controlled by the `resolveDepth` option:
|
|
255
289
|
|
|
256
|
-
|
|
|
257
|
-
|
|
258
|
-
|
|
|
259
|
-
|
|
|
260
|
-
| Invalid token provided | `403 Forbidden` |
|
|
261
|
-
| No token configured | **Shallow** by default (see `deep` option below) |
|
|
290
|
+
| `resolveDepth` returns | Response |
|
|
291
|
+
|------------------------|----------|
|
|
292
|
+
| `'shallow'` (or omitted) | **Shallow** — `200` with `{ status: "ok", timestamp, ...metadata }` |
|
|
293
|
+
| `'deep'` | **Deep** — `200`/`503` with full check results + metadata |
|
|
262
294
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
#### The `deep` Option
|
|
295
|
+
When `resolveDepth` is not provided, the handler always returns a shallow response.
|
|
266
296
|
|
|
267
|
-
|
|
297
|
+
The `resolveDepth` function receives the request object (`{ ip, headers, queryParams, authorizationHeader }`) and returns `'deep'` or `'shallow'` (or a promise of either). This lets you implement any depth policy — token-based, IP-based, header-based, or always-deep for internal services:
|
|
268
298
|
|
|
269
299
|
```typescript
|
|
300
|
+
// Always deep (internal service behind a private network)
|
|
270
301
|
createHealthcheckHandler({
|
|
271
302
|
registry,
|
|
272
|
-
|
|
303
|
+
resolveDepth: () => 'deep',
|
|
273
304
|
});
|
|
274
305
|
```
|
|
275
306
|
|
|
276
|
-
|
|
307
|
+
The shallow response lets load balancers and uptime monitors confirm the process is alive without needing a secret. The deep response is a superset of shallow — it includes everything shallow returns plus the `checks` object and a real health status.
|
|
277
308
|
|
|
278
|
-
|
|
309
|
+
### Metadata
|
|
279
310
|
|
|
280
|
-
|
|
311
|
+
Attach static key-value pairs that appear in both shallow and deep responses:
|
|
281
312
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
313
|
+
```typescript
|
|
314
|
+
createHealthcheckHandler({
|
|
315
|
+
registry,
|
|
316
|
+
metadata: {
|
|
317
|
+
build: 'stg-45d76e5',
|
|
318
|
+
buildTimestamp: '2025-02-25T19:41:56Z',
|
|
319
|
+
region: 'us-east-1',
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
```
|
|
288
323
|
|
|
289
|
-
|
|
324
|
+
Metadata values can be `string`, `number`, or `boolean`. Keys `status`, `timestamp`, `checks`, and `cachedAt` are reserved -- passing them throws at handler creation time.
|
|
290
325
|
|
|
291
|
-
|
|
326
|
+
#### `shallowMetadata`
|
|
327
|
+
|
|
328
|
+
By default, shallow responses include all `metadata` fields. Use `shallowMetadata` to override what appears in shallow responses while keeping `metadata` for deep responses:
|
|
292
329
|
|
|
293
330
|
```typescript
|
|
294
331
|
createHealthcheckHandler({
|
|
295
332
|
registry,
|
|
296
|
-
token: process.env.VITALS_TOKEN,
|
|
297
333
|
metadata: {
|
|
298
334
|
build: 'stg-45d76e5',
|
|
299
335
|
buildTimestamp: '2025-02-25T19:41:56Z',
|
|
300
336
|
region: 'us-east-1',
|
|
301
337
|
},
|
|
338
|
+
// Shallow responses only include status + timestamp (no build info)
|
|
339
|
+
shallowMetadata: {},
|
|
302
340
|
});
|
|
303
341
|
```
|
|
304
342
|
|
|
305
|
-
|
|
343
|
+
You can also include a subset of fields:
|
|
344
|
+
|
|
345
|
+
```typescript
|
|
346
|
+
createHealthcheckHandler({
|
|
347
|
+
registry,
|
|
348
|
+
metadata: { build: 'stg-45d76e5', region: 'us-east-1', version: '1.0.0' },
|
|
349
|
+
// Shallow responses include only version
|
|
350
|
+
shallowMetadata: { version: '1.0.0' },
|
|
351
|
+
});
|
|
352
|
+
```
|
|
306
353
|
|
|
307
|
-
|
|
354
|
+
When `shallowMetadata` is omitted, shallow responses fall back to using `metadata` (existing behavior).
|
|
308
355
|
|
|
309
|
-
|
|
310
|
-
- Query parameter: `?token=my-secret-token`
|
|
311
|
-
- Bearer header: `Authorization: Bearer my-secret-token`
|
|
356
|
+
### Utilities
|
|
312
357
|
|
|
313
|
-
|
|
358
|
+
`extractToken` and `verifyToken` are exported helpers for use inside your `resolveDepth` function.
|
|
314
359
|
|
|
315
360
|
```typescript
|
|
316
361
|
import { verifyToken, extractToken } from '@firebreak/vitals';
|
|
317
362
|
|
|
318
|
-
|
|
319
|
-
|
|
363
|
+
// Extract a token from query params (?token=...) or Authorization header
|
|
320
364
|
const token = extractToken({
|
|
321
365
|
queryParams: { token: 'abc' },
|
|
322
366
|
authorizationHeader: 'Bearer abc',
|
|
323
|
-
queryParamName: 'token',
|
|
324
367
|
});
|
|
368
|
+
|
|
369
|
+
// Timing-safe SHA-256 comparison
|
|
370
|
+
verifyToken('provided-token', 'expected-token'); // boolean
|
|
325
371
|
```
|
|
326
372
|
|
|
327
373
|
## Response Format
|
|
328
374
|
|
|
329
|
-
**Shallow response** (
|
|
375
|
+
**Shallow response** (`resolveDepth` returns `'shallow'` or is omitted):
|
|
330
376
|
|
|
331
377
|
```json
|
|
332
378
|
{
|
|
@@ -337,7 +383,7 @@ const token = extractToken({
|
|
|
337
383
|
}
|
|
338
384
|
```
|
|
339
385
|
|
|
340
|
-
**Deep response** (
|
|
386
|
+
**Deep response** (`resolveDepth` returns `'deep'`):
|
|
341
387
|
|
|
342
388
|
```json
|
|
343
389
|
{
|
|
@@ -362,11 +408,10 @@ const token = extractToken({
|
|
|
362
408
|
|
|
363
409
|
| Condition | HTTP Code | Status |
|
|
364
410
|
|-----------|-----------|--------|
|
|
365
|
-
| Shallow
|
|
411
|
+
| Shallow | `200` | `"ok"` |
|
|
366
412
|
| Deep — healthy | `200` | `"healthy"` |
|
|
367
413
|
| Deep — degraded | `503` | `"degraded"` |
|
|
368
414
|
| Deep — outage | `503` | `"outage"` |
|
|
369
|
-
| Invalid token | `403` | — |
|
|
370
415
|
|
|
371
416
|
## Requirements
|
|
372
417
|
|
|
@@ -5,6 +5,7 @@ interface HealthcheckHandlerOptions {
|
|
|
5
5
|
registry: HealthcheckRegistry;
|
|
6
6
|
resolveDepth?: ResolveDepthFn;
|
|
7
7
|
metadata?: Record<string, string | number | boolean>;
|
|
8
|
+
shallowMetadata?: Record<string, string | number | boolean>;
|
|
8
9
|
}
|
|
9
10
|
interface ShallowResponseJson {
|
|
10
11
|
status: 'ok';
|
|
@@ -5,6 +5,7 @@ interface HealthcheckHandlerOptions {
|
|
|
5
5
|
registry: HealthcheckRegistry;
|
|
6
6
|
resolveDepth?: ResolveDepthFn;
|
|
7
7
|
metadata?: Record<string, string | number | boolean>;
|
|
8
|
+
shallowMetadata?: Record<string, string | number | boolean>;
|
|
8
9
|
}
|
|
9
10
|
interface ShallowResponseJson {
|
|
10
11
|
status: 'ok';
|
package/dist/index.cjs
CHANGED
|
@@ -220,10 +220,12 @@ function extractToken(options) {
|
|
|
220
220
|
// src/handler.ts
|
|
221
221
|
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks", "cachedAt"];
|
|
222
222
|
function createHealthcheckHandler(options) {
|
|
223
|
-
const { registry, resolveDepth, metadata = {} } = options;
|
|
224
|
-
for (const
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
const { registry, resolveDepth, metadata = {}, shallowMetadata } = options;
|
|
224
|
+
for (const bag of [metadata, shallowMetadata ?? {}]) {
|
|
225
|
+
for (const key of Object.keys(bag)) {
|
|
226
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
227
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
228
|
+
}
|
|
227
229
|
}
|
|
228
230
|
}
|
|
229
231
|
return async (req) => {
|
|
@@ -247,7 +249,7 @@ function createHealthcheckHandler(options) {
|
|
|
247
249
|
const body = {
|
|
248
250
|
status: "ok",
|
|
249
251
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
250
|
-
...metadata
|
|
252
|
+
...shallowMetadata ?? metadata
|
|
251
253
|
};
|
|
252
254
|
return { status: 200, body };
|
|
253
255
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { H as HealthcheckResponseJson } from './core-Bee03bJm.cjs';
|
|
2
2
|
export { A as AsyncCheckFn, C as CheckInput, a as CheckResult, b as HealthcheckRegistry, c as HealthcheckResponse, S as Status, d as StatusLabel, e as StatusValue, f as SyncCheckFn, h as httpStatusCode, s as statusFromString, g as statusToLabel, i as syncCheck, t as toJson } from './core-Bee03bJm.cjs';
|
|
3
|
-
import { S as ShallowResponseJson } from './handler-
|
|
4
|
-
export { H as HealthcheckHandlerOptions, a as HealthcheckHandlerResult, R as ResolveDepthFn, c as createHealthcheckHandler } from './handler-
|
|
3
|
+
import { S as ShallowResponseJson } from './handler-C3eTDuSQ.cjs';
|
|
4
|
+
export { H as HealthcheckHandlerOptions, a as HealthcheckHandlerResult, R as ResolveDepthFn, c as createHealthcheckHandler } from './handler-C3eTDuSQ.cjs';
|
|
5
5
|
|
|
6
6
|
declare function verifyToken(provided: string, expected: string): boolean;
|
|
7
7
|
declare function extractToken(options: {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { H as HealthcheckResponseJson } from './core-Bee03bJm.js';
|
|
2
2
|
export { A as AsyncCheckFn, C as CheckInput, a as CheckResult, b as HealthcheckRegistry, c as HealthcheckResponse, S as Status, d as StatusLabel, e as StatusValue, f as SyncCheckFn, h as httpStatusCode, s as statusFromString, g as statusToLabel, i as syncCheck, t as toJson } from './core-Bee03bJm.js';
|
|
3
|
-
import { S as ShallowResponseJson } from './handler-
|
|
4
|
-
export { H as HealthcheckHandlerOptions, a as HealthcheckHandlerResult, R as ResolveDepthFn, c as createHealthcheckHandler } from './handler-
|
|
3
|
+
import { S as ShallowResponseJson } from './handler-DaFJivGK.js';
|
|
4
|
+
export { H as HealthcheckHandlerOptions, a as HealthcheckHandlerResult, R as ResolveDepthFn, c as createHealthcheckHandler } from './handler-DaFJivGK.js';
|
|
5
5
|
|
|
6
6
|
declare function verifyToken(provided: string, expected: string): boolean;
|
|
7
7
|
declare function extractToken(options: {
|
package/dist/index.mjs
CHANGED
|
@@ -184,10 +184,12 @@ function extractToken(options) {
|
|
|
184
184
|
// src/handler.ts
|
|
185
185
|
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks", "cachedAt"];
|
|
186
186
|
function createHealthcheckHandler(options) {
|
|
187
|
-
const { registry, resolveDepth, metadata = {} } = options;
|
|
188
|
-
for (const
|
|
189
|
-
|
|
190
|
-
|
|
187
|
+
const { registry, resolveDepth, metadata = {}, shallowMetadata } = options;
|
|
188
|
+
for (const bag of [metadata, shallowMetadata ?? {}]) {
|
|
189
|
+
for (const key of Object.keys(bag)) {
|
|
190
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
191
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
192
|
+
}
|
|
191
193
|
}
|
|
192
194
|
}
|
|
193
195
|
return async (req) => {
|
|
@@ -211,7 +213,7 @@ function createHealthcheckHandler(options) {
|
|
|
211
213
|
const body = {
|
|
212
214
|
status: "ok",
|
|
213
215
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
214
|
-
...metadata
|
|
216
|
+
...shallowMetadata ?? metadata
|
|
215
217
|
};
|
|
216
218
|
return { status: 200, body };
|
|
217
219
|
};
|
|
@@ -61,10 +61,12 @@ function httpStatusCode(status) {
|
|
|
61
61
|
// src/handler.ts
|
|
62
62
|
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks", "cachedAt"];
|
|
63
63
|
function createHealthcheckHandler(options) {
|
|
64
|
-
const { registry, resolveDepth, metadata = {} } = options;
|
|
65
|
-
for (const
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
const { registry, resolveDepth, metadata = {}, shallowMetadata } = options;
|
|
65
|
+
for (const bag of [metadata, shallowMetadata ?? {}]) {
|
|
66
|
+
for (const key of Object.keys(bag)) {
|
|
67
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
68
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
69
|
+
}
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
72
|
return async (req) => {
|
|
@@ -88,7 +90,7 @@ function createHealthcheckHandler(options) {
|
|
|
88
90
|
const body = {
|
|
89
91
|
status: "ok",
|
|
90
92
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
91
|
-
...metadata
|
|
93
|
+
...shallowMetadata ?? metadata
|
|
92
94
|
};
|
|
93
95
|
return { status: 200, body };
|
|
94
96
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import { H as HealthcheckHandlerOptions } from '../handler-
|
|
2
|
+
import { H as HealthcheckHandlerOptions } from '../handler-C3eTDuSQ.cjs';
|
|
3
3
|
import '../core-Bee03bJm.cjs';
|
|
4
4
|
|
|
5
5
|
type HealthcheckMiddlewareOptions = HealthcheckHandlerOptions;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import { H as HealthcheckHandlerOptions } from '../handler-
|
|
2
|
+
import { H as HealthcheckHandlerOptions } from '../handler-DaFJivGK.js';
|
|
3
3
|
import '../core-Bee03bJm.js';
|
|
4
4
|
|
|
5
5
|
type HealthcheckMiddlewareOptions = HealthcheckHandlerOptions;
|
|
@@ -35,10 +35,12 @@ function httpStatusCode(status) {
|
|
|
35
35
|
// src/handler.ts
|
|
36
36
|
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks", "cachedAt"];
|
|
37
37
|
function createHealthcheckHandler(options) {
|
|
38
|
-
const { registry, resolveDepth, metadata = {} } = options;
|
|
39
|
-
for (const
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
const { registry, resolveDepth, metadata = {}, shallowMetadata } = options;
|
|
39
|
+
for (const bag of [metadata, shallowMetadata ?? {}]) {
|
|
40
|
+
for (const key of Object.keys(bag)) {
|
|
41
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
42
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
43
|
+
}
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
return async (req) => {
|
|
@@ -62,7 +64,7 @@ function createHealthcheckHandler(options) {
|
|
|
62
64
|
const body = {
|
|
63
65
|
status: "ok",
|
|
64
66
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
65
|
-
...metadata
|
|
67
|
+
...shallowMetadata ?? metadata
|
|
66
68
|
};
|
|
67
69
|
return { status: 200, body };
|
|
68
70
|
};
|
|
@@ -61,10 +61,12 @@ function httpStatusCode(status) {
|
|
|
61
61
|
// src/handler.ts
|
|
62
62
|
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks", "cachedAt"];
|
|
63
63
|
function createHealthcheckHandler(options) {
|
|
64
|
-
const { registry, resolveDepth, metadata = {} } = options;
|
|
65
|
-
for (const
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
const { registry, resolveDepth, metadata = {}, shallowMetadata } = options;
|
|
65
|
+
for (const bag of [metadata, shallowMetadata ?? {}]) {
|
|
66
|
+
for (const key of Object.keys(bag)) {
|
|
67
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
68
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
69
|
+
}
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
72
|
return async (req) => {
|
|
@@ -88,7 +90,7 @@ function createHealthcheckHandler(options) {
|
|
|
88
90
|
const body = {
|
|
89
91
|
status: "ok",
|
|
90
92
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
91
|
-
...metadata
|
|
93
|
+
...shallowMetadata ?? metadata
|
|
92
94
|
};
|
|
93
95
|
return { status: 200, body };
|
|
94
96
|
};
|
|
@@ -35,10 +35,12 @@ function httpStatusCode(status) {
|
|
|
35
35
|
// src/handler.ts
|
|
36
36
|
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks", "cachedAt"];
|
|
37
37
|
function createHealthcheckHandler(options) {
|
|
38
|
-
const { registry, resolveDepth, metadata = {} } = options;
|
|
39
|
-
for (const
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
const { registry, resolveDepth, metadata = {}, shallowMetadata } = options;
|
|
39
|
+
for (const bag of [metadata, shallowMetadata ?? {}]) {
|
|
40
|
+
for (const key of Object.keys(bag)) {
|
|
41
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
42
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
43
|
+
}
|
|
42
44
|
}
|
|
43
45
|
}
|
|
44
46
|
return async (req) => {
|
|
@@ -62,7 +64,7 @@ function createHealthcheckHandler(options) {
|
|
|
62
64
|
const body = {
|
|
63
65
|
status: "ok",
|
|
64
66
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
65
|
-
...metadata
|
|
67
|
+
...shallowMetadata ?? metadata
|
|
66
68
|
};
|
|
67
69
|
return { status: 200, body };
|
|
68
70
|
};
|