data-validation-proximity 1.0.0 → 1.1.1

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.
Files changed (4) hide show
  1. package/CHANGELOG.md +153 -0
  2. package/README.md +330 -0
  3. package/index.js +341 -797
  4. package/package.json +1 -2
package/index.js CHANGED
@@ -1,95 +1,255 @@
1
- //this is the middelware for data validation
1
+ // Middleware for data validation
2
2
  const joi = require('joi');
3
3
 
4
- //auth validation data
4
+ // ============================================
5
+ // HELPER FUNCTIONS
6
+ // ============================================
7
+
8
+ /**
9
+ * Generic validation middleware factory
10
+ * @param {Object} schema - Joi schema to validate against
11
+ * @param {Function} preprocessor - Optional function to preprocess req.body
12
+ * @returns {Function} Express middleware function
13
+ */
14
+ const createValidationMiddleware = (schema, preprocessor = null) => {
15
+ return (req, res, next) => {
16
+ if (preprocessor) {
17
+ preprocessor(req);
18
+ }
19
+
20
+ const { error } = schema.validate(req.body);
21
+ if (error) {
22
+ console.error('Validation error:', error.details[0].message);
23
+ return res.status(400).send(error.details[0].message);
24
+ }
25
+ next();
26
+ };
27
+ };
28
+
29
+ /**
30
+ * Parse JSON string fields in request body
31
+ * @param {Object} req - Express request object
32
+ * @param {Array<string>} fields - Field names to parse
33
+ */
34
+ const parseJsonFields = (req, fields) => {
35
+ fields.forEach((field) => {
36
+ if (typeof req.body[field] === 'string' && req.body[field] !== '') {
37
+ try {
38
+ req.body[field] = JSON.parse(req.body[field]);
39
+ } catch (error) {
40
+ console.error(`Failed to parse ${field}:`, error);
41
+ }
42
+ }
43
+ });
44
+ };
45
+
46
+ /**
47
+ * Handle file array normalization
48
+ * @param {Object} req - Express request object
49
+ */
50
+ const normalizeFileArrays = (req) => {
51
+ if (req.files?.images?.name) {
52
+ req.files.images = [req.files.images];
53
+ }
54
+ if (req.files?.varientsImages?.name) {
55
+ req.files.varientsImages = [req.files.varientsImages];
56
+ }
57
+ };
58
+
59
+ // ============================================
60
+ // COMMON SCHEMA DEFINITIONS
61
+ // ============================================
62
+
63
+ const policySchema = joi
64
+ .object({
65
+ workingTime: joi
66
+ .object({
67
+ openTime: joi.string().required(),
68
+ closeTime: joi.string().required(),
69
+ })
70
+ .allow(null),
71
+ pickup: joi
72
+ .object({
73
+ timeLimit: joi.number().required(),
74
+ })
75
+ .allow(null),
76
+ delivery: joi
77
+ .object({
78
+ delivery: joi.boolean().required().allow(null),
79
+ })
80
+ .allow(null),
81
+ reservation: joi
82
+ .object({
83
+ duration: joi.number().allow(null).required(),
84
+ payment: joi
85
+ .object({
86
+ free: joi.boolean().allow(null).required(),
87
+ partial: joi
88
+ .object({
89
+ fixe: joi.number().allow(null).required(),
90
+ percentage: joi.number().allow(null).required(),
91
+ })
92
+ .allow(null),
93
+ total: joi.boolean().allow(null).required(),
94
+ })
95
+ .allow(null),
96
+ cancelation: joi
97
+ .object({
98
+ restrictions: joi
99
+ .object({
100
+ fixe: joi.number().allow(null).required(),
101
+ percentage: joi.number().allow(null).required(),
102
+ })
103
+ .allow(null),
104
+ })
105
+ .allow(null),
106
+ })
107
+ .allow(null),
108
+ return: joi
109
+ .object({
110
+ duration: joi.number().allow(null).required(),
111
+ productStatus: joi.string().allow('').allow(null).required(),
112
+ returnMethod: joi.string().allow('').allow(null).required(),
113
+ refund: joi
114
+ .object({
115
+ order: joi
116
+ .object({
117
+ fixe: joi.number().allow(null).required(),
118
+ percentage: joi.number().allow(null).required(),
119
+ })
120
+ .allow(null),
121
+ shipping: joi
122
+ .object({
123
+ fixe: joi.number().allow(null).required(),
124
+ percentage: joi.number().allow(null).required(),
125
+ })
126
+ .allow(null),
127
+ })
128
+ .allow(null),
129
+ })
130
+ .allow(null),
131
+ order: joi
132
+ .object({
133
+ validation: joi
134
+ .object({
135
+ auto: joi.boolean().allow(null).required(),
136
+ manual: joi.boolean().allow(null).required(),
137
+ })
138
+ .allow(null),
139
+ notification: joi
140
+ .object({
141
+ realtime: joi.boolean().allow(null).required(),
142
+ time: joi.string().allow(null).required(),
143
+ perOrdersNbr: joi.number().allow(null).required(),
144
+ sendMode: joi
145
+ .object({
146
+ mail: joi.boolean().allow(null).required(),
147
+ sms: joi.boolean().allow(null).required(),
148
+ popup: joi.boolean().allow(null).required(),
149
+ vibration: joi.boolean().allow(null).required(),
150
+ ringing: joi.boolean().allow(null).required(),
151
+ })
152
+ .allow(null),
153
+ })
154
+ .allow(null),
155
+ })
156
+ .allow(null),
157
+ })
158
+ .allow(null);
159
+
160
+ const addressSchema = joi.object({
161
+ latitude: joi.number().required(),
162
+ longitude: joi.number().required(),
163
+ countryCode: joi.string().min(2),
164
+ country: joi.string().min(3),
165
+ city: joi.string().min(3),
166
+ streetName: joi.string().min(3),
167
+ postalCode: joi.string().min(3),
168
+ fullAddress: joi.string(),
169
+ region: joi.string(),
170
+ apartmentNumber: joi.string(),
171
+ });
172
+
173
+ const workingTimeSchema = joi.object({
174
+ option: joi.string().min(1).required(),
175
+ fixedHours: joi.array().items(
176
+ joi.object({
177
+ openTime: joi.string().allow(null).required(),
178
+ closeTime: joi.string().allow(null).required(),
179
+ })
180
+ ),
181
+ customizedHours: joi
182
+ .object()
183
+ .allow(null)
184
+ .pattern(
185
+ joi.string(),
186
+ joi.array().items(
187
+ joi.object({
188
+ openTime: joi.string().allow(null).required(),
189
+ closeTime: joi.string().allow(null).required(),
190
+ })
191
+ )
192
+ ),
193
+ });
194
+
195
+ const validRoles = ['user', 'admin', 'seller', 'paymentManager', 'manager', 'SuperManager'];
196
+
197
+ // ============================================
198
+ // AUTH SCHEMAS
199
+ // ============================================
200
+
5
201
  const userSchema = joi.object({
6
202
  email: joi.string().email(),
7
203
  phone: joi.string(),
8
204
  username: joi.string().min(5).required(),
9
205
  password: joi.string().min(6).required(),
10
206
  password_confirmation: joi.string().min(6).required(),
11
- role: joi.string().valid('user', 'admin', 'seller', 'paymentManager','manager','SuperManager').required(),
207
+ role: joi.string().valid(...validRoles).required(),
12
208
  cart: joi.string().allow(null).allow(''),
13
209
  google: joi.boolean(),
14
210
  });
15
- exports.userSchemaValidation = (req, res, next) => {
16
- const { error } = userSchema.validate(req.body);
17
- if (error) {
18
- console.log(error);
19
- return res.status(400).send(error.details[0].message);
20
- }
21
- next();
22
- };
23
211
 
24
- //reset password request validation data
212
+ exports.userSchemaValidation = createValidationMiddleware(userSchema);
213
+
25
214
  const resetPasswordRequestSchema = joi.object({
26
215
  email: joi.string().required(),
27
216
  });
28
- exports.resetPasswordRequestSchemaValidation = (req, res, next) => {
29
- const { error } = resetPasswordRequestSchema.validate(req.body);
30
- if (error) {
31
- console.log(error);
32
- return res.status(400).send(error.details[0].message);
33
- }
34
- next();
35
- };
36
217
 
37
- //reset password validation data
218
+ exports.resetPasswordRequestSchemaValidation = createValidationMiddleware(resetPasswordRequestSchema);
219
+
38
220
  const resetPasswordSchema = joi.object({
39
221
  password: joi.string().min(6).required(),
40
222
  password_confirmation: joi.string().min(6).required(),
41
223
  });
42
- exports.resetPasswordSchemaValidation = (req, res, next) => {
43
- const { error } = resetPasswordSchema.validate(req.body);
44
- if (error) {
45
- console.log(error);
46
- return res.status(400).send(error.details[0].message);
47
- }
48
- next();
49
- };
224
+
225
+ exports.resetPasswordSchemaValidation = createValidationMiddleware(resetPasswordSchema);
50
226
 
51
227
  const userLoginSchema = joi.object({
52
228
  email: joi.string().required(),
53
- role: joi.string().valid('user', 'admin', 'seller', 'paymentManager','manager','SuperManager').required(),
229
+ role: joi.string().valid(...validRoles).required(),
54
230
  password: joi.string().min(6),
55
231
  google: joi.boolean(),
56
232
  name: joi.string(),
57
233
  });
58
- exports.userLoginSchemaValidation = (req, res, next) => {
59
- const { error } = userLoginSchema.validate(req.body);
60
- if (error) {
61
- console.log(error);
62
- return res.status(400).send(error.details[0].message);
63
- }
64
- next();
65
- };
234
+
235
+ exports.userLoginSchemaValidation = createValidationMiddleware(userLoginSchema);
66
236
 
67
237
  const userVerificationSchema = joi.object({
68
238
  email: joi.string().required(),
69
239
  verificationCode: joi.string().min(3).max(5).required(),
70
240
  });
71
- //user registration data
72
- exports.userVerificationSchemaValidation = (req, res, next) => {
73
- const { error } = userVerificationSchema.validate(req.body);
74
- if (error) {
75
- console.log(error);
76
- return res.status(400).send(error.details[0].message);
77
- }
78
- next();
79
- };
241
+
242
+ exports.userVerificationSchemaValidation = createValidationMiddleware(userVerificationSchema);
80
243
 
81
244
  const resendUserVerificationSchema = joi.object({
82
245
  email: joi.string().required(),
83
246
  });
84
- //user registration data
85
- exports.resendUserVerificationSchemaValidation = (req, res, next) => {
86
- const { error } = resendUserVerificationSchema.validate(req.body);
87
- if (error) {
88
- console.log(error);
89
- return res.status(400).send(error.details[0].message);
90
- }
91
- next();
92
- };
247
+
248
+ exports.resendUserVerificationSchemaValidation = createValidationMiddleware(resendUserVerificationSchema);
249
+
250
+ // ============================================
251
+ // USER UPDATE SCHEMA
252
+ // ============================================
93
253
 
94
254
  const updateSchema = joi.object({
95
255
  email: joi.string().email(),
@@ -98,108 +258,8 @@ const updateSchema = joi.object({
98
258
  username: joi.string().min(5),
99
259
  phone: joi.string().min(10),
100
260
  profileImage: joi.string().min(3).max(200),
101
- adresse: joi.object({
102
- latitude: joi.number().required(),
103
- longitude: joi.number().required(),
104
- countryCode: joi.string().min(2),
105
- country: joi.string().min(3),
106
- city: joi.string().min(3),
107
- streetName: joi.string().min(3),
108
- postalCode: joi.string().min(3),
109
- fullAdress: joi.string(),
110
- region: joi.string(),
111
- apartmentNumber: joi.string(),
112
- }),
113
- policy: joi
114
- .object({
115
- workingTime: joi
116
- .object({
117
- openTime: joi.string().required(),
118
- closeTime: joi.string().required(),
119
- })
120
- .allow(null),
121
- pickup: joi
122
- .object({
123
- timeLimit: joi.number().required(),
124
- })
125
- .allow(null),
126
- delivery: joi
127
- .object({
128
- delivery: joi.boolean().required().allow(null),
129
- })
130
- .allow(null),
131
- reservation: joi
132
- .object({
133
- duration: joi.number().allow(null).required(),
134
- payment: joi
135
- .object({
136
- free: joi.boolean().allow(null).required(),
137
- partial: joi
138
- .object({
139
- fixe: joi.number().allow(null).required(),
140
- percentage: joi.number().allow(null).required(),
141
- })
142
- .allow(null),
143
- total: joi.boolean().allow(null).required(),
144
- })
145
- .allow(null),
146
- cancelation: joi
147
- .object({
148
- restrictions: joi
149
- .object({
150
- fixe: joi.number().allow(null).required(),
151
- percentage: joi.number().allow(null).required(),
152
- })
153
- .allow(null),
154
- })
155
- .allow(null),
156
- })
157
- .allow(null),
158
- return: joi
159
- .object({
160
- duration: joi.number().allow(null).required(),
161
- productStatus: joi.string().allow('').allow(null).required(),
162
- returnMethod: joi.string().allow('').allow(null).required(),
163
- refund: joi
164
- .object({
165
- order: joi
166
- .object({
167
- fixe: joi.number().allow(null).required(),
168
- percentage: joi.number().allow(null).required(),
169
- })
170
- .allow(null),
171
- shipping: joi
172
- .object({
173
- fixe: joi.number().allow(null).required(),
174
- percentage: joi.number().allow(null).required(),
175
- })
176
- .allow(null),
177
- })
178
- .allow(null),
179
- })
180
- .allow(null),
181
- order: joi
182
- .object({
183
- notification: joi
184
- .object({
185
- realtime: joi.boolean().allow(null).required(),
186
- time: joi.string().allow(null).required(),
187
- perOrdersNbr: joi.number().allow(null).required(),
188
- sendMode: joi
189
- .object({
190
- mail: joi.boolean().allow(null).required(),
191
- sms: joi.boolean().allow(null).required(),
192
- popup: joi.boolean().allow(null).required(),
193
- vibration: joi.boolean().allow(null).required(),
194
- ringing: joi.boolean().allow(null).required(),
195
- })
196
- .allow(null),
197
- })
198
- .allow(null),
199
- })
200
- .allow(null),
201
- })
202
- .allow(null),
261
+ adresse: addressSchema,
262
+ policy: policySchema,
203
263
  discountCode: joi.string().min(3),
204
264
  companyName: joi.string().min(3),
205
265
  shippingAdress: joi.object({
@@ -208,7 +268,7 @@ const updateSchema = joi.object({
208
268
  city: joi.string().min(3),
209
269
  streetName: joi.string().min(3),
210
270
  postalCode: joi.string().min(3),
211
- fullAdress: joi.string(),
271
+ fullAddress: joi.string(),
212
272
  region: joi.string(),
213
273
  apartmentNumber: joi.string(),
214
274
  }),
@@ -218,49 +278,38 @@ const updateSchema = joi.object({
218
278
  notification: joi.string().allow(null),
219
279
  proximityRange: joi.number().min(0).max(1000),
220
280
  });
221
- exports.updateSchemaValidation = (req, res, next) => {
222
- if (typeof req.body.policy === 'string' && req.body.policy != '') {
223
- req.body.policy = JSON.parse(req.body.policy);
224
- }
225
281
 
226
- const { error } = updateSchema.validate(req.body);
227
- if (error) {
228
- console.log(error);
229
- return res.status(400).send(error.details[0].message);
230
- }
231
- next();
232
- };
233
- //cart validation data
282
+ exports.updateSchemaValidation = createValidationMiddleware(updateSchema, (req) => {
283
+ parseJsonFields(req, ['policy']);
284
+ });
285
+
286
+ // ============================================
287
+ // CART SCHEMAS
288
+ // ============================================
234
289
 
235
290
  const itemSchema = joi.object({
236
291
  productId: joi.string().required(),
237
292
  quantity: joi.number().min(1),
238
293
  variantId: joi.string().required(),
239
294
  });
240
- exports.itemSchemaValidation = (req, res, next) => {
241
- const { error } = itemSchema.validate(req.body);
242
- if (error) {
243
- console.log(error);
244
- return res.status(400).send(error.details[0].message);
245
- }
246
- next();
247
- };
248
295
 
249
- //category validation data
296
+ exports.itemSchemaValidation = createValidationMiddleware(itemSchema);
297
+
298
+ // ============================================
299
+ // CATEGORY SCHEMAS
300
+ // ============================================
250
301
 
251
302
  const createCategorySchema = joi.object({
252
303
  name: joi.string().required(),
253
304
  description: joi.string().required(),
254
305
  });
255
- exports.createCategorySchemaValidation = (req, res, next) => {
256
- const { error } = createCategorySchema.validate(req.body);
257
- if (error) {
258
- console.log(error);
259
- return res.status(400).send(error.details[0].message);
260
- }
261
- next();
262
- };
263
- //offer validation data
306
+
307
+ exports.createCategorySchemaValidation = createValidationMiddleware(createCategorySchema);
308
+
309
+ // ============================================
310
+ // OFFER SCHEMAS
311
+ // ============================================
312
+
264
313
  const schemaOffer = joi.object({
265
314
  productId: joi.string().required(),
266
315
  offerExpiration: joi.date(),
@@ -271,21 +320,17 @@ const schemaOffer = joi.object({
271
320
  offerStock: joi.number().required(),
272
321
  discountType: joi.string().valid('percentage', 'amount'),
273
322
  });
274
- exports.schemaOfferValidation = (req, res, next) => {
275
- const { error } = schemaOffer.validate(req.body);
276
- if (error) {
277
- console.log(error);
278
- return res.status(400).send(error.details[0].message);
279
- }
280
- next();
281
- };
323
+
324
+ exports.schemaOfferValidation = createValidationMiddleware(schemaOffer);
325
+
282
326
  const schemaGetOffers = joi.object({
283
327
  storeId: joi.string().required(),
284
328
  });
329
+
285
330
  exports.schemaGetOffersValidation = (req, res, next) => {
286
331
  const { error } = schemaGetOffers.validate({ storeId: req.params.storeId });
287
332
  if (error) {
288
- console.log(error);
333
+ console.error('Validation error:', error.details[0].message);
289
334
  return res.status(400).send(error.details[0].message);
290
335
  }
291
336
  next();
@@ -294,14 +339,8 @@ exports.schemaGetOffersValidation = (req, res, next) => {
294
339
  const schemaGetOfferById = joi.object({
295
340
  offerId: joi.string(),
296
341
  });
297
- exports.schemaGetOfferByIdValidation = (req, res, next) => {
298
- const { error } = schemaGetOfferById.validate(req.body);
299
- if (error) {
300
- console.log(error);
301
- return res.status(400).send(error.details[0].message);
302
- }
303
- next();
304
- };
342
+
343
+ exports.schemaGetOfferByIdValidation = createValidationMiddleware(schemaGetOfferById);
305
344
 
306
345
  const schemaUpdateOffer = joi.object({
307
346
  offerExpiration: joi.date(),
@@ -310,15 +349,13 @@ const schemaUpdateOffer = joi.object({
310
349
  offerDescription: joi.string(),
311
350
  offerDiscount: joi.number(),
312
351
  });
313
- exports.schemaUpdateOfferValidation = (req, res, next) => {
314
- const { error } = schemaUpdateOffer.validate(req.body);
315
- if (error) {
316
- console.log(error);
317
- return res.status(400).send(error.details[0].message);
318
- }
319
- next();
320
- };
321
- //order validation data
352
+
353
+ exports.schemaUpdateOfferValidation = createValidationMiddleware(schemaUpdateOffer);
354
+
355
+ // ============================================
356
+ // ORDER SCHEMAS
357
+ // ============================================
358
+
322
359
  const orderSchema = joi.object({
323
360
  storeId: joi.string().required(),
324
361
  clientId: joi.string().required(),
@@ -350,15 +387,39 @@ const orderSchema = joi.object({
350
387
  }),
351
388
  status: joi.string(),
352
389
  });
353
- exports.orderSchemaValidation = (req, res, next) => {
354
- const { error } = orderSchema.validate(req.body);
355
- if (error) {
356
- console.log(error);
357
- return res.status(400).send(error.details[0].message);
358
- }
359
- next();
360
- };
361
- //product validation data
390
+
391
+ exports.orderSchemaValidation = createValidationMiddleware(orderSchema);
392
+
393
+ // ============================================
394
+ // PRODUCT SCHEMAS
395
+ // ============================================
396
+
397
+ const variantSchema = joi.object({
398
+ _id: joi.string(),
399
+ name: joi.string().min(3),
400
+ quantity: joi.number().min(1).max(1000000),
401
+ price: joi.number().min(1).max(1000000),
402
+ description: joi.string().min(3).max(200),
403
+ image: joi.string().min(3).max(200),
404
+ characterstics: joi.array().items(
405
+ joi.object({
406
+ name: joi.string().min(3),
407
+ value: joi.string(),
408
+ })
409
+ ),
410
+ });
411
+
412
+ const createVariantSchema = joi.object({
413
+ price: joi.number().min(1).required(),
414
+ quantity: joi.number().min(1).required(),
415
+ characterstics: joi.array().items(
416
+ joi.object({
417
+ name: joi.string().min(3).required(),
418
+ value: joi.string().required(),
419
+ })
420
+ ),
421
+ });
422
+
362
423
  const updateProductSchema = joi.object({
363
424
  name: joi.string().min(3),
364
425
  sellerId: joi.string().required(),
@@ -372,139 +433,15 @@ const updateProductSchema = joi.object({
372
433
  storeCategoryId: joi.string(),
373
434
  subCategoryId: joi.string(),
374
435
  rayonId: joi.string(),
375
- variantes: joi.array().items(
376
- joi.object({
377
- _id: joi.string(),
378
- name: joi.string().min(3),
379
- quantity: joi.number().min(1).max(1000000),
380
- price: joi.number().min(1).max(1000000),
381
- description: joi.string().min(3).max(200),
382
- image: joi.string().min(3).max(200),
383
- characterstics: joi.array().items(
384
- joi.object({
385
- name: joi.string().min(3),
386
- value: joi.string(),
387
- })
388
- ),
389
- })
390
- ),
391
- policy: joi
392
- .object({
393
- workingTime: joi
394
- .object({
395
- openTime: joi.string().required(),
396
- closeTime: joi.string().required(),
397
- })
398
- .allow(null),
399
- pickup: joi
400
- .object({
401
- timeLimit: joi.number().required(),
402
- })
403
- .allow(null),
404
- delivery: joi
405
- .object({
406
- delivery: joi.boolean().required().allow(null),
407
- })
408
- .allow(null),
409
- reservation: joi
410
- .object({
411
- duration: joi.number().allow(null).required(),
412
- payment: joi
413
- .object({
414
- free: joi.boolean().allow(null).required(),
415
- partial: joi
416
- .object({
417
- fixe: joi.number().allow(null).required(),
418
- percentage: joi.number().allow(null).required(),
419
- })
420
- .allow(null),
421
- total: joi.boolean().allow(null).required(),
422
- })
423
- .allow(null),
424
- cancelation: joi
425
- .object({
426
- restrictions: joi
427
- .object({
428
- fixe: joi.number().allow(null).required(),
429
- percentage: joi.number().allow(null).required(),
430
- })
431
- .allow(null),
432
- })
433
- .allow(null),
434
- })
435
- .allow(null),
436
- return: joi
437
- .object({
438
- duration: joi.number().allow(null).required(),
439
- productStatus: joi.string().allow('').allow(null).required(),
440
- returnMethod: joi.string().allow('').allow(null).required(),
441
- refund: joi
442
- .object({
443
- order: joi
444
- .object({
445
- fixe: joi.number().allow(null).required(),
446
- percentage: joi.number().allow(null).required(),
447
- })
448
- .allow(null),
449
- shipping: joi
450
- .object({
451
- fixe: joi.number().allow(null).required(),
452
- percentage: joi.number().allow(null).required(),
453
- })
454
- .allow(null),
455
- })
456
- .allow(null),
457
- })
458
- .allow(null),
459
- order: joi
460
- .object({
461
- validation: joi
462
- .object({
463
- auto: joi.boolean().allow(null).required(),
464
- manual: joi.boolean().allow(null).required(),
465
- })
466
- .allow(null),
467
- notification: joi
468
- .object({
469
- realtime: joi.boolean().allow(null).required(),
470
- time: joi.string().allow(null).required(),
471
- perOrdersNbr: joi.number().allow(null).required(),
472
- sendMode: joi
473
- .object({
474
- mail: joi.boolean().allow(null).required(),
475
- sms: joi.boolean().allow(null).required(),
476
- popup: joi.boolean().allow(null).required(),
477
- vibration: joi.boolean().allow(null).required(),
478
- ringing: joi.boolean().allow(null).required(),
479
- })
480
- .allow(null),
481
- })
482
- .allow(null),
483
- })
484
- .allow(null),
485
- })
486
- .allow(null),
436
+ variantes: joi.array().items(variantSchema),
437
+ policy: policySchema,
487
438
  });
488
- exports.updateProductSchemaValidation = (req, res, next) => {
489
- if (typeof req.body.variantes === 'string') {
490
- req.body.variantes = JSON.parse(req.body.variantes);
491
- }
492
- console.log('req.body.variantes');
493
- console.log(req.body.variantes);
494
439
 
495
- if (typeof req.body.policy === 'string' && req.body.policy != '') {
496
- req.body.policy = JSON.parse(req.body.policy);
497
- }
498
-
499
- const { error } = updateProductSchema.validate(req.body);
500
- if (error) {
501
- console.log(error);
502
- return res.status(400).send(error.details[0].message);
503
- }
504
- next();
505
- };
440
+ exports.updateProductSchemaValidation = createValidationMiddleware(updateProductSchema, (req) => {
441
+ parseJsonFields(req, ['variantes', 'policy']);
442
+ console.log('req.body.variantes:', req.body.variantes);
443
+ });
506
444
 
507
- //product validation data
508
445
  const createProductSchema = joi.object({
509
446
  name: joi.string().min(3).required(),
510
447
  price: joi.number().min(1).required(),
@@ -521,155 +458,27 @@ const createProductSchema = joi.object({
521
458
  storeId: joi.string().required(),
522
459
  images: joi.array().items(joi.string().min(3).max(200)),
523
460
  characteristics: joi.object().pattern(joi.string(), joi.array().items(joi.string().min(1))),
524
- variantes: joi.array().items(
525
- joi.object({
526
- price: joi.number().min(1).required(),
527
- quantity: joi.number().min(1).required(),
528
- characterstics: joi.array().items(
529
- joi.object({
530
- name: joi.string().min(3).required(),
531
- value: joi.string().required(),
532
- })
533
- ),
534
- })
535
- ),
536
- policy: joi
537
- .object({
538
- workingTime: joi
539
- .object({
540
- openTime: joi.string().required(),
541
- closeTime: joi.string().required(),
542
- })
543
- .allow(null),
544
- pickup: joi
545
- .object({
546
- timeLimit: joi.number().required(),
547
- })
548
- .allow(null),
549
- delivery: joi
550
- .object({
551
- delivery: joi.boolean().required().allow(null),
552
- })
553
- .allow(null),
554
- reservation: joi
555
- .object({
556
- duration: joi.number().allow(null).required(),
557
- payment: joi
558
- .object({
559
- free: joi.boolean().allow(null).required(),
560
- partial: joi
561
- .object({
562
- fixe: joi.number().allow(null).required(),
563
- percentage: joi.number().allow(null).required(),
564
- })
565
- .allow(null),
566
- total: joi.boolean().allow(null).required(),
567
- })
568
- .allow(null),
569
- cancelation: joi
570
- .object({
571
- restrictions: joi
572
- .object({
573
- fixe: joi.number().allow(null).required(),
574
- percentage: joi.number().allow(null).required(),
575
- })
576
- .allow(null),
577
- })
578
- .allow(null),
579
- })
580
- .allow(null),
581
- return: joi
582
- .object({
583
- duration: joi.number().allow(null).required(),
584
- productStatus: joi.string().allow('').allow(null).required(),
585
- returnMethod: joi.string().allow('').allow(null).required(),
586
- refund: joi
587
- .object({
588
- order: joi
589
- .object({
590
- fixe: joi.number().allow(null).required(),
591
- percentage: joi.number().allow(null).required(),
592
- })
593
- .allow(null),
594
- shipping: joi
595
- .object({
596
- fixe: joi.number().allow(null).required(),
597
- percentage: joi.number().allow(null).required(),
598
- })
599
- .allow(null),
600
- })
601
- .allow(null),
602
- })
603
- .allow(null),
604
- order: joi
605
- .object({
606
- validation: joi
607
- .object({
608
- auto: joi.boolean().allow(null).required(),
609
- manual: joi.boolean().allow(null).required(),
610
- })
611
- .allow(null),
612
- notification: joi
613
- .object({
614
- realtime: joi.boolean().allow(null).required(),
615
- time: joi.string().allow(null).required(),
616
- perOrdersNbr: joi.number().allow(null).required(),
617
- sendMode: joi
618
- .object({
619
- mail: joi.boolean().allow(null).required(),
620
- sms: joi.boolean().allow(null).required(),
621
- popup: joi.boolean().allow(null).required(),
622
- vibration: joi.boolean().allow(null).required(),
623
- ringing: joi.boolean().allow(null).required(),
624
- })
625
- .allow(null),
626
- })
627
- .allow(null),
628
- })
629
- .allow(null),
630
- })
631
- .allow(null),
461
+ variantes: joi.array().items(createVariantSchema),
462
+ policy: policySchema,
632
463
  });
633
- exports.createProductSchemaValidation = (req, res, next) => {
634
- console.log(req.body);
635
- if (typeof req.body.variantes === 'string' && req.body.variantes != '') {
636
- req.body.variantes = JSON.parse(req.body.variantes);
637
464
 
638
- if (req.files.images && req.files.images.name) {
639
- req.files.images = [req.files.images];
640
- }
641
-
642
- if (req.files.varientsImages && req.files.varientsImages.name) {
643
- req.files.varientsImages = [req.files.varientsImages];
644
- }
645
- }
646
-
647
- if (typeof req.body.policy === 'string' && req.body.policy != '') {
648
- req.body.policy = JSON.parse(req.body.policy);
649
- }
465
+ exports.createProductSchemaValidation = createValidationMiddleware(createProductSchema, (req) => {
466
+ console.log('Validating product creation:', req.body);
467
+ parseJsonFields(req, ['variantes', 'policy']);
468
+ normalizeFileArrays(req);
469
+ });
650
470
 
651
- const { error } = createProductSchema.validate(req.body);
652
- if (error) {
653
- console.log(error);
654
- return res.status(400).send(error.details[0].message);
655
- }
656
- next();
657
- };
471
+ // ============================================
472
+ // SEARCH SCHEMAS
473
+ // ============================================
658
474
 
659
- //search validation data
660
475
  const schemaSearchStore = joi.object({
661
476
  langitude: joi.number().required(),
662
477
  latitude: joi.number().required(),
663
478
  radius: joi.number().required(),
664
479
  });
665
- exports.schemaSearchStoreValidation = (req, res, next) => {
666
- const { error } = schemaSearchStore.validate(req.body);
667
- if (error) {
668
- console.log(error);
669
- return res.status(400).send(error.details[0].message);
670
- }
671
- next();
672
- };
480
+
481
+ exports.schemaSearchStoreValidation = createValidationMiddleware(schemaSearchStore);
673
482
 
674
483
  const schemaSearchProduct = joi.object({
675
484
  langitude: joi.number().required(),
@@ -679,16 +488,22 @@ const schemaSearchProduct = joi.object({
679
488
  page: joi.number().min(0),
680
489
  limit: joi.number().min(0),
681
490
  });
682
- exports.schemaSearchProductValidation = (req, res, next) => {
683
- const { error } = schemaSearchProduct.validate(req.body);
684
- if (error) {
685
- console.log(error);
686
- return res.status(400).send(error.details[0].message);
687
- }
688
- next();
689
- };
690
491
 
691
- //store validation data
492
+ exports.schemaSearchProductValidation = createValidationMiddleware(schemaSearchProduct);
493
+
494
+ // ============================================
495
+ // STORE SCHEMAS
496
+ // ============================================
497
+
498
+ const storeAddressSchema = joi.object({
499
+ city: joi.string().min(3).required(),
500
+ streetName: joi.string().min(3),
501
+ postalCode: joi.string().min(2).max(5),
502
+ fullAdress: joi.string().min(3),
503
+ region: joi.string().allow(null),
504
+ country: joi.string().min(3),
505
+ countryCode: joi.string().min(2),
506
+ });
692
507
 
693
508
  const schemaStore = joi.object({
694
509
  name: joi.string().min(2).required(),
@@ -700,166 +515,29 @@ const schemaStore = joi.object({
700
515
  coordinates: joi.array().items().length(2).required(),
701
516
  })
702
517
  .required(),
703
- address: joi.object({
704
- city: joi.string().min(3).required(),
705
- streetName: joi.string().min(3),
706
- postalCode: joi.string().min(2).max(5),
707
- fullAdress: joi.string().min(3),
708
- region: joi.string().allow(null),
709
- country: joi.string().min(3),
710
- countryCode: joi.string().min(2),
711
- }),
712
- //* working time
713
- workingTime: joi.object({
714
- option: joi.string().min(1).required(),
715
- fixedHours: joi.array().items(
716
- joi.object({
717
- openTime: joi.string().allow(null).required(),
718
- closeTime: joi.string().allow(null).required(),
719
- })
720
- ),
721
- customizedHours: joi
722
- .object()
723
- .allow(null)
724
- .pattern(
725
- joi.string(),
726
- joi.array().items(
727
- joi.object({
728
- openTime: joi.string().allow(null).required(),
729
- closeTime: joi.string().allow(null).required(),
730
- })
731
- )
732
- ),
733
- }),
734
- policy: joi
735
- .object({
736
- workingTime: joi
737
- .object({
738
- openTime: joi.string().required(),
739
- closeTime: joi.string().required(),
740
- })
741
- .allow(null),
742
- pickup: joi
743
- .object({
744
- timeLimit: joi.number().required(),
745
- })
746
- .allow(null),
747
- delivery: joi
748
- .object({
749
- delivery: joi.boolean().required().allow(null),
750
- })
751
- .allow(null),
752
- reservation: joi
753
- .object({
754
- duration: joi.number().allow(null).required(),
755
- payment: joi
756
- .object({
757
- free: joi.boolean().allow(null).required(),
758
- partial: joi
759
- .object({
760
- fixe: joi.number().allow(null).required(),
761
- percentage: joi.number().allow(null).required(),
762
- })
763
- .allow(null),
764
- total: joi.boolean().allow(null).required(),
765
- })
766
- .allow(null),
767
- cancelation: joi
768
- .object({
769
- restrictions: joi
770
- .object({
771
- fixe: joi.number().allow(null).required(),
772
- percentage: joi.number().allow(null).required(),
773
- })
774
- .allow(null),
775
- })
776
- .allow(null),
777
- })
778
- .allow(null),
779
- return: joi
780
- .object({
781
- duration: joi.number().allow(null).required(),
782
- returnMethod: joi.string().allow('').allow(null).required(),
783
- productStatus: joi.string().allow('').allow(null).required(),
784
- refund: joi
785
- .object({
786
- order: joi
787
- .object({
788
- fixe: joi.number().allow(null).required(),
789
- percentage: joi.number().allow(null).required(),
790
- })
791
- .allow(null),
792
- shipping: joi
793
- .object({
794
- fixe: joi.number().allow(null).required(),
795
- percentage: joi.number().allow(null).required(),
796
- })
797
- .allow(null),
798
- })
799
- .allow(null),
800
- })
801
- .allow(null),
802
- order: joi
803
- .object({
804
- validation: joi
805
- .object({
806
- auto: joi.boolean().allow(null).required(),
807
- manual: joi.boolean().allow(null).required(),
808
- })
809
- .allow(null),
810
- notification: joi
811
- .object({
812
- realtime: joi.boolean().allow(null).required(),
813
- time: joi.string().allow(null).required(),
814
- perOrdersNbr: joi.number().allow(null).required(),
815
- sendMode: joi
816
- .object({
817
- mail: joi.boolean().allow(null).required(),
818
- sms: joi.boolean().allow(null).required(),
819
- popup: joi.boolean().allow(null).required(),
820
- vibration: joi.boolean().allow(null).required(),
821
- ringing: joi.boolean().allow(null).required(),
822
- })
823
- .allow(null),
824
- })
825
- .allow(null),
826
- })
827
- .allow(null),
828
- })
829
- .allow(null),
518
+ address: storeAddressSchema,
519
+ workingTime: workingTimeSchema,
520
+ policy: policySchema,
830
521
  image: joi.string().min(3),
831
522
  });
523
+
832
524
  exports.schemaStoreValidation = (req, res, next) => {
833
- console.log('start store validation');
525
+ console.log('Start store validation');
526
+ parseJsonFields(req, ['location', 'address', 'policy', 'workingTime']);
527
+ console.log('Parsed workingTime:', req.body.workingTime);
834
528
 
835
- if (typeof req.body.location === 'string') {
836
- req.body.location = JSON.parse(req.body.location);
837
- }
838
- if (typeof req.body.address === 'string') {
839
- req.body.address = JSON.parse(req.body.address);
840
- }
841
- if (typeof req.body.policy === 'string' && req.body.policy != '') {
842
- req.body.policy = JSON.parse(req.body.policy);
843
- }
844
- if (typeof req.body.workingTime === 'string' && req.body.workingTime != '') {
845
- req.body.workingTime = JSON.parse(req.body.workingTime);
846
- console.log('ff');
847
- console.log(req.body.workingTime);
529
+ const { error } = schemaStore.validate(req.body);
530
+ if (error) {
531
+ console.error('Store validation error:', error.details[0].message);
532
+ return res.status(400).send(error.details[0].message);
848
533
  }
849
534
 
850
- // const { error } = schemaStore.validate(req.body);
851
- // if (error) {
852
- // console.log("error");
853
- // console.log(error.details[0].message);
854
- // return res.status(400).send(error.details[0].message);
855
- // }
856
- console.log('next');
857
535
  next();
858
536
  };
537
+
859
538
  const schemaUpdateStore = joi.object({
860
539
  name: joi.string().min(3),
861
540
  description: joi.string().min(3).max(200),
862
-
863
541
  isActive: joi.bool(),
864
542
  address: joi.object({
865
543
  city: joi.string().min(3),
@@ -869,153 +547,26 @@ const schemaUpdateStore = joi.object({
869
547
  countryCode: joi.string().min(2),
870
548
  fullAdress: joi.string().min(3).max(40),
871
549
  region: joi.string().min(3),
872
- postalCode: joi.string().min(3),
873
550
  }),
874
- policy: joi
875
- .object({
876
- workingTime: joi
877
- .object({
878
- openTime: joi.string().required(),
879
- closeTime: joi.string().required(),
880
- })
881
- .allow(null),
882
- pickup: joi
883
- .object({
884
- timeLimit: joi.number().required(),
885
- })
886
- .allow(null),
887
- delivery: joi
888
- .object({
889
- delivery: joi.boolean().required().allow(null),
890
- })
891
- .allow(null),
892
- reservation: joi
893
- .object({
894
- duration: joi.number().allow(null).required(),
895
- payment: joi
896
- .object({
897
- free: joi.boolean().allow(null).required(),
898
- partial: joi
899
- .object({
900
- fixe: joi.number().allow(null).required(),
901
- percentage: joi.number().allow(null).required(),
902
- })
903
- .allow(null),
904
- total: joi.boolean().allow(null).required(),
905
- })
906
- .allow(null),
907
- cancelation: joi
908
- .object({
909
- restrictions: joi
910
- .object({
911
- fixe: joi.number().allow(null).required(),
912
- percentage: joi.number().allow(null).required(),
913
- })
914
- .allow(null),
915
- })
916
- .allow(null),
917
- })
918
- .allow(null),
919
- return: joi
920
- .object({
921
- duration: joi.number().allow(null).required(),
922
- productStatus: joi.string().allow('').allow(null).required(),
923
- returnMethod: joi.string().allow('').allow(null).required(),
924
- refund: joi
925
- .object({
926
- order: joi
927
- .object({
928
- fixe: joi.number().allow(null).required(),
929
- percentage: joi.number().allow(null).required(),
930
- })
931
- .allow(null),
932
- shipping: joi
933
- .object({
934
- fixe: joi.number().allow(null).required(),
935
- percentage: joi.number().allow(null).required(),
936
- })
937
- .allow(null),
938
- })
939
- .allow(null),
940
- })
941
- .allow(null),
942
- order: joi
943
- .object({
944
- validation: joi
945
- .object({
946
- auto: joi.boolean().allow(null).required(),
947
- manual: joi.boolean().allow(null).required(),
948
- })
949
- .allow(null),
950
- notification: joi
951
- .object({
952
- realtime: joi.boolean().allow(null).required(),
953
- time: joi.string().allow(null).required(),
954
- perOrdersNbr: joi.number().allow(null).required(),
955
- sendMode: joi
956
- .object({
957
- mail: joi.boolean().allow(null).required(),
958
- sms: joi.boolean().allow(null).required(),
959
- popup: joi.boolean().allow(null).required(),
960
- vibration: joi.boolean().allow(null).required(),
961
- ringing: joi.boolean().allow(null).required(),
962
- })
963
- .allow(null),
964
- })
965
- .allow(null),
966
- })
967
- .allow(null),
968
- })
969
- .allow(null),
551
+ policy: policySchema,
970
552
  location: joi.object({
971
553
  type: joi.string().valid('Point'),
972
554
  coordinates: joi.array().items().length(2),
973
555
  }),
974
- workingTime: joi.object({
975
- option: joi.string().min(1).required(),
976
- fixedHours: joi.array().items(
977
- joi.object({
978
- openTime: joi.string().allow(null).required(),
979
- closeTime: joi.string().allow(null).required(),
980
- })
981
- ),
982
- customizedHours: joi
983
- .object()
984
- .allow(null)
985
- .pattern(
986
- joi.string(),
987
- joi.array().items(
988
- joi.object({
989
- openTime: joi.string().allow(null).required(),
990
- closeTime: joi.string().allow(null).required(),
991
- })
992
- )
993
- ),
994
- }),
995
-
556
+ workingTime: workingTimeSchema,
996
557
  image: joi.string().min(3),
997
558
  });
559
+
998
560
  exports.schemaUpdateStoreValidation = (req, res, next) => {
999
- if (typeof req.body.location === 'string') {
1000
- req.body.location = JSON.parse(req.body.location);
1001
- }
1002
- if (typeof req.body.address === 'string') {
1003
- req.body.address = JSON.parse(req.body.address);
1004
- }
561
+ parseJsonFields(req, ['location', 'address', 'policy', 'workingTime']);
562
+ console.log('Parsed workingTime:', req.body.workingTime);
1005
563
 
1006
- if (typeof req.body.policy === 'string' && req.body.policy != '') {
1007
- req.body.policy = JSON.parse(req.body.policy);
1008
- }
1009
- if (typeof req.body.workingTime === 'string' && req.body.workingTime != '') {
1010
- req.body.workingTime = JSON.parse(req.body.workingTime);
1011
- console.log('ff');
1012
- console.log(req.body.workingTime);
564
+ const { error } = schemaUpdateStore.validate(req.body);
565
+ if (error) {
566
+ console.error('Update store validation error:', error.details[0].message);
567
+ return res.status(400).send(error.details[0].message);
1013
568
  }
1014
- // const { error } = schemaUpdateStore.validate(req.body);
1015
- // if (error) {
1016
- // console.log(error);
1017
- // return res.status(400).send(error.details[0].message);
1018
- // }
569
+
1019
570
  next();
1020
571
  };
1021
572
 
@@ -1025,11 +576,4 @@ const schemaUpdateStoreRating = joi.object({
1025
576
  rate: joi.number().required(),
1026
577
  });
1027
578
 
1028
- exports.schemaUpdateStoreRatingValidation = (req, res, next) => {
1029
- const { error } = schemaUpdateStoreRating.validate(req.body);
1030
- if (error) {
1031
- console.log(error);
1032
- return res.status(400).send(error.details[0].message);
1033
- }
1034
- next();
1035
- };
579
+ exports.schemaUpdateStoreRatingValidation = createValidationMiddleware(schemaUpdateStoreRating);