@francesco_ksh/app-ksh-mgd-schemas 2.1.5 → 2.1.6

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/models/Listing.js CHANGED
@@ -12,6 +12,8 @@ const listingSchema = new Schema(
12
12
  },
13
13
  slug: {
14
14
  type: String,
15
+ unique: true,
16
+ required: true,
15
17
  },
16
18
  discounts: {
17
19
  active: {
@@ -407,6 +409,48 @@ const listingSchema = new Schema(
407
409
  }
408
410
  );
409
411
 
412
+ // Helper function to create a URL-friendly slug
413
+ function createSlug(title) {
414
+ return title
415
+ .toLowerCase()
416
+ .replace(/[^a-z0-9\s-]/g, '') // Remove special characters
417
+ .replace(/\s+/g, '-') // Replace spaces with hyphens
418
+ .replace(/-+/g, '-') // Replace multiple hyphens with single hyphen
419
+ .replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
420
+ }
421
+
422
+ // Pre-save middleware to generate unique slug
423
+ listingSchema.pre('save', async function (next) {
424
+ // Only generate slug if it doesn't exist and we have title
425
+ if (!this.slug && this.title) {
426
+ const baseSlug = createSlug(this.title);
427
+ let slug = baseSlug;
428
+ let counter = 1;
429
+
430
+ // Keep trying until we find a unique slug
431
+ while (true) {
432
+ try {
433
+ // Check if slug already exists
434
+ const existingListing = await this.constructor.findOne({ slug });
435
+ if (!existingListing) {
436
+ this.slug = slug;
437
+ break;
438
+ }
439
+
440
+ // If slug exists, try with counter
441
+ slug = `${baseSlug}-${counter}`;
442
+ counter++;
443
+ } catch (error) {
444
+ // If there's an error checking for existing slug, try with counter
445
+ slug = `${baseSlug}-${counter}`;
446
+ counter++;
447
+ }
448
+ }
449
+ }
450
+
451
+ next();
452
+ });
453
+
410
454
  listingSchema.index({ '$**': 'text' });
411
455
  listingSchema.index({ author: 1 });
412
456
  listingSchema.index({ region: 1 });
@@ -414,5 +458,6 @@ listingSchema.index({ 'newSchema.supervised': 1 });
414
458
  listingSchema.index({ date: -1 });
415
459
  listingSchema.index({ status: 1 });
416
460
  listingSchema.index({ kashewId: 1 }, { unique: true, sparse: true });
461
+ listingSchema.index({ slug: 1 }, { unique: true, sparse: true });
417
462
 
418
463
  module.exports = listingSchema;
package/models/User.js CHANGED
@@ -9,6 +9,14 @@ const userSchema = new Schema(
9
9
  },
10
10
  slug: {
11
11
  type: String,
12
+ unique: true,
13
+ required: true,
14
+ },
15
+ kashewId: {
16
+ type: String,
17
+ unique: true,
18
+ required: false,
19
+ sparse: true,
12
20
  },
13
21
  lastName: {
14
22
  type: String,
@@ -481,6 +489,67 @@ const userSchema = new Schema(
481
489
  { supressReservedKeysWarning: true }
482
490
  );
483
491
 
492
+ // Helper function to create a URL-friendly slug
493
+ function createSlug(firstName, lastName) {
494
+ const name = lastName ? `${firstName}-${lastName}` : firstName;
495
+ return name
496
+ .toLowerCase()
497
+ .replace(/[^a-z0-9\s-]/g, '') // Remove special characters
498
+ .replace(/\s+/g, '-') // Replace spaces with hyphens
499
+ .replace(/-+/g, '-') // Replace multiple hyphens with single hyphen
500
+ .replace(/^-|-$/g, ''); // Remove leading/trailing hyphens
501
+ }
502
+
503
+ // Pre-save middleware to generate unique slug
504
+ userSchema.pre('save', async function (next) {
505
+ // Only generate slug if it doesn't exist and we have firstName
506
+ if (!this.slug && this.firstName) {
507
+ const baseSlug = createSlug(this.firstName, this.lastName);
508
+ let slug = baseSlug;
509
+ let counter = 1;
510
+
511
+ // Keep trying until we find a unique slug
512
+ while (true) {
513
+ try {
514
+ // Check if slug already exists
515
+ const existingUser = await this.constructor.findOne({ slug });
516
+ if (!existingUser) {
517
+ this.slug = slug;
518
+ break;
519
+ }
520
+
521
+ // If slug exists, try with counter
522
+ slug = `${baseSlug}-${counter}`;
523
+ counter++;
524
+ } catch (error) {
525
+ // If there's an error checking for existing slug, try with counter
526
+ slug = `${baseSlug}-${counter}`;
527
+ counter++;
528
+ }
529
+ }
530
+ }
531
+
532
+ // Generate kashewId if it doesn't exist
533
+ if (!this.kashewId) {
534
+ try {
535
+ // Find the highest existing kashewId and increment it
536
+ const counter = await mongoose.model('Counter').findOneAndUpdate(
537
+ { name: 'userId' }, // Counter for kashewId
538
+ { $inc: { count: 1 } }, // Increment by 1
539
+ { new: true, upsert: true } // Create if it doesn't exist
540
+ );
541
+
542
+ // Format the newId as KSH followed by 5 digits
543
+ this.kashewId = `${counter.count.toString().padStart(5, '0')}`;
544
+ } catch (err) {
545
+ return next(err);
546
+ }
547
+ }
548
+
549
+ next();
550
+ });
551
+
484
552
  userSchema.index({ '$**': 'text' });
553
+ userSchema.index({ kashewId: 1 }, { unique: true, sparse: true });
485
554
 
486
555
  module.exports = userSchema;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@francesco_ksh/app-ksh-mgd-schemas",
3
- "version": "2.1.5",
3
+ "version": "2.1.6",
4
4
  "description": "Mongoose schema definitions",
5
5
  "main": "index.js",
6
6
  "repository": {