@firebreak/vitals 1.0.3 → 1.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/dist/checks/databricks.cjs +57 -0
- package/dist/checks/databricks.d.cts +23 -0
- package/dist/checks/databricks.d.ts +23 -0
- package/dist/checks/databricks.mjs +30 -0
- package/dist/{handler-Bccbso4b.d.cts → handler-Bvf66wzh.d.cts} +8 -7
- package/dist/{handler-D0nYVQvu.d.ts → handler-R2U3ygLo.d.ts} +8 -7
- package/dist/index.cjs +17 -3
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +17 -3
- package/dist/integrations/express.cjs +17 -3
- package/dist/integrations/express.d.cts +1 -1
- package/dist/integrations/express.d.ts +1 -1
- package/dist/integrations/express.mjs +17 -3
- package/dist/integrations/next.cjs +17 -3
- package/dist/integrations/next.d.cts +1 -1
- package/dist/integrations/next.d.ts +1 -1
- package/dist/integrations/next.mjs +17 -3
- package/package.json +12 -2
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/checks/databricks.ts
|
|
21
|
+
var databricks_exports = {};
|
|
22
|
+
__export(databricks_exports, {
|
|
23
|
+
databricksCheck: () => databricksCheck
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(databricks_exports);
|
|
26
|
+
|
|
27
|
+
// src/types.ts
|
|
28
|
+
var Status = {
|
|
29
|
+
HEALTHY: 2,
|
|
30
|
+
DEGRADED: 1,
|
|
31
|
+
OUTAGE: 0
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// src/checks/databricks.ts
|
|
35
|
+
function databricksCheck(client) {
|
|
36
|
+
return async () => {
|
|
37
|
+
let session;
|
|
38
|
+
let op;
|
|
39
|
+
try {
|
|
40
|
+
session = await client.openSession();
|
|
41
|
+
op = await session.executeStatement("SELECT 1");
|
|
42
|
+
return { status: Status.HEALTHY, message: "" };
|
|
43
|
+
} catch (error) {
|
|
44
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
45
|
+
return { status: Status.OUTAGE, message };
|
|
46
|
+
} finally {
|
|
47
|
+
op?.close().catch(() => {
|
|
48
|
+
});
|
|
49
|
+
session?.close().catch(() => {
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
55
|
+
0 && (module.exports = {
|
|
56
|
+
databricksCheck
|
|
57
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { A as AsyncCheckFn } from '../core-BJ2Z0rRi.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Minimal interface for a connected Databricks SQL client.
|
|
5
|
+
* Avoids a hard dependency on `@databricks/sql`.
|
|
6
|
+
*/
|
|
7
|
+
interface DatabricksClient {
|
|
8
|
+
openSession(): Promise<DatabricksSession>;
|
|
9
|
+
}
|
|
10
|
+
interface DatabricksSession {
|
|
11
|
+
executeStatement(statement: string, options?: Record<string, unknown>): Promise<DatabricksOperation>;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
interface DatabricksOperation {
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates a healthcheck function that opens a session on an existing
|
|
19
|
+
* Databricks SQL client, runs `SELECT 1`, and closes the session.
|
|
20
|
+
*/
|
|
21
|
+
declare function databricksCheck(client: DatabricksClient): AsyncCheckFn;
|
|
22
|
+
|
|
23
|
+
export { AsyncCheckFn, type DatabricksClient, type DatabricksOperation, type DatabricksSession, databricksCheck };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { A as AsyncCheckFn } from '../core-BJ2Z0rRi.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Minimal interface for a connected Databricks SQL client.
|
|
5
|
+
* Avoids a hard dependency on `@databricks/sql`.
|
|
6
|
+
*/
|
|
7
|
+
interface DatabricksClient {
|
|
8
|
+
openSession(): Promise<DatabricksSession>;
|
|
9
|
+
}
|
|
10
|
+
interface DatabricksSession {
|
|
11
|
+
executeStatement(statement: string, options?: Record<string, unknown>): Promise<DatabricksOperation>;
|
|
12
|
+
close(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
interface DatabricksOperation {
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates a healthcheck function that opens a session on an existing
|
|
19
|
+
* Databricks SQL client, runs `SELECT 1`, and closes the session.
|
|
20
|
+
*/
|
|
21
|
+
declare function databricksCheck(client: DatabricksClient): AsyncCheckFn;
|
|
22
|
+
|
|
23
|
+
export { AsyncCheckFn, type DatabricksClient, type DatabricksOperation, type DatabricksSession, databricksCheck };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var Status = {
|
|
3
|
+
HEALTHY: 2,
|
|
4
|
+
DEGRADED: 1,
|
|
5
|
+
OUTAGE: 0
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// src/checks/databricks.ts
|
|
9
|
+
function databricksCheck(client) {
|
|
10
|
+
return async () => {
|
|
11
|
+
let session;
|
|
12
|
+
let op;
|
|
13
|
+
try {
|
|
14
|
+
session = await client.openSession();
|
|
15
|
+
op = await session.executeStatement("SELECT 1");
|
|
16
|
+
return { status: Status.HEALTHY, message: "" };
|
|
17
|
+
} catch (error) {
|
|
18
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
19
|
+
return { status: Status.OUTAGE, message };
|
|
20
|
+
} finally {
|
|
21
|
+
op?.close().catch(() => {
|
|
22
|
+
});
|
|
23
|
+
session?.close().catch(() => {
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
databricksCheck
|
|
30
|
+
};
|
|
@@ -4,22 +4,23 @@ interface HealthcheckHandlerOptions {
|
|
|
4
4
|
registry: HealthcheckRegistry;
|
|
5
5
|
token?: string | null;
|
|
6
6
|
queryParamName?: string;
|
|
7
|
+
metadata?: Record<string, string | number | boolean>;
|
|
7
8
|
}
|
|
8
9
|
interface HealthcheckRequest {
|
|
9
10
|
queryParams?: Record<string, string | string[] | undefined>;
|
|
10
11
|
authorizationHeader?: string | null;
|
|
11
12
|
}
|
|
13
|
+
interface ShallowResponseJson {
|
|
14
|
+
status: 'ok';
|
|
15
|
+
timestamp: string;
|
|
16
|
+
[key: string]: string | number | boolean;
|
|
17
|
+
}
|
|
12
18
|
interface HealthcheckHandlerResult {
|
|
13
19
|
status: number;
|
|
14
|
-
body: HealthcheckResponseJson | {
|
|
20
|
+
body: HealthcheckResponseJson | ShallowResponseJson | {
|
|
15
21
|
error: string;
|
|
16
22
|
};
|
|
17
23
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Framework-agnostic healthcheck handler. Takes a simple request object
|
|
20
|
-
* and returns a status code + JSON body. Framework integrations (Express,
|
|
21
|
-
* Next.js, etc.) are thin wrappers around this function.
|
|
22
|
-
*/
|
|
23
24
|
declare function createHealthcheckHandler(options: HealthcheckHandlerOptions): (req: HealthcheckRequest) => Promise<HealthcheckHandlerResult>;
|
|
24
25
|
|
|
25
|
-
export { type HealthcheckHandlerOptions as H, type HealthcheckHandlerResult as a, type HealthcheckRequest as b, createHealthcheckHandler as c };
|
|
26
|
+
export { type HealthcheckHandlerOptions as H, type ShallowResponseJson as S, type HealthcheckHandlerResult as a, type HealthcheckRequest as b, createHealthcheckHandler as c };
|
|
@@ -4,22 +4,23 @@ interface HealthcheckHandlerOptions {
|
|
|
4
4
|
registry: HealthcheckRegistry;
|
|
5
5
|
token?: string | null;
|
|
6
6
|
queryParamName?: string;
|
|
7
|
+
metadata?: Record<string, string | number | boolean>;
|
|
7
8
|
}
|
|
8
9
|
interface HealthcheckRequest {
|
|
9
10
|
queryParams?: Record<string, string | string[] | undefined>;
|
|
10
11
|
authorizationHeader?: string | null;
|
|
11
12
|
}
|
|
13
|
+
interface ShallowResponseJson {
|
|
14
|
+
status: 'ok';
|
|
15
|
+
timestamp: string;
|
|
16
|
+
[key: string]: string | number | boolean;
|
|
17
|
+
}
|
|
12
18
|
interface HealthcheckHandlerResult {
|
|
13
19
|
status: number;
|
|
14
|
-
body: HealthcheckResponseJson | {
|
|
20
|
+
body: HealthcheckResponseJson | ShallowResponseJson | {
|
|
15
21
|
error: string;
|
|
16
22
|
};
|
|
17
23
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Framework-agnostic healthcheck handler. Takes a simple request object
|
|
20
|
-
* and returns a status code + JSON body. Framework integrations (Express,
|
|
21
|
-
* Next.js, etc.) are thin wrappers around this function.
|
|
22
|
-
*/
|
|
23
24
|
declare function createHealthcheckHandler(options: HealthcheckHandlerOptions): (req: HealthcheckRequest) => Promise<HealthcheckHandlerResult>;
|
|
24
25
|
|
|
25
|
-
export { type HealthcheckHandlerOptions as H, type HealthcheckHandlerResult as a, type HealthcheckRequest as b, createHealthcheckHandler as c };
|
|
26
|
+
export { type HealthcheckHandlerOptions as H, type ShallowResponseJson as S, type HealthcheckHandlerResult as a, type HealthcheckRequest as b, createHealthcheckHandler as c };
|
package/dist/index.cjs
CHANGED
|
@@ -189,8 +189,14 @@ function extractToken(options) {
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
// src/handler.ts
|
|
192
|
+
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks"];
|
|
192
193
|
function createHealthcheckHandler(options) {
|
|
193
|
-
const { registry, token = null, queryParamName = "token" } = options;
|
|
194
|
+
const { registry, token = null, queryParamName = "token", metadata = {} } = options;
|
|
195
|
+
for (const key of Object.keys(metadata)) {
|
|
196
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
197
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
194
200
|
return async (req) => {
|
|
195
201
|
if (token !== null) {
|
|
196
202
|
const provided = extractToken({
|
|
@@ -198,14 +204,22 @@ function createHealthcheckHandler(options) {
|
|
|
198
204
|
authorizationHeader: req.authorizationHeader,
|
|
199
205
|
queryParamName
|
|
200
206
|
});
|
|
201
|
-
if (provided === null
|
|
207
|
+
if (provided === null) {
|
|
208
|
+
const body = {
|
|
209
|
+
status: "ok",
|
|
210
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
211
|
+
...metadata
|
|
212
|
+
};
|
|
213
|
+
return { status: 200, body };
|
|
214
|
+
}
|
|
215
|
+
if (!verifyToken(provided, token)) {
|
|
202
216
|
return { status: 403, body: { error: "Forbidden" } };
|
|
203
217
|
}
|
|
204
218
|
}
|
|
205
219
|
const response = await registry.run();
|
|
206
220
|
return {
|
|
207
221
|
status: httpStatusCode(response.status),
|
|
208
|
-
body: toJson(response)
|
|
222
|
+
body: { ...metadata, ...toJson(response) }
|
|
209
223
|
};
|
|
210
224
|
};
|
|
211
225
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { A as AsyncCheckFn, C as CheckInput, a as CheckResult, H as HealthcheckRegistry, b as HealthcheckResponse, c as HealthcheckResponseJson, 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-BJ2Z0rRi.cjs';
|
|
2
|
-
export { H as HealthcheckHandlerOptions, a as HealthcheckHandlerResult, b as HealthcheckRequest, c as createHealthcheckHandler } from './handler-
|
|
2
|
+
export { H as HealthcheckHandlerOptions, a as HealthcheckHandlerResult, b as HealthcheckRequest, S as ShallowResponseJson, c as createHealthcheckHandler } from './handler-Bvf66wzh.cjs';
|
|
3
3
|
|
|
4
4
|
declare function verifyToken(provided: string, expected: string): boolean;
|
|
5
5
|
declare function extractToken(options: {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { A as AsyncCheckFn, C as CheckInput, a as CheckResult, H as HealthcheckRegistry, b as HealthcheckResponse, c as HealthcheckResponseJson, 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-BJ2Z0rRi.js';
|
|
2
|
-
export { H as HealthcheckHandlerOptions, a as HealthcheckHandlerResult, b as HealthcheckRequest, c as createHealthcheckHandler } from './handler-
|
|
2
|
+
export { H as HealthcheckHandlerOptions, a as HealthcheckHandlerResult, b as HealthcheckRequest, S as ShallowResponseJson, c as createHealthcheckHandler } from './handler-R2U3ygLo.js';
|
|
3
3
|
|
|
4
4
|
declare function verifyToken(provided: string, expected: string): boolean;
|
|
5
5
|
declare function extractToken(options: {
|
package/dist/index.mjs
CHANGED
|
@@ -154,8 +154,14 @@ function extractToken(options) {
|
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
// src/handler.ts
|
|
157
|
+
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks"];
|
|
157
158
|
function createHealthcheckHandler(options) {
|
|
158
|
-
const { registry, token = null, queryParamName = "token" } = options;
|
|
159
|
+
const { registry, token = null, queryParamName = "token", metadata = {} } = options;
|
|
160
|
+
for (const key of Object.keys(metadata)) {
|
|
161
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
162
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
159
165
|
return async (req) => {
|
|
160
166
|
if (token !== null) {
|
|
161
167
|
const provided = extractToken({
|
|
@@ -163,14 +169,22 @@ function createHealthcheckHandler(options) {
|
|
|
163
169
|
authorizationHeader: req.authorizationHeader,
|
|
164
170
|
queryParamName
|
|
165
171
|
});
|
|
166
|
-
if (provided === null
|
|
172
|
+
if (provided === null) {
|
|
173
|
+
const body = {
|
|
174
|
+
status: "ok",
|
|
175
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
176
|
+
...metadata
|
|
177
|
+
};
|
|
178
|
+
return { status: 200, body };
|
|
179
|
+
}
|
|
180
|
+
if (!verifyToken(provided, token)) {
|
|
167
181
|
return { status: 403, body: { error: "Forbidden" } };
|
|
168
182
|
}
|
|
169
183
|
}
|
|
170
184
|
const response = await registry.run();
|
|
171
185
|
return {
|
|
172
186
|
status: httpStatusCode(response.status),
|
|
173
|
-
body: toJson(response)
|
|
187
|
+
body: { ...metadata, ...toJson(response) }
|
|
174
188
|
};
|
|
175
189
|
};
|
|
176
190
|
}
|
|
@@ -77,8 +77,14 @@ function httpStatusCode(status) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// src/handler.ts
|
|
80
|
+
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks"];
|
|
80
81
|
function createHealthcheckHandler(options) {
|
|
81
|
-
const { registry, token = null, queryParamName = "token" } = options;
|
|
82
|
+
const { registry, token = null, queryParamName = "token", metadata = {} } = options;
|
|
83
|
+
for (const key of Object.keys(metadata)) {
|
|
84
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
85
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
82
88
|
return async (req) => {
|
|
83
89
|
if (token !== null) {
|
|
84
90
|
const provided = extractToken({
|
|
@@ -86,14 +92,22 @@ function createHealthcheckHandler(options) {
|
|
|
86
92
|
authorizationHeader: req.authorizationHeader,
|
|
87
93
|
queryParamName
|
|
88
94
|
});
|
|
89
|
-
if (provided === null
|
|
95
|
+
if (provided === null) {
|
|
96
|
+
const body = {
|
|
97
|
+
status: "ok",
|
|
98
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
99
|
+
...metadata
|
|
100
|
+
};
|
|
101
|
+
return { status: 200, body };
|
|
102
|
+
}
|
|
103
|
+
if (!verifyToken(provided, token)) {
|
|
90
104
|
return { status: 403, body: { error: "Forbidden" } };
|
|
91
105
|
}
|
|
92
106
|
}
|
|
93
107
|
const response = await registry.run();
|
|
94
108
|
return {
|
|
95
109
|
status: httpStatusCode(response.status),
|
|
96
|
-
body: toJson(response)
|
|
110
|
+
body: { ...metadata, ...toJson(response) }
|
|
97
111
|
};
|
|
98
112
|
};
|
|
99
113
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestHandler } from 'express';
|
|
2
|
-
import { H as HealthcheckHandlerOptions } from '../handler-
|
|
2
|
+
import { H as HealthcheckHandlerOptions } from '../handler-Bvf66wzh.cjs';
|
|
3
3
|
import '../core-BJ2Z0rRi.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-R2U3ygLo.js';
|
|
3
3
|
import '../core-BJ2Z0rRi.js';
|
|
4
4
|
|
|
5
5
|
type HealthcheckMiddlewareOptions = HealthcheckHandlerOptions;
|
|
@@ -51,8 +51,14 @@ function httpStatusCode(status) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// src/handler.ts
|
|
54
|
+
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks"];
|
|
54
55
|
function createHealthcheckHandler(options) {
|
|
55
|
-
const { registry, token = null, queryParamName = "token" } = options;
|
|
56
|
+
const { registry, token = null, queryParamName = "token", metadata = {} } = options;
|
|
57
|
+
for (const key of Object.keys(metadata)) {
|
|
58
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
59
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
56
62
|
return async (req) => {
|
|
57
63
|
if (token !== null) {
|
|
58
64
|
const provided = extractToken({
|
|
@@ -60,14 +66,22 @@ function createHealthcheckHandler(options) {
|
|
|
60
66
|
authorizationHeader: req.authorizationHeader,
|
|
61
67
|
queryParamName
|
|
62
68
|
});
|
|
63
|
-
if (provided === null
|
|
69
|
+
if (provided === null) {
|
|
70
|
+
const body = {
|
|
71
|
+
status: "ok",
|
|
72
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
73
|
+
...metadata
|
|
74
|
+
};
|
|
75
|
+
return { status: 200, body };
|
|
76
|
+
}
|
|
77
|
+
if (!verifyToken(provided, token)) {
|
|
64
78
|
return { status: 403, body: { error: "Forbidden" } };
|
|
65
79
|
}
|
|
66
80
|
}
|
|
67
81
|
const response = await registry.run();
|
|
68
82
|
return {
|
|
69
83
|
status: httpStatusCode(response.status),
|
|
70
|
-
body: toJson(response)
|
|
84
|
+
body: { ...metadata, ...toJson(response) }
|
|
71
85
|
};
|
|
72
86
|
};
|
|
73
87
|
}
|
|
@@ -77,8 +77,14 @@ function httpStatusCode(status) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// src/handler.ts
|
|
80
|
+
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks"];
|
|
80
81
|
function createHealthcheckHandler(options) {
|
|
81
|
-
const { registry, token = null, queryParamName = "token" } = options;
|
|
82
|
+
const { registry, token = null, queryParamName = "token", metadata = {} } = options;
|
|
83
|
+
for (const key of Object.keys(metadata)) {
|
|
84
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
85
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
82
88
|
return async (req) => {
|
|
83
89
|
if (token !== null) {
|
|
84
90
|
const provided = extractToken({
|
|
@@ -86,14 +92,22 @@ function createHealthcheckHandler(options) {
|
|
|
86
92
|
authorizationHeader: req.authorizationHeader,
|
|
87
93
|
queryParamName
|
|
88
94
|
});
|
|
89
|
-
if (provided === null
|
|
95
|
+
if (provided === null) {
|
|
96
|
+
const body = {
|
|
97
|
+
status: "ok",
|
|
98
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
99
|
+
...metadata
|
|
100
|
+
};
|
|
101
|
+
return { status: 200, body };
|
|
102
|
+
}
|
|
103
|
+
if (!verifyToken(provided, token)) {
|
|
90
104
|
return { status: 403, body: { error: "Forbidden" } };
|
|
91
105
|
}
|
|
92
106
|
}
|
|
93
107
|
const response = await registry.run();
|
|
94
108
|
return {
|
|
95
109
|
status: httpStatusCode(response.status),
|
|
96
|
-
body: toJson(response)
|
|
110
|
+
body: { ...metadata, ...toJson(response) }
|
|
97
111
|
};
|
|
98
112
|
};
|
|
99
113
|
}
|
|
@@ -51,8 +51,14 @@ function httpStatusCode(status) {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
// src/handler.ts
|
|
54
|
+
var RESERVED_METADATA_KEYS = ["status", "timestamp", "checks"];
|
|
54
55
|
function createHealthcheckHandler(options) {
|
|
55
|
-
const { registry, token = null, queryParamName = "token" } = options;
|
|
56
|
+
const { registry, token = null, queryParamName = "token", metadata = {} } = options;
|
|
57
|
+
for (const key of Object.keys(metadata)) {
|
|
58
|
+
if (RESERVED_METADATA_KEYS.includes(key)) {
|
|
59
|
+
throw new Error(`Metadata key '${key}' is reserved. Use a different key name.`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
56
62
|
return async (req) => {
|
|
57
63
|
if (token !== null) {
|
|
58
64
|
const provided = extractToken({
|
|
@@ -60,14 +66,22 @@ function createHealthcheckHandler(options) {
|
|
|
60
66
|
authorizationHeader: req.authorizationHeader,
|
|
61
67
|
queryParamName
|
|
62
68
|
});
|
|
63
|
-
if (provided === null
|
|
69
|
+
if (provided === null) {
|
|
70
|
+
const body = {
|
|
71
|
+
status: "ok",
|
|
72
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
73
|
+
...metadata
|
|
74
|
+
};
|
|
75
|
+
return { status: 200, body };
|
|
76
|
+
}
|
|
77
|
+
if (!verifyToken(provided, token)) {
|
|
64
78
|
return { status: 403, body: { error: "Forbidden" } };
|
|
65
79
|
}
|
|
66
80
|
}
|
|
67
81
|
const response = await registry.run();
|
|
68
82
|
return {
|
|
69
83
|
status: httpStatusCode(response.status),
|
|
70
|
-
body: toJson(response)
|
|
84
|
+
body: { ...metadata, ...toJson(response) }
|
|
71
85
|
};
|
|
72
86
|
};
|
|
73
87
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@firebreak/vitals",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Deep healthcheck endpoints following the HEALTHCHECK_SPEC format",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -34,6 +34,16 @@
|
|
|
34
34
|
"default": "./dist/checks/http.cjs"
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
|
+
"./checks/databricks": {
|
|
38
|
+
"import": {
|
|
39
|
+
"types": "./dist/checks/databricks.d.ts",
|
|
40
|
+
"default": "./dist/checks/databricks.mjs"
|
|
41
|
+
},
|
|
42
|
+
"require": {
|
|
43
|
+
"types": "./dist/checks/databricks.d.cts",
|
|
44
|
+
"default": "./dist/checks/databricks.cjs"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
37
47
|
"./checks/redis": {
|
|
38
48
|
"import": {
|
|
39
49
|
"types": "./dist/checks/redis.d.ts",
|
|
@@ -109,5 +119,5 @@
|
|
|
109
119
|
"engines": {
|
|
110
120
|
"node": ">=20.0.0"
|
|
111
121
|
},
|
|
112
|
-
"license": "
|
|
122
|
+
"license": "MIT"
|
|
113
123
|
}
|