@zag-js/file-utils 0.29.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +31 -4
- package/dist/index.d.ts +31 -4
- package/dist/index.js +38 -13
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +36 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,29 @@
|
|
|
1
|
-
declare function
|
|
1
|
+
declare function dataURItoBlob(uri: string): Blob;
|
|
2
|
+
|
|
3
|
+
declare function isMSEdge(win: Window): win is Window & {
|
|
4
|
+
navigator: {
|
|
5
|
+
msSaveOrOpenBlob: Function;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
interface DownloadFileOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The name of the file
|
|
11
|
+
*/
|
|
12
|
+
name?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The MIME type of the file
|
|
15
|
+
*/
|
|
16
|
+
type?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The file contents
|
|
19
|
+
*/
|
|
20
|
+
file: File | Blob | string;
|
|
21
|
+
/**
|
|
22
|
+
* The window environment
|
|
23
|
+
*/
|
|
24
|
+
win: typeof window;
|
|
25
|
+
}
|
|
26
|
+
declare function downloadFile(options: DownloadFileOptions): void;
|
|
2
27
|
|
|
3
28
|
interface FormatByteOptions {
|
|
4
29
|
locale?: string;
|
|
@@ -13,8 +38,10 @@ declare const getTotalFileSize: (files: File[]) => number;
|
|
|
13
38
|
|
|
14
39
|
declare const isFileEqual: (file1: File, file2: File) => boolean;
|
|
15
40
|
|
|
16
|
-
|
|
41
|
+
type FileError = "TOO_MANY_FILES" | "FILE_INVALID_TYPE" | "FILE_TOO_LARGE" | "FILE_TOO_SMALL";
|
|
42
|
+
|
|
43
|
+
declare function isValidFileSize(file: File, minSize?: number, maxSize?: number): [boolean, FileError | null];
|
|
17
44
|
|
|
18
|
-
declare function isValidFileType(file: File, accept: string | undefined): [boolean,
|
|
45
|
+
declare function isValidFileType(file: File, accept: string | undefined): [boolean, FileError | null];
|
|
19
46
|
|
|
20
|
-
export { downloadFile, formatFileSize, getAcceptAttrString, getFileDataUrl, getTotalFileSize, isFileEqual, isValidFileSize, isValidFileType };
|
|
47
|
+
export { type FileError, dataURItoBlob, downloadFile, formatFileSize, getAcceptAttrString, getFileDataUrl, getTotalFileSize, isFileEqual, isMSEdge, isValidFileSize, isValidFileType };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,29 @@
|
|
|
1
|
-
declare function
|
|
1
|
+
declare function dataURItoBlob(uri: string): Blob;
|
|
2
|
+
|
|
3
|
+
declare function isMSEdge(win: Window): win is Window & {
|
|
4
|
+
navigator: {
|
|
5
|
+
msSaveOrOpenBlob: Function;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
interface DownloadFileOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The name of the file
|
|
11
|
+
*/
|
|
12
|
+
name?: string;
|
|
13
|
+
/**
|
|
14
|
+
* The MIME type of the file
|
|
15
|
+
*/
|
|
16
|
+
type?: string;
|
|
17
|
+
/**
|
|
18
|
+
* The file contents
|
|
19
|
+
*/
|
|
20
|
+
file: File | Blob | string;
|
|
21
|
+
/**
|
|
22
|
+
* The window environment
|
|
23
|
+
*/
|
|
24
|
+
win: typeof window;
|
|
25
|
+
}
|
|
26
|
+
declare function downloadFile(options: DownloadFileOptions): void;
|
|
2
27
|
|
|
3
28
|
interface FormatByteOptions {
|
|
4
29
|
locale?: string;
|
|
@@ -13,8 +38,10 @@ declare const getTotalFileSize: (files: File[]) => number;
|
|
|
13
38
|
|
|
14
39
|
declare const isFileEqual: (file1: File, file2: File) => boolean;
|
|
15
40
|
|
|
16
|
-
|
|
41
|
+
type FileError = "TOO_MANY_FILES" | "FILE_INVALID_TYPE" | "FILE_TOO_LARGE" | "FILE_TOO_SMALL";
|
|
42
|
+
|
|
43
|
+
declare function isValidFileSize(file: File, minSize?: number, maxSize?: number): [boolean, FileError | null];
|
|
17
44
|
|
|
18
|
-
declare function isValidFileType(file: File, accept: string | undefined): [boolean,
|
|
45
|
+
declare function isValidFileType(file: File, accept: string | undefined): [boolean, FileError | null];
|
|
19
46
|
|
|
20
|
-
export { downloadFile, formatFileSize, getAcceptAttrString, getFileDataUrl, getTotalFileSize, isFileEqual, isValidFileSize, isValidFileType };
|
|
47
|
+
export { type FileError, dataURItoBlob, downloadFile, formatFileSize, getAcceptAttrString, getFileDataUrl, getTotalFileSize, isFileEqual, isMSEdge, isValidFileSize, isValidFileType };
|
package/dist/index.js
CHANGED
|
@@ -20,32 +20,55 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
+
dataURItoBlob: () => dataURItoBlob,
|
|
23
24
|
downloadFile: () => downloadFile,
|
|
24
25
|
formatFileSize: () => formatFileSize,
|
|
25
26
|
getAcceptAttrString: () => getAcceptAttrString,
|
|
26
27
|
getFileDataUrl: () => getFileDataUrl,
|
|
27
28
|
getTotalFileSize: () => getTotalFileSize,
|
|
28
29
|
isFileEqual: () => isFileEqual,
|
|
30
|
+
isMSEdge: () => isMSEdge,
|
|
29
31
|
isValidFileSize: () => isValidFileSize,
|
|
30
32
|
isValidFileType: () => isValidFileType
|
|
31
33
|
});
|
|
32
34
|
module.exports = __toCommonJS(src_exports);
|
|
33
35
|
|
|
36
|
+
// src/data-url-to-blob.ts
|
|
37
|
+
function dataURItoBlob(uri) {
|
|
38
|
+
const binary = atob(uri.split(",")[1]);
|
|
39
|
+
const mimeString = uri.split(",")[0].split(":")[1].split(";")[0];
|
|
40
|
+
const buffer = new ArrayBuffer(binary.length);
|
|
41
|
+
const intArray = new Uint8Array(buffer);
|
|
42
|
+
for (let i = 0; i < binary.length; i++) {
|
|
43
|
+
intArray[i] = binary.charCodeAt(i);
|
|
44
|
+
}
|
|
45
|
+
return new Blob([buffer], { type: mimeString });
|
|
46
|
+
}
|
|
47
|
+
|
|
34
48
|
// src/download-file.ts
|
|
35
|
-
function
|
|
49
|
+
function isMSEdge(win) {
|
|
50
|
+
return Boolean(win.navigator && win.navigator.msSaveOrOpenBlob);
|
|
51
|
+
}
|
|
52
|
+
function downloadFile(options) {
|
|
53
|
+
const { file, win, type, name } = options;
|
|
36
54
|
const doc = win.document;
|
|
37
|
-
const
|
|
55
|
+
const obj = typeof file === "string" ? new Blob([file], { type }) : file;
|
|
56
|
+
const fileName = typeof file === "string" ? name : file instanceof File ? file.name : void 0;
|
|
57
|
+
if (isMSEdge(win)) {
|
|
58
|
+
win.navigator.msSaveOrOpenBlob(obj, fileName || "file-download");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const url = win.URL.createObjectURL(obj);
|
|
38
62
|
const anchor = doc.createElement("a");
|
|
39
63
|
anchor.style.display = "none";
|
|
40
|
-
anchor.href =
|
|
41
|
-
anchor.
|
|
42
|
-
|
|
64
|
+
anchor.href = url;
|
|
65
|
+
anchor.rel = "noopener";
|
|
66
|
+
anchor.download = fileName || "file-download";
|
|
67
|
+
doc.documentElement.appendChild(anchor);
|
|
43
68
|
anchor.click();
|
|
44
69
|
setTimeout(() => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
anchor?.parentNode?.removeChild(anchor);
|
|
70
|
+
win.URL.revokeObjectURL(url);
|
|
71
|
+
anchor.remove();
|
|
49
72
|
}, 0);
|
|
50
73
|
}
|
|
51
74
|
|
|
@@ -113,13 +136,13 @@ function isValidFileSize(file, minSize, maxSize) {
|
|
|
113
136
|
if (isDefined(file.size)) {
|
|
114
137
|
if (isDefined(minSize) && isDefined(maxSize)) {
|
|
115
138
|
if (file.size > maxSize)
|
|
116
|
-
return [false, "
|
|
139
|
+
return [false, "FILE_TOO_LARGE"];
|
|
117
140
|
if (file.size < minSize)
|
|
118
|
-
return [false, "
|
|
141
|
+
return [false, "FILE_TOO_SMALL"];
|
|
119
142
|
} else if (isDefined(minSize) && file.size < minSize) {
|
|
120
|
-
return [false, "
|
|
143
|
+
return [false, "FILE_TOO_SMALL"];
|
|
121
144
|
} else if (isDefined(maxSize) && file.size > maxSize) {
|
|
122
|
-
return [false, "
|
|
145
|
+
return [false, "FILE_TOO_LARGE"];
|
|
123
146
|
}
|
|
124
147
|
}
|
|
125
148
|
return [true, null];
|
|
@@ -151,12 +174,14 @@ function isValidFileType(file, accept) {
|
|
|
151
174
|
}
|
|
152
175
|
// Annotate the CommonJS export names for ESM import in node:
|
|
153
176
|
0 && (module.exports = {
|
|
177
|
+
dataURItoBlob,
|
|
154
178
|
downloadFile,
|
|
155
179
|
formatFileSize,
|
|
156
180
|
getAcceptAttrString,
|
|
157
181
|
getFileDataUrl,
|
|
158
182
|
getTotalFileSize,
|
|
159
183
|
isFileEqual,
|
|
184
|
+
isMSEdge,
|
|
160
185
|
isValidFileSize,
|
|
161
186
|
isValidFileType
|
|
162
187
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/download-file.ts","../src/format-file-size.ts","../src/get-accept-attr.ts","../src/get-file-data-url.ts","../src/get-total-file-size.ts","../src/is-file-equal.ts","../src/is-valid-file-size.ts","../src/is-valid-file-type.ts"],"sourcesContent":["export * from \"./download-file\"\nexport * from \"./format-file-size\"\nexport * from \"./get-accept-attr\"\nexport * from \"./get-file-data-url\"\nexport * from \"./get-total-file-size\"\nexport * from \"./is-file-equal\"\nexport * from \"./is-valid-file-size\"\nexport * from \"./is-valid-file-type\"\n","export function
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/data-url-to-blob.ts","../src/download-file.ts","../src/format-file-size.ts","../src/get-accept-attr.ts","../src/get-file-data-url.ts","../src/get-total-file-size.ts","../src/is-file-equal.ts","../src/is-valid-file-size.ts","../src/is-valid-file-type.ts"],"sourcesContent":["export * from \"./data-url-to-blob\"\nexport * from \"./download-file\"\nexport * from \"./format-file-size\"\nexport * from \"./get-accept-attr\"\nexport * from \"./get-file-data-url\"\nexport * from \"./get-total-file-size\"\nexport * from \"./is-file-equal\"\nexport * from \"./is-valid-file-size\"\nexport * from \"./is-valid-file-type\"\nexport type * from \"./types.ts\"\n","export function dataURItoBlob(uri: string): Blob {\n const binary = atob(uri.split(\",\")[1])\n\n // separate out the mime component\n const mimeString = uri.split(\",\")[0].split(\":\")[1].split(\";\")[0]\n\n // write the bytes of the string to an ArrayBuffer\n const buffer = new ArrayBuffer(binary.length)\n\n // create a view into the buffer\n const intArray = new Uint8Array(buffer)\n\n for (let i = 0; i < binary.length; i++) {\n intArray[i] = binary.charCodeAt(i)\n }\n\n return new Blob([buffer], { type: mimeString })\n}\n","export function isMSEdge(win: Window): win is Window & { navigator: { msSaveOrOpenBlob: Function } } {\n // @ts-ignore\n return Boolean(win.navigator && win.navigator.msSaveOrOpenBlob)\n}\n\ninterface DownloadFileOptions {\n /**\n * The name of the file\n */\n name?: string\n /**\n * The MIME type of the file\n */\n type?: string\n /**\n * The file contents\n */\n file: File | Blob | string\n /**\n * The window environment\n */\n win: typeof window\n}\n\nexport function downloadFile(options: DownloadFileOptions) {\n const { file, win, type, name } = options\n\n const doc = win.document\n\n const obj = typeof file === \"string\" ? new Blob([file], { type }) : file\n const fileName = typeof file === \"string\" ? name : file instanceof File ? file.name : undefined\n\n if (isMSEdge(win)) {\n win.navigator.msSaveOrOpenBlob(obj, fileName || \"file-download\")\n return\n }\n\n const url = win.URL.createObjectURL(obj)\n\n const anchor = doc.createElement(\"a\")\n anchor.style.display = \"none\"\n anchor.href = url\n anchor.rel = \"noopener\"\n anchor.download = fileName || \"file-download\"\n\n doc.documentElement.appendChild(anchor)\n anchor.click()\n\n setTimeout(() => {\n win.URL.revokeObjectURL(url)\n anchor.remove()\n }, 0)\n}\n","const SIZES = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\nconst KILO = 1024\n\ninterface FormatByteOptions {\n locale?: string\n}\n\nexport const formatFileSize = (bytes: number, options: FormatByteOptions = {}) => {\n const { locale = \"en-US\" } = options\n if (bytes === 0) return \"0 B\"\n\n const i = Math.floor(Math.log(bytes) / Math.log(KILO))\n const fileSize = bytes / Math.pow(KILO, i)\n\n const formattedSize = new Intl.NumberFormat(locale).format(fileSize)\n return `${formattedSize} ${SIZES[i]}`\n}\n","function isMIMEType(v: string) {\n return v === \"audio/*\" || v === \"video/*\" || v === \"image/*\" || v === \"text/*\" || /\\w+\\/[-+.\\w]+/g.test(v)\n}\n\nfunction isExt(v: string) {\n return /^.*\\.[\\w]+$/.test(v)\n}\n\nexport function getAcceptAttrString(accept: Record<string, string[]> | string | undefined) {\n if (!accept) return\n if (typeof accept === \"string\") return accept\n return Object.entries(accept)\n .reduce((a, [mimeType, ext]) => [...a, mimeType, ...ext], [] as string[])\n .filter((v) => isMIMEType(v) || isExt(v))\n .join(\",\")\n}\n","export const getFileDataUrl = async (file: File | Blob) => {\n const reader = new FileReader()\n return new Promise<string | undefined>((resolve, reject) => {\n reader.onerror = () => {\n reader.abort()\n reject(new Error(\"There was an error reading a file\"))\n }\n\n reader.onloadend = () => {\n const { result } = reader\n if (result instanceof ArrayBuffer) {\n reject(new Error(\"Expected DataURL as string from Blob/File, got ArrayBuffer\"))\n } else {\n resolve(result || undefined)\n }\n }\n\n reader.readAsDataURL(file)\n })\n}\n","export const getTotalFileSize = (files: File[]) => {\n return files.reduce((acc, file) => acc + file.size, 0)\n}\n","export const isFileEqual = (file1: File, file2: File) => {\n return file1.name === file2.name && file1.size === file2.size && file1.type === file2.type\n}\n","import type { FileError } from \"./types\"\n\nconst isDefined = <T>(v: T | undefined): v is T => v !== undefined && v !== null\n\nexport function isValidFileSize(file: File, minSize?: number, maxSize?: number): [boolean, FileError | null] {\n if (isDefined(file.size)) {\n if (isDefined(minSize) && isDefined(maxSize)) {\n if (file.size > maxSize) return [false, \"FILE_TOO_LARGE\"]\n if (file.size < minSize) return [false, \"FILE_TOO_SMALL\"]\n } else if (isDefined(minSize) && file.size < minSize) {\n return [false, \"FILE_TOO_SMALL\"]\n } else if (isDefined(maxSize) && file.size > maxSize) {\n return [false, \"FILE_TOO_LARGE\"]\n }\n }\n return [true, null]\n}\n","import type { FileError } from \"./types\"\n\nfunction isFileAccepted(file: File | null, accept: string[] | string | undefined) {\n if (file && accept) {\n const types = Array.isArray(accept) ? accept : accept.split(\",\")\n\n const fileName = file.name || \"\"\n const mimeType = (file.type || \"\").toLowerCase()\n const baseMimeType = mimeType.replace(/\\/.*$/, \"\")\n\n return types.some((type) => {\n const validType = type.trim().toLowerCase()\n\n if (validType.charAt(0) === \".\") {\n return fileName.toLowerCase().endsWith(validType)\n }\n\n if (validType.endsWith(\"/*\")) {\n return baseMimeType === validType.replace(/\\/.*$/, \"\")\n }\n\n return mimeType === validType\n })\n }\n return true\n}\n\nexport function isValidFileType(file: File, accept: string | undefined): [boolean, FileError | null] {\n const isAcceptable = file.type === \"application/x-moz-file\" || isFileAccepted(file, accept)\n return [isAcceptable, isAcceptable ? null : \"FILE_INVALID_TYPE\"]\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,39 @@
|
|
|
1
|
+
// src/data-url-to-blob.ts
|
|
2
|
+
function dataURItoBlob(uri) {
|
|
3
|
+
const binary = atob(uri.split(",")[1]);
|
|
4
|
+
const mimeString = uri.split(",")[0].split(":")[1].split(";")[0];
|
|
5
|
+
const buffer = new ArrayBuffer(binary.length);
|
|
6
|
+
const intArray = new Uint8Array(buffer);
|
|
7
|
+
for (let i = 0; i < binary.length; i++) {
|
|
8
|
+
intArray[i] = binary.charCodeAt(i);
|
|
9
|
+
}
|
|
10
|
+
return new Blob([buffer], { type: mimeString });
|
|
11
|
+
}
|
|
12
|
+
|
|
1
13
|
// src/download-file.ts
|
|
2
|
-
function
|
|
14
|
+
function isMSEdge(win) {
|
|
15
|
+
return Boolean(win.navigator && win.navigator.msSaveOrOpenBlob);
|
|
16
|
+
}
|
|
17
|
+
function downloadFile(options) {
|
|
18
|
+
const { file, win, type, name } = options;
|
|
3
19
|
const doc = win.document;
|
|
4
|
-
const
|
|
20
|
+
const obj = typeof file === "string" ? new Blob([file], { type }) : file;
|
|
21
|
+
const fileName = typeof file === "string" ? name : file instanceof File ? file.name : void 0;
|
|
22
|
+
if (isMSEdge(win)) {
|
|
23
|
+
win.navigator.msSaveOrOpenBlob(obj, fileName || "file-download");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const url = win.URL.createObjectURL(obj);
|
|
5
27
|
const anchor = doc.createElement("a");
|
|
6
28
|
anchor.style.display = "none";
|
|
7
|
-
anchor.href =
|
|
8
|
-
anchor.
|
|
9
|
-
|
|
29
|
+
anchor.href = url;
|
|
30
|
+
anchor.rel = "noopener";
|
|
31
|
+
anchor.download = fileName || "file-download";
|
|
32
|
+
doc.documentElement.appendChild(anchor);
|
|
10
33
|
anchor.click();
|
|
11
34
|
setTimeout(() => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
anchor?.parentNode?.removeChild(anchor);
|
|
35
|
+
win.URL.revokeObjectURL(url);
|
|
36
|
+
anchor.remove();
|
|
16
37
|
}, 0);
|
|
17
38
|
}
|
|
18
39
|
|
|
@@ -80,13 +101,13 @@ function isValidFileSize(file, minSize, maxSize) {
|
|
|
80
101
|
if (isDefined(file.size)) {
|
|
81
102
|
if (isDefined(minSize) && isDefined(maxSize)) {
|
|
82
103
|
if (file.size > maxSize)
|
|
83
|
-
return [false, "
|
|
104
|
+
return [false, "FILE_TOO_LARGE"];
|
|
84
105
|
if (file.size < minSize)
|
|
85
|
-
return [false, "
|
|
106
|
+
return [false, "FILE_TOO_SMALL"];
|
|
86
107
|
} else if (isDefined(minSize) && file.size < minSize) {
|
|
87
|
-
return [false, "
|
|
108
|
+
return [false, "FILE_TOO_SMALL"];
|
|
88
109
|
} else if (isDefined(maxSize) && file.size > maxSize) {
|
|
89
|
-
return [false, "
|
|
110
|
+
return [false, "FILE_TOO_LARGE"];
|
|
90
111
|
}
|
|
91
112
|
}
|
|
92
113
|
return [true, null];
|
|
@@ -117,12 +138,14 @@ function isValidFileType(file, accept) {
|
|
|
117
138
|
return [isAcceptable, isAcceptable ? null : "FILE_INVALID_TYPE"];
|
|
118
139
|
}
|
|
119
140
|
export {
|
|
141
|
+
dataURItoBlob,
|
|
120
142
|
downloadFile,
|
|
121
143
|
formatFileSize,
|
|
122
144
|
getAcceptAttrString,
|
|
123
145
|
getFileDataUrl,
|
|
124
146
|
getTotalFileSize,
|
|
125
147
|
isFileEqual,
|
|
148
|
+
isMSEdge,
|
|
126
149
|
isValidFileSize,
|
|
127
150
|
isValidFileType
|
|
128
151
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/download-file.ts","../src/format-file-size.ts","../src/get-accept-attr.ts","../src/get-file-data-url.ts","../src/get-total-file-size.ts","../src/is-file-equal.ts","../src/is-valid-file-size.ts","../src/is-valid-file-type.ts"],"sourcesContent":["export function
|
|
1
|
+
{"version":3,"sources":["../src/data-url-to-blob.ts","../src/download-file.ts","../src/format-file-size.ts","../src/get-accept-attr.ts","../src/get-file-data-url.ts","../src/get-total-file-size.ts","../src/is-file-equal.ts","../src/is-valid-file-size.ts","../src/is-valid-file-type.ts"],"sourcesContent":["export function dataURItoBlob(uri: string): Blob {\n const binary = atob(uri.split(\",\")[1])\n\n // separate out the mime component\n const mimeString = uri.split(\",\")[0].split(\":\")[1].split(\";\")[0]\n\n // write the bytes of the string to an ArrayBuffer\n const buffer = new ArrayBuffer(binary.length)\n\n // create a view into the buffer\n const intArray = new Uint8Array(buffer)\n\n for (let i = 0; i < binary.length; i++) {\n intArray[i] = binary.charCodeAt(i)\n }\n\n return new Blob([buffer], { type: mimeString })\n}\n","export function isMSEdge(win: Window): win is Window & { navigator: { msSaveOrOpenBlob: Function } } {\n // @ts-ignore\n return Boolean(win.navigator && win.navigator.msSaveOrOpenBlob)\n}\n\ninterface DownloadFileOptions {\n /**\n * The name of the file\n */\n name?: string\n /**\n * The MIME type of the file\n */\n type?: string\n /**\n * The file contents\n */\n file: File | Blob | string\n /**\n * The window environment\n */\n win: typeof window\n}\n\nexport function downloadFile(options: DownloadFileOptions) {\n const { file, win, type, name } = options\n\n const doc = win.document\n\n const obj = typeof file === \"string\" ? new Blob([file], { type }) : file\n const fileName = typeof file === \"string\" ? name : file instanceof File ? file.name : undefined\n\n if (isMSEdge(win)) {\n win.navigator.msSaveOrOpenBlob(obj, fileName || \"file-download\")\n return\n }\n\n const url = win.URL.createObjectURL(obj)\n\n const anchor = doc.createElement(\"a\")\n anchor.style.display = \"none\"\n anchor.href = url\n anchor.rel = \"noopener\"\n anchor.download = fileName || \"file-download\"\n\n doc.documentElement.appendChild(anchor)\n anchor.click()\n\n setTimeout(() => {\n win.URL.revokeObjectURL(url)\n anchor.remove()\n }, 0)\n}\n","const SIZES = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\nconst KILO = 1024\n\ninterface FormatByteOptions {\n locale?: string\n}\n\nexport const formatFileSize = (bytes: number, options: FormatByteOptions = {}) => {\n const { locale = \"en-US\" } = options\n if (bytes === 0) return \"0 B\"\n\n const i = Math.floor(Math.log(bytes) / Math.log(KILO))\n const fileSize = bytes / Math.pow(KILO, i)\n\n const formattedSize = new Intl.NumberFormat(locale).format(fileSize)\n return `${formattedSize} ${SIZES[i]}`\n}\n","function isMIMEType(v: string) {\n return v === \"audio/*\" || v === \"video/*\" || v === \"image/*\" || v === \"text/*\" || /\\w+\\/[-+.\\w]+/g.test(v)\n}\n\nfunction isExt(v: string) {\n return /^.*\\.[\\w]+$/.test(v)\n}\n\nexport function getAcceptAttrString(accept: Record<string, string[]> | string | undefined) {\n if (!accept) return\n if (typeof accept === \"string\") return accept\n return Object.entries(accept)\n .reduce((a, [mimeType, ext]) => [...a, mimeType, ...ext], [] as string[])\n .filter((v) => isMIMEType(v) || isExt(v))\n .join(\",\")\n}\n","export const getFileDataUrl = async (file: File | Blob) => {\n const reader = new FileReader()\n return new Promise<string | undefined>((resolve, reject) => {\n reader.onerror = () => {\n reader.abort()\n reject(new Error(\"There was an error reading a file\"))\n }\n\n reader.onloadend = () => {\n const { result } = reader\n if (result instanceof ArrayBuffer) {\n reject(new Error(\"Expected DataURL as string from Blob/File, got ArrayBuffer\"))\n } else {\n resolve(result || undefined)\n }\n }\n\n reader.readAsDataURL(file)\n })\n}\n","export const getTotalFileSize = (files: File[]) => {\n return files.reduce((acc, file) => acc + file.size, 0)\n}\n","export const isFileEqual = (file1: File, file2: File) => {\n return file1.name === file2.name && file1.size === file2.size && file1.type === file2.type\n}\n","import type { FileError } from \"./types\"\n\nconst isDefined = <T>(v: T | undefined): v is T => v !== undefined && v !== null\n\nexport function isValidFileSize(file: File, minSize?: number, maxSize?: number): [boolean, FileError | null] {\n if (isDefined(file.size)) {\n if (isDefined(minSize) && isDefined(maxSize)) {\n if (file.size > maxSize) return [false, \"FILE_TOO_LARGE\"]\n if (file.size < minSize) return [false, \"FILE_TOO_SMALL\"]\n } else if (isDefined(minSize) && file.size < minSize) {\n return [false, \"FILE_TOO_SMALL\"]\n } else if (isDefined(maxSize) && file.size > maxSize) {\n return [false, \"FILE_TOO_LARGE\"]\n }\n }\n return [true, null]\n}\n","import type { FileError } from \"./types\"\n\nfunction isFileAccepted(file: File | null, accept: string[] | string | undefined) {\n if (file && accept) {\n const types = Array.isArray(accept) ? accept : accept.split(\",\")\n\n const fileName = file.name || \"\"\n const mimeType = (file.type || \"\").toLowerCase()\n const baseMimeType = mimeType.replace(/\\/.*$/, \"\")\n\n return types.some((type) => {\n const validType = type.trim().toLowerCase()\n\n if (validType.charAt(0) === \".\") {\n return fileName.toLowerCase().endsWith(validType)\n }\n\n if (validType.endsWith(\"/*\")) {\n return baseMimeType === validType.replace(/\\/.*$/, \"\")\n }\n\n return mimeType === validType\n })\n }\n return true\n}\n\nexport function isValidFileType(file: File, accept: string | undefined): [boolean, FileError | null] {\n const isAcceptable = file.type === \"application/x-moz-file\" || isFileAccepted(file, accept)\n return [isAcceptable, isAcceptable ? null : \"FILE_INVALID_TYPE\"]\n}\n"],"mappings":"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","names":[]}
|