@weifuwujs/weifuwu 0.9.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.
- package/README.md +605 -0
- package/dist/app.d.ts +122 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +484 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +506 -0
- package/dist/cli.js.map +1 -0
- package/dist/compose.d.ts +12 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +29 -0
- package/dist/compose.js.map +1 -0
- package/dist/env.d.ts +12 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +46 -0
- package/dist/env.js.map +1 -0
- package/dist/group.d.ts +32 -0
- package/dist/group.d.ts.map +1 -0
- package/dist/group.js +66 -0
- package/dist/group.js.map +1 -0
- package/dist/helpers.d.ts +37 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +101 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/ioredis.d.ts +16 -0
- package/dist/ioredis.d.ts.map +1 -0
- package/dist/ioredis.js +42 -0
- package/dist/ioredis.js.map +1 -0
- package/dist/methods.d.ts +3 -0
- package/dist/methods.d.ts.map +1 -0
- package/dist/methods.js +10 -0
- package/dist/methods.js.map +1 -0
- package/dist/middleware/cors.d.ts +24 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/cors.js +77 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/index.d.ts +7 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +4 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/logger.d.ts +27 -0
- package/dist/middleware/logger.d.ts.map +1 -0
- package/dist/middleware/logger.js +48 -0
- package/dist/middleware/logger.js.map +1 -0
- package/dist/middleware/static.d.ts +27 -0
- package/dist/middleware/static.d.ts.map +1 -0
- package/dist/middleware/static.js +150 -0
- package/dist/middleware/static.js.map +1 -0
- package/dist/node.d.ts +27 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +193 -0
- package/dist/node.js.map +1 -0
- package/dist/path.d.ts +9 -0
- package/dist/path.d.ts.map +1 -0
- package/dist/path.js +31 -0
- package/dist/path.js.map +1 -0
- package/dist/postgres.d.ts +19 -0
- package/dist/postgres.d.ts.map +1 -0
- package/dist/postgres.js +27 -0
- package/dist/postgres.js.map +1 -0
- package/dist/react-router.d.ts +31 -0
- package/dist/react-router.d.ts.map +1 -0
- package/dist/react-router.js +25 -0
- package/dist/react-router.js.map +1 -0
- package/dist/resources.d.ts +35 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +54 -0
- package/dist/resources.js.map +1 -0
- package/dist/router.d.ts +30 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +122 -0
- package/dist/router.js.map +1 -0
- package/dist/types.d.ts +124 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/vite.d.ts +21 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +101 -0
- package/dist/vite.js.map +1 -0
- package/dist/websocket/accept.d.ts +22 -0
- package/dist/websocket/accept.d.ts.map +1 -0
- package/dist/websocket/accept.js +104 -0
- package/dist/websocket/accept.js.map +1 -0
- package/dist/websocket/close-code.d.ts +22 -0
- package/dist/websocket/close-code.d.ts.map +1 -0
- package/dist/websocket/close-code.js +35 -0
- package/dist/websocket/close-code.js.map +1 -0
- package/dist/websocket/connection.d.ts +71 -0
- package/dist/websocket/connection.d.ts.map +1 -0
- package/dist/websocket/connection.js +287 -0
- package/dist/websocket/connection.js.map +1 -0
- package/dist/websocket/index.d.ts +7 -0
- package/dist/websocket/index.d.ts.map +1 -0
- package/dist/websocket/index.js +4 -0
- package/dist/websocket/index.js.map +1 -0
- package/dist/websocket/types.d.ts +66 -0
- package/dist/websocket/types.d.ts.map +1 -0
- package/dist/websocket/types.js +2 -0
- package/dist/websocket/types.js.map +1 -0
- package/docs/ai.md +175 -0
- package/docs/data.md +81 -0
- package/docs/migrating.md +116 -0
- package/docs/react-router.md +187 -0
- package/docs/styling.md +69 -0
- package/package.json +144 -0
- package/templates/react-router/_gitignore +3 -0
- package/templates/react-router/app/app.css +1 -0
- package/templates/react-router/app/context.ts +4 -0
- package/templates/react-router/app/root.tsx +50 -0
- package/templates/react-router/app/routes/home.tsx +17 -0
- package/templates/react-router/app/routes.ts +3 -0
- package/templates/react-router/app/server.ts +29 -0
- package/templates/react-router/package.json +29 -0
- package/templates/react-router/react-router.config.ts +5 -0
- package/templates/react-router/tsconfig.json +19 -0
- package/templates/react-router/vite.config.ts +6 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
3
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
4
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
5
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
6
|
+
});
|
|
7
|
+
}
|
|
8
|
+
return path;
|
|
9
|
+
};
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import { loadEnvFiles } from "./env.js";
|
|
12
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, writeFileSync, writeSync, } from 'node:fs';
|
|
13
|
+
import { createServer as createHttpServer, } from 'node:http';
|
|
14
|
+
import { createRequire } from 'node:module';
|
|
15
|
+
import { basename, dirname, join, resolve, sep } from 'node:path';
|
|
16
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
17
|
+
import { serveStatic } from "./middleware/static.js";
|
|
18
|
+
import { toNodeHandler, toUpgradeHandler } from "./node.js";
|
|
19
|
+
function parseArgs(argv) {
|
|
20
|
+
const command = argv[0] ?? 'help';
|
|
21
|
+
let port;
|
|
22
|
+
let host;
|
|
23
|
+
let trustProxy;
|
|
24
|
+
let root = process.cwd();
|
|
25
|
+
const rest = [];
|
|
26
|
+
for (let index = 1; index < argv.length; index++) {
|
|
27
|
+
const arg = argv[index];
|
|
28
|
+
if (arg === '--port' || arg.startsWith('--port=')) {
|
|
29
|
+
const value = arg.includes('=') ? arg.slice(arg.indexOf('=') + 1) : argv[++index];
|
|
30
|
+
if (!value)
|
|
31
|
+
throw new Error('--port 需要提供一个值');
|
|
32
|
+
port = Number.parseInt(value, 10);
|
|
33
|
+
}
|
|
34
|
+
else if (arg === '--host' || arg.startsWith('--host=')) {
|
|
35
|
+
const value = arg.includes('=') ? arg.slice(arg.indexOf('=') + 1) : argv[++index];
|
|
36
|
+
if (!value)
|
|
37
|
+
throw new Error('--host 需要提供一个值');
|
|
38
|
+
host = value;
|
|
39
|
+
}
|
|
40
|
+
else if (arg === '--root' || arg.startsWith('--root=')) {
|
|
41
|
+
const value = arg.includes('=') ? arg.slice(arg.indexOf('=') + 1) : argv[++index];
|
|
42
|
+
if (!value)
|
|
43
|
+
throw new Error('--root 需要提供一个值');
|
|
44
|
+
root = resolve(value);
|
|
45
|
+
}
|
|
46
|
+
else if (arg === '--trust-proxy') {
|
|
47
|
+
trustProxy = true;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
rest.push(arg);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { command, port, host, root, trustProxy, rest };
|
|
54
|
+
}
|
|
55
|
+
async function runReactRouter(command, args, cwd) {
|
|
56
|
+
const require = createRequire(import.meta.url);
|
|
57
|
+
const packageJson = require.resolve('@react-router/dev/package.json');
|
|
58
|
+
const bin = join(dirname(packageJson), 'bin.cjs');
|
|
59
|
+
const child = spawn(process.execPath, [bin, command, ...args], {
|
|
60
|
+
cwd,
|
|
61
|
+
stdio: 'inherit',
|
|
62
|
+
env: process.env,
|
|
63
|
+
});
|
|
64
|
+
const code = await new Promise((resolveCode, reject) => {
|
|
65
|
+
child.once('error', reject);
|
|
66
|
+
child.once('exit', (value) => resolveCode(value ?? 0));
|
|
67
|
+
});
|
|
68
|
+
if (code !== 0)
|
|
69
|
+
process.exit(code);
|
|
70
|
+
}
|
|
71
|
+
/** dev 需要 `--conditions=development`(React/RR 的 development 导出),Node 无法运行时追加,只能 re-exec。返回 true 表示已交给子进程。 */
|
|
72
|
+
function maybeReexecDev() {
|
|
73
|
+
if (process.env.WEIFUWU_DEV_CHILD === '1')
|
|
74
|
+
return false;
|
|
75
|
+
const hasCondition = process.execArgv.includes('--conditions=development') ||
|
|
76
|
+
(process.env.NODE_OPTIONS ?? '').includes('--conditions=development');
|
|
77
|
+
if (hasCondition)
|
|
78
|
+
return false;
|
|
79
|
+
const entry = process.argv[1];
|
|
80
|
+
if (!entry)
|
|
81
|
+
return false;
|
|
82
|
+
const child = spawn(process.execPath, [
|
|
83
|
+
'--conditions=development',
|
|
84
|
+
...process.execArgv,
|
|
85
|
+
entry,
|
|
86
|
+
...process.argv.slice(2),
|
|
87
|
+
], {
|
|
88
|
+
stdio: 'inherit',
|
|
89
|
+
env: {
|
|
90
|
+
...process.env,
|
|
91
|
+
NODE_ENV: process.env.NODE_ENV ?? 'development',
|
|
92
|
+
WEIFUWU_DEV_CHILD: '1',
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
96
|
+
process.on(signal, () => child.kill(signal));
|
|
97
|
+
}
|
|
98
|
+
child.once('exit', (code, signal) => {
|
|
99
|
+
if (signal) {
|
|
100
|
+
// 转发器本身就是信号监听:先摘掉,否则 self-kill 会被自己的转发器吞掉(永不退出)
|
|
101
|
+
for (const forwarded of ['SIGINT', 'SIGTERM']) {
|
|
102
|
+
process.removeAllListeners(forwarded);
|
|
103
|
+
}
|
|
104
|
+
process.kill(process.pid, signal);
|
|
105
|
+
setTimeout(() => process.exit(128), 500).unref();
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
process.exit(code ?? 0);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
async function dev(options) {
|
|
114
|
+
process.env.NODE_ENV ??= 'development';
|
|
115
|
+
if (maybeReexecDev())
|
|
116
|
+
return;
|
|
117
|
+
// 与 start 对齐:.env 系列注入 process.env(真实环境变量优先)。
|
|
118
|
+
// 正常路径 RR/Vite 也会加载,这里保证 createServer 失败降级后仍然一致。
|
|
119
|
+
loadEnvFiles(options.root, process.env.NODE_ENV ?? 'development');
|
|
120
|
+
// RR 的 typegen watcher 在 routes.ts 非法时会产生未处理的 rejection;
|
|
121
|
+
// dev 下记录日志但不退出,保证 weifuwu 路由降级可用。
|
|
122
|
+
process.on('unhandledRejection', (reason) => {
|
|
123
|
+
console.error('[weifuwu] 未处理的异步错误(dev 保持运行):', reason);
|
|
124
|
+
});
|
|
125
|
+
const httpServer = createHttpServer();
|
|
126
|
+
const { createServer, searchForWorkspaceRoot } = await import('vite');
|
|
127
|
+
let createdVite;
|
|
128
|
+
try {
|
|
129
|
+
createdVite = await createServer({
|
|
130
|
+
root: options.root,
|
|
131
|
+
server: {
|
|
132
|
+
middlewareMode: true,
|
|
133
|
+
ws: { server: httpServer },
|
|
134
|
+
// 依赖可能被提升到项目根之外(monorepo / `file:` 依赖):Vite 的 fs.strict
|
|
135
|
+
// 默认只允许项目根,会让 `/@fs/<仓库根>/node_modules/...` 返回 403,
|
|
136
|
+
// 页面**静默失去 JS 增强**。这里把向上找到的 node_modules 显式加入白名单;
|
|
137
|
+
// `WEIFUWU_FS_ALLOW`(逗号分隔)可追加自定义路径。
|
|
138
|
+
fs: {
|
|
139
|
+
allow: [
|
|
140
|
+
options.root,
|
|
141
|
+
searchForWorkspaceRoot(options.root),
|
|
142
|
+
...hoistedModulesDirs(options.root),
|
|
143
|
+
...(process.env.WEIFUWU_FS_ALLOW?.split(',').filter(Boolean) ?? []),
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.error(`[weifuwu] Vite 初始化失败,降级为“无 HMR / 无 SSR 页面”模式:${error instanceof Error ? error.message : String(error)}`);
|
|
151
|
+
}
|
|
152
|
+
const vite = createdVite;
|
|
153
|
+
const pickApp = (module) => {
|
|
154
|
+
const app = module.default ?? module.app;
|
|
155
|
+
if (!app ||
|
|
156
|
+
typeof app !== 'object' ||
|
|
157
|
+
typeof app.fetch !== 'function') {
|
|
158
|
+
throw new Error('app/server.ts 需要默认导出一个 weifuwu App');
|
|
159
|
+
}
|
|
160
|
+
return app;
|
|
161
|
+
};
|
|
162
|
+
let nativeApp;
|
|
163
|
+
/** 从项目根向上收集实际存在的 node_modules(依赖提升场景,dev 静态白名单用) */
|
|
164
|
+
/** dev 下可由 Vite 直接服务的源文件扩展名(用于 isViteRequest 判定) */
|
|
165
|
+
const SOURCE_FILE_RE = /\.(?:[jt]sx?|m[jt]s|css|json|vue|svelte|astro|mdx)$/;
|
|
166
|
+
function hoistedModulesDirs(root) {
|
|
167
|
+
const dirs = [];
|
|
168
|
+
let current = resolve(root);
|
|
169
|
+
for (let depth = 0; depth < 8; depth += 1) {
|
|
170
|
+
const modules = join(current, 'node_modules');
|
|
171
|
+
if (existsSync(modules))
|
|
172
|
+
dirs.push(modules);
|
|
173
|
+
const parent = dirname(current);
|
|
174
|
+
if (parent === current)
|
|
175
|
+
break;
|
|
176
|
+
current = parent;
|
|
177
|
+
}
|
|
178
|
+
return dirs;
|
|
179
|
+
}
|
|
180
|
+
/** 关闭上一个 app(dev HMR 重新加载时避免资源连接泄漏);失败只记日志 */
|
|
181
|
+
const swapApp = (app) => {
|
|
182
|
+
const close = closeAppOf(currentApp);
|
|
183
|
+
if (close && currentApp !== app)
|
|
184
|
+
void close().catch((error) => console.error(error));
|
|
185
|
+
currentApp = app;
|
|
186
|
+
return app;
|
|
187
|
+
};
|
|
188
|
+
let currentApp;
|
|
189
|
+
const loadNativeApp = async () => {
|
|
190
|
+
nativeApp ??= pickApp((await import(__rewriteRelativeImportExtension(pathToFileURL(resolve(options.root, 'app/server.ts')).href))));
|
|
191
|
+
return swapApp(nativeApp);
|
|
192
|
+
};
|
|
193
|
+
let viteFailed = false;
|
|
194
|
+
const loadApp = async () => {
|
|
195
|
+
if (!vite)
|
|
196
|
+
return loadNativeApp();
|
|
197
|
+
try {
|
|
198
|
+
return swapApp(pickApp((await vite.ssrLoadModule('/app/server.ts'))));
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
if (!viteFailed) {
|
|
202
|
+
viteFailed = true;
|
|
203
|
+
console.warn(`[weifuwu] Vite 模块加载失败,降级为 Node 原生 import:${error instanceof Error ? error.message : String(error)}`);
|
|
204
|
+
}
|
|
205
|
+
return loadNativeApp();
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
const publicDir = resolve(options.root, 'public');
|
|
209
|
+
const publicStatic = existsSync(publicDir)
|
|
210
|
+
? serveStatic(publicDir, { maxAge: 0 })
|
|
211
|
+
: null;
|
|
212
|
+
const serveApp = (req, res) => {
|
|
213
|
+
void loadApp().then((app) => toNodeHandler(app, { trustProxy: options.trustProxy })(req, res), (loadError) => {
|
|
214
|
+
if (vite && loadError instanceof Error)
|
|
215
|
+
vite.ssrFixStacktrace(loadError);
|
|
216
|
+
console.error(loadError);
|
|
217
|
+
if (!res.headersSent) {
|
|
218
|
+
res.statusCode = 500;
|
|
219
|
+
res.end('Internal Server Error');
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
};
|
|
223
|
+
if (vite) {
|
|
224
|
+
/** Vite 保留命名空间:命中走 Vite 管线;其余 app-first(与 prod 顺序一致)。 */
|
|
225
|
+
const isViteRequest = (pathname) => {
|
|
226
|
+
if (pathname.startsWith('/@') ||
|
|
227
|
+
pathname === '/app' ||
|
|
228
|
+
pathname.startsWith('/app/') ||
|
|
229
|
+
pathname.startsWith('/node_modules/') ||
|
|
230
|
+
pathname.startsWith('/.vite/') ||
|
|
231
|
+
pathname.startsWith('/__')) {
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
const file = resolve(publicDir, `.${pathname}`);
|
|
235
|
+
if (file.startsWith(publicDir + sep) && existsSync(file))
|
|
236
|
+
return true;
|
|
237
|
+
// 项目内源文件(组件 import 了 `app/` 之外的项目模块,例如 `src/domain/*.ts`):
|
|
238
|
+
// dev 下必须走 Vite,否则客户端模块图断裂 → hydration 静默失败(SSR 仍可用,
|
|
239
|
+
// 问题只会以"JS 增强不生效"暴露;prod 由打包解决)。
|
|
240
|
+
if (SOURCE_FILE_RE.test(pathname)) {
|
|
241
|
+
const sourceFile = resolve(options.root, `.${pathname}`);
|
|
242
|
+
if (sourceFile.startsWith(options.root + sep) && existsSync(sourceFile)) {
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return false;
|
|
247
|
+
};
|
|
248
|
+
httpServer.on('request', (req, res) => {
|
|
249
|
+
const pathname = new URL(req.url ?? '/', 'http://localhost').pathname;
|
|
250
|
+
if (!isViteRequest(pathname)) {
|
|
251
|
+
serveApp(req, res);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
vite.middlewares(req, res, (error) => {
|
|
255
|
+
if (error) {
|
|
256
|
+
console.error(error);
|
|
257
|
+
if (!res.headersSent) {
|
|
258
|
+
res.statusCode = 500;
|
|
259
|
+
res.end('Internal Server Error');
|
|
260
|
+
}
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
serveApp(req, res);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
// 降级模式:public 静态 → app(weifuwu 路由可用;RR 页面依赖 Vite 不可用)
|
|
269
|
+
httpServer.on('request', toNodeHandler({
|
|
270
|
+
async fetch(request) {
|
|
271
|
+
if (publicStatic) {
|
|
272
|
+
const response = await tryStatic(publicStatic, request);
|
|
273
|
+
if (response)
|
|
274
|
+
return response;
|
|
275
|
+
}
|
|
276
|
+
return (await loadApp()).fetch(request);
|
|
277
|
+
},
|
|
278
|
+
}, { trustProxy: options.trustProxy }));
|
|
279
|
+
}
|
|
280
|
+
httpServer.on('upgrade', (req, socket, head) => {
|
|
281
|
+
const protocol = req.headers['sec-websocket-protocol'];
|
|
282
|
+
if (protocol === 'vite-hmr' || protocol === 'vite-ping')
|
|
283
|
+
return;
|
|
284
|
+
void loadApp().then((app) => {
|
|
285
|
+
const upgrade = app.upgrade;
|
|
286
|
+
if (typeof upgrade !== 'function') {
|
|
287
|
+
socket.destroy();
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
toUpgradeHandler({ fetch: app.fetch, upgrade }, { trustProxy: options.trustProxy })(req, socket, head);
|
|
291
|
+
}, () => socket.destroy());
|
|
292
|
+
});
|
|
293
|
+
const port = options.port ?? 3000;
|
|
294
|
+
await listen(httpServer, port, options.host);
|
|
295
|
+
console.log(`weifuwu dev listening on http://localhost:${port}`);
|
|
296
|
+
installShutdown(vite ? () => vite.close() : null, httpServer, async () => {
|
|
297
|
+
const close = closeAppOf(currentApp);
|
|
298
|
+
if (close)
|
|
299
|
+
await close();
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
async function start(options) {
|
|
303
|
+
process.env.NODE_ENV ??= 'production';
|
|
304
|
+
loadEnvFiles(options.root, process.env.NODE_ENV ?? 'production');
|
|
305
|
+
const entry = resolve(options.root, 'build/server/index.js');
|
|
306
|
+
if (!existsSync(entry)) {
|
|
307
|
+
throw new Error('未找到 build/server/index.js,请先运行 `weifuwu build`');
|
|
308
|
+
}
|
|
309
|
+
const module = (await import(__rewriteRelativeImportExtension(pathToFileURL(entry).href)));
|
|
310
|
+
const app = (module.default ?? module.app);
|
|
311
|
+
if (!app || typeof app.fetch !== 'function') {
|
|
312
|
+
throw new Error('build/server/index.js 未导出 weifuwu App');
|
|
313
|
+
}
|
|
314
|
+
const clientDir = resolve(options.root, 'build/client');
|
|
315
|
+
const assetsDir = resolve(clientDir, 'assets');
|
|
316
|
+
const assetsStatic = existsSync(assetsDir)
|
|
317
|
+
? serveStatic(assetsDir, { maxAge: 31_536_000, immutable: true })
|
|
318
|
+
: null;
|
|
319
|
+
const clientStatic = existsSync(clientDir)
|
|
320
|
+
? serveStatic(clientDir, { maxAge: 3_600 })
|
|
321
|
+
: null;
|
|
322
|
+
const fetchApp = {
|
|
323
|
+
async fetch(request) {
|
|
324
|
+
if (assetsStatic &&
|
|
325
|
+
new URL(request.url).pathname.startsWith('/assets/')) {
|
|
326
|
+
const response = await tryStatic(assetsStatic, request, '/assets');
|
|
327
|
+
if (response)
|
|
328
|
+
return response;
|
|
329
|
+
}
|
|
330
|
+
if (clientStatic) {
|
|
331
|
+
const response = await tryStatic(clientStatic, request);
|
|
332
|
+
if (response)
|
|
333
|
+
return response;
|
|
334
|
+
}
|
|
335
|
+
return app.fetch(request);
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
const httpServer = createHttpServer();
|
|
339
|
+
httpServer.on('request', toNodeHandler(fetchApp, { trustProxy: options.trustProxy }));
|
|
340
|
+
if (typeof app.upgrade === 'function') {
|
|
341
|
+
const upgradeApp = { fetch: app.fetch, upgrade: app.upgrade };
|
|
342
|
+
httpServer.on('upgrade', toUpgradeHandler(upgradeApp, { trustProxy: options.trustProxy }));
|
|
343
|
+
}
|
|
344
|
+
const port = options.port ?? 3000;
|
|
345
|
+
await listen(httpServer, port, options.host);
|
|
346
|
+
console.log(`weifuwu start listening on http://localhost:${port}`);
|
|
347
|
+
installShutdown(null, httpServer, closeAppOf(app));
|
|
348
|
+
}
|
|
349
|
+
/** 以 fetch handler 的方式尝试静态文件;未命中返回 null。 */
|
|
350
|
+
async function tryStatic(middleware, request, prefix) {
|
|
351
|
+
const scoped = prefix ? stripPrefix(request, prefix) : request;
|
|
352
|
+
const context = { params: {}, query: {} };
|
|
353
|
+
let missed = false;
|
|
354
|
+
const response = await middleware(scoped, context, () => {
|
|
355
|
+
missed = true;
|
|
356
|
+
return new Response(null, { status: 404 });
|
|
357
|
+
});
|
|
358
|
+
return missed ? null : response;
|
|
359
|
+
}
|
|
360
|
+
function stripPrefix(request, prefix) {
|
|
361
|
+
const url = new URL(request.url);
|
|
362
|
+
const rest = url.pathname.slice(prefix.length);
|
|
363
|
+
url.pathname = rest.startsWith('/') ? rest : `/${rest}`;
|
|
364
|
+
const init = {
|
|
365
|
+
method: request.method,
|
|
366
|
+
headers: request.headers,
|
|
367
|
+
body: request.body,
|
|
368
|
+
signal: request.signal,
|
|
369
|
+
};
|
|
370
|
+
if (request.body)
|
|
371
|
+
init.duplex = 'half';
|
|
372
|
+
return new Request(url, init);
|
|
373
|
+
}
|
|
374
|
+
function listen(server, port, host) {
|
|
375
|
+
return new Promise((resolveListen, reject) => {
|
|
376
|
+
server.once('error', reject);
|
|
377
|
+
if (host)
|
|
378
|
+
server.listen(port, host, () => resolveListen());
|
|
379
|
+
else
|
|
380
|
+
server.listen(port, () => resolveListen());
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
/** 从内置模板生成新项目:目录必须为空,`_gitignore` 改名、占位符注入。 */
|
|
384
|
+
function init(options) {
|
|
385
|
+
const target = resolve(options.root, options.rest[0] ?? '.');
|
|
386
|
+
if (existsSync(target) && readdirSync(target).length > 0) {
|
|
387
|
+
throw new Error(`目标目录非空:${target}`);
|
|
388
|
+
}
|
|
389
|
+
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
390
|
+
const templateDir = join(packageRoot, 'templates/react-router');
|
|
391
|
+
if (!existsSync(templateDir)) {
|
|
392
|
+
throw new Error(`未找到模板目录:${templateDir}`);
|
|
393
|
+
}
|
|
394
|
+
const name = basename(target)
|
|
395
|
+
.toLowerCase()
|
|
396
|
+
.replace(/[^a-z0-9-._~]+/g, '-')
|
|
397
|
+
.replace(/^[^a-z0-9]+/, '')
|
|
398
|
+
.replace(/[^a-z0-9]+$/, '') || 'weifuwu-app';
|
|
399
|
+
const { version } = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'));
|
|
400
|
+
mkdirSync(target, { recursive: true });
|
|
401
|
+
cpSync(templateDir, target, { recursive: true });
|
|
402
|
+
const placeholder = join(target, '_gitignore');
|
|
403
|
+
if (existsSync(placeholder)) {
|
|
404
|
+
renameSync(placeholder, join(target, '.gitignore'));
|
|
405
|
+
}
|
|
406
|
+
const packageJsonPath = join(target, 'package.json');
|
|
407
|
+
const packageJson = readFileSync(packageJsonPath, 'utf8')
|
|
408
|
+
.replaceAll('{{name}}', name)
|
|
409
|
+
.replaceAll('{{weifuwuVersion}}', `^${version}`);
|
|
410
|
+
writeFileSync(packageJsonPath, packageJson);
|
|
411
|
+
console.log(`weifuwu init 已生成项目 ${name}\n\n cd ${target}\n npm install\n npm run dev\n`);
|
|
412
|
+
}
|
|
413
|
+
function installShutdown(before, server, closeApp = null) {
|
|
414
|
+
// 未捕获异常是致命状态:同步写错误(process.exit 不保证异步 stderr 已冲刷),
|
|
415
|
+
// 按 Node 官方立场退出非 0,不尝试恢复运行(与 dev 的 unhandledRejection 策略区分)。
|
|
416
|
+
process.on('uncaughtException', (error) => {
|
|
417
|
+
const detail = error instanceof Error ? (error.stack ?? error.message) : String(error);
|
|
418
|
+
writeSync(2, `[weifuwu] 未捕获异常,退出:${detail}\n`);
|
|
419
|
+
process.exit(1);
|
|
420
|
+
});
|
|
421
|
+
let closing = false;
|
|
422
|
+
const shutdown = () => {
|
|
423
|
+
if (closing)
|
|
424
|
+
return;
|
|
425
|
+
closing = true;
|
|
426
|
+
// 第三方(Vite)可能把 128+signal 写进 exitCode;优雅退出必须显式归零
|
|
427
|
+
process.exitCode = 0;
|
|
428
|
+
// 兜底定时器**不 unref**:保持事件循环存活,避免 await 悬挂时提前 drain 退出(exitCode 被第三方改写)
|
|
429
|
+
const guard = setTimeout(() => process.exit(0), 2_000);
|
|
430
|
+
void (async () => {
|
|
431
|
+
// 每步限时,任一步悬挂不阻塞后续清理(app.close 必须跑到)
|
|
432
|
+
if (before)
|
|
433
|
+
await Promise.race([before().catch(() => { }), delay(1_000)]);
|
|
434
|
+
if (closeApp) {
|
|
435
|
+
await Promise.race([
|
|
436
|
+
closeApp().catch((error) => console.error(error)),
|
|
437
|
+
delay(1_000),
|
|
438
|
+
]);
|
|
439
|
+
}
|
|
440
|
+
server.close(() => {
|
|
441
|
+
clearTimeout(guard);
|
|
442
|
+
process.exit(0);
|
|
443
|
+
});
|
|
444
|
+
})();
|
|
445
|
+
};
|
|
446
|
+
process.on('SIGINT', shutdown);
|
|
447
|
+
process.on('SIGTERM', shutdown);
|
|
448
|
+
}
|
|
449
|
+
function delay(ms) {
|
|
450
|
+
return new Promise((resolveDelay) => setTimeout(resolveDelay, ms).unref());
|
|
451
|
+
}
|
|
452
|
+
/** 从 app 上取 `close()`(App.close / app.close 约定),没有则返回 null */
|
|
453
|
+
function closeAppOf(app) {
|
|
454
|
+
const close = app?.close;
|
|
455
|
+
if (typeof close !== 'function')
|
|
456
|
+
return null;
|
|
457
|
+
return () => close.call(app);
|
|
458
|
+
}
|
|
459
|
+
function printHelp() {
|
|
460
|
+
console.log(`weifuwu <command>
|
|
461
|
+
|
|
462
|
+
命令:
|
|
463
|
+
init 生成新项目(React Router + Tailwind + weifuwu)
|
|
464
|
+
dev 启动开发服务器(Vite + React Router SSR)
|
|
465
|
+
build 构建生产产物(react-router build)
|
|
466
|
+
start 启动生产服务器
|
|
467
|
+
typegen 生成 React Router 类型
|
|
468
|
+
routes 打印路由表(react-router routes)
|
|
469
|
+
|
|
470
|
+
选项:
|
|
471
|
+
--port <port> 监听端口,默认 3000
|
|
472
|
+
--host <host> 监听地址
|
|
473
|
+
--root <dir> 项目根目录,默认当前目录
|
|
474
|
+
--trust-proxy 信任 X-Forwarded-Proto / X-Forwarded-Host(反向代理场景)
|
|
475
|
+
`);
|
|
476
|
+
}
|
|
477
|
+
const options = parseArgs(process.argv.slice(2));
|
|
478
|
+
try {
|
|
479
|
+
switch (options.command) {
|
|
480
|
+
case 'init':
|
|
481
|
+
init(options);
|
|
482
|
+
break;
|
|
483
|
+
case 'dev':
|
|
484
|
+
await dev(options);
|
|
485
|
+
break;
|
|
486
|
+
case 'build':
|
|
487
|
+
await runReactRouter('build', options.rest, options.root);
|
|
488
|
+
break;
|
|
489
|
+
case 'start':
|
|
490
|
+
await start(options);
|
|
491
|
+
break;
|
|
492
|
+
case 'typegen':
|
|
493
|
+
await runReactRouter('typegen', options.rest, options.root);
|
|
494
|
+
break;
|
|
495
|
+
case 'routes':
|
|
496
|
+
await runReactRouter('routes', options.rest, options.root);
|
|
497
|
+
break;
|
|
498
|
+
default:
|
|
499
|
+
printHelp();
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
catch (error) {
|
|
503
|
+
console.error(error instanceof Error ? error.message : error);
|
|
504
|
+
process.exit(1);
|
|
505
|
+
}
|
|
506
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Context, Middleware, Next } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* 把中间件数组与终端处理器组合成洋葱模型(HTTP 与 WebSocket 共用一份实现)。
|
|
4
|
+
*
|
|
5
|
+
* - `next(req, ctx?)` 把控制权交给下一环,可传入新的 `req` / `ctx`
|
|
6
|
+
* - 中间件返回 `Response` 即短路(WS 中表示拒绝升级)
|
|
7
|
+
* - 同一个中间件重复调用 `next` 会抛出错误
|
|
8
|
+
* - `R` 是终端结果类型:HTTP 为 `Response`,WebSocket 为 `Response | void`
|
|
9
|
+
* - 注册位允许任意 R 的中间件(同一实例双端复用);HTTP 链的结果由调用方守卫为 Response
|
|
10
|
+
*/
|
|
11
|
+
export declare function compose<C extends Context = Context, R = Response>(middlewares: ReadonlyArray<Middleware<any, any, any>>, terminal: Next<C, R>): Next<C, Response | R>;
|
|
12
|
+
//# sourceMappingURL=compose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAE3D;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,OAAO,GAAG,OAAO,EAAE,CAAC,GAAG,QAAQ,EAC/D,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,EACrD,QAAQ,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GACnB,IAAI,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CA+BvB"}
|
package/dist/compose.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 把中间件数组与终端处理器组合成洋葱模型(HTTP 与 WebSocket 共用一份实现)。
|
|
3
|
+
*
|
|
4
|
+
* - `next(req, ctx?)` 把控制权交给下一环,可传入新的 `req` / `ctx`
|
|
5
|
+
* - 中间件返回 `Response` 即短路(WS 中表示拒绝升级)
|
|
6
|
+
* - 同一个中间件重复调用 `next` 会抛出错误
|
|
7
|
+
* - `R` 是终端结果类型:HTTP 为 `Response`,WebSocket 为 `Response | void`
|
|
8
|
+
* - 注册位允许任意 R 的中间件(同一实例双端复用);HTTP 链的结果由调用方守卫为 Response
|
|
9
|
+
*/
|
|
10
|
+
export function compose(middlewares, terminal) {
|
|
11
|
+
if (middlewares.length === 0) {
|
|
12
|
+
return terminal;
|
|
13
|
+
}
|
|
14
|
+
return function composed(req, ctx) {
|
|
15
|
+
let index = -1;
|
|
16
|
+
function dispatch(i, request, context) {
|
|
17
|
+
if (i <= index) {
|
|
18
|
+
return Promise.reject(new Error('next() called multiple times'));
|
|
19
|
+
}
|
|
20
|
+
index = i;
|
|
21
|
+
const middleware = middlewares[i];
|
|
22
|
+
if (!middleware)
|
|
23
|
+
return terminal(request, context);
|
|
24
|
+
return middleware(request, context, (nextReq, nextCtx) => dispatch(i + 1, nextReq ?? request, nextCtx ?? context));
|
|
25
|
+
}
|
|
26
|
+
return dispatch(0, req, ctx);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=compose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.js","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CACrB,WAAqD,EACrD,QAAoB;IAEpB,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,QAA4C,CAAA;IACrD,CAAC;IAED,OAAO,SAAS,QAAQ,CACtB,GAAY,EACZ,GAAM;QAEN,IAAI,KAAK,GAAG,CAAC,CAAC,CAAA;QAEd,SAAS,QAAQ,CACf,CAAS,EACT,OAAgB,EAChB,OAAgB;YAEhB,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;gBACf,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAA;YAClE,CAAC;YACD,KAAK,GAAG,CAAC,CAAA;YAET,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;YACjC,IAAI,CAAC,UAAU;gBAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,OAAY,CAAC,CAAA;YAEvD,OAAO,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CACvD,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,IAAI,OAAO,EAAE,OAAO,IAAI,OAAO,CAAC,CACxD,CAAA;QACH,CAAC;QAED,OAAO,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IAC9B,CAAC,CAAA;AACH,CAAC"}
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 零依赖 .env 加载:优先级(低 → 高)
|
|
3
|
+
* `.env` < `.env.local` < `.env.${mode}` < `.env.${mode}.local`。
|
|
4
|
+
* 真实 `process.env` 永远优先(文件只补缺)。
|
|
5
|
+
*/
|
|
6
|
+
/** 解析单个 .env 文件内容(忽略注释/空行,支持 `export` 与成对引号)。 */
|
|
7
|
+
export declare function parseEnv(content: string): Record<string, string>;
|
|
8
|
+
/** 读取并合并 .env 系列文件(不修改 process.env)。 */
|
|
9
|
+
export declare function readEnvFiles(root: string, mode: string): Record<string, string>;
|
|
10
|
+
/** 把 .env 系列文件注入 `process.env`;已存在的真实环境变量不被覆盖。 */
|
|
11
|
+
export declare function loadEnvFiles(root: string, mode: string): void;
|
|
12
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,iDAAiD;AACjD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBhE;AAED,wCAAwC;AACxC,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASxB;AAED,kDAAkD;AAClD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAI7D"}
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* 零依赖 .env 加载:优先级(低 → 高)
|
|
5
|
+
* `.env` < `.env.local` < `.env.${mode}` < `.env.${mode}.local`。
|
|
6
|
+
* 真实 `process.env` 永远优先(文件只补缺)。
|
|
7
|
+
*/
|
|
8
|
+
/** 解析单个 .env 文件内容(忽略注释/空行,支持 `export` 与成对引号)。 */
|
|
9
|
+
export function parseEnv(content) {
|
|
10
|
+
const result = {};
|
|
11
|
+
for (const line of content.split(/\r?\n/)) {
|
|
12
|
+
const trimmed = line.trim();
|
|
13
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
14
|
+
continue;
|
|
15
|
+
const match = /^(?:export\s+)?([^=\s]+)\s*=\s*(.*)$/.exec(trimmed);
|
|
16
|
+
if (!match)
|
|
17
|
+
continue;
|
|
18
|
+
const key = match[1];
|
|
19
|
+
let value = match[2].trim();
|
|
20
|
+
if ((value.startsWith('"') && value.endsWith('"')) ||
|
|
21
|
+
(value.startsWith("'") && value.endsWith("'"))) {
|
|
22
|
+
value = value.slice(1, -1);
|
|
23
|
+
}
|
|
24
|
+
result[key] = value;
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
/** 读取并合并 .env 系列文件(不修改 process.env)。 */
|
|
29
|
+
export function readEnvFiles(root, mode) {
|
|
30
|
+
const files = ['.env', '.env.local', `.env.${mode}`, `.env.${mode}.local`];
|
|
31
|
+
const merged = {};
|
|
32
|
+
for (const file of files) {
|
|
33
|
+
const path = join(root, file);
|
|
34
|
+
if (!existsSync(path))
|
|
35
|
+
continue;
|
|
36
|
+
Object.assign(merged, parseEnv(readFileSync(path, 'utf8')));
|
|
37
|
+
}
|
|
38
|
+
return merged;
|
|
39
|
+
}
|
|
40
|
+
/** 把 .env 系列文件注入 `process.env`;已存在的真实环境变量不被覆盖。 */
|
|
41
|
+
export function loadEnvFiles(root, mode) {
|
|
42
|
+
for (const [key, value] of Object.entries(readEnvFiles(root, mode))) {
|
|
43
|
+
process.env[key] ??= value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC;;;;GAIG;AAEH,iDAAiD;AACjD,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QACjD,MAAM,KAAK,GAAG,sCAAsC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAClE,IAAI,CAAC,KAAK;YAAE,SAAQ;QACpB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAE,CAAA;QACrB,IAAI,KAAK,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAA;QAC5B,IACE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC9C,CAAC;YACD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;IACrB,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,IAAY;IAEZ,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,IAAI,EAAE,EAAE,QAAQ,IAAI,QAAQ,CAAC,CAAA;IAC1E,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAQ;QAC/B,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;IAC7D,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,IAAY;IACrD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,CAAA;IAC5B,CAAC;AACH,CAAC"}
|