Skip to content

Commit

Permalink
refactor: getFileType、checkFileType 支持 antd UploadFile 对象
Browse files Browse the repository at this point in the history
  • Loading branch information
caijf committed Jul 29, 2024
1 parent 753c9f3 commit 8b49e67
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 15 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
"dependencies": {
"cache2": "^3.0.0",
"tslib": "^2.6.3",
"ut2": "^1.10.1"
"ut2": "^1.11.0"
},
"publishConfig": {
"registry": "https://registry.npmjs.org/"
Expand Down
20 changes: 9 additions & 11 deletions src/checkFileType.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { isBlob, isString, toString } from 'ut2';

// 测试文件名后缀
function testExt(name: string | undefined, ext: string) {
return !!name && name.slice(-ext.length) === ext;
}
import { isFile, isString, toString } from 'ut2';
import { isUploadFile, testExt, UploadFile } from './utils/file.util';

/**
* 检查文件是否符合 `accept` 类型说明符。
Expand All @@ -13,12 +9,12 @@ function testExt(name: string | undefined, ext: string) {
* @since 5.1.0
* @see {@link https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/input/file#唯一文件类型说明符 唯一文件类型说明符}
* @see {@link https://www.iana.org/assignments/media-types/media-types.xhtml Media Types}
* @param {File} file 文件对象。
* @param {File} file 文件对象。支持 antd `UploadFile` 对象。
* @param {string} [accept] 文件类型说明符。
* @returns {boolean} 如果 `file` 符合 `accept` 返回 `true`, 否则返回 `false`。
*/
function checkFileType(file: File, accept?: string) {
if (!isBlob(file)) {
function checkFileType(file: File | UploadFile, accept?: string) {
if (!isFile(file) && !isUploadFile(file)) {
return false;
}

Expand All @@ -33,13 +29,15 @@ function checkFileType(file: File, accept?: string) {
}

let ret = false;

const types = accept.toLowerCase().split(/,(?:\s+)?/);
const fileName = file.name.toLowerCase();
const fileType = file.type;
const fileType = file.type || '';
const fileUrl = (file as UploadFile).url || '';

types.some((type) => {
// .doc .docx .jpg .png
if (fileType === type || (type.indexOf('.') === 0 && testExt(fileName, type))) {
if (type === '*' || fileType === type || (type.indexOf('.') === 0 && (testExt(fileName, type) || testExt(fileUrl, type)))) {
ret = true;
} else if (type.includes('/*') && fileType.includes('/')) {
// image/* 匹配所有图片类型
Expand Down
7 changes: 4 additions & 3 deletions src/getFileType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { forEach, isBlob } from 'ut2';
import checkFileType from './checkFileType';
import { isUploadFile, UploadFile } from './utils/file.util';

// 内置文件类型和文件名后缀配置
const config = {
Expand All @@ -19,13 +20,13 @@ type FileType = keyof typeof config;
* @static
* @alias module:Other.getFileType
* @since 5.1.0
* @param {File} file 文件对象。
* @param {File} file 文件对象。支持 antd `UploadFile` 对象。
* @returns {"image" | "audio" | "video" | "pdf" | "word" | "excel" | undefined} 如果是 `image` `audio` `video` `pdf` `word` `excel` 这些类型的文件,返回对应的类型值,否则返回 `undefined`。
*/
function getFileType(file: File) {
function getFileType(file: File | UploadFile) {
let type: undefined | FileType;

if (isBlob(file)) {
if (isBlob(file) || isUploadFile(file)) {
forEach(config, (accept, fileType) => {
if (checkFileType(file, accept)) {
type = fileType;
Expand Down
16 changes: 16 additions & 0 deletions src/utils/file.util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { isObjectLike, isString } from 'ut2';

// 测试文件名后缀
export function testExt(name: string | undefined, ext: string) {
return !!name && name.slice(-ext.length) === ext;
}

export type UploadFile = { uid: string; name: string; type?: string; url?: string };

// 是否为 UploadFile
export function isUploadFile(fileObj: UploadFile) {
if (isObjectLike(fileObj) && isString(fileObj.uid) && isString(fileObj.name)) {
return true;
}
return false;
}
34 changes: 34 additions & 0 deletions test/checkFileType.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ describe('checkFileType', () => {
expect(checkFileType(jpeg, '*')).toBeTruthy();
expect(checkFileType(gif, '*')).toBeTruthy();
expect(checkFileType(png, '*')).toBeTruthy();

// 含有 *
expect(checkFileType(pdf, 'image/*,*,.png')).toBeTruthy();
});

it('不传 accept', () => {
Expand Down Expand Up @@ -66,6 +69,37 @@ describe('checkFileType', () => {
expect(checkFileType(png, 'image/*,.png,.gif,.pdf')).toBeTruthy();
});

it('UploadFile', () => {
const f1 = {
uid: '-1',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
name: '图片文件名称111'
};
const f2 = {
uid: '-2',
name: 'test.ofd'
};

expect(checkFileType(f1, '.png')).toBeTruthy();
expect(checkFileType(f2, '.ofd')).toBeTruthy();

expect(checkFileType(f1, 'image/*')).toBeFalsy();
expect(checkFileType(f2, 'application/*')).toBeFalsy();
});

it('无效的 UploadFile 对象', () => {
// UploadFile 必须包含 uid和name ,如果不是一个有效的 UploadFile ,检查文件类型始终返回 false
const f = {
uid: '-3',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
};

// @ts-ignore
expect(checkFileType(f, '.png')).toBeFalsy();
// @ts-ignore
expect(checkFileType(f, '*')).toBeFalsy();
});

it('异常参数', () => {
// @ts-ignore
// 不传参
Expand Down
28 changes: 28 additions & 0 deletions test/getFileType.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,34 @@ describe('getFileType', () => {
expect(getFileType(xlsx)).toBe('excel');
});

it('UploadFile', () => {
const f1 = {
uid: '-1',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
name: '图片文件名称111'
};
const f2 = {
uid: '-2',
name: 'test.ofd'
};

expect(getFileType(f1)).toBe('image');
expect(getFileType(f2)).toBeUndefined();
});

it('无效的 UploadFile 对象', () => {
// UploadFile 必须包含 uid和name ,如果不是一个有效的 UploadFile ,检查文件类型始终返回 undefined
const f = {
uid: '-3',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'
};

// @ts-ignore
expect(getFileType(f)).toBeUndefined();
// @ts-ignore
expect(getFileType(f)).toBeUndefined();
});

it('异常参数', () => {
// @ts-ignore
expect(getFileType()).toBe(undefined);
Expand Down

0 comments on commit 8b49e67

Please sign in to comment.