init router

This commit is contained in:
2024-10-16 00:47:30 +08:00
commit 733677f3f3
32 changed files with 2185 additions and 0 deletions

268
demo/simple/package-lock.json generated Normal file
View File

@@ -0,0 +1,268 @@
{
"name": "simple",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "simple",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@abearxiong/router": "../.."
},
"devDependencies": {
"ts-node": "^10.9.2",
"typescript": "^5.5.4"
}
},
"../..": {
"name": "@kevisual/router",
"version": "0.0.2",
"license": "ISC",
"dependencies": {
"ws": "^8.18.0"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^26.0.1",
"@rollup/plugin-node-resolve": "^15.2.4",
"@rollup/plugin-typescript": "^12.1.0",
"@types/lodash-es": "^4.17.12",
"@types/node": "^22.5.5",
"@types/ws": "^8.5.12",
"lodash-es": "^4.17.21",
"nanoid": "^5.0.7",
"rollup": "^4.22.4",
"ts-loader": "^9.5.1",
"ts-node": "^10.9.2",
"tslib": "^2.7.0",
"typescript": "^5.6.2",
"zod": "^3.23.8"
}
},
"node_modules/@abearxiong/router": {
"resolved": "../..",
"link": true
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmmirror.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.9",
"resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@tsconfig/node10": {
"version": "1.0.11",
"resolved": "https://registry.npmmirror.com/@tsconfig/node10/-/node10-1.0.11.tgz",
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
"dev": true,
"license": "MIT"
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmmirror.com/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
"dev": true,
"license": "MIT"
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
"dev": true,
"license": "MIT"
},
"node_modules/@tsconfig/node16": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.5.1",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-22.5.1.tgz",
"integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~6.19.2"
}
},
"node_modules/acorn": {
"version": "8.12.1",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.12.1.tgz",
"integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
"dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/acorn-walk": {
"version": "8.3.3",
"resolved": "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.3.3.tgz",
"integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==",
"dev": true,
"license": "MIT",
"dependencies": {
"acorn": "^8.11.0"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmmirror.com/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true,
"license": "MIT"
},
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true,
"license": "MIT"
},
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
},
"node_modules/make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmmirror.com/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true,
"license": "ISC"
},
"node_modules/ts-node": {
"version": "10.9.2",
"resolved": "https://registry.npmmirror.com/ts-node/-/ts-node-10.9.2.tgz",
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
},
"bin": {
"ts-node": "dist/bin.js",
"ts-node-cwd": "dist/bin-cwd.js",
"ts-node-esm": "dist/bin-esm.js",
"ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js"
},
"peerDependencies": {
"@swc/core": ">=1.2.50",
"@swc/wasm": ">=1.2.50",
"@types/node": "*",
"typescript": ">=2.7"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"@swc/wasm": {
"optional": true
}
}
},
"node_modules/typescript": {
"version": "5.5.4",
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.5.4.tgz",
"integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "6.19.8",
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"dev": true,
"license": "MIT",
"peer": true
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"dev": true,
"license": "MIT"
},
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
}
}
}

20
demo/simple/package.json Normal file
View File

@@ -0,0 +1,20 @@
{
"name": "simple",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"app": "node --no-warnings=ExperimentalWarning --loader ts-node/esm src/app.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"@abearxiong/router": "../.."
},
"devDependencies": {
"ts-node": "^10.9.2",
"typescript": "^5.5.4"
}
}

View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket with Redis</title>
</head>
<body>
<h1>Real-time Data Updates</h1>
<p id="output">Waiting for updates...</p>
<script>
// const ws = new WebSocket('ws://localhost:4002/api/router');
const ws = new WebSocket('ws://192.168.31.220:4002/api/router');
// 当连接成功时
ws.onopen = () => {
console.log('Connected to WebSocket server');
// 订阅数据 ID 为 1 的更新
// const message = JSON.stringify({ type: 'subscribe', dataId: '1' });
// ws.send(message);
const message = JSON.stringify({
type: 'router',
data: {
path: 'demo',
key: '01',
}
});
ws.send(message);
};
// 接收服务器的消息
ws.onmessage = (event) => {
const parseIfJson = (data) => {
try {
return JSON.parse(data);
} catch (error) {
return data;
}
};
const appendChild = (text) => {
const t = document.createElement('div');
t.innerText = text;
document.body.appendChild(t);
};
console.log('Received:', event.data);
const message = parseIfJson(event.data);
if (typeof message === 'string') {
appendChild(message);
return;
}
if (message.type === 'router') {
const res = message.data;
const text = `Data Updated: ${JSON.stringify(res)}`;
appendChild(text);
console.log('Data updated:', res);
} else {
document.querySelector('#output').innerText = event.data;
console.log('Unknown message type:', message.type);
}
};
// 处理 WebSocket 关闭
ws.onclose = () => {
console.log('Disconnected from WebSocket server');
};
</script>
</body>
</html>

41
demo/simple/src/app-02.ts Normal file
View File

@@ -0,0 +1,41 @@
import { App } from '@abearxiong/router';
const app = new App();
app.listen(4002, () => {
console.log('Server is running at http://localhost:4002');
});
const callback = (req, res) => {
if (req.url.startsWith('/api/v')) {
// 在这里处理 /api/v 的请求
// res.writeHead(200, { 'Content-Type': 'text/plain' });
setTimeout(() => {
res.end('Intercepted /api/v request');
}, 2000);
}
};
app.server.on(callback);
new app.Route('demo', '01')
.define(async (ctx) => {
ctx.body = '01';
return ctx;
})
.addTo(app);
app
.route('demo')
.define(async (ctx) => {
ctx.body = '02';
return ctx;
})
.addTo(app);
app
.route('demo', '03')
.define(async (ctx) => {
ctx.body = '03';
return ctx;
})
.addTo(app);

27
demo/simple/src/app-ws.ts Normal file
View File

@@ -0,0 +1,27 @@
import { Route, App } from '@abearxiong/router';
const app = new App({ io: true });
app.listen(4002);
const route01 = new Route('demo', '01');
route01.run = async (ctx) => {
ctx.body = '01';
return ctx;
};
app.use(
'demo',
async (ctx) => {
ctx.body = '01';
return ctx;
},
{ key: '01' },
);
const route02 = new Route('demo', '02');
route02.run = async (ctx) => {
ctx.body = '02';
return ctx;
};
app.addRoute(route02);
console.log(`http://localhost:4002/api/router?path=demo&key=02`);
console.log(`http://localhost:4002/api/router?path=demo&key=01`);

27
demo/simple/src/app.ts Normal file
View File

@@ -0,0 +1,27 @@
import { Route, App } from '@abearxiong/router';
const app = new App();
app.listen(4003);
const route01 = new Route('demo', '01');
route01.run = async (ctx) => {
ctx.body = '01';
return ctx;
};
app.use(
'demo',
async (ctx) => {
ctx.body = '01';
return ctx;
},
{ key: '01' },
);
const route02 = new Route('demo', '02');
route02.run = async (ctx) => {
ctx.body = '02';
return ctx;
};
app.addRoute(route02);
console.log(`http://localhost:4003/api/router?path=demo&key=02`);
console.log(`http://localhost:4003/api/router?path=demo&key=01`);

36
demo/simple/src/index.ts Normal file
View File

@@ -0,0 +1,36 @@
import { QueryRouter, Route, Server } from '@abearxiong/router';
const router = new QueryRouter();
const route01 = new Route('demo', '01');
route01.run = async (ctx) => {
ctx.body = '01';
return ctx;
};
router.add(route01);
const server = new Server({
handle: async (msg) => {
const res = await router.parse(msg);
const { code, body, message } = res;
// console.log('response', res);
return { code, data: body, message };
}
});
// server.setHandle(async (msg) => {
// const res = await router.parse(msg);
// const { code, body, message } = res;
// // console.log('response', res);
// return { code, data: body, message };
// });
server.listen(3000);
const route02 = new Route('demo', '02');
route02.run = async (ctx) => {
ctx.body = '02';
return ctx;
};
router.add(route02);

View File

@@ -0,0 +1,85 @@
import { Route, QueryRouter, RouteContext } from '@abearxiong/router';
const qr = new QueryRouter();
qr.add(
new Route('project', 'getList', {
description: 'get project list',
run: async (ctx) => {
ctx!.body = 'project list';
return ctx;
},
}),
);
qr.add(
new Route('project', 'getDetail', {
description: 'get project detail',
run: async (ctx) => {
ctx!.body = 'project detail';
return ctx;
},
}),
);
qr.add(
new Route('project', 'getDetail2', {
description: 'get project detail2',
run: async (ctx: RouteContext) => {
ctx!.body = 'project detail2';
return ctx;
},
validator: {
id: {
type: 'number',
required: true,
message: 'id is required',
},
data: {
// @ts-ignore
type: 'object',
message: 'data query is error',
properties: {
name: {
type: 'string',
required: true,
message: 'name is required',
},
age: {
type: 'number',
required: true,
message: 'age is error',
},
friends: {
type: 'object',
properties: {
hair: {
type: 'string',
required: true,
message: 'hair is required',
},
},
},
},
},
},
}),
);
const main = async () => {
// 调用要测试的函数
const res = await qr.parse({
path: 'project',
key: 'getDetail2',
id: 4,
data: {
name: 'john',
age: 's'+13,
friends: {
hair: 'black',
messages: 'hello',
},
},
} as any);
console.log('test===', res);
};
main();

43
demo/simple/tsconfig.json Normal file
View File

@@ -0,0 +1,43 @@
{
"compilerOptions": {
"module": "NodeNext",
"target": "esnext",
"noImplicitAny": false,
"outDir": "./dist",
"sourceMap": false,
"allowJs": true,
"newLine": "LF",
"baseUrl": "./",
"typeRoots": [
"node_modules/@types",
],
"declaration": true,
"noEmit": true,
"allowImportingTsExtensions": true,
"moduleResolution": "NodeNext",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"paths": {
"@/*": [
"src/*"
],
"*": [
"types/*"
]
}
},
"include": [
"typings.d.ts",
"src/**/*.ts"
],
"exclude": [
"node_modules",
"dist",
"src/**/*.test.ts",
"rollup.config.js",
],
"ts-node": {
"esm": true
}
}