@cyberskill/shared 2.3.1 → 2.4.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/node/upload/index.cjs +1 -1
- package/dist/node/upload/index.d.ts +1 -0
- package/dist/node/upload/index.js +12 -5
- package/dist/node/upload/upload.constant.cjs +1 -0
- package/dist/node/upload/upload.constant.d.ts +1 -0
- package/dist/node/upload/upload.constant.js +4 -0
- package/dist/node/upload/upload.type.d.ts +8 -11
- package/dist/node/upload/upload.util.cjs +1 -1
- package/dist/node/upload/upload.util.d.ts +72 -5
- package/dist/node/upload/upload.util.js +120 -78
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./upload.constant.cjs"),a=require("./upload.type.cjs"),e=require("./upload.util.cjs");exports.BYTES_PER_MB=t.BYTES_PER_MB;Object.defineProperty(exports,"E_UploadType",{enumerable:!0,get:()=>a.E_UploadType});exports.createUploadConfig=e.createUploadConfig;exports.getAndValidateFile=e.getAndValidateFile;exports.getFileSizeFromStream=e.getFileSizeFromStream;exports.getFileWebStream=e.getFileWebStream;exports.upload=e.upload;exports.validateFileExtension=e.validateFileExtension;exports.validateUpload=e.validateUpload;
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { BYTES_PER_MB as o } from "./upload.constant.js";
|
|
2
|
+
import { E_UploadType as l } from "./upload.type.js";
|
|
3
|
+
import { createUploadConfig as r, getAndValidateFile as d, getFileSizeFromStream as p, getFileWebStream as m, upload as F, validateFileExtension as f, validateUpload as g } from "./upload.util.js";
|
|
3
4
|
export {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
o as BYTES_PER_MB,
|
|
6
|
+
l as E_UploadType,
|
|
7
|
+
r as createUploadConfig,
|
|
8
|
+
d as getAndValidateFile,
|
|
9
|
+
p as getFileSizeFromStream,
|
|
10
|
+
m as getFileWebStream,
|
|
11
|
+
F as upload,
|
|
12
|
+
f as validateFileExtension,
|
|
13
|
+
g as validateUpload
|
|
7
14
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=1024*1024;exports.BYTES_PER_MB=e;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const BYTES_PER_MB: number;
|
|
@@ -18,19 +18,16 @@ export interface I_UploadConfig {
|
|
|
18
18
|
[E_UploadType.DOCUMENT]: I_UploadTypeConfig;
|
|
19
19
|
[E_UploadType.OTHER]: I_UploadTypeConfig;
|
|
20
20
|
}
|
|
21
|
+
export interface I_UploadFileData {
|
|
22
|
+
createReadStream: () => NodeJS.ReadableStream;
|
|
23
|
+
filename: string;
|
|
24
|
+
}
|
|
25
|
+
export interface I_UploadFile {
|
|
26
|
+
file: I_UploadFileData;
|
|
27
|
+
}
|
|
21
28
|
export interface I_UploadOptions {
|
|
22
|
-
file: Promise<
|
|
23
|
-
file: {
|
|
24
|
-
createReadStream: () => NodeJS.ReadableStream;
|
|
25
|
-
filename: string;
|
|
26
|
-
};
|
|
27
|
-
}>;
|
|
29
|
+
file: Promise<I_UploadFile>;
|
|
28
30
|
path: string;
|
|
29
31
|
type: E_UploadType;
|
|
30
32
|
config?: I_UploadConfig;
|
|
31
33
|
}
|
|
32
|
-
export interface I_UploadResult {
|
|
33
|
-
success: boolean;
|
|
34
|
-
message: string;
|
|
35
|
-
result: string;
|
|
36
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const z=require("node:buffer"),C=require("node:stream"),x=require("node:stream/web"),A=require("./upload.constant.cjs"),c=require("./upload.type.cjs"),D=require("../path/path.util.cjs"),S=require("../fs/fs.util.cjs"),f=require("../../constant/response-status.cjs");var P=Object.defineProperty,v=Object.getOwnPropertySymbols,h=Object.prototype.hasOwnProperty,F=Object.prototype.propertyIsEnumerable,T=(r,t,e)=>t in r?P(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e,O=(r,t)=>{for(var e in t||(t={}))h.call(t,e)&&T(r,e,t[e]);if(v)for(var e of v(t))F.call(t,e)&&T(r,e,t[e]);return r},m=(r,t,e)=>new Promise((i,a)=>{var s=l=>{try{o(e.next(l))}catch(d){a(d)}},n=l=>{try{o(e.throw(l))}catch(d){a(d)}},o=l=>l.done?i(l.value):Promise.resolve(l.value).then(s,n);o((e=e.apply(r,t)).next())});function w(r){return m(this,null,function*(){return new Promise((t,e)=>{let i=0;r.on("data",a=>{i+=a.length}),r.on("end",()=>t(i)),r.on("error",e)})})}function _(r,t,e){return m(this,null,function*(){const i=yield(yield t).file,a=i.createReadStream(),s=yield w(a),n=e!=null?e:y(),o=U({filename:i.filename,fileSize:s},n,r);return o.isValid?{success:!0,result:i,message:"File validated successfully"}:{success:!1,message:o.error||"File validation failed",code:f.RESPONSE_STATUS.BAD_REQUEST.CODE}})}function L(r,t,e){return m(this,null,function*(){const a=(e!=null?e:y())[r],s=yield _(r,t,e);if(!s.success)return s;const{createReadStream:n}=s.result;let o=a.sizeLimit;const l=new C.Transform({transform(u,p,g){o-=u.length,o<0?g(new Error(`File size exceeds limit of ${a.sizeLimit/A.BYTES_PER_MB}MB`)):g(null,u)}}),E=n().pipe(l);return{success:!0,result:new x.ReadableStream({start(u){E.on("data",p=>{u.enqueue(typeof p=="string"?z.Buffer.from(p):p)}),E.on("end",()=>u.close()),E.on("error",p=>u.error(p))}})}})}function R(r,t){const e=r.lastIndexOf(".");if(e===-1)return!1;const i=r.substring(e+1).toLowerCase();return t.includes(i)}function U(r,t,e){const{filename:i,fileSize:a}=r,s=t[e],{allowedExtensions:n,sizeLimit:o}=s;if(!R(i,n))return{isValid:!1,error:`File extension not allowed for ${e.toLowerCase()} files. Allowed extensions: ${n.join(", ")}`};if(a!==void 0&&a>o){const l=Math.round(o/1048576);return{isValid:!1,error:`File size exceeds limit for ${e.toLowerCase()} files. Maximum size: ${l}MB`}}return{isValid:!0}}function y(r){const t={[c.E_UploadType.IMAGE]:{allowedExtensions:["jpg","jpeg","png","gif","webp","svg"],sizeLimit:5242880},[c.E_UploadType.VIDEO]:{allowedExtensions:["mp4","avi","mov","wmv","flv","webm"],sizeLimit:524288e3},[c.E_UploadType.DOCUMENT]:{allowedExtensions:["pdf","doc","docx","txt","rtf"],sizeLimit:10485760},[c.E_UploadType.OTHER]:{allowedExtensions:["zip","rar","tar","gz"],sizeLimit:5242880}};return O(O({},t),r)}function b(r){return m(this,null,function*(){const{path:t,file:e,config:i,type:a}=r;if(!t||typeof t!="string")return{success:!1,message:"Invalid path provided",code:f.RESPONSE_STATUS.BAD_REQUEST.CODE};if(!e||typeof e!="object")return{success:!1,message:"Invalid file provided",code:f.RESPONSE_STATUS.BAD_REQUEST.CODE};if(i){const s=[c.E_UploadType.IMAGE,c.E_UploadType.VIDEO,c.E_UploadType.DOCUMENT,c.E_UploadType.OTHER];for(const n of s){if(!i[n]||!Array.isArray(i[n].allowedExtensions)||i[n].allowedExtensions.length===0)return{success:!1,message:`Invalid config for ${n.toLowerCase()} files`,code:f.RESPONSE_STATUS.BAD_REQUEST.CODE};if(typeof i[n].sizeLimit!="number"||i[n].sizeLimit<=0)return{success:!1,message:`Invalid size limit for ${n.toLowerCase()} files`,code:f.RESPONSE_STATUS.BAD_REQUEST.CODE}}}try{const s=yield _(a,yield e,i);if(!s.success)return s;const{createReadStream:n}=s.result,o=D.dirname(t);S.pathExistsSync(o)||S.mkdirSync(o,{recursive:!0});const l=n(),d=S.createWriteStream(t);return l.pipe(d),yield new Promise((E,u)=>{d.on("finish",()=>E()),d.on("error",u),l.on("error",u)}),{success:!0,result:t,message:"File uploaded successfully",code:f.RESPONSE_STATUS.OK.CODE}}catch(s){return{success:!1,message:s instanceof Error?s.message:"File upload failed",code:f.RESPONSE_STATUS.INTERNAL_SERVER_ERROR.CODE}}})}exports.createUploadConfig=y;exports.getAndValidateFile=_;exports.getFileSizeFromStream=w;exports.getFileWebStream=L;exports.upload=b;exports.validateFileExtension=R;exports.validateUpload=U;
|
|
@@ -1,4 +1,71 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ReadableStream } from 'node:stream/web';
|
|
2
|
+
import { I_Return } from '../../typescript/index.js';
|
|
3
|
+
import { I_UploadConfig, I_UploadFile, I_UploadFileData, I_UploadOptions, I_UploadValidationConfig, E_UploadType } from './upload.type.js';
|
|
4
|
+
/**
|
|
5
|
+
* Calculates the size of a file from a readable stream.
|
|
6
|
+
* This function reads through the entire stream to determine the total byte size
|
|
7
|
+
* by accumulating the length of each data chunk.
|
|
8
|
+
*
|
|
9
|
+
* @param stream - The readable stream to calculate the size for.
|
|
10
|
+
* @returns A promise that resolves to the total size of the stream in bytes.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getFileSizeFromStream(stream: NodeJS.ReadableStream): Promise<number>;
|
|
13
|
+
/**
|
|
14
|
+
* Extracts and validates file data from an upload file.
|
|
15
|
+
* This function processes upload files by:
|
|
16
|
+
* - Extracting file metadata and creating a readable stream
|
|
17
|
+
* - Calculating the file size from the stream
|
|
18
|
+
* - Validating file size and extension against upload configuration
|
|
19
|
+
* - Returning a standardized response with success status and error codes
|
|
20
|
+
* - Providing validated file data for further processing
|
|
21
|
+
*
|
|
22
|
+
* @param type - The type of upload being processed (IMAGE, VIDEO, DOCUMENT, OTHER).
|
|
23
|
+
* @param file - The upload file object containing file metadata and stream creation method.
|
|
24
|
+
* @param config - Optional upload configuration. If not provided, uses default configuration.
|
|
25
|
+
* @returns A promise that resolves to a standardized response containing validated file data or error information.
|
|
26
|
+
*/
|
|
27
|
+
export declare function getAndValidateFile(type: E_UploadType, file: I_UploadFile, config?: I_UploadConfig): Promise<I_Return<I_UploadFileData>>;
|
|
28
|
+
/**
|
|
29
|
+
* Creates a validated web-readable stream from an upload file with size validation.
|
|
30
|
+
* This function processes file uploads for web environments by:
|
|
31
|
+
* - Validating file data using getAndValidateFile function
|
|
32
|
+
* - Creating a size validation transform stream to monitor upload progress
|
|
33
|
+
* - Returning a web-compatible ReadableStream with real-time validation
|
|
34
|
+
* - Providing standardized error responses for validation failures
|
|
35
|
+
* - Wrapping the stream in a standardized response format
|
|
36
|
+
*
|
|
37
|
+
* @param type - The type of upload being processed (IMAGE, VIDEO, DOCUMENT, OTHER).
|
|
38
|
+
* @param file - The upload file object containing file metadata and stream creation method.
|
|
39
|
+
* @param config - Optional upload configuration. If not provided, uses default configuration.
|
|
40
|
+
* @returns A promise that resolves to a standardized response containing either a web ReadableStream or error information.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getFileWebStream(type: E_UploadType, file: I_UploadFile, config?: I_UploadConfig): Promise<I_Return<ReadableStream<Uint8Array>>>;
|
|
43
|
+
/**
|
|
44
|
+
* Validates if a file has an allowed extension.
|
|
45
|
+
* This function extracts the file extension from the filename and checks if it's
|
|
46
|
+
* included in the list of allowed extensions (case-insensitive comparison).
|
|
47
|
+
*
|
|
48
|
+
* @param filename - The filename to check for valid extension.
|
|
49
|
+
* @param allowedExtensions - An array of allowed file extensions (without dots).
|
|
50
|
+
* @returns True if the file extension is allowed, false otherwise.
|
|
51
|
+
*/
|
|
52
|
+
export declare function validateFileExtension(filename: string, allowedExtensions: string[]): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Validates an upload against the specified configuration.
|
|
55
|
+
* This function performs comprehensive validation including:
|
|
56
|
+
* - File extension validation against allowed extensions
|
|
57
|
+
* - File size validation against size limits
|
|
58
|
+
* - Returns detailed error messages for validation failures
|
|
59
|
+
*
|
|
60
|
+
* @param config - The validation configuration including filename and optional file size.
|
|
61
|
+
* @param uploadConfig - The upload configuration containing allowed extensions and size limits.
|
|
62
|
+
* @param uploadType - The type of upload being validated.
|
|
63
|
+
* @returns An object indicating validation success and optional error message.
|
|
64
|
+
*/
|
|
65
|
+
export declare function validateUpload(config: I_UploadValidationConfig, uploadConfig: I_UploadConfig, uploadType: E_UploadType): {
|
|
66
|
+
isValid: boolean;
|
|
67
|
+
error?: string;
|
|
68
|
+
};
|
|
2
69
|
/**
|
|
3
70
|
* Creates a default upload configuration with predefined settings for different file types.
|
|
4
71
|
* This function provides sensible defaults for image, video, document, and other file types,
|
|
@@ -13,12 +80,12 @@ export declare function createUploadConfig(overrides?: Partial<I_UploadConfig>):
|
|
|
13
80
|
* This function processes file uploads with the following features:
|
|
14
81
|
* - Input validation for path and file parameters
|
|
15
82
|
* - Configuration validation for all upload types
|
|
16
|
-
* - File
|
|
83
|
+
* - File validation using getAndValidateFile function
|
|
17
84
|
* - Automatic directory creation
|
|
18
85
|
* - Stream-based file writing
|
|
19
|
-
* - Comprehensive error handling
|
|
86
|
+
* - Comprehensive error handling with standardized response codes
|
|
20
87
|
*
|
|
21
88
|
* @param options - Upload configuration including file, path, type, and optional validation config.
|
|
22
|
-
* @returns A promise that resolves to
|
|
89
|
+
* @returns A promise that resolves to a standardized response with success status, message, file path, and response codes.
|
|
23
90
|
*/
|
|
24
|
-
export declare function upload(options: I_UploadOptions): Promise<
|
|
91
|
+
export declare function upload(options: I_UploadOptions): Promise<I_Return<string>>;
|
|
@@ -1,154 +1,196 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { Buffer as O } from "node:buffer";
|
|
2
|
+
import { Transform as x } from "node:stream";
|
|
3
|
+
import { ReadableStream as z } from "node:stream/web";
|
|
4
|
+
import { BYTES_PER_MB as C } from "./upload.constant.js";
|
|
5
|
+
import { E_UploadType as u } from "./upload.type.js";
|
|
6
|
+
import { dirname as D } from "../path/path.util.js";
|
|
7
|
+
import { pathExistsSync as R, mkdirSync as h, createWriteStream as L } from "../fs/fs.util.js";
|
|
8
|
+
import { RESPONSE_STATUS as d } from "../../constant/response-status.js";
|
|
9
|
+
var T = Object.defineProperty, v = Object.getOwnPropertySymbols, A = Object.prototype.hasOwnProperty, I = Object.prototype.propertyIsEnumerable, y = (t, r, e) => r in t ? T(t, r, { enumerable: !0, configurable: !0, writable: !0, value: e }) : t[r] = e, S = (t, r) => {
|
|
5
10
|
for (var e in r || (r = {}))
|
|
6
|
-
|
|
11
|
+
A.call(r, e) && y(t, e, r[e]);
|
|
7
12
|
if (v)
|
|
8
13
|
for (var e of v(r))
|
|
9
|
-
I.call(r, e) &&
|
|
10
|
-
return
|
|
11
|
-
},
|
|
12
|
-
var
|
|
14
|
+
I.call(r, e) && y(t, e, r[e]);
|
|
15
|
+
return t;
|
|
16
|
+
}, E = (t, r, e) => new Promise((i, a) => {
|
|
17
|
+
var s = (l) => {
|
|
13
18
|
try {
|
|
14
|
-
|
|
19
|
+
n(e.next(l));
|
|
15
20
|
} catch (c) {
|
|
16
|
-
|
|
21
|
+
a(c);
|
|
17
22
|
}
|
|
18
|
-
},
|
|
23
|
+
}, o = (l) => {
|
|
19
24
|
try {
|
|
20
|
-
|
|
25
|
+
n(e.throw(l));
|
|
21
26
|
} catch (c) {
|
|
22
|
-
|
|
27
|
+
a(c);
|
|
23
28
|
}
|
|
24
|
-
},
|
|
25
|
-
|
|
29
|
+
}, n = (l) => l.done ? i(l.value) : Promise.resolve(l.value).then(s, o);
|
|
30
|
+
n((e = e.apply(t, r)).next());
|
|
26
31
|
});
|
|
27
|
-
function
|
|
28
|
-
return
|
|
32
|
+
function P(t) {
|
|
33
|
+
return E(this, null, function* () {
|
|
29
34
|
return new Promise((r, e) => {
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}),
|
|
35
|
+
let i = 0;
|
|
36
|
+
t.on("data", (a) => {
|
|
37
|
+
i += a.length;
|
|
38
|
+
}), t.on("end", () => r(i)), t.on("error", e);
|
|
34
39
|
});
|
|
35
40
|
});
|
|
36
41
|
}
|
|
37
|
-
function
|
|
38
|
-
|
|
42
|
+
function w(t, r, e) {
|
|
43
|
+
return E(this, null, function* () {
|
|
44
|
+
const i = yield (yield r).file, a = i.createReadStream(), s = yield P(a), o = e != null ? e : _(), n = F(
|
|
45
|
+
{ filename: i.filename, fileSize: s },
|
|
46
|
+
o,
|
|
47
|
+
t
|
|
48
|
+
);
|
|
49
|
+
return n.isValid ? {
|
|
50
|
+
success: !0,
|
|
51
|
+
result: i,
|
|
52
|
+
message: "File validated successfully"
|
|
53
|
+
} : {
|
|
54
|
+
success: !1,
|
|
55
|
+
message: n.error || "File validation failed",
|
|
56
|
+
code: d.BAD_REQUEST.CODE
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function q(t, r, e) {
|
|
61
|
+
return E(this, null, function* () {
|
|
62
|
+
const a = (e != null ? e : _())[t], s = yield w(t, r, e);
|
|
63
|
+
if (!s.success)
|
|
64
|
+
return s;
|
|
65
|
+
const { createReadStream: o } = s.result;
|
|
66
|
+
let n = a.sizeLimit;
|
|
67
|
+
const l = new x({
|
|
68
|
+
transform(f, m, g) {
|
|
69
|
+
n -= f.length, n < 0 ? g(new Error(`File size exceeds limit of ${a.sizeLimit / C}MB`)) : g(null, f);
|
|
70
|
+
}
|
|
71
|
+
}), p = o().pipe(l);
|
|
72
|
+
return {
|
|
73
|
+
success: !0,
|
|
74
|
+
result: new z({
|
|
75
|
+
start(f) {
|
|
76
|
+
p.on("data", (m) => {
|
|
77
|
+
f.enqueue(typeof m == "string" ? O.from(m) : m);
|
|
78
|
+
}), p.on("end", () => f.close()), p.on("error", (m) => f.error(m));
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function B(t, r) {
|
|
85
|
+
const e = t.lastIndexOf(".");
|
|
39
86
|
if (e === -1)
|
|
40
87
|
return !1;
|
|
41
|
-
const
|
|
42
|
-
return r.includes(
|
|
88
|
+
const i = t.substring(e + 1).toLowerCase();
|
|
89
|
+
return r.includes(i);
|
|
43
90
|
}
|
|
44
|
-
function
|
|
45
|
-
const { filename:
|
|
46
|
-
if (!
|
|
91
|
+
function F(t, r, e) {
|
|
92
|
+
const { filename: i, fileSize: a } = t, s = r[e], { allowedExtensions: o, sizeLimit: n } = s;
|
|
93
|
+
if (!B(i, o))
|
|
47
94
|
return {
|
|
48
95
|
isValid: !1,
|
|
49
|
-
error: `File extension not allowed for ${e.toLowerCase()} files. Allowed extensions: ${
|
|
96
|
+
error: `File extension not allowed for ${e.toLowerCase()} files. Allowed extensions: ${o.join(", ")}`
|
|
50
97
|
};
|
|
51
|
-
if (
|
|
52
|
-
const
|
|
98
|
+
if (a !== void 0 && a > n) {
|
|
99
|
+
const l = Math.round(n / 1048576);
|
|
53
100
|
return {
|
|
54
101
|
isValid: !1,
|
|
55
|
-
error: `File size exceeds limit for ${e.toLowerCase()} files. Maximum size: ${
|
|
102
|
+
error: `File size exceeds limit for ${e.toLowerCase()} files. Maximum size: ${l}MB`
|
|
56
103
|
};
|
|
57
104
|
}
|
|
58
105
|
return { isValid: !0 };
|
|
59
106
|
}
|
|
60
|
-
function
|
|
107
|
+
function _(t) {
|
|
61
108
|
const r = {
|
|
62
|
-
[
|
|
109
|
+
[u.IMAGE]: {
|
|
63
110
|
allowedExtensions: ["jpg", "jpeg", "png", "gif", "webp", "svg"],
|
|
64
111
|
sizeLimit: 5242880
|
|
65
112
|
// 5MB
|
|
66
113
|
},
|
|
67
|
-
[
|
|
114
|
+
[u.VIDEO]: {
|
|
68
115
|
allowedExtensions: ["mp4", "avi", "mov", "wmv", "flv", "webm"],
|
|
69
116
|
sizeLimit: 524288e3
|
|
70
117
|
// 500MB
|
|
71
118
|
},
|
|
72
|
-
[
|
|
119
|
+
[u.DOCUMENT]: {
|
|
73
120
|
allowedExtensions: ["pdf", "doc", "docx", "txt", "rtf"],
|
|
74
121
|
sizeLimit: 10485760
|
|
75
122
|
// 10MB
|
|
76
123
|
},
|
|
77
|
-
[
|
|
124
|
+
[u.OTHER]: {
|
|
78
125
|
allowedExtensions: ["zip", "rar", "tar", "gz"],
|
|
79
126
|
sizeLimit: 5242880
|
|
80
127
|
// 5MB
|
|
81
128
|
}
|
|
82
129
|
};
|
|
83
|
-
return
|
|
130
|
+
return S(S({}, r), t);
|
|
84
131
|
}
|
|
85
|
-
function
|
|
86
|
-
return
|
|
87
|
-
const { path: r, file: e, config:
|
|
132
|
+
function G(t) {
|
|
133
|
+
return E(this, null, function* () {
|
|
134
|
+
const { path: r, file: e, config: i, type: a } = t;
|
|
88
135
|
if (!r || typeof r != "string")
|
|
89
136
|
return {
|
|
90
137
|
success: !1,
|
|
91
138
|
message: "Invalid path provided",
|
|
92
|
-
|
|
139
|
+
code: d.BAD_REQUEST.CODE
|
|
93
140
|
};
|
|
94
141
|
if (!e || typeof e != "object")
|
|
95
142
|
return {
|
|
96
143
|
success: !1,
|
|
97
144
|
message: "Invalid file provided",
|
|
98
|
-
|
|
145
|
+
code: d.BAD_REQUEST.CODE
|
|
99
146
|
};
|
|
100
|
-
if (
|
|
101
|
-
const
|
|
102
|
-
for (const
|
|
103
|
-
if (!
|
|
147
|
+
if (i) {
|
|
148
|
+
const s = [u.IMAGE, u.VIDEO, u.DOCUMENT, u.OTHER];
|
|
149
|
+
for (const o of s) {
|
|
150
|
+
if (!i[o] || !Array.isArray(i[o].allowedExtensions) || i[o].allowedExtensions.length === 0)
|
|
104
151
|
return {
|
|
105
152
|
success: !1,
|
|
106
|
-
message: `Invalid config for ${
|
|
107
|
-
|
|
153
|
+
message: `Invalid config for ${o.toLowerCase()} files`,
|
|
154
|
+
code: d.BAD_REQUEST.CODE
|
|
108
155
|
};
|
|
109
|
-
if (typeof
|
|
156
|
+
if (typeof i[o].sizeLimit != "number" || i[o].sizeLimit <= 0)
|
|
110
157
|
return {
|
|
111
158
|
success: !1,
|
|
112
|
-
message: `Invalid size limit for ${
|
|
113
|
-
|
|
159
|
+
message: `Invalid size limit for ${o.toLowerCase()} files`,
|
|
160
|
+
code: d.BAD_REQUEST.CODE
|
|
114
161
|
};
|
|
115
162
|
}
|
|
116
163
|
}
|
|
117
164
|
try {
|
|
118
|
-
const
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return {
|
|
127
|
-
success: !1,
|
|
128
|
-
message: p.error || "File validation failed",
|
|
129
|
-
result: ""
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
const o = E(r);
|
|
133
|
-
x(o) || z(o, { recursive: !0 });
|
|
134
|
-
const c = a(), d = h(r);
|
|
135
|
-
return c.pipe(d), yield new Promise((m, u) => {
|
|
136
|
-
d.on("finish", () => m()), d.on("error", u), c.on("error", u);
|
|
165
|
+
const s = yield w(a, yield e, i);
|
|
166
|
+
if (!s.success)
|
|
167
|
+
return s;
|
|
168
|
+
const { createReadStream: o } = s.result, n = D(r);
|
|
169
|
+
R(n) || h(n, { recursive: !0 });
|
|
170
|
+
const l = o(), c = L(r);
|
|
171
|
+
return l.pipe(c), yield new Promise((p, f) => {
|
|
172
|
+
c.on("finish", () => p()), c.on("error", f), l.on("error", f);
|
|
137
173
|
}), {
|
|
138
174
|
success: !0,
|
|
175
|
+
result: r,
|
|
139
176
|
message: "File uploaded successfully",
|
|
140
|
-
|
|
177
|
+
code: d.OK.CODE
|
|
141
178
|
};
|
|
142
|
-
} catch (
|
|
179
|
+
} catch (s) {
|
|
143
180
|
return {
|
|
144
181
|
success: !1,
|
|
145
|
-
message:
|
|
146
|
-
|
|
182
|
+
message: s instanceof Error ? s.message : "File upload failed",
|
|
183
|
+
code: d.INTERNAL_SERVER_ERROR.CODE
|
|
147
184
|
};
|
|
148
185
|
}
|
|
149
186
|
});
|
|
150
187
|
}
|
|
151
188
|
export {
|
|
152
|
-
|
|
153
|
-
|
|
189
|
+
_ as createUploadConfig,
|
|
190
|
+
w as getAndValidateFile,
|
|
191
|
+
P as getFileSizeFromStream,
|
|
192
|
+
q as getFileWebStream,
|
|
193
|
+
G as upload,
|
|
194
|
+
B as validateFileExtension,
|
|
195
|
+
F as validateUpload
|
|
154
196
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyberskill/shared",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.4.0",
|
|
5
5
|
"description": "CyberSkill Shared",
|
|
6
6
|
"author": "Stephen Cheng",
|
|
7
7
|
"license": "MIT",
|
|
@@ -272,7 +272,7 @@
|
|
|
272
272
|
"@commitlint/config-conventional": "19.8.1",
|
|
273
273
|
"@eslint/config-inspector": "1.1.0",
|
|
274
274
|
"@next/eslint-plugin-next": "15.4.4",
|
|
275
|
-
"@testing-library/jest-dom": "6.6.
|
|
275
|
+
"@testing-library/jest-dom": "6.6.4",
|
|
276
276
|
"@testing-library/react": "16.3.0",
|
|
277
277
|
"@types/apollo-upload-client": "18.0.0",
|
|
278
278
|
"@types/body-parser": "1.19.6",
|