@rezwanul7/storage 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/README.md +207 -2
- package/dist/fileRules.types-CGXBnwzd.d.cts +11 -0
- package/dist/fileRules.types-CGXBnwzd.d.ts +11 -0
- package/dist/index.cjs +475 -0
- package/dist/index.d.cts +116 -0
- package/dist/index.d.ts +116 -0
- package/dist/index.js +464 -0
- package/dist/server/index.cjs +545 -0
- package/dist/server/index.d.cts +269 -0
- package/dist/server/index.d.ts +269 -0
- package/dist/server/index.js +535 -0
- package/dist/zod/index.cjs +62 -0
- package/dist/zod/index.d.cts +22 -0
- package/dist/zod/index.d.ts +22 -0
- package/dist/zod/index.js +59 -0
- package/package.json +84 -3
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/shared/fileSize.ts
|
|
4
|
+
var SIZE_UNITS = {
|
|
5
|
+
b: 1,
|
|
6
|
+
kb: 1024,
|
|
7
|
+
mb: 1024 ** 2,
|
|
8
|
+
gb: 1024 ** 3,
|
|
9
|
+
tb: 1024 ** 4
|
|
10
|
+
};
|
|
11
|
+
function parseFileSize(input) {
|
|
12
|
+
if (input == null) return void 0;
|
|
13
|
+
if (typeof input === "number" && Number.isFinite(input)) return input;
|
|
14
|
+
if (typeof input !== "string") return void 0;
|
|
15
|
+
const match = input.trim().toLowerCase().match(/^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb|tb)?$/);
|
|
16
|
+
if (!match) return void 0;
|
|
17
|
+
return parseFloat(match[1]) * (SIZE_UNITS[match[2] || "b"] ?? 1);
|
|
18
|
+
}
|
|
19
|
+
function formatFileSize(bytes) {
|
|
20
|
+
if (bytes === 0) return "0 B";
|
|
21
|
+
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
22
|
+
const index = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
23
|
+
return `${(bytes / Math.pow(1024, index)).toFixed(1)} ${units[index]}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// src/shared/mimeTypes.ts
|
|
27
|
+
var DANGEROUS_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
28
|
+
"sh",
|
|
29
|
+
"bash",
|
|
30
|
+
"zsh",
|
|
31
|
+
"exe",
|
|
32
|
+
"dll",
|
|
33
|
+
"com",
|
|
34
|
+
"scr",
|
|
35
|
+
"bat",
|
|
36
|
+
"cmd",
|
|
37
|
+
"ps1",
|
|
38
|
+
"jar",
|
|
39
|
+
"class"
|
|
40
|
+
]);
|
|
41
|
+
var DANGEROUS_MIME = /* @__PURE__ */ new Set([
|
|
42
|
+
"application/x-sh",
|
|
43
|
+
"application/x-shellscript",
|
|
44
|
+
"text/x-shellscript",
|
|
45
|
+
"text/x-sh",
|
|
46
|
+
"application/x-dosexec",
|
|
47
|
+
"application/java-archive"
|
|
48
|
+
]);
|
|
49
|
+
var MIME_BY_EXT = {
|
|
50
|
+
// Image
|
|
51
|
+
png: "image/png",
|
|
52
|
+
jpg: "image/jpeg",
|
|
53
|
+
jpeg: "image/jpeg",
|
|
54
|
+
gif: "image/gif",
|
|
55
|
+
bmp: "image/bmp",
|
|
56
|
+
webp: "image/webp",
|
|
57
|
+
tiff: "image/tiff",
|
|
58
|
+
tif: "image/tiff",
|
|
59
|
+
svg: "image/svg+xml",
|
|
60
|
+
ico: "image/vnd.microsoft.icon",
|
|
61
|
+
avif: "image/avif",
|
|
62
|
+
heic: "image/heic",
|
|
63
|
+
// Audio
|
|
64
|
+
mp3: "audio/mpeg",
|
|
65
|
+
wav: "audio/wav",
|
|
66
|
+
ogg: "audio/ogg",
|
|
67
|
+
flac: "audio/x-flac",
|
|
68
|
+
m4a: "audio/mp4",
|
|
69
|
+
// Video
|
|
70
|
+
mp4: "video/mp4",
|
|
71
|
+
mkv: "video/x-matroska",
|
|
72
|
+
mov: "video/quicktime",
|
|
73
|
+
avi: "video/x-msvideo",
|
|
74
|
+
webm: "video/webm",
|
|
75
|
+
// Documents
|
|
76
|
+
pdf: "application/pdf",
|
|
77
|
+
xls: "application/vnd.ms-excel",
|
|
78
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
79
|
+
ods: "application/vnd.oasis.opendocument.spreadsheet",
|
|
80
|
+
ppt: "application/vnd.ms-powerpoint",
|
|
81
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
82
|
+
odp: "application/vnd.oasis.opendocument.presentation",
|
|
83
|
+
doc: "application/msword",
|
|
84
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
85
|
+
odt: "application/vnd.oasis.opendocument.text",
|
|
86
|
+
rtf: "application/rtf",
|
|
87
|
+
// Datasets (JSON Lines has no registered MIME, so it is served as JSON)
|
|
88
|
+
csv: "text/csv",
|
|
89
|
+
tsv: "text/tab-separated-values",
|
|
90
|
+
json: "application/json",
|
|
91
|
+
jsonl: "application/json",
|
|
92
|
+
ndjson: "application/json",
|
|
93
|
+
// Archives
|
|
94
|
+
zip: "application/zip",
|
|
95
|
+
rar: "application/x-rar-compressed",
|
|
96
|
+
"7z": "application/x-7z-compressed",
|
|
97
|
+
tar: "application/x-tar",
|
|
98
|
+
gz: "application/gzip",
|
|
99
|
+
// Code
|
|
100
|
+
js: "text/javascript",
|
|
101
|
+
jsx: "text/jsx",
|
|
102
|
+
ts: "text/typescript",
|
|
103
|
+
tsx: "text/tsx",
|
|
104
|
+
py: "text/x-python",
|
|
105
|
+
rb: "text/x-ruby",
|
|
106
|
+
php: "application/x-httpd-php",
|
|
107
|
+
java: "text/x-java-source",
|
|
108
|
+
kt: "text/x-kotlin",
|
|
109
|
+
c: "text/x-c",
|
|
110
|
+
cpp: "text/x-c",
|
|
111
|
+
h: "text/x-c",
|
|
112
|
+
hpp: "text/x-c",
|
|
113
|
+
cs: "text/x-csharp",
|
|
114
|
+
go: "text/x-go",
|
|
115
|
+
rs: "text/x-rust",
|
|
116
|
+
html: "text/html",
|
|
117
|
+
htm: "text/html",
|
|
118
|
+
css: "text/css",
|
|
119
|
+
scss: "text/x-scss",
|
|
120
|
+
yaml: "text/yaml",
|
|
121
|
+
yml: "text/yaml",
|
|
122
|
+
sql: "application/sql",
|
|
123
|
+
xml: "application/xml",
|
|
124
|
+
// Text
|
|
125
|
+
txt: "text/plain",
|
|
126
|
+
md: "text/markdown",
|
|
127
|
+
markdown: "text/markdown",
|
|
128
|
+
log: "text/plain",
|
|
129
|
+
ini: "text/plain",
|
|
130
|
+
cfg: "text/plain",
|
|
131
|
+
conf: "text/plain",
|
|
132
|
+
env: "text/plain",
|
|
133
|
+
// Executables (blocked by DANGEROUS_EXTENSIONS, mapped so they report a real MIME)
|
|
134
|
+
sh: "application/x-sh",
|
|
135
|
+
bash: "application/x-sh",
|
|
136
|
+
zsh: "application/x-sh",
|
|
137
|
+
exe: "application/x-msdos-program",
|
|
138
|
+
dll: "application/x-msdownload",
|
|
139
|
+
com: "application/x-msdownload",
|
|
140
|
+
bat: "application/x-msdownload",
|
|
141
|
+
jar: "application/java-archive",
|
|
142
|
+
class: "application/java-vm"
|
|
143
|
+
};
|
|
144
|
+
var EXT_BY_MIME = {};
|
|
145
|
+
for (const [ext, mime] of Object.entries(MIME_BY_EXT)) {
|
|
146
|
+
EXT_BY_MIME[mime] ??= ext;
|
|
147
|
+
}
|
|
148
|
+
function mimeFromExtension(ext) {
|
|
149
|
+
if (!ext) return void 0;
|
|
150
|
+
return MIME_BY_EXT[ext.toLowerCase()];
|
|
151
|
+
}
|
|
152
|
+
function extensionFromMime(mime) {
|
|
153
|
+
if (!mime) return void 0;
|
|
154
|
+
return EXT_BY_MIME[mime.toLowerCase()];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// src/shared/fileExtension.ts
|
|
158
|
+
function getFileExtension(name) {
|
|
159
|
+
const dot = name.lastIndexOf(".");
|
|
160
|
+
if (dot === -1) return void 0;
|
|
161
|
+
return name.slice(dot + 1).toLowerCase() || void 0;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/shared/detectFileTypeFromName.ts
|
|
165
|
+
function detectFileTypeFromName(input) {
|
|
166
|
+
const name = input.name;
|
|
167
|
+
const declaredMime = input.type || void 0;
|
|
168
|
+
const declaredExt = getFileExtension(name);
|
|
169
|
+
const finalExt = declaredExt;
|
|
170
|
+
const finalMime = resolveMime(declaredExt, declaredMime);
|
|
171
|
+
if (declaredExt && DANGEROUS_EXTENSIONS.has(declaredExt)) {
|
|
172
|
+
return {
|
|
173
|
+
ok: false,
|
|
174
|
+
reason: `Extension .${declaredExt} is blocked.`,
|
|
175
|
+
mime: finalMime,
|
|
176
|
+
ext: finalExt
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
if (declaredMime && DANGEROUS_MIME.has(declaredMime)) {
|
|
180
|
+
return {
|
|
181
|
+
ok: false,
|
|
182
|
+
reason: `MIME type ${declaredMime} is unsafe.`,
|
|
183
|
+
mime: finalMime,
|
|
184
|
+
ext: finalExt
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (declaredExt) {
|
|
188
|
+
return {
|
|
189
|
+
ok: true,
|
|
190
|
+
mime: finalMime,
|
|
191
|
+
ext: declaredExt
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
if (declaredMime) {
|
|
195
|
+
return {
|
|
196
|
+
ok: true,
|
|
197
|
+
mime: declaredMime,
|
|
198
|
+
ext: extensionFromMime(declaredMime)
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
ok: false,
|
|
203
|
+
reason: "Unable to determine file type.",
|
|
204
|
+
mime: finalMime,
|
|
205
|
+
ext: void 0
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function resolveMime(ext, declaredMime) {
|
|
209
|
+
const lookup = mimeFromExtension(ext);
|
|
210
|
+
if (lookup) {
|
|
211
|
+
return lookup;
|
|
212
|
+
}
|
|
213
|
+
if (declaredMime) {
|
|
214
|
+
return declaredMime;
|
|
215
|
+
}
|
|
216
|
+
return "application/octet-stream";
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// src/shared/fileCategories/fileCategories.detect.ts
|
|
220
|
+
var FILE_CATEGORY_DETECTORS = [
|
|
221
|
+
// ---- IMAGE ---------------------------------------------------------------
|
|
222
|
+
{
|
|
223
|
+
id: "Image",
|
|
224
|
+
parent: "Image",
|
|
225
|
+
detect: {
|
|
226
|
+
mimeStartsWith: ["image/"],
|
|
227
|
+
extensions: ["png", "jpg", "jpeg", "gif", "bmp", "webp", "tiff", "svg"]
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
// ---- AUDIO ---------------------------------------------------------------
|
|
231
|
+
{
|
|
232
|
+
id: "Audio",
|
|
233
|
+
parent: "Audio",
|
|
234
|
+
detect: {
|
|
235
|
+
mimeStartsWith: ["audio/"],
|
|
236
|
+
extensions: ["mp3", "wav", "ogg", "flac", "m4a"]
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
// ---- VIDEO ---------------------------------------------------------------
|
|
240
|
+
{
|
|
241
|
+
id: "Video",
|
|
242
|
+
parent: "Video",
|
|
243
|
+
detect: {
|
|
244
|
+
mimeStartsWith: ["video/"],
|
|
245
|
+
extensions: ["mp4", "mkv", "mov", "avi", "webm"]
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
// ---- PDF -----------------------------------------------------------------
|
|
249
|
+
{
|
|
250
|
+
id: "Pdf",
|
|
251
|
+
parent: "Document",
|
|
252
|
+
detect: {
|
|
253
|
+
mimeEquals: ["application/pdf"],
|
|
254
|
+
extensions: ["pdf"]
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
// ---- SPREADSHEET ---------------------------------------------------------
|
|
258
|
+
{
|
|
259
|
+
id: "Spreadsheet",
|
|
260
|
+
parent: "Document",
|
|
261
|
+
detect: {
|
|
262
|
+
mimeEquals: [
|
|
263
|
+
"application/vnd.ms-excel",
|
|
264
|
+
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
265
|
+
"application/vnd.oasis.opendocument.spreadsheet"
|
|
266
|
+
],
|
|
267
|
+
extensions: ["xls", "xlsx", "ods"]
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
// ---- PRESENTATION --------------------------------------------------------
|
|
271
|
+
{
|
|
272
|
+
id: "Presentation",
|
|
273
|
+
parent: "Document",
|
|
274
|
+
detect: {
|
|
275
|
+
mimeEquals: [
|
|
276
|
+
"application/vnd.ms-powerpoint",
|
|
277
|
+
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
278
|
+
"application/vnd.oasis.opendocument.presentation"
|
|
279
|
+
],
|
|
280
|
+
extensions: ["ppt", "pptx", "odp"]
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
// ---- DOCUMENT (WORD / RICH DOCS) ----------------------------------------
|
|
284
|
+
{
|
|
285
|
+
id: "Document",
|
|
286
|
+
parent: "Document",
|
|
287
|
+
detect: {
|
|
288
|
+
mimeEquals: [
|
|
289
|
+
"application/msword",
|
|
290
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
291
|
+
"application/vnd.oasis.opendocument.text"
|
|
292
|
+
],
|
|
293
|
+
extensions: ["doc", "docx", "odt", "rtf"]
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
// ---- DATASET (CSV, JSONL, NDJSON, TSV) -----------------------------------
|
|
297
|
+
{
|
|
298
|
+
id: "Dataset",
|
|
299
|
+
parent: "Document",
|
|
300
|
+
detect: {
|
|
301
|
+
mimeEquals: ["text/csv", "application/json", "text/tab-separated-values"],
|
|
302
|
+
extensions: ["csv", "tsv", "jsonl", "ndjson"]
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
// ---- ARCHIVE -------------------------------------------------------------
|
|
306
|
+
{
|
|
307
|
+
id: "Archive",
|
|
308
|
+
parent: "Binary",
|
|
309
|
+
detect: {
|
|
310
|
+
mimeEquals: [
|
|
311
|
+
"application/zip",
|
|
312
|
+
"application/x-7z-compressed",
|
|
313
|
+
"application/x-rar-compressed",
|
|
314
|
+
"application/x-tar",
|
|
315
|
+
"application/gzip"
|
|
316
|
+
],
|
|
317
|
+
extensions: ["zip", "rar", "7z", "tar", "gz"]
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
// ---- CODE ----------------------------------------------------------------
|
|
321
|
+
{
|
|
322
|
+
id: "Code",
|
|
323
|
+
parent: "Text",
|
|
324
|
+
detect: {
|
|
325
|
+
// Exact MIMEs (from MIME_BY_EXT) so source files match Code before Text's "text/" prefix
|
|
326
|
+
mimeEquals: [
|
|
327
|
+
"text/javascript",
|
|
328
|
+
"text/jsx",
|
|
329
|
+
"text/typescript",
|
|
330
|
+
"text/tsx",
|
|
331
|
+
"text/x-python",
|
|
332
|
+
"text/x-ruby",
|
|
333
|
+
"text/x-java-source",
|
|
334
|
+
"text/x-kotlin",
|
|
335
|
+
"text/x-c",
|
|
336
|
+
"text/x-csharp",
|
|
337
|
+
"text/x-go",
|
|
338
|
+
"text/x-rust",
|
|
339
|
+
"text/html",
|
|
340
|
+
"text/css",
|
|
341
|
+
"text/x-scss",
|
|
342
|
+
"text/yaml"
|
|
343
|
+
],
|
|
344
|
+
extensions: [
|
|
345
|
+
"js",
|
|
346
|
+
"ts",
|
|
347
|
+
"tsx",
|
|
348
|
+
"jsx",
|
|
349
|
+
"py",
|
|
350
|
+
"rb",
|
|
351
|
+
"php",
|
|
352
|
+
"java",
|
|
353
|
+
"kt",
|
|
354
|
+
"c",
|
|
355
|
+
"cpp",
|
|
356
|
+
"h",
|
|
357
|
+
"hpp",
|
|
358
|
+
"cs",
|
|
359
|
+
"go",
|
|
360
|
+
"rs",
|
|
361
|
+
"sh",
|
|
362
|
+
"bash",
|
|
363
|
+
"zsh",
|
|
364
|
+
"html",
|
|
365
|
+
"css",
|
|
366
|
+
"scss",
|
|
367
|
+
"json",
|
|
368
|
+
"yml",
|
|
369
|
+
"yaml",
|
|
370
|
+
"sql"
|
|
371
|
+
]
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
// ---- TEXT (PLAIN, MARKDOWN, LOGS, ETC.) ----------------------------------
|
|
375
|
+
{
|
|
376
|
+
id: "Text",
|
|
377
|
+
parent: "Text",
|
|
378
|
+
detect: {
|
|
379
|
+
mimeStartsWith: ["text/"],
|
|
380
|
+
extensions: ["txt", "md", "markdown", "log", "ini", "cfg", "conf", "env"]
|
|
381
|
+
}
|
|
382
|
+
},
|
|
383
|
+
// ---- BINARY (FALLBACK FOR NON-TEXT, NON-ARCHIVE) -------------------------
|
|
384
|
+
{
|
|
385
|
+
id: "Binary",
|
|
386
|
+
parent: "Binary",
|
|
387
|
+
detect: {
|
|
388
|
+
mimeEquals: ["application/octet-stream"]
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
// ---- UNKNOWN -------------------------------------------------------------
|
|
392
|
+
{
|
|
393
|
+
id: "Unknown",
|
|
394
|
+
parent: "Unknown"
|
|
395
|
+
}
|
|
396
|
+
];
|
|
397
|
+
|
|
398
|
+
// src/shared/fileCategories/getFileCategory.ts
|
|
399
|
+
function getFileCategory(input) {
|
|
400
|
+
const mime = normalize(input.mime);
|
|
401
|
+
const ext = normalize(input.ext);
|
|
402
|
+
if (mime) {
|
|
403
|
+
for (const def of FILE_CATEGORY_DETECTORS) {
|
|
404
|
+
const eq = def.detect?.mimeEquals;
|
|
405
|
+
if (eq && eq.includes(mime)) {
|
|
406
|
+
return def.id;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if (mime) {
|
|
411
|
+
for (const def of FILE_CATEGORY_DETECTORS) {
|
|
412
|
+
const prefixes = def.detect?.mimeStartsWith;
|
|
413
|
+
if (prefixes && prefixes.some((p) => mime.startsWith(p))) {
|
|
414
|
+
return def.id;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (ext) {
|
|
419
|
+
for (const def of FILE_CATEGORY_DETECTORS) {
|
|
420
|
+
const exts = def.detect?.extensions;
|
|
421
|
+
if (exts && exts.includes(ext)) {
|
|
422
|
+
return def.id;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return "Unknown";
|
|
427
|
+
}
|
|
428
|
+
function normalize(value) {
|
|
429
|
+
if (!value) return void 0;
|
|
430
|
+
const trimmed = value.trim().toLowerCase();
|
|
431
|
+
return trimmed || void 0;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// src/shared/fileCategories/getExtensionsByCategory.ts
|
|
435
|
+
function getExtensionsByCategory(category) {
|
|
436
|
+
const extensions = FILE_CATEGORY_DETECTORS.find((c) => c.id === category)?.detect?.extensions;
|
|
437
|
+
if (!extensions?.length) {
|
|
438
|
+
throw new Error(
|
|
439
|
+
`File category '${category}' does not define extensions. Please add the configuration in fileCategories.detect.ts.`
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
return [...extensions];
|
|
443
|
+
}
|
|
444
|
+
function getExtensionsByCategories(categories) {
|
|
445
|
+
return Array.from(
|
|
446
|
+
new Set(
|
|
447
|
+
categories.flatMap((category) => getExtensionsByCategory(category))
|
|
448
|
+
)
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// src/shared/fileCategories/getMimeTypesByCategory.ts
|
|
453
|
+
function getMimeTypesByCategory(category) {
|
|
454
|
+
const mimeEquals = FILE_CATEGORY_DETECTORS.find((c) => c.id === category)?.detect?.mimeEquals;
|
|
455
|
+
if (!mimeEquals?.length) {
|
|
456
|
+
throw new Error(
|
|
457
|
+
`File category '${category}' does not define 'mimeEquals'. Please add the configuration in fileCategories.detect.ts.`
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
return [...mimeEquals];
|
|
461
|
+
}
|
|
462
|
+
function getMimeTypesByCategories(categories) {
|
|
463
|
+
return Array.from(new Set(categories.flatMap(getMimeTypesByCategory)));
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
exports.FILE_CATEGORY_DETECTORS = FILE_CATEGORY_DETECTORS;
|
|
467
|
+
exports.detectFileTypeFromName = detectFileTypeFromName;
|
|
468
|
+
exports.formatFileSize = formatFileSize;
|
|
469
|
+
exports.getExtensionsByCategories = getExtensionsByCategories;
|
|
470
|
+
exports.getExtensionsByCategory = getExtensionsByCategory;
|
|
471
|
+
exports.getFileCategory = getFileCategory;
|
|
472
|
+
exports.getFileExtension = getFileExtension;
|
|
473
|
+
exports.getMimeTypesByCategories = getMimeTypesByCategories;
|
|
474
|
+
exports.getMimeTypesByCategory = getMimeTypesByCategory;
|
|
475
|
+
exports.parseFileSize = parseFileSize;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export { S as SharedFileRules } from './fileRules.types-CGXBnwzd.cjs';
|
|
2
|
+
|
|
3
|
+
/** Bytes for a size like "5MB", "200kb", "1.5GB", "500" or a number, or undefined if it can't be read. */
|
|
4
|
+
declare function parseFileSize(input?: string | number): number | undefined;
|
|
5
|
+
/** A byte count for people: "512.0 B", "1.2 KB", "8.5 MB". */
|
|
6
|
+
declare function formatFileSize(bytes: number): string;
|
|
7
|
+
|
|
8
|
+
/** A file's type as read from its name and declared MIME type, and whether that type is safe. */
|
|
9
|
+
interface FileTypeFromName {
|
|
10
|
+
/** False when the type is dangerous (an executable or script) or can't be determined. */
|
|
11
|
+
ok: boolean;
|
|
12
|
+
/** Why the file isn't `ok`. */
|
|
13
|
+
reason?: string;
|
|
14
|
+
/** The MIME type for the extension, else the declared one. */
|
|
15
|
+
mime: string | undefined;
|
|
16
|
+
/** The extension, lower case and without the dot. */
|
|
17
|
+
ext: string | undefined;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A file's type from its name and declared MIME type, without reading its bytes. Use it for early feedback in the
|
|
21
|
+
* browser; the server checks every upload again from its bytes.
|
|
22
|
+
*
|
|
23
|
+
* @param file - The file to inspect.
|
|
24
|
+
* @returns Its type and whether it is safe.
|
|
25
|
+
*/
|
|
26
|
+
declare function detectFileTypeFromName(file: File): FileTypeFromName;
|
|
27
|
+
/**
|
|
28
|
+
* A file's type from a name and a declared MIME type (`File.type`), without reading any bytes.
|
|
29
|
+
*
|
|
30
|
+
* @param info - The file name and the declared MIME type, which may be empty.
|
|
31
|
+
* @returns Its type and whether it is safe.
|
|
32
|
+
*/
|
|
33
|
+
declare function detectFileTypeFromName(info: {
|
|
34
|
+
name: string;
|
|
35
|
+
type?: string;
|
|
36
|
+
}): FileTypeFromName;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The lower-cased extension of a file name, without the dot.
|
|
40
|
+
*
|
|
41
|
+
* Undefined when the name has no dot ("Makefile") or nothing after it ("file."). A dotfile keeps its name as the
|
|
42
|
+
* extension (".env" → "env"), which the Text category relies on.
|
|
43
|
+
*/
|
|
44
|
+
declare function getFileExtension(name: string): string | undefined;
|
|
45
|
+
|
|
46
|
+
/** The File categories the package knows. */
|
|
47
|
+
type FileCategory = "Image" | "Audio" | "Video" | "Pdf" | "Document" | "Spreadsheet" | "Presentation" | "Dataset" | "Archive" | "Code" | "Text" | "Binary" | "Unknown";
|
|
48
|
+
/** A broader group a File category belongs to, such as Document for Pdf and Spreadsheet. */
|
|
49
|
+
type FileCategoryParent = "Image" | "Audio" | "Video" | "Document" | "Text" | "Binary" | "Unknown";
|
|
50
|
+
/** One row of {@link FILE_CATEGORY_DETECTORS}: a File category and how to recognise it. */
|
|
51
|
+
interface FileCategoryDetect {
|
|
52
|
+
/** The File category. */
|
|
53
|
+
id: FileCategory;
|
|
54
|
+
/** The broader group it belongs to. */
|
|
55
|
+
parent?: FileCategoryParent;
|
|
56
|
+
/** What identifies it. */
|
|
57
|
+
detect?: {
|
|
58
|
+
/** Exact MIME types. */
|
|
59
|
+
mimeEquals?: string[];
|
|
60
|
+
/** MIME type prefixes, such as `"image/"`. */
|
|
61
|
+
mimeStartsWith?: string[];
|
|
62
|
+
/** Extensions, lower case and without the dot. */
|
|
63
|
+
extensions?: string[];
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Every File category and how to recognise it, in the order {@link getFileCategory} tries them. */
|
|
68
|
+
declare const FILE_CATEGORY_DETECTORS: FileCategoryDetect[];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A file's File category from its MIME type and extension: an exact MIME match wins, then a MIME prefix, then the
|
|
72
|
+
* extension.
|
|
73
|
+
*
|
|
74
|
+
* @param input - The MIME type and extension, either of which may be missing.
|
|
75
|
+
* @returns The File category, or `"Unknown"`.
|
|
76
|
+
*/
|
|
77
|
+
declare function getFileCategory(input: {
|
|
78
|
+
mime?: string | null;
|
|
79
|
+
ext?: string | null;
|
|
80
|
+
}): FileCategory;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The extensions of a File category, to put in `allowedExtensions`.
|
|
84
|
+
*
|
|
85
|
+
* @param category - The File category.
|
|
86
|
+
* @returns Its extensions, lower case and without the dot.
|
|
87
|
+
* @throws Error when the category defines no extensions, such as `"Unknown"`.
|
|
88
|
+
*/
|
|
89
|
+
declare function getExtensionsByCategory(category: FileCategory): string[];
|
|
90
|
+
/**
|
|
91
|
+
* The extensions of several File categories, without duplicates.
|
|
92
|
+
*
|
|
93
|
+
* @param categories - The File categories.
|
|
94
|
+
* @returns Their extensions, lower case and without the dot.
|
|
95
|
+
* @throws Error when a category defines no extensions.
|
|
96
|
+
*/
|
|
97
|
+
declare function getExtensionsByCategories(categories: FileCategory[]): string[];
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The exact MIME types of a File category, to put in `allowedMimeTypes`.
|
|
101
|
+
*
|
|
102
|
+
* @param category - The File category.
|
|
103
|
+
* @returns Its MIME types.
|
|
104
|
+
* @throws Error when the category matches by MIME prefix only, such as `"Image"`, or defines none.
|
|
105
|
+
*/
|
|
106
|
+
declare function getMimeTypesByCategory(category: FileCategory): string[];
|
|
107
|
+
/**
|
|
108
|
+
* The exact MIME types of several File categories, without duplicates.
|
|
109
|
+
*
|
|
110
|
+
* @param categories - The File categories.
|
|
111
|
+
* @returns Their MIME types.
|
|
112
|
+
* @throws Error when a category defines no exact MIME types.
|
|
113
|
+
*/
|
|
114
|
+
declare function getMimeTypesByCategories(categories: FileCategory[]): string[];
|
|
115
|
+
|
|
116
|
+
export { FILE_CATEGORY_DETECTORS, type FileCategory, type FileCategoryDetect, type FileCategoryParent, type FileTypeFromName, detectFileTypeFromName, formatFileSize, getExtensionsByCategories, getExtensionsByCategory, getFileCategory, getFileExtension, getMimeTypesByCategories, getMimeTypesByCategory, parseFileSize };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export { S as SharedFileRules } from './fileRules.types-CGXBnwzd.js';
|
|
2
|
+
|
|
3
|
+
/** Bytes for a size like "5MB", "200kb", "1.5GB", "500" or a number, or undefined if it can't be read. */
|
|
4
|
+
declare function parseFileSize(input?: string | number): number | undefined;
|
|
5
|
+
/** A byte count for people: "512.0 B", "1.2 KB", "8.5 MB". */
|
|
6
|
+
declare function formatFileSize(bytes: number): string;
|
|
7
|
+
|
|
8
|
+
/** A file's type as read from its name and declared MIME type, and whether that type is safe. */
|
|
9
|
+
interface FileTypeFromName {
|
|
10
|
+
/** False when the type is dangerous (an executable or script) or can't be determined. */
|
|
11
|
+
ok: boolean;
|
|
12
|
+
/** Why the file isn't `ok`. */
|
|
13
|
+
reason?: string;
|
|
14
|
+
/** The MIME type for the extension, else the declared one. */
|
|
15
|
+
mime: string | undefined;
|
|
16
|
+
/** The extension, lower case and without the dot. */
|
|
17
|
+
ext: string | undefined;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A file's type from its name and declared MIME type, without reading its bytes. Use it for early feedback in the
|
|
21
|
+
* browser; the server checks every upload again from its bytes.
|
|
22
|
+
*
|
|
23
|
+
* @param file - The file to inspect.
|
|
24
|
+
* @returns Its type and whether it is safe.
|
|
25
|
+
*/
|
|
26
|
+
declare function detectFileTypeFromName(file: File): FileTypeFromName;
|
|
27
|
+
/**
|
|
28
|
+
* A file's type from a name and a declared MIME type (`File.type`), without reading any bytes.
|
|
29
|
+
*
|
|
30
|
+
* @param info - The file name and the declared MIME type, which may be empty.
|
|
31
|
+
* @returns Its type and whether it is safe.
|
|
32
|
+
*/
|
|
33
|
+
declare function detectFileTypeFromName(info: {
|
|
34
|
+
name: string;
|
|
35
|
+
type?: string;
|
|
36
|
+
}): FileTypeFromName;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The lower-cased extension of a file name, without the dot.
|
|
40
|
+
*
|
|
41
|
+
* Undefined when the name has no dot ("Makefile") or nothing after it ("file."). A dotfile keeps its name as the
|
|
42
|
+
* extension (".env" → "env"), which the Text category relies on.
|
|
43
|
+
*/
|
|
44
|
+
declare function getFileExtension(name: string): string | undefined;
|
|
45
|
+
|
|
46
|
+
/** The File categories the package knows. */
|
|
47
|
+
type FileCategory = "Image" | "Audio" | "Video" | "Pdf" | "Document" | "Spreadsheet" | "Presentation" | "Dataset" | "Archive" | "Code" | "Text" | "Binary" | "Unknown";
|
|
48
|
+
/** A broader group a File category belongs to, such as Document for Pdf and Spreadsheet. */
|
|
49
|
+
type FileCategoryParent = "Image" | "Audio" | "Video" | "Document" | "Text" | "Binary" | "Unknown";
|
|
50
|
+
/** One row of {@link FILE_CATEGORY_DETECTORS}: a File category and how to recognise it. */
|
|
51
|
+
interface FileCategoryDetect {
|
|
52
|
+
/** The File category. */
|
|
53
|
+
id: FileCategory;
|
|
54
|
+
/** The broader group it belongs to. */
|
|
55
|
+
parent?: FileCategoryParent;
|
|
56
|
+
/** What identifies it. */
|
|
57
|
+
detect?: {
|
|
58
|
+
/** Exact MIME types. */
|
|
59
|
+
mimeEquals?: string[];
|
|
60
|
+
/** MIME type prefixes, such as `"image/"`. */
|
|
61
|
+
mimeStartsWith?: string[];
|
|
62
|
+
/** Extensions, lower case and without the dot. */
|
|
63
|
+
extensions?: string[];
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Every File category and how to recognise it, in the order {@link getFileCategory} tries them. */
|
|
68
|
+
declare const FILE_CATEGORY_DETECTORS: FileCategoryDetect[];
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A file's File category from its MIME type and extension: an exact MIME match wins, then a MIME prefix, then the
|
|
72
|
+
* extension.
|
|
73
|
+
*
|
|
74
|
+
* @param input - The MIME type and extension, either of which may be missing.
|
|
75
|
+
* @returns The File category, or `"Unknown"`.
|
|
76
|
+
*/
|
|
77
|
+
declare function getFileCategory(input: {
|
|
78
|
+
mime?: string | null;
|
|
79
|
+
ext?: string | null;
|
|
80
|
+
}): FileCategory;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The extensions of a File category, to put in `allowedExtensions`.
|
|
84
|
+
*
|
|
85
|
+
* @param category - The File category.
|
|
86
|
+
* @returns Its extensions, lower case and without the dot.
|
|
87
|
+
* @throws Error when the category defines no extensions, such as `"Unknown"`.
|
|
88
|
+
*/
|
|
89
|
+
declare function getExtensionsByCategory(category: FileCategory): string[];
|
|
90
|
+
/**
|
|
91
|
+
* The extensions of several File categories, without duplicates.
|
|
92
|
+
*
|
|
93
|
+
* @param categories - The File categories.
|
|
94
|
+
* @returns Their extensions, lower case and without the dot.
|
|
95
|
+
* @throws Error when a category defines no extensions.
|
|
96
|
+
*/
|
|
97
|
+
declare function getExtensionsByCategories(categories: FileCategory[]): string[];
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The exact MIME types of a File category, to put in `allowedMimeTypes`.
|
|
101
|
+
*
|
|
102
|
+
* @param category - The File category.
|
|
103
|
+
* @returns Its MIME types.
|
|
104
|
+
* @throws Error when the category matches by MIME prefix only, such as `"Image"`, or defines none.
|
|
105
|
+
*/
|
|
106
|
+
declare function getMimeTypesByCategory(category: FileCategory): string[];
|
|
107
|
+
/**
|
|
108
|
+
* The exact MIME types of several File categories, without duplicates.
|
|
109
|
+
*
|
|
110
|
+
* @param categories - The File categories.
|
|
111
|
+
* @returns Their MIME types.
|
|
112
|
+
* @throws Error when a category defines no exact MIME types.
|
|
113
|
+
*/
|
|
114
|
+
declare function getMimeTypesByCategories(categories: FileCategory[]): string[];
|
|
115
|
+
|
|
116
|
+
export { FILE_CATEGORY_DETECTORS, type FileCategory, type FileCategoryDetect, type FileCategoryParent, type FileTypeFromName, detectFileTypeFromName, formatFileSize, getExtensionsByCategories, getExtensionsByCategory, getFileCategory, getFileExtension, getMimeTypesByCategories, getMimeTypesByCategory, parseFileSize };
|