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 110 111 112 113 114 115 116 117 118 119 120 121 122 | 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 1x 2x 9x 9x 9x 7x 9x 2x 1x 1x 1x | import { Capacitor } from '@capacitor/core';
import { Directory, Encoding, Filesystem } from '@capacitor/filesystem';
import { FilePicker } from '@capawesome/capacitor-file-picker';
import YAML from 'yaml';
/**
* **WARNING:** On native platforms, binary data is converted to base64 before writing, which can lag the UI for large files.
* @param {Blob | ArrayBuffer | string} content
* @param {string} filename
* @param {string} [contentType] defaults to 'text/plain' for strings and 'application/octet-stream' for blobs
* @returns {Promise<URL|void>} Saved file's URI on native platforms, void on web
*/
export async function downloadAsFile(content, filename, contentType) {
if (Capacitor.isNativePlatform()) {
const permission = await Filesystem.checkPermissions();
Iif (permission.publicStorage !== 'granted') {
await Filesystem.requestPermissions();
}
const { path: directoryUri } = await FilePicker.pickDirectory();
console.info('Got directory URI', directoryUri);
// Directory URI looks like: content://com.android.externalstorage.documents/tree/primary%3ADocuments%2Fcigale%20exports
const directory = new URL(
decodeURIComponent(new URL(directoryUri).pathname.split('/').at(-1) || '')
).pathname;
console.info('Saving file to', directory);
/** @type {Pick<import('@capacitor/filesystem').WriteFileOptions, 'data' | 'encoding'>} */
let input;
if (typeof content === 'string') {
input = {
data: content,
encoding: Encoding.UTF8,
};
} else E{
input = {
data: new Uint8Array(
content instanceof Blob ? await content.arrayBuffer() : content
).toBase64(),
};
}
const { uri } = await Filesystem.writeFile({
path: `${directory.replace(/^content:\/\//, '')}/${filename}`,
directory: Directory.ExternalStorage,
...input,
});
console.info('File saved to', uri);
try {
return new URL(uri);
} catch (err) {
// Some platforms return URIs that the URL constructor doesn't accept in Node/jsdom.
// Fall back to returning the raw string so callers can handle it.
return uri;
}
} else {
const blob =
content instanceof Blob
? content
: new Blob([content], {
type:
contentType ??
(typeof content === 'string'
? 'text/plain'
: 'application/octet-stream'),
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
}
}
/**
*
* @template {string} Keys
* @param { { [K in Keys]?: unknown } } object the object to serialize
* @param {readonly Keys[]} ordering an array of keys in target order, for the top-level object
* @param {'json' | 'yaml'} format
* @param {string} schema the json schema URL
*/
export function stringifyWithToplevelOrdering(format, schema, object, ordering) {
let keysOrder = [...ordering];
if (format === 'json') {
// @ts-expect-error
keysOrder = ['$schema', ...keysOrder];
}
/**
* @param {*} _
* @param {*} value
*/
const reviver = (_, value) => {
Iif (value === null) return value;
Iif (Array.isArray(value)) return value;
if (typeof value !== 'object') return value;
// @ts-expect-error
Eif (Object.keys(value).every((key) => keysOrder.includes(key))) {
return Object.fromEntries(keysOrder.map((key) => [key, value[key]]));
}
return value;
};
if (format === 'yaml') {
const yamled = YAML.stringify(object, reviver, 2);
return `# yaml-language-server: $schema=${schema}\n\n${yamled}`;
}
return JSON.stringify({ $schema: schema, ...object }, reviver, 2);
}
|