react-native-file-access
Version:
Filesystem access for React Native
261 lines (255 loc) • 6.86 kB
JavaScript
;
import FileAccessNative from "./NativeFileAccess.js";
export { AndroidScoped, Util } from "./util.js";
/**
* ID tracking next fetch request.
*/
const getRequestId = (() => {
let nextId = 0;
return () => ++nextId;
})();
/**
* Process fetch events for the request.
*/
function registerFetchListener(requestId, resolve, reject, onProgress) {
const progressListener = onProgress == null ? null : FileAccessNative.onFetchProgress(event => {
if (event.requestId === requestId) {
onProgress(event.bytesRead, event.contentLength, event.done);
}
});
const errorListener = FileAccessNative.onFetchError(event => {
if (event.requestId === requestId) {
unsubscribe();
reject(new Error(event.message));
}
});
const completeListener = FileAccessNative.onFetchComplete(event => {
if (event.requestId === requestId) {
unsubscribe();
const headersLower = new Map();
for (const [key, value] of Object.entries(event.headers)) {
headersLower.set(key.toLowerCase(), value);
}
resolve({
getHeader: header => headersLower.get(header.toLowerCase()),
headers: event.headers,
ok: event.ok,
redirected: event.redirected,
status: event.status,
statusText: event.statusText,
url: event.url
});
}
});
const unsubscribe = () => {
completeListener.remove();
errorListener.remove();
progressListener?.remove();
};
}
/**
* Get a `Promise` that will resolve after the specified timespan.
*/
function sleep(milliseconds) {
return new Promise(resolve => setTimeout(resolve, milliseconds));
}
/**
* Periodically report file copy status to the progress listener.
*/
async function wrapCpListener(source, target, completion, onProgress) {
const sourceStat = await FileSystem.stat(source);
while (true) {
const targetStat = await Promise.race([completion.then(() => true), sleep(150).then(() => FileSystem.stat(target)).catch(() => false)]);
if (targetStat === true) {
onProgress(sourceStat.size, sourceStat.size, true);
break; // Process completed.
} else if (targetStat !== false) {
onProgress(targetStat.size, sourceStat.size, false);
}
}
}
export const FileSystem = {
/**
* Append content to a file.
*
* Default encoding of `data` is assumed utf8.
*/
appendFile(path, data, encoding = 'utf8') {
return FileAccessNative.appendFile(path, data, encoding);
},
/**
* Append a file to another file.
*
* Returns number of bytes written.
*/
concatFiles(source, target) {
return FileAccessNative.concatFiles(source, target);
},
/**
* Copy a file.
*/
cp(source, target, onProgress) {
const res = FileAccessNative.cp(source, target);
return onProgress == null ? res : wrapCpListener(source, target, res, onProgress);
},
/**
* Copy a bundled asset file.
*
* When using Android asset type 'resource', include the folder, but skip the
* file extension. For example use 'raw/foo', for the file 'res/raw/foo.txt'.
* When possible, prefer using the 'assets/' folder; files in 'res/' have
* naming restrictions imposed by Android.
* https://developer.android.com/guide/topics/resources/providing-resources.html#OriginalFiles
*/
cpAsset(asset, target, type = 'asset') {
return FileAccessNative.cpAsset(asset, target, type);
},
/**
* Copy a file to an externally controlled location.
*
* On Android API level < 29, may require permission WRITE_EXTERNAL_STORAGE.
*/
cpExternal(source, targetName, dir) {
return FileAccessNative.cpExternal(source, targetName, dir);
},
/**
* Check device available space.
*/
df() {
return FileAccessNative.df();
},
/**
* Check if a path exists.
*/
exists(path) {
return FileAccessNative.exists(path);
},
/**
* Save a network request to a file.
*/
fetch(resource, init, onProgress) {
const requestId = getRequestId();
return new Promise((resolve, reject) => {
registerFetchListener(requestId, resolve, reject, onProgress);
FileAccessNative.fetch(requestId, resource, init);
});
},
/**
* Save a network request to a file.
*/
fetchManaged(resource, init, onProgress) {
const requestId = getRequestId();
return {
cancel: () => FileAccessNative.cancelFetch(requestId),
result: new Promise((resolve, reject) => {
registerFetchListener(requestId, resolve, reject, onProgress);
FileAccessNative.fetch(requestId, resource, init);
})
};
},
/**
* Return the local storage directory for app groups.
*
* This is an Apple only feature.
*/
getAppGroupDir(groupName) {
return FileAccessNative.getAppGroupDir(groupName);
},
/**
* Create a hard link.
*
* Creates a hard link at target pointing to source.
*/
hardlink(source, target) {
return FileAccessNative.hardlink(source, target);
},
/**
* Hash the file content.
*/
hash(path, algorithm) {
return FileAccessNative.hash(path, algorithm);
},
/**
* Check if a path is a directory.
*/
isDir(path) {
return FileAccessNative.isDir(path);
},
/**
* List files in a directory.
*/
ls(path) {
return FileAccessNative.ls(path);
},
/**
* Make a new directory.
*
* Returns path of the created directory.
*/
mkdir(path) {
return FileAccessNative.mkdir(path);
},
/**
* Move a file.
*/
mv(source, target) {
return FileAccessNative.mv(source, target);
},
/**
* Read the content of a file.
*/
readFile(path, encoding = 'utf8') {
return FileAccessNative.readFile(path, encoding);
},
/**
* Read a chunk of the content of a file.
*/
readFileChunk(path, offset, length, encoding = 'utf8') {
return FileAccessNative.readFileChunk(path, offset, length, encoding);
},
/**
* Read file metadata.
*/
stat(path) {
return FileAccessNative.stat(path);
},
/**
* Read metadata of all files in a directory.
*/
statDir(path) {
return FileAccessNative.statDir(path);
},
/**
* Create a symbolic link.
*
* Creates a symbolic link at target pointing to source.
*/
symlink(source, target) {
return FileAccessNative.symlink(source, target);
},
/**
* Delete a file.
*/
unlink(path) {
return FileAccessNative.unlink(path);
},
/**
* Extract a zip archive.
*/
unzip(source, target) {
return FileAccessNative.unzip(source, target);
},
/**
* Write content to a file.
*
* Default encoding of `data` is assumed utf8.
*/
writeFile(path, data, encoding = 'utf8') {
return FileAccessNative.writeFile(path, data, encoding);
}
};
/**
* Directory constants.
*/
export const Dirs = FileAccessNative.getConstants();
//# sourceMappingURL=index.js.map