Skip to content

Commit

Permalink
feat: file api
Browse files Browse the repository at this point in the history
  • Loading branch information
rosendolu committed May 2, 2024
1 parent cf6890a commit 0fc18c8
Show file tree
Hide file tree
Showing 16 changed files with 224 additions and 12 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ node_modules/
logs/*
*.log
*.local
temp/
3 changes: 3 additions & 0 deletions app/common/constant.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const path = require('path');

module.exports = {
isProdEnv: !/dev/i.test(process.env.NODE_ENV || ''),
rootDir: path.resolve(__dirname, '../../'),
koaSessionConfig: {
maxAge: 864e5 * 3e4, // 3e4 days
httpOnly: true /** (boolean) httpOnly or not (default true) */,
Expand Down
6 changes: 4 additions & 2 deletions app/common/logger.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const winston = require('winston');
const utils = require('./utils');
const path = require('path');
const { isProdEnv } = require('./constant');
const { isProdEnv, rootDir } = require('./constant');
const { ensureDirSync } = require('fs-extra');

const appLogPath = path.resolve('logs', utils.timestamp().split(' ')[0]);
const appLogPath = path.resolve(rootDir, 'temp/logs', utils.timestamp().split(' ')[0]);
ensureDirSync(appLogPath);
const loggerFileNameList = ['app'];

const fileFormat = winston.format.combine(
Expand Down
3 changes: 3 additions & 0 deletions app/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const Koa = require('koa');
const serve = require('koa-static');
const logger = require('./common/logger');
const cors = require('@koa/cors');
const router = require('./router/index');
Expand All @@ -11,12 +12,14 @@ require('dotenv').config({ path: ['.env', '.env.local'], override: true });
const koaSession = require('koa-session');
const constant = require('./common/constant');
const user = require('./middleware/user');
const path = require('node:path');
const app = new Koa();
app.keys = [process.env.SESSION_KEYS];
app.use(commonHandle());
app.use(koaSession(constant.koaSessionConfig, app));
app.use(user.userHandle());
app.use(useKoaBody());
app.use(serve(path.join(constant.rootDir, 'temp/upload')));
app.use(
cors({
credentials: true,
Expand Down
29 changes: 29 additions & 0 deletions app/middleware/file.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const assert = require('assert');
const { ensureDir, move } = require('fs-extra');
const path = require('node:path');
const util = require('node:util');
const { rootDir } = require('../common/constant');
const { glob } = require('glob');
module.exports = {
async uploadFile(ctx, next) {
const { uid, nickname } = ctx.session;
let fileArr = [];
// multiple files
const files = ctx.request.files.file;
assert(files, 'Empty file');
for (let i = 0; i < (files.length || 1); i++) {
const { filepath, mimetype, newFilename, originalFilename, size } = files[i] || files;
const userFilePath = path.join(rootDir, 'temp/upload/', uid, newFilename);
await ensureDir(path.dirname(userFilePath));
await move(filepath, userFilePath, { overwrite: true });
ctx.body = newFilename;
}
await next();
},
async listFile(ctx, next) {
let { uid, nickname } = ctx.session;
const userFilePath = path.join(rootDir, 'temp/upload/', uid);
const list = await glob('./**', { cwd: userFilePath, dot: false, maxDepth: 1 });
ctx.body = list;
},
};
7 changes: 5 additions & 2 deletions app/middleware/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const { koaBody } = require('koa-body');
const path = require('path');
const logger = require('../common/logger');
const { isProdEnv } = require('../common/constant');
const { isProdEnv, rootDir } = require('../common/constant');
const { ensureDirSync } = require('fs-extra');

module.exports = {
commonHandle: function commonHandle() {
Expand Down Expand Up @@ -49,14 +50,16 @@ module.exports = {
};
},
useKoaBody: function useKoaBody() {
const uploadDir = path.resolve(rootDir, 'temp/upload');
ensureDirSync(uploadDir);
return koaBody({
multipart: true,
jsonLimit: '100mb',
formLimit: '100mb',
textLimit: '100mb',
formidable: {
maxFieldsSize: 100 * 1024 * 1024, // 100mb
uploadDir: path.resolve('./temp'),
uploadDir: uploadDir,
keepExtensions: true,
},
});
Expand Down
4 changes: 2 additions & 2 deletions app/middleware/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ const { isProdEnv } = require('../common/constant');
const utils = require('../common/utils');

module.exports = {
userHandle: function userHandle() {
userHandle() {
return async function commonHandleMiddleware(ctx, next) {
if (ctx.session.isNew) {
ctx.session.visitCount = 0;
ctx.session.uid = utils.uid();
ctx.session.lastVisit = utils.timestamp();
ctx.session.nickname = utils.faker.name();
}
!ctx.session.nickname && (ctx.session.nickname = utils.faker.name());
await next();
ctx.session.visitCount += 1;
ctx.session.lastVisit = utils.timestamp();
Expand Down
5 changes: 2 additions & 3 deletions app/router/content-type.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const { getStaticFile } = require('../common/utils');
const logger = require('../common/logger');
const utils = require('../common/utils');
const JSONStream = require('../common/jsonStream');
const { rootDir } = require('../common/constant');

const prefix = '/res';
module.exports = router => {
Expand Down Expand Up @@ -53,9 +54,7 @@ module.exports = router => {
ctx.type = 'application/json';
// WARNNING json must be write one-time
// ctx.body = getStaticFile('index.json');
ctx.body = JSON.parse(
fs.readFileSync(path.resolve(__dirname, '../../static/index.json')).toString()
);
ctx.body = JSON.parse(fs.readFileSync(path.resolve(rootDir, 'static/index.json')).toString());
break;
}
await next();
Expand Down
7 changes: 7 additions & 0 deletions app/router/file.route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const fileMiddleware = require('../middleware/file');

const prefix = '/file';
module.exports = router => {
router.post(`${prefix}/upload`, fileMiddleware.uploadFile);
router.get(`${prefix}/list`, fileMiddleware.listFile);
};
4 changes: 2 additions & 2 deletions app/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ const Router = require('@koa/router');
const { glob } = require('glob');
const logger = require('../common/logger');
const path = require('path');
const { isProdEnv } = require('../common/constant');
const { isProdEnv, rootDir } = require('../common/constant');
const router = new Router();
const routerFiles = glob.sync('./**/*.route.js', { cwd: path.resolve('./app/router') });
const routerFiles = glob.sync('./**/*.route.js', { cwd: path.resolve(rootDir, 'app/router') });

if (!isProdEnv) {
logger.debug('Router/index.js %O', routerFiles);
Expand Down
1 change: 1 addition & 0 deletions app/router/root.route.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const dayjs = require('dayjs');
const utils = require('../common/utils');

module.exports = router => {
router.all('/', ctx => {
const { nickname, visitCount, uid, lastVisit } = ctx.session;
Expand Down
23 changes: 23 additions & 0 deletions doc/file.md
Original file line number Diff line number Diff line change
@@ -1 +1,24 @@
# File

> prefix: `/file`
## post `/upload`

Content-Type: multipart/form-data

req:

```sh
curl 'http://localhost:3000/file/upload' \
-H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryVuSkafv2P53NsDZB' \
--data-raw $'------WebKitFormBoundaryVuSkafv2P53NsDZB\r\nContent-Disposition: form-data; name="file"; filename="qr-code.png"\r\nContent-Type: image/png\r\n\r\n\r\n------WebKitFormBoundaryVuSkafv2P53NsDZB--\r\n'

```

## get `/list`

res

```json
{ "data": [".", "7262f7574b348cb21528d7e01.png"], "error": null, "message": "OK", "status": 200, "duration": 9 }
```
Loading

0 comments on commit 0fc18c8

Please sign in to comment.