securequ 1.1.6 → 1.1.8
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/client/Base.js +147 -1
- package/client/Base.js.map +1 -1
- package/client/Base.mjs +147 -1
- package/client/Base.mjs.map +1 -1
- package/client/index.js +139 -1
- package/client/index.js.map +1 -1
- package/client/index.mjs +139 -1
- package/client/index.mjs.map +1 -1
- package/client/types.d.ts +1 -1
- package/include/File.js +60 -1
- package/include/File.js.map +1 -1
- package/include/File.mjs +60 -1
- package/include/File.mjs.map +1 -1
- package/include/FileScaner.js +95 -1
- package/include/FileScaner.js.map +1 -1
- package/include/FileScaner.mjs +95 -1
- package/include/FileScaner.mjs.map +1 -1
- package/include/compress.js +19 -1
- package/include/compress.js.map +1 -1
- package/include/compress.mjs +19 -1
- package/include/compress.mjs.map +1 -1
- package/include/crypto.js +55 -1
- package/include/crypto.js.map +1 -1
- package/include/crypto.mjs +55 -1
- package/include/crypto.mjs.map +1 -1
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +1 -1
- package/server/Base.d.ts +1 -1
- package/server/Base.js +106 -1
- package/server/Base.js.map +1 -1
- package/server/Base.mjs +106 -1
- package/server/Base.mjs.map +1 -1
- package/server/Router.js +30 -1
- package/server/Router.js.map +1 -1
- package/server/Router.mjs +30 -1
- package/server/Router.mjs.map +1 -1
- package/server/index.js +182 -1
- package/server/index.js.map +1 -1
- package/server/index.mjs +182 -1
- package/server/index.mjs.map +1 -1
- package/server/types.d.ts +1 -1
package/client/index.mjs
CHANGED
|
@@ -1 +1,139 @@
|
|
|
1
|
-
import{__asyncValues
|
|
1
|
+
import {__asyncValues}from'tslib';import {getFileId,totalChunks,chunkFile}from'../include/File.mjs';import Base from'./Base.mjs';import {fileScaner}from'../include/FileScaner.mjs';class SecurequClient extends Base {
|
|
2
|
+
async send(path, init) {
|
|
3
|
+
await this.awaitForHandshake();
|
|
4
|
+
init = await this.hooksCall('beforeRequest', path, init) || init;
|
|
5
|
+
const url = await this.url(path);
|
|
6
|
+
if (url.pathname === '/')
|
|
7
|
+
throw new Error("Path is not allowed");
|
|
8
|
+
for (let key in init === null || init === void 0 ? void 0 : init.body) {
|
|
9
|
+
if ((init === null || init === void 0 ? void 0 : init.body[key]) instanceof File) {
|
|
10
|
+
init.body[key] = await this.uploadFile(init.body[key], init === null || init === void 0 ? void 0 : init.onProgress);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const res = await this.fetch(path, init);
|
|
14
|
+
if (["Signeture expired", "Request expired"].includes(res.message)) {
|
|
15
|
+
await this.handshake();
|
|
16
|
+
return await this.send(path, init);
|
|
17
|
+
}
|
|
18
|
+
await this.hooksCall('afterResponse', res);
|
|
19
|
+
return res;
|
|
20
|
+
}
|
|
21
|
+
async uploadFile(file, onProgress) {
|
|
22
|
+
var _a, e_1, _b, _c;
|
|
23
|
+
var _d, _e, _f;
|
|
24
|
+
await this.awaitForHandshake();
|
|
25
|
+
const fileId = await getFileId(file);
|
|
26
|
+
const controller = new AbortController();
|
|
27
|
+
let _file = await this.hooksCall('beforeUpload', file, fileId) || file;
|
|
28
|
+
const maxFileSize = (_d = this.handshakeInfo) === null || _d === void 0 ? void 0 : _d.maxFileSize;
|
|
29
|
+
if (maxFileSize && _file.size > maxFileSize * 1024) {
|
|
30
|
+
throw new Error(`File size exceeds the limit of ${maxFileSize / 1024} MB`);
|
|
31
|
+
}
|
|
32
|
+
const chunkSize = (_e = this.handshakeInfo) === null || _e === void 0 ? void 0 : _e.chunkSize;
|
|
33
|
+
// send metadata
|
|
34
|
+
const filemeta = {
|
|
35
|
+
fileId: fileId,
|
|
36
|
+
name: _file.name,
|
|
37
|
+
size: _file.size,
|
|
38
|
+
type: _file.type,
|
|
39
|
+
totalChunks: totalChunks(_file, chunkSize),
|
|
40
|
+
chunkIndex: 0,
|
|
41
|
+
isFinish: false
|
|
42
|
+
};
|
|
43
|
+
const abort = async () => {
|
|
44
|
+
await this.deleteFile(fileId);
|
|
45
|
+
controller.abort();
|
|
46
|
+
window.removeEventListener("pagehide", abort);
|
|
47
|
+
};
|
|
48
|
+
window.addEventListener("pagehide", abort);
|
|
49
|
+
try {
|
|
50
|
+
for (var _g = true, _h = __asyncValues(chunkFile(_file, chunkSize)), _j; _j = await _h.next(), _a = _j.done, !_a;) {
|
|
51
|
+
_c = _j.value;
|
|
52
|
+
_g = false;
|
|
53
|
+
try {
|
|
54
|
+
let { chunk, chunkIndex } = _c;
|
|
55
|
+
if (chunkIndex === 0 && ((_f = this.handshakeInfo) === null || _f === void 0 ? void 0 : _f.checkFileType) && !fileScaner(chunk)) {
|
|
56
|
+
await abort();
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
message: "Unknown or unsupported file type",
|
|
60
|
+
data: null,
|
|
61
|
+
code: 0
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
filemeta.chunkIndex = chunkIndex;
|
|
65
|
+
filemeta.isFinish = chunkIndex + 1 === filemeta.totalChunks;
|
|
66
|
+
const info = {
|
|
67
|
+
method: 'PUT',
|
|
68
|
+
signal: controller.signal,
|
|
69
|
+
body: {
|
|
70
|
+
chunk,
|
|
71
|
+
filemeta
|
|
72
|
+
},
|
|
73
|
+
onProgress: (p) => {
|
|
74
|
+
if (onProgress) {
|
|
75
|
+
const totalProgress = Math.floor(((chunkIndex + 1) / filemeta.totalChunks) * 100);
|
|
76
|
+
const currentProgress = Math.floor((p / 100) / filemeta.totalChunks * 100);
|
|
77
|
+
onProgress(Math.min(totalProgress + currentProgress, 100));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
await this.hooksCall('beforeUploadChunk', chunk, filemeta);
|
|
82
|
+
let res = await this.fetch('/', info);
|
|
83
|
+
if (!res.success) {
|
|
84
|
+
if (["Signeture expired", "Request expired"].includes(res.message)) {
|
|
85
|
+
await this.handshake();
|
|
86
|
+
window.removeEventListener("pagehide", abort);
|
|
87
|
+
res = await this.uploadFile(file, onProgress);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
await abort();
|
|
91
|
+
return res;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
await this.hooksCall('afterUploadChunk', res, filemeta);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
_g = true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
102
|
+
finally {
|
|
103
|
+
try {
|
|
104
|
+
if (!_g && !_a && (_b = _h.return)) await _b.call(_h);
|
|
105
|
+
}
|
|
106
|
+
finally { if (e_1) throw e_1.error; }
|
|
107
|
+
}
|
|
108
|
+
window.removeEventListener("pagehide", abort);
|
|
109
|
+
const info = {
|
|
110
|
+
success: true,
|
|
111
|
+
message: 'File uploaded successfully',
|
|
112
|
+
data: filemeta,
|
|
113
|
+
code: 200
|
|
114
|
+
};
|
|
115
|
+
await this.hooksCall('afterUpload', info, _file);
|
|
116
|
+
return info;
|
|
117
|
+
}
|
|
118
|
+
async deleteFile(fileId, init) {
|
|
119
|
+
await this.awaitForHandshake();
|
|
120
|
+
const res = await this.fetch('/', Object.assign(Object.assign({}, init), { method: 'DELETE', body: { fileId } }));
|
|
121
|
+
if (["Signeture expired", "Request expired"].includes(res.message)) {
|
|
122
|
+
await this.handshake();
|
|
123
|
+
return await this.deleteFile(fileId, init);
|
|
124
|
+
}
|
|
125
|
+
return res;
|
|
126
|
+
}
|
|
127
|
+
async get(path, init) {
|
|
128
|
+
return await this.send(path, init);
|
|
129
|
+
}
|
|
130
|
+
async post(path, init) {
|
|
131
|
+
return await this.send(path, Object.assign(Object.assign({}, init), { method: "POST" }));
|
|
132
|
+
}
|
|
133
|
+
async put(path, init) {
|
|
134
|
+
return await this.send(path, Object.assign(Object.assign({}, init), { method: "PUT" }));
|
|
135
|
+
}
|
|
136
|
+
async delete(path, init) {
|
|
137
|
+
return await this.send(path, Object.assign(Object.assign({}, init), { method: "DELETE" }));
|
|
138
|
+
}
|
|
139
|
+
}export{SecurequClient as default};//# sourceMappingURL=index.mjs.map
|
package/client/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../src/client/index.ts"],"sourcesContent":["import { HttpRequestInit, SecurequClientResponse } from \"./types\";\nimport { chunkFile, getFileId, totalChunks } from \"../include/File\";\nimport Base from \"./Base\";\nimport fileScaner from '../include/FileScaner';\nimport { UploadFileMeta } from \"../server/types\";\n\nclass SecurequClient extends Base {\n\n async send(path: string, init?: HttpRequestInit): Promise<SecurequClientResponse> {\n await this.awaitForHandshake();\n init = await this.hooksCall('beforeRequest', path, init) || init;\n const url = await this.url(path)\n if (url.pathname === '/') throw new Error(\"Path is not allowed\")\n\n for (let key in init?.body) {\n if (init?.body[key] instanceof File) {\n init.body[key] = await this.uploadFile(init.body[key], init?.onProgress)\n }\n }\n\n const res = await this.fetch(path, init);\n if ([\"Signeture expired\", \"Request expired\"].includes(res.message)) {\n await this.handshake();\n return await this.send(path, init);\n }\n await this.hooksCall('afterResponse', res);\n return res;\n }\n\n async uploadFile(file: File, onProgress?: (p: number) => void): Promise<SecurequClientResponse> {\n await this.awaitForHandshake();\n const fileId = await getFileId(file);\n const controller = new AbortController();\n\n let _file = await this.hooksCall('beforeUpload', file, fileId) || file;\n const maxFileSize = this.handshakeInfo?.maxFileSize\n if (maxFileSize && _file.size > maxFileSize * 1024) {\n throw new Error(`File size exceeds the limit of ${maxFileSize / 1024} MB`)\n }\n\n const chunkSize = this.handshakeInfo?.chunkSize\n\n // send metadata\n const filemeta: UploadFileMeta = {\n fileId: fileId,\n name: _file.name,\n size: _file.size,\n type: _file.type,\n totalChunks: totalChunks(_file, chunkSize),\n chunkIndex: 0,\n isFinish: false\n }\n\n const abort = async () => {\n await this.deleteFile(fileId);\n controller.abort();\n window.removeEventListener(\"pagehide\", abort);\n }\n\n window.addEventListener(\"pagehide\", abort);\n\n for await (let { chunk, chunkIndex } of chunkFile(_file, chunkSize)) {\n if (chunkIndex === 0 && this.handshakeInfo?.checkFileType && !fileScaner(chunk)) {\n await abort()\n return {\n success: false,\n message: \"Unknown or unsupported file type\",\n data: null,\n code: 0\n }\n }\n\n filemeta.chunkIndex = chunkIndex;\n filemeta.isFinish = chunkIndex + 1 === filemeta.totalChunks;\n\n const info: any = {\n method: 'PUT',\n signal: controller.signal,\n body: {\n chunk,\n filemeta\n },\n onProgress: (p: number) => {\n if (onProgress) {\n const totalProgress = Math.floor(((chunkIndex + 1) / filemeta.totalChunks) * 100)\n const currentProgress = Math.floor((p / 100) / filemeta.totalChunks * 100)\n onProgress(Math.min(totalProgress + currentProgress, 100))\n }\n }\n }\n await this.hooksCall('beforeUploadChunk', chunk, filemeta);\n\n let res = await this.fetch('/', info)\n\n if (!res.success) {\n if ([\"Signeture expired\", \"Request expired\"].includes(res.message)) {\n await this.handshake();\n window.removeEventListener(\"pagehide\", abort);\n res = await this.uploadFile(file, onProgress);\n } else {\n await abort()\n return res\n }\n }\n await this.hooksCall('afterUploadChunk', res, filemeta);\n }\n\n window.removeEventListener(\"pagehide\", abort);\n\n const info = {\n success: true,\n message: 'File uploaded successfully',\n data: filemeta,\n code: 200\n }\n await this.hooksCall('afterUpload', info, _file);\n return info\n }\n\n async deleteFile(fileId: string, init?: Omit<HttpRequestInit, 'body' | 'method'>): Promise<SecurequClientResponse> {\n await this.awaitForHandshake();\n const res = await this.fetch('/', {\n ...init,\n method: 'DELETE',\n body: { fileId }\n });\n if ([\"Signeture expired\", \"Request expired\"].includes(res.message)) {\n await this.handshake();\n return await this.deleteFile(fileId, init);\n }\n return res;\n }\n\n async get(path: string, init?: Omit<HttpRequestInit, 'body' | 'method'>) {\n return await this.send(path, init);\n }\n\n async post(path: string, init?: Omit<HttpRequestInit, 'method'>) {\n return await this.send(path, { ...init, method: \"POST\" });\n }\n\n async put(path: string, init?: Omit<HttpRequestInit, 'method'>) {\n return await this.send(path, { ...init, method: \"PUT\" });\n }\n\n async delete(path: string, init?: Omit<HttpRequestInit, 'method'>) {\n return await this.send(path, { ...init, method: \"DELETE\" });\n }\n\n}\n\nexport default SecurequClient;\n"],"names":["SecurequClient","Base","send","path","init","this","awaitForHandshake","hooksCall","url","pathname","Error","key","body","File","uploadFile","onProgress","res","fetch","includes","message","handshake","file","fileId","getFileId","controller","AbortController","_file","maxFileSize","_d","handshakeInfo","size","chunkSize","_e","filemeta","name","type","totalChunks","chunkIndex","isFinish","abort","async","deleteFile","window","removeEventListener","addEventListener","_j","_g","_h","__asyncValues","chunkFile","_a","next","done","_c","value","chunk","_f","checkFileType","fileScaner","success","data","code","info","method","signal","p","totalProgress","Math","floor","currentProgress","min","Object","assign","get","post","put"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../src/client/index.ts"],"sourcesContent":["import { HttpRequestInit, SecurequClientResponse } from \"./types\";\nimport { chunkFile, getFileId, totalChunks } from \"../include/File\";\nimport Base from \"./Base\";\nimport fileScaner from '../include/FileScaner';\nimport { UploadFileMeta } from \"../server/types\";\n\nclass SecurequClient extends Base {\n\n async send(path: string, init?: HttpRequestInit): Promise<SecurequClientResponse> {\n await this.awaitForHandshake();\n init = await this.hooksCall('beforeRequest', path, init) || init;\n const url = await this.url(path)\n if (url.pathname === '/') throw new Error(\"Path is not allowed\")\n\n for (let key in init?.body) {\n if (init?.body[key] instanceof File) {\n init.body[key] = await this.uploadFile(init.body[key], init?.onProgress)\n }\n }\n\n const res = await this.fetch(path, init);\n if ([\"Signeture expired\", \"Request expired\"].includes(res.message)) {\n await this.handshake();\n return await this.send(path, init);\n }\n await this.hooksCall('afterResponse', res);\n return res;\n }\n\n async uploadFile(file: File, onProgress?: (p: number) => void): Promise<SecurequClientResponse> {\n await this.awaitForHandshake();\n const fileId = await getFileId(file);\n const controller = new AbortController();\n\n let _file = await this.hooksCall('beforeUpload', file, fileId) || file;\n const maxFileSize = this.handshakeInfo?.maxFileSize\n if (maxFileSize && _file.size > maxFileSize * 1024) {\n throw new Error(`File size exceeds the limit of ${maxFileSize / 1024} MB`)\n }\n\n const chunkSize = this.handshakeInfo?.chunkSize\n\n // send metadata\n const filemeta: UploadFileMeta = {\n fileId: fileId,\n name: _file.name,\n size: _file.size,\n type: _file.type,\n totalChunks: totalChunks(_file, chunkSize),\n chunkIndex: 0,\n isFinish: false\n }\n\n const abort = async () => {\n await this.deleteFile(fileId);\n controller.abort();\n window.removeEventListener(\"pagehide\", abort);\n }\n\n window.addEventListener(\"pagehide\", abort);\n\n for await (let { chunk, chunkIndex } of chunkFile(_file, chunkSize)) {\n if (chunkIndex === 0 && this.handshakeInfo?.checkFileType && !fileScaner(chunk)) {\n await abort()\n return {\n success: false,\n message: \"Unknown or unsupported file type\",\n data: null,\n code: 0\n }\n }\n\n filemeta.chunkIndex = chunkIndex;\n filemeta.isFinish = chunkIndex + 1 === filemeta.totalChunks;\n\n const info: any = {\n method: 'PUT',\n signal: controller.signal,\n body: {\n chunk,\n filemeta\n },\n onProgress: (p: number) => {\n if (onProgress) {\n const totalProgress = Math.floor(((chunkIndex + 1) / filemeta.totalChunks) * 100)\n const currentProgress = Math.floor((p / 100) / filemeta.totalChunks * 100)\n onProgress(Math.min(totalProgress + currentProgress, 100))\n }\n }\n }\n await this.hooksCall('beforeUploadChunk', chunk, filemeta);\n\n let res = await this.fetch('/', info)\n\n if (!res.success) {\n if ([\"Signeture expired\", \"Request expired\"].includes(res.message)) {\n await this.handshake();\n window.removeEventListener(\"pagehide\", abort);\n res = await this.uploadFile(file, onProgress);\n } else {\n await abort()\n return res\n }\n }\n await this.hooksCall('afterUploadChunk', res, filemeta);\n }\n\n window.removeEventListener(\"pagehide\", abort);\n\n const info = {\n success: true,\n message: 'File uploaded successfully',\n data: filemeta,\n code: 200\n }\n await this.hooksCall('afterUpload', info, _file);\n return info\n }\n\n async deleteFile(fileId: string, init?: Omit<HttpRequestInit, 'body' | 'method'>): Promise<SecurequClientResponse> {\n await this.awaitForHandshake();\n const res = await this.fetch('/', {\n ...init,\n method: 'DELETE',\n body: { fileId }\n });\n if ([\"Signeture expired\", \"Request expired\"].includes(res.message)) {\n await this.handshake();\n return await this.deleteFile(fileId, init);\n }\n return res;\n }\n\n async get(path: string, init?: Omit<HttpRequestInit, 'body' | 'method'>) {\n return await this.send(path, init);\n }\n\n async post(path: string, init?: Omit<HttpRequestInit, 'method'>) {\n return await this.send(path, { ...init, method: \"POST\" });\n }\n\n async put(path: string, init?: Omit<HttpRequestInit, 'method'>) {\n return await this.send(path, { ...init, method: \"PUT\" });\n }\n\n async delete(path: string, init?: Omit<HttpRequestInit, 'method'>) {\n return await this.send(path, { ...init, method: \"DELETE\" });\n }\n\n}\n\nexport default SecurequClient;\n"],"names":[],"mappings":"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"}
|
package/client/types.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { XanFetchOptions } from 'xanfetch/types';
|
|
|
2
2
|
import { UploadFileMeta } from '../server/types.js';
|
|
3
3
|
|
|
4
4
|
type HandshakeInfo = {
|
|
5
|
-
dev: boolean;
|
|
6
5
|
timeDiffarenc: number;
|
|
7
6
|
signeture: string;
|
|
8
7
|
maxFileSize: number | null;
|
|
@@ -12,6 +11,7 @@ type HandshakeInfo = {
|
|
|
12
11
|
type SecurequClientConfig = {
|
|
13
12
|
url: string;
|
|
14
13
|
secret: string;
|
|
14
|
+
mode?: "development" | "production";
|
|
15
15
|
defaultOptions?: XanFetchOptions;
|
|
16
16
|
hooks?: {
|
|
17
17
|
beforeHandshake?: () => Promise<void> | void;
|
package/include/File.js
CHANGED
|
@@ -1 +1,60 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var tslib=require('tslib'),crypto=require('./crypto.js');function getChunkSize(fileSize) {
|
|
2
|
+
// fileSize in bytes
|
|
3
|
+
const MB = 1024 * 1024;
|
|
4
|
+
if (fileSize <= 1 * MB) {
|
|
5
|
+
// Very small files (<1MB): single small chunk
|
|
6
|
+
return 64 * 1024; // 64 KB
|
|
7
|
+
}
|
|
8
|
+
else if (fileSize <= 10 * MB) {
|
|
9
|
+
// Small files (1–10MB): medium chunks
|
|
10
|
+
return 256 * 1024; // 256 KB
|
|
11
|
+
}
|
|
12
|
+
else if (fileSize <= 100 * MB) {
|
|
13
|
+
// Medium files (10–100MB): faster upload, moderate size
|
|
14
|
+
return 512 * 1024; // 512 KB
|
|
15
|
+
}
|
|
16
|
+
else if (fileSize <= 500 * MB) {
|
|
17
|
+
// Large files (100–500MB): larger chunks to reduce overhead
|
|
18
|
+
return 1 * MB; // 1 MB
|
|
19
|
+
}
|
|
20
|
+
else if (fileSize <= 2 * 1024 * MB) {
|
|
21
|
+
// Very large files (500MB–2GB): fewer but larger parts
|
|
22
|
+
return 2 * MB; // 2 MB
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// Extremely large files (>2GB)
|
|
26
|
+
return 4 * MB; // 4 MB max chunk size
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const totalChunks = (file, chunkSize) => Math.ceil(file.size / (chunkSize || getChunkSize(file.size)));
|
|
30
|
+
function chunkFile(file, chunkSize) {
|
|
31
|
+
return tslib.__asyncGenerator(this, arguments, function* chunkFile_1() {
|
|
32
|
+
const fileSize = file.size;
|
|
33
|
+
chunkSize = chunkSize || getChunkSize(fileSize);
|
|
34
|
+
let offset = 0;
|
|
35
|
+
while (offset < fileSize) {
|
|
36
|
+
const chunk = file.slice(offset, offset + chunkSize);
|
|
37
|
+
const buffer = new Uint8Array(yield tslib.__await(chunk.arrayBuffer()));
|
|
38
|
+
yield yield tslib.__await({ chunk: buffer, chunkIndex: Math.floor(offset / chunkSize) });
|
|
39
|
+
offset += chunkSize;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async function getFileId(file) {
|
|
44
|
+
let data = [];
|
|
45
|
+
if (typeof window !== 'undefined') {
|
|
46
|
+
data = [
|
|
47
|
+
navigator.userAgent,
|
|
48
|
+
navigator.language,
|
|
49
|
+
screen.width,
|
|
50
|
+
screen.height,
|
|
51
|
+
screen.colorDepth,
|
|
52
|
+
new Date().getTimezoneOffset(),
|
|
53
|
+
Intl.DateTimeFormat().resolvedOptions().timeZone || ""
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
const meta = `${file.name}||${file.size}||${file.lastModified}||${data.join("||")}`;
|
|
57
|
+
const ext = file.name.split('.').pop() || '';
|
|
58
|
+
const id = await crypto.default.hash(meta);
|
|
59
|
+
return `${id}.${ext}`;
|
|
60
|
+
}exports.chunkFile=chunkFile;exports.getChunkSize=getChunkSize;exports.getFileId=getFileId;exports.totalChunks=totalChunks;//# sourceMappingURL=File.js.map
|
package/include/File.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"File.js","sources":["../../src/include/File.ts"],"sourcesContent":["import crypto from \"./crypto\";\n\nexport function getChunkSize(fileSize: number): number {\n // fileSize in bytes\n const MB = 1024 * 1024;\n\n if (fileSize <= 1 * MB) {\n // Very small files (<1MB): single small chunk\n return 64 * 1024; // 64 KB\n } else if (fileSize <= 10 * MB) {\n // Small files (1–10MB): medium chunks\n return 256 * 1024; // 256 KB\n } else if (fileSize <= 100 * MB) {\n // Medium files (10–100MB): faster upload, moderate size\n return 512 * 1024; // 512 KB\n } else if (fileSize <= 500 * MB) {\n // Large files (100–500MB): larger chunks to reduce overhead\n return 1 * MB; // 1 MB\n } else if (fileSize <= 2 * 1024 * MB) {\n // Very large files (500MB–2GB): fewer but larger parts\n return 2 * MB; // 2 MB\n } else {\n // Extremely large files (>2GB)\n return 4 * MB; // 4 MB max chunk size\n }\n}\n\nexport const totalChunks = (file: File, chunkSize?: number) => Math.ceil(file.size / (chunkSize || getChunkSize(file.size)));\n\nexport async function* chunkFile(file: File, chunkSize?: number) {\n const fileSize = file.size;\n chunkSize = chunkSize || getChunkSize(fileSize);\n let offset = 0;\n\n while (offset < fileSize) {\n const chunk = file.slice(offset, offset + chunkSize);\n const buffer = new Uint8Array(await chunk.arrayBuffer());\n yield { chunk: buffer, chunkIndex: Math.floor(offset / chunkSize) };\n offset += chunkSize;\n }\n}\n\n\nexport async function getFileId(file: File): Promise<string> {\n let data: any[] = [];\n if (typeof window !== 'undefined') {\n data = [\n navigator.userAgent,\n navigator.language,\n screen.width,\n screen.height,\n screen.colorDepth,\n new Date().getTimezoneOffset(),\n Intl.DateTimeFormat().resolvedOptions().timeZone || \"\"\n ]\n }\n\n const meta = `${file.name}||${file.size}||${file.lastModified}||${data.join(\"||\")}`\n const ext = file.name.split('.').pop() || ''\n const id = await crypto.hash(meta);\n return `${id}.${ext}`;\n}"],"names":["
|
|
1
|
+
{"version":3,"file":"File.js","sources":["../../src/include/File.ts"],"sourcesContent":["import crypto from \"./crypto\";\n\nexport function getChunkSize(fileSize: number): number {\n // fileSize in bytes\n const MB = 1024 * 1024;\n\n if (fileSize <= 1 * MB) {\n // Very small files (<1MB): single small chunk\n return 64 * 1024; // 64 KB\n } else if (fileSize <= 10 * MB) {\n // Small files (1–10MB): medium chunks\n return 256 * 1024; // 256 KB\n } else if (fileSize <= 100 * MB) {\n // Medium files (10–100MB): faster upload, moderate size\n return 512 * 1024; // 512 KB\n } else if (fileSize <= 500 * MB) {\n // Large files (100–500MB): larger chunks to reduce overhead\n return 1 * MB; // 1 MB\n } else if (fileSize <= 2 * 1024 * MB) {\n // Very large files (500MB–2GB): fewer but larger parts\n return 2 * MB; // 2 MB\n } else {\n // Extremely large files (>2GB)\n return 4 * MB; // 4 MB max chunk size\n }\n}\n\nexport const totalChunks = (file: File, chunkSize?: number) => Math.ceil(file.size / (chunkSize || getChunkSize(file.size)));\n\nexport async function* chunkFile(file: File, chunkSize?: number) {\n const fileSize = file.size;\n chunkSize = chunkSize || getChunkSize(fileSize);\n let offset = 0;\n\n while (offset < fileSize) {\n const chunk = file.slice(offset, offset + chunkSize);\n const buffer = new Uint8Array(await chunk.arrayBuffer());\n yield { chunk: buffer, chunkIndex: Math.floor(offset / chunkSize) };\n offset += chunkSize;\n }\n}\n\n\nexport async function getFileId(file: File): Promise<string> {\n let data: any[] = [];\n if (typeof window !== 'undefined') {\n data = [\n navigator.userAgent,\n navigator.language,\n screen.width,\n screen.height,\n screen.colorDepth,\n new Date().getTimezoneOffset(),\n Intl.DateTimeFormat().resolvedOptions().timeZone || \"\"\n ]\n }\n\n const meta = `${file.name}||${file.size}||${file.lastModified}||${data.join(\"||\")}`\n const ext = file.name.split('.').pop() || ''\n const id = await crypto.hash(meta);\n return `${id}.${ext}`;\n}"],"names":["__await","crypto"],"mappings":"+HAEM,SAAU,YAAY,CAAC,QAAgB,EAAA;;AAE1C,IAAA,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI;AAEtB,IAAA,IAAI,QAAQ,IAAI,CAAC,GAAG,EAAE,EAAE;;AAErB,QAAA,OAAO,EAAE,GAAG,IAAI,CAAC;AACnB,IAAA;AAAM,SAAA,IAAI,QAAQ,IAAI,EAAE,GAAG,EAAE,EAAE;;AAE7B,QAAA,OAAO,GAAG,GAAG,IAAI,CAAC;AACpB,IAAA;AAAM,SAAA,IAAI,QAAQ,IAAI,GAAG,GAAG,EAAE,EAAE;;AAE9B,QAAA,OAAO,GAAG,GAAG,IAAI,CAAC;AACpB,IAAA;AAAM,SAAA,IAAI,QAAQ,IAAI,GAAG,GAAG,EAAE,EAAE;;AAE9B,QAAA,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,IAAA;AAAM,SAAA,IAAI,QAAQ,IAAI,CAAC,GAAG,IAAI,GAAG,EAAE,EAAE;;AAEnC,QAAA,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,IAAA;AAAM,SAAA;;AAEJ,QAAA,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,IAAA;AACJ;AAEO,MAAM,WAAW,GAAG,CAAC,IAAU,EAAE,SAAkB,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAErH,SAAiB,SAAS,CAAC,IAAU,EAAE,SAAkB,EAAA;;AAC5D,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI;AAC1B,QAAA,SAAS,GAAG,SAAS,IAAI,YAAY,CAAC,QAAQ,CAAC;QAC/C,IAAI,MAAM,GAAG,CAAC;QAEd,OAAO,MAAM,GAAG,QAAQ,EAAE;AACvB,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;AACpD,YAAA,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAAA,aAAA,CAAM,KAAK,CAAC,WAAW,EAAE,CAAA,CAAC;AACxD,YAAA,MAAA,MAAAA,aAAA,CAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAA;YACnE,MAAM,IAAI,SAAS;AACrB,QAAA;IACJ,CAAC,CAAA;AAAA;AAGM,eAAe,SAAS,CAAC,IAAU,EAAA;IACvC,IAAI,IAAI,GAAU,EAAE;AACpB,IAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;AAChC,QAAA,IAAI,GAAG;AACJ,YAAA,SAAS,CAAC,SAAS;AACnB,YAAA,SAAS,CAAC,QAAQ;AAClB,YAAA,MAAM,CAAC,KAAK;AACZ,YAAA,MAAM,CAAC,MAAM;AACb,YAAA,MAAM,CAAC,UAAU;AACjB,YAAA,IAAI,IAAI,EAAE,CAAC,iBAAiB,EAAE;YAC9B,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,QAAQ,IAAI;SACtD;AACH,IAAA;IAED,MAAM,IAAI,GAAG,CAAA,EAAG,IAAI,CAAC,IAAI,CAAA,EAAA,EAAK,IAAI,CAAC,IAAI,CAAA,EAAA,EAAK,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAE;AACnF,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE;IAC5C,MAAM,EAAE,GAAG,MAAMC,cAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAClC,IAAA,OAAO,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,GAAG,EAAE;AACxB"}
|
package/include/File.mjs
CHANGED
|
@@ -1 +1,60 @@
|
|
|
1
|
-
import{__asyncGenerator
|
|
1
|
+
import {__asyncGenerator,__await}from'tslib';import crypto from'./crypto.mjs';function getChunkSize(fileSize) {
|
|
2
|
+
// fileSize in bytes
|
|
3
|
+
const MB = 1024 * 1024;
|
|
4
|
+
if (fileSize <= 1 * MB) {
|
|
5
|
+
// Very small files (<1MB): single small chunk
|
|
6
|
+
return 64 * 1024; // 64 KB
|
|
7
|
+
}
|
|
8
|
+
else if (fileSize <= 10 * MB) {
|
|
9
|
+
// Small files (1–10MB): medium chunks
|
|
10
|
+
return 256 * 1024; // 256 KB
|
|
11
|
+
}
|
|
12
|
+
else if (fileSize <= 100 * MB) {
|
|
13
|
+
// Medium files (10–100MB): faster upload, moderate size
|
|
14
|
+
return 512 * 1024; // 512 KB
|
|
15
|
+
}
|
|
16
|
+
else if (fileSize <= 500 * MB) {
|
|
17
|
+
// Large files (100–500MB): larger chunks to reduce overhead
|
|
18
|
+
return 1 * MB; // 1 MB
|
|
19
|
+
}
|
|
20
|
+
else if (fileSize <= 2 * 1024 * MB) {
|
|
21
|
+
// Very large files (500MB–2GB): fewer but larger parts
|
|
22
|
+
return 2 * MB; // 2 MB
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// Extremely large files (>2GB)
|
|
26
|
+
return 4 * MB; // 4 MB max chunk size
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const totalChunks = (file, chunkSize) => Math.ceil(file.size / (chunkSize || getChunkSize(file.size)));
|
|
30
|
+
function chunkFile(file, chunkSize) {
|
|
31
|
+
return __asyncGenerator(this, arguments, function* chunkFile_1() {
|
|
32
|
+
const fileSize = file.size;
|
|
33
|
+
chunkSize = chunkSize || getChunkSize(fileSize);
|
|
34
|
+
let offset = 0;
|
|
35
|
+
while (offset < fileSize) {
|
|
36
|
+
const chunk = file.slice(offset, offset + chunkSize);
|
|
37
|
+
const buffer = new Uint8Array(yield __await(chunk.arrayBuffer()));
|
|
38
|
+
yield yield __await({ chunk: buffer, chunkIndex: Math.floor(offset / chunkSize) });
|
|
39
|
+
offset += chunkSize;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async function getFileId(file) {
|
|
44
|
+
let data = [];
|
|
45
|
+
if (typeof window !== 'undefined') {
|
|
46
|
+
data = [
|
|
47
|
+
navigator.userAgent,
|
|
48
|
+
navigator.language,
|
|
49
|
+
screen.width,
|
|
50
|
+
screen.height,
|
|
51
|
+
screen.colorDepth,
|
|
52
|
+
new Date().getTimezoneOffset(),
|
|
53
|
+
Intl.DateTimeFormat().resolvedOptions().timeZone || ""
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
const meta = `${file.name}||${file.size}||${file.lastModified}||${data.join("||")}`;
|
|
57
|
+
const ext = file.name.split('.').pop() || '';
|
|
58
|
+
const id = await crypto.hash(meta);
|
|
59
|
+
return `${id}.${ext}`;
|
|
60
|
+
}export{chunkFile,getChunkSize,getFileId,totalChunks};//# sourceMappingURL=File.mjs.map
|
package/include/File.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"File.mjs","sources":["../../src/include/File.ts"],"sourcesContent":["import crypto from \"./crypto\";\n\nexport function getChunkSize(fileSize: number): number {\n // fileSize in bytes\n const MB = 1024 * 1024;\n\n if (fileSize <= 1 * MB) {\n // Very small files (<1MB): single small chunk\n return 64 * 1024; // 64 KB\n } else if (fileSize <= 10 * MB) {\n // Small files (1–10MB): medium chunks\n return 256 * 1024; // 256 KB\n } else if (fileSize <= 100 * MB) {\n // Medium files (10–100MB): faster upload, moderate size\n return 512 * 1024; // 512 KB\n } else if (fileSize <= 500 * MB) {\n // Large files (100–500MB): larger chunks to reduce overhead\n return 1 * MB; // 1 MB\n } else if (fileSize <= 2 * 1024 * MB) {\n // Very large files (500MB–2GB): fewer but larger parts\n return 2 * MB; // 2 MB\n } else {\n // Extremely large files (>2GB)\n return 4 * MB; // 4 MB max chunk size\n }\n}\n\nexport const totalChunks = (file: File, chunkSize?: number) => Math.ceil(file.size / (chunkSize || getChunkSize(file.size)));\n\nexport async function* chunkFile(file: File, chunkSize?: number) {\n const fileSize = file.size;\n chunkSize = chunkSize || getChunkSize(fileSize);\n let offset = 0;\n\n while (offset < fileSize) {\n const chunk = file.slice(offset, offset + chunkSize);\n const buffer = new Uint8Array(await chunk.arrayBuffer());\n yield { chunk: buffer, chunkIndex: Math.floor(offset / chunkSize) };\n offset += chunkSize;\n }\n}\n\n\nexport async function getFileId(file: File): Promise<string> {\n let data: any[] = [];\n if (typeof window !== 'undefined') {\n data = [\n navigator.userAgent,\n navigator.language,\n screen.width,\n screen.height,\n screen.colorDepth,\n new Date().getTimezoneOffset(),\n Intl.DateTimeFormat().resolvedOptions().timeZone || \"\"\n ]\n }\n\n const meta = `${file.name}||${file.size}||${file.lastModified}||${data.join(\"||\")}`\n const ext = file.name.split('.').pop() || ''\n const id = await crypto.hash(meta);\n return `${id}.${ext}`;\n}"],"names":[
|
|
1
|
+
{"version":3,"file":"File.mjs","sources":["../../src/include/File.ts"],"sourcesContent":["import crypto from \"./crypto\";\n\nexport function getChunkSize(fileSize: number): number {\n // fileSize in bytes\n const MB = 1024 * 1024;\n\n if (fileSize <= 1 * MB) {\n // Very small files (<1MB): single small chunk\n return 64 * 1024; // 64 KB\n } else if (fileSize <= 10 * MB) {\n // Small files (1–10MB): medium chunks\n return 256 * 1024; // 256 KB\n } else if (fileSize <= 100 * MB) {\n // Medium files (10–100MB): faster upload, moderate size\n return 512 * 1024; // 512 KB\n } else if (fileSize <= 500 * MB) {\n // Large files (100–500MB): larger chunks to reduce overhead\n return 1 * MB; // 1 MB\n } else if (fileSize <= 2 * 1024 * MB) {\n // Very large files (500MB–2GB): fewer but larger parts\n return 2 * MB; // 2 MB\n } else {\n // Extremely large files (>2GB)\n return 4 * MB; // 4 MB max chunk size\n }\n}\n\nexport const totalChunks = (file: File, chunkSize?: number) => Math.ceil(file.size / (chunkSize || getChunkSize(file.size)));\n\nexport async function* chunkFile(file: File, chunkSize?: number) {\n const fileSize = file.size;\n chunkSize = chunkSize || getChunkSize(fileSize);\n let offset = 0;\n\n while (offset < fileSize) {\n const chunk = file.slice(offset, offset + chunkSize);\n const buffer = new Uint8Array(await chunk.arrayBuffer());\n yield { chunk: buffer, chunkIndex: Math.floor(offset / chunkSize) };\n offset += chunkSize;\n }\n}\n\n\nexport async function getFileId(file: File): Promise<string> {\n let data: any[] = [];\n if (typeof window !== 'undefined') {\n data = [\n navigator.userAgent,\n navigator.language,\n screen.width,\n screen.height,\n screen.colorDepth,\n new Date().getTimezoneOffset(),\n Intl.DateTimeFormat().resolvedOptions().timeZone || \"\"\n ]\n }\n\n const meta = `${file.name}||${file.size}||${file.lastModified}||${data.join(\"||\")}`\n const ext = file.name.split('.').pop() || ''\n const id = await crypto.hash(meta);\n return `${id}.${ext}`;\n}"],"names":[],"mappings":"8EAEM,SAAU,YAAY,CAAC,QAAgB,EAAA;;AAE1C,IAAA,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI;AAEtB,IAAA,IAAI,QAAQ,IAAI,CAAC,GAAG,EAAE,EAAE;;AAErB,QAAA,OAAO,EAAE,GAAG,IAAI,CAAC;AACnB,IAAA;AAAM,SAAA,IAAI,QAAQ,IAAI,EAAE,GAAG,EAAE,EAAE;;AAE7B,QAAA,OAAO,GAAG,GAAG,IAAI,CAAC;AACpB,IAAA;AAAM,SAAA,IAAI,QAAQ,IAAI,GAAG,GAAG,EAAE,EAAE;;AAE9B,QAAA,OAAO,GAAG,GAAG,IAAI,CAAC;AACpB,IAAA;AAAM,SAAA,IAAI,QAAQ,IAAI,GAAG,GAAG,EAAE,EAAE;;AAE9B,QAAA,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,IAAA;AAAM,SAAA,IAAI,QAAQ,IAAI,CAAC,GAAG,IAAI,GAAG,EAAE,EAAE;;AAEnC,QAAA,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,IAAA;AAAM,SAAA;;AAEJ,QAAA,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,IAAA;AACJ;AAEO,MAAM,WAAW,GAAG,CAAC,IAAU,EAAE,SAAkB,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAErH,SAAiB,SAAS,CAAC,IAAU,EAAE,SAAkB,EAAA;;AAC5D,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI;AAC1B,QAAA,SAAS,GAAG,SAAS,IAAI,YAAY,CAAC,QAAQ,CAAC;QAC/C,IAAI,MAAM,GAAG,CAAC;QAEd,OAAO,MAAM,GAAG,QAAQ,EAAE;AACvB,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;AACpD,YAAA,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAA,OAAA,CAAM,KAAK,CAAC,WAAW,EAAE,CAAA,CAAC;AACxD,YAAA,MAAA,MAAA,OAAA,CAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAA;YACnE,MAAM,IAAI,SAAS;AACrB,QAAA;IACJ,CAAC,CAAA;AAAA;AAGM,eAAe,SAAS,CAAC,IAAU,EAAA;IACvC,IAAI,IAAI,GAAU,EAAE;AACpB,IAAA,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;AAChC,QAAA,IAAI,GAAG;AACJ,YAAA,SAAS,CAAC,SAAS;AACnB,YAAA,SAAS,CAAC,QAAQ;AAClB,YAAA,MAAM,CAAC,KAAK;AACZ,YAAA,MAAM,CAAC,MAAM;AACb,YAAA,MAAM,CAAC,UAAU;AACjB,YAAA,IAAI,IAAI,EAAE,CAAC,iBAAiB,EAAE;YAC9B,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,QAAQ,IAAI;SACtD;AACH,IAAA;IAED,MAAM,IAAI,GAAG,CAAA,EAAG,IAAI,CAAC,IAAI,CAAA,EAAA,EAAK,IAAI,CAAC,IAAI,CAAA,EAAA,EAAK,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA,CAAE;AACnF,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE;IAC5C,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;AAClC,IAAA,OAAO,CAAA,EAAG,EAAE,CAAA,CAAA,EAAI,GAAG,EAAE;AACxB"}
|
package/include/FileScaner.js
CHANGED
|
@@ -1 +1,95 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});/**
|
|
2
|
+
* Mega raw file-type detection from first chunk (magic bytes)
|
|
3
|
+
* Supports 100+ common file types: images, audio, video, docs, archives, installers, fonts, binaries.
|
|
4
|
+
*/
|
|
5
|
+
function fileScaner(chunk) {
|
|
6
|
+
if (!chunk || chunk.length < 4)
|
|
7
|
+
return { valid: false };
|
|
8
|
+
const match = (pattern) => pattern.every((b, i) => chunk[i] === b);
|
|
9
|
+
// --- Images ---
|
|
10
|
+
if (chunk.length >= 8) {
|
|
11
|
+
if (match([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]))
|
|
12
|
+
return { valid: true, ext: "png", mime: "image/png" };
|
|
13
|
+
if (match([0x47, 0x49, 0x46, 0x38]))
|
|
14
|
+
return { valid: true, ext: "gif", mime: "image/gif" };
|
|
15
|
+
if (match([0x52, 0x49, 0x46, 0x46]) && chunk.slice(8, 12).toString() === "WEBP")
|
|
16
|
+
return { valid: true, ext: "webp", mime: "image/webp" };
|
|
17
|
+
}
|
|
18
|
+
if (match([0xFF, 0xD8, 0xFF]))
|
|
19
|
+
return { valid: true, ext: "jpg", mime: "image/jpeg" };
|
|
20
|
+
if (match([0x42, 0x4D]))
|
|
21
|
+
return { valid: true, ext: "bmp", mime: "image/bmp" };
|
|
22
|
+
if (match([0x49, 0x49, 0x2A, 0x00]) || match([0x4D, 0x4D, 0x00, 0x2A]))
|
|
23
|
+
return { valid: true, ext: "tif", mime: "image/tiff" };
|
|
24
|
+
if (match([0x00, 0x00, 0x01, 0x00]))
|
|
25
|
+
return { valid: true, ext: "ico", mime: "image/x-icon" };
|
|
26
|
+
if (match([0x00, 0x00, 0x02, 0x00]))
|
|
27
|
+
return { valid: true, ext: "cur", mime: "image/x-icon" };
|
|
28
|
+
// --- Audio ---
|
|
29
|
+
if (match([0x49, 0x44, 0x33]))
|
|
30
|
+
return { valid: true, ext: "mp3", mime: "audio/mpeg" };
|
|
31
|
+
if (match([0x66, 0x4C, 0x61, 0x43]))
|
|
32
|
+
return { valid: true, ext: "flac", mime: "audio/flac" };
|
|
33
|
+
if (match([0x4F, 0x67, 0x67, 0x53]))
|
|
34
|
+
return { valid: true, ext: "ogg", mime: "audio/ogg" };
|
|
35
|
+
if (match([0x52, 0x49, 0x46, 0x46]) && chunk.slice(8, 12).toString() === "WAVE")
|
|
36
|
+
return { valid: true, ext: "wav", mime: "audio/wav" };
|
|
37
|
+
if (match([0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32]))
|
|
38
|
+
return { valid: true, ext: "mp4a", mime: "audio/mp4" };
|
|
39
|
+
// --- Video ---
|
|
40
|
+
if (match([0x00, 0x00, 0x00, 0x18]) && chunk.slice(4, 8).toString() === "ftyp")
|
|
41
|
+
return { valid: true, ext: "mp4", mime: "video/mp4" };
|
|
42
|
+
if (match([0x1A, 0x45, 0xDF, 0xA3]))
|
|
43
|
+
return { valid: true, ext: "mkv", mime: "video/x-matroska" };
|
|
44
|
+
if (match([0x52, 0x49, 0x46, 0x46]) && chunk.slice(8, 12).toString() === "AVI ")
|
|
45
|
+
return { valid: true, ext: "avi", mime: "video/x-msvideo" };
|
|
46
|
+
if (match([0x00, 0x00, 0x01, 0xBA]))
|
|
47
|
+
return { valid: true, ext: "mpeg", mime: "video/mpeg" };
|
|
48
|
+
if (match([0x47, 0x40, 0x00, 0x10]))
|
|
49
|
+
return { valid: true, ext: "ts", mime: "video/MP2T" };
|
|
50
|
+
if (match([0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32]))
|
|
51
|
+
return { valid: true, ext: "mov", mime: "video/quicktime" };
|
|
52
|
+
// --- Archives ---
|
|
53
|
+
if (match([0x50, 0x4B, 0x03, 0x04]))
|
|
54
|
+
return { valid: true, ext: "zip", mime: "application/zip" };
|
|
55
|
+
if (match([0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00]))
|
|
56
|
+
return { valid: true, ext: "rar", mime: "application/x-rar-compressed" };
|
|
57
|
+
if (match([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C]))
|
|
58
|
+
return { valid: true, ext: "7z", mime: "application/x-7z-compressed" };
|
|
59
|
+
if (match([0x1F, 0x8B]))
|
|
60
|
+
return { valid: true, ext: "gz", mime: "application/gzip" };
|
|
61
|
+
if (match([0x42, 0x5A, 0x68]))
|
|
62
|
+
return { valid: true, ext: "bz2", mime: "application/x-bzip2" };
|
|
63
|
+
// --- Documents ---
|
|
64
|
+
if (match([0x25, 0x50, 0x44, 0x46]))
|
|
65
|
+
return { valid: true, ext: "pdf", mime: "application/pdf" };
|
|
66
|
+
if (match([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1]))
|
|
67
|
+
return { valid: true, ext: "msi", mime: "application/vnd.ms-installer" };
|
|
68
|
+
if (match([0x4D, 0x5A]))
|
|
69
|
+
return { valid: true, ext: "exe", mime: "application/vnd.microsoft.portable-executable" };
|
|
70
|
+
if (match([0x09, 0x08, 0x10, 0x00]))
|
|
71
|
+
return { valid: true, ext: "doc", mime: "application/msword" };
|
|
72
|
+
if (match([0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05]))
|
|
73
|
+
return { valid: true, ext: "xls", mime: "application/vnd.ms-excel" };
|
|
74
|
+
if (match([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1]))
|
|
75
|
+
return { valid: true, ext: "ppt", mime: "application/vnd.ms-powerpoint" };
|
|
76
|
+
if (match([0x50, 0x4B, 0x03, 0x04]))
|
|
77
|
+
return { valid: true, ext: "docx", mime: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" };
|
|
78
|
+
// --- Fonts ---
|
|
79
|
+
if (match([0x00, 0x01, 0x00, 0x00]))
|
|
80
|
+
return { valid: true, ext: "ttf", mime: "font/ttf" };
|
|
81
|
+
if (match([0x4F, 0x54, 0x54, 0x4F]))
|
|
82
|
+
return { valid: true, ext: "otf", mime: "font/otf" };
|
|
83
|
+
// --- Scripts / Binary ---
|
|
84
|
+
if (match([0x23, 0x21]))
|
|
85
|
+
return { valid: true, ext: "sh", mime: "application/x-sh" }; // shell script
|
|
86
|
+
if (match([0x7F, 0x45, 0x4C, 0x46]))
|
|
87
|
+
return { valid: true, ext: "elf", mime: "application/x-elf" }; // Linux executable
|
|
88
|
+
// --- Others / fallback ---
|
|
89
|
+
if (match([0x46, 0x4C, 0x56]))
|
|
90
|
+
return { valid: true, ext: "flv", mime: "video/x-flv" };
|
|
91
|
+
if (match([0x50, 0x4E, 0x44, 0x52]))
|
|
92
|
+
return { valid: true, ext: "pdf", mime: "application/pdf" }; // alternate PDF
|
|
93
|
+
if (match([0x42, 0x50, 0x47, 0x0D]))
|
|
94
|
+
return { valid: true, ext: "bpg", mime: "image/bpg" }; // BPG
|
|
95
|
+
}exports.default=fileScaner;exports.fileScaner=fileScaner;//# sourceMappingURL=FileScaner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileScaner.js","sources":["../../src/include/FileScaner.ts"],"sourcesContent":["export type FileScanerResult = {\n valid: boolean;\n ext?: string;\n mime?: string;\n};\n\n/**\n * Mega raw file-type detection from first chunk (magic bytes)\n * Supports 100+ common file types: images, audio, video, docs, archives, installers, fonts, binaries.\n */\nexport function fileScaner(chunk: Uint8Array | Buffer): FileScanerResult | void {\n if (!chunk || chunk.length < 4) return { valid: false };\n const match = (pattern: number[]) => pattern.every((b, i) => chunk[i] === b);\n\n // --- Images ---\n if (chunk.length >= 8) {\n if (match([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) return { valid: true, ext: \"png\", mime: \"image/png\" };\n if (match([0x47, 0x49, 0x46, 0x38])) return { valid: true, ext: \"gif\", mime: \"image/gif\" };\n if (match([0x52, 0x49, 0x46, 0x46]) && chunk.slice(8, 12).toString() === \"WEBP\") return { valid: true, ext: \"webp\", mime: \"image/webp\" };\n }\n if (match([0xFF, 0xD8, 0xFF])) return { valid: true, ext: \"jpg\", mime: \"image/jpeg\" };\n if (match([0x42, 0x4D])) return { valid: true, ext: \"bmp\", mime: \"image/bmp\" };\n if (match([0x49, 0x49, 0x2A, 0x00]) || match([0x4D, 0x4D, 0x00, 0x2A])) return { valid: true, ext: \"tif\", mime: \"image/tiff\" };\n if (match([0x00, 0x00, 0x01, 0x00])) return { valid: true, ext: \"ico\", mime: \"image/x-icon\" };\n if (match([0x00, 0x00, 0x02, 0x00])) return { valid: true, ext: \"cur\", mime: \"image/x-icon\" };\n\n // --- Audio ---\n if (match([0x49, 0x44, 0x33])) return { valid: true, ext: \"mp3\", mime: \"audio/mpeg\" };\n if (match([0x66, 0x4C, 0x61, 0x43])) return { valid: true, ext: \"flac\", mime: \"audio/flac\" };\n if (match([0x4F, 0x67, 0x67, 0x53])) return { valid: true, ext: \"ogg\", mime: \"audio/ogg\" };\n if (match([0x52, 0x49, 0x46, 0x46]) && chunk.slice(8, 12).toString() === \"WAVE\") return { valid: true, ext: \"wav\", mime: \"audio/wav\" };\n if (match([0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32])) return { valid: true, ext: \"mp4a\", mime: \"audio/mp4\" };\n\n // --- Video ---\n if (match([0x00, 0x00, 0x00, 0x18]) && chunk.slice(4, 8).toString() === \"ftyp\") return { valid: true, ext: \"mp4\", mime: \"video/mp4\" };\n if (match([0x1A, 0x45, 0xDF, 0xA3])) return { valid: true, ext: \"mkv\", mime: \"video/x-matroska\" };\n if (match([0x52, 0x49, 0x46, 0x46]) && chunk.slice(8, 12).toString() === \"AVI \") return { valid: true, ext: \"avi\", mime: \"video/x-msvideo\" };\n if (match([0x00, 0x00, 0x01, 0xBA])) return { valid: true, ext: \"mpeg\", mime: \"video/mpeg\" };\n if (match([0x47, 0x40, 0x00, 0x10])) return { valid: true, ext: \"ts\", mime: \"video/MP2T\" };\n if (match([0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32])) return { valid: true, ext: \"mov\", mime: \"video/quicktime\" };\n\n // --- Archives ---\n if (match([0x50, 0x4B, 0x03, 0x04])) return { valid: true, ext: \"zip\", mime: \"application/zip\" };\n if (match([0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00])) return { valid: true, ext: \"rar\", mime: \"application/x-rar-compressed\" };\n if (match([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C])) return { valid: true, ext: \"7z\", mime: \"application/x-7z-compressed\" };\n if (match([0x1F, 0x8B])) return { valid: true, ext: \"gz\", mime: \"application/gzip\" };\n if (match([0x42, 0x5A, 0x68])) return { valid: true, ext: \"bz2\", mime: \"application/x-bzip2\" };\n\n // --- Documents ---\n if (match([0x25, 0x50, 0x44, 0x46])) return { valid: true, ext: \"pdf\", mime: \"application/pdf\" };\n if (match([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1])) return { valid: true, ext: \"msi\", mime: \"application/vnd.ms-installer\" };\n if (match([0x4D, 0x5A])) return { valid: true, ext: \"exe\", mime: \"application/vnd.microsoft.portable-executable\" };\n if (match([0x09, 0x08, 0x10, 0x00])) return { valid: true, ext: \"doc\", mime: \"application/msword\" };\n if (match([0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05])) return { valid: true, ext: \"xls\", mime: \"application/vnd.ms-excel\" };\n if (match([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1])) return { valid: true, ext: \"ppt\", mime: \"application/vnd.ms-powerpoint\" };\n if (match([0x50, 0x4B, 0x03, 0x04])) return { valid: true, ext: \"docx\", mime: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\" };\n\n // --- Fonts ---\n if (match([0x00, 0x01, 0x00, 0x00])) return { valid: true, ext: \"ttf\", mime: \"font/ttf\" };\n if (match([0x4F, 0x54, 0x54, 0x4F])) return { valid: true, ext: \"otf\", mime: \"font/otf\" };\n\n // --- Scripts / Binary ---\n if (match([0x23, 0x21])) return { valid: true, ext: \"sh\", mime: \"application/x-sh\" }; // shell script\n if (match([0x7F, 0x45, 0x4C, 0x46])) return { valid: true, ext: \"elf\", mime: \"application/x-elf\" }; // Linux executable\n\n // --- Others / fallback ---\n if (match([0x46, 0x4C, 0x56])) return { valid: true, ext: \"flv\", mime: \"video/x-flv\" };\n if (match([0x50, 0x4E, 0x44, 0x52])) return { valid: true, ext: \"pdf\", mime: \"application/pdf\" }; // alternate PDF\n if (match([0x42, 0x50, 0x47, 0x0D])) return { valid: true, ext: \"bpg\", mime: \"image/bpg\" }; // BPG\n\n}\n\nexport default fileScaner;"],"names":["fileScaner","chunk","length","valid","match","pattern","every","b","i","ext","mime","slice","toString","Object","defineProperty","exports","value","default"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"FileScaner.js","sources":["../../src/include/FileScaner.ts"],"sourcesContent":["export type FileScanerResult = {\n valid: boolean;\n ext?: string;\n mime?: string;\n};\n\n/**\n * Mega raw file-type detection from first chunk (magic bytes)\n * Supports 100+ common file types: images, audio, video, docs, archives, installers, fonts, binaries.\n */\nexport function fileScaner(chunk: Uint8Array | Buffer): FileScanerResult | void {\n if (!chunk || chunk.length < 4) return { valid: false };\n const match = (pattern: number[]) => pattern.every((b, i) => chunk[i] === b);\n\n // --- Images ---\n if (chunk.length >= 8) {\n if (match([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A])) return { valid: true, ext: \"png\", mime: \"image/png\" };\n if (match([0x47, 0x49, 0x46, 0x38])) return { valid: true, ext: \"gif\", mime: \"image/gif\" };\n if (match([0x52, 0x49, 0x46, 0x46]) && chunk.slice(8, 12).toString() === \"WEBP\") return { valid: true, ext: \"webp\", mime: \"image/webp\" };\n }\n if (match([0xFF, 0xD8, 0xFF])) return { valid: true, ext: \"jpg\", mime: \"image/jpeg\" };\n if (match([0x42, 0x4D])) return { valid: true, ext: \"bmp\", mime: \"image/bmp\" };\n if (match([0x49, 0x49, 0x2A, 0x00]) || match([0x4D, 0x4D, 0x00, 0x2A])) return { valid: true, ext: \"tif\", mime: \"image/tiff\" };\n if (match([0x00, 0x00, 0x01, 0x00])) return { valid: true, ext: \"ico\", mime: \"image/x-icon\" };\n if (match([0x00, 0x00, 0x02, 0x00])) return { valid: true, ext: \"cur\", mime: \"image/x-icon\" };\n\n // --- Audio ---\n if (match([0x49, 0x44, 0x33])) return { valid: true, ext: \"mp3\", mime: \"audio/mpeg\" };\n if (match([0x66, 0x4C, 0x61, 0x43])) return { valid: true, ext: \"flac\", mime: \"audio/flac\" };\n if (match([0x4F, 0x67, 0x67, 0x53])) return { valid: true, ext: \"ogg\", mime: \"audio/ogg\" };\n if (match([0x52, 0x49, 0x46, 0x46]) && chunk.slice(8, 12).toString() === \"WAVE\") return { valid: true, ext: \"wav\", mime: \"audio/wav\" };\n if (match([0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32])) return { valid: true, ext: \"mp4a\", mime: \"audio/mp4\" };\n\n // --- Video ---\n if (match([0x00, 0x00, 0x00, 0x18]) && chunk.slice(4, 8).toString() === \"ftyp\") return { valid: true, ext: \"mp4\", mime: \"video/mp4\" };\n if (match([0x1A, 0x45, 0xDF, 0xA3])) return { valid: true, ext: \"mkv\", mime: \"video/x-matroska\" };\n if (match([0x52, 0x49, 0x46, 0x46]) && chunk.slice(8, 12).toString() === \"AVI \") return { valid: true, ext: \"avi\", mime: \"video/x-msvideo\" };\n if (match([0x00, 0x00, 0x01, 0xBA])) return { valid: true, ext: \"mpeg\", mime: \"video/mpeg\" };\n if (match([0x47, 0x40, 0x00, 0x10])) return { valid: true, ext: \"ts\", mime: \"video/MP2T\" };\n if (match([0x66, 0x74, 0x79, 0x70, 0x6D, 0x70, 0x34, 0x32])) return { valid: true, ext: \"mov\", mime: \"video/quicktime\" };\n\n // --- Archives ---\n if (match([0x50, 0x4B, 0x03, 0x04])) return { valid: true, ext: \"zip\", mime: \"application/zip\" };\n if (match([0x52, 0x61, 0x72, 0x21, 0x1A, 0x07, 0x00])) return { valid: true, ext: \"rar\", mime: \"application/x-rar-compressed\" };\n if (match([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C])) return { valid: true, ext: \"7z\", mime: \"application/x-7z-compressed\" };\n if (match([0x1F, 0x8B])) return { valid: true, ext: \"gz\", mime: \"application/gzip\" };\n if (match([0x42, 0x5A, 0x68])) return { valid: true, ext: \"bz2\", mime: \"application/x-bzip2\" };\n\n // --- Documents ---\n if (match([0x25, 0x50, 0x44, 0x46])) return { valid: true, ext: \"pdf\", mime: \"application/pdf\" };\n if (match([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1])) return { valid: true, ext: \"msi\", mime: \"application/vnd.ms-installer\" };\n if (match([0x4D, 0x5A])) return { valid: true, ext: \"exe\", mime: \"application/vnd.microsoft.portable-executable\" };\n if (match([0x09, 0x08, 0x10, 0x00])) return { valid: true, ext: \"doc\", mime: \"application/msword\" };\n if (match([0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05])) return { valid: true, ext: \"xls\", mime: \"application/vnd.ms-excel\" };\n if (match([0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1])) return { valid: true, ext: \"ppt\", mime: \"application/vnd.ms-powerpoint\" };\n if (match([0x50, 0x4B, 0x03, 0x04])) return { valid: true, ext: \"docx\", mime: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\" };\n\n // --- Fonts ---\n if (match([0x00, 0x01, 0x00, 0x00])) return { valid: true, ext: \"ttf\", mime: \"font/ttf\" };\n if (match([0x4F, 0x54, 0x54, 0x4F])) return { valid: true, ext: \"otf\", mime: \"font/otf\" };\n\n // --- Scripts / Binary ---\n if (match([0x23, 0x21])) return { valid: true, ext: \"sh\", mime: \"application/x-sh\" }; // shell script\n if (match([0x7F, 0x45, 0x4C, 0x46])) return { valid: true, ext: \"elf\", mime: \"application/x-elf\" }; // Linux executable\n\n // --- Others / fallback ---\n if (match([0x46, 0x4C, 0x56])) return { valid: true, ext: \"flv\", mime: \"video/x-flv\" };\n if (match([0x50, 0x4E, 0x44, 0x52])) return { valid: true, ext: \"pdf\", mime: \"application/pdf\" }; // alternate PDF\n if (match([0x42, 0x50, 0x47, 0x0D])) return { valid: true, ext: \"bpg\", mime: \"image/bpg\" }; // BPG\n\n}\n\nexport default fileScaner;"],"names":[],"mappings":"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"}
|