1import { EventEmitter, UnavailabilityError } from 'expo-modules-core';
2import { Platform } from 'react-native';
3import { v4 as uuidv4 } from 'uuid';
4import ExponentFileSystem from './ExponentFileSystem';
5import { EncodingType, FileSystemSessionType, FileSystemUploadType, } from './FileSystem.types';
6if (!ExponentFileSystem) {
7    console.warn("No native ExponentFileSystem module found, are you sure the expo-file-system's module is linked properly?");
8}
9// Prevent webpack from pruning this.
10const _unused = new EventEmitter(ExponentFileSystem); // eslint-disable-line
11export { EncodingType, FileSystemSessionType, FileSystemUploadType, };
12function normalizeEndingSlash(p) {
13    if (p != null) {
14        return p.replace(/\/*$/, '') + '/';
15    }
16    return null;
17}
18export const documentDirectory = normalizeEndingSlash(ExponentFileSystem.documentDirectory);
19export const cacheDirectory = normalizeEndingSlash(ExponentFileSystem.cacheDirectory);
20export const { bundledAssets, bundleDirectory } = ExponentFileSystem;
21export async function getInfoAsync(fileUri, options = {}) {
22    if (!ExponentFileSystem.getInfoAsync) {
23        throw new UnavailabilityError('expo-file-system', 'getInfoAsync');
24    }
25    return await ExponentFileSystem.getInfoAsync(fileUri, options);
26}
27export async function readAsStringAsync(fileUri, options) {
28    if (!ExponentFileSystem.readAsStringAsync) {
29        throw new UnavailabilityError('expo-file-system', 'readAsStringAsync');
30    }
31    return await ExponentFileSystem.readAsStringAsync(fileUri, options || {});
32}
33export async function getContentUriAsync(fileUri) {
34    if (Platform.OS === 'android') {
35        if (!ExponentFileSystem.getContentUriAsync) {
36            throw new UnavailabilityError('expo-file-system', 'getContentUriAsync');
37        }
38        return await ExponentFileSystem.getContentUriAsync(fileUri);
39    }
40    else {
41        return new Promise(function (resolve, reject) {
42            resolve(fileUri);
43        });
44    }
45}
46export async function writeAsStringAsync(fileUri, contents, options = {}) {
47    if (!ExponentFileSystem.writeAsStringAsync) {
48        throw new UnavailabilityError('expo-file-system', 'writeAsStringAsync');
49    }
50    return await ExponentFileSystem.writeAsStringAsync(fileUri, contents, options);
51}
52export async function deleteAsync(fileUri, options = {}) {
53    if (!ExponentFileSystem.deleteAsync) {
54        throw new UnavailabilityError('expo-file-system', 'deleteAsync');
55    }
56    return await ExponentFileSystem.deleteAsync(fileUri, options);
57}
58export async function deleteLegacyDocumentDirectoryAndroid() {
59    if (Platform.OS !== 'android' || documentDirectory == null) {
60        return;
61    }
62    const legacyDocumentDirectory = `${documentDirectory}ExperienceData/`;
63    return await deleteAsync(legacyDocumentDirectory, { idempotent: true });
64}
65export async function moveAsync(options) {
66    if (!ExponentFileSystem.moveAsync) {
67        throw new UnavailabilityError('expo-file-system', 'moveAsync');
68    }
69    return await ExponentFileSystem.moveAsync(options);
70}
71export async function copyAsync(options) {
72    if (!ExponentFileSystem.copyAsync) {
73        throw new UnavailabilityError('expo-file-system', 'copyAsync');
74    }
75    return await ExponentFileSystem.copyAsync(options);
76}
77export async function makeDirectoryAsync(fileUri, options = {}) {
78    if (!ExponentFileSystem.makeDirectoryAsync) {
79        throw new UnavailabilityError('expo-file-system', 'makeDirectoryAsync');
80    }
81    return await ExponentFileSystem.makeDirectoryAsync(fileUri, options);
82}
83export async function readDirectoryAsync(fileUri) {
84    if (!ExponentFileSystem.readDirectoryAsync) {
85        throw new UnavailabilityError('expo-file-system', 'readDirectoryAsync');
86    }
87    return await ExponentFileSystem.readDirectoryAsync(fileUri, {});
88}
89export async function getFreeDiskStorageAsync() {
90    if (!ExponentFileSystem.getFreeDiskStorageAsync) {
91        throw new UnavailabilityError('expo-file-system', 'getFreeDiskStorageAsync');
92    }
93    return await ExponentFileSystem.getFreeDiskStorageAsync();
94}
95export async function getTotalDiskCapacityAsync() {
96    if (!ExponentFileSystem.getTotalDiskCapacityAsync) {
97        throw new UnavailabilityError('expo-file-system', 'getTotalDiskCapacityAsync');
98    }
99    return await ExponentFileSystem.getTotalDiskCapacityAsync();
100}
101export async function downloadAsync(uri, fileUri, options = {}) {
102    if (!ExponentFileSystem.downloadAsync) {
103        throw new UnavailabilityError('expo-file-system', 'downloadAsync');
104    }
105    return await ExponentFileSystem.downloadAsync(uri, fileUri, {
106        sessionType: FileSystemSessionType.BACKGROUND,
107        ...options,
108    });
109}
110export async function uploadAsync(url, fileUri, options = {}) {
111    if (!ExponentFileSystem.uploadAsync) {
112        throw new UnavailabilityError('expo-file-system', 'uploadAsync');
113    }
114    return await ExponentFileSystem.uploadAsync(url, fileUri, {
115        sessionType: FileSystemSessionType.BACKGROUND,
116        uploadType: FileSystemUploadType.BINARY_CONTENT,
117        ...options,
118        httpMethod: (options.httpMethod || 'POST').toUpperCase(),
119    });
120}
121export function createDownloadResumable(uri, fileUri, options, callback, resumeData) {
122    return new DownloadResumable(uri, fileUri, options, callback, resumeData);
123}
124export function createUploadTask(url, fileUri, options, callback) {
125    return new UploadTask(url, fileUri, options, callback);
126}
127export class FileSystemCancellableNetworkTask {
128    _uuid = uuidv4();
129    taskWasCanceled = false;
130    emitter = new EventEmitter(ExponentFileSystem);
131    subscription;
132    async cancelAsync() {
133        if (!ExponentFileSystem.networkTaskCancelAsync) {
134            throw new UnavailabilityError('expo-file-system', 'networkTaskCancelAsync');
135        }
136        this.removeSubscription();
137        this.taskWasCanceled = true;
138        return await ExponentFileSystem.networkTaskCancelAsync(this.uuid);
139    }
140    isTaskCancelled() {
141        if (this.taskWasCanceled) {
142            console.warn('This task was already canceled.');
143            return true;
144        }
145        return false;
146    }
147    get uuid() {
148        return this._uuid;
149    }
150    addSubscription() {
151        if (this.subscription) {
152            return;
153        }
154        this.subscription = this.emitter.addListener(this.getEventName(), (event) => {
155            if (event.uuid === this.uuid) {
156                const callback = this.getCallback();
157                if (callback) {
158                    callback(event.data);
159                }
160            }
161        });
162    }
163    removeSubscription() {
164        if (!this.subscription) {
165            return;
166        }
167        this.emitter.removeSubscription(this.subscription);
168        this.subscription = null;
169    }
170}
171export class UploadTask extends FileSystemCancellableNetworkTask {
172    url;
173    fileUri;
174    callback;
175    options;
176    constructor(url, fileUri, options, callback) {
177        super();
178        this.url = url;
179        this.fileUri = fileUri;
180        this.callback = callback;
181        const httpMethod = (options?.httpMethod?.toUpperCase ||
182            'POST');
183        this.options = {
184            sessionType: FileSystemSessionType.BACKGROUND,
185            uploadType: FileSystemUploadType.BINARY_CONTENT,
186            ...options,
187            httpMethod,
188        };
189    }
190    getEventName() {
191        return 'expo-file-system.uploadProgress';
192    }
193    getCallback() {
194        return this.callback;
195    }
196    async uploadAsync() {
197        if (!ExponentFileSystem.uploadTaskStartAsync) {
198            throw new UnavailabilityError('expo-file-system', 'uploadTaskStartAsync');
199        }
200        if (this.isTaskCancelled()) {
201            return;
202        }
203        this.addSubscription();
204        const result = await ExponentFileSystem.uploadTaskStartAsync(this.url, this.fileUri, this.uuid, this.options);
205        this.removeSubscription();
206        return result;
207    }
208}
209export class DownloadResumable extends FileSystemCancellableNetworkTask {
210    url;
211    _fileUri;
212    options;
213    callback;
214    resumeData;
215    constructor(url, _fileUri, options = {}, callback, resumeData) {
216        super();
217        this.url = url;
218        this._fileUri = _fileUri;
219        this.options = options;
220        this.callback = callback;
221        this.resumeData = resumeData;
222    }
223    get fileUri() {
224        return this._fileUri;
225    }
226    getEventName() {
227        return 'expo-file-system.downloadProgress';
228    }
229    getCallback() {
230        return this.callback;
231    }
232    async downloadAsync() {
233        if (!ExponentFileSystem.downloadResumableStartAsync) {
234            throw new UnavailabilityError('expo-file-system', 'downloadResumableStartAsync');
235        }
236        if (this.isTaskCancelled()) {
237            return;
238        }
239        this.addSubscription();
240        return await ExponentFileSystem.downloadResumableStartAsync(this.url, this._fileUri, this.uuid, this.options, this.resumeData);
241    }
242    async pauseAsync() {
243        if (!ExponentFileSystem.downloadResumablePauseAsync) {
244            throw new UnavailabilityError('expo-file-system', 'downloadResumablePauseAsync');
245        }
246        if (this.isTaskCancelled()) {
247            return {
248                fileUri: this._fileUri,
249                options: this.options,
250                url: this.url,
251            };
252        }
253        const pauseResult = await ExponentFileSystem.downloadResumablePauseAsync(this.uuid);
254        this.removeSubscription();
255        if (pauseResult) {
256            this.resumeData = pauseResult.resumeData;
257            return this.savable();
258        }
259        else {
260            throw new Error('Unable to generate a savable pause state');
261        }
262    }
263    async resumeAsync() {
264        if (!ExponentFileSystem.downloadResumableStartAsync) {
265            throw new UnavailabilityError('expo-file-system', 'downloadResumableStartAsync');
266        }
267        if (this.isTaskCancelled()) {
268            return;
269        }
270        this.addSubscription();
271        return await ExponentFileSystem.downloadResumableStartAsync(this.url, this.fileUri, this.uuid, this.options, this.resumeData);
272    }
273    savable() {
274        return {
275            url: this.url,
276            fileUri: this.fileUri,
277            options: this.options,
278            resumeData: this.resumeData,
279        };
280    }
281}
282const baseReadAsStringAsync = readAsStringAsync;
283const baseWriteAsStringAsync = writeAsStringAsync;
284const baseDeleteAsync = deleteAsync;
285const baseMoveAsync = moveAsync;
286const baseCopyAsync = copyAsync;
287/**
288 * Android only
289 */
290export var StorageAccessFramework;
291(function (StorageAccessFramework) {
292    function getUriForDirectoryInRoot(folderName) {
293        return `content://com.android.externalstorage.documents/tree/primary:${folderName}/document/primary:${folderName}`;
294    }
295    StorageAccessFramework.getUriForDirectoryInRoot = getUriForDirectoryInRoot;
296    async function requestDirectoryPermissionsAsync(initialFileUrl = null) {
297        if (!ExponentFileSystem.requestDirectoryPermissionsAsync) {
298            throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.requestDirectoryPermissionsAsync');
299        }
300        return await ExponentFileSystem.requestDirectoryPermissionsAsync(initialFileUrl);
301    }
302    StorageAccessFramework.requestDirectoryPermissionsAsync = requestDirectoryPermissionsAsync;
303    async function readDirectoryAsync(dirUri) {
304        if (!ExponentFileSystem.readSAFDirectoryAsync) {
305            throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.readDirectoryAsync');
306        }
307        return await ExponentFileSystem.readSAFDirectoryAsync(dirUri, {});
308    }
309    StorageAccessFramework.readDirectoryAsync = readDirectoryAsync;
310    async function makeDirectoryAsync(parentUri, dirName) {
311        if (!ExponentFileSystem.makeSAFDirectoryAsync) {
312            throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.makeDirectoryAsync');
313        }
314        return await ExponentFileSystem.makeSAFDirectoryAsync(parentUri, dirName);
315    }
316    StorageAccessFramework.makeDirectoryAsync = makeDirectoryAsync;
317    async function createFileAsync(parentUri, fileName, mimeType) {
318        if (!ExponentFileSystem.createSAFFileAsync) {
319            throw new UnavailabilityError('expo-file-system', 'StorageAccessFramework.createFileAsync');
320        }
321        return await ExponentFileSystem.createSAFFileAsync(parentUri, fileName, mimeType);
322    }
323    StorageAccessFramework.createFileAsync = createFileAsync;
324    StorageAccessFramework.writeAsStringAsync = baseWriteAsStringAsync;
325    StorageAccessFramework.readAsStringAsync = baseReadAsStringAsync;
326    StorageAccessFramework.deleteAsync = baseDeleteAsync;
327    StorageAccessFramework.moveAsync = baseMoveAsync;
328    StorageAccessFramework.copyAsync = baseCopyAsync;
329})(StorageAccessFramework || (StorageAccessFramework = {}));
330//# sourceMappingURL=FileSystem.js.map