capacitor-advanced-file-manager
Version:
Advanced file manager plugin for Capacitor with comprehensive file system operations including browse, create, edit, delete, move, copy, and search files and directories.
372 lines (365 loc) • 16 kB
JavaScript
var capacitorAdvancedFileManager = (function (exports, core) {
'use strict';
const AdvancedFileManager = core.registerPlugin('AdvancedFileManager', {
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.AdvancedFileManagerWeb()),
});
// 模块化功能导出 - 暂时注释掉,避免 Rollup 打包问题
// export * from './modules/search';
// export * from './modules/batch';
// export * from './modules/utils'; // 待实现
// export * from './modules/preview'; // 待实现
// export * from './modules/share'; // 待实现
// export * from './modules/web-enhanced'; // Web端增强功能
var __asyncValues = (undefined && undefined.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
class AdvancedFileManagerWeb extends core.WebPlugin {
// 检查是否支持 File System Access API
isFileSystemAccessSupported() {
return 'showDirectoryPicker' in window;
}
async requestPermissions() {
if (this.isFileSystemAccessSupported()) {
return { granted: true, message: 'File System Access API is supported' };
}
else {
return {
granted: false,
message: 'File System Access API is not supported in this browser'
};
}
}
async checkPermissions() {
return this.requestPermissions();
}
async listDirectory(options) {
var _a, e_1, _b, _c;
if (!this.isFileSystemAccessSupported()) {
throw new Error('File System Access API is not supported in this browser');
}
try {
// 在Web平台,我们需要用户选择目录
const dirHandle = await window.showDirectoryPicker();
const files = [];
try {
for (var _d = true, _e = __asyncValues(dirHandle.entries()), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const [name, handle] = _c;
const file = await this.getFileInfoFromHandle(handle, name, options.path);
if (options.showHidden || !file.isHidden) {
files.push(file);
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
}
finally { if (e_1) throw e_1.error; }
}
// 排序
if (options.sortBy) {
files.sort((a, b) => {
let comparison = 0;
switch (options.sortBy) {
case 'name':
comparison = a.name.localeCompare(b.name);
break;
case 'size':
comparison = a.size - b.size;
break;
case 'mtime':
comparison = a.mtime - b.mtime;
break;
case 'type':
comparison = a.type.localeCompare(b.type);
break;
}
return options.sortOrder === 'desc' ? -comparison : comparison;
});
}
return {
files,
totalCount: files.length
};
}
catch (error) {
throw new Error(`Failed to list directory: ${error}`);
}
}
async getFileInfoFromHandle(handle, name, basePath) {
const isDirectory = handle.kind === 'directory';
let size = 0;
let mtime = 0;
let ctime = 0;
if (!isDirectory) {
try {
const file = await handle.getFile();
size = file.size;
mtime = file.lastModified;
ctime = file.lastModified; // Web API doesn't provide creation time
}
catch (error) {
console.warn('Failed to get file info:', error);
}
}
return {
name,
path: `${basePath}/${name}`,
size,
type: isDirectory ? 'directory' : 'file',
mtime,
ctime,
isHidden: name.startsWith('.')
};
}
async createDirectory(_options) {
throw new Error('Creating directories is not supported in web browsers for security reasons');
}
async deleteDirectory(_options) {
throw new Error('Deleting directories is not supported in web browsers for security reasons');
}
async createFile(options) {
if (!this.isFileSystemAccessSupported()) {
throw new Error('File System Access API is not supported in this browser');
}
try {
const fileHandle = await window.showSaveFilePicker({
suggestedName: options.path.split('/').pop() || 'new-file.txt'
});
const writable = await fileHandle.createWritable();
const content = options.content || '';
if (options.encoding === 'base64') {
const binaryString = atob(content);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
await writable.write(bytes);
}
else {
await writable.write(content);
}
await writable.close();
}
catch (error) {
throw new Error(`Failed to create file: ${error}`);
}
}
async readFile(options) {
if (!this.isFileSystemAccessSupported()) {
throw new Error('File System Access API is not supported in this browser');
}
try {
const [fileHandle] = await window.showOpenFilePicker();
const file = await fileHandle.getFile();
let content;
const encoding = options.encoding || 'utf8';
if (encoding === 'base64') {
const arrayBuffer = await file.arrayBuffer();
const bytes = new Uint8Array(arrayBuffer);
content = btoa(String.fromCharCode(...bytes));
}
else {
content = await file.text();
}
return {
content,
encoding
};
}
catch (error) {
throw new Error(`Failed to read file: ${error}`);
}
}
async writeFile(options) {
// 在Web平台,写入文件通常需要用户交互
return this.createFile({
path: options.path,
content: options.content,
encoding: options.encoding
});
}
async deleteFile(_options) {
throw new Error('Deleting files is not supported in web browsers for security reasons');
}
async moveFile(_options) {
throw new Error('Moving files is not supported in web browsers for security reasons');
}
async copyFile(_options) {
throw new Error('Copying files is not supported in web browsers for security reasons');
}
async renameFile(_options) {
throw new Error('Renaming files is not supported in web browsers for security reasons');
}
async getFileInfo(_options) {
throw new Error('Getting file info for specific paths is not supported in web browsers');
}
async exists(_options) {
throw new Error('Checking file existence is not supported in web browsers for security reasons');
}
async searchFiles(_options) {
throw new Error('File search is not supported in web browsers for security reasons');
}
async searchContent(_options) {
// Web 平台不支持直接文件系统访问,返回空结果
console.warn('searchContent is not fully supported in web browsers');
return {
results: [],
totalFiles: 0,
totalMatches: 0,
duration: 0,
skippedFiles: 0
};
}
async openSystemFilePicker(options) {
if (!this.isFileSystemAccessSupported()) {
throw new Error('File System Access API is not supported in this browser');
}
try {
const files = [];
const directories = [];
if (options.type === 'directory' || options.type === 'both') {
// 选择目录
const dirHandle = await window.showDirectoryPicker();
const dirInfo = {
name: dirHandle.name,
path: `/${dirHandle.name}`,
uri: dirHandle.name,
size: 0,
type: 'directory',
mimeType: 'inode/directory',
mtime: Date.now(),
ctime: Date.now()
};
directories.push(dirInfo);
}
if (options.type === 'file' || options.type === 'both') {
// 选择文件
const fileHandles = await window.showOpenFilePicker({
multiple: options.multiple || false,
types: options.accept ? [{
description: 'Selected files',
accept: options.accept.reduce((acc, ext) => {
const mimeType = this.getMimeTypeFromExtension(ext);
if (!acc[mimeType])
acc[mimeType] = [];
acc[mimeType].push(`.${ext}`);
return acc;
}, {})
}] : undefined
});
for (const handle of fileHandles) {
try {
const file = await handle.getFile();
const fileInfo = {
name: file.name,
path: `/${file.name}`,
uri: file.name,
size: file.size,
type: 'file',
mimeType: file.type || 'application/octet-stream',
mtime: file.lastModified,
ctime: file.lastModified
};
files.push(fileInfo);
}
catch (error) {
console.warn('Failed to get file info:', error);
}
}
}
return {
files,
directories,
cancelled: false
};
}
catch (error) {
if (error instanceof Error && error.name === 'AbortError') {
return {
files: [],
directories: [],
cancelled: true
};
}
throw new Error(`File picker failed: ${error}`);
}
}
async openSystemFileManager(_path) {
// Web浏览器无法直接打开系统文件管理器
// 但可以提供一些替代方案
if (this.isFileSystemAccessSupported()) {
try {
await window.showDirectoryPicker();
}
catch (error) {
if (!(error instanceof Error) || error.name !== 'AbortError') {
throw new Error('Cannot open system file manager in web browsers');
}
}
}
else {
throw new Error('File system access not supported in this browser');
}
}
async openFileWithSystemApp(_filePath, _mimeType) {
throw new Error('Opening files with system apps is not supported in web browsers');
}
// ============ AI 编辑操作 ============
async readFileRange(_options) {
throw new Error('Reading file ranges is not supported in web browsers for security reasons');
}
async insertContent(_options) {
throw new Error('Inserting content is not supported in web browsers for security reasons');
}
async replaceInFile(_options) {
throw new Error('Replacing in file is not supported in web browsers for security reasons');
}
async applyDiff(_options) {
throw new Error('Applying diff is not supported in web browsers for security reasons');
}
async getFileHash(_options) {
throw new Error('Getting file hash is not supported in web browsers for security reasons');
}
async getLineCount(_options) {
throw new Error('Getting line count is not supported in web browsers for security reasons');
}
getMimeTypeFromExtension(extension) {
const mimeTypes = {
'txt': 'text/plain',
'pdf': 'application/pdf',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'png': 'image/png',
'gif': 'image/gif',
'mp4': 'video/mp4',
'mp3': 'audio/mpeg',
'zip': 'application/zip',
'json': 'application/json',
'xml': 'application/xml',
'html': 'text/html',
'css': 'text/css',
'js': 'application/javascript'
};
return mimeTypes[extension.toLowerCase()] || 'application/octet-stream';
}
async echo(options) {
console.log('ECHO', options);
return options;
}
}
var web = /*#__PURE__*/Object.freeze({
__proto__: null,
AdvancedFileManagerWeb: AdvancedFileManagerWeb
});
exports.AdvancedFileManager = AdvancedFileManager;
return exports;
})({}, capacitorExports);
//# sourceMappingURL=plugin.js.map