weifuwu 0.24.1 → 0.24.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/README.md +818 -712
- package/cli/template/app.ts +5 -1
- package/cli/template/index.ts +4 -1
- package/cli/template/locales/en.json +6 -1
- package/cli/template/locales/zh-CN.json +6 -1
- package/cli/template/locales/zh-TW.json +6 -1
- package/cli/template/locales/zh.json +6 -1
- package/cli/template/ui/app/globals.css +1 -1
- package/cli/template/ui/app/page.tsx +55 -16
- package/cli.ts +148 -104
- package/dist/agent/rest.d.ts +1 -1
- package/dist/agent/run.d.ts +2 -2
- package/dist/ai/workflow.d.ts +1 -1
- package/dist/ai-sdk.d.ts +1 -1
- package/dist/cli.js +135 -97
- package/dist/cookie.d.ts +24 -0
- package/dist/fts.d.ts +5 -5
- package/dist/iii/index.d.ts +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +787 -346
- package/dist/live.d.ts +2 -3
- package/dist/logdb/rest.d.ts +1 -1
- package/dist/mailer.d.ts +1 -1
- package/dist/messager/agent.d.ts +2 -2
- package/dist/messager/rest.d.ts +3 -3
- package/dist/messager/ws.d.ts +3 -3
- package/dist/opencode/index.d.ts +1 -1
- package/dist/opencode/permissions.d.ts +1 -1
- package/dist/opencode/run.d.ts +1 -1
- package/dist/opencode/session.d.ts +9 -9
- package/dist/opencode/tools/web.d.ts +1 -1
- package/dist/opencode/ws.d.ts +1 -2
- package/dist/permissions.d.ts +2 -2
- package/dist/postgres/module.d.ts +3 -3
- package/dist/postgres/schema/index.d.ts +1 -1
- package/dist/postgres/schema/table.d.ts +22 -20
- package/dist/postgres/types.d.ts +4 -4
- package/dist/queue/types.d.ts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.js +135 -90
- package/dist/router.d.ts +10 -10
- package/dist/session.d.ts +1 -2
- package/dist/tenant/graphql.d.ts +2 -2
- package/dist/tenant/index.d.ts +1 -1
- package/dist/tenant/rest.d.ts +2 -2
- package/dist/test-utils.d.ts +3 -3
- package/dist/user/index.d.ts +1 -1
- package/dist/user/oauth-login.d.ts +2 -2
- package/dist/vendor.d.ts +4 -0
- package/opencode/ui/app/globals.css +1 -1
- package/opencode/ui/app/layout.tsx +2 -3
- package/opencode/ui/app/page.tsx +302 -73
- package/package.json +26 -3
- package/cli/template/.weifuwu/ssr/2e3a7e60.js +0 -112
package/cli/template/app.ts
CHANGED
|
@@ -15,4 +15,8 @@ app.use(async (req, ctx, next) => {
|
|
|
15
15
|
return next(req, ctx)
|
|
16
16
|
})
|
|
17
17
|
app.get('/api/ping', () => Response.json({ pong: true, time: new Date().toISOString() }))
|
|
18
|
-
app.ws('/ws/echo', {
|
|
18
|
+
app.ws('/ws/echo', {
|
|
19
|
+
message(ws, _ctx, data) {
|
|
20
|
+
ws.send(`echo: ${data}`)
|
|
21
|
+
},
|
|
22
|
+
})
|
package/cli/template/index.ts
CHANGED
|
@@ -4,4 +4,7 @@ import { app } from './app.ts'
|
|
|
4
4
|
loadEnv()
|
|
5
5
|
const port = Number(process.env.PORT) || 3000
|
|
6
6
|
const srv = serve(app.handler(), { port, websocket: app.websocketHandler(), shutdown: false })
|
|
7
|
-
process.on('SIGINT', () => {
|
|
7
|
+
process.on('SIGINT', () => {
|
|
8
|
+
srv.stop()
|
|
9
|
+
process.exit(0)
|
|
10
|
+
})
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
"nav": { "home": "Home", "docs": "Docs", "api": "API" },
|
|
3
3
|
"hero": { "title": "Build Faster", "subtitle": "A modern web framework for Node.js" },
|
|
4
4
|
"cta": { "start": "Get Started", "learn": "Learn More" },
|
|
5
|
-
"demo": {
|
|
5
|
+
"demo": {
|
|
6
|
+
"title": "WebSocket Demo",
|
|
7
|
+
"placeholder": "Type a message...",
|
|
8
|
+
"send": "Send",
|
|
9
|
+
"echo": "Echo"
|
|
10
|
+
},
|
|
6
11
|
"ws": { "connected": "Connected", "connecting": "Connecting...", "disconnected": "Disconnected" },
|
|
7
12
|
"footer": { "privacy": "Privacy", "terms": "Terms" }
|
|
8
13
|
}
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
"nav": { "home": "首页", "docs": "文档", "api": "API" },
|
|
3
3
|
"hero": { "title": "更快地构建", "subtitle": "一个现代的 Node.js Web 框架" },
|
|
4
4
|
"cta": { "start": "开始使用", "learn": "了解更多" },
|
|
5
|
-
"demo": {
|
|
5
|
+
"demo": {
|
|
6
|
+
"title": "WebSocket 演示",
|
|
7
|
+
"placeholder": "输入消息...",
|
|
8
|
+
"send": "发送",
|
|
9
|
+
"echo": "回声"
|
|
10
|
+
},
|
|
6
11
|
"ws": { "connected": "已连接", "connecting": "连接中...", "disconnected": "未连接" },
|
|
7
12
|
"footer": { "privacy": "隐私", "terms": "条款" }
|
|
8
13
|
}
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
"nav": { "home": "首頁", "docs": "文件", "api": "API" },
|
|
3
3
|
"hero": { "title": "更快構建", "subtitle": "一個現代的 Node.js Web 框架" },
|
|
4
4
|
"cta": { "start": "開始使用", "learn": "了解更多" },
|
|
5
|
-
"demo": {
|
|
5
|
+
"demo": {
|
|
6
|
+
"title": "WebSocket 演示",
|
|
7
|
+
"placeholder": "輸入訊息...",
|
|
8
|
+
"send": "發送",
|
|
9
|
+
"echo": "回聲"
|
|
10
|
+
},
|
|
6
11
|
"ws": { "connected": "已連線", "connecting": "連線中...", "disconnected": "未連線" },
|
|
7
12
|
"footer": { "privacy": "隱私", "terms": "條款" }
|
|
8
13
|
}
|
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
"nav": { "home": "首页", "docs": "文档", "api": "API" },
|
|
3
3
|
"hero": { "title": "更快地构建", "subtitle": "一个现代的 Node.js Web 框架" },
|
|
4
4
|
"cta": { "start": "开始使用", "learn": "了解更多" },
|
|
5
|
-
"demo": {
|
|
5
|
+
"demo": {
|
|
6
|
+
"title": "WebSocket 演示",
|
|
7
|
+
"placeholder": "输入消息...",
|
|
8
|
+
"send": "发送",
|
|
9
|
+
"echo": "回声"
|
|
10
|
+
},
|
|
6
11
|
"ws": { "connected": "已连接", "connecting": "连接中...", "disconnected": "未连接" },
|
|
7
12
|
"footer": { "privacy": "隐私", "terms": "条款" }
|
|
8
13
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
@import
|
|
1
|
+
@import 'tailwindcss';
|
|
2
2
|
@variant dark (&:where([data-theme="dark"] *));
|
|
@@ -6,12 +6,11 @@ export default function Home() {
|
|
|
6
6
|
const [input, setInput] = useState('')
|
|
7
7
|
const { send, lastMessage, readyState } = useWebsocket('/ws/echo')
|
|
8
8
|
const { locale, t, setLocale } = useLocale()
|
|
9
|
-
const {
|
|
9
|
+
const { resolvedTheme, setTheme } = useTheme()
|
|
10
10
|
const ld = useLoaderData<{ features?: { title: string; desc: string }[] }>()
|
|
11
11
|
|
|
12
12
|
return (
|
|
13
13
|
<div className="min-h-screen bg-white dark:bg-gray-950 text-gray-900 dark:text-gray-100">
|
|
14
|
-
|
|
15
14
|
{/* Navbar */}
|
|
16
15
|
<header className="border-b dark:border-gray-800">
|
|
17
16
|
<div className="max-w-5xl mx-auto flex items-center justify-between h-14 px-4">
|
|
@@ -22,12 +21,16 @@ export default function Home() {
|
|
|
22
21
|
<span className="hover:text-blue-600 transition cursor-pointer">{t('nav.api')}</span>
|
|
23
22
|
</nav>
|
|
24
23
|
<div className="flex items-center gap-2 text-sm">
|
|
25
|
-
<button
|
|
26
|
-
|
|
24
|
+
<button
|
|
25
|
+
onClick={() => setLocale(locale === 'en' ? 'zh-CN' : 'en')}
|
|
26
|
+
className="px-2 py-1 rounded border dark:border-gray-700 hover:bg-gray-100 dark:hover:bg-gray-800 transition"
|
|
27
|
+
>
|
|
27
28
|
{locale === 'en' ? '中文' : 'EN'}
|
|
28
29
|
</button>
|
|
29
|
-
<button
|
|
30
|
-
|
|
30
|
+
<button
|
|
31
|
+
onClick={() => setTheme(resolvedTheme === 'light' ? 'dark' : 'light')}
|
|
32
|
+
className="px-2 py-1 rounded border dark:border-gray-700 hover:bg-gray-100 dark:hover:bg-gray-800 transition"
|
|
33
|
+
>
|
|
31
34
|
{resolvedTheme === 'light' ? '🌙' : '☀️'}
|
|
32
35
|
</button>
|
|
33
36
|
</div>
|
|
@@ -40,8 +43,18 @@ export default function Home() {
|
|
|
40
43
|
<p className="text-xl text-gray-500 dark:text-gray-400 mb-8">{t('hero.subtitle')}</p>
|
|
41
44
|
<Greeting name="Weifuwu" />
|
|
42
45
|
<div className="flex justify-center gap-4 mt-8">
|
|
43
|
-
<a
|
|
44
|
-
|
|
46
|
+
<a
|
|
47
|
+
href="#"
|
|
48
|
+
className="px-6 py-2.5 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition font-medium"
|
|
49
|
+
>
|
|
50
|
+
{t('cta.start')}
|
|
51
|
+
</a>
|
|
52
|
+
<a
|
|
53
|
+
href="#"
|
|
54
|
+
className="px-6 py-2.5 border dark:border-gray-700 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition font-medium"
|
|
55
|
+
>
|
|
56
|
+
{t('cta.learn')}
|
|
57
|
+
</a>
|
|
45
58
|
</div>
|
|
46
59
|
</section>
|
|
47
60
|
|
|
@@ -49,7 +62,10 @@ export default function Home() {
|
|
|
49
62
|
{ld.features && (
|
|
50
63
|
<section className="max-w-4xl mx-auto grid grid-cols-1 md:grid-cols-3 gap-6 px-4 pb-20">
|
|
51
64
|
{ld.features.map((f, i) => (
|
|
52
|
-
<div
|
|
65
|
+
<div
|
|
66
|
+
key={i}
|
|
67
|
+
className="p-6 rounded-xl border dark:border-gray-800 bg-gray-50 dark:bg-gray-900"
|
|
68
|
+
>
|
|
53
69
|
<h3 className="font-semibold mb-2">{f.title}</h3>
|
|
54
70
|
<p className="text-sm text-gray-500 dark:text-gray-400">{f.desc}</p>
|
|
55
71
|
</div>
|
|
@@ -62,17 +78,40 @@ export default function Home() {
|
|
|
62
78
|
<div className="border dark:border-gray-800 rounded-xl p-6 bg-gray-50 dark:bg-gray-900 space-y-4">
|
|
63
79
|
<h2 className="font-semibold">{t('demo.title')}</h2>
|
|
64
80
|
<p className="text-sm text-gray-500 dark:text-gray-400">
|
|
65
|
-
{readyState === 1
|
|
81
|
+
{readyState === 1
|
|
82
|
+
? t('ws.connected')
|
|
83
|
+
: readyState === 0
|
|
84
|
+
? t('ws.connecting')
|
|
85
|
+
: t('ws.disconnected')}
|
|
66
86
|
</p>
|
|
67
87
|
<div className="flex gap-2">
|
|
68
|
-
<input
|
|
69
|
-
|
|
88
|
+
<input
|
|
89
|
+
value={input}
|
|
90
|
+
onChange={(e) => setInput(e.target.value)}
|
|
91
|
+
onKeyDown={(e) => {
|
|
92
|
+
if (e.key === 'Enter') {
|
|
93
|
+
send(input)
|
|
94
|
+
setInput('')
|
|
95
|
+
}
|
|
96
|
+
}}
|
|
70
97
|
placeholder={t('demo.placeholder')}
|
|
71
|
-
className="flex-1 border dark:border-gray-700 rounded px-3 py-2 text-sm bg-white dark:bg-gray-950 outline-none focus:border-blue-500 transition"
|
|
72
|
-
|
|
73
|
-
|
|
98
|
+
className="flex-1 border dark:border-gray-700 rounded px-3 py-2 text-sm bg-white dark:bg-gray-950 outline-none focus:border-blue-500 transition"
|
|
99
|
+
/>
|
|
100
|
+
<button
|
|
101
|
+
onClick={() => {
|
|
102
|
+
send(input)
|
|
103
|
+
setInput('')
|
|
104
|
+
}}
|
|
105
|
+
className="px-4 py-2 bg-blue-600 text-white rounded text-sm hover:bg-blue-700 transition font-medium"
|
|
106
|
+
>
|
|
107
|
+
{t('demo.send')}
|
|
108
|
+
</button>
|
|
74
109
|
</div>
|
|
75
|
-
{lastMessage &&
|
|
110
|
+
{lastMessage && (
|
|
111
|
+
<p className="text-sm text-gray-600 dark:text-gray-400">
|
|
112
|
+
<span className="font-medium">{t('demo.echo')}:</span> {lastMessage}
|
|
113
|
+
</p>
|
|
114
|
+
)}
|
|
76
115
|
</div>
|
|
77
116
|
</section>
|
|
78
117
|
|
package/cli.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
4
|
import { mkdir, writeFile, copyFile, readFile, cp } from 'node:fs/promises'
|
|
3
5
|
import { existsSync, readdirSync } from 'node:fs'
|
|
4
6
|
import { execSync } from 'node:child_process'
|
|
@@ -33,8 +35,14 @@ async function cmdInit(name: string, opts: { minimal?: boolean; skipInstall?: bo
|
|
|
33
35
|
const targetDir = resolve(process.cwd(), name)
|
|
34
36
|
const pkg = await readPkg()
|
|
35
37
|
const v = pkg.version
|
|
38
|
+
// Map of known type package versions that align with our runtime deps
|
|
39
|
+
const typeVersions: Record<string, string> = {
|
|
40
|
+
'@types/react': '^19',
|
|
41
|
+
'@types/react-dom': '^19',
|
|
42
|
+
'@types/node': '^22',
|
|
43
|
+
}
|
|
36
44
|
const depVer = (depName: string) =>
|
|
37
|
-
`^${(pkg.devDependencies?.[depName] || '0.0.0').replace(/^\^/, '')}`
|
|
45
|
+
typeVersions[depName] || `^${(pkg.devDependencies?.[depName] || '0.0.0').replace(/^\^/, '')}`
|
|
38
46
|
|
|
39
47
|
await mkdir(targetDir, { recursive: true })
|
|
40
48
|
|
|
@@ -56,36 +64,45 @@ async function cmdInit(name: string, opts: { minimal?: boolean; skipInstall?: bo
|
|
|
56
64
|
const uiPage = join(targetDir, 'ui', 'app', 'page.tsx')
|
|
57
65
|
if (existsSync(uiPage)) {
|
|
58
66
|
let content = await readFile(uiPage, 'utf-8')
|
|
59
|
-
content = content
|
|
60
|
-
.replace(/from '\.\.\/\.\.\/\.\.\/\.\.\/react\.ts'/g, "from 'weifuwu/react'")
|
|
67
|
+
content = content.replace(/from '\.\.\/\.\.\/\.\.\/\.\.\/react\.ts'/g, "from 'weifuwu/react'")
|
|
61
68
|
await writeFile(uiPage, content)
|
|
62
69
|
}
|
|
63
70
|
|
|
64
71
|
// Minimal mode: strip SSR/i18n/theme, keep only HTTP core
|
|
65
72
|
if (opts.minimal) {
|
|
66
|
-
try {
|
|
67
|
-
|
|
73
|
+
try {
|
|
74
|
+
await rmrf(join(targetDir, 'ui'))
|
|
75
|
+
} catch {}
|
|
76
|
+
try {
|
|
77
|
+
await rmrf(join(targetDir, 'locales'))
|
|
78
|
+
} catch {}
|
|
68
79
|
|
|
69
80
|
// Write minimal app.ts
|
|
70
|
-
await writeFile(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
await writeFile(
|
|
82
|
+
join(targetDir, 'app.ts'),
|
|
83
|
+
[
|
|
84
|
+
`import { Router } from 'weifuwu'`,
|
|
85
|
+
``,
|
|
86
|
+
`export const app = new Router()`,
|
|
87
|
+
``,
|
|
88
|
+
`app.get('/', () => new Response('Hello from ${name}!'))`,
|
|
89
|
+
`app.get('/api/ping', () => Response.json({ pong: true, time: new Date().toISOString() }))`,
|
|
90
|
+
``,
|
|
91
|
+
].join('\n'),
|
|
92
|
+
)
|
|
79
93
|
|
|
80
94
|
// Write minimal index.ts
|
|
81
|
-
await writeFile(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
95
|
+
await writeFile(
|
|
96
|
+
join(targetDir, 'index.ts'),
|
|
97
|
+
[
|
|
98
|
+
`import { serve } from 'weifuwu'`,
|
|
99
|
+
`import { app } from './app.ts'`,
|
|
100
|
+
``,
|
|
101
|
+
`const port = Number(process.env.PORT) || 3000`,
|
|
102
|
+
`serve(app.handler(), { port })`,
|
|
103
|
+
``,
|
|
104
|
+
].join('\n'),
|
|
105
|
+
)
|
|
89
106
|
}
|
|
90
107
|
|
|
91
108
|
// Write package.json
|
|
@@ -100,64 +117,81 @@ async function cmdInit(name: string, opts: { minimal?: boolean; skipInstall?: bo
|
|
|
100
117
|
}
|
|
101
118
|
devDeps['@types/node'] = depVer('@types/node')
|
|
102
119
|
|
|
103
|
-
await writeFile(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
120
|
+
await writeFile(
|
|
121
|
+
join(targetDir, 'package.json'),
|
|
122
|
+
JSON.stringify(
|
|
123
|
+
{
|
|
124
|
+
name,
|
|
125
|
+
type: 'module',
|
|
126
|
+
scripts: {
|
|
127
|
+
dev: 'NODE_ENV=development node --watch index.ts',
|
|
128
|
+
start: 'node index.ts',
|
|
129
|
+
},
|
|
130
|
+
dependencies: deps,
|
|
131
|
+
devDependencies: devDeps,
|
|
132
|
+
},
|
|
133
|
+
null,
|
|
134
|
+
2,
|
|
135
|
+
) + '\n',
|
|
136
|
+
)
|
|
113
137
|
|
|
114
138
|
// Write tsconfig.json
|
|
115
139
|
const include = opts.minimal ? ['*.ts'] : ['*.ts', 'ui/**/*.ts', 'ui/**/*.tsx']
|
|
116
|
-
await writeFile(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
140
|
+
await writeFile(
|
|
141
|
+
join(targetDir, 'tsconfig.json'),
|
|
142
|
+
JSON.stringify(
|
|
143
|
+
{
|
|
144
|
+
compilerOptions: {
|
|
145
|
+
target: 'ESNext',
|
|
146
|
+
module: 'NodeNext',
|
|
147
|
+
moduleResolution: 'NodeNext',
|
|
148
|
+
strict: true,
|
|
149
|
+
jsx: 'react-jsx',
|
|
150
|
+
skipLibCheck: true,
|
|
151
|
+
noEmit: true,
|
|
152
|
+
allowImportingTsExtensions: true,
|
|
153
|
+
},
|
|
154
|
+
include,
|
|
155
|
+
},
|
|
156
|
+
null,
|
|
157
|
+
2,
|
|
158
|
+
) + '\n',
|
|
159
|
+
)
|
|
129
160
|
|
|
130
161
|
await writeFile(join(targetDir, '.gitignore'), 'node_modules\ndist\n.env\n.sessions\n.weifuwu\n')
|
|
131
162
|
await writeFile(join(targetDir, '.env'), 'PORT=3000\n')
|
|
132
|
-
await writeFile(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
163
|
+
await writeFile(
|
|
164
|
+
join(targetDir, 'AGENTS.md'),
|
|
165
|
+
[
|
|
166
|
+
`# ${name}`,
|
|
167
|
+
'',
|
|
168
|
+
`This is a [weifuwu](https://weifuwu.io) application — pure Node.js, no build step.`,
|
|
169
|
+
'',
|
|
170
|
+
'## Commands',
|
|
171
|
+
'',
|
|
172
|
+
'- `npm run dev` — start dev server with hot reload',
|
|
173
|
+
'- `npm start` — start production server',
|
|
174
|
+
'- `npm install` — install dependencies',
|
|
175
|
+
'- `npx tsc --noEmit` — type-check',
|
|
176
|
+
'',
|
|
177
|
+
'## API Reference',
|
|
178
|
+
'',
|
|
179
|
+
'See `node_modules/weifuwu/README.md` for the full documentation.',
|
|
180
|
+
'',
|
|
181
|
+
].join('\n'),
|
|
182
|
+
)
|
|
149
183
|
|
|
150
184
|
if (!opts.skipInstall) {
|
|
151
185
|
console.log('\nInstalling dependencies...')
|
|
152
186
|
execSync('npm install', { cwd: targetDir, stdio: 'inherit' })
|
|
153
187
|
}
|
|
154
|
-
console.log(
|
|
188
|
+
console.log(
|
|
189
|
+
`\n✅ Created ${name}/ — cd ${name} && ${opts.skipInstall ? 'npm install && ' : ''}npm run dev`,
|
|
190
|
+
)
|
|
155
191
|
}
|
|
156
192
|
|
|
157
193
|
async function cmdDev() {
|
|
158
|
-
const entry = existsSync('index.ts') ? 'index.ts'
|
|
159
|
-
: existsSync('app.ts') ? 'app.ts'
|
|
160
|
-
: null
|
|
194
|
+
const entry = existsSync('index.ts') ? 'index.ts' : existsSync('app.ts') ? 'app.ts' : null
|
|
161
195
|
|
|
162
196
|
if (!entry) {
|
|
163
197
|
console.error('No index.ts or app.ts found in current directory.')
|
|
@@ -182,44 +216,50 @@ async function cmdGenerate(type: string, name: string) {
|
|
|
182
216
|
}
|
|
183
217
|
|
|
184
218
|
await mkdir(dir, { recursive: true })
|
|
185
|
-
await writeFile(
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
219
|
+
await writeFile(
|
|
220
|
+
join(dir, 'index.ts'),
|
|
221
|
+
[
|
|
222
|
+
`import type { Middleware } from 'weifuwu'`,
|
|
223
|
+
``,
|
|
224
|
+
`export interface ${capitalize(name)}Options {`,
|
|
225
|
+
` // Add your options here`,
|
|
226
|
+
`}`,
|
|
227
|
+
``,
|
|
228
|
+
`export function ${name}(opts?: ${capitalize(name)}Options): Middleware {`,
|
|
229
|
+
` return async (req, ctx, next) => {`,
|
|
230
|
+
` // Your middleware logic here`,
|
|
231
|
+
` return next(req, ctx)`,
|
|
232
|
+
` }`,
|
|
233
|
+
`}`,
|
|
234
|
+
``,
|
|
235
|
+
].join('\n'),
|
|
236
|
+
)
|
|
200
237
|
|
|
201
238
|
await mkdir(join(dir, '..', 'test'), { recursive: true })
|
|
202
|
-
await writeFile(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
239
|
+
await writeFile(
|
|
240
|
+
join(dir, '..', 'test', `${name}.test.ts`),
|
|
241
|
+
[
|
|
242
|
+
`import { describe, it } from 'node:test'`,
|
|
243
|
+
`import assert from 'node:assert/strict'`,
|
|
244
|
+
`import { ${name} } from '../${name}/index.ts'`,
|
|
245
|
+
`import { Router } from 'weifuwu'`,
|
|
246
|
+
``,
|
|
247
|
+
`describe('${name}', () => {`,
|
|
248
|
+
` it('works as middleware', async () => {`,
|
|
249
|
+
` const app = new Router()`,
|
|
250
|
+
` app.use(${name}())`,
|
|
251
|
+
` app.get('/', () => new Response('ok'))`,
|
|
252
|
+
``,
|
|
253
|
+
` const res = await app.handler()(`,
|
|
254
|
+
` new Request('http://localhost/'),`,
|
|
255
|
+
` { params: {}, query: {} } as any,`,
|
|
256
|
+
` )`,
|
|
257
|
+
` assert.equal(res.status, 200)`,
|
|
258
|
+
` })`,
|
|
259
|
+
`})`,
|
|
260
|
+
``,
|
|
261
|
+
].join('\n'),
|
|
262
|
+
)
|
|
223
263
|
|
|
224
264
|
console.log(`✅ Created module ${name}/ with index.ts and test/${name}.test.ts`)
|
|
225
265
|
}
|
|
@@ -243,7 +283,9 @@ async function rmrf(dir: string) {
|
|
|
243
283
|
}
|
|
244
284
|
const { rmdir } = await import('node:fs/promises')
|
|
245
285
|
await rmdir(dir)
|
|
246
|
-
} catch {
|
|
286
|
+
} catch {
|
|
287
|
+
/* ignore */
|
|
288
|
+
}
|
|
247
289
|
}
|
|
248
290
|
|
|
249
291
|
import { parseArgs } from 'node:util'
|
|
@@ -283,7 +325,9 @@ if (cmd === 'version' || cmd === '-v' || cmd === '--version') {
|
|
|
283
325
|
console.error('Usage: npx weifuwu init <name> [--minimal] [--skip-install]')
|
|
284
326
|
process.exit(1)
|
|
285
327
|
}
|
|
286
|
-
cmdInit(name, { minimal: !!values.minimal, skipInstall: !!values['skip-install'] }).catch(
|
|
328
|
+
cmdInit(name, { minimal: !!values.minimal, skipInstall: !!values['skip-install'] }).catch(
|
|
329
|
+
console.error,
|
|
330
|
+
)
|
|
287
331
|
} else if (cmd === 'dev') {
|
|
288
332
|
cmdDev()
|
|
289
333
|
} else if (cmd === 'generate' || cmd === 'g') {
|
package/dist/agent/rest.d.ts
CHANGED
package/dist/agent/run.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { type Tool } from 'ai';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SqlClient } from '../vendor.ts';
|
|
3
3
|
import type { BoundTable } from '../postgres/schema/index.ts';
|
|
4
4
|
import type { AIProvider } from '../ai/provider.ts';
|
|
5
5
|
import type { RunParams, RunResult, KnowledgeDoc } from './types.ts';
|
|
6
6
|
interface RunnerDeps {
|
|
7
|
-
sql:
|
|
7
|
+
sql: SqlClient;
|
|
8
8
|
agents: BoundTable<any>;
|
|
9
9
|
runs: BoundTable<any>;
|
|
10
10
|
knowledge: BoundTable<any>;
|
package/dist/ai/workflow.d.ts
CHANGED
package/dist/ai-sdk.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { streamText, generateText, generateObject, streamObject, tool, embed, embedMany, smoothStream, } from 'ai';
|
|
2
|
-
export { openai, createOpenAI
|
|
2
|
+
export { openai, createOpenAI } from '@ai-sdk/openai';
|