@openstatus/health-typesense 0.1.4-dev.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 ADDED
@@ -0,0 +1,76 @@
1
+ # @openstatus/health-typesense
2
+
3
+ [Typesense](https://typesense.org/) probe for
4
+ [`@openstatus/health`](https://jsr.io/@openstatus/health). Sends
5
+ `GET {host}/health` and fails the check unless the node answers 2xx with
6
+ `{ "ok": true }` — with `fetch` alone, on every runtime, against Typesense
7
+ Cloud or your own cluster.
8
+
9
+ ```sh
10
+ deno add jsr:@openstatus/health jsr:@openstatus/health-typesense
11
+ npm install @openstatus/health @openstatus/health-typesense
12
+ ```
13
+
14
+ ```ts
15
+ import { createHealthHandler, readEnv } from "@openstatus/health";
16
+ import { typesenseProbe } from "@openstatus/health-typesense";
17
+
18
+ const host = readEnv("TYPESENSE_HOST");
19
+
20
+ Deno.serve(
21
+ createHealthHandler({
22
+ probes: [
23
+ // the factory validates `host` at construction, so pass a placeholder
24
+ // and let `skip` keep the unconfigured check from running.
25
+ typesenseProbe({
26
+ host: host ?? "http://localhost:8108",
27
+ skip: () => host == null,
28
+ }),
29
+ ],
30
+ }),
31
+ );
32
+ ```
33
+
34
+ `host` is a node URL — `https://xxx.a1.typesense.net` on Cloud or
35
+ `http://localhost:8108` locally. `/health` is the endpoint Typesense
36
+ documents for exactly this: it needs no API key, has no side effects and
37
+ answers `ok: false` while the node is still catching up on a cluster, which
38
+ the probe reports as a failed check. Pass `apiKey` to send one anyway when a
39
+ proxy in front of the node requires it. Like every probe here, this one
40
+ never reads the environment itself — pass the values in, and use `skip` for
41
+ environments where Typesense is not configured.
42
+
43
+ ```ts
44
+ typesenseProbe({
45
+ host,
46
+ apiKey: env.TYPESENSE_API_KEY,
47
+ // optional overrides from the Probe contract
48
+ name: "typesense",
49
+ critical: true,
50
+ timeoutMs: 1000,
51
+ skip: () => env.TYPESENSE_HOST == null,
52
+ });
53
+ ```
54
+
55
+ Non-critical by default: search is usually one feature of a service rather
56
+ than its request path, so an outage degrades the report instead of taking
57
+ the service out of rotation. Set `critical: true` when requests cannot be
58
+ served without it.
59
+
60
+ ## About openstatus
61
+
62
+ [openstatus](https://www.openstatus.dev/) is the open-source uptime monitoring
63
+ and status page platform. This package is part of
64
+ [`@openstatus/health`](https://github.com/openstatusHQ/health), the `/health`
65
+ endpoints behind openstatus's own services, extracted so any JavaScript server
66
+ can expose one. Point an
67
+ [openstatus monitor](https://www.openstatus.dev/docs/reference/http-monitor)
68
+ at the endpoint and assert on `status` in the body to be alerted on
69
+ `degraded` before it becomes `unhealthy`.
70
+
71
+ Source: [github.com/openstatusHQ/health](https://github.com/openstatusHQ/health).
72
+ Issues and PRs welcome.
73
+
74
+ ## License
75
+
76
+ [MIT](https://github.com/openstatusHQ/health/blob/main/LICENSE)
@@ -0,0 +1,30 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+
25
+ Object.defineProperty(exports, '__toESM', {
26
+ enumerable: true,
27
+ get: function () {
28
+ return __toESM;
29
+ }
30
+ });
package/dist/mod.cjs ADDED
@@ -0,0 +1,41 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const __openstatus_health = require_rolldown_runtime.__toESM(require("@openstatus/health"));
3
+
4
+ //#region src/mod.ts
5
+ /** Probe name when `name` is unset. */
6
+ const typesenseDefaultName = "search";
7
+ /** A probe that expects `GET {host}/health` to answer 2xx with `ok: true`; non-critical by default. Throws `ProbeConfigError` for an invalid `host` or an empty `apiKey`. */
8
+ function typesenseProbe(options) {
9
+ const doFetch = options.fetch ?? globalThis.fetch;
10
+ const url = (0, __openstatus_health.probeUrl)({
11
+ probe: "typesenseProbe",
12
+ field: "host",
13
+ value: options.host,
14
+ path: "/health"
15
+ });
16
+ if (options.apiKey != null && options.apiKey.length === 0) throw new __openstatus_health.ProbeConfigError("typesenseProbe", "apiKey", "must not be empty");
17
+ const headers = options.apiKey == null ? void 0 : { "x-typesense-api-key": options.apiKey };
18
+ return {
19
+ name: options.name ?? typesenseDefaultName,
20
+ critical: options.critical ?? false,
21
+ timeoutMs: options.timeoutMs,
22
+ skip: options.skip,
23
+ run: async (signal) => {
24
+ const res = await doFetch(url, {
25
+ method: "GET",
26
+ headers,
27
+ signal
28
+ });
29
+ if (!res.ok) {
30
+ await res.body?.cancel();
31
+ throw new Error(`unexpected status ${res.status}`);
32
+ }
33
+ const body = await res.json().catch(() => null);
34
+ if (body?.ok !== true) throw new Error(`unexpected health body ${JSON.stringify(body)}`);
35
+ }
36
+ };
37
+ }
38
+
39
+ //#endregion
40
+ exports.typesenseDefaultName = typesenseDefaultName;
41
+ exports.typesenseProbe = typesenseProbe;
package/dist/mod.d.cts ADDED
@@ -0,0 +1,21 @@
1
+ import { Probe, ProbeOverrides } from "@openstatus/health";
2
+
3
+ //#region src/mod.d.ts
4
+
5
+ /** Probe name when `name` is unset. */
6
+ declare const typesenseDefaultName = "search";
7
+ /** Options for `typesenseProbe()`. */
8
+ interface TypesenseProbeOptions extends ProbeOverrides {
9
+ /** The node URL, e.g. `https://xxx.a1.typesense.net` or `http://localhost:8108`. */
10
+ readonly host: string | URL;
11
+ /** An API key, sent as `x-typesense-api-key`. `/health` does not need one. */
12
+ readonly apiKey?: string;
13
+ /** Replacement `fetch`, for tests. */
14
+ readonly fetch?: typeof fetch;
15
+ }
16
+ /** A probe that expects `GET {host}/health` to answer 2xx with `ok: true`; non-critical by default. Throws `ProbeConfigError` for an invalid `host` or an empty `apiKey`. */
17
+ declare function typesenseProbe(options: TypesenseProbeOptions): Probe;
18
+ //# sourceMappingURL=mod.d.ts.map
19
+ //#endregion
20
+ export { TypesenseProbeOptions, typesenseDefaultName, typesenseProbe };
21
+ //# sourceMappingURL=mod.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;AAkCqE,cAbxD,oBAAA,GAawD,QAAA;;UAVpD,qBAAA,SAA8B;;0BAErB;;;;0BAIA;;;iBAIV,cAAA,UAAwB,wBAAwB"}
package/dist/mod.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ import { Probe, ProbeOverrides } from "@openstatus/health";
2
+
3
+ //#region src/mod.d.ts
4
+
5
+ /** Probe name when `name` is unset. */
6
+ declare const typesenseDefaultName = "search";
7
+ /** Options for `typesenseProbe()`. */
8
+ interface TypesenseProbeOptions extends ProbeOverrides {
9
+ /** The node URL, e.g. `https://xxx.a1.typesense.net` or `http://localhost:8108`. */
10
+ readonly host: string | URL;
11
+ /** An API key, sent as `x-typesense-api-key`. `/health` does not need one. */
12
+ readonly apiKey?: string;
13
+ /** Replacement `fetch`, for tests. */
14
+ readonly fetch?: typeof fetch;
15
+ }
16
+ /** A probe that expects `GET {host}/health` to answer 2xx with `ok: true`; non-critical by default. Throws `ProbeConfigError` for an invalid `host` or an empty `apiKey`. */
17
+ declare function typesenseProbe(options: TypesenseProbeOptions): Probe;
18
+ //# sourceMappingURL=mod.d.ts.map
19
+ //#endregion
20
+ export { TypesenseProbeOptions, typesenseDefaultName, typesenseProbe };
21
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;AAkCqE,cAbxD,oBAAA,GAawD,QAAA;;UAVpD,qBAAA,SAA8B;;0BAErB;;;;0BAIA;;;iBAIV,cAAA,UAAwB,wBAAwB"}
package/dist/mod.js ADDED
@@ -0,0 +1,40 @@
1
+ import { ProbeConfigError, probeUrl } from "@openstatus/health";
2
+
3
+ //#region src/mod.ts
4
+ /** Probe name when `name` is unset. */
5
+ const typesenseDefaultName = "search";
6
+ /** A probe that expects `GET {host}/health` to answer 2xx with `ok: true`; non-critical by default. Throws `ProbeConfigError` for an invalid `host` or an empty `apiKey`. */
7
+ function typesenseProbe(options) {
8
+ const doFetch = options.fetch ?? globalThis.fetch;
9
+ const url = probeUrl({
10
+ probe: "typesenseProbe",
11
+ field: "host",
12
+ value: options.host,
13
+ path: "/health"
14
+ });
15
+ if (options.apiKey != null && options.apiKey.length === 0) throw new ProbeConfigError("typesenseProbe", "apiKey", "must not be empty");
16
+ const headers = options.apiKey == null ? void 0 : { "x-typesense-api-key": options.apiKey };
17
+ return {
18
+ name: options.name ?? typesenseDefaultName,
19
+ critical: options.critical ?? false,
20
+ timeoutMs: options.timeoutMs,
21
+ skip: options.skip,
22
+ run: async (signal) => {
23
+ const res = await doFetch(url, {
24
+ method: "GET",
25
+ headers,
26
+ signal
27
+ });
28
+ if (!res.ok) {
29
+ await res.body?.cancel();
30
+ throw new Error(`unexpected status ${res.status}`);
31
+ }
32
+ const body = await res.json().catch(() => null);
33
+ if (body?.ok !== true) throw new Error(`unexpected health body ${JSON.stringify(body)}`);
34
+ }
35
+ };
36
+ }
37
+
38
+ //#endregion
39
+ export { typesenseDefaultName, typesenseProbe };
40
+ //# sourceMappingURL=mod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.js","names":["options: TypesenseProbeOptions","body: { readonly ok?: boolean } | null"],"sources":["../src/mod.ts"],"sourcesContent":["/**\n * Typesense probe for `@openstatus/health`, against `/health`, which must\n * report `ok: true`.\n *\n * ```ts\n * import { typesenseProbe } from \"@openstatus/health-typesense\";\n *\n * const probe = typesenseProbe({ host: env.TYPESENSE_HOST });\n * ```\n *\n * @module\n */\n\nimport {\n type Probe,\n ProbeConfigError,\n type ProbeOverrides,\n probeUrl,\n} from \"@openstatus/health\";\n\n/** Probe name when `name` is unset. */\nexport const typesenseDefaultName = \"search\";\n\n/** Options for `typesenseProbe()`. */\nexport interface TypesenseProbeOptions extends ProbeOverrides {\n /** The node URL, e.g. `https://xxx.a1.typesense.net` or `http://localhost:8108`. */\n readonly host: string | URL;\n /** An API key, sent as `x-typesense-api-key`. `/health` does not need one. */\n readonly apiKey?: string;\n /** Replacement `fetch`, for tests. */\n readonly fetch?: typeof fetch;\n}\n\n/** A probe that expects `GET {host}/health` to answer 2xx with `ok: true`; non-critical by default. Throws `ProbeConfigError` for an invalid `host` or an empty `apiKey`. */\nexport function typesenseProbe(options: TypesenseProbeOptions): Probe {\n const doFetch = options.fetch ?? globalThis.fetch;\n const url = probeUrl({\n probe: \"typesenseProbe\",\n field: \"host\",\n value: options.host,\n path: \"/health\",\n });\n if (options.apiKey != null && options.apiKey.length === 0) {\n throw new ProbeConfigError(\"typesenseProbe\", \"apiKey\", \"must not be empty\");\n }\n const headers = options.apiKey == null\n ? undefined\n : { \"x-typesense-api-key\": options.apiKey };\n return {\n name: options.name ?? typesenseDefaultName,\n critical: options.critical ?? false,\n timeoutMs: options.timeoutMs,\n skip: options.skip,\n run: async (signal) => {\n const res = await doFetch(url, { method: \"GET\", headers, signal });\n if (!res.ok) {\n await res.body?.cancel();\n throw new Error(`unexpected status ${res.status}`);\n }\n const body: { readonly ok?: boolean } | null = await res.json()\n .catch(() => null);\n if (body?.ok !== true) {\n throw new Error(`unexpected health body ${JSON.stringify(body)}`);\n }\n },\n };\n}\n"],"mappings":";;;;AAqBA,MAAa,uBAAuB;;AAapC,SAAgB,eAAeA,SAAuC;CACpE,MAAM,UAAU,QAAQ,SAAS,WAAW;CAC5C,MAAM,MAAM,SAAS;EACnB,OAAO;EACP,OAAO;EACP,OAAO,QAAQ;EACf,MAAM;CACP,EAAC;AACF,KAAI,QAAQ,UAAU,QAAQ,QAAQ,OAAO,WAAW,EACtD,OAAM,IAAI,iBAAiB,kBAAkB,UAAU;CAEzD,MAAM,UAAU,QAAQ,UAAU,gBAE9B,EAAE,uBAAuB,QAAQ,OAAQ;AAC7C,QAAO;EACL,MAAM,QAAQ,QAAQ;EACtB,UAAU,QAAQ,YAAY;EAC9B,WAAW,QAAQ;EACnB,MAAM,QAAQ;EACd,KAAK,OAAO,WAAW;GACrB,MAAM,MAAM,MAAM,QAAQ,KAAK;IAAE,QAAQ;IAAO;IAAS;GAAQ,EAAC;AAClE,QAAK,IAAI,IAAI;AACX,UAAM,IAAI,MAAM,QAAQ;AACxB,UAAM,IAAI,OAAO,oBAAoB,IAAI,OAAO;GACjD;GACD,MAAMC,OAAyC,MAAM,IAAI,MAAM,CAC5D,MAAM,MAAM,KAAK;AACpB,OAAI,MAAM,OAAO,KACf,OAAM,IAAI,OAAO,yBAAyB,KAAK,UAAU,KAAK,CAAC;EAElE;CACF;AACF"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@openstatus/health-typesense",
3
+ "version": "0.1.4-dev.0",
4
+ "description": "Typesense probe for @openstatus/health",
5
+ "keywords": [
6
+ "openstatus",
7
+ "health",
8
+ "healthcheck",
9
+ "typesense",
10
+ "search"
11
+ ],
12
+ "license": "MIT",
13
+ "author": {
14
+ "name": "openstatus",
15
+ "url": "https://www.openstatus.dev/"
16
+ },
17
+ "homepage": "https://github.com/openstatusHQ/health",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/openstatusHQ/health.git",
21
+ "directory": "packages/typesense/"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/openstatusHQ/health/issues"
25
+ },
26
+ "type": "module",
27
+ "module": "./dist/mod.js",
28
+ "main": "./dist/mod.cjs",
29
+ "types": "./dist/mod.d.ts",
30
+ "exports": {
31
+ ".": {
32
+ "types": {
33
+ "import": "./dist/mod.d.ts",
34
+ "require": "./dist/mod.d.cts"
35
+ },
36
+ "import": "./dist/mod.js",
37
+ "require": "./dist/mod.cjs"
38
+ },
39
+ "./package.json": "./package.json"
40
+ },
41
+ "sideEffects": false,
42
+ "files": [
43
+ "dist/"
44
+ ],
45
+ "engines": {
46
+ "node": ">=22"
47
+ },
48
+ "peerDependencies": {
49
+ "@openstatus/health": "^0.1.4-dev.0"
50
+ },
51
+ "devDependencies": {
52
+ "tsdown": "^0.12.7",
53
+ "typescript": "^5.8.3"
54
+ },
55
+ "scripts": {
56
+ "build": "tsdown",
57
+ "prepack": "tsdown",
58
+ "test": "node --experimental-transform-types --test"
59
+ }
60
+ }