temp: add eco
This commit is contained in:
parent
eba5e4988e
commit
a5d0e66b3c
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,3 +12,5 @@ deploy.tar.gz
|
|||||||
cache-file
|
cache-file
|
||||||
|
|
||||||
/apps
|
/apps
|
||||||
|
|
||||||
|
logs
|
18
ecosystem.config.cjs
Normal file
18
ecosystem.config.cjs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
module.exports = {
|
||||||
|
apps: [
|
||||||
|
{
|
||||||
|
name: 'codeflow', // 应用名称
|
||||||
|
script: './dist/app.mjs', // 入口文件
|
||||||
|
// cwd: '.', // 设置当前工作目录
|
||||||
|
output: './logs/codflow.log',
|
||||||
|
error: './logs/codflow.log',
|
||||||
|
log_date_format: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
// watch: true, // 自动监控文件变化
|
||||||
|
watch: ['dist'], // 监控的文件夹
|
||||||
|
ignore_watch: ['node_modules', 'logs'], // 忽略的文件夹
|
||||||
|
env: {
|
||||||
|
NODE_ENV: 'development'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -8,8 +8,9 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"watch": "rollup -c rollup.config.mjs -w",
|
"watch": "rollup -c rollup.config.mjs -w",
|
||||||
"dev": "cross-env NODE_ENV=development nodemon --delay 2.5 -e js,cjs,mjs --exec node dist/app.mjs",
|
"dev": "cross-env NODE_ENV=development nodemon --delay 2.5 -e js,cjs,mjs --exec node dist/app.mjs",
|
||||||
|
"dev:pm2": "pm2-dev start ecosystem.config.cjs",
|
||||||
"test": "tsx test/**/*.ts",
|
"test": "tsx test/**/*.ts",
|
||||||
"dev:watch": "concurrently -n \"Watch,Dev\" -c \"green,blue\" \"npm run watch\" \"sleep 1 && npm run dev\" ",
|
"dev:watch": "cross-env NODE_ENV=development concurrently -n \"Watch,Dev\" -c \"green,blue\" \"npm run watch\" \"sleep 1 && npm run dev\" ",
|
||||||
"build": "rimraf dist && rollup -c rollup.config.mjs",
|
"build": "rimraf dist && rollup -c rollup.config.mjs",
|
||||||
"deploy": "rsync -avz --delete ./dist/ --exclude='app.config.json5' light:~/apps/codeflow/backend",
|
"deploy": "rsync -avz --delete ./dist/ --exclude='app.config.json5' light:~/apps/codeflow/backend",
|
||||||
"clean": "rm -rf dist",
|
"clean": "rm -rf dist",
|
||||||
@ -70,6 +71,7 @@
|
|||||||
"@rollup/plugin-commonjs": "^28.0.1",
|
"@rollup/plugin-commonjs": "^28.0.1",
|
||||||
"@rollup/plugin-json": "^6.1.0",
|
"@rollup/plugin-json": "^6.1.0",
|
||||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||||
|
"@rollup/plugin-replace": "^6.0.1",
|
||||||
"@rollup/plugin-typescript": "^12.1.1",
|
"@rollup/plugin-typescript": "^12.1.1",
|
||||||
"@types/archiver": "^6.0.3",
|
"@types/archiver": "^6.0.3",
|
||||||
"@types/crypto-js": "^4.2.2",
|
"@types/crypto-js": "^4.2.2",
|
||||||
@ -83,6 +85,7 @@
|
|||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"nodemon": "^3.1.7",
|
"nodemon": "^3.1.7",
|
||||||
"pm2": "^5.4.3",
|
"pm2": "^5.4.3",
|
||||||
|
"pm2-dev": "^5.4.1",
|
||||||
"rimraf": "^6.0.1",
|
"rimraf": "^6.0.1",
|
||||||
"rollup": "^4.27.4",
|
"rollup": "^4.27.4",
|
||||||
"rollup-plugin-copy": "^3.5.0",
|
"rollup-plugin-copy": "^3.5.0",
|
||||||
|
28
pnpm-lock.yaml
generated
28
pnpm-lock.yaml
generated
@ -134,6 +134,9 @@ importers:
|
|||||||
'@rollup/plugin-node-resolve':
|
'@rollup/plugin-node-resolve':
|
||||||
specifier: ^15.3.0
|
specifier: ^15.3.0
|
||||||
version: 15.3.0(rollup@4.27.4)
|
version: 15.3.0(rollup@4.27.4)
|
||||||
|
'@rollup/plugin-replace':
|
||||||
|
specifier: ^6.0.1
|
||||||
|
version: 6.0.1(rollup@4.27.4)
|
||||||
'@rollup/plugin-typescript':
|
'@rollup/plugin-typescript':
|
||||||
specifier: ^12.1.1
|
specifier: ^12.1.1
|
||||||
version: 12.1.1(rollup@4.27.4)(tslib@2.8.1)(typescript@5.7.2)
|
version: 12.1.1(rollup@4.27.4)(tslib@2.8.1)(typescript@5.7.2)
|
||||||
@ -173,6 +176,9 @@ importers:
|
|||||||
pm2:
|
pm2:
|
||||||
specifier: ^5.4.3
|
specifier: ^5.4.3
|
||||||
version: 5.4.3
|
version: 5.4.3
|
||||||
|
pm2-dev:
|
||||||
|
specifier: ^5.4.1
|
||||||
|
version: 5.4.1
|
||||||
rimraf:
|
rimraf:
|
||||||
specifier: latest
|
specifier: latest
|
||||||
version: 6.0.1
|
version: 6.0.1
|
||||||
@ -1206,6 +1212,15 @@ packages:
|
|||||||
rollup:
|
rollup:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@rollup/plugin-replace@6.0.1':
|
||||||
|
resolution: {integrity: sha512-2sPh9b73dj5IxuMmDAsQWVFT7mR+yoHweBaXG2W/R8vQ+IWZlnaI7BR7J6EguVQUp1hd8Z7XuozpDjEKQAAC2Q==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
rollup:
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@rollup/plugin-typescript@12.1.1':
|
'@rollup/plugin-typescript@12.1.1':
|
||||||
resolution: {integrity: sha512-t7O653DpfB5MbFrqPe/VcKFFkvRuFNp9qId3xq4Eth5xlyymzxNpye2z8Hrl0RIMuXTSr5GGcFpkdlMeacUiFQ==}
|
resolution: {integrity: sha512-t7O653DpfB5MbFrqPe/VcKFFkvRuFNp9qId3xq4Eth5xlyymzxNpye2z8Hrl0RIMuXTSr5GGcFpkdlMeacUiFQ==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
@ -3282,6 +3297,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==}
|
resolution: {integrity: sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==}
|
||||||
engines: {node: '>=4.0.0'}
|
engines: {node: '>=4.0.0'}
|
||||||
|
|
||||||
|
pm2-dev@5.4.1:
|
||||||
|
resolution: {integrity: sha512-5b7igJb2kwUqiCDGciALSae4fBkFbC0008rsp1DGYNFUhfQw4CBQEjJpGEySLmse/4RNOLJm5Spjah6Jd4mmmQ==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
pm2-multimeter@0.1.2:
|
pm2-multimeter@0.1.2:
|
||||||
resolution: {integrity: sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==}
|
resolution: {integrity: sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==}
|
||||||
|
|
||||||
@ -5267,6 +5286,13 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
rollup: 4.27.4
|
rollup: 4.27.4
|
||||||
|
|
||||||
|
'@rollup/plugin-replace@6.0.1(rollup@4.27.4)':
|
||||||
|
dependencies:
|
||||||
|
'@rollup/pluginutils': 5.1.2(rollup@4.27.4)
|
||||||
|
magic-string: 0.30.11
|
||||||
|
optionalDependencies:
|
||||||
|
rollup: 4.27.4
|
||||||
|
|
||||||
'@rollup/plugin-typescript@12.1.1(rollup@4.27.2)(tslib@2.8.1)(typescript@5.7.2)':
|
'@rollup/plugin-typescript@12.1.1(rollup@4.27.2)(tslib@2.8.1)(typescript@5.7.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/pluginutils': 5.1.2(rollup@4.27.2)
|
'@rollup/pluginutils': 5.1.2(rollup@4.27.2)
|
||||||
@ -7486,6 +7512,8 @@ snapshots:
|
|||||||
run-series: 1.1.9
|
run-series: 1.1.9
|
||||||
tv4: 1.3.0
|
tv4: 1.3.0
|
||||||
|
|
||||||
|
pm2-dev@5.4.1: {}
|
||||||
|
|
||||||
pm2-multimeter@0.1.2:
|
pm2-multimeter@0.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
charm: 0.1.2
|
charm: 0.1.2
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
import typescript from '@rollup/plugin-typescript'
|
|
||||||
import resolve from '@rollup/plugin-node-resolve'
|
|
||||||
import commonjs from '@rollup/plugin-commonjs'
|
|
||||||
import copy from 'rollup-plugin-copy'
|
|
||||||
import { dts } from 'rollup-plugin-dts'
|
|
||||||
import json from '@rollup/plugin-json'
|
|
||||||
import * as glob from 'glob'
|
|
||||||
import path from 'path'
|
|
||||||
|
|
||||||
const files = glob.sync('src-apps/**/index.ts')
|
|
||||||
console.log(files)
|
|
||||||
const configs = files.map((file) => {
|
|
||||||
const inputFile = file
|
|
||||||
const directory = file.split('/').slice(0, -1).join('/')
|
|
||||||
const outputDirectory = directory.replace('src-apps', 'dist/apps')
|
|
||||||
console.log(directory)
|
|
||||||
console.log(outputDirectory)
|
|
||||||
/**
|
|
||||||
* @type {import('rollup').RollupOptions}
|
|
||||||
*/
|
|
||||||
const config = {
|
|
||||||
input: inputFile,
|
|
||||||
output: {
|
|
||||||
outDir: outputDirectory,
|
|
||||||
file: path.join(outputDirectory, 'index.mjs'),
|
|
||||||
// format: 'cjs'
|
|
||||||
format: 'esm',
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
resolve(),
|
|
||||||
commonjs(),
|
|
||||||
typescript({
|
|
||||||
declaration: false
|
|
||||||
})
|
|
||||||
// json(),
|
|
||||||
// copy({
|
|
||||||
// targets: [
|
|
||||||
// {
|
|
||||||
// src: `${directory}/*.html`,
|
|
||||||
// dest: outputDirectory,
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// }),
|
|
||||||
],
|
|
||||||
external: ['sequelize', '@kevisual/router']
|
|
||||||
}
|
|
||||||
return config
|
|
||||||
})
|
|
||||||
export default [...configs]
|
|
@ -1,15 +1,12 @@
|
|||||||
import typescript from '@rollup/plugin-typescript'
|
import resolve from '@rollup/plugin-node-resolve';
|
||||||
import resolve from '@rollup/plugin-node-resolve'
|
import commonjs from '@rollup/plugin-commonjs';
|
||||||
import commonjs from '@rollup/plugin-commonjs'
|
import json from '@rollup/plugin-json';
|
||||||
import copy from 'rollup-plugin-copy'
|
import * as glob from 'fast-glob';
|
||||||
import { dts } from 'rollup-plugin-dts'
|
import path from 'path';
|
||||||
import json from '@rollup/plugin-json'
|
import esbuild from 'rollup-plugin-esbuild';
|
||||||
import * as glob from 'fast-glob'
|
import alias from '@rollup/plugin-alias';
|
||||||
import path from 'path'
|
import replace from '@rollup/plugin-replace';
|
||||||
import esbuild from 'rollup-plugin-esbuild'
|
const isDev = process.env.NODE_ENV === 'development';
|
||||||
import alias from '@rollup/plugin-alias'
|
|
||||||
// import ignore from 'rollup-plugin-ignore';
|
|
||||||
// ignore(['xmlbuilder']),
|
|
||||||
/**
|
/**
|
||||||
* @type {import('rollup').RollupOptions}
|
* @type {import('rollup').RollupOptions}
|
||||||
*/
|
*/
|
||||||
@ -17,13 +14,15 @@ const config = {
|
|||||||
input: './src/index.ts',
|
input: './src/index.ts',
|
||||||
output: {
|
output: {
|
||||||
dir: './dist',
|
dir: './dist',
|
||||||
// file: path.join('./dist', 'app.mjs'),
|
|
||||||
entryFileNames: 'app.mjs',
|
entryFileNames: 'app.mjs',
|
||||||
chunkFileNames: '[name]-[hash].mjs',
|
chunkFileNames: '[name]-[hash].mjs',
|
||||||
// format: 'cjs'
|
format: 'esm',
|
||||||
format: 'esm'
|
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
replace({
|
||||||
|
preventAssignment: true, // 防止意外赋值
|
||||||
|
DEV_SERVER: JSON.stringify(isDev), // 替换 process.env.NODE_ENV
|
||||||
|
}),
|
||||||
alias({
|
alias({
|
||||||
// only esbuild needs to be configured
|
// only esbuild needs to be configured
|
||||||
entries: [
|
entries: [
|
||||||
@ -47,33 +46,20 @@ const config = {
|
|||||||
{ find: 'events', replacement: 'node:events' },
|
{ find: 'events', replacement: 'node:events' },
|
||||||
{ find: 'url', replacement: 'node:url' },
|
{ find: 'url', replacement: 'node:url' },
|
||||||
{ find: 'assert', replacement: 'node:assert' },
|
{ find: 'assert', replacement: 'node:assert' },
|
||||||
{ find: 'util', replacement: 'node:util' }
|
{ find: 'util', replacement: 'node:util' },
|
||||||
]
|
],
|
||||||
}),
|
}),
|
||||||
resolve({
|
resolve({
|
||||||
preferBuiltins: true // 强制优先使用内置模块
|
preferBuiltins: true, // 强制优先使用内置模块
|
||||||
}),
|
}),
|
||||||
commonjs(),
|
commonjs(),
|
||||||
// typescript({
|
|
||||||
// declaration: false
|
|
||||||
// }),
|
|
||||||
esbuild({
|
esbuild({
|
||||||
target: 'node22', // 目标为 Node.js 14
|
target: 'node22', // 目标为 Node.js 14
|
||||||
minify: false, // 启用代码压缩
|
minify: false, // 启用代码压缩
|
||||||
tsconfig: 'tsconfig.json'
|
tsconfig: 'tsconfig.json',
|
||||||
}),
|
}),
|
||||||
|
json(),
|
||||||
json()
|
|
||||||
// copy({
|
|
||||||
// targets: [
|
|
||||||
// {
|
|
||||||
// src: `${directory}/*.html`,
|
|
||||||
// dest: outputDirectory,
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// }),
|
|
||||||
|
|
||||||
],
|
],
|
||||||
external: ['sequelize', '@kevisual/router', 'ioredis', 'socket.io', 'minio']
|
external: ['sequelize', '@kevisual/router', 'ioredis', 'socket.io', 'minio'],
|
||||||
}
|
};
|
||||||
export default config
|
export default config;
|
||||||
|
@ -9,6 +9,7 @@ import { app, minioClient } from '@/app.ts';
|
|||||||
import { bucketName } from '@/modules/minio.ts';
|
import { bucketName } from '@/modules/minio.ts';
|
||||||
import { getContentType } from '@/utils/get-content-type.ts';
|
import { getContentType } from '@/utils/get-content-type.ts';
|
||||||
import { hash } from 'crypto';
|
import { hash } from 'crypto';
|
||||||
|
import { MicroAppModel } from '@/routes/micro-app/models.ts';
|
||||||
const cacheFilePath = useFileStore('cache-file', { needExists: true });
|
const cacheFilePath = useFileStore('cache-file', { needExists: true });
|
||||||
|
|
||||||
router.post('/api/micro-app/upload', async (req, res) => {
|
router.post('/api/micro-app/upload', async (req, res) => {
|
||||||
@ -119,6 +120,61 @@ router.post('/api/micro-app/upload', async (req, res) => {
|
|||||||
res.end(JSON.stringify(data));
|
res.end(JSON.stringify(data));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get('/api/micro-app/download/:id', async (req, res) => {
|
||||||
|
const { id } = req.params;
|
||||||
|
|
||||||
|
if (!id) {
|
||||||
|
res.writeHead(200, { 'Content-Type': 'application/javascript; charset=utf-8' });
|
||||||
|
res.end(error('Key parameter is required'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.headersSent) return; // 如果响应已发送,不再处理
|
||||||
|
let tokenUser;
|
||||||
|
if (!DEV_SERVER) {
|
||||||
|
const auth = await checkAuth(req, res);
|
||||||
|
tokenUser = auth.tokenUser;
|
||||||
|
if (!tokenUser) return;
|
||||||
|
}
|
||||||
|
const file = await MicroAppModel.findByPk(id);
|
||||||
|
if (!DEV_SERVER) {
|
||||||
|
file.uid !== tokenUser.id && res.end(error('No permission', 403));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
res.end(error('File not found'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const objectName = file.data?.file?.path;
|
||||||
|
const fileName = file.data?.file?.name;
|
||||||
|
if (!objectName) {
|
||||||
|
res.end(error('File not found'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(fileName)}"`);
|
||||||
|
res.writeHead(200, { 'Content-Type': 'application/octet-stream' });
|
||||||
|
try {
|
||||||
|
const stream = await minioClient.getObject(bucketName, objectName);
|
||||||
|
// 捕获流的错误,防止崩溃
|
||||||
|
stream.on('error', (err) => {
|
||||||
|
console.error('Error while streaming file:', err);
|
||||||
|
if (!res.headersSent) {
|
||||||
|
res.end(error('Error downloading file'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.pipe(res).on('finish', () => {
|
||||||
|
console.log(`File download completed: ${id}`);
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error during download:', err);
|
||||||
|
if (!res.headersSent) {
|
||||||
|
res.end(error('Error downloading file'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
function parseIfJson(collection: any): any {
|
function parseIfJson(collection: any): any {
|
||||||
try {
|
try {
|
||||||
return JSON.parse(collection);
|
return JSON.parse(collection);
|
||||||
|
@ -18,11 +18,15 @@ app
|
|||||||
const file = files[0];
|
const file = files[0];
|
||||||
console.log('File', files);
|
console.log('File', files);
|
||||||
const { path, name, hash, size } = file;
|
const { path, name, hash, size } = file;
|
||||||
|
const tags = [];
|
||||||
|
if (collection?.tags) {
|
||||||
|
tags.push(...collection.tags);
|
||||||
|
}
|
||||||
const microApp = await MicroAppModel.create({
|
const microApp = await MicroAppModel.create({
|
||||||
title: name,
|
title: name,
|
||||||
description: '',
|
description: collection?.readme || '',
|
||||||
type: 'micro-app',
|
type: 'micro-app',
|
||||||
tags: [],
|
tags: tags,
|
||||||
data: {
|
data: {
|
||||||
file: {
|
file: {
|
||||||
path,
|
path,
|
||||||
|
@ -8,9 +8,10 @@ type MicroAppData = {
|
|||||||
path: string;
|
path: string;
|
||||||
size: number;
|
size: number;
|
||||||
hash: string;
|
hash: string;
|
||||||
|
name: string;
|
||||||
};
|
};
|
||||||
data?: any;
|
data?: any;
|
||||||
collection?: any;
|
collection?: any; // 上传的信息汇总
|
||||||
};
|
};
|
||||||
export class MicroAppModel extends Model {
|
export class MicroAppModel extends Model {
|
||||||
declare id: string;
|
declare id: string;
|
||||||
|
@ -36,6 +36,11 @@ export const deleteFileAppInfo = async (key: string) => {
|
|||||||
fs.rmSync(directory, { recursive: true });
|
fs.rmSync(directory, { recursive: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
* @param key
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const loadApp = async (key: string) => {
|
export const loadApp = async (key: string) => {
|
||||||
const { mainEntry, app } = await loadFileAppInfo(key);
|
const { mainEntry, app } = await loadFileAppInfo(key);
|
||||||
// 1. 查询数据库,获取app信息,查看是否运行中
|
// 1. 查询数据库,获取app信息,查看是否运行中
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { getSession } from '@/app.ts';
|
import { getSession } from '@/modules/neo4j.ts';
|
||||||
export async function fetchData() {
|
export async function fetchData() {
|
||||||
const session = getSession();
|
const session = getSession();
|
||||||
try {
|
try {
|
||||||
|
2
typings.d.ts
vendored
2
typings.d.ts
vendored
@ -1,3 +1,5 @@
|
|||||||
type SimpleObject = {
|
type SimpleObject = {
|
||||||
[key: string | number]: any;
|
[key: string | number]: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
declare var DEV_SERVER:boolean;
|
Loading…
x
Reference in New Issue
Block a user