theokit 0.48.8 → 0.48.9
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 +86 -0
- package/dist/{actions-virtual-module-IICWQK43.js → actions-virtual-module-LB4NGONI.js} +2 -2
- package/dist/{agent-WZLCEXD4.js → agent-SK4TOO6M.js} +2 -2
- package/dist/{app-typed-client-4GDSR5T3.js → app-typed-client-G3J5G7E5.js} +2 -2
- package/dist/{build-5TKAROT4.js → build-FMRO4W4Q.js} +4 -4
- package/dist/{chunk-ABUVJU3P.js → chunk-BIVCP6X5.js} +2 -1
- package/dist/{chunk-UDPJP42U.js → chunk-GPX7I5ZY.js} +31 -4
- package/dist/chunk-GPX7I5ZY.js.map +1 -0
- package/dist/{chunk-RPIL7VRZ.js → chunk-GRI4XHBJ.js} +2 -2
- package/dist/{chunk-A4ZEP3FE.js → chunk-GVW5EKEU.js} +11 -2
- package/dist/chunk-GVW5EKEU.js.map +1 -0
- package/dist/{chunk-ZGNA66JK.js → chunk-Q2S2IGSM.js} +7 -7
- package/dist/{chunk-GH32R55S.js → chunk-S433N3CT.js} +2 -2
- package/dist/{chunk-HENNMZUH.js → chunk-SO64VQOD.js} +4 -4
- package/dist/chunk-V7MTRM6Q.js +90 -0
- package/dist/chunk-V7MTRM6Q.js.map +1 -0
- package/dist/{chunk-XSCZWSE3.js → chunk-YML4ZDFA.js} +11 -2
- package/dist/chunk-YML4ZDFA.js.map +1 -0
- package/dist/cli/index.js +19 -9
- package/dist/cli/index.js.map +1 -1
- package/dist/cookies-QWVS7OGS.js +23 -0
- package/dist/{dev-XGAJQ7DH.js → dev-P2MODWTG.js} +6 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/{info-MSBQ72EM.js → info-XW7HGUPH.js} +3 -3
- package/dist/{internal-api-AKYIRMT2.js → internal-api-V5L65YSJ.js} +2 -2
- package/dist/{load-config-2LP2OEKD.js → load-config-VKD6LKWU.js} +3 -3
- package/dist/{mcp-D7K6NJMW.js → mcp-EQHTPQ2L.js} +3 -3
- package/dist/{openapi-FWNYHB6T.js → openapi-HZXR335W.js} +3 -3
- package/dist/{routes-6AMNVFMI.js → routes-OLNQX7CT.js} +3 -3
- package/dist/{schema-Z3Y7SFLE.js → schema-ZO3OSWVG.js} +2 -2
- package/dist/server/index.js +1 -1
- package/dist/server/rate-limit/index.d.ts +49 -1
- package/dist/server/rate-limit/index.js +1 -1
- package/dist/{start-YR4TQQP2.js → start-KR2JJR7K.js} +142 -15
- package/dist/start-KR2JJR7K.js.map +1 -0
- package/dist/vite-plugin/index.js +1 -1
- package/dist/{vite-plugin-PUUCR6LR.js → vite-plugin-EQMDMDXV.js} +6 -6
- package/dist/vite-plugin-EQMDMDXV.js.map +1 -0
- package/package.json +11 -1
- package/dist/chunk-A4ZEP3FE.js.map +0 -1
- package/dist/chunk-UDPJP42U.js.map +0 -1
- package/dist/chunk-XSCZWSE3.js.map +0 -1
- package/dist/start-YR4TQQP2.js.map +0 -1
- /package/dist/{actions-virtual-module-IICWQK43.js.map → actions-virtual-module-LB4NGONI.js.map} +0 -0
- /package/dist/{agent-WZLCEXD4.js.map → agent-SK4TOO6M.js.map} +0 -0
- /package/dist/{app-typed-client-4GDSR5T3.js.map → app-typed-client-G3J5G7E5.js.map} +0 -0
- /package/dist/{build-5TKAROT4.js.map → build-FMRO4W4Q.js.map} +0 -0
- /package/dist/{chunk-ABUVJU3P.js.map → chunk-BIVCP6X5.js.map} +0 -0
- /package/dist/{chunk-RPIL7VRZ.js.map → chunk-GRI4XHBJ.js.map} +0 -0
- /package/dist/{chunk-ZGNA66JK.js.map → chunk-Q2S2IGSM.js.map} +0 -0
- /package/dist/{chunk-GH32R55S.js.map → chunk-S433N3CT.js.map} +0 -0
- /package/dist/{chunk-HENNMZUH.js.map → chunk-SO64VQOD.js.map} +0 -0
- /package/dist/{internal-api-AKYIRMT2.js.map → cookies-QWVS7OGS.js.map} +0 -0
- /package/dist/{dev-XGAJQ7DH.js.map → dev-P2MODWTG.js.map} +0 -0
- /package/dist/{info-MSBQ72EM.js.map → info-XW7HGUPH.js.map} +0 -0
- /package/dist/{load-config-2LP2OEKD.js.map → internal-api-V5L65YSJ.js.map} +0 -0
- /package/dist/{schema-Z3Y7SFLE.js.map → load-config-VKD6LKWU.js.map} +0 -0
- /package/dist/{mcp-D7K6NJMW.js.map → mcp-EQHTPQ2L.js.map} +0 -0
- /package/dist/{openapi-FWNYHB6T.js.map → openapi-HZXR335W.js.map} +0 -0
- /package/dist/{routes-6AMNVFMI.js.map → routes-OLNQX7CT.js.map} +0 -0
- /package/dist/{vite-plugin-PUUCR6LR.js.map → schema-ZO3OSWVG.js.map} +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# `theokit`
|
|
2
|
+
|
|
3
|
+
**Build the app your agent lives in.** Routing, auth, real-time, deploy — wired.
|
|
4
|
+
|
|
5
|
+
This is the framework core: the file-based router, the server surfaces, the Vite plugin, the CLI,
|
|
6
|
+
the deploy adapters and the devtools. The agent pipeline lives in
|
|
7
|
+
[`@theokit/agents`](https://www.npmjs.com/package/@theokit/agents), the decorator pipeline in
|
|
8
|
+
[`@theokit/http`](https://www.npmjs.com/package/@theokit/http), and the runtime in
|
|
9
|
+
[`@theokit/sdk`](https://www.npmjs.com/package/@theokit/sdk) — TheoKit compiles and serves; the SDK
|
|
10
|
+
runs the agent.
|
|
11
|
+
|
|
12
|
+
Full documentation, examples and the changelog live in the
|
|
13
|
+
[repository](https://github.com/usetheokit/theokit#readme).
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
Scaffold rather than install by hand — the app layout is a convention the framework reads:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx create-theokit my-app
|
|
21
|
+
cd my-app
|
|
22
|
+
pnpm dev
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Node `>= 22.12.0`. Peers: `react`, `react-dom`, `react-router`, `zod`, and — where you use them —
|
|
26
|
+
`@theokit/sdk`, `@theokit/ui`, `@theokit/studio`, `ws`, `db0`, `unstorage`.
|
|
27
|
+
|
|
28
|
+
## The conventions
|
|
29
|
+
|
|
30
|
+
| Put a file here | Get |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `app/page.tsx` | the `/` route (`layout` · `loading` · `error` · `not-found` beside it) |
|
|
33
|
+
| `app/(group)/pricing/page.tsx` | `/pricing` — the group organizes without entering the URL |
|
|
34
|
+
| `agents/support.ts` | `POST /api/agents/support`, bound on the client by `useAgent` |
|
|
35
|
+
| `server/routes/users.ts` | `/api/users`, one export per HTTP verb |
|
|
36
|
+
| `server/actions/*.ts` | server actions, with CSRF and validation handled |
|
|
37
|
+
| `server/controllers/*.ts` | `@Controller` classes |
|
|
38
|
+
| `server/ws/chat.ts` | `ws://…/ws/chat` |
|
|
39
|
+
| `server/middleware/01-cors.ts` | request middleware, in filename order |
|
|
40
|
+
|
|
41
|
+
## Authoring surfaces
|
|
42
|
+
|
|
43
|
+
Every surface is a fluent builder whose `.build()` is a compile error while a required link is
|
|
44
|
+
missing:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { route, action, websocket, middleware, tool, plugin } from 'theokit/server'
|
|
48
|
+
|
|
49
|
+
export const GET = route()
|
|
50
|
+
.query(z.object({ search: z.string().optional() }))
|
|
51
|
+
.handler(({ query }) => ({ results: search(query.search) }))
|
|
52
|
+
.build()
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Subpaths
|
|
56
|
+
|
|
57
|
+
| Subpath | What lives there |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `.` | `config()` and the framework entry |
|
|
60
|
+
| `./server` | The authoring builders plus every `server/*` capability re-exported |
|
|
61
|
+
| `./server/{agent,auth,cost,cron,define,http,jobs,observability,plugins,rate-limit,realtime,scan,security,storage,webhook}` | The capabilities on their own doors |
|
|
62
|
+
| `./client` | `theoFetch`, `useAgent`, `Link`, `Metadata`, `Image`, the transports |
|
|
63
|
+
| `./client/core` | The framework-agnostic client (no React) |
|
|
64
|
+
| `./react-query` | The TanStack Query adapter over `theoFetch` |
|
|
65
|
+
| `./vite-plugin` | The plugin that makes all of the above work |
|
|
66
|
+
| `./boot`, `./adapters/web-shim`, `./adapters/ws-shim` | Runtime shims |
|
|
67
|
+
|
|
68
|
+
## CLI
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
theokit dev | build | start # build takes --target <adapter>
|
|
72
|
+
theokit generate <type> <name> # page, route, action, ws, controller, agent, toolbox, …
|
|
73
|
+
theokit agent <name> [message] # run an agent in the terminal, approvals included
|
|
74
|
+
theokit routes | check | doctor | info
|
|
75
|
+
theokit openapi | db <action> | migrate <kind> | docker | add <package>
|
|
76
|
+
theokit mcp <agent> # serve an agent as an MCP server over stdio
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Deploy
|
|
80
|
+
|
|
81
|
+
`theokit build --target <name>`: `node` (default), `theo-cloud`, `vercel`, `netlify`,
|
|
82
|
+
`cloudflare`, `bun`, `deno-deploy`, `aws-lambda`, `static`.
|
|
83
|
+
|
|
84
|
+
## Licence
|
|
85
|
+
|
|
86
|
+
Apache-2.0 — see `LICENSE`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "tsx/esm";
|
|
3
|
-
import "./chunk-
|
|
3
|
+
import "./chunk-BIVCP6X5.js";
|
|
4
4
|
import "./chunk-6GGWS7J3.js";
|
|
5
5
|
import "./chunk-T5C46IIU.js";
|
|
6
6
|
import "./chunk-ZB7D62OA.js";
|
|
@@ -212,4 +212,4 @@ export const actions = manifest
|
|
|
212
212
|
export {
|
|
213
213
|
actionsVirtualModule
|
|
214
214
|
};
|
|
215
|
-
//# sourceMappingURL=actions-virtual-module-
|
|
215
|
+
//# sourceMappingURL=actions-virtual-module-LB4NGONI.js.map
|
|
@@ -3,7 +3,7 @@ import "tsx/esm";
|
|
|
3
3
|
import {
|
|
4
4
|
agentCommand,
|
|
5
5
|
createAgentSsrLoader
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SO64VQOD.js";
|
|
7
7
|
import "./chunk-HBU2GIMZ.js";
|
|
8
8
|
import "./chunk-6GGWS7J3.js";
|
|
9
9
|
import "./chunk-LNVMHQ2Z.js";
|
|
@@ -12,4 +12,4 @@ export {
|
|
|
12
12
|
agentCommand,
|
|
13
13
|
createAgentSsrLoader
|
|
14
14
|
};
|
|
15
|
-
//# sourceMappingURL=agent-
|
|
15
|
+
//# sourceMappingURL=agent-SK4TOO6M.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "tsx/esm";
|
|
3
|
-
import "./chunk-
|
|
3
|
+
import "./chunk-BIVCP6X5.js";
|
|
4
4
|
import "./chunk-6GGWS7J3.js";
|
|
5
5
|
import {
|
|
6
6
|
scanControllerModules
|
|
@@ -414,4 +414,4 @@ export {
|
|
|
414
414
|
generateClientDts,
|
|
415
415
|
shouldReemitForFile
|
|
416
416
|
};
|
|
417
|
-
//# sourceMappingURL=app-typed-client-
|
|
417
|
+
//# sourceMappingURL=app-typed-client-G3J5G7E5.js.map
|
|
@@ -17,11 +17,11 @@ import {
|
|
|
17
17
|
import {
|
|
18
18
|
importUserModule,
|
|
19
19
|
loadConfig
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-S433N3CT.js";
|
|
21
21
|
import {
|
|
22
22
|
loadEnv
|
|
23
23
|
} from "./chunk-HBU2GIMZ.js";
|
|
24
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-GVW5EKEU.js";
|
|
25
25
|
import {
|
|
26
26
|
buildManifest,
|
|
27
27
|
writeManifest
|
|
@@ -543,7 +543,7 @@ async function buildCommand(options) {
|
|
|
543
543
|
`);
|
|
544
544
|
}
|
|
545
545
|
async function runAdapterBuild(target, config, cwd) {
|
|
546
|
-
const { theoPluginAsync } = await import("./vite-plugin-
|
|
546
|
+
const { theoPluginAsync } = await import("./vite-plugin-EQMDMDXV.js");
|
|
547
547
|
const { default: react } = await import("@vitejs/plugin-react");
|
|
548
548
|
const ctx = {
|
|
549
549
|
// `react()` may return Plugin or Plugin[] depending on version; spread the
|
|
@@ -629,4 +629,4 @@ function relativize3(absPath, root) {
|
|
|
629
629
|
export {
|
|
630
630
|
buildCommand
|
|
631
631
|
};
|
|
632
|
-
//# sourceMappingURL=build-
|
|
632
|
+
//# sourceMappingURL=build-FMRO4W4Q.js.map
|
|
@@ -2314,6 +2314,7 @@ export {
|
|
|
2314
2314
|
extractTraceId,
|
|
2315
2315
|
findSuggestion,
|
|
2316
2316
|
createPluginRunnerFromConfig,
|
|
2317
|
+
InMemoryStore,
|
|
2317
2318
|
createRateLimiter,
|
|
2318
2319
|
makeThreadStartRun,
|
|
2319
2320
|
SSE_BASE_HEADERS,
|
|
@@ -2335,4 +2336,4 @@ export {
|
|
|
2335
2336
|
applySecurityHeaders,
|
|
2336
2337
|
generateNonce
|
|
2337
2338
|
};
|
|
2338
|
-
//# sourceMappingURL=chunk-
|
|
2339
|
+
//# sourceMappingURL=chunk-BIVCP6X5.js.map
|
|
@@ -5,6 +5,32 @@ import {
|
|
|
5
5
|
parseCookieHeader
|
|
6
6
|
} from "./chunk-4FWBKX6G.js";
|
|
7
7
|
|
|
8
|
+
// src/server/rate-limit/client-ip.ts
|
|
9
|
+
function hopCount(trustProxy) {
|
|
10
|
+
if (trustProxy === true) return 1;
|
|
11
|
+
if (trustProxy === false) return 0;
|
|
12
|
+
return trustProxy;
|
|
13
|
+
}
|
|
14
|
+
function headerValue(req, name) {
|
|
15
|
+
const raw = req.headers[name];
|
|
16
|
+
if (Array.isArray(raw)) return raw[raw.length - 1];
|
|
17
|
+
return raw;
|
|
18
|
+
}
|
|
19
|
+
function resolveClientIp(req, trustProxy = false) {
|
|
20
|
+
const socketAddress = req.socket?.remoteAddress ?? "unknown";
|
|
21
|
+
const hops = hopCount(trustProxy);
|
|
22
|
+
if (hops < 1) return socketAddress;
|
|
23
|
+
const forwarded = headerValue(req, "x-forwarded-for");
|
|
24
|
+
if (forwarded) {
|
|
25
|
+
const entries = forwarded.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
26
|
+
const index = entries.length - hops;
|
|
27
|
+
if (index >= 0 && index < entries.length) return entries[index];
|
|
28
|
+
}
|
|
29
|
+
const realIp = headerValue(req, "x-real-ip");
|
|
30
|
+
if (realIp) return realIp.trim();
|
|
31
|
+
return socketAddress;
|
|
32
|
+
}
|
|
33
|
+
|
|
8
34
|
// src/server/rate-limit/rate-limit-per-route.ts
|
|
9
35
|
function normalizePath(input) {
|
|
10
36
|
const noQuery = input.split("?")[0];
|
|
@@ -30,9 +56,9 @@ async function hashFragment(input) {
|
|
|
30
56
|
function readCookie(req, name) {
|
|
31
57
|
return parseCookieHeader(req.headers.cookie ?? void 0).get(name);
|
|
32
58
|
}
|
|
33
|
-
async function deriveKey(req, keyBy, cookieName) {
|
|
59
|
+
async function deriveKey(req, keyBy, cookieName, trustProxy = false) {
|
|
34
60
|
if (typeof keyBy === "function") return keyBy(req);
|
|
35
|
-
const ip = req
|
|
61
|
+
const ip = resolveClientIp(req, trustProxy);
|
|
36
62
|
switch (keyBy) {
|
|
37
63
|
case "session": {
|
|
38
64
|
const cookie = readCookie(req, cookieName);
|
|
@@ -59,6 +85,7 @@ function createRouteRateLimiter(config) {
|
|
|
59
85
|
const inMemoryStore = store;
|
|
60
86
|
const keyBy = cfg.keyBy ?? "ip";
|
|
61
87
|
const cookieName = cfg.cookieName ?? "theo_session";
|
|
88
|
+
const trustProxy = cfg.trustProxy ?? false;
|
|
62
89
|
const patternList = [];
|
|
63
90
|
if (cfg.routes) {
|
|
64
91
|
for (const [pattern, c] of Object.entries(cfg.routes)) patternList.push([pattern, c]);
|
|
@@ -80,7 +107,7 @@ function createRouteRateLimiter(config) {
|
|
|
80
107
|
return { limited: false, headers: {} };
|
|
81
108
|
}
|
|
82
109
|
const bucketSuffix = typeof matched === "undefined" ? "*default*" : normalizePath(url);
|
|
83
|
-
const key = `${await deriveKey(req, keyBy, cookieName)}|${bucketSuffix}`;
|
|
110
|
+
const key = `${await deriveKey(req, keyBy, cookieName, trustProxy)}|${bucketSuffix}`;
|
|
84
111
|
const state = inMemoryStore.incrSync(key, effective.windowMs);
|
|
85
112
|
if (state.count > effective.max) {
|
|
86
113
|
const retryAfter = Math.ceil((state.resetAt - Date.now()) / 1e3);
|
|
@@ -182,4 +209,4 @@ export {
|
|
|
182
209
|
deriveKeyFromRequest,
|
|
183
210
|
createRouteRateLimiterWeb
|
|
184
211
|
};
|
|
185
|
-
//# sourceMappingURL=chunk-
|
|
212
|
+
//# sourceMappingURL=chunk-GPX7I5ZY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/rate-limit/client-ip.ts","../src/server/rate-limit/rate-limit-per-route.ts"],"mappings":"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","names":[]}
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
makeThreadStartRun,
|
|
21
21
|
mintRunId,
|
|
22
22
|
parseAgentRequestBody
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-BIVCP6X5.js";
|
|
24
24
|
import {
|
|
25
25
|
getApprovalRegistry
|
|
26
26
|
} from "./chunk-6GGWS7J3.js";
|
|
@@ -709,4 +709,4 @@ export {
|
|
|
709
709
|
applyNonceToInlineScripts,
|
|
710
710
|
setupSsrDevMiddleware
|
|
711
711
|
};
|
|
712
|
-
//# sourceMappingURL=chunk-
|
|
712
|
+
//# sourceMappingURL=chunk-GRI4XHBJ.js.map
|
|
@@ -25,7 +25,16 @@ var rateLimitSchema = z.union([
|
|
|
25
25
|
z.enum(["ip", "session", "user"]),
|
|
26
26
|
z.function({ input: z.tuple([z.unknown()]), output: z.string() })
|
|
27
27
|
]).optional(),
|
|
28
|
-
cookieName: z.string().min(1).optional()
|
|
28
|
+
cookieName: z.string().min(1).optional(),
|
|
29
|
+
/**
|
|
30
|
+
* How many reverse proxies sit in front of the app, for `keyBy: 'ip'`. `false` (default)
|
|
31
|
+
* trusts none; `true` means one; a number names a longer chain.
|
|
32
|
+
*
|
|
33
|
+
* Required for correct limiting behind Caddy/nginx/a load balancer — without it every visitor
|
|
34
|
+
* keys on the proxy address and shares a single bucket. Off by default because
|
|
35
|
+
* `x-forwarded-for` is client-writable.
|
|
36
|
+
*/
|
|
37
|
+
trustProxy: z.union([z.boolean(), z.number().int().min(0)]).optional()
|
|
29
38
|
})
|
|
30
39
|
]);
|
|
31
40
|
|
|
@@ -410,4 +419,4 @@ export {
|
|
|
410
419
|
storageSchema,
|
|
411
420
|
theoConfigSchema
|
|
412
421
|
};
|
|
413
|
-
//# sourceMappingURL=chunk-
|
|
422
|
+
//# sourceMappingURL=chunk-GVW5EKEU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config/schema.ts","../src/core/contracts/theo-ui-theme.ts","../src/config/schemas/rate-limit.ts","../src/config/schemas/upload.ts","../src/config/schemas/logging.ts","../src/config/schemas/cache.ts","../src/config/schemas/security.ts","../src/config/schemas/header-safe.ts","../src/config/schemas/storage.ts"],"sourcesContent":["import { z } from 'zod'\n\nimport { THEME_NAME_PATTERN } from '../core/contracts/theo-ui-theme.js'\nimport { servicesConfigSchema } from '../services/index.js'\n\nimport {\n cacheSchema,\n loggingSchema,\n rateLimitSchema,\n securitySchema,\n storageSchema,\n uploadSchema,\n type FormatErrorContext,\n type FormatErrorHook,\n} from './schemas/index.js'\n\n// Re-export per-concern schemas + types so downstream consumers\n// (`adapters/*`, vite-plugin, generators) keep their existing imports valid.\n// Per plan T2.3 — pure structural split; zero behavior change at the call site.\n//\n// `rateLimitSchema` and `securitySchema` are NOT re-exported: they are composed into\n// `theoConfigSchema` below and nothing imports them from here. They remain available at their\n// source of truth, `./schemas/index.js`.\nexport { cacheSchema, corsSchema, securityHeadersSchema, storageSchema } from './schemas/index.js'\n\nexport type { StorageConfig } from './schemas/index.js'\n\n/**\n * Root `theo.config.ts` schema — composer assembled from the per-concern\n * primitives re-exported above.\n *\n * Embedded blocks that exist ONLY as part of the root config (`agents`,\n * `ui`, `devtools`, `jobs`, `openapi`) stay inline below. They have no\n * external consumers; splitting them would create lonely files (M5\n * smell) without comprehension benefit.\n */\nexport const theoConfigSchema = z\n .object({\n /**\n * Plan v1.2 T2.1 — project identifier propagated into\n * `.theokit/services.json` v2 `project` field. DNS-1123 compatible (drives\n * Gitea repo + ArgoCD App naming on TheoCloud). When omitted, the build\n * emits services.json v1 with the legacy `services-bundle` fallback\n * (ADR D10) and logs a deprecation warning.\n */\n name: z\n .string()\n .max(63)\n .refine(\n // DNS-1123 equivalent expressed as explicit single-char anchors so\n // security/detect-unsafe-regex stays clean (no backtracking).\n (value) =>\n value.length > 0 &&\n /^[a-z0-9-]+$/u.test(value) &&\n !value.startsWith('-') &&\n !value.endsWith('-'),\n 'name must match DNS-1123 (lowercase alphanumeric+hyphens, 1-63 chars, no leading/trailing hyphen)',\n )\n .optional(),\n appDir: z.string().default('app'),\n serverDir: z.string().default('server'),\n /**\n * Directory (relative to the project root) holding `agents/<name>.ts` definitions, scanned by\n * dev/build/terminal/mcp. Defaults to `\"agents\"` — apps that keep the canonical layout are\n * unaffected. Set to e.g. `\"core/agents\"` to organize agents under a domain root (#95 follow-up).\n */\n agentsDir: z.string().default('agents'),\n /**\n * T2.2 / EC-4 — Build output directory. Must be a relative path inside\n * the project root. Refused absolute or parent-relative paths to prevent\n * `cleanOutDir` from wiping arbitrary locations (defense-in-depth on\n * top of cleanOutDir's runtime EC-3 guard).\n */\n distDir: z\n .string()\n .default('.theokit')\n .refine(\n (d) => !/^([A-Za-z]:)?[/\\\\]/.test(d) && !d.startsWith('..'),\n 'distDir must be a relative path inside the project root (e.g., \".theokit\")',\n ),\n /**\n * Agent runtime configuration.\n *\n * - `maxRegistries` (T2.3, legacy): dev-mode cleanup of stale\n * `.theokit/agents/<id>/` dirs by mtime. Now superseded by SDK's\n * native registry GC but kept for backward-compat.\n * - `registry` (Phase 6, Production-Readiness #2): forwarded to\n * `Agent.registry.configure()` lazily on first request.\n * * `maxAgents` — LRU cap. MUST be ≥ max-concurrent-active-conversations\n * (EC-17 DOCUMENT): with maxAgents:1 and 2 concurrent chats, LRU evicts\n * mid-stream → SDK aborts with code:'aborted'. Default 100 covers\n * indie/small-team; tune up for high-traffic.\n * * `idleTimeoutMs` — auto-evict idle agents (default 30 min). 0 disables\n * idle eviction (LRU only).\n */\n agents: z\n .object({\n maxRegistries: z.number().int().positive().default(100),\n registry: z\n .object({\n /** LRU cap — MUST be ≥ max-concurrent-active-conversations. */\n maxAgents: z.number().int().positive().max(10_000).default(100),\n /** Idle eviction window in ms. 0 disables idle eviction (LRU only). */\n idleTimeoutMs: z\n .number()\n .int()\n .nonnegative()\n .default(30 * 60_000),\n })\n .optional(),\n })\n .optional(),\n port: z.number().int().min(1).max(65535).default(3000),\n /** Listen on all addresses (0.0.0.0) for LAN/mobile testing. */\n host: z.union([z.string(), z.boolean()]).default('localhost'),\n /** Automatically open browser on `theokit dev`. */\n open: z.union([z.boolean(), z.string()]).default(false),\n /** Exit if port is already in use instead of trying next available. */\n strictPort: z.boolean().default(false),\n /** Forward browser console/errors to terminal — useful for AI agent dev. */\n forwardConsole: z\n .union([\n z.boolean(),\n z.object({\n unhandledErrors: z.boolean().optional(),\n logLevels: z.array(z.enum(['error', 'warn', 'info', 'log', 'debug'])).optional(),\n }),\n ])\n .default(false),\n /** Pre-transform files on startup for faster first page load. */\n warmup: z\n .object({\n clientFiles: z.array(z.string()).optional(),\n ssrFiles: z.array(z.string()).optional(),\n })\n .optional(),\n ssr: z.boolean().default(false),\n /** When true (and ssr === true), use renderToPipeableStream with progressive\n * shell flush instead of single-shot renderToString. Opt-in for streaming\n * SSR; default false preserves the current behavior. */\n ssrStreaming: z.boolean().default(false),\n rateLimit: rateLimitSchema.optional(),\n upload: uploadSchema.optional(),\n logging: loggingSchema.optional(),\n security: securitySchema.optional(),\n serialization: z.enum(['json', 'superjson']).default('json'),\n // Plugins are validated structurally at runtime by createPluginRunnerFromConfig.\n // Zod only checks the shape minimally (must be array). Type-level safety is\n // provided through defineConfig at the user surface.\n plugins: z.array(z.unknown()).optional(),\n /** Enable client-side batching of theoFetch calls and the\n * /api/__theo_batch__ server endpoint. */\n batching: z\n .union([z.boolean(), z.object({ max: z.number().int().positive().optional() })])\n .optional(),\n /** T4.1 — Audit log. When `logger` is provided, framework events\n * (csrf.warn, rate-limit.exceeded, session.rotated, csp.violation) are\n * emitted to it. Default: noop. */\n audit: z\n .object({\n logger: z.unknown().optional(),\n })\n .optional(),\n /** TheoUI auto-wire (T2.1). `false` = opt-out; object = explicit theme/fonts;\n * undefined = enabled when @theokit/ui is detected in node_modules. */\n ui: z\n .union([\n z.literal(false),\n z.object({\n // Any theme @theokit/ui knows — built-in or from `defineTheme()`. This was a closed\n // enum of `violet-forge | noir | paper`, two of which never existed in @theokit/ui, so\n // the only accepted value was the default and every real theme was rejected. The pattern\n // mirrors what @theokit/ui's ThemeProvider enforces, and it is load-bearing: the value is\n // interpolated into the generated entry and into a CSS selector.\n theme: z\n .string()\n .regex(\n THEME_NAME_PATTERN,\n 'must start with a letter and contain only lowercase letters, digits and hyphens',\n )\n .optional(),\n fonts: z.enum(['bundled', 'cdn']).optional(),\n }),\n ])\n .optional(),\n /**\n * Cache subsystem (caching-and-revalidation-plan).\n * Default `undefined` keeps caching disabled (backward compatible).\n * Pass `cache: {}` to opt in with defaults.\n */\n cache: cacheSchema.optional(),\n /**\n * Devtools overlay (Phase 0.4.0+ —\n *\n * - `undefined` (default): devtools auto-injects in `pnpm dev`, NEVER in `vite build`.\n * - `false`: devtools disabled entirely (Vite plugin skips injection even in dev).\n * - `{ ... }`: devtools enabled with explicit defaults (position, theme).\n *\n * Tree-shaken to noop in prod via the dual-export pattern in\n * `packages/theo/src/devtools/index.ts` (EC-17 positive prod check).\n */\n devtools: z\n .union([\n z.literal(false),\n z.object({\n position: z.enum(['top-left', 'top-right', 'bottom-left', 'bottom-right']).optional(),\n theme: z.enum(['light', 'dark', 'system']).optional(),\n }),\n ])\n .optional(),\n /**\n * Informative list of deploy adapters the app supports. Does NOT\n * trigger per-build translations — only the `--target` CLI flag does\n * (EC-201 / ADR D2). If `config.adapters` includes a target NOT\n * matching `--target`, `theokit build` emits a cross-reference note.\n */\n adapters: z.array(z.string()).optional(),\n /**\n * Extra package names to pre-bundle via Vite's `optimizeDeps.include`.\n *\n * Framework auto-includes `@theokit/ui` and `lucide-react` when present.\n * Apps adding plugin peer-deps that rely on a runtime `import('<pkg>')`\n * (dynamic specifier) — e.g. `@theokit/plugin-canvas` consumers\n * installing `mermaid` for Mermaid SVG rendering — must declare those\n * here so Vite can resolve the literal in dev mode without\n * \"Failed to resolve module specifier\" errors. Production builds use\n * tsup/esbuild bundling and are not affected.\n *\n * Example:\n * viteOptimizeDeps: ['mermaid']\n */\n viteOptimizeDeps: z.array(z.string()).optional(),\n /**\n * Jobs backend (ADR D3 + T2.1). When configured, every request gets\n * `ctx.queue.enqueue` auto-wired via the outbox lifecycle. Pass a\n * `JobBackend` instance (InMemoryJobBackend, PostgresJobBackend, etc.).\n */\n jobs: z\n .object({\n backend: z.custom<unknown>((v) => typeof v === 'object' && v !== null),\n })\n .optional(),\n /**\n * StorageManager configuration (T1.1 / ADR-0007).\n *\n * Declares Postgres servers + databases + Redis servers. Consumed by\n * `getStorageManager().configure()` at boot via `start.ts`.\n *\n * Default `undefined` means manager exists but is not configured — adapters\n * relying on the manager (PostgresJobBackend.fromStorageManager, etc.) will\n * throw with an actionable error on first use.\n */\n storage: storageSchema.optional(),\n /**\n * Wave 2 — Polyglot services orchestration (T1.1 / ADR-0012/0013/0014/0015).\n *\n * Declarative external sidecar processes (Python FastAPI / Node Hono)\n * that boot alongside the TheoKit TS app. Empty `services: {}` is the\n * default and preserves Wave 1 behavior.\n */\n services: servicesConfigSchema,\n /**\n * G2 — OpenAPI emit (build-time only).\n *\n * When present, `theokit build` writes a generated `openapi.json` from\n * every `defineRoute()` body/query/params Zod schema. `undefined` keeps\n * the framework backward-compatible (no emit). Pass `openapi: {}` to\n * opt in with defaults.\n *\n * Defaults: spec 3.1.0 · servers `http://localhost:3000` · title\n * \"TheoKit App\" · version \"0.0.0\" · outDir \".theokit\" (next to dist).\n *\n * The env var `THEOKIT_OPENAPI_SERVERS` (CSV of URLs) overrides\n * `servers[].url` at emit time without rebuilding the config.\n */\n openapi: z\n .object({\n servers: z\n .array(\n z.object({\n url: z.url(),\n description: z.string().optional(),\n }),\n )\n .default([{ url: 'http://localhost:3000', description: 'Local development' }]),\n specVersion: z.enum(['3.1.0', '3.0.3']).default('3.1.0'),\n title: z.string().default('TheoKit App'),\n version: z.string().default('0.0.0'),\n outDir: z.string().default('.theokit'),\n })\n .optional(),\n /**\n * G5 T1.3 — error envelope transformer hook (blueprint ADR D3).\n *\n * When present, runs at framework error-boundary time to enrich the\n * envelope with consumer-defined extensions (`hint`, custom telemetry\n * tags, etc.) BEFORE the envelope is serialized to the client. The\n * function signature is preserved via the explicit `FormatErrorHook`\n * type — TS inference flows from `theo.config.ts` into `@theo/client`\n * codegen and `@theokit/ui` AgentErrorCard consumers.\n *\n * Use `z.custom<FormatErrorHook>(...)` because Zod's built-in\n * `z.function()` discards its TS signature after parse; `z.custom`\n * with a function-typed runtime guard preserves the call-site type\n * without trading off Zod runtime validation.\n */\n formatError: z\n .custom<FormatErrorHook>((val) => typeof val === 'function', {\n message: 'formatError must be a function',\n })\n .optional(),\n })\n // EC-2 fix: cross-config refine — no service may share TheoKit's web port.\n .refine((cfg) => !Object.values(cfg.services).some((s) => s.port === cfg.port), {\n message: 'service.port collides with TheoKit web port — change one of them',\n path: ['services'],\n })\n\nexport type TheoConfig = z.infer<typeof theoConfigSchema>\n\n// Silence unused-import warnings for type-only re-exports — TS strips at compile,\n// but exports above re-introduce them for downstream consumers.\ntype _FormatErrorContext = FormatErrorContext\n","/**\n * The `@theokit/ui` theme name — a contract shared by the config schema, the entry generators and\n * the Vite plugin's detector.\n *\n * It lives in `core/contracts/` because those three sit in different modules that may not depend on\n * one another: `config/` and `router/` are allowed to reach into `core/` only. Before this file the\n * union was written out separately in all three places, and all three drifted from what the design\n * system actually ships.\n */\n\n/**\n * Theme names `@theokit/ui` ships today — an autocomplete hint, NOT the accepted set.\n *\n * The accepted set used to be exactly `'violet-forge' | 'noir' | 'paper'`, and two of those three\n * were never real: the design system has no `noir` and no `paper`. So the only value config\n * validation accepted was the default, and every genuine theme — plus anything from\n * `defineTheme()` — was rejected.\n *\n * A closed union here is a copy of another package's catalogue; it rots the moment that package\n * ships a theme. This list is therefore advisory, and {@link TheoUiTheme} stays open. The\n * authoritative list is `builtinThemes`, exported by `@theokit/ui`.\n */\nexport type BuiltinThemeName =\n | 'violet-forge'\n | 'falcon-red'\n | 'classic-paper'\n | 'aurora-terminal'\n | 'vercel-mono'\n | 'github-dark'\n | 'dracula'\n | 'one-dark'\n | 'anthropic-style'\n | 'openai-style'\n | 'linear-glass'\n\n/**\n * A theme name. Built-ins autocomplete; a custom theme from `defineTheme()` is equally valid.\n *\n * `(string & {})` is the idiomatic way to keep literal suggestions on an open union — without it\n * TypeScript widens the whole type to `string` and the hints disappear.\n */\nexport type TheoUiTheme = BuiltinThemeName | (string & {})\n\n/** How fonts are delivered — bundled with the app, or fetched from a CDN. */\nexport type TheoUiFonts = 'bundled' | 'cdn'\n\n/**\n * The shape a theme name must have — mirrors the pattern `@theokit/ui`'s `ThemeProvider` enforces\n * before it writes `[data-theme=\"<name>\"]`.\n *\n * Validating here is not cosmetic. The value is interpolated into the generated entry\n * (`defaultTheme: '<name>'`) and into a CSS selector, so an unchecked name is a code-injection\n * vector — and anything this rejects would be rejected by the provider anyway, so the developer\n * gets the error at config time instead of at render time.\n */\nexport const THEME_NAME_PATTERN = /^[a-z][a-z0-9-]*$/\n","import { z } from 'zod'\n\n/**\n * Base bucket config — legacy shape preserved for backwards compatibility.\n */\nconst baseRateLimitSchema = z.object({\n windowMs: z.number().min(1),\n max: z.number().int().min(1),\n})\n\n/**\n * T2.2 — Per-route + per-user rate limit. The new shape adds `routes`\n * (path map), `keyBy`, and `cookieName`. The legacy flat shape is still\n * accepted via the union — see `createRouteRateLimiter` for normalization.\n */\nexport const rateLimitSchema = z.union([\n baseRateLimitSchema,\n z.object({\n default: baseRateLimitSchema.optional(),\n routes: z.record(z.string(), baseRateLimitSchema).optional(),\n keyBy: z\n .union([\n z.enum(['ip', 'session', 'user']),\n z.function({ input: z.tuple([z.unknown()]), output: z.string() }),\n ])\n .optional(),\n cookieName: z.string().min(1).optional(),\n /**\n * How many reverse proxies sit in front of the app, for `keyBy: 'ip'`. `false` (default)\n * trusts none; `true` means one; a number names a longer chain.\n *\n * Required for correct limiting behind Caddy/nginx/a load balancer — without it every visitor\n * keys on the proxy address and shares a single bucket. Off by default because\n * `x-forwarded-for` is client-writable.\n */\n trustProxy: z.union([z.boolean(), z.number().int().min(0)]).optional(),\n }),\n])\n","import { z } from 'zod'\n\nexport const uploadSchema = z.object({\n maxFileSize: z\n .number()\n .min(1)\n .default(10 * 1024 * 1024), // 10MB\n maxFiles: z.number().int().min(1).default(10),\n maxFieldSize: z\n .number()\n .min(1)\n .default(1 * 1024 * 1024), // 1MB\n})\n","import { z } from 'zod'\n\nexport const loggingSchema = z.object({\n level: z.enum(['debug', 'info', 'warn', 'error', 'silent']).default('info'),\n})\n","import { z } from 'zod'\n\n// `.finite()` was removed from the 4 numeric schemas below (agent-builder#319): in zod 4 it is a\n// no-op — `z.number()` already rejects `Infinity`, `-Infinity` and `NaN` by default. Measured before\n// removing, against the installed zod 4.4.3, and not assumed from the deprecation message: all five\n// cases (`Infinity`, `-Infinity`, `NaN`, `1.5`, `0`) give the SAME verdict with and without it.\n\n/**\n * Cache subsystem config (caching-and-revalidation-plan).\n * Default `cache: undefined` keeps the framework backward-compatible\n * (no engine initialized → no cache primitives available).\n *\n * Setting `cache: {}` opts in with all defaults.\n */\nconst routeRuleSchema = z.object({\n maxAge: z.number().nonnegative().optional(),\n swr: z.number().nonnegative().optional(),\n tags: z.array(z.string()).optional(),\n})\n\nexport const cacheSchema = z.object({\n enabled: z.boolean().default(true),\n /** 'memory' uses InMemoryCacheAdapter; otherwise pass a custom adapter instance. */\n storage: z.union([z.literal('memory'), z.custom<unknown>()]).default('memory'),\n maxEntries: z.number().int().positive().default(1000),\n defaults: z\n .object({\n maxAge: z.number().nonnegative().default(1),\n swr: z.number().nonnegative().optional(),\n cacheErrors: z.boolean().default(false),\n })\n .default({ maxAge: 1, cacheErrors: false }),\n keyDerivation: z\n .object({\n excludeQuery: z.array(z.string()).optional(),\n sortQuery: z.boolean().default(true),\n lowercaseHost: z.boolean().default(true),\n })\n .default({ sortQuery: true, lowercaseHost: true }),\n routeRules: z.record(z.string(), routeRuleSchema).optional(),\n})\n","import { z } from 'zod'\n\nimport { headerSafeString } from './header-safe.js'\n\n/**\n * Phase 5 — CSRF warn-first (EC-1).\n *\n * 0.2.0 default: `warn`. Existing apps keep working but get structured\n * warnings about every state-mutating request that does not carry the\n * `X-Theo-Action: 1` header. 0.3.0 will flip the default to `strict`.\n *\n * Set explicitly to `strict` to opt into the future default early,\n * or `off` to disable CSRF entirely (only valid when you have another\n * defense — bearer auth, no session cookies, etc).\n */\n\n/**\n * Phase 6 — Default security headers (D4 / EC-2).\n *\n * 0.2.0 defaults:\n * - CSP in `report-only` mode (EC-2: don't break existing apps)\n * - X-Frame-Options: DENY · X-Content-Type-Options: nosniff\n * - Referrer-Policy: strict-origin-when-cross-origin\n * - HSTS in production only (no TLS on localhost)\n *\n * Users override individual headers, swap CSP to `enforce`, or disable\n * CSP entirely (`csp: false` / `cspMode: 'off'`).\n */\nexport const securityHeadersSchema = z.object({\n csp: z.union([headerSafeString, z.literal(false)]).optional(),\n // T6.1 — default flipped from 'report-only' to 'enforce' for 0.3.0.\n // Users who want the old behaviour set `cspMode: 'report-only'`\n // explicitly.\n cspMode: z.enum(['enforce', 'report-only', 'off']).default('enforce'),\n hsts: z.union([headerSafeString, z.literal(false)]).optional(),\n frameOptions: z.enum(['DENY', 'SAMEORIGIN']).default('DENY'),\n contentTypeOptions: z.literal('nosniff').default('nosniff'),\n referrerPolicy: headerSafeString.default('strict-origin-when-cross-origin'),\n /**\n * T1.1 — Permissions-Policy directive string. EC-3-refined: rejects CR/LF.\n * Pass `false` to suppress the header.\n */\n permissionsPolicy: z.union([headerSafeString, z.literal(false)]).optional(),\n})\n\n/**\n * T5.1 — Disallowed-routes escalation pattern (Rails-inspired).\n *\n * `routes` accepts string (exact match — trailing slash matters) or\n * RegExp entries. Matched routes that would otherwise emit `csrf.warn`\n * dispatch through `disallowedBehavior` instead:\n * - `'warn'` : no-op vs the default warn-mode behavior\n * - `'raise'` : escalate to 403, even when global `csrf` mode is 'warn'\n *\n * Use to roll out strict mode per-route (e.g., flip /api/auth/* first)\n * without committing the entire surface to strict at once.\n */\nconst disallowedConfigSchema = z.object({\n routes: z.array(z.union([z.string(), z.instanceof(RegExp)])),\n behavior: z.enum(['warn', 'raise']).default('raise'),\n})\n\n/**\n * T1.2 — CORS configuration.\n *\n * `origins` accepts a single value (`'*'`, string, RegExp, callback) OR an\n * array of (string | RegExp). The spec-violating `origins: '*'` +\n * `credentials: true` combination is rejected at parse time (browsers\n * ignore wildcards when credentials are sent).\n *\n * EC-3 — `allowedHeaders` and `exposedHeaders` entries go through the\n * header-safe refinement (CR/LF rejected — CWE-113 mitigation).\n */\nexport const corsSchema = z\n .object({\n origins: z.union([\n z.literal('*'),\n headerSafeString,\n z.instanceof(RegExp),\n z.array(z.union([headerSafeString, z.instanceof(RegExp)])),\n z.function({ input: z.tuple([z.string()]), output: z.boolean() }),\n ]),\n methods: z\n .array(z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD']))\n .optional(),\n allowedHeaders: z.array(headerSafeString).optional(),\n exposedHeaders: z.array(headerSafeString).optional(),\n credentials: z.boolean().default(false),\n maxAge: z.number().int().min(0).max(86400).default(600),\n })\n .refine((c) => !(c.origins === '*' && c.credentials), {\n message: 'CORS spec forbids origins:\"*\" with credentials:true — browsers ignore the wildcard',\n })\n\nexport const securitySchema = z.object({\n // T6.1 — default flipped from 'warn' to 'strict' for 0.3.0. Apps that\n // grep their warn-mode logs from 0.2.x already know which endpoints\n // break; opt back into 'warn' globally OR use disallowedRoutes for\n // surgical migration.\n csrf: z.enum(['off', 'warn', 'strict']).default('strict'),\n headers: securityHeadersSchema.optional(),\n /** T5.1 — per-route escalation (Rails disallowed_warnings pattern). */\n disallowed: disallowedConfigSchema.optional(),\n /** T1.2 — Cross-Origin Resource Sharing. Single global config; runs first in pipeline. */\n cors: corsSchema.optional(),\n})\n","import { z } from 'zod'\n\n/**\n * EC-3 — CWE-113 HTTP Response Splitting mitigation.\n *\n * Every string that becomes a header value must reject CR/LF. Apps that\n * derive header values from untrusted input (feature flags, tenant config,\n * URL params) would otherwise let attackers inject Set-Cookie / Location\n * headers via `\\r\\n`. Apply this refinement to every header-bound string\n * field: permissionsPolicy, csp, hsts, referrerPolicy, CORS allow/expose.\n */\nexport const headerSafeString = z\n .string()\n .refine((s) => !/[\\r\\n]/.test(s), { message: 'Header value must not contain CR/LF' })\n","import { z } from 'zod'\n\n/**\n * StorageManager schemas (T1.1 / ADR-0007 D4).\n *\n * `theo.config.ts > storage` declares Postgres servers (credentials), the\n * databases on each server (TheoCloud / managed PG / self-host), and Redis\n * servers. The runtime `StorageManager` consumes this block; adapters\n * (PostgresJobBackend, PostgresConversationStorage, etc.) request pools by\n * database name and never see raw credentials at the call site.\n *\n * EC-1 (DOCUMENT in concept doc T4.1): Zod default strip-unknown mode\n * silently drops typo keys (`databasees` instead of `databases`). The\n * concept doc warns users to use exact names; runtime errors are still\n * actionable (`Database \"X\" not configured`).\n *\n * EC-2 (DEFERRED to use-time): `databases.X.server` references a key in\n * `servers`. Cross-field validation is intentionally NOT enforced at parse\n * time — `StorageManager.usePostgres()` throws an actionable error on the\n * first call with the dangling reference, matching Rails / Nitro behavior.\n */\nconst tlsConfigSchema = z.object({\n rejectUnauthorized: z.boolean().optional(),\n caCert: z.string().optional(),\n clientCert: z.string().optional(),\n clientKey: z.string().optional(),\n})\n\nconst serverConfigSchema = z.object({\n host: z.string().min(1),\n port: z.number().int().positive().max(65535).optional(),\n user: z.string().min(1),\n /** Password may be the empty string (some providers permit it). */\n password: z.string(),\n tls: tlsConfigSchema.optional(),\n})\n\nconst postgresPoolConfigSchema = z.object({\n min: z.number().int().nonnegative().optional(),\n max: z.number().int().positive().optional(),\n connectionTimeoutMillis: z.number().int().positive().optional(),\n idleTimeoutMillis: z.number().int().nonnegative().optional(),\n})\n\nconst postgresDatabaseConfigSchema = z.object({\n /** References a key in `storage.servers`. Resolved at `usePostgres()` call time. */\n server: z.string().min(1),\n database: z.string().min(1),\n pool: postgresPoolConfigSchema.optional(),\n})\n\nconst redisServerConfigSchema = serverConfigSchema.extend({\n db: z.number().int().nonnegative().optional(),\n maxRetriesPerRequest: z.number().int().nonnegative().optional(),\n})\n\nexport const storageSchema = z.object({\n servers: z.record(z.string(), serverConfigSchema).optional(),\n databases: z.record(z.string(), postgresDatabaseConfigSchema).optional(),\n redis: z.record(z.string(), redisServerConfigSchema).optional(),\n})\n\nexport type StorageConfig = z.infer<typeof storageSchema>\n"],"mappings":"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","names":["z","z","z","z","z","z","z","z","z"]}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
serveAgentAuxRoute,
|
|
10
10
|
setupSsrDevMiddleware,
|
|
11
11
|
writeWebResponseToServerResponse
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-GRI4XHBJ.js";
|
|
13
13
|
import {
|
|
14
14
|
isMcpPath
|
|
15
15
|
} from "./chunk-2CVV6CNN.js";
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from "./chunk-IEES3CHD.js";
|
|
20
20
|
import {
|
|
21
21
|
loadConfig
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-S433N3CT.js";
|
|
23
23
|
import {
|
|
24
24
|
buildServicesProxyConfig
|
|
25
25
|
} from "./chunk-7VPQHEAJ.js";
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
handleCspReport,
|
|
45
45
|
handleCsrfReadiness,
|
|
46
46
|
mountAgent
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-BIVCP6X5.js";
|
|
48
48
|
import {
|
|
49
49
|
getApprovalRegistry,
|
|
50
50
|
resolveProvider
|
|
@@ -1927,19 +1927,19 @@ async function theoPluginAsync(rootOrOptions) {
|
|
|
1927
1927
|
})
|
|
1928
1928
|
);
|
|
1929
1929
|
}
|
|
1930
|
-
const { appTypedClientPlugin } = await import("./app-typed-client-
|
|
1930
|
+
const { appTypedClientPlugin } = await import("./app-typed-client-G3J5G7E5.js");
|
|
1931
1931
|
const appClientPlugin = appTypedClientPlugin({
|
|
1932
1932
|
cwd: projectRoot,
|
|
1933
1933
|
serverDir: serverDirAbs,
|
|
1934
1934
|
distDir: resolve6(projectRoot, ".theokit")
|
|
1935
1935
|
});
|
|
1936
|
-
const { actionsVirtualModule } = await import("./actions-virtual-module-
|
|
1936
|
+
const { actionsVirtualModule } = await import("./actions-virtual-module-LB4NGONI.js");
|
|
1937
1937
|
const actionsPlugin = actionsVirtualModule({
|
|
1938
1938
|
serverDir: serverDirAbs,
|
|
1939
1939
|
distDir: resolve6(projectRoot, ".theokit")
|
|
1940
1940
|
});
|
|
1941
1941
|
const { agentsTypedClientPlugin } = await import("./agents-typed-client-D4OA2TXB.js");
|
|
1942
|
-
const { generateManifest } = await import("./internal-api-
|
|
1942
|
+
const { generateManifest } = await import("./internal-api-V5L65YSJ.js");
|
|
1943
1943
|
const agentsClientPlugin = agentsTypedClientPlugin({
|
|
1944
1944
|
projectRoot,
|
|
1945
1945
|
agentsDir: agentsDirName,
|
|
@@ -2121,4 +2121,4 @@ export {
|
|
|
2121
2121
|
theoPluginAsync,
|
|
2122
2122
|
theoPlugin
|
|
2123
2123
|
};
|
|
2124
|
-
//# sourceMappingURL=chunk-
|
|
2124
|
+
//# sourceMappingURL=chunk-Q2S2IGSM.js.map
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "./chunk-HBU2GIMZ.js";
|
|
6
6
|
import {
|
|
7
7
|
theoConfigSchema
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-GVW5EKEU.js";
|
|
9
9
|
|
|
10
10
|
// src/config/load-config.ts
|
|
11
11
|
import { existsSync } from "fs";
|
|
@@ -140,4 +140,4 @@ export {
|
|
|
140
140
|
deepMerge,
|
|
141
141
|
loadConfig
|
|
142
142
|
};
|
|
143
|
-
//# sourceMappingURL=chunk-
|
|
143
|
+
//# sourceMappingURL=chunk-S433N3CT.js.map
|
|
@@ -145,7 +145,7 @@ async function agentCommand(name, message, deps = {}) {
|
|
|
145
145
|
);
|
|
146
146
|
}
|
|
147
147
|
const projectRoot = deps.projectRoot ?? process.cwd();
|
|
148
|
-
const agentsDir = deps.agentsDir ?? (await (await import("./load-config-
|
|
148
|
+
const agentsDir = deps.agentsDir ?? (await (await import("./load-config-VKD6LKWU.js")).loadConfig(projectRoot)).agentsDir;
|
|
149
149
|
const agents = scanAgents(projectRoot, agentsDir);
|
|
150
150
|
const agent = agents.find((a) => a.name === name);
|
|
151
151
|
if (!agent) {
|
|
@@ -178,8 +178,8 @@ async function agentCommand(name, message, deps = {}) {
|
|
|
178
178
|
async function createAgentSsrLoader(projectRoot) {
|
|
179
179
|
const { createServer } = await import("vite");
|
|
180
180
|
const react = (await import("@vitejs/plugin-react")).default;
|
|
181
|
-
const { theoPluginAsync } = await import("./vite-plugin-
|
|
182
|
-
const { loadConfig } = await import("./load-config-
|
|
181
|
+
const { theoPluginAsync } = await import("./vite-plugin-EQMDMDXV.js");
|
|
182
|
+
const { loadConfig } = await import("./load-config-VKD6LKWU.js");
|
|
183
183
|
const config = await loadConfig(projectRoot);
|
|
184
184
|
const theoPlugins = await theoPluginAsync({
|
|
185
185
|
root: projectRoot,
|
|
@@ -212,4 +212,4 @@ export {
|
|
|
212
212
|
agentCommand,
|
|
213
213
|
createAgentSsrLoader
|
|
214
214
|
};
|
|
215
|
-
//# sourceMappingURL=chunk-
|
|
215
|
+
//# sourceMappingURL=chunk-SO64VQOD.js.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "tsx/esm";
|
|
3
|
+
|
|
4
|
+
// src/server/http/cookies.ts
|
|
5
|
+
function parseCookieHeader(header) {
|
|
6
|
+
const map = /* @__PURE__ */ new Map();
|
|
7
|
+
if (!header) return map;
|
|
8
|
+
for (const pair of header.split(";")) {
|
|
9
|
+
const trimmed = pair.trim();
|
|
10
|
+
const eqIdx = trimmed.indexOf("=");
|
|
11
|
+
if (eqIdx === -1) continue;
|
|
12
|
+
const key = trimmed.slice(0, eqIdx);
|
|
13
|
+
const rawValue = trimmed.slice(eqIdx + 1);
|
|
14
|
+
let value;
|
|
15
|
+
try {
|
|
16
|
+
value = decodeURIComponent(rawValue);
|
|
17
|
+
} catch {
|
|
18
|
+
value = rawValue;
|
|
19
|
+
}
|
|
20
|
+
map.set(key, value);
|
|
21
|
+
}
|
|
22
|
+
return map;
|
|
23
|
+
}
|
|
24
|
+
function getCookie(req, name) {
|
|
25
|
+
const cookies = parseCookieHeader(req.headers.cookie);
|
|
26
|
+
const value = cookies.get(name);
|
|
27
|
+
if (value === void 0) return void 0;
|
|
28
|
+
if (/(?:%[^0-9A-Fa-f])|(?:%[0-9A-Fa-f]$)/.test(value)) return void 0;
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
function serializeCookie(name, value, options) {
|
|
32
|
+
const opts = {
|
|
33
|
+
httpOnly: true,
|
|
34
|
+
secure: process.env.NODE_ENV === "production",
|
|
35
|
+
sameSite: "lax",
|
|
36
|
+
path: "/",
|
|
37
|
+
...options
|
|
38
|
+
};
|
|
39
|
+
const parts = [`${name}=${encodeURIComponent(value)}`];
|
|
40
|
+
if (opts.httpOnly) parts.push("HttpOnly");
|
|
41
|
+
if (opts.secure) parts.push("Secure");
|
|
42
|
+
const sameSiteCanonical = opts.sameSite.charAt(0).toUpperCase() + opts.sameSite.slice(1);
|
|
43
|
+
parts.push(`SameSite=${sameSiteCanonical}`);
|
|
44
|
+
if (opts.maxAge !== void 0) parts.push(`Max-Age=${opts.maxAge}`);
|
|
45
|
+
if (opts.path) parts.push(`Path=${opts.path}`);
|
|
46
|
+
if (opts.domain) parts.push(`Domain=${opts.domain}`);
|
|
47
|
+
return parts.join("; ");
|
|
48
|
+
}
|
|
49
|
+
function setCookie(res, name, value, options) {
|
|
50
|
+
const serialized = serializeCookie(name, value, options);
|
|
51
|
+
const existing = res.getHeader("Set-Cookie");
|
|
52
|
+
let cookies = [];
|
|
53
|
+
if (Array.isArray(existing)) {
|
|
54
|
+
cookies = existing.map(String);
|
|
55
|
+
} else if (existing !== void 0) {
|
|
56
|
+
cookies = [String(existing)];
|
|
57
|
+
}
|
|
58
|
+
cookies.push(serialized);
|
|
59
|
+
res.setHeader("Set-Cookie", cookies);
|
|
60
|
+
}
|
|
61
|
+
function deleteCookie(res, name, options) {
|
|
62
|
+
setCookie(res, name, "", { maxAge: 0, path: options?.path ?? "/" });
|
|
63
|
+
}
|
|
64
|
+
function getCookieFromRequest(request, name) {
|
|
65
|
+
const cookieHeader = request.headers.get("cookie");
|
|
66
|
+
if (cookieHeader === null) return void 0;
|
|
67
|
+
const cookies = parseCookieHeader(cookieHeader);
|
|
68
|
+
const value = cookies.get(name);
|
|
69
|
+
if (value === void 0) return void 0;
|
|
70
|
+
if (/(?:%[^0-9A-Fa-f])|(?:%[0-9A-Fa-f]$)/.test(value)) return void 0;
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
function appendCookieToHeaders(target, name, value, options) {
|
|
74
|
+
target.append("Set-Cookie", serializeCookie(name, value, options));
|
|
75
|
+
}
|
|
76
|
+
function appendDeleteCookieToHeaders(target, name, options) {
|
|
77
|
+
appendCookieToHeaders(target, name, "", { maxAge: 0, path: options?.path ?? "/" });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export {
|
|
81
|
+
parseCookieHeader,
|
|
82
|
+
getCookie,
|
|
83
|
+
serializeCookie,
|
|
84
|
+
setCookie,
|
|
85
|
+
deleteCookie,
|
|
86
|
+
getCookieFromRequest,
|
|
87
|
+
appendCookieToHeaders,
|
|
88
|
+
appendDeleteCookieToHeaders
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=chunk-V7MTRM6Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/server/http/cookies.ts"],"sourcesContent":["import type { IncomingMessage, ServerResponse } from 'node:http'\n\nexport interface CookieOptions {\n httpOnly?: boolean\n secure?: boolean\n sameSite?: 'strict' | 'lax' | 'none'\n maxAge?: number\n path?: string\n domain?: string\n}\n\n/**\n * Parse a `Cookie` header into a Map (RFC 6265 §5.4).\n * - Empty/missing input → empty Map.\n * - Malformed entries (no `=`) skipped silently (defensive).\n * - Duplicate names → last-wins.\n * - Values URL-decoded if possible; raw on decode failure (CR-009 protection).\n *\n * Canonical helper (T3.2 of architecture-review-remediation-plan; PV-4 DRY).\n * Consumed by `getCookie` here AND by `rate-limit/rate-limit-per-route.ts`.\n */\nexport function parseCookieHeader(header: string | undefined): Map<string, string> {\n const map = new Map<string, string>()\n if (!header) return map\n for (const pair of header.split(';')) {\n const trimmed = pair.trim()\n const eqIdx = trimmed.indexOf('=')\n if (eqIdx === -1) continue\n const key = trimmed.slice(0, eqIdx)\n const rawValue = trimmed.slice(eqIdx + 1)\n let value: string\n try {\n value = decodeURIComponent(rawValue)\n } catch {\n // Malformed percent-encoding — preserve raw to not lose data,\n // but the consumer is responsible for treating it as untrusted.\n value = rawValue\n }\n map.set(key, value)\n }\n return map\n}\n\nexport function getCookie(req: IncomingMessage, name: string): string | undefined {\n const cookies = parseCookieHeader(req.headers.cookie)\n const value = cookies.get(name)\n // CR-009 fix: malformed percent-encoding returns raw via parseCookieHeader.\n // If decoding failed in parse, we get the raw value (with %XX intact).\n // Treat that as \"unreadable\" for the typed getCookie API to preserve the\n // original \"treat as unauthenticated\" semantics.\n if (value === undefined) return undefined\n // Sanity: if rawValue contains lone `%` that didn't decode, parseCookieHeader\n // returned the raw — return undefined to preserve old getCookie contract.\n if (/(?:%[^0-9A-Fa-f])|(?:%[0-9A-Fa-f]$)/.test(value)) return undefined\n return value\n}\n\n/**\n * T5a.2 Phase B slice 6/6 — pure Set-Cookie serializer. Extracted from\n * `setCookie(res, ...)` so the IncomingMessage path AND the Web Headers\n * path can share the cookie attribute composition.\n *\n * Returns the canonical `Set-Cookie` header value string (no surrounding\n * `Set-Cookie:` prefix — caller wraps via `res.setHeader('Set-Cookie', ...)`\n * or `headers.append('Set-Cookie', ...)`).\n *\n * Defaults: `httpOnly: true`, `secure: NODE_ENV === 'production'`,\n * `sameSite: 'lax'`, `path: '/'`.\n */\nexport function serializeCookie(name: string, value: string, options?: CookieOptions): string {\n const opts: Required<Omit<CookieOptions, 'maxAge' | 'domain'>> &\n Pick<CookieOptions, 'maxAge' | 'domain'> = {\n httpOnly: true,\n secure: process.env.NODE_ENV === 'production',\n sameSite: 'lax',\n path: '/',\n ...options,\n }\n\n const parts = [`${name}=${encodeURIComponent(value)}`]\n if (opts.httpOnly) parts.push('HttpOnly')\n if (opts.secure) parts.push('Secure')\n const sameSiteCanonical = opts.sameSite.charAt(0).toUpperCase() + opts.sameSite.slice(1)\n parts.push(`SameSite=${sameSiteCanonical}`)\n if (opts.maxAge !== undefined) parts.push(`Max-Age=${opts.maxAge}`)\n if (opts.path) parts.push(`Path=${opts.path}`)\n if (opts.domain) parts.push(`Domain=${opts.domain}`)\n return parts.join('; ')\n}\n\nexport function setCookie(\n res: ServerResponse,\n name: string,\n value: string,\n options?: CookieOptions,\n): void {\n const serialized = serializeCookie(name, value, options)\n // Append to existing Set-Cookie headers (EC-1: don't overwrite)\n const existing = res.getHeader('Set-Cookie')\n let cookies: string[] = []\n if (Array.isArray(existing)) {\n cookies = existing.map(String)\n } else if (existing !== undefined) {\n cookies = [String(existing)]\n }\n cookies.push(serialized)\n res.setHeader('Set-Cookie', cookies)\n}\n\nexport function deleteCookie(res: ServerResponse, name: string, options?: { path?: string }): void {\n setCookie(res, name, '', { maxAge: 0, path: options?.path ?? '/' })\n}\n\n/**\n * T5a.2 Phase B slice 6/6 — Web-Standards cookie getter.\n *\n * Mirror of `getCookie(req: IncomingMessage, name)` for the Web `Request`\n * shape. Consumes `request.headers.get('cookie')` (native `Headers` API)\n * instead of `req.headers.cookie`. Same parse logic + same malformed\n * percent-encoding sanity (returns undefined when raw value contains a\n * lone `%` that didn't decode, preserving the IncomingMessage path's\n * \"treat as unreadable\" CR-009 semantics).\n */\nexport function getCookieFromRequest(request: Request, name: string): string | undefined {\n const cookieHeader = request.headers.get('cookie')\n if (cookieHeader === null) return undefined\n const cookies = parseCookieHeader(cookieHeader)\n const value = cookies.get(name)\n if (value === undefined) return undefined\n if (/(?:%[^0-9A-Fa-f])|(?:%[0-9A-Fa-f]$)/.test(value)) return undefined\n return value\n}\n\n/**\n * T5a.2 Phase B slice 6/6 — Web-Standards cookie setter.\n *\n * Mirror of `setCookie(res, name, value, options)` for the Web `Headers`\n * shape. Appends a `Set-Cookie` entry to the caller's `Headers` instance\n * via `headers.append('Set-Cookie', ...)`. Multiple appends produce\n * multiple `Set-Cookie` headers per the Web spec; `headers.getSetCookie()`\n * retrieves them as an array (the one multi-value header the Web API\n * exposes natively).\n *\n * Uses the shared `serializeCookie` pure helper — same defaults and\n * attribute composition as the IncomingMessage path.\n */\nexport function appendCookieToHeaders(\n target: Headers,\n name: string,\n value: string,\n options?: CookieOptions,\n): void {\n target.append('Set-Cookie', serializeCookie(name, value, options))\n}\n\n/**\n * T5a.2 Phase B slice 6/6 — Web-Standards cookie deleter.\n *\n * Mirror of `deleteCookie(res, name, options)` — emits a Set-Cookie with\n * `Max-Age=0` so the browser drops the cookie immediately.\n */\nexport function appendDeleteCookieToHeaders(\n target: Headers,\n name: string,\n options?: { path?: string },\n): void {\n appendCookieToHeaders(target, name, '', { maxAge: 0, path: options?.path ?? '/' })\n}\n"],"mappings":";;;;AAqBO,SAAS,kBAAkB,QAAiD;AACjF,QAAM,MAAM,oBAAI,IAAoB;AACpC,MAAI,CAAC,OAAQ,QAAO;AACpB,aAAW,QAAQ,OAAO,MAAM,GAAG,GAAG;AACpC,UAAM,UAAU,KAAK,KAAK;AAC1B,UAAM,QAAQ,QAAQ,QAAQ,GAAG;AACjC,QAAI,UAAU,GAAI;AAClB,UAAM,MAAM,QAAQ,MAAM,GAAG,KAAK;AAClC,UAAM,WAAW,QAAQ,MAAM,QAAQ,CAAC;AACxC,QAAI;AACJ,QAAI;AACF,cAAQ,mBAAmB,QAAQ;AAAA,IACrC,QAAQ;AAGN,cAAQ;AAAA,IACV;AACA,QAAI,IAAI,KAAK,KAAK;AAAA,EACpB;AACA,SAAO;AACT;AAEO,SAAS,UAAU,KAAsB,MAAkC;AAChF,QAAM,UAAU,kBAAkB,IAAI,QAAQ,MAAM;AACpD,QAAM,QAAQ,QAAQ,IAAI,IAAI;AAK9B,MAAI,UAAU,OAAW,QAAO;AAGhC,MAAI,sCAAsC,KAAK,KAAK,EAAG,QAAO;AAC9D,SAAO;AACT;AAcO,SAAS,gBAAgB,MAAc,OAAe,SAAiC;AAC5F,QAAM,OACuC;AAAA,IAC3C,UAAU;AAAA,IACV,QAAQ,QAAQ,IAAI,aAAa;AAAA,IACjC,UAAU;AAAA,IACV,MAAM;AAAA,IACN,GAAG;AAAA,EACL;AAEA,QAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,mBAAmB,KAAK,CAAC,EAAE;AACrD,MAAI,KAAK,SAAU,OAAM,KAAK,UAAU;AACxC,MAAI,KAAK,OAAQ,OAAM,KAAK,QAAQ;AACpC,QAAM,oBAAoB,KAAK,SAAS,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,SAAS,MAAM,CAAC;AACvF,QAAM,KAAK,YAAY,iBAAiB,EAAE;AAC1C,MAAI,KAAK,WAAW,OAAW,OAAM,KAAK,WAAW,KAAK,MAAM,EAAE;AAClE,MAAI,KAAK,KAAM,OAAM,KAAK,QAAQ,KAAK,IAAI,EAAE;AAC7C,MAAI,KAAK,OAAQ,OAAM,KAAK,UAAU,KAAK,MAAM,EAAE;AACnD,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,UACd,KACA,MACA,OACA,SACM;AACN,QAAM,aAAa,gBAAgB,MAAM,OAAO,OAAO;AAEvD,QAAM,WAAW,IAAI,UAAU,YAAY;AAC3C,MAAI,UAAoB,CAAC;AACzB,MAAI,MAAM,QAAQ,QAAQ,GAAG;AAC3B,cAAU,SAAS,IAAI,MAAM;AAAA,EAC/B,WAAW,aAAa,QAAW;AACjC,cAAU,CAAC,OAAO,QAAQ,CAAC;AAAA,EAC7B;AACA,UAAQ,KAAK,UAAU;AACvB,MAAI,UAAU,cAAc,OAAO;AACrC;AAEO,SAAS,aAAa,KAAqB,MAAc,SAAmC;AACjG,YAAU,KAAK,MAAM,IAAI,EAAE,QAAQ,GAAG,MAAM,SAAS,QAAQ,IAAI,CAAC;AACpE;AAYO,SAAS,qBAAqB,SAAkB,MAAkC;AACvF,QAAM,eAAe,QAAQ,QAAQ,IAAI,QAAQ;AACjD,MAAI,iBAAiB,KAAM,QAAO;AAClC,QAAM,UAAU,kBAAkB,YAAY;AAC9C,QAAM,QAAQ,QAAQ,IAAI,IAAI;AAC9B,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,sCAAsC,KAAK,KAAK,EAAG,QAAO;AAC9D,SAAO;AACT;AAeO,SAAS,sBACd,QACA,MACA,OACA,SACM;AACN,SAAO,OAAO,cAAc,gBAAgB,MAAM,OAAO,OAAO,CAAC;AACnE;AAQO,SAAS,4BACd,QACA,MACA,SACM;AACN,wBAAsB,QAAQ,MAAM,IAAI,EAAE,QAAQ,GAAG,MAAM,SAAS,QAAQ,IAAI,CAAC;AACnF;","names":[]}
|
|
@@ -216,7 +216,16 @@ var rateLimitSchema = z.union([
|
|
|
216
216
|
z.enum(["ip", "session", "user"]),
|
|
217
217
|
z.function({ input: z.tuple([z.unknown()]), output: z.string() })
|
|
218
218
|
]).optional(),
|
|
219
|
-
cookieName: z.string().min(1).optional()
|
|
219
|
+
cookieName: z.string().min(1).optional(),
|
|
220
|
+
/**
|
|
221
|
+
* How many reverse proxies sit in front of the app, for `keyBy: 'ip'`. `false` (default)
|
|
222
|
+
* trusts none; `true` means one; a number names a longer chain.
|
|
223
|
+
*
|
|
224
|
+
* Required for correct limiting behind Caddy/nginx/a load balancer — without it every visitor
|
|
225
|
+
* keys on the proxy address and shares a single bucket. Off by default because
|
|
226
|
+
* `x-forwarded-for` is client-writable.
|
|
227
|
+
*/
|
|
228
|
+
trustProxy: z.union([z.boolean(), z.number().int().min(0)]).optional()
|
|
220
229
|
})
|
|
221
230
|
]);
|
|
222
231
|
|
|
@@ -3401,4 +3410,4 @@ export {
|
|
|
3401
3410
|
theoPluginAsync,
|
|
3402
3411
|
theoPlugin
|
|
3403
3412
|
};
|
|
3404
|
-
//# sourceMappingURL=chunk-
|
|
3413
|
+
//# sourceMappingURL=chunk-YML4ZDFA.js.map
|