test deno
This commit is contained in:
parent
d93af32354
commit
a54ba4d823
42
deno-router-demo/deno.json
Normal file
42
deno-router-demo/deno.json
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"tasks": {
|
||||||
|
"start": "deno run --allow-all index.ts"
|
||||||
|
},
|
||||||
|
"imports": {
|
||||||
|
"@kevisual/router": "https://esm.xiongxiao.me/@kevisual/router/src/mod.ts"
|
||||||
|
},
|
||||||
|
"compilerOptions": {
|
||||||
|
"types": [
|
||||||
|
"./types",
|
||||||
|
"https://esm.xiongxiao.me/@kevisual/router@0.0.10/dist/router.d.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fmt": {
|
||||||
|
"files": {
|
||||||
|
|
||||||
|
"include": ["src/"],
|
||||||
|
"exclude": []
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"lineWidth": 80,
|
||||||
|
"indentWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"singleQuote": false,
|
||||||
|
"proseWrap": "preserve"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"include": [
|
||||||
|
"./src/**/*.ts",
|
||||||
|
"index.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"./types"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"tags": ["recommended"],
|
||||||
|
"include": [],
|
||||||
|
"exclude": ["require-await"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
deno-router-demo/package.json
Normal file
17
deno-router-demo/package.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "deno-router-demo",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
||||||
|
"license": "MIT",
|
||||||
|
"packageManager": "pnpm@10.8.1",
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"@kevisual/router": "^0.0.11"
|
||||||
|
}
|
||||||
|
}
|
83
deno-router-demo/pnpm-lock.yaml
generated
Normal file
83
deno-router-demo/pnpm-lock.yaml
generated
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
lockfileVersion: '9.0'
|
||||||
|
|
||||||
|
settings:
|
||||||
|
autoInstallPeers: true
|
||||||
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
|
importers:
|
||||||
|
|
||||||
|
.:
|
||||||
|
dependencies:
|
||||||
|
'@kevisual/router':
|
||||||
|
specifier: ^0.0.11
|
||||||
|
version: 0.0.11
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
'@kevisual/router@0.0.11':
|
||||||
|
resolution: {integrity: sha512-i/gVqIv3UpjdyS0zZHoDWYTBnL4YWGmj/8O8GQV7xxXZXJPRXLHjLC1ylRhwEGBdb6UxabKohplr7HKRuIJ2Ag==}
|
||||||
|
|
||||||
|
'@types/node-forge@1.3.11':
|
||||||
|
resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
|
||||||
|
|
||||||
|
'@types/node@22.14.1':
|
||||||
|
resolution: {integrity: sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==}
|
||||||
|
|
||||||
|
node-forge@1.3.1:
|
||||||
|
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
|
||||||
|
engines: {node: '>= 6.13.0'}
|
||||||
|
|
||||||
|
path-to-regexp@8.2.0:
|
||||||
|
resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==}
|
||||||
|
engines: {node: '>=16'}
|
||||||
|
|
||||||
|
selfsigned@2.4.1:
|
||||||
|
resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
undici-types@6.21.0:
|
||||||
|
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
||||||
|
|
||||||
|
ws@8.18.1:
|
||||||
|
resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==}
|
||||||
|
engines: {node: '>=10.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
bufferutil: ^4.0.1
|
||||||
|
utf-8-validate: '>=5.0.2'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
bufferutil:
|
||||||
|
optional: true
|
||||||
|
utf-8-validate:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
snapshots:
|
||||||
|
|
||||||
|
'@kevisual/router@0.0.11':
|
||||||
|
dependencies:
|
||||||
|
path-to-regexp: 8.2.0
|
||||||
|
selfsigned: 2.4.1
|
||||||
|
ws: 8.18.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- bufferutil
|
||||||
|
- utf-8-validate
|
||||||
|
|
||||||
|
'@types/node-forge@1.3.11':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 22.14.1
|
||||||
|
|
||||||
|
'@types/node@22.14.1':
|
||||||
|
dependencies:
|
||||||
|
undici-types: 6.21.0
|
||||||
|
|
||||||
|
node-forge@1.3.1: {}
|
||||||
|
|
||||||
|
path-to-regexp@8.2.0: {}
|
||||||
|
|
||||||
|
selfsigned@2.4.1:
|
||||||
|
dependencies:
|
||||||
|
'@types/node-forge': 1.3.11
|
||||||
|
node-forge: 1.3.1
|
||||||
|
|
||||||
|
undici-types@6.21.0: {}
|
||||||
|
|
||||||
|
ws@8.18.1: {}
|
32
deno-router-demo/src/index.ts
Normal file
32
deno-router-demo/src/index.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// import { App } from '@kevisual/router';
|
||||||
|
import { App } from '@kevisual/router/mod.ts';
|
||||||
|
|
||||||
|
console.log('meta', import.meta.url);
|
||||||
|
// deno run --allow-all index.ts
|
||||||
|
// deno run --config ./deno.json --allow-all index.ts
|
||||||
|
console.log('hello world');
|
||||||
|
|
||||||
|
const app = new App({
|
||||||
|
io: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
app
|
||||||
|
.route({
|
||||||
|
path: 'demo',
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
|
ctx.body = 'hello world';
|
||||||
|
})
|
||||||
|
.addTo(app);
|
||||||
|
|
||||||
|
app.listen(10004, () => {
|
||||||
|
console.log('Server is running on http://localhost:10004');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.io.addListener('goo', async ({ data, ws, end }) => {
|
||||||
|
console.log('goo', data);
|
||||||
|
end({
|
||||||
|
code: 200,
|
||||||
|
message: 'hello world goo',
|
||||||
|
});
|
||||||
|
});
|
28
deno-router-demo/src/web-ws.ts
Normal file
28
deno-router-demo/src/web-ws.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
const ws = new WebSocket('ws://localhost:10004/api/router');
|
||||||
|
|
||||||
|
ws.onopen = () => {
|
||||||
|
console.log('open');
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
console.log('message', event.data);
|
||||||
|
const data = event.data;
|
||||||
|
if (data === 'connected') {
|
||||||
|
const data = {
|
||||||
|
type: 'router',
|
||||||
|
requestId: 'requestId',
|
||||||
|
data: {
|
||||||
|
path: 'demo',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ws.send(JSON.stringify(data));
|
||||||
|
const data2= {
|
||||||
|
type: 'goo'
|
||||||
|
};
|
||||||
|
ws.send(JSON.stringify(data2));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onerror = (event) => {
|
||||||
|
console.log('error', event);
|
||||||
|
};
|
41
deno-router-demo/tsconfig.json
Normal file
41
deno-router-demo/tsconfig.json
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "NodeNext",
|
||||||
|
"target": "esnext",
|
||||||
|
"noImplicitAny": false,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"sourceMap": false,
|
||||||
|
"allowJs": true,
|
||||||
|
"newLine": "LF",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"typeRoots": [
|
||||||
|
"node_modules/@types",
|
||||||
|
"src/@types"
|
||||||
|
],
|
||||||
|
"declaration": true,
|
||||||
|
"noEmit": false,
|
||||||
|
// "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",
|
||||||
|
"webpack.config.cjs",
|
||||||
|
],
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
|
import { App } from '@kevisual/router/mod.ts';
|
||||||
// @ts-types="https://esm.xiongxiao.me/@kevisual/router/dist/router.d.ts?raw"
|
// @ts-types="https://esm.xiongxiao.me/@kevisual/router/dist/router.d.ts?raw"
|
||||||
import { App } from '@kevisual/router';
|
|
||||||
|
|
||||||
console.log('meta', import.meta.url)
|
console.log('meta', import.meta.url)
|
||||||
// deno run --allow-all index.ts
|
// deno run --allow-all index.ts
|
||||||
|
6
deno-router2/check-env.ts
Normal file
6
deno-router2/check-env.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
const isDeno = typeof Deno !== "undefined" && !!Deno.version;
|
||||||
|
const isNode = typeof process !== "undefined" && !!process.versions?.node;
|
||||||
|
|
||||||
|
console.log('process', process.version);
|
||||||
|
console.log("isDeno", isDeno);
|
||||||
|
console.log("isNode", isNode);
|
48
deno-router2/deno.json
Normal file
48
deno-router2/deno.json
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"tasks": {
|
||||||
|
"start": "deno run --allow-all index.ts"
|
||||||
|
},
|
||||||
|
"imports": {
|
||||||
|
"@kevisual/router/mod.ts": "https://esm.xiongxiao.me/@kevisual/router/src/mod.ts",
|
||||||
|
"ws": "npm:ws@8.13.0"
|
||||||
|
},
|
||||||
|
"compilerOptions": {
|
||||||
|
"types": [
|
||||||
|
"./types",
|
||||||
|
"https://esm.xiongxiao.me/@kevisual/router@0.0.10/dist/router.d.ts"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fmt": {
|
||||||
|
"files": {
|
||||||
|
"include": [
|
||||||
|
"src/"
|
||||||
|
],
|
||||||
|
"exclude": []
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"lineWidth": 80,
|
||||||
|
"indentWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"singleQuote": false,
|
||||||
|
"proseWrap": "preserve"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"include": [
|
||||||
|
"./src/**/*.ts",
|
||||||
|
"index.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"./types"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"tags": [
|
||||||
|
"recommended"
|
||||||
|
],
|
||||||
|
"include": [],
|
||||||
|
"exclude": [
|
||||||
|
"require-await"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
62
deno-router2/deno.lock
generated
Normal file
62
deno-router2/deno.lock
generated
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"version": "4",
|
||||||
|
"specifiers": {
|
||||||
|
"npm:@types/node@*": "22.12.0",
|
||||||
|
"npm:ws@8.13.0": "8.13.0"
|
||||||
|
},
|
||||||
|
"npm": {
|
||||||
|
"@types/node@22.12.0": {
|
||||||
|
"integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==",
|
||||||
|
"dependencies": [
|
||||||
|
"undici-types"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"undici-types@6.20.0": {
|
||||||
|
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
|
||||||
|
},
|
||||||
|
"ws@8.13.0": {
|
||||||
|
"integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA=="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"redirects": {
|
||||||
|
"http://esm.xiongxiao.me/@types/ws@~8.18.1/index.d.mts": "http://esm.xiongxiao.me/@types/ws@8.18.1/index.d.mts",
|
||||||
|
"http://esm.xiongxiao.me/bufferutil@^4.0.1?target=denonext": "http://esm.xiongxiao.me/bufferutil@4.0.9?target=denonext",
|
||||||
|
"http://esm.xiongxiao.me/cookie?target=denonext": "http://esm.xiongxiao.me/cookie@1.0.2?target=denonext",
|
||||||
|
"http://esm.xiongxiao.me/lodash-es?target=denonext": "http://esm.xiongxiao.me/lodash-es@4.17.21?target=denonext",
|
||||||
|
"http://esm.xiongxiao.me/nanoid?target=denonext": "http://esm.xiongxiao.me/nanoid@5.1.5?target=denonext",
|
||||||
|
"http://esm.xiongxiao.me/node-gyp-build@^4.3.0?target=denonext": "http://esm.xiongxiao.me/node-gyp-build@4.8.4?target=denonext",
|
||||||
|
"http://esm.xiongxiao.me/utf-8-validate@%3E=5.0.2?target=denonext": "http://esm.xiongxiao.me/utf-8-validate@6.0.5?target=denonext",
|
||||||
|
"http://esm.xiongxiao.me/ws@^8.18.1?target=denonext": "http://esm.xiongxiao.me/ws@8.18.1?target=denonext",
|
||||||
|
"http://esm.xiongxiao.me/zod?target=denonext": "http://esm.xiongxiao.me/zod@3.24.3?target=denonext",
|
||||||
|
"https://esm.xiongxiao.me/@kevisual/router": "http://esm.xiongxiao.me/@kevisual/router@0.0.10",
|
||||||
|
"https://esm.xiongxiao.me/@kevisual/router/router": "http://esm.xiongxiao.me/@kevisual/router@0.0.10/router",
|
||||||
|
"https://esm.xiongxiao.me/@kevisual/router/src/mod.ts": "http://esm.xiongxiao.me/@kevisual/router@0.0.11/src/mod.ts"
|
||||||
|
},
|
||||||
|
"remote": {
|
||||||
|
"http://esm.xiongxiao.me/@kevisual/router@0.0.10": "f7e3ea672cef9b532b62cc557f3369afbe7bdfd35001a62cd246033b303af048",
|
||||||
|
"http://esm.xiongxiao.me/@kevisual/router@0.0.10/denonext/router.mjs": "ee734dfbbe30415695d67e9d735e968e0e4554dc77b14368603a51273641a580",
|
||||||
|
"http://esm.xiongxiao.me/@kevisual/router@0.0.11/denonext/src/mod.ts.mjs": "f205c1fa864e6deaad100ab873c194b21e1005a0366699ec5b17391faf7abfec",
|
||||||
|
"http://esm.xiongxiao.me/@kevisual/router@0.0.11/src/mod.ts": "553715d1d0e8e9ba5b1ba7bbfc33362162e8f8f4840c09110951b67c877861ae",
|
||||||
|
"http://esm.xiongxiao.me/bufferutil@4.0.9/denonext/bufferutil.mjs": "13dca4d5bb2c68cbe119f880fa3bd785b9a81a8e02e0834dae604b4b85295cd8",
|
||||||
|
"http://esm.xiongxiao.me/bufferutil@4.0.9?target=denonext": "e32574569ab438facfcc3f412c659b0719bbf05477136ca176938c9a3ac45125",
|
||||||
|
"http://esm.xiongxiao.me/cookie@1.0.2/denonext/cookie.mjs": "6c4f976d4d933ff2d7afc1f6ee7af134108c9858f5a2aadc6189084bd5972275",
|
||||||
|
"http://esm.xiongxiao.me/cookie@1.0.2?target=denonext": "04dabbcad7a7a96d841d6b21f00cb20191fb29339781237088d8edabad52df66",
|
||||||
|
"http://esm.xiongxiao.me/lodash-es@4.17.21/denonext/lodash-es.mjs": "83b25b8f85872b2805e6b0273c90d6c96960c80a710c55e89a7b399107fc6fa8",
|
||||||
|
"http://esm.xiongxiao.me/lodash-es@4.17.21?target=denonext": "1252ccd86311d14f2dd05282cf3e40e1ff76bfa79c71ca49b903e902129944cb",
|
||||||
|
"http://esm.xiongxiao.me/nanoid@5.1.5/denonext/nanoid.mjs": "dc919f2d7339a244f732a0cf02e3962dd1289535668026f52fb26bd593e9358b",
|
||||||
|
"http://esm.xiongxiao.me/nanoid@5.1.5?target=denonext": "33ad5b17f1290cb850164cfcf30f642d9dad489ba19909bc3cfd9eb78369f451",
|
||||||
|
"http://esm.xiongxiao.me/node-gyp-build@4.8.4/denonext/node-gyp-build.mjs": "9a86f2d044fc77bd60aaa3d697c2ba1b818da5fb1b9aaeedec59a40b8e908803",
|
||||||
|
"http://esm.xiongxiao.me/node-gyp-build@4.8.4?target=denonext": "261a6cedf1fdbf159798141ba1e2311ac1510682c5c8b55dacc8cf5fdee4aa06",
|
||||||
|
"http://esm.xiongxiao.me/utf-8-validate@6.0.5/denonext/utf-8-validate.mjs": "66b8ea532a0c745068f5b96ddb1bae332c3036703243541d2e89e66331974d98",
|
||||||
|
"http://esm.xiongxiao.me/utf-8-validate@6.0.5?target=denonext": "071bc33ba1a58297e23a34d69dd589fd06df04b0f373b382ff5da544a623f271",
|
||||||
|
"http://esm.xiongxiao.me/ws@8.18.1/denonext/ws.mjs": "9c6726c262f19d2dbbd5b5224d9f118cdbeb793ea475ecd40de2b778886a5e16",
|
||||||
|
"http://esm.xiongxiao.me/ws@8.18.1?target=denonext": "e99b670fc49b38e15a7576ddcd5bb01e123fe9b3a017db7f97898127811b4e27",
|
||||||
|
"http://esm.xiongxiao.me/zod@3.24.3/denonext/zod.mjs": "46c4acb1f87caf349962b648f519cbf3999a8746fb40df0331ad2d3b62a197c0",
|
||||||
|
"http://esm.xiongxiao.me/zod@3.24.3?target=denonext": "8fb963869b1a83e910ff2fc4e64af7918e34b1350088455141b653233f274395"
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"dependencies": [
|
||||||
|
"npm:ws@8.13.0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
34
deno-router2/index.ts
Normal file
34
deno-router2/index.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// import { App } from '@kevisual/router';
|
||||||
|
// @ts-types="https://esm.xiongxiao.me/@kevisual/router/dist/router.d.ts?raw"
|
||||||
|
import { App } from '@kevisual/router/mod.ts';
|
||||||
|
|
||||||
|
console.log('meta', import.meta.url);
|
||||||
|
// deno run --allow-all index.ts
|
||||||
|
// deno run --config ./deno.json --allow-all index.ts
|
||||||
|
console.log('hello world');
|
||||||
|
|
||||||
|
const app = new App({
|
||||||
|
io: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
app
|
||||||
|
.route({
|
||||||
|
path: 'demo',
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
|
ctx.body = 'hello world';
|
||||||
|
})
|
||||||
|
.addTo(app);
|
||||||
|
|
||||||
|
app.listen(10004, () => {
|
||||||
|
console.log('Server is running on http://localhost:10004');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.io.addListener('goo', async ({ data, ws, end }) => {
|
||||||
|
console.log('goo', data);
|
||||||
|
end({
|
||||||
|
code: 200,
|
||||||
|
message: 'hello world goo',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
618
deno-router2/types/router.d.ts
vendored
Normal file
618
deno-router2/types/router.d.ts
vendored
Normal file
@ -0,0 +1,618 @@
|
|||||||
|
import { Schema } from 'http://esm.xiongxiao.me/zod@3.24.3/index.d.ts';
|
||||||
|
export { Schema } from 'http://esm.xiongxiao.me/zod@3.24.3/index.d.ts';
|
||||||
|
import http, { IncomingMessage, ServerResponse } from 'node:http';
|
||||||
|
import https from 'node:https';
|
||||||
|
import http2 from 'node:http2';
|
||||||
|
import * as cookie from 'http://esm.xiongxiao.me/cookie@1.0.2/dist/index.d.ts';
|
||||||
|
import { WebSocketServer, WebSocket } from 'http://esm.xiongxiao.me/@types/ws@~8.18.1/index.d.mts';
|
||||||
|
|
||||||
|
type BaseRule = {
|
||||||
|
value?: any;
|
||||||
|
required?: boolean;
|
||||||
|
message?: string;
|
||||||
|
};
|
||||||
|
type RuleString = {
|
||||||
|
type: 'string';
|
||||||
|
minLength?: number;
|
||||||
|
maxLength?: number;
|
||||||
|
regex?: string;
|
||||||
|
} & BaseRule;
|
||||||
|
type RuleNumber = {
|
||||||
|
type: 'number';
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
} & BaseRule;
|
||||||
|
type RuleBoolean = {
|
||||||
|
type: 'boolean';
|
||||||
|
} & BaseRule;
|
||||||
|
type RuleArray = {
|
||||||
|
type: 'array';
|
||||||
|
items: Rule;
|
||||||
|
minItems?: number;
|
||||||
|
maxItems?: number;
|
||||||
|
} & BaseRule;
|
||||||
|
type RuleObject = {
|
||||||
|
type: 'object';
|
||||||
|
properties: {
|
||||||
|
[key: string]: Rule;
|
||||||
|
};
|
||||||
|
} & BaseRule;
|
||||||
|
type RuleAny = {
|
||||||
|
type: 'any';
|
||||||
|
} & BaseRule;
|
||||||
|
type Rule = RuleString | RuleNumber | RuleBoolean | RuleArray | RuleObject | RuleAny;
|
||||||
|
declare const createSchema: (rule: Rule) => Schema;
|
||||||
|
|
||||||
|
type RouterContextT = {
|
||||||
|
code?: number;
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
type RouteContext<T = {
|
||||||
|
code?: number;
|
||||||
|
}, S = any> = {
|
||||||
|
query?: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
/** return body */
|
||||||
|
body?: number | string | Object;
|
||||||
|
/** return code */
|
||||||
|
code?: number;
|
||||||
|
/** return msg */
|
||||||
|
message?: string;
|
||||||
|
state?: S;
|
||||||
|
currentPath?: string;
|
||||||
|
currentKey?: string;
|
||||||
|
currentRoute?: Route;
|
||||||
|
progress?: [[string, string]][];
|
||||||
|
nextQuery?: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
end?: boolean;
|
||||||
|
queryRouter?: QueryRouter;
|
||||||
|
error?: any;
|
||||||
|
/** 请求 route的返回结果,包函ctx */
|
||||||
|
call?: (message: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
[key: string]: any;
|
||||||
|
} | {
|
||||||
|
id: string;
|
||||||
|
apyload?: any;
|
||||||
|
[key: string]: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}) => Promise<any>;
|
||||||
|
/** 请求 route的返回结果,不包函ctx */
|
||||||
|
queryRoute?: (message: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}) => Promise<any>;
|
||||||
|
index?: number;
|
||||||
|
throw?: (code?: number | string, message?: string, tips?: string) => void;
|
||||||
|
/** 是否需要序列化 */
|
||||||
|
needSerialize?: boolean;
|
||||||
|
} & T;
|
||||||
|
type Run<T = any> = (ctx: RouteContext<T>) => Promise<typeof ctx | null | void>;
|
||||||
|
type NextRoute = Pick<Route, 'id' | 'path' | 'key'>;
|
||||||
|
type RouteOpts = {
|
||||||
|
path?: string;
|
||||||
|
key?: string;
|
||||||
|
id?: string;
|
||||||
|
run?: Run;
|
||||||
|
nextRoute?: NextRoute;
|
||||||
|
description?: string;
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
middleware?: Route[] | string[];
|
||||||
|
type?: 'route' | 'middleware';
|
||||||
|
/**
|
||||||
|
* validator: {
|
||||||
|
* packageName: {
|
||||||
|
* type: 'string',
|
||||||
|
* required: true,
|
||||||
|
* },
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
validator?: {
|
||||||
|
[key: string]: Rule;
|
||||||
|
};
|
||||||
|
schema?: {
|
||||||
|
[key: string]: Schema<any>;
|
||||||
|
};
|
||||||
|
isVerify?: boolean;
|
||||||
|
verify?: (ctx?: RouteContext, dev?: boolean) => boolean;
|
||||||
|
verifyKey?: (key: string, ctx?: RouteContext, dev?: boolean) => boolean;
|
||||||
|
/**
|
||||||
|
* $#$ will be used to split path and key
|
||||||
|
*/
|
||||||
|
idUsePath?: boolean;
|
||||||
|
isDebug?: boolean;
|
||||||
|
};
|
||||||
|
type DefineRouteOpts = Omit<RouteOpts, 'idUsePath' | 'verify' | 'verifyKey' | 'nextRoute'>;
|
||||||
|
declare const pickValue: readonly ["path", "key", "id", "description", "type", "validator", "middleware"];
|
||||||
|
type RouteInfo = Pick<Route, (typeof pickValue)[number]>;
|
||||||
|
declare class Route<U = {
|
||||||
|
[key: string]: any;
|
||||||
|
}> {
|
||||||
|
/**
|
||||||
|
* 一级路径
|
||||||
|
*/
|
||||||
|
path?: string;
|
||||||
|
/**
|
||||||
|
* 二级路径
|
||||||
|
*/
|
||||||
|
key?: string;
|
||||||
|
id?: string;
|
||||||
|
share?: boolean;
|
||||||
|
run?: Run;
|
||||||
|
nextRoute?: NextRoute;
|
||||||
|
description?: string;
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
middleware?: (Route | string)[];
|
||||||
|
type?: string;
|
||||||
|
private _validator?;
|
||||||
|
schema?: {
|
||||||
|
[key: string]: Schema<any>;
|
||||||
|
};
|
||||||
|
data?: any;
|
||||||
|
/**
|
||||||
|
* 是否需要验证
|
||||||
|
*/
|
||||||
|
isVerify?: boolean;
|
||||||
|
/**
|
||||||
|
* 是否开启debug,开启后会打印错误信息
|
||||||
|
*/
|
||||||
|
isDebug?: boolean;
|
||||||
|
constructor(path: string, key?: string, opts?: RouteOpts);
|
||||||
|
private createSchema;
|
||||||
|
/**
|
||||||
|
* set validator and create schema
|
||||||
|
* @param validator
|
||||||
|
*/
|
||||||
|
set validator(validator: {
|
||||||
|
[key: string]: Rule;
|
||||||
|
});
|
||||||
|
get validator(): {
|
||||||
|
[key: string]: Rule;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* has code, body, message in ctx, return ctx if has error
|
||||||
|
* @param ctx
|
||||||
|
* @param dev
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
verify(ctx: RouteContext, dev?: boolean): void;
|
||||||
|
/**
|
||||||
|
* Need to manully call return ctx fn and configure body, code, message
|
||||||
|
* @param key
|
||||||
|
* @param ctx
|
||||||
|
* @param dev
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
verifyKey(key: string, ctx: RouteContext, dev?: boolean): {
|
||||||
|
message: string;
|
||||||
|
path: string;
|
||||||
|
key: string;
|
||||||
|
error: any;
|
||||||
|
} | {
|
||||||
|
message: string;
|
||||||
|
path: string;
|
||||||
|
key: string;
|
||||||
|
error?: undefined;
|
||||||
|
};
|
||||||
|
setValidator(validator: {
|
||||||
|
[key: string]: Rule;
|
||||||
|
}): this;
|
||||||
|
define<T extends {
|
||||||
|
[key: string]: any;
|
||||||
|
} = RouterContextT>(opts: DefineRouteOpts): this;
|
||||||
|
define<T extends {
|
||||||
|
[key: string]: any;
|
||||||
|
} = RouterContextT>(fn: Run<T & U>): this;
|
||||||
|
define<T extends {
|
||||||
|
[key: string]: any;
|
||||||
|
} = RouterContextT>(key: string, fn: Run<T & U>): this;
|
||||||
|
define<T extends {
|
||||||
|
[key: string]: any;
|
||||||
|
} = RouterContextT>(path: string, key: string, fn: Run<T & U>): this;
|
||||||
|
addTo(router: QueryRouter | {
|
||||||
|
add: (route: Route) => void;
|
||||||
|
[key: string]: any;
|
||||||
|
}): void;
|
||||||
|
setData(data: any): this;
|
||||||
|
throw(code?: number | string, message?: string, tips?: string): void;
|
||||||
|
}
|
||||||
|
declare class QueryRouter {
|
||||||
|
routes: Route[];
|
||||||
|
maxNextRoute: number;
|
||||||
|
context?: RouteContext;
|
||||||
|
constructor();
|
||||||
|
add(route: Route): void;
|
||||||
|
/**
|
||||||
|
* remove route by path and key
|
||||||
|
* @param route
|
||||||
|
*/
|
||||||
|
remove(route: Route | {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
}): void;
|
||||||
|
/**
|
||||||
|
* remove route by id
|
||||||
|
* @param uniqueId
|
||||||
|
*/
|
||||||
|
removeById(unique: string): void;
|
||||||
|
/**
|
||||||
|
* 执行route
|
||||||
|
* @param path
|
||||||
|
* @param key
|
||||||
|
* @param ctx
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
runRoute(path: string, key: string, ctx?: RouteContext): any;
|
||||||
|
/**
|
||||||
|
* 第一次执行
|
||||||
|
* @param message
|
||||||
|
* @param ctx
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
parse(message: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
/**
|
||||||
|
* 返回的数据包含所有的context的请求返回的内容,可做其他处理
|
||||||
|
* @param message
|
||||||
|
* @param ctx
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
call(message: {
|
||||||
|
id?: string;
|
||||||
|
path?: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
/**
|
||||||
|
* 请求 result 的数据
|
||||||
|
* @param message
|
||||||
|
* @param ctx
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
queryRoute(message: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<{
|
||||||
|
code: any;
|
||||||
|
data: any;
|
||||||
|
message: any;
|
||||||
|
}>;
|
||||||
|
setContext(ctx: RouteContext): Promise<void>;
|
||||||
|
getList(): RouteInfo[];
|
||||||
|
getHandle<T = any>(router: QueryRouter, wrapperFn?: HandleFn<T>, ctx?: RouteContext): (msg: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}, handleContext?: RouteContext) => Promise<{
|
||||||
|
[key: string]: any;
|
||||||
|
code: string;
|
||||||
|
data?: any;
|
||||||
|
message?: string;
|
||||||
|
} | {
|
||||||
|
code: any;
|
||||||
|
data: any;
|
||||||
|
message: any;
|
||||||
|
} | {
|
||||||
|
code: number;
|
||||||
|
message: any;
|
||||||
|
data?: undefined;
|
||||||
|
}>;
|
||||||
|
exportRoutes(): Route<{
|
||||||
|
[key: string]: any;
|
||||||
|
}>[];
|
||||||
|
importRoutes(routes: Route[]): void;
|
||||||
|
importRouter(router: QueryRouter): void;
|
||||||
|
throw(code?: number | string, message?: string, tips?: string): void;
|
||||||
|
hasRoute(path: string, key?: string): Route<{
|
||||||
|
[key: string]: any;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
type QueryRouterServerOpts = {
|
||||||
|
handleFn?: HandleFn;
|
||||||
|
context?: RouteContext;
|
||||||
|
};
|
||||||
|
interface HandleFn<T = any> {
|
||||||
|
(msg: {
|
||||||
|
path: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}, ctx?: any): {
|
||||||
|
code: string;
|
||||||
|
data?: any;
|
||||||
|
message?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
(res: RouteContext<T>): any;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* QueryRouterServer
|
||||||
|
* @description 移除server相关的功能,只保留router相关的功能,和http.createServer不相关,独立
|
||||||
|
*/
|
||||||
|
declare class QueryRouterServer extends QueryRouter {
|
||||||
|
handle: any;
|
||||||
|
constructor(opts?: QueryRouterServerOpts);
|
||||||
|
setHandle(wrapperFn?: HandleFn, ctx?: RouteContext): void;
|
||||||
|
use(path: string, fn: (ctx: any) => any, opts?: RouteOpts): void;
|
||||||
|
addRoute(route: Route): void;
|
||||||
|
Route: typeof Route;
|
||||||
|
route(opts: RouteOpts): Route<Required<RouteContext>>;
|
||||||
|
route(path: string, key?: string): Route<Required<RouteContext>>;
|
||||||
|
route(path: string, opts?: RouteOpts): Route<Required<RouteContext>>;
|
||||||
|
route(path: string, key?: string, opts?: RouteOpts): Route<Required<RouteContext>>;
|
||||||
|
/**
|
||||||
|
* 等于queryRoute,但是调用了handle
|
||||||
|
* @param param0
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
run({ path, key, payload }: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare class Connect {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
_fn?: (ctx?: RouteContext) => Promise<RouteContext>;
|
||||||
|
description?: string;
|
||||||
|
connects: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
}[];
|
||||||
|
share: boolean;
|
||||||
|
constructor(path: string);
|
||||||
|
use(path: string): void;
|
||||||
|
useList(paths: string[]): void;
|
||||||
|
useConnect(connect: Connect): void;
|
||||||
|
useConnectList(connects: Connect[]): void;
|
||||||
|
getPathList(): string[];
|
||||||
|
set fn(fn: (ctx?: RouteContext) => Promise<RouteContext>);
|
||||||
|
get fn(): (ctx?: RouteContext) => Promise<RouteContext>;
|
||||||
|
}
|
||||||
|
declare class QueryConnect {
|
||||||
|
connects: Connect[];
|
||||||
|
constructor();
|
||||||
|
add(connect: Connect): void;
|
||||||
|
remove(connect: Connect): void;
|
||||||
|
getList(): {
|
||||||
|
path: string;
|
||||||
|
key: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
type Listener = (...args: any[]) => void;
|
||||||
|
type CookieFn = (name: string, value: string, options?: cookie.SerializeOptions, end?: boolean) => void;
|
||||||
|
type HandleCtx = {
|
||||||
|
req: IncomingMessage & {
|
||||||
|
cookies: Record<string, string>;
|
||||||
|
};
|
||||||
|
res: ServerResponse & {
|
||||||
|
/**
|
||||||
|
* cookie 函数, end 参数用于设置是否立即设置到响应头,设置了后面的cookie再设置会覆盖前面的
|
||||||
|
*/
|
||||||
|
cookie: CookieFn;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
type Cors = {
|
||||||
|
/**
|
||||||
|
* @default '*''
|
||||||
|
*/
|
||||||
|
origin?: string | undefined;
|
||||||
|
};
|
||||||
|
type ServerOpts = {
|
||||||
|
/**path default `/api/router` */
|
||||||
|
path?: string;
|
||||||
|
/**handle Fn */
|
||||||
|
handle?: (msg?: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}, ctx?: {
|
||||||
|
req: http.IncomingMessage;
|
||||||
|
res: http.ServerResponse;
|
||||||
|
}) => any;
|
||||||
|
cors?: Cors;
|
||||||
|
httpType?: 'http' | 'https' | 'http2';
|
||||||
|
httpsKey?: string;
|
||||||
|
httpsCert?: string;
|
||||||
|
};
|
||||||
|
declare class Server {
|
||||||
|
path: string;
|
||||||
|
private _server;
|
||||||
|
handle: ServerOpts['handle'];
|
||||||
|
private _callback;
|
||||||
|
private cors;
|
||||||
|
private hasOn;
|
||||||
|
private httpType;
|
||||||
|
private options;
|
||||||
|
constructor(opts?: ServerOpts);
|
||||||
|
listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, hostname?: string, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, listeningListener?: () => void): void;
|
||||||
|
listen(path: string, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(path: string, listeningListener?: () => void): void;
|
||||||
|
listen(handle: any, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(handle: any, listeningListener?: () => void): void;
|
||||||
|
createServer(): http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | https.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | http2.Http2SecureServer<typeof http.IncomingMessage, typeof http.ServerResponse, typeof http2.Http2ServerRequest, typeof http2.Http2ServerResponse>;
|
||||||
|
setHandle(handle?: any): void;
|
||||||
|
/**
|
||||||
|
* get callback
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
createCallback(): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
||||||
|
get handleServer(): any;
|
||||||
|
set handleServer(fn: any);
|
||||||
|
/**
|
||||||
|
* 兜底监听,当除开 `/api/router` 之外的请求,框架只监听一个api,所以有其他的请求都执行其他的监听
|
||||||
|
* @description 主要是为了兼容其他的监听
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
on(listener: Listener | Listener[]): void;
|
||||||
|
get callback(): any;
|
||||||
|
get server(): http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | https.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | http2.Http2SecureServer<typeof http.IncomingMessage, typeof http.ServerResponse, typeof http2.Http2ServerRequest, typeof http2.Http2ServerResponse>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get params and body
|
||||||
|
* 优先原则
|
||||||
|
* 1. 请求参数中的 payload 的token 优先
|
||||||
|
* 2. 请求头中的 authorization 优先
|
||||||
|
* 3. 请求头中的 cookie 优先
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
declare const handleServer: (req: IncomingMessage, res: ServerResponse) => Promise<{
|
||||||
|
cookies: Record<string, string>;
|
||||||
|
token: string;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
/** 自定义错误 */
|
||||||
|
declare class CustomError extends Error {
|
||||||
|
code?: number;
|
||||||
|
data?: any;
|
||||||
|
message: string;
|
||||||
|
tips?: string;
|
||||||
|
constructor(code?: number | string, message?: string, tips?: string);
|
||||||
|
static fromCode(code?: number): CustomError;
|
||||||
|
static fromErrorData(code?: number, data?: any): CustomError;
|
||||||
|
static parseError(e: CustomError): {
|
||||||
|
code: number;
|
||||||
|
data: any;
|
||||||
|
message: string;
|
||||||
|
tips: string;
|
||||||
|
};
|
||||||
|
parse(e?: CustomError): {
|
||||||
|
code: number;
|
||||||
|
data: any;
|
||||||
|
message: string;
|
||||||
|
tips: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type WsServerBaseOpts = {
|
||||||
|
wss?: WebSocketServer;
|
||||||
|
path?: string;
|
||||||
|
};
|
||||||
|
type ListenerFn = (message: {
|
||||||
|
data: Record<string, any>;
|
||||||
|
ws: WebSocket;
|
||||||
|
end: (data: any) => any;
|
||||||
|
}) => Promise<any>;
|
||||||
|
declare class WsServerBase {
|
||||||
|
wss: WebSocketServer;
|
||||||
|
path: string;
|
||||||
|
listeners: {
|
||||||
|
type: string;
|
||||||
|
listener: ListenerFn;
|
||||||
|
}[];
|
||||||
|
listening: boolean;
|
||||||
|
constructor(opts: WsServerBaseOpts);
|
||||||
|
setPath(path: string): void;
|
||||||
|
listen(): void;
|
||||||
|
addListener(type: string, listener: ListenerFn): void;
|
||||||
|
removeListener(type: string): void;
|
||||||
|
}
|
||||||
|
declare class WsServer extends WsServerBase {
|
||||||
|
server: Server;
|
||||||
|
constructor(server: Server, opts?: any);
|
||||||
|
initListener(): void;
|
||||||
|
listen(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
type RouterHandle = (msg: {
|
||||||
|
path: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}) => {
|
||||||
|
code: string;
|
||||||
|
data?: any;
|
||||||
|
message?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
type AppOptions<T = {}> = {
|
||||||
|
router?: QueryRouter;
|
||||||
|
server?: Server;
|
||||||
|
/** handle msg 关联 */
|
||||||
|
routerHandle?: RouterHandle;
|
||||||
|
routerContext?: RouteContext<T>;
|
||||||
|
serverOptions?: ServerOpts;
|
||||||
|
io?: boolean;
|
||||||
|
ioOpts?: {
|
||||||
|
routerHandle?: RouterHandle;
|
||||||
|
routerContext?: RouteContext<T>;
|
||||||
|
path?: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
type AppReqRes = HandleCtx;
|
||||||
|
/**
|
||||||
|
* 封装了 Router 和 Server 的 App 模块,处理http的请求和响应,内置了 Cookie 和 Token 和 res 的处理
|
||||||
|
*/
|
||||||
|
declare class App<T = {}, U = AppReqRes> {
|
||||||
|
router: QueryRouter;
|
||||||
|
server: Server;
|
||||||
|
io: WsServer;
|
||||||
|
constructor(opts?: AppOptions<T>);
|
||||||
|
listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, hostname?: string, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, listeningListener?: () => void): void;
|
||||||
|
listen(path: string, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(path: string, listeningListener?: () => void): void;
|
||||||
|
listen(handle: any, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(handle: any, listeningListener?: () => void): void;
|
||||||
|
use(path: string, fn: (ctx: any) => any, opts?: RouteOpts): void;
|
||||||
|
addRoute(route: Route): void;
|
||||||
|
add: (route: Route) => void;
|
||||||
|
Route: typeof Route;
|
||||||
|
route(opts: RouteOpts): Route<U>;
|
||||||
|
route(path: string, key?: string): Route<U>;
|
||||||
|
route(path: string, opts?: RouteOpts): Route<U>;
|
||||||
|
route(path: string, key?: string, opts?: RouteOpts): Route<U>;
|
||||||
|
call(message: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
queryRoute(path: string, key?: string, payload?: any, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<{
|
||||||
|
code: any;
|
||||||
|
data: any;
|
||||||
|
message: any;
|
||||||
|
}>;
|
||||||
|
exportRoutes(): Route<{
|
||||||
|
[key: string]: any;
|
||||||
|
}>[];
|
||||||
|
importRoutes(routes: any[]): void;
|
||||||
|
importApp(app: App): void;
|
||||||
|
throw(code?: number | string, message?: string, tips?: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { App, Connect, CustomError, QueryConnect, QueryRouter, QueryRouterServer, Route, Server, createSchema, handleServer };
|
||||||
|
export type { RouteContext, RouteOpts, Rule, Run };
|
6
deno-router3/check-env.ts
Normal file
6
deno-router3/check-env.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
const isDeno = typeof Deno !== "undefined" && !!Deno.version;
|
||||||
|
const isNode = typeof process !== "undefined" && !!process.versions?.node;
|
||||||
|
|
||||||
|
console.log('process', process.version);
|
||||||
|
console.log("isDeno", isDeno);
|
||||||
|
console.log("isNode", isNode);
|
49
deno-router3/deno.json
Normal file
49
deno-router3/deno.json
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"tasks": {
|
||||||
|
"start": "deno run --allow-all index.ts",
|
||||||
|
"listen": "deno run --allow-all listen.ts"
|
||||||
|
},
|
||||||
|
"imports": {
|
||||||
|
"@kevisual/router/dist/router.js": "https://esm.sh/@kevisual/router@0.0.13/dist/router.js",
|
||||||
|
"@kevisual/router/router": "https://esm.sh/@kevisual/router@0.0.13/dist/router.js",
|
||||||
|
"@kevisual/router": "https://esm.sh/@kevisual/router@0.0.13/mod.ts?build=deno"
|
||||||
|
},
|
||||||
|
"compilerOptions": {
|
||||||
|
"types": [
|
||||||
|
"./types"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"fmt": {
|
||||||
|
"files": {
|
||||||
|
"include": [
|
||||||
|
"src/"
|
||||||
|
],
|
||||||
|
"exclude": []
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"lineWidth": 80,
|
||||||
|
"indentWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"singleQuote": false,
|
||||||
|
"proseWrap": "preserve"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"include": [
|
||||||
|
"./src/**/*.ts",
|
||||||
|
"index.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"./types"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"tags": [
|
||||||
|
"recommended"
|
||||||
|
],
|
||||||
|
"include": [],
|
||||||
|
"exclude": [
|
||||||
|
"require-await"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
78
deno-router3/deno.lock
generated
Normal file
78
deno-router3/deno.lock
generated
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"version": "4",
|
||||||
|
"specifiers": {
|
||||||
|
"jsr:@std/webgpu@*": "0.224.8",
|
||||||
|
"npm:@types/node@*": "22.12.0"
|
||||||
|
},
|
||||||
|
"jsr": {
|
||||||
|
"@std/webgpu@0.224.8": {
|
||||||
|
"integrity": "47c6bab2671dc7c36cb2505167cbf856bde1028be554f7be6463b30f51e4f8a3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"npm": {
|
||||||
|
"@types/node@22.12.0": {
|
||||||
|
"integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==",
|
||||||
|
"dependencies": [
|
||||||
|
"undici-types"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"undici-types@6.20.0": {
|
||||||
|
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"redirects": {
|
||||||
|
"https://esm.sh/@kevisual/router/mod.ts?build=deno": "https://esm.sh/@kevisual/router@0.0.13/mod.ts?build=deno",
|
||||||
|
"https://esm.sh/@kevisual/router/mod.ts?raw": "https://esm.sh/@kevisual/router@0.0.13/mod.ts?raw",
|
||||||
|
"https://esm.sh/@types/lodash-es@~4.17.12/index.d.ts": "https://esm.sh/@types/lodash-es@4.17.12/index.d.ts",
|
||||||
|
"https://esm.sh/@types/ws@~8.18.1/index.d.mts": "https://esm.sh/@types/ws@8.18.1/index.d.mts",
|
||||||
|
"https://esm.sh/@types/ws@~8.5.14/index.d.mts": "https://esm.sh/@types/ws@8.5.14/index.d.mts",
|
||||||
|
"https://esm.sh/bufferutil@^4.0.1?target=denonext": "https://esm.sh/bufferutil@4.0.9?target=denonext",
|
||||||
|
"https://esm.sh/cookie?target=denonext": "https://esm.sh/cookie@1.0.2?target=denonext",
|
||||||
|
"https://esm.sh/lodash-es?target=denonext": "https://esm.sh/lodash-es@4.17.21?target=denonext",
|
||||||
|
"https://esm.sh/nanoid?target=denonext": "https://esm.sh/nanoid@5.1.5?target=denonext",
|
||||||
|
"https://esm.sh/node-gyp-build@^4.3.0?target=denonext": "https://esm.sh/node-gyp-build@4.8.4?target=denonext",
|
||||||
|
"https://esm.sh/utf-8-validate@%3E=5.0.2?target=denonext": "https://esm.sh/utf-8-validate@6.0.5?target=denonext",
|
||||||
|
"https://esm.sh/ws?target=denonext": "https://esm.sh/ws@8.18.1?target=denonext",
|
||||||
|
"https://esm.sh/zod?target=denonext": "https://esm.sh/zod@3.24.3?target=denonext"
|
||||||
|
},
|
||||||
|
"remote": {
|
||||||
|
"https://esm.sh/@kevisual/router/dist/router.js": "e21ea4aa25ffe1881f5d7f5fd693092e61373ec75f49e18cd6cc9eae2414aa87",
|
||||||
|
"https://esm.sh/@kevisual/router@0.0.12/es2022/router.mjs": "ab943944d6b5ac7a1094908eb3ce1bdd702421f6b87b5f593a010f8df286a3ca",
|
||||||
|
"https://esm.sh/@kevisual/router@0.0.13/denonext/mod.ts.mjs": "c410c788ebf66e21cc46f3388983d986efa6c34d7865261d93636bb6b9ef1215",
|
||||||
|
"https://esm.sh/@kevisual/router@0.0.13/denonext/router.mjs": "582f85d04bff25c875bf8c5b34a5cda63bfe6bdb2455b0fafaa8cc398b6ca43a",
|
||||||
|
"https://esm.sh/@kevisual/router@0.0.13/dist/router.js": "2428e75cd75f1ed2ab133b1e14d79d1bcb331e90630730d56bd658ae24c26032",
|
||||||
|
"https://esm.sh/@kevisual/router@0.0.13/mod.ts?build=deno": "a22a2c1b416e615e10da854a89d027314a6deb8392102a9eb7cc97e119736dcd",
|
||||||
|
"https://esm.sh/bufferutil@4.0.9/denonext/bufferutil.mjs": "13dca4d5bb2c68cbe119f880fa3bd785b9a81a8e02e0834dae604b4b85295cd8",
|
||||||
|
"https://esm.sh/bufferutil@4.0.9?target=denonext": "e32574569ab438facfcc3f412c659b0719bbf05477136ca176938c9a3ac45125",
|
||||||
|
"https://esm.sh/cookie@1.0.2/denonext/cookie.mjs": "6c4f976d4d933ff2d7afc1f6ee7af134108c9858f5a2aadc6189084bd5972275",
|
||||||
|
"https://esm.sh/cookie@1.0.2?target=denonext": "04dabbcad7a7a96d841d6b21f00cb20191fb29339781237088d8edabad52df66",
|
||||||
|
"https://esm.sh/lodash-es@4.17.21/denonext/lodash-es.mjs": "83b25b8f85872b2805e6b0273c90d6c96960c80a710c55e89a7b399107fc6fa8",
|
||||||
|
"https://esm.sh/lodash-es@4.17.21?target=denonext": "1252ccd86311d14f2dd05282cf3e40e1ff76bfa79c71ca49b903e902129944cb",
|
||||||
|
"https://esm.sh/nanoid@5.1.5/denonext/nanoid.mjs": "dc919f2d7339a244f732a0cf02e3962dd1289535668026f52fb26bd593e9358b",
|
||||||
|
"https://esm.sh/nanoid@5.1.5?target=denonext": "33ad5b17f1290cb850164cfcf30f642d9dad489ba19909bc3cfd9eb78369f451",
|
||||||
|
"https://esm.sh/node-gyp-build@4.8.4/denonext/node-gyp-build.mjs": "9a86f2d044fc77bd60aaa3d697c2ba1b818da5fb1b9aaeedec59a40b8e908803",
|
||||||
|
"https://esm.sh/node-gyp-build@4.8.4?target=denonext": "261a6cedf1fdbf159798141ba1e2311ac1510682c5c8b55dacc8cf5fdee4aa06",
|
||||||
|
"https://esm.sh/node/async_hooks.mjs": "d4a1534a095d1f582630fd1a553aa0a4a7a18430e218436852fcae9b1832cf8c",
|
||||||
|
"https://esm.sh/node/buffer.mjs": "43d7ffab85c67adc0575a7d7c463e84a61ee8efc455d95665c8eb8d4a31e17cd",
|
||||||
|
"https://esm.sh/node/chunk-2OF3LYRV.mjs": "d7de750c968c3ecde19048322afb56c171047475c042de0d183d636ec2261f5a",
|
||||||
|
"https://esm.sh/node/chunk-6GKFKS3A.mjs": "7902e4736377601004f9c88d66082a4ed0ab5615b4cd922011215527721916ab",
|
||||||
|
"https://esm.sh/node/chunk-AAUDITJX.mjs": "bc58a1ed4be556edd5788a17f933332b5722308b4b20245d92fd94b0e8af7459",
|
||||||
|
"https://esm.sh/node/chunk-KJ4M6W4Z.mjs": "e758c20e0173250999825c305e42e2005ead5aae78927ccbd310d236254f434e",
|
||||||
|
"https://esm.sh/node/chunk-WV3DHSZU.mjs": "69325e3b23d7ea15773f164a4995f2c0052808db8479bc1b6ec6a1df39c33c1b",
|
||||||
|
"https://esm.sh/node/events.mjs": "583424d07fdbb9a1248bf5090098ac4107aebcbe512763e6f509e5e7667f1014",
|
||||||
|
"https://esm.sh/node/http.mjs": "b29aedee4b801bd589a38d38103fd417c75af732511610ae5f28204b7e76b919",
|
||||||
|
"https://esm.sh/node/http2.mjs": "40fe45808ad7a0c70d80dd9f2758d1691bd76c02419617b2be6f27354c0ab670",
|
||||||
|
"https://esm.sh/node/https.mjs": "190895efe5bf1d7cd734c77b755eab0768556c667e04328ed6627c628025633b",
|
||||||
|
"https://esm.sh/node/net.mjs": "bdc14e7b53ad5d7be43ef36a425f2cfdf723f3b72a2da2c0ddb71cadeac8d786",
|
||||||
|
"https://esm.sh/node/path.mjs": "cae9540da52fce2321292b45936e839f523cb70fea4166feea75b764ddcff7e3",
|
||||||
|
"https://esm.sh/node/querystring.mjs": "dedbd6385b2cb7999b4a245cc446100e3263e155ecdc51de07dbfda12907547b",
|
||||||
|
"https://esm.sh/node/stream.mjs": "135b4483eb457de5fd856fa174d7efdedc55e26847a1bdbdafb19035719e79e9",
|
||||||
|
"https://esm.sh/node/url.mjs": "74e9759ff9b2603b1f74134f1ae6d3844928245999314d7a88aceb81ed18454b",
|
||||||
|
"https://esm.sh/utf-8-validate@6.0.5/denonext/utf-8-validate.mjs": "66b8ea532a0c745068f5b96ddb1bae332c3036703243541d2e89e66331974d98",
|
||||||
|
"https://esm.sh/utf-8-validate@6.0.5?target=denonext": "071bc33ba1a58297e23a34d69dd589fd06df04b0f373b382ff5da544a623f271",
|
||||||
|
"https://esm.sh/ws@8.18.1/denonext/ws.mjs": "732cae76ba0acb311a561003d2f7ef569293cb9159d67dd800ab346b84f80432",
|
||||||
|
"https://esm.sh/ws@8.18.1?target=denonext": "e99b670fc49b38e15a7576ddcd5bb01e123fe9b3a017db7f97898127811b4e27",
|
||||||
|
"https://esm.sh/zod@3.24.3/denonext/zod.mjs": "46c4acb1f87caf349962b648f519cbf3999a8746fb40df0331ad2d3b62a197c0",
|
||||||
|
"https://esm.sh/zod@3.24.3?target=denonext": "8fb963869b1a83e910ff2fc4e64af7918e34b1350088455141b653233f274395"
|
||||||
|
}
|
||||||
|
}
|
15
deno-router3/gpu.ts
Normal file
15
deno-router3/gpu.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { createTextureWithData } from "jsr:@std/webgpu";
|
||||||
|
|
||||||
|
const adapter = await navigator.gpu.requestAdapter();
|
||||||
|
const device = await adapter?.requestDevice()!;
|
||||||
|
|
||||||
|
const texture = createTextureWithData(device, {
|
||||||
|
format: "bgra8unorm-srgb",
|
||||||
|
size: {
|
||||||
|
width: 3,
|
||||||
|
height: 2,
|
||||||
|
},
|
||||||
|
usage: GPUTextureUsage.COPY_SRC,
|
||||||
|
}, new Uint8Array([1, 1, 1, 1, 1, 1, 1]));
|
||||||
|
|
||||||
|
console.log(texture);
|
59
deno-router3/index.ts
Normal file
59
deno-router3/index.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// import { App } from "@kevisual/router";
|
||||||
|
import { App } from '@kevisual/router/router';
|
||||||
|
import path from 'node:path';
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import http, { Server } from 'node:http';
|
||||||
|
|
||||||
|
// https://esm.sh/@kevisual/router@0.0.12/dist/router.d.ts
|
||||||
|
// https://esm.sh/@kevisual/router@0.0.13/dist/router.d.ts
|
||||||
|
// https://esm.sh/@kevisual/router@0.0.13/dist/router.d.ts
|
||||||
|
console.log('meta', import.meta.url);
|
||||||
|
// deno run --allow-all index.ts
|
||||||
|
// deno run --config ./deno.json --allow-all index.ts
|
||||||
|
console.log('hello world');
|
||||||
|
|
||||||
|
const app = new App({
|
||||||
|
io: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
app
|
||||||
|
.route({
|
||||||
|
path: 'demo',
|
||||||
|
})
|
||||||
|
.define(async (ctx) => {
|
||||||
|
ctx.body = 'hello world';
|
||||||
|
})
|
||||||
|
.addTo(app);
|
||||||
|
|
||||||
|
const socketPath = path.resolve('/tmp/http-deno.sock');
|
||||||
|
// const socketPath = path.resolve(Deno.cwd(), './http.sock');
|
||||||
|
if (fs.existsSync(socketPath)) {
|
||||||
|
fs.unlinkSync(socketPath);
|
||||||
|
}
|
||||||
|
// app.listen(10004, () => {
|
||||||
|
// console.log('Server is running on http://localhost:10004');
|
||||||
|
// });
|
||||||
|
// process.umask(0); // 设置默认权限掩码
|
||||||
|
|
||||||
|
// app.listen(socketPath, () => {
|
||||||
|
// // console.log('Server is running on. \ncurl --unix-socket ./http-deno.sock http://localhost/api/router?path=demo');
|
||||||
|
// console.log('Server is running on. \ncurl --unix-socket /tmp/http-deno.sock http://localhost/api/router?path=demo');
|
||||||
|
// console.log(`Actual path: ${fs.realpathSync(socketPath)}`);
|
||||||
|
// });
|
||||||
|
|
||||||
|
const sv = app.server.server as Server;
|
||||||
|
sv.listen(socketPath, () => {
|
||||||
|
console.log('Server is running on. \ncurl --unix-socket /tmp/http-deno.sock http://localhost/api/router?path=demo');
|
||||||
|
console.log(`Actual path: ${fs.realpathSync(socketPath)}`);
|
||||||
|
});
|
||||||
|
app.server.server.on('error', (err) => {
|
||||||
|
console.error('error', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.io.addListener('goo', async ({ data, ws, end }) => {
|
||||||
|
console.log('goo', data);
|
||||||
|
end({
|
||||||
|
code: 200,
|
||||||
|
message: 'hello world goo',
|
||||||
|
});
|
||||||
|
});
|
34
deno-router3/listen.ts
Normal file
34
deno-router3/listen.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { createServer } from 'node:http';
|
||||||
|
import fs from 'node:fs';
|
||||||
|
|
||||||
|
const server = createServer((req, res) => {
|
||||||
|
res.end('Hello World');
|
||||||
|
});
|
||||||
|
|
||||||
|
const socketPath = '/tmp/http-listen.sock';
|
||||||
|
if (fs.existsSync(socketPath)) {
|
||||||
|
fs.unlinkSync(socketPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
server.listen(
|
||||||
|
{
|
||||||
|
path: socketPath,
|
||||||
|
transport: 'unix', // 指定传输方式为 Unix 套接字
|
||||||
|
port: 10004,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
console.log('Server is running on. \ncurl --unix-socket /tmp/http-listen.sock http://localhost/api/router?path=demo');
|
||||||
|
throw new Error('test');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Deno.serve(
|
||||||
|
// {
|
||||||
|
// path: socketPath,
|
||||||
|
// transport: 'unix',
|
||||||
|
// },
|
||||||
|
// async (req) => {
|
||||||
|
// console.log(req.url);
|
||||||
|
// return new Response('Hello World2');
|
||||||
|
// },
|
||||||
|
// );
|
618
deno-router3/types/router.d.ts
vendored
Normal file
618
deno-router3/types/router.d.ts
vendored
Normal file
@ -0,0 +1,618 @@
|
|||||||
|
import { Schema } from 'http://esm.xiongxiao.me/zod@3.24.3/index.d.ts';
|
||||||
|
export { Schema } from 'http://esm.xiongxiao.me/zod@3.24.3/index.d.ts';
|
||||||
|
import http, { IncomingMessage, ServerResponse } from 'node:http';
|
||||||
|
import https from 'node:https';
|
||||||
|
import http2 from 'node:http2';
|
||||||
|
import * as cookie from 'http://esm.xiongxiao.me/cookie@1.0.2/dist/index.d.ts';
|
||||||
|
import { WebSocketServer, WebSocket } from 'http://esm.xiongxiao.me/@types/ws@~8.18.1/index.d.mts';
|
||||||
|
|
||||||
|
type BaseRule = {
|
||||||
|
value?: any;
|
||||||
|
required?: boolean;
|
||||||
|
message?: string;
|
||||||
|
};
|
||||||
|
type RuleString = {
|
||||||
|
type: 'string';
|
||||||
|
minLength?: number;
|
||||||
|
maxLength?: number;
|
||||||
|
regex?: string;
|
||||||
|
} & BaseRule;
|
||||||
|
type RuleNumber = {
|
||||||
|
type: 'number';
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
} & BaseRule;
|
||||||
|
type RuleBoolean = {
|
||||||
|
type: 'boolean';
|
||||||
|
} & BaseRule;
|
||||||
|
type RuleArray = {
|
||||||
|
type: 'array';
|
||||||
|
items: Rule;
|
||||||
|
minItems?: number;
|
||||||
|
maxItems?: number;
|
||||||
|
} & BaseRule;
|
||||||
|
type RuleObject = {
|
||||||
|
type: 'object';
|
||||||
|
properties: {
|
||||||
|
[key: string]: Rule;
|
||||||
|
};
|
||||||
|
} & BaseRule;
|
||||||
|
type RuleAny = {
|
||||||
|
type: 'any';
|
||||||
|
} & BaseRule;
|
||||||
|
type Rule = RuleString | RuleNumber | RuleBoolean | RuleArray | RuleObject | RuleAny;
|
||||||
|
declare const createSchema: (rule: Rule) => Schema;
|
||||||
|
|
||||||
|
type RouterContextT = {
|
||||||
|
code?: number;
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
type RouteContext<T = {
|
||||||
|
code?: number;
|
||||||
|
}, S = any> = {
|
||||||
|
query?: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
/** return body */
|
||||||
|
body?: number | string | Object;
|
||||||
|
/** return code */
|
||||||
|
code?: number;
|
||||||
|
/** return msg */
|
||||||
|
message?: string;
|
||||||
|
state?: S;
|
||||||
|
currentPath?: string;
|
||||||
|
currentKey?: string;
|
||||||
|
currentRoute?: Route;
|
||||||
|
progress?: [[string, string]][];
|
||||||
|
nextQuery?: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
end?: boolean;
|
||||||
|
queryRouter?: QueryRouter;
|
||||||
|
error?: any;
|
||||||
|
/** 请求 route的返回结果,包函ctx */
|
||||||
|
call?: (message: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
[key: string]: any;
|
||||||
|
} | {
|
||||||
|
id: string;
|
||||||
|
apyload?: any;
|
||||||
|
[key: string]: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}) => Promise<any>;
|
||||||
|
/** 请求 route的返回结果,不包函ctx */
|
||||||
|
queryRoute?: (message: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}) => Promise<any>;
|
||||||
|
index?: number;
|
||||||
|
throw?: (code?: number | string, message?: string, tips?: string) => void;
|
||||||
|
/** 是否需要序列化 */
|
||||||
|
needSerialize?: boolean;
|
||||||
|
} & T;
|
||||||
|
type Run<T = any> = (ctx: RouteContext<T>) => Promise<typeof ctx | null | void>;
|
||||||
|
type NextRoute = Pick<Route, 'id' | 'path' | 'key'>;
|
||||||
|
type RouteOpts = {
|
||||||
|
path?: string;
|
||||||
|
key?: string;
|
||||||
|
id?: string;
|
||||||
|
run?: Run;
|
||||||
|
nextRoute?: NextRoute;
|
||||||
|
description?: string;
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
middleware?: Route[] | string[];
|
||||||
|
type?: 'route' | 'middleware';
|
||||||
|
/**
|
||||||
|
* validator: {
|
||||||
|
* packageName: {
|
||||||
|
* type: 'string',
|
||||||
|
* required: true,
|
||||||
|
* },
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
validator?: {
|
||||||
|
[key: string]: Rule;
|
||||||
|
};
|
||||||
|
schema?: {
|
||||||
|
[key: string]: Schema<any>;
|
||||||
|
};
|
||||||
|
isVerify?: boolean;
|
||||||
|
verify?: (ctx?: RouteContext, dev?: boolean) => boolean;
|
||||||
|
verifyKey?: (key: string, ctx?: RouteContext, dev?: boolean) => boolean;
|
||||||
|
/**
|
||||||
|
* $#$ will be used to split path and key
|
||||||
|
*/
|
||||||
|
idUsePath?: boolean;
|
||||||
|
isDebug?: boolean;
|
||||||
|
};
|
||||||
|
type DefineRouteOpts = Omit<RouteOpts, 'idUsePath' | 'verify' | 'verifyKey' | 'nextRoute'>;
|
||||||
|
declare const pickValue: readonly ["path", "key", "id", "description", "type", "validator", "middleware"];
|
||||||
|
type RouteInfo = Pick<Route, (typeof pickValue)[number]>;
|
||||||
|
declare class Route<U = {
|
||||||
|
[key: string]: any;
|
||||||
|
}> {
|
||||||
|
/**
|
||||||
|
* 一级路径
|
||||||
|
*/
|
||||||
|
path?: string;
|
||||||
|
/**
|
||||||
|
* 二级路径
|
||||||
|
*/
|
||||||
|
key?: string;
|
||||||
|
id?: string;
|
||||||
|
share?: boolean;
|
||||||
|
run?: Run;
|
||||||
|
nextRoute?: NextRoute;
|
||||||
|
description?: string;
|
||||||
|
metadata?: {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
middleware?: (Route | string)[];
|
||||||
|
type?: string;
|
||||||
|
private _validator?;
|
||||||
|
schema?: {
|
||||||
|
[key: string]: Schema<any>;
|
||||||
|
};
|
||||||
|
data?: any;
|
||||||
|
/**
|
||||||
|
* 是否需要验证
|
||||||
|
*/
|
||||||
|
isVerify?: boolean;
|
||||||
|
/**
|
||||||
|
* 是否开启debug,开启后会打印错误信息
|
||||||
|
*/
|
||||||
|
isDebug?: boolean;
|
||||||
|
constructor(path: string, key?: string, opts?: RouteOpts);
|
||||||
|
private createSchema;
|
||||||
|
/**
|
||||||
|
* set validator and create schema
|
||||||
|
* @param validator
|
||||||
|
*/
|
||||||
|
set validator(validator: {
|
||||||
|
[key: string]: Rule;
|
||||||
|
});
|
||||||
|
get validator(): {
|
||||||
|
[key: string]: Rule;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* has code, body, message in ctx, return ctx if has error
|
||||||
|
* @param ctx
|
||||||
|
* @param dev
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
verify(ctx: RouteContext, dev?: boolean): void;
|
||||||
|
/**
|
||||||
|
* Need to manully call return ctx fn and configure body, code, message
|
||||||
|
* @param key
|
||||||
|
* @param ctx
|
||||||
|
* @param dev
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
verifyKey(key: string, ctx: RouteContext, dev?: boolean): {
|
||||||
|
message: string;
|
||||||
|
path: string;
|
||||||
|
key: string;
|
||||||
|
error: any;
|
||||||
|
} | {
|
||||||
|
message: string;
|
||||||
|
path: string;
|
||||||
|
key: string;
|
||||||
|
error?: undefined;
|
||||||
|
};
|
||||||
|
setValidator(validator: {
|
||||||
|
[key: string]: Rule;
|
||||||
|
}): this;
|
||||||
|
define<T extends {
|
||||||
|
[key: string]: any;
|
||||||
|
} = RouterContextT>(opts: DefineRouteOpts): this;
|
||||||
|
define<T extends {
|
||||||
|
[key: string]: any;
|
||||||
|
} = RouterContextT>(fn: Run<T & U>): this;
|
||||||
|
define<T extends {
|
||||||
|
[key: string]: any;
|
||||||
|
} = RouterContextT>(key: string, fn: Run<T & U>): this;
|
||||||
|
define<T extends {
|
||||||
|
[key: string]: any;
|
||||||
|
} = RouterContextT>(path: string, key: string, fn: Run<T & U>): this;
|
||||||
|
addTo(router: QueryRouter | {
|
||||||
|
add: (route: Route) => void;
|
||||||
|
[key: string]: any;
|
||||||
|
}): void;
|
||||||
|
setData(data: any): this;
|
||||||
|
throw(code?: number | string, message?: string, tips?: string): void;
|
||||||
|
}
|
||||||
|
declare class QueryRouter {
|
||||||
|
routes: Route[];
|
||||||
|
maxNextRoute: number;
|
||||||
|
context?: RouteContext;
|
||||||
|
constructor();
|
||||||
|
add(route: Route): void;
|
||||||
|
/**
|
||||||
|
* remove route by path and key
|
||||||
|
* @param route
|
||||||
|
*/
|
||||||
|
remove(route: Route | {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
}): void;
|
||||||
|
/**
|
||||||
|
* remove route by id
|
||||||
|
* @param uniqueId
|
||||||
|
*/
|
||||||
|
removeById(unique: string): void;
|
||||||
|
/**
|
||||||
|
* 执行route
|
||||||
|
* @param path
|
||||||
|
* @param key
|
||||||
|
* @param ctx
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
runRoute(path: string, key: string, ctx?: RouteContext): any;
|
||||||
|
/**
|
||||||
|
* 第一次执行
|
||||||
|
* @param message
|
||||||
|
* @param ctx
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
parse(message: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
/**
|
||||||
|
* 返回的数据包含所有的context的请求返回的内容,可做其他处理
|
||||||
|
* @param message
|
||||||
|
* @param ctx
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
call(message: {
|
||||||
|
id?: string;
|
||||||
|
path?: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
/**
|
||||||
|
* 请求 result 的数据
|
||||||
|
* @param message
|
||||||
|
* @param ctx
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
queryRoute(message: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<{
|
||||||
|
code: any;
|
||||||
|
data: any;
|
||||||
|
message: any;
|
||||||
|
}>;
|
||||||
|
setContext(ctx: RouteContext): Promise<void>;
|
||||||
|
getList(): RouteInfo[];
|
||||||
|
getHandle<T = any>(router: QueryRouter, wrapperFn?: HandleFn<T>, ctx?: RouteContext): (msg: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}, handleContext?: RouteContext) => Promise<{
|
||||||
|
[key: string]: any;
|
||||||
|
code: string;
|
||||||
|
data?: any;
|
||||||
|
message?: string;
|
||||||
|
} | {
|
||||||
|
code: any;
|
||||||
|
data: any;
|
||||||
|
message: any;
|
||||||
|
} | {
|
||||||
|
code: number;
|
||||||
|
message: any;
|
||||||
|
data?: undefined;
|
||||||
|
}>;
|
||||||
|
exportRoutes(): Route<{
|
||||||
|
[key: string]: any;
|
||||||
|
}>[];
|
||||||
|
importRoutes(routes: Route[]): void;
|
||||||
|
importRouter(router: QueryRouter): void;
|
||||||
|
throw(code?: number | string, message?: string, tips?: string): void;
|
||||||
|
hasRoute(path: string, key?: string): Route<{
|
||||||
|
[key: string]: any;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
type QueryRouterServerOpts = {
|
||||||
|
handleFn?: HandleFn;
|
||||||
|
context?: RouteContext;
|
||||||
|
};
|
||||||
|
interface HandleFn<T = any> {
|
||||||
|
(msg: {
|
||||||
|
path: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}, ctx?: any): {
|
||||||
|
code: string;
|
||||||
|
data?: any;
|
||||||
|
message?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
(res: RouteContext<T>): any;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* QueryRouterServer
|
||||||
|
* @description 移除server相关的功能,只保留router相关的功能,和http.createServer不相关,独立
|
||||||
|
*/
|
||||||
|
declare class QueryRouterServer extends QueryRouter {
|
||||||
|
handle: any;
|
||||||
|
constructor(opts?: QueryRouterServerOpts);
|
||||||
|
setHandle(wrapperFn?: HandleFn, ctx?: RouteContext): void;
|
||||||
|
use(path: string, fn: (ctx: any) => any, opts?: RouteOpts): void;
|
||||||
|
addRoute(route: Route): void;
|
||||||
|
Route: typeof Route;
|
||||||
|
route(opts: RouteOpts): Route<Required<RouteContext>>;
|
||||||
|
route(path: string, key?: string): Route<Required<RouteContext>>;
|
||||||
|
route(path: string, opts?: RouteOpts): Route<Required<RouteContext>>;
|
||||||
|
route(path: string, key?: string, opts?: RouteOpts): Route<Required<RouteContext>>;
|
||||||
|
/**
|
||||||
|
* 等于queryRoute,但是调用了handle
|
||||||
|
* @param param0
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
run({ path, key, payload }: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare class Connect {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
_fn?: (ctx?: RouteContext) => Promise<RouteContext>;
|
||||||
|
description?: string;
|
||||||
|
connects: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
}[];
|
||||||
|
share: boolean;
|
||||||
|
constructor(path: string);
|
||||||
|
use(path: string): void;
|
||||||
|
useList(paths: string[]): void;
|
||||||
|
useConnect(connect: Connect): void;
|
||||||
|
useConnectList(connects: Connect[]): void;
|
||||||
|
getPathList(): string[];
|
||||||
|
set fn(fn: (ctx?: RouteContext) => Promise<RouteContext>);
|
||||||
|
get fn(): (ctx?: RouteContext) => Promise<RouteContext>;
|
||||||
|
}
|
||||||
|
declare class QueryConnect {
|
||||||
|
connects: Connect[];
|
||||||
|
constructor();
|
||||||
|
add(connect: Connect): void;
|
||||||
|
remove(connect: Connect): void;
|
||||||
|
getList(): {
|
||||||
|
path: string;
|
||||||
|
key: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
type Listener = (...args: any[]) => void;
|
||||||
|
type CookieFn = (name: string, value: string, options?: cookie.SerializeOptions, end?: boolean) => void;
|
||||||
|
type HandleCtx = {
|
||||||
|
req: IncomingMessage & {
|
||||||
|
cookies: Record<string, string>;
|
||||||
|
};
|
||||||
|
res: ServerResponse & {
|
||||||
|
/**
|
||||||
|
* cookie 函数, end 参数用于设置是否立即设置到响应头,设置了后面的cookie再设置会覆盖前面的
|
||||||
|
*/
|
||||||
|
cookie: CookieFn;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
type Cors = {
|
||||||
|
/**
|
||||||
|
* @default '*''
|
||||||
|
*/
|
||||||
|
origin?: string | undefined;
|
||||||
|
};
|
||||||
|
type ServerOpts = {
|
||||||
|
/**path default `/api/router` */
|
||||||
|
path?: string;
|
||||||
|
/**handle Fn */
|
||||||
|
handle?: (msg?: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}, ctx?: {
|
||||||
|
req: http.IncomingMessage;
|
||||||
|
res: http.ServerResponse;
|
||||||
|
}) => any;
|
||||||
|
cors?: Cors;
|
||||||
|
httpType?: 'http' | 'https' | 'http2';
|
||||||
|
httpsKey?: string;
|
||||||
|
httpsCert?: string;
|
||||||
|
};
|
||||||
|
declare class Server {
|
||||||
|
path: string;
|
||||||
|
private _server;
|
||||||
|
handle: ServerOpts['handle'];
|
||||||
|
private _callback;
|
||||||
|
private cors;
|
||||||
|
private hasOn;
|
||||||
|
private httpType;
|
||||||
|
private options;
|
||||||
|
constructor(opts?: ServerOpts);
|
||||||
|
listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, hostname?: string, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, listeningListener?: () => void): void;
|
||||||
|
listen(path: string, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(path: string, listeningListener?: () => void): void;
|
||||||
|
listen(handle: any, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(handle: any, listeningListener?: () => void): void;
|
||||||
|
createServer(): http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | https.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | http2.Http2SecureServer<typeof http.IncomingMessage, typeof http.ServerResponse, typeof http2.Http2ServerRequest, typeof http2.Http2ServerResponse>;
|
||||||
|
setHandle(handle?: any): void;
|
||||||
|
/**
|
||||||
|
* get callback
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
createCallback(): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
|
||||||
|
get handleServer(): any;
|
||||||
|
set handleServer(fn: any);
|
||||||
|
/**
|
||||||
|
* 兜底监听,当除开 `/api/router` 之外的请求,框架只监听一个api,所以有其他的请求都执行其他的监听
|
||||||
|
* @description 主要是为了兼容其他的监听
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
on(listener: Listener | Listener[]): void;
|
||||||
|
get callback(): any;
|
||||||
|
get server(): http.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | https.Server<typeof http.IncomingMessage, typeof http.ServerResponse> | http2.Http2SecureServer<typeof http.IncomingMessage, typeof http.ServerResponse, typeof http2.Http2ServerRequest, typeof http2.Http2ServerResponse>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get params and body
|
||||||
|
* 优先原则
|
||||||
|
* 1. 请求参数中的 payload 的token 优先
|
||||||
|
* 2. 请求头中的 authorization 优先
|
||||||
|
* 3. 请求头中的 cookie 优先
|
||||||
|
* @param req
|
||||||
|
* @param res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
declare const handleServer: (req: IncomingMessage, res: ServerResponse) => Promise<{
|
||||||
|
cookies: Record<string, string>;
|
||||||
|
token: string;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
/** 自定义错误 */
|
||||||
|
declare class CustomError extends Error {
|
||||||
|
code?: number;
|
||||||
|
data?: any;
|
||||||
|
message: string;
|
||||||
|
tips?: string;
|
||||||
|
constructor(code?: number | string, message?: string, tips?: string);
|
||||||
|
static fromCode(code?: number): CustomError;
|
||||||
|
static fromErrorData(code?: number, data?: any): CustomError;
|
||||||
|
static parseError(e: CustomError): {
|
||||||
|
code: number;
|
||||||
|
data: any;
|
||||||
|
message: string;
|
||||||
|
tips: string;
|
||||||
|
};
|
||||||
|
parse(e?: CustomError): {
|
||||||
|
code: number;
|
||||||
|
data: any;
|
||||||
|
message: string;
|
||||||
|
tips: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type WsServerBaseOpts = {
|
||||||
|
wss?: WebSocketServer;
|
||||||
|
path?: string;
|
||||||
|
};
|
||||||
|
type ListenerFn = (message: {
|
||||||
|
data: Record<string, any>;
|
||||||
|
ws: WebSocket;
|
||||||
|
end: (data: any) => any;
|
||||||
|
}) => Promise<any>;
|
||||||
|
declare class WsServerBase {
|
||||||
|
wss: WebSocketServer;
|
||||||
|
path: string;
|
||||||
|
listeners: {
|
||||||
|
type: string;
|
||||||
|
listener: ListenerFn;
|
||||||
|
}[];
|
||||||
|
listening: boolean;
|
||||||
|
constructor(opts: WsServerBaseOpts);
|
||||||
|
setPath(path: string): void;
|
||||||
|
listen(): void;
|
||||||
|
addListener(type: string, listener: ListenerFn): void;
|
||||||
|
removeListener(type: string): void;
|
||||||
|
}
|
||||||
|
declare class WsServer extends WsServerBase {
|
||||||
|
server: Server;
|
||||||
|
constructor(server: Server, opts?: any);
|
||||||
|
initListener(): void;
|
||||||
|
listen(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
type RouterHandle = (msg: {
|
||||||
|
path: string;
|
||||||
|
[key: string]: any;
|
||||||
|
}) => {
|
||||||
|
code: string;
|
||||||
|
data?: any;
|
||||||
|
message?: string;
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
type AppOptions<T = {}> = {
|
||||||
|
router?: QueryRouter;
|
||||||
|
server?: Server;
|
||||||
|
/** handle msg 关联 */
|
||||||
|
routerHandle?: RouterHandle;
|
||||||
|
routerContext?: RouteContext<T>;
|
||||||
|
serverOptions?: ServerOpts;
|
||||||
|
io?: boolean;
|
||||||
|
ioOpts?: {
|
||||||
|
routerHandle?: RouterHandle;
|
||||||
|
routerContext?: RouteContext<T>;
|
||||||
|
path?: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
type AppReqRes = HandleCtx;
|
||||||
|
/**
|
||||||
|
* 封装了 Router 和 Server 的 App 模块,处理http的请求和响应,内置了 Cookie 和 Token 和 res 的处理
|
||||||
|
*/
|
||||||
|
declare class App<T = {}, U = AppReqRes> {
|
||||||
|
router: QueryRouter;
|
||||||
|
server: Server;
|
||||||
|
io: WsServer;
|
||||||
|
constructor(opts?: AppOptions<T>);
|
||||||
|
listen(port: number, hostname?: string, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, hostname?: string, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(port: number, listeningListener?: () => void): void;
|
||||||
|
listen(path: string, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(path: string, listeningListener?: () => void): void;
|
||||||
|
listen(handle: any, backlog?: number, listeningListener?: () => void): void;
|
||||||
|
listen(handle: any, listeningListener?: () => void): void;
|
||||||
|
use(path: string, fn: (ctx: any) => any, opts?: RouteOpts): void;
|
||||||
|
addRoute(route: Route): void;
|
||||||
|
add: (route: Route) => void;
|
||||||
|
Route: typeof Route;
|
||||||
|
route(opts: RouteOpts): Route<U>;
|
||||||
|
route(path: string, key?: string): Route<U>;
|
||||||
|
route(path: string, opts?: RouteOpts): Route<U>;
|
||||||
|
route(path: string, key?: string, opts?: RouteOpts): Route<U>;
|
||||||
|
call(message: {
|
||||||
|
path: string;
|
||||||
|
key?: string;
|
||||||
|
payload?: any;
|
||||||
|
}, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<any>;
|
||||||
|
queryRoute(path: string, key?: string, payload?: any, ctx?: RouteContext & {
|
||||||
|
[key: string]: any;
|
||||||
|
}): Promise<{
|
||||||
|
code: any;
|
||||||
|
data: any;
|
||||||
|
message: any;
|
||||||
|
}>;
|
||||||
|
exportRoutes(): Route<{
|
||||||
|
[key: string]: any;
|
||||||
|
}>[];
|
||||||
|
importRoutes(routes: any[]): void;
|
||||||
|
importApp(app: App): void;
|
||||||
|
throw(code?: number | string, message?: string, tips?: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { App, Connect, CustomError, QueryConnect, QueryRouter, QueryRouterServer, Route, Server, createSchema, handleServer };
|
||||||
|
export type { RouteContext, RouteOpts, Rule, Run };
|
5
deno-server/server.ts
Normal file
5
deno-server/server.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
const server = Deno.serve(async (req) => {
|
||||||
|
return new Response('Hello, World!');
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(server);
|
30
deno-server/ws-server.ts
Normal file
30
deno-server/ws-server.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// 创建 HTTP 服务器
|
||||||
|
const server = Deno.serve({ port: 8080 }, (req) => {
|
||||||
|
if (req.headers.get('upgrade') === 'websocket') {
|
||||||
|
const { socket, response } = Deno.upgradeWebSocket(req);
|
||||||
|
socket.addEventListener('open', () => {
|
||||||
|
console.log('a client connected!');
|
||||||
|
});
|
||||||
|
socket.addEventListener('message', (event) => {
|
||||||
|
if (event.data === 'ping') {
|
||||||
|
socket.send('pong');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
return new Response('HTTP server running', {
|
||||||
|
status: 200,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 注释掉有问题的代码,使用上面的 Deno.serve API
|
||||||
|
// const server2 = Deno.listen({ port: 8080 });
|
||||||
|
//
|
||||||
|
// for await (const conn of server2) {
|
||||||
|
// const httpConn = Deno.serveHttp(conn);
|
||||||
|
// for await (const requestEvent of httpConn) {
|
||||||
|
// console.log(requestEvent);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
console.log('WebSocket server running on http://localhost:8080');
|
33
deno.json
Normal file
33
deno.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": [
|
||||||
|
"deno.window"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tasks": {
|
||||||
|
"start": "deno run --allow-net deno-server/server.ts"
|
||||||
|
},
|
||||||
|
"imports": {
|
||||||
|
"http/": "https://deno.land/std@0.220.1/http/"
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"include": [
|
||||||
|
"./src/**/*.ts",
|
||||||
|
"index.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"./types"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"tags": [
|
||||||
|
"recommended"
|
||||||
|
],
|
||||||
|
"include": [],
|
||||||
|
"exclude": [
|
||||||
|
"require-await",
|
||||||
|
"no-explicit-any",
|
||||||
|
"unused-vars"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
44
deno.lock
generated
Normal file
44
deno.lock
generated
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"version": "4",
|
||||||
|
"remote": {
|
||||||
|
"https://deno.land/std@0.200.0/async/delay.ts": "a6142eb44cdd856b645086af2b811b1fcce08ec06bb7d50969e6a872ee9b8659",
|
||||||
|
"https://deno.land/std@0.200.0/http/server.ts": "1b2403b3c544c0624ad23e8ca4e05877e65380d9e0d75d04957432d65c3d5f41",
|
||||||
|
"https://deno.land/std@0.92.0/_util/assert.ts": "2f868145a042a11d5ad0a3c748dcf580add8a0dbc0e876eaa0026303a5488f58",
|
||||||
|
"https://deno.land/std@0.92.0/_util/has_own_property.ts": "f5edd94ed3f3c20c517d812045deb97977e18501c9b7105b5f5c11a31893d7a2",
|
||||||
|
"https://deno.land/std@0.92.0/async/deferred.ts": "624bef4b755b71394620508a0c234a93cb8020cbd1b04bfcdad41c174392cef6",
|
||||||
|
"https://deno.land/std@0.92.0/async/delay.ts": "9de1d8d07d1927767ab7f82434b883f3d8294fb19cad819691a2ad81a728cf3d",
|
||||||
|
"https://deno.land/std@0.92.0/async/mod.ts": "253b41c658d768613eacfb11caa0a9ca7148442f932018a45576f7f27554c853",
|
||||||
|
"https://deno.land/std@0.92.0/async/mux_async_iterator.ts": "b9091909db04cdb0af6f7807677372f64c1488de6c4bd86004511b064bf230d6",
|
||||||
|
"https://deno.land/std@0.92.0/async/pool.ts": "876f9e6815366cd017a3b4fbb9e9ae40310b1b6972f1bd541c94358bc11fb7e5",
|
||||||
|
"https://deno.land/std@0.92.0/bytes/mod.ts": "1ae1ccfe98c4b979f12b015982c7444f81fcb921bea7aa215bf37d84f46e1e13",
|
||||||
|
"https://deno.land/std@0.92.0/fmt/colors.ts": "db22b314a2ae9430ae7460ce005e0a7130e23ae1c999157e3bb77cf55800f7e4",
|
||||||
|
"https://deno.land/std@0.92.0/hash/sha1.ts": "1cca324b4b253885a47f121adafcfac55b4cc96113e22b338e1db26f37a730b8",
|
||||||
|
"https://deno.land/std@0.92.0/http/_io.ts": "bf1331dd3be8aace9120614c1fedc2bb2449edc4779e31b74c0181ea9173f702",
|
||||||
|
"https://deno.land/std@0.92.0/http/http_status.ts": "ebaa9bebfb8adc3d7b20c49e11037e4eefd79629ad80d81383933f4cdc91b3eb",
|
||||||
|
"https://deno.land/std@0.92.0/http/server.ts": "d4e17c2aa5a5c65a2d19b9f24483be5f6c2a3e03665996fdf973e53c43091b48",
|
||||||
|
"https://deno.land/std@0.92.0/io/buffer.ts": "2a92f02c1d8daaebaf13e5678ea5969c89f4fab533f687b9e7e86f49f11c3118",
|
||||||
|
"https://deno.land/std@0.92.0/io/bufio.ts": "4053ea5d978479be68ae4d73424045a59c6b7a6e8f66727e4bfde516baa07126",
|
||||||
|
"https://deno.land/std@0.92.0/io/ioutil.ts": "275fa440494df9b4b3aa656301ced2eeac533feec128b3a39b2b40f4cd957e42",
|
||||||
|
"https://deno.land/std@0.92.0/io/util.ts": "03ca10e063afce551c501505c607ec336a40b9cb72363f5508e2a9ac81096bbf",
|
||||||
|
"https://deno.land/std@0.92.0/node/_utils.ts": "33b06f2877d3ee80f17190ee81fdc436755ce74b9c2a9a4492c7cdfe2a03e4c6",
|
||||||
|
"https://deno.land/std@0.92.0/node/events.ts": "0feda0707e2229363f5df8b799fed41bb91de6ca7106f27c7a9f0a02ea11b9d4",
|
||||||
|
"https://deno.land/std@0.92.0/testing/_diff.ts": "961eaf6d9f5b0a8556c9d835bbc6fa74f5addd7d3b02728ba7936ff93364f7a3",
|
||||||
|
"https://deno.land/std@0.92.0/testing/asserts.ts": "83889f9a37bdab16cb68b023a15f9172ceb644f62c0e727c72d4870a666e53d6",
|
||||||
|
"https://deno.land/std@0.92.0/textproto/mod.ts": "1c89b39a079dd158893ab2e9ff79391c66049433d6ca82da7d64b32280570d51",
|
||||||
|
"https://deno.land/std@0.92.0/ws/mod.ts": "bc521b3066441eb115ac94e3507bcc73098542f81d8d3ce7aad8d837316ce990",
|
||||||
|
"https://deno.land/x/websocket@v0.1.4/deps.ts": "1299887e27e09209d2eedc5c3b6552090842fac9e08f00dd235de39219efbd42",
|
||||||
|
"https://deno.land/x/websocket@v0.1.4/lib/errors.ts": "efb2251dac1ac2036809b0bfb520d737aee70e362eba1e287c84d5299fb211e8",
|
||||||
|
"https://deno.land/x/websocket@v0.1.4/lib/websocket.ts": "3363e0a8f59284de5439f5f3bd8831b65a2cfba047113fbc72e32934ebec3208",
|
||||||
|
"https://deno.land/x/websocket@v0.1.4/mod.ts": "6b24e14dd1c5d64c1671dd678ca545cce9e2ebc91f67e8be864069808b948267"
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"packageJson": {
|
||||||
|
"dependencies": [
|
||||||
|
"npm:@kevisual/router@^0.0.10",
|
||||||
|
"npm:@kevisual/use-config@^1.0.10",
|
||||||
|
"npm:pino-pretty@13",
|
||||||
|
"npm:pino@^9.6.0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,7 +12,7 @@
|
|||||||
"packageManager": "pnpm@10.6.2",
|
"packageManager": "pnpm@10.6.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@kevisual/router": "^0.0.10",
|
"@kevisual/router": "^0.0.13",
|
||||||
"@kevisual/use-config": "^1.0.10",
|
"@kevisual/use-config": "^1.0.10",
|
||||||
"pino": "^9.6.0",
|
"pino": "^9.6.0",
|
||||||
"pino-pretty": "^13.0.0"
|
"pino-pretty": "^13.0.0"
|
||||||
|
28
pnpm-lock.yaml
generated
28
pnpm-lock.yaml
generated
@ -9,8 +9,8 @@ importers:
|
|||||||
.:
|
.:
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@kevisual/router':
|
'@kevisual/router':
|
||||||
specifier: ^0.0.10
|
specifier: ^0.0.13
|
||||||
version: 0.0.10
|
version: 0.0.13
|
||||||
'@kevisual/use-config':
|
'@kevisual/use-config':
|
||||||
specifier: ^1.0.10
|
specifier: ^1.0.10
|
||||||
version: 1.0.10(dotenv@16.5.0)
|
version: 1.0.10(dotenv@16.5.0)
|
||||||
@ -26,8 +26,8 @@ packages:
|
|||||||
'@kevisual/load@0.0.4':
|
'@kevisual/load@0.0.4':
|
||||||
resolution: {integrity: sha512-TJBieKsEoEPfP4+tDyhNZdMX2LMAGiDZ/IrAXPFWB4jeFP0Ywm1W5xDV52LhhHq4nwTmuhyTVmPxJYiEVYTHtA==}
|
resolution: {integrity: sha512-TJBieKsEoEPfP4+tDyhNZdMX2LMAGiDZ/IrAXPFWB4jeFP0Ywm1W5xDV52LhhHq4nwTmuhyTVmPxJYiEVYTHtA==}
|
||||||
|
|
||||||
'@kevisual/router@0.0.10':
|
'@kevisual/router@0.0.13':
|
||||||
resolution: {integrity: sha512-prQGiMIboQhDNN1Eubp8x7YDyRCmAsUqpHQwzfu9f7WvgisVWSLOWSaLbqjqNssV2xcc1DgVrHIKdLhbx8HCqQ==}
|
resolution: {integrity: sha512-raji8aKXr0jigmJVOKBXb5gpstiAuyoIDy9m6SyPf4lRjCU3pspVI1bpscOUCBlaPICo6TLzPQxXhyTvvvtdWw==}
|
||||||
|
|
||||||
'@kevisual/use-config@1.0.10':
|
'@kevisual/use-config@1.0.10':
|
||||||
resolution: {integrity: sha512-fH2B4BnR4+OjR3PzAegF8H9RJpyFZu6BnVDyfvSSZavZMurufkJ949jizoRde+bNAHff/PRcpa5EZg2imZNf1g==}
|
resolution: {integrity: sha512-fH2B4BnR4+OjR3PzAegF8H9RJpyFZu6BnVDyfvSSZavZMurufkJ949jizoRde+bNAHff/PRcpa5EZg2imZNf1g==}
|
||||||
@ -153,32 +153,16 @@ packages:
|
|||||||
wrappy@1.0.2:
|
wrappy@1.0.2:
|
||||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||||
|
|
||||||
ws@8.18.1:
|
|
||||||
resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==}
|
|
||||||
engines: {node: '>=10.0.0'}
|
|
||||||
peerDependencies:
|
|
||||||
bufferutil: ^4.0.1
|
|
||||||
utf-8-validate: '>=5.0.2'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
bufferutil:
|
|
||||||
optional: true
|
|
||||||
utf-8-validate:
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@kevisual/load@0.0.4':
|
'@kevisual/load@0.0.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
eventemitter3: 5.0.1
|
eventemitter3: 5.0.1
|
||||||
|
|
||||||
'@kevisual/router@0.0.10':
|
'@kevisual/router@0.0.13':
|
||||||
dependencies:
|
dependencies:
|
||||||
path-to-regexp: 8.2.0
|
path-to-regexp: 8.2.0
|
||||||
selfsigned: 2.4.1
|
selfsigned: 2.4.1
|
||||||
ws: 8.18.1
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- bufferutil
|
|
||||||
- utf-8-validate
|
|
||||||
|
|
||||||
'@kevisual/use-config@1.0.10(dotenv@16.5.0)':
|
'@kevisual/use-config@1.0.10(dotenv@16.5.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -300,5 +284,3 @@ snapshots:
|
|||||||
undici-types@6.21.0: {}
|
undici-types@6.21.0: {}
|
||||||
|
|
||||||
wrappy@1.0.2: {}
|
wrappy@1.0.2: {}
|
||||||
|
|
||||||
ws@8.18.1: {}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user