@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/README.en.md +284 -18
- package/README.md +285 -18
- package/dist/index.cjs +1 -513
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +195 -90
- package/dist/index.d.ts +195 -90
- package/dist/index.js +1 -506
- package/dist/index.js.map +1 -1
- package/package.json +18 -9
- package/skills/querykit-mongoose/SKILL.md +189 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Types, Model, Connection, ClientSession } from 'mongoose';
|
|
2
|
-
import * as
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
type
|
|
43
|
-
type
|
|
44
|
-
type
|
|
45
|
-
type
|
|
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>> =
|
|
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>> =
|
|
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?:
|
|
75
|
+
idKey?: LooseFieldKey<TDoc>;
|
|
70
76
|
}
|
|
71
77
|
/** Options for {@link Repository.upsert} / {@link Repository.upsertMany}. */
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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 =
|
|
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 =
|
|
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?:
|
|
108
|
+
cursorKey?: LooseFieldKey<TDoc>;
|
|
121
109
|
order?: SortDirection;
|
|
122
110
|
direction?: "forward" | "backward";
|
|
123
111
|
}
|
|
124
|
-
type CursorMeta =
|
|
112
|
+
type CursorMeta = Core.CursorMeta;
|
|
125
113
|
interface CursorResult<T> {
|
|
126
114
|
data: T[];
|
|
127
115
|
meta: CursorMeta;
|
|
128
116
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
/**
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
*
|
|
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
|
-
/**
|
|
182
|
-
|
|
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
|
|
186
|
-
deleteWhere(filter: Filter<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
|
-
|
|
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
|
-
|
|
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
|
|
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?:
|
|
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 {
|
|
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 };
|