@authhero/cloudflare-adapter 2.34.1 → 2.35.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.
@@ -0,0 +1,33 @@
1
+ import type { DataAdapters } from "@authhero/adapter-interfaces";
2
+ import { type DefaultsPayloadEntities } from "@authhero/multi-tenancy";
3
+ import type { DispatchNamespace } from "../code-executor";
4
+ export interface DispatchSyncDefaultsOptions {
5
+ /** The dispatch namespace binding the tenant workers live in. */
6
+ dispatcher: DispatchNamespace;
7
+ /** Script-name convention. Supports `{tenant_id}`. */
8
+ scriptNameTemplate?: string;
9
+ /**
10
+ * Shared secret the tenant worker checks on `/internal/sync-defaults`
11
+ * (`WFP_INTERNAL_SYNC_SECRET`). Sent as a bearer token.
12
+ */
13
+ internalSecret: string;
14
+ /** The control-plane tenant id whose defaults are projected. */
15
+ controlPlaneTenantId: string;
16
+ /** Adapters for reading the control plane's rows (secrets decrypted). */
17
+ controlPlaneAdapters: DataAdapters;
18
+ /** Which entities to include in the payload. Defaults to all. */
19
+ entities?: DefaultsPayloadEntities;
20
+ /** Per-push timeout. Defaults to 30s. */
21
+ timeoutMs?: number;
22
+ }
23
+ /**
24
+ * Builds a **push** function that projects the control plane's defaults into a
25
+ * single tenant's database over a dispatch namespace.
26
+ *
27
+ * Pure push: the control plane builds the payload with
28
+ * `buildControlPlaneDefaultsPayload` and POSTs it to the tenant worker's
29
+ * `/internal/sync-defaults` route (which applies it). The tenant worker never
30
+ * calls back to the control plane. Use the returned function as the
31
+ * provision-time seed and for on-change / rotation re-syncs.
32
+ */
33
+ export declare function createDispatchSyncDefaults(options: DispatchSyncDefaultsOptions): (tenantId: string) => Promise<void>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `@authhero/cloudflare-adapter/wfp` — the Workers-for-Platforms control-plane
3
+ * sync surface. Kept out of the package's main entry because it imports the
4
+ * app-level packages (`authhero`, `@authhero/multi-tenancy`), which are
5
+ * **optional peer dependencies**: install them only if you import this subpath.
6
+ */
7
+ export { createDispatchSyncDefaults, type DispatchSyncDefaultsOptions, } from "./dispatch-sync-defaults";
8
+ export { createWfpTenantApp, type WfpTenantEnv, type WfpTenantAppOptions, } from "./tenant-app";
@@ -0,0 +1,62 @@
1
+ import { type ExecutionContext } from "hono";
2
+ import { type AuthHeroConfig, type DataAdapters } from "authhero";
3
+ /**
4
+ * Env contract for a WFP tenant worker — the bindings + secrets
5
+ * `createCloudflareWfpD1Provisioner` (and the host's `secrets` resolver) set on
6
+ * each tenant script. `AUTH_DB` is the D1 binding; the rest are plain
7
+ * text / secret text.
8
+ */
9
+ export interface WfpTenantEnv {
10
+ /** Per-tenant D1 binding. Consumed by the host's `createDataAdapter`. */
11
+ AUTH_DB: unknown;
12
+ /** This tenant's own at-rest encryption key (base64, 32 bytes). */
13
+ ENCRYPTION_KEY: string;
14
+ /** This tenant's JWT `iss`. */
15
+ ISSUER: string;
16
+ /** Control-plane tenant id whose projected defaults this worker inherits. */
17
+ CONTROL_PLANE_TENANT_ID: string;
18
+ /**
19
+ * The control plane's own issuer. Accepted in addition to `ISSUER` so a
20
+ * control-plane-minted admin token forwarded here verifies — its signature is
21
+ * checked against the control plane's PUBLIC keys, which are projected into
22
+ * this tenant's DB (no runtime JWKS fetch).
23
+ */
24
+ CONTROL_PLANE_ISSUER: string;
25
+ /**
26
+ * Key for the `cp` key-ring id — encrypts inherited control-plane rows so the
27
+ * tenant operator can hold but not read them. When omitted, a single key is
28
+ * used for everything.
29
+ */
30
+ CONTROL_PLANE_ENCRYPTION_KEY?: string;
31
+ /** Shared secret authenticating control-plane pushes to `/internal/sync-defaults`. */
32
+ WFP_INTERNAL_SYNC_SECRET?: string;
33
+ [key: string]: unknown;
34
+ }
35
+ export interface WfpTenantAppOptions<Env extends WfpTenantEnv = WfpTenantEnv> {
36
+ /**
37
+ * Builds the tenant's **base** data adapters from its env (typically
38
+ * `createAdapters(drizzle(env.AUTH_DB))`). Injected so this package carries no
39
+ * ORM dependency — the host owns the `@authhero/drizzle` (or other) import.
40
+ */
41
+ createDataAdapter: (env: Env) => DataAdapters;
42
+ /**
43
+ * Hook to extend or override the authhero config before `init` — add custom
44
+ * hooks, code executors, `signingKeyMode`, extra issuers, etc. Receives the
45
+ * scaffold's base config and the env.
46
+ */
47
+ configure?: (base: AuthHeroConfig, env: Env) => AuthHeroConfig;
48
+ }
49
+ /**
50
+ * Builds a WFP tenant worker `{ fetch }` handler: key-ring encryption over the
51
+ * tenant's own D1, runtime fallback for inherited control-plane defaults, the
52
+ * `/internal/sync-defaults` push receiver, and the control-plane issuer gate —
53
+ * all from one factory.
54
+ *
55
+ * Pure push: this worker never calls the control plane at request time. Defaults
56
+ * and the control plane's public verify keys arrive only via
57
+ * `/internal/sync-defaults`. The built app is cached per `env` (one build per
58
+ * isolate).
59
+ */
60
+ export declare function createWfpTenantApp<Env extends WfpTenantEnv = WfpTenantEnv>(options: WfpTenantAppOptions<Env>): {
61
+ fetch: (request: Request, env: Env, ctx: ExecutionContext) => Promise<Response>;
62
+ };
@@ -33,12 +33,24 @@ export interface D1QueryResult {
33
33
  meta?: Record<string, unknown>;
34
34
  results?: unknown[];
35
35
  }
36
- export interface ScriptBinding {
37
- type: "d1" | "plain_text" | "secret_text";
36
+ export type ScriptBinding = {
37
+ type: "d1";
38
38
  name: string;
39
- id?: string;
40
- text?: string;
41
- }
39
+ id: string;
40
+ } | {
41
+ type: "plain_text";
42
+ name: string;
43
+ text: string;
44
+ } | {
45
+ type: "secret_text";
46
+ name: string;
47
+ text: string;
48
+ } | {
49
+ type: "service";
50
+ name: string;
51
+ service: string;
52
+ environment?: string;
53
+ };
42
54
  export interface ScriptUploadOptions {
43
55
  /** Script source (JavaScript ES module). */
44
56
  script: string;
@@ -2,5 +2,7 @@ export { createCloudflareWfpD1Provisioner } from "./provisioner";
2
2
  export type { CloudflareWfpD1Provisioner, CloudflareWfpD1ProvisionerOptions, ProvisionResult, ProvisionerMigration, TenantSecretsResolver, } from "./types";
3
3
  export { createWfpTenantProvisioningHook } from "./tenant-hook";
4
4
  export type { WfpTenantProvisioningHook, WfpTenantProvisioningHookOptions, } from "./tenant-hook";
5
+ export { createWfpForwardMiddleware } from "./wfp-forward";
6
+ export type { WfpForwardOptions } from "./wfp-forward";
5
7
  export { CloudflareApiClient, CloudflareApiError } from "./cf-api";
6
8
  export type { CfApiClientOptions, D1Database, D1QueryResult, ScriptBinding, ScriptUploadOptions, } from "./cf-api";
@@ -1,3 +1,4 @@
1
+ import type { ScriptBinding } from "./cf-api";
1
2
  /**
2
3
  * Public types for the Workers-for-Platforms + D1 tenant provisioner.
3
4
  *
@@ -90,6 +91,17 @@ export interface CloudflareWfpD1ProvisionerOptions {
90
91
  * the per-script secrets API.
91
92
  */
92
93
  secrets: TenantSecretsResolver;
94
+ /**
95
+ * Extra bindings to attach to every provisioned tenant worker, appended
96
+ * after the always-present `AUTH_DB` (d1) and `CONTROL_PLANE_BASE_URL`
97
+ * (plain_text) bindings. Use this to wire e.g. a `service` binding to a
98
+ * shared upstream worker, or additional `plain_text` config the tenant
99
+ * bundle expects. Secrets still go through the `secrets` resolver, not here.
100
+ *
101
+ * `uploadNamespacedScript` forwards these verbatim into the CF script
102
+ * metadata, so any binding type the CF API accepts is valid.
103
+ */
104
+ extraBindings?: ScriptBinding[];
93
105
  /**
94
106
  * Naming convention for the namespaced script. Supports `{tenant_id}`
95
107
  * placeholder. Defaults to `"{tenant_id}"`.
@@ -0,0 +1,37 @@
1
+ import type { Context, MiddlewareHandler } from "hono";
2
+ import type { TenantsDataAdapter } from "@authhero/adapter-interfaces";
3
+ export interface WfpForwardOptions {
4
+ /** Tenants adapter, used to look up the resolved tenant's `deployment_type`. */
5
+ tenants: TenantsDataAdapter;
6
+ /**
7
+ * The control-plane tenant id. Requests for this tenant (and anything not a
8
+ * `wfp` tenant) fall through to the local app instead of being dispatched.
9
+ */
10
+ controlPlaneTenantId: string;
11
+ /** Env binding name of the dispatch namespace. Defaults to `"DISPATCHER"`. */
12
+ dispatcherBinding?: string;
13
+ /**
14
+ * Script-name convention for a tenant's worker. Supports `{tenant_id}`.
15
+ * Defaults to `"tenant-{tenant_id}-auth"` — must match the provisioner's
16
+ * `scriptNameTemplate`.
17
+ */
18
+ scriptNameTemplate?: string;
19
+ /**
20
+ * Resolves the tenant id for the incoming request. Defaults to reading the
21
+ * `tenant-id` header (legacy compatibility). Replace it to resolve from a
22
+ * subdomain or custom domain. Return `undefined` to fall through locally.
23
+ */
24
+ resolveTenantId?: (c: Context) => string | undefined | Promise<string | undefined>;
25
+ }
26
+ /**
27
+ * Hono middleware that forwards a request to its tenant's WFP worker over a
28
+ * dispatch namespace, instead of serving it from the current (control-plane)
29
+ * worker.
30
+ *
31
+ * For each request it resolves a tenant id, and **only** dispatches when that
32
+ * tenant exists and has `deployment_type === "wfp"`. The control-plane tenant,
33
+ * unknown tenants, and shared (colocated) tenants all fall through to the next
34
+ * handler so the local app serves them. The tenant worker receives the original
35
+ * request verbatim and owns the full response.
36
+ */
37
+ export declare function createWfpForwardMiddleware(options: WfpForwardOptions): MiddlewareHandler;
package/dist/wfp.cjs ADDED
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@authhero/multi-tenancy"),t=require("hono"),n=require("authhero");var r=`tenant-{tenant_id}-auth`,i=3e4,a=`/internal/sync-defaults`;function o(e,t){return e.replace(/\{tenant_id\}/g,t)}function s(t){let{dispatcher:n,scriptNameTemplate:s=r,internalSecret:c,controlPlaneTenantId:l,controlPlaneAdapters:u,entities:d,timeoutMs:f=i}=t;return async t=>{let r=await(0,e.buildControlPlaneDefaultsPayload)(u,l,d),i=o(s,t),p=new AbortController,m=setTimeout(()=>p.abort(),f),h;try{h=await n.get(i).fetch(`https://tenant.internal${a}`,{method:`POST`,headers:{"content-type":`application/json`,authorization:`Bearer ${c}`},body:JSON.stringify(r),signal:p.signal})}finally{clearTimeout(m)}if(!h.ok){let e=await h.text().catch(()=>``);throw Error(`sync-defaults push to "${i}" failed: ${h.status} ${e.slice(0,256)}`)}}}var c=`cp`,l=`/internal/sync-defaults`;async function u(r,i){let a=r.CONTROL_PLANE_TENANT_ID,o=await(0,n.loadEncryptionKey)(r.ENCRYPTION_KEY),s=r.CONTROL_PLANE_ENCRYPTION_KEY?{default:o,keys:{[c]:await(0,n.loadEncryptionKey)(r.CONTROL_PLANE_ENCRYPTION_KEY)}}:{default:o},u=(0,n.createEncryptedDataAdapterWithKeyRing)(i.createDataAdapter(r),s,{resolveEncryptKeyId:e=>e===a?c:void 0}),d={dataAdapter:(0,e.withRuntimeFallback)(u,{controlPlaneTenantId:a}),additionalIssuers:()=>[r.CONTROL_PLANE_ISSUER]},{app:f}=(0,n.init)(i.configure?i.configure(d,r):d),p=new t.Hono;return p.post(l,async t=>{let n=r.WFP_INTERNAL_SYNC_SECRET,i=t.req.header(`authorization`);if(!n||i!==`Bearer ${n}`)return t.json({error:`unauthorized`},401);let o;try{o=await t.req.json()}catch{return t.json({error:`invalid JSON`},400)}let s=await(0,e.applyControlPlaneDefaultsPayload)(o,u,a);return t.json(s)}),p.route(`/`,f),p}function d(e){let t=new WeakMap;return{fetch(n,r,i){let a=t.get(r);return a||(a=u(r,e),t.set(r,a)),a.then(e=>e.fetch(n,r,i))}}}exports.createDispatchSyncDefaults=s,exports.createWfpTenantApp=d;
package/dist/wfp.d.ts ADDED
@@ -0,0 +1,120 @@
1
+ import { DataAdapters } from '@authhero/adapter-interfaces';
2
+ import { DefaultsPayloadEntities } from '@authhero/multi-tenancy';
3
+ import { ExecutionContext } from 'hono';
4
+ import { DataAdapters as DataAdapters$1, AuthHeroConfig } from 'authhero';
5
+
6
+ /**
7
+ * Cloudflare Workers for Platforms dispatch namespace binding type.
8
+ * This is the type of `env.DISPATCHER` when configured in wrangler.toml:
9
+ *
10
+ * ```toml
11
+ * [[dispatch_namespaces]]
12
+ * binding = "DISPATCHER"
13
+ * namespace = "authhero-hooks"
14
+ * ```
15
+ */
16
+ interface DispatchNamespace {
17
+ get(name: string, options?: Record<string, unknown>, init?: {
18
+ limits?: {
19
+ cpuMs?: number;
20
+ subrequests?: number;
21
+ };
22
+ }): {
23
+ fetch(request: Request | string, init?: RequestInit): Promise<Response>;
24
+ };
25
+ }
26
+
27
+ interface DispatchSyncDefaultsOptions {
28
+ /** The dispatch namespace binding the tenant workers live in. */
29
+ dispatcher: DispatchNamespace;
30
+ /** Script-name convention. Supports `{tenant_id}`. */
31
+ scriptNameTemplate?: string;
32
+ /**
33
+ * Shared secret the tenant worker checks on `/internal/sync-defaults`
34
+ * (`WFP_INTERNAL_SYNC_SECRET`). Sent as a bearer token.
35
+ */
36
+ internalSecret: string;
37
+ /** The control-plane tenant id whose defaults are projected. */
38
+ controlPlaneTenantId: string;
39
+ /** Adapters for reading the control plane's rows (secrets decrypted). */
40
+ controlPlaneAdapters: DataAdapters;
41
+ /** Which entities to include in the payload. Defaults to all. */
42
+ entities?: DefaultsPayloadEntities;
43
+ /** Per-push timeout. Defaults to 30s. */
44
+ timeoutMs?: number;
45
+ }
46
+ /**
47
+ * Builds a **push** function that projects the control plane's defaults into a
48
+ * single tenant's database over a dispatch namespace.
49
+ *
50
+ * Pure push: the control plane builds the payload with
51
+ * `buildControlPlaneDefaultsPayload` and POSTs it to the tenant worker's
52
+ * `/internal/sync-defaults` route (which applies it). The tenant worker never
53
+ * calls back to the control plane. Use the returned function as the
54
+ * provision-time seed and for on-change / rotation re-syncs.
55
+ */
56
+ declare function createDispatchSyncDefaults(options: DispatchSyncDefaultsOptions): (tenantId: string) => Promise<void>;
57
+
58
+ /**
59
+ * Env contract for a WFP tenant worker — the bindings + secrets
60
+ * `createCloudflareWfpD1Provisioner` (and the host's `secrets` resolver) set on
61
+ * each tenant script. `AUTH_DB` is the D1 binding; the rest are plain
62
+ * text / secret text.
63
+ */
64
+ interface WfpTenantEnv {
65
+ /** Per-tenant D1 binding. Consumed by the host's `createDataAdapter`. */
66
+ AUTH_DB: unknown;
67
+ /** This tenant's own at-rest encryption key (base64, 32 bytes). */
68
+ ENCRYPTION_KEY: string;
69
+ /** This tenant's JWT `iss`. */
70
+ ISSUER: string;
71
+ /** Control-plane tenant id whose projected defaults this worker inherits. */
72
+ CONTROL_PLANE_TENANT_ID: string;
73
+ /**
74
+ * The control plane's own issuer. Accepted in addition to `ISSUER` so a
75
+ * control-plane-minted admin token forwarded here verifies — its signature is
76
+ * checked against the control plane's PUBLIC keys, which are projected into
77
+ * this tenant's DB (no runtime JWKS fetch).
78
+ */
79
+ CONTROL_PLANE_ISSUER: string;
80
+ /**
81
+ * Key for the `cp` key-ring id — encrypts inherited control-plane rows so the
82
+ * tenant operator can hold but not read them. When omitted, a single key is
83
+ * used for everything.
84
+ */
85
+ CONTROL_PLANE_ENCRYPTION_KEY?: string;
86
+ /** Shared secret authenticating control-plane pushes to `/internal/sync-defaults`. */
87
+ WFP_INTERNAL_SYNC_SECRET?: string;
88
+ [key: string]: unknown;
89
+ }
90
+ interface WfpTenantAppOptions<Env extends WfpTenantEnv = WfpTenantEnv> {
91
+ /**
92
+ * Builds the tenant's **base** data adapters from its env (typically
93
+ * `createAdapters(drizzle(env.AUTH_DB))`). Injected so this package carries no
94
+ * ORM dependency — the host owns the `@authhero/drizzle` (or other) import.
95
+ */
96
+ createDataAdapter: (env: Env) => DataAdapters$1;
97
+ /**
98
+ * Hook to extend or override the authhero config before `init` — add custom
99
+ * hooks, code executors, `signingKeyMode`, extra issuers, etc. Receives the
100
+ * scaffold's base config and the env.
101
+ */
102
+ configure?: (base: AuthHeroConfig, env: Env) => AuthHeroConfig;
103
+ }
104
+ /**
105
+ * Builds a WFP tenant worker `{ fetch }` handler: key-ring encryption over the
106
+ * tenant's own D1, runtime fallback for inherited control-plane defaults, the
107
+ * `/internal/sync-defaults` push receiver, and the control-plane issuer gate —
108
+ * all from one factory.
109
+ *
110
+ * Pure push: this worker never calls the control plane at request time. Defaults
111
+ * and the control plane's public verify keys arrive only via
112
+ * `/internal/sync-defaults`. The built app is cached per `env` (one build per
113
+ * isolate).
114
+ */
115
+ declare function createWfpTenantApp<Env extends WfpTenantEnv = WfpTenantEnv>(options: WfpTenantAppOptions<Env>): {
116
+ fetch: (request: Request, env: Env, ctx: ExecutionContext) => Promise<Response>;
117
+ };
118
+
119
+ export { createDispatchSyncDefaults, createWfpTenantApp };
120
+ export type { DispatchSyncDefaultsOptions, WfpTenantAppOptions, WfpTenantEnv };
package/dist/wfp.mjs ADDED
@@ -0,0 +1,64 @@
1
+ import { applyControlPlaneDefaultsPayload as e, buildControlPlaneDefaultsPayload as t, withRuntimeFallback as n } from "@authhero/multi-tenancy";
2
+ import { Hono as r } from "hono";
3
+ import { createEncryptedDataAdapterWithKeyRing as i, init as a, loadEncryptionKey as o } from "authhero";
4
+ //#region src/wfp/dispatch-sync-defaults.ts
5
+ var s = "tenant-{tenant_id}-auth", c = 3e4, l = "/internal/sync-defaults";
6
+ function u(e, t) {
7
+ return e.replace(/\{tenant_id\}/g, t);
8
+ }
9
+ function d(e) {
10
+ let { dispatcher: n, scriptNameTemplate: r = s, internalSecret: i, controlPlaneTenantId: a, controlPlaneAdapters: o, entities: d, timeoutMs: f = c } = e;
11
+ return async (e) => {
12
+ let s = await t(o, a, d), c = u(r, e), p = new AbortController(), m = setTimeout(() => p.abort(), f), h;
13
+ try {
14
+ h = await n.get(c).fetch(`https://tenant.internal${l}`, {
15
+ method: "POST",
16
+ headers: {
17
+ "content-type": "application/json",
18
+ authorization: `Bearer ${i}`
19
+ },
20
+ body: JSON.stringify(s),
21
+ signal: p.signal
22
+ });
23
+ } finally {
24
+ clearTimeout(m);
25
+ }
26
+ if (!h.ok) {
27
+ let e = await h.text().catch(() => "");
28
+ throw Error(`sync-defaults push to "${c}" failed: ${h.status} ${e.slice(0, 256)}`);
29
+ }
30
+ };
31
+ }
32
+ //#endregion
33
+ //#region src/wfp/tenant-app.ts
34
+ var f = "cp", p = "/internal/sync-defaults";
35
+ async function m(t, s) {
36
+ let c = t.CONTROL_PLANE_TENANT_ID, l = await o(t.ENCRYPTION_KEY), u = t.CONTROL_PLANE_ENCRYPTION_KEY ? {
37
+ default: l,
38
+ keys: { [f]: await o(t.CONTROL_PLANE_ENCRYPTION_KEY) }
39
+ } : { default: l }, d = i(s.createDataAdapter(t), u, { resolveEncryptKeyId: (e) => e === c ? f : void 0 }), m = {
40
+ dataAdapter: n(d, { controlPlaneTenantId: c }),
41
+ additionalIssuers: () => [t.CONTROL_PLANE_ISSUER]
42
+ }, { app: h } = a(s.configure ? s.configure(m, t) : m), g = new r();
43
+ return g.post(p, async (n) => {
44
+ let r = t.WFP_INTERNAL_SYNC_SECRET, i = n.req.header("authorization");
45
+ if (!r || i !== `Bearer ${r}`) return n.json({ error: "unauthorized" }, 401);
46
+ let a;
47
+ try {
48
+ a = await n.req.json();
49
+ } catch {
50
+ return n.json({ error: "invalid JSON" }, 400);
51
+ }
52
+ let o = await e(a, d, c);
53
+ return n.json(o);
54
+ }), g.route("/", h), g;
55
+ }
56
+ function h(e) {
57
+ let t = /* @__PURE__ */ new WeakMap();
58
+ return { fetch(n, r, i) {
59
+ let a = t.get(r);
60
+ return a || (a = m(r, e), t.set(r, a)), a.then((e) => e.fetch(n, r, i));
61
+ } };
62
+ }
63
+ //#endregion
64
+ export { d as createDispatchSyncDefaults, h as createWfpTenantApp };
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "type": "git",
12
12
  "url": "https://github.com/markusahlstrand/authhero"
13
13
  },
14
- "version": "2.34.1",
14
+ "version": "2.35.0",
15
15
  "files": [
16
16
  "dist"
17
17
  ],
@@ -23,6 +23,11 @@
23
23
  "types": "./dist/cloudflare-adapter.d.ts",
24
24
  "require": "./dist/cloudflare-adapter.cjs",
25
25
  "import": "./dist/cloudflare-adapter.mjs"
26
+ },
27
+ "./wfp": {
28
+ "types": "./dist/wfp.d.ts",
29
+ "require": "./dist/wfp.cjs",
30
+ "import": "./dist/wfp.mjs"
26
31
  }
27
32
  },
28
33
  "devDependencies": {
@@ -36,12 +41,24 @@
36
41
  "rollup-plugin-dts": "^6.4.1",
37
42
  "typescript": "^5.9.3",
38
43
  "vite": "^8.0.14",
39
- "vitest": "^4.1.7"
44
+ "vitest": "^4.1.7",
45
+ "@authhero/multi-tenancy": "14.25.0",
46
+ "authhero": "8.5.0"
40
47
  },
41
48
  "peerDependencies": {
49
+ "@authhero/multi-tenancy": "^14.0.0",
42
50
  "@hono/zod-openapi": "^1.4.0",
51
+ "authhero": "^3.0.0",
43
52
  "hono": "^4.6.8"
44
53
  },
54
+ "peerDependenciesMeta": {
55
+ "@authhero/multi-tenancy": {
56
+ "optional": true
57
+ },
58
+ "authhero": {
59
+ "optional": true
60
+ }
61
+ },
45
62
  "dependencies": {
46
63
  "nanoid": "^5.1.11",
47
64
  "wretch": "^3.0.8",