@duvdu-v1/duvdu 1.1.221 → 1.1.222
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/build/middlewares/global-upload.middleware.js +4 -4
- package/build/models/favourites.model.js +1 -2
- package/build/models/portfolio-post.model.d.ts +9 -0
- package/build/models/portfolio-post.model.js +11 -0
- package/build/models/teamProject.model.js +4 -1
- package/build/utils/bucket.js +45 -24
- package/package.json +56 -56
|
@@ -26,7 +26,7 @@ const globalUploadMiddleware = (folder, options) => {
|
|
|
26
26
|
const upload = (0, multer_1.default)({
|
|
27
27
|
storage: customStorage,
|
|
28
28
|
limits: {
|
|
29
|
-
fileSize: (options === null || options === void 0 ? void 0 : options.maxSize) || 3 * 1024 * 1024 // 3MB default
|
|
29
|
+
fileSize: (options === null || options === void 0 ? void 0 : options.maxSize) || 3 * 1024 * 1024, // 3MB default
|
|
30
30
|
},
|
|
31
31
|
fileFilter: (options === null || options === void 0 ? void 0 : options.fileFilter)
|
|
32
32
|
? options.fileFilter
|
|
@@ -36,7 +36,7 @@ const globalUploadMiddleware = (folder, options) => {
|
|
|
36
36
|
if (!file.mimetype.startsWith('image')) {
|
|
37
37
|
return callback(new bad_request_error_1.BadRequestError({
|
|
38
38
|
en: 'Invalid file format',
|
|
39
|
-
ar: 'صيغة الملف غير صالحة'
|
|
39
|
+
ar: 'صيغة الملف غير صالحة',
|
|
40
40
|
}, 'en'));
|
|
41
41
|
}
|
|
42
42
|
return callback(null, true);
|
|
@@ -47,7 +47,7 @@ const globalUploadMiddleware = (folder, options) => {
|
|
|
47
47
|
else {
|
|
48
48
|
return callback(new bad_request_error_1.BadRequestError({
|
|
49
49
|
en: 'Invalid file format',
|
|
50
|
-
ar: 'صيغة الملف غير صالحة'
|
|
50
|
+
ar: 'صيغة الملف غير صالحة',
|
|
51
51
|
}, 'en'));
|
|
52
52
|
}
|
|
53
53
|
},
|
|
@@ -57,7 +57,7 @@ const globalUploadMiddleware = (folder, options) => {
|
|
|
57
57
|
array: upload.array.bind(upload),
|
|
58
58
|
fields: upload.fields.bind(upload),
|
|
59
59
|
none: upload.none.bind(upload),
|
|
60
|
-
any: upload.any.bind(upload)
|
|
60
|
+
any: upload.any.bind(upload),
|
|
61
61
|
};
|
|
62
62
|
};
|
|
63
63
|
exports.globalUploadMiddleware = globalUploadMiddleware;
|
|
@@ -6,5 +6,4 @@ const model_names_1 = require("../types/model-names");
|
|
|
6
6
|
exports.Favourites = (0, mongoose_1.model)(model_names_1.MODELS.favourites, new mongoose_1.Schema({
|
|
7
7
|
project: { type: mongoose_1.Schema.Types.ObjectId, ref: model_names_1.MODELS.projects },
|
|
8
8
|
user: { type: mongoose_1.Schema.Types.ObjectId, ref: model_names_1.MODELS.user },
|
|
9
|
-
}, { timestamps: true, collection: model_names_1.MODELS.favourites })
|
|
10
|
-
.index({ project: 1, user: 1 }, { unique: true }));
|
|
9
|
+
}, { timestamps: true, collection: model_names_1.MODELS.favourites }).index({ project: 1, user: 1 }, { unique: true }));
|
|
@@ -41,6 +41,15 @@ export interface IprojectCycle {
|
|
|
41
41
|
ar: string;
|
|
42
42
|
en: string;
|
|
43
43
|
}[];
|
|
44
|
+
relatedCategory: {
|
|
45
|
+
category: Types.ObjectId;
|
|
46
|
+
subCategories: {
|
|
47
|
+
subCategory: Types.ObjectId;
|
|
48
|
+
tags: {
|
|
49
|
+
tag: Types.ObjectId;
|
|
50
|
+
}[];
|
|
51
|
+
}[];
|
|
52
|
+
}[];
|
|
44
53
|
cover: string;
|
|
45
54
|
audioCover: string;
|
|
46
55
|
attachments: string[];
|
|
@@ -18,6 +18,17 @@ exports.ProjectCycle = (0, mongoose_1.model)(model_names_1.MODELS.portfolioPost,
|
|
|
18
18
|
_id: String,
|
|
19
19
|
},
|
|
20
20
|
tags: [{ ar: { type: String, default: null }, en: { type: String, default: null } }],
|
|
21
|
+
relatedCategory: [
|
|
22
|
+
{
|
|
23
|
+
category: { type: mongoose_1.Schema.Types.ObjectId, ref: model_names_1.MODELS.category },
|
|
24
|
+
subCategories: [
|
|
25
|
+
{
|
|
26
|
+
subCategory: { type: mongoose_1.Schema.Types.ObjectId },
|
|
27
|
+
tags: [{ tag: { type: mongoose_1.Schema.Types.ObjectId } }],
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
],
|
|
21
32
|
cover: { type: String, default: null },
|
|
22
33
|
audioCover: { type: String, default: null },
|
|
23
34
|
attachments: [{ type: String, default: null }],
|
|
@@ -95,5 +95,8 @@ exports.TeamContract = (0, mongoose_1.model)(model_names_1.MODELS.teamContract,
|
|
|
95
95
|
paymentAmount: { type: Number, default: 0 },
|
|
96
96
|
attachments: [String],
|
|
97
97
|
totalCheckoutAt: Date,
|
|
98
|
-
submitFiles: {
|
|
98
|
+
submitFiles: {
|
|
99
|
+
link: { type: String, default: null },
|
|
100
|
+
notes: { type: String, default: null },
|
|
101
|
+
},
|
|
99
102
|
}, { timestamps: true, collection: model_names_1.MODELS.teamContract }));
|
package/build/utils/bucket.js
CHANGED
|
@@ -86,18 +86,21 @@ class Bucket {
|
|
|
86
86
|
else
|
|
87
87
|
resolve({
|
|
88
88
|
PartNumber: partNumber,
|
|
89
|
-
ETag: data.ETag
|
|
89
|
+
ETag: data.ETag,
|
|
90
90
|
});
|
|
91
91
|
});
|
|
92
92
|
});
|
|
93
93
|
const timeoutPromise = new Promise((_, reject) => {
|
|
94
94
|
setTimeout(() => reject(new Error('Upload timeout')), 30000);
|
|
95
95
|
});
|
|
96
|
-
return yield Promise.race([
|
|
96
|
+
return (yield Promise.race([
|
|
97
|
+
uploadPromise,
|
|
98
|
+
timeoutPromise,
|
|
99
|
+
]));
|
|
97
100
|
}
|
|
98
101
|
catch (error) {
|
|
99
102
|
if (retryCount < MAX_RETRIES) {
|
|
100
|
-
yield new Promise(resolve => setTimeout(resolve, Math.pow(2, retryCount) * 1000));
|
|
103
|
+
yield new Promise((resolve) => setTimeout(resolve, Math.pow(2, retryCount) * 1000));
|
|
101
104
|
return uploadChunkWithRetry(retryCount + 1);
|
|
102
105
|
}
|
|
103
106
|
throw error;
|
|
@@ -113,7 +116,7 @@ class Bucket {
|
|
|
113
116
|
Bucket: this.bucketName,
|
|
114
117
|
Key: `${folder}/${file.filename}`,
|
|
115
118
|
UploadId: uploadId,
|
|
116
|
-
MultipartUpload: { Parts: parts }
|
|
119
|
+
MultipartUpload: { Parts: parts },
|
|
117
120
|
}, (err, data) => {
|
|
118
121
|
if (err)
|
|
119
122
|
reject(err);
|
|
@@ -128,7 +131,7 @@ class Bucket {
|
|
|
128
131
|
this.s3.abortMultipartUpload({
|
|
129
132
|
Bucket: this.bucketName,
|
|
130
133
|
Key: `${folder}/${file.filename}`,
|
|
131
|
-
UploadId: multipartUpload.UploadId
|
|
134
|
+
UploadId: multipartUpload.UploadId,
|
|
132
135
|
}, () => resolve(null));
|
|
133
136
|
});
|
|
134
137
|
}
|
|
@@ -165,7 +168,7 @@ class Bucket {
|
|
|
165
168
|
yield new Promise((resolve, reject) => {
|
|
166
169
|
this.s3.deleteObjects({
|
|
167
170
|
Bucket: this.bucketName,
|
|
168
|
-
Delete: { Objects: batch.map((el) => ({ Key: el })) }
|
|
171
|
+
Delete: { Objects: batch.map((el) => ({ Key: el })) },
|
|
169
172
|
}, (err, data) => {
|
|
170
173
|
if (err)
|
|
171
174
|
reject(err);
|
|
@@ -193,35 +196,41 @@ class Bucket {
|
|
|
193
196
|
Image: {
|
|
194
197
|
S3Object: {
|
|
195
198
|
Bucket: this.bucketName,
|
|
196
|
-
Name: imageKey
|
|
197
|
-
}
|
|
199
|
+
Name: imageKey,
|
|
200
|
+
},
|
|
198
201
|
},
|
|
199
|
-
Attributes: ['ALL']
|
|
202
|
+
Attributes: ['ALL'],
|
|
200
203
|
};
|
|
201
204
|
const result = yield this.rekognition.detectFaces(params).promise();
|
|
202
205
|
if (!result.FaceDetails || result.FaceDetails.length === 0) {
|
|
203
206
|
return {
|
|
204
207
|
isValid: false,
|
|
205
|
-
error: { en: 'No face detected in the image', ar: 'لا يوجد وجه مكتشف في الصورة' }
|
|
208
|
+
error: { en: 'No face detected in the image', ar: 'لا يوجد وجه مكتشف في الصورة' },
|
|
206
209
|
};
|
|
207
210
|
}
|
|
208
211
|
if (result.FaceDetails.length > 1) {
|
|
209
212
|
return {
|
|
210
213
|
isValid: false,
|
|
211
|
-
error: {
|
|
214
|
+
error: {
|
|
215
|
+
en: 'Multiple faces detected in the image',
|
|
216
|
+
ar: 'تم الكشف عن أكثر من وجه في الصورة',
|
|
217
|
+
},
|
|
212
218
|
};
|
|
213
219
|
}
|
|
214
220
|
const face = result.FaceDetails[0];
|
|
215
221
|
if (!face.Confidence || face.Confidence < 95) {
|
|
216
222
|
return {
|
|
217
223
|
isValid: false,
|
|
218
|
-
error: { en: 'Image quality is not sufficient', ar: 'جودة الصورة غير كافية' }
|
|
224
|
+
error: { en: 'Image quality is not sufficient', ar: 'جودة الصورة غير كافية' },
|
|
219
225
|
};
|
|
220
226
|
}
|
|
221
227
|
if (((_a = face.Sunglasses) === null || _a === void 0 ? void 0 : _a.Value) || ((_b = face.Eyeglasses) === null || _b === void 0 ? void 0 : _b.Value)) {
|
|
222
228
|
return {
|
|
223
229
|
isValid: false,
|
|
224
|
-
error: {
|
|
230
|
+
error: {
|
|
231
|
+
en: 'Please remove glasses or sunglasses',
|
|
232
|
+
ar: 'يرجى إزالة النظارات أو النظارات الشمسية',
|
|
233
|
+
},
|
|
225
234
|
};
|
|
226
235
|
}
|
|
227
236
|
const leftEyeOpen = ((_c = face.EyesOpen) === null || _c === void 0 ? void 0 : _c.Value) && ((_e = (_d = face.EyesOpen) === null || _d === void 0 ? void 0 : _d.Confidence) !== null && _e !== void 0 ? _e : 0) > 95;
|
|
@@ -229,13 +238,16 @@ class Bucket {
|
|
|
229
238
|
if (!leftEyeOpen || !rightEyeOpen) {
|
|
230
239
|
return {
|
|
231
240
|
isValid: false,
|
|
232
|
-
error: {
|
|
241
|
+
error: {
|
|
242
|
+
en: 'Eyes must be fully open and clearly visible',
|
|
243
|
+
ar: 'يجب أن تكون العينين مفتوحتين بالكامل وواضحتين',
|
|
244
|
+
},
|
|
233
245
|
};
|
|
234
246
|
}
|
|
235
247
|
if ((_j = face.MouthOpen) === null || _j === void 0 ? void 0 : _j.Value) {
|
|
236
248
|
return {
|
|
237
249
|
isValid: false,
|
|
238
|
-
error: { en: 'Mouth should be closed', ar: 'يجب أن يكون الفم مغلقاً' }
|
|
250
|
+
error: { en: 'Mouth should be closed', ar: 'يجب أن يكون الفم مغلقاً' },
|
|
239
251
|
};
|
|
240
252
|
}
|
|
241
253
|
const pose = face.Pose;
|
|
@@ -245,19 +257,28 @@ class Bucket {
|
|
|
245
257
|
Math.abs((pose === null || pose === void 0 ? void 0 : pose.Yaw) || 0) > poseThreshold) {
|
|
246
258
|
return {
|
|
247
259
|
isValid: false,
|
|
248
|
-
error: {
|
|
260
|
+
error: {
|
|
261
|
+
en: 'Face must be directly facing the camera',
|
|
262
|
+
ar: 'يجب أن يكون الوجه مواجهاً للكاميرا مباشرة',
|
|
263
|
+
},
|
|
249
264
|
};
|
|
250
265
|
}
|
|
251
266
|
if ((_k = face.FaceOccluded) === null || _k === void 0 ? void 0 : _k.Value) {
|
|
252
267
|
return {
|
|
253
268
|
isValid: false,
|
|
254
|
-
error: {
|
|
269
|
+
error: {
|
|
270
|
+
en: 'Face must be fully visible without any coverings',
|
|
271
|
+
ar: 'يجب أن يكون الوجه مرئياً بالكامل بدون أي أغطية',
|
|
272
|
+
},
|
|
255
273
|
};
|
|
256
274
|
}
|
|
257
275
|
if ((_l = face.Smile) === null || _l === void 0 ? void 0 : _l.Value) {
|
|
258
276
|
return {
|
|
259
277
|
isValid: false,
|
|
260
|
-
error: {
|
|
278
|
+
error: {
|
|
279
|
+
en: 'Please maintain a neutral expression (no smiling)',
|
|
280
|
+
ar: 'يرجى الحفاظ على تعبير محايد (بدون ابتسامة)',
|
|
281
|
+
},
|
|
261
282
|
};
|
|
262
283
|
}
|
|
263
284
|
return { isValid: true };
|
|
@@ -266,7 +287,7 @@ class Bucket {
|
|
|
266
287
|
console.error('Error validating face:', error);
|
|
267
288
|
return {
|
|
268
289
|
isValid: false,
|
|
269
|
-
error: { en: 'Error processing image', ar: 'خطأ في معالجة الصورة' }
|
|
290
|
+
error: { en: 'Error processing image', ar: 'خطأ في معالجة الصورة' },
|
|
270
291
|
};
|
|
271
292
|
}
|
|
272
293
|
});
|
|
@@ -282,7 +303,7 @@ const MIME_TYPES = {
|
|
|
282
303
|
'.mov': 'video/quicktime',
|
|
283
304
|
'.wmv': 'video/x-ms-wmv',
|
|
284
305
|
'.mkv': 'video/x-matroska',
|
|
285
|
-
'.flv': 'video/x-flv'
|
|
306
|
+
'.flv': 'video/x-flv',
|
|
286
307
|
},
|
|
287
308
|
audio: {
|
|
288
309
|
'.mp3': 'audio/mpeg',
|
|
@@ -290,7 +311,7 @@ const MIME_TYPES = {
|
|
|
290
311
|
'.aac': 'audio/aac',
|
|
291
312
|
'.flac': 'audio/flac',
|
|
292
313
|
'.m4a': 'audio/x-m4a',
|
|
293
|
-
'.wma': 'audio/x-ms-wma'
|
|
314
|
+
'.wma': 'audio/x-ms-wma',
|
|
294
315
|
},
|
|
295
316
|
image: {
|
|
296
317
|
'.jpg': 'image/jpeg',
|
|
@@ -301,9 +322,9 @@ const MIME_TYPES = {
|
|
|
301
322
|
'.webp': 'image/webp',
|
|
302
323
|
'.svg': 'image/svg+xml',
|
|
303
324
|
'.tiff': 'image/tiff',
|
|
304
|
-
'.tif': 'image/tiff'
|
|
325
|
+
'.tif': 'image/tiff',
|
|
305
326
|
},
|
|
306
327
|
document: {
|
|
307
|
-
'.pdf': 'application/pdf'
|
|
308
|
-
}
|
|
328
|
+
'.pdf': 'application/pdf',
|
|
329
|
+
},
|
|
309
330
|
};
|
package/package.json
CHANGED
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@duvdu-v1/duvdu",
|
|
3
|
-
"version": "1.1.
|
|
4
|
-
"main": "./build/index.js",
|
|
5
|
-
"types": "./build/index.d.ts",
|
|
6
|
-
"files": [
|
|
7
|
-
"build/**/*"
|
|
8
|
-
],
|
|
9
|
-
"scripts": {
|
|
10
|
-
"clean": "rimraf ./build",
|
|
11
|
-
"build": "npm run clean && tsc",
|
|
12
|
-
"fix:build": "mv ./build/common/src/* ./build && rm -rf ./build/auth ./build/common",
|
|
13
|
-
"pub": "git add . && git commit -m \"updates\" && npm version patch && npm run build && npm publish",
|
|
14
|
-
"lint": "eslint .",
|
|
15
|
-
"lint:fix": "eslint --fix .",
|
|
16
|
-
"format": "prettier --write ."
|
|
17
|
-
},
|
|
18
|
-
"keywords": [],
|
|
19
|
-
"author": "motemed khaled",
|
|
20
|
-
"license": "ISC",
|
|
21
|
-
"dependencies": {
|
|
22
|
-
"@types/express": "^4.17.21",
|
|
23
|
-
"@types/express-session": "^1.18.0",
|
|
24
|
-
"@types/jsonwebtoken": "^9.0.5",
|
|
25
|
-
"@types/multer": "^1.4.11",
|
|
26
|
-
"@types/node": "^20.11.0",
|
|
27
|
-
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
28
|
-
"@typescript-eslint/parser": "^6.19.0",
|
|
29
|
-
"aws-sdk": "^2.1595.0",
|
|
30
|
-
"connect-redis": "^7.1.1",
|
|
31
|
-
"express": "^4.18.2",
|
|
32
|
-
"express-async-errors": "^3.1.1",
|
|
33
|
-
"express-session": "^1.18.0",
|
|
34
|
-
"express-validator": "^7.0.1",
|
|
35
|
-
"jsonwebtoken": "^9.0.2",
|
|
36
|
-
"mongoose": "^8.0.4",
|
|
37
|
-
"multer": "^1.4.5-lts.1",
|
|
38
|
-
"node-nats-streaming": "^0.3.2",
|
|
39
|
-
"redis": "^4.6.13",
|
|
40
|
-
"rimraf": "^5.0.5",
|
|
41
|
-
"typescript": "^5.3.3",
|
|
42
|
-
"uuid": "^9.0.1",
|
|
43
|
-
"winston": "^3.13.0",
|
|
44
|
-
"winston-daily-rotate-file": "^5.0.0"
|
|
45
|
-
},
|
|
46
|
-
"devDependencies": {
|
|
47
|
-
"@types/uuid": "^9.0.8",
|
|
48
|
-
"del-cli": "^5.1.0",
|
|
49
|
-
"eslint": "^8.56.0",
|
|
50
|
-
"eslint-config-prettier": "^9.1.0",
|
|
51
|
-
"eslint-plugin-import": "^2.29.1",
|
|
52
|
-
"eslint-plugin-prettier": "^5.1.3",
|
|
53
|
-
"prettier": "^3.2.4"
|
|
54
|
-
},
|
|
55
|
-
"description": ""
|
|
56
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@duvdu-v1/duvdu",
|
|
3
|
+
"version": "1.1.222",
|
|
4
|
+
"main": "./build/index.js",
|
|
5
|
+
"types": "./build/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"build/**/*"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"clean": "rimraf ./build",
|
|
11
|
+
"build": "npm run clean && tsc",
|
|
12
|
+
"fix:build": "mv ./build/common/src/* ./build && rm -rf ./build/auth ./build/common",
|
|
13
|
+
"pub": "git add . && git commit -m \"updates\" && npm version patch && npm run build && npm publish",
|
|
14
|
+
"lint": "eslint .",
|
|
15
|
+
"lint:fix": "eslint --fix .",
|
|
16
|
+
"format": "prettier --write ."
|
|
17
|
+
},
|
|
18
|
+
"keywords": [],
|
|
19
|
+
"author": "motemed khaled",
|
|
20
|
+
"license": "ISC",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@types/express": "^4.17.21",
|
|
23
|
+
"@types/express-session": "^1.18.0",
|
|
24
|
+
"@types/jsonwebtoken": "^9.0.5",
|
|
25
|
+
"@types/multer": "^1.4.11",
|
|
26
|
+
"@types/node": "^20.11.0",
|
|
27
|
+
"@typescript-eslint/eslint-plugin": "^6.19.0",
|
|
28
|
+
"@typescript-eslint/parser": "^6.19.0",
|
|
29
|
+
"aws-sdk": "^2.1595.0",
|
|
30
|
+
"connect-redis": "^7.1.1",
|
|
31
|
+
"express": "^4.18.2",
|
|
32
|
+
"express-async-errors": "^3.1.1",
|
|
33
|
+
"express-session": "^1.18.0",
|
|
34
|
+
"express-validator": "^7.0.1",
|
|
35
|
+
"jsonwebtoken": "^9.0.2",
|
|
36
|
+
"mongoose": "^8.0.4",
|
|
37
|
+
"multer": "^1.4.5-lts.1",
|
|
38
|
+
"node-nats-streaming": "^0.3.2",
|
|
39
|
+
"redis": "^4.6.13",
|
|
40
|
+
"rimraf": "^5.0.5",
|
|
41
|
+
"typescript": "^5.3.3",
|
|
42
|
+
"uuid": "^9.0.1",
|
|
43
|
+
"winston": "^3.13.0",
|
|
44
|
+
"winston-daily-rotate-file": "^5.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/uuid": "^9.0.8",
|
|
48
|
+
"del-cli": "^5.1.0",
|
|
49
|
+
"eslint": "^8.56.0",
|
|
50
|
+
"eslint-config-prettier": "^9.1.0",
|
|
51
|
+
"eslint-plugin-import": "^2.29.1",
|
|
52
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
53
|
+
"prettier": "^3.2.4"
|
|
54
|
+
},
|
|
55
|
+
"description": ""
|
|
56
|
+
}
|