Skip to content

Commit

Permalink
f
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed Feb 3, 2025
1 parent 998a6d1 commit c48a1ec
Show file tree
Hide file tree
Showing 12 changed files with 289 additions and 289 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,6 @@
"src"
],
"types": "./dist/commonjs/index.d.ts",
"main": "./dist/commonjs/index.js"
"main": "./dist/commonjs/index.js",
"module": "./dist/esm/index.js"
}
2 changes: 1 addition & 1 deletion src/app/middleware/multipart.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { pathMatching } from 'egg-path-matching';
import type { Context, Next, EggCore } from '@eggjs/core';
import type { MultipartConfig } from '/src/config/config.default.js';
import type { MultipartConfig } from '../../config/config.default.js';

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export default (options: MultipartConfig, _app: EggCore) => {
Expand Down
14 changes: 9 additions & 5 deletions src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const whitelist = [
'.psd',
// text
'.svg',
'.js', '.jsx',
'.js', '.jsx', '.ts', '.tsx',
'.json',
'.css', '.less',
'.html', '.htm',
Expand All @@ -27,7 +27,7 @@ export const whitelist = [
'.mp3',
'.mp4',
'.avi',
] as const;
];

export function humanizeBytes(size: number | string) {
if (typeof size === 'number') {
Expand Down Expand Up @@ -62,11 +62,15 @@ export function normalizeOptions(options: MultipartConfig) {
}

function checkExt(fileName: string) {
if (typeof options.whitelist === 'function') return options.whitelist(fileName);
if (typeof options.whitelist === 'function') {
return options.whitelist(fileName);
}
const extname = path.extname(fileName).toLowerCase();
if (Array.isArray(options.whitelist)) return options.whitelist.includes(extname);
if (Array.isArray(options.whitelist)) {
return options.whitelist.includes(extname);
}
// only if user don't provide whitelist, we will use default whitelist + fileExtensions
return exports.whitelist.includes(extname) || options.fileExtensions.includes(extname);
return whitelist.includes(extname) || options.fileExtensions.includes(extname);
}

options.checkFile = (_fieldName: string, fileStream: any, fileName: string): void | Error => {
Expand Down
28 changes: 13 additions & 15 deletions test/dynamic-option.test.js → test/dynamic-option.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
'use strict';
import { strict as assert } from 'node:assert';
import fs from 'node:fs/promises';
import formstream from 'formstream';
import urllib from 'urllib';
import { mm, MockApplication } from '@eggjs/mock';

const assert = require('assert');
const formstream = require('formstream');
const urllib = require('urllib');
const mock = require('egg-mock');
const fs = require('fs').promises;

describe('test/dynamic-option.test.js', () => {
let app;
let server;
let host;
describe('test/dynamic-option.test.ts', () => {
let app: MockApplication;
let server: any;
let host: string;
before(() => {
app = mock.app({
app = mm.app({
baseDir: 'apps/dynamic-option',
});
return app.ready();
Expand All @@ -26,7 +24,7 @@ describe('test/dynamic-option.test.js', () => {
after(() => app.close());
after(() => server.close());
beforeEach(() => app.mockCsrf());
afterEach(mock.restore);
afterEach(() => mm.restore());

it('should work with saveRequestFiles options', async () => {
const form = formstream();
Expand All @@ -36,11 +34,11 @@ describe('test/dynamic-option.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
// dataType: 'json',
});

assert(res.status === 413);
assert.equal(res.status, 413);
assert.match(res.data.toString(), /Error: Reach fileSize limit/);
});
});
112 changes: 57 additions & 55 deletions test/file-mode.test.js → test/file-mode.test.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
'use strict';

const assert = require('assert');
const formstream = require('formstream');
const urllib = require('urllib');
const path = require('path');
const mock = require('egg-mock');
const fs = require('fs').promises;
const dayjs = require('dayjs');
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

describe('test/file-mode.test.js', () => {
let app;
let server;
let host;
import assert from 'node:assert';
import path from 'node:path';
import fs from 'node:fs/promises';
import { scheduler } from 'node:timers/promises';
import { fileURLToPath } from 'node:url';
import { mm, mock, MockApplication } from '@eggjs/mock';
import dayjs from 'dayjs';
import formstream from 'formstream';
import urllib from 'urllib';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

describe('test/file-mode.test.ts', () => {
let app: MockApplication;
let server: any;
let host: string;
before(() => {
app = mock.app({
app = mm.app({
baseDir: 'apps/file-mode',
});
return app.ready();
Expand All @@ -29,7 +31,7 @@ describe('test/file-mode.test.js', () => {
after(() => app.close());
after(() => server.close());
beforeEach(() => app.mockCsrf());
afterEach(mock.restore);
afterEach(mm.restore);

it('should ignore non multipart request', async () => {
const res = await app.httpRequest()
Expand Down Expand Up @@ -62,32 +64,32 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 200);
const data = JSON.parse(res.data);
assert.deepStrictEqual(data.body, { foo: 'fengmk2', love: 'egg', work: 'with Node.js' });
assert(data.files.length === 3);
assert(data.files[0].field === 'file1');
assert(data.files[0].filename === 'foooooooo.js');
assert.equal(data.files[0].filename, 'foooooooo.js');
assert(data.files[0].encoding === '7bit');
assert(data.files[0].mime === 'application/javascript');
assert(data.files[0].filepath.startsWith(app.config.multipart.tmpdir));

assert(data.files[1].field === 'file2');
assert(data.files[1].fieldname === 'file2');
assert(data.files[1].filename === 'file-mode.test.js');
assert.equal(data.files[1].filename, 'file-mode.test.ts');
assert(data.files[1].encoding === '7bit');
assert(data.files[1].transferEncoding === '7bit');
assert(data.files[1].mime === 'application/javascript');
assert(data.files[1].mimeType === 'application/javascript');
assert.equal(data.files[1].mime, 'video/mp2t');
assert.equal(data.files[1].mimeType, 'video/mp2t');
assert(data.files[1].filepath.startsWith(app.config.multipart.tmpdir));

assert(data.files[2].field === 'bigfile');
assert(data.files[2].filename === 'bigfile.js');
assert.equal(data.files[2].filename, 'bigfile.js');
assert(data.files[2].encoding === '7bit');
assert(data.files[2].mime === 'application/javascript');
assert.equal(data.files[2].mime, 'application/javascript');
assert(data.files[2].filepath.startsWith(app.config.multipart.tmpdir));
});

Expand All @@ -98,18 +100,18 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});
assert(res.status === 200);
const data = JSON.parse(res.data);
assert(data.files.length === 1);
assert(data.files[0].field === 'file');
assert(data.files[0].filename === '10mb.js');
assert(data.files[0].encoding === '7bit');
assert(data.files[0].mime === 'application/octet-stream');
assert.equal(data.files.length, 1);
assert.equal(data.files[0].field, 'file');
assert.equal(data.files[0].filename, '10mb.js');
assert.equal(data.files[0].encoding, '7bit');
assert.equal(data.files[0].mime, 'application/octet-stream');
assert(data.files[0].filepath.startsWith(app.config.multipart.tmpdir));
const stat = await fs.stat(data.files[0].filepath);
assert(stat.size === 10 * 1024 * 1024 - 1);
assert.equal(stat.size, 10 * 1024 * 1024 - 1);
});

it('should 200 when field size just 100kb', async () => {
Expand All @@ -120,7 +122,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 200);
Expand All @@ -138,7 +140,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 200);
Expand All @@ -156,7 +158,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 200);
Expand All @@ -183,7 +185,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 413);
Expand All @@ -201,7 +203,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 413);
Expand All @@ -216,7 +218,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 413);
Expand All @@ -233,7 +235,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 413);
Expand All @@ -252,7 +254,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 413);
Expand All @@ -271,7 +273,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 400);
Expand All @@ -289,10 +291,10 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload?call_multipart_twice=1', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 500);
assert.equal(res.status, 500);
assert(res.data.toString().includes('the multipart request can\'t be consumed twice'));
});

Expand All @@ -307,7 +309,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload?cleanup=true', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 200);
Expand All @@ -326,7 +328,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload?async_cleanup=true', {
method: 'POST',
headers,
stream: form,
stream: form as any,
});

assert(res.status === 200);
Expand All @@ -339,15 +341,15 @@ describe('test/file-mode.test.js', () => {
// [egg-schedule]: register schedule /hello/egg-multipart/app/schedule/clean_tmpdir.js
const logger = app.loggers.scheduleLogger;
const content = await fs.readFile(logger.options.file, 'utf8');
assert(/\[egg-schedule\]: register schedule .+clean_tmpdir\.js/.test(content));
assert.match(content, /\[@eggjs\/schedule\]: register schedule .+clean_tmpdir\.ts/);
});

it('should remove nothing', async () => {
app.mockLog();
await app.runSchedule(path.join(__dirname, '../app/schedule/clean_tmpdir'));
await sleep(1000);
app.expectLog('[egg-multipart:CleanTmpdir] start clean tmpdir: "', 'coreLogger');
app.expectLog('[egg-multipart:CleanTmpdir] end', 'coreLogger');
await app.runSchedule(path.join(__dirname, '../src/app/schedule/clean_tmpdir'));
await scheduler.wait(1000);
app.expectLog('[@eggjs/multipart:CleanTmpdir] start clean tmpdir: "', 'coreLogger');
app.expectLog('[@eggjs/multipart:CleanTmpdir] end', 'coreLogger');
});

it('should remove old dirs', async () => {
Expand All @@ -366,7 +368,7 @@ describe('test/file-mode.test.js', () => {
const currentMonth = new Date().getMonth();
const fourMonthBefore = path.join(app.config.multipart.tmpdir, dayjs().subtract(4, 'months').format('YYYY/MM/DD/HH'));
if (currentMonth < 4) {
// if current month is less than April, four months before shoule be last year.
// if current month is less than April, four months before should be last year.
oldDirs.push(fourMonthBefore);
} else {
shouldKeepDirs.push(fourMonthBefore);
Expand All @@ -380,7 +382,7 @@ describe('test/file-mode.test.js', () => {
}));

app.mockLog();
await app.runSchedule(path.join(__dirname, '../app/schedule/clean_tmpdir'));
await app.runSchedule(path.join(__dirname, '../src/app/schedule/clean_tmpdir'));
for (const dir of oldDirs) {
const exists = await fs.access(dir).then(() => true).catch(() => false);
assert(!exists, dir);
Expand All @@ -389,8 +391,8 @@ describe('test/file-mode.test.js', () => {
const exists = await fs.access(dir).then(() => true).catch(() => false);
assert(exists, dir);
}
app.expectLog('[egg-multipart:CleanTmpdir] removing tmpdir: "', 'coreLogger');
app.expectLog('[egg-multipart:CleanTmpdir:success] tmpdir: "', 'coreLogger');
app.expectLog('[@eggjs/multipart:CleanTmpdir] removing tmpdir: "', 'coreLogger');
app.expectLog('[@eggjs/multipart:CleanTmpdir:success] tmpdir: "', 'coreLogger');
});
});

Expand All @@ -405,7 +407,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
dataType: 'json',
});
assert.deepStrictEqual(res.data.body, { foo: 'egg' });
Expand All @@ -423,7 +425,7 @@ describe('test/file-mode.test.js', () => {
const res = await urllib.request(host + '/upload', {
method: 'POST',
headers,
stream: form,
stream: form as any,
dataType: 'json',
});
assert.deepStrictEqual(res.data.body, { foo: [ 'fengmk2', 'like', 'egg' ] });
Expand Down
Loading

0 comments on commit c48a1ec

Please sign in to comment.