@nest-admin/nestjs 0.11.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/LICENSE +21 -0
- package/README.md +252 -0
- package/dist/admin-ui/assets/index-AyWOamlt.js +50 -0
- package/dist/admin-ui/assets/index-AyWOamlt.js.map +1 -0
- package/dist/admin-ui/assets/index-D4Eh84eD.css +2 -0
- package/dist/admin-ui/index.html +14 -0
- package/dist/chunk-7IXLRGGQ.js +356 -0
- package/dist/chunk-7IXLRGGQ.js.map +1 -0
- package/dist/drizzle.cjs +895 -0
- package/dist/drizzle.cjs.map +1 -0
- package/dist/drizzle.d.cts +335 -0
- package/dist/drizzle.d.ts +335 -0
- package/dist/drizzle.js +756 -0
- package/dist/drizzle.js.map +1 -0
- package/dist/index.cjs +3247 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1652 -0
- package/dist/index.d.ts +1652 -0
- package/dist/index.js +2901 -0
- package/dist/index.js.map +1 -0
- package/dist/prisma.cjs +1159 -0
- package/dist/prisma.cjs.map +1 -0
- package/dist/prisma.d.cts +585 -0
- package/dist/prisma.d.ts +585 -0
- package/dist/prisma.js +995 -0
- package/dist/prisma.js.map +1 -0
- package/package.json +130 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../prisma/src/adapter.ts","../../prisma/src/client/delegate.ts","../../prisma/src/client/version-gate.ts","../../prisma/src/metadata/read-dmmf.ts","../../prisma/src/metadata/to-metadata.ts","../../prisma/src/query/to-include.ts","../../prisma/src/errors/constraints.ts","../../prisma/src/query/to-related-where.ts","../../prisma/src/query/to-prisma-args.ts","../../prisma/src/auth/store.ts"],"sourcesContent":["/**\n * `PrismaAdapter` - the Prisma implementation of Core's `OrmAdapter`.\n *\n * The adapter never constructs a Prisma Client. Prisma 7 builds clients from\n * driver adapters, so only the consuming application knows the provider, the\n * credentials and the connection strategy. We receive a constructed client and\n * use it.\n */\nimport {\n AdapterError,\n FieldNotFoundError,\n InvalidQueryError,\n ModelNotFoundError,\n isNestAdminError,\n RecordNotFoundError,\n type ListQuery,\n type ModelMetadata,\n type OrmAdapter,\n type Page,\n type RecordData,\n type RecordId,\n} from '@nest-admin/core'\n\nimport { resolveDelegate, type PrismaModelDelegate } from './client/delegate.js'\nimport { assertSupportedPrismaVersion } from './client/version-gate.js'\nimport { readDatasourceProvider, readPrismaDmmf } from './metadata/read-dmmf.js'\nimport { toModelMetadata } from './metadata/to-metadata.js'\nimport { toIncludeClause } from './query/to-include.js'\nimport { toConstraintError } from './errors/constraints.js'\nimport { toRelatedWhere } from './query/to-related-where.js'\nimport { resolvePagination, toFindManyArgs } from './query/to-prisma-args.js'\n\n/** Prisma's error code for \"record required but not found\". */\nconst PRISMA_RECORD_NOT_FOUND = 'P2025'\n\nexport interface PrismaAdapterOptions {\n /**\n * A constructed Prisma Client. Owned entirely by the consuming application:\n * the adapter never calls `new PrismaClient()`, because under Prisma 7 the\n * client is built from a driver adapter that only the application can supply.\n */\n readonly client: unknown\n /**\n * Path to `schema.prisma`, or to a directory of `.prisma` files. When\n * omitted, `prisma/schema.prisma`, `prisma/schema` and `schema.prisma` are\n * tried in that order, relative to `cwd`.\n */\n readonly schemaPath?: string\n /** Base directory for schema resolution. Defaults to `process.cwd()`. */\n readonly cwd?: string\n}\n\nexport class PrismaAdapter implements OrmAdapter {\n readonly name = 'prisma'\n\n readonly #client: unknown\n readonly #schemaPath: string | undefined\n readonly #cwd: string | undefined\n\n /**\n * Metadata is derived from a static schema, so it is read once and reused.\n * Every operation validates against it, which would otherwise re-parse the\n * schema on each call.\n */\n #models: readonly ModelMetadata[] | undefined\n\n /**\n * Which database this is, so a search can ignore capitalisation the way that\n * database allows. Read alongside the metadata, and `undefined` when the\n * schema does not say - see `insensitively` in `to-prisma-args.ts`.\n */\n #provider: string | undefined\n\n constructor(options: PrismaAdapterOptions) {\n if (options.client === null || options.client === undefined) {\n throw new AdapterError(\n 'PrismaAdapter requires a constructed Prisma Client. ' +\n 'Pass one via `new PrismaAdapter({ client })`.',\n )\n }\n this.#client = options.client\n this.#schemaPath = options.schemaPath\n this.#cwd = options.cwd\n }\n\n async getModels(): Promise<readonly ModelMetadata[]> {\n if (this.#models) return this.#models\n // Checked before parsing: a version mismatch would otherwise surface as\n // \"Prisma rejected the schema\", pointing at the user's valid schema.\n assertSupportedPrismaVersion(this.#client)\n const dmmf = readPrismaDmmf({\n ...(this.#schemaPath !== undefined ? { schemaPath: this.#schemaPath } : {}),\n ...(this.#cwd !== undefined ? { cwd: this.#cwd } : {}),\n })\n this.#models = toModelMetadata(dmmf)\n this.#provider = readDatasourceProvider({\n ...(this.#schemaPath !== undefined ? { schemaPath: this.#schemaPath } : {}),\n ...(this.#cwd !== undefined ? { cwd: this.#cwd } : {}),\n })\n return this.#models\n }\n\n async list(model: string, query: ListQuery): Promise<Page<RecordData>> {\n const declared = await this.#requireModel(model)\n const delegate = await this.#delegate(model)\n\n // Narrowed first: everything below reads the model, so restricting it once\n // restricts field lookup, free-text search and relation loading together.\n const metadata = narrowFields(declared, query.fields)\n\n const args = toFindManyArgs(metadata, query, this.#provider)\n const include = toIncludeClause(metadata, await this.getModels())\n const omit = omitClause(declared, query.fields)\n const withRelations = { ...args, ...(include ? { include } : {}), ...(omit ? { omit } : {}) }\n const { page, perPage } = resolvePagination(query)\n\n const [rows, total] = await this.#run(model, () =>\n Promise.all([\n delegate.findMany(withRelations),\n delegate.count(args.where ? { where: args.where } : {}),\n ]),\n )\n\n return { data: rows as RecordData[], total, page, perPage }\n }\n\n async findOne(model: string, id: RecordId): Promise<RecordData | null> {\n const metadata = await this.#requireModel(model)\n const delegate = await this.#delegate(model)\n const where = this.#whereById(metadata, id)\n\n const include = toIncludeClause(metadata, await this.getModels())\n const record = await this.#run(model, () =>\n delegate.findUnique(include ? { where, include } : { where }),\n )\n return (record as RecordData | null) ?? null\n }\n\n async create(model: string, data: RecordData): Promise<RecordData> {\n const metadata = await this.#requireModel(model)\n const delegate = await this.#delegate(model)\n const writable = this.#validateWritableData(metadata, data)\n\n const created = await this.#run(model, () => delegate.create({ data: writable }))\n return created as RecordData\n }\n\n async update(model: string, id: RecordId, data: RecordData): Promise<RecordData> {\n const metadata = await this.#requireModel(model)\n const delegate = await this.#delegate(model)\n const where = this.#whereById(metadata, id)\n const writable = this.#validateWritableData(metadata, data)\n\n const updated = await this.#run(model, () => delegate.update({ where, data: writable }), id)\n return updated as RecordData\n }\n\n async delete(model: string, id: RecordId): Promise<void> {\n const metadata = await this.#requireModel(model)\n const delegate = await this.#delegate(model)\n const where = this.#whereById(metadata, id)\n\n await this.#run(model, () => delegate.delete({ where }), id)\n }\n\n /**\n * A page of the records on the far side of a to-many relation.\n *\n * Implemented as an ordinary list of the *target* model with one extra\n * condition, so pagination, sorting, filtering and relation loading all\n * behave exactly as they do on a top-level list. See `to-related-where.ts`.\n */\n async listRelated(\n model: string,\n id: RecordId,\n relationField: string,\n query: ListQuery,\n ): Promise<Page<RecordData>> {\n const metadata = await this.#requireModel(model)\n const models = await this.getModels()\n\n // The relation is validated first: a bad field name is wrong whether or\n // not the record exists, and rejecting it here costs no query.\n const { target, where } = toRelatedWhere(metadata, relationField, id, models)\n\n // A missing parent is a 404, not an empty page. The condition below would\n // simply match nothing, which reads as \"this record has no children\".\n await this.#requireRecord(model, metadata, id)\n const delegate = await this.#delegate(target.name)\n\n const narrowed = narrowFields(target, query.fields)\n const args = toFindManyArgs(narrowed, query, this.#provider)\n const combined = args.where ? { AND: [args.where, where] } : where\n const include = toIncludeClause(narrowed, models)\n const omit = omitClause(target, query.fields)\n\n const { page, perPage } = resolvePagination(query)\n const [rows, total] = await this.#run(target.name, () =>\n Promise.all([\n delegate.findMany({\n ...args,\n where: combined,\n ...(include ? { include } : {}),\n ...(omit ? { omit } : {}),\n }),\n delegate.count({ where: combined }),\n ]),\n )\n\n return { data: rows as RecordData[], total, page, perPage }\n }\n\n async attachRelated(\n model: string,\n id: RecordId,\n relationField: string,\n targetId: RecordId,\n ): Promise<void> {\n await this.#link(model, id, relationField, targetId, 'connect')\n }\n\n async detachRelated(\n model: string,\n id: RecordId,\n relationField: string,\n targetId: RecordId,\n ): Promise<void> {\n await this.#link(model, id, relationField, targetId, 'disconnect')\n }\n\n // ---------------------------------------------------------------- internals\n\n /**\n * Add or remove one link, from the parent's side.\n *\n * Prisma expresses both the same way and works out where the link is stored -\n * a join-table row for a many-to-many, the child's foreign key for a\n * one-to-many. Whether the operation is allowed is the caller's decision;\n * this performs it.\n */\n async #link(\n model: string,\n id: RecordId,\n relationField: string,\n targetId: RecordId,\n operation: 'connect' | 'disconnect',\n ): Promise<void> {\n const metadata = await this.#requireModel(model)\n const models = await this.getModels()\n const { target } = toRelatedWhere(metadata, relationField, id, models)\n\n const [targetKey] = target.primaryKey\n if (targetKey === undefined) {\n throw new FieldNotFoundError(target.name, relationField, 'The target has no primary key.')\n }\n\n const delegate = await this.#delegate(model)\n await this.#run(\n model,\n () =>\n delegate.update({\n where: this.#whereById(metadata, id),\n data: { [relationField]: { [operation]: { [targetKey]: targetId } } },\n }),\n id,\n )\n }\n\n /** Throw `RecordNotFoundError` unless the record exists. */\n async #requireRecord(model: string, metadata: ModelMetadata, id: RecordId): Promise<void> {\n const delegate = await this.#delegate(model)\n const found = await this.#run(\n model,\n () => delegate.findUnique({ where: this.#whereById(metadata, id) }),\n id,\n )\n if (found === null || found === undefined) throw new RecordNotFoundError(model, id)\n }\n\n async #requireModel(model: string): Promise<ModelMetadata> {\n const models = await this.getModels()\n const found = models.find((candidate) => candidate.name === model)\n if (!found) {\n throw new ModelNotFoundError(\n model,\n models.map((candidate) => candidate.name),\n )\n }\n return found\n }\n\n async #delegate(model: string): Promise<PrismaModelDelegate> {\n const models = await this.getModels()\n return resolveDelegate(\n this.#client,\n model,\n models.map((candidate) => candidate.name),\n )\n }\n\n /**\n * Build a `where` clause addressing a single record by primary key.\n *\n * Composite keys are represented in metadata but not supported here: a\n * `RecordId` is a single scalar, so there is nothing to map the second\n * column from. Rejected explicitly rather than silently mis-querying.\n */\n #whereById(model: ModelMetadata, id: RecordId): Record<string, unknown> {\n const [primaryKeyField, ...rest] = model.primaryKey\n\n if (primaryKeyField === undefined) {\n throw new InvalidQueryError(\n `Model \"${model.name}\" has no primary key, so records cannot be addressed by id.`,\n )\n }\n if (rest.length > 0) {\n throw new InvalidQueryError(\n `Model \"${model.name}\" has a composite primary key ` +\n `(${model.primaryKey.join(', ')}), which is not supported in this version.`,\n )\n }\n\n return { [primaryKeyField]: this.#coerceId(model, primaryKeyField, id) }\n }\n\n /**\n * Coerce an id to the type the schema declares.\n *\n * Ids arriving from a URL are always strings, but a Prisma `Int @id` column\n * must be queried with a number or Prisma rejects the argument.\n */\n #coerceId(model: ModelMetadata, fieldName: string, id: RecordId): RecordId {\n const field = model.fields.find((candidate) => candidate.name === fieldName)\n if (field?.kind !== 'number' || typeof id === 'number') return id\n\n const numeric = Number(id)\n if (!Number.isFinite(numeric)) {\n throw new InvalidQueryError(\n `Invalid id ${JSON.stringify(id)} for numeric primary key ` +\n `\"${model.name}.${fieldName}\".`,\n )\n }\n return numeric\n }\n\n /**\n * Reject anything the caller has no business writing.\n *\n * Unknown keys are an error rather than silently dropped: quietly discarding\n * a field the user filled in is worse than telling them it does not exist.\n * Relation and list fields are rejected because nested writes are not\n * implemented - see the Phase 2 report.\n */\n #validateWritableData(model: ModelMetadata, data: RecordData): RecordData {\n if (typeof data !== 'object' || data === null || Array.isArray(data)) {\n throw new InvalidQueryError(`Write payload for \"${model.name}\" must be an object.`)\n }\n\n const writable: RecordData = {}\n for (const [key, value] of Object.entries(data)) {\n const field = model.fields.find((candidate) => candidate.name === key)\n if (!field) {\n throw new FieldNotFoundError(model.name, key)\n }\n if (field.kind === 'relation') {\n throw new FieldNotFoundError(\n model.name,\n key,\n 'Writing relation fields is not supported in this version.',\n )\n }\n if (field.isList) {\n throw new FieldNotFoundError(\n model.name,\n key,\n 'Writing list fields is not supported in this version.',\n )\n }\n writable[key] = value\n }\n return writable\n }\n\n /**\n * Run a client call, translating Prisma failures into Core errors.\n *\n * Prisma error types are identified by their `code` property rather than\n * `instanceof`. Importing `@prisma/client` to get the error classes would\n * mean loading a second copy of a package the consumer owns, and would tie\n * us to their Prisma version.\n */\n async #run<T>(model: string, operation: () => Promise<T>, id?: RecordId): Promise<T> {\n try {\n return await operation()\n } catch (cause) {\n if (isNestAdminError(cause)) throw cause\n\n if (isPrismaError(cause) && cause.code === PRISMA_RECORD_NOT_FOUND && id !== undefined) {\n throw new RecordNotFoundError(model, id)\n }\n\n // A refused write is a fact about the request, not a failure of the\n // database. Reporting it as an internal error is what made a duplicate\n // email indistinguishable from a dead connection.\n const constraint = toConstraintError(cause, model)\n if (constraint) throw constraint\n\n const detail = cause instanceof Error ? cause.message : String(cause)\n throw new AdapterError(`Prisma operation failed for model \"${model}\": ${detail}`, { cause })\n }\n }\n}\n\nfunction isPrismaError(value: unknown): value is { code: string } {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'code' in value &&\n typeof (value as { code: unknown }).code === 'string'\n )\n}\n\n/**\n * The model as this query is allowed to see it.\n *\n * Narrowing once, at the top, is what keeps the rest of the adapter honest:\n * field lookup, free-text search and relation loading all read the model, so\n * they inherit the restriction without knowing it exists. Doing it per-concern\n * would mean three places to forget.\n */\nfunction narrowFields(model: ModelMetadata, fields: readonly string[] | undefined): ModelMetadata {\n if (!fields) return model\n\n const allowed = new Set(fields)\n return { ...model, fields: model.fields.filter((field) => allowed.has(field.name)) }\n}\n\n/**\n * Columns to leave out of the result.\n *\n * `omit` rather than `select` because it composes with `include`: a `select`\n * would have to enumerate the relations too, and would silently drop any the\n * caller forgot. This way a hidden column is never read at all, which is a\n * stronger guarantee than removing it from the response afterwards.\n */\nfunction omitClause(\n model: ModelMetadata,\n fields: readonly string[] | undefined,\n): Record<string, true> | undefined {\n if (!fields) return undefined\n\n const allowed = new Set(fields)\n const omitted: Record<string, true> = {}\n\n for (const field of model.fields) {\n // Relations are excluded through `include`, not `omit`; Prisma rejects\n // naming them here.\n if (!allowed.has(field.name) && field.kind !== 'relation') omitted[field.name] = true\n }\n\n return Object.keys(omitted).length > 0 ? omitted : undefined\n}\n","/**\n * Dynamic model resolution.\n *\n * The admin addresses models by name at runtime (`\"User\"`), so the Prisma\n * Client's statically-typed delegates cannot be reached through their types.\n * This module is the single, deliberately narrow place where that type escape\n * happens. Nothing else in the package casts the client.\n */\nimport { AdapterError, ModelNotFoundError } from '@nest-admin/core'\n\n/**\n * The subset of a Prisma model delegate the adapter uses.\n *\n * Declared structurally rather than imported from `@prisma/client`: the client\n * is generated in the consumer's project against their schema, so there is no\n * meaningful shared type to import, and depending on one would couple us to a\n * Prisma version we do not control.\n */\nexport interface PrismaModelDelegate {\n findMany(args?: unknown): Promise<unknown[]>\n findUnique(args: unknown): Promise<unknown>\n count(args?: unknown): Promise<number>\n create(args: unknown): Promise<unknown>\n update(args: unknown): Promise<unknown>\n delete(args: unknown): Promise<unknown>\n}\n\nconst REQUIRED_METHODS = [\n 'findMany',\n 'findUnique',\n 'count',\n 'create',\n 'update',\n 'delete',\n] as const satisfies readonly (keyof PrismaModelDelegate)[]\n\n/**\n * Property names that must never be used as a delegate lookup key, regardless\n * of what the caller passes. Model names are validated against known metadata\n * before we get here, so this is defence in depth rather than the only guard.\n */\nconst FORBIDDEN_KEYS = new Set(['__proto__', 'constructor', 'prototype'])\n\n/**\n * Prisma exposes `model User` as `prisma.user` - the model name with only its\n * first character lower-cased. Note this is not general camelCase conversion:\n * `UserProfile` becomes `userProfile`, and `HTTPLog` becomes `hTTPLog`.\n */\nexport function toDelegateKey(modelName: string): string {\n if (modelName.length === 0) return modelName\n return modelName.charAt(0).toLowerCase() + modelName.slice(1)\n}\n\n/**\n * Resolve a model name to its Prisma Client delegate.\n *\n * `knownModels` is the metadata-derived allowlist. A name outside it is\n * rejected before the client is touched at all, so an attacker-controlled\n * model name can never reach arbitrary client properties.\n */\nexport function resolveDelegate(\n client: unknown,\n modelName: string,\n knownModels: readonly string[],\n): PrismaModelDelegate {\n if (!knownModels.includes(modelName)) {\n throw new ModelNotFoundError(modelName, knownModels)\n }\n\n const key = toDelegateKey(modelName)\n if (FORBIDDEN_KEYS.has(key)) {\n throw new ModelNotFoundError(modelName, knownModels)\n }\n\n if (typeof client !== 'object' || client === null) {\n throw new AdapterError(\n 'PrismaAdapter requires a constructed Prisma Client instance. ' +\n `Received ${client === null ? 'null' : typeof client}.`,\n )\n }\n\n // The one type escape. Guarded above by the metadata allowlist and below by\n // a shape check, so the cast is asserted rather than assumed.\n const candidate = (client as Record<string, unknown>)[key]\n\n if (typeof candidate !== 'object' || candidate === null) {\n throw new AdapterError(\n `The Prisma Client has no delegate \"${key}\" for model \"${modelName}\". ` +\n 'This usually means the client was generated from a different schema ' +\n 'than the one Nest Admin read - re-run `prisma generate`.',\n )\n }\n\n const delegate = candidate as Record<string, unknown>\n const missing = REQUIRED_METHODS.filter((method) => typeof delegate[method] !== 'function')\n if (missing.length > 0) {\n throw new AdapterError(\n `Prisma Client delegate \"${key}\" is missing expected methods: ${missing.join(', ')}.`,\n )\n }\n\n return candidate as PrismaModelDelegate\n}\n","/**\n * Prisma version gate.\n *\n * Phase 1 established that `@prisma/get-dmmf` is pinned exactly and enforces\n * *its own* Prisma version's schema rules: given a Prisma 6 schema, the 7.x\n * parser rejects `url` inside `datasource` even though the schema is perfectly\n * valid for that consumer. Without a gate, that surfaces as a confusing\n * \"Prisma rejected the schema\" error pointing at the user's own valid file.\n *\n * The gate turns that into a statement about versions.\n *\n * ## Two deliberate design choices\n *\n * **It fails open on detection.** The client version is read from\n * `client._clientVersion`, an underscore-prefixed internal. If Prisma renames\n * or removes it, the gate silently does nothing rather than breaking every\n * consumer on an otherwise-fine upgrade. A version check that itself becomes\n * the outage is worse than no version check.\n *\n * **It compares majors only.** Minor and patch releases have not changed the\n * schema language; majors have. Pinning tighter would produce false alarms on\n * every routine bump.\n *\n * This lives in `packages/prisma`, not Core - Core must never learn what\n * Prisma is.\n */\nimport { NestAdminError } from '@nest-admin/core'\n\n/**\n * Prisma majors whose schema language this adapter's pinned parser handles.\n *\n * Derived from the parser we ship (`@prisma/get-dmmf`, pinned in\n * package.json), not from what we wish were true. Widen this only after\n * testing against the new major.\n */\nexport const SUPPORTED_PRISMA_MAJORS: readonly number[] = [7]\n\n/** Raised when the consumer's Prisma Client major is outside the tested range. */\nexport class PrismaVersionUnsupportedError extends NestAdminError {\n constructor(\n readonly clientVersion: string,\n readonly supportedMajors: readonly number[],\n ) {\n super(\n `Nest Admin ships a Prisma ${supportedMajors.join('/')} schema parser, ` +\n `but this application uses Prisma Client ${clientVersion}. ` +\n 'Schema parsing would likely fail with a misleading error, so it was ' +\n 'stopped here instead. Align the versions, or open an issue if ' +\n `Prisma ${clientVersion.split('.')[0]} should be supported.`,\n )\n }\n}\n\n/**\n * Read the Prisma Client version from an instance.\n *\n * Returns `undefined` when it cannot be determined - see \"fails open\" above.\n */\nexport function readClientVersion(client: unknown): string | undefined {\n if (typeof client !== 'object' || client === null) return undefined\n const version = (client as Record<string, unknown>)['_clientVersion']\n return typeof version === 'string' && version !== '' ? version : undefined\n}\n\nfunction majorOf(version: string): number | undefined {\n const major = Number(version.split('.')[0])\n return Number.isInteger(major) ? major : undefined\n}\n\n/**\n * Throw when the client's major is known and unsupported.\n *\n * Silent when the version is unreadable or unparseable.\n */\nexport function assertSupportedPrismaVersion(\n client: unknown,\n supportedMajors: readonly number[] = SUPPORTED_PRISMA_MAJORS,\n): void {\n const version = readClientVersion(client)\n if (version === undefined) return\n\n const major = majorOf(version)\n if (major === undefined) return\n\n if (!supportedMajors.includes(major)) {\n throw new PrismaVersionUnsupportedError(version, supportedMajors)\n }\n}\n","/**\n * Prisma schema acquisition.\n *\n * This is the ONLY module in the repository permitted to import\n * `@prisma/get-dmmf`. Everything downstream consumes the returned\n * `DMMF.Document` and nothing else, which is what keeps the eventual switch to\n * a build-time Prisma generator a change to this file alone.\n */\nimport { existsSync, readdirSync, readFileSync, statSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nimport { AdapterError, isNestAdminError, NestAdminError } from '@nest-admin/core'\nimport { getDMMF } from '@prisma/get-dmmf'\nimport type * as DMMF from '@prisma/dmmf'\n\n/** Paths tried, in order, when no explicit schema location is configured. */\nconst DEFAULT_SCHEMA_CANDIDATES = ['prisma/schema.prisma', 'prisma/schema', 'schema.prisma']\n\n/** Raised when the Prisma schema cannot be located or read. */\nexport class PrismaSchemaNotFoundError extends NestAdminError {\n constructor(\n readonly triedPaths: readonly string[],\n explicit: boolean,\n ) {\n super(\n explicit\n ? `Prisma schema not found at \"${triedPaths[0]}\".`\n : `Could not locate a Prisma schema. Tried: ${triedPaths.join(', ')}. ` +\n 'Pass `schemaPath` to PrismaAdapter if your schema lives elsewhere.',\n )\n }\n}\n\n/** Raised when Prisma rejects the schema. Carries Prisma's own validation text. */\nexport class PrismaSchemaInvalidError extends NestAdminError {\n constructor(\n readonly prismaMessage: string,\n options?: { cause?: unknown },\n ) {\n super(`Prisma rejected the schema:\\n${prismaMessage}`, options)\n }\n}\n\n/**\n * Resolve the schema location to an absolute path.\n *\n * `schemaPath` may point at a single `.prisma` file or, since Prisma 7, at a\n * directory of `.prisma` files. Both are supported.\n */\nfunction locateSchema(schemaPath: string | undefined, cwd: string): string {\n if (schemaPath !== undefined) {\n const absolute = resolve(cwd, schemaPath)\n if (!existsSync(absolute)) throw new PrismaSchemaNotFoundError([absolute], true)\n return absolute\n }\n\n const tried: string[] = []\n for (const candidate of DEFAULT_SCHEMA_CANDIDATES) {\n const absolute = resolve(cwd, candidate)\n tried.push(absolute)\n if (existsSync(absolute)) return absolute\n }\n throw new PrismaSchemaNotFoundError(tried, false)\n}\n\n/**\n * Read the schema as `[filename, content]` tuples.\n *\n * `getDMMF` accepts this shape natively (`SchemaFileInput = string |\n * Array<[filename, content]>`), so multi-file schemas need no concatenation\n * and no parsing on our side. Passing real filenames also means Prisma's\n * validation errors point at the right file.\n */\nfunction readSchemaFiles(absolutePath: string): Array<[string, string]> {\n if (statSync(absolutePath).isDirectory()) {\n const files = readdirSync(absolutePath)\n .filter((name) => name.endsWith('.prisma'))\n .sort()\n if (files.length === 0) {\n throw new PrismaSchemaNotFoundError([join(absolutePath, '*.prisma')], true)\n }\n return files.map((name) => {\n const file = join(absolutePath, name)\n return [file, readFileSync(file, 'utf8')] as [string, string]\n })\n }\n\n return [[absolutePath, readFileSync(absolutePath, 'utf8')]]\n}\n\nexport interface ReadDmmfOptions {\n /** Path to a `.prisma` file or a directory of them. Auto-detected if absent. */\n readonly schemaPath?: string\n /** Base directory for relative paths and auto-detection. Defaults to `process.cwd()`. */\n readonly cwd?: string\n}\n\n/**\n * Load and parse the Prisma schema into a DMMF document.\n *\n * Note the two traps this function exists to absorb:\n *\n * 1. `getDMMF` is **synchronous** and returns `DMMF.Document | GetDMMFError` -\n * it does not throw and does not reject. Reading `.datamodel` off an error\n * result yields a bare `TypeError` with none of Prisma's diagnostics.\n * 2. Returning empty metadata on failure would surface as an admin panel with\n * no resources, which reads as a configuration mistake and costs hours.\n * Every failure here is loud.\n */\nexport function readPrismaDmmf(options: ReadDmmfOptions = {}): DMMF.Document {\n const cwd = options.cwd ?? process.cwd()\n const absolutePath = locateSchema(options.schemaPath, cwd)\n\n let files: Array<[string, string]>\n try {\n files = readSchemaFiles(absolutePath)\n } catch (cause) {\n if (isNestAdminError(cause)) throw cause\n throw new AdapterError(`Failed to read the Prisma schema at \"${absolutePath}\".`, { cause })\n }\n\n const result = getDMMF({ datamodel: files })\n\n if (!isDmmfDocument(result)) {\n throw new PrismaSchemaInvalidError(extractPrismaMessage(result), { cause: result.error })\n }\n return result\n}\n\n/**\n * The datasource provider the schema declares - `postgresql`, `sqlite`, and so\n * on - or `undefined` when it cannot be read.\n *\n * Needed because Prisma accepts `mode: 'insensitive'` on some providers and\n * *throws* on the rest, so a search that ignores capitalisation has to know\n * which database it is talking to. See `to-prisma-args.ts`.\n *\n * ## Why this is read from the text\n *\n * The provider is not in the DMMF: `getDMMF` returns the datamodel, and the\n * datasource block is not part of it. Nor can it be asked of the client -\n * Prisma 7 builds clients from driver adapters, and what the application passed\n * is not something this package is allowed to introspect. The declaration is a\n * fixed one-line form in a file we are already reading, so it is read from\n * there, and every failure is answered with `undefined` rather than a throw:\n * an unreadable provider must degrade to the case-sensitive search that was the\n * behaviour before this existed, never to a broken panel.\n *\n * It reads the schema a second time. That happens once, at startup, on a file\n * of a few kilobytes - cheaper than threading a second return value through\n * every caller of `readPrismaDmmf`.\n */\nexport function readDatasourceProvider(options: ReadDmmfOptions = {}): string | undefined {\n try {\n const files = readSchemaFiles(locateSchema(options.schemaPath, options.cwd ?? process.cwd()))\n for (const [, content] of files) {\n const declared = /datasources+w+s*{[^}]*?providers*=s*\"([a-z]+)\"/i.exec(content)\n if (declared?.[1] !== undefined) return declared[1].toLowerCase()\n }\n } catch {\n // Unreadable schema. The DMMF read reports that properly; this one is an\n // optimisation and has nothing useful to add.\n }\n return undefined\n}\n\nfunction isDmmfDocument(value: DMMF.Document | { error: Error }): value is DMMF.Document {\n return 'datamodel' in value\n}\n\n/**\n * Prisma reports validation failures as a JSON string inside `error.message`,\n * carrying an ANSI-coloured `P1012` report. Unwrap it where possible so the\n * message we surface is the one a developer would see from the Prisma CLI.\n */\nfunction extractPrismaMessage(result: { reason: string; error: Error }): string {\n const raw = result.error?.message ?? result.reason\n try {\n const parsed: unknown = JSON.parse(raw)\n if (typeof parsed === 'object' && parsed !== null && 'message' in parsed) {\n const message = (parsed as { message: unknown }).message\n if (typeof message === 'string') return stripAnsi(message)\n }\n } catch {\n // Not JSON - fall through and use the raw text.\n }\n return stripAnsi(raw)\n}\n\nconst ANSI_PATTERN = new RegExp(`${String.fromCharCode(27)}\\\\[[0-9;]*m`, 'g')\n\nfunction stripAnsi(value: string): string {\n return value.replace(ANSI_PATTERN, '')\n}\n","/**\n * DMMF -> Core `ModelMetadata`.\n *\n * The one place Prisma's vocabulary is translated into ours. No DMMF type\n * escapes this module: everything downstream (the adapter, the future HTTP\n * layer, the admin UI) sees only Core shapes.\n *\n * This mapper is deliberately independent of *how* the DMMF was obtained, so\n * it is unaffected by a later switch to a build-time Prisma generator.\n */\nimport type { FieldKind, FieldMetadata, ModelMetadata } from '@nest-admin/core'\nimport type * as DMMF from '@prisma/dmmf'\n\n/**\n * Prisma scalar type -> Core field kind.\n *\n * `BigInt`, `Decimal` and `Bytes` are intentionally mapped to `'unknown'`\n * rather than squeezed into `'number'` or `'string'`. They do not round-trip\n * through JSON without losing precision or fidelity, and the MVP has not\n * tested editing them - claiming support we have not verified would be worse\n * than declaring them unhandled. They are still listed, so the admin can show\n * them read-only.\n */\nconst SCALAR_KINDS: Readonly<Record<string, FieldKind>> = {\n String: 'string',\n Int: 'number',\n Float: 'number',\n Boolean: 'boolean',\n DateTime: 'datetime',\n Json: 'json',\n}\n\nfunction toFieldKind(field: DMMF.Field): FieldKind {\n if (field.kind === 'object') return 'relation'\n if (field.kind === 'enum') return 'enum'\n if (field.kind === 'scalar') return SCALAR_KINDS[field.type] ?? 'unknown'\n return 'unknown'\n}\n\n/**\n * Is this default produced by the database or the ORM, rather than supplied by\n * the user?\n *\n * Measured against Prisma 7.10.0, DMMF distinguishes the two by *shape*:\n *\n * @default(cuid()) -> { name: 'cuid', args: [1] } (object)\n * @default(now()) -> { name: 'now', args: [] } (object)\n * @default(autoincrement()) -> { name: 'autoincrement' } (object)\n * @default(dbgenerated(..)) -> { name: 'dbgenerated', ... } (object)\n * @default(true) -> true (primitive)\n * @default(0) -> 0 (primitive)\n * @default(\"USER\") -> \"USER\" (primitive)\n *\n * So a function default is an object carrying `name`; a literal default is a\n * primitive. Treating \"has a default\" as \"generated\" would wrongly lock\n * `active Boolean @default(true)` out of every create form.\n */\nfunction isFunctionDefault(value: unknown): value is { name: string; args?: unknown[] } {\n return typeof value === 'object' && value !== null && !Array.isArray(value) && 'name' in value\n}\n\nfunction toFieldMetadata(\n field: DMMF.Field,\n enums: ReadonlyMap<string, readonly string[]>,\n): FieldMetadata {\n const kind = toFieldKind(field)\n\n // A value the database or ORM supplies: a function default, or @updatedAt.\n const isGenerated = field.isUpdatedAt === true || isFunctionDefault(field.default)\n\n // A literal default is a pre-fill for the create form, not a generated value.\n const hasLiteralDefault = field.hasDefaultValue === true && !isFunctionDefault(field.default)\n\n const base = {\n name: field.name,\n kind,\n isId: field.isId === true,\n isRequired: field.isRequired === true,\n isUnique: field.isUnique === true,\n isList: field.isList === true,\n isGenerated,\n } satisfies Omit<FieldMetadata, 'defaultValue' | 'enumValues' | 'relation'>\n\n return {\n ...base,\n ...(hasLiteralDefault ? { defaultValue: field.default } : {}),\n ...(kind === 'enum' ? { enumValues: enums.get(field.type) ?? [] } : {}),\n ...(kind === 'relation'\n ? {\n relation: {\n targetModel: field.type,\n // Cardinality follows directly from isList - the single attribute\n // the generated Prisma Client does not expose at runtime, which is\n // why metadata comes from the schema rather than the client.\n cardinality: field.isList === true ? ('many' as const) : ('one' as const),\n // Present only on the owning side of a to-one relation. Prisma\n // gives both sides a relation field but only one of them a column,\n // and these arrays are empty on the side that has none - so an\n // empty array means \"no foreign key here\", not \"unknown\".\n ...(field.relationFromFields?.[0] !== undefined\n ? { from: field.relationFromFields[0] }\n : {}),\n ...(field.relationToFields?.[0] !== undefined ? { to: field.relationToFields[0] } : {}),\n // Shared by both halves, so the other side can be found. Prisma\n // generates one when the schema does not name it.\n ...(field.relationName !== undefined ? { name: field.relationName } : {}),\n },\n }\n : {}),\n }\n}\n\n/**\n * Field names forming the model's primary key.\n *\n * Prisma expresses a single-column key as `@id` on the field and a composite\n * key as a model-level `@@id`, which DMMF surfaces as `primaryKey.fields`.\n * Both are represented here; the adapter is what limits the MVP to\n * single-column keys.\n */\nfunction toPrimaryKey(model: DMMF.Model): readonly string[] {\n const compositeFields = model.primaryKey?.fields\n if (compositeFields && compositeFields.length > 0) return [...compositeFields]\n return model.fields.filter((field) => field.isId === true).map((field) => field.name)\n}\n\n/** Translate a whole DMMF document into Core model metadata. */\nexport function toModelMetadata(dmmf: DMMF.Document): readonly ModelMetadata[] {\n const enums = new Map<string, readonly string[]>(\n dmmf.datamodel.enums.map((enumType) => [\n enumType.name,\n enumType.values.map((value) => value.name),\n ]),\n )\n\n return dmmf.datamodel.models.map((model) => ({\n name: model.name,\n primaryKey: toPrimaryKey(model),\n fields: model.fields.map((field) => toFieldMetadata(field, enums)),\n }))\n}\n","/**\n * Loading the readable side of a to-one relation.\n *\n * A record stores `authorId`. A person needs \"Ada Lovelace\". Resolving that in\n * the caller would mean one query per row - the classic N+1 - so it is done in\n * the same query, with an `include`.\n *\n * ## Only two columns are ever selected\n *\n * The `include` carries an explicit `select` of the target's primary key and\n * its display field, and nothing else. That is a security boundary, not an\n * optimisation: `include: { author: true }` would attach the *whole* related\n * record to every row, so a `User.passwordHash` would be published by the act\n * of listing `Post`. Naming the two columns means a relation can never widen\n * what a response contains.\n *\n * To-many relations are not loaded. They have no column on this side, they can\n * be unbounded, and one `include` per row would turn a list page into an\n * unpredictable amount of work. They arrive in 0.4.0, paginated and asked for\n * explicitly.\n */\nimport { displayFieldFor, type ModelMetadata } from '@nest-admin/core'\n\n/** A Prisma `include` clause, or `undefined` when the model has no to-one relations. */\nexport type IncludeClause = Record<string, { select: Record<string, true> }>\n\n/**\n * Build the `include` for every to-one relation the model owns.\n *\n * `models` is the full set, because the display field belongs to the *target*\n * model and can only be resolved by looking it up. A relation whose target is\n * missing from that set is skipped rather than guessed at: the target may have\n * been excluded from the admin by configuration, and inventing a column name\n * would produce a Prisma error blaming the schema.\n */\nexport function toIncludeClause(\n model: ModelMetadata,\n models: readonly ModelMetadata[],\n): IncludeClause | undefined {\n const include: IncludeClause = {}\n\n for (const field of model.fields) {\n const relation = field.relation\n // `from` is what distinguishes the owning side from the other one. Without\n // it there is no column here, so there is nothing to resolve.\n if (!relation || relation.cardinality !== 'one' || relation.from === undefined) continue\n\n const target = models.find((candidate) => candidate.name === relation.targetModel)\n if (!target) continue\n\n const select: Record<string, true> = {}\n for (const key of target.primaryKey) select[key] = true\n select[displayFieldFor(target)] = true\n\n include[field.name] = { select }\n }\n\n return Object.keys(include).length > 0 ? include : undefined\n}\n","/**\n * Prisma error codes -> Core constraint errors.\n *\n * Everything here exists so that an ordinary mistake in a form stops being\n * reported as an internal error. Before it, a duplicate email, a foreign key\n * pointing at nothing and a missing required value all came back as\n * \"an internal error occurred\" - the correct treatment for a broken database\n * and the wrong one for a person who typed the same address twice.\n *\n * ## Codes, not classes\n *\n * Matched by `code` rather than `instanceof PrismaClientKnownRequestError`, for\n * the reason the adapter already gives: importing `@prisma/client` here would\n * load a second copy of a package the consumer owns and tie this package to\n * their Prisma version.\n *\n * ## Field names come from `meta`, and may not be there\n *\n * Prisma reports the columns involved differently per code and per connector,\n * and sometimes not at all - a SQLite unique violation on a composite index\n * names the index rather than the columns. Where a name is missing the error\n * says so in general terms rather than inventing one, because a message that\n * blames the wrong field is worse than one that blames none.\n */\nimport { ConstraintError, type ConstraintKind } from '@nest-admin/core'\n\n/**\n * Measured against Prisma 7.10.0.\n *\n * `P2014` is the one worth naming: it fires when a *delete* would orphan a\n * required relation, so it is a foreign-key problem arriving from the opposite\n * direction to `P2003`.\n */\nconst CONSTRAINT_CODES: Readonly<Record<string, ConstraintKind>> = {\n P2002: 'unique',\n P2003: 'foreign-key',\n P2014: 'foreign-key',\n P2011: 'required',\n P2012: 'required',\n P2013: 'required',\n}\n\ninterface PrismaKnownError {\n readonly code: string\n readonly meta?: Readonly<Record<string, unknown>>\n}\n\nfunction isPrismaKnownError(value: unknown): value is PrismaKnownError {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'code' in value &&\n typeof (value as { code: unknown }).code === 'string'\n )\n}\n\n/**\n * The columns Prisma named, if it named any.\n *\n * The shape differs by code: `target` for a unique violation (a string or an\n * array, depending on the connector), `field_name` for a foreign key,\n * `constraint` for a null violation. Anything unrecognised yields nothing,\n * which the message handles.\n */\nfunction fieldsFrom(meta: Readonly<Record<string, unknown>> | undefined): readonly string[] {\n if (!meta) return []\n\n // Prisma 7 with a driver adapter nests the connector's own report, and that\n // is the only place the column names appear - `meta.target` is the older,\n // flatter shape and is still what a client without a driver adapter reports.\n // Both are read, because which one arrives depends on how the consumer built\n // their client rather than on anything this package controls.\n const nested = (meta['driverAdapterError'] as { cause?: { constraint?: unknown } } | undefined)\n ?.cause?.constraint\n\n const candidate =\n (nested as { fields?: unknown } | undefined)?.fields ??\n meta['target'] ??\n meta['field_name'] ??\n meta['constraint']\n\n if (Array.isArray(candidate)) {\n return candidate.filter((entry): entry is string => typeof entry === 'string')\n }\n\n if (typeof candidate !== 'string') return []\n\n // Some connectors report the index name rather than the columns -\n // `User_email_key` for `@unique` on `email`. The column is recoverable from\n // the convention, and a wrong guess here would name a field that does not\n // exist, so it is only trusted when the shape matches exactly.\n const index = /^(.+?)_(.+)_key$/.exec(candidate)\n if (index?.[2] !== undefined) return index[2].split('_')\n\n return [candidate]\n}\n\n/**\n * A missing required argument, which Prisma refuses before the database sees it.\n *\n * It arrives as `PrismaClientValidationError`, which carries **no code** - so\n * it cannot be matched the way every other case here is, and without special\n * handling a form submitted without a required field answers with a generic\n * 500.\n *\n * The message names the arguments in a fixed phrase, and that phrase is all\n * that is read from it. The rest of the text is a rendering of the call site\n * and of the data that was submitted - absolute paths and field values - so\n * forwarding any of it is out of the question.\n */\nfunction missingArguments(cause: unknown): readonly string[] {\n if (!(cause instanceof Error) || cause.constructor.name !== 'PrismaClientValidationError') {\n return []\n }\n\n const names: string[] = []\n for (const match of cause.message.matchAll(/Argument `([A-Za-z0-9_]+)` is missing/g)) {\n if (match[1] !== undefined) names.push(match[1])\n }\n\n return names\n}\n\n/**\n * A `ConstraintError` when Prisma refused the write for a reason a caller can\n * act on, or `undefined` when it did not.\n */\nexport function toConstraintError(cause: unknown, model: string): ConstraintError | undefined {\n const missing = missingArguments(cause)\n if (missing.length > 0) return new ConstraintError('required', model, missing)\n\n if (!isPrismaKnownError(cause)) return undefined\n\n const constraint = CONSTRAINT_CODES[cause.code]\n if (!constraint) return undefined\n\n return new ConstraintError(constraint, model, fieldsFrom(cause.meta))\n}\n","/**\n * Asking the target model for the records linked to one parent.\n *\n * A related list could be fetched from the parent - `user.posts()` - but then\n * pagination, sorting, filtering and relation loading would all have to be\n * reimplemented for that path. Asking the *target* model with an extra `where`\n * instead means a related list is an ordinary list that happens to be\n * constrained, and everything already built for lists applies to it unchanged.\n *\n * The constraint is expressed through the relation's other half, which is why\n * relation names matter:\n *\n * User.posts -> inverse is Post.author (to-one) -> { author: { id: <parent> } }\n * Post.tags -> inverse is Tag.posts (to-many) -> { posts: { some: { id: <parent> } } }\n *\n * Both are Prisma relation filters on the target, so neither needs to know\n * whether a foreign key exists or where it lives.\n */\nimport {\n FieldNotFoundError,\n inverseRelationField,\n type ModelMetadata,\n type RecordId,\n} from '@nest-admin/core'\n\n/**\n * A `where` clause selecting the target records linked to `parentId`.\n *\n * `parentKey` is the parent's primary-key field, which the filter matches on.\n */\nexport function toRelatedWhere(\n parent: ModelMetadata,\n relationFieldName: string,\n parentId: RecordId,\n models: readonly ModelMetadata[],\n): { target: ModelMetadata; where: Record<string, unknown> } {\n const field = parent.fields.find((candidate) => candidate.name === relationFieldName)\n\n if (!field?.relation) {\n throw new FieldNotFoundError(\n parent.name,\n relationFieldName,\n 'Only a relation field can be listed this way.',\n )\n }\n\n if (field.relation.cardinality !== 'many') {\n throw new FieldNotFoundError(\n parent.name,\n relationFieldName,\n 'This is a to-one relation. It arrives with the record itself.',\n )\n }\n\n const target = models.find((candidate) => candidate.name === field.relation?.targetModel)\n if (!target) {\n // The target is not part of this admin - excluded by configuration, or\n // hidden from this principal. Either way there is nothing to list.\n throw new FieldNotFoundError(\n parent.name,\n relationFieldName,\n `${field.relation.targetModel} is not available.`,\n )\n }\n\n const inverse = inverseRelationField(field, models)\n if (!inverse) {\n // Without the other half there is no way to express the constraint, and\n // returning every record of the target would be catastrophically wrong.\n throw new FieldNotFoundError(\n parent.name,\n relationFieldName,\n 'The other half of this relation could not be resolved.',\n )\n }\n\n const [parentKey] = parent.primaryKey\n if (parentKey === undefined) {\n throw new FieldNotFoundError(\n parent.name,\n relationFieldName,\n `${parent.name} has no primary key.`,\n )\n }\n\n const match = { [parentKey]: parentId }\n\n return {\n target,\n where: {\n [inverse.name]: inverse.relation?.cardinality === 'many' ? { some: match } : { is: match },\n },\n }\n}\n","/**\n * Core `ListQuery` -> Prisma `findMany` arguments.\n *\n * Everything here is validated against model metadata before it reaches the\n * client. Field names arriving from an HTTP request eventually flow into this\n * module, so an unvalidated name would become an injection surface into the\n * query object. There is no raw SQL anywhere; all queries go through Prisma's\n * structured API.\n */\nimport {\n FieldNotFoundError,\n InvalidQueryError,\n type FieldMetadata,\n type FilterRule,\n type ListQuery,\n type ModelMetadata,\n} from '@nest-admin/core'\n\nexport const DEFAULT_PER_PAGE = 25\nexport const MAX_PER_PAGE = 100\n\n/** Operators that only make sense on string fields. */\nconst STRING_ONLY_OPERATORS = new Set(['contains', 'startsWith', 'endsWith'])\n\n/** Operators that require an ordered (numeric, date, or string) field. */\nconst COMPARISON_OPERATORS = new Set(['gt', 'gte', 'lt', 'lte'])\n\nexport interface PrismaFindManyArgs {\n where?: Record<string, unknown>\n orderBy?: Array<Record<string, 'asc' | 'desc'>>\n skip?: number\n take?: number\n}\n\n/**\n * What the field is being resolved for.\n *\n * Only relations care, and they care because the two cases are not symmetric.\n * See {@link findQueryableField}.\n */\ntype QueryPurpose = 'filter' | 'sort'\n\n/**\n * A field usable in a filter or a sort.\n *\n * A to-one relation the model owns is stored in a scalar column, so a **filter**\n * on `author` is answerable: it means exactly a filter on `authorId`, and the\n * caller gets to use whichever name they think in.\n *\n * **Sorting** by it is refused, even though it would run. `authorId` holds a\n * cuid, so ordering by it is ordering by a random-looking string - a result\n * that looks sorted, is stable, and means nothing. What someone asking to sort\n * by `author` wants is the author's *name*, which is sorting by a field on\n * another model and is not this version. A refusal that says so is better than\n * a page of rows in an order nobody can explain.\n *\n * List fields are excluded outright: there is no column on this side at all.\n */\nfunction findQueryableField(\n model: ModelMetadata,\n fieldName: string,\n purpose: QueryPurpose,\n): FieldMetadata {\n const field = model.fields.find((candidate) => candidate.name === fieldName)\n if (!field) {\n throw new FieldNotFoundError(model.name, fieldName)\n }\n if (field.kind === 'relation') {\n const owned = field.relation?.from\n if (owned !== undefined && field.relation?.cardinality === 'one') {\n if (purpose === 'filter') return findQueryableField(model, owned, purpose)\n\n throw new FieldNotFoundError(\n model.name,\n fieldName,\n `Sorting by a relation is not supported in this version. ` +\n `Sorting by \"${owned}\" would order by an opaque key rather than by ` +\n `anything readable.`,\n )\n }\n\n throw new FieldNotFoundError(\n model.name,\n fieldName,\n 'Relation fields cannot be filtered or sorted in this version.',\n )\n }\n if (field.isList) {\n throw new FieldNotFoundError(\n model.name,\n fieldName,\n 'List fields cannot be filtered or sorted in this version.',\n )\n }\n return field\n}\n\nfunction toPrismaCondition(model: ModelMetadata, rule: FilterRule): Record<string, unknown> {\n const field = findQueryableField(model, rule.field, 'filter')\n\n if (STRING_ONLY_OPERATORS.has(rule.operator) && field.kind !== 'string') {\n throw new InvalidQueryError(\n `Operator \"${rule.operator}\" requires a string field, but ` +\n `\"${model.name}.${field.name}\" is of kind \"${field.kind}\".`,\n )\n }\n\n if (COMPARISON_OPERATORS.has(rule.operator) && field.kind === 'boolean') {\n throw new InvalidQueryError(\n `Operator \"${rule.operator}\" cannot be applied to boolean field ` +\n `\"${model.name}.${field.name}\".`,\n )\n }\n\n if (rule.operator === 'in') {\n if (!Array.isArray(rule.value)) {\n throw new InvalidQueryError(\n `Operator \"in\" requires an array value for \"${model.name}.${field.name}\".`,\n )\n }\n return { [field.name]: { in: rule.value } }\n }\n\n if (rule.operator === 'eq') return { [field.name]: { equals: rule.value } }\n if (rule.operator === 'ne') return { [field.name]: { not: rule.value } }\n\n return { [field.name]: { [rule.operator]: rule.value } }\n}\n\n/**\n * Providers where Prisma accepts `mode: 'insensitive'`.\n *\n * The list is short because Prisma *throws* on the others rather than ignoring\n * the option, so being wrong here breaks every search rather than degrading it.\n *\n * The omissions are deliberate, not oversights:\n *\n * | Provider | Why nothing is sent |\n * | ---------- | ---------------------------------------------------------- |\n * | mysql | Its default collations end in `_ci`; `LIKE` already ignores case. |\n * | sqlite | `LIKE` is case-insensitive for ASCII by default. |\n * | sqlserver | Its default collation is case-insensitive. |\n * | cockroachdb | Prisma documents `mode` for PostgreSQL and MongoDB only. |\n *\n * So on the four below, the option is unnecessary; on CockroachDB it is\n * unproven, and this is not the place to guess.\n */\nconst INSENSITIVE_MODE_PROVIDERS: ReadonlySet<string> = new Set([\n 'postgresql',\n 'postgres',\n 'mongodb',\n])\n\n/**\n * The case-insensitivity option for this provider, if it takes one.\n *\n * Spread into every string comparison. Returning an object to spread rather\n * than a boolean to branch on keeps the option out of the query entirely where\n * it is not supported - Prisma rejects `mode: undefined` as readily as it\n * rejects `mode: 'insensitive'` on SQLite.\n */\nexport function insensitively(provider: string | undefined): { mode?: 'insensitive' } {\n return provider !== undefined && INSENSITIVE_MODE_PROVIDERS.has(provider)\n ? { mode: 'insensitive' }\n : {}\n}\n\n/** String comparisons, which are the ones capitalisation applies to. */\nconst TEXTUAL_OPERATORS: ReadonlySet<string> = new Set(['contains', 'startsWith', 'endsWith'])\n\n/**\n * Free-text search: `contains` across the model's meaningful string fields.\n *\n * Generated string fields are excluded. A `cuid()` or `uuid()` primary key is\n * an opaque machine value, and including it makes single-letter searches match\n * essentially at random - searching \"e\" returns any record whose id happens to\n * contain an \"e\". Looking a record up by its id is an exact-match concern, so\n * it belongs in a filter (`{ field: 'id', operator: 'eq' }`), not in free text.\n *\n * Capitalisation is ignored, which needed the provider to say so. Searching\n * \"ada\" and getting nothing because the record says \"Ada\" is the kind of defect\n * people conclude the search is broken from, and they are not wrong. What it\n * takes to ignore case differs per database, and on some of them the option\n * that does it is an error - hence `insensitively`.\n */\nfunction toSearchCondition(\n model: ModelMetadata,\n term: string,\n provider: string | undefined,\n): Record<string, unknown> | undefined {\n // Foreign keys are string columns holding a cuid, so they match the same\n // rule the generated-id exclusion exists for - and they are not generated,\n // so that rule misses them. Left in, a search for \"e\" matches almost every\n // row of any model that references another, because most cuids contain an e.\n const foreignKeys = new Set(\n model.fields.map((field) => field.relation?.from).filter((name) => name !== undefined),\n )\n\n const stringFields = model.fields.filter(\n (field) =>\n field.kind === 'string' &&\n !field.isList &&\n !field.isGenerated &&\n !foreignKeys.has(field.name),\n )\n if (stringFields.length === 0) return undefined\n\n return {\n OR: stringFields.map((field) => ({\n [field.name]: { contains: term, ...insensitively(provider) },\n })),\n }\n}\n\nexport function buildWhere(\n model: ModelMetadata,\n query: Pick<ListQuery, 'filters' | 'search'>,\n provider?: string,\n): Record<string, unknown> | undefined {\n const conditions: Array<Record<string, unknown>> = []\n\n for (const rule of query.filters ?? []) {\n const condition = toPrismaCondition(model, rule)\n // A \"contains\" filter is the same promise the search box makes, typed into\n // a different box. It would be strange for one to ignore case and not the\n // other, and stranger still to have to know which.\n conditions.push(\n TEXTUAL_OPERATORS.has(rule.operator) ? insensitive(condition, provider) : condition,\n )\n }\n\n const search = query.search?.trim()\n if (search) {\n const searchCondition = toSearchCondition(model, search, provider)\n if (searchCondition) conditions.push(searchCondition)\n }\n\n if (conditions.length === 0) return undefined\n if (conditions.length === 1) return conditions[0]\n return { AND: conditions }\n}\n\nfunction buildOrderBy(\n model: ModelMetadata,\n query: Pick<ListQuery, 'sort'>,\n): Array<Record<string, 'asc' | 'desc'>> | undefined {\n const rules = query.sort ?? []\n if (rules.length === 0) return undefined\n\n return rules.map((rule) => {\n const field = findQueryableField(model, rule.field, 'sort')\n return { [field.name]: rule.direction }\n })\n}\n\n/** Normalised, clamped pagination. Page numbers are 1-based. */\nexport function resolvePagination(query: Pick<ListQuery, 'page' | 'perPage'>): {\n page: number\n perPage: number\n skip: number\n take: number\n} {\n const rawPage = query.page ?? 1\n if (!Number.isInteger(rawPage) || rawPage < 1) {\n throw new InvalidQueryError(\n `\"page\" must be an integer >= 1, received ${JSON.stringify(query.page)}.`,\n )\n }\n\n const rawPerPage = query.perPage ?? DEFAULT_PER_PAGE\n if (!Number.isInteger(rawPerPage) || rawPerPage < 1) {\n throw new InvalidQueryError(\n `\"perPage\" must be an integer >= 1, received ${JSON.stringify(query.perPage)}.`,\n )\n }\n\n // Clamped rather than rejected: a UI asking for too much should get a\n // capped page, not an error.\n const perPage = Math.min(rawPerPage, MAX_PER_PAGE)\n return { page: rawPage, perPage, skip: (rawPage - 1) * perPage, take: perPage }\n}\n\n/**\n * The same condition, told to ignore case.\n *\n * A condition is `{ field: { operator: value } }`, and the option belongs\n * beside the operator rather than beside the field, so it cannot simply be\n * spread at the top level.\n */\nfunction insensitive(\n condition: Record<string, unknown>,\n provider: string | undefined,\n): Record<string, unknown> {\n const mode = insensitively(provider)\n if (mode.mode === undefined) return condition\n\n const entries = Object.entries(condition).map(([field, comparison]) => [\n field,\n typeof comparison === 'object' && comparison !== null\n ? { ...(comparison as Record<string, unknown>), ...mode }\n : comparison,\n ])\n return Object.fromEntries(entries) as Record<string, unknown>\n}\n\nexport function toFindManyArgs(\n model: ModelMetadata,\n query: ListQuery,\n provider?: string,\n): PrismaFindManyArgs {\n const { skip, take } = resolvePagination(query)\n const where = buildWhere(model, query, provider)\n const orderBy = buildOrderBy(model, query)\n\n return {\n ...(where ? { where } : {}),\n ...(orderBy ? { orderBy } : {}),\n skip,\n take,\n }\n}\n","/**\n * Admin accounts, in Prisma.\n *\n * ## A model of its own\n *\n * The default is `AdminAccount`, and that default is the design rather than a\n * placeholder. The people who administer a system are usually not rows in the\n * table they administer, and pointing this at the application's `User` would\n * mean every customer record carries a password that opens the admin - which is\n * a decision nobody makes on purpose and several people make by accident.\n *\n * The model name is configurable because some applications already have a\n * `Staff` or an `Operator`. Pointing it at `User` is possible and is a choice,\n * not a default.\n *\n * ## What it does not do\n *\n * Create, update, delete. The store contract is read-only, and this implements\n * only what it declares: an admin that could mint its own administrators is an\n * escalation waiting for its first mistake in a policy. Seeding the first\n * account is the application's job, with `hashAdminPassword`.\n *\n * ## The account model should not be a resource\n *\n * Nothing here can arrange that - which models the admin exposes is the\n * module's business - so it is the one thing a consumer has to remember:\n *\n * ```ts\n * resources: { exclude: ['AdminAccount'] }\n * ```\n *\n * Without it, anyone who may edit that model can grant themselves whatever the\n * admin can do. `builtInAuth` warns at startup when it sees the account model\n * among the exposed resources.\n */\nimport type { AdminAccount, AdminAccountStore } from '@nest-admin/core'\n\nimport { resolveDelegate } from '../client/delegate.js'\n\nexport interface PrismaAccountStoreOptions {\n /** A constructed Prisma Client - the same one the adapter is given. */\n readonly client: unknown\n\n /** The model holding admin accounts. `AdminAccount` by default. */\n readonly model?: string\n\n /**\n * Column names, where they differ from the defaults.\n *\n * A mapping rather than a required schema: an application that already has a\n * `Staff` table with `login` and `hash` should not have to migrate it to use\n * this.\n */\n readonly fields?: {\n readonly id?: string\n readonly email?: string\n readonly name?: string\n readonly passwordHash?: string\n readonly disabled?: string\n /** Written on a successful sign-in, when the column exists. */\n readonly lastLoginAt?: string\n }\n}\n\nconst DEFAULTS = {\n id: 'id',\n email: 'email',\n name: 'name',\n passwordHash: 'passwordHash',\n disabled: 'disabled',\n lastLoginAt: 'lastLoginAt',\n} as const\n\nexport function prismaAccountStore(options: PrismaAccountStoreOptions): AdminAccountStore {\n const model = options.model ?? 'AdminAccount'\n const column = { ...DEFAULTS, ...options.fields }\n\n /*\n * The allowlist is the one configured name.\n *\n * `resolveDelegate` takes a list because the adapter resolves a model named\n * by a *request*, where an allowlist is the whole defence. Here the name\n * comes from the application's own configuration and there is nothing to\n * defend against - but passing it anyway keeps the property-name guard\n * inside `resolveDelegate`, which is the part that still matters, and gives\n * a clear error rather than `undefined.findMany is not a function` when the\n * model does not exist.\n */\n const delegate = () => resolveDelegate(options.client, model, [model])\n\n /**\n * A row as the contract describes it.\n *\n * Returns `null` for a row with no usable hash rather than an account that\n * can never sign in. The difference matters at the point of use: a `null`\n * takes the same path as an unknown email, and an account object with an\n * empty hash would be compared against and fail in a way that takes a\n * measurably different amount of time.\n */\n const toAccount = (row: unknown): AdminAccount | null => {\n if (typeof row !== 'object' || row === null) return null\n const record = row as Record<string, unknown>\n\n const id = record[column.id]\n const email = record[column.email]\n const hash = record[column.passwordHash]\n\n if (typeof id !== 'string' && typeof id !== 'number') return null\n if (typeof email !== 'string') return null\n if (typeof hash !== 'string' || hash === '') return null\n\n const name = record[column.name]\n const disabled = record[column.disabled]\n\n return {\n id: String(id),\n email,\n passwordHash: hash,\n ...(typeof name === 'string' && name !== '' ? { name } : {}),\n ...(typeof disabled === 'boolean' ? { disabled } : {}),\n }\n }\n\n return {\n describes: model,\n\n async findByEmail(email) {\n /*\n * `findFirst`, not `findUnique`.\n *\n * The email column is very likely unique, and this store cannot know\n * that - a consumer mapping it onto an existing table may have it\n * indexed and not constrained. `findUnique` throws on a column Prisma\n * does not consider unique, which would turn a schema difference into a\n * 500 on the login route.\n */\n const rows = await delegate().findMany({\n where: { [column.email]: email },\n take: 1,\n })\n return toAccount(rows[0])\n },\n\n async findById(id) {\n const rows = await delegate().findMany({ where: { [column.id]: id }, take: 1 })\n return toAccount(rows[0])\n },\n\n async count() {\n return delegate().count()\n },\n\n async recordLogin(id) {\n // Best effort. A store mapped onto a table without this column should\n // not turn a successful sign-in into a failure, and the caller already\n // treats a rejection here as something to log rather than to surface.\n await delegate().update({\n where: { [column.id]: id },\n data: { [column.lastLoginAt]: new Date() },\n })\n },\n }\n}\n"],"mappings":"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","names":["NestAdminError","AdapterError","FieldNotFoundError","ModelNotFoundError","InvalidQueryError","isNestAdminError"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nest-admin/nestjs",
|
|
3
|
+
"version": "0.11.0",
|
|
4
|
+
"description": "NestJS integration for Nest Admin. This is the single package published to npm.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"nestjs",
|
|
7
|
+
"admin",
|
|
8
|
+
"admin-panel",
|
|
9
|
+
"admin-dashboard",
|
|
10
|
+
"prisma",
|
|
11
|
+
"crud",
|
|
12
|
+
"backoffice",
|
|
13
|
+
"generator",
|
|
14
|
+
"typescript"
|
|
15
|
+
],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": "abdumomin_dev",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/abdum0min/nestjs-admin.git",
|
|
21
|
+
"directory": "packages/nestjs"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/abdum0min/nestjs-admin#readme",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/abdum0min/nestjs-admin/issues"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=20.11.0"
|
|
29
|
+
},
|
|
30
|
+
"type": "module",
|
|
31
|
+
"main": "./dist/index.cjs",
|
|
32
|
+
"module": "./dist/index.js",
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"import": {
|
|
37
|
+
"types": "./dist/index.d.ts",
|
|
38
|
+
"default": "./dist/index.js"
|
|
39
|
+
},
|
|
40
|
+
"require": {
|
|
41
|
+
"types": "./dist/index.d.cts",
|
|
42
|
+
"default": "./dist/index.cjs"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"./prisma": {
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./dist/prisma.d.ts",
|
|
48
|
+
"default": "./dist/prisma.js"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/prisma.d.cts",
|
|
52
|
+
"default": "./dist/prisma.cjs"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"./drizzle": {
|
|
56
|
+
"import": {
|
|
57
|
+
"types": "./dist/drizzle.d.ts",
|
|
58
|
+
"default": "./dist/drizzle.js"
|
|
59
|
+
},
|
|
60
|
+
"require": {
|
|
61
|
+
"types": "./dist/drizzle.d.cts",
|
|
62
|
+
"default": "./dist/drizzle.cjs"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"./package.json": "./package.json"
|
|
66
|
+
},
|
|
67
|
+
"files": [
|
|
68
|
+
"dist",
|
|
69
|
+
"LICENSE"
|
|
70
|
+
],
|
|
71
|
+
"sideEffects": false,
|
|
72
|
+
"publishConfig": {
|
|
73
|
+
"access": "public"
|
|
74
|
+
},
|
|
75
|
+
"scripts": {
|
|
76
|
+
"build": "tsup && node scripts/copy-admin-ui.mjs",
|
|
77
|
+
"dev": "tsup --watch",
|
|
78
|
+
"typecheck": "tsc --noEmit",
|
|
79
|
+
"prepublishOnly": "node scripts/assert-publishable.mjs"
|
|
80
|
+
},
|
|
81
|
+
"dependencies": {
|
|
82
|
+
"@prisma/get-dmmf": "7.10.0"
|
|
83
|
+
},
|
|
84
|
+
"peerDependencies": {
|
|
85
|
+
"@nestjs/common": ">=10.0.0 <13",
|
|
86
|
+
"@nestjs/core": ">=10.0.0 <13",
|
|
87
|
+
"@prisma/client": "^7.0.0",
|
|
88
|
+
"reflect-metadata": "^0.1.13 || ^0.2.0",
|
|
89
|
+
"rxjs": "^7.0.0",
|
|
90
|
+
"drizzle-orm": ">=0.44.0 <1"
|
|
91
|
+
},
|
|
92
|
+
"peerDependenciesMeta": {
|
|
93
|
+
"@prisma/client": {
|
|
94
|
+
"optional": true
|
|
95
|
+
},
|
|
96
|
+
"drizzle-orm": {
|
|
97
|
+
"optional": true
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"devDependencies": {
|
|
101
|
+
"@nest-admin/admin-ui": "workspace:*",
|
|
102
|
+
"@nest-admin/core": "workspace:*",
|
|
103
|
+
"@nest-admin/drizzle": "workspace:*",
|
|
104
|
+
"@nest-admin/prisma": "workspace:*",
|
|
105
|
+
"@nestjs/common": "catalog:",
|
|
106
|
+
"@nestjs/core": "catalog:",
|
|
107
|
+
"@nestjs/platform-express": "catalog:",
|
|
108
|
+
"@nestjs/testing": "catalog:",
|
|
109
|
+
"@prisma/adapter-better-sqlite3": "7.10.0",
|
|
110
|
+
"@prisma/client": "catalog:",
|
|
111
|
+
"@swc/core": "^1.16.1",
|
|
112
|
+
"@types/better-sqlite3": "7.6.13",
|
|
113
|
+
"@types/supertest": "6.0.3",
|
|
114
|
+
"better-sqlite3": "12.11.1",
|
|
115
|
+
"drizzle-orm": "0.45.2",
|
|
116
|
+
"prisma": "catalog:",
|
|
117
|
+
"reflect-metadata": "catalog:",
|
|
118
|
+
"rxjs": "catalog:",
|
|
119
|
+
"supertest": "7.1.4",
|
|
120
|
+
"tsup": "catalog:",
|
|
121
|
+
"typescript": "catalog:"
|
|
122
|
+
},
|
|
123
|
+
"typesVersions": {
|
|
124
|
+
"*": {
|
|
125
|
+
"prisma": [
|
|
126
|
+
"./dist/prisma.d.ts"
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|