@ooky/sdk 0.5.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -3,6 +3,19 @@
3
3
  All notable changes to `@ooky/sdk`. Versions follow [semver](https://semver.org);
4
4
  pre-1.0, minor versions may include breaking changes (called out explicitly).
5
5
 
6
+ ## 0.6.0 — 2026-06-19
7
+
8
+ ### Fixed
9
+ - **Middleware fails safe on missing config (high).** `createOokyHandler` throws
10
+ when `apiKey`/`domain` are missing, and the adapters built the handler at
11
+ module load — so an unset or typo'd `OOKY_API_KEY` / `OOKY_DOMAIN` threw on
12
+ construction and **500'd the customer's entire site** (the middleware runs on
13
+ every request, e.g. Vercel's `MIDDLEWARE_INVOCATION_FAILED`). The Express,
14
+ Next, and Edge adapters now wrap construction: on failure they log one loud
15
+ line and return a pass-through middleware, so a misconfigured integration
16
+ disables Ooky **without taking down the host app**. Complements the existing
17
+ per-request pass-through hardening.
18
+
6
19
  ## 0.5.0 — 2026-06-12
7
20
 
8
21
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ooky/sdk",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Ooky SDK — middleware for serving AI brand intelligence and capturing AI-bot analytics from your Node, Next.js, or Vercel Edge app.",
5
5
  "keywords": [
6
6
  "ai",
package/src/core.js CHANGED
@@ -19,7 +19,7 @@ import { detectBot as detectFromList, DEFAULT_BOTS, sanitizeBotRegistry } from "
19
19
  import { detectAIReferral } from "./referrals.js";
20
20
  import { handleMcpJsonRpc, McpToolError } from "./mcp.js";
21
21
 
22
- export const SDK_VERSION = "0.5.0";
22
+ export const SDK_VERSION = "0.6.0";
23
23
 
24
24
  // Defensive length caps on untrusted strings copied into the event payload.
25
25
  // The load-bearing clamp is server-side (owned by the backend), but capping
@@ -33,6 +33,25 @@ export function clampString(value, max) {
33
33
  return value.length > max ? value.slice(0, max) : value;
34
34
  }
35
35
 
36
+ /**
37
+ * Log (loudly) that the middleware could not be constructed — almost always a
38
+ * missing/invalid OOKY_API_KEY or OOKY_DOMAIN. The adapters call this and then
39
+ * return a pass-through middleware: a misconfigured integration must NEVER take
40
+ * down the customer's site (the middleware runs on every request). Never throws.
41
+ */
42
+ export function logMiddlewareDisabled(err) {
43
+ const msg = err && err.message ? err.message : String(err);
44
+ try {
45
+ console.error(
46
+ `[@ooky/sdk] Middleware disabled — ${msg}. Requests pass through ` +
47
+ `untouched (your app is unaffected); Ooky features are inactive. ` +
48
+ `Check that OOKY_API_KEY and OOKY_DOMAIN are set.`
49
+ );
50
+ } catch {
51
+ // console may be unavailable in exotic runtimes — never throw from here.
52
+ }
53
+ }
54
+
36
55
  /**
37
56
  * Hard cap on the MCP request body the adapters will read before answering.
38
57
  * The Express adapter enforces this while streaming; the Next/Edge adapter
package/src/express.js CHANGED
@@ -10,6 +10,7 @@
10
10
 
11
11
  import {
12
12
  createOokyHandler,
13
+ logMiddlewareDisabled,
13
14
  MAX_MCP_BODY_BYTES,
14
15
  MAX_UA_LENGTH,
15
16
  MAX_PATH_LENGTH,
@@ -17,7 +18,19 @@ import {
17
18
  } from "./core.js";
18
19
 
19
20
  export function ookyMiddleware(options) {
20
- const handler = createOokyHandler(options);
21
+ let handler;
22
+ try {
23
+ handler = createOokyHandler(options);
24
+ } catch (err) {
25
+ // Construction failed (almost always missing OOKY_API_KEY / OOKY_DOMAIN).
26
+ // This middleware is mounted on every request, so throwing here would take
27
+ // down the customer's whole app. Fail safe: log loudly, return a no-op that
28
+ // simply calls next().
29
+ logMiddlewareDisabled(err);
30
+ return function ookyHandlerDisabled(req, res, next) {
31
+ return next();
32
+ };
33
+ }
21
34
 
22
35
  return async function ookyHandler(req, res, next) {
23
36
  const rawUa = req.headers["user-agent"] || "";
package/src/next.js CHANGED
@@ -13,10 +13,21 @@
13
13
  * bot / ai_referral analytics events.
14
14
  */
15
15
 
16
- import { createOokyHandler, MAX_MCP_BODY_BYTES, MAX_UA_LENGTH, MAX_PATH_LENGTH, clampString } from "./core.js";
16
+ import { createOokyHandler, logMiddlewareDisabled, MAX_MCP_BODY_BYTES, MAX_UA_LENGTH, MAX_PATH_LENGTH, clampString } from "./core.js";
17
17
 
18
18
  export function ookyMiddleware(options) {
19
- const handler = createOokyHandler(options);
19
+ let handler;
20
+ try {
21
+ handler = createOokyHandler(options);
22
+ } catch (err) {
23
+ // Construction failed (almost always missing OOKY_API_KEY / OOKY_DOMAIN).
24
+ // The middleware runs on every request, so throwing here would 500 the
25
+ // customer's entire site. Fail safe: log loudly, return a pass-through.
26
+ logMiddlewareDisabled(err);
27
+ return function ookyNextMiddlewareDisabled() {
28
+ return undefined; // Next continues to the route — app unaffected.
29
+ };
30
+ }
20
31
 
21
32
  return async function ookyNextMiddleware(request, event) {
22
33
  const url = new URL(request.url);