@lyxa.ai/types 1.1.52 → 1.1.54
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/README.md
CHANGED
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
type ReadonlyNonEmptyArray<T> = readonly [T, ...T[]];
|
|
3
|
-
export interface FilterSchemaConfig<TSelect extends ReadonlyNonEmptyArray<string>, TPopulate extends ReadonlyNonEmptyArray<string>, TSearch extends ReadonlyNonEmptyArray<string
|
|
3
|
+
export interface FilterSchemaConfig<TSelect extends ReadonlyNonEmptyArray<string>, TPopulate extends ReadonlyNonEmptyArray<string>, TSearch extends ReadonlyNonEmptyArray<string>, TQuery extends ReadonlyNonEmptyArray<string> | [] = []> {
|
|
4
4
|
selectableFields: TSelect;
|
|
5
5
|
populatableFields: TPopulate;
|
|
6
6
|
searchableFields: TSearch;
|
|
7
|
+
queryableFields?: TQuery;
|
|
7
8
|
maxSize?: number;
|
|
8
9
|
defaultSize?: number;
|
|
9
10
|
}
|
|
@@ -18,11 +19,11 @@ export type PopulateObject<TPopulate extends ReadonlyNonEmptyArray<string>, TSel
|
|
|
18
19
|
};
|
|
19
20
|
populate?: PopulateObject<TPopulate, TSelect> | PopulateObject<TPopulate, TSelect>[];
|
|
20
21
|
};
|
|
21
|
-
export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string>, TPopulate extends ReadonlyNonEmptyArray<string>, TSearch extends ReadonlyNonEmptyArray<string
|
|
22
|
+
export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string>, TPopulate extends ReadonlyNonEmptyArray<string>, TSearch extends ReadonlyNonEmptyArray<string>, TQuery extends ReadonlyNonEmptyArray<string> | [] = []> = {
|
|
22
23
|
size?: number;
|
|
23
24
|
page?: number;
|
|
24
25
|
sort?: Record<string, 1 | -1>;
|
|
25
|
-
query?: Record<string, any>;
|
|
26
|
+
query?: TQuery extends ReadonlyNonEmptyArray<string> ? Partial<Record<TQuery[number], any>> : Record<string, any>;
|
|
26
27
|
select?: Partial<Record<TSelect[number], 0 | 1>>;
|
|
27
28
|
populate?: PopulateObject<TPopulate, TSelect> | PopulateObject<TPopulate, TSelect>[];
|
|
28
29
|
search?: {
|
|
@@ -30,5 +31,5 @@ export type FilterDTO<TSelect extends ReadonlyNonEmptyArray<string>, TPopulate e
|
|
|
30
31
|
searchFields?: TSearch[number][];
|
|
31
32
|
};
|
|
32
33
|
};
|
|
33
|
-
export declare function createFilterSchema<TSelect extends ReadonlyNonEmptyArray<string>, TPopulate extends ReadonlyNonEmptyArray<string>, TSearch extends ReadonlyNonEmptyArray<string
|
|
34
|
+
export declare function createFilterSchema<TSelect extends ReadonlyNonEmptyArray<string>, TPopulate extends ReadonlyNonEmptyArray<string>, TSearch extends ReadonlyNonEmptyArray<string>, TQuery extends ReadonlyNonEmptyArray<string> | [] = []>(config: FilterSchemaConfig<TSelect, TPopulate, TSearch, TQuery>): z.ZodType<FilterDTO<TSelect, TPopulate, TSearch, TQuery>>;
|
|
34
35
|
export {};
|
|
@@ -3,9 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
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
|
-
const MongoQuerySchema = zod_1.z.record(zod_1.z.string(), zod_1.z.any());
|
|
7
6
|
function createFilterSchema(config) {
|
|
8
|
-
const { selectableFields, populatableFields, searchableFields, maxSize = 100, defaultSize = 10 } = config;
|
|
7
|
+
const { selectableFields, populatableFields, searchableFields, queryableFields, maxSize = 100, defaultSize = 10, } = config;
|
|
9
8
|
const selectSchema = zod_1.z.record(zod_1.z.enum(selectableFields), zod_1.z.union([zod_1.z.literal(0), zod_1.z.literal(1)]));
|
|
10
9
|
const populateSchema = zod_1.z.lazy(() => zod_1.z.object({
|
|
11
10
|
path: zod_1.z.enum(populatableFields),
|
|
@@ -24,11 +23,14 @@ function createFilterSchema(config) {
|
|
|
24
23
|
searchKey: zod_1.z.string(),
|
|
25
24
|
searchFields: zod_1.z.array(zod_1.z.enum(searchableFields)).optional(),
|
|
26
25
|
});
|
|
26
|
+
const querySchema = queryableFields && queryableFields.length > 0
|
|
27
|
+
? zod_1.z.record(zod_1.z.enum(queryableFields), zod_1.z.any())
|
|
28
|
+
: zod_1.z.any();
|
|
27
29
|
const schema = zod_1.z.object({
|
|
28
30
|
size: zod_1.z.number().min(1).max(maxSize).optional().default(defaultSize),
|
|
29
31
|
page: zod_1.z.number().min(1).optional().default(1),
|
|
30
32
|
sort: sortSchema.optional(),
|
|
31
|
-
query:
|
|
33
|
+
query: querySchema.optional(),
|
|
32
34
|
select: selectSchema.optional(),
|
|
33
35
|
populate: zod_1.z.union([populateSchema, zod_1.z.array(populateSchema)]).optional(),
|
|
34
36
|
search: searchSchema.optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-schema.factory.js","sourceRoot":"/","sources":["utilities/validation/filter-schema.factory.ts"],"names":[],"mappings":";;
|
|
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 } from 'zod';\n\nconst sortSchema = z.record(z.string(), z.union([z.literal(1), z.literal(-1)]));\n\ntype ReadonlyNonEmptyArray<T> = readonly [T, ...T[]];\n\nexport interface FilterSchemaConfig<\n\tTSelect extends ReadonlyNonEmptyArray<string>,\n\tTPopulate extends ReadonlyNonEmptyArray<string>,\n\tTSearch extends ReadonlyNonEmptyArray<string>,\n\tTQuery extends ReadonlyNonEmptyArray<string> | [] = [],\n> {\n\tselectableFields: TSelect;\n\tpopulatableFields: TPopulate;\n\tsearchableFields: TSearch;\n\tqueryableFields?: TQuery;\n\tmaxSize?: number;\n\tdefaultSize?: number;\n}\n\nexport type PopulateObject<\n\tTPopulate extends ReadonlyNonEmptyArray<string>,\n\tTSelect extends ReadonlyNonEmptyArray<string>,\n> = {\n\tpath: TPopulate[number];\n\tselect?: Partial<Record<TSelect[number], 0 | 1>>;\n\tmatch?: Record<string, any>;\n\toptions?: { sort?: Record<string, 1 | -1>; limit?: number; skip?: number };\n\tpopulate?: PopulateObject<TPopulate, TSelect> | PopulateObject<TPopulate, TSelect>[];\n};\n\nexport type FilterDTO<\n\tTSelect extends ReadonlyNonEmptyArray<string>,\n\tTPopulate extends ReadonlyNonEmptyArray<string>,\n\tTSearch extends ReadonlyNonEmptyArray<string>,\n\tTQuery extends ReadonlyNonEmptyArray<string> | [] = [],\n> = {\n\tsize?: number;\n\tpage?: number;\n\tsort?: Record<string, 1 | -1>;\n\tquery?: TQuery extends ReadonlyNonEmptyArray<string>\n\t\t? Partial<Record<TQuery[number], any>>\n\t\t: Record<string, any>;\n\tselect?: Partial<Record<TSelect[number], 0 | 1>>;\n\tpopulate?: PopulateObject<TPopulate, TSelect> | PopulateObject<TPopulate, TSelect>[];\n\tsearch?: { searchKey: string; searchFields?: TSearch[number][] };\n};\n\nexport function createFilterSchema<\n\tTSelect extends ReadonlyNonEmptyArray<string>,\n\tTPopulate extends ReadonlyNonEmptyArray<string>,\n\tTSearch extends ReadonlyNonEmptyArray<string>,\n\tTQuery extends ReadonlyNonEmptyArray<string> | [] = [],\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\t// select schema\n\tconst selectSchema = z.record(z.enum(selectableFields), z.union([z.literal(0), z.literal(1)]));\n\n\t// populate schema\n\tconst populateSchema: z.ZodType<PopulateObject<TPopulate, TSelect>> = z.lazy(\n\t\t() =>\n\t\t\tz.object({\n\t\t\t\tpath: z.enum(populatableFields),\n\t\t\t\tselect: z.record(z.enum(selectableFields), z.union([z.literal(0), z.literal(1)])).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\tpopulate: z.union([populateSchema, z.array(populateSchema)]).optional(),\n\t\t\t}) as z.ZodType<PopulateObject<TPopulate, TSelect>>\n\t);\n\n\t// search schema\n\tconst searchSchema = z.object({\n\t\tsearchKey: z.string(),\n\t\tsearchFields: z.array(z.enum(searchableFields)).optional(),\n\t});\n\n\t// query schema\n\tconst querySchema =\n\t\tqueryableFields && queryableFields.length > 0\n\t\t\t? z.record(z.enum(queryableFields as ReadonlyNonEmptyArray<string>), z.any())\n\t\t\t: z.any();\n\n\tconst schema = z.object({\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\tquery: querySchema.optional(),\n\t\tselect: selectSchema.optional(),\n\t\tpopulate: z.union([populateSchema, z.array(populateSchema)]).optional(),\n\t\tsearch: searchSchema.optional(),\n\t});\n\n\treturn schema as z.ZodType<FilterDTO<TSelect, TPopulate, TSearch, TQuery>>;\n}\n\n/**\n *\n * @Example\n *\n * const UserFilterSchema = createFilterSchema({\n * \tselectableFields: ['_id', 'name', 'email', 'role'] as const,\n * \tpopulatableFields: ['organization'] as const,\n * \tsearchableFields: ['name', 'email'] as const,\n * \tqueryableFields: ['role', 'active'] as const,\n * });\n *\n * type UserFilterDTO = z.infer<typeof UserFilterSchema>;\n *\n * ✅ Correct\n * const correctFilter: UserFilterDTO = {\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 catch errors\n * const wrongFilter: UserFilterDTO = {\n * \tselect: { name: 1, email: 1, password: 1 },\n * \tquery: { status: true },\n * \tpopulate: [{ path: 'shops', select: { name: 1 } }],\n * \tsearch: { searchKey: 'john', searchFields: ['name', 'email', 'price'] },\n * \tpage: 1,\n * \tsize: 20,\n * };\n */\n"]}
|