zod-paginate 1.2.0 → 1.3.0

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
@@ -100,23 +100,44 @@ Returns:
100
100
  - `responseSchema`: pre-built Zod schema for validating responses using `defaultSelect` (or all selectable fields). Equivalent to calling `validatorSchema()` with no arguments.
101
101
 
102
102
  ```ts
103
+ // Overload 1 — LIMIT_OFFSET
103
104
  export function paginate<
104
105
  TSchema extends DataSchema,
105
106
  const TSelectable extends readonly AllowedPath<TSchema>[],
106
107
  >(
107
- config: QueryConfigFromSchema<TSchema, TSelectable[number]>,
108
- ): PaginateResult<TSchema, TSelectable[number]>;
108
+ config: CommonQueryConfigFromSchema<TSchema, TSelectable[number]> & { paginationType: "LIMIT_OFFSET" },
109
+ ): PaginateResult<TSchema, TSelectable[number], "LIMIT_OFFSET">;
110
+
111
+ // Overload 2 — CURSOR
112
+ export function paginate<
113
+ TSchema extends DataSchema,
114
+ const TSelectable extends readonly AllowedPath<TSchema>[],
115
+ >(
116
+ config: CommonQueryConfigFromSchema<TSchema, TSelectable[number]> & CursorPaginationConfig<…>,
117
+ ): PaginateResult<TSchema, TSelectable[number], "CURSOR">;
109
118
  ```
110
119
 
111
- #### `PaginateResult<TSchema, TSelectable?>`
120
+ #### `PaginateResult<TSchema, TSelectable?, TType?>`
121
+
122
+ Use `PaginateResult<TSchema, TSelectable, TType>` instead of `ReturnType<typeof paginate>` when you need an explicit return type — it preserves the generics so that `z.infer<typeof responseSchema>` correctly narrows both `data` keys and pagination metadata.
112
123
 
113
- Use `PaginateResult<TSchema, TSelectable>` instead of `ReturnType<typeof paginate>` when you need an explicit return type it preserves the generics so that `z.infer<typeof responseSchema>` correctly narrows the `data` keys to the configured `selectable` paths.
124
+ - **`TType`** (`'LIMIT_OFFSET' | 'CURSOR'`): When specified, narrows the response/payload types so you get `totalItems`/`totalPages` (LIMIT_OFFSET) or `cursor` (CURSOR) without manual narrowing. Defaults to the union if omitted.
114
125
 
115
126
  ```ts
116
127
  import { paginate, type PaginateResult } from "zod-paginate";
117
128
 
118
- // TSelectable defaults to all paths if omitted
119
- function createPaginator(): PaginateResult<typeof ModelSchema, "id" | "status"> {
129
+ // TSelectable defaults to all paths if omitted, TType defaults to union
130
+ function createPaginator(): PaginateResult<typeof ModelSchema, "id" | "status", "LIMIT_OFFSET"> {
131
+ return paginate({
132
+ paginationType: "LIMIT_OFFSET",
133
+ dataSchema: ModelSchema,
134
+ selectable: ["id", "status"],
135
+ /* … */
136
+ });
137
+ }
138
+
139
+ // Without TType — pagination is still a union, but data keys are narrowed
140
+ function createPaginatorUnion(): PaginateResult<typeof ModelSchema, "id" | "status"> {
120
141
  return paginate({ dataSchema: ModelSchema, selectable: ["id", "status"], /* … */ });
121
142
  }
122
143
  ```
@@ -554,6 +575,8 @@ responseSchema.parse({
554
575
  // Type-safe: z.infer narrows data keys to selectable paths
555
576
  type Response = z.infer<typeof responseSchema>;
556
577
  // Response["data"][0] → { id?: unknown; status?: unknown; createdAt?: unknown; meta?: unknown }
578
+ // Response["pagination"] → LimitOffsetPaginationResponseMeta (not a union!)
579
+ // Response["pagination"].totalItems → number ✓ (no manual narrowing needed)
557
580
  ```
558
581
 
559
582
  Or using `validatorSchema(parsed)` for request-aware projection:
@@ -165,10 +165,13 @@ export interface CommonQueryConfigFromSchema<TSchema extends DataSchema, TSelect
165
165
  property: AllowedPath<TSchema>;
166
166
  direction: SortDirection;
167
167
  }[];
168
- defaultLimit?: number;
169
- defaultSelect?: readonly (TSelectable | '*')[];
170
- maxLimit?: number;
168
+ defaultLimit: number;
169
+ defaultSelect: readonly TSelectable[] | '*';
170
+ maxLimit: number;
171
171
  }
172
+ /**
173
+ * Full query config type, which includes pagination-specific properties depending on the pagination type.
174
+ */
172
175
  export type QueryConfigFromSchema<TSchema extends DataSchema, TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>> = CommonQueryConfigFromSchema<TSchema, TSelectable> & (LimitOffsetPaginationConfig | CursorPaginationConfig<InferData<TSchema>>);
173
176
  export interface SortItemTyped<TSchema extends DataSchema> {
174
177
  property: AllowedPath<TSchema>;
@@ -176,7 +179,7 @@ export interface SortItemTyped<TSchema extends DataSchema> {
176
179
  }
177
180
  export interface LimitOffsetPaginationPayload<TSchema extends DataSchema> {
178
181
  type: 'LIMIT_OFFSET';
179
- limit?: number;
182
+ limit: number;
180
183
  page?: number;
181
184
  sortBy?: SortItemTyped<TSchema>[];
182
185
  select?: AllowedPath<TSchema>[];
@@ -188,16 +191,17 @@ export interface LimitOffsetPaginationPayload<TSchema extends DataSchema> {
188
191
  */
189
192
  export interface CursorPaginationPayload<TSchema extends DataSchema> {
190
193
  type: 'CURSOR';
191
- limit?: number;
194
+ limit: number;
192
195
  cursor?: number | string;
193
196
  cursorProperty: AllowedPath<TSchema>;
194
197
  sortBy?: SortItemTyped<TSchema>[];
195
198
  select?: AllowedPath<TSchema>[];
196
199
  filters?: WhereNode;
197
200
  }
198
- export type PaginationPayload<TSchema extends DataSchema> = LimitOffsetPaginationPayload<TSchema> | CursorPaginationPayload<TSchema>;
199
- export interface PaginationQueryParams<TSchema extends DataSchema> {
200
- pagination: PaginationPayload<TSchema>;
201
+ export type PaginationType = 'LIMIT_OFFSET' | 'CURSOR';
202
+ export type PaginationPayload<TSchema extends DataSchema, TType extends PaginationType = PaginationType> = TType extends 'LIMIT_OFFSET' ? LimitOffsetPaginationPayload<TSchema> : TType extends 'CURSOR' ? CursorPaginationPayload<TSchema> : never;
203
+ export interface PaginationQueryParams<TSchema extends DataSchema, TType extends PaginationType = PaginationType> {
204
+ pagination: PaginationPayload<TSchema, TType>;
201
205
  }
202
206
  export interface LimitOffsetPaginationResponseMeta {
203
207
  itemsPerPage: number;
@@ -227,7 +231,7 @@ export interface CursorPaginationResponse<TSchema extends DataSchema, TSelect ex
227
231
  data: ProjectedData<TSchema, TSelect>[];
228
232
  pagination: CursorPaginationResponseMeta;
229
233
  }
230
- export type PaginationResponse<TSchema extends DataSchema, TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>> = LimitOffsetPaginationResponse<TSchema, TSelect> | CursorPaginationResponse<TSchema, TSelect>;
234
+ export type PaginationResponse<TSchema extends DataSchema, TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>, TType extends PaginationType = PaginationType> = TType extends 'LIMIT_OFFSET' ? LimitOffsetPaginationResponse<TSchema, TSelect> : TType extends 'CURSOR' ? CursorPaginationResponse<TSchema, TSelect> : never;
231
235
  /**
232
236
  * Result type returned by `paginate()`. Use this instead of
233
237
  * `ReturnType<typeof paginate>` to preserve the generic `TSchema`.
@@ -237,10 +241,10 @@ export type PaginationResponse<TSchema extends DataSchema, TSelect extends Allow
237
241
  * return paginate({ dataSchema: MySchema, … });
238
242
  * }
239
243
  */
240
- export interface PaginateResult<TSchema extends DataSchema, TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>> {
241
- queryParamsSchema: z.ZodType<PaginationQueryParams<TSchema>>;
242
- validatorSchema: (parsed?: PaginationPayload<TSchema>) => z.ZodType<PaginationResponse<TSchema, TSelectable>>;
243
- responseSchema: z.ZodType<PaginationResponse<TSchema, TSelectable>>;
244
+ export interface PaginateResult<TSchema extends DataSchema, TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>, TType extends PaginationType = PaginationType> {
245
+ queryParamsSchema: z.ZodType<PaginationQueryParams<TSchema, TType>>;
246
+ validatorSchema: (parsed?: PaginationPayload<TSchema>) => z.ZodType<PaginationResponse<TSchema, TSelectable, TType>>;
247
+ responseSchema: z.ZodType<PaginationResponse<TSchema, TSelectable, TType>>;
244
248
  }
245
249
  /**
246
250
  * Generate Zod schemas and runtime validators for pagination query parameters, based on a config object.
@@ -250,5 +254,40 @@ export interface PaginateResult<TSchema extends DataSchema, TSelectable extends
250
254
  * - `validatorSchema`: A function that takes the already-parsed query parameters and returns a Zod schema for further validation (e.g. filters).
251
255
  * - `responseSchema`: A pre-built Zod schema for validating the response (uses defaultSelect or all selectable fields).
252
256
  */
253
- export declare function paginate<TSchema extends DataSchema, const TSelectable extends readonly AllowedPath<TSchema>[]>(config: QueryConfigFromSchema<TSchema, TSelectable[number]>): PaginateResult<TSchema, TSelectable[number]>;
257
+ export declare function paginate<TSchema extends DataSchema, const TSelectable extends readonly AllowedPath<TSchema>[]>(config: Omit<CommonQueryConfigFromSchema<TSchema, TSelectable[number]>, 'selectable' | 'defaultSelect' | 'sortable' | 'defaultSortBy' | 'filterable'> & LimitOffsetPaginationConfig & {
258
+ selectable?: TSelectable;
259
+ defaultSelect: readonly NoInfer<TSelectable[number]>[] | '*';
260
+ sortable?: readonly NoInfer<TSelectable[number]>[];
261
+ defaultSortBy?: readonly {
262
+ property: NoInfer<TSelectable[number]>;
263
+ direction: SortDirection;
264
+ }[];
265
+ filterable?: Partial<{
266
+ [P in NoInfer<TSelectable[number]>]: FilterableFieldConfig<FieldTypeFromValue<PathValue<InferData<TSchema>, P>>>;
267
+ }>;
268
+ }): PaginateResult<TSchema, TSelectable[number], 'LIMIT_OFFSET'>;
269
+ export declare function paginate<TSchema extends DataSchema, const TSelectable extends readonly AllowedPath<TSchema>[]>(config: Omit<CommonQueryConfigFromSchema<TSchema, TSelectable[number]>, 'selectable' | 'defaultSelect' | 'sortable' | 'defaultSortBy' | 'filterable'> & CursorPaginationConfig<InferData<TSchema>> & {
270
+ selectable?: TSelectable;
271
+ defaultSelect: readonly NoInfer<TSelectable[number]>[] | '*';
272
+ sortable?: readonly NoInfer<TSelectable[number]>[];
273
+ defaultSortBy?: readonly {
274
+ property: NoInfer<TSelectable[number]>;
275
+ direction: SortDirection;
276
+ }[];
277
+ filterable?: Partial<{
278
+ [P in NoInfer<TSelectable[number]>]: FilterableFieldConfig<FieldTypeFromValue<PathValue<InferData<TSchema>, P>>>;
279
+ }>;
280
+ }): PaginateResult<TSchema, TSelectable[number], 'CURSOR'>;
281
+ export declare function paginate<TSchema extends DataSchema, const TSelectable extends readonly AllowedPath<TSchema>[]>(config: Omit<CommonQueryConfigFromSchema<TSchema, TSelectable[number]>, 'selectable' | 'defaultSelect' | 'sortable' | 'defaultSortBy' | 'filterable'> & {
282
+ selectable?: TSelectable;
283
+ defaultSelect: readonly NoInfer<TSelectable[number]>[] | '*';
284
+ sortable?: readonly NoInfer<TSelectable[number]>[];
285
+ defaultSortBy?: readonly {
286
+ property: NoInfer<TSelectable[number]>;
287
+ direction: SortDirection;
288
+ }[];
289
+ filterable?: Partial<{
290
+ [P in NoInfer<TSelectable[number]>]: FilterableFieldConfig<FieldTypeFromValue<PathValue<InferData<TSchema>, P>>>;
291
+ }>;
292
+ } & (LimitOffsetPaginationConfig | CursorPaginationConfig<InferData<TSchema>>)): PaginateResult<TSchema, TSelectable[number]>;
254
293
  export {};
package/dist/paginate.js CHANGED
@@ -466,12 +466,10 @@ function toFilterableRuntime(filterable) {
466
466
  }
467
467
  return out;
468
468
  }
469
- function computeLimit(limit, config) {
469
+ function computeLimit(limit, defaultLimit) {
470
470
  if (typeof limit === 'number')
471
471
  return limit;
472
- if (typeof config.defaultLimit === 'number')
473
- return config.defaultLimit;
474
- return undefined;
472
+ return defaultLimit;
475
473
  }
476
474
  /* ---------------------------------- */
477
475
  /* Runtime value/type validation */
@@ -674,17 +672,6 @@ function coerceCursorFromProperty(dataSchema, cursorProperty, rawCursor) {
674
672
  }
675
673
  throw new Error(`cursorProperty "${cursorProperty}" must be a string|number|date`);
676
674
  }
677
- /* ---------------------------------- */
678
- /* Factory */
679
- /* ---------------------------------- */
680
- /**
681
- * Generate Zod schemas and runtime validators for pagination query parameters, based on a config object.
682
- * @param config The configuration object defining the pagination behavior and allowed fields.
683
- * @returns An object containing:
684
- * - `queryParamsSchema`: A Zod schema for validating and parsing the raw query parameters.
685
- * - `validatorSchema`: A function that takes the already-parsed query parameters and returns a Zod schema for further validation (e.g. filters).
686
- * - `responseSchema`: A pre-built Zod schema for validating the response (uses defaultSelect or all selectable fields).
687
- */
688
675
  function paginate(config) {
689
676
  const allowedSelectable = new Set();
690
677
  for (const f of config.selectable ?? [])
@@ -763,9 +750,7 @@ function paginate(config) {
763
750
  }
764
751
  }
765
752
  // limit / maxLimit
766
- if (typeof val.limit === 'number' &&
767
- typeof config.maxLimit === 'number' &&
768
- val.limit > config.maxLimit) {
753
+ if (typeof val.limit === 'number' && val.limit > config.maxLimit) {
769
754
  ctx.addIssue({
770
755
  code: 'custom',
771
756
  path: ['limit'],
@@ -782,8 +767,8 @@ function paginate(config) {
782
767
  }
783
768
  // select allowlist + "*" expandability
784
769
  const selectForValidation = val.select ??
785
- (config.defaultSelect ? config.defaultSelect.map((x) => `${x}`) : undefined);
786
- if (selectForValidation) {
770
+ (config.defaultSelect === '*' ? ['*'] : config.defaultSelect.map((x) => `${x}`));
771
+ {
787
772
  let index = 0;
788
773
  for (const field of selectForValidation) {
789
774
  if (field === '*') {
@@ -823,7 +808,7 @@ function paginate(config) {
823
808
  else if (sortItems) {
824
809
  let index = 0;
825
810
  for (const item of sortItems) {
826
- if (!allowedSortable.has(`${item.property}`)) {
811
+ if (!allowedSortable.has(item.property)) {
827
812
  ctx.addIssue({
828
813
  code: 'custom',
829
814
  path: ['sortBy', index],
@@ -891,7 +876,7 @@ function paginate(config) {
891
876
  }
892
877
  })
893
878
  .transform((val) => {
894
- const limit = computeLimit(val.limit, config);
879
+ const limit = computeLimit(val.limit, config.defaultLimit);
895
880
  const sortBy = computeSortBy(val.sortBy, config);
896
881
  const select = (0, select_1.computeSelect)(val.select, config);
897
882
  const hasAnyFilter = Object.keys(val.rawFilters).length > 0;
@@ -1 +1 @@
1
- {"version":3,"file":"paginate.js","sourceRoot":"","sources":["../src/paginate.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n type AllowedPath,\n computeSelect,\n type DataSchema,\n expandSelect,\n getOwnProp,\n getZodAtPath,\n type InferData,\n isPlainObject,\n isZodSchema,\n type Path,\n type PathValue,\n pickFromAllowlist,\n projectDataSchema,\n type ProjectedData,\n SelectSchema,\n} from './select';\n\n/* ---------------------------------- */\n/* Querystring value types */\n/* ---------------------------------- */\n\ntype QueryStringValue = string | string[] | undefined;\ntype QueryStringRecord = Record<string, QueryStringValue>;\n\n/* ---------------------------------- */\n/* Pagination config */\n/* ---------------------------------- */\n\ninterface LimitOffsetPaginationConfig {\n paginationType: 'LIMIT_OFFSET';\n}\n\ninterface CursorPaginationConfig<T> {\n paginationType: 'CURSOR';\n cursorProperty: Path<T>;\n}\n\n/* ---------------------------------- */\n/* Common input normalizers */\n/* ---------------------------------- */\n\n/**\n * We often want to allow both single values and arrays in the querystring, e.g. \"select=field1,field2\" or \"select[]=field1&select[]=field2\".\n * This function normalizes both cases to a string array.\n */\nfunction toStringArrayFromQueryString(v: QueryStringValue): string[] {\n if (v === undefined) return [];\n if (Array.isArray(v)) return v;\n return [v];\n}\n\n/**\n * Zod schema for a querystring parameter that can be either a single string or an array of strings.\n * It normalizes the output to always be an array of strings.\n */\nconst StringOrStringArraySchema = z\n .union([z.string(), z.array(z.string())])\n .transform((v) => (typeof v === 'string' ? [v] : v));\n\n/* ---------------------------------- */\n/* Sort */\n/* ---------------------------------- */\n\nexport const SortDirectionSchema = z.enum(['ASC', 'DESC']);\nexport type SortDirection = z.infer<typeof SortDirectionSchema>;\n\nexport const SortItemSchema = z.object({\n property: z.string().min(1),\n direction: SortDirectionSchema,\n});\nexport type SortItem = z.infer<typeof SortItemSchema>;\n\n/**\n * Parse \"field:ASC\" into a SortItem.\n * The input must have a colon separating the field and direction, and the direction must be either \"ASC\" or \"DESC\" (case-insensitive).\n * */\nfunction parseSortItem(raw: string): SortItem {\n const [propertyRaw, dirRaw] = raw.split(':');\n const property = (propertyRaw ?? '').trim();\n const direction = SortDirectionSchema.parse((dirRaw ?? '').trim());\n return SortItemSchema.parse({ property, direction });\n}\n\n/* ---------------------------------- */\n/* Conditions + grouping */\n/* ---------------------------------- */\n\n/**\n * Supported operators.\n * $eq: equality (for strings, numbers, dates)\n * $null: checks for null (ignores the value)\n * $in: checks if the field value is in the provided array (for strings, numbers, dates)\n * $gt, $gte, $lt, $lte: comparison operators (for numbers and dates)\n * $btw: checks if the field value is between two values (for numbers and dates)\n * $ilike: case-insensitive substring match (for strings)\n * $sw: case-insensitive starts-with match (for strings)\n * $contains: checks if the field value contains the provided value (for strings)\n */\nexport const OperatorSchema = z.enum([\n '$eq',\n '$null',\n '$in',\n '$gt',\n '$gte',\n '$lt',\n '$lte',\n '$btw',\n '$ilike',\n '$sw',\n '$contains',\n]);\nexport type Operator = z.infer<typeof OperatorSchema>;\n\n/**\n * Logical combinators for grouping conditions. $and and $or can be used to combine multiple conditions within the same group.\n */\nexport const CombinatorSchema = z.enum(['$and', '$or']);\nexport type Combinator = z.infer<typeof CombinatorSchema>;\n\nconst ROOT_GROUP_ID = '0';\nexport const IntegerStringSchema = z.string().regex(/^\\d+$/, 'Must be an integer string');\n\n/**\n * Regex for validating ISO date strings (YYYY-MM-DD).\n */\nexport const ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * Regex for validating ISO datetime strings (YYYY-MM-DDTHH:mm:ss.sssZ or with timezone offset).\n */\nexport const ISO_DATETIME_RE =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{1,6})?)?(Z|[+-]\\d{2}:\\d{2})$/;\n\nexport const NumericStringSchema = z\n .string()\n .trim()\n .regex(/^\\d+$/, 'Must be a numeric string')\n .transform((s) => Number(s));\n\nexport const NumOrDateSchema = z.union([z.number(), z.string()]);\n\ntype FieldType = 'string' | 'number' | 'date' | 'any';\n\ntype FieldTypeFromValue<V> = V extends Date\n ? 'date'\n : V extends number\n ? 'number'\n : V extends string\n ? 'string'\n : 'any';\n\ntype CommonOps = '$eq' | '$null' | '$in' | '$contains';\ntype StringOnlyOps = '$ilike' | '$sw';\ntype ComparableOps = '$gt' | '$gte' | '$lt' | '$lte' | '$btw';\n\ntype OpsForFieldType<TKind extends FieldType> = TKind extends 'string'\n ? CommonOps | StringOnlyOps\n : TKind extends 'number'\n ? CommonOps | ComparableOps\n : TKind extends 'date'\n ? CommonOps | ComparableOps\n : Operator;\n\nexport const ConditionSchema = z.discriminatedUnion('op', [\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.literal('$null'),\n not: z.literal(true).optional(),\n }),\n\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.literal('$eq'),\n not: z.literal(true).optional(),\n value: NumOrDateSchema,\n }),\n\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.enum(['$ilike', '$sw']),\n not: z.literal(true).optional(),\n value: z.string(),\n }),\n\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.enum(['$in', '$contains']),\n not: z.literal(true).optional(),\n value: z.array(z.string()),\n }),\n\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.enum(['$gt', '$gte', '$lt', '$lte']),\n not: z.literal(true).optional(),\n value: NumOrDateSchema,\n }),\n\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.literal('$btw'),\n not: z.literal(true).optional(),\n value: z.tuple([NumOrDateSchema, NumOrDateSchema]),\n }),\n]);\n\nexport type Condition = z.infer<typeof ConditionSchema>;\n\n/* ---------------------------------- */\n/* Filters AST */\n/* ---------------------------------- */\n\nexport interface WhereFilter {\n type: 'filter';\n field: string;\n condition: Condition;\n}\nexport interface WhereAnd {\n type: 'and';\n items: WhereNode[];\n}\nexport interface WhereOr {\n type: 'or';\n items: WhereNode[];\n}\nexport type WhereNode = WhereFilter | WhereAnd | WhereOr;\n\nfunction and(items: WhereNode[]): WhereNode {\n if (items.length === 1 && items[0]) return items[0];\n return { type: 'and', items };\n}\n\nfunction or(items: WhereNode[]): WhereNode {\n if (items.length === 1 && items[0]) return items[0];\n return { type: 'or', items };\n}\n\nfunction fold(op: Combinator | undefined, left: WhereNode, right: WhereNode): WhereNode {\n if (op === '$or') {\n if (left.type === 'or') return or([...left.items, right]);\n return or([left, right]);\n }\n if (left.type === 'and') return and([...left.items, right]);\n return and([left, right]);\n}\n\nconst WhereNodeSchema: z.ZodType<WhereNode> = z.lazy(() =>\n z.union([\n z.object({ type: z.literal('filter'), field: z.string(), condition: ConditionSchema }),\n z.object({ type: z.literal('and'), items: z.array(WhereNodeSchema) }),\n z.object({ type: z.literal('or'), items: z.array(WhereNodeSchema) }),\n ]),\n);\n\n/* ---------------------------------- */\n/* Group tree */\n/* ---------------------------------- */\n\ninterface GroupDef {\n parent?: string;\n join?: Combinator;\n op?: Combinator;\n}\ntype GroupDefs = Record<string, GroupDef>;\n\nfunction extractGroupDefs(q: Record<string, unknown>): GroupDefs {\n const defs: GroupDefs = {};\n\n for (const [k, v] of Object.entries(q)) {\n if (!k.startsWith('group.')) continue;\n\n const rest = k.slice('group.'.length);\n const dotIdx = rest.indexOf('.');\n if (dotIdx === -1) continue;\n\n const groupIdRaw = rest.slice(0, dotIdx).trim();\n const prop = rest.slice(dotIdx + 1).trim();\n\n const parsedId = IntegerStringSchema.safeParse(groupIdRaw);\n if (!parsedId.success) continue;\n const id = parsedId.data;\n\n const first = Array.isArray(v) ? v[0] : v;\n const valueStr = typeof first === 'string' ? first : '';\n\n const current = defs[id] ?? {};\n\n if (prop === 'parent') {\n defs[id] = { ...current, parent: IntegerStringSchema.parse(valueStr.trim()) };\n continue;\n }\n if (prop === 'join') {\n defs[id] = { ...current, join: CombinatorSchema.parse(valueStr.trim()) };\n continue;\n }\n if (prop === 'op') {\n defs[id] = { ...current, op: CombinatorSchema.parse(valueStr.trim()) };\n continue;\n }\n }\n\n return defs;\n}\n\nfunction validateGroupDefs(defs: GroupDefs): void {\n const root = defs[ROOT_GROUP_ID];\n if (root && (root.parent !== undefined || root.join !== undefined)) {\n throw new Error(\n `group.0 can only define \"op\". \"parent\" and \"join\" are not allowed on root group \"0\".`,\n );\n }\n\n for (const [id, def] of Object.entries(defs)) {\n if (id === ROOT_GROUP_ID) continue;\n if (def.parent !== undefined) IntegerStringSchema.parse(def.parent);\n }\n\n const visiting = new Set<string>();\n const visited = new Set<string>();\n\n const visit = (id: string): void => {\n if (visited.has(id)) return;\n if (visiting.has(id)) throw new Error(`Group cycle detected at group \"${id}\".`);\n visiting.add(id);\n\n const parent = defs[id]?.parent;\n if (parent && parent !== ROOT_GROUP_ID) visit(parent);\n\n visiting.delete(id);\n visited.add(id);\n };\n\n for (const id of Object.keys(defs)) {\n if (id === ROOT_GROUP_ID) continue;\n visit(id);\n }\n}\n\nfunction buildGroupConditionExprs(rawFilters: Record<string, Condition[]>): Map<string, WhereNode> {\n const groupNodes = new Map<string, WhereFilter[]>();\n\n for (const [field, conditions] of Object.entries(rawFilters)) {\n for (const cond of conditions) {\n const groupId = cond.group;\n const list = groupNodes.get(groupId) ?? [];\n const isFirst = list.length === 0;\n\n if (isFirst && cond.combinator !== undefined) {\n throw new Error(\n `Invalid combinator \"${cond.combinator}\" on first condition of group \"${groupId}\". ` +\n `First condition in a group cannot define \"$and\" or \"$or\".`,\n );\n }\n\n list.push({ type: 'filter', field, condition: cond });\n groupNodes.set(groupId, list);\n }\n }\n\n const exprs = new Map<string, WhereNode>();\n for (const [groupId, nodes] of groupNodes.entries()) {\n if (nodes.length === 0) continue;\n if (!nodes[0]) continue;\n\n let current: WhereNode = nodes[0];\n for (let i = 1; i < nodes.length; i += 1) {\n const next = nodes[i];\n if (!next) break;\n current = fold(next.condition.combinator, current, next);\n }\n exprs.set(groupId, current);\n }\n\n return exprs;\n}\n\nfunction buildWhereAstWithGroups(\n rawFilters: Record<string, Condition[]>,\n groupDefs: GroupDefs,\n): WhereNode {\n const groupExprs = buildGroupConditionExprs(rawFilters);\n\n const allGroupIds = new Set<string>();\n for (const id of groupExprs.keys()) allGroupIds.add(id);\n for (const id of Object.keys(groupDefs)) allGroupIds.add(id);\n allGroupIds.add(ROOT_GROUP_ID);\n\n const effectiveParent = (id: string): string => {\n if (id === ROOT_GROUP_ID) return ROOT_GROUP_ID;\n return groupDefs[id]?.parent ?? ROOT_GROUP_ID;\n };\n\n const childrenByParent = new Map<string, string[]>();\n for (const id of allGroupIds) {\n if (id === ROOT_GROUP_ID) continue;\n const parentId = effectiveParent(id);\n const arr = childrenByParent.get(parentId) ?? [];\n arr.push(id);\n childrenByParent.set(parentId, arr);\n }\n\n const sortNumericIds = (ids: string[]): string[] => {\n const pairs = ids.map((s) => ({ s, n: Number(s) }));\n pairs.sort((a, b) => a.n - b.n);\n return pairs.map((p) => p.s);\n };\n\n const visiting = new Set<string>();\n const resolved = new Map<string, WhereNode>();\n\n const resolveGroup = (id: string): WhereNode => {\n const cached = resolved.get(id);\n if (cached) return cached;\n\n if (visiting.has(id)) throw new Error(`Group cycle detected while resolving group \"${id}\".`);\n visiting.add(id);\n\n const items: { expr: WhereNode; join?: Combinator }[] = [];\n\n const own = groupExprs.get(id);\n if (own) items.push({ expr: own });\n\n const children = sortNumericIds(childrenByParent.get(id) ?? []);\n const parentOp = groupDefs[id]?.op;\n\n for (const childId of children) {\n const childExpr = resolveGroup(childId);\n const childJoin = groupDefs[childId]?.join;\n items.push({ expr: childExpr, join: childJoin ?? parentOp });\n }\n\n if (items.length === 0 || !items[0]) {\n const empty: WhereNode = { type: 'and', items: [] };\n resolved.set(id, empty);\n visiting.delete(id);\n return empty;\n }\n\n if (items[0].join !== undefined) {\n throw new Error(\n `Invalid group join \"${items[0].join}\" for the first item inside group \"${id}\". ` +\n `A group cannot start with \"$and\" or \"$or\" because there is nothing to join with.`,\n );\n }\n\n let current = items[0].expr;\n for (let i = 1; i < items.length; i += 1) {\n const next = items[i];\n if (!next) break;\n current = fold(next.join, current, next.expr);\n }\n\n resolved.set(id, current);\n visiting.delete(id);\n return current;\n };\n\n validateGroupDefs(groupDefs);\n return resolveGroup(ROOT_GROUP_ID);\n}\n\n/* ---------------------------------- */\n/* DSL parsing */\n/* ---------------------------------- */\n\n/** Parse a string as either a finite number or an ISO date string. */\nfunction parseNumOrDateStrict(raw: string, ctx: string): number | string {\n const s = raw.trim();\n\n if (/^[+-]?\\d+(\\.\\d+)?$/.test(s)) {\n const n = Number(s);\n if (!Number.isFinite(n)) throw new Error(`Invalid number for ${ctx}: \"${raw}\"`);\n return n;\n }\n\n if (ISO_DATE_RE.test(s) || ISO_DATETIME_RE.test(s)) {\n const t = Date.parse(s);\n if (Number.isNaN(t)) throw new Error(`Invalid ISO date for ${ctx}: \"${raw}\"`);\n return s;\n }\n\n throw new Error(`Expected number or ISO date for ${ctx}, got \"${raw}\"`);\n}\n\n/** Ensure $btw bounds are both numbers or both dates. */\nfunction assertSameKind(a: number | string, b: number | string, ctx: string): void {\n const ka = typeof a === 'number' ? 'number' : 'date';\n const kb = typeof b === 'number' ? 'number' : 'date';\n if (ka !== kb) {\n throw new Error(`$btw bounds must be same type (both number or both date) for ${ctx}`);\n }\n}\n\n/** Parse a single \"filter.<field>\" DSL string into a Condition. */\nfunction parseSingleCondition(raw: string): Condition {\n const parts = raw.split(':');\n\n let group = ROOT_GROUP_ID;\n let cursor = parts;\n\n if (cursor[0] === '$g') {\n group = IntegerStringSchema.parse((cursor[1] ?? '').trim());\n cursor = cursor.slice(2);\n if (cursor.length === 0) {\n throw new Error(`Invalid group prefix in \"${raw}\" (missing condition after \"$g:<id>\")`);\n }\n }\n\n let combinator: Combinator | undefined;\n if (cursor[0] === '$and' || cursor[0] === '$or') {\n combinator = CombinatorSchema.parse(cursor[0]);\n cursor = cursor.slice(1);\n if (cursor.length === 0) {\n throw new Error(`Invalid combinator in \"${raw}\" (missing condition after \"${combinator}\")`);\n }\n }\n\n const hasNot = cursor[0] === '$not';\n if (hasNot && !cursor[1]) {\n throw new Error(`Invalid \"$not\" usage in \"${raw}\" (missing operator after \"$not\")`);\n }\n\n const head = hasNot ? cursor[1] : cursor[0];\n const rest = hasNot ? cursor.slice(2).join(':') : cursor.slice(1).join(':');\n const not = hasNot ? true : undefined;\n\n if (!head?.startsWith('$')) {\n return ConditionSchema.parse({\n group,\n combinator,\n op: '$eq',\n value: cursor.join(':'),\n });\n }\n\n const op = OperatorSchema.parse(head);\n\n if (op === '$null') return ConditionSchema.parse({ group, combinator, op: '$null', not });\n\n if (op === '$eq') {\n let value: number | string;\n try {\n value = parseNumOrDateStrict(rest, '$eq');\n } catch {\n value = rest;\n }\n return ConditionSchema.parse({ group, combinator, op: '$eq', not, value });\n }\n\n if (op === '$btw') {\n const [aRaw, bRaw] = rest.split(',');\n if (!aRaw || !bRaw) throw new Error(`Invalid $btw \"${raw}\" (expected \"$btw:a,b\")`);\n const a = parseNumOrDateStrict(aRaw, '$btw');\n const b = parseNumOrDateStrict(bRaw, '$btw');\n assertSameKind(a, b, '$btw');\n return ConditionSchema.parse({ group, combinator, op: '$btw', not, value: [a, b] });\n }\n\n if (op === '$in' || op === '$contains') {\n const arr = rest\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n return ConditionSchema.parse({ group, combinator, op, not, value: arr });\n }\n\n if (op === '$gt' || op === '$gte' || op === '$lt' || op === '$lte') {\n const v = parseNumOrDateStrict(rest, op);\n return ConditionSchema.parse({ group, combinator, op, not, value: v });\n }\n\n // $ilike | $sw\n return ConditionSchema.parse({ group, combinator, op, not, value: rest });\n}\n\n/* ---------------------------------- */\n/* Extract raw filters */\n/* ---------------------------------- */\n\nfunction extractAndNormalizeRawFilters(q: QueryStringRecord): Record<string, Condition[]> {\n const result: Record<string, Condition[]> = {};\n\n for (const [k, v] of Object.entries(q)) {\n if (!k.startsWith('filter.')) continue;\n\n const field = k.slice('filter.'.length).trim();\n if (!field) continue;\n\n const rawList = toStringArrayFromQueryString(v);\n result[field] = rawList.filter(Boolean).map(parseSingleCondition);\n }\n\n return result;\n}\n\nfunction toQueryStringRecord(q: Record<string, unknown>): QueryStringRecord {\n const out: QueryStringRecord = {};\n for (const [k, v] of Object.entries(q)) {\n if (typeof v === 'string') {\n out[k] = v;\n continue;\n }\n if (Array.isArray(v) && v.every((x) => typeof x === 'string')) {\n out[k] = v;\n continue;\n }\n out[k] = undefined;\n }\n return out;\n}\n\ninterface FilterableFieldConfig<TKind extends FieldType> {\n type: TKind;\n ops: readonly OpsForFieldType<TKind>[];\n}\n\nexport interface CommonQueryConfigFromSchema<\n TSchema extends DataSchema,\n TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n dataSchema: TSchema;\n\n selectable?: readonly TSelectable[];\n sortable?: readonly AllowedPath<TSchema>[];\n\n filterable?: Partial<{\n [P in AllowedPath<TSchema>]: FilterableFieldConfig<\n FieldTypeFromValue<PathValue<InferData<TSchema>, P>>\n >;\n }>;\n\n defaultSortBy?: readonly { property: AllowedPath<TSchema>; direction: SortDirection }[];\n defaultLimit?: number;\n\n defaultSelect?: readonly (TSelectable | '*')[];\n maxLimit?: number;\n}\n\nexport type QueryConfigFromSchema<\n TSchema extends DataSchema,\n TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> = CommonQueryConfigFromSchema<TSchema, TSelectable> &\n (LimitOffsetPaginationConfig | CursorPaginationConfig<InferData<TSchema>>);\n\n/* ---------------------------------- */\n/* Runtime filterable map */\n/* ---------------------------------- */\n\ninterface FilterableRuntimeFieldConfig {\n type: FieldType;\n ops: readonly Operator[];\n}\n\nfunction toFilterableRuntime(\n filterable: Partial<Record<string, { type: FieldType; ops: readonly Operator[] }>> | undefined,\n): Record<string, FilterableRuntimeFieldConfig> {\n const out: Record<string, FilterableRuntimeFieldConfig> = {};\n if (!filterable) return out;\n\n for (const [k, v] of Object.entries(filterable)) {\n if (!v) continue;\n out[k] = { type: v.type, ops: [...v.ops] };\n }\n\n return out;\n}\n\nfunction computeLimit<TSchema extends DataSchema>(\n limit: number | undefined,\n config: QueryConfigFromSchema<TSchema, AllowedPath<TSchema>>,\n): number | undefined {\n if (typeof limit === 'number') return limit;\n if (typeof config.defaultLimit === 'number') return config.defaultLimit;\n return undefined;\n}\n\n/* ---------------------------------- */\n/* Runtime value/type validation */\n/* ---------------------------------- */\n\nfunction isISODateString(v: unknown): boolean {\n if (typeof v !== 'string') return false;\n if (!(ISO_DATE_RE.test(v) || ISO_DATETIME_RE.test(v))) return false;\n return !Number.isNaN(Date.parse(v));\n}\n\nfunction isFiniteNumber(v: unknown): boolean {\n return typeof v === 'number' && Number.isFinite(v);\n}\n\nfunction validateConditionType(expected: FieldType, cond: Condition, field: string): string | null {\n if (expected === 'any') return null;\n if (cond.op === '$null') return null;\n\n if (cond.op === '$eq') {\n if (expected === 'number' && !isFiniteNumber(cond.value))\n return `Field \"${field}\" expects a number for \"$eq\"`;\n if (expected === 'date' && !isISODateString(cond.value))\n return `Field \"${field}\" expects an ISO date for \"$eq\"`;\n if (expected === 'string' && typeof cond.value !== 'string')\n return `Field \"${field}\" expects a string for \"$eq\"`;\n return null;\n }\n\n if (cond.op === '$ilike' || cond.op === '$sw') {\n if (expected !== 'string')\n return `Field \"${field}\" does not support \"${cond.op}\" (configured as ${expected})`;\n return null;\n }\n\n if (cond.op === '$in' || cond.op === '$contains') return null;\n\n if (cond.op === '$gt' || cond.op === '$gte' || cond.op === '$lt' || cond.op === '$lte') {\n if (expected === 'string')\n return `Field \"${field}\" does not support \"${cond.op}\" (configured as string)`;\n if (expected === 'number' && !isFiniteNumber(cond.value))\n return `Field \"${field}\" expects number for \"${cond.op}\"`;\n if (expected === 'date' && !isISODateString(cond.value))\n return `Field \"${field}\" expects ISO date for \"${cond.op}\"`;\n return null;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (cond.op === '$btw') {\n const [a, b] = cond.value;\n if (expected === 'string')\n return `Field \"${field}\" does not support \"$btw\" (configured as string)`;\n if (expected === 'number' && (!isFiniteNumber(a) || !isFiniteNumber(b)))\n return `Field \"${field}\" expects numbers for \"$btw\"`;\n if (expected === 'date' && (!isISODateString(a) || !isISODateString(b)))\n return `Field \"${field}\" expects ISO dates for \"$btw\"`;\n return null;\n }\n\n return null;\n}\n\n/* ---------------------------------- */\n/* Sort defaults (typed, no \"as\") */\n/* ---------------------------------- */\n\nexport interface SortItemTyped<TSchema extends DataSchema> {\n property: AllowedPath<TSchema>;\n direction: SortDirection;\n}\n\nfunction computeSortBy<TSchema extends DataSchema>(\n sortByRaw: string[] | undefined,\n config: QueryConfigFromSchema<TSchema, AllowedPath<TSchema>>,\n): SortItemTyped<TSchema>[] | undefined {\n if (sortByRaw) {\n const cleaned = sortByRaw.map((s) => s.trim()).filter(Boolean);\n if (cleaned.length > 0) {\n const out: SortItemTyped<TSchema>[] = [];\n for (const raw of cleaned) {\n const parsed = parseSortItem(raw);\n\n const picked = pickFromAllowlist(config.sortable, parsed.property);\n if (!picked) continue;\n\n out.push({ property: picked, direction: parsed.direction });\n }\n return out.length > 0 ? out : undefined;\n }\n }\n\n if (config.defaultSortBy && config.defaultSortBy.length > 0) {\n return config.defaultSortBy.map((x) => ({ property: x.property, direction: x.direction }));\n }\n\n return undefined;\n}\n\n/* ---------------------------------- */\n/* QueryParams output (generic) */\n/* ---------------------------------- */\n\nexport interface LimitOffsetPaginationPayload<TSchema extends DataSchema> {\n type: 'LIMIT_OFFSET';\n limit?: number;\n page?: number;\n sortBy?: SortItemTyped<TSchema>[];\n select?: AllowedPath<TSchema>[];\n filters?: WhereNode;\n}\n\n/**\n * Cursor is always a string in the query input, BUT we coerce it at parse-time\n * to match the type of cursorProperty (number / string / ISO date string).\n */\nexport interface CursorPaginationPayload<TSchema extends DataSchema> {\n type: 'CURSOR';\n limit?: number;\n cursor?: number | string;\n cursorProperty: AllowedPath<TSchema>;\n sortBy?: SortItemTyped<TSchema>[];\n select?: AllowedPath<TSchema>[];\n filters?: WhereNode;\n}\n\nexport type PaginationPayload<TSchema extends DataSchema> =\n | LimitOffsetPaginationPayload<TSchema>\n | CursorPaginationPayload<TSchema>;\n\nexport interface PaginationQueryParams<TSchema extends DataSchema> {\n pagination: PaginationPayload<TSchema>;\n}\n\n/* ---------------------------------- */\n/* Validator response types */\n/* ---------------------------------- */\n\nexport interface LimitOffsetPaginationResponseMeta {\n itemsPerPage: number;\n totalItems: number;\n currentPage: number;\n totalPages: number;\n sortBy?: { property: string; direction: SortDirection }[];\n filter?: WhereNode;\n}\n\nexport interface CursorPaginationResponseMeta {\n itemsPerPage: number;\n cursor: number | string | Date;\n sortBy?: { property: string; direction: SortDirection }[];\n filter?: WhereNode;\n}\n\nexport interface LimitOffsetPaginationResponse<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n data: ProjectedData<TSchema, TSelect>[];\n pagination: LimitOffsetPaginationResponseMeta;\n}\n\nexport interface CursorPaginationResponse<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n data: ProjectedData<TSchema, TSelect>[];\n pagination: CursorPaginationResponseMeta;\n}\n\nexport type PaginationResponse<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> = LimitOffsetPaginationResponse<TSchema, TSelect> | CursorPaginationResponse<TSchema, TSelect>;\n\n/**\n * Result type returned by `paginate()`. Use this instead of\n * `ReturnType<typeof paginate>` to preserve the generic `TSchema`.\n *\n * @example\n * function createPaginator(): PaginateResult<typeof MySchema> {\n * return paginate({ dataSchema: MySchema, … });\n * }\n */\nexport interface PaginateResult<\n TSchema extends DataSchema,\n TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n queryParamsSchema: z.ZodType<PaginationQueryParams<TSchema>>;\n validatorSchema: (\n parsed?: PaginationPayload<TSchema>,\n ) => z.ZodType<PaginationResponse<TSchema, TSelectable>>;\n responseSchema: z.ZodType<PaginationResponse<TSchema, TSelectable>>;\n}\n\nfunction callMethodIfReturnsZod(obj: unknown, methodName: string): z.ZodType | undefined {\n if (!isPlainObject(obj)) return undefined;\n\n const maybeFn = getOwnProp(obj, methodName);\n if (typeof maybeFn !== 'function') return undefined;\n\n const result = maybeFn.call(obj);\n if (isZodSchema(result)) return result;\n\n return undefined;\n}\n\nfunction getInnerSchemaFromDef(obj: unknown): z.ZodType | undefined {\n if (!isPlainObject(obj)) return undefined;\n\n const def = getOwnProp(obj, 'def') ?? getOwnProp(obj, '_def');\n if (!isPlainObject(def)) return undefined;\n\n const candidates = ['innerType', 'schema', 'type', 'in', 'out'];\n\n for (const key of candidates) {\n const v = getOwnProp(def, key);\n if (isZodSchema(v)) return v;\n }\n\n return undefined;\n}\n\nfunction unwrapSchema(schema: z.ZodType): z.ZodType {\n let current: unknown = schema;\n\n for (let i = 0; i < 30; i += 1) {\n const unwrapped = callMethodIfReturnsZod(current, 'unwrap');\n if (unwrapped) {\n current = unwrapped;\n continue;\n }\n\n const removedDefault = callMethodIfReturnsZod(current, 'removeDefault');\n if (removedDefault) {\n current = removedDefault;\n continue;\n }\n\n const innerType = callMethodIfReturnsZod(current, 'innerType');\n if (innerType) {\n current = innerType;\n continue;\n }\n\n const sourceType = callMethodIfReturnsZod(current, 'sourceType');\n if (sourceType) {\n current = sourceType;\n continue;\n }\n\n const innerFromDef = getInnerSchemaFromDef(current);\n if (innerFromDef) {\n current = innerFromDef;\n continue;\n }\n\n break;\n }\n\n if (isZodSchema(current)) return current;\n return schema;\n}\n\n/**\n * Robust constructor name getter that works with Zod objects (constructor is on the prototype).\n * No `as`, no unsafe casts.\n */\nfunction getConstructorName(v: unknown): string | undefined {\n if (typeof v !== 'object' || v === null) return undefined;\n\n const proto: unknown = Object.getPrototypeOf(v);\n if (typeof proto !== 'object' || proto === null) return undefined;\n\n const ctorUnknown: unknown = Reflect.get(proto, 'constructor');\n if (!(ctorUnknown instanceof Function)) return undefined;\n\n return ctorUnknown.name;\n}\n\n/* ---------------------------------- */\n/* Cursor: schema inference + coercion */\n/* ---------------------------------- */\n\n/**\n * Return the expected cursor schema for API responses:\n * - number field => cursor: number\n * - string field => cursor: string\n * - date field => cursor: ISO string OR Date (optional support)\n */\nfunction cursorSchemaFromProperty<TSchema extends DataSchema>(\n dataSchema: TSchema,\n cursorProperty: AllowedPath<TSchema>,\n): z.ZodType<number | string | Date> {\n const raw = getZodAtPath(dataSchema, `${cursorProperty}`);\n const s = unwrapSchema(raw);\n const ctorName = getConstructorName(s);\n\n if (ctorName === 'ZodNumber') return z.number();\n if (ctorName === 'ZodString') return z.string();\n if (ctorName === 'ZodDate') return z.union([z.string().refine(isISODateString), z.date()]);\n\n // Unsupported cursor field type\n return z.never();\n}\n\n/**\n * Coerce the query input cursor (always string) into the right type based on cursorProperty.\n * - number field => \"123\" -> 123\n * - string field => \"abc\" -> \"abc\"\n * - date field => \"2022-01-01\" -> \"2022-01-01\" (validated as ISO)\n */\nfunction coerceCursorFromProperty<TSchema extends DataSchema>(\n dataSchema: TSchema,\n cursorProperty: AllowedPath<TSchema>,\n rawCursor: string,\n): number | string {\n const schemaAtPath = unwrapSchema(getZodAtPath(dataSchema, `${cursorProperty}`));\n const ctorName = getConstructorName(schemaAtPath);\n\n if (ctorName === 'ZodNumber') {\n const s = rawCursor.trim();\n if (!/^[+-]?\\d+$/.test(s)) throw new Error(`cursor must be an integer string`);\n const n = Number(s);\n if (!Number.isFinite(n)) throw new Error(`cursor must be a finite number`);\n return n;\n }\n\n if (ctorName === 'ZodString') {\n return rawCursor;\n }\n\n if (ctorName === 'ZodDate') {\n const s = rawCursor.trim();\n if (!isISODateString(s)) throw new Error(`cursor must be an ISO date string`);\n return s;\n }\n\n throw new Error(`cursorProperty \"${cursorProperty}\" must be a string|number|date`);\n}\n\n/* ---------------------------------- */\n/* Factory */\n/* ---------------------------------- */\n\n/**\n * Generate Zod schemas and runtime validators for pagination query parameters, based on a config object.\n * @param config The configuration object defining the pagination behavior and allowed fields.\n * @returns An object containing:\n * - `queryParamsSchema`: A Zod schema for validating and parsing the raw query parameters.\n * - `validatorSchema`: A function that takes the already-parsed query parameters and returns a Zod schema for further validation (e.g. filters).\n * - `responseSchema`: A pre-built Zod schema for validating the response (uses defaultSelect or all selectable fields).\n */\nexport function paginate<\n TSchema extends DataSchema,\n const TSelectable extends readonly AllowedPath<TSchema>[],\n>(\n config: QueryConfigFromSchema<TSchema, TSelectable[number]>,\n): PaginateResult<TSchema, TSelectable[number]> {\n const allowedSelectable = new Set<string>();\n for (const f of config.selectable ?? []) allowedSelectable.add(`${f}`);\n\n const allowedSortable = new Set<string>();\n for (const f of config.sortable ?? []) allowedSortable.add(`${f}`);\n\n const filterable = toFilterableRuntime(config.filterable);\n\n const baseSchema = z.object({\n limit: NumericStringSchema.optional(),\n page: NumericStringSchema.optional(),\n\n /**\n * Query input is always a string if present.\n * We will coerce it later in the final transform (CURSOR mode only).\n */\n cursor: z.string().min(1).optional(),\n\n sortBy: StringOrStringArraySchema.optional(),\n select: SelectSchema.optional(),\n\n rawFilters: z.record(z.string(), z.array(ConditionSchema)),\n groupDefs: z.record(\n z.string(),\n z.object({\n parent: IntegerStringSchema.optional(),\n join: CombinatorSchema.optional(),\n op: CombinatorSchema.optional(),\n }),\n ),\n });\n\n const queryParamsSchema: z.ZodType<PaginationQueryParams<TSchema>> = z\n .record(z.string(), z.unknown())\n .transform(\n (\n q,\n ): Record<string, unknown> & {\n rawFilters: Record<string, Condition[]>;\n groupDefs: GroupDefs;\n } => {\n const qs = toQueryStringRecord(q);\n\n return {\n ...q,\n rawFilters: extractAndNormalizeRawFilters(qs),\n groupDefs: extractGroupDefs(q),\n };\n },\n )\n .pipe(\n baseSchema\n .superRefine((val, ctx): void => {\n // Pagination mode constraints\n if (config.paginationType === 'LIMIT_OFFSET') {\n if (val.cursor !== undefined) {\n ctx.addIssue({\n code: 'custom',\n path: ['cursor'],\n message: `cursor is not allowed when paginationType is LIMIT_OFFSET`,\n });\n }\n }\n\n if (config.paginationType === 'CURSOR') {\n if (val.page !== undefined) {\n ctx.addIssue({\n code: 'custom',\n path: ['page'],\n message: `page is not allowed when paginationType is CURSOR`,\n });\n }\n\n if (`${config.cursorProperty}`.trim().length === 0) {\n ctx.addIssue({\n code: 'custom',\n path: [],\n message: `cursorProperty must be a non-empty string when paginationType is CURSOR`,\n });\n }\n\n // Validate that cursor (if provided) can be coerced for that cursorProperty\n if (val.cursor !== undefined) {\n try {\n void coerceCursorFromProperty(config.dataSchema, config.cursorProperty, val.cursor);\n } catch (e) {\n const message = e instanceof Error ? e.message : 'Invalid cursor';\n ctx.addIssue({\n code: 'custom',\n path: ['cursor'],\n message,\n });\n }\n }\n }\n\n // limit / maxLimit\n if (\n typeof val.limit === 'number' &&\n typeof config.maxLimit === 'number' &&\n val.limit > config.maxLimit\n ) {\n ctx.addIssue({\n code: 'custom',\n path: ['limit'],\n message: `limit must be <= ${config.maxLimit}`,\n });\n }\n\n // select forbidden if no selectable configured\n if (val.select && (!config.selectable || config.selectable.length === 0)) {\n ctx.addIssue({\n code: 'custom',\n path: ['select'],\n message: `select is not allowed (no selectable fields configured)`,\n });\n }\n\n // select allowlist + \"*\" expandability\n const selectForValidation =\n val.select ??\n (config.defaultSelect ? config.defaultSelect.map((x) => `${x}`) : undefined);\n\n if (selectForValidation) {\n let index = 0;\n\n for (const field of selectForValidation) {\n if (field === '*') {\n index += 1;\n continue;\n }\n\n if (allowedSelectable.size > 0 && !allowedSelectable.has(field)) {\n ctx.addIssue({\n code: 'custom',\n path: ['select', index],\n message: `select field \"${field}\" is not allowed`,\n });\n }\n\n index += 1;\n }\n\n if (selectForValidation.includes('*')) {\n const expanded = expandSelect(selectForValidation, config);\n if (!expanded || expanded.length === 0) {\n ctx.addIssue({\n code: 'custom',\n path: ['select'],\n message: `select \"*\" cannot be expanded (missing selectable in config)`,\n });\n }\n }\n }\n\n // sort allowlist\n const sortItems = computeSortBy(val.sortBy, config);\n if (val.sortBy) {\n if (!config.sortable || config.sortable.length === 0) {\n ctx.addIssue({\n code: 'custom',\n path: ['sortBy'],\n message: `sortBy is not allowed (no sortable fields configured)`,\n });\n } else if (sortItems) {\n let index = 0;\n for (const item of sortItems) {\n if (!allowedSortable.has(`${item.property}`)) {\n ctx.addIssue({\n code: 'custom',\n path: ['sortBy', index],\n message: `sort property \"${item.property}\" is not allowed`,\n });\n }\n index += 1;\n }\n }\n }\n\n // filter allowlist + operator/type validation\n for (const [field, conditions] of Object.entries(val.rawFilters)) {\n const cfg = filterable[field];\n\n if (!cfg) {\n ctx.addIssue({\n code: 'custom',\n path: ['rawFilters', field],\n message: `filter field \"${field}\" is not allowed`,\n });\n continue;\n }\n\n const allowedOps = new Set(cfg.ops);\n\n let index = 0;\n for (const cond of conditions) {\n if (!allowedOps.has(cond.op)) {\n ctx.addIssue({\n code: 'custom',\n path: ['rawFilters', field, index, 'op'],\n message: `operator \"${cond.op}\" is not allowed for \"${field}\"`,\n });\n }\n\n const typeError = validateConditionType(cfg.type, cond, field);\n if (typeError) {\n ctx.addIssue({\n code: 'custom',\n path: ['rawFilters', field, index],\n message: typeError,\n });\n }\n\n index += 1;\n }\n }\n\n // group consistency\n const hasAnyFilter = Object.keys(val.rawFilters).length > 0;\n const hasAnyGroupDef = Object.keys(val.groupDefs).length > 0;\n\n if (hasAnyGroupDef && !hasAnyFilter) {\n ctx.addIssue({\n code: 'custom',\n path: ['groupDefs'],\n message: `group.* is not allowed without any filter.*`,\n });\n } else if (hasAnyFilter) {\n try {\n void buildWhereAstWithGroups(val.rawFilters, val.groupDefs);\n } catch (e) {\n const message = e instanceof Error ? e.message : 'Invalid group configuration';\n ctx.addIssue({\n code: 'custom',\n path: ['groupDefs'],\n message,\n });\n }\n }\n })\n .transform((val): PaginationQueryParams<TSchema> => {\n const limit = computeLimit(val.limit, config);\n const sortBy = computeSortBy(val.sortBy, config);\n const select = computeSelect(val.select, config);\n\n const hasAnyFilter = Object.keys(val.rawFilters).length > 0;\n\n const maybeFilters = hasAnyFilter\n ? { filters: buildWhereAstWithGroups(val.rawFilters, val.groupDefs) }\n : {};\n\n if (config.paginationType === 'LIMIT_OFFSET') {\n return {\n pagination: {\n type: 'LIMIT_OFFSET',\n limit,\n page: val.page,\n sortBy,\n select,\n ...maybeFilters,\n },\n };\n }\n\n // CURSOR: coerce string cursor into number/string based on cursorProperty\n let cursor: number | string | undefined = undefined;\n if (val.cursor !== undefined) {\n cursor = coerceCursorFromProperty(config.dataSchema, config.cursorProperty, val.cursor);\n }\n\n return {\n pagination: {\n type: 'CURSOR',\n limit,\n cursor,\n cursorProperty: config.cursorProperty,\n sortBy,\n select,\n ...maybeFilters,\n },\n };\n }),\n );\n\n const validatorSchema = (\n parsed?: PaginationPayload<TSchema>,\n ): z.ZodType<PaginationResponse<TSchema, TSelectable[number]>> => {\n const effectiveSelect = parsed?.select ?? computeSelect(undefined, config) ?? undefined;\n\n const dataItemSchema =\n effectiveSelect && effectiveSelect.length > 0\n ? projectDataSchema(\n config.dataSchema,\n effectiveSelect.map((x) => `${x}`),\n )\n : config.dataSchema;\n\n const dataArraySchema = z.array(dataItemSchema);\n\n if (config.paginationType === 'LIMIT_OFFSET') {\n return z.object({\n data: dataArraySchema,\n pagination: z.object({\n itemsPerPage: z.number(),\n totalItems: z.number(),\n currentPage: z.number(),\n totalPages: z.number(),\n sortBy: z\n .array(\n z.object({\n property: z.string(),\n direction: SortDirectionSchema,\n }),\n )\n .optional(),\n filter: WhereNodeSchema.optional(),\n }),\n });\n }\n\n const cursorType = cursorSchemaFromProperty(config.dataSchema, config.cursorProperty);\n\n return z.object({\n data: dataArraySchema,\n pagination: z.object({\n itemsPerPage: z.number(),\n cursor: cursorType,\n sortBy: z\n .array(\n z.object({\n property: z.string(),\n direction: SortDirectionSchema,\n }),\n )\n .optional(),\n filter: WhereNodeSchema.optional(),\n }),\n });\n };\n\n const responseSchema = validatorSchema();\n\n return { queryParamsSchema, validatorSchema, responseSchema };\n}\n"]}
1
+ {"version":3,"file":"paginate.js","sourceRoot":"","sources":["../src/paginate.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport {\n type AllowedPath,\n computeSelect,\n type DataSchema,\n expandSelect,\n getOwnProp,\n getZodAtPath,\n type InferData,\n isPlainObject,\n isZodSchema,\n type Path,\n type PathValue,\n pickFromAllowlist,\n projectDataSchema,\n type ProjectedData,\n SelectSchema,\n} from './select';\n\n/* ---------------------------------- */\n/* Querystring value types */\n/* ---------------------------------- */\n\ntype QueryStringValue = string | string[] | undefined;\ntype QueryStringRecord = Record<string, QueryStringValue>;\n\n/* ---------------------------------- */\n/* Pagination config */\n/* ---------------------------------- */\n\ninterface LimitOffsetPaginationConfig {\n paginationType: 'LIMIT_OFFSET';\n}\n\ninterface CursorPaginationConfig<T> {\n paginationType: 'CURSOR';\n cursorProperty: Path<T>;\n}\n\n/* ---------------------------------- */\n/* Common input normalizers */\n/* ---------------------------------- */\n\n/**\n * We often want to allow both single values and arrays in the querystring, e.g. \"select=field1,field2\" or \"select[]=field1&select[]=field2\".\n * This function normalizes both cases to a string array.\n */\nfunction toStringArrayFromQueryString(v: QueryStringValue): string[] {\n if (v === undefined) return [];\n if (Array.isArray(v)) return v;\n return [v];\n}\n\n/**\n * Zod schema for a querystring parameter that can be either a single string or an array of strings.\n * It normalizes the output to always be an array of strings.\n */\nconst StringOrStringArraySchema = z\n .union([z.string(), z.array(z.string())])\n .transform((v) => (typeof v === 'string' ? [v] : v));\n\n/* ---------------------------------- */\n/* Sort */\n/* ---------------------------------- */\n\nexport const SortDirectionSchema = z.enum(['ASC', 'DESC']);\nexport type SortDirection = z.infer<typeof SortDirectionSchema>;\n\nexport const SortItemSchema = z.object({\n property: z.string().min(1),\n direction: SortDirectionSchema,\n});\nexport type SortItem = z.infer<typeof SortItemSchema>;\n\n/**\n * Parse \"field:ASC\" into a SortItem.\n * The input must have a colon separating the field and direction, and the direction must be either \"ASC\" or \"DESC\" (case-insensitive).\n * */\nfunction parseSortItem(raw: string): SortItem {\n const [propertyRaw, dirRaw] = raw.split(':');\n const property = (propertyRaw ?? '').trim();\n const direction = SortDirectionSchema.parse((dirRaw ?? '').trim());\n return SortItemSchema.parse({ property, direction });\n}\n\n/* ---------------------------------- */\n/* Conditions + grouping */\n/* ---------------------------------- */\n\n/**\n * Supported operators.\n * $eq: equality (for strings, numbers, dates)\n * $null: checks for null (ignores the value)\n * $in: checks if the field value is in the provided array (for strings, numbers, dates)\n * $gt, $gte, $lt, $lte: comparison operators (for numbers and dates)\n * $btw: checks if the field value is between two values (for numbers and dates)\n * $ilike: case-insensitive substring match (for strings)\n * $sw: case-insensitive starts-with match (for strings)\n * $contains: checks if the field value contains the provided value (for strings)\n */\nexport const OperatorSchema = z.enum([\n '$eq',\n '$null',\n '$in',\n '$gt',\n '$gte',\n '$lt',\n '$lte',\n '$btw',\n '$ilike',\n '$sw',\n '$contains',\n]);\nexport type Operator = z.infer<typeof OperatorSchema>;\n\n/**\n * Logical combinators for grouping conditions. $and and $or can be used to combine multiple conditions within the same group.\n */\nexport const CombinatorSchema = z.enum(['$and', '$or']);\nexport type Combinator = z.infer<typeof CombinatorSchema>;\n\nconst ROOT_GROUP_ID = '0';\nexport const IntegerStringSchema = z.string().regex(/^\\d+$/, 'Must be an integer string');\n\n/**\n * Regex for validating ISO date strings (YYYY-MM-DD).\n */\nexport const ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/**\n * Regex for validating ISO datetime strings (YYYY-MM-DDTHH:mm:ss.sssZ or with timezone offset).\n */\nexport const ISO_DATETIME_RE =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{1,6})?)?(Z|[+-]\\d{2}:\\d{2})$/;\n\nexport const NumericStringSchema = z\n .string()\n .trim()\n .regex(/^\\d+$/, 'Must be a numeric string')\n .transform((s) => Number(s));\n\nexport const NumOrDateSchema = z.union([z.number(), z.string()]);\n\ntype FieldType = 'string' | 'number' | 'date' | 'any';\n\ntype FieldTypeFromValue<V> = V extends Date\n ? 'date'\n : V extends number\n ? 'number'\n : V extends string\n ? 'string'\n : 'any';\n\ntype CommonOps = '$eq' | '$null' | '$in' | '$contains';\ntype StringOnlyOps = '$ilike' | '$sw';\ntype ComparableOps = '$gt' | '$gte' | '$lt' | '$lte' | '$btw';\n\ntype OpsForFieldType<TKind extends FieldType> = TKind extends 'string'\n ? CommonOps | StringOnlyOps\n : TKind extends 'number'\n ? CommonOps | ComparableOps\n : TKind extends 'date'\n ? CommonOps | ComparableOps\n : Operator;\n\nexport const ConditionSchema = z.discriminatedUnion('op', [\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.literal('$null'),\n not: z.literal(true).optional(),\n }),\n\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.literal('$eq'),\n not: z.literal(true).optional(),\n value: NumOrDateSchema,\n }),\n\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.enum(['$ilike', '$sw']),\n not: z.literal(true).optional(),\n value: z.string(),\n }),\n\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.enum(['$in', '$contains']),\n not: z.literal(true).optional(),\n value: z.array(z.string()),\n }),\n\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.enum(['$gt', '$gte', '$lt', '$lte']),\n not: z.literal(true).optional(),\n value: NumOrDateSchema,\n }),\n\n z.object({\n group: IntegerStringSchema,\n combinator: CombinatorSchema.optional(),\n op: z.literal('$btw'),\n not: z.literal(true).optional(),\n value: z.tuple([NumOrDateSchema, NumOrDateSchema]),\n }),\n]);\n\nexport type Condition = z.infer<typeof ConditionSchema>;\n\n/* ---------------------------------- */\n/* Filters AST */\n/* ---------------------------------- */\n\nexport interface WhereFilter {\n type: 'filter';\n field: string;\n condition: Condition;\n}\nexport interface WhereAnd {\n type: 'and';\n items: WhereNode[];\n}\nexport interface WhereOr {\n type: 'or';\n items: WhereNode[];\n}\nexport type WhereNode = WhereFilter | WhereAnd | WhereOr;\n\nfunction and(items: WhereNode[]): WhereNode {\n if (items.length === 1 && items[0]) return items[0];\n return { type: 'and', items };\n}\n\nfunction or(items: WhereNode[]): WhereNode {\n if (items.length === 1 && items[0]) return items[0];\n return { type: 'or', items };\n}\n\nfunction fold(op: Combinator | undefined, left: WhereNode, right: WhereNode): WhereNode {\n if (op === '$or') {\n if (left.type === 'or') return or([...left.items, right]);\n return or([left, right]);\n }\n if (left.type === 'and') return and([...left.items, right]);\n return and([left, right]);\n}\n\nconst WhereNodeSchema: z.ZodType<WhereNode> = z.lazy(() =>\n z.union([\n z.object({ type: z.literal('filter'), field: z.string(), condition: ConditionSchema }),\n z.object({ type: z.literal('and'), items: z.array(WhereNodeSchema) }),\n z.object({ type: z.literal('or'), items: z.array(WhereNodeSchema) }),\n ]),\n);\n\n/* ---------------------------------- */\n/* Group tree */\n/* ---------------------------------- */\n\ninterface GroupDef {\n parent?: string;\n join?: Combinator;\n op?: Combinator;\n}\ntype GroupDefs = Record<string, GroupDef>;\n\nfunction extractGroupDefs(q: Record<string, unknown>): GroupDefs {\n const defs: GroupDefs = {};\n\n for (const [k, v] of Object.entries(q)) {\n if (!k.startsWith('group.')) continue;\n\n const rest = k.slice('group.'.length);\n const dotIdx = rest.indexOf('.');\n if (dotIdx === -1) continue;\n\n const groupIdRaw = rest.slice(0, dotIdx).trim();\n const prop = rest.slice(dotIdx + 1).trim();\n\n const parsedId = IntegerStringSchema.safeParse(groupIdRaw);\n if (!parsedId.success) continue;\n const id = parsedId.data;\n\n const first = Array.isArray(v) ? v[0] : v;\n const valueStr = typeof first === 'string' ? first : '';\n\n const current = defs[id] ?? {};\n\n if (prop === 'parent') {\n defs[id] = { ...current, parent: IntegerStringSchema.parse(valueStr.trim()) };\n continue;\n }\n if (prop === 'join') {\n defs[id] = { ...current, join: CombinatorSchema.parse(valueStr.trim()) };\n continue;\n }\n if (prop === 'op') {\n defs[id] = { ...current, op: CombinatorSchema.parse(valueStr.trim()) };\n continue;\n }\n }\n\n return defs;\n}\n\nfunction validateGroupDefs(defs: GroupDefs): void {\n const root = defs[ROOT_GROUP_ID];\n if (root && (root.parent !== undefined || root.join !== undefined)) {\n throw new Error(\n `group.0 can only define \"op\". \"parent\" and \"join\" are not allowed on root group \"0\".`,\n );\n }\n\n for (const [id, def] of Object.entries(defs)) {\n if (id === ROOT_GROUP_ID) continue;\n if (def.parent !== undefined) IntegerStringSchema.parse(def.parent);\n }\n\n const visiting = new Set<string>();\n const visited = new Set<string>();\n\n const visit = (id: string): void => {\n if (visited.has(id)) return;\n if (visiting.has(id)) throw new Error(`Group cycle detected at group \"${id}\".`);\n visiting.add(id);\n\n const parent = defs[id]?.parent;\n if (parent && parent !== ROOT_GROUP_ID) visit(parent);\n\n visiting.delete(id);\n visited.add(id);\n };\n\n for (const id of Object.keys(defs)) {\n if (id === ROOT_GROUP_ID) continue;\n visit(id);\n }\n}\n\nfunction buildGroupConditionExprs(rawFilters: Record<string, Condition[]>): Map<string, WhereNode> {\n const groupNodes = new Map<string, WhereFilter[]>();\n\n for (const [field, conditions] of Object.entries(rawFilters)) {\n for (const cond of conditions) {\n const groupId = cond.group;\n const list = groupNodes.get(groupId) ?? [];\n const isFirst = list.length === 0;\n\n if (isFirst && cond.combinator !== undefined) {\n throw new Error(\n `Invalid combinator \"${cond.combinator}\" on first condition of group \"${groupId}\". ` +\n `First condition in a group cannot define \"$and\" or \"$or\".`,\n );\n }\n\n list.push({ type: 'filter', field, condition: cond });\n groupNodes.set(groupId, list);\n }\n }\n\n const exprs = new Map<string, WhereNode>();\n for (const [groupId, nodes] of groupNodes.entries()) {\n if (nodes.length === 0) continue;\n if (!nodes[0]) continue;\n\n let current: WhereNode = nodes[0];\n for (let i = 1; i < nodes.length; i += 1) {\n const next = nodes[i];\n if (!next) break;\n current = fold(next.condition.combinator, current, next);\n }\n exprs.set(groupId, current);\n }\n\n return exprs;\n}\n\nfunction buildWhereAstWithGroups(\n rawFilters: Record<string, Condition[]>,\n groupDefs: GroupDefs,\n): WhereNode {\n const groupExprs = buildGroupConditionExprs(rawFilters);\n\n const allGroupIds = new Set<string>();\n for (const id of groupExprs.keys()) allGroupIds.add(id);\n for (const id of Object.keys(groupDefs)) allGroupIds.add(id);\n allGroupIds.add(ROOT_GROUP_ID);\n\n const effectiveParent = (id: string): string => {\n if (id === ROOT_GROUP_ID) return ROOT_GROUP_ID;\n return groupDefs[id]?.parent ?? ROOT_GROUP_ID;\n };\n\n const childrenByParent = new Map<string, string[]>();\n for (const id of allGroupIds) {\n if (id === ROOT_GROUP_ID) continue;\n const parentId = effectiveParent(id);\n const arr = childrenByParent.get(parentId) ?? [];\n arr.push(id);\n childrenByParent.set(parentId, arr);\n }\n\n const sortNumericIds = (ids: string[]): string[] => {\n const pairs = ids.map((s) => ({ s, n: Number(s) }));\n pairs.sort((a, b) => a.n - b.n);\n return pairs.map((p) => p.s);\n };\n\n const visiting = new Set<string>();\n const resolved = new Map<string, WhereNode>();\n\n const resolveGroup = (id: string): WhereNode => {\n const cached = resolved.get(id);\n if (cached) return cached;\n\n if (visiting.has(id)) throw new Error(`Group cycle detected while resolving group \"${id}\".`);\n visiting.add(id);\n\n const items: { expr: WhereNode; join?: Combinator }[] = [];\n\n const own = groupExprs.get(id);\n if (own) items.push({ expr: own });\n\n const children = sortNumericIds(childrenByParent.get(id) ?? []);\n const parentOp = groupDefs[id]?.op;\n\n for (const childId of children) {\n const childExpr = resolveGroup(childId);\n const childJoin = groupDefs[childId]?.join;\n items.push({ expr: childExpr, join: childJoin ?? parentOp });\n }\n\n if (items.length === 0 || !items[0]) {\n const empty: WhereNode = { type: 'and', items: [] };\n resolved.set(id, empty);\n visiting.delete(id);\n return empty;\n }\n\n if (items[0].join !== undefined) {\n throw new Error(\n `Invalid group join \"${items[0].join}\" for the first item inside group \"${id}\". ` +\n `A group cannot start with \"$and\" or \"$or\" because there is nothing to join with.`,\n );\n }\n\n let current = items[0].expr;\n for (let i = 1; i < items.length; i += 1) {\n const next = items[i];\n if (!next) break;\n current = fold(next.join, current, next.expr);\n }\n\n resolved.set(id, current);\n visiting.delete(id);\n return current;\n };\n\n validateGroupDefs(groupDefs);\n return resolveGroup(ROOT_GROUP_ID);\n}\n\n/* ---------------------------------- */\n/* DSL parsing */\n/* ---------------------------------- */\n\n/** Parse a string as either a finite number or an ISO date string. */\nfunction parseNumOrDateStrict(raw: string, ctx: string): number | string {\n const s = raw.trim();\n\n if (/^[+-]?\\d+(\\.\\d+)?$/.test(s)) {\n const n = Number(s);\n if (!Number.isFinite(n)) throw new Error(`Invalid number for ${ctx}: \"${raw}\"`);\n return n;\n }\n\n if (ISO_DATE_RE.test(s) || ISO_DATETIME_RE.test(s)) {\n const t = Date.parse(s);\n if (Number.isNaN(t)) throw new Error(`Invalid ISO date for ${ctx}: \"${raw}\"`);\n return s;\n }\n\n throw new Error(`Expected number or ISO date for ${ctx}, got \"${raw}\"`);\n}\n\n/** Ensure $btw bounds are both numbers or both dates. */\nfunction assertSameKind(a: number | string, b: number | string, ctx: string): void {\n const ka = typeof a === 'number' ? 'number' : 'date';\n const kb = typeof b === 'number' ? 'number' : 'date';\n if (ka !== kb) {\n throw new Error(`$btw bounds must be same type (both number or both date) for ${ctx}`);\n }\n}\n\n/** Parse a single \"filter.<field>\" DSL string into a Condition. */\nfunction parseSingleCondition(raw: string): Condition {\n const parts = raw.split(':');\n\n let group = ROOT_GROUP_ID;\n let cursor = parts;\n\n if (cursor[0] === '$g') {\n group = IntegerStringSchema.parse((cursor[1] ?? '').trim());\n cursor = cursor.slice(2);\n if (cursor.length === 0) {\n throw new Error(`Invalid group prefix in \"${raw}\" (missing condition after \"$g:<id>\")`);\n }\n }\n\n let combinator: Combinator | undefined;\n if (cursor[0] === '$and' || cursor[0] === '$or') {\n combinator = CombinatorSchema.parse(cursor[0]);\n cursor = cursor.slice(1);\n if (cursor.length === 0) {\n throw new Error(`Invalid combinator in \"${raw}\" (missing condition after \"${combinator}\")`);\n }\n }\n\n const hasNot = cursor[0] === '$not';\n if (hasNot && !cursor[1]) {\n throw new Error(`Invalid \"$not\" usage in \"${raw}\" (missing operator after \"$not\")`);\n }\n\n const head = hasNot ? cursor[1] : cursor[0];\n const rest = hasNot ? cursor.slice(2).join(':') : cursor.slice(1).join(':');\n const not = hasNot ? true : undefined;\n\n if (!head?.startsWith('$')) {\n return ConditionSchema.parse({\n group,\n combinator,\n op: '$eq',\n value: cursor.join(':'),\n });\n }\n\n const op = OperatorSchema.parse(head);\n\n if (op === '$null') return ConditionSchema.parse({ group, combinator, op: '$null', not });\n\n if (op === '$eq') {\n let value: number | string;\n try {\n value = parseNumOrDateStrict(rest, '$eq');\n } catch {\n value = rest;\n }\n return ConditionSchema.parse({ group, combinator, op: '$eq', not, value });\n }\n\n if (op === '$btw') {\n const [aRaw, bRaw] = rest.split(',');\n if (!aRaw || !bRaw) throw new Error(`Invalid $btw \"${raw}\" (expected \"$btw:a,b\")`);\n const a = parseNumOrDateStrict(aRaw, '$btw');\n const b = parseNumOrDateStrict(bRaw, '$btw');\n assertSameKind(a, b, '$btw');\n return ConditionSchema.parse({ group, combinator, op: '$btw', not, value: [a, b] });\n }\n\n if (op === '$in' || op === '$contains') {\n const arr = rest\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n return ConditionSchema.parse({ group, combinator, op, not, value: arr });\n }\n\n if (op === '$gt' || op === '$gte' || op === '$lt' || op === '$lte') {\n const v = parseNumOrDateStrict(rest, op);\n return ConditionSchema.parse({ group, combinator, op, not, value: v });\n }\n\n // $ilike | $sw\n return ConditionSchema.parse({ group, combinator, op, not, value: rest });\n}\n\n/* ---------------------------------- */\n/* Extract raw filters */\n/* ---------------------------------- */\n\nfunction extractAndNormalizeRawFilters(q: QueryStringRecord): Record<string, Condition[]> {\n const result: Record<string, Condition[]> = {};\n\n for (const [k, v] of Object.entries(q)) {\n if (!k.startsWith('filter.')) continue;\n\n const field = k.slice('filter.'.length).trim();\n if (!field) continue;\n\n const rawList = toStringArrayFromQueryString(v);\n result[field] = rawList.filter(Boolean).map(parseSingleCondition);\n }\n\n return result;\n}\n\nfunction toQueryStringRecord(q: Record<string, unknown>): QueryStringRecord {\n const out: QueryStringRecord = {};\n for (const [k, v] of Object.entries(q)) {\n if (typeof v === 'string') {\n out[k] = v;\n continue;\n }\n if (Array.isArray(v) && v.every((x) => typeof x === 'string')) {\n out[k] = v;\n continue;\n }\n out[k] = undefined;\n }\n return out;\n}\n\ninterface FilterableFieldConfig<TKind extends FieldType> {\n type: TKind;\n ops: readonly OpsForFieldType<TKind>[];\n}\n\nexport interface CommonQueryConfigFromSchema<\n TSchema extends DataSchema,\n TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n dataSchema: TSchema;\n\n selectable?: readonly TSelectable[];\n sortable?: readonly AllowedPath<TSchema>[];\n\n filterable?: Partial<{\n [P in AllowedPath<TSchema>]: FilterableFieldConfig<\n FieldTypeFromValue<PathValue<InferData<TSchema>, P>>\n >;\n }>;\n\n defaultSortBy?: readonly { property: AllowedPath<TSchema>; direction: SortDirection }[];\n defaultLimit: number;\n\n defaultSelect: readonly TSelectable[] | '*';\n maxLimit: number;\n}\n\n/**\n * Full query config type, which includes pagination-specific properties depending on the pagination type.\n */\nexport type QueryConfigFromSchema<\n TSchema extends DataSchema,\n TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> = CommonQueryConfigFromSchema<TSchema, TSelectable> &\n (LimitOffsetPaginationConfig | CursorPaginationConfig<InferData<TSchema>>);\n\n/* ---------------------------------- */\n/* Runtime filterable map */\n/* ---------------------------------- */\n\ninterface FilterableRuntimeFieldConfig {\n type: FieldType;\n ops: readonly Operator[];\n}\n\nfunction toFilterableRuntime(\n filterable: Partial<Record<string, { type: FieldType; ops: readonly Operator[] }>> | undefined,\n): Record<string, FilterableRuntimeFieldConfig> {\n const out: Record<string, FilterableRuntimeFieldConfig> = {};\n if (!filterable) return out;\n\n for (const [k, v] of Object.entries(filterable)) {\n if (!v) continue;\n out[k] = { type: v.type, ops: [...v.ops] };\n }\n\n return out;\n}\n\nfunction computeLimit(limit: number | undefined, defaultLimit: number): number {\n if (typeof limit === 'number') return limit;\n return defaultLimit;\n}\n\n/* ---------------------------------- */\n/* Runtime value/type validation */\n/* ---------------------------------- */\n\nfunction isISODateString(v: unknown): boolean {\n if (typeof v !== 'string') return false;\n if (!(ISO_DATE_RE.test(v) || ISO_DATETIME_RE.test(v))) return false;\n return !Number.isNaN(Date.parse(v));\n}\n\nfunction isFiniteNumber(v: unknown): boolean {\n return typeof v === 'number' && Number.isFinite(v);\n}\n\nfunction validateConditionType(expected: FieldType, cond: Condition, field: string): string | null {\n if (expected === 'any') return null;\n if (cond.op === '$null') return null;\n\n if (cond.op === '$eq') {\n if (expected === 'number' && !isFiniteNumber(cond.value))\n return `Field \"${field}\" expects a number for \"$eq\"`;\n if (expected === 'date' && !isISODateString(cond.value))\n return `Field \"${field}\" expects an ISO date for \"$eq\"`;\n if (expected === 'string' && typeof cond.value !== 'string')\n return `Field \"${field}\" expects a string for \"$eq\"`;\n return null;\n }\n\n if (cond.op === '$ilike' || cond.op === '$sw') {\n if (expected !== 'string')\n return `Field \"${field}\" does not support \"${cond.op}\" (configured as ${expected})`;\n return null;\n }\n\n if (cond.op === '$in' || cond.op === '$contains') return null;\n\n if (cond.op === '$gt' || cond.op === '$gte' || cond.op === '$lt' || cond.op === '$lte') {\n if (expected === 'string')\n return `Field \"${field}\" does not support \"${cond.op}\" (configured as string)`;\n if (expected === 'number' && !isFiniteNumber(cond.value))\n return `Field \"${field}\" expects number for \"${cond.op}\"`;\n if (expected === 'date' && !isISODateString(cond.value))\n return `Field \"${field}\" expects ISO date for \"${cond.op}\"`;\n return null;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (cond.op === '$btw') {\n const [a, b] = cond.value;\n if (expected === 'string')\n return `Field \"${field}\" does not support \"$btw\" (configured as string)`;\n if (expected === 'number' && (!isFiniteNumber(a) || !isFiniteNumber(b)))\n return `Field \"${field}\" expects numbers for \"$btw\"`;\n if (expected === 'date' && (!isISODateString(a) || !isISODateString(b)))\n return `Field \"${field}\" expects ISO dates for \"$btw\"`;\n return null;\n }\n\n return null;\n}\n\n/* ---------------------------------- */\n/* Sort defaults */\n/* ---------------------------------- */\n\nexport interface SortItemTyped<TSchema extends DataSchema> {\n property: AllowedPath<TSchema>;\n direction: SortDirection;\n}\n\nfunction computeSortBy<TSchema extends DataSchema>(\n sortByRaw: string[] | undefined,\n config: Pick<CommonQueryConfigFromSchema<TSchema>, 'sortable' | 'defaultSortBy'>,\n): SortItemTyped<TSchema>[] | undefined {\n if (sortByRaw) {\n const cleaned = sortByRaw.map((s) => s.trim()).filter(Boolean);\n if (cleaned.length > 0) {\n const out: SortItemTyped<TSchema>[] = [];\n for (const raw of cleaned) {\n const parsed = parseSortItem(raw);\n\n const picked = pickFromAllowlist(config.sortable, parsed.property);\n if (!picked) continue;\n\n out.push({ property: picked, direction: parsed.direction });\n }\n return out.length > 0 ? out : undefined;\n }\n }\n\n if (config.defaultSortBy && config.defaultSortBy.length > 0) {\n return config.defaultSortBy.map((x) => ({ property: x.property, direction: x.direction }));\n }\n\n return undefined;\n}\n\n/* ---------------------------------- */\n/* QueryParams output (generic) */\n/* ---------------------------------- */\n\nexport interface LimitOffsetPaginationPayload<TSchema extends DataSchema> {\n type: 'LIMIT_OFFSET';\n limit: number;\n page?: number;\n sortBy?: SortItemTyped<TSchema>[];\n select?: AllowedPath<TSchema>[];\n filters?: WhereNode;\n}\n\n/**\n * Cursor is always a string in the query input, BUT we coerce it at parse-time\n * to match the type of cursorProperty (number / string / ISO date string).\n */\nexport interface CursorPaginationPayload<TSchema extends DataSchema> {\n type: 'CURSOR';\n limit: number;\n cursor?: number | string;\n cursorProperty: AllowedPath<TSchema>;\n sortBy?: SortItemTyped<TSchema>[];\n select?: AllowedPath<TSchema>[];\n filters?: WhereNode;\n}\n\nexport type PaginationType = 'LIMIT_OFFSET' | 'CURSOR';\n\nexport type PaginationPayload<\n TSchema extends DataSchema,\n TType extends PaginationType = PaginationType,\n> = TType extends 'LIMIT_OFFSET'\n ? LimitOffsetPaginationPayload<TSchema>\n : TType extends 'CURSOR'\n ? CursorPaginationPayload<TSchema>\n : never;\n\nexport interface PaginationQueryParams<\n TSchema extends DataSchema,\n TType extends PaginationType = PaginationType,\n> {\n pagination: PaginationPayload<TSchema, TType>;\n}\n\n/* ---------------------------------- */\n/* Validator response types */\n/* ---------------------------------- */\n\nexport interface LimitOffsetPaginationResponseMeta {\n itemsPerPage: number;\n totalItems: number;\n currentPage: number;\n totalPages: number;\n sortBy?: { property: string; direction: SortDirection }[];\n filter?: WhereNode;\n}\n\nexport interface CursorPaginationResponseMeta {\n itemsPerPage: number;\n cursor: number | string | Date;\n sortBy?: { property: string; direction: SortDirection }[];\n filter?: WhereNode;\n}\n\nexport interface LimitOffsetPaginationResponse<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n data: ProjectedData<TSchema, TSelect>[];\n pagination: LimitOffsetPaginationResponseMeta;\n}\n\nexport interface CursorPaginationResponse<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n data: ProjectedData<TSchema, TSelect>[];\n pagination: CursorPaginationResponseMeta;\n}\n\nexport type PaginationResponse<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n TType extends PaginationType = PaginationType,\n> = TType extends 'LIMIT_OFFSET'\n ? LimitOffsetPaginationResponse<TSchema, TSelect>\n : TType extends 'CURSOR'\n ? CursorPaginationResponse<TSchema, TSelect>\n : never;\n\n/**\n * Result type returned by `paginate()`. Use this instead of\n * `ReturnType<typeof paginate>` to preserve the generic `TSchema`.\n *\n * @example\n * function createPaginator(): PaginateResult<typeof MySchema> {\n * return paginate({ dataSchema: MySchema, … });\n * }\n */\nexport interface PaginateResult<\n TSchema extends DataSchema,\n TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n TType extends PaginationType = PaginationType,\n> {\n queryParamsSchema: z.ZodType<PaginationQueryParams<TSchema, TType>>;\n validatorSchema: (\n parsed?: PaginationPayload<TSchema>,\n ) => z.ZodType<PaginationResponse<TSchema, TSelectable, TType>>;\n responseSchema: z.ZodType<PaginationResponse<TSchema, TSelectable, TType>>;\n}\n\nfunction callMethodIfReturnsZod(obj: unknown, methodName: string): z.ZodType | undefined {\n if (!isPlainObject(obj)) return undefined;\n\n const maybeFn = getOwnProp(obj, methodName);\n if (typeof maybeFn !== 'function') return undefined;\n\n const result = maybeFn.call(obj);\n if (isZodSchema(result)) return result;\n\n return undefined;\n}\n\nfunction getInnerSchemaFromDef(obj: unknown): z.ZodType | undefined {\n if (!isPlainObject(obj)) return undefined;\n\n const def = getOwnProp(obj, 'def') ?? getOwnProp(obj, '_def');\n if (!isPlainObject(def)) return undefined;\n\n const candidates = ['innerType', 'schema', 'type', 'in', 'out'];\n\n for (const key of candidates) {\n const v = getOwnProp(def, key);\n if (isZodSchema(v)) return v;\n }\n\n return undefined;\n}\n\nfunction unwrapSchema(schema: z.ZodType): z.ZodType {\n let current: unknown = schema;\n\n for (let i = 0; i < 30; i += 1) {\n const unwrapped = callMethodIfReturnsZod(current, 'unwrap');\n if (unwrapped) {\n current = unwrapped;\n continue;\n }\n\n const removedDefault = callMethodIfReturnsZod(current, 'removeDefault');\n if (removedDefault) {\n current = removedDefault;\n continue;\n }\n\n const innerType = callMethodIfReturnsZod(current, 'innerType');\n if (innerType) {\n current = innerType;\n continue;\n }\n\n const sourceType = callMethodIfReturnsZod(current, 'sourceType');\n if (sourceType) {\n current = sourceType;\n continue;\n }\n\n const innerFromDef = getInnerSchemaFromDef(current);\n if (innerFromDef) {\n current = innerFromDef;\n continue;\n }\n\n break;\n }\n\n if (isZodSchema(current)) return current;\n return schema;\n}\n\n/**\n * Robust constructor name getter that works with Zod objects (constructor is on the prototype).\n * No `as`, no unsafe casts.\n */\nfunction getConstructorName(v: unknown): string | undefined {\n if (typeof v !== 'object' || v === null) return undefined;\n\n const proto: unknown = Object.getPrototypeOf(v);\n if (typeof proto !== 'object' || proto === null) return undefined;\n\n const ctorUnknown: unknown = Reflect.get(proto, 'constructor');\n if (!(ctorUnknown instanceof Function)) return undefined;\n\n return ctorUnknown.name;\n}\n\n/* ---------------------------------- */\n/* Cursor: schema inference + coercion */\n/* ---------------------------------- */\n\n/**\n * Return the expected cursor schema for API responses:\n * - number field => cursor: number\n * - string field => cursor: string\n * - date field => cursor: ISO string OR Date (optional support)\n */\nfunction cursorSchemaFromProperty<TSchema extends DataSchema>(\n dataSchema: TSchema,\n cursorProperty: AllowedPath<TSchema>,\n): z.ZodType<number | string | Date> {\n const raw = getZodAtPath(dataSchema, `${cursorProperty}`);\n const s = unwrapSchema(raw);\n const ctorName = getConstructorName(s);\n\n if (ctorName === 'ZodNumber') return z.number();\n if (ctorName === 'ZodString') return z.string();\n if (ctorName === 'ZodDate') return z.union([z.string().refine(isISODateString), z.date()]);\n\n // Unsupported cursor field type\n return z.never();\n}\n\n/**\n * Coerce the query input cursor (always string) into the right type based on cursorProperty.\n * - number field => \"123\" -> 123\n * - string field => \"abc\" -> \"abc\"\n * - date field => \"2022-01-01\" -> \"2022-01-01\" (validated as ISO)\n */\nfunction coerceCursorFromProperty<TSchema extends DataSchema>(\n dataSchema: TSchema,\n cursorProperty: AllowedPath<TSchema>,\n rawCursor: string,\n): number | string {\n const schemaAtPath = unwrapSchema(getZodAtPath(dataSchema, `${cursorProperty}`));\n const ctorName = getConstructorName(schemaAtPath);\n\n if (ctorName === 'ZodNumber') {\n const s = rawCursor.trim();\n if (!/^[+-]?\\d+$/.test(s)) throw new Error(`cursor must be an integer string`);\n const n = Number(s);\n if (!Number.isFinite(n)) throw new Error(`cursor must be a finite number`);\n return n;\n }\n\n if (ctorName === 'ZodString') {\n return rawCursor;\n }\n\n if (ctorName === 'ZodDate') {\n const s = rawCursor.trim();\n if (!isISODateString(s)) throw new Error(`cursor must be an ISO date string`);\n return s;\n }\n\n throw new Error(`cursorProperty \"${cursorProperty}\" must be a string|number|date`);\n}\n\n/* ---------------------------------- */\n/* Factory */\n/* ---------------------------------- */\n\n/**\n * Generate Zod schemas and runtime validators for pagination query parameters, based on a config object.\n * @param config The configuration object defining the pagination behavior and allowed fields.\n * @returns An object containing:\n * - `queryParamsSchema`: A Zod schema for validating and parsing the raw query parameters.\n * - `validatorSchema`: A function that takes the already-parsed query parameters and returns a Zod schema for further validation (e.g. filters).\n * - `responseSchema`: A pre-built Zod schema for validating the response (uses defaultSelect or all selectable fields).\n */\nexport function paginate<\n TSchema extends DataSchema,\n const TSelectable extends readonly AllowedPath<TSchema>[],\n>(\n config: Omit<\n CommonQueryConfigFromSchema<TSchema, TSelectable[number]>,\n 'selectable' | 'defaultSelect' | 'sortable' | 'defaultSortBy' | 'filterable'\n > &\n LimitOffsetPaginationConfig & {\n selectable?: TSelectable;\n defaultSelect: readonly NoInfer<TSelectable[number]>[] | '*';\n sortable?: readonly NoInfer<TSelectable[number]>[];\n defaultSortBy?: readonly {\n property: NoInfer<TSelectable[number]>;\n direction: SortDirection;\n }[];\n filterable?: Partial<{\n [P in NoInfer<TSelectable[number]>]: FilterableFieldConfig<\n FieldTypeFromValue<PathValue<InferData<TSchema>, P>>\n >;\n }>;\n },\n): PaginateResult<TSchema, TSelectable[number], 'LIMIT_OFFSET'>;\n\nexport function paginate<\n TSchema extends DataSchema,\n const TSelectable extends readonly AllowedPath<TSchema>[],\n>(\n config: Omit<\n CommonQueryConfigFromSchema<TSchema, TSelectable[number]>,\n 'selectable' | 'defaultSelect' | 'sortable' | 'defaultSortBy' | 'filterable'\n > &\n CursorPaginationConfig<InferData<TSchema>> & {\n selectable?: TSelectable;\n defaultSelect: readonly NoInfer<TSelectable[number]>[] | '*';\n sortable?: readonly NoInfer<TSelectable[number]>[];\n defaultSortBy?: readonly {\n property: NoInfer<TSelectable[number]>;\n direction: SortDirection;\n }[];\n filterable?: Partial<{\n [P in NoInfer<TSelectable[number]>]: FilterableFieldConfig<\n FieldTypeFromValue<PathValue<InferData<TSchema>, P>>\n >;\n }>;\n },\n): PaginateResult<TSchema, TSelectable[number], 'CURSOR'>;\n\nexport function paginate<\n TSchema extends DataSchema,\n const TSelectable extends readonly AllowedPath<TSchema>[],\n>(\n config: Omit<\n CommonQueryConfigFromSchema<TSchema, TSelectable[number]>,\n 'selectable' | 'defaultSelect' | 'sortable' | 'defaultSortBy' | 'filterable'\n > & {\n selectable?: TSelectable;\n defaultSelect: readonly NoInfer<TSelectable[number]>[] | '*';\n sortable?: readonly NoInfer<TSelectable[number]>[];\n defaultSortBy?: readonly {\n property: NoInfer<TSelectable[number]>;\n direction: SortDirection;\n }[];\n filterable?: Partial<{\n [P in NoInfer<TSelectable[number]>]: FilterableFieldConfig<\n FieldTypeFromValue<PathValue<InferData<TSchema>, P>>\n >;\n }>;\n } & (LimitOffsetPaginationConfig | CursorPaginationConfig<InferData<TSchema>>),\n): PaginateResult<TSchema, TSelectable[number]>;\n\nexport function paginate<\n TSchema extends DataSchema,\n const TSelectable extends readonly AllowedPath<TSchema>[],\n>(\n config: Omit<\n CommonQueryConfigFromSchema<TSchema, TSelectable[number]>,\n 'selectable' | 'defaultSelect' | 'sortable' | 'defaultSortBy' | 'filterable'\n > & {\n selectable?: TSelectable;\n defaultSelect: readonly TSelectable[number][] | '*';\n sortable?: readonly TSelectable[number][];\n defaultSortBy?: readonly {\n property: TSelectable[number];\n direction: SortDirection;\n }[];\n filterable?: Partial<{\n [P in TSelectable[number]]: FilterableFieldConfig<\n FieldTypeFromValue<PathValue<InferData<TSchema>, P>>\n >;\n }>;\n } & (LimitOffsetPaginationConfig | CursorPaginationConfig<InferData<TSchema>>),\n): PaginateResult<TSchema, TSelectable[number]> {\n const allowedSelectable = new Set<string>();\n for (const f of config.selectable ?? []) allowedSelectable.add(`${f}`);\n\n const allowedSortable = new Set<string>();\n for (const f of config.sortable ?? []) allowedSortable.add(`${f}`);\n\n const filterable = toFilterableRuntime(config.filterable);\n\n const baseSchema = z.object({\n limit: NumericStringSchema.optional(),\n page: NumericStringSchema.optional(),\n\n /**\n * Query input is always a string if present.\n * We will coerce it later in the final transform (CURSOR mode only).\n */\n cursor: z.string().min(1).optional(),\n\n sortBy: StringOrStringArraySchema.optional(),\n select: SelectSchema.optional(),\n\n rawFilters: z.record(z.string(), z.array(ConditionSchema)),\n groupDefs: z.record(\n z.string(),\n z.object({\n parent: IntegerStringSchema.optional(),\n join: CombinatorSchema.optional(),\n op: CombinatorSchema.optional(),\n }),\n ),\n });\n\n const queryParamsSchema: z.ZodType<PaginationQueryParams<TSchema>> = z\n .record(z.string(), z.unknown())\n .transform(\n (\n q,\n ): Record<string, unknown> & {\n rawFilters: Record<string, Condition[]>;\n groupDefs: GroupDefs;\n } => {\n const qs = toQueryStringRecord(q);\n\n return {\n ...q,\n rawFilters: extractAndNormalizeRawFilters(qs),\n groupDefs: extractGroupDefs(q),\n };\n },\n )\n .pipe(\n baseSchema\n .superRefine((val, ctx): void => {\n // Pagination mode constraints\n if (config.paginationType === 'LIMIT_OFFSET') {\n if (val.cursor !== undefined) {\n ctx.addIssue({\n code: 'custom',\n path: ['cursor'],\n message: `cursor is not allowed when paginationType is LIMIT_OFFSET`,\n });\n }\n }\n\n if (config.paginationType === 'CURSOR') {\n if (val.page !== undefined) {\n ctx.addIssue({\n code: 'custom',\n path: ['page'],\n message: `page is not allowed when paginationType is CURSOR`,\n });\n }\n\n if (`${config.cursorProperty}`.trim().length === 0) {\n ctx.addIssue({\n code: 'custom',\n path: [],\n message: `cursorProperty must be a non-empty string when paginationType is CURSOR`,\n });\n }\n\n // Validate that cursor (if provided) can be coerced for that cursorProperty\n if (val.cursor !== undefined) {\n try {\n void coerceCursorFromProperty(config.dataSchema, config.cursorProperty, val.cursor);\n } catch (e) {\n const message = e instanceof Error ? e.message : 'Invalid cursor';\n ctx.addIssue({\n code: 'custom',\n path: ['cursor'],\n message,\n });\n }\n }\n }\n\n // limit / maxLimit\n if (typeof val.limit === 'number' && val.limit > config.maxLimit) {\n ctx.addIssue({\n code: 'custom',\n path: ['limit'],\n message: `limit must be <= ${config.maxLimit}`,\n });\n }\n\n // select forbidden if no selectable configured\n if (val.select && (!config.selectable || config.selectable.length === 0)) {\n ctx.addIssue({\n code: 'custom',\n path: ['select'],\n message: `select is not allowed (no selectable fields configured)`,\n });\n }\n\n // select allowlist + \"*\" expandability\n const selectForValidation =\n val.select ??\n (config.defaultSelect === '*' ? ['*'] : config.defaultSelect.map((x) => `${x}`));\n\n {\n let index = 0;\n\n for (const field of selectForValidation) {\n if (field === '*') {\n index += 1;\n continue;\n }\n\n if (allowedSelectable.size > 0 && !allowedSelectable.has(field)) {\n ctx.addIssue({\n code: 'custom',\n path: ['select', index],\n message: `select field \"${field}\" is not allowed`,\n });\n }\n\n index += 1;\n }\n\n if (selectForValidation.includes('*')) {\n const expanded = expandSelect(selectForValidation, config);\n if (!expanded || expanded.length === 0) {\n ctx.addIssue({\n code: 'custom',\n path: ['select'],\n message: `select \"*\" cannot be expanded (missing selectable in config)`,\n });\n }\n }\n }\n\n // sort allowlist\n const sortItems = computeSortBy(val.sortBy, config);\n if (val.sortBy) {\n if (!config.sortable || config.sortable.length === 0) {\n ctx.addIssue({\n code: 'custom',\n path: ['sortBy'],\n message: `sortBy is not allowed (no sortable fields configured)`,\n });\n } else if (sortItems) {\n let index = 0;\n for (const item of sortItems) {\n if (!allowedSortable.has(item.property)) {\n ctx.addIssue({\n code: 'custom',\n path: ['sortBy', index],\n message: `sort property \"${item.property}\" is not allowed`,\n });\n }\n index += 1;\n }\n }\n }\n\n // filter allowlist + operator/type validation\n for (const [field, conditions] of Object.entries(val.rawFilters)) {\n const cfg = filterable[field];\n\n if (!cfg) {\n ctx.addIssue({\n code: 'custom',\n path: ['rawFilters', field],\n message: `filter field \"${field}\" is not allowed`,\n });\n continue;\n }\n\n const allowedOps = new Set(cfg.ops);\n\n let index = 0;\n for (const cond of conditions) {\n if (!allowedOps.has(cond.op)) {\n ctx.addIssue({\n code: 'custom',\n path: ['rawFilters', field, index, 'op'],\n message: `operator \"${cond.op}\" is not allowed for \"${field}\"`,\n });\n }\n\n const typeError = validateConditionType(cfg.type, cond, field);\n if (typeError) {\n ctx.addIssue({\n code: 'custom',\n path: ['rawFilters', field, index],\n message: typeError,\n });\n }\n\n index += 1;\n }\n }\n\n // group consistency\n const hasAnyFilter = Object.keys(val.rawFilters).length > 0;\n const hasAnyGroupDef = Object.keys(val.groupDefs).length > 0;\n\n if (hasAnyGroupDef && !hasAnyFilter) {\n ctx.addIssue({\n code: 'custom',\n path: ['groupDefs'],\n message: `group.* is not allowed without any filter.*`,\n });\n } else if (hasAnyFilter) {\n try {\n void buildWhereAstWithGroups(val.rawFilters, val.groupDefs);\n } catch (e) {\n const message = e instanceof Error ? e.message : 'Invalid group configuration';\n ctx.addIssue({\n code: 'custom',\n path: ['groupDefs'],\n message,\n });\n }\n }\n })\n .transform((val): PaginationQueryParams<TSchema> => {\n const limit = computeLimit(val.limit, config.defaultLimit);\n const sortBy = computeSortBy(val.sortBy, config);\n const select = computeSelect(val.select, config);\n\n const hasAnyFilter = Object.keys(val.rawFilters).length > 0;\n\n const maybeFilters = hasAnyFilter\n ? { filters: buildWhereAstWithGroups(val.rawFilters, val.groupDefs) }\n : {};\n\n if (config.paginationType === 'LIMIT_OFFSET') {\n return {\n pagination: {\n type: 'LIMIT_OFFSET',\n limit,\n page: val.page,\n sortBy,\n select,\n ...maybeFilters,\n },\n };\n }\n\n // CURSOR: coerce string cursor into number/string based on cursorProperty\n let cursor: number | string | undefined = undefined;\n if (val.cursor !== undefined) {\n cursor = coerceCursorFromProperty(config.dataSchema, config.cursorProperty, val.cursor);\n }\n\n return {\n pagination: {\n type: 'CURSOR',\n limit,\n cursor,\n cursorProperty: config.cursorProperty,\n sortBy,\n select,\n ...maybeFilters,\n },\n };\n }),\n );\n\n const validatorSchema = (\n parsed?: PaginationPayload<TSchema>,\n ): z.ZodType<PaginationResponse<TSchema, TSelectable[number]>> => {\n const effectiveSelect = parsed?.select ?? computeSelect(undefined, config) ?? undefined;\n\n const dataItemSchema =\n effectiveSelect && effectiveSelect.length > 0\n ? projectDataSchema(\n config.dataSchema,\n effectiveSelect.map((x) => `${x}`),\n )\n : config.dataSchema;\n\n const dataArraySchema = z.array(dataItemSchema);\n\n if (config.paginationType === 'LIMIT_OFFSET') {\n return z.object({\n data: dataArraySchema,\n pagination: z.object({\n itemsPerPage: z.number(),\n totalItems: z.number(),\n currentPage: z.number(),\n totalPages: z.number(),\n sortBy: z\n .array(\n z.object({\n property: z.string(),\n direction: SortDirectionSchema,\n }),\n )\n .optional(),\n filter: WhereNodeSchema.optional(),\n }),\n });\n }\n\n const cursorType = cursorSchemaFromProperty(config.dataSchema, config.cursorProperty);\n\n return z.object({\n data: dataArraySchema,\n pagination: z.object({\n itemsPerPage: z.number(),\n cursor: cursorType,\n sortBy: z\n .array(\n z.object({\n property: z.string(),\n direction: SortDirectionSchema,\n }),\n )\n .optional(),\n filter: WhereNodeSchema.optional(),\n }),\n });\n };\n\n const responseSchema = validatorSchema();\n\n return { queryParamsSchema, validatorSchema, responseSchema };\n}\n"]}
package/dist/select.d.ts CHANGED
@@ -33,7 +33,7 @@ export type AllowedPath<TSchema extends DataSchema> = Path<InferData<TSchema>>;
33
33
  export declare const SelectSchema: z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>;
34
34
  export interface SelectableConfig<TSchema extends DataSchema, TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>> {
35
35
  selectable?: readonly TSelect[];
36
- defaultSelect?: readonly (TSelect | '*')[];
36
+ defaultSelect: readonly TSelect[] | '*';
37
37
  }
38
38
  /**
39
39
  * Find a typed AllowedPath value from a string, by matching against a typed allowlist.
@@ -52,7 +52,7 @@ export declare function projectDataSchema(dataSchema: z.ZodObject<z.ZodRawShape>
52
52
  export interface SelectConfig<TSchema extends DataSchema, TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>> {
53
53
  dataSchema: TSchema;
54
54
  selectable: readonly TSelect[];
55
- defaultSelect?: readonly (TSelect | '*')[];
55
+ defaultSelect: readonly TSelect[] | '*';
56
56
  }
57
57
  /**
58
58
  * Extract the top-level key from a dot-path.
@@ -93,5 +93,8 @@ export interface SelectResult<TSchema extends DataSchema, TSelectable extends Al
93
93
  * - `validatorSchema`: A function that takes the already-parsed query parameters and returns a Zod schema for validating the response.
94
94
  * - `responseSchema`: A pre-built Zod schema for validating the response (uses defaultSelect or all selectable fields).
95
95
  */
96
- export declare function select<TSchema extends DataSchema, const TSelectable extends readonly AllowedPath<TSchema>[]>(config: SelectConfig<TSchema, TSelectable[number]>): SelectResult<TSchema, TSelectable[number]>;
96
+ export declare function select<TSchema extends DataSchema, const TSelectable extends readonly AllowedPath<TSchema>[]>(config: Omit<SelectConfig<TSchema, TSelectable[number]>, 'selectable' | 'defaultSelect'> & {
97
+ selectable: TSelectable;
98
+ defaultSelect: readonly NoInfer<TSelectable[number]>[] | '*';
99
+ }): SelectResult<TSchema, TSelectable[number]>;
97
100
  export {};
package/dist/select.js CHANGED
@@ -67,13 +67,11 @@ function computeSelect(select, config) {
67
67
  return undefined;
68
68
  return [...expanded];
69
69
  }
70
- if (config.defaultSelect) {
71
- const expanded = expandSelect(config.defaultSelect.map((x) => `${x}`), config);
72
- if (!expanded)
73
- return undefined;
74
- return [...expanded];
75
- }
76
- return undefined;
70
+ const defaultSelectArr = config.defaultSelect === '*' ? ['*'] : [...config.defaultSelect];
71
+ const expanded = expandSelect(defaultSelectArr, config);
72
+ if (!expanded)
73
+ return undefined;
74
+ return [...expanded];
77
75
  }
78
76
  function isPlainObject(v) {
79
77
  return typeof v === 'object' && v !== null && !Array.isArray(v);
@@ -204,16 +202,7 @@ function select(config) {
204
202
  })
205
203
  .pipe(baseSchema
206
204
  .superRefine((val, ctx) => {
207
- const selectForValidation = val.select ??
208
- (config.defaultSelect ? config.defaultSelect.map((x) => `${x}`) : undefined);
209
- if (!selectForValidation) {
210
- ctx.addIssue({
211
- code: 'custom',
212
- path: ['select'],
213
- message: 'select is required (no defaultSelect configured)',
214
- });
215
- return;
216
- }
205
+ const selectForValidation = val.select ?? (config.defaultSelect === '*' ? ['*'] : [...config.defaultSelect]);
217
206
  let index = 0;
218
207
  for (const field of selectForValidation) {
219
208
  if (field === '*') {
@@ -250,7 +239,7 @@ function select(config) {
250
239
  const validatorSchema = (parsed) => {
251
240
  const effectiveSelect = parsed?.select ?? computeSelect(undefined, config) ?? undefined;
252
241
  const dataItemSchema = effectiveSelect && effectiveSelect.length > 0
253
- ? projectDataSchema(config.dataSchema, effectiveSelect.map((x) => `${x}`))
242
+ ? projectDataSchema(config.dataSchema, effectiveSelect.map((x) => x))
254
243
  : config.dataSchema;
255
244
  return zod_1.z.object({
256
245
  data: zod_1.z.array(dataItemSchema),
@@ -1 +1 @@
1
- {"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\n\n/* ---------------------------------- */\n/* Typed field paths (dot notation) */\n/* ---------------------------------- */\n\n/**\n * Primitive types that we consider as leaves in the Path type. Arrays are also considered leaves, since we don't want to generate paths like \"arrayField.0.someProp\".\n */\ntype Primitive = string | number | boolean | bigint | symbol | null | undefined | Date;\n\n/**\n * Join two path segments K and P with a dot, if both are strings. Otherwise, return never.\n */\ntype Join<K, P> = K extends string ? (P extends string ? `${K}.${P}` : never) : never;\n\n/**\n * Generate dot notation paths for a given type T, up to a certain depth D (default 5).\n * For example, for { a: { b: string }, c: number }, we would generate \"a\", \"a.b\", and \"c\". We stop recursion at depth 0 to prevent infinite types.\n */\ntype Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n\n/**\n * Generate dot notation paths for a given type T. For example, for { a: { b: string }, c: number }, we would generate \"a\", \"a.b\", and \"c\".\n */\nexport type Path<T, D extends number = 5> = D extends 0\n ? never\n : T extends Primitive\n ? never\n : T extends readonly unknown[]\n ? never\n : {\n [K in Extract<keyof T, string>]: T[K] extends Primitive | readonly unknown[]\n ? K\n : K | Join<K, Path<T[K], Prev[D]>>;\n }[Extract<keyof T, string>];\n\n/**\n * Given a type T and a dot notation path P, resolve the type at that path.\n * For example, for T = { a: { b: string }, c: number } and P = \"a.b\", we would get string.\n */\nexport type PathValue<T, P extends string> = P extends `${infer K}.${infer Rest}`\n ? K extends keyof T\n ? PathValue<T[K], Rest>\n : never\n : P extends keyof T\n ? T[P]\n : never;\n\n/* ---------------------------------- */\n/* Schema types */\n/* ---------------------------------- */\n\nexport type DataSchema = z.ZodObject<z.ZodRawShape>;\nexport type InferData<TSchema extends DataSchema> = z.infer<TSchema>;\nexport type AllowedPath<TSchema extends DataSchema> = Path<InferData<TSchema>>;\n\n/* ---------------------------------- */\n/* Select schema */\n/* ---------------------------------- */\n\n/**\n * Zod schema for the \"select\" parameter, which can be a comma-separated string.\n * It normalizes the output to an array of strings.\n */\nexport const SelectSchema = z\n .string()\n .transform((s) =>\n s\n .split(',')\n .map((x) => x.trim())\n .filter(Boolean),\n )\n .refine((arr) => arr.length > 0, { message: 'select cannot be empty' });\n\n/* ---------------------------------- */\n/* Select config (shared) */\n/* ---------------------------------- */\n\nexport interface SelectableConfig<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n selectable?: readonly TSelect[];\n defaultSelect?: readonly (TSelect | '*')[];\n}\n\n/* ---------------------------------- */\n/* Allowlist helpers */\n/* ---------------------------------- */\n\n/**\n * Find a typed AllowedPath value from a string, by matching against a typed allowlist.\n * This avoids `as`: we return the existing typed value.\n */\nexport function pickFromAllowlist<T extends string>(\n allowlist: readonly T[] | undefined,\n value: string,\n): T | undefined {\n if (!allowlist) return undefined;\n for (const item of allowlist) {\n if (item === value) return item;\n }\n return undefined;\n}\n\n/** Expand \"*\" to selectable; otherwise map through allowlist. */\nexport function expandSelect<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n>(\n select: readonly string[] | undefined,\n config: SelectableConfig<TSchema, TSelect>,\n): readonly TSelect[] | undefined {\n if (!select) return undefined;\n\n if (!select.includes('*')) {\n if (!config.selectable || config.selectable.length === 0) return undefined;\n\n const out: TSelect[] = [];\n for (const field of select) {\n const picked = pickFromAllowlist(config.selectable, field);\n if (picked) out.push(picked);\n }\n return out;\n }\n\n if (config.selectable && config.selectable.length > 0) return [...config.selectable];\n return undefined;\n}\n\nexport function computeSelect<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n>(select: string[] | undefined, config: SelectableConfig<TSchema, TSelect>): TSelect[] | undefined {\n if (select) {\n const expanded = expandSelect(select, config);\n if (!expanded) return undefined;\n return [...expanded];\n }\n\n if (config.defaultSelect) {\n const expanded = expandSelect(\n config.defaultSelect.map((x) => `${x}`),\n config,\n );\n if (!expanded) return undefined;\n return [...expanded];\n }\n\n return undefined;\n}\n\n/* ---------------------------------- */\n/* Projection helpers (NO \"as\") */\n/* ---------------------------------- */\n\ntype MutableShape = Record<string, z.ZodType>;\n\nexport function isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nexport function getOwnProp(obj: Record<string, unknown>, key: string): unknown {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) return undefined;\n return obj[key];\n}\n\n/** Duck-typed Zod schema check. */\nexport function isZodSchema(v: unknown): v is z.ZodType {\n if (!isPlainObject(v)) return false;\n const parseFn = getOwnProp(v, 'parse');\n return typeof parseFn === 'function';\n}\n\n/** Duck-typed ZodObject check. */\nfunction isZodObjectSchema(v: unknown): v is z.ZodObject<z.ZodRawShape> {\n if (!isPlainObject(v)) return false;\n const parseFn = getOwnProp(v, 'parse');\n if (typeof parseFn !== 'function') return false;\n const shape = getOwnProp(v, 'shape');\n return isPlainObject(shape);\n}\n\nfunction getObjectShape(obj: z.ZodObject<z.ZodRawShape>): Readonly<Record<string, unknown>> {\n return obj.shape;\n}\n\nexport function getZodAtPath(obj: z.ZodObject<z.ZodRawShape>, path: string): z.ZodType {\n const parts = path.split('.').filter(Boolean);\n\n let current: unknown = obj;\n\n for (const p of parts) {\n if (!isZodObjectSchema(current)) {\n throw new Error(`dataSchema path \"${path}\" is invalid: \"${p}\" is not inside a ZodObject`);\n }\n\n const shape = getObjectShape(current);\n const next = shape[p];\n\n if (!next) throw new Error(`dataSchema path \"${path}\" is invalid: missing key \"${p}\"`);\n if (!isZodSchema(next)) {\n throw new Error(`dataSchema path \"${path}\" is invalid: \"${p}\" is not a Zod schema`);\n }\n\n current = next;\n }\n\n if (!isZodSchema(current)) {\n throw new Error(`dataSchema path \"${path}\" is invalid: resolved value is not a Zod schema`);\n }\n\n return current;\n}\n\nexport function projectDataSchema(\n dataSchema: z.ZodObject<z.ZodRawShape>,\n selectedPaths: string[],\n): z.ZodObject<z.ZodRawShape> {\n const tree: Record<string, unknown> = {};\n\n const ensureTreeNode = (node: Record<string, unknown>, key: string): Record<string, unknown> => {\n const existing = node[key];\n\n if (existing === undefined) {\n const child: Record<string, unknown> = {};\n node[key] = child;\n return child;\n }\n\n if (isPlainObject(existing)) return existing;\n\n if (isZodSchema(existing)) {\n throw new Error(`Cannot project \"${key}\": \"${key}\" is selected as a leaf and as an object`);\n }\n\n throw new Error(`Cannot project \"${key}\": conflicting selection`);\n };\n\n for (const fullPath of selectedPaths) {\n const parts = fullPath.split('.').filter(Boolean);\n if (parts.length === 0) continue;\n\n let cursor = tree;\n\n for (let i = 0; i < parts.length; i += 1) {\n const key = parts[i];\n if (!key) continue;\n\n const isLeaf = i === parts.length - 1;\n\n if (isLeaf) {\n cursor[key] = getZodAtPath(dataSchema, fullPath);\n } else {\n cursor = ensureTreeNode(cursor, key);\n }\n }\n }\n\n const buildObjectFromTree = (node: Record<string, unknown>): z.ZodObject<z.ZodRawShape> => {\n const shape: MutableShape = {};\n\n for (const [k, v] of Object.entries(node)) {\n if (isZodSchema(v)) {\n shape[k] = v;\n continue;\n }\n if (isPlainObject(v)) {\n shape[k] = buildObjectFromTree(v);\n continue;\n }\n throw new Error(`Invalid projection tree at \"${k}\"`);\n }\n\n return z.object(shape);\n };\n\n return buildObjectFromTree(tree);\n}\n\n/* ---------------------------------- */\n/* Config */\n/* ---------------------------------- */\n\nexport interface SelectConfig<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n dataSchema: TSchema;\n selectable: readonly TSelect[];\n defaultSelect?: readonly (TSelect | '*')[];\n}\n\n/* ---------------------------------- */\n/* Output */\n/* ---------------------------------- */\n\n/**\n * Extract the top-level key from a dot-path.\n * e.g. `'meta.score'` → `'meta'`, `'id'` → `'id'`.\n */\nexport type TopLevelKey<P extends string> = P extends `${infer K}.${string}` ? K : P;\n\n/**\n * Projected data item: exposes only the selectable keys of the original schema\n * with `unknown` values. This gives consumers key auto-completion\n * without requiring `as` (projectDataSchema erases value types at runtime).\n */\nexport type ProjectedData<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> = Partial<Record<TopLevelKey<TSelect> & keyof InferData<TSchema>, unknown>>;\n\nexport interface SelectQueryParams<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n select: TSelect[];\n}\n\nexport interface SelectResponse<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n data: ProjectedData<TSchema, TSelect>[];\n}\n\n/**\n * Result type returned by `select()`. Use this instead of\n * `ReturnType<typeof select>` to preserve the generic `TSchema`.\n *\n * @example\n * function createSelector(): SelectResult<typeof MySchema> {\n * return select({ dataSchema: MySchema, … });\n * }\n */\nexport interface SelectResult<\n TSchema extends DataSchema,\n TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n queryParamsSchema: z.ZodType<SelectQueryParams<TSchema, TSelectable>>;\n validatorSchema: (\n parsed?: SelectQueryParams<TSchema, TSelectable>,\n ) => z.ZodType<SelectResponse<TSchema, TSelectable>>;\n responseSchema: z.ZodType<SelectResponse<TSchema, TSelectable>>;\n}\n\n/* ---------------------------------- */\n/* Factory */\n/* ---------------------------------- */\n\n/**\n * Generate Zod schemas and runtime validators for select-only query parameters, based on a config object.\n * @param config The configuration object defining the selectable fields.\n * @returns An object containing:\n * - `queryParamsSchema`: A Zod schema for validating and parsing the raw query parameters.\n * - `validatorSchema`: A function that takes the already-parsed query parameters and returns a Zod schema for validating the response.\n * - `responseSchema`: A pre-built Zod schema for validating the response (uses defaultSelect or all selectable fields).\n */\nexport function select<\n TSchema extends DataSchema,\n const TSelectable extends readonly AllowedPath<TSchema>[],\n>(config: SelectConfig<TSchema, TSelectable[number]>): SelectResult<TSchema, TSelectable[number]> {\n const allowedSelectable = new Set<string>();\n for (const f of config.selectable) allowedSelectable.add(`${f}`);\n\n const baseSchema = z.object({\n select: SelectSchema.optional(),\n });\n\n const queryParamsSchema: z.ZodType<SelectQueryParams<TSchema, TSelectable[number]>> = z\n .record(z.string(), z.unknown())\n .transform((q): Record<string, unknown> => {\n const raw = q.select;\n return {\n ...q,\n select: typeof raw === 'string' ? raw : undefined,\n };\n })\n .pipe(\n baseSchema\n .superRefine((val, ctx): void => {\n const selectForValidation =\n val.select ??\n (config.defaultSelect ? config.defaultSelect.map((x) => `${x}`) : undefined);\n\n if (!selectForValidation) {\n ctx.addIssue({\n code: 'custom',\n path: ['select'],\n message: 'select is required (no defaultSelect configured)',\n });\n return;\n }\n\n let index = 0;\n for (const field of selectForValidation) {\n if (field === '*') {\n index += 1;\n continue;\n }\n\n if (!allowedSelectable.has(field)) {\n ctx.addIssue({\n code: 'custom',\n path: ['select', index],\n message: `select field \"${field}\" is not allowed`,\n });\n }\n\n index += 1;\n }\n\n if (selectForValidation.includes('*')) {\n const expanded = expandSelect(selectForValidation, config);\n if (!expanded || expanded.length === 0) {\n ctx.addIssue({\n code: 'custom',\n path: ['select'],\n message: 'select \"*\" cannot be expanded (empty selectable)',\n });\n }\n }\n })\n .transform((val): SelectQueryParams<TSchema, TSelectable[number]> => {\n const resolved = computeSelect(val.select, config);\n\n if (!resolved || resolved.length === 0) {\n throw new Error('select resolved to empty (this should not happen after validation)');\n }\n\n return { select: resolved };\n }),\n );\n\n const validatorSchema = (\n parsed?: SelectQueryParams<TSchema, TSelectable[number]>,\n ): z.ZodType<SelectResponse<TSchema, TSelectable[number]>> => {\n const effectiveSelect = parsed?.select ?? computeSelect(undefined, config) ?? undefined;\n\n const dataItemSchema =\n effectiveSelect && effectiveSelect.length > 0\n ? projectDataSchema(\n config.dataSchema,\n effectiveSelect.map((x) => `${x}`),\n )\n : config.dataSchema;\n\n return z.object({\n data: z.array(dataItemSchema),\n });\n };\n\n const responseSchema = validatorSchema();\n\n return { queryParamsSchema, validatorSchema, responseSchema };\n}\n"]}
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\n\n/* ---------------------------------- */\n/* Typed field paths (dot notation) */\n/* ---------------------------------- */\n\n/**\n * Primitive types that we consider as leaves in the Path type. Arrays are also considered leaves, since we don't want to generate paths like \"arrayField.0.someProp\".\n */\ntype Primitive = string | number | boolean | bigint | symbol | null | undefined | Date;\n\n/**\n * Join two path segments K and P with a dot, if both are strings. Otherwise, return never.\n */\ntype Join<K, P> = K extends string ? (P extends string ? `${K}.${P}` : never) : never;\n\n/**\n * Generate dot notation paths for a given type T, up to a certain depth D (default 5).\n * For example, for { a: { b: string }, c: number }, we would generate \"a\", \"a.b\", and \"c\". We stop recursion at depth 0 to prevent infinite types.\n */\ntype Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\n\n/**\n * Generate dot notation paths for a given type T. For example, for { a: { b: string }, c: number }, we would generate \"a\", \"a.b\", and \"c\".\n */\nexport type Path<T, D extends number = 5> = D extends 0\n ? never\n : T extends Primitive\n ? never\n : T extends readonly unknown[]\n ? never\n : {\n [K in Extract<keyof T, string>]: T[K] extends Primitive | readonly unknown[]\n ? K\n : K | Join<K, Path<T[K], Prev[D]>>;\n }[Extract<keyof T, string>];\n\n/**\n * Given a type T and a dot notation path P, resolve the type at that path.\n * For example, for T = { a: { b: string }, c: number } and P = \"a.b\", we would get string.\n */\nexport type PathValue<T, P extends string> = P extends `${infer K}.${infer Rest}`\n ? K extends keyof T\n ? PathValue<T[K], Rest>\n : never\n : P extends keyof T\n ? T[P]\n : never;\n\n/* ---------------------------------- */\n/* Schema types */\n/* ---------------------------------- */\n\nexport type DataSchema = z.ZodObject<z.ZodRawShape>;\nexport type InferData<TSchema extends DataSchema> = z.infer<TSchema>;\nexport type AllowedPath<TSchema extends DataSchema> = Path<InferData<TSchema>>;\n\n/* ---------------------------------- */\n/* Select schema */\n/* ---------------------------------- */\n\n/**\n * Zod schema for the \"select\" parameter, which can be a comma-separated string.\n * It normalizes the output to an array of strings.\n */\nexport const SelectSchema = z\n .string()\n .transform((s) =>\n s\n .split(',')\n .map((x) => x.trim())\n .filter(Boolean),\n )\n .refine((arr) => arr.length > 0, { message: 'select cannot be empty' });\n\n/* ---------------------------------- */\n/* Select config (shared) */\n/* ---------------------------------- */\n\nexport interface SelectableConfig<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n selectable?: readonly TSelect[];\n defaultSelect: readonly TSelect[] | '*';\n}\n\n/* ---------------------------------- */\n/* Allowlist helpers */\n/* ---------------------------------- */\n\n/**\n * Find a typed AllowedPath value from a string, by matching against a typed allowlist.\n * This avoids `as`: we return the existing typed value.\n */\nexport function pickFromAllowlist<T extends string>(\n allowlist: readonly T[] | undefined,\n value: string,\n): T | undefined {\n if (!allowlist) return undefined;\n for (const item of allowlist) {\n if (item === value) return item;\n }\n return undefined;\n}\n\n/** Expand \"*\" to selectable; otherwise map through allowlist. */\nexport function expandSelect<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n>(\n select: readonly string[] | undefined,\n config: SelectableConfig<TSchema, TSelect>,\n): readonly TSelect[] | undefined {\n if (!select) return undefined;\n\n if (!select.includes('*')) {\n if (!config.selectable || config.selectable.length === 0) return undefined;\n\n const out: TSelect[] = [];\n for (const field of select) {\n const picked = pickFromAllowlist(config.selectable, field);\n if (picked) out.push(picked);\n }\n return out;\n }\n\n if (config.selectable && config.selectable.length > 0) return [...config.selectable];\n return undefined;\n}\n\nexport function computeSelect<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n>(select: string[] | undefined, config: SelectableConfig<TSchema, TSelect>): TSelect[] | undefined {\n if (select) {\n const expanded = expandSelect(select, config);\n if (!expanded) return undefined;\n return [...expanded];\n }\n\n const defaultSelectArr = config.defaultSelect === '*' ? ['*'] : [...config.defaultSelect];\n const expanded = expandSelect(defaultSelectArr, config);\n if (!expanded) return undefined;\n return [...expanded];\n}\n\n/* ---------------------------------- */\n/* Projection helpers (NO \"as\") */\n/* ---------------------------------- */\n\ntype MutableShape = Record<string, z.ZodType>;\n\nexport function isPlainObject(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\nexport function getOwnProp(obj: Record<string, unknown>, key: string): unknown {\n if (!Object.prototype.hasOwnProperty.call(obj, key)) return undefined;\n return obj[key];\n}\n\n/** Duck-typed Zod schema check. */\nexport function isZodSchema(v: unknown): v is z.ZodType {\n if (!isPlainObject(v)) return false;\n const parseFn = getOwnProp(v, 'parse');\n return typeof parseFn === 'function';\n}\n\n/** Duck-typed ZodObject check. */\nfunction isZodObjectSchema(v: unknown): v is z.ZodObject<z.ZodRawShape> {\n if (!isPlainObject(v)) return false;\n const parseFn = getOwnProp(v, 'parse');\n if (typeof parseFn !== 'function') return false;\n const shape = getOwnProp(v, 'shape');\n return isPlainObject(shape);\n}\n\nfunction getObjectShape(obj: z.ZodObject<z.ZodRawShape>): Readonly<Record<string, unknown>> {\n return obj.shape;\n}\n\nexport function getZodAtPath(obj: z.ZodObject<z.ZodRawShape>, path: string): z.ZodType {\n const parts = path.split('.').filter(Boolean);\n\n let current: unknown = obj;\n\n for (const p of parts) {\n if (!isZodObjectSchema(current)) {\n throw new Error(`dataSchema path \"${path}\" is invalid: \"${p}\" is not inside a ZodObject`);\n }\n\n const shape = getObjectShape(current);\n const next = shape[p];\n\n if (!next) throw new Error(`dataSchema path \"${path}\" is invalid: missing key \"${p}\"`);\n if (!isZodSchema(next)) {\n throw new Error(`dataSchema path \"${path}\" is invalid: \"${p}\" is not a Zod schema`);\n }\n\n current = next;\n }\n\n if (!isZodSchema(current)) {\n throw new Error(`dataSchema path \"${path}\" is invalid: resolved value is not a Zod schema`);\n }\n\n return current;\n}\n\nexport function projectDataSchema(\n dataSchema: z.ZodObject<z.ZodRawShape>,\n selectedPaths: string[],\n): z.ZodObject<z.ZodRawShape> {\n const tree: Record<string, unknown> = {};\n\n const ensureTreeNode = (node: Record<string, unknown>, key: string): Record<string, unknown> => {\n const existing = node[key];\n\n if (existing === undefined) {\n const child: Record<string, unknown> = {};\n node[key] = child;\n return child;\n }\n\n if (isPlainObject(existing)) return existing;\n\n if (isZodSchema(existing)) {\n throw new Error(`Cannot project \"${key}\": \"${key}\" is selected as a leaf and as an object`);\n }\n\n throw new Error(`Cannot project \"${key}\": conflicting selection`);\n };\n\n for (const fullPath of selectedPaths) {\n const parts = fullPath.split('.').filter(Boolean);\n if (parts.length === 0) continue;\n\n let cursor = tree;\n\n for (let i = 0; i < parts.length; i += 1) {\n const key = parts[i];\n if (!key) continue;\n\n const isLeaf = i === parts.length - 1;\n\n if (isLeaf) {\n cursor[key] = getZodAtPath(dataSchema, fullPath);\n } else {\n cursor = ensureTreeNode(cursor, key);\n }\n }\n }\n\n const buildObjectFromTree = (node: Record<string, unknown>): z.ZodObject<z.ZodRawShape> => {\n const shape: MutableShape = {};\n\n for (const [k, v] of Object.entries(node)) {\n if (isZodSchema(v)) {\n shape[k] = v;\n continue;\n }\n if (isPlainObject(v)) {\n shape[k] = buildObjectFromTree(v);\n continue;\n }\n throw new Error(`Invalid projection tree at \"${k}\"`);\n }\n\n return z.object(shape);\n };\n\n return buildObjectFromTree(tree);\n}\n\n/* ---------------------------------- */\n/* Config */\n/* ---------------------------------- */\n\nexport interface SelectConfig<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n dataSchema: TSchema;\n selectable: readonly TSelect[];\n defaultSelect: readonly TSelect[] | '*';\n}\n\n/* ---------------------------------- */\n/* Output */\n/* ---------------------------------- */\n\n/**\n * Extract the top-level key from a dot-path.\n * e.g. `'meta.score'` → `'meta'`, `'id'` → `'id'`.\n */\nexport type TopLevelKey<P extends string> = P extends `${infer K}.${string}` ? K : P;\n\n/**\n * Projected data item: exposes only the selectable keys of the original schema\n * with `unknown` values. This gives consumers key auto-completion\n * without requiring `as` (projectDataSchema erases value types at runtime).\n */\nexport type ProjectedData<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> = Partial<Record<TopLevelKey<TSelect> & keyof InferData<TSchema>, unknown>>;\n\nexport interface SelectQueryParams<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n select: TSelect[];\n}\n\nexport interface SelectResponse<\n TSchema extends DataSchema,\n TSelect extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n data: ProjectedData<TSchema, TSelect>[];\n}\n\n/**\n * Result type returned by `select()`. Use this instead of\n * `ReturnType<typeof select>` to preserve the generic `TSchema`.\n *\n * @example\n * function createSelector(): SelectResult<typeof MySchema> {\n * return select({ dataSchema: MySchema, … });\n * }\n */\nexport interface SelectResult<\n TSchema extends DataSchema,\n TSelectable extends AllowedPath<TSchema> = AllowedPath<TSchema>,\n> {\n queryParamsSchema: z.ZodType<SelectQueryParams<TSchema, TSelectable>>;\n validatorSchema: (\n parsed?: SelectQueryParams<TSchema, TSelectable>,\n ) => z.ZodType<SelectResponse<TSchema, TSelectable>>;\n responseSchema: z.ZodType<SelectResponse<TSchema, TSelectable>>;\n}\n\n/* ---------------------------------- */\n/* Factory */\n/* ---------------------------------- */\n\n/**\n * Generate Zod schemas and runtime validators for select-only query parameters, based on a config object.\n * @param config The configuration object defining the selectable fields.\n * @returns An object containing:\n * - `queryParamsSchema`: A Zod schema for validating and parsing the raw query parameters.\n * - `validatorSchema`: A function that takes the already-parsed query parameters and returns a Zod schema for validating the response.\n * - `responseSchema`: A pre-built Zod schema for validating the response (uses defaultSelect or all selectable fields).\n */\nexport function select<\n TSchema extends DataSchema,\n const TSelectable extends readonly AllowedPath<TSchema>[],\n>(\n config: Omit<SelectConfig<TSchema, TSelectable[number]>, 'selectable' | 'defaultSelect'> & {\n selectable: TSelectable;\n defaultSelect: readonly NoInfer<TSelectable[number]>[] | '*';\n },\n): SelectResult<TSchema, TSelectable[number]> {\n const allowedSelectable = new Set<string>();\n for (const f of config.selectable) allowedSelectable.add(`${f}`);\n\n const baseSchema = z.object({\n select: SelectSchema.optional(),\n });\n\n const queryParamsSchema: z.ZodType<SelectQueryParams<TSchema, TSelectable[number]>> = z\n .record(z.string(), z.unknown())\n .transform((q): Record<string, unknown> => {\n const raw = q.select;\n return {\n ...q,\n select: typeof raw === 'string' ? raw : undefined,\n };\n })\n .pipe(\n baseSchema\n .superRefine((val, ctx): void => {\n const selectForValidation =\n val.select ?? (config.defaultSelect === '*' ? ['*'] : [...config.defaultSelect]);\n\n let index = 0;\n for (const field of selectForValidation) {\n if (field === '*') {\n index += 1;\n continue;\n }\n\n if (!allowedSelectable.has(field)) {\n ctx.addIssue({\n code: 'custom',\n path: ['select', index],\n message: `select field \"${field}\" is not allowed`,\n });\n }\n\n index += 1;\n }\n\n if (selectForValidation.includes('*')) {\n const expanded = expandSelect(selectForValidation, config);\n if (!expanded || expanded.length === 0) {\n ctx.addIssue({\n code: 'custom',\n path: ['select'],\n message: 'select \"*\" cannot be expanded (empty selectable)',\n });\n }\n }\n })\n .transform((val): SelectQueryParams<TSchema, TSelectable[number]> => {\n const resolved = computeSelect<TSchema, TSelectable[number]>(val.select, config);\n\n if (!resolved || resolved.length === 0) {\n throw new Error('select resolved to empty (this should not happen after validation)');\n }\n\n return { select: resolved };\n }),\n );\n\n const validatorSchema = (\n parsed?: SelectQueryParams<TSchema, TSelectable[number]>,\n ): z.ZodType<SelectResponse<TSchema, TSelectable[number]>> => {\n const effectiveSelect =\n parsed?.select ?? computeSelect<TSchema, TSelectable[number]>(undefined, config) ?? undefined;\n\n const dataItemSchema =\n effectiveSelect && effectiveSelect.length > 0\n ? projectDataSchema(\n config.dataSchema,\n effectiveSelect.map((x): string => x),\n )\n : config.dataSchema;\n\n return z.object({\n data: z.array(dataItemSchema),\n });\n };\n\n const responseSchema = validatorSchema();\n\n return { queryParamsSchema, validatorSchema, responseSchema };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod-paginate",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "A small utility to parse and validate pagination using Zod",
5
5
  "keywords": [
6
6
  "zod",