@snups/rjsf-utils
Version:
Utility functions for @snups/rjsf-core
46 lines (42 loc) • 1.96 kB
text/typescript
/** Given the `FileReader.readAsDataURL()` based `dataURI` extracts that data into an actual Blob along with the name
* of that Blob if provided in the URL. If no name is provided, then the name falls back to `unknown`.
*
* @param dataURI - The `DataUrl` potentially containing name and raw data to be converted to a Blob
* @returns - an object containing a Blob and its name, extracted from the URI
*/
export default function dataURItoBlob(dataURILike: string) {
// check if is dataURI
if (dataURILike.indexOf('data:') === -1) {
throw new Error('File is invalid: URI must be a dataURI');
}
const dataURI = dataURILike.slice(5);
// split the dataURI into media and base64, with the base64 signature
const splitted = dataURI.split(';base64,');
// if the base64 signature is not present, the latter part will become empty
if (splitted.length !== 2) {
throw new Error('File is invalid: dataURI must be base64');
}
// extract the mime type, media parameters including the name, and the base64 string
const [media, base64] = splitted;
const [mime, ...mediaparams] = media.split(';');
const type = mime || '';
// extract the name from the parameters
const name = decodeURI(
// parse the parameters into key-value pairs, find a key, and extract a value
// if no key is found, then the name is unknown
mediaparams.map((param) => param.split('=')).find(([key]) => key === 'name')?.[1] || 'unknown',
);
// Built the Uint8Array Blob parameter from the base64 string.
try {
const binary = atob(base64);
const array = new Array(binary.length);
for (let i = 0; i < binary.length; i++) {
array[i] = binary.charCodeAt(i);
}
// Create the blob object
const blob = new window.Blob([new Uint8Array(array)], { type });
return { blob, name };
} catch (error) {
throw new Error('File is invalid: ' + (error as Error).message);
}
}