weifuwu 0.25.2 → 0.27.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.
Files changed (208) hide show
  1. package/README.md +291 -2489
  2. package/ai/provider.ts +129 -0
  3. package/ai/stream.ts +63 -0
  4. package/cli.ts +55 -257
  5. package/core/cookie.ts +114 -0
  6. package/core/env.ts +142 -0
  7. package/core/logger.ts +72 -0
  8. package/core/router.ts +795 -0
  9. package/core/serve.ts +294 -0
  10. package/core/sse.ts +85 -0
  11. package/core/trace.ts +146 -0
  12. package/graphql.ts +267 -0
  13. package/hub.ts +133 -0
  14. package/index.ts +71 -0
  15. package/mailer.ts +81 -0
  16. package/middleware/compress.ts +103 -0
  17. package/middleware/cors.ts +81 -0
  18. package/middleware/csrf.ts +112 -0
  19. package/middleware/flash.ts +144 -0
  20. package/middleware/health.ts +44 -0
  21. package/middleware/helmet.ts +98 -0
  22. package/middleware/i18n.ts +175 -0
  23. package/middleware/rate-limit.ts +167 -0
  24. package/middleware/request-id.ts +60 -0
  25. package/middleware/static.ts +149 -0
  26. package/middleware/theme.ts +84 -0
  27. package/middleware/upload.ts +168 -0
  28. package/middleware/validate.ts +186 -0
  29. package/package.json +14 -36
  30. package/postgres/client.ts +132 -0
  31. package/postgres/index.ts +4 -0
  32. package/postgres/module.ts +37 -0
  33. package/postgres/schema/columns.ts +186 -0
  34. package/postgres/schema/index.ts +36 -0
  35. package/postgres/schema/sql.ts +39 -0
  36. package/postgres/schema/table.ts +548 -0
  37. package/postgres/schema/where.ts +99 -0
  38. package/postgres/types.ts +48 -0
  39. package/queue/cron.ts +90 -0
  40. package/queue/index.ts +654 -0
  41. package/queue/types.ts +60 -0
  42. package/redis/client.ts +24 -0
  43. package/{dist/redis/index.d.ts → redis/index.ts} +2 -2
  44. package/redis/types.ts +28 -0
  45. package/types.ts +78 -0
  46. package/cli/template/app.ts +0 -22
  47. package/cli/template/index.ts +0 -10
  48. package/cli/template/locales/en.json +0 -13
  49. package/cli/template/locales/zh-CN.json +0 -13
  50. package/cli/template/locales/zh-TW.json +0 -13
  51. package/cli/template/locales/zh.json +0 -13
  52. package/cli/template/ui/app/globals.css +0 -2
  53. package/cli/template/ui/app/layout.tsx +0 -15
  54. package/cli/template/ui/app/page.tsx +0 -124
  55. package/cli/template/ui/components/Greeting.tsx +0 -3
  56. package/dist/agent/client.d.ts +0 -2
  57. package/dist/agent/index.d.ts +0 -2
  58. package/dist/agent/rest.d.ts +0 -14
  59. package/dist/agent/run.d.ts +0 -19
  60. package/dist/agent/types.d.ts +0 -55
  61. package/dist/ai/provider.d.ts +0 -45
  62. package/dist/ai/utils.d.ts +0 -5
  63. package/dist/ai/workflow.d.ts +0 -17
  64. package/dist/ai-sdk.d.ts +0 -2
  65. package/dist/ai.d.ts +0 -13
  66. package/dist/analytics.d.ts +0 -45
  67. package/dist/auth.d.ts +0 -22
  68. package/dist/cache.d.ts +0 -74
  69. package/dist/cli.d.ts +0 -2
  70. package/dist/cli.js +0 -302
  71. package/dist/client-locale.d.ts +0 -25
  72. package/dist/client-pref.d.ts +0 -3
  73. package/dist/client-router.d.ts +0 -300
  74. package/dist/client-state.d.ts +0 -22
  75. package/dist/client-theme.d.ts +0 -36
  76. package/dist/compile.d.ts +0 -15
  77. package/dist/compress.d.ts +0 -20
  78. package/dist/cookie.d.ts +0 -36
  79. package/dist/cors.d.ts +0 -25
  80. package/dist/cron-utils.d.ts +0 -73
  81. package/dist/csrf.d.ts +0 -47
  82. package/dist/deploy/config.d.ts +0 -2
  83. package/dist/deploy/gateway.d.ts +0 -2
  84. package/dist/deploy/index.d.ts +0 -4
  85. package/dist/deploy/manager.d.ts +0 -16
  86. package/dist/deploy/process.d.ts +0 -14
  87. package/dist/deploy/types.d.ts +0 -53
  88. package/dist/env.d.ts +0 -69
  89. package/dist/error-boundary.d.ts +0 -2
  90. package/dist/flash.d.ts +0 -90
  91. package/dist/fts.d.ts +0 -36
  92. package/dist/graphql.d.ts +0 -16
  93. package/dist/head.d.ts +0 -6
  94. package/dist/health.d.ts +0 -24
  95. package/dist/helmet.d.ts +0 -33
  96. package/dist/html-shell.d.ts +0 -1
  97. package/dist/hub.d.ts +0 -37
  98. package/dist/i18n.d.ts +0 -39
  99. package/dist/iii/client.d.ts +0 -2
  100. package/dist/iii/index.d.ts +0 -4
  101. package/dist/iii/register-worker.d.ts +0 -9
  102. package/dist/iii/rest.d.ts +0 -3
  103. package/dist/iii/stream.d.ts +0 -82
  104. package/dist/iii/types.d.ts +0 -121
  105. package/dist/iii/worker.d.ts +0 -2
  106. package/dist/iii/ws.d.ts +0 -22
  107. package/dist/index.d.ts +0 -101
  108. package/dist/index.js +0 -12752
  109. package/dist/kb/index.d.ts +0 -3
  110. package/dist/kb/types.d.ts +0 -72
  111. package/dist/layout.d.ts +0 -2
  112. package/dist/live.d.ts +0 -7
  113. package/dist/logdb/client.d.ts +0 -2
  114. package/dist/logdb/index.d.ts +0 -2
  115. package/dist/logdb/rest.d.ts +0 -5
  116. package/dist/logdb/types.d.ts +0 -27
  117. package/dist/logger.d.ts +0 -16
  118. package/dist/mailer.d.ts +0 -51
  119. package/dist/mcp.d.ts +0 -34
  120. package/dist/messager/agent.d.ts +0 -11
  121. package/dist/messager/client.d.ts +0 -2
  122. package/dist/messager/index.d.ts +0 -2
  123. package/dist/messager/rest.d.ts +0 -15
  124. package/dist/messager/types.d.ts +0 -57
  125. package/dist/messager/ws.d.ts +0 -14
  126. package/dist/module-server.d.ts +0 -9
  127. package/dist/not-found.d.ts +0 -2
  128. package/dist/notifier/client.d.ts +0 -2
  129. package/dist/notifier/index.d.ts +0 -2
  130. package/dist/notifier/types.d.ts +0 -105
  131. package/dist/opencode/client.d.ts +0 -2
  132. package/dist/opencode/index.d.ts +0 -2
  133. package/dist/opencode/permissions.d.ts +0 -5
  134. package/dist/opencode/prompt.d.ts +0 -8
  135. package/dist/opencode/rest.d.ts +0 -16
  136. package/dist/opencode/run.d.ts +0 -13
  137. package/dist/opencode/session.d.ts +0 -26
  138. package/dist/opencode/skills.d.ts +0 -4
  139. package/dist/opencode/tools/bash.d.ts +0 -6
  140. package/dist/opencode/tools/edit.d.ts +0 -19
  141. package/dist/opencode/tools/glob.d.ts +0 -9
  142. package/dist/opencode/tools/grep.d.ts +0 -17
  143. package/dist/opencode/tools/index.d.ts +0 -12
  144. package/dist/opencode/tools/question.d.ts +0 -5
  145. package/dist/opencode/tools/read.d.ts +0 -16
  146. package/dist/opencode/tools/skill.d.ts +0 -18
  147. package/dist/opencode/tools/web.d.ts +0 -18
  148. package/dist/opencode/tools/write.d.ts +0 -13
  149. package/dist/opencode/types.d.ts +0 -90
  150. package/dist/opencode/ws.d.ts +0 -21
  151. package/dist/permissions.d.ts +0 -51
  152. package/dist/postgres/client.d.ts +0 -4
  153. package/dist/postgres/index.d.ts +0 -4
  154. package/dist/postgres/module.d.ts +0 -17
  155. package/dist/postgres/schema/columns.d.ts +0 -99
  156. package/dist/postgres/schema/index.d.ts +0 -6
  157. package/dist/postgres/schema/sql.d.ts +0 -22
  158. package/dist/postgres/schema/table.d.ts +0 -141
  159. package/dist/postgres/schema/where.d.ts +0 -29
  160. package/dist/postgres/types.d.ts +0 -50
  161. package/dist/queue/index.d.ts +0 -2
  162. package/dist/queue/types.d.ts +0 -62
  163. package/dist/rate-limit.d.ts +0 -45
  164. package/dist/react.d.ts +0 -14
  165. package/dist/react.js +0 -751
  166. package/dist/redis/client.d.ts +0 -2
  167. package/dist/redis/types.d.ts +0 -18
  168. package/dist/request-id.d.ts +0 -40
  169. package/dist/router.d.ts +0 -73
  170. package/dist/s3.d.ts +0 -68
  171. package/dist/seo.d.ts +0 -104
  172. package/dist/serve.d.ts +0 -38
  173. package/dist/server-registry.d.ts +0 -10
  174. package/dist/session.d.ts +0 -117
  175. package/dist/sse.d.ts +0 -47
  176. package/dist/ssr-entries.d.ts +0 -4
  177. package/dist/ssr.d.ts +0 -11
  178. package/dist/static.d.ts +0 -23
  179. package/dist/stream.d.ts +0 -24
  180. package/dist/tailwind.d.ts +0 -15
  181. package/dist/tenant/client.d.ts +0 -2
  182. package/dist/tenant/graphql.d.ts +0 -3
  183. package/dist/tenant/index.d.ts +0 -2
  184. package/dist/tenant/rest.d.ts +0 -3
  185. package/dist/tenant/schema.d.ts +0 -5
  186. package/dist/tenant/types.d.ts +0 -48
  187. package/dist/tenant/utils.d.ts +0 -9
  188. package/dist/test-utils.d.ts +0 -194
  189. package/dist/theme.d.ts +0 -31
  190. package/dist/trace.d.ts +0 -95
  191. package/dist/tsx-context.d.ts +0 -32
  192. package/dist/types.d.ts +0 -47
  193. package/dist/upload.d.ts +0 -55
  194. package/dist/use-action.d.ts +0 -42
  195. package/dist/use-agent-stream.d.ts +0 -49
  196. package/dist/use-flash-message.d.ts +0 -17
  197. package/dist/use-websocket.d.ts +0 -42
  198. package/dist/user/client.d.ts +0 -30
  199. package/dist/user/index.d.ts +0 -2
  200. package/dist/user/oauth-login.d.ts +0 -21
  201. package/dist/user/oauth2.d.ts +0 -31
  202. package/dist/user/types.d.ts +0 -178
  203. package/dist/validate.d.ts +0 -32
  204. package/dist/vendor.d.ts +0 -7
  205. package/dist/webhook.d.ts +0 -79
  206. package/opencode/ui/app/globals.css +0 -1
  207. package/opencode/ui/app/layout.tsx +0 -13
  208. package/opencode/ui/app/page.tsx +0 -523
@@ -1,48 +0,0 @@
1
- import type { Context, Handler } from '../types.ts';
2
- import type { Router } from '../router.ts';
3
- import type { PostgresClient } from '../postgres/types.ts';
4
- declare module '../types.ts' {
5
- interface Context {
6
- tenant: TenantContext;
7
- }
8
- }
9
- export interface TenantContext {
10
- id: string;
11
- name: string;
12
- role: string;
13
- }
14
- export type FieldType = 'string' | 'integer' | 'float' | 'boolean' | 'text' | 'datetime' | 'date' | 'enum' | 'json' | 'vector';
15
- export interface RelationDef {
16
- table: string;
17
- field?: string;
18
- onDelete?: 'cascade' | 'restrict' | 'setnull';
19
- }
20
- export interface FieldDef {
21
- name: string;
22
- type: FieldType;
23
- required?: boolean;
24
- unique?: boolean;
25
- index?: boolean | 'desc' | 'gin' | 'hnsw';
26
- default?: unknown;
27
- options?: string[];
28
- dimensions?: number;
29
- relation?: RelationDef;
30
- }
31
- export interface UserTableRow {
32
- id: number;
33
- tenant_id: string;
34
- slug: string;
35
- label: string;
36
- fields: FieldDef[];
37
- created_at: string;
38
- }
39
- export interface TenantOptions {
40
- pg: PostgresClient;
41
- usersTable: string;
42
- }
43
- export interface TenantModule extends Router {
44
- migrate: () => Promise<void>;
45
- middleware: () => (req: Request, ctx: Context, next: Handler<Context>) => Promise<Response>;
46
- graphql: () => Router;
47
- close: () => Promise<void>;
48
- }
@@ -1,9 +0,0 @@
1
- import type { FieldDef } from './types.ts';
2
- export declare function internalTableName(tenantId: string, slug: string): string;
3
- export declare function pascalCase(slug: string): string;
4
- export declare function sqlTypeForField(field: FieldDef): string;
5
- export declare function validateSlug(slug: string): string | null;
6
- export declare function validateFieldDefs(fields: FieldDef[]): string[];
7
- export declare function formatDefault(field: FieldDef): string;
8
- export declare function getRelationFields(fields: FieldDef[]): FieldDef[];
9
- export declare function findRelation(fields: FieldDef[], targetSlug: string): FieldDef | undefined;
@@ -1,194 +0,0 @@
1
- import type { Context, Handler } from './types.ts';
2
- import type { SqlClient } from './vendor.ts';
3
- import { Router } from './router.ts';
4
- import { WebSocket as WSWebSocket } from 'ws';
5
- export interface TestResponse {
6
- readonly status: number;
7
- readonly headers: Headers;
8
- json<T = unknown>(): Promise<T>;
9
- text(): Promise<string>;
10
- }
11
- export declare class TestRequest {
12
- private headers;
13
- private ctxMixin;
14
- private bodyData;
15
- private app;
16
- private method;
17
- private path;
18
- constructor(app: TestApp, method: string, path: string);
19
- /** Set a request header */
20
- header(name: string, value: string): this;
21
- /** Mix properties into ctx (simulating middleware injection) */
22
- with(mixin: Partial<Context>): this;
23
- /** Shortcut: set ctx.user */
24
- withUser(user: unknown): this;
25
- /** Shortcut: set ctx.tenant */
26
- withTenant(tenant: {
27
- id: string;
28
- name: string;
29
- role: string;
30
- }): this;
31
- /** Set JSON request body */
32
- body(data: unknown): this;
33
- /** Set raw text body */
34
- rawBody(data: string): this;
35
- /** Send the request and return the response */
36
- send(): Promise<TestResponse>;
37
- }
38
- export declare class TestApp {
39
- private router;
40
- private wsServer;
41
- private wsConnections;
42
- constructor();
43
- /**
44
- * Register a WebSocket handler.
45
- */
46
- ws(path: string, handler: import('./router.ts').WebSocketHandler): this;
47
- /** Get the raw Router (for advanced use). */
48
- get _router(): Router;
49
- /** Add global middleware */
50
- use(mw: any): this;
51
- /** Register a GET route — supports route-level middleware via spread args. */
52
- get(path: string, ...args: any[]): this;
53
- /** Register a POST route. */
54
- post(path: string, ...args: any[]): this;
55
- /** Register a PUT route. */
56
- put(path: string, ...args: any[]): this;
57
- /** Register a PATCH route. */
58
- patch(path: string, ...args: any[]): this;
59
- /** Register a DELETE route. */
60
- delete(path: string, ...args: any[]): this;
61
- /** Start building a GET request */
62
- getReq(path: string): TestRequest;
63
- /** Start building a POST request */
64
- postReq(path: string): TestRequest;
65
- /** Start building a PUT request */
66
- putReq(path: string): TestRequest;
67
- /** Start building a PATCH request */
68
- patchReq(path: string): TestRequest;
69
- /** Start building a DELETE request */
70
- deleteReq(path: string): TestRequest;
71
- /** Get the underlying handler (for advanced usage) */
72
- handler(): Handler;
73
- /** Start building a WebSocket connection to the given path. */
74
- wsReq(path: string): TestWSRequest;
75
- /**
76
- * Internal: ensure HTTP server is running for WebSocket connections.
77
- * Starts on a random port.
78
- */
79
- _ensureServer(): Promise<string>;
80
- /**
81
- * Internal: register a WS connection for cleanup.
82
- */
83
- _trackConnection(conn: TestWSConnection): void;
84
- /**
85
- * Cleanup all WebSocket connections and stop the server.
86
- */
87
- close(): Promise<void>;
88
- }
89
- /** Start building a WebSocket test connection. */
90
- export declare class TestWSRequest {
91
- private app;
92
- private path;
93
- private _timeout;
94
- constructor(app: TestApp, path: string);
95
- /** Set the timeout for operations (default: 5000ms). */
96
- timeout(ms: number): this;
97
- /**
98
- * Connect to the WebSocket endpoint.
99
- * Starts a real HTTP server (random port) if not already running.
100
- */
101
- connect(): Promise<TestWSConnection>;
102
- }
103
- /**
104
- * A connected WebSocket for testing.
105
- *
106
- * ```ts
107
- * const conn = await app.wsReq('/echo').connect()
108
- * conn.send('hello')
109
- * const msg = await conn.receive()
110
- * assert.equal(msg, 'hello')
111
- * conn.close()
112
- * ```
113
- */
114
- export declare class TestWSConnection {
115
- private ws;
116
- private _timeout;
117
- private messageQueue;
118
- private resolveQueue;
119
- private _closed;
120
- constructor(ws: WSWebSocket, timeout?: number);
121
- /** Send a text message. */
122
- send(data: string): void;
123
- /** Send a JSON message. */
124
- json(data: unknown): void;
125
- /**
126
- * Wait for the next message. Returns the raw text.
127
- * Throws on timeout or if the connection is closed.
128
- */
129
- receive(timeout?: number): Promise<string>;
130
- /** Wait for the next message and parse as JSON. */
131
- receiveJson<T = unknown>(): Promise<T>;
132
- /**
133
- * Assert that no message is received within the given silence period.
134
- * Useful for verifying that something did NOT happen.
135
- */
136
- expectSilent(ms: number): Promise<void>;
137
- /** Close the connection. */
138
- close(): void;
139
- /** Whether the connection is closed. */
140
- get closed(): boolean;
141
- }
142
- /** Create a new test app */
143
- export declare function testApp(): TestApp;
144
- /**
145
- * Result of createTestDb().
146
- */
147
- export interface TestDb {
148
- /** Tagged-template SQL client connected to the test database. */
149
- sql: SqlClient;
150
- /** Connection URL of the test database. */
151
- url: string;
152
- /** Schema name used for this test session. */
153
- schema: string;
154
- /** Destroy the test database (drop schema). */
155
- destroy: () => Promise<void>;
156
- }
157
- /**
158
- * Create an isolated test database schema for integration testing.
159
- *
160
- * Uses PostgreSQL schemas for isolation — no separate database needed.
161
- * Each call creates a unique schema under the same database.
162
- *
163
- * ```ts
164
- * const db = await createTestDb()
165
- * await db.sql`CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT)`
166
- * // ... run tests ...
167
- * await db.destroy() // drops the schema
168
- * ```
169
- *
170
- * Uses `TEST_DATABASE_URL` or `DATABASE_URL` env var.
171
- */
172
- export declare function createTestDb(options?: {
173
- /** Database URL. Default: TEST_DATABASE_URL or DATABASE_URL. */
174
- url?: string;
175
- /** Schema name. Default: auto-generated 'test_<timestamp>_<random>'. */
176
- schema?: string;
177
- }): Promise<TestDb>;
178
- /**
179
- * Run a test callback within an isolated transaction that is rolled back
180
- * after completion. This provides the fastest isolation — no cleanup needed.
181
- *
182
- * ```ts
183
- * await withTestDb(async (sql) => {
184
- * await sql`INSERT INTO users ...`
185
- * // All changes are rolled back after this callback returns
186
- * })
187
- * ```
188
- *
189
- * @param optionsOrFn Either a URL string or options object, or the callback directly.
190
- * @param fn Async callback receiving a tagged-template sql client.
191
- */
192
- export declare function withTestDb(optionsOrFn: string | {
193
- url?: string;
194
- } | ((sql: SqlClient) => Promise<void>), fn?: (sql: SqlClient) => Promise<void>): Promise<void>;
package/dist/theme.d.ts DELETED
@@ -1,31 +0,0 @@
1
- import type { Context, Middleware } from './types.ts';
2
- import { Router } from './router.ts';
3
- declare module './types.ts' {
4
- interface Context {
5
- theme: ThemeInjected;
6
- }
7
- }
8
- export interface ThemeInjected {
9
- value: string;
10
- set: (value: string, loc?: string) => Response;
11
- }
12
- export interface ThemeOptions {
13
- /** Default theme value (default: 'system'). */
14
- default?: string;
15
- /** Cookie name (default: 'theme'). Set to empty string to disable cookie. */
16
- cookie?: string;
17
- }
18
- /**
19
- * Theme module. Returns a Router with an attached `.middleware()` method.
20
- *
21
- * ```ts
22
- * const t = theme()
23
- * app.use(t.middleware()) // → ctx.theme = { value, set }
24
- * app.use('/', t) // → GET /__theme/dark (switch route)
25
- * ```
26
- */
27
- export interface ThemeModule extends Router {
28
- /** Middleware that injects `ctx.theme = { value, set }`. */
29
- middleware: () => Middleware<Context, Context & ThemeInjected>;
30
- }
31
- export declare function theme(options?: ThemeOptions): ThemeModule;
package/dist/trace.d.ts DELETED
@@ -1,95 +0,0 @@
1
- import type { Context, Middleware } from './types.ts';
2
- declare module './types.ts' {
3
- interface Context {
4
- trace: TraceInjected;
5
- }
6
- }
7
- export interface TraceInjected {
8
- /** Unique request identifier (from X-Request-ID header or auto-generated). */
9
- requestId: string;
10
- /** Unique trace identifier for the request. */
11
- traceId: string;
12
- /** Milliseconds elapsed since the trace started. */
13
- elapsed: () => number;
14
- /** Timestamp (ms) when the trace started. */
15
- startTime: number;
16
- }
17
- export interface TraceContext {
18
- /** Unique identifier for the current request trace. */
19
- traceId: string;
20
- /** Timestamp (ms since epoch) when the trace started. */
21
- startTime: number;
22
- }
23
- /**
24
- * Get the current request's trace ID.
25
- * Returns `undefined` when called outside a request context (e.g. at startup).
26
- *
27
- * ```ts
28
- * const traceId = currentTraceId()
29
- * log.info({ traceId }, 'request started')
30
- * ```
31
- */
32
- export declare function currentTraceId(): string | undefined;
33
- /**
34
- * Get the full current trace context ({ traceId, startTime }).
35
- * Returns `undefined` outside a request.
36
- */
37
- export declare function currentTrace(): TraceContext | undefined;
38
- /**
39
- * Run a function inside a trace context.
40
- * Used internally by `serve()` for every incoming request.
41
- * If `incomingTraceId` is provided (e.g. from an `X-Trace-Id` header) it is reused;
42
- * otherwise a new UUID is generated.
43
- *
44
- * ```ts
45
- * const result = runWithTrace(req.headers.get('x-trace-id'), () => {
46
- * return handleRequest(req)
47
- * })
48
- * ```
49
- *
50
- * @param incomingTraceId - Optional trace ID from upstream. Pass `null` to auto-generate.
51
- * @param fn - Function to execute within the trace scope.
52
- * @returns The return value of `fn`.
53
- */
54
- export declare function runWithTrace<T>(incomingTraceId: string | null, fn: () => T): T;
55
- /**
56
- * Milliseconds elapsed since the current trace started.
57
- * Returns `0` if called outside a request context.
58
- *
59
- * ```ts
60
- * app.use(async (req, ctx, next) => {
61
- * const res = await next(req, ctx)
62
- * console.log('handled in', traceElapsed(), 'ms')
63
- * return res
64
- * })
65
- * ```
66
- */
67
- export declare function traceElapsed(): number;
68
- /** Options for {@link trace}. */
69
- export interface TraceOptions {
70
- /** Header name for request ID (default: `'X-Request-ID'`). */
71
- header?: string;
72
- /** Custom ID generator (default: `crypto.randomUUID`). */
73
- generator?: () => string;
74
- }
75
- /**
76
- * Request tracing middleware.
77
- *
78
- * Injects `ctx.trace = { requestId, traceId, elapsed, startTime }`.
79
- * Reads/writes `X-Request-ID` header. Combines the functionality of `requestId()`
80
- * with the per-request tracing from `AsyncLocalStorage`.
81
- *
82
- * ```ts
83
- * import { trace } from 'weifuwu'
84
- * app.use(trace())
85
- *
86
- * app.get('/', (req, ctx) => {
87
- * console.log(ctx.trace.requestId) // 550e8400-e29b-...
88
- * console.log(ctx.trace.traceId) // same as currentTraceId()
89
- * console.log(ctx.trace.elapsed()) // ms since request start
90
- * })
91
- * ```
92
- */
93
- export declare function trace(options?: TraceOptions): Middleware<Context, Context & {
94
- trace: TraceInjected;
95
- }>;
@@ -1,32 +0,0 @@
1
- export interface PageContext {
2
- params: Record<string, string>;
3
- query: Record<string, string>;
4
- user: {
5
- id?: string;
6
- };
7
- parsed: Record<string, unknown>;
8
- theme?: {
9
- value: string;
10
- set?: (value: string, loc?: string) => Response;
11
- };
12
- i18n?: {
13
- locale: string;
14
- messages?: Record<string, unknown>;
15
- t: (key: string, params?: Record<string, string>, fallback?: string) => string;
16
- };
17
- flash?: {
18
- value?: string;
19
- set?: (data: any, loc?: string) => Response;
20
- };
21
- loaderData: Record<string, unknown>;
22
- env: Record<string, string>;
23
- }
24
- type Rebuilder = (value: Partial<PageContext>) => Partial<PageContext> | null;
25
- export declare function addCtxRebuilder(fn: Rebuilder): void;
26
- /** @internal Injected by tsx-instance.ts for async-safe context isolation */
27
- export declare function __registerAls(getStore: () => PageContext | undefined): void;
28
- declare function setCtx(value: Partial<PageContext>): void;
29
- declare function useCtx(): PageContext;
30
- export declare function useLoaderData<T = Record<string, unknown>>(): T;
31
- export declare const TsxContext: import("react").Context<PageContext>;
32
- export { useCtx, setCtx };
package/dist/types.d.ts DELETED
@@ -1,47 +0,0 @@
1
- export interface Context {
2
- params: Record<string, string>;
3
- query: Record<string, string>;
4
- mountPath?: string;
5
- layoutStack?: {
6
- path: string;
7
- component: unknown;
8
- }[];
9
- [key: string]: unknown;
10
- }
11
- export type Handler<T extends Context = Context> = (req: Request, ctx: T) => Response | Promise<Response>;
12
- /**
13
- * Metadata for middleware dependency checking.
14
- * Middleware factories attach this for runtime validation.
15
- */
16
- export interface MiddlewareMeta {
17
- /** Fields this middleware injects into ctx. */
18
- injects: string[];
19
- /** Fields this middleware depends on (must be injected earlier). */
20
- depends: string[];
21
- }
22
- export type Middleware<In extends Context = Context, Out extends In = In> = {
23
- (req: Request, ctx: In, next: Handler<Out>): Response | Promise<Response>;
24
- __meta?: MiddlewareMeta;
25
- };
26
- export type ErrorHandler<T extends Context = Context> = (error: Error, req: Request, ctx: T) => Response | Promise<Response>;
27
- /**
28
- * Interface for resources that require explicit cleanup (connections, pools, timers).
29
- * All stateful modules implement this.
30
- */
31
- export interface Closeable {
32
- /** Release all resources. Call once when shutting down. */
33
- close(): Promise<void>;
34
- }
35
- /**
36
- * HTTP error with an explicit status code.
37
- * Throw from a handler or middleware to return a non-200 response.
38
- *
39
- * ```ts
40
- * if (!resource) throw new HttpError('Not found', 404)
41
- * serve() catches it and returns the status code.
42
- * ```
43
- */
44
- export declare class HttpError extends Error {
45
- status: number;
46
- constructor(message: string, status: number);
47
- }
package/dist/upload.d.ts DELETED
@@ -1,55 +0,0 @@
1
- import type { Context, Middleware } from './types.ts';
2
- declare module './types.ts' {
3
- interface Context {
4
- parsed: Record<string, unknown>;
5
- }
6
- }
7
- /** Upload middleware — a {@link Middleware} that injects `ctx.parsed` with file fields. */
8
- export type UploadModule = Middleware<Context, Context & {
9
- parsed: Record<string, unknown>;
10
- }>;
11
- /** A parsed file from a multipart upload. */
12
- export interface UploadedFile {
13
- /** Original filename from the client. */
14
- name: string;
15
- /** MIME type from the `Content-Type` part header. */
16
- type: string;
17
- /** File size in bytes. */
18
- size: number;
19
- /** Path where the file was saved (when `dir` option is set). */
20
- path?: string;
21
- /** File content as Buffer (when `dir` option is not set). */
22
- buffer?: Buffer;
23
- }
24
- /** Options for {@link upload}. */
25
- export interface UploadOptions {
26
- /** Directory to save uploaded files. If not set, files stay in memory via `.buffer`. */
27
- dir?: string;
28
- /** Maximum file size in bytes. Default: 10 MB. Set `0` to allow unlimited. */
29
- maxFileSize?: number;
30
- /** Allowed MIME types (e.g. `['image/jpeg', 'image/png']`). Empty array allows all. */
31
- allowedTypes?: string[];
32
- }
33
- /**
34
- * Multipart file upload middleware.
35
- *
36
- * Parses `multipart/form-data` requests, extracting files and fields.
37
- * Files can be saved to disk (`dir` option) or kept in memory as Buffers.
38
- * Parsed fields are available in `ctx.parsed`.
39
- *
40
- * ```ts
41
- * import { upload } from 'weifuwu'
42
- *
43
- * // Save to disk
44
- * app.use(upload({ dir: './uploads', maxFileSize: 5_000_000 }))
45
- *
46
- * // In-memory
47
- * app.post('/upload', async (req, ctx) => {
48
- * const file = ctx.parsed?.file as UploadedFile
49
- * console.log(file.name, file.type, file.buffer!.length)
50
- * })
51
- * ```
52
- */
53
- export declare function upload(options?: UploadOptions): Middleware<Context, Context & {
54
- parsed: Record<string, unknown>;
55
- }>;
@@ -1,42 +0,0 @@
1
- /** Options for {@link useAction}. */
2
- export interface UseActionOptions<T = any> {
3
- /** HTTP method (default: `'POST'`). */
4
- method?: string;
5
- /** Additional request headers. */
6
- headers?: Record<string, string>;
7
- /** Called with the response data on success. */
8
- onSuccess?: (data: T) => void;
9
- /** Called with the error on failure. */
10
- onError?: (err: Error) => void;
11
- }
12
- /** Return value of {@link useAction}. */
13
- export interface UseActionReturn<T = any> {
14
- /** Submit the action. Pass a body to send as JSON (or FormData). */
15
- submit: (body?: any) => Promise<T | undefined>;
16
- /** Response data from the last successful submission. */
17
- data: T | null;
18
- /** Error from the last failed submission. */
19
- error: Error | null;
20
- /** Whether a submission is in progress. */
21
- pending: boolean;
22
- /** Reset data and error to their initial states. */
23
- reset: () => void;
24
- }
25
- /**
26
- * Hook to submit form actions via `fetch`. Handles JSON serialization,
27
- * CSRF token injection, and loading/error state.
28
- *
29
- * ```tsx
30
- * import { useAction } from 'weifuwu/react'
31
- *
32
- * function SaveButton() {
33
- * const { submit, pending, error } = useAction('/api/save')
34
- * return (
35
- * <button onClick={() => submit({ title: 'Hello' })} disabled={pending}>
36
- * {pending ? 'Saving...' : 'Save'}
37
- * </button>
38
- * )
39
- * }
40
- * ```
41
- */
42
- export declare function useAction<T = any>(url: string | URL, options?: UseActionOptions<T>): UseActionReturn<T>;
@@ -1,49 +0,0 @@
1
- /** Streaming state for all agents in a channel. */
2
- export interface AgentStreamState {
3
- /** Accumulated streaming text per agent, keyed by `agent_id`. */
4
- streams: Record<number, string>;
5
- /** Whether any agent is currently streaming (typing). */
6
- streaming: boolean;
7
- /** Set of agent IDs currently streaming. */
8
- activeAgents: Set<number>;
9
- }
10
- /** Options for {@link useAgentStream}. */
11
- export interface UseAgentStreamOptions {
12
- /** WebSocket path, e.g. `'/ws'`. */
13
- wsPath: string;
14
- /** Channel ID to listen for agent streams. */
15
- channelId: number;
16
- /** Called when an agent finishes generating. */
17
- onStreamEnd?: (agentId: number, fullText: string) => void;
18
- /** Called on stream error. */
19
- onError?: (agentId: number, error: string) => void;
20
- }
21
- /** Return value of {@link useAgentStream}. */
22
- export interface UseAgentStreamReturn {
23
- /** Accumulated streaming state for all agents. */
24
- stream: AgentStreamState;
25
- /** Get accumulated text for a specific agent by ID. */
26
- getAgentText: (agentId: number) => string;
27
- /** Whether a specific agent is currently streaming. */
28
- isAgentStreaming: (agentId: number) => boolean;
29
- }
30
- /**
31
- * React hook to consume agent AI streaming output via WebSocket.
32
- *
33
- * Connects to a WebSocket endpoint, listens for `agent_stream`,
34
- * `agent_stream_end`, and `agent_error` messages, and accumulates
35
- * the token stream per agent.
36
- *
37
- * ```tsx
38
- * import { useAgentStream } from 'weifuwu/react'
39
- *
40
- * function Chat() {
41
- * const { stream, getAgentText } = useAgentStream({
42
- * wsPath: '/ws/chat',
43
- * channelId: 1,
44
- * })
45
- * return <pre>{getAgentText(1)}</pre>
46
- * }
47
- * ```
48
- */
49
- export declare function useAgentStream(opts: UseAgentStreamOptions): UseAgentStreamReturn;
@@ -1,17 +0,0 @@
1
- /**
2
- * React hook to read the server-flashed message on the client side.
3
- *
4
- * Reads `window.__WEIFUWU_CTX.flash.value` (set by the flash middleware
5
- * during SSR). Returns `null` when no flash message is present.
6
- *
7
- * ```tsx
8
- * import { useFlashMessage } from 'weifuwu/react'
9
- *
10
- * function FlashNotice() {
11
- * const flash = useFlashMessage<{ type: string; text: string }>()
12
- * if (!flash) return null
13
- * return <div className={flash.type}>{flash.text}</div>
14
- * }
15
- * ```
16
- */
17
- export declare function useFlashMessage<T = any>(): T | null;
@@ -1,42 +0,0 @@
1
- /** Options for {@link useWebsocket}. */
2
- export type UseWebsocketOptions = {
3
- /** Called when a message is received. */
4
- onMessage?: (data: string) => void;
5
- /** Auto-reconnect config. Set to `false` to disable. Default: `{ maxRetries: 10, delay: 3000 }`. */
6
- reconnect?: boolean | {
7
- maxRetries?: number;
8
- delay?: number;
9
- };
10
- /** WebSocket sub-protocols. */
11
- protocols?: string | string[];
12
- /** Whether the WebSocket is enabled. Set to `false` to keep closed. Default: `true`. */
13
- enabled?: boolean;
14
- };
15
- /** Return value of {@link useWebsocket}. */
16
- export type UseWebsocketReturn = {
17
- /** Send data through the WebSocket. */
18
- send: (data: string | ArrayBuffer | Blob) => void;
19
- /** Close the WebSocket manually. */
20
- close: () => void;
21
- /** Current `WebSocket.readyState`. */
22
- readyState: number;
23
- /** The last received message string. */
24
- lastMessage: string | null;
25
- /** Manually trigger reconnection. */
26
- reconnect: () => void;
27
- };
28
- /**
29
- * React hook for WebSocket connections with auto-reconnect.
30
- *
31
- * ```tsx
32
- * import { useWebsocket } from 'weifuwu/react'
33
- *
34
- * function Chat() {
35
- * const { send, lastMessage, readyState } = useWebsocket('/ws/chat', {
36
- * onMessage: (data) => console.log('received:', data),
37
- * })
38
- * return <button onClick={() => send('Hello')}>Send</button>
39
- * }
40
- * ```
41
- */
42
- export declare function useWebsocket(url: string | URL | (() => string | URL | null), options?: UseWebsocketOptions): UseWebsocketReturn;