@cyberskill/shared 2.27.0 → 3.0.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/config/config.util.cjs +1 -1
- package/dist/config/config.util.js +24 -33
- package/dist/config/eslint/index.cjs +1 -1
- package/dist/config/eslint/index.d.ts +6 -0
- package/dist/config/eslint/index.js +4 -12
- package/dist/config/graphql-codegen/graphql-codegen.util.cjs +1 -1
- package/dist/config/graphql-codegen/graphql-codegen.util.js +28 -33
- package/dist/config/storybook/storybook.preview.cjs +1 -1
- package/dist/config/storybook/storybook.preview.js +10 -13
- package/dist/config/vitest/vitest.e2e.cjs +1 -1
- package/dist/config/vitest/vitest.e2e.js +1 -1
- package/dist/config/vitest/vitest.unit.cjs +1 -1
- package/dist/config/vitest/vitest.unit.js +19 -8
- package/dist/constant/common.cjs +1 -1
- package/dist/constant/common.js +1 -1
- package/dist/node/apollo-server/apollo-server.util.cjs +1 -1
- package/dist/node/apollo-server/apollo-server.util.js +21 -48
- package/dist/node/cli/index.cjs +2 -5
- package/dist/node/cli/index.js +109 -170
- package/dist/node/command/command.util.cjs +2 -2
- package/dist/node/command/command.util.js +135 -170
- package/dist/node/express/express.util.cjs +1 -1
- package/dist/node/express/express.util.js +39 -72
- package/dist/node/fs/fs.util.cjs +4 -1
- package/dist/node/fs/fs.util.d.ts +8 -0
- package/dist/node/fs/fs.util.js +46 -53
- package/dist/node/fs/index.cjs +1 -1
- package/dist/node/fs/index.js +13 -12
- package/dist/node/log/log.util.cjs +1 -1
- package/dist/node/log/log.util.js +29 -30
- package/dist/node/mongo/mongo.controller.cjs +1 -1
- package/dist/node/mongo/mongo.controller.js +531 -629
- package/dist/node/mongo/mongo.type.js +3 -3
- package/dist/node/mongo/mongo.util.cjs +2 -5
- package/dist/node/mongo/mongo.util.js +308 -354
- package/dist/node/package/package.util.cjs +1 -1
- package/dist/node/package/package.util.js +197 -226
- package/dist/node/path/index.cjs +1 -1
- package/dist/node/path/index.js +26 -25
- package/dist/node/path/path.constant.cjs +1 -1
- package/dist/node/path/path.constant.d.ts +2 -0
- package/dist/node/path/path.constant.js +130 -150
- package/dist/node/storage/storage.util.cjs +1 -1
- package/dist/node/storage/storage.util.js +110 -158
- package/dist/node/upload/upload.util.cjs +1 -1
- package/dist/node/upload/upload.util.js +119 -150
- package/dist/node/ws/ts.util.cjs +1 -1
- package/dist/node/ws/ts.util.js +31 -54
- package/dist/react/apollo-client/apollo-client.component.cjs +1 -1
- package/dist/react/apollo-client/apollo-client.component.js +4 -4
- package/dist/react/apollo-client/apollo-client.util.cjs +1 -1
- package/dist/react/apollo-client/apollo-client.util.js +51 -58
- package/dist/react/apollo-client/links/upload.cjs +1 -1
- package/dist/react/apollo-client/links/upload.js +71 -74
- package/dist/react/apollo-client-nextjs/apollo-client-nextjs.util.cjs +1 -1
- package/dist/react/apollo-client-nextjs/apollo-client-nextjs.util.js +11 -18
- package/dist/react/apollo-error/apollo-error.component.cjs +1 -1
- package/dist/react/apollo-error/apollo-error.component.js +61 -23
- package/dist/react/apollo-error/apollo-error.module.scss.cjs +1 -1
- package/dist/react/apollo-error/apollo-error.module.scss.js +6 -6
- package/dist/react/apollo-error/apollo-error.test.unit.d.ts +1 -0
- package/dist/react/apollo-error/apollo-error.util.cjs +1 -1
- package/dist/react/apollo-error/apollo-error.util.js +6 -6
- package/dist/react/loading/loading.component.cjs +2 -2
- package/dist/react/loading/loading.component.js +30 -46
- package/dist/react/log/log.util.cjs +1 -1
- package/dist/react/log/log.util.js +4 -4
- package/dist/react/next-intl/next-intl.hoc.cjs +1 -1
- package/dist/react/next-intl/next-intl.hoc.js +13 -22
- package/dist/react/next-intl/next-intl.provider.cjs +1 -1
- package/dist/react/next-intl/next-intl.provider.js +7 -7
- package/dist/react/storage/storage.hook.cjs +1 -1
- package/dist/react/storage/storage.hook.js +43 -59
- package/dist/react/storage/storage.util.cjs +1 -1
- package/dist/react/storage/storage.util.js +28 -53
- package/dist/react/userback/userback.component.cjs +1 -1
- package/dist/react/userback/userback.component.js +18 -42
- package/dist/style.css +1 -1
- package/dist/util/common/common.util.cjs +1 -1
- package/dist/util/common/common.util.d.ts +11 -0
- package/dist/util/common/common.util.js +33 -37
- package/dist/util/common/index.cjs +1 -1
- package/dist/util/common/index.js +6 -5
- package/dist/util/index.cjs +1 -1
- package/dist/util/index.js +22 -20
- package/dist/util/object/object.util.cjs +1 -1
- package/dist/util/object/object.util.js +70 -70
- package/dist/util/string/index.cjs +1 -1
- package/dist/util/string/index.js +4 -3
- package/dist/util/string/string.util.cjs +1 -1
- package/dist/util/string/string.util.d.ts +12 -0
- package/dist/util/string/string.util.js +63 -44
- package/package.json +53 -44
- package/public/tsconfig.base.json +7 -3
- package/README.md +0 -470
- package/dist/node/mongo/mongo.util.d.ts +0 -1040
- /package/dist/node_modules/.pnpm/{vitest@4.0.17_@types_node@25.0.9_jiti@2.6.1_jsdom@27.4.0_@noble_hashes@1.8.0__sass@1.97.2_tsx@4.21.0_yaml@2.8.2 → vitest@4.0.18_@types_node@25.3.3_jiti@2.6.1_jsdom@28.1.0_@noble_hashes@1.8.0__sass@1.97.3_tsx@4.21.0_yaml@2.8.2}/node_modules/vitest/dist/config.cjs +0 -0
- /package/dist/node_modules/.pnpm/{vitest@4.0.17_@types_node@25.0.9_jiti@2.6.1_jsdom@27.4.0_@noble_hashes@1.8.0__sass@1.97.2_tsx@4.21.0_yaml@2.8.2 → vitest@4.0.18_@types_node@25.3.3_jiti@2.6.1_jsdom@28.1.0_@noble_hashes@1.8.0__sass@1.97.3_tsx@4.21.0_yaml@2.8.2}/node_modules/vitest/dist/config.js +0 -0
|
@@ -1,143 +1,106 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { STORAGE_KEY_EXTENSION as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
try {
|
|
10
|
-
m(t.next(u));
|
|
11
|
-
} catch (v) {
|
|
12
|
-
d(v);
|
|
13
|
-
}
|
|
14
|
-
}, O = (u) => {
|
|
15
|
-
try {
|
|
16
|
-
m(t.throw(u));
|
|
17
|
-
} catch (v) {
|
|
18
|
-
d(v);
|
|
19
|
-
}
|
|
20
|
-
}, m = (u) => u.done ? i(u.value) : Promise.resolve(u.value).then(y, O);
|
|
21
|
-
m((t = t.apply(e, r)).next());
|
|
22
|
-
});
|
|
23
|
-
const h = N(), o = {
|
|
24
|
-
baseDir: h.CYBERSKILL_STORAGE_DIRECTORY
|
|
1
|
+
import w from "localforage";
|
|
2
|
+
import i from "node:fs/promises";
|
|
3
|
+
import E from "node:path";
|
|
4
|
+
import { STORAGE_KEY_EXTENSION as d, NODE_FS_DRIVER_NAME as v, STORAGE_STORE_NAME as R, STORAGE_INSTANCE_NAME as I } from "./storage.constant.js";
|
|
5
|
+
import { catchError as s, log as h } from "../log/log.util.js";
|
|
6
|
+
import { getEnv as S } from "../../config/env/env.util.js";
|
|
7
|
+
const l = S(), a = {
|
|
8
|
+
baseDir: l.CYBERSKILL_STORAGE_DIRECTORY
|
|
25
9
|
};
|
|
26
|
-
function
|
|
27
|
-
return `${encodeURIComponent(
|
|
10
|
+
function g(r) {
|
|
11
|
+
return `${encodeURIComponent(r)}${d}`;
|
|
28
12
|
}
|
|
29
|
-
function
|
|
30
|
-
return decodeURIComponent(
|
|
13
|
+
function _(r) {
|
|
14
|
+
return decodeURIComponent(r.slice(0, -d.length));
|
|
31
15
|
}
|
|
32
|
-
function
|
|
33
|
-
return
|
|
16
|
+
function y(r, e) {
|
|
17
|
+
return E.join(e, g(r));
|
|
34
18
|
}
|
|
35
|
-
const
|
|
36
|
-
_driver:
|
|
19
|
+
const c = {
|
|
20
|
+
_driver: v,
|
|
37
21
|
_support: !0,
|
|
38
22
|
/** Ensures the storage directory exists and respects custom baseDir overrides. */
|
|
39
|
-
_initStorage(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
});
|
|
23
|
+
async _initStorage(r) {
|
|
24
|
+
try {
|
|
25
|
+
const e = typeof r == "object" && r !== null && "baseDir" in r ? r.baseDir : void 0;
|
|
26
|
+
typeof e == "string" && e.length > 0 ? a.baseDir = e : a.baseDir = l.CYBERSKILL_STORAGE_DIRECTORY, await i.mkdir(a.baseDir, { recursive: !0 });
|
|
27
|
+
} catch (e) {
|
|
28
|
+
throw h.error("[Storage:init]", e), e;
|
|
29
|
+
}
|
|
48
30
|
},
|
|
49
31
|
/** Deletes all stored entries by recreating the directory. */
|
|
50
|
-
clear() {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
yield l.rm(e, { recursive: !0, force: !0 }), yield l.mkdir(e, { recursive: !0 });
|
|
54
|
-
});
|
|
32
|
+
async clear() {
|
|
33
|
+
const { baseDir: r } = a;
|
|
34
|
+
await i.rm(r, { recursive: !0, force: !0 }), await i.mkdir(r, { recursive: !0 });
|
|
55
35
|
},
|
|
56
36
|
/** Reads and parses a stored value; returns null when the file is missing. */
|
|
57
|
-
getItem(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
});
|
|
37
|
+
async getItem(r) {
|
|
38
|
+
const { baseDir: e } = a, t = y(r, e);
|
|
39
|
+
try {
|
|
40
|
+
const n = await i.readFile(t, "utf8");
|
|
41
|
+
return JSON.parse(n);
|
|
42
|
+
} catch (n) {
|
|
43
|
+
if (n.code === "ENOENT")
|
|
44
|
+
return null;
|
|
45
|
+
throw n;
|
|
46
|
+
}
|
|
69
47
|
},
|
|
70
48
|
/** Iterates through all keys, invoking the iterator until it returns a value. */
|
|
71
|
-
iterate(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
});
|
|
49
|
+
async iterate(r) {
|
|
50
|
+
const e = await c.keys();
|
|
51
|
+
let t = 1;
|
|
52
|
+
for (const n of e) {
|
|
53
|
+
const D = await c.getItem(n), f = r(D, n, t);
|
|
54
|
+
if (f !== void 0)
|
|
55
|
+
return f;
|
|
56
|
+
t += 1;
|
|
57
|
+
}
|
|
82
58
|
},
|
|
83
59
|
/** Returns the key name at the given index or null when out of bounds. */
|
|
84
|
-
key(
|
|
85
|
-
return
|
|
86
|
-
var r;
|
|
87
|
-
return (r = (yield a.keys())[e]) != null ? r : null;
|
|
88
|
-
});
|
|
60
|
+
async key(r) {
|
|
61
|
+
return (await c.keys())[r] ?? null;
|
|
89
62
|
},
|
|
90
63
|
/** Lists all stored keys. */
|
|
91
|
-
keys() {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
});
|
|
64
|
+
async keys() {
|
|
65
|
+
const { baseDir: r } = a;
|
|
66
|
+
try {
|
|
67
|
+
return (await i.readdir(r)).filter((t) => t.endsWith(d)).map(_);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
if (e.code === "ENOENT")
|
|
70
|
+
return [];
|
|
71
|
+
throw e;
|
|
72
|
+
}
|
|
102
73
|
},
|
|
103
74
|
/** Returns the count of stored keys. */
|
|
104
|
-
length() {
|
|
105
|
-
return
|
|
106
|
-
return (yield a.keys()).length;
|
|
107
|
-
});
|
|
75
|
+
async length() {
|
|
76
|
+
return (await c.keys()).length;
|
|
108
77
|
},
|
|
109
78
|
/** Removes a stored value for the given key. */
|
|
110
|
-
removeItem(
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
yield l.rm(t, { force: !0 });
|
|
114
|
-
});
|
|
79
|
+
async removeItem(r) {
|
|
80
|
+
const { baseDir: e } = a, t = y(r, e);
|
|
81
|
+
await i.rm(t, { force: !0 });
|
|
115
82
|
},
|
|
116
83
|
/** Stores a value as JSON on disk. */
|
|
117
|
-
setItem(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return yield l.mkdir(t, { recursive: !0 }), yield l.writeFile(i, JSON.stringify(r), "utf8"), r;
|
|
121
|
-
});
|
|
84
|
+
async setItem(r, e) {
|
|
85
|
+
const { baseDir: t } = a, n = y(r, t);
|
|
86
|
+
return await i.mkdir(t, { recursive: !0 }), await i.writeFile(n, JSON.stringify(e), "utf8"), e;
|
|
122
87
|
}
|
|
123
88
|
};
|
|
124
|
-
let
|
|
125
|
-
function
|
|
126
|
-
return
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}), yield c, D);
|
|
138
|
-
});
|
|
89
|
+
let o = null, m = null;
|
|
90
|
+
async function u() {
|
|
91
|
+
return o ? (await o, m) : (o = (async () => {
|
|
92
|
+
await w.defineDriver(c), a.baseDir = l.CYBERSKILL_STORAGE_DIRECTORY;
|
|
93
|
+
const r = await w.getDriver(v), e = {
|
|
94
|
+
baseDir: a.baseDir,
|
|
95
|
+
name: I,
|
|
96
|
+
storeName: R
|
|
97
|
+
};
|
|
98
|
+
await r._initStorage(e), m = r;
|
|
99
|
+
})().catch((r) => {
|
|
100
|
+
throw o = null, r;
|
|
101
|
+
}), await o, m);
|
|
139
102
|
}
|
|
140
|
-
const
|
|
103
|
+
const A = {
|
|
141
104
|
/**
|
|
142
105
|
* Retrieves a value from persistent storage by key.
|
|
143
106
|
* This method fetches data that was previously stored using the set method.
|
|
@@ -146,15 +109,12 @@ const w = {
|
|
|
146
109
|
* @param key - The unique identifier for the stored value.
|
|
147
110
|
* @returns A promise that resolves to the stored value or null if not found.
|
|
148
111
|
*/
|
|
149
|
-
get(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return s(r, { returnValue: null });
|
|
156
|
-
}
|
|
157
|
-
});
|
|
112
|
+
async get(r) {
|
|
113
|
+
try {
|
|
114
|
+
return await (await u()).getItem(r) ?? null;
|
|
115
|
+
} catch (e) {
|
|
116
|
+
return s(e, { returnValue: null });
|
|
117
|
+
}
|
|
158
118
|
},
|
|
159
119
|
/**
|
|
160
120
|
* Stores a value in persistent storage with a unique key.
|
|
@@ -165,14 +125,12 @@ const w = {
|
|
|
165
125
|
* @param value - The data to store (will be automatically serialized).
|
|
166
126
|
* @returns A promise that resolves when the storage operation is complete.
|
|
167
127
|
*/
|
|
168
|
-
set(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
});
|
|
128
|
+
async set(r, e) {
|
|
129
|
+
try {
|
|
130
|
+
await (await u()).setItem(r, e);
|
|
131
|
+
} catch (t) {
|
|
132
|
+
s(t);
|
|
133
|
+
}
|
|
176
134
|
},
|
|
177
135
|
/**
|
|
178
136
|
* Removes a value from persistent storage by key.
|
|
@@ -181,14 +139,12 @@ const w = {
|
|
|
181
139
|
* @param key - The unique identifier of the value to remove.
|
|
182
140
|
* @returns A promise that resolves when the removal operation is complete.
|
|
183
141
|
*/
|
|
184
|
-
remove(
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
});
|
|
142
|
+
async remove(r) {
|
|
143
|
+
try {
|
|
144
|
+
await (await u()).removeItem(r);
|
|
145
|
+
} catch (e) {
|
|
146
|
+
s(e);
|
|
147
|
+
}
|
|
192
148
|
},
|
|
193
149
|
/**
|
|
194
150
|
* Retrieves all storage keys.
|
|
@@ -197,15 +153,13 @@ const w = {
|
|
|
197
153
|
*
|
|
198
154
|
* @returns A promise that resolves to an array of storage keys.
|
|
199
155
|
*/
|
|
200
|
-
keys() {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
});
|
|
156
|
+
async keys() {
|
|
157
|
+
try {
|
|
158
|
+
const e = await (await u()).keys();
|
|
159
|
+
return Array.isArray(e) ? e : (h.warn("[Storage:keys] Invalid keys response:", e), []);
|
|
160
|
+
} catch (r) {
|
|
161
|
+
return s(r, { returnValue: [] });
|
|
162
|
+
}
|
|
209
163
|
},
|
|
210
164
|
/**
|
|
211
165
|
* Gets a human-readable log link for a storage key.
|
|
@@ -215,16 +169,14 @@ const w = {
|
|
|
215
169
|
* @param key - The storage key to generate a log link for.
|
|
216
170
|
* @returns A promise that resolves to a formatted log link string or null if an error occurs.
|
|
217
171
|
*/
|
|
218
|
-
getLogLink(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
});
|
|
172
|
+
async getLogLink(r) {
|
|
173
|
+
try {
|
|
174
|
+
return `${E.join(l.CYBERSKILL_STORAGE_DIRECTORY, g(r))} (key: ${r})`;
|
|
175
|
+
} catch (e) {
|
|
176
|
+
return s(e, { returnValue: null });
|
|
177
|
+
}
|
|
226
178
|
}
|
|
227
179
|
};
|
|
228
180
|
export {
|
|
229
|
-
|
|
181
|
+
A as storage
|
|
230
182
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const O=require("node:buffer"),U=require("node:stream"),A=require("node:stream/web"),_=require("./upload.constant.cjs"),E=require("./upload.type.cjs"),C=require("../path/path.util.cjs"),m=require("../fs/fs.util.cjs"),c=require("../../constant/response-status.cjs");async function y(t){return new Promise((a,i)=>{let e=0;t.on("data",o=>{e+=o.length}),t.on("end",()=>a(e)),t.on("error",i)})}async function p(t,a,i){const e=await(await a).file,o=e.createReadStream(),s=await y(o),r=i??g(),n=w({filename:e.filename,fileSize:s},r,t);return n.isValid?{success:!0,result:e,message:"File validated successfully"}:{success:!1,message:n.error||"File validation failed",code:c.RESPONSE_STATUS.BAD_REQUEST.CODE}}async function D(t,a,i){const o=(i??g())[t],s=await p(t,a,i);if(!s.success)return s;const{createReadStream:r}=s.result;let n=o.sizeLimit;const u=new U.Transform({transform(l,d,T){n-=l.length,n<0?T(new Error(`File size exceeds limit of ${o.sizeLimit/_.BYTES_PER_MB}MB`)):T(null,l)}}),f=r().pipe(u);return{success:!0,result:new A.ReadableStream({start(l){f.on("data",d=>{l.enqueue(typeof d=="string"?O.Buffer.from(d):d)}),f.on("end",()=>l.close()),f.on("error",d=>l.error(d))}})}}function R(t,a){const i=t.lastIndexOf(".");if(i===-1)return!1;const e=t.substring(i+1).toLowerCase();return a.includes(e)}function w(t,a,i){const{filename:e,fileSize:o}=t,s=a[i],{allowedExtensions:r,sizeLimit:n}=s;if(!R(e,r))return{isValid:!1,error:`File extension not allowed for ${i.toLowerCase()} files. Allowed extensions: ${r.join(", ")}`};if(o!==void 0&&o>n){const u=Math.round(n/1048576);return{isValid:!1,error:`File size exceeds limit for ${i.toLowerCase()} files. Maximum size: ${u}MB`}}return{isValid:!0}}function g(t){return{..._.DEFAULT_UPLOAD_CONFIG,...t}}async function F(t){const{path:a,file:i,config:e,type:o}=t;if(!a||typeof a!="string")return{success:!1,message:"Invalid path provided",code:c.RESPONSE_STATUS.BAD_REQUEST.CODE};if(!i||typeof i!="object")return{success:!1,message:"Invalid file provided",code:c.RESPONSE_STATUS.BAD_REQUEST.CODE};if(e){const s=[E.E_UploadType.IMAGE,E.E_UploadType.VIDEO,E.E_UploadType.DOCUMENT,E.E_UploadType.OTHER];for(const r of s){if(!e[r]||!Array.isArray(e[r].allowedExtensions)||e[r].allowedExtensions.length===0)return{success:!1,message:`Invalid config for ${r.toLowerCase()} files`,code:c.RESPONSE_STATUS.BAD_REQUEST.CODE};if(typeof e[r].sizeLimit!="number"||e[r].sizeLimit<=0)return{success:!1,message:`Invalid size limit for ${r.toLowerCase()} files`,code:c.RESPONSE_STATUS.BAD_REQUEST.CODE}}}try{const s=await p(o,await i,e);if(!s.success)return s;const{createReadStream:r}=s.result,n=C.dirname(a);m.pathExistsSync(n)||m.mkdirSync(n,{recursive:!0});const u=r(),S=m.createWriteStream(a);return u.pipe(S),await new Promise((f,l)=>{S.on("finish",()=>f()),S.on("error",l),u.on("error",l)}),{success:!0,result:a,message:"File uploaded successfully",code:c.RESPONSE_STATUS.OK.CODE}}catch(s){return{success:!1,message:s instanceof Error?s.message:"File upload failed",code:c.RESPONSE_STATUS.INTERNAL_SERVER_ERROR.CODE}}}exports.createUploadConfig=g;exports.getAndValidateFile=p;exports.getFileSizeFromStream=y;exports.getFileWebStream=D;exports.upload=F;exports.validateFileExtension=R;exports.validateUpload=w;
|
|
@@ -1,174 +1,143 @@
|
|
|
1
1
|
import { Buffer as w } from "node:buffer";
|
|
2
2
|
import { Transform as C } from "node:stream";
|
|
3
3
|
import { ReadableStream as D } from "node:stream/web";
|
|
4
|
-
import {
|
|
5
|
-
import { E_UploadType as
|
|
6
|
-
import { dirname as
|
|
7
|
-
import { pathExistsSync as
|
|
8
|
-
import { RESPONSE_STATUS as
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return t;
|
|
16
|
-
}, E = (t, r, e) => new Promise((i, a) => {
|
|
17
|
-
var s = (l) => {
|
|
18
|
-
try {
|
|
19
|
-
n(e.next(l));
|
|
20
|
-
} catch (c) {
|
|
21
|
-
a(c);
|
|
22
|
-
}
|
|
23
|
-
}, o = (l) => {
|
|
24
|
-
try {
|
|
25
|
-
n(e.throw(l));
|
|
26
|
-
} catch (c) {
|
|
27
|
-
a(c);
|
|
28
|
-
}
|
|
29
|
-
}, n = (l) => l.done ? i(l.value) : Promise.resolve(l.value).then(s, o);
|
|
30
|
-
n((e = e.apply(t, r)).next());
|
|
31
|
-
});
|
|
32
|
-
function B(t) {
|
|
33
|
-
return E(this, null, function* () {
|
|
34
|
-
return new Promise((r, e) => {
|
|
35
|
-
let i = 0;
|
|
36
|
-
t.on("data", (a) => {
|
|
37
|
-
i += a.length;
|
|
38
|
-
}), t.on("end", () => r(i)), t.on("error", e);
|
|
39
|
-
});
|
|
4
|
+
import { DEFAULT_UPLOAD_CONFIG as y, BYTES_PER_MB as R } from "./upload.constant.js";
|
|
5
|
+
import { E_UploadType as E } from "./upload.type.js";
|
|
6
|
+
import { dirname as O } from "../path/path.util.js";
|
|
7
|
+
import { pathExistsSync as x, mkdirSync as z, createWriteStream as v } from "../fs/fs.util.js";
|
|
8
|
+
import { RESPONSE_STATUS as c } from "../../constant/response-status.js";
|
|
9
|
+
async function A(i) {
|
|
10
|
+
return new Promise((o, t) => {
|
|
11
|
+
let e = 0;
|
|
12
|
+
i.on("data", (n) => {
|
|
13
|
+
e += n.length;
|
|
14
|
+
}), i.on("end", () => o(e)), i.on("error", t);
|
|
40
15
|
});
|
|
41
16
|
}
|
|
42
|
-
function
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
};
|
|
58
|
-
});
|
|
17
|
+
async function S(i, o, t) {
|
|
18
|
+
const e = await (await o).file, n = e.createReadStream(), s = await A(n), r = t ?? g(), a = T(
|
|
19
|
+
{ filename: e.filename, fileSize: s },
|
|
20
|
+
r,
|
|
21
|
+
i
|
|
22
|
+
);
|
|
23
|
+
return a.isValid ? {
|
|
24
|
+
success: !0,
|
|
25
|
+
result: e,
|
|
26
|
+
message: "File validated successfully"
|
|
27
|
+
} : {
|
|
28
|
+
success: !1,
|
|
29
|
+
message: a.error || "File validation failed",
|
|
30
|
+
code: c.BAD_REQUEST.CODE
|
|
31
|
+
};
|
|
59
32
|
}
|
|
60
|
-
function
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
33
|
+
async function h(i, o, t) {
|
|
34
|
+
const n = (t ?? g())[i], s = await S(i, o, t);
|
|
35
|
+
if (!s.success)
|
|
36
|
+
return s;
|
|
37
|
+
const { createReadStream: r } = s.result;
|
|
38
|
+
let a = n.sizeLimit;
|
|
39
|
+
const f = new C({
|
|
40
|
+
transform(l, d, p) {
|
|
41
|
+
a -= l.length, a < 0 ? p(new Error(`File size exceeds limit of ${n.sizeLimit / R}MB`)) : p(null, l);
|
|
42
|
+
}
|
|
43
|
+
}), u = r().pipe(f);
|
|
44
|
+
return {
|
|
45
|
+
success: !0,
|
|
46
|
+
result: new D({
|
|
47
|
+
start(l) {
|
|
48
|
+
u.on("data", (d) => {
|
|
49
|
+
l.enqueue(typeof d == "string" ? w.from(d) : d);
|
|
50
|
+
}), u.on("end", () => l.close()), u.on("error", (d) => l.error(d));
|
|
70
51
|
}
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
success: !0,
|
|
74
|
-
result: new D({
|
|
75
|
-
start(f) {
|
|
76
|
-
m.on("data", (d) => {
|
|
77
|
-
f.enqueue(typeof d == "string" ? w.from(d) : d);
|
|
78
|
-
}), m.on("end", () => f.close()), m.on("error", (d) => f.error(d));
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
};
|
|
82
|
-
});
|
|
52
|
+
})
|
|
53
|
+
};
|
|
83
54
|
}
|
|
84
|
-
function
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
55
|
+
function F(i, o) {
|
|
56
|
+
const t = i.lastIndexOf(".");
|
|
57
|
+
if (t === -1)
|
|
87
58
|
return !1;
|
|
88
|
-
const
|
|
89
|
-
return
|
|
59
|
+
const e = i.substring(t + 1).toLowerCase();
|
|
60
|
+
return o.includes(e);
|
|
90
61
|
}
|
|
91
|
-
function
|
|
92
|
-
const { filename:
|
|
93
|
-
if (!
|
|
62
|
+
function T(i, o, t) {
|
|
63
|
+
const { filename: e, fileSize: n } = i, s = o[t], { allowedExtensions: r, sizeLimit: a } = s;
|
|
64
|
+
if (!F(e, r))
|
|
94
65
|
return {
|
|
95
66
|
isValid: !1,
|
|
96
|
-
error: `File extension not allowed for ${
|
|
67
|
+
error: `File extension not allowed for ${t.toLowerCase()} files. Allowed extensions: ${r.join(", ")}`
|
|
97
68
|
};
|
|
98
|
-
if (
|
|
99
|
-
const
|
|
69
|
+
if (n !== void 0 && n > a) {
|
|
70
|
+
const f = Math.round(a / 1048576);
|
|
100
71
|
return {
|
|
101
72
|
isValid: !1,
|
|
102
|
-
error: `File size exceeds limit for ${
|
|
73
|
+
error: `File size exceeds limit for ${t.toLowerCase()} files. Maximum size: ${f}MB`
|
|
103
74
|
};
|
|
104
75
|
}
|
|
105
76
|
return { isValid: !0 };
|
|
106
77
|
}
|
|
107
|
-
function
|
|
108
|
-
return
|
|
78
|
+
function g(i) {
|
|
79
|
+
return { ...y, ...i };
|
|
109
80
|
}
|
|
110
|
-
function
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
try {
|
|
143
|
-
const s = yield g(a, yield e, i);
|
|
144
|
-
if (!s.success)
|
|
145
|
-
return s;
|
|
146
|
-
const { createReadStream: o } = s.result, n = x(r);
|
|
147
|
-
z(n) || A(n, { recursive: !0 });
|
|
148
|
-
const l = o(), c = F(r);
|
|
149
|
-
return l.pipe(c), yield new Promise((m, f) => {
|
|
150
|
-
c.on("finish", () => m()), c.on("error", f), l.on("error", f);
|
|
151
|
-
}), {
|
|
152
|
-
success: !0,
|
|
153
|
-
result: r,
|
|
154
|
-
message: "File uploaded successfully",
|
|
155
|
-
code: u.OK.CODE
|
|
156
|
-
};
|
|
157
|
-
} catch (s) {
|
|
158
|
-
return {
|
|
159
|
-
success: !1,
|
|
160
|
-
message: s instanceof Error ? s.message : "File upload failed",
|
|
161
|
-
code: u.INTERNAL_SERVER_ERROR.CODE
|
|
162
|
-
};
|
|
81
|
+
async function N(i) {
|
|
82
|
+
const { path: o, file: t, config: e, type: n } = i;
|
|
83
|
+
if (!o || typeof o != "string")
|
|
84
|
+
return {
|
|
85
|
+
success: !1,
|
|
86
|
+
message: "Invalid path provided",
|
|
87
|
+
code: c.BAD_REQUEST.CODE
|
|
88
|
+
};
|
|
89
|
+
if (!t || typeof t != "object")
|
|
90
|
+
return {
|
|
91
|
+
success: !1,
|
|
92
|
+
message: "Invalid file provided",
|
|
93
|
+
code: c.BAD_REQUEST.CODE
|
|
94
|
+
};
|
|
95
|
+
if (e) {
|
|
96
|
+
const s = [E.IMAGE, E.VIDEO, E.DOCUMENT, E.OTHER];
|
|
97
|
+
for (const r of s) {
|
|
98
|
+
if (!e[r] || !Array.isArray(e[r].allowedExtensions) || e[r].allowedExtensions.length === 0)
|
|
99
|
+
return {
|
|
100
|
+
success: !1,
|
|
101
|
+
message: `Invalid config for ${r.toLowerCase()} files`,
|
|
102
|
+
code: c.BAD_REQUEST.CODE
|
|
103
|
+
};
|
|
104
|
+
if (typeof e[r].sizeLimit != "number" || e[r].sizeLimit <= 0)
|
|
105
|
+
return {
|
|
106
|
+
success: !1,
|
|
107
|
+
message: `Invalid size limit for ${r.toLowerCase()} files`,
|
|
108
|
+
code: c.BAD_REQUEST.CODE
|
|
109
|
+
};
|
|
163
110
|
}
|
|
164
|
-
}
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const s = await S(n, await t, e);
|
|
114
|
+
if (!s.success)
|
|
115
|
+
return s;
|
|
116
|
+
const { createReadStream: r } = s.result, a = O(o);
|
|
117
|
+
x(a) || z(a, { recursive: !0 });
|
|
118
|
+
const f = r(), m = v(o);
|
|
119
|
+
return f.pipe(m), await new Promise((u, l) => {
|
|
120
|
+
m.on("finish", () => u()), m.on("error", l), f.on("error", l);
|
|
121
|
+
}), {
|
|
122
|
+
success: !0,
|
|
123
|
+
result: o,
|
|
124
|
+
message: "File uploaded successfully",
|
|
125
|
+
code: c.OK.CODE
|
|
126
|
+
};
|
|
127
|
+
} catch (s) {
|
|
128
|
+
return {
|
|
129
|
+
success: !1,
|
|
130
|
+
message: s instanceof Error ? s.message : "File upload failed",
|
|
131
|
+
code: c.INTERNAL_SERVER_ERROR.CODE
|
|
132
|
+
};
|
|
133
|
+
}
|
|
165
134
|
}
|
|
166
135
|
export {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
136
|
+
g as createUploadConfig,
|
|
137
|
+
S as getAndValidateFile,
|
|
138
|
+
A as getFileSizeFromStream,
|
|
139
|
+
h as getFileWebStream,
|
|
140
|
+
N as upload,
|
|
141
|
+
F as validateFileExtension,
|
|
142
|
+
T as validateUpload
|
|
174
143
|
};
|