add init demos
This commit is contained in:
25
server/.gitignore
vendored
Normal file
25
server/.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
node_modules
|
||||
|
||||
dist
|
||||
|
||||
app.config.json5
|
||||
|
||||
apps.config.json
|
||||
|
||||
deploy.tar.gz
|
||||
cache-file
|
||||
|
||||
/apps
|
||||
|
||||
logs
|
||||
|
||||
release/*
|
||||
!release/.gitkeep
|
||||
|
||||
.turbo
|
||||
|
||||
.env*
|
||||
!.env.example
|
||||
|
||||
pack-dist
|
||||
app.config.json5.envision
|
||||
@@ -8,6 +8,7 @@ const external = ['sequelize', 'pg', 'ioredis', 'pm2'];
|
||||
/**
|
||||
* @type {import('bun').BuildConfig}
|
||||
*/
|
||||
// @ts-ignore
|
||||
await Bun.build({
|
||||
target: 'node',
|
||||
format: 'esm',
|
||||
|
||||
24
server/code/root/light-code-demo/main.ts
Normal file
24
server/code/root/light-code-demo/main.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { QueryRouterServer } from "@kevisual/router";
|
||||
|
||||
const app = new QueryRouterServer();
|
||||
|
||||
app.route({
|
||||
path: 'main'
|
||||
}).define(async (ctx) => {
|
||||
ctx.body = {
|
||||
message: 'this is main. filename: root/light-code-demo/main.ts',
|
||||
params: ctx.query
|
||||
}
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'main2'
|
||||
}).define(async (ctx) => {
|
||||
ctx.body = {
|
||||
message: 'this is main2. filename: root/light-code-demo/main.ts',
|
||||
params: ctx.query
|
||||
}
|
||||
}).addTo(app)
|
||||
|
||||
|
||||
app.wait()
|
||||
46
server/code/root/light-code-demo/sign.ts
Normal file
46
server/code/root/light-code-demo/sign.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { QueryRouterServer as Mini } from "@kevisual/router";
|
||||
import { NocoApi } from "@kevisual/noco";
|
||||
const config = {
|
||||
NOCODB_URL: process.env.NOCODB_URL || 'https://nocodb.xiongxiao.me',
|
||||
NOCODB_API_KEY: process.env.NOCODB_API_KEY || 'uca1Zx3p_0pnNUBV6ot9mBP6JCPqQ0X1TF3N3R7s'
|
||||
}
|
||||
const table = 'mcby44q8zrayvn9'
|
||||
const nocoAPi = new NocoApi({
|
||||
baseURL: config.NOCODB_URL,
|
||||
token: config.NOCODB_API_KEY,
|
||||
table,
|
||||
});
|
||||
console.log('nocoAPi', await nocoAPi.record.list())
|
||||
const app = new Mini();
|
||||
|
||||
|
||||
app.route({
|
||||
path: 'sign'
|
||||
}).define(async (ctx) => {
|
||||
const { Title, Description } = ctx.query
|
||||
// 这里可以处理签到
|
||||
await nocoAPi.record.create({ Title, Description })
|
||||
const list = await nocoAPi.record.list({ sort: '-CreatedAt' })
|
||||
ctx.body = { message: '签到成功', list }
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'sign',
|
||||
key: 'list'
|
||||
}).define(async (ctx) => {
|
||||
// 这里可以处理签到
|
||||
ctx.body = await nocoAPi.record.list()
|
||||
}).addTo(app)
|
||||
|
||||
app.route({
|
||||
path: 'sign',
|
||||
key: 'delete'
|
||||
}).define(async (ctx) => {
|
||||
const { id } = ctx.query
|
||||
// 这里可以处理签到
|
||||
await nocoAPi.record.delete({ Id: id })
|
||||
const list = await nocoAPi.record.list({ sort: '-CreatedAt' })
|
||||
ctx.body = { message: '删除成功', list }
|
||||
}).addTo(app)
|
||||
|
||||
app.wait()
|
||||
56
server/code/root/light-code-demo/weather.ts
Normal file
56
server/code/root/light-code-demo/weather.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
const weatherHost = 'n65khufe5n.re.qweatherapi.com';
|
||||
const token = 'fdad5aeb2ba54949a8a1df2a0f3d1efb'
|
||||
const xihu = '101210113'; // 西湖
|
||||
export const getWeather = async (location: string = xihu) => {
|
||||
const url = `https://${weatherHost}/v7/weather/3d?location=${location}`;
|
||||
const headers = {
|
||||
'Authorization': `Bearer ${token}`
|
||||
};
|
||||
const res = await fetch(url, { headers });
|
||||
if (!res.ok) {
|
||||
throw new Error(`HTTP error! status: ${res.status}`);
|
||||
}
|
||||
const data = await res.json();
|
||||
return data;
|
||||
}
|
||||
// getWeather().then(console.log).catch(console.error);
|
||||
|
||||
// https://dev.qweather.com/
|
||||
class Weather {
|
||||
host: string;
|
||||
token: string;
|
||||
constructor(opts: { host: string; token: string }) {
|
||||
this.host = opts.host;
|
||||
this.token = opts.token;
|
||||
console.log(this.host, this.token);
|
||||
}
|
||||
getWeather(location: string) {
|
||||
return fetch(`https://${this.host}/v7/weather/now?location=${location}`, {
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-QW-Api-Key': '<KEY>'.replace('<KEY>', this.token),
|
||||
},
|
||||
}).then((res) => res.json());
|
||||
}
|
||||
}
|
||||
const newWeather = new Weather({
|
||||
host: process.env?.QWEATHER_HOST || weatherHost,
|
||||
token: process.env?.QWEATHER_TOKEN || token,
|
||||
});
|
||||
|
||||
|
||||
// newWeather.getWeather(xihu).then(console.log).catch(console.error);
|
||||
|
||||
|
||||
import { QueryRouterServer as Mini } from "@kevisual/router";
|
||||
|
||||
const app = new Mini();
|
||||
|
||||
app.route({
|
||||
path: 'main'
|
||||
}).define(async (ctx) => {
|
||||
ctx.body = await newWeather.getWeather(xihu);
|
||||
}).addTo(app)
|
||||
|
||||
|
||||
app.wait()
|
||||
@@ -1,10 +1,9 @@
|
||||
import fs from 'node:fs'
|
||||
const main = () => {
|
||||
const random = Math.random().toString(36).slice(-6)
|
||||
return 'hello a' + random
|
||||
return 'hello a ' + random
|
||||
}
|
||||
|
||||
fs.writeFileSync('./a.txt', main() + '\n', { flag: 'a' })
|
||||
// fs.writeFileSync('./a.txt', main() + '\n', { flag: 'a' })
|
||||
console.log('pwd', process.cwd())
|
||||
// const value = fs.readFileSync('./bun.config.ts', 'utf-8')
|
||||
// console.log('a.txt 内容:', value)
|
||||
@@ -29,10 +28,10 @@ const listen = async () => {
|
||||
|
||||
// 发送结果回主进程
|
||||
const response = {
|
||||
success: true,
|
||||
foo: 'bar',
|
||||
params,
|
||||
main: result,
|
||||
success: true,
|
||||
data: { code: 200, data: result },
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
|
||||
14
server/code/root/listen-demo/router.ts
Normal file
14
server/code/root/listen-demo/router.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { QueryRouterServer } from "@kevisual/router";
|
||||
|
||||
const app = new QueryRouterServer();
|
||||
|
||||
app.route({
|
||||
path: 'main'
|
||||
}).define(async (ctx) => {
|
||||
ctx.body = {
|
||||
message: 'this is main. filename: root/listen-demo/router.ts',
|
||||
params: ctx.query
|
||||
}
|
||||
}).addTo(app)
|
||||
|
||||
app.wait()
|
||||
1
server/demo/test/a/index.html
Normal file
1
server/demo/test/a/index.html
Normal file
@@ -0,0 +1 @@
|
||||
测试静态页面
|
||||
@@ -5,6 +5,7 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "bun run --watch --hot src/index.ts",
|
||||
"start": "bun run src/index.ts",
|
||||
"build": "NODE_ENV=production bun bun.config.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
@@ -13,12 +14,14 @@
|
||||
"packageManager": "pnpm@10.16.1",
|
||||
"type": "module",
|
||||
"devDependencies": {
|
||||
"@kevisual/local-proxy": "^0.0.6",
|
||||
"@kevisual/types": "^0.0.10",
|
||||
"@kevisual/use-config": "^1.0.19",
|
||||
"@types/bun": "^1.3.0",
|
||||
"bun": "^1.3.0"
|
||||
"@types/bun": "^1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@kevisual/router": "^0.0.28"
|
||||
"@kevisual/noco": "^0.0.1",
|
||||
"@kevisual/router": "^0.0.29",
|
||||
"fast-glob": "^3.3.3"
|
||||
}
|
||||
}
|
||||
3
server/src/app.ts
Normal file
3
server/src/app.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { App } from '@kevisual/router'
|
||||
|
||||
export const app = new App()
|
||||
@@ -1,38 +0,0 @@
|
||||
import { App } from '@kevisual/router'
|
||||
import { fork } from 'child_process'
|
||||
const app = new App()
|
||||
import path from 'path'
|
||||
|
||||
// http://localhost:3000/api/router?path=call
|
||||
app.route({
|
||||
path: 'call'
|
||||
}).define(async (ctx) => {
|
||||
ctx.body = 'Hello World'
|
||||
const pwd = process.cwd()
|
||||
const testA = path.join(pwd, 'src/test/a.ts')
|
||||
const child = fork(testA, {
|
||||
})
|
||||
console.log('Child process started with PID:', child.pid)
|
||||
child.on('message', (msg) => {
|
||||
console.log('Message from child', msg)
|
||||
setTimeout(() => {
|
||||
console.log('child process connected:', child.connected)
|
||||
console.log('child process killed:', child.killed)
|
||||
console.log('child process exit code:', child.exitCode)
|
||||
}, 20)
|
||||
})
|
||||
|
||||
child.on('exit', (code, signal) => {
|
||||
console.log('子进程已退出,退出码:', code, '信号:', signal)
|
||||
})
|
||||
|
||||
child.on('close', (code, signal) => {
|
||||
console.log('子进程已关闭,退出码:', code, '信号:', signal)
|
||||
})
|
||||
child.send({ hello: 'world' })
|
||||
|
||||
}).addTo(app)
|
||||
|
||||
app.listen(3000, () => {
|
||||
console.log('Server is running on http://localhost:3000')
|
||||
})
|
||||
@@ -1,51 +1,16 @@
|
||||
import { App } from '@kevisual/router'
|
||||
import { fork } from 'child_process'
|
||||
const app = new App()
|
||||
import path from 'path'
|
||||
import { proxyRoute, initProxy } from '@kevisual/local-proxy/proxy.ts';
|
||||
// http://localhost:4005/test/a/index.html
|
||||
initProxy({
|
||||
pagesDir: './demo',
|
||||
watch: true,
|
||||
});
|
||||
|
||||
// http://localhost:3000/api/router?path=call
|
||||
app.route({
|
||||
path: 'call'
|
||||
}).define(async (ctx) => {
|
||||
ctx.body = 'Hello World'
|
||||
const pwd = process.cwd()
|
||||
const testA = path.join(pwd, 'src/test/a.ts')
|
||||
import { app } from './app.ts'
|
||||
import './routes/index.ts'
|
||||
|
||||
// 使用 Bun 的 fork 模式启动子进程
|
||||
const child = fork(testA, [], {
|
||||
execArgv: [],
|
||||
cwd: "/tmp", // 限制工作目录
|
||||
})
|
||||
|
||||
console.log('Child process started with PID:', child.pid)
|
||||
app.listen(4005, () => {
|
||||
console.log('Server is running on http://localhost:4005')
|
||||
})
|
||||
|
||||
// 监听来自子进程的消息
|
||||
child.on('message', (msg) => {
|
||||
console.log('Message from child:', msg)
|
||||
setTimeout(() => {
|
||||
console.log('child process connected:', child.connected)
|
||||
console.log('child process killed:', child.killed)
|
||||
console.log('child process exit code:', child.exitCode)
|
||||
}, 20)
|
||||
})
|
||||
|
||||
child.on('exit', (code, signal) => {
|
||||
console.log('子进程已退出,退出码:', code, '信号:', signal)
|
||||
})
|
||||
|
||||
child.on('close', (code, signal) => {
|
||||
console.log('子进程已关闭,退出码:', code, '信号:', signal)
|
||||
})
|
||||
|
||||
child.on('error', (error) => {
|
||||
console.error('子进程错误:', error)
|
||||
})
|
||||
|
||||
// 向子进程发送消息
|
||||
child.send({ hello: 'world' })
|
||||
|
||||
}).addTo(app)
|
||||
|
||||
app.listen(3000, () => {
|
||||
console.log('Server is running on http://localhost:3000')
|
||||
})
|
||||
app.onServerRequest(proxyRoute);
|
||||
50
server/src/modules/run-code/run.ts
Normal file
50
server/src/modules/run-code/run.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { fork } from 'child_process'
|
||||
|
||||
export type RunCodeParams = {
|
||||
path?: string;
|
||||
key?: string;
|
||||
payload?: string;
|
||||
[key: string]: any
|
||||
}
|
||||
type RunCode = {
|
||||
// 调用进程的功能
|
||||
success?: boolean
|
||||
data?: {
|
||||
// 调用router的结果
|
||||
code?: number
|
||||
data?: any
|
||||
message?: string
|
||||
[key: string]: any
|
||||
};
|
||||
error?: any
|
||||
timestamp?: string
|
||||
[key: string]: any
|
||||
}
|
||||
export const runCode = async (tsPath: string, params: RunCodeParams = {}): Promise<RunCode> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 使用 Bun 的 fork 模式启动子进程
|
||||
const child = fork(tsPath)
|
||||
|
||||
// 监听来自子进程的消息
|
||||
child.on('message', (msg: RunCode) => {
|
||||
resolve(msg)
|
||||
})
|
||||
|
||||
// child.on('exit', (code, signal) => {
|
||||
// console.log('子进程已退出,退出码:', code, '信号:', signal)
|
||||
// })
|
||||
|
||||
// child.on('close', (code, signal) => {
|
||||
// console.log('子进程已关闭,退出码:', code, '信号:', signal)
|
||||
// })
|
||||
|
||||
child.on('error', (error) => {
|
||||
resolve({
|
||||
success: false, error: error?.message
|
||||
})
|
||||
})
|
||||
|
||||
// 向子进程发送消息
|
||||
child.send(params)
|
||||
});
|
||||
}
|
||||
24
server/src/routes/call/index.ts
Normal file
24
server/src/routes/call/index.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { app } from '../../app.ts'
|
||||
import path from 'path'
|
||||
import { runCode } from '../../modules/run-code/run.ts'
|
||||
|
||||
// http://localhost:4005/api/router?path=call
|
||||
app.route({
|
||||
path: 'call'
|
||||
}).define(async (ctx) => {
|
||||
const filename = ctx.query?.filename || 'root/listen-demo/router.ts'
|
||||
const data = ctx.query?.data || {}
|
||||
const pwd = process.cwd()
|
||||
const testA = path.join(pwd, 'code', filename)
|
||||
const resulst = await runCode(testA, data)
|
||||
if (resulst.success) {
|
||||
const callResult = resulst.data;
|
||||
if (callResult.code === 200) ctx.body = callResult.data
|
||||
else {
|
||||
const callError = `调用程序错误: ${callResult.message}`
|
||||
ctx.throw(callResult.code, callError)
|
||||
}
|
||||
} else {
|
||||
ctx.body = `执行脚本错误: ${resulst.error}`
|
||||
}
|
||||
}).addTo(app)
|
||||
28
server/src/routes/file-code/index.ts
Normal file
28
server/src/routes/file-code/index.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { app } from '@/app.ts';
|
||||
import path from 'node:path'
|
||||
import glob from 'fast-glob';
|
||||
import fs from 'node:fs'
|
||||
const list = async () => {
|
||||
const root = path.join(process.cwd(), 'code');
|
||||
const files = await glob('**/*.ts', { cwd: root });
|
||||
type FileContent = {
|
||||
path: string;
|
||||
content: string;
|
||||
}
|
||||
const filesContent: FileContent[] = [];
|
||||
for (const file of files) {
|
||||
if (file.startsWith('node_modules') || file.startsWith('dist') || file.startsWith('.git')) continue;
|
||||
const fullPath = path.join(root, file);
|
||||
const content = fs.readFileSync(fullPath, 'utf-8');
|
||||
if (content) {
|
||||
filesContent.push({ path: file, content: content });
|
||||
}
|
||||
}
|
||||
return filesContent;
|
||||
}
|
||||
app.route({
|
||||
path: 'file-code'
|
||||
}).define(async (ctx) => {
|
||||
const files = await list();
|
||||
ctx.body = files
|
||||
}).addTo(app);
|
||||
3
server/src/routes/index.ts
Normal file
3
server/src/routes/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import './call/index.ts';
|
||||
|
||||
import './file-code/index.ts';
|
||||
@@ -9,11 +9,11 @@
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"server/src/*"
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
},
|
||||
"include": [
|
||||
"server/src/**/*",
|
||||
"src/**/*", "code/**/*",
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user