@lyxa.ai/core 1.1.66 → 1.1.68

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.
@@ -0,0 +1,12 @@
1
+ import { Ref } from '@typegoose/typegoose';
2
+ import { Status } from '../../../../utilities/enum';
3
+ import { Product } from '../product.model';
4
+ export declare class BestSellerCategory {
5
+ title?: string;
6
+ status?: Status;
7
+ }
8
+ export declare class FavouritesCategory {
9
+ title?: string;
10
+ status?: Status;
11
+ products?: Ref<Product>[];
12
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FavouritesCategory = exports.BestSellerCategory = void 0;
13
+ const typegoose_1 = require("@typegoose/typegoose");
14
+ const enum_1 = require("../../../../utilities/enum");
15
+ const product_model_1 = require("../product.model");
16
+ class BestSellerCategory {
17
+ title;
18
+ status;
19
+ }
20
+ exports.BestSellerCategory = BestSellerCategory;
21
+ __decorate([
22
+ (0, typegoose_1.prop)({ type: String, default: 'Best Seller' }),
23
+ __metadata("design:type", String)
24
+ ], BestSellerCategory.prototype, "title", void 0);
25
+ __decorate([
26
+ (0, typegoose_1.prop)({ type: String, enum: enum_1.Status, default: enum_1.Status.INACTIVE }),
27
+ __metadata("design:type", String)
28
+ ], BestSellerCategory.prototype, "status", void 0);
29
+ class FavouritesCategory {
30
+ title;
31
+ status;
32
+ products;
33
+ }
34
+ exports.FavouritesCategory = FavouritesCategory;
35
+ __decorate([
36
+ (0, typegoose_1.prop)({ type: String, default: 'Favourites' }),
37
+ __metadata("design:type", String)
38
+ ], FavouritesCategory.prototype, "title", void 0);
39
+ __decorate([
40
+ (0, typegoose_1.prop)({ type: String, enum: enum_1.Status, default: enum_1.Status.INACTIVE }),
41
+ __metadata("design:type", String)
42
+ ], FavouritesCategory.prototype, "status", void 0);
43
+ __decorate([
44
+ (0, typegoose_1.prop)({ ref: () => product_model_1.Product, default: [] }),
45
+ __metadata("design:type", Array)
46
+ ], FavouritesCategory.prototype, "products", void 0);
47
+ //# sourceMappingURL=best-seller-category.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"best-seller-category.model.js","sourceRoot":"/","sources":["libraries/mongo/models/embedded/best-seller-category.model.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAiD;AACjD,qDAAoD;AACpD,oDAA2C;AAE3C,MAAa,kBAAkB;IAEvB,KAAK,CAAU;IAGf,MAAM,CAAU;CACvB;AAND,gDAMC;AAJO;IADN,IAAA,gBAAI,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;;iDACzB;AAGf;IADN,IAAA,gBAAI,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAM,EAAE,OAAO,EAAE,aAAM,CAAC,QAAQ,EAAE,CAAC;;kDACxC;AAGxB,MAAa,kBAAkB;IAEvB,KAAK,CAAU;IAGf,MAAM,CAAU;IAGhB,QAAQ,CAAkB;CACjC;AATD,gDASC;AAPO;IADN,IAAA,gBAAI,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;;iDACxB;AAGf;IADN,IAAA,gBAAI,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAM,EAAE,OAAO,EAAE,aAAM,CAAC,QAAQ,EAAE,CAAC;;kDACxC;AAGhB;IADN,IAAA,gBAAI,EAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,uBAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;;oDACT","sourcesContent":["import { prop, Ref } from '@typegoose/typegoose';\nimport { Status } from '../../../../utilities/enum';\nimport { Product } from '../product.model';\n\nexport class BestSellerCategory {\n\t@prop({ type: String, default: 'Best Seller' })\n\tpublic title?: string;\n\n\t@prop({ type: String, enum: Status, default: Status.INACTIVE })\n\tpublic status?: Status;\n}\n\nexport class FavouritesCategory {\n\t@prop({ type: String, default: 'Favourites' })\n\tpublic title?: string;\n\n\t@prop({ type: String, enum: Status, default: Status.INACTIVE })\n\tpublic status?: Status;\n\n\t@prop({ ref: () => Product, default: [] })\n\tpublic products?: Ref<Product>[];\n}\n"]}
@@ -9,6 +9,7 @@ import { StartEndTime, WorkHourSetting } from './shared/work-hour.model';
9
9
  import { Tag } from './tag.model';
10
10
  import { DeliveryInfo } from './embedded/delivery-info.model';
11
11
  import { ShopSearchFields } from './embedded/shop-search-fields.model';
12
+ import { BestSellerCategory, FavouritesCategory } from './embedded/best-seller-category.model';
12
13
  export declare class Shop extends TimeStamps {
13
14
  shopId: string;
14
15
  name: string;
@@ -37,6 +38,7 @@ export declare class Shop extends TimeStamps {
37
38
  isShopDelivery?: boolean;
38
39
  deliveryFee?: number;
39
40
  minimumOrderAmount?: number;
41
+ orderCapacityEnabled?: boolean;
40
42
  orderCapacity?: number;
41
43
  shopActiveTimingsOfCurrentDate?: StartEndTime[];
42
44
  deliveryInfo?: DeliveryInfo;
@@ -46,11 +48,8 @@ export declare class Shop extends TimeStamps {
46
48
  riderNote?: string;
47
49
  defaultPreparationTime?: number;
48
50
  exchangeRate?: number;
49
- isFavouriteCategoryVisible?: boolean;
50
- favouriteCategoryTitle?: string;
51
- isBestSellerCategoryVisible?: boolean;
52
- bestSellerCategoryTitle?: string;
53
- orderCapacityEnabled: boolean;
51
+ bestSellerCategory?: BestSellerCategory;
52
+ favouritesCategory?: FavouritesCategory;
54
53
  avgRating?: number;
55
54
  ordersCount?: number;
56
55
  customersCount?: number;
@@ -24,6 +24,7 @@ const shop_hooks_1 = require("../utilities/shop.hooks");
24
24
  const shop_search_fields_model_1 = require("./embedded/shop-search-fields.model");
25
25
  const id_generator_1 = require("../../../utilities/id-generator");
26
26
  const _1 = require(".");
27
+ const best_seller_category_model_1 = require("./embedded/best-seller-category.model");
27
28
  let Shop = class Shop extends defaultClasses_1.TimeStamps {
28
29
  shopId;
29
30
  name;
@@ -52,6 +53,7 @@ let Shop = class Shop extends defaultClasses_1.TimeStamps {
52
53
  isShopDelivery;
53
54
  deliveryFee;
54
55
  minimumOrderAmount;
56
+ orderCapacityEnabled;
55
57
  orderCapacity;
56
58
  shopActiveTimingsOfCurrentDate;
57
59
  deliveryInfo;
@@ -61,11 +63,8 @@ let Shop = class Shop extends defaultClasses_1.TimeStamps {
61
63
  riderNote;
62
64
  defaultPreparationTime;
63
65
  exchangeRate;
64
- isFavouriteCategoryVisible;
65
- favouriteCategoryTitle;
66
- isBestSellerCategoryVisible;
67
- bestSellerCategoryTitle;
68
- orderCapacityEnabled;
66
+ bestSellerCategory;
67
+ favouritesCategory;
69
68
  avgRating;
70
69
  ordersCount;
71
70
  customersCount;
@@ -187,7 +186,11 @@ __decorate([
187
186
  __metadata("design:type", Number)
188
187
  ], Shop.prototype, "minimumOrderAmount", void 0);
189
188
  __decorate([
190
- (0, typegoose_1.prop)({ type: Number, default: Infinity }),
189
+ (0, typegoose_1.prop)({ type: Boolean, default: false }),
190
+ __metadata("design:type", Boolean)
191
+ ], Shop.prototype, "orderCapacityEnabled", void 0);
192
+ __decorate([
193
+ (0, typegoose_1.prop)({ type: Number }),
191
194
  __metadata("design:type", Number)
192
195
  ], Shop.prototype, "orderCapacity", void 0);
193
196
  __decorate([
@@ -219,29 +222,17 @@ __decorate([
219
222
  __metadata("design:type", Number)
220
223
  ], Shop.prototype, "defaultPreparationTime", void 0);
221
224
  __decorate([
222
- (0, typegoose_1.prop)({ type: Number, default: null }),
225
+ (0, typegoose_1.prop)({ type: Number, default: 0 }),
223
226
  __metadata("design:type", Number)
224
227
  ], Shop.prototype, "exchangeRate", void 0);
225
228
  __decorate([
226
- (0, typegoose_1.prop)({ required: false, type: () => Boolean }),
227
- __metadata("design:type", Boolean)
228
- ], Shop.prototype, "isFavouriteCategoryVisible", void 0);
229
+ (0, typegoose_1.prop)({ type: best_seller_category_model_1.BestSellerCategory, default: new best_seller_category_model_1.BestSellerCategory() }),
230
+ __metadata("design:type", best_seller_category_model_1.BestSellerCategory)
231
+ ], Shop.prototype, "bestSellerCategory", void 0);
229
232
  __decorate([
230
- (0, typegoose_1.prop)({ required: false, type: () => String }),
231
- __metadata("design:type", String)
232
- ], Shop.prototype, "favouriteCategoryTitle", void 0);
233
- __decorate([
234
- (0, typegoose_1.prop)({ required: false, type: () => Boolean }),
235
- __metadata("design:type", Boolean)
236
- ], Shop.prototype, "isBestSellerCategoryVisible", void 0);
237
- __decorate([
238
- (0, typegoose_1.prop)({ required: false, type: () => String }),
239
- __metadata("design:type", String)
240
- ], Shop.prototype, "bestSellerCategoryTitle", void 0);
241
- __decorate([
242
- (0, typegoose_1.prop)({ required: true, type: () => Boolean }),
243
- __metadata("design:type", Boolean)
244
- ], Shop.prototype, "orderCapacityEnabled", void 0);
233
+ (0, typegoose_1.prop)({ type: best_seller_category_model_1.FavouritesCategory, default: new best_seller_category_model_1.FavouritesCategory() }),
234
+ __metadata("design:type", best_seller_category_model_1.FavouritesCategory)
235
+ ], Shop.prototype, "favouritesCategory", void 0);
245
236
  __decorate([
246
237
  (0, typegoose_1.prop)({ default: 0, type: () => Number }),
247
238
  __metadata("design:type", Number)
@@ -1 +1 @@
1
- {"version":3,"file":"shop.model.js","sourceRoot":"/","sources":["libraries/mongo/models/shop.model.ts"],"names":[],"mappings":"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","sourcesContent":["import { modelOptions, prop, Ref, Severity, index, pre } from '@typegoose/typegoose';\nimport { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';\nimport { CounterType, ItemType, ShopOnlineStatus, Status } from '../../../utilities/enum';\nimport { Brand } from './brand.model';\nimport { ShopDocument } from './embedded/shop-document.model';\nimport { Parent } from './parent.model';\nimport { Address } from './shared/address.model';\nimport { StartEndTime, WorkHourSetting } from './shared/work-hour.model';\nimport { Tag } from './tag.model';\nimport { DeliveryInfo } from './embedded/delivery-info.model';\nimport { handleShopPreSave } from '../utilities/shop.hooks';\nimport { ShopSearchFields } from './embedded/shop-search-fields.model';\nimport { generateId } from '../../../utilities/id-generator';\nimport { CounterModel } from '.';\n\n@modelOptions({\n\tschemaOptions: { collection: 'shops' },\n\toptions: { allowMixed: Severity.ALLOW },\n})\n@index({ name: 1, itemType: 1 }, { unique: true, partialFilterExpression: { deletedAt: null } })\n@index({ parent: 1, status: 1, isVisibleToUser: 1 }, { partialFilterExpression: { deletedAt: null } })\n@index({ status: 1, createdAt: -1 }, { partialFilterExpression: { deletedAt: null } })\n@pre<Shop>('save', async function (next) {\n\tawait handleShopPreSave.call(this);\n\n\tnext();\n})\n\n@pre<Shop>('save', async function () {\n\tif (this.isNew) {\n\t\tthis.shopId = await generateId(CounterModel, CounterType.SHOP);\n\t}\n})\nexport class Shop extends TimeStamps {\n\t@prop({ type: String, unique: true, index: true })\n\tpublic shopId: string;\n\n\t@prop({ required: true, type: String })\n\tpublic name!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic ownerName!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic email!: string;\n\n\t@prop({ required: true, ref: () => Parent })\n\tpublic parent: Ref<Parent>;\n\n\t@prop({ required: true, type: String, enum: ItemType })\n\tpublic itemType!: ItemType;\n\n\t@prop({ required: true, type: String, enum: Status, default: Status.ACTIVE })\n\tpublic status!: Status;\n\n\t@prop({ required: true, ref: () => Brand })\n\tpublic brand: Ref<Brand>;\n\n\t@prop({ type: Number, default: 1, min: 1, max: 4 })\n\tpublic priceRange?: number;\n\n\t@prop({ required: true, type: String })\n\tpublic phoneNumber!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic userPhoneNumber!: string;\n\n\t@prop({ type: () => [String], default: [] })\n\tpublic additionalPhoneNumbers?: string[];\n\n\t@prop({ type: String, maxlength: 100 })\n\tpublic bobContactName?: string;\n\n\t@prop({ type: String, maxlength: 15 })\n\tpublic bobContactPhoneNumber?: string;\n\n\t@prop({ required: true, type: Address })\n\tpublic address!: Address;\n\n\t@prop({ type: String })\n\tpublic logo?: string;\n\n\t@prop({ type: String })\n\tpublic banner?: string;\n\n\t@prop({ type: ShopDocument })\n\tpublic document?: ShopDocument;\n\n\t@prop({\n\t\ttype: String,\n\t\tenum: ShopOnlineStatus,\n\t\tdefault: ShopOnlineStatus.OFFLINE,\n\t})\n\tpublic onlineStatus?: ShopOnlineStatus;\n\n\t@prop({ type: WorkHourSetting })\n\tpublic workHourSetting?: WorkHourSetting;\n\n\t@prop({ type: () => [String], default: [] })\n\tpublic dietaries?: string[];\n\n\t@prop({ ref: () => Tag, default: [] })\n\tpublic tags?: Ref<Tag>[];\n\n\t@prop({ required: true, type: Boolean })\n\tpublic isBeirutAuthentic!: boolean;\n\n\t@prop({ required: true, type: Boolean })\n\tpublic isVisibleToUser!: boolean;\n\n\t@prop({ type: Boolean, default: false })\n\tpublic isShopDelivery?: boolean;\n\n\t@prop({ type: Number })\n\tpublic deliveryFee?: number;\n\n\t@prop({ type: Number, default: 0 })\n\tpublic minimumOrderAmount?: number;\n\n\t@prop({ type: Number, default: Infinity })\n\tpublic orderCapacity?: number;\n\n\t@prop({ type: () => [StartEndTime], default: [] })\n\tpublic shopActiveTimingsOfCurrentDate?: StartEndTime[];\n\n\t@prop({ type: DeliveryInfo })\n\tpublic deliveryInfo?: DeliveryInfo;\n\n\t@prop({ type: Number })\n\tpublic sortingOrder?: number;\n\n\t// Setting\n\t@prop({ type: Boolean, default: false })\n\tpublic allowSpecialInstructions?: boolean;\n\n\t@prop({ type: Boolean, default: false })\n\tpublic isRiderNoteVisible?: boolean;\n\n\t@prop({ type: String })\n\tpublic riderNote?: string;\n\n\t@prop({ type: Number, default: 10 })\n\tpublic defaultPreparationTime?: number;\n\n\t@prop({ type: Number, default: null })\n\texchangeRate?: number;\n\n\t@prop({ required: false, type: () => Boolean })\n\tpublic isFavouriteCategoryVisible?: boolean;\n\n\t@prop({ required: false, type: () => String })\n\tpublic favouriteCategoryTitle?: string;\n\n\t@prop({ required: false, type: () => Boolean })\n\tpublic isBestSellerCategoryVisible?: boolean;\n\n\t@prop({ required: false, type: () => String })\n\tpublic bestSellerCategoryTitle?: string;\n\n\t@prop({ required: true, type: () => Boolean })\n\tpublic orderCapacityEnabled!: boolean;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic avgRating?: number;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic ordersCount?: number;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic customersCount?: number;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic vat_reg_number?: number;\n\n\t@prop({ type: () => [String], default: [] })\n\tpublic fcmTokens?: string[];\n\n\t@prop({ type: ShopSearchFields })\n\tpublic searchFields?: ShopSearchFields\n}\n"]}
1
+ {"version":3,"file":"shop.model.js","sourceRoot":"/","sources":["libraries/mongo/models/shop.model.ts"],"names":[],"mappings":"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","sourcesContent":["import { modelOptions, prop, Ref, Severity, index, pre } from '@typegoose/typegoose';\nimport { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';\nimport { CounterType, ItemType, ShopOnlineStatus, Status } from '../../../utilities/enum';\nimport { Brand } from './brand.model';\nimport { ShopDocument } from './embedded/shop-document.model';\nimport { Parent } from './parent.model';\nimport { Address } from './shared/address.model';\nimport { StartEndTime, WorkHourSetting } from './shared/work-hour.model';\nimport { Tag } from './tag.model';\nimport { DeliveryInfo } from './embedded/delivery-info.model';\nimport { handleShopPreSave } from '../utilities/shop.hooks';\nimport { ShopSearchFields } from './embedded/shop-search-fields.model';\nimport { generateId } from '../../../utilities/id-generator';\nimport { CounterModel } from '.';\nimport { BestSellerCategory, FavouritesCategory } from './embedded/best-seller-category.model';\n\n@modelOptions({\n\tschemaOptions: { collection: 'shops' },\n\toptions: { allowMixed: Severity.ALLOW },\n})\n@index({ name: 1, itemType: 1 }, { unique: true, partialFilterExpression: { deletedAt: null } })\n@index({ parent: 1, status: 1, isVisibleToUser: 1 }, { partialFilterExpression: { deletedAt: null } })\n@index({ status: 1, createdAt: -1 }, { partialFilterExpression: { deletedAt: null } })\n@pre<Shop>('save', async function (next) {\n\tawait handleShopPreSave.call(this);\n\n\tnext();\n})\n@pre<Shop>('save', async function () {\n\tif (this.isNew) {\n\t\tthis.shopId = await generateId(CounterModel, CounterType.SHOP);\n\t}\n})\nexport class Shop extends TimeStamps {\n\t@prop({ type: String, unique: true, index: true })\n\tpublic shopId: string;\n\n\t@prop({ required: true, type: String })\n\tpublic name!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic ownerName!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic email!: string;\n\n\t@prop({ required: true, ref: () => Parent })\n\tpublic parent: Ref<Parent>;\n\n\t@prop({ required: true, type: String, enum: ItemType })\n\tpublic itemType!: ItemType;\n\n\t@prop({ required: true, type: String, enum: Status, default: Status.ACTIVE })\n\tpublic status!: Status;\n\n\t@prop({ required: true, ref: () => Brand })\n\tpublic brand: Ref<Brand>;\n\n\t@prop({ type: Number, default: 1, min: 1, max: 4 })\n\tpublic priceRange?: number;\n\n\t@prop({ required: true, type: String })\n\tpublic phoneNumber!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic userPhoneNumber!: string;\n\n\t@prop({ type: () => [String], default: [] })\n\tpublic additionalPhoneNumbers?: string[];\n\n\t@prop({ type: String, maxlength: 100 })\n\tpublic bobContactName?: string;\n\n\t@prop({ type: String, maxlength: 15 })\n\tpublic bobContactPhoneNumber?: string;\n\n\t@prop({ required: true, type: Address })\n\tpublic address!: Address;\n\n\t@prop({ type: String })\n\tpublic logo?: string;\n\n\t@prop({ type: String })\n\tpublic banner?: string;\n\n\t@prop({ type: ShopDocument })\n\tpublic document?: ShopDocument;\n\n\t@prop({\n\t\ttype: String,\n\t\tenum: ShopOnlineStatus,\n\t\tdefault: ShopOnlineStatus.OFFLINE,\n\t})\n\tpublic onlineStatus?: ShopOnlineStatus;\n\n\t@prop({ type: WorkHourSetting })\n\tpublic workHourSetting?: WorkHourSetting;\n\n\t@prop({ type: () => [String], default: [] })\n\tpublic dietaries?: string[];\n\n\t@prop({ ref: () => Tag, default: [] })\n\tpublic tags?: Ref<Tag>[];\n\n\t@prop({ required: true, type: Boolean })\n\tpublic isBeirutAuthentic!: boolean;\n\n\t@prop({ required: true, type: Boolean })\n\tpublic isVisibleToUser!: boolean;\n\n\t@prop({ type: Boolean, default: false })\n\tpublic isShopDelivery?: boolean;\n\n\t@prop({ type: Number })\n\tpublic deliveryFee?: number;\n\n\t@prop({ type: Number, default: 0 })\n\tpublic minimumOrderAmount?: number;\n\n\t@prop({ type: Boolean, default: false })\n\tpublic orderCapacityEnabled?: boolean;\n\n\t@prop({ type: Number })\n\tpublic orderCapacity?: number;\n\n\t@prop({ type: () => [StartEndTime], default: [] })\n\tpublic shopActiveTimingsOfCurrentDate?: StartEndTime[];\n\n\t@prop({ type: DeliveryInfo })\n\tpublic deliveryInfo?: DeliveryInfo;\n\n\t@prop({ type: Number })\n\tpublic sortingOrder?: number;\n\n\t// Setting\n\t@prop({ type: Boolean, default: false })\n\tpublic allowSpecialInstructions?: boolean;\n\n\t@prop({ type: Boolean, default: false })\n\tpublic isRiderNoteVisible?: boolean;\n\n\t@prop({ type: String })\n\tpublic riderNote?: string;\n\n\t@prop({ type: Number, default: 10 })\n\tpublic defaultPreparationTime?: number;\n\n\t@prop({ type: Number, default: 0 })\n\tpublic exchangeRate?: number;\n\n\t// Best seller category\n\t@prop({ type: BestSellerCategory, default: new BestSellerCategory() })\n\tpublic bestSellerCategory?: BestSellerCategory;\n\n\t// Favourites category\n\t@prop({ type: FavouritesCategory, default: new FavouritesCategory() })\n\tpublic favouritesCategory?: FavouritesCategory;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic avgRating?: number;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic ordersCount?: number;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic customersCount?: number;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic vat_reg_number?: number;\n\n\t@prop({ type: () => [String], default: [] })\n\tpublic fcmTokens?: string[];\n\n\t@prop({ type: ShopSearchFields })\n\tpublic searchFields?: ShopSearchFields;\n}\n"]}
@@ -7,7 +7,7 @@ import { StartEndTime, WorkHourSetting } from './shared/work-hour.model';
7
7
  import { Tag } from './tag.model';
8
8
  import { Zone } from './zone.model';
9
9
  import { VendorParent } from '.';
10
- import { Service } from "./service.model";
10
+ import { Service } from './service.model';
11
11
  import { ServiceOrderSettings } from './embedded/service-order-settings.model';
12
12
  import { CleaningServiceSettings } from './embedded/cleaning-service-settings.model';
13
13
  export declare class Vendor extends TimeStamps {
@@ -30,9 +30,6 @@ export declare class Vendor extends TimeStamps {
30
30
  tags?: Ref<Tag>[];
31
31
  isVisibleToUser: boolean;
32
32
  sortingOrder?: number;
33
- isFavouriteCategoryVisible?: boolean;
34
- favouriteCategoryTitle?: string;
35
- isBestSellerCategoryVisible?: boolean;
36
33
  avgRating?: number;
37
34
  ordersCount?: number;
38
35
  customersCount?: number;
@@ -46,9 +46,6 @@ let Vendor = class Vendor extends defaultClasses_1.TimeStamps {
46
46
  tags;
47
47
  isVisibleToUser;
48
48
  sortingOrder;
49
- isFavouriteCategoryVisible;
50
- favouriteCategoryTitle;
51
- isBestSellerCategoryVisible;
52
49
  avgRating;
53
50
  ordersCount;
54
51
  customersCount;
@@ -133,18 +130,6 @@ __decorate([
133
130
  (0, typegoose_1.prop)({ type: Number }),
134
131
  __metadata("design:type", Number)
135
132
  ], Vendor.prototype, "sortingOrder", void 0);
136
- __decorate([
137
- (0, typegoose_1.prop)({ required: false, type: () => Boolean }),
138
- __metadata("design:type", Boolean)
139
- ], Vendor.prototype, "isFavouriteCategoryVisible", void 0);
140
- __decorate([
141
- (0, typegoose_1.prop)({ required: false, type: () => String }),
142
- __metadata("design:type", String)
143
- ], Vendor.prototype, "favouriteCategoryTitle", void 0);
144
- __decorate([
145
- (0, typegoose_1.prop)({ required: false, type: () => Boolean }),
146
- __metadata("design:type", Boolean)
147
- ], Vendor.prototype, "isBestSellerCategoryVisible", void 0);
148
133
  __decorate([
149
134
  (0, typegoose_1.prop)({ default: 0, type: () => Number }),
150
135
  __metadata("design:type", Number)
@@ -1 +1 @@
1
- {"version":3,"file":"vendor.model.js","sourceRoot":"/","sources":["libraries/mongo/models/vendor.model.ts"],"names":[],"mappings":"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","sourcesContent":["import { modelOptions, prop, Ref, Severity, Index, pre } from '@typegoose/typegoose';\nimport { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';\nimport { Status } from '../../../utilities/enum';\nimport { ShopDocument } from './embedded/shop-document.model';\nimport { Address } from './shared/address.model';\nimport { StartEndTime, WorkHourSetting } from './shared/work-hour.model';\nimport { Tag } from './tag.model';\nimport { Zone } from './zone.model';\nimport { VendorParent, VendorModel } from '.';\nimport slugify from 'slugify';\nimport { Service } from \"./service.model\";\nimport { ServiceOrderSettings } from './embedded/service-order-settings.model';\nimport { CleaningServiceSettings } from './embedded/cleaning-service-settings.model';\n\n@modelOptions({\n\tschemaOptions: { collection: 'vendors' },\n\toptions: { allowMixed: Severity.ALLOW },\n})\n@Index({ name: 1, itemType: 1 }, { unique: true, partialFilterExpression: { deletedAt: null } })\n@Index({ parent: 1, status: 1, isVisibleToUser: 1, deletedAt: 1 })\n@pre<Vendor>('save', async function (next) {\n\t// Only set sortingOrder if it's a new document or sortingOrder is not set\n\tif (this.isNew || typeof this.sortingOrder === 'undefined') {\n\t\ttry {\n\t\t\t// Find the maximum sortingOrder for shops with the same itemType that aren't deleted\n\t\t\tconst maxSortingOrder = await VendorModel.aggregate<{ maxSortingOrder: number }>([\n\t\t\t\t{\n\t\t\t\t\t$group: {\n\t\t\t\t\t\t_id: null,\n\t\t\t\t\t\tmaxSortingOrder: { $max: '$sortingOrder' },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]).exec();\n\n\t\t\t// Set the new sortingOrder to max + 1 (or 0 if no items found)\n\t\t\tthis.sortingOrder = (maxSortingOrder[0]?.maxSortingOrder ?? -1) + 1;\n\t\t} catch (error) {\n\t\t\treturn next(error as Error);\n\t\t}\n\t}\n\ttry {\n\t\tif (this.isNew) {\n\t\t\tconst baseSlug = slugify(this.name, { lower: true, strict: true });\n\t\t\tlet slug = baseSlug;\n\t\t\tlet count = 0;\n\t\t\twhile (await VendorModel.exists({ slug })) {\n\t\t\t\tcount++;\n\t\t\t\tslug = `${baseSlug}-${count}`;\n\t\t\t}\n\t\t\tthis.slug = slug;\n\t\t}\n\t\tnext();\n\t} catch (error) {\n\t\tnext(error as Error);\n\t}\n\tnext();\n})\nexport class Vendor extends TimeStamps {\n\t@prop({ required: true, type: String })\n\tpublic name!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic ownerName!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic email!: string;\n\n\t@prop({ unique: true, type: String })\n\tpublic slug?: string;\n\n\t@prop({ required: true, ref: () => VendorParent })\n\tpublic parent: Ref<VendorParent>;\n\n\t@prop({ required: true, ref: () => Service })\n\tpublic service: Ref<Service>\n\n\t@prop({ required: true, type: String, enum: Status, default: Status.ACTIVE })\n\tpublic status!: Status;\n\n\t@prop({ required: true, type: String })\n\tpublic phoneNumber!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic userPhoneNumber!: string;\n\n\t@prop({ type: () => [String], default: [] })\n\tpublic additionalPhoneNumbers?: string[];\n\n\t@prop({ required: true, type: Address })\n\tpublic address!: Address;\n\n\t@prop({ required: true, ref: () => Zone, type: () => [String] })\n\tpublic zone!: Ref<Zone>[];\n\n\t@prop({ type: String })\n\tpublic logo?: string;\n\n\t@prop({ type: String })\n\tpublic banner?: string;\n\n\t@prop({ type: ShopDocument })\n\tpublic document?: ShopDocument;\n\n\t@prop({ type: () => [StartEndTime], default: [] })\n\tpublic vendorActiveTimingsOfCurrentDate?: StartEndTime[];\n\n\t@prop({ ref: () => Tag, default: [] })\n\tpublic tags?: Ref<Tag>[];\n\n\t@prop({ required: true, type: Boolean })\n\tpublic isVisibleToUser!: boolean;\n\n\t@prop({ type: Number })\n\tpublic sortingOrder?: number;\n\n\t@prop({ required: false, type: () => Boolean })\n\tpublic isFavouriteCategoryVisible?: boolean;\n\n\t@prop({ required: false, type: () => String })\n\tpublic favouriteCategoryTitle?: string;\n\n\t@prop({ required: false, type: () => Boolean })\n\tpublic isBestSellerCategoryVisible?: boolean;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic avgRating?: number;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic ordersCount?: number\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic customersCount?: number\n\n\t@prop({ type: () => ServiceOrderSettings })\n\tpublic orderSettings?: ServiceOrderSettings\n\n\t@prop({type: ()=> CleaningServiceSettings})\n\tpublic cleaningServiceSettings?: CleaningServiceSettings\n\n\t@prop({ type: WorkHourSetting })\n\tpublic workHourSetting?: WorkHourSetting;\n}\n"]}
1
+ {"version":3,"file":"vendor.model.js","sourceRoot":"/","sources":["libraries/mongo/models/vendor.model.ts"],"names":[],"mappings":"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","sourcesContent":["import { modelOptions, prop, Ref, Severity, Index, pre } from '@typegoose/typegoose';\nimport { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';\nimport { Status } from '../../../utilities/enum';\nimport { ShopDocument } from './embedded/shop-document.model';\nimport { Address } from './shared/address.model';\nimport { StartEndTime, WorkHourSetting } from './shared/work-hour.model';\nimport { Tag } from './tag.model';\nimport { Zone } from './zone.model';\nimport { VendorParent, VendorModel } from '.';\nimport slugify from 'slugify';\nimport { Service } from './service.model';\nimport { ServiceOrderSettings } from './embedded/service-order-settings.model';\nimport { CleaningServiceSettings } from './embedded/cleaning-service-settings.model';\n\n@modelOptions({\n\tschemaOptions: { collection: 'vendors' },\n\toptions: { allowMixed: Severity.ALLOW },\n})\n@Index({ name: 1, itemType: 1 }, { unique: true, partialFilterExpression: { deletedAt: null } })\n@Index({ parent: 1, status: 1, isVisibleToUser: 1, deletedAt: 1 })\n@pre<Vendor>('save', async function (next) {\n\t// Only set sortingOrder if it's a new document or sortingOrder is not set\n\tif (this.isNew || typeof this.sortingOrder === 'undefined') {\n\t\ttry {\n\t\t\t// Find the maximum sortingOrder for shops with the same itemType that aren't deleted\n\t\t\tconst maxSortingOrder = await VendorModel.aggregate<{ maxSortingOrder: number }>([\n\t\t\t\t{\n\t\t\t\t\t$group: {\n\t\t\t\t\t\t_id: null,\n\t\t\t\t\t\tmaxSortingOrder: { $max: '$sortingOrder' },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t]).exec();\n\n\t\t\t// Set the new sortingOrder to max + 1 (or 0 if no items found)\n\t\t\tthis.sortingOrder = (maxSortingOrder[0]?.maxSortingOrder ?? -1) + 1;\n\t\t} catch (error) {\n\t\t\treturn next(error as Error);\n\t\t}\n\t}\n\ttry {\n\t\tif (this.isNew) {\n\t\t\tconst baseSlug = slugify(this.name, { lower: true, strict: true });\n\t\t\tlet slug = baseSlug;\n\t\t\tlet count = 0;\n\t\t\twhile (await VendorModel.exists({ slug })) {\n\t\t\t\tcount++;\n\t\t\t\tslug = `${baseSlug}-${count}`;\n\t\t\t}\n\t\t\tthis.slug = slug;\n\t\t}\n\t\tnext();\n\t} catch (error) {\n\t\tnext(error as Error);\n\t}\n\tnext();\n})\nexport class Vendor extends TimeStamps {\n\t@prop({ required: true, type: String })\n\tpublic name!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic ownerName!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic email!: string;\n\n\t@prop({ unique: true, type: String })\n\tpublic slug?: string;\n\n\t@prop({ required: true, ref: () => VendorParent })\n\tpublic parent: Ref<VendorParent>;\n\n\t@prop({ required: true, ref: () => Service })\n\tpublic service: Ref<Service>;\n\n\t@prop({ required: true, type: String, enum: Status, default: Status.ACTIVE })\n\tpublic status!: Status;\n\n\t@prop({ required: true, type: String })\n\tpublic phoneNumber!: string;\n\n\t@prop({ required: true, type: String })\n\tpublic userPhoneNumber!: string;\n\n\t@prop({ type: () => [String], default: [] })\n\tpublic additionalPhoneNumbers?: string[];\n\n\t@prop({ required: true, type: Address })\n\tpublic address!: Address;\n\n\t@prop({ required: true, ref: () => Zone, type: () => [String] })\n\tpublic zone!: Ref<Zone>[];\n\n\t@prop({ type: String })\n\tpublic logo?: string;\n\n\t@prop({ type: String })\n\tpublic banner?: string;\n\n\t@prop({ type: ShopDocument })\n\tpublic document?: ShopDocument;\n\n\t@prop({ type: () => [StartEndTime], default: [] })\n\tpublic vendorActiveTimingsOfCurrentDate?: StartEndTime[];\n\n\t@prop({ ref: () => Tag, default: [] })\n\tpublic tags?: Ref<Tag>[];\n\n\t@prop({ required: true, type: Boolean })\n\tpublic isVisibleToUser!: boolean;\n\n\t@prop({ type: Number })\n\tpublic sortingOrder?: number;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic avgRating?: number;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic ordersCount?: number;\n\n\t@prop({ default: 0, type: () => Number })\n\tpublic customersCount?: number;\n\n\t@prop({ type: () => ServiceOrderSettings })\n\tpublic orderSettings?: ServiceOrderSettings;\n\n\t@prop({ type: () => CleaningServiceSettings })\n\tpublic cleaningServiceSettings?: CleaningServiceSettings;\n\n\t@prop({ type: WorkHourSetting })\n\tpublic workHourSetting?: WorkHourSetting;\n}\n"]}
@@ -22,7 +22,7 @@ Perfect for sharing types between frontend and backend applications.
22
22
 
23
23
  ## Version
24
24
 
25
- Version: 1.1.66
25
+ Version: 1.1.68
26
26
 
27
27
  ## Dependencies
28
28
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lyxa.ai/types",
3
- "version": "1.1.66",
3
+ "version": "1.1.68",
4
4
  "description": "Lyxa type definitions and validation schemas for both frontend and backend",
5
5
  "author": "elie <42282499+Internalizable@users.noreply.github.com>",
6
6
  "license": "MIT",
@@ -1,10 +1,11 @@
1
1
  import { z, ZodTypeAny } from 'zod';
2
2
  type ReadonlyNonEmptyArray<T> = readonly [T, ...T[]];
3
- export interface FilterSchemaConfig<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}> {
3
+ export interface FilterSchemaConfig<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}, TSort extends ReadonlyNonEmptyArray<string> | [] = []> {
4
4
  selectableFields?: TSelect;
5
5
  populatableFields?: TPopulate;
6
6
  searchableFields?: TSearch;
7
7
  queryableFields?: TQuery;
8
+ sortableFields?: TSort;
8
9
  maxSize?: number;
9
10
  defaultSize?: number;
10
11
  }
@@ -21,10 +22,10 @@ export type PopulateObject<TPath extends string, TSelectFields extends ReadonlyN
21
22
  type PopulateUnion<TPopulate extends Record<string, ReadonlyNonEmptyArray<string>>> = {
22
23
  [K in keyof TPopulate]: PopulateObject<K & string, TPopulate[K]>;
23
24
  }[keyof TPopulate];
24
- export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}> = {
25
+ export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}, TSort extends ReadonlyNonEmptyArray<string> | [] = []> = {
25
26
  size?: number;
26
27
  page?: number;
27
- sort?: Record<string, 1 | -1>;
28
+ sort?: TSort extends ReadonlyNonEmptyArray<string> ? Partial<Record<TSort[number], 1 | -1>> : never;
28
29
  select?: TSelect extends ReadonlyNonEmptyArray<string> ? Partial<Record<TSelect[number], 0 | 1>> : never;
29
30
  populate?: PopulateUnion<TPopulate>[];
30
31
  search?: TSearch extends ReadonlyNonEmptyArray<string> ? {
@@ -35,5 +36,5 @@ export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], T
35
36
  [K in keyof TQuery]?: z.infer<TQuery[K]>;
36
37
  };
37
38
  };
38
- export declare function createFilterSchema<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}>(config: FilterSchemaConfig<TSelect, TPopulate, TSearch, TQuery>): z.ZodType<FilterDTO<TSelect, TPopulate, TSearch, TQuery>>;
39
+ export declare function createFilterSchema<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}, TSort extends ReadonlyNonEmptyArray<string> | [] = []>(config: FilterSchemaConfig<TSelect, TPopulate, TSearch, TQuery, TSort>): z.ZodType<FilterDTO<TSelect, TPopulate, TSearch, TQuery, TSort>>;
39
40
  export {};
@@ -4,13 +4,17 @@ exports.createFilterSchema = createFilterSchema;
4
4
  const zod_1 = require("zod");
5
5
  const sortSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.union([zod_1.z.literal(1), zod_1.z.literal(-1)]));
6
6
  function createFilterSchema(config) {
7
- const { selectableFields, populatableFields, searchableFields, queryableFields, maxSize = 100, defaultSize = 10, } = config;
7
+ const { selectableFields, populatableFields, searchableFields, queryableFields, sortableFields, maxSize = 100, defaultSize = 10, } = config;
8
8
  const populateKeys = populatableFields ? Object.keys(populatableFields) : [];
9
9
  const schemaShape = {
10
10
  size: zod_1.z.number().min(1).max(maxSize).optional().default(defaultSize),
11
11
  page: zod_1.z.number().min(1).optional().default(1),
12
- sort: sortSchema.optional(),
13
12
  };
13
+ if (sortableFields?.length) {
14
+ schemaShape.sort = zod_1.z
15
+ .record(zod_1.z.enum([...sortableFields]), zod_1.z.union([zod_1.z.literal(1), zod_1.z.literal(-1)]))
16
+ .optional();
17
+ }
14
18
  if (selectableFields?.length) {
15
19
  schemaShape.select = zod_1.z
16
20
  .record(zod_1.z.enum([...selectableFields]), zod_1.z.union([zod_1.z.literal(0), zod_1.z.literal(1)]))
@@ -59,14 +63,7 @@ function createFilterSchema(config) {
59
63
  return zod_1.z.object(schemaShape);
60
64
  }
61
65
  const TicketFilterSchema = createFilterSchema({
62
- selectableFields: [
63
- '_id',
64
- 'ticketId',
65
- 'type',
66
- 'status',
67
- 'createdAt',
68
- 'updatedAt',
69
- ],
66
+ selectableFields: ['_id', 'ticketId', 'type', 'status', 'createdAt', 'updatedAt'],
70
67
  populatableFields: {
71
68
  chatroom: ['_id', 'lastMessage', 'participants', 'unreadCount'],
72
69
  client: ['_id', 'name', 'profilePhoto', 'type'],
@@ -74,6 +71,7 @@ const TicketFilterSchema = createFilterSchema({
74
71
  order: ['_id', 'orderId', 'shop', 'total'],
75
72
  },
76
73
  searchableFields: ['ticketId'],
74
+ sortableFields: ['createdAt', 'updatedAt', 'ticketId', 'status'],
77
75
  queryableFields: {
78
76
  status: zod_1.z.enum(['OPEN', 'CLOSED', 'PENDING']),
79
77
  type: zod_1.z.enum(['ORDER', 'GENERAL', 'COMPLAINT']),
@@ -81,5 +79,7 @@ const TicketFilterSchema = createFilterSchema({
81
79
  clientType: zod_1.z.enum(['USER', 'SHOP']),
82
80
  },
83
81
  });
84
- const ticket = {};
82
+ const ticket = {
83
+ sort: { createdAt: -1, status: 1 },
84
+ };
85
85
  //# sourceMappingURL=filter-schema.factory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-schema.factory.js","sourceRoot":"/","sources":["utilities/validation/filter-schema.factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { z, ZodTypeAny } from 'zod';\n\ntype ReadonlyNonEmptyArray<T> = readonly [T, ...T[]];\n\nexport interface FilterSchemaConfig<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n> {\n\tselectableFields?: TSelect;\n\tpopulatableFields?: TPopulate;\n\tsearchableFields?: TSearch;\n\tqueryableFields?: TQuery;\n\tmaxSize?: number;\n\tdefaultSize?: number;\n}\n\n// Populate object type\nexport type PopulateObject<\n\tTPath extends string,\n\tTSelectFields extends ReadonlyNonEmptyArray<string>\n> = {\n\tpath: TPath;\n\tselect?: Partial<Record<TSelectFields[number], 0 | 1>>;\n\tmatch?: Record<string, any>;\n\toptions?: { sort?: Record<string, 1 | -1>; limit?: number; skip?: number };\n};\n\n// Union of all possible populate objects based on populatableFields\ntype PopulateUnion<TPopulate extends Record<string, ReadonlyNonEmptyArray<string>>> = {\n\t[K in keyof TPopulate]: PopulateObject<K & string, TPopulate[K]>;\n}[keyof TPopulate];\n\n// DTO type\nexport type FilterDTO<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n> = {\n\tsize?: number;\n\tpage?: number;\n\tsort?: Record<string, 1 | -1>;\n\tselect?: TSelect extends ReadonlyNonEmptyArray<string>\n\t\t? Partial<Record<TSelect[number], 0 | 1>>\n\t\t: never;\n\tpopulate?: PopulateUnion<TPopulate>[];\n\tsearch?: TSearch extends ReadonlyNonEmptyArray<string>\n\t\t? { searchKey: string; searchFields?: TSearch[number][] }\n\t\t: never;\n\tquery?: { [K in keyof TQuery]?: z.infer<TQuery[K]> };\n};\n\nconst sortSchema = z.record(z.string(), z.union([z.literal(1), z.literal(-1)]));\n\nexport function createFilterSchema<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n>(config: FilterSchemaConfig<TSelect, TPopulate, TSearch, TQuery>) {\n\tconst {\n\t\tselectableFields,\n\t\tpopulatableFields,\n\t\tsearchableFields,\n\t\tqueryableFields,\n\t\tmaxSize = 100,\n\t\tdefaultSize = 10,\n\t} = config;\n\n\tconst populateKeys = populatableFields ? (Object.keys(populatableFields) as (keyof TPopulate)[]) : [];\n\n\tconst schemaShape: Record<string, any> = {\n\t\tsize: z.number().min(1).max(maxSize).optional().default(defaultSize),\n\t\tpage: z.number().min(1).optional().default(1),\n\t\tsort: sortSchema.optional(),\n\t};\n\n\t// Top-level select\n\tif (selectableFields?.length) {\n\t\tschemaShape.select = z\n\t\t\t.record(\n\t\t\t\tz.enum([...selectableFields] as [string, ...string[]]),\n\t\t\t\tz.union([z.literal(0), z.literal(1)]),\n\t\t\t)\n\t\t\t.optional();\n\t}\n\n\t// Populate as array of objects with strict typing per path\n\tif (populateKeys.length) {\n\t\tconst populateSchemas: ZodTypeAny[] = [];\n\n\t\tfor (const path of populateKeys) {\n\t\t\tconst allowedSelects = populatableFields![path] as ReadonlyNonEmptyArray<string>;\n\n\t\t\tconst populateSchema = z.object({\n\t\t\t\tpath: z.literal(path as string),\n\t\t\t\tselect: z\n\t\t\t\t\t.record(z.enum([...allowedSelects] as [string, ...string[]]), z.union([z.literal(0), z.literal(1)]))\n\t\t\t\t\t.optional(),\n\t\t\t\tmatch: z.record(z.string(), z.any()).optional(),\n\t\t\t\toptions: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\tsort: sortSchema.optional(),\n\t\t\t\t\t\tlimit: z.number().optional(),\n\t\t\t\t\t\tskip: z.number().optional(),\n\t\t\t\t\t})\n\t\t\t\t\t.optional(),\n\t\t\t});\n\n\t\t\tpopulateSchemas.push(populateSchema);\n\t\t}\n\n\t\tconst unionSchema =\n\t\t\tpopulateSchemas.length === 1\n\t\t\t\t? populateSchemas[0]\n\t\t\t\t: z.union(populateSchemas as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]);\n\n\t\tschemaShape.populate = z.array(unionSchema).optional();\n\t}\n\n\t// Search\n\tif (searchableFields?.length) {\n\t\tschemaShape.search = z\n\t\t\t.object({\n\t\t\t\tsearchKey: z.string(),\n\t\t\t\tsearchFields: z.array(z.enum([...searchableFields] as [string, ...string[]])).optional(),\n\t\t\t})\n\t\t\t.optional();\n\t}\n\n\t// Query\n\tif (queryableFields && Object.keys(queryableFields).length) {\n\t\tconst queryShape: Record<string, ZodTypeAny> = {};\n\t\tfor (const key in queryableFields) {\n\t\t\tqueryShape[key] = queryableFields[key].optional();\n\t\t}\n\t\tschemaShape.query = z.object(queryShape).optional();\n\t}\n\n\treturn z.object(schemaShape) as z.ZodType<FilterDTO<TSelect, TPopulate, TSearch, TQuery>>;\n}\n\n\nconst TicketFilterSchema = createFilterSchema({\n\t// Top-level document fields that can be selected\n\tselectableFields: [\n\t\t'_id',\n\t\t'ticketId',\n\t\t'type',\n\t\t'status',\n\t\t'createdAt',\n\t\t'updatedAt',\n\t] as const,\n\n\t// Each populate path has its own allowed select fields\n\tpopulatableFields: {\n\t\tchatroom: ['_id', 'lastMessage', 'participants', 'unreadCount'] as const,\n\t\tclient: ['_id', 'name', 'profilePhoto', 'type'] as const,\n\t\tadmin: ['_id', 'name', 'profilePhoto'] as const,\n\t\torder: ['_id', 'orderId', 'shop', 'total'] as const,\n\t} as const,\n\n\tsearchableFields: ['ticketId'] as const,\n\n\tqueryableFields: {\n\t\tstatus: z.enum(['OPEN', 'CLOSED', 'PENDING']),\n\t\ttype: z.enum(['ORDER', 'GENERAL', 'COMPLAINT']),\n\t\tclient: z.string(),\n\t\tclientType: z.enum(['USER', 'SHOP']),\n\t},\n});\n\ntype TicketFilterDTO = z.infer<typeof TicketFilterSchema>;\n\nconst ticket: TicketFilterDTO = {\n\n}\n\n\n/**\n * EXAMPLE USAGE\n *\n * const TicketFilterSchema = createFilterSchema({\n * // Top-level document fields that can be selected\n * selectableFields: [\n * '_id',\n * 'ticketId',\n * 'type',\n * 'status',\n * 'createdAt',\n * 'updatedAt',\n * ] as const,\n *\n * // Each populate path has its own allowed select fields\n * populatableFields: {\n * chatroom: ['_id', 'lastMessage', 'participants', 'unreadCount'] as const,\n * client: ['_id', 'name', 'profilePhoto', 'type'] as const,\n * admin: ['_id', 'name', 'profilePhoto'] as const,\n * order: ['_id', 'orderId', 'shop', 'total'] as const,\n * } as const,\n *\n * searchableFields: ['ticketId'] as const,\n *\n * queryableFields: {\n * status: z.enum(['OPEN', 'CLOSED', 'PENDING']),\n * type: z.enum(['ORDER', 'GENERAL', 'COMPLAINT']),\n * client: z.string(),\n * clientType: z.enum(['USER', 'SHOP']),\n * },\n * });\n *\n * type TicketFilterDTO = z.infer<typeof TicketFilterSchema>;\n *\n * // ✅ VALID EXAMPLES\n *\n * // Example 1: Select only top-level fields\n * const filter1: TicketFilterDTO = {\n * select: { ticketId: 1, status: 1, createdAt: 1 },\n * query: { status: 'OPEN' },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 2: Populate client with specific fields\n * const filter2: TicketFilterDTO = {\n * populate: {\n * path: 'client',\n * select: { name: 1, profilePhoto: 1 }, // Uses client's allowed fields\n * },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 3: Populate multiple relations\n * const filter3: TicketFilterDTO = {\n * populate: [\n * { path: 'client', select: { name: 1, profilePhoto: 1 } },\n * { path: 'order', select: { orderId: 1, total: 1 } },\n * { path: 'chatroom', select: { lastMessage: 1, unreadCount: 1 } },\n * ],\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 4: Complex query with search\n * const filter4: TicketFilterDTO = {\n * query: { status: 'OPEN', type: 'ORDER' },\n * search: { searchKey: 'TKT-123', searchFields: ['ticketId'] },\n * populate: { path: 'client', select: { name: 1 } },\n * sort: { createdAt: -1 },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 5: Populate with match and options\n * const filter5: TicketFilterDTO = {\n * populate: {\n * path: 'order',\n * select: { orderId: 1, shop: 1 },\n * match: { status: 'DELIVERED' },\n * options: { sort: { createdAt: -1 }, limit: 10 },\n * },\n * page: 1,\n * size: 20,\n * };\n *\n * // ❌ INVALID EXAMPLES (TypeScript will reject)\n *\n * const invalid1: TicketFilterDTO = {\n * select: { invalidField: 1 }, // ❌ not in selectableFields\n * };\n *\n * const invalid2: TicketFilterDTO = {\n * populate: {\n * path: 'client',\n * select: { email: 1 }, // ❌ email not in client's populatableFields\n * },\n * };\n *\n * const invalid3: TicketFilterDTO = {\n * populate: {\n * path: 'invalidPath', // ❌ path doesn't exist\n * select: { name: 1 },\n * },\n * };\n *\n * const invalid4: TicketFilterDTO = {\n * query: { status: 'INVALID_STATUS' }, // ❌ not in enum\n * }\n */"]}
1
+ {"version":3,"file":"filter-schema.factory.js","sourceRoot":"/","sources":["utilities/validation/filter-schema.factory.ts"],"names":[],"mappings":"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","sourcesContent":["import { z, ZodTypeAny } from 'zod';\n\ntype ReadonlyNonEmptyArray<T> = readonly [T, ...T[]];\n\nexport interface FilterSchemaConfig<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n\tTSort extends ReadonlyNonEmptyArray<string> | [] = [],\n> {\n\tselectableFields?: TSelect;\n\tpopulatableFields?: TPopulate;\n\tsearchableFields?: TSearch;\n\tqueryableFields?: TQuery;\n\tsortableFields?: TSort;\n\tmaxSize?: number;\n\tdefaultSize?: number;\n}\n\n// Populate object type\nexport type PopulateObject<TPath extends string, TSelectFields extends ReadonlyNonEmptyArray<string>> = {\n\tpath: TPath;\n\tselect?: Partial<Record<TSelectFields[number], 0 | 1>>;\n\tmatch?: Record<string, any>;\n\toptions?: { sort?: Record<string, 1 | -1>; limit?: number; skip?: number };\n};\n\n// Union of all possible populate objects based on populatableFields\ntype PopulateUnion<TPopulate extends Record<string, ReadonlyNonEmptyArray<string>>> = {\n\t[K in keyof TPopulate]: PopulateObject<K & string, TPopulate[K]>;\n}[keyof TPopulate];\n\n// DTO type\nexport type FilterDTO<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n\tTSort extends ReadonlyNonEmptyArray<string> | [] = [],\n> = {\n\tsize?: number;\n\tpage?: number;\n\tsort?: TSort extends ReadonlyNonEmptyArray<string> ? Partial<Record<TSort[number], 1 | -1>> : never;\n\tselect?: TSelect extends ReadonlyNonEmptyArray<string> ? Partial<Record<TSelect[number], 0 | 1>> : never;\n\tpopulate?: PopulateUnion<TPopulate>[];\n\tsearch?: TSearch extends ReadonlyNonEmptyArray<string>\n\t\t? { searchKey: string; searchFields?: TSearch[number][] }\n\t\t: never;\n\tquery?: { [K in keyof TQuery]?: z.infer<TQuery[K]> };\n};\n\nconst sortSchema = z.record(z.string(), z.union([z.literal(1), z.literal(-1)]));\n\nexport function createFilterSchema<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n\tTSort extends ReadonlyNonEmptyArray<string> | [] = [],\n>(config: FilterSchemaConfig<TSelect, TPopulate, TSearch, TQuery, TSort>) {\n\tconst {\n\t\tselectableFields,\n\t\tpopulatableFields,\n\t\tsearchableFields,\n\t\tqueryableFields,\n\t\tsortableFields,\n\t\tmaxSize = 100,\n\t\tdefaultSize = 10,\n\t} = config;\n\n\tconst populateKeys = populatableFields ? (Object.keys(populatableFields) as (keyof TPopulate)[]) : [];\n\n\tconst schemaShape: Record<string, any> = {\n\t\tsize: z.number().min(1).max(maxSize).optional().default(defaultSize),\n\t\tpage: z.number().min(1).optional().default(1),\n\t};\n\n\t// Sort with allowed fields\n\tif (sortableFields?.length) {\n\t\tschemaShape.sort = z\n\t\t\t.record(z.enum([...sortableFields] as [string, ...string[]]), z.union([z.literal(1), z.literal(-1)]))\n\t\t\t.optional();\n\t}\n\n\t// Top-level select\n\tif (selectableFields?.length) {\n\t\tschemaShape.select = z\n\t\t\t.record(z.enum([...selectableFields] as [string, ...string[]]), z.union([z.literal(0), z.literal(1)]))\n\t\t\t.optional();\n\t}\n\n\t// Populate as array of objects with strict typing per path\n\tif (populateKeys.length) {\n\t\tconst populateSchemas: ZodTypeAny[] = [];\n\n\t\tfor (const path of populateKeys) {\n\t\t\tconst allowedSelects = populatableFields![path] as ReadonlyNonEmptyArray<string>;\n\n\t\t\tconst populateSchema = z.object({\n\t\t\t\tpath: z.literal(path as string),\n\t\t\t\tselect: z\n\t\t\t\t\t.record(z.enum([...allowedSelects] as [string, ...string[]]), z.union([z.literal(0), z.literal(1)]))\n\t\t\t\t\t.optional(),\n\t\t\t\tmatch: z.record(z.string(), z.any()).optional(),\n\t\t\t\toptions: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\tsort: sortSchema.optional(),\n\t\t\t\t\t\tlimit: z.number().optional(),\n\t\t\t\t\t\tskip: z.number().optional(),\n\t\t\t\t\t})\n\t\t\t\t\t.optional(),\n\t\t\t});\n\n\t\t\tpopulateSchemas.push(populateSchema);\n\t\t}\n\n\t\tconst unionSchema =\n\t\t\tpopulateSchemas.length === 1\n\t\t\t\t? populateSchemas[0]\n\t\t\t\t: z.union(populateSchemas as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]);\n\n\t\tschemaShape.populate = z.array(unionSchema).optional();\n\t}\n\n\t// Search\n\tif (searchableFields?.length) {\n\t\tschemaShape.search = z\n\t\t\t.object({\n\t\t\t\tsearchKey: z.string(),\n\t\t\t\tsearchFields: z.array(z.enum([...searchableFields] as [string, ...string[]])).optional(),\n\t\t\t})\n\t\t\t.optional();\n\t}\n\n\t// Query\n\tif (queryableFields && Object.keys(queryableFields).length) {\n\t\tconst queryShape: Record<string, ZodTypeAny> = {};\n\t\tfor (const key in queryableFields) {\n\t\t\tqueryShape[key] = queryableFields[key].optional();\n\t\t}\n\t\tschemaShape.query = z.object(queryShape).optional();\n\t}\n\n\treturn z.object(schemaShape) as z.ZodType<FilterDTO<TSelect, TPopulate, TSearch, TQuery, TSort>>;\n}\n\nconst TicketFilterSchema = createFilterSchema({\n\t// Top-level document fields that can be selected\n\tselectableFields: ['_id', 'ticketId', 'type', 'status', 'createdAt', 'updatedAt'] as const,\n\n\t// Each populate path has its own allowed select fields\n\tpopulatableFields: {\n\t\tchatroom: ['_id', 'lastMessage', 'participants', 'unreadCount'] as const,\n\t\tclient: ['_id', 'name', 'profilePhoto', 'type'] as const,\n\t\tadmin: ['_id', 'name', 'profilePhoto'] as const,\n\t\torder: ['_id', 'orderId', 'shop', 'total'] as const,\n\t} as const,\n\n\tsearchableFields: ['ticketId'] as const,\n\n\tsortableFields: ['createdAt', 'updatedAt', 'ticketId', 'status'] as const,\n\n\tqueryableFields: {\n\t\tstatus: z.enum(['OPEN', 'CLOSED', 'PENDING']),\n\t\ttype: z.enum(['ORDER', 'GENERAL', 'COMPLAINT']),\n\t\tclient: z.string(),\n\t\tclientType: z.enum(['USER', 'SHOP']),\n\t},\n});\n\ntype TicketFilterDTO = z.infer<typeof TicketFilterSchema>;\n\nconst ticket: TicketFilterDTO = {\n\tsort: { createdAt: -1, status: 1 }, // ✅ Only allowed fields with 1 or -1\n};\n\n/**\n * EXAMPLE USAGE\n *\n * const TicketFilterSchema = createFilterSchema({\n * selectableFields: [\n * '_id',\n * 'ticketId',\n * 'type',\n * 'status',\n * 'createdAt',\n * 'updatedAt',\n * ] as const,\n *\n * populatableFields: {\n * chatroom: ['_id', 'lastMessage', 'participants', 'unreadCount'] as const,\n * client: ['_id', 'name', 'profilePhoto', 'type'] as const,\n * admin: ['_id', 'name', 'profilePhoto'] as const,\n * order: ['_id', 'orderId', 'shop', 'total'] as const,\n * } as const,\n *\n * searchableFields: ['ticketId'] as const,\n *\n * sortableFields: ['createdAt', 'updatedAt', 'ticketId', 'status'] as const,\n *\n * queryableFields: {\n * status: z.enum(['OPEN', 'CLOSED', 'PENDING']),\n * type: z.enum(['ORDER', 'GENERAL', 'COMPLAINT']),\n * client: z.string(),\n * clientType: z.enum(['USER', 'SHOP']),\n * },\n * });\n *\n * type TicketFilterDTO = z.infer<typeof TicketFilterSchema>;\n *\n * // ✅ VALID EXAMPLES\n *\n * // Example 1: Sort by allowed fields\n * const filter1: TicketFilterDTO = {\n * sort: { createdAt: -1, status: 1 },\n * query: { status: 'OPEN' },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 2: Populate client with specific fields\n * const filter2: TicketFilterDTO = {\n * populate: [\n * { path: 'client', select: { name: 1, profilePhoto: 1 } }\n * ],\n * sort: { updatedAt: -1 },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 3: Populate multiple relations with sort\n * const filter3: TicketFilterDTO = {\n * populate: [\n * { path: 'client', select: { name: 1, profilePhoto: 1 } },\n * { path: 'order', select: { orderId: 1, total: 1 } },\n * { path: 'chatroom', select: { lastMessage: 1, unreadCount: 1 } },\n * ],\n * sort: { createdAt: -1 },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 4: Complex query with search and sort\n * const filter4: TicketFilterDTO = {\n * query: { status: 'OPEN', type: 'ORDER' },\n * search: { searchKey: 'TKT-123', searchFields: ['ticketId'] },\n * populate: [{ path: 'client', select: { name: 1 } }],\n * sort: { createdAt: -1, ticketId: 1 },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 5: Populate with match and options\n * const filter5: TicketFilterDTO = {\n * populate: [\n * {\n * path: 'order',\n * select: { orderId: 1, shop: 1 },\n * match: { status: 'DELIVERED' },\n * options: { sort: { createdAt: -1 }, limit: 10 },\n * }\n * ],\n * sort: { updatedAt: -1 },\n * page: 1,\n * size: 20,\n * };\n *\n * // ❌ INVALID EXAMPLES (TypeScript will reject)\n *\n * const invalid1: TicketFilterDTO = {\n * sort: { invalidField: 1 }, // ❌ not in sortableFields\n * };\n *\n * const invalid2: TicketFilterDTO = {\n * sort: { createdAt: 2 }, // ❌ must be 1 or -1\n * };\n *\n * const invalid3: TicketFilterDTO = {\n * populate: [\n * {\n * path: 'client',\n * select: { email: 1 }, // ❌ email not in client's populatableFields\n * }\n * ],\n * };\n *\n * const invalid4: TicketFilterDTO = {\n * query: { status: 'INVALID_STATUS' }, // ❌ not in enum\n * }\n */\n"]}
@@ -1,10 +1,11 @@
1
1
  import { z, ZodTypeAny } from 'zod';
2
2
  type ReadonlyNonEmptyArray<T> = readonly [T, ...T[]];
3
- export interface FilterSchemaConfig<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}> {
3
+ export interface FilterSchemaConfig<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}, TSort extends ReadonlyNonEmptyArray<string> | [] = []> {
4
4
  selectableFields?: TSelect;
5
5
  populatableFields?: TPopulate;
6
6
  searchableFields?: TSearch;
7
7
  queryableFields?: TQuery;
8
+ sortableFields?: TSort;
8
9
  maxSize?: number;
9
10
  defaultSize?: number;
10
11
  }
@@ -21,10 +22,10 @@ export type PopulateObject<TPath extends string, TSelectFields extends ReadonlyN
21
22
  type PopulateUnion<TPopulate extends Record<string, ReadonlyNonEmptyArray<string>>> = {
22
23
  [K in keyof TPopulate]: PopulateObject<K & string, TPopulate[K]>;
23
24
  }[keyof TPopulate];
24
- export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}> = {
25
+ export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}, TSort extends ReadonlyNonEmptyArray<string> | [] = []> = {
25
26
  size?: number;
26
27
  page?: number;
27
- sort?: Record<string, 1 | -1>;
28
+ sort?: TSort extends ReadonlyNonEmptyArray<string> ? Partial<Record<TSort[number], 1 | -1>> : never;
28
29
  select?: TSelect extends ReadonlyNonEmptyArray<string> ? Partial<Record<TSelect[number], 0 | 1>> : never;
29
30
  populate?: PopulateUnion<TPopulate>[];
30
31
  search?: TSearch extends ReadonlyNonEmptyArray<string> ? {
@@ -35,5 +36,5 @@ export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], T
35
36
  [K in keyof TQuery]?: z.infer<TQuery[K]>;
36
37
  };
37
38
  };
38
- export declare function createFilterSchema<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}>(config: FilterSchemaConfig<TSelect, TPopulate, TSearch, TQuery>): z.ZodType<FilterDTO<TSelect, TPopulate, TSearch, TQuery>>;
39
+ export declare function createFilterSchema<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {}, TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}, TSort extends ReadonlyNonEmptyArray<string> | [] = []>(config: FilterSchemaConfig<TSelect, TPopulate, TSearch, TQuery, TSort>): z.ZodType<FilterDTO<TSelect, TPopulate, TSearch, TQuery, TSort>>;
39
40
  export {};
@@ -4,13 +4,17 @@ exports.createFilterSchema = createFilterSchema;
4
4
  const zod_1 = require("zod");
5
5
  const sortSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.union([zod_1.z.literal(1), zod_1.z.literal(-1)]));
6
6
  function createFilterSchema(config) {
7
- const { selectableFields, populatableFields, searchableFields, queryableFields, maxSize = 100, defaultSize = 10, } = config;
7
+ const { selectableFields, populatableFields, searchableFields, queryableFields, sortableFields, maxSize = 100, defaultSize = 10, } = config;
8
8
  const populateKeys = populatableFields ? Object.keys(populatableFields) : [];
9
9
  const schemaShape = {
10
10
  size: zod_1.z.number().min(1).max(maxSize).optional().default(defaultSize),
11
11
  page: zod_1.z.number().min(1).optional().default(1),
12
- sort: sortSchema.optional(),
13
12
  };
13
+ if (sortableFields?.length) {
14
+ schemaShape.sort = zod_1.z
15
+ .record(zod_1.z.enum([...sortableFields]), zod_1.z.union([zod_1.z.literal(1), zod_1.z.literal(-1)]))
16
+ .optional();
17
+ }
14
18
  if (selectableFields?.length) {
15
19
  schemaShape.select = zod_1.z
16
20
  .record(zod_1.z.enum([...selectableFields]), zod_1.z.union([zod_1.z.literal(0), zod_1.z.literal(1)]))
@@ -59,14 +63,7 @@ function createFilterSchema(config) {
59
63
  return zod_1.z.object(schemaShape);
60
64
  }
61
65
  const TicketFilterSchema = createFilterSchema({
62
- selectableFields: [
63
- '_id',
64
- 'ticketId',
65
- 'type',
66
- 'status',
67
- 'createdAt',
68
- 'updatedAt',
69
- ],
66
+ selectableFields: ['_id', 'ticketId', 'type', 'status', 'createdAt', 'updatedAt'],
70
67
  populatableFields: {
71
68
  chatroom: ['_id', 'lastMessage', 'participants', 'unreadCount'],
72
69
  client: ['_id', 'name', 'profilePhoto', 'type'],
@@ -74,6 +71,7 @@ const TicketFilterSchema = createFilterSchema({
74
71
  order: ['_id', 'orderId', 'shop', 'total'],
75
72
  },
76
73
  searchableFields: ['ticketId'],
74
+ sortableFields: ['createdAt', 'updatedAt', 'ticketId', 'status'],
77
75
  queryableFields: {
78
76
  status: zod_1.z.enum(['OPEN', 'CLOSED', 'PENDING']),
79
77
  type: zod_1.z.enum(['ORDER', 'GENERAL', 'COMPLAINT']),
@@ -81,5 +79,7 @@ const TicketFilterSchema = createFilterSchema({
81
79
  clientType: zod_1.z.enum(['USER', 'SHOP']),
82
80
  },
83
81
  });
84
- const ticket = {};
82
+ const ticket = {
83
+ sort: { createdAt: -1, status: 1 },
84
+ };
85
85
  //# sourceMappingURL=filter-schema.factory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-schema.factory.js","sourceRoot":"/","sources":["utilities/validation/filter-schema.factory.ts"],"names":[],"mappings":";;AAwDA,gDAsFC;AA9ID,6BAAoC;AAsDpC,MAAM,UAAU,GAAG,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,SAAgB,kBAAkB,CAKhC,MAA+D;IAChE,MAAM,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,OAAO,GAAG,GAAG,EACb,WAAW,GAAG,EAAE,GAChB,GAAG,MAAM,CAAC;IAEX,MAAM,YAAY,GAAG,iBAAiB,CAAC,CAAC,CAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;IAEtG,MAAM,WAAW,GAAwB;QACxC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;QACpE,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7C,IAAI,EAAE,UAAU,CAAC,QAAQ,EAAE;KAC3B,CAAC;IAGF,IAAI,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC9B,WAAW,CAAC,MAAM,GAAG,OAAC;aACpB,MAAM,CACN,OAAC,CAAC,IAAI,CAAC,CAAC,GAAG,gBAAgB,CAA0B,CAAC,EACtD,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CACrC;aACA,QAAQ,EAAE,CAAC;IACd,CAAC;IAGD,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,eAAe,GAAiB,EAAE,CAAC;QAEzC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YACjC,MAAM,cAAc,GAAG,iBAAkB,CAAC,IAAI,CAAkC,CAAC;YAEjF,MAAM,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC;gBAC/B,IAAI,EAAE,OAAC,CAAC,OAAO,CAAC,IAAc,CAAC;gBAC/B,MAAM,EAAE,OAAC;qBACP,MAAM,CAAC,OAAC,CAAC,IAAI,CAAC,CAAC,GAAG,cAAc,CAA0B,CAAC,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;qBACnG,QAAQ,EAAE;gBACZ,KAAK,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;gBAC/C,OAAO,EAAE,OAAC;qBACR,MAAM,CAAC;oBACP,IAAI,EAAE,UAAU,CAAC,QAAQ,EAAE;oBAC3B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;oBAC5B,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;iBAC3B,CAAC;qBACD,QAAQ,EAAE;aACZ,CAAC,CAAC;YAEH,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,WAAW,GAChB,eAAe,CAAC,MAAM,KAAK,CAAC;YAC3B,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;YACpB,CAAC,CAAC,OAAC,CAAC,KAAK,CAAC,eAA4D,CAAC,CAAC;QAE1E,WAAW,CAAC,QAAQ,GAAG,OAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxD,CAAC;IAGD,IAAI,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC9B,WAAW,CAAC,MAAM,GAAG,OAAC;aACpB,MAAM,CAAC;YACP,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE;YACrB,YAAY,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,IAAI,CAAC,CAAC,GAAG,gBAAgB,CAA0B,CAAC,CAAC,CAAC,QAAQ,EAAE;SACxF,CAAC;aACD,QAAQ,EAAE,CAAC;IACd,CAAC;IAGD,IAAI,eAAe,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,CAAC;QAC5D,MAAM,UAAU,GAA+B,EAAE,CAAC;QAClD,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACnC,UAAU,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QACnD,CAAC;QACD,WAAW,CAAC,KAAK,GAAG,OAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;IACrD,CAAC;IAED,OAAO,OAAC,CAAC,MAAM,CAAC,WAAW,CAA8D,CAAC;AAC3F,CAAC;AAGD,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;IAE7C,gBAAgB,EAAE;QACjB,KAAK;QACL,UAAU;QACV,MAAM;QACN,QAAQ;QACR,WAAW;QACX,WAAW;KACF;IAGV,iBAAiB,EAAE;QAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,CAAU;QACxE,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,CAAU;QACxD,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAU;QAC/C,KAAK,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAU;KAC1C;IAEV,gBAAgB,EAAE,CAAC,UAAU,CAAU;IAEvC,eAAe,EAAE;QAChB,MAAM,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7C,IAAI,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QAC/C,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE;QAClB,UAAU,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACpC;CACD,CAAC,CAAC;AAIH,MAAM,MAAM,GAAoB,EAE/B,CAAA","sourcesContent":["import { z, ZodTypeAny } from 'zod';\n\ntype ReadonlyNonEmptyArray<T> = readonly [T, ...T[]];\n\nexport interface FilterSchemaConfig<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n> {\n\tselectableFields?: TSelect;\n\tpopulatableFields?: TPopulate;\n\tsearchableFields?: TSearch;\n\tqueryableFields?: TQuery;\n\tmaxSize?: number;\n\tdefaultSize?: number;\n}\n\n// Populate object type\nexport type PopulateObject<\n\tTPath extends string,\n\tTSelectFields extends ReadonlyNonEmptyArray<string>\n> = {\n\tpath: TPath;\n\tselect?: Partial<Record<TSelectFields[number], 0 | 1>>;\n\tmatch?: Record<string, any>;\n\toptions?: { sort?: Record<string, 1 | -1>; limit?: number; skip?: number };\n};\n\n// Union of all possible populate objects based on populatableFields\ntype PopulateUnion<TPopulate extends Record<string, ReadonlyNonEmptyArray<string>>> = {\n\t[K in keyof TPopulate]: PopulateObject<K & string, TPopulate[K]>;\n}[keyof TPopulate];\n\n// DTO type\nexport type FilterDTO<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n> = {\n\tsize?: number;\n\tpage?: number;\n\tsort?: Record<string, 1 | -1>;\n\tselect?: TSelect extends ReadonlyNonEmptyArray<string>\n\t\t? Partial<Record<TSelect[number], 0 | 1>>\n\t\t: never;\n\tpopulate?: PopulateUnion<TPopulate>[];\n\tsearch?: TSearch extends ReadonlyNonEmptyArray<string>\n\t\t? { searchKey: string; searchFields?: TSearch[number][] }\n\t\t: never;\n\tquery?: { [K in keyof TQuery]?: z.infer<TQuery[K]> };\n};\n\nconst sortSchema = z.record(z.string(), z.union([z.literal(1), z.literal(-1)]));\n\nexport function createFilterSchema<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n>(config: FilterSchemaConfig<TSelect, TPopulate, TSearch, TQuery>) {\n\tconst {\n\t\tselectableFields,\n\t\tpopulatableFields,\n\t\tsearchableFields,\n\t\tqueryableFields,\n\t\tmaxSize = 100,\n\t\tdefaultSize = 10,\n\t} = config;\n\n\tconst populateKeys = populatableFields ? (Object.keys(populatableFields) as (keyof TPopulate)[]) : [];\n\n\tconst schemaShape: Record<string, any> = {\n\t\tsize: z.number().min(1).max(maxSize).optional().default(defaultSize),\n\t\tpage: z.number().min(1).optional().default(1),\n\t\tsort: sortSchema.optional(),\n\t};\n\n\t// Top-level select\n\tif (selectableFields?.length) {\n\t\tschemaShape.select = z\n\t\t\t.record(\n\t\t\t\tz.enum([...selectableFields] as [string, ...string[]]),\n\t\t\t\tz.union([z.literal(0), z.literal(1)]),\n\t\t\t)\n\t\t\t.optional();\n\t}\n\n\t// Populate as array of objects with strict typing per path\n\tif (populateKeys.length) {\n\t\tconst populateSchemas: ZodTypeAny[] = [];\n\n\t\tfor (const path of populateKeys) {\n\t\t\tconst allowedSelects = populatableFields![path] as ReadonlyNonEmptyArray<string>;\n\n\t\t\tconst populateSchema = z.object({\n\t\t\t\tpath: z.literal(path as string),\n\t\t\t\tselect: z\n\t\t\t\t\t.record(z.enum([...allowedSelects] as [string, ...string[]]), z.union([z.literal(0), z.literal(1)]))\n\t\t\t\t\t.optional(),\n\t\t\t\tmatch: z.record(z.string(), z.any()).optional(),\n\t\t\t\toptions: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\tsort: sortSchema.optional(),\n\t\t\t\t\t\tlimit: z.number().optional(),\n\t\t\t\t\t\tskip: z.number().optional(),\n\t\t\t\t\t})\n\t\t\t\t\t.optional(),\n\t\t\t});\n\n\t\t\tpopulateSchemas.push(populateSchema);\n\t\t}\n\n\t\tconst unionSchema =\n\t\t\tpopulateSchemas.length === 1\n\t\t\t\t? populateSchemas[0]\n\t\t\t\t: z.union(populateSchemas as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]);\n\n\t\tschemaShape.populate = z.array(unionSchema).optional();\n\t}\n\n\t// Search\n\tif (searchableFields?.length) {\n\t\tschemaShape.search = z\n\t\t\t.object({\n\t\t\t\tsearchKey: z.string(),\n\t\t\t\tsearchFields: z.array(z.enum([...searchableFields] as [string, ...string[]])).optional(),\n\t\t\t})\n\t\t\t.optional();\n\t}\n\n\t// Query\n\tif (queryableFields && Object.keys(queryableFields).length) {\n\t\tconst queryShape: Record<string, ZodTypeAny> = {};\n\t\tfor (const key in queryableFields) {\n\t\t\tqueryShape[key] = queryableFields[key].optional();\n\t\t}\n\t\tschemaShape.query = z.object(queryShape).optional();\n\t}\n\n\treturn z.object(schemaShape) as z.ZodType<FilterDTO<TSelect, TPopulate, TSearch, TQuery>>;\n}\n\n\nconst TicketFilterSchema = createFilterSchema({\n\t// Top-level document fields that can be selected\n\tselectableFields: [\n\t\t'_id',\n\t\t'ticketId',\n\t\t'type',\n\t\t'status',\n\t\t'createdAt',\n\t\t'updatedAt',\n\t] as const,\n\n\t// Each populate path has its own allowed select fields\n\tpopulatableFields: {\n\t\tchatroom: ['_id', 'lastMessage', 'participants', 'unreadCount'] as const,\n\t\tclient: ['_id', 'name', 'profilePhoto', 'type'] as const,\n\t\tadmin: ['_id', 'name', 'profilePhoto'] as const,\n\t\torder: ['_id', 'orderId', 'shop', 'total'] as const,\n\t} as const,\n\n\tsearchableFields: ['ticketId'] as const,\n\n\tqueryableFields: {\n\t\tstatus: z.enum(['OPEN', 'CLOSED', 'PENDING']),\n\t\ttype: z.enum(['ORDER', 'GENERAL', 'COMPLAINT']),\n\t\tclient: z.string(),\n\t\tclientType: z.enum(['USER', 'SHOP']),\n\t},\n});\n\ntype TicketFilterDTO = z.infer<typeof TicketFilterSchema>;\n\nconst ticket: TicketFilterDTO = {\n\n}\n\n\n/**\n * EXAMPLE USAGE\n *\n * const TicketFilterSchema = createFilterSchema({\n * // Top-level document fields that can be selected\n * selectableFields: [\n * '_id',\n * 'ticketId',\n * 'type',\n * 'status',\n * 'createdAt',\n * 'updatedAt',\n * ] as const,\n *\n * // Each populate path has its own allowed select fields\n * populatableFields: {\n * chatroom: ['_id', 'lastMessage', 'participants', 'unreadCount'] as const,\n * client: ['_id', 'name', 'profilePhoto', 'type'] as const,\n * admin: ['_id', 'name', 'profilePhoto'] as const,\n * order: ['_id', 'orderId', 'shop', 'total'] as const,\n * } as const,\n *\n * searchableFields: ['ticketId'] as const,\n *\n * queryableFields: {\n * status: z.enum(['OPEN', 'CLOSED', 'PENDING']),\n * type: z.enum(['ORDER', 'GENERAL', 'COMPLAINT']),\n * client: z.string(),\n * clientType: z.enum(['USER', 'SHOP']),\n * },\n * });\n *\n * type TicketFilterDTO = z.infer<typeof TicketFilterSchema>;\n *\n * // ✅ VALID EXAMPLES\n *\n * // Example 1: Select only top-level fields\n * const filter1: TicketFilterDTO = {\n * select: { ticketId: 1, status: 1, createdAt: 1 },\n * query: { status: 'OPEN' },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 2: Populate client with specific fields\n * const filter2: TicketFilterDTO = {\n * populate: {\n * path: 'client',\n * select: { name: 1, profilePhoto: 1 }, // Uses client's allowed fields\n * },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 3: Populate multiple relations\n * const filter3: TicketFilterDTO = {\n * populate: [\n * { path: 'client', select: { name: 1, profilePhoto: 1 } },\n * { path: 'order', select: { orderId: 1, total: 1 } },\n * { path: 'chatroom', select: { lastMessage: 1, unreadCount: 1 } },\n * ],\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 4: Complex query with search\n * const filter4: TicketFilterDTO = {\n * query: { status: 'OPEN', type: 'ORDER' },\n * search: { searchKey: 'TKT-123', searchFields: ['ticketId'] },\n * populate: { path: 'client', select: { name: 1 } },\n * sort: { createdAt: -1 },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 5: Populate with match and options\n * const filter5: TicketFilterDTO = {\n * populate: {\n * path: 'order',\n * select: { orderId: 1, shop: 1 },\n * match: { status: 'DELIVERED' },\n * options: { sort: { createdAt: -1 }, limit: 10 },\n * },\n * page: 1,\n * size: 20,\n * };\n *\n * // ❌ INVALID EXAMPLES (TypeScript will reject)\n *\n * const invalid1: TicketFilterDTO = {\n * select: { invalidField: 1 }, // ❌ not in selectableFields\n * };\n *\n * const invalid2: TicketFilterDTO = {\n * populate: {\n * path: 'client',\n * select: { email: 1 }, // ❌ email not in client's populatableFields\n * },\n * };\n *\n * const invalid3: TicketFilterDTO = {\n * populate: {\n * path: 'invalidPath', // ❌ path doesn't exist\n * select: { name: 1 },\n * },\n * };\n *\n * const invalid4: TicketFilterDTO = {\n * query: { status: 'INVALID_STATUS' }, // ❌ not in enum\n * }\n */"]}
1
+ {"version":3,"file":"filter-schema.factory.js","sourceRoot":"/","sources":["utilities/validation/filter-schema.factory.ts"],"names":[],"mappings":";;AAsDA,gDA2FC;AAjJD,6BAAoC;AAoDpC,MAAM,UAAU,GAAG,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,SAAgB,kBAAkB,CAMhC,MAAsE;IACvE,MAAM,EACL,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,OAAO,GAAG,GAAG,EACb,WAAW,GAAG,EAAE,GAChB,GAAG,MAAM,CAAC;IAEX,MAAM,YAAY,GAAG,iBAAiB,CAAC,CAAC,CAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;IAEtG,MAAM,WAAW,GAAwB;QACxC,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC;QACpE,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;KAC7C,CAAC;IAGF,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC;QAC5B,WAAW,CAAC,IAAI,GAAG,OAAC;aAClB,MAAM,CAAC,OAAC,CAAC,IAAI,CAAC,CAAC,GAAG,cAAc,CAA0B,CAAC,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACpG,QAAQ,EAAE,CAAC;IACd,CAAC;IAGD,IAAI,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC9B,WAAW,CAAC,MAAM,GAAG,OAAC;aACpB,MAAM,CAAC,OAAC,CAAC,IAAI,CAAC,CAAC,GAAG,gBAAgB,CAA0B,CAAC,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACrG,QAAQ,EAAE,CAAC;IACd,CAAC;IAGD,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,eAAe,GAAiB,EAAE,CAAC;QAEzC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YACjC,MAAM,cAAc,GAAG,iBAAkB,CAAC,IAAI,CAAkC,CAAC;YAEjF,MAAM,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC;gBAC/B,IAAI,EAAE,OAAC,CAAC,OAAO,CAAC,IAAc,CAAC;gBAC/B,MAAM,EAAE,OAAC;qBACP,MAAM,CAAC,OAAC,CAAC,IAAI,CAAC,CAAC,GAAG,cAAc,CAA0B,CAAC,EAAE,OAAC,CAAC,KAAK,CAAC,CAAC,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;qBACnG,QAAQ,EAAE;gBACZ,KAAK,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,MAAM,EAAE,EAAE,OAAC,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,EAAE;gBAC/C,OAAO,EAAE,OAAC;qBACR,MAAM,CAAC;oBACP,IAAI,EAAE,UAAU,CAAC,QAAQ,EAAE;oBAC3B,KAAK,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;oBAC5B,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;iBAC3B,CAAC;qBACD,QAAQ,EAAE;aACZ,CAAC,CAAC;YAEH,eAAe,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,WAAW,GAChB,eAAe,CAAC,MAAM,KAAK,CAAC;YAC3B,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;YACpB,CAAC,CAAC,OAAC,CAAC,KAAK,CAAC,eAA4D,CAAC,CAAC;QAE1E,WAAW,CAAC,QAAQ,GAAG,OAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC;IACxD,CAAC;IAGD,IAAI,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC9B,WAAW,CAAC,MAAM,GAAG,OAAC;aACpB,MAAM,CAAC;YACP,SAAS,EAAE,OAAC,CAAC,MAAM,EAAE;YACrB,YAAY,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,IAAI,CAAC,CAAC,GAAG,gBAAgB,CAA0B,CAAC,CAAC,CAAC,QAAQ,EAAE;SACxF,CAAC;aACD,QAAQ,EAAE,CAAC;IACd,CAAC;IAGD,IAAI,eAAe,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,CAAC;QAC5D,MAAM,UAAU,GAA+B,EAAE,CAAC;QAClD,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YACnC,UAAU,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QACnD,CAAC;QACD,WAAW,CAAC,KAAK,GAAG,OAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;IACrD,CAAC;IAED,OAAO,OAAC,CAAC,MAAM,CAAC,WAAW,CAAqE,CAAC;AAClG,CAAC;AAED,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;IAE7C,gBAAgB,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAU;IAG1F,iBAAiB,EAAE;QAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,CAAU;QACxE,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,CAAU;QACxD,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,CAAU;QAC/C,KAAK,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAU;KAC1C;IAEV,gBAAgB,EAAE,CAAC,UAAU,CAAU;IAEvC,cAAc,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAU;IAEzE,eAAe,EAAE;QAChB,MAAM,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7C,IAAI,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QAC/C,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE;QAClB,UAAU,EAAE,OAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACpC;CACD,CAAC,CAAC;AAIH,MAAM,MAAM,GAAoB;IAC/B,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;CAClC,CAAC","sourcesContent":["import { z, ZodTypeAny } from 'zod';\n\ntype ReadonlyNonEmptyArray<T> = readonly [T, ...T[]];\n\nexport interface FilterSchemaConfig<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n\tTSort extends ReadonlyNonEmptyArray<string> | [] = [],\n> {\n\tselectableFields?: TSelect;\n\tpopulatableFields?: TPopulate;\n\tsearchableFields?: TSearch;\n\tqueryableFields?: TQuery;\n\tsortableFields?: TSort;\n\tmaxSize?: number;\n\tdefaultSize?: number;\n}\n\n// Populate object type\nexport type PopulateObject<TPath extends string, TSelectFields extends ReadonlyNonEmptyArray<string>> = {\n\tpath: TPath;\n\tselect?: Partial<Record<TSelectFields[number], 0 | 1>>;\n\tmatch?: Record<string, any>;\n\toptions?: { sort?: Record<string, 1 | -1>; limit?: number; skip?: number };\n};\n\n// Union of all possible populate objects based on populatableFields\ntype PopulateUnion<TPopulate extends Record<string, ReadonlyNonEmptyArray<string>>> = {\n\t[K in keyof TPopulate]: PopulateObject<K & string, TPopulate[K]>;\n}[keyof TPopulate];\n\n// DTO type\nexport type FilterDTO<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n\tTSort extends ReadonlyNonEmptyArray<string> | [] = [],\n> = {\n\tsize?: number;\n\tpage?: number;\n\tsort?: TSort extends ReadonlyNonEmptyArray<string> ? Partial<Record<TSort[number], 1 | -1>> : never;\n\tselect?: TSelect extends ReadonlyNonEmptyArray<string> ? Partial<Record<TSelect[number], 0 | 1>> : never;\n\tpopulate?: PopulateUnion<TPopulate>[];\n\tsearch?: TSearch extends ReadonlyNonEmptyArray<string>\n\t\t? { searchKey: string; searchFields?: TSearch[number][] }\n\t\t: never;\n\tquery?: { [K in keyof TQuery]?: z.infer<TQuery[K]> };\n};\n\nconst sortSchema = z.record(z.string(), z.union([z.literal(1), z.literal(-1)]));\n\nexport function createFilterSchema<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends Record<string, ReadonlyNonEmptyArray<string>> | {} = {},\n\tTSearch extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTQuery extends Record<string, ZodTypeAny> = {},\n\tTSort extends ReadonlyNonEmptyArray<string> | [] = [],\n>(config: FilterSchemaConfig<TSelect, TPopulate, TSearch, TQuery, TSort>) {\n\tconst {\n\t\tselectableFields,\n\t\tpopulatableFields,\n\t\tsearchableFields,\n\t\tqueryableFields,\n\t\tsortableFields,\n\t\tmaxSize = 100,\n\t\tdefaultSize = 10,\n\t} = config;\n\n\tconst populateKeys = populatableFields ? (Object.keys(populatableFields) as (keyof TPopulate)[]) : [];\n\n\tconst schemaShape: Record<string, any> = {\n\t\tsize: z.number().min(1).max(maxSize).optional().default(defaultSize),\n\t\tpage: z.number().min(1).optional().default(1),\n\t};\n\n\t// Sort with allowed fields\n\tif (sortableFields?.length) {\n\t\tschemaShape.sort = z\n\t\t\t.record(z.enum([...sortableFields] as [string, ...string[]]), z.union([z.literal(1), z.literal(-1)]))\n\t\t\t.optional();\n\t}\n\n\t// Top-level select\n\tif (selectableFields?.length) {\n\t\tschemaShape.select = z\n\t\t\t.record(z.enum([...selectableFields] as [string, ...string[]]), z.union([z.literal(0), z.literal(1)]))\n\t\t\t.optional();\n\t}\n\n\t// Populate as array of objects with strict typing per path\n\tif (populateKeys.length) {\n\t\tconst populateSchemas: ZodTypeAny[] = [];\n\n\t\tfor (const path of populateKeys) {\n\t\t\tconst allowedSelects = populatableFields![path] as ReadonlyNonEmptyArray<string>;\n\n\t\t\tconst populateSchema = z.object({\n\t\t\t\tpath: z.literal(path as string),\n\t\t\t\tselect: z\n\t\t\t\t\t.record(z.enum([...allowedSelects] as [string, ...string[]]), z.union([z.literal(0), z.literal(1)]))\n\t\t\t\t\t.optional(),\n\t\t\t\tmatch: z.record(z.string(), z.any()).optional(),\n\t\t\t\toptions: z\n\t\t\t\t\t.object({\n\t\t\t\t\t\tsort: sortSchema.optional(),\n\t\t\t\t\t\tlimit: z.number().optional(),\n\t\t\t\t\t\tskip: z.number().optional(),\n\t\t\t\t\t})\n\t\t\t\t\t.optional(),\n\t\t\t});\n\n\t\t\tpopulateSchemas.push(populateSchema);\n\t\t}\n\n\t\tconst unionSchema =\n\t\t\tpopulateSchemas.length === 1\n\t\t\t\t? populateSchemas[0]\n\t\t\t\t: z.union(populateSchemas as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]);\n\n\t\tschemaShape.populate = z.array(unionSchema).optional();\n\t}\n\n\t// Search\n\tif (searchableFields?.length) {\n\t\tschemaShape.search = z\n\t\t\t.object({\n\t\t\t\tsearchKey: z.string(),\n\t\t\t\tsearchFields: z.array(z.enum([...searchableFields] as [string, ...string[]])).optional(),\n\t\t\t})\n\t\t\t.optional();\n\t}\n\n\t// Query\n\tif (queryableFields && Object.keys(queryableFields).length) {\n\t\tconst queryShape: Record<string, ZodTypeAny> = {};\n\t\tfor (const key in queryableFields) {\n\t\t\tqueryShape[key] = queryableFields[key].optional();\n\t\t}\n\t\tschemaShape.query = z.object(queryShape).optional();\n\t}\n\n\treturn z.object(schemaShape) as z.ZodType<FilterDTO<TSelect, TPopulate, TSearch, TQuery, TSort>>;\n}\n\nconst TicketFilterSchema = createFilterSchema({\n\t// Top-level document fields that can be selected\n\tselectableFields: ['_id', 'ticketId', 'type', 'status', 'createdAt', 'updatedAt'] as const,\n\n\t// Each populate path has its own allowed select fields\n\tpopulatableFields: {\n\t\tchatroom: ['_id', 'lastMessage', 'participants', 'unreadCount'] as const,\n\t\tclient: ['_id', 'name', 'profilePhoto', 'type'] as const,\n\t\tadmin: ['_id', 'name', 'profilePhoto'] as const,\n\t\torder: ['_id', 'orderId', 'shop', 'total'] as const,\n\t} as const,\n\n\tsearchableFields: ['ticketId'] as const,\n\n\tsortableFields: ['createdAt', 'updatedAt', 'ticketId', 'status'] as const,\n\n\tqueryableFields: {\n\t\tstatus: z.enum(['OPEN', 'CLOSED', 'PENDING']),\n\t\ttype: z.enum(['ORDER', 'GENERAL', 'COMPLAINT']),\n\t\tclient: z.string(),\n\t\tclientType: z.enum(['USER', 'SHOP']),\n\t},\n});\n\ntype TicketFilterDTO = z.infer<typeof TicketFilterSchema>;\n\nconst ticket: TicketFilterDTO = {\n\tsort: { createdAt: -1, status: 1 }, // ✅ Only allowed fields with 1 or -1\n};\n\n/**\n * EXAMPLE USAGE\n *\n * const TicketFilterSchema = createFilterSchema({\n * selectableFields: [\n * '_id',\n * 'ticketId',\n * 'type',\n * 'status',\n * 'createdAt',\n * 'updatedAt',\n * ] as const,\n *\n * populatableFields: {\n * chatroom: ['_id', 'lastMessage', 'participants', 'unreadCount'] as const,\n * client: ['_id', 'name', 'profilePhoto', 'type'] as const,\n * admin: ['_id', 'name', 'profilePhoto'] as const,\n * order: ['_id', 'orderId', 'shop', 'total'] as const,\n * } as const,\n *\n * searchableFields: ['ticketId'] as const,\n *\n * sortableFields: ['createdAt', 'updatedAt', 'ticketId', 'status'] as const,\n *\n * queryableFields: {\n * status: z.enum(['OPEN', 'CLOSED', 'PENDING']),\n * type: z.enum(['ORDER', 'GENERAL', 'COMPLAINT']),\n * client: z.string(),\n * clientType: z.enum(['USER', 'SHOP']),\n * },\n * });\n *\n * type TicketFilterDTO = z.infer<typeof TicketFilterSchema>;\n *\n * // ✅ VALID EXAMPLES\n *\n * // Example 1: Sort by allowed fields\n * const filter1: TicketFilterDTO = {\n * sort: { createdAt: -1, status: 1 },\n * query: { status: 'OPEN' },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 2: Populate client with specific fields\n * const filter2: TicketFilterDTO = {\n * populate: [\n * { path: 'client', select: { name: 1, profilePhoto: 1 } }\n * ],\n * sort: { updatedAt: -1 },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 3: Populate multiple relations with sort\n * const filter3: TicketFilterDTO = {\n * populate: [\n * { path: 'client', select: { name: 1, profilePhoto: 1 } },\n * { path: 'order', select: { orderId: 1, total: 1 } },\n * { path: 'chatroom', select: { lastMessage: 1, unreadCount: 1 } },\n * ],\n * sort: { createdAt: -1 },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 4: Complex query with search and sort\n * const filter4: TicketFilterDTO = {\n * query: { status: 'OPEN', type: 'ORDER' },\n * search: { searchKey: 'TKT-123', searchFields: ['ticketId'] },\n * populate: [{ path: 'client', select: { name: 1 } }],\n * sort: { createdAt: -1, ticketId: 1 },\n * page: 1,\n * size: 20,\n * };\n *\n * // Example 5: Populate with match and options\n * const filter5: TicketFilterDTO = {\n * populate: [\n * {\n * path: 'order',\n * select: { orderId: 1, shop: 1 },\n * match: { status: 'DELIVERED' },\n * options: { sort: { createdAt: -1 }, limit: 10 },\n * }\n * ],\n * sort: { updatedAt: -1 },\n * page: 1,\n * size: 20,\n * };\n *\n * // ❌ INVALID EXAMPLES (TypeScript will reject)\n *\n * const invalid1: TicketFilterDTO = {\n * sort: { invalidField: 1 }, // ❌ not in sortableFields\n * };\n *\n * const invalid2: TicketFilterDTO = {\n * sort: { createdAt: 2 }, // ❌ must be 1 or -1\n * };\n *\n * const invalid3: TicketFilterDTO = {\n * populate: [\n * {\n * path: 'client',\n * select: { email: 1 }, // ❌ email not in client's populatableFields\n * }\n * ],\n * };\n *\n * const invalid4: TicketFilterDTO = {\n * query: { status: 'INVALID_STATUS' }, // ❌ not in enum\n * }\n */\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lyxa.ai/core",
3
- "version": "1.1.66",
3
+ "version": "1.1.68",
4
4
  "description": "The Core system of the Lyxa services.",
5
5
  "author": "elie <42282499+Internalizable@users.noreply.github.com>",
6
6
  "license": "MIT",