@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":["../../drizzle/src/adapter.ts","../../drizzle/src/errors/constraints.ts","../../drizzle/src/metadata/to-metadata.ts","../../drizzle/src/query/build.ts","../../drizzle/src/schema/introspect.ts"],"sourcesContent":["/**\n * The Drizzle implementation of `OrmAdapter`.\n *\n * This package exists to answer a question the Prisma adapter cannot: is\n * `OrmAdapter` a contract, or is it a description of Prisma? Writing a second\n * implementation against a genuinely different ORM - a query builder with no\n * generated client, no DMMF and no normalised errors - is the only way to find\n * out before 1.0 freezes it.\n *\n * The answer, recorded here because it is the point of the package: Core needed\n * no changes. What differs is entirely inside this directory, and each\n * difference is documented where it is handled.\n *\n * ## What Drizzle does not give us, and what is done instead\n *\n * | Prisma | Drizzle | Handled in |\n * | --- | --- | --- |\n * | DMMF describing every model | the schema object itself | `schema/introspect.ts` |\n * | `P2xxx` codes with `meta` | the driver's own error | `errors/constraints.ts` |\n * | `mode: 'insensitive'` | `lower()` on both sides | `query/build.ts` |\n * | escaped `contains` | escaped by hand | `query/build.ts` |\n * | relations always named | named only if declared | `schema/introspect.ts` |\n *\n * ## Relations are not loaded with the record\n *\n * The Prisma adapter includes a to-one's target so a list can show a person's\n * name rather than their id. Drizzle can do the same with a join, but only with\n * the relational query API, which needs `relations()` declared - and this\n * adapter deliberately works without them. So a to-one arrives as its foreign\n * key, and the interface resolves the label through the relation picker, which\n * it already does for every relation it cannot see inline.\n */\nimport {\n AdapterError,\n FieldNotFoundError,\n isNestAdminError,\n ModelNotFoundError,\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'\nimport { and, count, eq, type SQL } from 'drizzle-orm'\n\nimport { toConstraintError } from './errors/constraints.js'\nimport { toModelMetadata } from './metadata/to-metadata.js'\nimport { buildOrderBy, buildWhere, resolvePagination } from './query/build.js'\nimport { readSchema, type DrizzleSchema, type DrizzleTable } from './schema/introspect.js'\n\n/** The parts of a Drizzle database this adapter uses. */\ninterface DrizzleDatabase {\n select(fields?: Record<string, unknown>): {\n from(table: object): QueryBuilder\n }\n insert(table: object): {\n values(data: Record<string, unknown>): { returning(): Promise<Record<string, unknown>[]> }\n }\n update(table: object): {\n set(data: Record<string, unknown>): {\n where(condition: SQL): { returning(): Promise<Record<string, unknown>[]> }\n }\n }\n delete(table: object): {\n where(condition: SQL): { returning(): Promise<Record<string, unknown>[]> }\n }\n}\n\ninterface QueryBuilder extends Promise<Record<string, unknown>[]> {\n where(condition: SQL | undefined): QueryBuilder\n orderBy(...rules: SQL[]): QueryBuilder\n limit(value: number): QueryBuilder\n offset(value: number): QueryBuilder\n}\n\nexport interface DrizzleAdapterOptions {\n /** A constructed Drizzle database, from any dialect's `drizzle()`. */\n readonly db: unknown\n /**\n * The schema module.\n *\n * Passed separately from `db` even though `drizzle(client, { schema })` also\n * takes it, because that form is optional and a database built without it\n * carries nothing to introspect.\n */\n readonly schema: Readonly<Record<string, unknown>>\n}\n\nexport class DrizzleAdapter implements OrmAdapter {\n readonly name = 'drizzle'\n\n readonly #db: DrizzleDatabase\n readonly #schemaModule: Readonly<Record<string, unknown>>\n\n #schema: DrizzleSchema | undefined\n #models: readonly ModelMetadata[] | undefined\n\n constructor(options: DrizzleAdapterOptions) {\n if (options.db === null || options.db === undefined) {\n throw new AdapterError(\n 'DrizzleAdapter requires a constructed Drizzle database. ' +\n 'Pass one via `new DrizzleAdapter({ db, schema })`.',\n )\n }\n if (options.schema === null || options.schema === undefined) {\n throw new AdapterError(\n 'DrizzleAdapter requires the schema module. ' +\n \"Import it with `import * as schema from './schema.js'` and pass it as `schema`.\",\n )\n }\n\n this.#db = options.db as DrizzleDatabase\n this.#schemaModule = options.schema\n }\n\n async getModels(): Promise<readonly ModelMetadata[]> {\n if (this.#models) return this.#models\n\n const schema = await readSchema(this.#schemaModule)\n\n if (schema.dialect === 'mysql') {\n // MySQL has no `RETURNING`, so `create` and `update` cannot report what\n // they wrote without a second query and a way to identify the new row -\n // which for a generated key means reading `insertId`, which is dialect\n // and driver specific. Refused here rather than shipped untested: an\n // adapter that silently returns the submitted data instead of the stored\n // row would hide every default and every trigger.\n throw new AdapterError(\n 'The Drizzle adapter does not support MySQL yet, because MySQL has no ' +\n 'RETURNING clause and writes could not report the stored row. ' +\n 'SQLite and PostgreSQL are supported.',\n )\n }\n\n this.#schema = schema\n this.#models = toModelMetadata({\n schema,\n compositeKeys: await this.#compositeKeys(schema),\n })\n\n return this.#models\n }\n\n async list(model: string, query: ListQuery): Promise<Page<RecordData>> {\n const { metadata, entry } = await this.#require(model)\n\n const where = buildWhere(metadata, entry, query)\n const orderBy = buildOrderBy(metadata, entry, query.sort)\n const { page, perPage, offset, limit } = resolvePagination(query)\n\n return this.#run(model, async () => {\n let rows = this.#db.select().from(entry.table).where(where)\n if (orderBy.length > 0) rows = rows.orderBy(...orderBy)\n\n const [data, totals] = await Promise.all([\n rows.limit(limit).offset(offset),\n this.#db.select({ value: count() }).from(entry.table).where(where),\n ])\n\n const total = Number(totals[0]?.['value'] ?? 0)\n return { data: data as RecordData[], total, page, perPage }\n })\n }\n\n async findOne(model: string, id: RecordId): Promise<RecordData | null> {\n const { metadata, entry } = await this.#require(model)\n\n const rows = await this.#run(model, () =>\n this.#db\n .select()\n .from(entry.table)\n .where(this.#byId(metadata, entry, id))\n .limit(1),\n )\n\n return (rows[0] as RecordData | undefined) ?? null\n }\n\n async create(model: string, data: RecordData): Promise<RecordData> {\n const { metadata, entry } = await this.#require(model)\n const writable = this.#writable(metadata, entry, data)\n\n const rows = await this.#run(model, () =>\n this.#db.insert(entry.table).values(writable).returning(),\n )\n\n const created = rows[0]\n if (created === undefined) {\n throw new AdapterError(`Creating a ${model} returned no row.`)\n }\n return created as RecordData\n }\n\n async update(model: string, id: RecordId, data: RecordData): Promise<RecordData> {\n const { metadata, entry } = await this.#require(model)\n const writable = this.#writable(metadata, entry, data)\n\n // An update with nothing to set is a request to see the record, and every\n // dialect rejects `SET` with no assignments.\n if (Object.keys(writable).length === 0) {\n const existing = await this.findOne(model, id)\n if (existing === null) throw new RecordNotFoundError(model, id)\n return existing\n }\n\n const rows = await this.#run(model, () =>\n this.#db\n .update(entry.table)\n .set(writable)\n .where(this.#byId(metadata, entry, id))\n .returning(),\n )\n\n const updated = rows[0]\n // Drizzle updates nothing and says nothing when the row is absent; Prisma\n // raises P2025. The contract expects the second, so it is produced here.\n if (updated === undefined) throw new RecordNotFoundError(model, id)\n return updated as RecordData\n }\n\n async delete(model: string, id: RecordId): Promise<void> {\n const { metadata, entry } = await this.#require(model)\n\n const rows = await this.#run(model, () =>\n this.#db\n .delete(entry.table)\n .where(this.#byId(metadata, entry, id))\n .returning(),\n )\n\n if (rows.length === 0) throw new RecordNotFoundError(model, id)\n }\n\n async listRelated(\n model: string,\n id: RecordId,\n relationField: string,\n query: ListQuery,\n ): Promise<Page<RecordData>> {\n const link = await this.#link(model, relationField)\n const { metadata: targetMetadata, entry: target } = await this.#require(link.targetModel)\n\n // The parent's own key value, which the children's foreign key holds. Read\n // rather than assumed equal to `id`, because a relation may reference a\n // unique column that is not the primary key.\n const parentValue = await this.#referencedValue(model, id, link.to)\n\n const foreignKey = target.columns.get(link.from)\n if (foreignKey === undefined) {\n throw new FieldNotFoundError(link.targetModel, link.from)\n }\n\n const declared = buildWhere(targetMetadata, target, query)\n const belongs = eq(foreignKey as never, parentValue)\n const where = declared ? and(belongs, declared) : belongs\n\n const orderBy = buildOrderBy(targetMetadata, target, query.sort)\n const { page, perPage, offset, limit } = resolvePagination(query)\n\n return this.#run(link.targetModel, async () => {\n let rows = this.#db.select().from(target.table).where(where)\n if (orderBy.length > 0) rows = rows.orderBy(...orderBy)\n\n const [data, totals] = await Promise.all([\n rows.limit(limit).offset(offset),\n this.#db.select({ value: count() }).from(target.table).where(where),\n ])\n\n return {\n data: data as RecordData[],\n total: Number(totals[0]?.['value'] ?? 0),\n page,\n perPage,\n }\n })\n }\n\n async attachRelated(\n model: string,\n id: RecordId,\n relationField: string,\n targetId: RecordId,\n ): Promise<void> {\n const link = await this.#link(model, relationField)\n const parentValue = await this.#referencedValue(model, id, link.to)\n\n // Rewriting the child's key, which also removes it from whoever held it.\n // The contract says so, and says the warning is the transport's job.\n await this.#setForeignKey(link, targetId, parentValue)\n }\n\n async detachRelated(\n model: string,\n id: RecordId,\n relationField: string,\n targetId: RecordId,\n ): Promise<void> {\n const link = await this.#link(model, relationField)\n await this.#setForeignKey(link, targetId, null)\n }\n\n /* ---------------------------------------------------------------------- */\n\n async #require(model: string): Promise<{ metadata: ModelMetadata; entry: DrizzleTable }> {\n const models = await this.getModels()\n const metadata = models.find((candidate) => candidate.name === model)\n if (!metadata) throw new ModelNotFoundError(model)\n\n const entry = this.#schema?.tables.find((candidate) => candidate.model === model)\n if (!entry) throw new ModelNotFoundError(model)\n\n return { metadata, entry }\n }\n\n /**\n * The two ends of a to-many, resolved to property names.\n *\n * `from` is the foreign key on the child, `to` the column on this model it\n * points at. Only the `one` side carries them, so a `many` is resolved by\n * finding its partner - which is why both sides are given the same relation\n * name when the schema is read.\n */\n async #link(\n model: string,\n relationField: string,\n ): Promise<{ targetModel: string; from: string; to: string }> {\n const { metadata } = await this.#require(model)\n\n const field = metadata.fields.find((candidate) => candidate.name === relationField)\n if (!field?.relation) throw new FieldNotFoundError(model, relationField)\n\n if (field.relation.cardinality !== 'many') {\n throw new FieldNotFoundError(\n model,\n relationField,\n 'Only to-many relations can be listed or modified through this route.',\n )\n }\n\n const models = await this.getModels()\n const target = models.find((candidate) => candidate.name === field.relation?.targetModel)\n const inverse = target?.fields.find(\n (candidate) =>\n candidate.relation?.cardinality === 'one' &&\n candidate.relation.name === field.relation?.name,\n )\n\n const from = inverse?.relation?.from\n const to = inverse?.relation?.to\n\n if (from === undefined || to === undefined) {\n // A many-to-many, or a relation whose owning side is not in this admin.\n // Drizzle has no first-class many-to-many: a join table is a table, and\n // appears in the admin as one, with a to-one on each side.\n throw new FieldNotFoundError(\n model,\n relationField,\n 'This relation has no foreign key on the far side. A many-to-many in ' +\n 'Drizzle is a join table, and is administered as its own resource.',\n )\n }\n\n return { targetModel: field.relation.targetModel, from, to }\n }\n\n async #referencedValue(model: string, id: RecordId, column: string): Promise<unknown> {\n const record = await this.findOne(model, id)\n if (record === null) throw new RecordNotFoundError(model, id)\n return record[column]\n }\n\n async #setForeignKey(\n link: { targetModel: string; from: string },\n targetId: RecordId,\n value: unknown,\n ): Promise<void> {\n const { metadata, entry } = await this.#require(link.targetModel)\n\n await this.#run(link.targetModel, () =>\n this.#db\n .update(entry.table)\n .set({ [link.from]: value })\n .where(this.#byId(metadata, entry, targetId))\n .returning(),\n )\n }\n\n #byId(metadata: ModelMetadata, entry: DrizzleTable, id: RecordId): SQL {\n const key = metadata.primaryKey[0]\n if (key === undefined || metadata.primaryKey.length > 1) {\n throw new AdapterError(\n `${metadata.name} has ${metadata.primaryKey.length === 0 ? 'no' : 'a composite'} ` +\n 'primary key. Records are addressed by a single key in this version.',\n )\n }\n\n const column = entry.columns.get(key)\n if (column === undefined) throw new FieldNotFoundError(metadata.name, key)\n\n // A numeric key arrives from the URL as a string, and `=` on an integer\n // column would compare against text.\n const field = metadata.fields.find((candidate) => candidate.name === key)\n const value = field?.kind === 'number' ? Number(id) : id\n\n return eq(column as never, value)\n }\n\n /**\n * The submitted data, restricted to columns that exist and may be written.\n *\n * Generated columns are dropped rather than refused: a form that round-trips\n * a record would otherwise fail on the id it was shown. Unknown keys *are*\n * refused, because silently ignoring a field is how a value appears to save\n * and does not.\n */\n #writable(metadata: ModelMetadata, entry: DrizzleTable, data: RecordData): RecordData {\n const writable: RecordData = {}\n\n for (const [key, value] of Object.entries(data)) {\n const field = metadata.fields.find((candidate) => candidate.name === key)\n\n if (!field || !entry.columns.has(key)) {\n // A relation field is a legitimate name that is not a column; anything\n // else is a mistake worth reporting.\n if (field?.kind === 'relation') continue\n throw new FieldNotFoundError(metadata.name, key)\n }\n\n if (field.isGenerated && field.isId) continue\n\n writable[key] =\n field.kind === 'datetime' && typeof value === 'string' ? new Date(value) : value\n }\n\n return writable\n }\n\n /** Composite primary keys, which are only reachable through the dialect's config. */\n async #compositeKeys(schema: DrizzleSchema): Promise<ReadonlyMap<string, readonly string[]>> {\n const core = (await import(\n schema.dialect === 'pg' ? 'drizzle-orm/pg-core' : 'drizzle-orm/sqlite-core'\n )) as {\n getTableConfig: (table: object) => {\n primaryKeys: readonly { columns: readonly { name: string }[] }[]\n }\n }\n\n const keys = new Map<string, readonly string[]>()\n\n for (const entry of schema.tables) {\n const declared = core.getTableConfig(entry.table).primaryKeys[0]\n if (declared === undefined) continue\n\n const names: string[] = []\n for (const column of declared.columns) {\n for (const [key, candidate] of entry.columns) {\n if (candidate.name === column.name) names.push(key)\n }\n }\n\n if (names.length > 0) keys.set(entry.model, names)\n }\n\n return keys\n }\n\n /**\n * Run a query, and translate whatever it throws.\n *\n * Core's own errors pass through: they were raised by this adapter and\n * already say what is wrong. Everything else is the driver's, and becomes\n * either a constraint the interface can put beside a field or an\n * `AdapterError`, which the HTTP layer reports without its message.\n */\n async #run<T>(model: string, operation: () => Promise<T>): Promise<T> {\n try {\n return await operation()\n } catch (cause) {\n if (isNestAdminError(cause)) throw cause\n\n const entry = this.#schema?.tables.find((candidate) => candidate.model === model)\n const toFieldNames = (sqlNames: readonly string[]): readonly string[] => {\n if (entry === undefined) return sqlNames\n const named: string[] = []\n for (const sqlName of sqlNames) {\n for (const [key, column] of entry.columns) {\n if (column.name === sqlName) named.push(key)\n }\n }\n return named\n }\n\n const constraint = toConstraintError(cause, model, toFieldNames)\n if (constraint) throw constraint\n\n throw new AdapterError(\n `The database refused a ${model} operation: ${cause instanceof Error ? cause.message : String(cause)}`,\n { cause },\n )\n }\n }\n}\n","/**\n * A driver's refusal, as a `ConstraintError`.\n *\n * Drizzle does not normalise driver errors - it is a query builder, and what\n * reaches this code is whatever `better-sqlite3`, `pg` or `mysql2` threw. That\n * is the opposite of Prisma, which turns every one of them into a `P2xxx` code\n * with a `meta` object, and it is the single largest difference between writing\n * these two adapters.\n *\n * So this reads the driver's own report. Codes where the driver provides one;\n * the message only where it does not, and only to recover column names, which\n * are the difference between \"that was refused\" and \"that email is taken\".\n *\n * ## Why a wrong guess here is safe\n *\n * The field names only decide where the interface draws the message. Naming no\n * field puts it in a banner over the form, which is the fallback for every\n * shape not recognised below - so an unparsed message degrades to a correct\n * error in a less convenient place, never to a wrong one.\n */\nimport { ConstraintError, type ConstraintKind } from '@nest-admin/core'\n\ninterface DriverError {\n readonly code?: unknown\n readonly message?: unknown\n readonly constraint?: unknown\n readonly column?: unknown\n readonly detail?: unknown\n}\n\nfunction driverErrorOf(cause: unknown): DriverError | undefined {\n if (typeof cause !== 'object' || cause === null) return undefined\n\n // Drizzle rethrows the driver's error, sometimes wrapped once.\n const error = cause as DriverError & { cause?: unknown }\n const inner = error.cause\n if (typeof error.code !== 'string' && typeof inner === 'object' && inner !== null) {\n return inner as DriverError\n }\n return error\n}\n\n/**\n * SQLite reports the kind in the code and the columns in the message:\n *\n * SQLITE_CONSTRAINT_UNIQUE \"UNIQUE constraint failed: users.email\"\n * SQLITE_CONSTRAINT_NOTNULL \"NOT NULL constraint failed: users.name\"\n * SQLITE_CONSTRAINT_FOREIGNKEY \"FOREIGN KEY constraint failed\"\n */\nconst SQLITE_KINDS: Readonly<Record<string, ConstraintKind>> = {\n SQLITE_CONSTRAINT_UNIQUE: 'unique',\n SQLITE_CONSTRAINT_PRIMARYKEY: 'unique',\n SQLITE_CONSTRAINT_NOTNULL: 'required',\n SQLITE_CONSTRAINT_FOREIGNKEY: 'foreign-key',\n SQLITE_CONSTRAINT_TRIGGER: 'foreign-key',\n}\n\n/** Postgres and MySQL both use numeric-ish codes, and both name the constraint. */\nconst CODE_KINDS: Readonly<Record<string, ConstraintKind>> = {\n // Postgres\n '23505': 'unique',\n '23503': 'foreign-key',\n '23502': 'required',\n // MySQL\n ER_DUP_ENTRY: 'unique',\n ER_NO_REFERENCED_ROW_2: 'foreign-key',\n ER_ROW_IS_REFERENCED_2: 'foreign-key',\n ER_BAD_NULL_ERROR: 'required',\n}\n\n/** `users.email` in a SQLite message. Several, for a composite constraint. */\nfunction sqliteColumns(message: string): readonly string[] {\n const listed = /constraint failed: (.+)$/i.exec(message)?.[1]\n if (listed === undefined) return []\n\n return listed\n .split(',')\n .map((entry) => entry.trim().split('.').at(-1) ?? '')\n .filter((entry) => entry !== '')\n}\n\n/**\n * The column a Postgres error is about.\n *\n * `column` is populated for a not-null violation. For a unique violation the\n * column names are only in `detail` - `Key (email)=(a@b.c) already exists.` -\n * and the constraint name is a convention (`users_email_key`) rather than a\n * promise, so it is only trusted when the shape matches exactly.\n */\nfunction postgresColumns(error: DriverError): readonly string[] {\n if (typeof error.column === 'string' && error.column !== '') return [error.column]\n\n if (typeof error.detail === 'string') {\n const key = /^Key \\(([^)]+)\\)=/.exec(error.detail)?.[1]\n if (key !== undefined) return key.split(',').map((entry) => entry.trim())\n }\n\n if (typeof error.constraint === 'string') {\n const index = /^(.+?)_(.+)_(key|pkey|fkey)$/.exec(error.constraint)\n if (index?.[2] !== undefined) return index[2].split('_')\n }\n\n return []\n}\n\n/**\n * Column names in the schema's terms, not the database's.\n *\n * A driver reports SQL column names (`author_id`); every other layer of the\n * admin speaks in the schema's property names (`authorId`). Reporting the\n * former would name a field the form does not have, so the message would land\n * in the banner anyway - and be wrong about which box to look at.\n */\nexport type ColumnNames = (sqlNames: readonly string[]) => readonly string[]\n\nexport function toConstraintError(\n cause: unknown,\n model: string,\n toFieldNames: ColumnNames,\n): ConstraintError | undefined {\n const error = driverErrorOf(cause)\n if (error === undefined) return undefined\n\n const code = typeof error.code === 'string' ? error.code : undefined\n const message = typeof error.message === 'string' ? error.message : ''\n\n if (code !== undefined && code in SQLITE_KINDS) {\n return new ConstraintError(SQLITE_KINDS[code]!, model, toFieldNames(sqliteColumns(message)))\n }\n\n if (code !== undefined && code in CODE_KINDS) {\n return new ConstraintError(CODE_KINDS[code]!, model, toFieldNames(postgresColumns(error)))\n }\n\n // Some SQLite builds report only `SQLITE_CONSTRAINT`; the message still says\n // which kind it was, and it is the only thing left to read.\n if (code === 'SQLITE_CONSTRAINT' || (code === undefined && /constraint failed/i.test(message))) {\n const kind: ConstraintKind = /UNIQUE/i.test(message)\n ? 'unique'\n : /NOT NULL/i.test(message)\n ? 'required'\n : 'foreign-key'\n return new ConstraintError(kind, model, toFieldNames(sqliteColumns(message)))\n }\n\n return undefined\n}\n","/**\n * A Drizzle schema, as `ModelMetadata`.\n *\n * The mapping is small because Core's vocabulary was chosen to be ORM-neutral,\n * and this is the first time that claim has been tested by something other than\n * Prisma. The places where the two ORMs disagree are noted where they occur;\n * none of them needed a change to Core.\n */\nimport { is, SQL } from 'drizzle-orm'\nimport type { FieldKind, FieldMetadata, ModelMetadata } from '@nest-admin/core'\n\nimport type { DrizzleColumn, DrizzleSchema, DrizzleTable } from '../schema/introspect.js'\n\n/**\n * Drizzle's `dataType` to Core's `FieldKind`.\n *\n * `dataType` is the neutral one of the two type fields a column carries -\n * `columnType` is dialect-specific (`SQLiteText`, `PgVarchar`) and would make\n * this a table per dialect for no gain.\n *\n * `bigint` becomes `string`: it arrives as a `BigInt`, which does not survive\n * `JSON.stringify`, and the admin's transport is JSON. Calling it a number\n * would promise arithmetic that silently loses precision.\n */\nconst KINDS: Readonly<Record<string, FieldKind>> = {\n string: 'string',\n number: 'number',\n boolean: 'boolean',\n date: 'datetime',\n json: 'json',\n bigint: 'string',\n buffer: 'unknown',\n array: 'unknown',\n custom: 'unknown',\n}\n\nfunction kindOf(column: DrizzleColumn): FieldKind {\n // An enum in Drizzle is a text column with a list of allowed values, whatever\n // the dialect calls it underneath.\n if (column.enumValues !== undefined && column.enumValues.length > 0) return 'enum'\n return KINDS[column.dataType] ?? 'unknown'\n}\n\n/**\n * Whether the database or the ORM supplies this value.\n *\n * The same rule the Prisma adapter uses, stated in Drizzle's terms: a value\n * produced by *running something* is generated, a literal is a pre-fill for the\n * create form.\n *\n * `.default('USER')` literal - a default value, offered in forms\n * `` .default(sql`now()`) `` generated - the database fills it in\n * `.$defaultFn(...)` generated - Drizzle fills it in\n * `.$onUpdateFn(...)` generated - the equivalent of `@updatedAt`\n * `.primaryKey({autoIncrement})` generated\n */\nfunction isGenerated(column: DrizzleColumn): boolean {\n return (\n column.autoIncrement === true ||\n typeof column.defaultFn === 'function' ||\n typeof column.onUpdateFn === 'function' ||\n is(column.default, SQL)\n )\n}\n\nfunction literalDefault(column: DrizzleColumn): unknown {\n if (!column.hasDefault || isGenerated(column)) return undefined\n return column.default\n}\n\nfunction toField(key: string, column: DrizzleColumn, primaryKey: readonly string[]): FieldMetadata {\n const isId = primaryKey.includes(key)\n const defaultValue = literalDefault(column)\n\n return {\n name: key,\n kind: kindOf(column),\n isId,\n isRequired: column.notNull,\n // A primary key is unique whether or not anyone said so.\n isUnique: column.isUnique || isId,\n // Drizzle has no list columns outside Postgres arrays, which arrive as\n // `dataType: 'array'` and are mapped to `unknown` above.\n isList: false,\n isGenerated: isGenerated(column),\n ...(defaultValue !== undefined ? { defaultValue } : {}),\n ...(column.enumValues !== undefined && column.enumValues.length > 0\n ? { enumValues: [...column.enumValues] }\n : {}),\n }\n}\n\nfunction primaryKeyOf(\n entry: DrizzleTable,\n composite: ReadonlyMap<string, readonly string[]>,\n): readonly string[] {\n const declared = composite.get(entry.model)\n if (declared && declared.length > 0) return declared\n\n const inline: string[] = []\n for (const [key, column] of entry.columns) {\n if (column.primary) inline.push(key)\n }\n return inline\n}\n\nexport interface ToMetadataInput {\n readonly schema: DrizzleSchema\n /** Composite keys, resolved by the caller because reading them needs the dialect. */\n readonly compositeKeys: ReadonlyMap<string, readonly string[]>\n}\n\nexport function toModelMetadata(input: ToMetadataInput): readonly ModelMetadata[] {\n const { schema, compositeKeys } = input\n\n return schema.tables.map((entry) => {\n const primaryKey = primaryKeyOf(entry, compositeKeys)\n\n const columns: FieldMetadata[] = []\n for (const [key, column] of entry.columns) {\n columns.push(toField(key, column, primaryKey))\n }\n\n const relations: FieldMetadata[] = schema.relations\n .filter((relation) => relation.model === entry.model)\n .map((relation) => ({\n name: relation.field,\n kind: 'relation' as const,\n isId: false,\n // A to-one is required exactly when its foreign key is. A to-many never\n // is: a parent with no children is a parent.\n isRequired:\n relation.cardinality === 'one' && relation.from !== undefined\n ? (entry.columns.get(relation.from)?.notNull ?? false)\n : false,\n isUnique: false,\n isList: relation.cardinality === 'many',\n isGenerated: false,\n relation: {\n targetModel: relation.targetModel,\n cardinality: relation.cardinality,\n name: relation.name,\n ...(relation.from !== undefined ? { from: relation.from } : {}),\n ...(relation.to !== undefined ? { to: relation.to } : {}),\n },\n }))\n\n return { name: entry.model, primaryKey, fields: [...columns, ...relations] }\n })\n}\n","/**\n * `ListQuery` into a Drizzle query.\n *\n * The rules enforced here are the ones the Prisma adapter enforces, and they\n * are enforced again rather than shared because they are about *this* ORM's\n * capabilities: which fields can be filtered, which operators a kind admits,\n * what a search box searches. Where the two adapters agree, they agree because\n * Core's contract says the same thing to both.\n *\n * ## Two places Drizzle needs work Prisma did for us\n *\n * **Case insensitivity.** Prisma has `mode: 'insensitive'`, on the providers\n * that support it. Drizzle has `ilike`, on Postgres only. Rather than branch per\n * dialect, both sides of the comparison go through `lower()`, which every\n * dialect this adapter supports has. It costs an index unless one is declared on\n * the expression - noted here because that is a real trade and not a free one.\n *\n * **`LIKE` metacharacters.** Prisma escapes `%` and `_` inside `contains`.\n * Building the pattern by hand means doing it here, or a search for `100%`\n * silently matches every row.\n */\nimport {\n FieldNotFoundError,\n InvalidQueryError,\n type FieldMetadata,\n type FilterRule,\n type ListQuery,\n type ModelMetadata,\n type SortRule,\n} from '@nest-admin/core'\nimport { and, asc, desc, eq, gt, gte, inArray, lt, lte, ne, or, sql, type SQL } from 'drizzle-orm'\n\nimport type { DrizzleColumn, DrizzleTable } from '../schema/introspect.js'\n\n/** Kept in step with `MAX_PER_PAGE` in the Prisma adapter and the UI's page-size list. */\nexport const DEFAULT_PER_PAGE = 25\nexport const MAX_PER_PAGE = 100\n\nconst STRING_ONLY = new Set(['contains', 'startsWith', 'endsWith'])\nconst COMPARISON = new Set(['gt', 'gte', 'lt', 'lte'])\n\ntype Purpose = 'filter' | 'sort'\n\n/**\n * The field a rule may address, and the reason when it may not.\n *\n * Filtering by a to-one relation is answered by filtering its foreign key,\n * which is the same record with a name the caller is more likely to have. The\n * refusals mirror the Prisma adapter's, message for message, because they are\n * about what the admin promises rather than about either ORM.\n */\nfunction queryable(model: ModelMetadata, fieldName: string, purpose: Purpose): FieldMetadata {\n const field = model.fields.find((candidate) => candidate.name === fieldName)\n if (!field) 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 queryable(model, owned, purpose)\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 throw new FieldNotFoundError(\n model.name,\n fieldName,\n 'Relation fields cannot be filtered or sorted in this version.',\n )\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\n return field\n}\n\nfunction columnOf(entry: DrizzleTable, field: FieldMetadata): DrizzleColumn {\n const column = entry.columns.get(field.name)\n if (column === undefined) {\n // Metadata and schema came from the same object, so this is unreachable\n // short of a schema mutated after `getModels`.\n throw new FieldNotFoundError(entry.model, field.name)\n }\n return column\n}\n\n/** `%`, `_` and the escape character itself, so a search for \"100%\" means it. */\nfunction escapeLike(term: string): string {\n return term.replace(/[\\\\%_]/g, (match) => `\\\\${match}`)\n}\n\n/** A case-insensitive LIKE that works on every dialect this adapter supports. */\nfunction insensitiveLike(column: unknown, pattern: string): SQL {\n return sql`lower(${column}) LIKE lower(${pattern}) ESCAPE '\\\\'`\n}\n\nfunction condition(model: ModelMetadata, entry: DrizzleTable, rule: FilterRule): SQL {\n const field = queryable(model, rule.field, 'filter')\n const column = columnOf(entry, field)\n\n if (STRING_ONLY.has(rule.operator) && field.kind !== 'string' && field.kind !== 'enum') {\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.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 const value = coerce(field, rule.value, model.name)\n\n switch (rule.operator) {\n case '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 inArray(\n column as never,\n rule.value.map((entryValue) => coerce(field, entryValue, model.name)),\n )\n }\n case 'eq':\n return eq(column as never, value)\n case 'ne':\n return ne(column as never, value)\n case 'gt':\n return gt(column as never, value)\n case 'gte':\n return gte(column as never, value)\n case 'lt':\n return lt(column as never, value)\n case 'lte':\n return lte(column as never, value)\n case 'contains':\n return insensitiveLike(column, `%${escapeLike(String(rule.value))}%`)\n case 'startsWith':\n return insensitiveLike(column, `${escapeLike(String(rule.value))}%`)\n case 'endsWith':\n return insensitiveLike(column, `%${escapeLike(String(rule.value))}`)\n }\n}\n\n/**\n * A value in the shape Drizzle's column mapper expects.\n *\n * Prisma accepts an ISO string for a `DateTime`; Drizzle's timestamp columns\n * expect a `Date` and will store the string as-is otherwise, which reads back\n * as an invalid date. The HTTP layer's coercion is type-directed but produces\n * JSON values, so the last step happens here - where the column is known.\n */\nfunction coerce(field: FieldMetadata, value: unknown, model: string): unknown {\n if (value === null || value === undefined) return value\n\n if (field.kind === 'datetime' && !(value instanceof Date)) {\n const parsed = new Date(String(value))\n if (Number.isNaN(parsed.getTime())) {\n throw new InvalidQueryError(`\"${value}\" is not a date, for \"${model}.${field.name}\".`)\n }\n return parsed\n }\n\n return value\n}\n\n/**\n * What the search box searches.\n *\n * The same exclusions the Prisma adapter makes: generated columns, and foreign\n * keys. A foreign key is a string column holding an opaque id, so leaving it in\n * makes a one-letter search match nearly every row of any model that references\n * another.\n */\nexport function searchCondition(\n model: ModelMetadata,\n entry: DrizzleTable,\n term: string,\n): SQL | undefined {\n const foreignKeys = new Set(\n model.fields.map((field) => field.relation?.from).filter((name) => name !== undefined),\n )\n\n const searchable = model.fields.filter(\n (field) =>\n (field.kind === 'string' || field.kind === 'enum') &&\n !field.isList &&\n !field.isGenerated &&\n !foreignKeys.has(field.name) &&\n entry.columns.has(field.name),\n )\n\n if (searchable.length === 0) return undefined\n\n const pattern = `%${escapeLike(term)}%`\n return or(...searchable.map((field) => insensitiveLike(columnOf(entry, field), pattern)))\n}\n\nexport function buildWhere(\n model: ModelMetadata,\n entry: DrizzleTable,\n query: Pick<ListQuery, 'filters' | 'search'>,\n): SQL | undefined {\n const conditions: SQL[] = []\n\n for (const rule of query.filters ?? []) {\n conditions.push(condition(model, entry, rule))\n }\n\n const term = query.search?.trim()\n if (term) {\n const search = searchCondition(model, entry, term)\n if (search) conditions.push(search)\n }\n\n if (conditions.length === 0) return undefined\n return conditions.length === 1 ? conditions[0] : and(...conditions)\n}\n\nexport function buildOrderBy(\n model: ModelMetadata,\n entry: DrizzleTable,\n rules: readonly SortRule[] | undefined,\n): readonly SQL[] {\n return (rules ?? []).map((rule) => {\n const field = queryable(model, rule.field, 'sort')\n const column = columnOf(entry, field)\n return (rule.direction === 'desc' ? desc(column as never) : asc(column as never)) as SQL\n })\n}\n\nexport function resolvePagination(query: Pick<ListQuery, 'page' | 'perPage'>): {\n page: number\n perPage: number\n offset: number\n limit: number\n} {\n const rawPage = query.page ?? 1\n const rawPerPage = query.perPage ?? DEFAULT_PER_PAGE\n\n const page = Number.isFinite(rawPage) && rawPage >= 1 ? Math.floor(rawPage) : 1\n // Clamped rather than refused, matching the Prisma adapter: a page size above\n // the ceiling is a request for \"as many as you will give me\".\n const perPage =\n Number.isFinite(rawPerPage) && rawPerPage >= 1\n ? Math.min(Math.floor(rawPerPage), MAX_PER_PAGE)\n : DEFAULT_PER_PAGE\n\n return { page, perPage, offset: (page - 1) * perPage, limit: perPage }\n}\n","/**\n * Reading a Drizzle schema.\n *\n * Drizzle has no DMMF and no generated client to interrogate. What it has is\n * the schema module itself - a plain object of table definitions - and the\n * table objects carry everything needed, because Drizzle Kit reads them the\n * same way to write migrations.\n *\n * ## Where the names come from\n *\n * A Drizzle table has two names: the SQL one (`users`) and the key it is\n * exported under (`users`, or `Users`, or whatever the developer wrote). This\n * uses the **export key** as the model name, and the **property key** as the\n * field name.\n *\n * That is deliberate. Those are the names the developer typed, the names their\n * own queries use, and - since rows come back keyed by property rather than by\n * column - the names the data already arrives under. Using the SQL names would\n * mean an admin whose URLs and configuration disagree with the schema file the\n * developer is looking at.\n *\n * ## Dialect\n *\n * `getTableConfig` is exported per dialect, not generically, and foreign keys\n * are only reachable through it. The dialect is discoverable without importing\n * any of them: every column's `columnType` is prefixed with it (`SQLiteText`,\n * `PgInteger`, `MySqlInt`). So the dialect is detected from the schema and the\n * matching module is imported once, on demand - which also means a SQLite\n * application never loads the Postgres core.\n */\nimport { AdapterError } from '@nest-admin/core'\nimport {\n createTableRelationsHelpers,\n getTableColumns,\n getTableName,\n is,\n Many,\n One,\n Relations,\n SQL,\n Table,\n} from 'drizzle-orm'\n\n/** What a Drizzle column exposes. Structural, because the generic type is not usable here. */\nexport interface DrizzleColumn {\n readonly name: string\n readonly dataType: string\n readonly columnType: string\n readonly notNull: boolean\n readonly hasDefault: boolean\n readonly primary: boolean\n readonly isUnique: boolean\n readonly autoIncrement?: boolean\n readonly enumValues?: readonly string[] | undefined\n readonly default?: unknown\n readonly defaultFn?: unknown\n readonly onUpdateFn?: unknown\n}\n\nexport type Dialect = 'sqlite' | 'pg' | 'mysql'\n\n/** A table, under the name the developer exported it as. */\nexport interface DrizzleTable {\n /** The export key. This is the model name the admin uses everywhere. */\n readonly model: string\n /** The SQL table name. Only used in diagnostics. */\n readonly sqlName: string\n readonly table: object\n /** Property key to column. The property key is the field name. */\n readonly columns: ReadonlyMap<string, DrizzleColumn>\n}\n\n/** One side of a relation, resolved to property keys. */\nexport interface DrizzleRelation {\n /** The model this field is on. */\n readonly model: string\n /** The field name it appears under. */\n readonly field: string\n readonly targetModel: string\n readonly cardinality: 'one' | 'many'\n /**\n * Shared by both sides, so `inverseRelationField` can pair them.\n *\n * Built from the foreign key rather than from either field name, because the\n * two sides are named independently and a name derived from one of them\n * would not match the other.\n */\n readonly name: string\n /** On the `one` side: the foreign key on this model, and what it points at. */\n readonly from?: string\n readonly to?: string\n}\n\nexport interface DrizzleSchema {\n readonly dialect: Dialect\n readonly tables: readonly DrizzleTable[]\n readonly relations: readonly DrizzleRelation[]\n}\n\ninterface TableConfig {\n readonly primaryKeys: readonly { readonly columns: readonly DrizzleColumn[] }[]\n readonly foreignKeys: readonly {\n reference(): {\n readonly columns: readonly DrizzleColumn[]\n readonly foreignTable: object\n readonly foreignColumns: readonly DrizzleColumn[]\n }\n }[]\n}\n\nfunction dialectOf(tables: readonly DrizzleTable[]): Dialect {\n for (const entry of tables) {\n for (const column of entry.columns.values()) {\n if (column.columnType.startsWith('SQLite')) return 'sqlite'\n if (column.columnType.startsWith('Pg')) return 'pg'\n if (column.columnType.startsWith('MySql')) return 'mysql'\n }\n }\n\n throw new AdapterError(\n 'Could not tell which SQL dialect this Drizzle schema uses. ' +\n 'Pass a schema containing at least one table with at least one column.',\n )\n}\n\nconst CORES: Readonly<Record<Dialect, string>> = {\n sqlite: 'drizzle-orm/sqlite-core',\n pg: 'drizzle-orm/pg-core',\n mysql: 'drizzle-orm/mysql-core',\n}\n\nasync function configReader(dialect: Dialect): Promise<(table: object) => TableConfig> {\n const core = (await import(CORES[dialect])) as {\n getTableConfig: (table: object) => TableConfig\n }\n return core.getTableConfig\n}\n\n/** The property key a column is exported under, given its SQL name. */\nfunction keyOf(entry: DrizzleTable, column: DrizzleColumn): string | undefined {\n for (const [key, candidate] of entry.columns) {\n if (candidate.name === column.name) return key\n }\n return undefined\n}\n\n/**\n * Relations the developer declared with `relations()`.\n *\n * Read by calling the config with Drizzle's own helpers, which is how Drizzle's\n * relational queries read it too. When they are declared, their names are\n * authoritative: `author` is what the developer called it, and no heuristic\n * should overrule that.\n */\nfunction declaredRelations(\n schema: Readonly<Record<string, unknown>>,\n tables: readonly DrizzleTable[],\n nameOfFk: (child: string, fk: string) => string,\n): readonly DrizzleRelation[] {\n const byTable = new Map(tables.map((entry) => [entry.table, entry]))\n const found: DrizzleRelation[] = []\n\n for (const value of Object.values(schema)) {\n if (!is(value, Relations)) continue\n\n const owner = byTable.get(value.table)\n if (owner === undefined) continue\n\n const built = value.config(createTableRelationsHelpers(value.table)) as Record<string, unknown>\n\n for (const [field, relation] of Object.entries(built)) {\n const one = is(relation, One)\n if (!one && !is(relation, Many)) continue\n\n const target = byTable.get((relation as { referencedTable: object }).referencedTable)\n if (target === undefined) continue\n\n if (!one) {\n // A `many` declares no columns; the foreign key lives on the far side,\n // and the pairing name is worked out once both sides are known.\n found.push({\n model: owner.model,\n field,\n targetModel: target.model,\n cardinality: 'many',\n name: '',\n })\n continue\n }\n\n const config = (relation as { config?: { fields?: readonly DrizzleColumn[] } }).config\n const fk = config?.fields?.[0]\n const reference = (relation as { config?: { references?: readonly DrizzleColumn[] } }).config\n ?.references?.[0]\n const fkKey = fk ? keyOf(owner, fk) : undefined\n const refKey = reference ? keyOf(target, reference) : undefined\n\n found.push({\n model: owner.model,\n field,\n targetModel: target.model,\n cardinality: 'one',\n name: fkKey ? nameOfFk(owner.model, fkKey) : '',\n ...(fkKey !== undefined ? { from: fkKey } : {}),\n ...(refKey !== undefined ? { to: refKey } : {}),\n })\n }\n }\n\n return found\n}\n\n/**\n * Read a Drizzle schema module into something ORM-neutral.\n *\n * Relations come from `relations()` where the developer declared them, and from\n * foreign keys where they did not - so an admin works against a schema that has\n * never heard of Drizzle's relational API, and uses the developer's own names\n * the moment it has.\n */\nexport async function readSchema(\n schema: Readonly<Record<string, unknown>>,\n): Promise<DrizzleSchema> {\n const tables: DrizzleTable[] = []\n\n for (const [model, value] of Object.entries(schema)) {\n if (!is(value, Table)) continue\n\n const columns = new Map<string, DrizzleColumn>(\n Object.entries(getTableColumns(value) as Record<string, DrizzleColumn>),\n )\n\n tables.push({ model, sqlName: getTableName(value), table: value, columns })\n }\n\n if (tables.length === 0) {\n throw new AdapterError(\n 'This Drizzle schema exports no tables. Pass the schema module itself, ' +\n \"for example `new DrizzleAdapter({ db, schema })` after `import * as schema from './schema.js'`.\",\n )\n }\n\n const dialect = dialectOf(tables)\n const getTableConfig = await configReader(dialect)\n const byTable = new Map(tables.map((entry) => [entry.table, entry]))\n\n const nameOfFk = (child: string, fk: string): string => `${child}.${fk}`\n\n const declared = declaredRelations(schema, tables, nameOfFk)\n const declaredOn = new Set(declared.map((relation) => `${relation.model}.${relation.field}`))\n\n const relations: DrizzleRelation[] = []\n\n // Foreign keys, read from both ends. Each one is two fields: a `one` on the\n // table that holds the key, and a `many` on the table it points at.\n for (const child of tables) {\n for (const foreign of getTableConfig(child.table).foreignKeys) {\n const reference = foreign.reference()\n const parent = byTable.get(reference.foreignTable)\n const column = reference.columns[0]\n const target = reference.foreignColumns[0]\n if (parent === undefined || column === undefined || target === undefined) continue\n\n const fkKey = keyOf(child, column)\n const refKey = keyOf(parent, target)\n if (fkKey === undefined || refKey === undefined) continue\n\n const name = nameOfFk(child.model, fkKey)\n\n // Only where the developer declared nothing. A declared relation carries\n // the name they chose, and inventing a second field beside it would show\n // the same link twice.\n const declaredOne = declared.find(\n (relation) => relation.cardinality === 'one' && relation.name === name,\n )\n\n if (declaredOne === undefined) {\n relations.push({\n model: child.model,\n // `authorId` describes a column; `author` describes the thing on the\n // other end, which is what a person reading a record wants named.\n field: relationFieldName(fkKey, child.columns),\n targetModel: parent.model,\n cardinality: 'one',\n name,\n from: fkKey,\n to: refKey,\n })\n }\n\n const declaredMany = declared.find(\n (relation) =>\n relation.cardinality === 'many' &&\n relation.model === parent.model &&\n relation.targetModel === child.model &&\n relation.name === '',\n )\n\n if (declaredMany === undefined) {\n relations.push({\n model: parent.model,\n field: manyFieldName(child.model, parent, declaredOn),\n targetModel: child.model,\n cardinality: 'many',\n name,\n })\n } else {\n // Pair the declared `many` with this key, so both sides share a name.\n relations.push({ ...declaredMany, name })\n }\n }\n }\n\n // Declared `one` relations keep their own field names.\n for (const relation of declared) {\n if (relation.cardinality === 'one' && relation.name !== '') relations.push(relation)\n }\n\n return { dialect, tables, relations }\n}\n\n/**\n * `authorId` becomes `author`, unless something is already called that.\n *\n * The suffix is stripped rather than the field being called `authorId` twice,\n * because the relation and the key are two different things: one is a record,\n * the other is an opaque string, and the interface renders them differently.\n */\nfunction relationFieldName(fkKey: string, columns: ReadonlyMap<string, DrizzleColumn>): string {\n const stripped = /^(.+?)(Id|_id|ID)$/.exec(fkKey)?.[1]\n if (stripped === undefined || stripped === '') return `${fkKey}Ref`\n return columns.has(stripped) ? `${fkKey}Ref` : stripped\n}\n\n/** `Post` on `User` becomes `posts`, unless the table already has that column. */\nfunction manyFieldName(\n childModel: string,\n parent: DrizzleTable,\n declaredOn: ReadonlySet<string>,\n): string {\n const base = `${childModel.charAt(0).toLowerCase()}${childModel.slice(1)}`\n const plural = base.endsWith('s') ? base : `${base}s`\n const taken = parent.columns.has(plural) || declaredOn.has(`${parent.model}.${plural}`)\n return taken ? `${plural}Related` : plural\n}\n\nexport { SQL }\n"],"mappings":"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","names":["and","eq","is","SQL","is","AdapterError","FieldNotFoundError","eq","and"]}
|