@querykitjs/mongoose 1.0.0 → 3.0.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/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Types, Model, Connection, ClientSession } from 'mongoose';
2
- import * as _querykitjs_core from '@querykitjs/core';
2
+ import * as Core from '@querykitjs/core';
3
+ import { AllRows, MutationCount, MutationRows, RelationRule, SkippedCondition, QueryLimits, createFilters as createFilters$1 } from '@querykitjs/core';
3
4
  export { f } from '@querykitjs/core';
4
5
 
5
6
  /**
@@ -9,10 +10,8 @@ export { f } from '@querykitjs/core';
9
10
  * escape-hatch bound to a native Mongo `FilterQuery`.
10
11
  *
11
12
  * The public surface mirrors `@querykitjs/drizzle-pg` so the same frontend
12
- * request contract works regardless of backend.
13
- *
14
- * NOTE: Stage 1 exposes only read methods (+ scoped). Writes/upsert/aggregate/
15
- * transaction land in stage 2.
13
+ * request contract works regardless of backend: same option names, same
14
+ * semantics, one shared source in core.
16
15
  */
17
16
 
18
17
  /** Plain (lean) document type — what reads return. */
@@ -33,18 +32,25 @@ type Id = string | number | Types.ObjectId;
33
32
  type RawFilter<_TDoc = unknown> = Record<string, unknown>;
34
33
  /** Union of a document's field keys. */
35
34
  type FieldKey<TDoc> = keyof TDoc & string;
36
- type FilterOperator = _querykitjs_core.FilterOperator;
37
- type FilterScalar = _querykitjs_core.FilterScalar;
38
- type FilterValue = _querykitjs_core.FilterValue;
39
- type FieldCondition<TDoc = Record<string, unknown>> = _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
40
- type AndGroup<TDoc = Record<string, unknown>> = _querykitjs_core.AndGroup<FieldKey<TDoc>, RawFilter<TDoc>>;
41
- type OrGroup<TDoc = Record<string, unknown>> = _querykitjs_core.OrGroup<FieldKey<TDoc>, RawFilter<TDoc>>;
42
- type NotGroup<TDoc = Record<string, unknown>> = _querykitjs_core.NotGroup<FieldKey<TDoc>, RawFilter<TDoc>>;
43
- type FilterNode<TDoc = Record<string, unknown>> = _querykitjs_core.FilterNode<FieldKey<TDoc>, RawFilter<TDoc>>;
44
- type Filter<TDoc = Record<string, unknown>> = _querykitjs_core.Filter<FieldKey<TDoc>, RawFilter<TDoc>>;
45
- type SortDirection = _querykitjs_core.SortDirection;
35
+ /**
36
+ * A field key that also accepts any `string`. Filter/sort keys arrive from the
37
+ * wire as plain strings and the adapter skips the ones it cannot resolve, so a
38
+ * validated payload can go straight into a repository call with no `as` cast.
39
+ * Autocomplete still suggests the document's real fields.
40
+ */
41
+ type LooseFieldKey<TDoc> = Core.LooseKey<FieldKey<TDoc>>;
42
+ type FilterOperator = Core.FilterOperator;
43
+ type FilterScalar = Core.FilterScalar;
44
+ type FilterValue = Core.FilterValue;
45
+ type FieldCondition<TDoc = Record<string, unknown>> = Core.FieldCondition<LooseFieldKey<TDoc>>;
46
+ type AndGroup<TDoc = Record<string, unknown>> = Core.AndGroup<LooseFieldKey<TDoc>, RawFilter<TDoc>>;
47
+ type OrGroup<TDoc = Record<string, unknown>> = Core.OrGroup<LooseFieldKey<TDoc>, RawFilter<TDoc>>;
48
+ type NotGroup<TDoc = Record<string, unknown>> = Core.NotGroup<LooseFieldKey<TDoc>, RawFilter<TDoc>>;
49
+ type FilterNode<TDoc = Record<string, unknown>> = Core.FilterNode<LooseFieldKey<TDoc>, RawFilter<TDoc>>;
50
+ type Filter<TDoc = Record<string, unknown>> = Core.Filter<LooseFieldKey<TDoc>, RawFilter<TDoc>>;
51
+ type SortDirection = Core.SortDirection;
46
52
  /** One sort field by typed field key (`{ key, direction }`) — autocomplete. */
47
- type SortItem<TDoc = Record<string, unknown>> = _querykitjs_core.SortItem<FieldKey<TDoc>>;
53
+ type SortItem<TDoc = Record<string, unknown>> = Core.SortItem<LooseFieldKey<TDoc>>;
48
54
  /**
49
55
  * Sort — **always an array** of `{ key, direction }` (multi-field). This is the
50
56
  * exact shape the querykit frontend sends (`@querykitjs/web` decodes its
@@ -63,43 +69,25 @@ interface QueryParams<TDoc = Record<string, unknown>> {
63
69
  withDeleted?: boolean;
64
70
  }
65
71
  /** Equality scope applied to every operation of a scoped repository. */
66
- type Scope<TDoc = Record<string, unknown>> = Partial<Record<FieldKey<TDoc>, FilterScalar>>;
72
+ type Scope<TDoc = Record<string, unknown>> = Core.Scope<FieldKey<TDoc>>;
67
73
  interface ByIdParams<TDoc = Record<string, unknown>> extends QueryParams<TDoc> {
68
74
  /** Field to match against the id. Defaults to `"id"` (→ `_id`). */
69
- idKey?: FieldKey<TDoc>;
75
+ idKey?: LooseFieldKey<TDoc>;
70
76
  }
71
77
  /** Options for {@link Repository.upsert} / {@link Repository.upsertMany}. */
72
- interface UpsertOptions<TDoc = Record<string, unknown>> {
73
- /** Unique field(s) whose match triggers an update instead of an insert. */
74
- target: FieldKey<TDoc> | FieldKey<TDoc>[];
75
- /** Fields to update on conflict. Defaults to the inserted values minus `target`. */
76
- set?: Partial<Insert<TDoc>>;
77
- }
78
- type AggKeys<TDoc> = FieldKey<TDoc> | FieldKey<TDoc>[];
79
- /** Aggregate query specification (mirrors drizzle-pg). */
80
- interface AggregateSpec<TDoc = Record<string, unknown>> {
81
- filter?: Filter<TDoc>;
82
- /** Group by these field(s); each appears in the output rows. */
83
- groupBy?: AggKeys<TDoc>;
84
- /** `$sum:1` → `count`. */
85
- count?: boolean;
86
- /** `$sum` → `sum_<field>`. */
87
- sum?: AggKeys<TDoc>;
88
- /** `$avg` → `avg_<field>`. */
89
- avg?: AggKeys<TDoc>;
90
- /** `$min` → `min_<field>`. */
91
- min?: AggKeys<TDoc>;
92
- /** `$max` → `max_<field>`. */
93
- max?: AggKeys<TDoc>;
94
- withDeleted?: boolean;
95
- }
78
+ type UpsertOptions<TDoc = Record<string, unknown>> = Core.UpsertOptions<FieldKey<TDoc>, Insert<TDoc>>;
79
+ /** Aggregate query specification (`count`/`sum`/`avg`/`min`/`max` + `groupBy`). */
80
+ type AggregateSpec<TDoc = Record<string, unknown>> = Core.AggregateSpec<FieldKey<TDoc>, Filter<TDoc>>;
96
81
  /** One aggregated result row (group fields + aggregate values). */
97
82
  type AggregateRow = Record<string, unknown>;
83
+
98
84
  interface OffsetParams<TDoc = Record<string, unknown>> extends QueryParams<TDoc> {
99
85
  page?: number;
100
86
  perPage?: number;
87
+ /** `false` — no count query: `perPage + 1` rows are read, `total_items` / `total_pages` are `null` (task 013). Default `true`. */
88
+ withTotal?: boolean;
101
89
  }
102
- type OffsetMeta = _querykitjs_core.OffsetMeta;
90
+ type OffsetMeta = Core.OffsetMeta;
103
91
  interface OffsetResult<T> {
104
92
  data: T[];
105
93
  meta: OffsetMeta;
@@ -108,7 +96,7 @@ interface InfiniteParams<TDoc = Record<string, unknown>> extends QueryParams<TDo
108
96
  limit?: number;
109
97
  offset?: number;
110
98
  }
111
- type InfiniteMeta = _querykitjs_core.InfiniteMeta;
99
+ type InfiniteMeta = Core.InfiniteMeta;
112
100
  interface InfiniteResult<T> {
113
101
  data: T[];
114
102
  meta: InfiniteMeta;
@@ -117,26 +105,79 @@ interface CursorParams<TDoc = Record<string, unknown>> extends QueryParams<TDoc>
117
105
  limit?: number;
118
106
  cursor?: string | null;
119
107
  /** Field the cursor walks over. Defaults to `"id"` (→ `_id`). */
120
- cursorKey?: FieldKey<TDoc>;
108
+ cursorKey?: LooseFieldKey<TDoc>;
121
109
  order?: SortDirection;
122
110
  direction?: "forward" | "backward";
123
111
  }
124
- type CursorMeta = _querykitjs_core.CursorMeta;
112
+ type CursorMeta = Core.CursorMeta;
125
113
  interface CursorResult<T> {
126
114
  data: T[];
127
115
  meta: CursorMeta;
128
116
  }
129
- /** Map of relation field name → the Mongoose model it refers to. */
130
- type RelationMap = Record<string, Model<any>>;
131
- type DocOf<M> = M extends Model<infer T> ? T : never;
117
+
118
+ /**
119
+ * Relation field → its rule (task 014, R21): `{ model?, columns, filterable?, nested? }` opens it for a
120
+ * client `with` (`columns` required — a list or `"*"`). A bare model (`{ author: User }`) still types
121
+ * `with`, but opens nothing: `with: { author: … }` is `forbidden-key`, `site: "with"`.
122
+ */
123
+ type RelationMap = Record<string, Model<any> | (RelationRule & {
124
+ model?: Model<any>;
125
+ })>;
126
+ type DocOf<M> = M extends Model<infer T> ? T : M extends {
127
+ model: Model<infer T>;
128
+ } ? T : Record<string, unknown>;
132
129
  /** Resolve a {@link RelationMap} to `{ field: <its document type> }`. */
133
130
  type RelationDocs<TRel extends RelationMap> = {
134
131
  [K in keyof TRel]: DocOf<TRel[K]>;
135
132
  };
136
- /** Options for `registry.repository(model, options)`. */
137
- interface RepositoryOptions<TRel extends RelationMap = RelationMap> {
138
- /** Declare populatable relations (field → model) so `with` types the result. */
133
+ /**
134
+ * Options for `registry.repository(model, options)`.
135
+ *
136
+ * Philosophy: the guard lives in the **repository**, not the route — `scope`
137
+ * (RBAC) already worked that way and projection joins it. Same names and same
138
+ * semantics as the drizzle-pg adapter's `RepositoryOptions`.
139
+ *
140
+ * ⚠️ `forcedColumns`/`allowedColumns` affect **read** methods only
141
+ * (`findAll`/`findOne`/`findById`/`findList`/`findInfinite`/`findCursor` +
142
+ * `aggregate`). Write methods (`create`, `upsert`, `updateById`, `softDelete`, …)
143
+ * return the full `Row` by type contract — trimming it at runtime would make the
144
+ * type a lie. Re-read with `findById`, or map it yourself, before handing a write
145
+ * result to a client.
146
+ */
147
+ interface RepositoryOptions<TDoc = any, TRel extends RelationMap = RelationMap> {
148
+ /** Populatable relations: field → `{ model?, columns, filterable?, nested? }` (R21), or a bare model (typing only). */
139
149
  relations?: TRel;
150
+ /** Constant equality filter added to every read/write (RBAC / multi-tenancy). */
151
+ scope?: Scope<TDoc>;
152
+ /**
153
+ * Forced projection — the client's `columns` is **ignored entirely**. Keeps a
154
+ * password out of a `users` response without a `{ ...params, columns }` trick in
155
+ * every route. Must select at least one field, else building the repository throws.
156
+ */
157
+ forcedColumns?: ColumnSelection<TDoc>;
158
+ /**
159
+ * Allowlist — the client's `columns` is intersected with it. An empty
160
+ * intersection yields the allowlist itself, **never** the full document.
161
+ * An empty array throws (a projection selecting nothing means "everything").
162
+ */
163
+ allowedColumns?: readonly FieldKey<TDoc>[];
164
+ /**
165
+ * Paths a client may filter by, and the operators for each (`"*"` — all). A path
166
+ * not listed ⇒ `reason: "forbidden-key"`, an operator not listed ⇒
167
+ * `"forbidden-operator"` — a `QueryKitError` whatever `strict` says, before the
168
+ * query runs. **When not given** — `allowedColumns` (else the `forcedColumns` keys,
169
+ * else only `_id`) with `"="` and `"in"` only. `aggregate` paths come from this list too.
170
+ */
171
+ filterable?: Core.Filterable<FieldKey<TDoc> | "_id">;
172
+ /**
173
+ * Paths a client may sort (and use as `cursorKey`) by. When not given — `_id` and
174
+ * `createdAt` (when the schema has it). Anything else ⇒ `reason: "forbidden-key"`.
175
+ */
176
+ sortable?: readonly (FieldKey<TDoc> | "_id")[];
177
+ /** Request limits for this repository — over the registry's `limits`. */
178
+ limits?: Partial<Core.QueryLimits>;
179
+ /** Read time limit for this repository, in ms — over the registry's `maxTimeMS`. */
180
+ maxTimeMS?: number;
140
181
  }
141
182
  type TrueKeys<T> = {
142
183
  [K in keyof T]: T[K] extends true ? K : never;
@@ -154,7 +195,7 @@ type Params<TBase, TColumns, TWith> = Omit<TBase, "columns" | "with"> & {
154
195
  with?: TWith;
155
196
  };
156
197
  /**
157
- * Table-scoped repository (stage 1: reads + scoped). Read methods infer their
198
+ * Model-scoped repository. Read methods infer their
158
199
  * return type from the `columns` argument, mirroring `@querykitjs/drizzle-pg`.
159
200
  */
160
201
  interface Repository<TDoc = Record<string, unknown>, TRel extends Record<string, unknown> = Record<never, never>> {
@@ -178,12 +219,32 @@ interface Repository<TDoc = Record<string, unknown>, TRel extends Record<string,
178
219
  upsertMany(values: Insert<TDoc>[], options: UpsertOptions<TDoc>): Promise<Row<TDoc>[]>;
179
220
  /** Update one document by id; returns the updated doc (or undefined). */
180
221
  updateById(id: Id, patch: Partial<Insert<TDoc>>, idKey?: FieldKey<TDoc>): Promise<Row<TDoc> | undefined>;
181
- /** Update all documents matching the filter; returns the updated docs. */
182
- updateWhere(filter: Filter<TDoc>, patch: Partial<Insert<TDoc>>): Promise<Row<TDoc>[]>;
222
+ /**
223
+ * Update every document matching the filter in one `updateMany` → `{ count }` (matched, task 013).
224
+ * No filter only with `{ all: true }` (the scope still applies); an empty or fully skipped
225
+ * filter is `QueryKitError` `empty-filter`. The filter passes the request policy like a read.
226
+ */
227
+ updateWhere(filter: Filter<TDoc> | AllRows, patch: Partial<Insert<TDoc>>, options?: {
228
+ returning?: false;
229
+ }): Promise<MutationCount>;
230
+ /** With `returning: { limit }`: `{ count, rows }` — the rows are read right after the update with the same filter (not atomic). */
231
+ updateWhere(filter: Filter<TDoc> | AllRows, patch: Partial<Insert<TDoc>>, options: {
232
+ returning: {
233
+ limit: number;
234
+ };
235
+ }): Promise<MutationRows<Row<TDoc>>>;
183
236
  /** Hard-delete one document by id; returns the deleted doc (or undefined). */
184
237
  deleteById(id: Id, idKey?: FieldKey<TDoc>): Promise<Row<TDoc> | undefined>;
185
- /** Hard-delete all documents matching the filter; returns the deleted docs. */
186
- deleteWhere(filter: Filter<TDoc>): Promise<Row<TDoc>[]>;
238
+ /** Hard-delete every document matching the filter in one `deleteMany` → `{ count }` (same rules as `updateWhere`). */
239
+ deleteWhere(filter: Filter<TDoc> | AllRows, options?: {
240
+ returning?: false;
241
+ }): Promise<MutationCount>;
242
+ /** With `returning: { limit }`: `{ count, rows }` — the rows are read just before the delete (not atomic). */
243
+ deleteWhere(filter: Filter<TDoc> | AllRows, options: {
244
+ returning: {
245
+ limit: number;
246
+ };
247
+ }): Promise<MutationRows<Row<TDoc>>>;
187
248
  /** Soft-delete (set `deletedAt`); requires a `deletedAt` schema path. */
188
249
  softDelete(id: Id, idKey?: FieldKey<TDoc>): Promise<Row<TDoc> | undefined>;
189
250
  /** Restore a soft-deleted document (`deletedAt = null`). */
@@ -192,12 +253,61 @@ interface Repository<TDoc = Record<string, unknown>, TRel extends Record<string,
192
253
  aggregate(spec: AggregateSpec<TDoc>): Promise<AggregateRow[]>;
193
254
  scoped(scope: Scope<TDoc>): Repository<TDoc, TRel>;
194
255
  }
195
- /** {@link createRegistry} options — pagination defaults. */
256
+
257
+ /** {@link createRegistry} options — pagination defaults and bounds. */
196
258
  interface RegistryOptions {
197
259
  /** `findList` default page size (core `DEFAULT_PER_PAGE` = 20). */
198
260
  defaultPerPage?: number;
199
261
  /** `findInfinite`/`findCursor` default limit (core `DEFAULT_LIMIT` = 20). */
200
262
  defaultLimit?: number;
263
+ /**
264
+ * Upper bound for `perPage` (core `DEFAULT_MAX_PER_PAGE` = 200). Applied even
265
+ * when validation was bypassed — defense in depth. Disable with `Infinity`.
266
+ */
267
+ maxPerPage?: number;
268
+ /** Upper bound for `limit` (`findInfinite`/`findCursor`, core `DEFAULT_MAX_LIMIT` = 200). */
269
+ maxLimit?: number;
270
+ /**
271
+ * **Strict mode.** An unknown filter/sort key, or a value the operator cannot
272
+ * use, is no longer dropped silently — a `QueryKitError` is thrown (the backend
273
+ * maps it to a 400). Defaults to `false`, keeping the legacy (DbService)
274
+ * behaviour that dozens of existing endpoints rely on.
275
+ *
276
+ * Why it matters: a filter is meant to **narrow** a result set, so a mistyped
277
+ * key that vanishes silently makes the endpoint return **more** data than
278
+ * intended, with nothing in the log to show it.
279
+ */
280
+ strict?: boolean;
281
+ /**
282
+ * Called for every dropped condition (also when `strict` is off). Migration
283
+ * path: watch with the hook first, flip `strict: true` once the log is clean.
284
+ */
285
+ onSkippedCondition?: (info: Core.SkippedCondition) => void;
286
+ /**
287
+ * Server-side request limits (core `DEFAULT_QUERY_LIMITS`) — enforced even when
288
+ * validation was bypassed. Past one ⇒ `QueryKitError` (`reason: "limit-exceeded"`).
289
+ * A repository's own `limits` win.
290
+ */
291
+ limits?: Partial<Core.QueryLimits>;
292
+ /**
293
+ * Time limit for every read (`find`, `findOne`, `countDocuments`, `aggregate`), in ms.
294
+ * Default `2000`. Past it MongoDB aborts the read and the repository throws
295
+ * `QueryKitTimeoutError` (`code: "QUERYKIT_TIMEOUT"`). A repository's own `maxTimeMS` wins.
296
+ */
297
+ maxTimeMS?: number;
298
+ /**
299
+ * Signs cursor tokens (HMAC-SHA256, task 012). With it a token that was not
300
+ * issued by this server — or was changed — is `invalid-value`.
301
+ */
302
+ cursorSecret?: string;
303
+ /**
304
+ * The createdAt / deletedAt field names (task 014; default `createdAt`, `deletedAt`): the default
305
+ * sort and the default `sortable` use `createdAt`, soft delete uses `deletedAt`.
306
+ */
307
+ timestamps?: {
308
+ createdAt?: string;
309
+ deletedAt?: string;
310
+ };
201
311
  }
202
312
  /** Extends a base repository with custom, model-specific methods (drizzle-pg style). */
203
313
  type RepositoryExtender<TDoc, TRel extends Record<string, unknown>, TExt extends Record<string, unknown>> = (base: Repository<TDoc, TRel>) => TExt;
@@ -208,9 +318,9 @@ interface Registry {
208
318
  /** …extended with custom methods (2nd-arg extender fn — same as drizzle-pg). */
209
319
  repository<TDoc, TExt extends Record<string, unknown>>(model: Model<TDoc>, extend: RepositoryExtender<TDoc, Record<never, never>, TExt>): Repository<TDoc> & TExt;
210
320
  /** …with typed relations so populated `with` fields are typed. */
211
- repository<TDoc, TRel extends RelationMap>(model: Model<TDoc>, options: RepositoryOptions<TRel>): Repository<TDoc, RelationDocs<TRel>>;
321
+ repository<TDoc, TRel extends RelationMap>(model: Model<TDoc>, options: RepositoryOptions<TDoc, TRel>): Repository<TDoc, RelationDocs<TRel>>;
212
322
  /** …with both typed relations and custom methods. */
213
- repository<TDoc, TRel extends RelationMap, TExt extends Record<string, unknown>>(model: Model<TDoc>, options: RepositoryOptions<TRel>, extend: RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>): Repository<TDoc, RelationDocs<TRel>> & TExt;
323
+ repository<TDoc, TRel extends RelationMap, TExt extends Record<string, unknown>>(model: Model<TDoc>, options: RepositoryOptions<TDoc, TRel>, extend: RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>): Repository<TDoc, RelationDocs<TRel>> & TExt;
214
324
  /** Runs `fn` inside a MongoDB transaction (requires a replica set). */
215
325
  transaction<T>(fn: () => Promise<T>): Promise<T>;
216
326
  }
@@ -238,16 +348,32 @@ interface RepoRuntime {
238
348
  getSession: () => ClientSession | undefined;
239
349
  defaultPerPage: number;
240
350
  defaultLimit: number;
351
+ /** Upper bound for `perPage`, applied even when validation was bypassed. */
352
+ maxPerPage: number;
353
+ /** Upper bound for `limit` (`findInfinite`/`findCursor`). */
354
+ maxLimit: number;
355
+ /** Throw `QueryKitError` instead of dropping an unresolvable condition. */
356
+ strict: boolean;
357
+ /** Called for every dropped condition (also when `strict` is off). */
358
+ onSkippedCondition?: (info: SkippedCondition) => void;
359
+ /** Registry-level request limits; a repository's own `limits` win. */
360
+ limits?: Partial<QueryLimits>;
361
+ /** Read time limit in ms; a repository's own `maxTimeMS` wins. */
362
+ maxTimeMS: number;
363
+ /** Signs cursor tokens (task 012). */
364
+ cursorSecret?: string;
365
+ /** createdAt / deletedAt field names (task 014); default `createdAt`, `deletedAt`. */
366
+ timestamps?: {
367
+ createdAt?: string;
368
+ deletedAt?: string;
369
+ };
241
370
  }
242
- /** Per-repository configuration (scope). */
243
- interface RepoConfig<TDoc> {
244
- scope?: Scope<TDoc>;
245
- }
371
+
246
372
  /**
247
373
  * Build a model-scoped repository. `runtime` (session getter + defaults) comes
248
- * from the registry, so this file never touches the connection directly.
374
+ * from the registry, so this module never touches the connection directly.
249
375
  */
250
- declare function buildRepository<TDoc>(runtime: RepoRuntime, model: Model<TDoc>, config?: RepoConfig<TDoc>): Repository<TDoc>;
376
+ declare function buildRepository<TDoc>(runtime: RepoRuntime, model: Model<TDoc>, config?: RepositoryOptions<TDoc>): Repository<TDoc>;
251
377
 
252
378
  /**
253
379
  * Typed, ergonomic filter builders for a document type (field-name autocomplete).
@@ -260,28 +386,7 @@ declare function buildRepository<TDoc>(runtime: RepoRuntime, model: Model<TDoc>,
260
386
  * await usersRepo.findAll({ filter: uf.and(uf.eq("status", "active"), uf.gte("age", 18)) });
261
387
  * ```
262
388
  */
263
- declare function createFilters<TDoc>(): {
264
- eq: (key: FieldKey<TDoc>, value: _querykitjs_core.FilterValue) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
265
- ne: (key: FieldKey<TDoc>, value: _querykitjs_core.FilterValue) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
266
- gt: (key: FieldKey<TDoc>, value: _querykitjs_core.FilterValue) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
267
- gte: (key: FieldKey<TDoc>, value: _querykitjs_core.FilterValue) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
268
- lt: (key: FieldKey<TDoc>, value: _querykitjs_core.FilterValue) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
269
- lte: (key: FieldKey<TDoc>, value: _querykitjs_core.FilterValue) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
270
- contains: (key: FieldKey<TDoc>, value: string) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
271
- startsWith: (key: FieldKey<TDoc>, value: string) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
272
- endsWith: (key: FieldKey<TDoc>, value: string) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
273
- like: (key: FieldKey<TDoc>, value: string) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
274
- ilike: (key: FieldKey<TDoc>, value: string) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
275
- notLike: (key: FieldKey<TDoc>, value: string) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
276
- in: (key: FieldKey<TDoc>, value: Array<string | number>) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
277
- notIn: (key: FieldKey<TDoc>, value: Array<string | number>) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
278
- between: (key: FieldKey<TDoc>, min: _querykitjs_core.FilterScalar | Date, max: _querykitjs_core.FilterScalar | Date) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
279
- range: (key: FieldKey<TDoc>, from: _querykitjs_core.FilterScalar | Date, to: _querykitjs_core.FilterScalar | Date) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>[];
280
- isNull: (key: FieldKey<TDoc>) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
281
- isNotNull: (key: FieldKey<TDoc>) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
282
- and: (...nodes: _querykitjs_core.FilterNode<FieldKey<TDoc>, RawFilter<_TDoc>>[]) => _querykitjs_core.AndGroup<FieldKey<TDoc>, RawFilter<_TDoc>>;
283
- or: (...nodes: _querykitjs_core.FilterNode<FieldKey<TDoc>, RawFilter<_TDoc>>[]) => _querykitjs_core.OrGroup<FieldKey<TDoc>, RawFilter<_TDoc>>;
284
- not: (node: _querykitjs_core.FilterNode<FieldKey<TDoc>, RawFilter<_TDoc>>) => _querykitjs_core.NotGroup<FieldKey<TDoc>, RawFilter<_TDoc>>;
285
- };
389
+ declare function createFilters<TDoc>(): ReturnType<typeof createFilters$1<FieldKey<TDoc>, RawFilter<TDoc>>>;
286
390
 
287
- export { type AggregateRow, type AggregateSpec, type AndGroup, type ByIdParams, type ColumnSelection, type CursorMeta, type CursorParams, type CursorResult, type FieldCondition, type FieldKey, type Filter, type FilterNode, type FilterOperator, type FilterScalar, type FilterValue, type Id, type InfiniteMeta, type InfiniteParams, type InfiniteResult, type Insert, type NotGroup, type OffsetMeta, type OffsetParams, type OffsetResult, type OrGroup, type QueryParams, type RawFilter, type Registry, type RegistryOptions, type RelationDocs, type RelationMap, type RepoConfig, type RepoRuntime, type Repository, type RepositoryExtender, type RepositoryOptions, type Result, type Row, type Scope, type Sort, type SortDirection, type SortItem, type UpsertOptions, type WithRelations, buildRepository, createFilters, createRegistry };
391
+ export { buildRepository, createFilters, createRegistry };
392
+ export type { AggregateRow, AggregateSpec, AndGroup, ByIdParams, ColumnSelection, CursorMeta, CursorParams, CursorResult, FieldCondition, FieldKey, Filter, FilterNode, FilterOperator, FilterScalar, FilterValue, Id, InfiniteMeta, InfiniteParams, InfiniteResult, Insert, LooseFieldKey, NotGroup, OffsetMeta, OffsetParams, OffsetResult, OrGroup, QueryParams, RawFilter, Registry, RegistryOptions, RelationDocs, RelationMap, RepoRuntime, Repository, RepositoryExtender, RepositoryOptions, Result, Row, Scope, Sort, SortDirection, SortItem, UpsertOptions, WithRelations };