@openstatus/health-posthog 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,79 @@
1
+ # @openstatus/health-posthog
2
+
3
+ [PostHog](https://posthog.com/) probe for
4
+ [`@openstatus/health`](https://jsr.io/@openstatus/health). Sends
5
+ `GET {baseUrl}/api/projects/@current/` with a personal API key as a bearer
6
+ header, so it proves both that the PostHog API answers and that the key is
7
+ valid — with `fetch` alone, on every runtime.
8
+
9
+ ```sh
10
+ deno add jsr:@openstatus/health jsr:@openstatus/health-posthog
11
+ npm install @openstatus/health @openstatus/health-posthog
12
+ ```
13
+
14
+ ```ts
15
+ import { createHealthHandler, readEnv } from "@openstatus/health";
16
+ import { posthogProbe } from "@openstatus/health-posthog";
17
+
18
+ const personalApiKey = readEnv("POSTHOG_PERSONAL_API_KEY");
19
+
20
+ Deno.serve(
21
+ createHealthHandler({
22
+ probes: [
23
+ // the factory validates `personalApiKey` at construction, so pass a
24
+ // placeholder and let `skip` keep the unconfigured check from running.
25
+ posthogProbe({
26
+ personalApiKey: personalApiKey || "unconfigured",
27
+ skip: () => !personalApiKey,
28
+ }),
29
+ ],
30
+ }),
31
+ );
32
+ ```
33
+
34
+ `personalApiKey` is a `phx_…` personal API key with the `project:read` scope —
35
+ not the `phc_…` project token the browser SDK uses, which cannot call the
36
+ private API. Reading the current project is a cheap read with no side effects,
37
+ so the probe can run on every health request. `baseUrl` defaults to
38
+ `https://us.posthog.com`; pass `https://eu.posthog.com` for EU Cloud or the
39
+ URL of a self-hosted instance. Like every probe here, this one never reads the
40
+ environment itself — pass the values in, and use `skip` for environments where
41
+ PostHog is not configured.
42
+
43
+ This proves the API your server calls for feature-flag definitions and queries
44
+ is reachable. Event capture goes to the ingestion host (`us.i.posthog.com` /
45
+ `eu.i.posthog.com`), which the SDKs buffer and retry on their own.
46
+
47
+ ```ts
48
+ posthogProbe({
49
+ personalApiKey,
50
+ // optional overrides from the Probe contract
51
+ name: "analytics",
52
+ critical: true,
53
+ timeoutMs: 2000,
54
+ skip: () => !personalApiKey,
55
+ });
56
+ ```
57
+
58
+ Non-critical by default: analytics and feature flags are evaluated from cached
59
+ definitions, so an outage degrades the report instead of taking the service
60
+ out of rotation. Set `critical: true` when requests block on a live flag
61
+ evaluation.
62
+
63
+ ## About openstatus
64
+
65
+ [openstatus](https://www.openstatus.dev/) is the open-source uptime monitoring
66
+ and status page platform. This package is part of
67
+ [`@openstatus/health`](https://github.com/openstatusHQ/health), the `/health`
68
+ endpoints behind openstatus's own services, extracted so any JavaScript server
69
+ can expose one. Point an
70
+ [openstatus monitor](https://www.openstatus.dev/docs/reference/http-monitor)
71
+ at the endpoint and assert on `status` in the body to be alerted on
72
+ `degraded` before it becomes `unhealthy`.
73
+
74
+ Source: [github.com/openstatusHQ/health](https://github.com/openstatusHQ/health).
75
+ Issues and PRs welcome.
76
+
77
+ ## License
78
+
79
+ [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,36 @@
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
+ /** API base URL when `baseUrl` is unset. */
6
+ const posthogDefaultBaseUrl = "https://us.posthog.com";
7
+ /** Probe name when `name` is unset. */
8
+ const posthogDefaultName = "posthog";
9
+ /** A probe that expects 2xx from `GET {baseUrl}/api/projects/@current/` with `personalApiKey` as a bearer token; non-critical by default. Throws `ProbeConfigError` for an empty `personalApiKey` or an invalid `baseUrl`. */
10
+ function posthogProbe(options) {
11
+ const doFetch = options.fetch ?? globalThis.fetch;
12
+ const url = (0, __openstatus_health.probeUrl)({
13
+ probe: "posthogProbe",
14
+ field: "baseUrl",
15
+ value: options.baseUrl ?? posthogDefaultBaseUrl,
16
+ path: "/api/projects/@current/"
17
+ });
18
+ if (typeof options.personalApiKey !== "string" || options.personalApiKey.length === 0) throw new __openstatus_health.ProbeConfigError("posthogProbe", "personalApiKey", typeof options.personalApiKey !== "string" ? `must be a string, got ${String(options.personalApiKey)}` : "must not be empty");
19
+ const headers = { authorization: `Bearer ${options.personalApiKey}` };
20
+ return {
21
+ name: options.name ?? posthogDefaultName,
22
+ critical: options.critical ?? false,
23
+ timeoutMs: options.timeoutMs,
24
+ skip: options.skip,
25
+ run: (signal) => (0, __openstatus_health.expectOk)(doFetch(url, {
26
+ method: "GET",
27
+ headers,
28
+ signal
29
+ }))
30
+ };
31
+ }
32
+
33
+ //#endregion
34
+ exports.posthogDefaultBaseUrl = posthogDefaultBaseUrl;
35
+ exports.posthogDefaultName = posthogDefaultName;
36
+ exports.posthogProbe = posthogProbe;
package/dist/mod.d.cts ADDED
@@ -0,0 +1,23 @@
1
+ import { Probe, ProbeOverrides } from "@openstatus/health";
2
+
3
+ //#region src/mod.d.ts
4
+
5
+ /** API base URL when `baseUrl` is unset. */
6
+ declare const posthogDefaultBaseUrl = "https://us.posthog.com";
7
+ /** Probe name when `name` is unset. */
8
+ declare const posthogDefaultName = "posthog";
9
+ /** Options for `posthogProbe()`. */
10
+ interface PosthogProbeOptions extends ProbeOverrides {
11
+ /** A personal API key (`phx_…`) with `project:read` scope. */
12
+ readonly personalApiKey: string;
13
+ /** API host. Default `posthogDefaultBaseUrl`. */
14
+ readonly baseUrl?: string | URL;
15
+ /** Replacement `fetch`, for tests. */
16
+ readonly fetch?: typeof fetch;
17
+ }
18
+ /** A probe that expects 2xx from `GET {baseUrl}/api/projects/@current/` with `personalApiKey` as a bearer token; non-critical by default. Throws `ProbeConfigError` for an empty `personalApiKey` or an invalid `baseUrl`. */
19
+ declare function posthogProbe(options: PosthogProbeOptions): Probe;
20
+ //# sourceMappingURL=mod.d.ts.map
21
+ //#endregion
22
+ export { PosthogProbeOptions, posthogDefaultBaseUrl, posthogDefaultName, posthogProbe };
23
+ //# sourceMappingURL=mod.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;AAoCsC,cAfzB,qBAAA,GAeyB,wBAAA;;AAA2B,cAbpD,kBAAA,GAaoD,SAAA;;UAVhD,mBAAA,SAA4B;;;;8BAIf;;0BAEJ;;;iBAIV,YAAA,UAAsB,sBAAsB"}
package/dist/mod.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ import { Probe, ProbeOverrides } from "@openstatus/health";
2
+
3
+ //#region src/mod.d.ts
4
+
5
+ /** API base URL when `baseUrl` is unset. */
6
+ declare const posthogDefaultBaseUrl = "https://us.posthog.com";
7
+ /** Probe name when `name` is unset. */
8
+ declare const posthogDefaultName = "posthog";
9
+ /** Options for `posthogProbe()`. */
10
+ interface PosthogProbeOptions extends ProbeOverrides {
11
+ /** A personal API key (`phx_…`) with `project:read` scope. */
12
+ readonly personalApiKey: string;
13
+ /** API host. Default `posthogDefaultBaseUrl`. */
14
+ readonly baseUrl?: string | URL;
15
+ /** Replacement `fetch`, for tests. */
16
+ readonly fetch?: typeof fetch;
17
+ }
18
+ /** A probe that expects 2xx from `GET {baseUrl}/api/projects/@current/` with `personalApiKey` as a bearer token; non-critical by default. Throws `ProbeConfigError` for an empty `personalApiKey` or an invalid `baseUrl`. */
19
+ declare function posthogProbe(options: PosthogProbeOptions): Probe;
20
+ //# sourceMappingURL=mod.d.ts.map
21
+ //#endregion
22
+ export { PosthogProbeOptions, posthogDefaultBaseUrl, posthogDefaultName, posthogProbe };
23
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;AAoCsC,cAfzB,qBAAA,GAeyB,wBAAA;;AAA2B,cAbpD,kBAAA,GAaoD,SAAA;;UAVhD,mBAAA,SAA4B;;;;8BAIf;;0BAEJ;;;iBAIV,YAAA,UAAsB,sBAAsB"}
package/dist/mod.js ADDED
@@ -0,0 +1,34 @@
1
+ import { ProbeConfigError, expectOk, probeUrl } from "@openstatus/health";
2
+
3
+ //#region src/mod.ts
4
+ /** API base URL when `baseUrl` is unset. */
5
+ const posthogDefaultBaseUrl = "https://us.posthog.com";
6
+ /** Probe name when `name` is unset. */
7
+ const posthogDefaultName = "posthog";
8
+ /** A probe that expects 2xx from `GET {baseUrl}/api/projects/@current/` with `personalApiKey` as a bearer token; non-critical by default. Throws `ProbeConfigError` for an empty `personalApiKey` or an invalid `baseUrl`. */
9
+ function posthogProbe(options) {
10
+ const doFetch = options.fetch ?? globalThis.fetch;
11
+ const url = probeUrl({
12
+ probe: "posthogProbe",
13
+ field: "baseUrl",
14
+ value: options.baseUrl ?? posthogDefaultBaseUrl,
15
+ path: "/api/projects/@current/"
16
+ });
17
+ if (typeof options.personalApiKey !== "string" || options.personalApiKey.length === 0) throw new ProbeConfigError("posthogProbe", "personalApiKey", typeof options.personalApiKey !== "string" ? `must be a string, got ${String(options.personalApiKey)}` : "must not be empty");
18
+ const headers = { authorization: `Bearer ${options.personalApiKey}` };
19
+ return {
20
+ name: options.name ?? posthogDefaultName,
21
+ critical: options.critical ?? false,
22
+ timeoutMs: options.timeoutMs,
23
+ skip: options.skip,
24
+ run: (signal) => expectOk(doFetch(url, {
25
+ method: "GET",
26
+ headers,
27
+ signal
28
+ }))
29
+ };
30
+ }
31
+
32
+ //#endregion
33
+ export { posthogDefaultBaseUrl, posthogDefaultName, posthogProbe };
34
+ //# sourceMappingURL=mod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.js","names":["options: PosthogProbeOptions"],"sources":["../src/mod.ts"],"sourcesContent":["/**\n * PostHog reachability probe for `@openstatus/health`, against `/api/projects/@current/`.\n *\n * ```ts\n * import { posthogProbe } from \"@openstatus/health-posthog\";\n *\n * const probe = posthogProbe({ personalApiKey: env.POSTHOG_PERSONAL_API_KEY });\n * ```\n *\n * @module\n */\n\nimport {\n expectOk,\n type Probe,\n ProbeConfigError,\n type ProbeOverrides,\n probeUrl,\n} from \"@openstatus/health\";\n\n/** API base URL when `baseUrl` is unset. */\nexport const posthogDefaultBaseUrl = \"https://us.posthog.com\";\n/** Probe name when `name` is unset. */\nexport const posthogDefaultName = \"posthog\";\n\n/** Options for `posthogProbe()`. */\nexport interface PosthogProbeOptions extends ProbeOverrides {\n /** A personal API key (`phx_…`) with `project:read` scope. */\n readonly personalApiKey: string;\n /** API host. Default `posthogDefaultBaseUrl`. */\n readonly baseUrl?: string | URL;\n /** Replacement `fetch`, for tests. */\n readonly fetch?: typeof fetch;\n}\n\n/** A probe that expects 2xx from `GET {baseUrl}/api/projects/@current/` with `personalApiKey` as a bearer token; non-critical by default. Throws `ProbeConfigError` for an empty `personalApiKey` or an invalid `baseUrl`. */\nexport function posthogProbe(options: PosthogProbeOptions): Probe {\n const doFetch = options.fetch ?? globalThis.fetch;\n const url = probeUrl({\n probe: \"posthogProbe\",\n field: \"baseUrl\",\n value: options.baseUrl ?? posthogDefaultBaseUrl,\n path: \"/api/projects/@current/\",\n });\n if (\n typeof options.personalApiKey !== \"string\" ||\n options.personalApiKey.length === 0\n ) {\n throw new ProbeConfigError(\n \"posthogProbe\",\n \"personalApiKey\",\n typeof options.personalApiKey !== \"string\"\n ? `must be a string, got ${String(options.personalApiKey)}`\n : \"must not be empty\",\n );\n }\n const headers = { authorization: `Bearer ${options.personalApiKey}` };\n return {\n name: options.name ?? posthogDefaultName,\n critical: options.critical ?? false,\n timeoutMs: options.timeoutMs,\n skip: options.skip,\n run: (signal) => expectOk(doFetch(url, { method: \"GET\", headers, signal })),\n };\n}\n"],"mappings":";;;;AAqBA,MAAa,wBAAwB;;AAErC,MAAa,qBAAqB;;AAalC,SAAgB,aAAaA,SAAqC;CAChE,MAAM,UAAU,QAAQ,SAAS,WAAW;CAC5C,MAAM,MAAM,SAAS;EACnB,OAAO;EACP,OAAO;EACP,OAAO,QAAQ,WAAW;EAC1B,MAAM;CACP,EAAC;AACF,YACS,QAAQ,mBAAmB,YAClC,QAAQ,eAAe,WAAW,EAElC,OAAM,IAAI,iBACR,gBACA,yBACO,QAAQ,mBAAmB,YAC7B,wBAAwB,OAAO,QAAQ,eAAe,CAAC,IACxD;CAGR,MAAM,UAAU,EAAE,gBAAgB,SAAS,QAAQ,eAAe,EAAG;AACrE,QAAO;EACL,MAAM,QAAQ,QAAQ;EACtB,UAAU,QAAQ,YAAY;EAC9B,WAAW,QAAQ;EACnB,MAAM,QAAQ;EACd,KAAK,CAAC,WAAW,SAAS,QAAQ,KAAK;GAAE,QAAQ;GAAO;GAAS;EAAQ,EAAC,CAAC;CAC5E;AACF"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@openstatus/health-posthog",
3
+ "version": "0.1.4-dev.0",
4
+ "description": "PostHog API probe for @openstatus/health",
5
+ "keywords": [
6
+ "openstatus",
7
+ "health",
8
+ "healthcheck",
9
+ "posthog",
10
+ "analytics",
11
+ "feature-flags"
12
+ ],
13
+ "license": "MIT",
14
+ "author": {
15
+ "name": "openstatus",
16
+ "url": "https://www.openstatus.dev/"
17
+ },
18
+ "homepage": "https://github.com/openstatusHQ/health",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/openstatusHQ/health.git",
22
+ "directory": "packages/posthog/"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/openstatusHQ/health/issues"
26
+ },
27
+ "type": "module",
28
+ "module": "./dist/mod.js",
29
+ "main": "./dist/mod.cjs",
30
+ "types": "./dist/mod.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "types": {
34
+ "import": "./dist/mod.d.ts",
35
+ "require": "./dist/mod.d.cts"
36
+ },
37
+ "import": "./dist/mod.js",
38
+ "require": "./dist/mod.cjs"
39
+ },
40
+ "./package.json": "./package.json"
41
+ },
42
+ "sideEffects": false,
43
+ "files": [
44
+ "dist/"
45
+ ],
46
+ "engines": {
47
+ "node": ">=22"
48
+ },
49
+ "peerDependencies": {
50
+ "@openstatus/health": "^0.1.4-dev.0"
51
+ },
52
+ "devDependencies": {
53
+ "tsdown": "^0.12.7",
54
+ "typescript": "^5.8.3"
55
+ },
56
+ "scripts": {
57
+ "build": "tsdown",
58
+ "prepack": "tsdown",
59
+ "test": "node --experimental-transform-types --test"
60
+ }
61
+ }