106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
const getFileExtension = (filename: string) => {
|
||
return filename.split('.').pop();
|
||
};
|
||
const getFileType = (extension: string) => {
|
||
switch (extension) {
|
||
case 'js':
|
||
return 'text/javascript';
|
||
case 'css':
|
||
return 'text/css';
|
||
case 'html':
|
||
return 'text/html';
|
||
case 'json':
|
||
return 'application/json';
|
||
case 'png':
|
||
return 'image/png';
|
||
case 'jpg':
|
||
return 'image/jpeg';
|
||
case 'jpeg':
|
||
return 'image/jpeg';
|
||
case 'gif':
|
||
return 'image/gif';
|
||
case 'svg':
|
||
return 'image/svg+xml';
|
||
case 'webp':
|
||
return 'image/webp';
|
||
case 'ico':
|
||
return 'image/x-icon';
|
||
default:
|
||
return 'text/plain';
|
||
}
|
||
};
|
||
const checkIsBase64 = (content: string) => {
|
||
return content.startsWith('data:');
|
||
};
|
||
/**
|
||
* 获取文件的目录和文件名
|
||
* @param filename 文件名
|
||
* @returns 目录和文件名
|
||
*/
|
||
export const getDirectoryAndName = (filename: string) => {
|
||
if (!filename) {
|
||
return null;
|
||
}
|
||
if (filename.startsWith('.')) {
|
||
return null;
|
||
} else {
|
||
filename = filename.replace(/^\/+/, ''); // Remove all leading slashes
|
||
}
|
||
const hasDirectory = filename.includes('/');
|
||
if (!hasDirectory) {
|
||
return { directory: '', name: filename };
|
||
}
|
||
const parts = filename.split('/');
|
||
const name = parts.pop()!; // Get the last part as the file name
|
||
const directory = parts.join('/'); // Join the remaining parts as the directory
|
||
return { directory, name };
|
||
};
|
||
/**
|
||
* 把字符串转为文件流,并返回文件流,根据filename的扩展名,自动设置文件类型.
|
||
* 当不是文本类型,自动需要把base64的字符串转为blob
|
||
* @param content 字符串
|
||
* @param filename 文件名
|
||
* @returns 文件流
|
||
*/
|
||
export const toFile = (content: string, filename: string) => {
|
||
// 如果文件名是 a/d/a.js 格式的,则需要把d作为目录,a.js作为文件名
|
||
const directoryAndName = getDirectoryAndName(filename);
|
||
if (!directoryAndName) {
|
||
throw new Error('Invalid filename');
|
||
}
|
||
const { name } = directoryAndName;
|
||
const extension = getFileExtension(name);
|
||
if (!extension) {
|
||
throw new Error('Invalid filename');
|
||
}
|
||
const isBase64 = checkIsBase64(content);
|
||
const type = getFileType(extension);
|
||
|
||
if (isBase64) {
|
||
// Decode base64 string
|
||
const base64Data = content.split(',')[1]; // Remove the data URL prefix
|
||
const byteCharacters = atob(base64Data);
|
||
const byteNumbers = new Array(byteCharacters.length);
|
||
for (let i = 0; i < byteCharacters.length; i++) {
|
||
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
||
}
|
||
const byteArray = new Uint8Array(byteNumbers);
|
||
const blob = new Blob([byteArray], { type });
|
||
return new File([blob], filename, { type });
|
||
} else {
|
||
const blob = new Blob([content], { type });
|
||
return new File([blob], filename, { type });
|
||
}
|
||
};
|
||
|
||
/**
|
||
* 把字符串转为文本文件
|
||
* @param content 字符串
|
||
* @param filename 文件名
|
||
* @returns 文件流
|
||
*/
|
||
export const toTextFile = (content: string = 'keep directory exist', filename: string = 'keep.txt') => {
|
||
const file = toFile(content, filename);
|
||
return file;
|
||
};
|