weifuwu 0.27.28 → 0.28.2
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/index.d.ts +8 -0
- package/index.js +26 -0
- package/package.json +9 -52
- package/README.md +0 -711
- package/dist/ai/provider.d.ts +0 -45
- package/dist/ai/stream.d.ts +0 -13
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +0 -126
- package/dist/core/cookie.d.ts +0 -36
- package/dist/core/env.d.ts +0 -69
- package/dist/core/logger.d.ts +0 -16
- package/dist/core/router.d.ts +0 -88
- package/dist/core/serve.d.ts +0 -38
- package/dist/core/sse.d.ts +0 -47
- package/dist/core/trace.d.ts +0 -95
- package/dist/graphql.d.ts +0 -16
- package/dist/hub.d.ts +0 -36
- package/dist/index.d.ts +0 -51
- package/dist/index.js +0 -3249
- package/dist/middleware/compress.d.ts +0 -20
- package/dist/middleware/cors.d.ts +0 -25
- package/dist/middleware/health.d.ts +0 -24
- package/dist/middleware/helmet.d.ts +0 -33
- package/dist/middleware/rate-limit.d.ts +0 -44
- package/dist/middleware/request-id.d.ts +0 -40
- package/dist/middleware/static.d.ts +0 -23
- package/dist/middleware/upload.d.ts +0 -55
- package/dist/middleware/validate.d.ts +0 -32
- package/dist/postgres/client.d.ts +0 -4
- package/dist/postgres/index.d.ts +0 -3
- package/dist/postgres/module.d.ts +0 -12
- package/dist/postgres/types.d.ts +0 -42
- package/dist/queue/cron.d.ts +0 -9
- package/dist/queue/index.d.ts +0 -2
- package/dist/queue/types.d.ts +0 -61
- package/dist/redis/client.d.ts +0 -2
- package/dist/redis/index.d.ts +0 -2
- package/dist/redis/types.d.ts +0 -17
- package/dist/test/test-utils.d.ts +0 -193
- package/dist/types.d.ts +0 -76
package/dist/ai/provider.d.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import type { Context, Middleware } from '../types.ts';
|
|
2
|
-
import { generateText as aiGenerateText, streamText as aiStreamText, type LanguageModel, type EmbeddingModel } from 'ai';
|
|
3
|
-
declare module '../types.ts' {
|
|
4
|
-
interface Context {
|
|
5
|
-
ai: AIProvider;
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
export interface AIProviderInjected {
|
|
9
|
-
ai: AIProvider;
|
|
10
|
-
}
|
|
11
|
-
export interface AIProviderOptions {
|
|
12
|
-
/** API base URL (default: OPENAI_BASE_URL env or http://localhost:11434/v1). */
|
|
13
|
-
baseURL?: string;
|
|
14
|
-
/** API key (default: OPENAI_API_KEY env or 'ollama'). */
|
|
15
|
-
apiKey?: string;
|
|
16
|
-
/** Chat model name (default: OPENAI_MODEL env or 'qwen3:0.6b'). */
|
|
17
|
-
model?: string;
|
|
18
|
-
/** Embedding model name (default: OPENAI_EMBEDDING_MODEL env or 'qwen3-embedding:0.6b'). */
|
|
19
|
-
embeddingModel?: string;
|
|
20
|
-
/** Vector dimension (default: EMBEDDING_DIMENSION env or 1024). */
|
|
21
|
-
embeddingDimension?: number;
|
|
22
|
-
}
|
|
23
|
-
export interface AIProvider {
|
|
24
|
-
/** Get the language model. Caches by default; pass a name to override. */
|
|
25
|
-
model(name?: string): LanguageModel;
|
|
26
|
-
/** Get the embedding model. Caches by default; pass a name to override. */
|
|
27
|
-
embeddingModel(name?: string): EmbeddingModel;
|
|
28
|
-
/** Embed a single text string into a vector. */
|
|
29
|
-
embed(text: string): Promise<number[]>;
|
|
30
|
-
/** Embed multiple text strings in batch. */
|
|
31
|
-
embedMany(texts: string[]): Promise<number[][]>;
|
|
32
|
-
/** The configured vector dimension. */
|
|
33
|
-
readonly dimension: number;
|
|
34
|
-
/**
|
|
35
|
-
* Generate text using the configured model.
|
|
36
|
-
* All options are passed through to the AI SDK's `generateText`, with `model` auto-injected.
|
|
37
|
-
*/
|
|
38
|
-
generateText(params: Omit<Parameters<typeof aiGenerateText>[0], 'model'>): ReturnType<typeof aiGenerateText>;
|
|
39
|
-
/**
|
|
40
|
-
* Stream text using the configured model.
|
|
41
|
-
* All options are passed through to the AI SDK's `streamText`, with `model` auto-injected.
|
|
42
|
-
*/
|
|
43
|
-
streamText(params: Omit<Parameters<typeof aiStreamText>[0], 'model'>): ReturnType<typeof aiStreamText>;
|
|
44
|
-
}
|
|
45
|
-
export declare function aiProvider(options?: AIProviderOptions): Middleware<Context, Context & AIProviderInjected> & AIProvider;
|
package/dist/ai/stream.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { Context } from '../types.ts';
|
|
2
|
-
import { Router } from '../core/router.ts';
|
|
3
|
-
import type { AIProvider } from './provider.ts';
|
|
4
|
-
export type AIHandler = (req: Request, ctx: Context) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
5
|
-
export declare const _ai: Record<string, any>;
|
|
6
|
-
/**
|
|
7
|
-
* Create a streaming AI endpoint.
|
|
8
|
-
*
|
|
9
|
-
* @param handler - Returns options for `streamText` or `streamObject` (if `schema` is present).
|
|
10
|
-
* @param provider - Optional AI provider. If provided and the handler does not return a `model`,
|
|
11
|
-
* `provider.model()` is used as the default.
|
|
12
|
-
*/
|
|
13
|
-
export declare function aiStream(handler: AIHandler, provider?: AIProvider): Promise<Router>;
|
package/dist/cli.d.ts
DELETED
package/dist/cli.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
// cli.ts
|
|
4
|
-
import { mkdir, writeFile } from "node:fs/promises";
|
|
5
|
-
import { existsSync } from "node:fs";
|
|
6
|
-
import { execSync } from "node:child_process";
|
|
7
|
-
import { join, dirname, resolve } from "node:path";
|
|
8
|
-
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { parseArgs } from "node:util";
|
|
10
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
11
|
-
var __dirname = dirname(__filename);
|
|
12
|
-
var pkgRoot = existsSync(join(__dirname, "package.json")) ? __dirname : resolve(__dirname, "..");
|
|
13
|
-
async function readPkg() {
|
|
14
|
-
return JSON.parse(
|
|
15
|
-
await import("node:fs/promises").then(
|
|
16
|
-
(fs) => fs.readFile(join(pkgRoot, "package.json"), "utf-8")
|
|
17
|
-
)
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
async function cmdVersion() {
|
|
21
|
-
const pkg = await readPkg();
|
|
22
|
-
console.log(pkg.version);
|
|
23
|
-
}
|
|
24
|
-
async function cmdInit(name, opts) {
|
|
25
|
-
const targetDir = resolve(process.cwd(), name);
|
|
26
|
-
if (existsSync(targetDir)) {
|
|
27
|
-
console.error(`Directory ${name} already exists.`);
|
|
28
|
-
process.exit(1);
|
|
29
|
-
}
|
|
30
|
-
const pkg = await readPkg();
|
|
31
|
-
const typesNodeVersion = pkg.devDependencies?.["@types/node"] || "^22";
|
|
32
|
-
await generateMinimal(targetDir, name, pkg.version, typesNodeVersion, opts.skipInstall);
|
|
33
|
-
}
|
|
34
|
-
async function generateMinimal(targetDir, name, version, typesNodeVersion, skipInstall) {
|
|
35
|
-
await mkdir(targetDir, { recursive: true });
|
|
36
|
-
await writeFile(
|
|
37
|
-
join(targetDir, "app.ts"),
|
|
38
|
-
[
|
|
39
|
-
`import { Router } from 'weifuwu'`,
|
|
40
|
-
``,
|
|
41
|
-
`export const app = new Router()`,
|
|
42
|
-
``,
|
|
43
|
-
`app.get('/', () => new Response('Hello from ${name}!'))`,
|
|
44
|
-
`app.get('/api/ping', () => Response.json({ pong: true, time: new Date().toISOString() }))`,
|
|
45
|
-
``
|
|
46
|
-
].join("\n")
|
|
47
|
-
);
|
|
48
|
-
await writeFile(
|
|
49
|
-
join(targetDir, "index.ts"),
|
|
50
|
-
[
|
|
51
|
-
`import { loadEnv, serve } from 'weifuwu'`,
|
|
52
|
-
`import { app } from './app.ts'`,
|
|
53
|
-
``,
|
|
54
|
-
`loadEnv()`,
|
|
55
|
-
`const port = Number(process.env.PORT) || 3000`,
|
|
56
|
-
`serve(app.handler(), { port })`,
|
|
57
|
-
``
|
|
58
|
-
].join("\n")
|
|
59
|
-
);
|
|
60
|
-
await writePackageJson(targetDir, name, version, typesNodeVersion, {});
|
|
61
|
-
await writeCommonFiles(targetDir);
|
|
62
|
-
await finishInit(targetDir, skipInstall);
|
|
63
|
-
}
|
|
64
|
-
async function writePackageJson(targetDir, name, version, typesNodeVersion, _extra) {
|
|
65
|
-
const pkg = {
|
|
66
|
-
name,
|
|
67
|
-
type: "module",
|
|
68
|
-
scripts: {
|
|
69
|
-
dev: "node --watch index.ts",
|
|
70
|
-
start: "node index.ts"
|
|
71
|
-
},
|
|
72
|
-
dependencies: {
|
|
73
|
-
weifuwu: "^" + version
|
|
74
|
-
},
|
|
75
|
-
devDependencies: {
|
|
76
|
-
"@types/node": typesNodeVersion
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
await writeFile(join(targetDir, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
|
|
80
|
-
}
|
|
81
|
-
async function writeCommonFiles(targetDir) {
|
|
82
|
-
await writeFile(join(targetDir, ".gitignore"), "node_modules\n.env\n.weifuwu\n");
|
|
83
|
-
await writeFile(join(targetDir, ".env"), "PORT=3000\n");
|
|
84
|
-
}
|
|
85
|
-
async function finishInit(targetDir, skipInstall) {
|
|
86
|
-
if (!skipInstall) {
|
|
87
|
-
console.log("\nInstalling dependencies...");
|
|
88
|
-
execSync("npm install", { cwd: targetDir, stdio: "inherit" });
|
|
89
|
-
}
|
|
90
|
-
console.log(`
|
|
91
|
-
\u2705 Created ${targetDir.split("/").pop()}/`);
|
|
92
|
-
console.log(` cd ${targetDir.split("/").pop()}`);
|
|
93
|
-
if (skipInstall) console.log(` npm install`);
|
|
94
|
-
console.log(` npm run dev`);
|
|
95
|
-
}
|
|
96
|
-
var cmd = process.argv[2];
|
|
97
|
-
var HELP = `
|
|
98
|
-
weifuwu \u2014 Web-standard HTTP microframework for Node.js
|
|
99
|
-
|
|
100
|
-
Usage:
|
|
101
|
-
npx weifuwu init <name> Create a new project
|
|
102
|
-
npx weifuwu init <name> --skip-install Skip npm install
|
|
103
|
-
npx weifuwu version Print version
|
|
104
|
-
`;
|
|
105
|
-
if (cmd === "version" || cmd === "-v" || cmd === "--version") {
|
|
106
|
-
cmdVersion().catch(console.error);
|
|
107
|
-
} else if (cmd === "init") {
|
|
108
|
-
const { values, positionals } = parseArgs({
|
|
109
|
-
args: process.argv.slice(3),
|
|
110
|
-
options: {
|
|
111
|
-
"skip-install": { type: "boolean" }
|
|
112
|
-
},
|
|
113
|
-
strict: false,
|
|
114
|
-
allowPositionals: true
|
|
115
|
-
});
|
|
116
|
-
const name = positionals[0];
|
|
117
|
-
if (!name) {
|
|
118
|
-
console.error("Usage: npx weifuwu init <name> [--skip-install]");
|
|
119
|
-
process.exit(1);
|
|
120
|
-
}
|
|
121
|
-
cmdInit(name, { skipInstall: !!values["skip-install"] }).catch(
|
|
122
|
-
console.error
|
|
123
|
-
);
|
|
124
|
-
} else {
|
|
125
|
-
console.log(HELP);
|
|
126
|
-
}
|
package/dist/core/cookie.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/** Options for setting a cookie. All fields map to standard Set-Cookie attributes. */
|
|
2
|
-
export interface CookieOptions {
|
|
3
|
-
domain?: string;
|
|
4
|
-
path?: string;
|
|
5
|
-
maxAge?: number;
|
|
6
|
-
expires?: Date;
|
|
7
|
-
httpOnly?: boolean;
|
|
8
|
-
secure?: boolean;
|
|
9
|
-
sameSite?: 'strict' | 'lax' | 'none';
|
|
10
|
-
}
|
|
11
|
-
/** Parse cookies from a Request's `Cookie` header.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* const cookies = getCookies(req)
|
|
16
|
-
* console.log(cookies.session_id) // value or undefined
|
|
17
|
-
* ``` */
|
|
18
|
-
export declare function getCookies(req: Request): Record<string, string>;
|
|
19
|
-
/** Set a cookie on a Response.
|
|
20
|
-
*
|
|
21
|
-
* Appends a `Set-Cookie` header to the existing response headers.
|
|
22
|
-
* Returns a new Response with the added header.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```ts
|
|
26
|
-
* const res = new Response('ok')
|
|
27
|
-
* return setCookie(res, 'session', token, { httpOnly: true, path: '/' })
|
|
28
|
-
* ``` */
|
|
29
|
-
export declare function setCookie(res: Response, name: string, value: string, options?: CookieOptions): Response;
|
|
30
|
-
/** Delete a cookie by setting `Max-Age=0`.
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* ```ts
|
|
34
|
-
* return deleteCookie(res, 'session')
|
|
35
|
-
* ``` */
|
|
36
|
-
export declare function deleteCookie(res: Response, name: string, options?: Omit<CookieOptions, 'maxAge'>): Response;
|
package/dist/core/env.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import type { Context, Middleware } from '../types.ts';
|
|
2
|
-
/**
|
|
3
|
-
* Get all public environment variables (those prefixed with `WEIFUWU_PUBLIC_`),
|
|
4
|
-
* with the prefix stripped.
|
|
5
|
-
*
|
|
6
|
-
* ```ts
|
|
7
|
-
* const pub = getPublicEnv()
|
|
8
|
-
* // WEIFUWU_PUBLIC_API_URL=http://api.example.com → { API_URL: 'http://api.example.com' }
|
|
9
|
-
* ```
|
|
10
|
-
*/
|
|
11
|
-
export declare function getPublicEnv(): Record<string, string>;
|
|
12
|
-
declare module '../types.ts' {
|
|
13
|
-
interface Context {
|
|
14
|
-
env?: Record<string, string>;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Whether this code is running from the compiled `dist/index.js` bundle.
|
|
19
|
-
* `false` when running TypeScript source directly (dev workflow in weifuwu repo).
|
|
20
|
-
*
|
|
21
|
-
* Used by modules that need to resolve package-internal files differently
|
|
22
|
-
* depending on whether they are compiled (published npm package) or raw TS.
|
|
23
|
-
*/
|
|
24
|
-
export declare function isBundled(): boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Whether `NODE_ENV` is explicitly set to `'development'`.
|
|
27
|
-
*
|
|
28
|
-
* Used for dev-only features: HMR, livereload, React `createRoot` (not hydrate).
|
|
29
|
-
* **Not** the opposite of {@link isProd} — when `NODE_ENV` is unset, both return `false`.
|
|
30
|
-
*/
|
|
31
|
-
export declare function isDev(): boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Whether `NODE_ENV` is explicitly set to `'production'`.
|
|
34
|
-
*
|
|
35
|
-
* Used for production-only behavior: plain-text 404, suppressed warnings, minified output.
|
|
36
|
-
*/
|
|
37
|
-
export declare function isProd(): boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Load environment variables from a `.env` file into `process.env`.
|
|
40
|
-
*
|
|
41
|
-
* Does **not** override existing `process.env` values.
|
|
42
|
-
* Supports quoted values and inline comments.
|
|
43
|
-
*
|
|
44
|
-
* @param path - Path to `.env` file (default: `'.env'` relative to cwd).
|
|
45
|
-
*
|
|
46
|
-
* ```ts
|
|
47
|
-
* import { loadEnv } from 'weifuwu'
|
|
48
|
-
* loadEnv()
|
|
49
|
-
* console.log(process.env.PORT)
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
|
-
export declare function loadEnv(path?: string): void;
|
|
53
|
-
/**
|
|
54
|
-
* Public env middleware.
|
|
55
|
-
*
|
|
56
|
-
* Injects `ctx.env` with all environment variables prefixed with `WEIFUWU_PUBLIC_`,
|
|
57
|
-
* with the prefix stripped. Safe to expose to the client.
|
|
58
|
-
*
|
|
59
|
-
* ```ts
|
|
60
|
-
* import { env } from 'weifuwu'
|
|
61
|
-
* app.use(env())
|
|
62
|
-
*
|
|
63
|
-
* // .env: WEIFUWU_PUBLIC_API_URL=https://api.example.com
|
|
64
|
-
* // ctx: ctx.env.API_URL === 'https://api.example.com'
|
|
65
|
-
* ```
|
|
66
|
-
*/
|
|
67
|
-
export declare function env(): Middleware<Context, Context & {
|
|
68
|
-
env: Record<string, string>;
|
|
69
|
-
}>;
|
package/dist/core/logger.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { Middleware, Context } from '../types.ts';
|
|
2
|
-
export interface LoggerOptions {
|
|
3
|
-
/** 'short' = method + path + status + ms, 'combined' = short + query string, 'json' = structured stderr JSON */
|
|
4
|
-
format?: 'short' | 'combined' | 'json';
|
|
5
|
-
}
|
|
6
|
-
export interface LogEvent {
|
|
7
|
-
level: 'info' | 'warn' | 'error';
|
|
8
|
-
message: string;
|
|
9
|
-
method?: string;
|
|
10
|
-
path?: string;
|
|
11
|
-
status?: number;
|
|
12
|
-
elapsed_ms?: number;
|
|
13
|
-
traceId?: string;
|
|
14
|
-
timestamp?: string;
|
|
15
|
-
}
|
|
16
|
-
export declare function logger(options?: LoggerOptions): Middleware<Context, Context>;
|
package/dist/core/router.d.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import type { WebSocket, Context, Handler, Middleware, ErrorHandler } from '../types.ts';
|
|
2
|
-
import { type IncomingMessage } from 'node:http';
|
|
3
|
-
import type { Duplex } from 'node:stream';
|
|
4
|
-
import { type Hub } from '../hub.ts';
|
|
5
|
-
declare module '../types.ts' {
|
|
6
|
-
interface Context {
|
|
7
|
-
ws: {
|
|
8
|
-
/** Per-connection state object */
|
|
9
|
-
state: Record<string, unknown>;
|
|
10
|
-
/** Send JSON to this connection */
|
|
11
|
-
json(data: unknown): void;
|
|
12
|
-
/** Join a room */
|
|
13
|
-
join(room: string): void;
|
|
14
|
-
/** Leave a room */
|
|
15
|
-
leave(room: string): void;
|
|
16
|
-
/** Broadcast to a room */
|
|
17
|
-
sendRoom(room: string, data: unknown): void;
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
export type WebSocketHandler = {
|
|
22
|
-
open?: (ws: WebSocket, ctx: Context) => void | Promise<void>;
|
|
23
|
-
message?: (ws: WebSocket, ctx: Context, data: string | Buffer) => void | Promise<void>;
|
|
24
|
-
close?: (ws: WebSocket, ctx: Context) => void | Promise<void>;
|
|
25
|
-
error?: (ws: WebSocket, ctx: Context, error: Error) => void | Promise<void>;
|
|
26
|
-
};
|
|
27
|
-
type WsUpgradeHandler = (req: IncomingMessage, socket: Duplex, head: Buffer) => void;
|
|
28
|
-
export declare class Router<T extends Context = Context> {
|
|
29
|
-
private root;
|
|
30
|
-
private wsRoot;
|
|
31
|
-
private globalMws;
|
|
32
|
-
private errorHandler?;
|
|
33
|
-
private _hasWildcard;
|
|
34
|
-
private _hub?;
|
|
35
|
-
private _wss?;
|
|
36
|
-
/** Track which ctx fields have been injected so far (for dependency checking). */
|
|
37
|
-
private _ctxFields;
|
|
38
|
-
private get wss();
|
|
39
|
-
private get hub();
|
|
40
|
-
/** Inject a custom hub (e.g. with Redis for cross-process broadcast). */
|
|
41
|
-
wsHub(hub: Hub): this;
|
|
42
|
-
use<Out extends Context>(mw: Middleware<Context, Out>): Router<T & Out>;
|
|
43
|
-
use(path: string, mw: Middleware<T, T>): Router<T>;
|
|
44
|
-
use(path: string, router: Router<Context>): Router<T>;
|
|
45
|
-
use(mod: Router & {
|
|
46
|
-
middleware: () => Middleware;
|
|
47
|
-
}): Router<T>;
|
|
48
|
-
/**
|
|
49
|
-
* Check a middleware's dependency metadata and emit warnings if
|
|
50
|
-
* required fields haven't been injected yet.
|
|
51
|
-
* Attach __meta to a middleware function:
|
|
52
|
-
*
|
|
53
|
-
* ```ts
|
|
54
|
-
* mw.__meta = { injects: ['sql'], depends: ['session'] }
|
|
55
|
-
* ```
|
|
56
|
-
*/
|
|
57
|
-
private _checkMiddlewareMeta;
|
|
58
|
-
get(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
59
|
-
post(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
60
|
-
put(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
61
|
-
delete(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
62
|
-
patch(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
63
|
-
head(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
64
|
-
options(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
65
|
-
all(path: string, ...args: [...Middleware<T, T>[], Handler<T> | Router<Context>]): Router<T>;
|
|
66
|
-
onError(handler: ErrorHandler<T>): Router<T>;
|
|
67
|
-
private _route;
|
|
68
|
-
/** Internal route registration — no type constraints (used by _mountRouter). */
|
|
69
|
-
private _routeImpl;
|
|
70
|
-
ws(path: string, ...args: [...Middleware<T, T>[], WebSocketHandler]): Router<T>;
|
|
71
|
-
handler(): Handler<T>;
|
|
72
|
-
/** Returns a human-readable list of all registered routes. Useful for debugging. */
|
|
73
|
-
routes(): string[];
|
|
74
|
-
private _collectRoutes;
|
|
75
|
-
private _collectWsRoutes;
|
|
76
|
-
websocketHandler(): WsUpgradeHandler;
|
|
77
|
-
private _mountRouter;
|
|
78
|
-
private mergeMws;
|
|
79
|
-
private _collect;
|
|
80
|
-
private _collectWs;
|
|
81
|
-
private splitPath;
|
|
82
|
-
private matchTrie;
|
|
83
|
-
private matchWsTrie;
|
|
84
|
-
private handleError;
|
|
85
|
-
private handle;
|
|
86
|
-
private runChain;
|
|
87
|
-
}
|
|
88
|
-
export {};
|
package/dist/core/serve.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { type IncomingMessage, type ServerResponse } from 'node:http';
|
|
2
|
-
import type { Duplex } from 'node:stream';
|
|
3
|
-
import { type Handler } from '../types.ts';
|
|
4
|
-
export interface ServeOptions {
|
|
5
|
-
port?: number;
|
|
6
|
-
hostname?: string;
|
|
7
|
-
signal?: AbortSignal;
|
|
8
|
-
websocket?: (req: IncomingMessage, socket: Duplex, head: Buffer) => void;
|
|
9
|
-
/** Max request body size in bytes. Default: 10MB. Set to 0 for unlimited. */
|
|
10
|
-
maxBodySize?: number;
|
|
11
|
-
/** Socket timeout in ms (inactivity). Default: 30_000. */
|
|
12
|
-
timeout?: number;
|
|
13
|
-
/** Keep-Alive idle timeout in ms. Default: 5_000. */
|
|
14
|
-
keepAliveTimeout?: number;
|
|
15
|
-
/** Headers timeout in ms (must be > keepAliveTimeout). Default: 6_000. */
|
|
16
|
-
headersTimeout?: number;
|
|
17
|
-
shutdown?: boolean;
|
|
18
|
-
}
|
|
19
|
-
export interface Server {
|
|
20
|
-
stop: (timeoutMs?: number) => Promise<void>;
|
|
21
|
-
/** Alias for `stop()`. Prefer this for consistency with other modules. */
|
|
22
|
-
close: (timeoutMs?: number) => Promise<void>;
|
|
23
|
-
readonly port: number;
|
|
24
|
-
readonly hostname: string;
|
|
25
|
-
ready: Promise<void>;
|
|
26
|
-
}
|
|
27
|
-
/** Default max body size: 10MB. Set maxBodySize: 0 for unlimited. */
|
|
28
|
-
export declare const DEFAULT_MAX_BODY: number;
|
|
29
|
-
export declare function readBody(req: IncomingMessage, maxSize?: number): Promise<Buffer>;
|
|
30
|
-
export declare function createRequest(req: IncomingMessage, body: Buffer): [Request, Record<string, string>];
|
|
31
|
-
export declare function sendResponse(res: ServerResponse, response: Response, opts?: {
|
|
32
|
-
traceId?: string | null;
|
|
33
|
-
}): Promise<void>;
|
|
34
|
-
export declare function createTestServer(handler: Handler, options?: ServeOptions): Promise<{
|
|
35
|
-
server: Server;
|
|
36
|
-
url: string;
|
|
37
|
-
}>;
|
|
38
|
-
export declare function serve(handler: Handler, options?: ServeOptions): Server;
|
package/dist/core/sse.d.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Format an SSE message string with a named event type.
|
|
3
|
-
*
|
|
4
|
-
* ```ts
|
|
5
|
-
* formatSSE('ping', { ts: Date.now() })
|
|
6
|
-
* // "event: ping\ndata: {"ts":...}\n\n"
|
|
7
|
-
* ```
|
|
8
|
-
*/
|
|
9
|
-
export declare function formatSSE(event: string, data: unknown): string;
|
|
10
|
-
/**
|
|
11
|
-
* Format an SSE message string with only a data line (no event type).
|
|
12
|
-
*
|
|
13
|
-
* ```ts
|
|
14
|
-
* formatSSEData({ message: 'hello' })
|
|
15
|
-
* // "data: {"message":"hello"}\n\n"
|
|
16
|
-
* ```
|
|
17
|
-
*/
|
|
18
|
-
export declare function formatSSEData(data: unknown): string;
|
|
19
|
-
/** An SSE event to be sent via {@link createSSEStream}. */
|
|
20
|
-
export interface SSEEvent {
|
|
21
|
-
/** Event type (maps to `event:` field). */
|
|
22
|
-
event: string;
|
|
23
|
-
/** Event payload (serialized as JSON in `data:` field). */
|
|
24
|
-
data: unknown;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Create a Server-Sent Events (SSE) `Response` from an async iterable.
|
|
28
|
-
*
|
|
29
|
-
* Each item in the iterable is serialized as an SSE message:
|
|
30
|
-
* - If the item has a `.type` property → `event: {type}` + `data: {item}`
|
|
31
|
-
* - Otherwise → `data: {item}`
|
|
32
|
-
*
|
|
33
|
-
* Errors are sent as `event: error` messages. `AbortError` is silently ignored.
|
|
34
|
-
*
|
|
35
|
-
* ```ts
|
|
36
|
-
* app.get('/events', () => {
|
|
37
|
-
* async function* generate() {
|
|
38
|
-
* yield { type: 'ping', data: { ts: Date.now() } }
|
|
39
|
-
* }
|
|
40
|
-
* return createSSEStream(generate())
|
|
41
|
-
* })
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
export declare function createSSEStream(iterable: AsyncIterable<any>, opts?: {
|
|
45
|
-
headers?: Record<string, string>;
|
|
46
|
-
status?: number;
|
|
47
|
-
}): Response;
|
package/dist/core/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
|
-
}>;
|
package/dist/graphql.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { type GraphQLSchema } from 'graphql';
|
|
2
|
-
import type { Context } from './types.ts';
|
|
3
|
-
import { Router } from './core/router.ts';
|
|
4
|
-
export interface GraphQLOptions {
|
|
5
|
-
schema: string | GraphQLSchema;
|
|
6
|
-
rootValue?: any;
|
|
7
|
-
resolvers?: any;
|
|
8
|
-
context?: (req: Request, ctx: Context) => Record<string, any> | Promise<Record<string, any>>;
|
|
9
|
-
graphiql?: boolean;
|
|
10
|
-
/** Max query depth (nesting). Default: 10. Set 0 to disable. */
|
|
11
|
-
maxDepth?: number;
|
|
12
|
-
/** Execution timeout in ms. Default: 30_000. */
|
|
13
|
-
timeout?: number;
|
|
14
|
-
}
|
|
15
|
-
export type GraphQLHandler = (req: Request, ctx: Context) => GraphQLOptions | Promise<GraphQLOptions>;
|
|
16
|
-
export declare function graphql(handler: GraphQLHandler): Router;
|
package/dist/hub.d.ts
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { Redis, WebSocket, Closeable } from './types.ts';
|
|
2
|
-
/** Options for {@link createHub}. */
|
|
3
|
-
export interface HubOptions {
|
|
4
|
-
/** Optional Redis client for cross-process pub/sub broadcast. */
|
|
5
|
-
redis?: Redis;
|
|
6
|
-
/** Key prefix for Redis channels (default: `'hub:'`). */
|
|
7
|
-
prefix?: string;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* In-memory (and optionally Redis-backed) pub/sub hub for WebSocket rooms.
|
|
11
|
-
*
|
|
12
|
-
* Used internally by the WebSocket handler to implement `ctx.ws.join()` / `ctx.ws.sendRoom()`. */
|
|
13
|
-
export interface Hub extends Closeable {
|
|
14
|
-
/** Subscribe a WebSocket to a room/group. */
|
|
15
|
-
join(key: string, ws: WebSocket): void;
|
|
16
|
-
/** Unsubscribe a WebSocket from all rooms. */
|
|
17
|
-
leave(ws: WebSocket): void;
|
|
18
|
-
/** Send a JSON message to all members of a room. */
|
|
19
|
-
broadcast(key: string, data: unknown): void;
|
|
20
|
-
/** Close the hub, disconnect Redis subscribers, clear all rooms. */
|
|
21
|
-
close(): Promise<void>;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Create a pub/sub hub for WebSocket room management.
|
|
25
|
-
*
|
|
26
|
-
* In-memory by default. Pass `redis` to enable cross-process broadcasting.
|
|
27
|
-
*
|
|
28
|
-
* ```ts
|
|
29
|
-
* import { createHub } from 'weifuwu'
|
|
30
|
-
*
|
|
31
|
-
* const hub = createHub()
|
|
32
|
-
* hub.join('room:general', ws)
|
|
33
|
-
* hub.broadcast('room:general', { type: 'chat', text: 'Hello' })
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
export declare function createHub(opts?: HubOptions): Hub;
|