@querykitjs/mongoose 1.0.0 → 2.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 +121 -1
- package/README.md +121 -1
- package/dist/index.cjs +134 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +90 -50
- package/dist/index.d.ts +90 -50
- package/dist/index.js +135 -38
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/fields.ts","../src/internal/operators.ts","../src/internal/where.ts","../src/internal/order-by.ts","../src/internal/cursor.ts","../src/repository.ts","../src/internal/context.ts","../src/registry.ts","../src/filters.ts"],"names":["f","AsyncLocalStorage","DEFAULT_PER_PAGE","DEFAULT_LIMIT","coreCreateFilters"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Model } from \"mongoose\";\n\n/** Any Mongoose model, regardless of its document type. */\nexport type AnyModel = Model<any>;\n\n/**\n * Map a public field key to a real Mongoose schema path. `\"id\"` is aliased to\n * `\"_id\"` so the wire contract stays identical across adapters. Unknown fields\n * return `undefined` (the caller skips them silently, like the Drizzle adapter).\n */\nexport function resolveField(model: AnyModel, key: string): string | undefined {\n const name = key === \"id\" ? \"_id\" : key;\n if (name === \"_id\") return \"_id\";\n return model.schema.path(name) ? name : undefined;\n}\n\n/** Whether the schema has a given path (e.g. `deletedAt`, `updatedAt`). */\nexport function hasPath(model: AnyModel, path: string): boolean {\n return Boolean(model.schema.path(path));\n}\n\n/**\n * Cast a raw (decoded cursor) value to the field's schema type so keyset\n * comparisons (`$gt`/`$lt`) work — e.g. a hex string → `ObjectId`, an ISO\n * string → `Date`. Falls back to the raw value if casting fails.\n */\nexport function castValue(model: AnyModel, field: string, value: unknown): unknown {\n const path = model.schema.path(field);\n if (!path) return value;\n try {\n return path.cast(value);\n } catch {\n return value;\n }\n}\n","import type { FilterOperator, FilterValue } from \"../types\";\n\n/** A field-level Mongo fragment, e.g. `{ $gte: 1, $lte: 9 }`. `undefined` = drop. */\ntype Fragment = Record<string, unknown> | undefined;\ntype Builder = (value: FilterValue | undefined) => Fragment;\n\n/** Escape a literal string for use inside a regex (contains/startsWith/endsWith). */\nconst esc = (s: unknown): string => String(s ?? \"\").replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/** Translate a SQL LIKE pattern (`%` → any, `_` → one char) to an anchored regex. */\nconst sqlLikeToRegex = (pattern: unknown): string => {\n let out = \"\";\n for (const ch of String(pattern ?? \"\")) {\n if (ch === \"%\") out += \".*\";\n else if (ch === \"_\") out += \".\";\n else out += ch.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n }\n return `^${out}$`;\n};\n\nconst asTuple = (v: FilterValue | undefined): [unknown, unknown] | undefined => (Array.isArray(v) && v.length === 2 ? [v[0], v[1]] : undefined);\n\n/**\n * Operator → Mongo fragment map. Mirrors the Drizzle adapter's semantics: both\n * token (`\"%_%\"`) and name-alias (`\"contains\"`) forms are handled;\n * `contains/startsWith/endsWith` are case-insensitive; invalid values (non-array\n * `in`, non-2-tuple `between`) drop the condition (`undefined`).\n */\nexport const operators: Record<FilterOperator, Builder> = {\n \"=\": v => ({ $eq: v }),\n eq: v => ({ $eq: v }),\n // SQL three-valued logic: inequality/negation excludes NULL (and missing) rows,\n // matching drizzle-pg. `$nin: [v, null]` = \"not v AND not null\".\n \"!=\": v => ({ $nin: [v, null] }),\n ne: v => ({ $nin: [v, null] }),\n \">\": v => ({ $gt: v }),\n gt: v => ({ $gt: v }),\n \">=\": v => ({ $gte: v }),\n gte: v => ({ $gte: v }),\n \"<\": v => ({ $lt: v }),\n lt: v => ({ $lt: v }),\n \"<=\": v => ({ $lte: v }),\n lte: v => ({ $lte: v }),\n\n contains: v => ({ $regex: esc(v), $options: \"i\" }),\n \"%_%\": v => ({ $regex: esc(v), $options: \"i\" }),\n startsWith: v => ({ $regex: `^${esc(v)}`, $options: \"i\" }),\n \"%_\": v => ({ $regex: `^${esc(v)}`, $options: \"i\" }),\n endsWith: v => ({ $regex: `${esc(v)}$`, $options: \"i\" }),\n \"_%\": v => ({ $regex: `${esc(v)}$`, $options: \"i\" }),\n\n like: v => ({ $regex: sqlLikeToRegex(v) }),\n ilike: v => ({ $regex: sqlLikeToRegex(v), $options: \"i\" }),\n // negation also excludes NULL/missing (SQL `NOT LIKE` semantics).\n notLike: v => ({ $not: { $regex: sqlLikeToRegex(v) }, $ne: null }),\n\n in: v => (Array.isArray(v) ? { $in: v } : undefined),\n notIn: v => (Array.isArray(v) ? { $nin: [...v, null] } : undefined),\n\n between: v => {\n const t = asTuple(v);\n return t ? { $gte: t[0], $lte: t[1] } : undefined;\n },\n notBetween: v => {\n const t = asTuple(v);\n return t ? { $not: { $gte: t[0], $lte: t[1] }, $ne: null } : undefined;\n },\n\n isNull: () => ({ $eq: null }),\n isNotNull: () => ({ $ne: null }),\n};\n","import type { Filter, FieldCondition, FilterNode } from \"../types\";\nimport { operators } from \"./operators\";\nimport { resolveField, type AnyModel } from \"./fields\";\n\n/** A Mongo filter query object. */\nexport type Query = Record<string, unknown>;\n\nconst isObject = (n: unknown): n is Record<string, unknown> => typeof n === \"object\" && n !== null;\n\nconst isFieldCondition = (n: unknown): n is FieldCondition => isObject(n) && \"key\" in n && !(\"and\" in n) && !(\"or\" in n) && !(\"not\" in n);\n\n/** Combine parts (dropping `undefined`): 0 → undefined, 1 → the part, else `$and`/`$or`. */\nfunction combine(kind: \"$and\" | \"$or\", parts: (Query | undefined)[]): Query | undefined {\n const valid = parts.filter((p): p is Query => p !== undefined);\n if (valid.length === 0) return undefined;\n if (valid.length === 1) return valid[0];\n return { [kind]: valid };\n}\n\nfunction buildCondition(model: AnyModel, cond: FieldCondition): Query | undefined {\n const operator = cond.operation ?? \"=\";\n const build = operators[operator];\n if (!build) throw new Error(`Unsupported filter operator: \"${operator}\"`);\n const field = resolveField(model, cond.key);\n if (!field) return undefined; // unknown field → skip silently\n const fragment = build(cond.value);\n if (fragment === undefined) return undefined;\n return { [field]: fragment };\n}\n\nfunction buildNode(model: AnyModel, node: FilterNode): Query | undefined {\n if (isFieldCondition(node)) return buildCondition(model, node);\n if (isObject(node)) {\n if (\"and\" in node)\n return combine(\n \"$and\",\n (node.and as FilterNode[]).map(n => buildNode(model, n)),\n );\n if (\"or\" in node)\n return combine(\n \"$or\",\n (node.or as FilterNode[]).map(n => buildNode(model, n)),\n );\n if (\"not\" in node) {\n const notNode = node.not as FilterNode;\n const inner = buildNode(model, notNode);\n if (!inner) return undefined;\n // SQL `NOT(pred)` drops NULL rows (three-valued logic), but Mongo `$nor`\n // includes null/missing. For a single-field comparison predicate, also\n // require the field non-null so results match drizzle. `isNull`/`isNotNull`\n // are two-valued (never NULL) → no guard, else `not(isNotNull)` would\n // wrongly return nothing. Multi-field `not` groups keep bare `$nor`.\n if (isFieldCondition(notNode)) {\n const op = notNode.operation ?? \"=\";\n if (op !== \"isNull\" && op !== \"isNotNull\") {\n const field = resolveField(model, notNode.key);\n if (field) return { $and: [{ [field]: { $ne: null } }, { $nor: [inner] }] };\n }\n }\n return { $nor: [inner] };\n }\n // Raw escape hatch — a plain Mongo filter object, used as-is.\n return node as Query;\n }\n return undefined;\n}\n\n/** Translate a filter (tree / node / flat array / raw) into a single Mongo query. */\nexport function buildWhere(model: AnyModel, filter?: Filter): Query | undefined {\n if (filter === undefined) return undefined;\n // Array elements go through buildNode (not buildCondition) so a flat array may\n // also hold logical groups / raw nodes (implicit AND), matching drizzle-pg.\n if (Array.isArray(filter))\n return combine(\n \"$and\",\n filter.map(c => buildNode(model, c)),\n );\n return buildNode(model, filter);\n}\n","import type { Sort } from \"../types\";\nimport { resolveField, hasPath, type AnyModel } from \"./fields\";\n\n/** A Mongo sort spec, e.g. `{ name: 1, createdAt: -1 }`. */\nexport type SortSpec = Record<string, 1 | -1>;\n\ninterface NormalizedSort {\n key: string;\n direction: \"asc\" | \"desc\";\n}\n\n/** Sort is always a `{ key, direction }[]` array → a flat normalized list (empty keys skipped). */\nfunction normalize(sort?: Sort): NormalizedSort[] {\n if (!sort) return [];\n return sort.filter(item => item && item.key).map(item => ({ key: item.key, direction: item.direction ?? \"asc\" }));\n}\n\n/**\n * Build a Mongo sort spec from the sort input. Unknown fields are skipped; when\n * nothing valid remains, defaults to newest-first (`createdAt` desc, else `_id`).\n */\nexport function buildSort(model: AnyModel, sort?: Sort): SortSpec {\n const spec: SortSpec = {};\n for (const item of normalize(sort)) {\n const field = resolveField(model, item.key);\n if (field) spec[field] = item.direction === \"desc\" ? -1 : 1;\n }\n if (Object.keys(spec).length === 0) {\n if (hasPath(model, \"createdAt\")) spec.createdAt = -1;\n else spec._id = -1;\n }\n return spec;\n}\n","/**\n * Opaque cursor tokens for keyset pagination. A token is the base64url encoding\n * of `{ v: <cursor field value> }`. Dates/ObjectIds are preserved as strings and\n * re-cast to the field's type on decode (see `castValue`).\n */\n\ninterface CursorPayload {\n v: unknown;\n}\n\nexport function encodeCursor(value: unknown): string {\n const normalized = value instanceof Date ? value.toISOString() : value;\n const json = JSON.stringify({ v: normalized } satisfies CursorPayload);\n return Buffer.from(json, \"utf8\").toString(\"base64url\");\n}\n\nexport function decodeCursor(cursor?: string | null): unknown | undefined {\n if (!cursor) return undefined;\n try {\n const json = Buffer.from(cursor, \"base64url\").toString(\"utf8\");\n const payload = JSON.parse(json) as CursorPayload;\n return payload.v;\n } catch {\n return undefined;\n }\n}\n","import type { ClientSession, Model } from \"mongoose\";\n\nimport type {\n AggregateRow,\n AggregateSpec,\n ByIdParams,\n CursorParams,\n CursorResult,\n FieldCondition,\n FieldKey,\n Filter,\n Id,\n InfiniteParams,\n InfiniteResult,\n Insert,\n OffsetParams,\n OffsetResult,\n QueryParams,\n Repository,\n Row,\n Scope,\n Sort,\n SortDirection,\n UpsertOptions,\n} from \"./types\";\nimport { resolveField, hasPath, castValue, type AnyModel } from \"./internal/fields\";\nimport { buildWhere, type Query } from \"./internal/where\";\nimport { buildSort } from \"./internal/order-by\";\nimport { encodeCursor, decodeCursor } from \"./internal/cursor\";\n\n/** Registry-level runtime injected into every repository. */\nexport interface RepoRuntime {\n /** Active transaction session, if any. */\n getSession: () => ClientSession | undefined;\n defaultPerPage: number;\n defaultLimit: number;\n}\n\n/** Per-repository configuration (scope). */\nexport interface RepoConfig<TDoc> {\n scope?: Scope<TDoc>;\n}\n\n// Mongoose's Query generics are extremely deep; we drive queries untyped\n// internally (the public Repository surface stays fully typed) and cast results.\n\ntype AnyQuery = any;\n\n/**\n * Build a model-scoped repository. `runtime` (session getter + defaults) comes\n * from the registry, so this file never touches the connection directly.\n */\nexport function buildRepository<TDoc>(runtime: RepoRuntime, model: Model<TDoc>, config: RepoConfig<TDoc> = {}): Repository<TDoc> {\n const m = model as AnyModel;\n const hasDeletedAt = hasPath(m, \"deletedAt\");\n // Mongoose auto-bumps `updatedAt` only when the schema opts into timestamps;\n // for a manual `updatedAt` path we stamp it ourselves so every update path\n // bumps it — matching drizzle-pg's forUpdate.\n const timestampsOn = Boolean((m.schema as { options?: { timestamps?: unknown } }).options?.timestamps);\n const stampUpdatedAt = hasPath(m, \"updatedAt\") && !timestampsOn;\n const forUpdate = <T extends object>(patch: T): T => (stampUpdatedAt ? { ...patch, updatedAt: new Date() } : patch);\n\n // Scope → equality conditions applied to every query (as a flat filter).\n const scopeConditions: FieldCondition[] = config.scope\n ? Object.entries(config.scope).map(([key, value]) => ({ key, operation: \"=\", value: value as never }))\n : [];\n const scopeWhere = scopeConditions.length ? buildWhere(m, scopeConditions) : undefined;\n\n const sortSpec = (sort?: Sort<TDoc>): Record<string, 1 | -1> => buildSort(m, sort as Sort | undefined);\n\n /** Compose user filter + scope + soft-delete guard into one Mongo query. */\n const composeWhere = (userFilter?: Filter<TDoc>, withDeleted?: boolean): Query => {\n const parts = [buildWhere(m, userFilter as Filter | undefined), scopeWhere, hasDeletedAt && !withDeleted ? { deletedAt: { $eq: null } } : undefined].filter(\n (p): p is Query => p !== undefined,\n );\n if (parts.length === 0) return {};\n if (parts.length === 1) return parts[0]!;\n return { $and: parts };\n };\n\n /** Merge an id predicate into a filter as AND. */\n const withId = (filter: Filter<TDoc> | undefined, idKey: string, id: Id): Filter<TDoc> => {\n const idCondition: FieldCondition<TDoc> = { key: idKey as FieldKey<TDoc>, operation: \"=\", value: id as never };\n if (!filter) return [idCondition];\n if (Array.isArray(filter)) return [...filter, idCondition];\n return { and: [filter, idCondition] };\n };\n\n /**\n * Column selection → Mongo projection, or undefined when empty. Adds `_id: 0`\n * unless the caller selected `id`/`_id`, so the runtime shape matches the\n * inferred `Pick<...>` type (Mongo otherwise always returns `_id`). Returns\n * undefined (full doc) when no requested column resolves.\n */\n const projection = (columns?: QueryParams<TDoc>[\"columns\"]): Record<string, 0 | 1> | undefined => {\n if (!columns) return undefined;\n const keys = Object.keys(columns).filter(k => (columns as Record<string, boolean>)[k]);\n if (keys.length === 0) return undefined;\n const proj: Record<string, 0 | 1> = {};\n let includesId = false;\n for (const k of keys) {\n const field = resolveField(m, k);\n if (!field) continue;\n proj[field] = 1;\n if (field === \"_id\") includesId = true;\n }\n if (Object.keys(proj).length === 0) return undefined; // all unknown → full doc\n if (!includesId) proj._id = 0; // exclude _id unless explicitly selected (exact columns, like drizzle)\n return proj;\n };\n\n const applyPopulate = (q: AnyQuery, withRel?: QueryParams<TDoc>[\"with\"]): AnyQuery => {\n if (withRel) {\n for (const key of Object.keys(withRel)) {\n const value = (withRel as Record<string, unknown>)[key];\n if (!value) continue;\n // `true` → populate the field; an object → pass through as populate options\n // (`{ author: { select: \"name\" } }` → `.populate({ path, select })`).\n q.populate(typeof value === \"object\" ? { path: key, ...(value as object) } : key);\n }\n }\n return q;\n };\n\n const attachSession = (q: AnyQuery): AnyQuery => {\n const s = runtime.getSession();\n if (s) q.session(s);\n return q;\n };\n\n const toArr = <T>(v?: T | T[]): T[] => (v === undefined ? [] : Array.isArray(v) ? v : [v]);\n\n /** Apply scope defaults to insert values — scope wins (can't be overridden). */\n const forInsert = (values: object): Record<string, unknown> => ({\n ...(config.scope as object),\n ...values,\n ...(config.scope as object),\n });\n\n /** Build the `{filter, update}` for an upsert (target → filter, rest → $set/$setOnInsert). */\n const buildUpsert = (values: Insert<TDoc>, options: UpsertOptions<TDoc>) => {\n const targetKeys = toArr(options.target) as string[];\n const inserted = forInsert(values);\n const filter: Record<string, unknown> = {};\n for (const key of targetKeys) {\n const field = resolveField(m, key);\n if (!field) throw new Error(`upsert: unknown target field \"${key}\".`);\n filter[field] = inserted[key];\n }\n // $set (applied on insert + conflict) defaults to values minus target keys.\n const set: Record<string, unknown> = options.set\n ? { ...(options.set as Record<string, unknown>) }\n : Object.fromEntries(Object.entries(inserted).filter(([k]) => !targetKeys.includes(k)));\n // $setOnInsert (insert only) = remaining non-target values not already in $set.\n const setOnInsert = Object.fromEntries(Object.entries(inserted).filter(([k]) => !targetKeys.includes(k) && !(k in set)));\n const update: Record<string, unknown> = {};\n if (Object.keys(set).length) update.$set = set;\n if (Object.keys(setOnInsert).length) update.$setOnInsert = setOnInsert;\n return { filter, update };\n };\n\n interface FindOpts {\n sort?: Record<string, 1 | -1>;\n columns?: QueryParams<TDoc>[\"columns\"];\n with?: QueryParams<TDoc>[\"with\"];\n limit?: number;\n skip?: number;\n }\n\n const runFind = (where: Query, opts: FindOpts): Promise<unknown[]> => {\n let q: AnyQuery = m.find(where, projection(opts.columns));\n if (opts.sort) q = q.sort(opts.sort);\n if (typeof opts.skip === \"number\") q = q.skip(opts.skip);\n if (typeof opts.limit === \"number\") q = q.limit(opts.limit);\n q = applyPopulate(q, opts.with);\n return attachSession(q).lean().exec() as Promise<unknown[]>;\n };\n\n const countWhere = (where: Query): Promise<number> => attachSession(m.countDocuments(where)).exec() as Promise<number>;\n\n const repository = {\n model,\n\n async findAll(params: QueryParams<TDoc> = {}) {\n const rows = await runFind(composeWhere(params.filter, params.withDeleted), {\n sort: sortSpec(params.sort),\n columns: params.columns,\n with: params.with,\n });\n return rows as never;\n },\n\n async findOne(params: QueryParams<TDoc> = {}) {\n let q: AnyQuery = m.findOne(composeWhere(params.filter, params.withDeleted), projection(params.columns));\n q = q.sort(sortSpec(params.sort));\n q = applyPopulate(q, params.with);\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as never;\n },\n\n async findById(id: Id, params: ByIdParams<TDoc> = {}) {\n const { idKey = \"id\", filter, columns, with: withRel } = params;\n let q: AnyQuery = m.findOne(composeWhere(withId(filter, idKey as string, id), params.withDeleted), projection(columns));\n q = applyPopulate(q, withRel);\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as never;\n },\n\n async findList(params: OffsetParams<TDoc> = {}) {\n const page = Math.max(1, Math.trunc(params.page ?? 1));\n const perPage = Math.max(1, Math.trunc(params.perPage ?? runtime.defaultPerPage));\n const where = composeWhere(params.filter, params.withDeleted);\n\n const [data, total_items] = await Promise.all([\n runFind(where, { sort: sortSpec(params.sort), columns: params.columns, with: params.with, limit: perPage, skip: (page - 1) * perPage }),\n countWhere(where),\n ]);\n\n const total_pages = Math.ceil(total_items / perPage);\n return {\n data,\n meta: {\n total_items,\n total_pages,\n current_page: page,\n per_page: perPage,\n has_next: page < total_pages,\n has_prev: page > 1,\n },\n } as OffsetResult<never>;\n },\n\n async findInfinite(params: InfiniteParams<TDoc> = {}) {\n const limit = Math.max(1, Math.trunc(params.limit ?? runtime.defaultLimit));\n const offset = Math.max(0, Math.trunc(params.offset ?? 0));\n\n const rows = await runFind(composeWhere(params.filter, params.withDeleted), {\n sort: sortSpec(params.sort),\n columns: params.columns,\n with: params.with,\n limit: limit + 1,\n skip: offset,\n });\n\n const has_more = rows.length > limit;\n const data = has_more ? rows.slice(0, limit) : rows;\n return {\n data,\n meta: { limit, offset, count: data.length, has_more, next_offset: has_more ? offset + limit : null },\n } as InfiniteResult<never>;\n },\n\n async findCursor(params: CursorParams<TDoc> = {}) {\n const limit = Math.max(1, Math.trunc(params.limit ?? runtime.defaultLimit));\n const cursorKey = (params.cursorKey ?? \"id\") as string;\n const order: SortDirection = params.order ?? \"asc\";\n const direction = params.direction ?? \"forward\";\n\n const field = resolveField(m, cursorKey);\n if (!field) throw new Error(`findCursor: unknown cursorKey \"${cursorKey}\".`);\n\n const decoded = decodeCursor(params.cursor);\n const cursorValue = decoded !== undefined ? castValue(m, field, decoded) : undefined;\n const baseWhere = composeWhere(params.filter, params.withDeleted);\n\n const ascInQuery = direction === \"forward\" ? order === \"asc\" : order === \"desc\";\n const seek: Query | undefined = cursorValue !== undefined ? { [field]: ascInQuery ? { $gt: cursorValue } : { $lt: cursorValue } } : undefined;\n const where: Query = seek ? (Object.keys(baseWhere).length ? { $and: [baseWhere, seek] } : seek) : baseWhere;\n\n // Force-include the cursor field in the projection so next/prev tokens work.\n const selected = projection(params.columns);\n const proj = selected ? { ...selected, [field]: 1 } : undefined;\n\n let q: AnyQuery = m\n .find(where, proj)\n .sort({ [field]: ascInQuery ? 1 : -1 })\n .limit(limit + 1);\n q = applyPopulate(q, params.with);\n const rows = (await attachSession(q).lean().exec()) as Record<string, unknown>[];\n\n const hasExtra = rows.length > limit;\n let pageRows = hasExtra ? rows.slice(0, limit) : rows;\n if (direction === \"backward\") pageRows = [...pageRows].reverse();\n\n const first = pageRows[0];\n const last = pageRows[pageRows.length - 1];\n\n const has_next = direction === \"forward\" ? hasExtra : cursorValue !== undefined;\n const has_prev = direction === \"forward\" ? cursorValue !== undefined : hasExtra;\n\n return {\n data: pageRows,\n meta: {\n limit,\n has_next,\n has_prev,\n next_cursor: has_next && last ? encodeCursor(last[field]) : null,\n prev_cursor: has_prev && first ? encodeCursor(first[field]) : null,\n },\n } as CursorResult<never>;\n },\n\n count(filter?: Filter<TDoc>) {\n return countWhere(composeWhere(filter));\n },\n\n async exists(filter?: Filter<TDoc>) {\n return (await countWhere(composeWhere(filter))) > 0;\n },\n\n /* ------------------------------- writes ------------------------------- */\n\n async create(values: Insert<TDoc>) {\n const [doc] = await m.create([forInsert(values)], { session: runtime.getSession() });\n return doc!.toObject() as Row<TDoc>;\n },\n\n async createMany(values: Insert<TDoc>[]) {\n if (values.length === 0) return [];\n const docs = await m.insertMany(values.map(forInsert), { session: runtime.getSession() });\n return docs.map((d: { toObject: () => unknown }) => d.toObject()) as Row<TDoc>[];\n },\n\n async upsert(values: Insert<TDoc>, options: UpsertOptions<TDoc>) {\n const { filter, update } = buildUpsert(values, options);\n const q: AnyQuery = m.findOneAndUpdate(filter, update, { returnDocument: \"after\", upsert: true });\n return (await attachSession(q).lean().exec()) as Row<TDoc>;\n },\n\n async upsertMany(values: Insert<TDoc>[], options: UpsertOptions<TDoc>) {\n if (values.length === 0) return [];\n const CHUNK = 1000;\n const entries = values.map(v => buildUpsert(v, options)); // input order preserved\n for (let i = 0; i < entries.length; i += CHUNK) {\n const ops = entries.slice(i, i + CHUNK).map(e => ({ updateOne: { filter: e.filter, update: e.update, upsert: true } }));\n await m.bulkWrite(ops, { session: runtime.getSession() });\n }\n // Re-fetch affected rows and return them in INPUT order (matches drizzle's\n // `.returning()`), keyed by the resolved target field(s).\n const rows = (await attachSession(m.find({ $or: entries.map(e => e.filter) }))\n .lean()\n .exec()) as Record<string, unknown>[];\n const targetFields = (toArr(options.target) as string[]).map(k => resolveField(m, k)).filter((f): f is string => Boolean(f));\n const keyOf = (o: Record<string, unknown>): string => targetFields.map(f => String(o[f])).join(\"\u0000\");\n const byKey = new Map(rows.map(r => [keyOf(r), r]));\n return entries.map(e => byKey.get(keyOf(e.filter))).filter((r): r is Record<string, unknown> => Boolean(r)) as Row<TDoc>[];\n },\n\n async updateById(id: Id, patch: Partial<Insert<TDoc>>, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n const where = composeWhere(withId(undefined, idKey as string, id));\n const q: AnyQuery = m.findOneAndUpdate(where, forUpdate(patch), { returnDocument: \"after\" });\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async updateWhere(filter: Filter<TDoc>, patch: Partial<Insert<TDoc>>) {\n const where = composeWhere(filter);\n const found = (await attachSession(m.find(where).select({ _id: 1 }))\n .lean()\n .exec()) as { _id: unknown }[];\n if (found.length === 0) return [];\n const ids = found.map(d => d._id);\n await attachSession(m.updateMany({ _id: { $in: ids } }, forUpdate(patch))).exec();\n return (await attachSession(m.find({ _id: { $in: ids } }))\n .lean()\n .exec()) as Row<TDoc>[];\n },\n\n async deleteById(id: Id, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n const where = composeWhere(withId(undefined, idKey as string, id));\n const row = await attachSession(m.findOneAndDelete(where)).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async deleteWhere(filter: Filter<TDoc>) {\n const where = composeWhere(filter);\n const rows = (await attachSession(m.find(where)).lean().exec()) as { _id: unknown }[];\n if (rows.length === 0) return [];\n await attachSession(m.deleteMany({ _id: { $in: rows.map(d => d._id) } })).exec();\n return rows as Row<TDoc>[];\n },\n\n async softDelete(id: Id, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n if (!hasDeletedAt) throw new Error(\"softDelete: schema has no deletedAt path.\");\n const where = composeWhere(withId(undefined, idKey as string, id), false);\n const q: AnyQuery = m.findOneAndUpdate(where, forUpdate({ deletedAt: new Date() }), { returnDocument: \"after\" });\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async restore(id: Id, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n if (!hasDeletedAt) throw new Error(\"restore: schema has no deletedAt path.\");\n const where = composeWhere(withId(undefined, idKey as string, id), true);\n const q: AnyQuery = m.findOneAndUpdate(where, forUpdate({ deletedAt: null }), { returnDocument: \"after\" });\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async aggregate(spec: AggregateSpec<TDoc>) {\n const groupKeys = toArr(spec.groupBy) as string[];\n // Aggregate `$match` doesn't auto-cast values the way `find()` does; cast\n // the filter against the schema so wire strings (dates / ObjectIds) become\n // proper BSON types — keeping aggregate filters consistent with reads.\n const rawMatch = composeWhere(spec.filter, spec.withDeleted);\n let match: Record<string, unknown> = rawMatch;\n try {\n const q = m.find(rawMatch);\n q.cast(m);\n match = q.getFilter();\n } catch {\n /* fall back to the uncast filter */\n }\n const groupId = groupKeys.length ? Object.fromEntries(groupKeys.map(k => [k, `$${resolveField(m, k) ?? k}`])) : null;\n const group: Record<string, unknown> = { _id: groupId };\n if (spec.count) group.count = { $sum: 1 };\n const addAgg = (op: \"$sum\" | \"$avg\" | \"$min\" | \"$max\", keys: string[], prefix: string) => {\n for (const k of keys) {\n const field = resolveField(m, k);\n if (field) group[`${prefix}_${k}`] = { [op]: `$${field}` };\n }\n };\n addAgg(\"$sum\", toArr(spec.sum) as string[], \"sum\");\n addAgg(\"$avg\", toArr(spec.avg) as string[], \"avg\");\n addAgg(\"$min\", toArr(spec.min) as string[], \"min\");\n addAgg(\"$max\", toArr(spec.max) as string[], \"max\");\n\n let agg = m.aggregate([{ $match: match }, { $group: group }] as never);\n const session = runtime.getSession();\n if (session) agg = agg.session(session);\n const rows = (await agg.exec()) as Record<string, unknown>[];\n // Flatten the group `_id` fields back into each row (matches drizzle's shape).\n return rows.map(({ _id, ...rest }) => ({ ...(typeof _id === \"object\" && _id ? _id : {}), ...rest })) as AggregateRow[];\n },\n\n scoped(scope: Scope<TDoc>) {\n return buildRepository(runtime, model, { ...config, scope: { ...config.scope, ...scope } });\n },\n };\n\n return repository as unknown as Repository<TDoc>;\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type { ClientSession } from \"mongoose\";\n\n/**\n * Per-transaction ambient state. Lets repositories pick up the active Mongo\n * `ClientSession` without threading it through every call. Set by\n * `registry.transaction`.\n */\nexport interface RepoContext {\n session?: ClientSession;\n}\n\nexport interface ContextStore {\n /** Read the current ambient context (undefined outside any `run`). */\n get(): RepoContext | undefined;\n /** Run `fn` with `patch` merged over the current context. */\n run<T>(patch: RepoContext, fn: () => T): T;\n}\n\nexport function createContextStore(): ContextStore {\n const als = new AsyncLocalStorage<RepoContext>();\n return {\n get: () => als.getStore(),\n run: (patch, fn) => als.run({ ...als.getStore(), ...patch }, fn),\n };\n}\n","import type { Connection, Model } from \"mongoose\";\nimport { DEFAULT_LIMIT, DEFAULT_PER_PAGE } from \"@querykitjs/core\";\n\nimport type { RelationDocs, RelationMap, Registry, RegistryOptions, Repository, RepositoryExtender, RepositoryOptions } from \"./types\";\nimport { buildRepository, type RepoRuntime } from \"./repository\";\nimport { createContextStore } from \"./internal/context\";\n\n/**\n * Create the DB **registry** once. It holds the Mongoose connection (for\n * transactions) and yields a {@link Repository} per model. Transactions flow\n * ambiently via AsyncLocalStorage — repositories used inside\n * `registry.transaction(...)` automatically run on that session.\n *\n * @param connection - the Mongoose `Connection` the models belong to.\n * @param options - `defaultPerPage` (findList) / `defaultLimit` (infinite/cursor);\n * defaults to `@querykitjs/core`'s `DEFAULT_PER_PAGE` / `DEFAULT_LIMIT` (20).\n * @example\n * ```ts\n * const registry = createRegistry(mongoose.connection);\n * const usersRepo = registry.repository(User);\n * ```\n */\nexport function createRegistry(connection: Connection, options: RegistryOptions = {}): Registry {\n const ctx = createContextStore();\n const runtime: RepoRuntime = {\n getSession: () => ctx.get()?.session,\n defaultPerPage: options.defaultPerPage ?? DEFAULT_PER_PAGE,\n defaultLimit: options.defaultLimit ?? DEFAULT_LIMIT,\n };\n\n function repository<TDoc>(model: Model<TDoc>): Repository<TDoc>;\n function repository<TDoc, TExt extends Record<string, unknown>>(\n model: Model<TDoc>,\n extend: RepositoryExtender<TDoc, Record<never, never>, TExt>,\n ): Repository<TDoc> & TExt;\n function repository<TDoc, TRel extends RelationMap>(model: Model<TDoc>, options: RepositoryOptions<TRel>): Repository<TDoc, RelationDocs<TRel>>;\n function repository<TDoc, TRel extends RelationMap, TExt extends Record<string, unknown>>(\n model: Model<TDoc>,\n options: RepositoryOptions<TRel>,\n extend: RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>,\n ): Repository<TDoc, RelationDocs<TRel>> & TExt;\n function repository<TDoc, TRel extends RelationMap, TExt extends Record<string, unknown>>(\n model: Model<TDoc>,\n arg2?: RepositoryOptions<TRel> | RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>,\n arg3?: RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>,\n ) {\n // 2nd arg is either the relations options object or the extender fn.\n // `relations` is type-only (drives `with` inference); runtime populate is\n // opt-in per call, so nothing to wire from it here.\n const extend = typeof arg2 === \"function\" ? arg2 : arg3;\n const base = buildRepository(runtime, model) as unknown as Repository<TDoc, RelationDocs<TRel>>;\n return extend ? { ...base, ...extend(base) } : base;\n }\n\n const transaction = async <T>(fn: () => Promise<T>): Promise<T> => {\n // Already inside a transaction (Mongo has no nested tx/savepoints) → reuse it.\n if (ctx.get()?.session) return fn();\n\n const session = await connection.startSession();\n try {\n let result!: T;\n await session.withTransaction(async () => {\n result = await ctx.run({ session }, fn);\n });\n return result;\n } finally {\n await session.endSession();\n }\n };\n\n return { repository, transaction };\n}\n","import { createFilters as coreCreateFilters, f } from \"@querykitjs/core\";\n\nimport type { FieldKey, RawFilter } from \"./types\";\n\n/**\n * Typed, ergonomic filter builders for a document type (field-name autocomplete).\n * A thin wrapper over `@querykitjs/core`'s builder — the key type is the model's\n * field key, the raw escape-hatch is a native Mongo `QueryFilter`.\n *\n * @example\n * ```ts\n * const uf = createFilters<IUser>();\n * await usersRepo.findAll({ filter: uf.and(uf.eq(\"status\", \"active\"), uf.gte(\"age\", 18)) });\n * ```\n */\nexport function createFilters<TDoc>() {\n return coreCreateFilters<FieldKey<TDoc>, RawFilter<TDoc>>();\n}\n\n/** Untyped filter helpers for quick use. */\nexport { f };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/fields.ts","../src/internal/coerce.ts","../src/internal/diagnostics.ts","../src/internal/operators.ts","../src/internal/where.ts","../src/internal/order-by.ts","../src/internal/cursor.ts","../src/repository.ts","../src/internal/context.ts","../src/registry.ts","../src/filters.ts"],"names":["TEXT_FILTER_OPERATORS","cast","QueryKitError","f","AsyncLocalStorage","DEFAULT_PER_PAGE","DEFAULT_LIMIT","DEFAULT_MAX_PER_PAGE","DEFAULT_MAX_LIMIT","coreCreateFilters"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Model } from \"mongoose\";\n\n/** Any Mongoose model, regardless of its document type. */\nexport type AnyModel = Model<any>;\n\n/**\n * Map a public field key to a real Mongoose schema path. `\"id\"` is aliased to\n * `\"_id\"` so the wire contract stays identical across adapters. Unknown fields\n * return `undefined` (the caller skips them silently, like the Drizzle adapter).\n */\nexport function resolveField(model: AnyModel, key: string): string | undefined {\n const name = key === \"id\" ? \"_id\" : key;\n if (name === \"_id\") return \"_id\";\n return model.schema.path(name) ? name : undefined;\n}\n\n/** Whether the schema has a given path (e.g. `deletedAt`, `updatedAt`). */\nexport function hasPath(model: AnyModel, path: string): boolean {\n return Boolean(model.schema.path(path));\n}\n\n/**\n * Cast a raw (decoded cursor) value to the field's schema type so keyset\n * comparisons (`$gt`/`$lt`) work — e.g. a hex string → `ObjectId`, an ISO\n * string → `Date`. Falls back to the raw value if casting fails.\n */\nexport function castValue(model: AnyModel, field: string, value: unknown): unknown {\n const path = model.schema.path(field);\n if (!path) return value;\n try {\n return path.cast(value);\n } catch {\n return value;\n }\n}\n","import { TEXT_FILTER_OPERATORS } from \"@querykitjs/core\";\n\nimport type { FilterOperator, FilterValue } from \"../types\";\nimport type { AnyModel } from \"./fields\";\n\n/**\n * Operators whose value is a text pattern — never cast. A `$regex` fragment must\n * keep the caller's raw string even on a `Date` path. The list lives in\n * `@querykitjs/core` so both adapters share it.\n */\nconst TEXT_OPERATORS: ReadonlySet<FilterOperator> = new Set(TEXT_FILTER_OPERATORS);\n\n/**\n * Returned when a value cannot be represented in the path's type (e.g. the\n * string `\"not-a-date\"` on a `Date` path). Callers drop the condition — the same\n * contract `operators.ts` already uses for a non-array `in` value, and the same\n * symbol-based contract the drizzle adapter uses.\n */\nexport const INVALID_VALUE = Symbol(\"querykit.invalid-value\");\n\n/** Whether this operator compares against a text pattern (`like`, `contains`, …). */\nexport const isTextOperator = (operator: FilterOperator): boolean => TEXT_OPERATORS.has(operator);\n\n/** Whether a schema path stores a `Date` (the only type both adapters cast locally). */\nexport function isDatePath(model: AnyModel, field: string): boolean {\n return model.schema.path(field)?.instance === \"Date\";\n}\n\n/**\n * Cast a single wire value to the path's type, or report it as uncastable.\n *\n * Scoped to `Date` paths **on purpose**, so both adapters behave identically:\n * drizzle can only judge columns it maps through JS (`dataType: \"date\"`) and\n * leaves everything else to Postgres, so mongoose likewise leaves other paths to\n * its own query cast. Mongoose casts these values itself when the query runs;\n * doing it here keeps the behaviour pinned by tests instead of relying on\n * mongoose internals, and turns a cryptic `CastError` 500 into a skipped\n * condition (observable via `onSkippedCondition`).\n */\nexport function castForPath(model: AnyModel, field: string, value: unknown): unknown | typeof INVALID_VALUE {\n const path = model.schema.path(field);\n if (!path || path.instance !== \"Date\" || value === null || value === undefined) return value;\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? INVALID_VALUE : value;\n try {\n const cast = path.cast(value) as unknown;\n if (cast instanceof Date) return Number.isNaN(cast.getTime()) ? INVALID_VALUE : cast;\n return cast ?? INVALID_VALUE;\n } catch {\n return INVALID_VALUE;\n }\n}\n\n/**\n * Bring one condition's value in line with the path's type before it reaches an\n * operator builder — the mongoose counterpart of the drizzle adapter's\n * `coerceCondition`, with the same signature shape, the same text-operator\n * carve-out and the same all-or-nothing rule for arrays/tuples.\n */\nexport function coerceCondition(\n model: AnyModel,\n field: string,\n operator: FilterOperator,\n value: FilterValue | undefined,\n): FilterValue | undefined | typeof INVALID_VALUE {\n if (value === undefined || TEXT_OPERATORS.has(operator)) return value;\n\n if (Array.isArray(value)) {\n const items: unknown[] = [];\n for (const item of value) {\n const cast = castForPath(model, field, item);\n if (cast === INVALID_VALUE) return INVALID_VALUE;\n items.push(cast);\n }\n return items as FilterValue;\n }\n\n const cast = castForPath(model, field, value);\n return cast === INVALID_VALUE ? INVALID_VALUE : (cast as FilterValue);\n}\n","import { QueryKitError, type SkippedCondition } from \"@querykitjs/core\";\n\n/**\n * Per-repository diagnostics channel. The compilers (`where`, `order-by`) drop\n * conditions they cannot resolve — good for db-service parity, but a typo in a\n * filter key then makes an endpoint return **more** documents than intended,\n * silently. This makes each drop either visible (`onSkipped`) or fatal (`strict`).\n *\n * Identical to the drizzle-pg adapter's `Diagnostics`, and `SkippedCondition` /\n * `QueryKitError` come from core — so both backends report identically.\n */\nexport interface Diagnostics {\n /** Model name (drizzle: table name), for the report. */\n source: string;\n /** Throw `QueryKitError` instead of dropping the condition. Default `false`. */\n strict: boolean;\n onSkipped?: (info: SkippedCondition) => void;\n}\n\n/**\n * Report a dropped condition. `strict` turns it into a `QueryKitError` the\n * backend can map to a 400; otherwise the hook is called and the condition is\n * dropped exactly as before — the default path stays byte-for-byte unchanged.\n */\nexport function reportSkip(diag: Diagnostics | undefined, info: Omit<SkippedCondition, \"source\">): void {\n if (!diag) return;\n const full: SkippedCondition = { ...info, source: diag.source };\n if (diag.strict) throw new QueryKitError(full);\n diag.onSkipped?.(full);\n}\n","import type { FilterOperator, FilterValue } from \"../types\";\n\n/** A field-level Mongo fragment, e.g. `{ $gte: 1, $lte: 9 }`. `undefined` = drop. */\ntype Fragment = Record<string, unknown> | undefined;\ntype Builder = (value: FilterValue | undefined) => Fragment;\n\n/** Escape a literal string for use inside a regex (contains/startsWith/endsWith). */\nconst esc = (s: unknown): string => String(s ?? \"\").replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/** Translate a SQL LIKE pattern (`%` → any, `_` → one char) to an anchored regex. */\nconst sqlLikeToRegex = (pattern: unknown): string => {\n let out = \"\";\n for (const ch of String(pattern ?? \"\")) {\n if (ch === \"%\") out += \".*\";\n else if (ch === \"_\") out += \".\";\n else out += ch.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n }\n return `^${out}$`;\n};\n\nconst asTuple = (v: FilterValue | undefined): [unknown, unknown] | undefined => (Array.isArray(v) && v.length === 2 ? [v[0], v[1]] : undefined);\n\n/**\n * Operator → Mongo fragment map. Mirrors the Drizzle adapter's semantics: both\n * token (`\"%_%\"`) and name-alias (`\"contains\"`) forms are handled;\n * `contains/startsWith/endsWith` are case-insensitive; invalid values (non-array\n * `in`, non-2-tuple `between`) drop the condition (`undefined`).\n */\nexport const operators: Record<FilterOperator, Builder> = {\n \"=\": v => ({ $eq: v }),\n eq: v => ({ $eq: v }),\n // SQL three-valued logic: inequality/negation excludes NULL (and missing) rows,\n // matching drizzle-pg. `$nin: [v, null]` = \"not v AND not null\".\n \"!=\": v => ({ $nin: [v, null] }),\n ne: v => ({ $nin: [v, null] }),\n \">\": v => ({ $gt: v }),\n gt: v => ({ $gt: v }),\n \">=\": v => ({ $gte: v }),\n gte: v => ({ $gte: v }),\n \"<\": v => ({ $lt: v }),\n lt: v => ({ $lt: v }),\n \"<=\": v => ({ $lte: v }),\n lte: v => ({ $lte: v }),\n\n contains: v => ({ $regex: esc(v), $options: \"i\" }),\n \"%_%\": v => ({ $regex: esc(v), $options: \"i\" }),\n startsWith: v => ({ $regex: `^${esc(v)}`, $options: \"i\" }),\n \"%_\": v => ({ $regex: `^${esc(v)}`, $options: \"i\" }),\n endsWith: v => ({ $regex: `${esc(v)}$`, $options: \"i\" }),\n \"_%\": v => ({ $regex: `${esc(v)}$`, $options: \"i\" }),\n\n like: v => ({ $regex: sqlLikeToRegex(v) }),\n ilike: v => ({ $regex: sqlLikeToRegex(v), $options: \"i\" }),\n // negation also excludes NULL/missing (SQL `NOT LIKE` semantics).\n notLike: v => ({ $not: { $regex: sqlLikeToRegex(v) }, $ne: null }),\n\n in: v => (Array.isArray(v) ? { $in: v } : undefined),\n notIn: v => (Array.isArray(v) ? { $nin: [...v, null] } : undefined),\n\n between: v => {\n const t = asTuple(v);\n return t ? { $gte: t[0], $lte: t[1] } : undefined;\n },\n notBetween: v => {\n const t = asTuple(v);\n return t ? { $not: { $gte: t[0], $lte: t[1] }, $ne: null } : undefined;\n },\n\n isNull: () => ({ $eq: null }),\n isNotNull: () => ({ $ne: null }),\n};\n","import type { Filter, FieldCondition, FilterNode } from \"../types\";\nimport { coerceCondition, INVALID_VALUE, isDatePath, isTextOperator } from \"./coerce\";\nimport { reportSkip, type Diagnostics } from \"./diagnostics\";\nimport { operators } from \"./operators\";\nimport { resolveField, type AnyModel } from \"./fields\";\n\n/** A Mongo filter query object. */\nexport type Query = Record<string, unknown>;\n\nconst isObject = (n: unknown): n is Record<string, unknown> => typeof n === \"object\" && n !== null;\n\nconst isFieldCondition = (n: unknown): n is FieldCondition => isObject(n) && \"key\" in n && !(\"and\" in n) && !(\"or\" in n) && !(\"not\" in n);\n\n/** Combine parts (dropping `undefined`): 0 → undefined, 1 → the part, else `$and`/`$or`. */\nfunction combine(kind: \"$and\" | \"$or\", parts: (Query | undefined)[]): Query | undefined {\n const valid = parts.filter((p): p is Query => p !== undefined);\n if (valid.length === 0) return undefined;\n if (valid.length === 1) return valid[0];\n return { [kind]: valid };\n}\n\nfunction buildCondition(model: AnyModel, cond: FieldCondition, diag?: Diagnostics): Query | undefined {\n const operator = cond.operation ?? \"=\";\n const build = operators[operator];\n if (!build) throw new Error(`Unsupported filter operator: \"${operator}\"`);\n\n const field = resolveField(model, cond.key);\n if (!field) {\n // Unknown field → skip. Usually a typo, and a dropped filter widens the\n // result set rather than narrowing it, so it is worth reporting.\n reportSkip(diag, { site: \"filter\", key: cond.key, operation: operator, reason: \"unknown-key\" });\n return undefined;\n }\n\n // A text pattern cannot be matched against a Date path: Mongo rejects\n // `$regex`/`$options` on a Date (\"Can't use $options with Date\"), which used to\n // surface as a 500. Drizzle can do it (Postgres renders the timestamp as text\n // and ILIKEs it), so exact result parity is not reachable here — the rendered\n // forms differ. Skipping keeps both adapters non-crashing and makes the\n // difference observable via `onSkippedCondition` instead of a stack trace.\n if (isTextOperator(operator) && isDatePath(model, field)) {\n reportSkip(diag, { site: \"filter\", key: cond.key, operation: operator, reason: \"invalid-value\" });\n return undefined;\n }\n\n // Cast wire (JSON) values to the path's type first, matching the drizzle\n // adapter — text-pattern operators keep their raw string.\n const value = coerceCondition(model, field, operator, cond.value);\n if (value === INVALID_VALUE) {\n reportSkip(diag, { site: \"filter\", key: cond.key, operation: operator, reason: \"invalid-value\" });\n return undefined;\n }\n\n const fragment = build(value);\n if (fragment === undefined) {\n // The operator rejected the value shape (a non-array `in`, a non-2-tuple\n // `between`) — same class of problem as an uncastable value.\n reportSkip(diag, { site: \"filter\", key: cond.key, operation: operator, reason: \"invalid-value\" });\n return undefined;\n }\n return { [field]: fragment };\n}\n\nfunction buildNode(model: AnyModel, node: FilterNode, diag?: Diagnostics): Query | undefined {\n if (isFieldCondition(node)) return buildCondition(model, node, diag);\n if (isObject(node)) {\n if (\"and\" in node)\n return combine(\n \"$and\",\n (node.and as FilterNode[]).map(n => buildNode(model, n, diag)),\n );\n if (\"or\" in node)\n return combine(\n \"$or\",\n (node.or as FilterNode[]).map(n => buildNode(model, n, diag)),\n );\n if (\"not\" in node) {\n const notNode = node.not as FilterNode;\n const inner = buildNode(model, notNode, diag);\n if (!inner) return undefined;\n // SQL `NOT(pred)` drops NULL rows (three-valued logic), but Mongo `$nor`\n // includes null/missing. For a single-field comparison predicate, also\n // require the field non-null so results match drizzle. `isNull`/`isNotNull`\n // are two-valued (never NULL) → no guard, else `not(isNotNull)` would\n // wrongly return nothing. Multi-field `not` groups keep bare `$nor`.\n if (isFieldCondition(notNode)) {\n const op = notNode.operation ?? \"=\";\n if (op !== \"isNull\" && op !== \"isNotNull\") {\n const field = resolveField(model, notNode.key);\n if (field) return { $and: [{ [field]: { $ne: null } }, { $nor: [inner] }] };\n }\n }\n return { $nor: [inner] };\n }\n // Raw escape hatch — a plain Mongo filter object, used as-is.\n return node as Query;\n }\n return undefined;\n}\n\n/**\n * Translate a filter (tree / node / flat array / raw) into a single Mongo query.\n *\n * `diag` is optional: without it, unresolvable conditions are dropped silently\n * exactly as before; with it they are reported (or, in strict mode, throw).\n */\nexport function buildWhere(model: AnyModel, filter?: Filter, diag?: Diagnostics): Query | undefined {\n if (filter === undefined) return undefined;\n // Array elements go through buildNode (not buildCondition) so a flat array may\n // also hold logical groups / raw nodes (implicit AND), matching drizzle-pg.\n if (Array.isArray(filter))\n return combine(\n \"$and\",\n filter.map(c => buildNode(model, c, diag)),\n );\n return buildNode(model, filter, diag);\n}\n","import type { Sort } from \"../types\";\nimport { reportSkip, type Diagnostics } from \"./diagnostics\";\nimport { resolveField, hasPath, type AnyModel } from \"./fields\";\n\n/** A Mongo sort spec, e.g. `{ name: 1, createdAt: -1 }`. */\nexport type SortSpec = Record<string, 1 | -1>;\n\ninterface NormalizedSort {\n key: string;\n direction: \"asc\" | \"desc\";\n}\n\n/** Sort is always a `{ key, direction }[]` array → a flat normalized list (empty keys skipped). */\nfunction normalize(sort?: Sort): NormalizedSort[] {\n if (!sort) return [];\n return sort.filter(item => item && item.key).map(item => ({ key: item.key, direction: item.direction ?? \"asc\" }));\n}\n\n/**\n * Build a Mongo sort spec from the sort input. Unknown fields are skipped; when\n * nothing valid remains, defaults to newest-first (`createdAt` desc, else `_id`).\n */\nexport function buildSort(model: AnyModel, sort?: Sort, diag?: Diagnostics): SortSpec {\n const spec: SortSpec = {};\n for (const item of normalize(sort)) {\n const field = resolveField(model, item.key);\n if (field) spec[field] = item.direction === \"desc\" ? -1 : 1;\n // An unknown sort key falls back to the default order, so the list looks\n // \"unsorted\" to the caller with nothing in the log to explain it.\n else reportSkip(diag, { site: \"sort\", key: item.key, reason: \"unknown-key\" });\n }\n if (Object.keys(spec).length === 0) {\n if (hasPath(model, \"createdAt\")) spec.createdAt = -1;\n else spec._id = -1;\n }\n return spec;\n}\n","/**\n * Opaque cursor tokens for keyset pagination. A token is the base64url encoding\n * of `{ v: <cursor field value> }`. Dates/ObjectIds are preserved as strings and\n * re-cast to the field's type on decode (see `castValue`).\n */\n\ninterface CursorPayload {\n v: unknown;\n}\n\nexport function encodeCursor(value: unknown): string {\n const normalized = value instanceof Date ? value.toISOString() : value;\n const json = JSON.stringify({ v: normalized } satisfies CursorPayload);\n return Buffer.from(json, \"utf8\").toString(\"base64url\");\n}\n\nexport function decodeCursor(cursor?: string | null): unknown | undefined {\n if (!cursor) return undefined;\n try {\n const json = Buffer.from(cursor, \"base64url\").toString(\"utf8\");\n const payload = JSON.parse(json) as CursorPayload;\n return payload.v;\n } catch {\n return undefined;\n }\n}\n","import type { ClientSession, Model } from \"mongoose\";\nimport { QueryKitError, type SkippedCondition } from \"@querykitjs/core\";\n\nimport type {\n AggregateRow,\n AggregateSpec,\n ByIdParams,\n CursorParams,\n CursorResult,\n FieldCondition,\n FieldKey,\n Filter,\n Id,\n InfiniteParams,\n InfiniteResult,\n Insert,\n OffsetParams,\n OffsetResult,\n ColumnSelection,\n QueryParams,\n Repository,\n RepositoryOptions,\n Row,\n Scope,\n Sort,\n SortDirection,\n UpsertOptions,\n} from \"./types\";\nimport { resolveField, hasPath, castValue, type AnyModel } from \"./internal/fields\";\nimport { buildWhere, type Query } from \"./internal/where\";\nimport { reportSkip, type Diagnostics } from \"./internal/diagnostics\";\nimport { buildSort } from \"./internal/order-by\";\nimport { encodeCursor, decodeCursor } from \"./internal/cursor\";\n\n/** Registry-level runtime injected into every repository. */\nexport interface RepoRuntime {\n /** Active transaction session, if any. */\n getSession: () => ClientSession | undefined;\n defaultPerPage: number;\n defaultLimit: number;\n /** Upper bound for `perPage`, applied even when validation was bypassed. */\n maxPerPage: number;\n /** Upper bound for `limit` (`findInfinite`/`findCursor`). */\n maxLimit: number;\n /** Throw `QueryKitError` instead of dropping an unresolvable condition. */\n strict: boolean;\n /** Called for every dropped condition (also when `strict` is off). */\n onSkippedCondition?: (info: SkippedCondition) => void;\n}\n\n/**\n * Clamp a requested page size into `[1, max]`, falling back to the default when\n * omitted. Applied in the repository as well as in validation, so a bypassed or\n * mis-configured schema still cannot ask for the whole collection.\n */\nconst clampPageSize = (requested: number | undefined, fallback: number, max: number): number => Math.min(max, Math.max(1, Math.trunc(requested ?? fallback)));\n\n// Mongoose's Query generics are extremely deep; we drive queries untyped\n// internally (the public Repository surface stays fully typed) and cast results.\n\ntype AnyQuery = any;\n\n/**\n * Build a model-scoped repository. `runtime` (session getter + defaults) comes\n * from the registry, so this file never touches the connection directly.\n */\nexport function buildRepository<TDoc>(runtime: RepoRuntime, model: Model<TDoc>, config: RepositoryOptions<TDoc> = {}): Repository<TDoc> {\n const m = model as AnyModel;\n const hasDeletedAt = hasPath(m, \"deletedAt\");\n // Mongoose auto-bumps `updatedAt` only when the schema opts into timestamps;\n // for a manual `updatedAt` path we stamp it ourselves so every update path\n // bumps it — matching drizzle-pg's forUpdate.\n const timestampsOn = Boolean((m.schema as { options?: { timestamps?: unknown } }).options?.timestamps);\n const stampUpdatedAt = hasPath(m, \"updatedAt\") && !timestampsOn;\n const forUpdate = <T extends object>(patch: T): T => (stampUpdatedAt ? { ...patch, updatedAt: new Date() } : patch);\n\n // Scope → equality conditions applied to every query (as a flat filter).\n const scopeConditions: FieldCondition[] = config.scope\n ? Object.entries(config.scope).map(([key, value]) => ({ key, operation: \"=\", value: value as never }))\n : [];\n // A scope is the server's own RBAC / tenancy filter, so a key that does not\n // resolve must never be dropped: that would silently widen every query on this\n // repository. Fail when it is configured, not per request, and regardless of\n // `strict` — this is a programming error, not bad input.\n for (const condition of scopeConditions) {\n if (!resolveField(m, condition.key)) {\n throw new QueryKitError({ source: m.modelName, site: \"filter\", key: condition.key, reason: \"unknown-key\" });\n }\n }\n const scopeWhere = scopeConditions.length ? buildWhere(m, scopeConditions) : undefined;\n\n /* Diagnostics channel — built once, threaded into the filter/sort compilers. */\n const diag: Diagnostics = {\n source: m.modelName,\n strict: runtime.strict,\n onSkipped: runtime.onSkippedCondition,\n };\n\n const sortSpec = (sort?: Sort<TDoc>): Record<string, 1 | -1> => buildSort(m, sort as Sort | undefined, diag);\n\n /** Compose user filter + scope + soft-delete guard into one Mongo query. */\n const composeWhere = (userFilter?: Filter<TDoc>, withDeleted?: boolean): Query => {\n const parts = [\n buildWhere(m, userFilter as Filter | undefined, diag),\n scopeWhere,\n hasDeletedAt && !withDeleted ? { deletedAt: { $eq: null } } : undefined,\n ].filter((p): p is Query => p !== undefined);\n if (parts.length === 0) return {};\n if (parts.length === 1) return parts[0]!;\n return { $and: parts };\n };\n\n /** Merge an id predicate into a filter as AND. */\n const withId = (filter: Filter<TDoc> | undefined, idKey: string, id: Id): Filter<TDoc> => {\n const idCondition: FieldCondition<TDoc> = { key: idKey as FieldKey<TDoc>, operation: \"=\", value: id as never };\n if (!filter) return [idCondition];\n if (Array.isArray(filter)) return [...filter, idCondition];\n return { and: [filter, idCondition] };\n };\n\n /* ------------------------- projection guards --------------------------- */\n /* `columns` may arrive straight from the wire, so the safe selection belongs\n * here rather than in every route — the same reasoning as `scope`. Both options\n * are validated once, at build time, so a misconfiguration surfaces in\n * development instead of quietly returning full documents in production.\n * Identical semantics to the drizzle-pg adapter. */\n\n const truthyKeys = (selection: ColumnSelection<TDoc>): string[] =>\n Object.entries(selection)\n .filter(([, on]) => on)\n .map(([key]) => key);\n\n const forcedKeys = config.forcedColumns ? truthyKeys(config.forcedColumns) : undefined;\n if (config.forcedColumns && forcedKeys!.length === 0) {\n throw new Error(\"buildRepository: forcedColumns must select at least one field (an empty selection would return the full document).\");\n }\n\n const allowed = config.allowedColumns ? new Set<string>(config.allowedColumns as readonly string[]) : undefined;\n if (config.allowedColumns && allowed!.size === 0) {\n throw new Error(\"buildRepository: allowedColumns must list at least one field (an empty allowlist would return the full document).\");\n }\n\n const guarded = Boolean(forcedKeys ?? allowed);\n /** Whether a field may appear in a result at all. */\n const permits = (key: string): boolean => (forcedKeys ? forcedKeys.includes(key) : allowed ? allowed.has(key) : true);\n\n /** Client selection ∩ allowlist; empty intersection → the allowlist itself. */\n const intersectAllowed = (requested: string[]): string[] => {\n const hit = requested.filter(key => allowed!.has(key));\n return hit.length > 0 ? hit : [...allowed!];\n };\n\n /**\n * Column selection → Mongo projection, or undefined when empty. Adds `_id: 0`\n * unless the caller selected `id`/`_id`, so the runtime shape matches the\n * inferred `Pick<...>` type (Mongo otherwise always returns `_id`). Returns\n * undefined (full doc) when no requested column resolves.\n *\n * With `forcedColumns` the caller's selection is ignored outright; with\n * `allowedColumns` it is intersected, and an empty intersection falls back to\n * the allowlist — **never** to the full document.\n */\n const projection = (columns?: QueryParams<TDoc>[\"columns\"]): Record<string, 0 | 1> | undefined => {\n const requested = columns ? truthyKeys(columns as ColumnSelection<TDoc>) : [];\n const keys = forcedKeys ?? (allowed ? intersectAllowed(requested) : requested);\n if (keys.length === 0) return undefined;\n const proj: Record<string, 0 | 1> = {};\n let includesId = false;\n for (const k of keys) {\n const field = resolveField(m, k);\n if (!field) continue;\n proj[field] = 1;\n if (field === \"_id\") includesId = true;\n }\n if (Object.keys(proj).length === 0) return undefined; // all unknown → full doc\n if (!includesId) proj._id = 0; // exclude _id unless explicitly selected (exact columns, like drizzle)\n return proj;\n };\n\n const applyPopulate = (q: AnyQuery, withRel?: QueryParams<TDoc>[\"with\"]): AnyQuery => {\n if (withRel) {\n for (const key of Object.keys(withRel)) {\n const value = (withRel as Record<string, unknown>)[key];\n if (!value) continue;\n // `true` → populate the field; an object → pass through as populate options\n // (`{ author: { select: \"name\" } }` → `.populate({ path, select })`).\n q.populate(typeof value === \"object\" ? { path: key, ...(value as object) } : key);\n }\n }\n return q;\n };\n\n const attachSession = (q: AnyQuery): AnyQuery => {\n const s = runtime.getSession();\n if (s) q.session(s);\n return q;\n };\n\n const toArr = <T>(v?: T | T[]): T[] => (v === undefined ? [] : Array.isArray(v) ? v : [v]);\n\n /** Apply scope defaults to insert values — scope wins (can't be overridden). */\n const forInsert = (values: object): Record<string, unknown> => ({\n ...(config.scope as object),\n ...values,\n ...(config.scope as object),\n });\n\n /** Build the `{filter, update}` for an upsert (target → filter, rest → $set/$setOnInsert). */\n const buildUpsert = (values: Insert<TDoc>, options: UpsertOptions<TDoc>) => {\n const targetKeys = toArr(options.target) as string[];\n const inserted = forInsert(values);\n const filter: Record<string, unknown> = {};\n for (const key of targetKeys) {\n const field = resolveField(m, key);\n if (!field) throw new Error(`upsert: unknown target field \"${key}\".`);\n filter[field] = inserted[key];\n }\n // $set (applied on insert + conflict) defaults to values minus target keys.\n const set: Record<string, unknown> = options.set\n ? { ...(options.set as Record<string, unknown>) }\n : Object.fromEntries(Object.entries(inserted).filter(([k]) => !targetKeys.includes(k)));\n // $setOnInsert (insert only) = remaining non-target values not already in $set.\n const setOnInsert = Object.fromEntries(Object.entries(inserted).filter(([k]) => !targetKeys.includes(k) && !(k in set)));\n const update: Record<string, unknown> = {};\n if (Object.keys(set).length) update.$set = set;\n if (Object.keys(setOnInsert).length) update.$setOnInsert = setOnInsert;\n return { filter, update };\n };\n\n interface FindOpts {\n sort?: Record<string, 1 | -1>;\n columns?: QueryParams<TDoc>[\"columns\"];\n with?: QueryParams<TDoc>[\"with\"];\n limit?: number;\n skip?: number;\n }\n\n const runFind = (where: Query, opts: FindOpts): Promise<unknown[]> => {\n let q: AnyQuery = m.find(where, projection(opts.columns));\n if (opts.sort) q = q.sort(opts.sort);\n if (typeof opts.skip === \"number\") q = q.skip(opts.skip);\n if (typeof opts.limit === \"number\") q = q.limit(opts.limit);\n q = applyPopulate(q, opts.with);\n return attachSession(q).lean().exec() as Promise<unknown[]>;\n };\n\n const countWhere = (where: Query): Promise<number> => attachSession(m.countDocuments(where)).exec() as Promise<number>;\n\n const repository = {\n model,\n\n async findAll(params: QueryParams<TDoc> = {}) {\n const rows = await runFind(composeWhere(params.filter, params.withDeleted), {\n sort: sortSpec(params.sort),\n columns: params.columns,\n with: params.with,\n });\n return rows as never;\n },\n\n async findOne(params: QueryParams<TDoc> = {}) {\n let q: AnyQuery = m.findOne(composeWhere(params.filter, params.withDeleted), projection(params.columns));\n q = q.sort(sortSpec(params.sort));\n q = applyPopulate(q, params.with);\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as never;\n },\n\n async findById(id: Id, params: ByIdParams<TDoc> = {}) {\n const { idKey = \"id\", filter, columns, with: withRel } = params;\n let q: AnyQuery = m.findOne(composeWhere(withId(filter, idKey as string, id), params.withDeleted), projection(columns));\n q = applyPopulate(q, withRel);\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as never;\n },\n\n async findList(params: OffsetParams<TDoc> = {}) {\n const page = Math.max(1, Math.trunc(params.page ?? 1));\n const perPage = clampPageSize(params.perPage, runtime.defaultPerPage, runtime.maxPerPage);\n const where = composeWhere(params.filter, params.withDeleted);\n\n const [data, total_items] = await Promise.all([\n runFind(where, { sort: sortSpec(params.sort), columns: params.columns, with: params.with, limit: perPage, skip: (page - 1) * perPage }),\n countWhere(where),\n ]);\n\n const total_pages = Math.ceil(total_items / perPage);\n return {\n data,\n meta: {\n total_items,\n total_pages,\n current_page: page,\n per_page: perPage,\n has_next: page < total_pages,\n has_prev: page > 1,\n },\n } as OffsetResult<never>;\n },\n\n async findInfinite(params: InfiniteParams<TDoc> = {}) {\n const limit = clampPageSize(params.limit, runtime.defaultLimit, runtime.maxLimit);\n const offset = Math.max(0, Math.trunc(params.offset ?? 0));\n\n const rows = await runFind(composeWhere(params.filter, params.withDeleted), {\n sort: sortSpec(params.sort),\n columns: params.columns,\n with: params.with,\n limit: limit + 1,\n skip: offset,\n });\n\n const has_more = rows.length > limit;\n const data = has_more ? rows.slice(0, limit) : rows;\n return {\n data,\n meta: { limit, offset, count: data.length, has_more, next_offset: has_more ? offset + limit : null },\n } as InfiniteResult<never>;\n },\n\n async findCursor(params: CursorParams<TDoc> = {}) {\n const limit = clampPageSize(params.limit, runtime.defaultLimit, runtime.maxLimit);\n const cursorKey = (params.cursorKey ?? \"id\") as string;\n const order: SortDirection = params.order ?? \"asc\";\n const direction = params.direction ?? \"forward\";\n\n const field = resolveField(m, cursorKey);\n // Always fatal: without a usable cursor field there is no pagination to\n // fall back to. Reported as a `QueryKitError` so the backend maps it to a\n // 400 the same way as any other bad condition (both adapters agree).\n if (!field) throw new QueryKitError({ source: diag.source, site: \"cursorKey\", key: cursorKey, reason: \"unknown-key\" });\n\n const decoded = decodeCursor(params.cursor);\n const cursorValue = decoded !== undefined ? castValue(m, field, decoded) : undefined;\n const baseWhere = composeWhere(params.filter, params.withDeleted);\n\n const ascInQuery = direction === \"forward\" ? order === \"asc\" : order === \"desc\";\n const seek: Query | undefined = cursorValue !== undefined ? { [field]: ascInQuery ? { $gt: cursorValue } : { $lt: cursorValue } } : undefined;\n const where: Query = seek ? (Object.keys(baseWhere).length ? { $and: [baseWhere, seek] } : seek) : baseWhere;\n\n // Force-include the cursor field in the projection so next/prev tokens work.\n // `cursorKey` is client-supplied, so under a projection guard this would be\n // a way to read a forbidden field: keep it in the query (pagination needs\n // it) but strip it from the documents we hand back.\n const selected = projection(params.columns);\n const proj = selected ? { ...selected, [field]: 1 } : undefined;\n const leaksCursorField = guarded && selected !== undefined && !permits(cursorKey) && !permits(field);\n\n let q: AnyQuery = m\n .find(where, proj)\n .sort({ [field]: ascInQuery ? 1 : -1 })\n .limit(limit + 1);\n q = applyPopulate(q, params.with);\n const rows = (await attachSession(q).lean().exec()) as Record<string, unknown>[];\n\n const hasExtra = rows.length > limit;\n let pageRows = hasExtra ? rows.slice(0, limit) : rows;\n if (direction === \"backward\") pageRows = [...pageRows].reverse();\n\n const first = pageRows[0];\n const last = pageRows[pageRows.length - 1];\n\n const has_next = direction === \"forward\" ? hasExtra : cursorValue !== undefined;\n const has_prev = direction === \"forward\" ? cursorValue !== undefined : hasExtra;\n\n const meta = {\n limit,\n has_next,\n has_prev,\n next_cursor: has_next && last ? encodeCursor(last[field]) : null,\n prev_cursor: has_prev && first ? encodeCursor(first[field]) : null,\n };\n\n // Cursor values are read above, so the field can go now.\n if (leaksCursorField) {\n pageRows = pageRows.map(row => {\n const { [field]: _cursor, ...rest } = row;\n return rest;\n });\n }\n\n return { data: pageRows, meta } as CursorResult<never>;\n },\n\n count(filter?: Filter<TDoc>) {\n return countWhere(composeWhere(filter));\n },\n\n async exists(filter?: Filter<TDoc>) {\n return (await countWhere(composeWhere(filter))) > 0;\n },\n\n /* ------------------------------- writes ------------------------------- */\n\n async create(values: Insert<TDoc>) {\n const [doc] = await m.create([forInsert(values)], { session: runtime.getSession() });\n return doc!.toObject() as Row<TDoc>;\n },\n\n async createMany(values: Insert<TDoc>[]) {\n if (values.length === 0) return [];\n const docs = await m.insertMany(values.map(forInsert), { session: runtime.getSession() });\n return docs.map((d: { toObject: () => unknown }) => d.toObject()) as Row<TDoc>[];\n },\n\n async upsert(values: Insert<TDoc>, options: UpsertOptions<TDoc>) {\n const { filter, update } = buildUpsert(values, options);\n const q: AnyQuery = m.findOneAndUpdate(filter, update, { returnDocument: \"after\", upsert: true });\n return (await attachSession(q).lean().exec()) as Row<TDoc>;\n },\n\n async upsertMany(values: Insert<TDoc>[], options: UpsertOptions<TDoc>) {\n if (values.length === 0) return [];\n const CHUNK = 1000;\n const entries = values.map(v => buildUpsert(v, options)); // input order preserved\n for (let i = 0; i < entries.length; i += CHUNK) {\n const ops = entries.slice(i, i + CHUNK).map(e => ({ updateOne: { filter: e.filter, update: e.update, upsert: true } }));\n await m.bulkWrite(ops, { session: runtime.getSession() });\n }\n // Re-fetch affected rows and return them in INPUT order (matches drizzle's\n // `.returning()`), keyed by the resolved target field(s).\n const rows = (await attachSession(m.find({ $or: entries.map(e => e.filter) }))\n .lean()\n .exec()) as Record<string, unknown>[];\n const targetFields = (toArr(options.target) as string[]).map(k => resolveField(m, k)).filter((f): f is string => Boolean(f));\n const keyOf = (o: Record<string, unknown>): string => targetFields.map(f => String(o[f])).join(\"\u0000\");\n const byKey = new Map(rows.map(r => [keyOf(r), r]));\n return entries.map(e => byKey.get(keyOf(e.filter))).filter((r): r is Record<string, unknown> => Boolean(r)) as Row<TDoc>[];\n },\n\n async updateById(id: Id, patch: Partial<Insert<TDoc>>, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n const where = composeWhere(withId(undefined, idKey as string, id));\n const q: AnyQuery = m.findOneAndUpdate(where, forUpdate(patch), { returnDocument: \"after\" });\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async updateWhere(filter: Filter<TDoc>, patch: Partial<Insert<TDoc>>) {\n const where = composeWhere(filter);\n const found = (await attachSession(m.find(where).select({ _id: 1 }))\n .lean()\n .exec()) as { _id: unknown }[];\n if (found.length === 0) return [];\n const ids = found.map(d => d._id);\n await attachSession(m.updateMany({ _id: { $in: ids } }, forUpdate(patch))).exec();\n return (await attachSession(m.find({ _id: { $in: ids } }))\n .lean()\n .exec()) as Row<TDoc>[];\n },\n\n async deleteById(id: Id, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n const where = composeWhere(withId(undefined, idKey as string, id));\n const row = await attachSession(m.findOneAndDelete(where)).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async deleteWhere(filter: Filter<TDoc>) {\n const where = composeWhere(filter);\n const rows = (await attachSession(m.find(where)).lean().exec()) as { _id: unknown }[];\n if (rows.length === 0) return [];\n await attachSession(m.deleteMany({ _id: { $in: rows.map(d => d._id) } })).exec();\n return rows as Row<TDoc>[];\n },\n\n async softDelete(id: Id, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n if (!hasDeletedAt) throw new Error(\"softDelete: schema has no deletedAt path.\");\n const where = composeWhere(withId(undefined, idKey as string, id), false);\n const q: AnyQuery = m.findOneAndUpdate(where, forUpdate({ deletedAt: new Date() }), { returnDocument: \"after\" });\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async restore(id: Id, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n if (!hasDeletedAt) throw new Error(\"restore: schema has no deletedAt path.\");\n const where = composeWhere(withId(undefined, idKey as string, id), true);\n const q: AnyQuery = m.findOneAndUpdate(where, forUpdate({ deletedAt: null }), { returnDocument: \"after\" });\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async aggregate(spec: AggregateSpec<TDoc>) {\n // An aggregate spec can also come from a request, and `min(password)` or a\n // `groupBy` on a hidden field leaks just as much as a projection — so the\n // same guard applies here (matching the drizzle-pg adapter).\n const aggregable = (key: string) => {\n const field = permits(key) ? resolveField(m, key) : undefined;\n if (!field) reportSkip(diag, { site: \"aggregate\", key, reason: \"unknown-key\" });\n return field;\n };\n const groupKeys = (toArr(spec.groupBy) as string[]).filter(key => Boolean(aggregable(key)));\n // Aggregate `$match` doesn't auto-cast values the way `find()` does; cast\n // the filter against the schema so wire strings (dates / ObjectIds) become\n // proper BSON types — keeping aggregate filters consistent with reads.\n const rawMatch = composeWhere(spec.filter, spec.withDeleted);\n let match: Record<string, unknown> = rawMatch;\n try {\n const q = m.find(rawMatch);\n q.cast(m);\n match = q.getFilter();\n } catch {\n /* fall back to the uncast filter */\n }\n const groupId = groupKeys.length ? Object.fromEntries(groupKeys.map(k => [k, `$${aggregable(k) ?? k}`])) : null;\n const group: Record<string, unknown> = { _id: groupId };\n if (spec.count) group.count = { $sum: 1 };\n const addAgg = (op: \"$sum\" | \"$avg\" | \"$min\" | \"$max\", keys: string[], prefix: string) => {\n for (const k of keys) {\n const field = aggregable(k);\n if (field) group[`${prefix}_${k}`] = { [op]: `$${field}` };\n }\n };\n addAgg(\"$sum\", toArr(spec.sum) as string[], \"sum\");\n addAgg(\"$avg\", toArr(spec.avg) as string[], \"avg\");\n addAgg(\"$min\", toArr(spec.min) as string[], \"min\");\n addAgg(\"$max\", toArr(spec.max) as string[], \"max\");\n\n let agg = m.aggregate([{ $match: match }, { $group: group }] as never);\n const session = runtime.getSession();\n if (session) agg = agg.session(session);\n const rows = (await agg.exec()) as Record<string, unknown>[];\n // Flatten the group `_id` fields back into each row (matches drizzle's shape).\n return rows.map(({ _id, ...rest }) => ({ ...(typeof _id === \"object\" && _id ? _id : {}), ...rest })) as AggregateRow[];\n },\n\n scoped(scope: Scope<TDoc>) {\n return buildRepository(runtime, model, { ...config, scope: { ...config.scope, ...scope } });\n },\n };\n\n return repository as unknown as Repository<TDoc>;\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type { ClientSession } from \"mongoose\";\n\n/**\n * Per-transaction ambient state. Lets repositories pick up the active Mongo\n * `ClientSession` without threading it through every call. Set by\n * `registry.transaction`.\n */\nexport interface RepoContext {\n session?: ClientSession;\n}\n\nexport interface ContextStore {\n /** Read the current ambient context (undefined outside any `run`). */\n get(): RepoContext | undefined;\n /** Run `fn` with `patch` merged over the current context. */\n run<T>(patch: RepoContext, fn: () => T): T;\n}\n\nexport function createContextStore(): ContextStore {\n const als = new AsyncLocalStorage<RepoContext>();\n return {\n get: () => als.getStore(),\n run: (patch, fn) => als.run({ ...als.getStore(), ...patch }, fn),\n };\n}\n","import type { Connection, Model } from \"mongoose\";\nimport { DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_MAX_PER_PAGE, DEFAULT_PER_PAGE } from \"@querykitjs/core\";\n\nimport type { RelationDocs, RelationMap, Registry, RegistryOptions, Repository, RepositoryExtender, RepositoryOptions } from \"./types\";\nimport { buildRepository, type RepoRuntime } from \"./repository\";\nimport { createContextStore } from \"./internal/context\";\n\n/**\n * Create the DB **registry** once. It holds the Mongoose connection (for\n * transactions) and yields a {@link Repository} per model. Transactions flow\n * ambiently via AsyncLocalStorage — repositories used inside\n * `registry.transaction(...)` automatically run on that session.\n *\n * @param connection - the Mongoose `Connection` the models belong to.\n * @param options - `defaultPerPage` (findList) / `defaultLimit` (infinite/cursor);\n * defaults to `@querykitjs/core`'s `DEFAULT_PER_PAGE` / `DEFAULT_LIMIT` (20).\n * @example\n * ```ts\n * const registry = createRegistry(mongoose.connection);\n * const usersRepo = registry.repository(User);\n * ```\n */\nexport function createRegistry(connection: Connection, options: RegistryOptions = {}): Registry {\n const ctx = createContextStore();\n const runtime: RepoRuntime = {\n getSession: () => ctx.get()?.session,\n defaultPerPage: options.defaultPerPage ?? DEFAULT_PER_PAGE,\n defaultLimit: options.defaultLimit ?? DEFAULT_LIMIT,\n maxPerPage: options.maxPerPage ?? DEFAULT_MAX_PER_PAGE,\n maxLimit: options.maxLimit ?? DEFAULT_MAX_LIMIT,\n strict: options.strict ?? false,\n onSkippedCondition: options.onSkippedCondition,\n };\n\n function repository<TDoc>(model: Model<TDoc>): Repository<TDoc>;\n function repository<TDoc, TExt extends Record<string, unknown>>(\n model: Model<TDoc>,\n extend: RepositoryExtender<TDoc, Record<never, never>, TExt>,\n ): Repository<TDoc> & TExt;\n function repository<TDoc, TRel extends RelationMap>(model: Model<TDoc>, options: RepositoryOptions<TDoc, TRel>): Repository<TDoc, RelationDocs<TRel>>;\n function repository<TDoc, TRel extends RelationMap, TExt extends Record<string, unknown>>(\n model: Model<TDoc>,\n options: RepositoryOptions<TDoc, TRel>,\n extend: RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>,\n ): Repository<TDoc, RelationDocs<TRel>> & TExt;\n function repository<TDoc, TRel extends RelationMap, TExt extends Record<string, unknown>>(\n model: Model<TDoc>,\n arg2?: RepositoryOptions<TDoc, TRel> | RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>,\n arg3?: RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>,\n ) {\n // 2nd arg is either the options object or the extender fn (same dispatch as\n // the drizzle-pg adapter, so both registries read identically).\n // `relations` is type-only (it drives `with` inference); `scope` and the\n // projection guards are runtime and must reach buildRepository — before this\n // they were silently dropped, so `forcedColumns` had no effect.\n const repoOptions = typeof arg2 === \"function\" ? undefined : arg2;\n const extend = typeof arg2 === \"function\" ? arg2 : arg3;\n const base = buildRepository(runtime, model, repoOptions) as unknown as Repository<TDoc, RelationDocs<TRel>>;\n return extend ? { ...base, ...extend(base) } : base;\n }\n\n const transaction = async <T>(fn: () => Promise<T>): Promise<T> => {\n // Already inside a transaction (Mongo has no nested tx/savepoints) → reuse it.\n if (ctx.get()?.session) return fn();\n\n const session = await connection.startSession();\n try {\n let result!: T;\n await session.withTransaction(async () => {\n result = await ctx.run({ session }, fn);\n });\n return result;\n } finally {\n await session.endSession();\n }\n };\n\n return { repository, transaction };\n}\n","import { createFilters as coreCreateFilters, f } from \"@querykitjs/core\";\n\nimport type { FieldKey, RawFilter } from \"./types\";\n\n/**\n * Typed, ergonomic filter builders for a document type (field-name autocomplete).\n * A thin wrapper over `@querykitjs/core`'s builder — the key type is the model's\n * field key, the raw escape-hatch is a native Mongo `QueryFilter`.\n *\n * @example\n * ```ts\n * const uf = createFilters<IUser>();\n * await usersRepo.findAll({ filter: uf.and(uf.eq(\"status\", \"active\"), uf.gte(\"age\", 18)) });\n * ```\n */\nexport function createFilters<TDoc>() {\n return coreCreateFilters<FieldKey<TDoc>, RawFilter<TDoc>>();\n}\n\n/** Untyped filter helpers for quick use. */\nexport { f };\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Types, Model, Connection, ClientSession } from 'mongoose';
|
|
2
2
|
import * as _querykitjs_core from '@querykitjs/core';
|
|
3
|
+
import { SkippedCondition } 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;
|
|
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> = _querykitjs_core.LooseKey<FieldKey<TDoc>>;
|
|
36
42
|
type FilterOperator = _querykitjs_core.FilterOperator;
|
|
37
43
|
type FilterScalar = _querykitjs_core.FilterScalar;
|
|
38
44
|
type FilterValue = _querykitjs_core.FilterValue;
|
|
39
|
-
type FieldCondition<TDoc = Record<string, unknown>> = _querykitjs_core.FieldCondition<
|
|
40
|
-
type AndGroup<TDoc = Record<string, unknown>> = _querykitjs_core.AndGroup<
|
|
41
|
-
type OrGroup<TDoc = Record<string, unknown>> = _querykitjs_core.OrGroup<
|
|
42
|
-
type NotGroup<TDoc = Record<string, unknown>> = _querykitjs_core.NotGroup<
|
|
43
|
-
type FilterNode<TDoc = Record<string, unknown>> = _querykitjs_core.FilterNode<
|
|
44
|
-
type Filter<TDoc = Record<string, unknown>> = _querykitjs_core.Filter<
|
|
45
|
+
type FieldCondition<TDoc = Record<string, unknown>> = _querykitjs_core.FieldCondition<LooseFieldKey<TDoc>>;
|
|
46
|
+
type AndGroup<TDoc = Record<string, unknown>> = _querykitjs_core.AndGroup<LooseFieldKey<TDoc>, RawFilter<TDoc>>;
|
|
47
|
+
type OrGroup<TDoc = Record<string, unknown>> = _querykitjs_core.OrGroup<LooseFieldKey<TDoc>, RawFilter<TDoc>>;
|
|
48
|
+
type NotGroup<TDoc = Record<string, unknown>> = _querykitjs_core.NotGroup<LooseFieldKey<TDoc>, RawFilter<TDoc>>;
|
|
49
|
+
type FilterNode<TDoc = Record<string, unknown>> = _querykitjs_core.FilterNode<LooseFieldKey<TDoc>, RawFilter<TDoc>>;
|
|
50
|
+
type Filter<TDoc = Record<string, unknown>> = _querykitjs_core.Filter<LooseFieldKey<TDoc>, RawFilter<TDoc>>;
|
|
45
51
|
type SortDirection = _querykitjs_core.SortDirection;
|
|
46
52
|
/** One sort field by typed field key (`{ key, direction }`) — autocomplete. */
|
|
47
|
-
type SortItem<TDoc = Record<string, unknown>> = _querykitjs_core.SortItem<
|
|
53
|
+
type SortItem<TDoc = Record<string, unknown>> = _querykitjs_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,36 +69,15 @@ 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>> = _querykitjs_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>> = _querykitjs_core.UpsertOptions<FieldKey<TDoc>, Insert<TDoc>>;
|
|
79
|
+
/** Aggregate query specification (`count`/`sum`/`avg`/`min`/`max` + `groupBy`). */
|
|
80
|
+
type AggregateSpec<TDoc = Record<string, unknown>> = _querykitjs_core.AggregateSpec<FieldKey<TDoc>, Filter<TDoc>>;
|
|
96
81
|
/** One aggregated result row (group fields + aggregate values). */
|
|
97
82
|
type AggregateRow = Record<string, unknown>;
|
|
98
83
|
interface OffsetParams<TDoc = Record<string, unknown>> extends QueryParams<TDoc> {
|
|
@@ -117,7 +102,7 @@ interface CursorParams<TDoc = Record<string, unknown>> extends QueryParams<TDoc>
|
|
|
117
102
|
limit?: number;
|
|
118
103
|
cursor?: string | null;
|
|
119
104
|
/** Field the cursor walks over. Defaults to `"id"` (→ `_id`). */
|
|
120
|
-
cursorKey?:
|
|
105
|
+
cursorKey?: LooseFieldKey<TDoc>;
|
|
121
106
|
order?: SortDirection;
|
|
122
107
|
direction?: "forward" | "backward";
|
|
123
108
|
}
|
|
@@ -133,10 +118,37 @@ type DocOf<M> = M extends Model<infer T> ? T : never;
|
|
|
133
118
|
type RelationDocs<TRel extends RelationMap> = {
|
|
134
119
|
[K in keyof TRel]: DocOf<TRel[K]>;
|
|
135
120
|
};
|
|
136
|
-
/**
|
|
137
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Options for `registry.repository(model, options)`.
|
|
123
|
+
*
|
|
124
|
+
* Philosophy: the guard lives in the **repository**, not the route — `scope`
|
|
125
|
+
* (RBAC) already worked that way and projection joins it. Same names and same
|
|
126
|
+
* semantics as the drizzle-pg adapter's `RepositoryOptions`.
|
|
127
|
+
*
|
|
128
|
+
* ⚠️ `forcedColumns`/`allowedColumns` affect **read** methods only
|
|
129
|
+
* (`findAll`/`findOne`/`findById`/`findList`/`findInfinite`/`findCursor` +
|
|
130
|
+
* `aggregate`). Write methods (`create`, `upsert`, `updateById`, `softDelete`, …)
|
|
131
|
+
* return the full `Row` by type contract — trimming it at runtime would make the
|
|
132
|
+
* type a lie. Re-read with `findById`, or map it yourself, before handing a write
|
|
133
|
+
* result to a client.
|
|
134
|
+
*/
|
|
135
|
+
interface RepositoryOptions<TDoc = any, TRel extends RelationMap = RelationMap> {
|
|
138
136
|
/** Declare populatable relations (field → model) so `with` types the result. */
|
|
139
137
|
relations?: TRel;
|
|
138
|
+
/** Constant equality filter added to every read/write (RBAC / multi-tenancy). */
|
|
139
|
+
scope?: Scope<TDoc>;
|
|
140
|
+
/**
|
|
141
|
+
* Forced projection — the client's `columns` is **ignored entirely**. Keeps a
|
|
142
|
+
* password out of a `users` response without a `{ ...params, columns }` trick in
|
|
143
|
+
* every route. Must select at least one field, else building the repository throws.
|
|
144
|
+
*/
|
|
145
|
+
forcedColumns?: ColumnSelection<TDoc>;
|
|
146
|
+
/**
|
|
147
|
+
* Allowlist — the client's `columns` is intersected with it. An empty
|
|
148
|
+
* intersection yields the allowlist itself, **never** the full document.
|
|
149
|
+
* An empty array throws (a projection selecting nothing means "everything").
|
|
150
|
+
*/
|
|
151
|
+
allowedColumns?: readonly FieldKey<TDoc>[];
|
|
140
152
|
}
|
|
141
153
|
type TrueKeys<T> = {
|
|
142
154
|
[K in keyof T]: T[K] extends true ? K : never;
|
|
@@ -154,7 +166,7 @@ type Params<TBase, TColumns, TWith> = Omit<TBase, "columns" | "with"> & {
|
|
|
154
166
|
with?: TWith;
|
|
155
167
|
};
|
|
156
168
|
/**
|
|
157
|
-
*
|
|
169
|
+
* Model-scoped repository. Read methods infer their
|
|
158
170
|
* return type from the `columns` argument, mirroring `@querykitjs/drizzle-pg`.
|
|
159
171
|
*/
|
|
160
172
|
interface Repository<TDoc = Record<string, unknown>, TRel extends Record<string, unknown> = Record<never, never>> {
|
|
@@ -192,12 +204,35 @@ interface Repository<TDoc = Record<string, unknown>, TRel extends Record<string,
|
|
|
192
204
|
aggregate(spec: AggregateSpec<TDoc>): Promise<AggregateRow[]>;
|
|
193
205
|
scoped(scope: Scope<TDoc>): Repository<TDoc, TRel>;
|
|
194
206
|
}
|
|
195
|
-
/** {@link createRegistry} options — pagination defaults. */
|
|
207
|
+
/** {@link createRegistry} options — pagination defaults and bounds. */
|
|
196
208
|
interface RegistryOptions {
|
|
197
209
|
/** `findList` default page size (core `DEFAULT_PER_PAGE` = 20). */
|
|
198
210
|
defaultPerPage?: number;
|
|
199
211
|
/** `findInfinite`/`findCursor` default limit (core `DEFAULT_LIMIT` = 20). */
|
|
200
212
|
defaultLimit?: number;
|
|
213
|
+
/**
|
|
214
|
+
* Upper bound for `perPage` (core `DEFAULT_MAX_PER_PAGE` = 200). Applied even
|
|
215
|
+
* when validation was bypassed — defense in depth. Disable with `Infinity`.
|
|
216
|
+
*/
|
|
217
|
+
maxPerPage?: number;
|
|
218
|
+
/** Upper bound for `limit` (`findInfinite`/`findCursor`, core `DEFAULT_MAX_LIMIT` = 200). */
|
|
219
|
+
maxLimit?: number;
|
|
220
|
+
/**
|
|
221
|
+
* **Strict mode.** An unknown filter/sort key, or a value the operator cannot
|
|
222
|
+
* use, is no longer dropped silently — a `QueryKitError` is thrown (the backend
|
|
223
|
+
* maps it to a 400). Defaults to `false`, keeping the legacy (DbService)
|
|
224
|
+
* behaviour that dozens of existing endpoints rely on.
|
|
225
|
+
*
|
|
226
|
+
* Why it matters: a filter is meant to **narrow** a result set, so a mistyped
|
|
227
|
+
* key that vanishes silently makes the endpoint return **more** data than
|
|
228
|
+
* intended, with nothing in the log to show it.
|
|
229
|
+
*/
|
|
230
|
+
strict?: boolean;
|
|
231
|
+
/**
|
|
232
|
+
* Called for every dropped condition (also when `strict` is off). Migration
|
|
233
|
+
* path: watch with the hook first, flip `strict: true` once the log is clean.
|
|
234
|
+
*/
|
|
235
|
+
onSkippedCondition?: (info: _querykitjs_core.SkippedCondition) => void;
|
|
201
236
|
}
|
|
202
237
|
/** Extends a base repository with custom, model-specific methods (drizzle-pg style). */
|
|
203
238
|
type RepositoryExtender<TDoc, TRel extends Record<string, unknown>, TExt extends Record<string, unknown>> = (base: Repository<TDoc, TRel>) => TExt;
|
|
@@ -208,9 +243,9 @@ interface Registry {
|
|
|
208
243
|
/** …extended with custom methods (2nd-arg extender fn — same as drizzle-pg). */
|
|
209
244
|
repository<TDoc, TExt extends Record<string, unknown>>(model: Model<TDoc>, extend: RepositoryExtender<TDoc, Record<never, never>, TExt>): Repository<TDoc> & TExt;
|
|
210
245
|
/** …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>>;
|
|
246
|
+
repository<TDoc, TRel extends RelationMap>(model: Model<TDoc>, options: RepositoryOptions<TDoc, TRel>): Repository<TDoc, RelationDocs<TRel>>;
|
|
212
247
|
/** …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;
|
|
248
|
+
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
249
|
/** Runs `fn` inside a MongoDB transaction (requires a replica set). */
|
|
215
250
|
transaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
216
251
|
}
|
|
@@ -238,16 +273,20 @@ interface RepoRuntime {
|
|
|
238
273
|
getSession: () => ClientSession | undefined;
|
|
239
274
|
defaultPerPage: number;
|
|
240
275
|
defaultLimit: number;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
276
|
+
/** Upper bound for `perPage`, applied even when validation was bypassed. */
|
|
277
|
+
maxPerPage: number;
|
|
278
|
+
/** Upper bound for `limit` (`findInfinite`/`findCursor`). */
|
|
279
|
+
maxLimit: number;
|
|
280
|
+
/** Throw `QueryKitError` instead of dropping an unresolvable condition. */
|
|
281
|
+
strict: boolean;
|
|
282
|
+
/** Called for every dropped condition (also when `strict` is off). */
|
|
283
|
+
onSkippedCondition?: (info: SkippedCondition) => void;
|
|
245
284
|
}
|
|
246
285
|
/**
|
|
247
286
|
* Build a model-scoped repository. `runtime` (session getter + defaults) comes
|
|
248
287
|
* from the registry, so this file never touches the connection directly.
|
|
249
288
|
*/
|
|
250
|
-
declare function buildRepository<TDoc>(runtime: RepoRuntime, model: Model<TDoc>, config?:
|
|
289
|
+
declare function buildRepository<TDoc>(runtime: RepoRuntime, model: Model<TDoc>, config?: RepositoryOptions<TDoc>): Repository<TDoc>;
|
|
251
290
|
|
|
252
291
|
/**
|
|
253
292
|
* Typed, ergonomic filter builders for a document type (field-name autocomplete).
|
|
@@ -276,6 +315,7 @@ declare function createFilters<TDoc>(): {
|
|
|
276
315
|
in: (key: FieldKey<TDoc>, value: Array<string | number>) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
|
|
277
316
|
notIn: (key: FieldKey<TDoc>, value: Array<string | number>) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
|
|
278
317
|
between: (key: FieldKey<TDoc>, min: _querykitjs_core.FilterScalar | Date, max: _querykitjs_core.FilterScalar | Date) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
|
|
318
|
+
notBetween: (key: FieldKey<TDoc>, min: _querykitjs_core.FilterScalar | Date, max: _querykitjs_core.FilterScalar | Date) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
|
|
279
319
|
range: (key: FieldKey<TDoc>, from: _querykitjs_core.FilterScalar | Date, to: _querykitjs_core.FilterScalar | Date) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>[];
|
|
280
320
|
isNull: (key: FieldKey<TDoc>) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
|
|
281
321
|
isNotNull: (key: FieldKey<TDoc>) => _querykitjs_core.FieldCondition<FieldKey<TDoc>>;
|
|
@@ -284,4 +324,4 @@ declare function createFilters<TDoc>(): {
|
|
|
284
324
|
not: (node: _querykitjs_core.FilterNode<FieldKey<TDoc>, RawFilter<_TDoc>>) => _querykitjs_core.NotGroup<FieldKey<TDoc>, RawFilter<_TDoc>>;
|
|
285
325
|
};
|
|
286
326
|
|
|
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
|
|
327
|
+
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 LooseFieldKey, type NotGroup, type OffsetMeta, type OffsetParams, type OffsetResult, type OrGroup, type QueryParams, type RawFilter, type Registry, type RegistryOptions, type RelationDocs, type RelationMap, 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 };
|