@lyxa.ai/core 1.1.59 → 1.1.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/libraries/mongo/models/user.model.d.ts +1 -1
- package/dist/types/README.md +1 -1
- package/dist/types/package.json +1 -1
- package/dist/types/utilities/validation/common-validation.d.ts +2 -78
- package/dist/types/utilities/validation/filter-schema.factory.d.ts +11 -9
- package/dist/types/utilities/validation/filter-schema.factory.js +10 -7
- package/dist/types/utilities/validation/filter-schema.factory.js.map +1 -1
- package/dist/types/utilities/validation/global-validation.d.ts +14 -38
- package/dist/utilities/validation/common-validation.d.ts +2 -78
- package/dist/utilities/validation/filter-schema.factory.d.ts +11 -9
- package/dist/utilities/validation/filter-schema.factory.js +10 -7
- package/dist/utilities/validation/filter-schema.factory.js.map +1 -1
- package/dist/utilities/validation/global-validation.d.ts +14 -38
- package/dist/utilities/workHourSetting.d.ts +23 -0
- package/dist/utilities/workHourSetting.js +156 -0
- package/dist/utilities/workHourSetting.js.map +1 -0
- package/package.json +1 -1
|
@@ -32,7 +32,7 @@ export declare class User extends TimeStamps {
|
|
|
32
32
|
isPhoneVerified?: boolean;
|
|
33
33
|
onlineStatus?: OnlineStatus;
|
|
34
34
|
fcmTokens?: string[];
|
|
35
|
-
static updateWallet(this: ReturnModelType<typeof User>, userId: string, amount: number): Promise<(import("mongoose").Document<unknown, import("@typegoose/typegoose/lib/types").BeAnObject, User, import("@typegoose/typegoose/lib/types").BeAnyObject> & Omit<User & {
|
|
35
|
+
static updateWallet(this: ReturnModelType<typeof User>, userId: string, amount: number): Promise<(import("mongoose").Document<unknown, import("@typegoose/typegoose/lib/types").BeAnObject, User, import("@typegoose/typegoose/lib/types").BeAnyObject, {}> & Omit<User & {
|
|
36
36
|
_id: import("mongoose").Types.ObjectId;
|
|
37
37
|
} & {
|
|
38
38
|
__v: number;
|
package/dist/types/README.md
CHANGED
package/dist/types/package.json
CHANGED
|
@@ -646,7 +646,7 @@ export declare const createResponseSchema: <T>(schema: z.ZodSchema<T>) => z.ZodO
|
|
|
646
646
|
totalPages: number;
|
|
647
647
|
} | undefined;
|
|
648
648
|
}>, z.ZodType<T, z.ZodTypeDef, T>]>>;
|
|
649
|
-
}>, any> extends infer T_1 ? { [k in keyof T_1]: z.
|
|
649
|
+
}>, any> extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never, z.baseObjectInputType<{
|
|
650
650
|
success: z.ZodBoolean;
|
|
651
651
|
message: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
652
652
|
data: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
|
|
@@ -684,83 +684,7 @@ export declare const createResponseSchema: <T>(schema: z.ZodSchema<T>) => z.ZodO
|
|
|
684
684
|
totalPages: number;
|
|
685
685
|
} | undefined;
|
|
686
686
|
}>, z.ZodType<T, z.ZodTypeDef, T>]>>;
|
|
687
|
-
}
|
|
688
|
-
success: z.ZodBoolean;
|
|
689
|
-
message: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
690
|
-
data: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
|
|
691
|
-
metadata: z.ZodOptional<z.ZodObject<{
|
|
692
|
-
page: z.ZodNumber;
|
|
693
|
-
size: z.ZodNumber;
|
|
694
|
-
totalElements: z.ZodNumber;
|
|
695
|
-
totalPages: z.ZodNumber;
|
|
696
|
-
}, "strip", z.ZodTypeAny, {
|
|
697
|
-
size: number;
|
|
698
|
-
page: number;
|
|
699
|
-
totalElements: number;
|
|
700
|
-
totalPages: number;
|
|
701
|
-
}, {
|
|
702
|
-
size: number;
|
|
703
|
-
page: number;
|
|
704
|
-
totalElements: number;
|
|
705
|
-
totalPages: number;
|
|
706
|
-
}>>;
|
|
707
|
-
documents: z.ZodArray<z.ZodType<T, z.ZodTypeDef, T>, "many">;
|
|
708
|
-
}, "strip", z.ZodTypeAny, {
|
|
709
|
-
documents: T[];
|
|
710
|
-
metadata?: {
|
|
711
|
-
size: number;
|
|
712
|
-
page: number;
|
|
713
|
-
totalElements: number;
|
|
714
|
-
totalPages: number;
|
|
715
|
-
} | undefined;
|
|
716
|
-
}, {
|
|
717
|
-
documents: T[];
|
|
718
|
-
metadata?: {
|
|
719
|
-
size: number;
|
|
720
|
-
page: number;
|
|
721
|
-
totalElements: number;
|
|
722
|
-
totalPages: number;
|
|
723
|
-
} | undefined;
|
|
724
|
-
}>, z.ZodType<T, z.ZodTypeDef, T>]>>;
|
|
725
|
-
}> extends infer T_2 ? { [k_1 in keyof T_2]: z.baseObjectInputType<{
|
|
726
|
-
success: z.ZodBoolean;
|
|
727
|
-
message: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
728
|
-
data: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
|
|
729
|
-
metadata: z.ZodOptional<z.ZodObject<{
|
|
730
|
-
page: z.ZodNumber;
|
|
731
|
-
size: z.ZodNumber;
|
|
732
|
-
totalElements: z.ZodNumber;
|
|
733
|
-
totalPages: z.ZodNumber;
|
|
734
|
-
}, "strip", z.ZodTypeAny, {
|
|
735
|
-
size: number;
|
|
736
|
-
page: number;
|
|
737
|
-
totalElements: number;
|
|
738
|
-
totalPages: number;
|
|
739
|
-
}, {
|
|
740
|
-
size: number;
|
|
741
|
-
page: number;
|
|
742
|
-
totalElements: number;
|
|
743
|
-
totalPages: number;
|
|
744
|
-
}>>;
|
|
745
|
-
documents: z.ZodArray<z.ZodType<T, z.ZodTypeDef, T>, "many">;
|
|
746
|
-
}, "strip", z.ZodTypeAny, {
|
|
747
|
-
documents: T[];
|
|
748
|
-
metadata?: {
|
|
749
|
-
size: number;
|
|
750
|
-
page: number;
|
|
751
|
-
totalElements: number;
|
|
752
|
-
totalPages: number;
|
|
753
|
-
} | undefined;
|
|
754
|
-
}, {
|
|
755
|
-
documents: T[];
|
|
756
|
-
metadata?: {
|
|
757
|
-
size: number;
|
|
758
|
-
page: number;
|
|
759
|
-
totalElements: number;
|
|
760
|
-
totalPages: number;
|
|
761
|
-
} | undefined;
|
|
762
|
-
}>, z.ZodType<T, z.ZodTypeDef, T>]>>;
|
|
763
|
-
}>[k_1]; } : never>;
|
|
687
|
+
}> extends infer T_2 ? { [k_1 in keyof T_2]: T_2[k_1]; } : never>;
|
|
764
688
|
export type PaginatedDTO<T> = {
|
|
765
689
|
metadata: DTO<typeof metadataSchema>;
|
|
766
690
|
documents: T[];
|
|
@@ -8,25 +8,27 @@ export interface FilterSchemaConfig<TSelect extends ReadonlyNonEmptyArray<string
|
|
|
8
8
|
maxSize?: number;
|
|
9
9
|
defaultSize?: number;
|
|
10
10
|
}
|
|
11
|
-
export type PopulateObject<TPath extends string,
|
|
11
|
+
export type PopulateObject<TPath extends string, TSelect extends ReadonlyNonEmptyArray<string>> = {
|
|
12
12
|
path: TPath;
|
|
13
|
-
select
|
|
14
|
-
match?: Record<
|
|
13
|
+
select: Partial<Record<TSelect[number], 0 | 1>>;
|
|
14
|
+
match?: Partial<Record<TSelect[number], any>>;
|
|
15
15
|
options?: {
|
|
16
16
|
sort?: Record<string, 1 | -1>;
|
|
17
17
|
limit?: number;
|
|
18
18
|
skip?: number;
|
|
19
19
|
};
|
|
20
|
+
populate?: never;
|
|
20
21
|
};
|
|
21
|
-
type
|
|
22
|
-
[K in keyof TPopulate]: PopulateObject<K & string, TPopulate[K]>;
|
|
23
|
-
}[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> = {}> = {
|
|
22
|
+
export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends ReadonlyNonEmptyArray<string> | [] = [], TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}> = {
|
|
25
23
|
size?: number;
|
|
26
24
|
page?: number;
|
|
27
25
|
sort?: Record<string, 1 | -1>;
|
|
28
26
|
select?: TSelect extends ReadonlyNonEmptyArray<string> ? Partial<Record<TSelect[number], 0 | 1>> : never;
|
|
29
|
-
populate?:
|
|
27
|
+
populate?: TPopulate extends ReadonlyNonEmptyArray<string> ? {
|
|
28
|
+
[P in TPopulate[number]]: PopulateObject<P, Extract<TSelect, ReadonlyNonEmptyArray<string>>>;
|
|
29
|
+
}[TPopulate[number]] | Array<{
|
|
30
|
+
[P in TPopulate[number]]: PopulateObject<P, Extract<TSelect, ReadonlyNonEmptyArray<string>>>;
|
|
31
|
+
}[TPopulate[number]]> : never;
|
|
30
32
|
search?: TSearch extends ReadonlyNonEmptyArray<string> ? {
|
|
31
33
|
searchKey: string;
|
|
32
34
|
searchFields?: TSearch[number][];
|
|
@@ -35,5 +37,5 @@ export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], T
|
|
|
35
37
|
[K in keyof TQuery]?: z.infer<TQuery[K]>;
|
|
36
38
|
};
|
|
37
39
|
};
|
|
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>>;
|
|
40
|
+
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, keyof TPopulate extends never ? [] : readonly [keyof TPopulate & string, ...(keyof TPopulate & string)[]], TSearch, TQuery>>;
|
|
39
41
|
export {};
|
|
@@ -17,15 +17,15 @@ function createFilterSchema(config) {
|
|
|
17
17
|
.optional();
|
|
18
18
|
}
|
|
19
19
|
if (populateKeys.length) {
|
|
20
|
-
const
|
|
20
|
+
const populateSchemaMap = {};
|
|
21
21
|
for (const path of populateKeys) {
|
|
22
22
|
const allowedSelects = populatableFields[path];
|
|
23
|
-
|
|
23
|
+
populateSchemaMap[path] = zod_1.z.lazy(() => zod_1.z.object({
|
|
24
24
|
path: zod_1.z.literal(path),
|
|
25
25
|
select: zod_1.z
|
|
26
26
|
.record(zod_1.z.enum([...allowedSelects]), zod_1.z.union([zod_1.z.literal(0), zod_1.z.literal(1)]))
|
|
27
27
|
.optional(),
|
|
28
|
-
match: zod_1.z.record(zod_1.z.
|
|
28
|
+
match: zod_1.z.record(zod_1.z.enum([...allowedSelects]), zod_1.z.any()).optional(),
|
|
29
29
|
options: zod_1.z
|
|
30
30
|
.object({
|
|
31
31
|
sort: sortSchema.optional(),
|
|
@@ -33,18 +33,21 @@ function createFilterSchema(config) {
|
|
|
33
33
|
skip: zod_1.z.number().optional(),
|
|
34
34
|
})
|
|
35
35
|
.optional(),
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
populate: zod_1.z.never(),
|
|
37
|
+
}));
|
|
38
38
|
}
|
|
39
|
+
const populateSchemas = Object.values(populateSchemaMap);
|
|
39
40
|
if (populateSchemas.length > 0) {
|
|
40
41
|
let unionSchema;
|
|
41
42
|
if (populateSchemas.length === 1) {
|
|
42
|
-
unionSchema = populateSchemas[0];
|
|
43
|
+
unionSchema = zod_1.z.union([populateSchemas[0], populateSchemas[0]]);
|
|
43
44
|
}
|
|
44
45
|
else {
|
|
45
46
|
unionSchema = zod_1.z.union(populateSchemas);
|
|
46
47
|
}
|
|
47
|
-
schemaShape.populate = zod_1.z
|
|
48
|
+
schemaShape.populate = zod_1.z
|
|
49
|
+
.union([unionSchema, zod_1.z.array(unionSchema)])
|
|
50
|
+
.optional();
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
if (searchableFields?.length) {
|
|
@@ -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// Each populate path has its own select fields from populatableFields\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// Create a union type 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\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> ? Partial<Record<TSelect[number], 0 | 1>> : never;\n\tpopulate?: keyof TPopulate extends never ? never : PopulateUnion<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// Select - uses selectableFields for top-level document fields\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 - each path uses its own select fields from populatableFields\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\tif (populateSchemas.length > 0) {\n\t\t\tlet unionSchema: ZodTypeAny;\n\t\t\tif (populateSchemas.length === 1) {\n\t\t\t\tunionSchema = populateSchemas[0];\n\t\t\t} else {\n\t\t\t\tunionSchema = z.union(populateSchemas as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]);\n\t\t\t}\n\t\t\tschemaShape.populate = z.union([unionSchema, z.array(unionSchema)]).optional();\n\t\t}\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/**\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> {\n\tselectableFields?: TSelect;\n\tpopulatableFields?: TPopulate;\n\tsearchableFields?: TSearch;\n\tqueryableFields?: TQuery;\n\tmaxSize?: number;\n\tdefaultSize?: number;\n}\n\nexport type PopulateObject<TPath extends string, TSelect extends ReadonlyNonEmptyArray<string>> = {\n\tpath: TPath;\n\tselect: Partial<Record<TSelect[number], 0 | 1>>;\n\tmatch?: Partial<Record<TSelect[number], any>>;\n\toptions?: { sort?: Record<string, 1 | -1>; limit?: number; skip?: number };\n\tpopulate?: never;\n};\n\nexport type FilterDTO<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends 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> ? Partial<Record<TSelect[number], 0 | 1>> : never;\n\tpopulate?: TPopulate extends ReadonlyNonEmptyArray<string>\n\t\t?\n\t\t\t\t| {\n\t\t\t\t\t\t[P in TPopulate[number]]: PopulateObject<P, Extract<TSelect, ReadonlyNonEmptyArray<string>>>;\n\t\t\t\t }[TPopulate[number]]\n\t\t\t\t| Array<\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t[P in TPopulate[number]]: PopulateObject<P, Extract<TSelect, ReadonlyNonEmptyArray<string>>>;\n\t\t\t\t\t\t}[TPopulate[number]]\n\t\t\t\t >\n\t\t: never;\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// 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\n\tif (populateKeys.length) {\n\t\tconst populateSchemaMap: Record<string, ZodTypeAny> = {};\n\n\t\tfor (const path of populateKeys) {\n\t\t\tconst allowedSelects = populatableFields![path] as ReadonlyNonEmptyArray<string>;\n\n\t\t\tpopulateSchemaMap[path as string] = z.lazy(() =>\n\t\t\t\tz.object({\n\t\t\t\t\tpath: z.literal(path as string),\n\t\t\t\t\tselect: z\n\t\t\t\t\t\t.record(\n\t\t\t\t\t\t\tz.enum([...allowedSelects] as [string, ...string[]]),\n\t\t\t\t\t\t\tz.union([z.literal(0), z.literal(1)])\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.optional(),\n\t\t\t\t\tmatch: z.record(z.enum([...allowedSelects] as [string, ...string[]]), z.any()).optional(),\n\t\t\t\t\toptions: z\n\t\t\t\t\t\t.object({\n\t\t\t\t\t\t\tsort: sortSchema.optional(),\n\t\t\t\t\t\t\tlimit: z.number().optional(),\n\t\t\t\t\t\t\tskip: z.number().optional(),\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.optional(),\n\t\t\t\t\tpopulate: z.never(),\n\t\t\t\t})\n\t\t\t) as ZodTypeAny;\n\t\t}\n\n\t\tconst populateSchemas = Object.values(populateSchemaMap);\n\n\t\tif (populateSchemas.length > 0) {\n\t\t\tlet unionSchema: ZodTypeAny;\n\t\t\tif (populateSchemas.length === 1) {\n\t\t\t\tunionSchema = z.union([populateSchemas[0], populateSchemas[0]]);\n\t\t\t} else {\n\t\t\t\tunionSchema = z.union(populateSchemas as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]);\n\t\t\t}\n\t\t\tschemaShape.populate = z\n\t\t\t\t.union([unionSchema, z.array(unionSchema)] as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]])\n\t\t\t\t.optional();\n\t\t}\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\ttype KeysToReadonlyNonEmptyArray<T> = keyof T extends never\n\t\t? []\n\t\t: readonly [keyof T & string, ...(keyof T & string)[]];\n\n\treturn z.object(schemaShape) as z.ZodType<\n\t\tFilterDTO<TSelect, KeysToReadonlyNonEmptyArray<TPopulate>, TSearch, TQuery>\n\t>;\n}\n\n/**\n *\n *\n * const UserFilterSchema = createFilterSchema({\n * \tselectableFields: ['_id', 'name', 'email', 'role'] as const,\n * \tpopulatableFields: { organization: ['_id', 'name', 'address'] as const },\n * \tsearchableFields: ['name', 'email'] as const,\n * \tqueryableFields: {\n * \t\trole: z.string(),\n * \t\tactive: z.boolean(),\n * \t},\n * });\n *\n * type UserFilter = z.infer<typeof UserFilterSchema>;\n *\n * const validFilter: UserFilter = {\n * \tselect: { name: 1, email: 1 },\n * \tquery: { role: 'admin', active: true },\n * \tpopulate: { path: 'organization', select: { name: 1 } },\n * \tsearch: { searchKey: 'john', searchFields: ['name', 'email'] },\n * \tpage: 1,\n * \tsize: 20,\n * };\n *\n * ❌ TypeScript will reject invalid assignments\n * const invalidFilter: UserFilter = {\n * \tselect: { password: 1 }, // ❌ not allowed\n * \tquery: { role: 123, active: 'yes' }, // ❌ not allowed\n * \tpopulate: { path: 'organization', select: { unknown: 1 } }, // ❌ not allowed\n * \tsearch: { searchKey: 'x', searchFields: ['unknown'] }, // ❌ not allowed\n * };\n *\n */\n"]}
|
|
@@ -76,34 +76,22 @@ export declare class SchemaBuilder<T extends z.ZodRawShape> {
|
|
|
76
76
|
private baseSchema;
|
|
77
77
|
constructor(baseFields: T, includeTimestamps?: boolean, includeTracking?: boolean);
|
|
78
78
|
private createBaseSchema;
|
|
79
|
-
getBaseSchema(): z.ZodObject<T, "strict", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_1 ? { [k in keyof T_1]:
|
|
79
|
+
getBaseSchema(): z.ZodObject<T, "strict", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never, z.baseObjectInputType<T> extends infer T_2 ? { [k_1 in keyof T_2]: T_2[k_1]; } : never>;
|
|
80
80
|
getEntitySchema(): z.ZodObject<z.objectUtil.extendShape<T, {
|
|
81
81
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
82
|
-
}> extends infer T_1 extends z.ZodRawShape ? { [k in keyof T_1]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
82
|
+
}> extends infer T_1 extends z.ZodRawShape ? { [k in keyof T_1]: z.ZodOptional<T_1[k]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
83
83
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
84
|
-
}>[k]>; } : never,
|
|
84
|
+
}> extends infer T_2 extends z.ZodRawShape ? { [k in keyof T_2]: z.ZodOptional<T_2[k]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
85
85
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
86
|
-
}> extends infer
|
|
87
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
88
|
-
}>[k]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
89
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
90
|
-
}> extends infer T_3 extends z.ZodRawShape ? { [k in keyof T_3]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
91
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
92
|
-
}>[k]>; } : never, z.ZodTypeAny, "passthrough">>;
|
|
86
|
+
}> extends infer T_3 extends z.ZodRawShape ? { [k in keyof T_3]: z.ZodOptional<T_3[k]>; } : never, z.ZodTypeAny, "passthrough">>;
|
|
93
87
|
getIdSchema(): z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
94
88
|
getUpdateSchema(excludeFields?: ExcludeFromUpdate): z.ZodObject<z.objectUtil.extendShape<T, {
|
|
95
89
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
96
|
-
}> extends infer T_1 extends z.ZodRawShape ? { [k in keyof T_1]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
97
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
98
|
-
}>[k]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
99
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
100
|
-
}> extends infer T_2 extends z.ZodRawShape ? { [k in keyof T_2]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
101
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
102
|
-
}>[k]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
90
|
+
}> extends infer T_1 extends z.ZodRawShape ? { [k in keyof T_1]: z.ZodOptional<T_1[k]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
103
91
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
104
|
-
}> extends infer
|
|
92
|
+
}> extends infer T_2 extends z.ZodRawShape ? { [k in keyof T_2]: z.ZodOptional<T_2[k]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
105
93
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
106
|
-
}>[k]>; } : never, z.ZodTypeAny, "passthrough">> | z.ZodObject<{
|
|
94
|
+
}> extends infer T_3 extends z.ZodRawShape ? { [k in keyof T_3]: z.ZodOptional<T_3[k]>; } : never, z.ZodTypeAny, "passthrough">> | z.ZodObject<{
|
|
107
95
|
[x: string]: z.ZodOptional<z.ZodTypeAny>;
|
|
108
96
|
}, "strict", z.ZodTypeAny, {
|
|
109
97
|
[x: string]: any;
|
|
@@ -126,34 +114,22 @@ export declare class SchemaBuilder<T extends z.ZodRawShape> {
|
|
|
126
114
|
[x: string]: any;
|
|
127
115
|
}>;
|
|
128
116
|
getAllSchemas(excludeFromUpdate?: ExcludeFromUpdate): {
|
|
129
|
-
BaseSchema: z.ZodObject<T, "strict", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_1 ? { [k in keyof T_1]:
|
|
117
|
+
BaseSchema: z.ZodObject<T, "strict", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never, z.baseObjectInputType<T> extends infer T_2 ? { [k_1 in keyof T_2]: T_2[k_1]; } : never>;
|
|
130
118
|
EntitySchema: z.ZodObject<z.objectUtil.extendShape<T, {
|
|
131
119
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
132
|
-
}> extends infer T_3 extends z.ZodRawShape ? { [k_2 in keyof T_3]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
120
|
+
}> extends infer T_3 extends z.ZodRawShape ? { [k_2 in keyof T_3]: z.ZodOptional<T_3[k_2]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
133
121
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
134
|
-
}>[k_2]>; } : never,
|
|
122
|
+
}> extends infer T_4 extends z.ZodRawShape ? { [k_2 in keyof T_4]: z.ZodOptional<T_4[k_2]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
135
123
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
136
|
-
}> extends infer
|
|
137
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
138
|
-
}>[k_2]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
139
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
140
|
-
}> extends infer T_5 extends z.ZodRawShape ? { [k_2 in keyof T_5]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
141
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
142
|
-
}>[k_2]>; } : never, z.ZodTypeAny, "passthrough">>;
|
|
124
|
+
}> extends infer T_5 extends z.ZodRawShape ? { [k_2 in keyof T_5]: z.ZodOptional<T_5[k_2]>; } : never, z.ZodTypeAny, "passthrough">>;
|
|
143
125
|
IdSchema: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
144
126
|
UpdateSchema: z.ZodObject<z.objectUtil.extendShape<T, {
|
|
145
127
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
146
|
-
}> extends infer T_6 extends z.ZodRawShape ? { [k_2 in keyof T_6]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
147
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
148
|
-
}>[k_2]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
149
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
150
|
-
}> extends infer T_7 extends z.ZodRawShape ? { [k_2 in keyof T_7]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
151
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
152
|
-
}>[k_2]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
128
|
+
}> extends infer T_6 extends z.ZodRawShape ? { [k_2 in keyof T_6]: z.ZodOptional<T_6[k_2]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
153
129
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
154
|
-
}> extends infer
|
|
130
|
+
}> extends infer T_7 extends z.ZodRawShape ? { [k_2 in keyof T_7]: z.ZodOptional<T_7[k_2]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
155
131
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
156
|
-
}>[k_2]>; } : never, z.ZodTypeAny, "passthrough">> | z.ZodObject<{
|
|
132
|
+
}> extends infer T_8 extends z.ZodRawShape ? { [k_2 in keyof T_8]: z.ZodOptional<T_8[k_2]>; } : never, z.ZodTypeAny, "passthrough">> | z.ZodObject<{
|
|
157
133
|
[x: string]: z.ZodOptional<z.ZodTypeAny>;
|
|
158
134
|
}, "strict", z.ZodTypeAny, {
|
|
159
135
|
[x: string]: any;
|
|
@@ -646,7 +646,7 @@ export declare const createResponseSchema: <T>(schema: z.ZodSchema<T>) => z.ZodO
|
|
|
646
646
|
totalPages: number;
|
|
647
647
|
} | undefined;
|
|
648
648
|
}>, z.ZodType<T, z.ZodTypeDef, T>]>>;
|
|
649
|
-
}>, any> extends infer T_1 ? { [k in keyof T_1]: z.
|
|
649
|
+
}>, any> extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never, z.baseObjectInputType<{
|
|
650
650
|
success: z.ZodBoolean;
|
|
651
651
|
message: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
652
652
|
data: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
|
|
@@ -684,83 +684,7 @@ export declare const createResponseSchema: <T>(schema: z.ZodSchema<T>) => z.ZodO
|
|
|
684
684
|
totalPages: number;
|
|
685
685
|
} | undefined;
|
|
686
686
|
}>, z.ZodType<T, z.ZodTypeDef, T>]>>;
|
|
687
|
-
}
|
|
688
|
-
success: z.ZodBoolean;
|
|
689
|
-
message: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
690
|
-
data: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
|
|
691
|
-
metadata: z.ZodOptional<z.ZodObject<{
|
|
692
|
-
page: z.ZodNumber;
|
|
693
|
-
size: z.ZodNumber;
|
|
694
|
-
totalElements: z.ZodNumber;
|
|
695
|
-
totalPages: z.ZodNumber;
|
|
696
|
-
}, "strip", z.ZodTypeAny, {
|
|
697
|
-
page: number;
|
|
698
|
-
size: number;
|
|
699
|
-
totalElements: number;
|
|
700
|
-
totalPages: number;
|
|
701
|
-
}, {
|
|
702
|
-
page: number;
|
|
703
|
-
size: number;
|
|
704
|
-
totalElements: number;
|
|
705
|
-
totalPages: number;
|
|
706
|
-
}>>;
|
|
707
|
-
documents: z.ZodArray<z.ZodType<T, z.ZodTypeDef, T>, "many">;
|
|
708
|
-
}, "strip", z.ZodTypeAny, {
|
|
709
|
-
documents: T[];
|
|
710
|
-
metadata?: {
|
|
711
|
-
page: number;
|
|
712
|
-
size: number;
|
|
713
|
-
totalElements: number;
|
|
714
|
-
totalPages: number;
|
|
715
|
-
} | undefined;
|
|
716
|
-
}, {
|
|
717
|
-
documents: T[];
|
|
718
|
-
metadata?: {
|
|
719
|
-
page: number;
|
|
720
|
-
size: number;
|
|
721
|
-
totalElements: number;
|
|
722
|
-
totalPages: number;
|
|
723
|
-
} | undefined;
|
|
724
|
-
}>, z.ZodType<T, z.ZodTypeDef, T>]>>;
|
|
725
|
-
}> extends infer T_2 ? { [k_1 in keyof T_2]: z.baseObjectInputType<{
|
|
726
|
-
success: z.ZodBoolean;
|
|
727
|
-
message: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
728
|
-
data: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
|
|
729
|
-
metadata: z.ZodOptional<z.ZodObject<{
|
|
730
|
-
page: z.ZodNumber;
|
|
731
|
-
size: z.ZodNumber;
|
|
732
|
-
totalElements: z.ZodNumber;
|
|
733
|
-
totalPages: z.ZodNumber;
|
|
734
|
-
}, "strip", z.ZodTypeAny, {
|
|
735
|
-
page: number;
|
|
736
|
-
size: number;
|
|
737
|
-
totalElements: number;
|
|
738
|
-
totalPages: number;
|
|
739
|
-
}, {
|
|
740
|
-
page: number;
|
|
741
|
-
size: number;
|
|
742
|
-
totalElements: number;
|
|
743
|
-
totalPages: number;
|
|
744
|
-
}>>;
|
|
745
|
-
documents: z.ZodArray<z.ZodType<T, z.ZodTypeDef, T>, "many">;
|
|
746
|
-
}, "strip", z.ZodTypeAny, {
|
|
747
|
-
documents: T[];
|
|
748
|
-
metadata?: {
|
|
749
|
-
page: number;
|
|
750
|
-
size: number;
|
|
751
|
-
totalElements: number;
|
|
752
|
-
totalPages: number;
|
|
753
|
-
} | undefined;
|
|
754
|
-
}, {
|
|
755
|
-
documents: T[];
|
|
756
|
-
metadata?: {
|
|
757
|
-
page: number;
|
|
758
|
-
size: number;
|
|
759
|
-
totalElements: number;
|
|
760
|
-
totalPages: number;
|
|
761
|
-
} | undefined;
|
|
762
|
-
}>, z.ZodType<T, z.ZodTypeDef, T>]>>;
|
|
763
|
-
}>[k_1]; } : never>;
|
|
687
|
+
}> extends infer T_2 ? { [k_1 in keyof T_2]: T_2[k_1]; } : never>;
|
|
764
688
|
export type PaginatedDTO<T> = {
|
|
765
689
|
metadata: DTO<typeof metadataSchema>;
|
|
766
690
|
documents: T[];
|
|
@@ -8,25 +8,27 @@ export interface FilterSchemaConfig<TSelect extends ReadonlyNonEmptyArray<string
|
|
|
8
8
|
maxSize?: number;
|
|
9
9
|
defaultSize?: number;
|
|
10
10
|
}
|
|
11
|
-
export type PopulateObject<TPath extends string,
|
|
11
|
+
export type PopulateObject<TPath extends string, TSelect extends ReadonlyNonEmptyArray<string>> = {
|
|
12
12
|
path: TPath;
|
|
13
|
-
select
|
|
14
|
-
match?: Record<
|
|
13
|
+
select: Partial<Record<TSelect[number], 0 | 1>>;
|
|
14
|
+
match?: Partial<Record<TSelect[number], any>>;
|
|
15
15
|
options?: {
|
|
16
16
|
sort?: Record<string, 1 | -1>;
|
|
17
17
|
limit?: number;
|
|
18
18
|
skip?: number;
|
|
19
19
|
};
|
|
20
|
+
populate?: never;
|
|
20
21
|
};
|
|
21
|
-
type
|
|
22
|
-
[K in keyof TPopulate]: PopulateObject<K & string, TPopulate[K]>;
|
|
23
|
-
}[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> = {}> = {
|
|
22
|
+
export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], TPopulate extends ReadonlyNonEmptyArray<string> | [] = [], TSearch extends ReadonlyNonEmptyArray<string> | [] = [], TQuery extends Record<string, ZodTypeAny> = {}> = {
|
|
25
23
|
size?: number;
|
|
26
24
|
page?: number;
|
|
27
25
|
sort?: Record<string, 1 | -1>;
|
|
28
26
|
select?: TSelect extends ReadonlyNonEmptyArray<string> ? Partial<Record<TSelect[number], 0 | 1>> : never;
|
|
29
|
-
populate?:
|
|
27
|
+
populate?: TPopulate extends ReadonlyNonEmptyArray<string> ? {
|
|
28
|
+
[P in TPopulate[number]]: PopulateObject<P, Extract<TSelect, ReadonlyNonEmptyArray<string>>>;
|
|
29
|
+
}[TPopulate[number]] | Array<{
|
|
30
|
+
[P in TPopulate[number]]: PopulateObject<P, Extract<TSelect, ReadonlyNonEmptyArray<string>>>;
|
|
31
|
+
}[TPopulate[number]]> : never;
|
|
30
32
|
search?: TSearch extends ReadonlyNonEmptyArray<string> ? {
|
|
31
33
|
searchKey: string;
|
|
32
34
|
searchFields?: TSearch[number][];
|
|
@@ -35,5 +37,5 @@ export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string> | [] = [], T
|
|
|
35
37
|
[K in keyof TQuery]?: z.infer<TQuery[K]>;
|
|
36
38
|
};
|
|
37
39
|
};
|
|
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>>;
|
|
40
|
+
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, keyof TPopulate extends never ? [] : readonly [keyof TPopulate & string, ...(keyof TPopulate & string)[]], TSearch, TQuery>>;
|
|
39
41
|
export {};
|
|
@@ -17,15 +17,15 @@ function createFilterSchema(config) {
|
|
|
17
17
|
.optional();
|
|
18
18
|
}
|
|
19
19
|
if (populateKeys.length) {
|
|
20
|
-
const
|
|
20
|
+
const populateSchemaMap = {};
|
|
21
21
|
for (const path of populateKeys) {
|
|
22
22
|
const allowedSelects = populatableFields[path];
|
|
23
|
-
|
|
23
|
+
populateSchemaMap[path] = zod_1.z.lazy(() => zod_1.z.object({
|
|
24
24
|
path: zod_1.z.literal(path),
|
|
25
25
|
select: zod_1.z
|
|
26
26
|
.record(zod_1.z.enum([...allowedSelects]), zod_1.z.union([zod_1.z.literal(0), zod_1.z.literal(1)]))
|
|
27
27
|
.optional(),
|
|
28
|
-
match: zod_1.z.record(zod_1.z.
|
|
28
|
+
match: zod_1.z.record(zod_1.z.enum([...allowedSelects]), zod_1.z.any()).optional(),
|
|
29
29
|
options: zod_1.z
|
|
30
30
|
.object({
|
|
31
31
|
sort: sortSchema.optional(),
|
|
@@ -33,18 +33,21 @@ function createFilterSchema(config) {
|
|
|
33
33
|
skip: zod_1.z.number().optional(),
|
|
34
34
|
})
|
|
35
35
|
.optional(),
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
populate: zod_1.z.never(),
|
|
37
|
+
}));
|
|
38
38
|
}
|
|
39
|
+
const populateSchemas = Object.values(populateSchemaMap);
|
|
39
40
|
if (populateSchemas.length > 0) {
|
|
40
41
|
let unionSchema;
|
|
41
42
|
if (populateSchemas.length === 1) {
|
|
42
|
-
unionSchema = populateSchemas[0];
|
|
43
|
+
unionSchema = zod_1.z.union([populateSchemas[0], populateSchemas[0]]);
|
|
43
44
|
}
|
|
44
45
|
else {
|
|
45
46
|
unionSchema = zod_1.z.union(populateSchemas);
|
|
46
47
|
}
|
|
47
|
-
schemaShape.populate = zod_1.z
|
|
48
|
+
schemaShape.populate = zod_1.z
|
|
49
|
+
.union([unionSchema, zod_1.z.array(unionSchema)])
|
|
50
|
+
.optional();
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
if (searchableFields?.length) {
|
|
@@ -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// Each populate path has its own select fields from populatableFields\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// Create a union type 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\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> ? Partial<Record<TSelect[number], 0 | 1>> : never;\n\tpopulate?: keyof TPopulate extends never ? never : PopulateUnion<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// Select - uses selectableFields for top-level document fields\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 - each path uses its own select fields from populatableFields\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\tif (populateSchemas.length > 0) {\n\t\t\tlet unionSchema: ZodTypeAny;\n\t\t\tif (populateSchemas.length === 1) {\n\t\t\t\tunionSchema = populateSchemas[0];\n\t\t\t} else {\n\t\t\t\tunionSchema = z.union(populateSchemas as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]);\n\t\t\t}\n\t\t\tschemaShape.populate = z.union([unionSchema, z.array(unionSchema)]).optional();\n\t\t}\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/**\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> {\n\tselectableFields?: TSelect;\n\tpopulatableFields?: TPopulate;\n\tsearchableFields?: TSearch;\n\tqueryableFields?: TQuery;\n\tmaxSize?: number;\n\tdefaultSize?: number;\n}\n\nexport type PopulateObject<TPath extends string, TSelect extends ReadonlyNonEmptyArray<string>> = {\n\tpath: TPath;\n\tselect: Partial<Record<TSelect[number], 0 | 1>>;\n\tmatch?: Partial<Record<TSelect[number], any>>;\n\toptions?: { sort?: Record<string, 1 | -1>; limit?: number; skip?: number };\n\tpopulate?: never;\n};\n\nexport type FilterDTO<\n\tTSelect extends ReadonlyNonEmptyArray<string> | [] = [],\n\tTPopulate extends 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> ? Partial<Record<TSelect[number], 0 | 1>> : never;\n\tpopulate?: TPopulate extends ReadonlyNonEmptyArray<string>\n\t\t?\n\t\t\t\t| {\n\t\t\t\t\t\t[P in TPopulate[number]]: PopulateObject<P, Extract<TSelect, ReadonlyNonEmptyArray<string>>>;\n\t\t\t\t }[TPopulate[number]]\n\t\t\t\t| Array<\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t[P in TPopulate[number]]: PopulateObject<P, Extract<TSelect, ReadonlyNonEmptyArray<string>>>;\n\t\t\t\t\t\t}[TPopulate[number]]\n\t\t\t\t >\n\t\t: never;\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// 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\n\tif (populateKeys.length) {\n\t\tconst populateSchemaMap: Record<string, ZodTypeAny> = {};\n\n\t\tfor (const path of populateKeys) {\n\t\t\tconst allowedSelects = populatableFields![path] as ReadonlyNonEmptyArray<string>;\n\n\t\t\tpopulateSchemaMap[path as string] = z.lazy(() =>\n\t\t\t\tz.object({\n\t\t\t\t\tpath: z.literal(path as string),\n\t\t\t\t\tselect: z\n\t\t\t\t\t\t.record(\n\t\t\t\t\t\t\tz.enum([...allowedSelects] as [string, ...string[]]),\n\t\t\t\t\t\t\tz.union([z.literal(0), z.literal(1)])\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.optional(),\n\t\t\t\t\tmatch: z.record(z.enum([...allowedSelects] as [string, ...string[]]), z.any()).optional(),\n\t\t\t\t\toptions: z\n\t\t\t\t\t\t.object({\n\t\t\t\t\t\t\tsort: sortSchema.optional(),\n\t\t\t\t\t\t\tlimit: z.number().optional(),\n\t\t\t\t\t\t\tskip: z.number().optional(),\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.optional(),\n\t\t\t\t\tpopulate: z.never(),\n\t\t\t\t})\n\t\t\t) as ZodTypeAny;\n\t\t}\n\n\t\tconst populateSchemas = Object.values(populateSchemaMap);\n\n\t\tif (populateSchemas.length > 0) {\n\t\t\tlet unionSchema: ZodTypeAny;\n\t\t\tif (populateSchemas.length === 1) {\n\t\t\t\tunionSchema = z.union([populateSchemas[0], populateSchemas[0]]);\n\t\t\t} else {\n\t\t\t\tunionSchema = z.union(populateSchemas as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]]);\n\t\t\t}\n\t\t\tschemaShape.populate = z\n\t\t\t\t.union([unionSchema, z.array(unionSchema)] as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]])\n\t\t\t\t.optional();\n\t\t}\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\ttype KeysToReadonlyNonEmptyArray<T> = keyof T extends never\n\t\t? []\n\t\t: readonly [keyof T & string, ...(keyof T & string)[]];\n\n\treturn z.object(schemaShape) as z.ZodType<\n\t\tFilterDTO<TSelect, KeysToReadonlyNonEmptyArray<TPopulate>, TSearch, TQuery>\n\t>;\n}\n\n/**\n *\n *\n * const UserFilterSchema = createFilterSchema({\n * \tselectableFields: ['_id', 'name', 'email', 'role'] as const,\n * \tpopulatableFields: { organization: ['_id', 'name', 'address'] as const },\n * \tsearchableFields: ['name', 'email'] as const,\n * \tqueryableFields: {\n * \t\trole: z.string(),\n * \t\tactive: z.boolean(),\n * \t},\n * });\n *\n * type UserFilter = z.infer<typeof UserFilterSchema>;\n *\n * const validFilter: UserFilter = {\n * \tselect: { name: 1, email: 1 },\n * \tquery: { role: 'admin', active: true },\n * \tpopulate: { path: 'organization', select: { name: 1 } },\n * \tsearch: { searchKey: 'john', searchFields: ['name', 'email'] },\n * \tpage: 1,\n * \tsize: 20,\n * };\n *\n * ❌ TypeScript will reject invalid assignments\n * const invalidFilter: UserFilter = {\n * \tselect: { password: 1 }, // ❌ not allowed\n * \tquery: { role: 123, active: 'yes' }, // ❌ not allowed\n * \tpopulate: { path: 'organization', select: { unknown: 1 } }, // ❌ not allowed\n * \tsearch: { searchKey: 'x', searchFields: ['unknown'] }, // ❌ not allowed\n * };\n *\n */\n"]}
|
|
@@ -76,34 +76,22 @@ export declare class SchemaBuilder<T extends z.ZodRawShape> {
|
|
|
76
76
|
private baseSchema;
|
|
77
77
|
constructor(baseFields: T, includeTimestamps?: boolean, includeTracking?: boolean);
|
|
78
78
|
private createBaseSchema;
|
|
79
|
-
getBaseSchema(): z.ZodObject<T, "strict", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_1 ? { [k in keyof T_1]:
|
|
79
|
+
getBaseSchema(): z.ZodObject<T, "strict", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never, z.baseObjectInputType<T> extends infer T_2 ? { [k_1 in keyof T_2]: T_2[k_1]; } : never>;
|
|
80
80
|
getEntitySchema(): z.ZodObject<z.objectUtil.extendShape<T, {
|
|
81
81
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
82
|
-
}> extends infer T_1 extends z.ZodRawShape ? { [k in keyof T_1]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
82
|
+
}> extends infer T_1 extends z.ZodRawShape ? { [k in keyof T_1]: z.ZodOptional<T_1[k]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
83
83
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
84
|
-
}>[k]>; } : never,
|
|
84
|
+
}> extends infer T_2 extends z.ZodRawShape ? { [k in keyof T_2]: z.ZodOptional<T_2[k]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
85
85
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
86
|
-
}> extends infer
|
|
87
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
88
|
-
}>[k]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
89
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
90
|
-
}> extends infer T_3 extends z.ZodRawShape ? { [k in keyof T_3]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
91
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
92
|
-
}>[k]>; } : never, z.ZodTypeAny, "passthrough">>;
|
|
86
|
+
}> extends infer T_3 extends z.ZodRawShape ? { [k in keyof T_3]: z.ZodOptional<T_3[k]>; } : never, z.ZodTypeAny, "passthrough">>;
|
|
93
87
|
getIdSchema(): z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
94
88
|
getUpdateSchema(excludeFields?: ExcludeFromUpdate): z.ZodObject<z.objectUtil.extendShape<T, {
|
|
95
89
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
96
|
-
}> extends infer T_1 extends z.ZodRawShape ? { [k in keyof T_1]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
97
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
98
|
-
}>[k]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
99
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
100
|
-
}> extends infer T_2 extends z.ZodRawShape ? { [k in keyof T_2]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
101
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
102
|
-
}>[k]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
90
|
+
}> extends infer T_1 extends z.ZodRawShape ? { [k in keyof T_1]: z.ZodOptional<T_1[k]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
103
91
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
104
|
-
}> extends infer
|
|
92
|
+
}> extends infer T_2 extends z.ZodRawShape ? { [k in keyof T_2]: z.ZodOptional<T_2[k]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
105
93
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
106
|
-
}>[k]>; } : never, z.ZodTypeAny, "passthrough">> | z.ZodObject<{
|
|
94
|
+
}> extends infer T_3 extends z.ZodRawShape ? { [k in keyof T_3]: z.ZodOptional<T_3[k]>; } : never, z.ZodTypeAny, "passthrough">> | z.ZodObject<{
|
|
107
95
|
[x: string]: z.ZodOptional<z.ZodTypeAny>;
|
|
108
96
|
}, "strict", z.ZodTypeAny, {
|
|
109
97
|
[x: string]: any;
|
|
@@ -126,34 +114,22 @@ export declare class SchemaBuilder<T extends z.ZodRawShape> {
|
|
|
126
114
|
[x: string]: any;
|
|
127
115
|
}>;
|
|
128
116
|
getAllSchemas(excludeFromUpdate?: ExcludeFromUpdate): {
|
|
129
|
-
BaseSchema: z.ZodObject<T, "strict", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_1 ? { [k in keyof T_1]:
|
|
117
|
+
BaseSchema: z.ZodObject<T, "strict", z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_1 ? { [k in keyof T_1]: T_1[k]; } : never, z.baseObjectInputType<T> extends infer T_2 ? { [k_1 in keyof T_2]: T_2[k_1]; } : never>;
|
|
130
118
|
EntitySchema: z.ZodObject<z.objectUtil.extendShape<T, {
|
|
131
119
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
132
|
-
}> extends infer T_3 extends z.ZodRawShape ? { [k_2 in keyof T_3]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
120
|
+
}> extends infer T_3 extends z.ZodRawShape ? { [k_2 in keyof T_3]: z.ZodOptional<T_3[k_2]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
133
121
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
134
|
-
}>[k_2]>; } : never,
|
|
122
|
+
}> extends infer T_4 extends z.ZodRawShape ? { [k_2 in keyof T_4]: z.ZodOptional<T_4[k_2]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
135
123
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
136
|
-
}> extends infer
|
|
137
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
138
|
-
}>[k_2]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
139
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
140
|
-
}> extends infer T_5 extends z.ZodRawShape ? { [k_2 in keyof T_5]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
141
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
142
|
-
}>[k_2]>; } : never, z.ZodTypeAny, "passthrough">>;
|
|
124
|
+
}> extends infer T_5 extends z.ZodRawShape ? { [k_2 in keyof T_5]: z.ZodOptional<T_5[k_2]>; } : never, z.ZodTypeAny, "passthrough">>;
|
|
143
125
|
IdSchema: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
144
126
|
UpdateSchema: z.ZodObject<z.objectUtil.extendShape<T, {
|
|
145
127
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
146
|
-
}> extends infer T_6 extends z.ZodRawShape ? { [k_2 in keyof T_6]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
147
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
148
|
-
}>[k_2]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
149
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
150
|
-
}> extends infer T_7 extends z.ZodRawShape ? { [k_2 in keyof T_7]: z.ZodOptional<z.objectUtil.extendShape<T, {
|
|
151
|
-
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
152
|
-
}>[k_2]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
128
|
+
}> extends infer T_6 extends z.ZodRawShape ? { [k_2 in keyof T_6]: z.ZodOptional<T_6[k_2]>; } : never, "passthrough", z.ZodTypeAny, z.objectOutputType<z.objectUtil.extendShape<T, {
|
|
153
129
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
154
|
-
}> extends infer
|
|
130
|
+
}> extends infer T_7 extends z.ZodRawShape ? { [k_2 in keyof T_7]: z.ZodOptional<T_7[k_2]>; } : never, z.ZodTypeAny, "passthrough">, z.objectInputType<z.objectUtil.extendShape<T, {
|
|
155
131
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, mongoose.Types.ObjectId, string>, z.ZodType<mongoose.Types.ObjectId, z.ZodTypeDef, mongoose.Types.ObjectId>]>;
|
|
156
|
-
}>[k_2]>; } : never, z.ZodTypeAny, "passthrough">> | z.ZodObject<{
|
|
132
|
+
}> extends infer T_8 extends z.ZodRawShape ? { [k_2 in keyof T_8]: z.ZodOptional<T_8[k_2]>; } : never, z.ZodTypeAny, "passthrough">> | z.ZodObject<{
|
|
157
133
|
[x: string]: z.ZodOptional<z.ZodTypeAny>;
|
|
158
134
|
}, "strict", z.ZodTypeAny, {
|
|
159
135
|
[x: string]: any;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import dayjs, { Dayjs } from 'dayjs';
|
|
2
|
+
import { HolidayHour, NormalHour, StartEndTime } from '../libraries/mongo/models/shared/work-hour.model';
|
|
3
|
+
import { WeekDay } from './enum';
|
|
4
|
+
export declare const getDaysOfWeek: () => string[];
|
|
5
|
+
export declare const getFullDayHours: () => StartEndTime[];
|
|
6
|
+
export declare const parseTimeString: (timeHHMM: string, zone: string) => dayjs.Dayjs;
|
|
7
|
+
export declare const calculateIntersection: (opening: StartEndTime, valid: StartEndTime, timeZone: string) => StartEndTime | null;
|
|
8
|
+
export declare const getIntersectedHours: (openingHours: StartEndTime[], validHours: StartEndTime[], timeZone?: string) => StartEndTime[];
|
|
9
|
+
export declare const checkWithinNormalHours: (hours: StartEndTime[], normalTimings: NormalHour[], day: keyof typeof WeekDay) => StartEndTime[];
|
|
10
|
+
export declare const checkWithinHolidayHours: (hours: StartEndTime[], holidayTimings: HolidayHour[], currentDate: Dayjs) => StartEndTime[];
|
|
11
|
+
export declare const getHolidayIntersectedHours: (openingHours: StartEndTime[], closingHours: StartEndTime[], timeZone?: string) => StartEndTime[];
|
|
12
|
+
export declare const subtractSegment: (segment: {
|
|
13
|
+
start: dayjs.Dayjs;
|
|
14
|
+
end: dayjs.Dayjs;
|
|
15
|
+
}, block: {
|
|
16
|
+
start: dayjs.Dayjs;
|
|
17
|
+
end: dayjs.Dayjs;
|
|
18
|
+
}) => {
|
|
19
|
+
start: dayjs.Dayjs;
|
|
20
|
+
end: dayjs.Dayjs;
|
|
21
|
+
}[];
|
|
22
|
+
export declare const adminAfterHolidayWorkingHours: (workHourSetting: any) => StartEndTime[];
|
|
23
|
+
export declare const isLyxaOpen: (workHourSetting: any) => boolean;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isLyxaOpen = exports.adminAfterHolidayWorkingHours = exports.subtractSegment = exports.getHolidayIntersectedHours = exports.checkWithinHolidayHours = exports.checkWithinNormalHours = exports.getIntersectedHours = exports.calculateIntersection = exports.parseTimeString = exports.getFullDayHours = exports.getDaysOfWeek = void 0;
|
|
7
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
8
|
+
const utc_1 = __importDefault(require("dayjs/plugin/utc"));
|
|
9
|
+
const timezone_1 = __importDefault(require("dayjs/plugin/timezone"));
|
|
10
|
+
const minMax_1 = __importDefault(require("dayjs/plugin/minMax"));
|
|
11
|
+
const enum_1 = require("./enum");
|
|
12
|
+
const time_1 = require("./time");
|
|
13
|
+
dayjs_1.default.extend(utc_1.default);
|
|
14
|
+
dayjs_1.default.extend(timezone_1.default);
|
|
15
|
+
dayjs_1.default.extend(minMax_1.default);
|
|
16
|
+
const getDaysOfWeek = () => {
|
|
17
|
+
return Array.from({ length: 7 }, (_, i) => (0, dayjs_1.default)().day(i).format('dddd'));
|
|
18
|
+
};
|
|
19
|
+
exports.getDaysOfWeek = getDaysOfWeek;
|
|
20
|
+
const getFullDayHours = () => {
|
|
21
|
+
return [{ start: '0000', end: '2359' }];
|
|
22
|
+
};
|
|
23
|
+
exports.getFullDayHours = getFullDayHours;
|
|
24
|
+
const parseTimeString = (timeHHMM, zone) => {
|
|
25
|
+
const hour = Number(timeHHMM.slice(0, 2));
|
|
26
|
+
const minute = Number(timeHHMM.slice(2));
|
|
27
|
+
return (0, dayjs_1.default)().tz(zone).hour(hour).minute(minute).second(0).millisecond(0);
|
|
28
|
+
};
|
|
29
|
+
exports.parseTimeString = parseTimeString;
|
|
30
|
+
const calculateIntersection = (opening, valid, timeZone) => {
|
|
31
|
+
const openingStart = (0, exports.parseTimeString)(opening.start, timeZone);
|
|
32
|
+
const openingEnd = (0, exports.parseTimeString)(opening.end, timeZone);
|
|
33
|
+
const validStart = (0, exports.parseTimeString)(valid.start, timeZone);
|
|
34
|
+
const validEnd = (0, exports.parseTimeString)(valid.end, timeZone);
|
|
35
|
+
const intersectionStart = dayjs_1.default.max(openingStart, validStart);
|
|
36
|
+
const intersectionEnd = dayjs_1.default.min(openingEnd, validEnd);
|
|
37
|
+
return intersectionStart && intersectionEnd && intersectionStart.isBefore(intersectionEnd)
|
|
38
|
+
? {
|
|
39
|
+
start: intersectionStart.format('HHmm'),
|
|
40
|
+
end: intersectionEnd.format('HHmm'),
|
|
41
|
+
}
|
|
42
|
+
: null;
|
|
43
|
+
};
|
|
44
|
+
exports.calculateIntersection = calculateIntersection;
|
|
45
|
+
const getIntersectedHours = (openingHours, validHours, timeZone = 'Asia/Dhaka') => {
|
|
46
|
+
const intersections = [];
|
|
47
|
+
for (const opening of openingHours) {
|
|
48
|
+
for (const valid of validHours) {
|
|
49
|
+
const intersection = (0, exports.calculateIntersection)(opening, valid, timeZone);
|
|
50
|
+
if (intersection !== null) {
|
|
51
|
+
intersections.push(intersection);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return intersections;
|
|
56
|
+
};
|
|
57
|
+
exports.getIntersectedHours = getIntersectedHours;
|
|
58
|
+
const checkWithinNormalHours = (hours, normalTimings, day) => {
|
|
59
|
+
const dayTiming = normalTimings.find(timing => timing.day === enum_1.WeekDay[day]);
|
|
60
|
+
if (!dayTiming)
|
|
61
|
+
return [];
|
|
62
|
+
const statusHandlers = {
|
|
63
|
+
[enum_1.WorkStatus.CLOSED]: () => [],
|
|
64
|
+
[enum_1.WorkStatus.FULL_DAY]: () => (0, exports.getFullDayHours)(),
|
|
65
|
+
[enum_1.WorkStatus.OPEN]: () => dayTiming.openingHours?.length ? (0, exports.getIntersectedHours)(dayTiming.openingHours, hours) : [],
|
|
66
|
+
};
|
|
67
|
+
return statusHandlers[dayTiming.status]?.() || [];
|
|
68
|
+
};
|
|
69
|
+
exports.checkWithinNormalHours = checkWithinNormalHours;
|
|
70
|
+
const checkWithinHolidayHours = (hours, holidayTimings, currentDate) => {
|
|
71
|
+
if (!holidayTimings.length) {
|
|
72
|
+
return hours;
|
|
73
|
+
}
|
|
74
|
+
const currentDateInTimezone = currentDate.tz(time_1.LyxaTimezone);
|
|
75
|
+
const todaysHoliday = holidayTimings.find(holiday => {
|
|
76
|
+
if (!holiday.date)
|
|
77
|
+
return false;
|
|
78
|
+
const holidayDate = (0, dayjs_1.default)(holiday.date).tz(time_1.LyxaTimezone);
|
|
79
|
+
return currentDateInTimezone.isSame(holidayDate, 'day');
|
|
80
|
+
});
|
|
81
|
+
if (!todaysHoliday)
|
|
82
|
+
return hours;
|
|
83
|
+
if (todaysHoliday.status === enum_1.HolidayWorkStatus.FULL_DAY)
|
|
84
|
+
return [];
|
|
85
|
+
if (todaysHoliday.status === enum_1.HolidayWorkStatus.CLOSED &&
|
|
86
|
+
todaysHoliday.closingHour?.start &&
|
|
87
|
+
todaysHoliday.closingHour?.end) {
|
|
88
|
+
return (0, exports.getHolidayIntersectedHours)(hours, [todaysHoliday.closingHour]);
|
|
89
|
+
}
|
|
90
|
+
return hours;
|
|
91
|
+
};
|
|
92
|
+
exports.checkWithinHolidayHours = checkWithinHolidayHours;
|
|
93
|
+
const getHolidayIntersectedHours = (openingHours, closingHours, timeZone = 'Asia/Dhaka') => {
|
|
94
|
+
if (!openingHours.length || !closingHours.length) {
|
|
95
|
+
return openingHours;
|
|
96
|
+
}
|
|
97
|
+
const result = [];
|
|
98
|
+
for (const opening of openingHours) {
|
|
99
|
+
const openingStart = (0, exports.parseTimeString)(opening.start, timeZone);
|
|
100
|
+
const openingEnd = (0, exports.parseTimeString)(opening.end, timeZone);
|
|
101
|
+
let segments = [{ start: openingStart, end: openingEnd }];
|
|
102
|
+
for (const closing of closingHours) {
|
|
103
|
+
const closingStart = (0, exports.parseTimeString)(closing.start, timeZone);
|
|
104
|
+
const closingEnd = (0, exports.parseTimeString)(closing.end, timeZone);
|
|
105
|
+
const block = { start: closingStart, end: closingEnd };
|
|
106
|
+
segments = segments.flatMap(segment => (0, exports.subtractSegment)(segment, block));
|
|
107
|
+
}
|
|
108
|
+
for (const segment of segments) {
|
|
109
|
+
result.push({
|
|
110
|
+
start: segment.start.format('HHmm'),
|
|
111
|
+
end: segment.end.format('HHmm'),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
};
|
|
117
|
+
exports.getHolidayIntersectedHours = getHolidayIntersectedHours;
|
|
118
|
+
const subtractSegment = (segment, block) => {
|
|
119
|
+
const { start, end } = segment;
|
|
120
|
+
const { start: blockStart, end: blockEnd } = block;
|
|
121
|
+
if (end.isBefore(blockStart) || start.isAfter(blockEnd))
|
|
122
|
+
return [segment];
|
|
123
|
+
if (blockStart.isBefore(start) && blockEnd.isAfter(end))
|
|
124
|
+
return [];
|
|
125
|
+
if (blockStart.isAfter(start) && blockEnd.isBefore(end)) {
|
|
126
|
+
return [
|
|
127
|
+
{ start, end: blockStart },
|
|
128
|
+
{ start: blockEnd, end },
|
|
129
|
+
];
|
|
130
|
+
}
|
|
131
|
+
if (blockStart.isBefore(end) && blockEnd.isBefore(end) && blockEnd.isAfter(start)) {
|
|
132
|
+
return [{ start: blockEnd, end }];
|
|
133
|
+
}
|
|
134
|
+
if (blockEnd.isAfter(start) && blockStart.isAfter(start) && blockStart.isBefore(end)) {
|
|
135
|
+
return [{ start, end: blockStart }];
|
|
136
|
+
}
|
|
137
|
+
return [];
|
|
138
|
+
};
|
|
139
|
+
exports.subtractSegment = subtractSegment;
|
|
140
|
+
const adminAfterHolidayWorkingHours = (workHourSetting) => {
|
|
141
|
+
const fullDayHours = (0, exports.getFullDayHours)();
|
|
142
|
+
const now = (0, dayjs_1.default)().tz(time_1.LyxaTimezone);
|
|
143
|
+
const currentDayIndex = now.day();
|
|
144
|
+
const currentDay = (0, exports.getDaysOfWeek)()[currentDayIndex];
|
|
145
|
+
const currentDate = (0, dayjs_1.default)().utc().startOf('day');
|
|
146
|
+
const adminNormalWorkingHours = (0, exports.checkWithinNormalHours)(fullDayHours, workHourSetting.normalHours, currentDay);
|
|
147
|
+
return (0, exports.checkWithinHolidayHours)(adminNormalWorkingHours, workHourSetting.holidayHours, currentDate);
|
|
148
|
+
};
|
|
149
|
+
exports.adminAfterHolidayWorkingHours = adminAfterHolidayWorkingHours;
|
|
150
|
+
const isLyxaOpen = (workHourSetting) => {
|
|
151
|
+
const currentTime = new Date().getHours() * 100 + new Date().getMinutes();
|
|
152
|
+
const lyxaOpenHour = (0, exports.adminAfterHolidayWorkingHours)(workHourSetting);
|
|
153
|
+
return lyxaOpenHour.some(timing => parseInt(timing.start) <= currentTime && currentTime <= parseInt(timing.end));
|
|
154
|
+
};
|
|
155
|
+
exports.isLyxaOpen = isLyxaOpen;
|
|
156
|
+
//# sourceMappingURL=workHourSetting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workHourSetting.js","sourceRoot":"/","sources":["utilities/workHourSetting.ts"],"names":[],"mappings":"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","sourcesContent":["import dayjs, { Dayjs } from 'dayjs';\nimport utc from 'dayjs/plugin/utc';\nimport timezone from 'dayjs/plugin/timezone';\nimport minMax from 'dayjs/plugin/minMax';\nimport { HolidayHour, NormalHour, StartEndTime } from '../libraries/mongo/models/shared/work-hour.model';\nimport { HolidayWorkStatus, WeekDay, WorkStatus } from './enum';\nimport { LyxaTimezone } from './time';\n\ndayjs.extend(utc);\ndayjs.extend(timezone);\ndayjs.extend(minMax);\n\nexport const getDaysOfWeek = (): string[] => {\n\treturn Array.from({ length: 7 }, (_, i) => dayjs().day(i).format('dddd'));\n};\n\nexport const getFullDayHours = (): StartEndTime[] => {\n\treturn [{ start: '0000', end: '2359' }];\n};\n\nexport const parseTimeString = (timeHHMM: string, zone: string): dayjs.Dayjs => {\n\tconst hour = Number(timeHHMM.slice(0, 2));\n\tconst minute = Number(timeHHMM.slice(2));\n\treturn dayjs().tz(zone).hour(hour).minute(minute).second(0).millisecond(0);\n};\nexport const calculateIntersection = (\n\topening: StartEndTime,\n\tvalid: StartEndTime,\n\ttimeZone: string\n): StartEndTime | null => {\n\tconst openingStart = parseTimeString(opening.start, timeZone);\n\tconst openingEnd = parseTimeString(opening.end, timeZone);\n\tconst validStart = parseTimeString(valid.start, timeZone);\n\tconst validEnd = parseTimeString(valid.end, timeZone);\n\n\tconst intersectionStart = dayjs.max(openingStart, validStart);\n\tconst intersectionEnd = dayjs.min(openingEnd, validEnd);\n\n\treturn intersectionStart && intersectionEnd && intersectionStart.isBefore(intersectionEnd)\n\t\t? {\n\t\t\t\tstart: intersectionStart.format('HHmm'),\n\t\t\t\tend: intersectionEnd.format('HHmm'),\n\t\t\t}\n\t\t: null;\n};\n\nexport const getIntersectedHours = (\n\topeningHours: StartEndTime[],\n\tvalidHours: StartEndTime[],\n\ttimeZone = 'Asia/Dhaka'\n): StartEndTime[] => {\n\tconst intersections: StartEndTime[] = [];\n\n\tfor (const opening of openingHours) {\n\t\tfor (const valid of validHours) {\n\t\t\tconst intersection = calculateIntersection(opening, valid, timeZone);\n\n\t\t\tif (intersection !== null) {\n\t\t\t\tintersections.push(intersection);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn intersections;\n};\n\nexport const checkWithinNormalHours = (\n\thours: StartEndTime[],\n\tnormalTimings: NormalHour[],\n\tday: keyof typeof WeekDay\n): StartEndTime[] => {\n\tconst dayTiming = normalTimings.find(timing => timing.day === WeekDay[day]);\n\n\tif (!dayTiming) return [];\n\n\tconst statusHandlers = {\n\t\t[WorkStatus.CLOSED]: () => [],\n\t\t[WorkStatus.FULL_DAY]: () => getFullDayHours(),\n\t\t[WorkStatus.OPEN]: () =>\n\t\t\tdayTiming.openingHours?.length ? getIntersectedHours(dayTiming.openingHours, hours) : [],\n\t};\n\n\treturn statusHandlers[dayTiming.status]?.() || [];\n};\n\nexport const checkWithinHolidayHours = (\n\thours: StartEndTime[],\n\tholidayTimings: HolidayHour[],\n\tcurrentDate: Dayjs\n): StartEndTime[] => {\n\tif (!holidayTimings.length) {\n\t\treturn hours;\n\t}\n\n\t/** Find If Today Is Holiday */\n\tconst currentDateInTimezone = currentDate.tz(LyxaTimezone);\n\tconst todaysHoliday = holidayTimings.find(holiday => {\n\t\tif (!holiday.date) return false;\n\t\tconst holidayDate = dayjs(holiday.date).tz(LyxaTimezone);\n\t\treturn currentDateInTimezone.isSame(holidayDate, 'day');\n\t});\n\n\t/** No holiday today - return original hours */\n\tif (!todaysHoliday) return hours;\n\n\t/** Handle holiday status --> Full Day Holiday */\n\tif (todaysHoliday.status === HolidayWorkStatus.FULL_DAY) return [];\n\n\t/** Handle holiday status --> Certain Hour Closed Holiday */\n\tif (\n\t\ttodaysHoliday.status === HolidayWorkStatus.CLOSED &&\n\t\ttodaysHoliday.closingHour?.start &&\n\t\ttodaysHoliday.closingHour?.end\n\t) {\n\t\treturn getHolidayIntersectedHours(hours, [todaysHoliday.closingHour]);\n\t}\n\n\t/** Default fallback - return original hours */\n\treturn hours;\n};\n\nexport const getHolidayIntersectedHours = (\n\topeningHours: StartEndTime[],\n\tclosingHours: StartEndTime[],\n\ttimeZone = 'Asia/Dhaka'\n): StartEndTime[] => {\n\tif (!openingHours.length || !closingHours.length) {\n\t\treturn openingHours;\n\t}\n\n\tconst result: StartEndTime[] = [];\n\n\tfor (const opening of openingHours) {\n\t\tconst openingStart = parseTimeString(opening.start, timeZone);\n\t\tconst openingEnd = parseTimeString(opening.end, timeZone);\n\n\t\tlet segments = [{ start: openingStart, end: openingEnd }];\n\n\t\t/** Applying each closing period to current segments */\n\t\tfor (const closing of closingHours) {\n\t\t\tconst closingStart = parseTimeString(closing.start, timeZone);\n\t\t\tconst closingEnd = parseTimeString(closing.end, timeZone);\n\t\t\tconst block = { start: closingStart, end: closingEnd };\n\n\t\t\tsegments = segments.flatMap(segment => subtractSegment(segment, block));\n\t\t}\n\n\t\t/** Converting segments to result format */\n\t\tfor (const segment of segments) {\n\t\t\tresult.push({\n\t\t\t\tstart: segment.start.format('HHmm'),\n\t\t\t\tend: segment.end.format('HHmm'),\n\t\t\t});\n\t\t}\n\t}\n\n\treturn result;\n};\nexport const subtractSegment = (\n\tsegment: { start: dayjs.Dayjs; end: dayjs.Dayjs },\n\tblock: { start: dayjs.Dayjs; end: dayjs.Dayjs }\n): { start: dayjs.Dayjs; end: dayjs.Dayjs }[] => {\n\tconst { start, end } = segment;\n\tconst { start: blockStart, end: blockEnd } = block;\n\n\t/** Sequence Matter */\n\t/** No Overlap */\n\tif (end.isBefore(blockStart) || start.isAfter(blockEnd)) return [segment];\n\n\t/** Fully Overlapped */\n\tif (blockStart.isBefore(start) && blockEnd.isAfter(end)) return [];\n\n\t/** Block Inside Segment (Middle Cut) */\n\tif (blockStart.isAfter(start) && blockEnd.isBefore(end)) {\n\t\treturn [\n\t\t\t{ start, end: blockStart },\n\t\t\t{ start: blockEnd, end },\n\t\t];\n\t}\n\n\t/** Overlap At Start */\n\tif (blockStart.isBefore(end) && blockEnd.isBefore(end) && blockEnd.isAfter(start)) {\n\t\treturn [{ start: blockEnd, end }];\n\t}\n\n\t/** Overlap At End */\n\tif (blockEnd.isAfter(start) && blockStart.isAfter(start) && blockStart.isBefore(end)) {\n\t\treturn [{ start, end: blockStart }];\n\t}\n\n\treturn [];\n};\n\nexport const adminAfterHolidayWorkingHours = (workHourSetting: any) => {\n\tconst fullDayHours = getFullDayHours();\n\tconst now = dayjs().tz(LyxaTimezone);\n\tconst currentDayIndex = now.day(); // 0 (Sunday) through 6 (Saturday)\n\tconst currentDay = getDaysOfWeek()[currentDayIndex] as keyof typeof WeekDay;\n\tconst currentDate = dayjs().utc().startOf('day');\n\n\t/**Admin Normal Working Hour*/\n\tconst adminNormalWorkingHours = checkWithinNormalHours(\n\t\tfullDayHours,\n\t\tworkHourSetting.normalHours,\n\t\tcurrentDay\n\t);\n\t/**Admin Working Hour After Subtracting From Admin Holiday Hour */\n\treturn checkWithinHolidayHours(adminNormalWorkingHours, workHourSetting.holidayHours, currentDate);\n};\n\nexport const isLyxaOpen = (workHourSetting: any) => {\n\tconst currentTime = new Date().getHours() * 100 + new Date().getMinutes();\n\tconst lyxaOpenHour = adminAfterHolidayWorkingHours(workHourSetting);\n\treturn lyxaOpenHour.some(\n\t\ttiming => parseInt(timing.start) <= currentTime && currentTime <= parseInt(timing.end)\n\t);\n};\n"]}
|