weifuwu 0.23.2 → 0.23.3
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 +55 -0
- package/cli/template/.weifuwu/ssr/2e3a7e60.js +3 -3
- package/dist/analytics.d.ts +20 -0
- package/dist/client-locale.d.ts +20 -0
- package/dist/client-theme.d.ts +29 -0
- package/dist/compress.d.ts +14 -0
- package/dist/cors.d.ts +15 -0
- package/dist/cron-utils.d.ts +65 -0
- package/dist/csrf.d.ts +29 -0
- package/dist/env.d.ts +25 -5
- package/dist/flash.d.ts +66 -7
- package/dist/health.d.ts +18 -0
- package/dist/helmet.d.ts +15 -0
- package/dist/hub.d.ts +25 -1
- package/dist/index.js +102 -36
- package/dist/mailer.d.ts +30 -0
- package/dist/permissions.d.ts +5 -3
- package/dist/postgres/schema/columns.d.ts +56 -0
- package/dist/postgres/schema/sql.d.ts +15 -0
- package/dist/postgres/schema/table.d.ts +54 -1
- package/dist/postgres/schema/where.d.ts +14 -0
- package/dist/rate-limit.d.ts +25 -3
- package/dist/request-id.d.ts +19 -0
- package/dist/seo.d.ts +65 -0
- package/dist/sse.d.ts +37 -0
- package/dist/static.d.ts +16 -0
- package/dist/stream.d.ts +15 -0
- package/dist/trace.d.ts +41 -5
- package/dist/types.d.ts +10 -1
- package/dist/upload.d.ts +30 -0
- package/dist/use-action.d.ts +28 -0
- package/dist/use-agent-stream.d.ts +32 -10
- package/dist/use-flash-message.d.ts +16 -0
- package/dist/use-websocket.d.ts +25 -0
- package/dist/user/client.d.ts +15 -0
- package/dist/user/oauth2.d.ts +10 -0
- package/dist/user/types.d.ts +58 -4
- package/dist/webhook.d.ts +40 -15
- package/package.json +4 -2
- package/cli/template/.weifuwu/ssr/560568d7.js +0 -14
package/README.md
CHANGED
|
@@ -475,6 +475,26 @@ app.use(cors({ credentials: true, maxAge: 3600 }))
|
|
|
475
475
|
| `credentials` | `boolean` | `false` | Allow cookies/credentials |
|
|
476
476
|
| `maxAge` | `number` | — | Preflight cache duration (seconds) |
|
|
477
477
|
|
|
478
|
+
### flash [α]
|
|
479
|
+
|
|
480
|
+
Cookie-based flash message. Read from request, write via redirect.
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
app.use(flash())
|
|
484
|
+
|
|
485
|
+
app.get('/', (req, ctx) => {
|
|
486
|
+
const msg = ctx.flash.value // { type: 'success', text: 'Saved!' } or undefined
|
|
487
|
+
})
|
|
488
|
+
|
|
489
|
+
app.post('/save', (req, ctx) => {
|
|
490
|
+
return ctx.flash.set({ type: 'success', text: 'Saved!' }, '/articles')
|
|
491
|
+
})
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
| Option | Type | Default | Description |
|
|
495
|
+
|--------|------|---------|-------------|
|
|
496
|
+
| `name` | `string` | `'flash'` | Cookie name |
|
|
497
|
+
|
|
478
498
|
### cache [α]
|
|
479
499
|
|
|
480
500
|
Response caching middleware with memory and Redis stores. Caches GET/HEAD responses, with tag-based invalidation.
|
|
@@ -1092,6 +1112,24 @@ class MyModule extends PgModule {
|
|
|
1092
1112
|
|
|
1093
1113
|
Where helpers + `and`/`or`/`not` can be imported from `'weifuwu'` alongside `postgres`. Full column builders and table helpers are in the same barrel.
|
|
1094
1114
|
|
|
1115
|
+
### cron-utils
|
|
1116
|
+
|
|
1117
|
+
Shared cron expression parsing utilities. All functions operate in **local timezone**.
|
|
1118
|
+
|
|
1119
|
+
```ts
|
|
1120
|
+
import { cronNext } from 'weifuwu'
|
|
1121
|
+
|
|
1122
|
+
// Next weekday at 09:00
|
|
1123
|
+
const next = cronNext('0 9 * * 1-5')
|
|
1124
|
+
console.log(new Date(next))
|
|
1125
|
+
```
|
|
1126
|
+
|
|
1127
|
+
| Function | Description |
|
|
1128
|
+
|----------|-------------|
|
|
1129
|
+
| `parsePattern(pattern)` | Parse 5-field cron pattern into `Set<number>[]` |
|
|
1130
|
+
| `matches(fields, date)` | Check if a date matches a parsed pattern |
|
|
1131
|
+
| `cronNext(expr, from?)` | Calculate next matching timestamp (`from` defaults to now) |
|
|
1132
|
+
|
|
1095
1133
|
### fts — Full-Text Search (PostgreSQL)
|
|
1096
1134
|
|
|
1097
1135
|
Utilities for PostgreSQL full-text search: create GIN indexes, search with ranking, and generate highlighted snippets.
|
|
@@ -1315,7 +1353,24 @@ app.use(requestId({ header: 'X-Request-Id', generator: () => crypto.randomUUID()
|
|
|
1315
1353
|
| `header` | `string` | `'X-Request-ID'` | Header name to read/write |
|
|
1316
1354
|
| `generator` | `() => string` | `crypto.randomUUID()` | ID generator |
|
|
1317
1355
|
|
|
1356
|
+
### trace
|
|
1318
1357
|
|
|
1358
|
+
Request-scoped tracing via `AsyncLocalStorage`. Used internally by `serve()`.
|
|
1359
|
+
|
|
1360
|
+
```ts
|
|
1361
|
+
import { currentTraceId, runWithTrace, traceElapsed } from 'weifuwu'
|
|
1362
|
+
|
|
1363
|
+
// Inside a middleware or handler
|
|
1364
|
+
const traceId = currentTraceId() // UUID or incoming X-Trace-Id
|
|
1365
|
+
const elapsed = traceElapsed() // ms since request started
|
|
1366
|
+
```
|
|
1367
|
+
|
|
1368
|
+
| Function | Description |
|
|
1369
|
+
|----------|-------------|
|
|
1370
|
+
| `currentTraceId()` | Current request trace ID, or `undefined` outside a request |
|
|
1371
|
+
| `currentTrace()` | Full `{ traceId, startTime }` context |
|
|
1372
|
+
| `traceElapsed()` | Milliseconds elapsed since the trace started |
|
|
1373
|
+
| `runWithTrace(traceId, fn)` | Execute `fn` inside a trace scope |
|
|
1319
1374
|
|
|
1320
1375
|
### s3 [α] — S3-compatible object storage
|
|
1321
1376
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// ui/app/page.tsx
|
|
1
|
+
// cli/template/ui/app/page.tsx
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { useWebsocket, useLoaderData, useLocale, useTheme } from "weifuwu/react";
|
|
4
4
|
|
|
5
|
-
// ui/components/Greeting.tsx
|
|
5
|
+
// cli/template/ui/components/Greeting.tsx
|
|
6
6
|
import { jsxs } from "react/jsx-runtime";
|
|
7
7
|
function Greeting({ name }) {
|
|
8
8
|
return /* @__PURE__ */ jsxs("span", { className: "text-red-500 font-bold", children: [
|
|
@@ -11,7 +11,7 @@ function Greeting({ name }) {
|
|
|
11
11
|
] });
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
// ui/app/page.tsx
|
|
14
|
+
// cli/template/ui/app/page.tsx
|
|
15
15
|
import { jsx, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
16
16
|
function Home() {
|
|
17
17
|
const [input, setInput] = useState("");
|
package/dist/analytics.d.ts
CHANGED
|
@@ -1,15 +1,35 @@
|
|
|
1
1
|
import type { Middleware } from './types.ts';
|
|
2
2
|
import { Router } from './router.ts';
|
|
3
|
+
/** Options for {@link analytics}. */
|
|
3
4
|
export interface AnalyticsOptions {
|
|
5
|
+
/** Path prefixes to exclude from analytics (default: `['/__analytics', '/__wfw', '/static']`). */
|
|
4
6
|
excluded?: string[];
|
|
7
|
+
/** PostgreSQL client for persistent storage. Required for production use. */
|
|
5
8
|
pg?: {
|
|
6
9
|
sql: (strings: TemplateStringsArray, ...values: any[]) => Promise<any[]>;
|
|
7
10
|
table: (name: string, cols: any) => any;
|
|
8
11
|
};
|
|
9
12
|
}
|
|
13
|
+
/** Analytics module returned by {@link analytics}. */
|
|
10
14
|
export interface AnalyticsModule extends Router {
|
|
15
|
+
/** Middleware that records page views. */
|
|
11
16
|
middleware: () => Middleware;
|
|
17
|
+
/** Create/update the analytics database tables. */
|
|
12
18
|
migrate: () => Promise<void>;
|
|
19
|
+
/** Close the in-memory store and any timers. */
|
|
13
20
|
close: () => Promise<void>;
|
|
14
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Page view analytics module.
|
|
24
|
+
*
|
|
25
|
+
* Records page views with referrer and device type. Supports in-memory and PostgreSQL storage.
|
|
26
|
+
* Provides a dashboard at `GET /__analytics`.
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { analytics, postgres } from 'weifuwu'
|
|
30
|
+
*
|
|
31
|
+
* const pg = postgres({ connection: DATABASE_URL })
|
|
32
|
+
* app.use(analytics({ pg }).middleware())
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
15
35
|
export declare function analytics(options?: AnalyticsOptions): AnalyticsModule;
|
package/dist/client-locale.d.ts
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React hook to read and change the locale on the client side.
|
|
3
|
+
*
|
|
4
|
+
* Changes are made via SPA navigation to `/__lang/{locale}`, which is
|
|
5
|
+
* intercepted by the client router and applied without a full page reload.
|
|
6
|
+
*
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import { useLocale } from 'weifuwu/react'
|
|
9
|
+
*
|
|
10
|
+
* function LangSwitcher() {
|
|
11
|
+
* const { locale, setLocale, t } = useLocale()
|
|
12
|
+
* return (
|
|
13
|
+
* <>
|
|
14
|
+
* <p>{t('greeting')}</p>
|
|
15
|
+
* <button onClick={() => setLocale('zh')}>中文</button>
|
|
16
|
+
* </>
|
|
17
|
+
* )
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
1
21
|
export declare function useLocale(): {
|
|
2
22
|
locale: string | undefined;
|
|
3
23
|
setLocale: (locale: string) => Promise<void>;
|
package/dist/client-theme.d.ts
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Apply a theme value to the DOM by setting `document.documentElement.dataset.theme`.
|
|
3
|
+
* Resolves `'system'` to the user's `prefers-color-scheme` preference.
|
|
4
|
+
* Call this directly from non-React code (e.g. a `<script>` tag).
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { applyTheme } from 'weifuwu/react'
|
|
8
|
+
* applyTheme('dark')
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
1
11
|
declare function applyTheme(theme: string): void;
|
|
12
|
+
/**
|
|
13
|
+
* React hook to read and change the theme on the client side.
|
|
14
|
+
*
|
|
15
|
+
* Applies the resolved theme to `document.documentElement.dataset.theme`.
|
|
16
|
+
* Tracks system preference changes when theme is `'system'`.
|
|
17
|
+
*
|
|
18
|
+
* ```tsx
|
|
19
|
+
* import { useTheme } from 'weifuwu/react'
|
|
20
|
+
*
|
|
21
|
+
* function ThemeToggle() {
|
|
22
|
+
* const { theme, resolvedTheme, setTheme } = useTheme()
|
|
23
|
+
* return (
|
|
24
|
+
* <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
|
|
25
|
+
* Current: {resolvedTheme}
|
|
26
|
+
* </button>
|
|
27
|
+
* )
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
2
31
|
export declare function useTheme(): {
|
|
3
32
|
theme: string;
|
|
4
33
|
resolvedTheme: string;
|
package/dist/compress.d.ts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import type { Middleware } from './types.ts';
|
|
2
|
+
/** Options for {@link compress}. */
|
|
2
3
|
export interface CompressOptions {
|
|
4
|
+
/** Compression level (1-9, default: 6). */
|
|
3
5
|
level?: number;
|
|
6
|
+
/** Minimum response body size in bytes to compress (default: 1024). */
|
|
4
7
|
threshold?: number;
|
|
5
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Response compression middleware (brotli, gzip, deflate).
|
|
11
|
+
*
|
|
12
|
+
* Automatically selects the best encoding based on `Accept-Encoding` header.
|
|
13
|
+
* Skips compression for small responses, images, audio, video, and already-encoded responses.
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* import { compress } from 'weifuwu'
|
|
17
|
+
* app.use(compress())
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
6
20
|
export declare function compress(options?: CompressOptions): Middleware;
|
package/dist/cors.d.ts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import type { Middleware } from './types.ts';
|
|
2
|
+
/** Options for {@link cors}. */
|
|
2
3
|
export interface CORSOptions {
|
|
4
|
+
/** Allowed origin(s). Default `'*'`. If `credentials: true`, reflects the request origin. */
|
|
3
5
|
origin?: string | string[] | ((origin: string) => string | boolean | undefined);
|
|
6
|
+
/** Allowed HTTP methods. Default: `GET, HEAD, PUT, PATCH, POST, DELETE`. */
|
|
4
7
|
methods?: string[];
|
|
8
|
+
/** Allowed request headers. Default: `Content-Type, Authorization`. */
|
|
5
9
|
allowedHeaders?: string[];
|
|
10
|
+
/** Exposed response headers. */
|
|
6
11
|
exposedHeaders?: string[];
|
|
12
|
+
/** Whether to expose `Access-Control-Allow-Credentials`. */
|
|
7
13
|
credentials?: boolean;
|
|
14
|
+
/** `Access-Control-Max-Age` in seconds. */
|
|
8
15
|
maxAge?: number;
|
|
9
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* CORS middleware.
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { cors } from 'weifuwu'
|
|
22
|
+
* app.use(cors({ origin: 'https://myapp.com', credentials: true }))
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
10
25
|
export declare function cors(options?: CORSOptions): Middleware;
|
package/dist/cron-utils.d.ts
CHANGED
|
@@ -1,8 +1,73 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared cron expression parsing utilities.
|
|
3
3
|
* Used by both queue (Redis-backed) and in-memory scheduler.
|
|
4
|
+
*
|
|
5
|
+
* All functions operate in **local timezone**.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { cronNext } from 'weifuwu'
|
|
9
|
+
*
|
|
10
|
+
* // Get next weekday at 09:00
|
|
11
|
+
* const next = cronNext('0 9 * * 1-5')
|
|
12
|
+
* console.log(new Date(next))
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Parse a single cron field (e.g. `"* /5"`, `"1-10"`, `"1,3,5"`) into a set
|
|
17
|
+
* of matching integer values within `[min, max]`.
|
|
18
|
+
*
|
|
19
|
+
* @param field - The cron field expression.
|
|
20
|
+
* @param min - Minimum valid value (inclusive).
|
|
21
|
+
* @param max - Maximum valid value (inclusive).
|
|
22
|
+
* @returns Set of matching integer values.
|
|
23
|
+
* @throws If the field contains an invalid expression (step of 0, NaN, etc.).
|
|
24
|
+
*
|
|
25
|
+
* ```ts
|
|
26
|
+
* parseField('1-5', 1, 31) // Set { 1, 2, 3, 4, 5 }
|
|
27
|
+
* ```
|
|
4
28
|
*/
|
|
5
29
|
export declare function parseField(field: string, min: number, max: number): Set<number>;
|
|
30
|
+
/**
|
|
31
|
+
* Parse a full 5-field cron expression into an array of 5 Sets.
|
|
32
|
+
*
|
|
33
|
+
* @param pattern - Standard cron expression: `minute hour day month weekday`
|
|
34
|
+
* @returns Array of 5 Sets (minute, hour, day, month, weekday).
|
|
35
|
+
* @throws If the pattern does not contain exactly 5 fields.
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* const fields = parsePattern('0 9 * * 1-5')
|
|
39
|
+
* fields[1] // hour: { 9 }
|
|
40
|
+
* fields[4] // weekday: { 1, 2, 3, 4, 5 }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
6
43
|
export declare function parsePattern(pattern: string): Set<number>[];
|
|
44
|
+
/**
|
|
45
|
+
* Check whether a given date matches a parsed cron pattern.
|
|
46
|
+
* Uses local timezone methods (getMinutes, getHours, etc.).
|
|
47
|
+
*
|
|
48
|
+
* @param fields - Parsed pattern from {@link parsePattern}.
|
|
49
|
+
* @param date - Date to check.
|
|
50
|
+
* @returns `true` if the date matches the pattern.
|
|
51
|
+
*
|
|
52
|
+
* ```ts
|
|
53
|
+
* const fields = parsePattern('0 9 * * 1-5') // weekdays at 09:00
|
|
54
|
+
* matches(fields, new Date('2026-06-15T09:00:00')) // true (Monday)
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
7
57
|
export declare function matches(fields: Set<number>[], date: Date): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Calculate the next future timestamp (ms since epoch) matching a cron expression.
|
|
60
|
+
* Scans forward minute by minute, up to 1 year ahead.
|
|
61
|
+
* Uses local timezone.
|
|
62
|
+
*
|
|
63
|
+
* @param expr - Standard 5-field cron expression.
|
|
64
|
+
* @param from - Starting point (default: now). The result is always > `from`.
|
|
65
|
+
* @returns Unix timestamp (ms) of the next matching time.
|
|
66
|
+
* @throws If no matching time is found within 1 year.
|
|
67
|
+
*
|
|
68
|
+
* ```ts
|
|
69
|
+
* const next = cronNext('30 14 * * *') // next 14:30
|
|
70
|
+
* console.log(new Date(next).toISOString())
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
8
73
|
export declare function cronNext(expr: string, from?: Date): number;
|
package/dist/csrf.d.ts
CHANGED
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
import type { Context, Middleware } from './types.ts';
|
|
2
|
+
/** Options for {@link csrf}. */
|
|
2
3
|
export interface CsrfOptions {
|
|
4
|
+
/** Cookie name for CSRF token (default: `'_csrf'`). */
|
|
3
5
|
cookie?: string;
|
|
6
|
+
/** Request header name for CSRF token (default: `'x-csrf-token'`). */
|
|
4
7
|
header?: string;
|
|
8
|
+
/** Form body key for CSRF token (default: `'_csrf'`). */
|
|
5
9
|
key?: string;
|
|
10
|
+
/** HTTP methods to exclude from CSRF protection (default: `['GET', 'HEAD', 'OPTIONS']`). */
|
|
6
11
|
excludeMethods?: string[];
|
|
7
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* CSRF protection middleware.
|
|
15
|
+
*
|
|
16
|
+
* On excluded methods (GET, HEAD, OPTIONS), generates a token and stores it
|
|
17
|
+
* in a cookie. On other methods, validates the token from header or body
|
|
18
|
+
* against the cookie.
|
|
19
|
+
*
|
|
20
|
+
* Injects `ctx.csrfToken` for use in forms.
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { csrf } from 'weifuwu'
|
|
24
|
+
* app.use(csrf())
|
|
25
|
+
*
|
|
26
|
+
* // In a form:
|
|
27
|
+
* app.get('/form', (req, ctx) => {
|
|
28
|
+
* return new Response(`
|
|
29
|
+
* <form method="POST">
|
|
30
|
+
* <input type="hidden" name="_csrf" value="${ctx.csrfToken}" />
|
|
31
|
+
* <input type="submit" />
|
|
32
|
+
* </form>
|
|
33
|
+
* `, { headers: { 'content-type': 'text/html' } })
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
8
37
|
export declare function csrf(options?: CsrfOptions): Middleware<Context, Context & {
|
|
9
38
|
csrfToken: string;
|
|
10
39
|
}>;
|
package/dist/env.d.ts
CHANGED
|
@@ -1,8 +1,28 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
1
|
+
/**
|
|
2
|
+
* Whether `NODE_ENV` is explicitly set to `'development'`.
|
|
3
|
+
*
|
|
4
|
+
* Used for dev-only features: HMR, livereload, React `createRoot` (not hydrate).
|
|
5
|
+
* **Not** the opposite of {@link isProd} — when `NODE_ENV` is unset, both return `false`.
|
|
6
|
+
*/
|
|
4
7
|
export declare function isDev(): boolean;
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
8
|
+
/**
|
|
9
|
+
* Whether `NODE_ENV` is explicitly set to `'production'`.
|
|
10
|
+
*
|
|
11
|
+
* Used for production-only behavior: plain-text 404, suppressed warnings, minified output.
|
|
12
|
+
*/
|
|
7
13
|
export declare function isProd(): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Load environment variables from a `.env` file into `process.env`.
|
|
16
|
+
*
|
|
17
|
+
* Does **not** override existing `process.env` values.
|
|
18
|
+
* Supports quoted values and inline comments.
|
|
19
|
+
*
|
|
20
|
+
* @param path - Path to `.env` file (default: `'.env'` relative to cwd).
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { loadEnv } from 'weifuwu'
|
|
24
|
+
* loadEnv()
|
|
25
|
+
* console.log(process.env.PORT)
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
8
28
|
export declare function loadEnv(path?: string): void;
|
package/dist/flash.d.ts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import type { Middleware } from './types.ts';
|
|
2
|
-
export interface FlashOptions {
|
|
3
|
-
/** Cookie name (default: 'flash'). */
|
|
4
|
-
name?: string;
|
|
5
|
-
}
|
|
6
1
|
/**
|
|
7
2
|
* Flash message middleware.
|
|
8
3
|
*
|
|
4
|
+
* Provides a cookie-based flash message system:
|
|
5
|
+
* - Read: `ctx.flash.value` parses the incoming flash cookie
|
|
6
|
+
* - Write: `ctx.flash.set(data, location)` sets a new flash and redirects
|
|
7
|
+
* - Auto-clear: after reading, the flash cookie is cleared from the response
|
|
8
|
+
*
|
|
9
9
|
* ```ts
|
|
10
|
+
* import { flash } from 'weifuwu'
|
|
11
|
+
*
|
|
10
12
|
* app.use(flash())
|
|
11
13
|
*
|
|
12
14
|
* // Read flash
|
|
13
15
|
* app.get('/', (req, ctx) => {
|
|
14
|
-
* const msg = ctx.flash.value // { type: 'success', text: 'Saved!' }
|
|
16
|
+
* const msg = ctx.flash.value // e.g. { type: 'success', text: 'Saved!' }
|
|
15
17
|
* })
|
|
16
18
|
*
|
|
17
19
|
* // Set flash + redirect
|
|
@@ -21,4 +23,61 @@ export interface FlashOptions {
|
|
|
21
23
|
* })
|
|
22
24
|
* ```
|
|
23
25
|
*/
|
|
24
|
-
|
|
26
|
+
import type { Context, Middleware } from './types.ts';
|
|
27
|
+
/** Options for {@link flash}. */
|
|
28
|
+
export interface FlashOptions {
|
|
29
|
+
/**
|
|
30
|
+
* Cookie name to store the flash message.
|
|
31
|
+
* @default 'flash'
|
|
32
|
+
*/
|
|
33
|
+
name?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Flash message object injected into `ctx.flash`.
|
|
37
|
+
*
|
|
38
|
+
* Access the current flash with `.value`, or set a new flash with `.set()`.
|
|
39
|
+
* The `.value` is automatically cleared after being read.
|
|
40
|
+
*/
|
|
41
|
+
export interface FlashInjected {
|
|
42
|
+
/**
|
|
43
|
+
* The flash value read from the incoming cookie.
|
|
44
|
+
* `undefined` if no flash cookie is present.
|
|
45
|
+
* Automatically cleared after the response is sent.
|
|
46
|
+
*/
|
|
47
|
+
value: unknown;
|
|
48
|
+
/**
|
|
49
|
+
* Set a flash message and return a 302 redirect response.
|
|
50
|
+
*
|
|
51
|
+
* @param data - Any JSON-serializable value to store as the flash message.
|
|
52
|
+
* @param location - Redirect location (defaults to the `Referer` header).
|
|
53
|
+
* @returns A 302 Response with a `Set-Cookie` header.
|
|
54
|
+
*
|
|
55
|
+
* ```ts
|
|
56
|
+
* return ctx.flash.set({ type: 'success', text: 'Saved!' }, '/articles')
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
set: (data: unknown, location?: string) => Response;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Flash message middleware — injects `ctx.flash`.
|
|
63
|
+
*
|
|
64
|
+
* @param options - Cookie name configuration.
|
|
65
|
+
* @returns Middleware that injects `ctx.flash` (`FlashInjected`).
|
|
66
|
+
*
|
|
67
|
+
* ```ts
|
|
68
|
+
* app.use(flash())
|
|
69
|
+
*
|
|
70
|
+
* // Read
|
|
71
|
+
* app.get('/', (req, ctx) => {
|
|
72
|
+
* const msg = ctx.flash.value
|
|
73
|
+
* })
|
|
74
|
+
*
|
|
75
|
+
* // Write + redirect
|
|
76
|
+
* app.post('/save', async (req, ctx) => {
|
|
77
|
+
* return ctx.flash.set({ type: 'success', text: 'Saved!' }, '/articles')
|
|
78
|
+
* })
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function flash(options?: FlashOptions): Middleware<Context, Context & {
|
|
82
|
+
flash: FlashInjected;
|
|
83
|
+
}>;
|
package/dist/health.d.ts
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import { Router } from './router.ts';
|
|
2
|
+
/** Options for {@link health}. */
|
|
2
3
|
export interface HealthOptions {
|
|
4
|
+
/** Health check endpoint path (default: `'/__health'`). */
|
|
3
5
|
path?: string;
|
|
6
|
+
/** Async function that throws if the service is unhealthy. Called on each request. */
|
|
4
7
|
check?: () => Promise<void>;
|
|
5
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Health check endpoint.
|
|
11
|
+
*
|
|
12
|
+
* Returns 200 with `'OK'` if the check passes, 503 if it fails.
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { health } from 'weifuwu'
|
|
16
|
+
*
|
|
17
|
+
* app.use(health({
|
|
18
|
+
* check: async () => {
|
|
19
|
+
* await db.query('SELECT 1')
|
|
20
|
+
* },
|
|
21
|
+
* }))
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
6
24
|
export declare function health(options?: HealthOptions): Router;
|
package/dist/helmet.d.ts
CHANGED
|
@@ -1,18 +1,33 @@
|
|
|
1
1
|
import type { Middleware } from './types.ts';
|
|
2
|
+
/** Options for {@link helmet}. Set any header to `false` to omit it. */
|
|
2
3
|
export interface HelmetOptions {
|
|
4
|
+
/** `Content-Security-Policy` header value. */
|
|
3
5
|
contentSecurityPolicy?: string | false;
|
|
6
|
+
/** `Cross-Origin-Embedder-Policy` header value. */
|
|
4
7
|
crossOriginEmbedderPolicy?: string | false;
|
|
8
|
+
/** `Cross-Origin-Opener-Policy` header value. */
|
|
5
9
|
crossOriginOpenerPolicy?: string | false;
|
|
10
|
+
/** `Cross-Origin-Resource-Policy` header value. */
|
|
6
11
|
crossOriginResourcePolicy?: string | false;
|
|
12
|
+
/** `Origin-Agent-Cluster` header value. */
|
|
7
13
|
originAgentCluster?: string | false;
|
|
14
|
+
/** `Referrer-Policy` header value. */
|
|
8
15
|
referrerPolicy?: string | false;
|
|
16
|
+
/** `Strict-Transport-Security` header value. */
|
|
9
17
|
strictTransportSecurity?: string | false;
|
|
18
|
+
/** `X-Content-Type-Options` header value. */
|
|
10
19
|
xContentTypeOptions?: string | false;
|
|
20
|
+
/** `X-DNS-Prefetch-Control` header value. */
|
|
11
21
|
xDnsPrefetchControl?: string | false;
|
|
22
|
+
/** `X-Download-Options` header value. */
|
|
12
23
|
xDownloadOptions?: string | false;
|
|
24
|
+
/** `X-Frame-Options` header value. */
|
|
13
25
|
xFrameOptions?: string | false;
|
|
26
|
+
/** `X-Permitted-Cross-Domain-Policies` header value. */
|
|
14
27
|
xPermittedCrossDomainPolicies?: string | false;
|
|
28
|
+
/** `X-XSS-Protection` header value. */
|
|
15
29
|
xXssProtection?: string | false;
|
|
30
|
+
/** `Permissions-Policy` header value. */
|
|
16
31
|
permissionsPolicy?: string | false;
|
|
17
32
|
}
|
|
18
33
|
export declare function helmet(options?: HelmetOptions): Middleware;
|
package/dist/hub.d.ts
CHANGED
|
@@ -1,12 +1,36 @@
|
|
|
1
|
-
import type { Redis } from './vendor.ts';
|
|
1
|
+
import type { Redis, WebSocket } from './vendor.ts';
|
|
2
|
+
/** Options for {@link createHub}. */
|
|
2
3
|
export interface HubOptions {
|
|
4
|
+
/** Optional Redis client for cross-process pub/sub broadcast. */
|
|
3
5
|
redis?: Redis;
|
|
6
|
+
/** Key prefix for Redis channels (default: `'hub:'`). */
|
|
4
7
|
prefix?: string;
|
|
5
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()`. */
|
|
6
13
|
export interface Hub {
|
|
14
|
+
/** Subscribe a WebSocket to a room/group. */
|
|
7
15
|
join(key: string, ws: WebSocket): void;
|
|
16
|
+
/** Unsubscribe a WebSocket from all rooms. */
|
|
8
17
|
leave(ws: WebSocket): void;
|
|
18
|
+
/** Send a JSON message to all members of a room. */
|
|
9
19
|
broadcast(key: string, data: unknown): void;
|
|
20
|
+
/** Close the hub, disconnect Redis subscribers, clear all rooms. */
|
|
10
21
|
close(): Promise<void>;
|
|
11
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
|
+
*/
|
|
12
36
|
export declare function createHub(opts?: HubOptions): Hub;
|