weifuwu 0.24.0 → 0.24.1
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 +200 -92
- package/dist/agent/types.d.ts +2 -1
- package/dist/analytics.d.ts +2 -2
- package/dist/cache.d.ts +4 -4
- package/dist/cors.d.ts +2 -2
- package/dist/deploy/types.d.ts +2 -2
- package/dist/helmet.d.ts +2 -2
- package/dist/hub.d.ts +2 -1
- package/dist/iii/register-worker.d.ts +1 -1
- package/dist/iii/types.d.ts +4 -4
- package/dist/index.js +119 -97
- package/dist/kb/types.d.ts +8 -0
- package/dist/logdb/types.d.ts +2 -1
- package/dist/mailer.d.ts +2 -1
- package/dist/messager/types.d.ts +2 -1
- package/dist/opencode/types.d.ts +2 -1
- package/dist/permissions.d.ts +2 -2
- package/dist/postgres/module.d.ts +2 -1
- package/dist/postgres/types.d.ts +2 -2
- package/dist/queue/types.d.ts +2 -2
- package/dist/rate-limit.d.ts +1 -1
- package/dist/react.js +6 -6
- package/dist/redis/types.d.ts +2 -2
- package/dist/seo.d.ts +2 -2
- package/dist/serve.d.ts +1 -1
- package/dist/session.d.ts +9 -5
- package/dist/tailwind.d.ts +9 -0
- package/dist/tenant/types.d.ts +3 -3
- package/dist/types.d.ts +8 -0
- package/dist/upload.d.ts +4 -2
- package/dist/user/types.d.ts +2 -2
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -196,14 +196,13 @@ The `ctx` object accumulates properties as it passes through the middleware chai
|
|
|
196
196
|
| `query` | Router | `Record<string, string>` | URL query parameters |
|
|
197
197
|
| `mountPath` | Router | `string` | Current sub-router mount prefix |
|
|
198
198
|
| `env` | `loadEnv()` | `Record<string, string>` | Public env vars (`WEIFUWU_PUBLIC_*`) |
|
|
199
|
-
| `
|
|
199
|
+
| `csrf.token` | `csrf()` | `string` | CSRF token (namespace) |
|
|
200
200
|
| `requestId` | `requestId()` | `string` | Request ID |
|
|
201
201
|
| `session` | `session()` | `Session` | Session data object |
|
|
202
202
|
| `sql` | `postgres()` | `Sql<{}>` | PostgreSQL tagged-template client |
|
|
203
203
|
| `redis` | `redis()` | `Redis` | Redis client |
|
|
204
204
|
| `ai` | `aiProvider()` | `AIProvider` | AI model & embedding |
|
|
205
205
|
| `queue` | `queue()` | `Queue` | Job queue |
|
|
206
|
-
| `session` | `session()` | `Session` | Session data object |
|
|
207
206
|
| `user` | `auth()` / `user().middleware()` | `{ id?: string }` | Authenticated user |
|
|
208
207
|
| `permissions` | `permissions()` | `{ roles, permissions }` | RBAC roles & permissions sets |
|
|
209
208
|
| `theme` | `theme()` | `{ value, set }` | Current theme + switcher |
|
|
@@ -223,12 +222,12 @@ Middleware-injected properties are **automatically typed** through chained `use(
|
|
|
223
222
|
|
|
224
223
|
```ts
|
|
225
224
|
const app = new Router()
|
|
226
|
-
.use(csrf()) // → Router<Context & {
|
|
227
|
-
.use(requestId()) // → Router<Context & {
|
|
228
|
-
.use(postgres()) // → Router<Context & {
|
|
225
|
+
.use(csrf()) // → Router<Context & { csrf: { token: string } }>
|
|
226
|
+
.use(requestId()) // → Router<Context & { csrf: ..., requestId }>
|
|
227
|
+
.use(postgres()) // → Router<Context & { csrf: ..., requestId, sql }>
|
|
229
228
|
|
|
230
229
|
app.get('/me', (_req, ctx) => {
|
|
231
|
-
ctx.
|
|
230
|
+
ctx.csrf.token // ✅ string (IDE autocomplete)
|
|
232
231
|
ctx.requestId // ✅ string
|
|
233
232
|
ctx.sql`SELECT 1` // ✅ Sql<{}>
|
|
234
233
|
})
|
|
@@ -379,6 +378,22 @@ graph TD
|
|
|
379
378
|
| **Multi-tenant BaaS** | `tenant()` | β |
|
|
380
379
|
| **Client-side routing** | `useNavigate()`, `<Link>` | δ |
|
|
381
380
|
| **WebSocket in React** | `useWebsocket()` | δ |
|
|
381
|
+
| **Compression (brotli/gzip)** | `compress()` | α |
|
|
382
|
+
| **Security headers (CSP, HSTS)** | `helmet()` | α |
|
|
383
|
+
| **CORS** | `cors()` | α |
|
|
384
|
+
| **CSRF protection** | `csrf()` | α |
|
|
385
|
+
| **Request ID tracing** | `requestId()` | α |
|
|
386
|
+
| **Environment variables** | `env()` / `loadEnv()` | α |
|
|
387
|
+
| **Static file serving** | `serveStatic()` | α |
|
|
388
|
+
| **Object storage (S3/MinIO)** | `s3()` | α |
|
|
389
|
+
| **Send email** | `mailer()` | γ |
|
|
390
|
+
| **Scheduled / cron tasks** | `cron-utils` (`cronNext()`) | γ |
|
|
391
|
+
| **Server-Sent Events** | `createSSEStream()` | γ |
|
|
392
|
+
| **Multi-process deploy** | `deploy()` | γ |
|
|
393
|
+
| **Distributed functions (iii)** | `iii()` | β |
|
|
394
|
+
| **Webhook receiver** | `webhook()` | β |
|
|
395
|
+
| **Social login (OAuth)** | `user({ oauthLogin })` | β |
|
|
396
|
+
| **Database migrations** | `pg.migrate()` | — |
|
|
382
397
|
|
|
383
398
|
---
|
|
384
399
|
|
|
@@ -699,7 +714,7 @@ mem.close()
|
|
|
699
714
|
|
|
700
715
|
```ts
|
|
701
716
|
app.use(csrf())
|
|
702
|
-
// ctx.
|
|
717
|
+
// ctx.csrf.token — set on GET/HEAD/OPTIONS
|
|
703
718
|
// Auto-validates x-csrf-token or x-xsrf-token header on POST/PUT/DELETE/PATCH
|
|
704
719
|
// Falls back to body field matching the key name
|
|
705
720
|
```
|
|
@@ -817,7 +832,40 @@ Restart=always
|
|
|
817
832
|
| `buildCommand` | — | Build command |
|
|
818
833
|
| `ports` | — | `[port, port+1]` for blue-green |
|
|
819
834
|
|
|
835
|
+
### env [α] [DevTools]
|
|
836
|
+
|
|
837
|
+
Environment variable middleware. Injects `ctx.env` with all `WEIFUWU_PUBLIC_*` variables (prefix stripped).
|
|
838
|
+
Safe to expose to the client.
|
|
839
|
+
|
|
840
|
+
```ts
|
|
841
|
+
import { env, loadEnv } from 'weifuwu'
|
|
842
|
+
loadEnv() // Load .env into process.env
|
|
843
|
+
app.use(env()) // → ctx.env
|
|
844
|
+
|
|
845
|
+
app.get('/config', (req, ctx) => {
|
|
846
|
+
return Response.json({ apiUrl: ctx.env.API_URL })
|
|
847
|
+
})
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
Helper utilities:
|
|
851
|
+
|
|
852
|
+
```ts
|
|
853
|
+
import { isDev, isProd, isBundled, getPublicEnv } from 'weifuwu'
|
|
854
|
+
|
|
855
|
+
isDev() // NODE_ENV === 'development'
|
|
856
|
+
isProd() // NODE_ENV === 'production'
|
|
857
|
+
isBundled() // Running from compiled dist/index.js?
|
|
858
|
+
getPublicEnv() // { API_URL: '...' } — no middleware needed
|
|
859
|
+
```
|
|
820
860
|
|
|
861
|
+
| Function | Description |
|
|
862
|
+
|----------|-------------|
|
|
863
|
+
| `loadEnv(path?)` | Load `.env` file into `process.env` (does not override existing) |
|
|
864
|
+
| `env()` | Middleware — injects `ctx.env` with public vars |
|
|
865
|
+
| `getPublicEnv()` | Returns `WEIFUWU_PUBLIC_*` vars with prefix stripped |
|
|
866
|
+
| `isDev()` | `true` when `NODE_ENV === 'development'` |
|
|
867
|
+
| `isProd()` | `true` when `NODE_ENV === 'production'` |
|
|
868
|
+
| `isBundled()` | `true` when running from compiled bundle |
|
|
821
869
|
|
|
822
870
|
### graphql [β] [API]
|
|
823
871
|
|
|
@@ -997,7 +1045,7 @@ app.use(logger({ format: 'combined' })) // with query params
|
|
|
997
1045
|
|
|
998
1046
|
| Option | Type | Default | Description |
|
|
999
1047
|
|--------|------|---------|-------------|
|
|
1000
|
-
| `format` | `'short' \| 'combined'` | `'short'` | Log format: path only,
|
|
1048
|
+
| `format` | `'short' \| 'combined' \| 'json'` | `'short'` | Log format: path only, path + query params, or JSON to stderr |
|
|
1001
1049
|
|
|
1002
1050
|
### mailer [γ] [Networking]
|
|
1003
1051
|
|
|
@@ -1014,28 +1062,31 @@ await mail.send({ to: 'user@test.com', subject: 'Hello', text: 'Body', html: '<p
|
|
|
1014
1062
|
|
|
1015
1063
|
|
|
1016
1064
|
|
|
1017
|
-
###
|
|
1065
|
+
### oauthLogin (via user()) — Social login (OAuth 2.0 client) [Security]
|
|
1018
1066
|
|
|
1019
|
-
|
|
1020
|
-
import { oauthClient } from 'weifuwu'
|
|
1067
|
+
Social login is built into the [`user()`](#user-β) module via the `oauthLogin` option — no separate import needed.
|
|
1021
1068
|
|
|
1069
|
+
```ts
|
|
1022
1070
|
app.use(session()) // required — stores OAuth state
|
|
1023
|
-
|
|
1024
|
-
app.use('/auth', oauthClient({ // mounts /auth/google, /auth/google/callback
|
|
1071
|
+
const u = user({
|
|
1025
1072
|
pg,
|
|
1026
|
-
jwtSecret
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1073
|
+
jwtSecret: process.env.JWT_SECRET!,
|
|
1074
|
+
oauthLogin: {
|
|
1075
|
+
redirectUrl: '/dashboard',
|
|
1076
|
+
providers: {
|
|
1077
|
+
google: {
|
|
1078
|
+
clientId: process.env.GOOGLE_CLIENT_ID,
|
|
1079
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
|
1080
|
+
},
|
|
1081
|
+
github: {
|
|
1082
|
+
clientId: process.env.GITHUB_CLIENT_ID,
|
|
1083
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET,
|
|
1084
|
+
},
|
|
1036
1085
|
},
|
|
1037
1086
|
},
|
|
1038
|
-
})
|
|
1087
|
+
})
|
|
1088
|
+
await u.migrate()
|
|
1089
|
+
app.use(u) // POST /register, POST /login, GET /auth/:provider, GET /auth/:provider/callback
|
|
1039
1090
|
```
|
|
1040
1091
|
|
|
1041
1092
|
**Flow:** User clicks "Login with Google" → redirected to Google → back to app → user created/linked in database → JWT signed → session created → redirected to `redirectUrl` with `?token=` (or JSON response for API clients).
|
|
@@ -1043,39 +1094,37 @@ app.use('/auth', oauthClient({ // mounts /auth/google, /auth/google/ca
|
|
|
1043
1094
|
Supports custom providers via `authUrl`, `tokenUrl`, `userUrl`, and `parseUser`:
|
|
1044
1095
|
|
|
1045
1096
|
```ts
|
|
1046
|
-
|
|
1097
|
+
const u = user({
|
|
1047
1098
|
pg,
|
|
1048
|
-
jwtSecret
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1099
|
+
jwtSecret: process.env.JWT_SECRET!,
|
|
1100
|
+
oauthLogin: {
|
|
1101
|
+
providers: {
|
|
1102
|
+
discord: {
|
|
1103
|
+
clientId: process.env.DISCORD_CLIENT_ID,
|
|
1104
|
+
clientSecret: process.env.DISCORD_CLIENT_SECRET,
|
|
1105
|
+
authUrl: 'https://discord.com/api/oauth2/authorize',
|
|
1106
|
+
tokenUrl: 'https://discord.com/api/oauth2/token',
|
|
1107
|
+
userUrl: 'https://discord.com/api/users/@me',
|
|
1108
|
+
parseUser: (data) => ({
|
|
1109
|
+
id: data.id,
|
|
1110
|
+
email: data.email ?? '',
|
|
1111
|
+
name: data.global_name ?? data.username,
|
|
1112
|
+
avatarUrl: data.avatar
|
|
1113
|
+
? `https://cdn.discordapp.com/avatars/${data.id}/${data.avatar}.png`
|
|
1114
|
+
: '',
|
|
1115
|
+
}),
|
|
1116
|
+
},
|
|
1064
1117
|
},
|
|
1065
1118
|
},
|
|
1066
|
-
})
|
|
1119
|
+
})
|
|
1067
1120
|
```
|
|
1068
1121
|
|
|
1069
|
-
| Option | Type | Default | Description |
|
|
1122
|
+
| Option (oauthLogin) | Type | Default | Description |
|
|
1070
1123
|
|--------|------|---------|-------------|
|
|
1071
|
-
| `pg` | `PostgresClient` | — | **Required.** Database connection |
|
|
1072
|
-
| `jwtSecret` | `string` | — | **Required.** Must match `user()` module's secret |
|
|
1073
1124
|
| `providers` | `Record<string, OAuthProviderConfig>` | — | **Required.** Provider configs (Google/GitHub built-in, any custom) |
|
|
1074
1125
|
| `redirectUrl` | `string` | `'/'` | Post-login redirect destination |
|
|
1075
|
-
| `expiresIn` | `string \| number` | `'24h'` | JWT expiry |
|
|
1076
|
-
| `table` | `string` | `'_auth_providers'` | Provider-user link table name |
|
|
1077
1126
|
|
|
1078
|
-
|
|
1127
|
+
Built-in providers (Google, GitHub) have preset URLs — you only need to provide `clientId` and `clientSecret`. The module auto-creates a `_auth_providers` table on first request.
|
|
1079
1128
|
|
|
1080
1129
|
|
|
1081
1130
|
### messager [β] [Networking]
|
|
@@ -1373,7 +1422,6 @@ app.use(i18n({ default: 'zh', dir: './locales' }))
|
|
|
1373
1422
|
// app.use(l.middleware())
|
|
1374
1423
|
// app.use('/', l)
|
|
1375
1424
|
```
|
|
1376
|
-
```
|
|
1377
1425
|
|
|
1378
1426
|
| Option | Type | Default | Description |
|
|
1379
1427
|
|--------|------|---------|-------------|
|
|
@@ -1524,16 +1572,35 @@ app.use(requestId({ header: 'X-Request-Id', generator: () => crypto.randomUUID()
|
|
|
1524
1572
|
| `header` | `string` | `'X-Request-ID'` | Header name to read/write |
|
|
1525
1573
|
| `generator` | `() => string` | `crypto.randomUUID()` | ID generator |
|
|
1526
1574
|
|
|
1527
|
-
### trace [
|
|
1575
|
+
### trace [α] [DevTools]
|
|
1528
1576
|
|
|
1529
|
-
Request-scoped tracing via `AsyncLocalStorage`.
|
|
1577
|
+
Request-scoped tracing via `AsyncLocalStorage`. Use as middleware to inject `ctx.trace`:
|
|
1530
1578
|
|
|
1531
1579
|
```ts
|
|
1532
|
-
import {
|
|
1580
|
+
import { trace } from 'weifuwu'
|
|
1581
|
+
app.use(trace()) // → ctx.trace
|
|
1582
|
+
app.use(trace({ header: 'X-Trace-Id' })) // custom header
|
|
1583
|
+
|
|
1584
|
+
app.get('/', (req, ctx) => {
|
|
1585
|
+
console.log(ctx.trace.requestId) // 550e8400-e29b-...
|
|
1586
|
+
console.log(ctx.trace.traceId) // trace UUID
|
|
1587
|
+
console.log(ctx.trace.elapsed()) // ms since request start
|
|
1588
|
+
})
|
|
1589
|
+
```
|
|
1590
|
+
|
|
1591
|
+
| Option | Type | Default | Description |
|
|
1592
|
+
|--------|------|---------|-------------|
|
|
1593
|
+
| `header` | `string` | `'X-Request-ID'` | Request ID header name |
|
|
1594
|
+
| `generator` | `() => string` | `crypto.randomUUID()` | Custom ID generator |
|
|
1595
|
+
|
|
1596
|
+
Utility functions (also available standalone):
|
|
1597
|
+
|
|
1598
|
+
```ts
|
|
1599
|
+
import { currentTraceId, runWithTrace, traceElapsed, currentTrace } from 'weifuwu'
|
|
1533
1600
|
|
|
1534
|
-
// Inside a middleware or handler
|
|
1535
1601
|
const traceId = currentTraceId() // UUID or incoming X-Trace-Id
|
|
1536
1602
|
const elapsed = traceElapsed() // ms since request started
|
|
1603
|
+
runWithTrace(incomingId, () => { ... }) // manual scope
|
|
1537
1604
|
```
|
|
1538
1605
|
|
|
1539
1606
|
| Function | Description |
|
|
@@ -1751,7 +1818,7 @@ app.use('/', ssr({ dir: './ui' }))
|
|
|
1751
1818
|
- The vendor bundle (react + react-dom + weifuwu client libs) is compiled once and cached
|
|
1752
1819
|
- Page components are pre-compiled to `/__ssr/{hash}.js` — no runtime esbuild after first request
|
|
1753
1820
|
- **Dev:** `createRoot` + render; **Production:** `hydrateRoot` (reuses SSR DOM)
|
|
1754
|
-
-
|
|
1821
|
+
- The hydration script and page component share the same SSR context store — data flows seamlessly from server to client
|
|
1755
1822
|
- Tailwind CSS served at `/__wfw/style/{hash}.css` (cached, content-hashed)
|
|
1756
1823
|
- Dev mode extras: HMR WebSocket, file watcher, hot component replacement
|
|
1757
1824
|
|
|
@@ -1960,14 +2027,15 @@ Built-in verifiers handle HMAC-SHA256, timestamp validation (Slack's 5-min windo
|
|
|
1960
2027
|
### Client-side navigation [δ] [Client]
|
|
1961
2028
|
|
|
1962
2029
|
```tsx
|
|
1963
|
-
import { Link, useNavigate, useNavigating } from 'weifuwu/react'
|
|
2030
|
+
import { Link, navigate, useNavigate, useNavigating } from 'weifuwu/react'
|
|
1964
2031
|
|
|
1965
2032
|
<Link href="/about" prefetch>About</Link> // client-side nav + prefetch on hover/visible
|
|
1966
|
-
const
|
|
2033
|
+
const n = useNavigate() // hook: n('/contact')
|
|
2034
|
+
navigate('/contact') // bare function (no hook needed)
|
|
1967
2035
|
const loading = useNavigating() // reactive loading state
|
|
1968
2036
|
```
|
|
1969
2037
|
|
|
1970
|
-
`navigate()` fetches SSR, extracts
|
|
2038
|
+
`navigate()` fetches the SSR page, extracts the root container content, and replaces it in-place. Middleware runs on server each nav — data is always fresh.
|
|
1971
2039
|
|
|
1972
2040
|
**Preference URLs** (`/__lang/`, `/__theme/`) are intercepted by modular interceptors registered via `addInterceptor()` — no page reload needed. Importing `useLocale` or `useTheme` registers the interceptor automatically.
|
|
1973
2041
|
|
|
@@ -2062,7 +2130,7 @@ function Page() {
|
|
|
2062
2130
|
}
|
|
2063
2131
|
```
|
|
2064
2132
|
|
|
2065
|
-
On the server, data flows from middleware → `ctx` → `setCtx(ctxValue)` (serialized via JSON). On the client, the hydration script calls `setCtx(ctxData)` which populates the shared store
|
|
2133
|
+
On the server, data flows from middleware → `ctx` → `setCtx(ctxValue)` (serialized via JSON). On the client, the hydration script calls `setCtx(ctxData)` which populates the shared context store. `useLoaderData()` reads from the snapshot via `useSyncExternalStore` — no SSR-specific code needed in your components.
|
|
2066
2134
|
|
|
2067
2135
|
**`addInterceptor(fn)`** — Register a URL interceptor. Interceptors run before SPA navigation; if one returns `true`, `navigate()` skips the fetch-and-swap.
|
|
2068
2136
|
|
|
@@ -2116,7 +2184,7 @@ Auto-detected when `NODE_ENV === 'development'`. `ssr({dir})` automatically regi
|
|
|
2116
2184
|
|
|
2117
2185
|
- Inline hydration script uses `createRoot` + render (replaces SSR DOM)
|
|
2118
2186
|
- Vendor bundle served at `/__wfw/v/bundle?h=<hash>` — compiled from source, unminified
|
|
2119
|
-
- Hot component replacement: file changes → WebSocket message → browser imports hot bundle →
|
|
2187
|
+
- Hot component replacement: file changes → WebSocket message → browser imports hot bundle → component refreshed in place — `useState` values preserved
|
|
2120
2188
|
- Tailwind CSS hot-reloads without page refresh
|
|
2121
2189
|
- Layout changes trigger a full page reload
|
|
2122
2190
|
|
|
@@ -2206,16 +2274,24 @@ Every public symbol can be imported from `'weifuwu'`:
|
|
|
2206
2274
|
```ts
|
|
2207
2275
|
serve, createTestServer, Router, ssr,
|
|
2208
2276
|
Context, Handler, Middleware, ErrorHandler, ServeOptions, Server,
|
|
2209
|
-
loadEnv,
|
|
2210
|
-
currentTraceId, currentTrace, runWithTrace, traceElapsed, TraceContext,
|
|
2277
|
+
loadEnv, env, isDev, isProd, isBundled, getPublicEnv,
|
|
2278
|
+
currentTraceId, currentTrace, runWithTrace, traceElapsed, trace, TraceContext,
|
|
2279
|
+
testApp, TestApp, TestRequest, TestResponse,
|
|
2280
|
+
createTestDb, withTestDb,
|
|
2281
|
+
getCookies, setCookie, deleteCookie,
|
|
2282
|
+
createSSEStream, formatSSE, formatSSEData, SSEEvent,
|
|
2283
|
+
DEFAULT_MAX_BODY, MIGRATIONS_TABLE,
|
|
2211
2284
|
```
|
|
2212
2285
|
|
|
2213
|
-
### Middleware
|
|
2286
|
+
### Middleware / DevTools
|
|
2214
2287
|
|
|
2215
2288
|
```ts
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2289
|
+
logger, cors, compress, helmet,
|
|
2290
|
+
rateLimit, requestId, validate, upload,
|
|
2291
|
+
csrf, session, MemoryStore, RedisStore, SessionStore,
|
|
2292
|
+
cache, MemoryCache, RedisCache, CacheStore,
|
|
2293
|
+
flash, permissions,
|
|
2294
|
+
serveStatic, s3,
|
|
2219
2295
|
```
|
|
2220
2296
|
|
|
2221
2297
|
### Database
|
|
@@ -2225,55 +2301,87 @@ postgres, PostgresOptions, PostgresClient,
|
|
|
2225
2301
|
redis, RedisOptions, RedisClient,
|
|
2226
2302
|
queue, QueueOptions, QueueJob, Queue,
|
|
2227
2303
|
PostgresInjected, RedisInjected, QueueInjected,
|
|
2228
|
-
// Schema helpers
|
|
2304
|
+
// Schema helpers:
|
|
2229
2305
|
pgTable, SQL, sql,
|
|
2230
2306
|
ColumnBuilder, serial, uuid, text, integer, boolean, boolean_, timestamptz, jsonb, textArray, vector,
|
|
2231
2307
|
partitionBy, timestamps, toDDL, PartitionByDef,
|
|
2232
2308
|
Table, BoundTable, IndexOptions, FindOptions, CreateOptions,
|
|
2233
|
-
eq, ne, gt, gte, lt, lte, isNull, isNotNull, like, contains, in_, and, or, not
|
|
2309
|
+
eq, ne, gt, gte, lt, lte, isNull, isNotNull, like, contains, in_, and, or, not,
|
|
2310
|
+
fts,
|
|
2234
2311
|
```
|
|
2235
2312
|
|
|
2236
|
-
###
|
|
2313
|
+
### Security / Auth
|
|
2237
2314
|
|
|
2238
2315
|
```ts
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2316
|
+
auth,
|
|
2317
|
+
user, UserModule, UserData, UserOptions, UserInjected, OAuthProviderConfig, OAuth2Client,
|
|
2318
|
+
permissions, PermissionsModule, PermissionsOptions,
|
|
2319
|
+
csrf, CsrfOptions, CsrfInjected,
|
|
2320
|
+
helmet, HelmetOptions,
|
|
2321
|
+
session, SessionStore, SessionOptions, SessionData, SessionInjected,
|
|
2322
|
+
rateLimit, RateLimitOptions,
|
|
2245
2323
|
```
|
|
2246
|
-
export type { UseAgentStreamOptions, UseAgentStreamReturn, AgentStreamState } from 'weifuwu/react'
|
|
2247
2324
|
|
|
2248
|
-
###
|
|
2325
|
+
### UX Middleware
|
|
2249
2326
|
|
|
2250
2327
|
```ts
|
|
2251
|
-
|
|
2328
|
+
theme, ThemeOptions, ThemeInjected,
|
|
2329
|
+
i18n, I18nOptions, I18nInjected,
|
|
2330
|
+
flash, FlashOptions, FlashInjected,
|
|
2252
2331
|
```
|
|
2253
2332
|
|
|
2254
|
-
### AI
|
|
2333
|
+
### AI
|
|
2255
2334
|
|
|
2256
2335
|
```ts
|
|
2336
|
+
aiProvider, AIProvider, AIProviderOptions, AIProviderInjected,
|
|
2257
2337
|
streamText, generateText, streamObject, generateObject,
|
|
2258
2338
|
tool, embed, embedMany, smoothStream,
|
|
2259
|
-
openai, createOpenAI
|
|
2339
|
+
openai, createOpenAI,
|
|
2340
|
+
aiStream, AIHandler,
|
|
2341
|
+
runWorkflow,
|
|
2342
|
+
agent, AgentModule, AgentOptions,
|
|
2343
|
+
knowledgeBase, KBModule, KBOptions,
|
|
2344
|
+
opencode, OpencodeModule, OpencodeOptions,
|
|
2260
2345
|
```
|
|
2261
2346
|
|
|
2262
|
-
###
|
|
2347
|
+
### API / Routing
|
|
2263
2348
|
|
|
2264
2349
|
```ts
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2350
|
+
analytics, AnalyticsModule, AnalyticsOptions,
|
|
2351
|
+
health, HealthOptions,
|
|
2352
|
+
graphql, GraphQLOptions, GraphQLHandler,
|
|
2353
|
+
logdb, LogdbModule, LogdbOptions,
|
|
2354
|
+
seo, seoMiddleware, seoTags, SeoOptions,
|
|
2355
|
+
webhook, WebhookModule, WebhookOptions,
|
|
2356
|
+
iii, createWorker, registerWorker, IIIModule, IIIOptions,
|
|
2357
|
+
```
|
|
2358
|
+
|
|
2359
|
+
### Networking / Storage
|
|
2360
|
+
|
|
2361
|
+
```ts
|
|
2362
|
+
s3, S3Options, S3Module, S3Body,
|
|
2363
|
+
mailer, MailerOptions, Mailer,
|
|
2364
|
+
messager, MessagerModule, MessagerOptions,
|
|
2365
|
+
hub, createHub, Hub, HubOptions,
|
|
2366
|
+
deploy, defineConfig, DeployConfig, AppConfig,
|
|
2367
|
+
tenant, TenantModule, TenantOptions, TenantContext,
|
|
2368
|
+
```
|
|
2369
|
+
|
|
2370
|
+
### Client-side (from `'weifuwu/react'`)
|
|
2371
|
+
|
|
2372
|
+
```ts
|
|
2373
|
+
TsxContext, setCtx, useCtx, addCtxRebuilder, useLoaderData,
|
|
2374
|
+
useWebsocket, useAction, useFetch, useQueryState, createStore,
|
|
2375
|
+
Link, useNavigate, useNavigating, addInterceptor,
|
|
2376
|
+
useLocale, useTheme, applyTheme, useFlashMessage,
|
|
2377
|
+
useAgentStream,
|
|
2378
|
+
Head,
|
|
2379
|
+
|
|
2380
|
+
// Types:
|
|
2381
|
+
StoreApi,
|
|
2382
|
+
UseActionOptions, UseActionReturn,
|
|
2383
|
+
UseWebsocketOptions, UseWebsocketReturn,
|
|
2384
|
+
UseAgentStreamOptions, UseAgentStreamReturn, AgentStreamState,
|
|
2277
2385
|
```
|
|
2278
2386
|
|
|
2279
2387
|
---
|
package/dist/agent/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Router } from '../router.ts';
|
|
2
2
|
import type { LanguageModel, EmbeddingModel, Tool } from 'ai';
|
|
3
3
|
import type { AIProvider } from '../ai/provider.ts';
|
|
4
|
+
import type { Closeable } from '../types.ts';
|
|
4
5
|
export interface AgentConfig {
|
|
5
6
|
id: number;
|
|
6
7
|
tenant_id: string | null;
|
|
@@ -46,7 +47,7 @@ export interface AgentOptions {
|
|
|
46
47
|
embeddingDimension?: number;
|
|
47
48
|
tools?: Record<string, Tool>;
|
|
48
49
|
}
|
|
49
|
-
export interface AgentModule extends Router {
|
|
50
|
+
export interface AgentModule extends Router, Closeable {
|
|
50
51
|
migrate: () => Promise<void>;
|
|
51
52
|
run: (agentId: number, params: RunParams) => Promise<RunResult>;
|
|
52
53
|
addKnowledge: (agentId: number, title: string, content: string) => Promise<KnowledgeDoc>;
|
package/dist/analytics.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Middleware } from './types.ts';
|
|
1
|
+
import type { Middleware, Closeable } from './types.ts';
|
|
2
2
|
import { Router } from './router.ts';
|
|
3
3
|
/** Options for {@link analytics}. */
|
|
4
4
|
export interface AnalyticsOptions {
|
|
@@ -11,7 +11,7 @@ export interface AnalyticsOptions {
|
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
13
|
/** Analytics module returned by {@link analytics}. */
|
|
14
|
-
export interface AnalyticsModule extends Router {
|
|
14
|
+
export interface AnalyticsModule extends Router, Closeable {
|
|
15
15
|
/** Middleware that records page views. */
|
|
16
16
|
middleware: () => Middleware;
|
|
17
17
|
/** Create/update the analytics database tables. */
|
package/dist/cache.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Context, Middleware } from './types.ts';
|
|
1
|
+
import type { Context, Middleware, Closeable } from './types.ts';
|
|
2
2
|
import type { Redis } from './vendor.ts';
|
|
3
3
|
export interface CachedResponse {
|
|
4
4
|
status: number;
|
|
@@ -33,13 +33,13 @@ export interface CacheOptions {
|
|
|
33
33
|
/** Maximum number of bytes per cached body. Default: 1MB. Larger bodies are skipped. */
|
|
34
34
|
maxBodySize?: number;
|
|
35
35
|
}
|
|
36
|
-
export interface CacheMiddleware extends Middleware {
|
|
36
|
+
export interface CacheMiddleware extends Middleware, Closeable {
|
|
37
37
|
/** Invalidate all entries with a given tag. */
|
|
38
38
|
invalidate(tag: string): Promise<void>;
|
|
39
39
|
/** Flush all cached entries. */
|
|
40
40
|
flush(): Promise<void>;
|
|
41
41
|
/** Cleanup. */
|
|
42
|
-
close(): void
|
|
42
|
+
close(): Promise<void>;
|
|
43
43
|
/** Store reference (for testing). */
|
|
44
44
|
store: CacheStore;
|
|
45
45
|
}
|
|
@@ -54,7 +54,7 @@ export declare class MemoryCache implements CacheStore {
|
|
|
54
54
|
invalidate(tag: string): Promise<void>;
|
|
55
55
|
flush(): Promise<void>;
|
|
56
56
|
private cleanup;
|
|
57
|
-
close(): void
|
|
57
|
+
close(): Promise<void>;
|
|
58
58
|
/** Testing only. */
|
|
59
59
|
get size(): number;
|
|
60
60
|
}
|
package/dist/cors.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Middleware } from './types.ts';
|
|
1
|
+
import type { Middleware, Context } from './types.ts';
|
|
2
2
|
/** Options for {@link cors}. */
|
|
3
3
|
export interface CORSOptions {
|
|
4
4
|
/** Allowed origin(s). Default `'*'`. If `credentials: true`, reflects the request origin. */
|
|
@@ -22,4 +22,4 @@ export interface CORSOptions {
|
|
|
22
22
|
* app.use(cors({ origin: 'https://myapp.com', credentials: true }))
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
export declare function cors(options?: CORSOptions): Middleware
|
|
25
|
+
export declare function cors(options?: CORSOptions): Middleware<Context, Context>;
|
package/dist/deploy/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IncomingMessage } from 'node:http';
|
|
2
2
|
import type { Duplex } from 'node:stream';
|
|
3
|
-
import type { Handler } from '../types.ts';
|
|
3
|
+
import type { Handler, Closeable } from '../types.ts';
|
|
4
4
|
export interface DeployConfig {
|
|
5
5
|
domain?: string;
|
|
6
6
|
port?: number;
|
|
@@ -27,7 +27,7 @@ export interface AppStatus {
|
|
|
27
27
|
uptime?: number;
|
|
28
28
|
error?: string;
|
|
29
29
|
}
|
|
30
|
-
export interface DeployServer {
|
|
30
|
+
export interface DeployServer extends Closeable {
|
|
31
31
|
close(): Promise<void>;
|
|
32
32
|
ready: Promise<void>;
|
|
33
33
|
url: string;
|
package/dist/helmet.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Middleware } from './types.ts';
|
|
1
|
+
import type { Middleware, Context } from './types.ts';
|
|
2
2
|
/** Options for {@link helmet}. Set any header to `false` to omit it. */
|
|
3
3
|
export interface HelmetOptions {
|
|
4
4
|
/** `Content-Security-Policy` header value. */
|
|
@@ -30,4 +30,4 @@ export interface HelmetOptions {
|
|
|
30
30
|
/** `Permissions-Policy` header value. */
|
|
31
31
|
permissionsPolicy?: string | false;
|
|
32
32
|
}
|
|
33
|
-
export declare function helmet(options?: HelmetOptions): Middleware
|
|
33
|
+
export declare function helmet(options?: HelmetOptions): Middleware<Context, Context>;
|
package/dist/hub.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Redis, WebSocket } from './vendor.ts';
|
|
2
|
+
import type { Closeable } from './types.ts';
|
|
2
3
|
/** Options for {@link createHub}. */
|
|
3
4
|
export interface HubOptions {
|
|
4
5
|
/** Optional Redis client for cross-process pub/sub broadcast. */
|
|
@@ -10,7 +11,7 @@ export interface HubOptions {
|
|
|
10
11
|
* In-memory (and optionally Redis-backed) pub/sub hub for WebSocket rooms.
|
|
11
12
|
*
|
|
12
13
|
* Used internally by the WebSocket handler to implement `ctx.ws.join()` / `ctx.ws.sendRoom()`. */
|
|
13
|
-
export interface Hub {
|
|
14
|
+
export interface Hub extends Closeable {
|
|
14
15
|
/** Subscribe a WebSocket to a room/group. */
|
|
15
16
|
join(key: string, ws: WebSocket): void;
|
|
16
17
|
/** Unsubscribe a WebSocket from all rooms. */
|
package/dist/iii/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Router } from '../router.ts';
|
|
2
|
+
import type { Closeable } from '../types.ts';
|
|
2
3
|
import type { Redis } from '../vendor.ts';
|
|
3
4
|
import type { PostgresClient } from '../postgres/types.ts';
|
|
4
5
|
export type FunctionHandler = (payload: unknown, ctx: FunctionContext) => unknown | Promise<unknown>;
|
|
@@ -30,7 +31,7 @@ export interface TriggerOptions {
|
|
|
30
31
|
action?: 'sync' | 'void';
|
|
31
32
|
timeout_ms?: number;
|
|
32
33
|
}
|
|
33
|
-
export interface IIIModule extends Router {
|
|
34
|
+
export interface IIIModule extends Router, Closeable {
|
|
34
35
|
wsHandler: () => any;
|
|
35
36
|
addWorker: (worker: Worker) => void;
|
|
36
37
|
trigger: (request: TriggerRequest) => Promise<unknown>;
|
|
@@ -39,8 +40,6 @@ export interface IIIModule extends Router {
|
|
|
39
40
|
listFunctions: () => FunctionInfo[];
|
|
40
41
|
listTriggers: () => TriggerInfo[];
|
|
41
42
|
migrate: () => Promise<void>;
|
|
42
|
-
shutdown: () => Promise<void>;
|
|
43
|
-
/** Alias for shutdown(). */
|
|
44
43
|
close: () => Promise<void>;
|
|
45
44
|
}
|
|
46
45
|
export interface WorkerInfo {
|
|
@@ -87,7 +86,8 @@ export interface RemoteWorker {
|
|
|
87
86
|
registerTrigger: (input: TriggerInput) => void;
|
|
88
87
|
unregisterTrigger: (functionId: string) => void;
|
|
89
88
|
trigger: (request: TriggerRequest) => Promise<unknown>;
|
|
90
|
-
|
|
89
|
+
/** Cleanup worker resources. */
|
|
90
|
+
close: () => void;
|
|
91
91
|
}
|
|
92
92
|
export interface FunctionRegistration {
|
|
93
93
|
id: string;
|