feat: add listener

This commit is contained in:
熊潇 2025-06-07 12:08:54 +08:00
parent 9d3336e1c2
commit 7b415f5ca8
6 changed files with 567 additions and 118 deletions

View File

@ -48,19 +48,20 @@
"ioredis": "^5.6.1", "ioredis": "^5.6.1",
"minio": "^8.0.5", "minio": "^8.0.5",
"pg": "^8.16.0", "pg": "^8.16.0",
"pm2": "^6.0.6", "pm2": "^6.0.8",
"sequelize": "^6.37.7", "sequelize": "^6.37.7",
"sqlite3": "^5.1.7" "sqlite3": "^5.1.7"
}, },
"devDependencies": { "devDependencies": {
"@kevisual/code-center-module": "workspace:*", "@kevisual/code-center-module": "workspace:*",
"@kevisual/local-app-manager": "0.1.20", "@kevisual/file-listener": "^0.0.2",
"@kevisual/local-app-manager": "0.1.22",
"@kevisual/logger": "^0.0.4", "@kevisual/logger": "^0.0.4",
"@kevisual/oss": "workspace:*", "@kevisual/oss": "workspace:*",
"@kevisual/permission": "^0.0.3", "@kevisual/permission": "^0.0.3",
"@kevisual/router": "0.0.20", "@kevisual/router": "0.0.22",
"@kevisual/types": "^0.0.10", "@kevisual/types": "^0.0.10",
"@kevisual/use-config": "^1.0.17", "@kevisual/use-config": "^1.0.18",
"@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-alias": "^5.1.1",
"@rollup/plugin-commonjs": "^28.0.3", "@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-json": "^6.1.0", "@rollup/plugin-json": "^6.1.0",
@ -72,8 +73,8 @@
"@types/formidable": "^3.4.5", "@types/formidable": "^3.4.5",
"@types/jsonwebtoken": "^9.0.9", "@types/jsonwebtoken": "^9.0.9",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@types/node": "^22.15.19", "@types/node": "^22.15.30",
"@types/react": "^19.1.4", "@types/react": "^19.1.6",
"@types/semver": "^7.7.0", "@types/semver": "^7.7.0",
"@types/uuid": "^10.0.0", "@types/uuid": "^10.0.0",
"archiver": "^7.0.1", "archiver": "^7.0.1",
@ -92,9 +93,9 @@
"nodemon": "^3.1.10", "nodemon": "^3.1.10",
"p-queue": "^8.1.0", "p-queue": "^8.1.0",
"pg": "^8.16.0", "pg": "^8.16.0",
"pm2": "^6.0.6", "pm2": "^6.0.8",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"rollup": "^4.41.0", "rollup": "^4.42.0",
"rollup-plugin-copy": "^3.5.0", "rollup-plugin-copy": "^3.5.0",
"rollup-plugin-dts": "^6.2.1", "rollup-plugin-dts": "^6.2.1",
"rollup-plugin-esbuild": "^6.2.1", "rollup-plugin-esbuild": "^6.2.1",
@ -105,10 +106,10 @@
"tape": "^5.9.0", "tape": "^5.9.0",
"tar": "^7.4.3", "tar": "^7.4.3",
"tsx": "^4.19.4", "tsx": "^4.19.4",
"turbo": "^2.5.3", "turbo": "^2.5.4",
"typescript": "^5.8.3", "typescript": "^5.8.3",
"uuid": "^11.1.0", "uuid": "^11.1.0",
"zod": "^3.25.7" "zod": "^3.25.56"
}, },
"resolutions": { "resolutions": {
"inflight": "latest", "inflight": "latest",
@ -116,5 +117,5 @@
"picomatch": "^4.0.2" "picomatch": "^4.0.2"
}, },
"pnpm": {}, "pnpm": {},
"packageManager": "pnpm@10.11.0" "packageManager": "pnpm@10.11.1"
} }

549
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
import './list.ts';

View File

@ -0,0 +1,107 @@
import { Op } from 'sequelize';
import { app } from '@/app.ts';
import { FileSyncModel } from './model.ts';
app
.route({
path: 'file-listener',
key: 'list',
middleware: ['auth'],
description: '获取用户的某一个文件夹下的所有的列表的数据',
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const username = tokenUser.username;
const { page = 1, pageSize = 20, sort = 'DESC' } = ctx.query;
let { prefix } = ctx.query;
if (prefix) {
if (typeof prefix !== 'string') {
ctx.throw(400, 'prefix must be a string');
}
if (prefix.startsWith('/')) {
prefix = prefix.slice(1); // Remove leading slash if present
}
if (!prefix.startsWith(username + '/')) {
ctx.throw(400, 'prefix must start with the your username:', username);
}
}
const searchWhere = prefix
? {
[Op.or]: [{ name: { [Op.like]: `${prefix}%` } }],
}
: {};
const { rows: files, count } = await FileSyncModel.findAndCountAll({
where: {
...searchWhere,
},
offset: (page - 1) * pageSize,
limit: pageSize,
order: [['updatedAt', sort]],
});
const getPublicFiles = (files: FileSyncModel[]) => {
return files.map((file) => {
const value = file.toJSON();
const stat = value.stat || {};
delete stat.password;
return {
...value,
stat: stat,
};
});
};
ctx.body = {
list: getPublicFiles(files),
pagination: {
page,
current: page,
pageSize,
total: count,
},
};
})
.addTo(app);
app
.route({
path: 'file-listener',
key: 'get',
middleware: ['auth'],
})
.define(async (ctx) => {
const tokenUser = ctx.state.tokenUser;
const username = tokenUser.username;
const { id, name, hash } = ctx.query.data || {};
if (!id && !name && !hash) {
ctx.throw(400, 'id, name or hash is required');
}
let fileSync: FileSyncModel | null = null;
if (id) {
fileSync = await FileSyncModel.findByPk(id);
}
if (name && !fileSync) {
fileSync = await FileSyncModel.findOne({
where: {
name,
hash,
},
});
}
if (!fileSync && hash) {
fileSync = await FileSyncModel.findOne({
where: {
name: {
[Op.like]: `${username}/%`,
},
hash,
},
});
}
if (!fileSync || !fileSync.name.startsWith(`${username}/`)) {
ctx.throw(404, 'NotFoundFile');
}
ctx.body = fileSync;
})
.addTo(app);

View File

@ -0,0 +1,3 @@
import { FileSyncModel, FileSyncModelType } from '@kevisual/file-listener/src/file-sync/model.ts';
export { FileSyncModel, FileSyncModelType };

View File

@ -13,3 +13,5 @@ import './micro-app/index.ts';
import './config/index.ts'; import './config/index.ts';
import './mark/index.ts'; import './mark/index.ts';
import './file-listener/index.ts';