weifuwu 0.27.25 → 0.27.28
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 +17 -16
- package/dist/cli.js +16 -27
- package/dist/core/router.d.ts +16 -0
- package/dist/index.d.ts +1 -19
- package/dist/index.js +49 -600
- package/dist/types.d.ts +27 -7
- package/package.json +5 -9
- package/dist/docs/ssr/ui.md +0 -472
- package/dist/middleware/csrf.d.ts +0 -47
- package/dist/middleware/flash.d.ts +0 -90
- package/dist/middleware/i18n.d.ts +0 -39
- package/dist/middleware/theme.d.ts +0 -31
- package/dist/ssr/assets.d.ts +0 -5
- package/dist/ssr/compile.d.ts +0 -21
- package/dist/ssr/css.d.ts +0 -16
- package/dist/ssr/html.d.ts +0 -53
- package/dist/ssr/layout.d.ts +0 -2
- package/dist/ssr/ui/assets.d.ts +0 -4
- package/dist/ssr/view.d.ts +0 -36
- package/dist/template/AGENTS.md +0 -28
- package/dist/template/app.ts +0 -20
- package/dist/template/index.ts +0 -6
- package/dist/template/locales/en.json +0 -7
- package/dist/template/locales/zh-CN.json +0 -7
- package/dist/template/package.json +0 -11
- package/dist/template/tsconfig.json +0 -15
- package/dist/template/ui/app/globals.css +0 -2
- package/dist/template/ui/app/layout.ts +0 -39
- package/dist/template/ui/app/page.ts +0 -39
- package/dist/weifuwu-ui.css +0 -646
- package/dist/weifuwu-ui.js +0 -998
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ app.use(rateLimit({ window: 60 }))
|
|
|
66
66
|
## Full-stack SSR
|
|
67
67
|
|
|
68
68
|
Server-rendered HTML with zero frontend build tools. Uses `html()` tagged templates
|
|
69
|
-
for safe HTML rendering, and
|
|
69
|
+
for safe HTML rendering, and **HTMX + Alpine.js + weifuwu-ui** for client-side interactions.
|
|
70
70
|
|
|
71
71
|
```ts
|
|
72
72
|
import { Router, serve, html, raw, layout, view, wfuwAssets, wfuwVersion, theme, i18n, flash } from 'weifuwu'
|
|
@@ -78,7 +78,7 @@ app.use(theme())
|
|
|
78
78
|
app.use(i18n({ dir: './locales' }))
|
|
79
79
|
app.use(flash())
|
|
80
80
|
|
|
81
|
-
// weifuwu-ui frontend
|
|
81
|
+
// HTMX + Alpine.js + weifuwu-ui frontend assets
|
|
82
82
|
app.use('/', wfuwAssets())
|
|
83
83
|
|
|
84
84
|
// Layout (wraps all pages)
|
|
@@ -134,8 +134,10 @@ export default function (body: string, ctx: any) {
|
|
|
134
134
|
<head>
|
|
135
135
|
<meta charset="utf-8" />
|
|
136
136
|
<link rel="stylesheet" href="/__wfw/css/weifuwu-ui.css?v=${wfuwVersion}" />
|
|
137
|
+
<script src="/__wfw/js/htmx.min.js?v=${wfuwVersion}"></script>
|
|
138
|
+
<script defer src="/__wfw/js/alpine.min.js?v=${wfuwVersion}"></script>
|
|
137
139
|
<script src="/__wfw/js/weifuwu-ui.js?v=${wfuwVersion}"></script>
|
|
138
|
-
<script id="
|
|
140
|
+
<script id="__wf-i18n" type="application/json">
|
|
139
141
|
${raw(JSON.stringify(ctx.i18n?.messages || {}))}
|
|
140
142
|
</script>
|
|
141
143
|
</head>
|
|
@@ -160,16 +162,14 @@ export default function (ctx: any) {
|
|
|
160
162
|
}
|
|
161
163
|
```
|
|
162
164
|
|
|
163
|
-
### UI frontend runtime
|
|
165
|
+
### UI frontend runtime
|
|
164
166
|
|
|
165
|
-
weifuwu
|
|
166
|
-
|
|
167
|
-
WebSocket, theme/i18n/flash integration, and UI components.
|
|
167
|
+
weifuwu ships with **HTMX** (AJAX, SSE, WebSocket, forms) + **Alpine.js** (state, DOM
|
|
168
|
+
binding, UI components) + **weifuwu-ui** (Alpine stores for theme/i18n/flash).
|
|
168
169
|
|
|
169
170
|
```ts
|
|
170
171
|
import { wfuwAssets } from 'weifuwu'
|
|
171
|
-
|
|
172
|
-
app.use(wfuwAssets()) // serve /__wfw/js/weifuwu-ui.js + /__wfw/css/weifuwu-ui.css
|
|
172
|
+
app.use(wfuwAssets()) // serve htmx.min.js + alpine.min.js + weifuwu-ui.js
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
In your layout (with cache-busting via `wfuwVersion`):
|
|
@@ -179,6 +179,8 @@ import { wfuwVersion } from 'weifuwu'
|
|
|
179
179
|
```
|
|
180
180
|
|
|
181
181
|
```html
|
|
182
|
+
<script src="/__wfw/js/htmx.min.js?v=${wfuwVersion}"></script>
|
|
183
|
+
<script defer src="/__wfw/js/alpine.min.js?v=${wfuwVersion}"></script>
|
|
182
184
|
<script src="/__wfw/js/weifuwu-ui.js?v=${wfuwVersion}"></script>
|
|
183
185
|
<link rel="stylesheet" href="/__wfw/css/weifuwu-ui.css?v=${wfuwVersion}" />
|
|
184
186
|
```
|
|
@@ -560,9 +562,7 @@ app.get('/', view('./ui/app/page.ts'))
|
|
|
560
562
|
|
|
561
563
|
#### wfuwAssets()
|
|
562
564
|
|
|
563
|
-
Serve
|
|
564
|
-
Covers: AJAX loading, state binding, SSE streaming, WebSocket, theme/i18n/flash,
|
|
565
|
-
modal/collapse/tabs/dropdown/toast components.
|
|
565
|
+
Serve HTMX, Alpine.js, and weifuwu-ui (Alpine stores for theme/i18n/flash).
|
|
566
566
|
|
|
567
567
|
```ts
|
|
568
568
|
import { wfuwAssets } from 'weifuwu'
|
|
@@ -574,6 +574,8 @@ import { wfuwVersion } from 'weifuwu'
|
|
|
574
574
|
```
|
|
575
575
|
|
|
576
576
|
```html
|
|
577
|
+
<script src="/__wfw/js/htmx.min.js?v=${wfuwVersion}"></script>
|
|
578
|
+
<script defer src="/__wfw/js/alpine.min.js?v=${wfuwVersion}"></script>
|
|
577
579
|
<script src="/__wfw/js/weifuwu-ui.js?v=${wfuwVersion}"></script>
|
|
578
580
|
<link rel="stylesheet" href="/__wfw/css/weifuwu-ui.css?v=${wfuwVersion}" />
|
|
579
581
|
```
|
|
@@ -702,9 +704,8 @@ Creates a minimal API project with `app.ts`, `index.ts`, and TypeScript config.
|
|
|
702
704
|
|
|
703
705
|
### Frontend
|
|
704
706
|
|
|
705
|
-
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
modal/collapse/tabs/dropdown/toast components.
|
|
707
|
+
- **HTMX** (~14KB) — AJAX loading, SSE, WebSocket, form submission
|
|
708
|
+
- **Alpine.js** (~15KB) — state management, DOM binding, UI components
|
|
709
|
+
- **weifuwu-ui** (~2KB) — Alpine stores for theme/i18n/flash/toast
|
|
709
710
|
|
|
710
711
|
Zero build tools. Zero frontend framework compilation.
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// cli.ts
|
|
4
|
-
import { mkdir, writeFile
|
|
4
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { execSync } from "node:child_process";
|
|
7
7
|
import { join, dirname, resolve } from "node:path";
|
|
@@ -28,13 +28,10 @@ async function cmdInit(name, opts) {
|
|
|
28
28
|
process.exit(1);
|
|
29
29
|
}
|
|
30
30
|
const pkg = await readPkg();
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} else {
|
|
34
|
-
await generateFull(targetDir, name, pkg.version, opts.skipInstall);
|
|
35
|
-
}
|
|
31
|
+
const typesNodeVersion = pkg.devDependencies?.["@types/node"] || "^22";
|
|
32
|
+
await generateMinimal(targetDir, name, pkg.version, typesNodeVersion, opts.skipInstall);
|
|
36
33
|
}
|
|
37
|
-
async function generateMinimal(targetDir, name, version, skipInstall) {
|
|
34
|
+
async function generateMinimal(targetDir, name, version, typesNodeVersion, skipInstall) {
|
|
38
35
|
await mkdir(targetDir, { recursive: true });
|
|
39
36
|
await writeFile(
|
|
40
37
|
join(targetDir, "app.ts"),
|
|
@@ -60,22 +57,11 @@ async function generateMinimal(targetDir, name, version, skipInstall) {
|
|
|
60
57
|
``
|
|
61
58
|
].join("\n")
|
|
62
59
|
);
|
|
63
|
-
await writePackageJson(targetDir, name, version, {});
|
|
60
|
+
await writePackageJson(targetDir, name, version, typesNodeVersion, {});
|
|
64
61
|
await writeCommonFiles(targetDir);
|
|
65
62
|
await finishInit(targetDir, skipInstall);
|
|
66
63
|
}
|
|
67
|
-
async function
|
|
68
|
-
const templateDir = existsSync(join(__dirname, "cli", "template")) ? join(__dirname, "cli", "template") : join(__dirname, "template");
|
|
69
|
-
await cp(templateDir, targetDir, { recursive: true });
|
|
70
|
-
const pkgPath = join(targetDir, "package.json");
|
|
71
|
-
const pkgContent = await readFile(pkgPath, "utf-8");
|
|
72
|
-
await writeFile(
|
|
73
|
-
pkgPath,
|
|
74
|
-
pkgContent.replace("__PROJECT_NAME__", name).replace("__VERSION__", version)
|
|
75
|
-
);
|
|
76
|
-
await finishInit(targetDir, skipInstall);
|
|
77
|
-
}
|
|
78
|
-
async function writePackageJson(targetDir, name, version, extra) {
|
|
64
|
+
async function writePackageJson(targetDir, name, version, typesNodeVersion, _extra) {
|
|
79
65
|
const pkg = {
|
|
80
66
|
name,
|
|
81
67
|
type: "module",
|
|
@@ -83,7 +69,12 @@ async function writePackageJson(targetDir, name, version, extra) {
|
|
|
83
69
|
dev: "node --watch index.ts",
|
|
84
70
|
start: "node index.ts"
|
|
85
71
|
},
|
|
86
|
-
|
|
72
|
+
dependencies: {
|
|
73
|
+
weifuwu: "^" + version
|
|
74
|
+
},
|
|
75
|
+
devDependencies: {
|
|
76
|
+
"@types/node": typesNodeVersion
|
|
77
|
+
}
|
|
87
78
|
};
|
|
88
79
|
await writeFile(join(targetDir, "package.json"), JSON.stringify(pkg, null, 2) + "\n");
|
|
89
80
|
}
|
|
@@ -107,8 +98,7 @@ var HELP = `
|
|
|
107
98
|
weifuwu \u2014 Web-standard HTTP microframework for Node.js
|
|
108
99
|
|
|
109
100
|
Usage:
|
|
110
|
-
npx weifuwu init <name> Create a new project
|
|
111
|
-
npx weifuwu init <name> --minimal Create a minimal API-only project
|
|
101
|
+
npx weifuwu init <name> Create a new project
|
|
112
102
|
npx weifuwu init <name> --skip-install Skip npm install
|
|
113
103
|
npx weifuwu version Print version
|
|
114
104
|
`;
|
|
@@ -118,18 +108,17 @@ if (cmd === "version" || cmd === "-v" || cmd === "--version") {
|
|
|
118
108
|
const { values, positionals } = parseArgs({
|
|
119
109
|
args: process.argv.slice(3),
|
|
120
110
|
options: {
|
|
121
|
-
"skip-install": { type: "boolean" }
|
|
122
|
-
minimal: { type: "boolean" }
|
|
111
|
+
"skip-install": { type: "boolean" }
|
|
123
112
|
},
|
|
124
113
|
strict: false,
|
|
125
114
|
allowPositionals: true
|
|
126
115
|
});
|
|
127
116
|
const name = positionals[0];
|
|
128
117
|
if (!name) {
|
|
129
|
-
console.error("Usage: npx weifuwu init <name> [--skip-install]
|
|
118
|
+
console.error("Usage: npx weifuwu init <name> [--skip-install]");
|
|
130
119
|
process.exit(1);
|
|
131
120
|
}
|
|
132
|
-
cmdInit(name, { skipInstall: !!values["skip-install"]
|
|
121
|
+
cmdInit(name, { skipInstall: !!values["skip-install"] }).catch(
|
|
133
122
|
console.error
|
|
134
123
|
);
|
|
135
124
|
} else {
|
package/dist/core/router.d.ts
CHANGED
|
@@ -2,6 +2,22 @@ import type { WebSocket, Context, Handler, Middleware, ErrorHandler } from '../t
|
|
|
2
2
|
import { type IncomingMessage } from 'node:http';
|
|
3
3
|
import type { Duplex } from 'node:stream';
|
|
4
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
|
+
}
|
|
5
21
|
export type WebSocketHandler = {
|
|
6
22
|
open?: (ws: WebSocket, ctx: Context) => void | Promise<void>;
|
|
7
23
|
message?: (ws: WebSocket, ctx: Context, data: string | Buffer) => void | Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { Context, Handler, Middleware, ErrorHandler } from './types.ts';
|
|
1
|
+
export type { Context, Handler, Middleware, ErrorHandler, WsContext } from './types.ts';
|
|
2
2
|
export { HttpError } from './types.ts';
|
|
3
3
|
export { currentTraceId, currentTrace, runWithTrace, traceElapsed, trace } from './core/trace.ts';
|
|
4
4
|
export type { TraceContext, TraceInjected, TraceOptions } from './core/trace.ts';
|
|
@@ -49,21 +49,3 @@ export { queue } from './queue/index.ts';
|
|
|
49
49
|
export type { QueueOptions, QueueJob, Queue, QueueInjected } from './queue/types.ts';
|
|
50
50
|
export { health } from './middleware/health.ts';
|
|
51
51
|
export type { HealthOptions } from './middleware/health.ts';
|
|
52
|
-
export { theme } from './middleware/theme.ts';
|
|
53
|
-
export type { ThemeOptions, ThemeInjected } from './middleware/theme.ts';
|
|
54
|
-
export { i18n } from './middleware/i18n.ts';
|
|
55
|
-
export type { I18nOptions, I18nInjected } from './middleware/i18n.ts';
|
|
56
|
-
export { flash } from './middleware/flash.ts';
|
|
57
|
-
export type { FlashOptions, FlashInjected, FlashModule } from './middleware/flash.ts';
|
|
58
|
-
export { csrf } from './middleware/csrf.ts';
|
|
59
|
-
export type { CsrfOptions, CsrfInjected, CsrfModule } from './middleware/csrf.ts';
|
|
60
|
-
export { html, raw } from './ssr/html.ts';
|
|
61
|
-
export type { RawString } from './ssr/html.ts';
|
|
62
|
-
export { layout } from './ssr/layout.ts';
|
|
63
|
-
export { view } from './ssr/view.ts';
|
|
64
|
-
export type { ViewOptions } from './ssr/view.ts';
|
|
65
|
-
export { loadModule, clearModuleCache } from './ssr/compile.ts';
|
|
66
|
-
export { cssContext, cssRouter, clearCSSCache } from './ssr/css.ts';
|
|
67
|
-
export type { CssAsset } from './ssr/css.ts';
|
|
68
|
-
export { assetRouter, assetScripts } from './ssr/assets.ts';
|
|
69
|
-
export { wfuwAssets, wfuwVersion } from './ssr/ui/assets.ts';
|