All files / lib/storage capacitor.ts

85.71% Statements 30/35
75% Branches 6/8
92.85% Functions 13/14
85.71% Lines 30/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                3x 1x   2x   2x     1x 1x       1x           1x     1x           3x         3x   3x     1x   1x     1x         2x   2x 1x 1x 1x         2x               1x         1x     2x       1x 1x     2x         2x 1x       1x                
import type { BinaryStorageBackend } from './types.js';
 
import { Capacitor } from '@capacitor/core';
import { Directory, Filesystem } from '@capacitor/filesystem';
 
import { locatorToPath } from './utils.js';
 
export function CapacitorFilesystemBackend(): BinaryStorageBackend<'capacitor'> {
	if (!Capacitor.isNativePlatform())
		throw new Error('Capacitor filesystem binary storage backend is not supported on Web');
 
	const root = Directory.Data;
 
	return {
		name: 'capacitor',
		async exists(locator) {
			try {
				const stat = await Filesystem.stat({
					directory: root,
					path: locatorToPath(locator),
				});
				console.debug('[local fs] exists? yes: ', locatorToPath(locator), stat);
			} catch (error) {
				console.debug('[local fs] exists? no: ', locatorToPath(locator), error);
				return false;
			}
 
			return true;
		},
		async delete(locator) {
			await Filesystem.deleteFile({
				directory: root,
				path: locatorToPath(locator),
			});
		},
		async bytes(locator) {
			const file = await Filesystem.readFile({
				directory: root,
				path: locatorToPath(locator),
			});
 
			const bytes = Uint8Array.fromBase64(file.data as string);
 
			return bytes.buffer;
		},
		async text(locator) {
			const bytes = await this.bytes(locator);
 
			return new TextDecoder().decode(bytes);
		},
		async read(locator, type) {
			return new File([await this.bytes(locator)], locator.name, { type });
		},
		async write(locator, content) {
			let base64: string;
 
			Iif (content instanceof Blob) {
				base64 = (await content.bytes()).toBase64();
			} else if ('text' in content) {
				base64 = btoa(content.text);
			} else if ('bytes' in content) {
				base64 = new Uint8Array(content.bytes).toBase64();
			} else E{
				base64 = content.base64;
			}
 
			await Filesystem.writeFile({
				directory: root,
				path: locatorToPath(locator),
				data: base64,
				recursive: true,
			});
		},
		async size(locator) {
			const stat = await Filesystem.stat({
				directory: root,
				path: locatorToPath(locator),
			});
 
			return stat.size;
		},
		async count(locator) {
			return Filesystem.readdir({
				directory: root,
				path: locatorToPath(locator),
			})
				.then(({ files }) => files.length)
				.catch(() => 0);
		},
		async *list(locator) {
			const { files } = await Filesystem.readdir({
				directory: root,
				path: locatorToPath(locator),
			}).catch(() => ({ files: [] }));
 
			for (const file of files) {
				yield { ...locator, name: file.name };
			}
		},
		async clear(locator) {
			await Filesystem.rmdir({
				directory: root,
				path: locatorToPath(locator),
				recursive: true,
			});
		},
	};
}