@zenstackhq/runtime 2.14.2 → 2.15.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cross/clone.ts","../../src/cross/model-data-visitor.ts","../../src/cross/model-meta.ts","../../src/cross/mutator.ts","../../src/cross/nested-read-visitor.ts","../../src/cross/types.ts","../../src/cross/utils.ts","../../src/cross/nested-write-visitor.ts","../../src/cross/query-analyzer.ts"],"sourcesContent":["import { isPlainObject } from 'is-plain-object';\n\n/**\n * Clones the given object. Only arrays and plain objects are cloned. Other values are returned as is.\n */\nexport function clone<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map((v) => clone(v)) as T;\n }\n\n if (typeof value === 'object') {\n if (!value || !isPlainObject(value)) {\n return value;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result: any = {};\n for (const key of Object.keys(value)) {\n result[key] = clone(value[key as keyof T]);\n }\n return result;\n }\n\n return value;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { resolveField, type ModelMeta } from '.';\n\n/**\n * Callback for @see ModelDataVisitor.\n */\nexport type ModelDataVisitorCallback = (model: string, data: any, scalarData: any) => void;\n\n/**\n * Visitor that traverses data returned by a Prisma query.\n */\nexport class ModelDataVisitor {\n constructor(private modelMeta: ModelMeta) {}\n\n /**\n * Visits the given model data.\n */\n visit(model: string, data: any, callback: ModelDataVisitorCallback) {\n if (!data || typeof data !== 'object') {\n return;\n }\n\n const scalarData: Record<string, unknown> = {};\n const subTasks: Array<{ model: string; data: any }> = [];\n\n for (const [k, v] of Object.entries(data)) {\n const field = resolveField(this.modelMeta, model, k);\n if (field && field.isDataModel) {\n if (field.isArray && Array.isArray(v)) {\n subTasks.push(...v.map((item) => ({ model: field.type, data: item })));\n } else {\n subTasks.push({ model: field.type, data: v });\n }\n } else {\n scalarData[k] = v;\n }\n }\n\n callback(model, data, scalarData);\n subTasks.forEach(({ model, data }) => this.visit(model, data, callback));\n }\n}\n","import { lowerCaseFirst } from 'lower-case-first';\n\n/**\n * Runtime information of a data model or field attribute\n */\nexport type RuntimeAttribute = {\n /**\n * Attribute name\n */\n name: string;\n\n /**\n * Attribute arguments\n */\n args: Array<{ name?: string; value: unknown }>;\n};\n\n/**\n * Function for computing default value for a field\n */\nexport type FieldDefaultValueProvider = (userContext: unknown) => unknown;\n\n/**\n * Runtime information of a data model field\n */\nexport type FieldInfo = {\n /**\n * Field name\n */\n name: string;\n\n /**\n * Field type name\n */\n type: string;\n\n /**\n * If the field is an ID field or part of a multi-field ID\n */\n isId?: boolean;\n\n /**\n * If the field type is a data model (or an optional/array of data model)\n */\n isDataModel?: boolean;\n\n /**\n * If the field type is a type def (or an optional/array of type def)\n */\n isTypeDef?: boolean;\n\n /**\n * If the field is an array\n */\n isArray?: boolean;\n\n /**\n * If the field is optional\n */\n isOptional?: boolean;\n\n /**\n * Attributes on the field\n */\n attributes?: RuntimeAttribute[];\n\n /**\n * If the field is a relation field, the field name of the reverse side of the relation\n */\n backLink?: string;\n\n /**\n * If the field is the owner side of a relation\n */\n isRelationOwner?: boolean;\n\n /**\n * If the field is a foreign key field\n */\n isForeignKey?: boolean;\n\n /**\n * If the field is a foreign key field, the field name of the corresponding relation field.\n * Only available on foreign key fields.\n */\n relationField?: string;\n\n /**\n * Mapping from relation's pk to fk. Only available on relation fields.\n */\n foreignKeyMapping?: Record<string, string>;\n\n /**\n * Model from which the field is inherited\n */\n inheritedFrom?: string;\n\n /**\n * A function that provides a default value for the field\n */\n defaultValueProvider?: FieldDefaultValueProvider;\n\n /**\n * If the field is an auto-increment field\n */\n isAutoIncrement?: boolean;\n};\n\n/**\n * Metadata for a model-level unique constraint\n * e.g.: @@unique([a, b])\n */\nexport type UniqueConstraint = { name: string; fields: string[] };\n\n/**\n * Metadata for a data model\n */\nexport type ModelInfo = {\n /**\n * Model name\n */\n name: string;\n\n /**\n * Base types (not including abstract base models).\n */\n baseTypes?: string[];\n\n /**\n * Fields\n */\n fields: Record<string, FieldInfo>;\n\n /**\n * Unique constraints\n */\n uniqueConstraints?: Record<string, UniqueConstraint>;\n\n /**\n * Attributes on the model\n */\n attributes?: RuntimeAttribute[];\n\n /**\n * Discriminator field name\n */\n discriminator?: string;\n};\n\n/**\n * Metadata for a type def\n */\nexport type TypeDefInfo = {\n /**\n * TypeDef name\n */\n name: string;\n\n /**\n * Fields\n */\n fields: Record<string, FieldInfo>;\n};\n\n/**\n * ZModel data model metadata\n */\nexport type ModelMeta = {\n /**\n * Data models\n */\n models: Record<string, ModelInfo>;\n\n /**\n * Type defs\n */\n typeDefs?: Record<string, TypeDefInfo>;\n\n /**\n * Mapping from model name to models that will be deleted because of it due to cascade delete\n */\n deleteCascade?: Record<string, string[]>;\n\n /**\n * Name of model that backs the `auth()` function\n */\n authModel?: string;\n\n /**\n * Optional map from full names to shortened names, used for extra fields/relations generated by ZenStack\n */\n shortNameMap?: Record<string, string>;\n};\n\n/**\n * Resolves a model field to its metadata. Returns undefined if not found.\n */\nexport function resolveField(\n modelMeta: ModelMeta,\n modelOrTypeDef: string,\n field: string,\n isTypeDef = false\n): FieldInfo | undefined {\n const container = isTypeDef ? modelMeta.typeDefs : modelMeta.models;\n return container?.[lowerCaseFirst(modelOrTypeDef)]?.fields?.[field];\n}\n\n/**\n * Resolves a model field to its metadata. Throws an error if not found.\n */\nexport function requireField(modelMeta: ModelMeta, model: string, field: string, isTypeDef = false) {\n const f = resolveField(modelMeta, model, field, isTypeDef);\n if (!f) {\n throw new Error(`Field ${model}.${field} cannot be resolved`);\n }\n return f;\n}\n\n/**\n * Gets all fields of a model.\n */\nexport function getFields(modelMeta: ModelMeta, model: string) {\n return modelMeta.models[lowerCaseFirst(model)]?.fields;\n}\n\n/**\n * Gets unique constraints of a model.\n */\nexport function getUniqueConstraints(modelMeta: ModelMeta, model: string) {\n return modelMeta.models[lowerCaseFirst(model)]?.uniqueConstraints;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { v4 as uuid } from 'uuid';\nimport {\n FieldInfo,\n NestedWriteVisitor,\n enumerate,\n getFields,\n getIdFields,\n type ModelMeta,\n type PrismaWriteActionType,\n} from '.';\nimport { clone } from './clone';\n\n/**\n * Tries to apply a mutation to a query result.\n *\n * @param queryModel the model of the query\n * @param queryOp the operation of the query\n * @param queryData the result data of the query\n * @param mutationModel the model of the mutation\n * @param mutationOp the operation of the mutation\n * @param mutationArgs the arguments of the mutation\n * @param modelMeta the model metadata\n * @param logging whether to log the mutation application\n * @returns the updated query data if the mutation is applicable, otherwise undefined\n */\nexport async function applyMutation(\n queryModel: string,\n queryOp: string,\n queryData: any,\n mutationModel: string,\n mutationOp: PrismaWriteActionType,\n mutationArgs: any,\n modelMeta: ModelMeta,\n logging: boolean\n) {\n if (!queryData || (typeof queryData !== 'object' && !Array.isArray(queryData))) {\n return undefined;\n }\n\n if (!queryOp.startsWith('find')) {\n // only findXXX results are applicable\n return undefined;\n }\n\n return await doApplyMutation(queryModel, queryData, mutationModel, mutationOp, mutationArgs, modelMeta, logging);\n}\n\nasync function doApplyMutation(\n queryModel: string,\n queryData: any,\n mutationModel: string,\n mutationOp: PrismaWriteActionType,\n mutationArgs: any,\n modelMeta: ModelMeta,\n logging: boolean\n) {\n let resultData = queryData;\n let updated = false;\n\n const visitor = new NestedWriteVisitor(modelMeta, {\n create: (model, args) => {\n if (\n model === queryModel &&\n Array.isArray(resultData) // \"create\" mutation is only relevant for arrays\n ) {\n const r = createMutate(queryModel, resultData, args, modelMeta, logging);\n if (r) {\n resultData = r;\n updated = true;\n }\n }\n },\n\n createMany: (model, args) => {\n if (\n model === queryModel &&\n args?.data &&\n Array.isArray(resultData) // \"createMany\" mutation is only relevant for arrays\n ) {\n for (const oneArg of enumerate(args.data)) {\n const r = createMutate(queryModel, resultData, oneArg, modelMeta, logging);\n if (r) {\n resultData = r;\n updated = true;\n }\n }\n }\n },\n\n update: (model, args) => {\n if (\n model === queryModel &&\n !Array.isArray(resultData) // array elements will be handled with recursion\n ) {\n const r = updateMutate(queryModel, resultData, model, args, modelMeta, logging);\n if (r) {\n resultData = r;\n updated = true;\n }\n }\n },\n\n upsert: (model, args) => {\n if (model === queryModel && args?.where && args?.create && args?.update) {\n const r = upsertMutate(queryModel, resultData, model, args, modelMeta, logging);\n if (r) {\n resultData = r;\n updated = true;\n }\n }\n },\n\n delete: (model, args) => {\n if (model === queryModel) {\n const r = deleteMutate(queryModel, resultData, model, args, modelMeta, logging);\n if (r) {\n resultData = r;\n updated = true;\n }\n }\n },\n });\n\n await visitor.visit(mutationModel, mutationOp, mutationArgs);\n\n const modelFields = getFields(modelMeta, queryModel);\n\n if (Array.isArray(resultData)) {\n // try to apply mutation to each item in the array, replicate the entire\n // array if any item is updated\n\n let arrayCloned = false;\n for (let i = 0; i < resultData.length; i++) {\n const item = resultData[i];\n if (\n !item ||\n typeof item !== 'object' ||\n item.$optimistic // skip items already optimistically updated\n ) {\n continue;\n }\n\n const r = await doApplyMutation(\n queryModel,\n item,\n mutationModel,\n mutationOp,\n mutationArgs,\n modelMeta,\n logging\n );\n\n if (r && typeof r === 'object') {\n if (!arrayCloned) {\n resultData = [...resultData];\n arrayCloned = true;\n }\n resultData[i] = r;\n updated = true;\n }\n }\n } else if (resultData !== null && typeof resultData === 'object') {\n // Clone resultData to prevent mutations affecting the loop\n const currentData = { ...resultData };\n\n // iterate over each field and apply mutation to nested data models\n for (const [key, value] of Object.entries(currentData)) {\n const fieldInfo = modelFields[key];\n if (!fieldInfo?.isDataModel) {\n continue;\n }\n\n const r = await doApplyMutation(\n fieldInfo.type,\n value,\n mutationModel,\n mutationOp,\n mutationArgs,\n modelMeta,\n logging\n );\n\n if (r && typeof r === 'object') {\n resultData = { ...resultData, [key]: r };\n updated = true;\n }\n }\n }\n\n return updated ? resultData : undefined;\n}\n\nfunction createMutate(queryModel: string, currentData: any, newData: any, modelMeta: ModelMeta, logging: boolean) {\n if (!newData) {\n return undefined;\n }\n\n const modelFields = getFields(modelMeta, queryModel);\n if (!modelFields) {\n return undefined;\n }\n\n const insert: any = {};\n const newDataFields = Object.keys(newData);\n\n Object.entries(modelFields).forEach(([name, field]) => {\n if (field.isDataModel && newData[name]) {\n // deal with \"connect\"\n assignForeignKeyFields(field, insert, newData[name]);\n return;\n }\n\n if (newDataFields.includes(name)) {\n insert[name] = clone(newData[name]);\n } else {\n const defaultAttr = field.attributes?.find((attr) => attr.name === '@default');\n if (field.type === 'DateTime') {\n // default value for DateTime field\n if (defaultAttr || field.attributes?.some((attr) => attr.name === '@updatedAt')) {\n insert[name] = new Date();\n }\n } else if (defaultAttr?.args?.[0]?.value !== undefined) {\n // other default value\n insert[name] = defaultAttr.args[0].value;\n }\n }\n });\n\n // add temp id value\n const idFields = getIdFields(modelMeta, queryModel, false);\n idFields.forEach((f) => {\n if (insert[f.name] === undefined) {\n if (f.type === 'Int' || f.type === 'BigInt') {\n const currMax = Array.isArray(currentData)\n ? Math.max(\n ...[...currentData].map((item) => {\n const idv = parseInt(item[f.name]);\n return isNaN(idv) ? 0 : idv;\n })\n )\n : 0;\n insert[f.name] = currMax + 1;\n } else {\n insert[f.name] = uuid();\n }\n }\n });\n\n insert.$optimistic = true;\n\n if (logging) {\n console.log(`Optimistic create for ${queryModel}:`, insert);\n }\n return [insert, ...(Array.isArray(currentData) ? currentData : [])];\n}\n\nfunction updateMutate(\n queryModel: string,\n currentData: any,\n mutateModel: string,\n mutateArgs: any,\n modelMeta: ModelMeta,\n logging: boolean\n) {\n if (!currentData || typeof currentData !== 'object') {\n return undefined;\n }\n\n if (!mutateArgs?.where || typeof mutateArgs.where !== 'object') {\n return undefined;\n }\n\n if (!mutateArgs?.data || typeof mutateArgs.data !== 'object') {\n return undefined;\n }\n\n if (!idFieldsMatch(mutateModel, currentData, mutateArgs.where, modelMeta)) {\n return undefined;\n }\n\n const modelFields = getFields(modelMeta, queryModel);\n if (!modelFields) {\n return undefined;\n }\n\n let updated = false;\n let resultData = currentData;\n\n for (const [key, value] of Object.entries<any>(mutateArgs.data)) {\n const fieldInfo = modelFields[key];\n if (!fieldInfo) {\n continue;\n }\n\n if (fieldInfo.isDataModel && !value?.connect) {\n // relation field but without \"connect\"\n continue;\n }\n\n if (!updated) {\n // clone\n resultData = { ...currentData };\n }\n\n if (fieldInfo.isDataModel) {\n // deal with \"connect\"\n assignForeignKeyFields(fieldInfo, resultData, value);\n } else {\n resultData[key] = clone(value);\n }\n resultData.$optimistic = true;\n updated = true;\n\n if (logging) {\n console.log(`Optimistic update for ${queryModel}:`, resultData);\n }\n }\n\n return updated ? resultData : undefined;\n}\n\nfunction upsertMutate(\n queryModel: string,\n currentData: any,\n model: string,\n args: { where: object; create: any; update: any },\n modelMeta: ModelMeta,\n logging: boolean\n) {\n let updated = false;\n let resultData = currentData;\n\n if (Array.isArray(resultData)) {\n // check if we should create or update\n const foundIndex = resultData.findIndex((x) => idFieldsMatch(model, x, args.where, modelMeta));\n if (foundIndex >= 0) {\n const updateResult = updateMutate(\n queryModel,\n resultData[foundIndex],\n model,\n { where: args.where, data: args.update },\n modelMeta,\n logging\n );\n if (updateResult) {\n // replace the found item with updated item\n resultData = [...resultData.slice(0, foundIndex), updateResult, ...resultData.slice(foundIndex + 1)];\n updated = true;\n }\n } else {\n const createResult = createMutate(queryModel, resultData, args.create, modelMeta, logging);\n if (createResult) {\n resultData = createResult;\n updated = true;\n }\n }\n } else {\n // try update only\n const updateResult = updateMutate(\n queryModel,\n resultData,\n model,\n { where: args.where, data: args.update },\n modelMeta,\n logging\n );\n if (updateResult) {\n resultData = updateResult;\n updated = true;\n }\n }\n\n return updated ? resultData : undefined;\n}\n\nfunction deleteMutate(\n queryModel: string,\n currentData: any,\n mutateModel: string,\n mutateArgs: any,\n modelMeta: ModelMeta,\n logging: boolean\n) {\n // TODO: handle mutation of nested reads?\n\n if (!currentData || !mutateArgs) {\n return undefined;\n }\n\n if (queryModel !== mutateModel) {\n return undefined;\n }\n\n let updated = false;\n let result = currentData;\n\n if (Array.isArray(currentData)) {\n for (const item of currentData) {\n if (idFieldsMatch(mutateModel, item, mutateArgs, modelMeta)) {\n result = (result as unknown[]).filter((x) => x !== item);\n updated = true;\n if (logging) {\n console.log(`Optimistic delete for ${queryModel}:`, item);\n }\n }\n }\n } else {\n if (idFieldsMatch(mutateModel, currentData, mutateArgs, modelMeta)) {\n result = null;\n updated = true;\n if (logging) {\n console.log(`Optimistic delete for ${queryModel}:`, currentData);\n }\n }\n }\n\n return updated ? result : undefined;\n}\n\nfunction idFieldsMatch(model: string, x: any, y: any, modelMeta: ModelMeta) {\n if (!x || !y || typeof x !== 'object' || typeof y !== 'object') {\n return false;\n }\n const idFields = getIdFields(modelMeta, model, false);\n if (idFields.length === 0) {\n return false;\n }\n return idFields.every((f) => x[f.name] === y[f.name]);\n}\n\nfunction assignForeignKeyFields(field: FieldInfo, resultData: any, mutationData: any) {\n // convert \"connect\" like `{ connect: { id: '...' } }` to foreign key fields\n // assignment: `{ userId: '...' }`\n if (!mutationData?.connect) {\n return;\n }\n\n if (!field.foreignKeyMapping) {\n return;\n }\n\n for (const [idField, fkField] of Object.entries(field.foreignKeyMapping)) {\n if (idField in mutationData.connect) {\n resultData[fkField] = mutationData.connect[idField];\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { resolveField, type FieldInfo, type ModelMeta } from './model-meta';\n\nexport type NestedReadVisitorCallback = {\n field?: (\n model: string,\n field: FieldInfo | undefined,\n kind: 'include' | 'select' | undefined,\n args: unknown\n ) => void | boolean;\n};\n\n/**\n * Visitor for nested read payload.\n */\nexport class NestedReadVisitor {\n constructor(private readonly modelMeta: ModelMeta, private readonly callback: NestedReadVisitorCallback) {}\n\n doVisit(model: string, field: FieldInfo | undefined, kind: 'include' | 'select' | undefined, args: unknown) {\n if (this.callback.field) {\n const r = this.callback.field(model, field, kind, args);\n if (r === false) {\n return;\n }\n }\n\n if (!args || typeof args !== 'object') {\n return;\n }\n\n let selectInclude: any;\n let nextKind: 'select' | 'include' | undefined;\n if ((args as any).select) {\n selectInclude = (args as any).select;\n nextKind = 'select';\n } else if ((args as any).include) {\n selectInclude = (args as any).include;\n nextKind = 'include';\n }\n\n if (selectInclude && typeof selectInclude === 'object') {\n for (const [k, v] of Object.entries(selectInclude)) {\n if (k === '_count' && typeof v === 'object' && v) {\n // recurse into { _count: { ... } }\n this.doVisit(model, field, kind, v);\n } else {\n const field = resolveField(this.modelMeta, model, k);\n if (field) {\n this.doVisit(field.type, field, nextKind, v);\n }\n }\n }\n }\n }\n\n visit(model: string, args: unknown) {\n this.doVisit(model, undefined, undefined, args);\n }\n}\n","/**\n * Prisma write operation kinds\n */\nexport const PrismaWriteActions = [\n 'create',\n 'createMany',\n 'createManyAndReturn',\n 'connectOrCreate',\n 'update',\n 'updateMany',\n 'updateManyAndReturn',\n 'upsert',\n 'connect',\n 'disconnect',\n 'set',\n 'delete',\n 'deleteMany',\n] as const;\n\n/**\n * Prisma write operation kinds\n */\nexport type PrismaWriteActionType = (typeof PrismaWriteActions)[number];\n\n/**\n * Maybe promise\n */\nexport type MaybePromise<T> = T | Promise<T> | PromiseLike<T>;\n","import { lowerCaseFirst } from 'lower-case-first';\nimport { requireField, type ModelInfo, type ModelMeta, type TypeDefInfo } from '.';\n\n/**\n * Gets field names in a data model entity, filtering out internal fields.\n */\nexport function getModelFields(data: object) {\n return data ? Object.keys(data) : [];\n}\n\n/**\n * Array or scalar\n */\nexport type Enumerable<T> = T | Array<T>;\n\n/**\n * Uniformly enumerates an array or scalar.\n */\nexport function enumerate<T>(x: Enumerable<T>) {\n if (x === null || x === undefined) {\n return [];\n } else if (Array.isArray(x)) {\n return x;\n } else {\n return [x];\n }\n}\n\n/**\n * Zip two arrays or scalars.\n */\nexport function zip<T1, T2>(x: Enumerable<T1>, y: Enumerable<T2>): Array<[T1, T2]> {\n if (Array.isArray(x)) {\n if (!Array.isArray(y)) {\n throw new Error('x and y should be both array or both scalar');\n }\n if (x.length !== y.length) {\n throw new Error('x and y should have the same length');\n }\n return x.map((_, i) => [x[i], y[i]] as [T1, T2]);\n } else {\n if (Array.isArray(y)) {\n throw new Error('x and y should be both array or both scalar');\n }\n return [[x, y]];\n }\n}\n\n/**\n * Gets ID fields of a model.\n */\nexport function getIdFields(modelMeta: ModelMeta, model: string, throwIfNotFound = false) {\n const uniqueConstraints = modelMeta.models[lowerCaseFirst(model)]?.uniqueConstraints ?? {};\n\n const entries = Object.values(uniqueConstraints);\n if (entries.length === 0) {\n if (throwIfNotFound) {\n throw new Error(`Model ${model} does not have any id field`);\n }\n return [];\n }\n\n return entries[0].fields.map((f) => requireField(modelMeta, model, f));\n}\n\n/**\n * Gets info for a model.\n */\nexport function getModelInfo<Throw extends boolean = false>(\n modelMeta: ModelMeta,\n model: string,\n throwIfNotFound: Throw = false as Throw\n): Throw extends true ? ModelInfo : ModelInfo | undefined {\n const info = modelMeta.models[lowerCaseFirst(model)];\n if (!info && throwIfNotFound) {\n throw new Error(`Unable to load info for ${model}`);\n }\n return info;\n}\n\n/**\n * Gets info for a type def.\n */\nexport function getTypeDefInfo<Throw extends boolean = false>(\n modelMeta: ModelMeta,\n typeDef: string,\n throwIfNotFound: Throw = false as Throw\n): Throw extends true ? TypeDefInfo : TypeDefInfo | undefined {\n const info = modelMeta.typeDefs?.[lowerCaseFirst(typeDef)];\n if (!info && throwIfNotFound) {\n throw new Error(`Unable to load info for ${typeDef}`);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return info as any;\n}\n\n/**\n * Checks if a model is a delegate model.\n */\nexport function isDelegateModel(modelMeta: ModelMeta, model: string) {\n return !!getModelInfo(modelMeta, model)?.attributes?.some((attr) => attr.name === '@@delegate');\n}\n","/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { FieldInfo, ModelMeta } from './model-meta';\nimport { resolveField } from './model-meta';\nimport { MaybePromise, PrismaWriteActionType, PrismaWriteActions } from './types';\nimport { enumerate, getModelFields } from './utils';\n\ntype NestingPathItem = { field?: FieldInfo; model: string; where: any; unique: boolean };\n\n/**\n * Context for visiting\n */\nexport type NestedWriteVisitorContext = {\n /**\n * Parent data, can be used to replace fields\n */\n parent: any;\n\n /**\n * Current field, undefined if toplevel\n */\n field?: FieldInfo;\n\n /**\n * A top-down path of all nested update conditions and corresponding field till now\n */\n nestingPath: NestingPathItem[];\n};\n\n/**\n * NestedWriteVisitor's callback actions. A call back function should return true or void to indicate\n * that the visitor should continue traversing its children, or false to stop. It can also return an object\n * to let the visitor traverse it instead of its original children.\n */\nexport type NestedWriterVisitorCallback = {\n create?: (model: string, data: any, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;\n\n createMany?: (\n model: string,\n args: { data: any; skipDuplicates?: boolean },\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n connectOrCreate?: (\n model: string,\n args: { where: object; create: any },\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n connect?: (\n model: string,\n args: object,\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n disconnect?: (\n model: string,\n args: object,\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n set?: (model: string, args: object, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;\n\n update?: (model: string, args: object, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;\n\n updateMany?: (\n model: string,\n args: { where?: object; data: any },\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n upsert?: (\n model: string,\n args: { where: object; create: any; update: any },\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n delete?: (\n model: string,\n args: object | boolean,\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n deleteMany?: (\n model: string,\n args: any | object,\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n field?: (\n field: FieldInfo,\n action: PrismaWriteActionType,\n data: any,\n context: NestedWriteVisitorContext\n ) => MaybePromise<void>;\n};\n\n/**\n * Recursive visitor for nested write (create/update) payload.\n */\nexport class NestedWriteVisitor {\n constructor(private readonly modelMeta: ModelMeta, private readonly callback: NestedWriterVisitorCallback) {}\n\n private isPrismaWriteAction(value: string): value is PrismaWriteActionType {\n return PrismaWriteActions.includes(value as PrismaWriteActionType);\n }\n\n /**\n * Start visiting\n *\n * @see NestedWriterVisitorCallback\n */\n async visit(model: string, action: PrismaWriteActionType, args: any): Promise<void> {\n if (!args) {\n return;\n }\n\n let topData = args;\n\n switch (action) {\n // create has its data wrapped in 'data' field\n case 'create':\n topData = topData.data;\n break;\n\n case 'delete':\n case 'deleteMany':\n topData = topData.where;\n break;\n }\n\n await this.doVisit(model, action, topData, undefined, undefined, []);\n }\n\n private async doVisit(\n model: string,\n action: PrismaWriteActionType,\n data: any,\n parent: any,\n field: FieldInfo | undefined,\n nestingPath: NestingPathItem[]\n ): Promise<void> {\n if (!data) {\n return;\n }\n\n const toplevel = field == undefined;\n\n const context = { parent, field, nestingPath: [...nestingPath] };\n const pushNewContext = (field: FieldInfo | undefined, model: string, where: any, unique = false) => {\n return { ...context, nestingPath: [...context.nestingPath, { field, model, where, unique }] };\n };\n\n // visit payload\n switch (action) {\n case 'create':\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, {});\n let callbackResult: any;\n if (this.callback.create) {\n callbackResult = await this.callback.create(model, item, newContext);\n }\n if (callbackResult !== false) {\n const subPayload = typeof callbackResult === 'object' ? callbackResult : item;\n await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);\n }\n }\n break;\n\n case 'createMany':\n case 'createManyAndReturn':\n if (data) {\n const newContext = pushNewContext(field, model, {});\n let callbackResult: any;\n if (this.callback.createMany) {\n callbackResult = await this.callback.createMany(model, data, newContext);\n }\n if (callbackResult !== false) {\n const subPayload = typeof callbackResult === 'object' ? callbackResult : data.data;\n await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);\n }\n }\n break;\n\n case 'connectOrCreate':\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item.where);\n let callbackResult: any;\n if (this.callback.connectOrCreate) {\n callbackResult = await this.callback.connectOrCreate(model, item, newContext);\n }\n if (callbackResult !== false) {\n const subPayload = typeof callbackResult === 'object' ? callbackResult : item.create;\n await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);\n }\n }\n break;\n\n case 'connect':\n if (this.callback.connect) {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item, true);\n await this.callback.connect(model, item, newContext);\n }\n }\n break;\n\n case 'disconnect':\n // disconnect has two forms:\n // if relation is to-many, the payload is a unique filter object\n // if relation is to-one, the payload can only be boolean `true`\n if (this.callback.disconnect) {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item, typeof item === 'object');\n await this.callback.disconnect(model, item, newContext);\n }\n }\n break;\n\n case 'set':\n if (this.callback.set) {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item, true);\n await this.callback.set(model, item, newContext);\n }\n }\n break;\n\n case 'update':\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item.where);\n let callbackResult: any;\n if (this.callback.update) {\n callbackResult = await this.callback.update(model, item, newContext);\n }\n if (callbackResult !== false) {\n const subPayload =\n typeof callbackResult === 'object'\n ? callbackResult\n : typeof item.data === 'object'\n ? item.data\n : item;\n await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);\n }\n }\n break;\n\n case 'updateMany':\n case 'updateManyAndReturn':\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item.where);\n let callbackResult: any;\n if (this.callback.updateMany) {\n callbackResult = await this.callback.updateMany(model, item, newContext);\n }\n if (callbackResult !== false) {\n const subPayload = typeof callbackResult === 'object' ? callbackResult : item;\n await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);\n }\n }\n break;\n\n case 'upsert': {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item.where);\n let callbackResult: any;\n if (this.callback.upsert) {\n callbackResult = await this.callback.upsert(model, item, newContext);\n }\n if (callbackResult !== false) {\n if (typeof callbackResult === 'object') {\n await this.visitSubPayload(model, action, callbackResult, newContext.nestingPath);\n } else {\n await this.visitSubPayload(model, action, item.create, newContext.nestingPath);\n await this.visitSubPayload(model, action, item.update, newContext.nestingPath);\n }\n }\n }\n break;\n }\n\n case 'delete': {\n if (this.callback.delete) {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, toplevel ? item.where : item);\n await this.callback.delete(model, item, newContext);\n }\n }\n break;\n }\n\n case 'deleteMany':\n if (this.callback.deleteMany) {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, toplevel ? item.where : item);\n await this.callback.deleteMany(model, item, newContext);\n }\n }\n break;\n\n default: {\n throw new Error(`unhandled action type ${action}`);\n }\n }\n }\n\n private async visitSubPayload(\n model: string,\n action: PrismaWriteActionType,\n payload: any,\n nestingPath: NestingPathItem[]\n ) {\n for (const item of enumerate(payload)) {\n for (const field of getModelFields(item)) {\n const fieldInfo = resolveField(this.modelMeta, model, field);\n if (!fieldInfo) {\n continue;\n }\n\n if (fieldInfo.isDataModel) {\n if (item[field]) {\n // recurse into nested payloads\n for (const [subAction, subData] of Object.entries<any>(item[field])) {\n if (this.isPrismaWriteAction(subAction) && subData) {\n await this.doVisit(fieldInfo.type, subAction, subData, item[field], fieldInfo, [\n ...nestingPath,\n ]);\n }\n }\n }\n } else {\n // visit plain field\n if (this.callback.field) {\n await this.callback.field(fieldInfo, action, item[field], {\n parent: item,\n nestingPath,\n field: fieldInfo,\n });\n }\n }\n }\n }\n }\n\n // enumerate a (possible) array in reverse order, so that the enumeration\n // callback can safely delete the current item\n private *enumerateReverse(data: any) {\n if (Array.isArray(data)) {\n for (let i = data.length - 1; i >= 0; i--) {\n yield data[i];\n }\n } else {\n yield data;\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { lowerCaseFirst } from 'lower-case-first';\nimport type { ModelMeta } from './model-meta';\nimport { NestedReadVisitor } from './nested-read-visitor';\nimport { NestedWriteVisitor } from './nested-write-visitor';\nimport type { PrismaWriteActionType } from './types';\nimport { getModelInfo } from './utils';\n\n/**\n * Gets models read (including nested ones) given a query args.\n * @param model\n * @param targetModels\n * @param modelMeta\n * @param args\n * @returns\n */\nexport function getReadModels(model: string, modelMeta: ModelMeta, args: any) {\n const result = new Set<string>();\n result.add(model);\n const visitor = new NestedReadVisitor(modelMeta, {\n field: (model) => {\n result.add(model);\n return true;\n },\n });\n visitor.visit(model, args);\n return [...result];\n}\n\n/**\n * Gets mutated models (including nested ones) given a mutation args.\n */\nexport async function getMutatedModels(\n model: string,\n operation: PrismaWriteActionType,\n mutationArgs: any,\n modelMeta: ModelMeta\n) {\n const result = new Set<string>();\n result.add(model);\n\n if (mutationArgs) {\n const addModel = (model: string) => void result.add(model);\n\n // add models that are cascaded deleted recursively\n const addCascades = (model: string) => {\n const cascades = new Set<string>();\n const visited = new Set<string>();\n collectDeleteCascades(model, modelMeta, cascades, visited);\n cascades.forEach((m) => addModel(m));\n };\n\n const visitor = new NestedWriteVisitor(modelMeta, {\n create: addModel,\n createMany: addModel,\n connectOrCreate: addModel,\n connect: addModel,\n disconnect: addModel,\n set: addModel,\n update: addModel,\n updateMany: addModel,\n upsert: addModel,\n delete: (model) => {\n addModel(model);\n addCascades(model);\n },\n deleteMany: (model) => {\n addModel(model);\n addCascades(model);\n },\n });\n await visitor.visit(model, operation, mutationArgs);\n }\n\n // include delegate base models recursively\n result.forEach((m) => {\n getBaseRecursively(m, modelMeta, result);\n });\n\n return [...result];\n}\n\nfunction collectDeleteCascades(model: string, modelMeta: ModelMeta, result: Set<string>, visited: Set<string>) {\n if (visited.has(model)) {\n // break circle\n return;\n }\n visited.add(model);\n\n const cascades = modelMeta.deleteCascade?.[lowerCaseFirst(model)];\n\n if (!cascades) {\n return;\n }\n\n cascades.forEach((m) => {\n result.add(m);\n collectDeleteCascades(m, modelMeta, result, visited);\n });\n}\n\nfunction getBaseRecursively(model: string, modelMeta: ModelMeta, result: Set<string>) {\n const bases = getModelInfo(modelMeta, model)?.baseTypes;\n if (bases) {\n bases.forEach((base) => {\n result.add(base);\n getBaseRecursively(base, modelMeta, result);\n });\n }\n}\n"],"mappings":"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","names":["model","data","field","lowerCaseFirst","lowerCaseFirst","field","model","lowerCaseFirst","model","lowerCaseFirst"]}
1
+ {"version":3,"sources":["../../src/cross/clone.ts","../../src/cross/model-data-visitor.ts","../../src/cross/model-meta.ts","../../src/cross/mutator.ts","../../src/cross/nested-read-visitor.ts","../../src/cross/types.ts","../../src/cross/utils.ts","../../src/cross/nested-write-visitor.ts","../../src/cross/query-analyzer.ts"],"sourcesContent":["import { isPlainObject } from 'is-plain-object';\n\n/**\n * Clones the given object. Only arrays and plain objects are cloned. Other values are returned as is.\n */\nexport function clone<T>(value: T): T {\n if (Array.isArray(value)) {\n return value.map((v) => clone(v)) as T;\n }\n\n if (typeof value === 'object') {\n if (!value || !isPlainObject(value)) {\n return value;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result: any = {};\n for (const key of Object.keys(value)) {\n result[key] = clone(value[key as keyof T]);\n }\n return result;\n }\n\n return value;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { resolveField, type ModelMeta } from '.';\n\n/**\n * Callback for @see ModelDataVisitor.\n */\nexport type ModelDataVisitorCallback = (model: string, data: any, scalarData: any) => void;\n\n/**\n * Visitor that traverses data returned by a Prisma query.\n */\nexport class ModelDataVisitor {\n constructor(private modelMeta: ModelMeta) {}\n\n /**\n * Visits the given model data.\n */\n visit(model: string, data: any, callback: ModelDataVisitorCallback) {\n if (!data || typeof data !== 'object') {\n return;\n }\n\n const scalarData: Record<string, unknown> = {};\n const subTasks: Array<{ model: string; data: any }> = [];\n\n for (const [k, v] of Object.entries(data)) {\n const field = resolveField(this.modelMeta, model, k);\n if (field && field.isDataModel) {\n if (field.isArray && Array.isArray(v)) {\n subTasks.push(...v.map((item) => ({ model: field.type, data: item })));\n } else {\n subTasks.push({ model: field.type, data: v });\n }\n } else {\n scalarData[k] = v;\n }\n }\n\n callback(model, data, scalarData);\n subTasks.forEach(({ model, data }) => this.visit(model, data, callback));\n }\n}\n","import { lowerCaseFirst } from 'lower-case-first';\n\n/**\n * Runtime information of a data model or field attribute\n */\nexport type RuntimeAttribute = {\n /**\n * Attribute name\n */\n name: string;\n\n /**\n * Attribute arguments\n */\n args: Array<{ name?: string; value: unknown }>;\n};\n\n/**\n * Function for computing default value for a field\n */\nexport type FieldDefaultValueProvider = (userContext: unknown) => unknown;\n\n/**\n * Action to take when the related model is deleted or updated\n */\nexport type RelationAction = 'Cascade' | 'Restrict' | 'NoAction' | 'SetNull' | 'SetDefault';\n\n/**\n * Runtime information of a data model field\n */\nexport type FieldInfo = {\n /**\n * Field name\n */\n name: string;\n\n /**\n * Field type name\n */\n type: string;\n\n /**\n * If the field is an ID field or part of a multi-field ID\n */\n isId?: boolean;\n\n /**\n * If the field type is a data model (or an optional/array of data model)\n */\n isDataModel?: boolean;\n\n /**\n * If the field type is a type def (or an optional/array of type def)\n */\n isTypeDef?: boolean;\n\n /**\n * If the field is an array\n */\n isArray?: boolean;\n\n /**\n * If the field is optional\n */\n isOptional?: boolean;\n\n /**\n * Attributes on the field\n */\n attributes?: RuntimeAttribute[];\n\n /**\n * If the field is a relation field, the field name of the reverse side of the relation\n */\n backLink?: string;\n\n /**\n * If the field is the owner side of a relation\n */\n isRelationOwner?: boolean;\n\n /**\n * Action to take when the related model is deleted.\n */\n onDeleteAction?: RelationAction;\n\n /**\n * Action to take when the related model is updated.\n */\n onUpdateAction?: RelationAction;\n\n /**\n * If the field is a foreign key field\n */\n isForeignKey?: boolean;\n\n /**\n * If the field is a foreign key field, the field name of the corresponding relation field.\n * Only available on foreign key fields.\n */\n relationField?: string;\n\n /**\n * Mapping from relation's pk to fk. Only available on relation fields.\n */\n foreignKeyMapping?: Record<string, string>;\n\n /**\n * Model from which the field is inherited\n */\n inheritedFrom?: string;\n\n /**\n * A function that provides a default value for the field\n */\n defaultValueProvider?: FieldDefaultValueProvider;\n\n /**\n * If the field is an auto-increment field\n */\n isAutoIncrement?: boolean;\n};\n\n/**\n * Metadata for a model-level unique constraint\n * e.g.: @@unique([a, b])\n */\nexport type UniqueConstraint = { name: string; fields: string[] };\n\n/**\n * Metadata for a data model\n */\nexport type ModelInfo = {\n /**\n * Model name\n */\n name: string;\n\n /**\n * Base types (not including abstract base models).\n */\n baseTypes?: string[];\n\n /**\n * Fields\n */\n fields: Record<string, FieldInfo>;\n\n /**\n * Unique constraints\n */\n uniqueConstraints?: Record<string, UniqueConstraint>;\n\n /**\n * Attributes on the model\n */\n attributes?: RuntimeAttribute[];\n\n /**\n * Discriminator field name\n */\n discriminator?: string;\n};\n\n/**\n * Metadata for a type def\n */\nexport type TypeDefInfo = {\n /**\n * TypeDef name\n */\n name: string;\n\n /**\n * Fields\n */\n fields: Record<string, FieldInfo>;\n};\n\n/**\n * ZModel data model metadata\n */\nexport type ModelMeta = {\n /**\n * Data models\n */\n models: Record<string, ModelInfo>;\n\n /**\n * Type defs\n */\n typeDefs?: Record<string, TypeDefInfo>;\n\n /**\n * Mapping from model name to models that will be deleted because of it due to cascade delete\n */\n deleteCascade?: Record<string, string[]>;\n\n /**\n * Name of model that backs the `auth()` function\n */\n authModel?: string;\n\n /**\n * Optional map from full names to shortened names, used for extra fields/relations generated by ZenStack\n */\n shortNameMap?: Record<string, string>;\n};\n\n/**\n * Resolves a model field to its metadata. Returns undefined if not found.\n */\nexport function resolveField(\n modelMeta: ModelMeta,\n modelOrTypeDef: string,\n field: string,\n isTypeDef = false\n): FieldInfo | undefined {\n const container = isTypeDef ? modelMeta.typeDefs : modelMeta.models;\n return container?.[lowerCaseFirst(modelOrTypeDef)]?.fields?.[field];\n}\n\n/**\n * Resolves a model field to its metadata. Throws an error if not found.\n */\nexport function requireField(modelMeta: ModelMeta, model: string, field: string, isTypeDef = false) {\n const f = resolveField(modelMeta, model, field, isTypeDef);\n if (!f) {\n throw new Error(`Field ${model}.${field} cannot be resolved`);\n }\n return f;\n}\n\n/**\n * Gets all fields of a model.\n */\nexport function getFields(modelMeta: ModelMeta, model: string) {\n return modelMeta.models[lowerCaseFirst(model)]?.fields;\n}\n\n/**\n * Gets unique constraints of a model.\n */\nexport function getUniqueConstraints(modelMeta: ModelMeta, model: string) {\n return modelMeta.models[lowerCaseFirst(model)]?.uniqueConstraints;\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { v4 as uuid } from 'uuid';\nimport {\n FieldInfo,\n NestedWriteVisitor,\n enumerate,\n getFields,\n getIdFields,\n type ModelMeta,\n type PrismaWriteActionType,\n} from '.';\nimport { clone } from './clone';\n\n/**\n * Tries to apply a mutation to a query result.\n *\n * @param queryModel the model of the query\n * @param queryOp the operation of the query\n * @param queryData the result data of the query\n * @param mutationModel the model of the mutation\n * @param mutationOp the operation of the mutation\n * @param mutationArgs the arguments of the mutation\n * @param modelMeta the model metadata\n * @param logging whether to log the mutation application\n * @returns the updated query data if the mutation is applicable, otherwise undefined\n */\nexport async function applyMutation(\n queryModel: string,\n queryOp: string,\n queryData: any,\n mutationModel: string,\n mutationOp: PrismaWriteActionType,\n mutationArgs: any,\n modelMeta: ModelMeta,\n logging: boolean\n) {\n if (!queryData || (typeof queryData !== 'object' && !Array.isArray(queryData))) {\n return undefined;\n }\n\n if (!queryOp.startsWith('find')) {\n // only findXXX results are applicable\n return undefined;\n }\n\n return await doApplyMutation(queryModel, queryData, mutationModel, mutationOp, mutationArgs, modelMeta, logging);\n}\n\nasync function doApplyMutation(\n queryModel: string,\n queryData: any,\n mutationModel: string,\n mutationOp: PrismaWriteActionType,\n mutationArgs: any,\n modelMeta: ModelMeta,\n logging: boolean\n) {\n let resultData = queryData;\n let updated = false;\n\n const visitor = new NestedWriteVisitor(modelMeta, {\n create: (model, args) => {\n if (\n model === queryModel &&\n Array.isArray(resultData) // \"create\" mutation is only relevant for arrays\n ) {\n const r = createMutate(queryModel, resultData, args, modelMeta, logging);\n if (r) {\n resultData = r;\n updated = true;\n }\n }\n },\n\n createMany: (model, args) => {\n if (\n model === queryModel &&\n args?.data &&\n Array.isArray(resultData) // \"createMany\" mutation is only relevant for arrays\n ) {\n for (const oneArg of enumerate(args.data)) {\n const r = createMutate(queryModel, resultData, oneArg, modelMeta, logging);\n if (r) {\n resultData = r;\n updated = true;\n }\n }\n }\n },\n\n update: (model, args) => {\n if (\n model === queryModel &&\n !Array.isArray(resultData) // array elements will be handled with recursion\n ) {\n const r = updateMutate(queryModel, resultData, model, args, modelMeta, logging);\n if (r) {\n resultData = r;\n updated = true;\n }\n }\n },\n\n upsert: (model, args) => {\n if (model === queryModel && args?.where && args?.create && args?.update) {\n const r = upsertMutate(queryModel, resultData, model, args, modelMeta, logging);\n if (r) {\n resultData = r;\n updated = true;\n }\n }\n },\n\n delete: (model, args) => {\n if (model === queryModel) {\n const r = deleteMutate(queryModel, resultData, model, args, modelMeta, logging);\n if (r) {\n resultData = r;\n updated = true;\n }\n }\n },\n });\n\n await visitor.visit(mutationModel, mutationOp, mutationArgs);\n\n const modelFields = getFields(modelMeta, queryModel);\n\n if (Array.isArray(resultData)) {\n // try to apply mutation to each item in the array, replicate the entire\n // array if any item is updated\n\n let arrayCloned = false;\n for (let i = 0; i < resultData.length; i++) {\n const item = resultData[i];\n if (\n !item ||\n typeof item !== 'object' ||\n item.$optimistic // skip items already optimistically updated\n ) {\n continue;\n }\n\n const r = await doApplyMutation(\n queryModel,\n item,\n mutationModel,\n mutationOp,\n mutationArgs,\n modelMeta,\n logging\n );\n\n if (r && typeof r === 'object') {\n if (!arrayCloned) {\n resultData = [...resultData];\n arrayCloned = true;\n }\n resultData[i] = r;\n updated = true;\n }\n }\n } else if (resultData !== null && typeof resultData === 'object') {\n // Clone resultData to prevent mutations affecting the loop\n const currentData = { ...resultData };\n\n // iterate over each field and apply mutation to nested data models\n for (const [key, value] of Object.entries(currentData)) {\n const fieldInfo = modelFields[key];\n if (!fieldInfo?.isDataModel) {\n continue;\n }\n\n const r = await doApplyMutation(\n fieldInfo.type,\n value,\n mutationModel,\n mutationOp,\n mutationArgs,\n modelMeta,\n logging\n );\n\n if (r && typeof r === 'object') {\n resultData = { ...resultData, [key]: r };\n updated = true;\n }\n }\n }\n\n return updated ? resultData : undefined;\n}\n\nfunction createMutate(queryModel: string, currentData: any, newData: any, modelMeta: ModelMeta, logging: boolean) {\n if (!newData) {\n return undefined;\n }\n\n const modelFields = getFields(modelMeta, queryModel);\n if (!modelFields) {\n return undefined;\n }\n\n const insert: any = {};\n const newDataFields = Object.keys(newData);\n\n Object.entries(modelFields).forEach(([name, field]) => {\n if (field.isDataModel && newData[name]) {\n // deal with \"connect\"\n assignForeignKeyFields(field, insert, newData[name]);\n return;\n }\n\n if (newDataFields.includes(name)) {\n insert[name] = clone(newData[name]);\n } else {\n const defaultAttr = field.attributes?.find((attr) => attr.name === '@default');\n if (field.type === 'DateTime') {\n // default value for DateTime field\n if (defaultAttr || field.attributes?.some((attr) => attr.name === '@updatedAt')) {\n insert[name] = new Date();\n }\n } else if (defaultAttr?.args?.[0]?.value !== undefined) {\n // other default value\n insert[name] = defaultAttr.args[0].value;\n }\n }\n });\n\n // add temp id value\n const idFields = getIdFields(modelMeta, queryModel, false);\n idFields.forEach((f) => {\n if (insert[f.name] === undefined) {\n if (f.type === 'Int' || f.type === 'BigInt') {\n const currMax = Array.isArray(currentData)\n ? Math.max(\n ...[...currentData].map((item) => {\n const idv = parseInt(item[f.name]);\n return isNaN(idv) ? 0 : idv;\n })\n )\n : 0;\n insert[f.name] = currMax + 1;\n } else {\n insert[f.name] = uuid();\n }\n }\n });\n\n insert.$optimistic = true;\n\n if (logging) {\n console.log(`Optimistic create for ${queryModel}:`, insert);\n }\n return [insert, ...(Array.isArray(currentData) ? currentData : [])];\n}\n\nfunction updateMutate(\n queryModel: string,\n currentData: any,\n mutateModel: string,\n mutateArgs: any,\n modelMeta: ModelMeta,\n logging: boolean\n) {\n if (!currentData || typeof currentData !== 'object') {\n return undefined;\n }\n\n if (!mutateArgs?.where || typeof mutateArgs.where !== 'object') {\n return undefined;\n }\n\n if (!mutateArgs?.data || typeof mutateArgs.data !== 'object') {\n return undefined;\n }\n\n if (!idFieldsMatch(mutateModel, currentData, mutateArgs.where, modelMeta)) {\n return undefined;\n }\n\n const modelFields = getFields(modelMeta, queryModel);\n if (!modelFields) {\n return undefined;\n }\n\n let updated = false;\n let resultData = currentData;\n\n for (const [key, value] of Object.entries<any>(mutateArgs.data)) {\n const fieldInfo = modelFields[key];\n if (!fieldInfo) {\n continue;\n }\n\n if (fieldInfo.isDataModel && !value?.connect) {\n // relation field but without \"connect\"\n continue;\n }\n\n if (!updated) {\n // clone\n resultData = { ...currentData };\n }\n\n if (fieldInfo.isDataModel) {\n // deal with \"connect\"\n assignForeignKeyFields(fieldInfo, resultData, value);\n } else {\n resultData[key] = clone(value);\n }\n resultData.$optimistic = true;\n updated = true;\n\n if (logging) {\n console.log(`Optimistic update for ${queryModel}:`, resultData);\n }\n }\n\n return updated ? resultData : undefined;\n}\n\nfunction upsertMutate(\n queryModel: string,\n currentData: any,\n model: string,\n args: { where: object; create: any; update: any },\n modelMeta: ModelMeta,\n logging: boolean\n) {\n let updated = false;\n let resultData = currentData;\n\n if (Array.isArray(resultData)) {\n // check if we should create or update\n const foundIndex = resultData.findIndex((x) => idFieldsMatch(model, x, args.where, modelMeta));\n if (foundIndex >= 0) {\n const updateResult = updateMutate(\n queryModel,\n resultData[foundIndex],\n model,\n { where: args.where, data: args.update },\n modelMeta,\n logging\n );\n if (updateResult) {\n // replace the found item with updated item\n resultData = [...resultData.slice(0, foundIndex), updateResult, ...resultData.slice(foundIndex + 1)];\n updated = true;\n }\n } else {\n const createResult = createMutate(queryModel, resultData, args.create, modelMeta, logging);\n if (createResult) {\n resultData = createResult;\n updated = true;\n }\n }\n } else {\n // try update only\n const updateResult = updateMutate(\n queryModel,\n resultData,\n model,\n { where: args.where, data: args.update },\n modelMeta,\n logging\n );\n if (updateResult) {\n resultData = updateResult;\n updated = true;\n }\n }\n\n return updated ? resultData : undefined;\n}\n\nfunction deleteMutate(\n queryModel: string,\n currentData: any,\n mutateModel: string,\n mutateArgs: any,\n modelMeta: ModelMeta,\n logging: boolean\n) {\n // TODO: handle mutation of nested reads?\n\n if (!currentData || !mutateArgs) {\n return undefined;\n }\n\n if (queryModel !== mutateModel) {\n return undefined;\n }\n\n let updated = false;\n let result = currentData;\n\n if (Array.isArray(currentData)) {\n for (const item of currentData) {\n if (idFieldsMatch(mutateModel, item, mutateArgs, modelMeta)) {\n result = (result as unknown[]).filter((x) => x !== item);\n updated = true;\n if (logging) {\n console.log(`Optimistic delete for ${queryModel}:`, item);\n }\n }\n }\n } else {\n if (idFieldsMatch(mutateModel, currentData, mutateArgs, modelMeta)) {\n result = null;\n updated = true;\n if (logging) {\n console.log(`Optimistic delete for ${queryModel}:`, currentData);\n }\n }\n }\n\n return updated ? result : undefined;\n}\n\nfunction idFieldsMatch(model: string, x: any, y: any, modelMeta: ModelMeta) {\n if (!x || !y || typeof x !== 'object' || typeof y !== 'object') {\n return false;\n }\n const idFields = getIdFields(modelMeta, model, false);\n if (idFields.length === 0) {\n return false;\n }\n return idFields.every((f) => x[f.name] === y[f.name]);\n}\n\nfunction assignForeignKeyFields(field: FieldInfo, resultData: any, mutationData: any) {\n // convert \"connect\" like `{ connect: { id: '...' } }` to foreign key fields\n // assignment: `{ userId: '...' }`\n if (!mutationData?.connect) {\n return;\n }\n\n if (!field.foreignKeyMapping) {\n return;\n }\n\n for (const [idField, fkField] of Object.entries(field.foreignKeyMapping)) {\n if (idField in mutationData.connect) {\n resultData[fkField] = mutationData.connect[idField];\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { resolveField, type FieldInfo, type ModelMeta } from './model-meta';\n\nexport type NestedReadVisitorCallback = {\n field?: (\n model: string,\n field: FieldInfo | undefined,\n kind: 'include' | 'select' | undefined,\n args: unknown\n ) => void | boolean;\n};\n\n/**\n * Visitor for nested read payload.\n */\nexport class NestedReadVisitor {\n constructor(private readonly modelMeta: ModelMeta, private readonly callback: NestedReadVisitorCallback) {}\n\n doVisit(model: string, field: FieldInfo | undefined, kind: 'include' | 'select' | undefined, args: unknown) {\n if (this.callback.field) {\n const r = this.callback.field(model, field, kind, args);\n if (r === false) {\n return;\n }\n }\n\n if (!args || typeof args !== 'object') {\n return;\n }\n\n let selectInclude: any;\n let nextKind: 'select' | 'include' | undefined;\n if ((args as any).select) {\n selectInclude = (args as any).select;\n nextKind = 'select';\n } else if ((args as any).include) {\n selectInclude = (args as any).include;\n nextKind = 'include';\n }\n\n if (selectInclude && typeof selectInclude === 'object') {\n for (const [k, v] of Object.entries(selectInclude)) {\n if (k === '_count' && typeof v === 'object' && v) {\n // recurse into { _count: { ... } }\n this.doVisit(model, field, kind, v);\n } else {\n const field = resolveField(this.modelMeta, model, k);\n if (field) {\n this.doVisit(field.type, field, nextKind, v);\n }\n }\n }\n }\n }\n\n visit(model: string, args: unknown) {\n this.doVisit(model, undefined, undefined, args);\n }\n}\n","/**\n * Prisma write operation kinds\n */\nexport const PrismaWriteActions = [\n 'create',\n 'createMany',\n 'createManyAndReturn',\n 'connectOrCreate',\n 'update',\n 'updateMany',\n 'updateManyAndReturn',\n 'upsert',\n 'connect',\n 'disconnect',\n 'set',\n 'delete',\n 'deleteMany',\n] as const;\n\n/**\n * Prisma write operation kinds\n */\nexport type PrismaWriteActionType = (typeof PrismaWriteActions)[number];\n\n/**\n * Maybe promise\n */\nexport type MaybePromise<T> = T | Promise<T> | PromiseLike<T>;\n","import { lowerCaseFirst } from 'lower-case-first';\nimport { requireField, type ModelInfo, type ModelMeta, type TypeDefInfo } from '.';\n\n/**\n * Gets field names in a data model entity, filtering out internal fields.\n */\nexport function getModelFields(data: object) {\n return data ? Object.keys(data) : [];\n}\n\n/**\n * Array or scalar\n */\nexport type Enumerable<T> = T | Array<T>;\n\n/**\n * Uniformly enumerates an array or scalar.\n */\nexport function enumerate<T>(x: Enumerable<T>) {\n if (x === null || x === undefined) {\n return [];\n } else if (Array.isArray(x)) {\n return x;\n } else {\n return [x];\n }\n}\n\n/**\n * Zip two arrays or scalars.\n */\nexport function zip<T1, T2>(x: Enumerable<T1>, y: Enumerable<T2>): Array<[T1, T2]> {\n if (Array.isArray(x)) {\n if (!Array.isArray(y)) {\n throw new Error('x and y should be both array or both scalar');\n }\n if (x.length !== y.length) {\n throw new Error('x and y should have the same length');\n }\n return x.map((_, i) => [x[i], y[i]] as [T1, T2]);\n } else {\n if (Array.isArray(y)) {\n throw new Error('x and y should be both array or both scalar');\n }\n return [[x, y]];\n }\n}\n\n/**\n * Gets ID fields of a model.\n */\nexport function getIdFields(modelMeta: ModelMeta, model: string, throwIfNotFound = false) {\n const uniqueConstraints = modelMeta.models[lowerCaseFirst(model)]?.uniqueConstraints ?? {};\n\n const entries = Object.values(uniqueConstraints);\n if (entries.length === 0) {\n if (throwIfNotFound) {\n throw new Error(`Model ${model} does not have any id field`);\n }\n return [];\n }\n\n return entries[0].fields.map((f) => requireField(modelMeta, model, f));\n}\n\n/**\n * Gets info for a model.\n */\nexport function getModelInfo<Throw extends boolean = false>(\n modelMeta: ModelMeta,\n model: string,\n throwIfNotFound: Throw = false as Throw\n): Throw extends true ? ModelInfo : ModelInfo | undefined {\n const info = modelMeta.models[lowerCaseFirst(model)];\n if (!info && throwIfNotFound) {\n throw new Error(`Unable to load info for ${model}`);\n }\n return info;\n}\n\n/**\n * Gets info for a type def.\n */\nexport function getTypeDefInfo<Throw extends boolean = false>(\n modelMeta: ModelMeta,\n typeDef: string,\n throwIfNotFound: Throw = false as Throw\n): Throw extends true ? TypeDefInfo : TypeDefInfo | undefined {\n const info = modelMeta.typeDefs?.[lowerCaseFirst(typeDef)];\n if (!info && throwIfNotFound) {\n throw new Error(`Unable to load info for ${typeDef}`);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return info as any;\n}\n\n/**\n * Checks if a model is a delegate model.\n */\nexport function isDelegateModel(modelMeta: ModelMeta, model: string) {\n return !!getModelInfo(modelMeta, model)?.attributes?.some((attr) => attr.name === '@@delegate');\n}\n","/* eslint-disable @typescript-eslint/explicit-module-boundary-types */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { FieldInfo, ModelMeta } from './model-meta';\nimport { resolveField } from './model-meta';\nimport { MaybePromise, PrismaWriteActionType, PrismaWriteActions } from './types';\nimport { enumerate, getModelFields } from './utils';\n\ntype NestingPathItem = { field?: FieldInfo; model: string; where: any; unique: boolean };\n\n/**\n * Context for visiting\n */\nexport type NestedWriteVisitorContext = {\n /**\n * Parent data, can be used to replace fields\n */\n parent: any;\n\n /**\n * Current field, undefined if toplevel\n */\n field?: FieldInfo;\n\n /**\n * A top-down path of all nested update conditions and corresponding field till now\n */\n nestingPath: NestingPathItem[];\n};\n\n/**\n * NestedWriteVisitor's callback actions. A call back function should return true or void to indicate\n * that the visitor should continue traversing its children, or false to stop. It can also return an object\n * to let the visitor traverse it instead of its original children.\n */\nexport type NestedWriterVisitorCallback = {\n create?: (model: string, data: any, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;\n\n createMany?: (\n model: string,\n args: { data: any; skipDuplicates?: boolean },\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n connectOrCreate?: (\n model: string,\n args: { where: object; create: any },\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n connect?: (\n model: string,\n args: object,\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n disconnect?: (\n model: string,\n args: object,\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n set?: (model: string, args: object, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;\n\n update?: (model: string, args: object, context: NestedWriteVisitorContext) => MaybePromise<boolean | object | void>;\n\n updateMany?: (\n model: string,\n args: { where?: object; data: any },\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n upsert?: (\n model: string,\n args: { where: object; create: any; update: any },\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n delete?: (\n model: string,\n args: object | boolean,\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n deleteMany?: (\n model: string,\n args: any | object,\n context: NestedWriteVisitorContext\n ) => MaybePromise<boolean | object | void>;\n\n field?: (\n field: FieldInfo,\n action: PrismaWriteActionType,\n data: any,\n context: NestedWriteVisitorContext\n ) => MaybePromise<void>;\n};\n\n/**\n * Recursive visitor for nested write (create/update) payload.\n */\nexport class NestedWriteVisitor {\n constructor(private readonly modelMeta: ModelMeta, private readonly callback: NestedWriterVisitorCallback) {}\n\n private isPrismaWriteAction(value: string): value is PrismaWriteActionType {\n return PrismaWriteActions.includes(value as PrismaWriteActionType);\n }\n\n /**\n * Start visiting\n *\n * @see NestedWriterVisitorCallback\n */\n async visit(model: string, action: PrismaWriteActionType, args: any): Promise<void> {\n if (!args) {\n return;\n }\n\n let topData = args;\n\n switch (action) {\n // create has its data wrapped in 'data' field\n case 'create':\n topData = topData.data;\n break;\n\n case 'delete':\n case 'deleteMany':\n topData = topData.where;\n break;\n }\n\n await this.doVisit(model, action, topData, undefined, undefined, []);\n }\n\n private async doVisit(\n model: string,\n action: PrismaWriteActionType,\n data: any,\n parent: any,\n field: FieldInfo | undefined,\n nestingPath: NestingPathItem[]\n ): Promise<void> {\n if (!data) {\n return;\n }\n\n const toplevel = field == undefined;\n\n const context = { parent, field, nestingPath: [...nestingPath] };\n const pushNewContext = (field: FieldInfo | undefined, model: string, where: any, unique = false) => {\n return { ...context, nestingPath: [...context.nestingPath, { field, model, where, unique }] };\n };\n\n // visit payload\n switch (action) {\n case 'create':\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, {});\n let callbackResult: any;\n if (this.callback.create) {\n callbackResult = await this.callback.create(model, item, newContext);\n }\n if (callbackResult !== false) {\n const subPayload = typeof callbackResult === 'object' ? callbackResult : item;\n await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);\n }\n }\n break;\n\n case 'createMany':\n case 'createManyAndReturn':\n if (data) {\n const newContext = pushNewContext(field, model, {});\n let callbackResult: any;\n if (this.callback.createMany) {\n callbackResult = await this.callback.createMany(model, data, newContext);\n }\n if (callbackResult !== false) {\n const subPayload = typeof callbackResult === 'object' ? callbackResult : data.data;\n await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);\n }\n }\n break;\n\n case 'connectOrCreate':\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item.where);\n let callbackResult: any;\n if (this.callback.connectOrCreate) {\n callbackResult = await this.callback.connectOrCreate(model, item, newContext);\n }\n if (callbackResult !== false) {\n const subPayload = typeof callbackResult === 'object' ? callbackResult : item.create;\n await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);\n }\n }\n break;\n\n case 'connect':\n if (this.callback.connect) {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item, true);\n await this.callback.connect(model, item, newContext);\n }\n }\n break;\n\n case 'disconnect':\n // disconnect has two forms:\n // if relation is to-many, the payload is a unique filter object\n // if relation is to-one, the payload can only be boolean `true`\n if (this.callback.disconnect) {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item, typeof item === 'object');\n await this.callback.disconnect(model, item, newContext);\n }\n }\n break;\n\n case 'set':\n if (this.callback.set) {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item, true);\n await this.callback.set(model, item, newContext);\n }\n }\n break;\n\n case 'update':\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item.where);\n let callbackResult: any;\n if (this.callback.update) {\n callbackResult = await this.callback.update(model, item, newContext);\n }\n if (callbackResult !== false) {\n const subPayload =\n typeof callbackResult === 'object'\n ? callbackResult\n : typeof item.data === 'object'\n ? item.data\n : item;\n await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);\n }\n }\n break;\n\n case 'updateMany':\n case 'updateManyAndReturn':\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item.where);\n let callbackResult: any;\n if (this.callback.updateMany) {\n callbackResult = await this.callback.updateMany(model, item, newContext);\n }\n if (callbackResult !== false) {\n const subPayload = typeof callbackResult === 'object' ? callbackResult : item;\n await this.visitSubPayload(model, action, subPayload, newContext.nestingPath);\n }\n }\n break;\n\n case 'upsert': {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, item.where);\n let callbackResult: any;\n if (this.callback.upsert) {\n callbackResult = await this.callback.upsert(model, item, newContext);\n }\n if (callbackResult !== false) {\n if (typeof callbackResult === 'object') {\n await this.visitSubPayload(model, action, callbackResult, newContext.nestingPath);\n } else {\n await this.visitSubPayload(model, action, item.create, newContext.nestingPath);\n await this.visitSubPayload(model, action, item.update, newContext.nestingPath);\n }\n }\n }\n break;\n }\n\n case 'delete': {\n if (this.callback.delete) {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, toplevel ? item.where : item);\n await this.callback.delete(model, item, newContext);\n }\n }\n break;\n }\n\n case 'deleteMany':\n if (this.callback.deleteMany) {\n for (const item of this.enumerateReverse(data)) {\n const newContext = pushNewContext(field, model, toplevel ? item.where : item);\n await this.callback.deleteMany(model, item, newContext);\n }\n }\n break;\n\n default: {\n throw new Error(`unhandled action type ${action}`);\n }\n }\n }\n\n private async visitSubPayload(\n model: string,\n action: PrismaWriteActionType,\n payload: any,\n nestingPath: NestingPathItem[]\n ) {\n for (const item of enumerate(payload)) {\n for (const field of getModelFields(item)) {\n const fieldInfo = resolveField(this.modelMeta, model, field);\n if (!fieldInfo) {\n continue;\n }\n\n if (fieldInfo.isDataModel) {\n if (item[field]) {\n // recurse into nested payloads\n for (const [subAction, subData] of Object.entries<any>(item[field])) {\n if (this.isPrismaWriteAction(subAction) && subData) {\n await this.doVisit(fieldInfo.type, subAction, subData, item[field], fieldInfo, [\n ...nestingPath,\n ]);\n }\n }\n }\n } else {\n // visit plain field\n if (this.callback.field) {\n await this.callback.field(fieldInfo, action, item[field], {\n parent: item,\n nestingPath,\n field: fieldInfo,\n });\n }\n }\n }\n }\n }\n\n // enumerate a (possible) array in reverse order, so that the enumeration\n // callback can safely delete the current item\n private *enumerateReverse(data: any) {\n if (Array.isArray(data)) {\n for (let i = data.length - 1; i >= 0; i--) {\n yield data[i];\n }\n } else {\n yield data;\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { lowerCaseFirst } from 'lower-case-first';\nimport type { ModelMeta } from './model-meta';\nimport { NestedReadVisitor } from './nested-read-visitor';\nimport { NestedWriteVisitor } from './nested-write-visitor';\nimport type { PrismaWriteActionType } from './types';\nimport { getModelInfo } from './utils';\n\n/**\n * Gets models read (including nested ones) given a query args.\n * @param model\n * @param targetModels\n * @param modelMeta\n * @param args\n * @returns\n */\nexport function getReadModels(model: string, modelMeta: ModelMeta, args: any) {\n const result = new Set<string>();\n result.add(model);\n const visitor = new NestedReadVisitor(modelMeta, {\n field: (model) => {\n result.add(model);\n return true;\n },\n });\n visitor.visit(model, args);\n return [...result];\n}\n\n/**\n * Gets mutated models (including nested ones) given a mutation args.\n */\nexport async function getMutatedModels(\n model: string,\n operation: PrismaWriteActionType,\n mutationArgs: any,\n modelMeta: ModelMeta\n) {\n const result = new Set<string>();\n result.add(model);\n\n if (mutationArgs) {\n const addModel = (model: string) => void result.add(model);\n\n // add models that are cascaded deleted recursively\n const addCascades = (model: string) => {\n const cascades = new Set<string>();\n const visited = new Set<string>();\n collectDeleteCascades(model, modelMeta, cascades, visited);\n cascades.forEach((m) => addModel(m));\n };\n\n const visitor = new NestedWriteVisitor(modelMeta, {\n create: addModel,\n createMany: addModel,\n connectOrCreate: addModel,\n connect: addModel,\n disconnect: addModel,\n set: addModel,\n update: addModel,\n updateMany: addModel,\n upsert: addModel,\n delete: (model) => {\n addModel(model);\n addCascades(model);\n },\n deleteMany: (model) => {\n addModel(model);\n addCascades(model);\n },\n });\n await visitor.visit(model, operation, mutationArgs);\n }\n\n // include delegate base models recursively\n result.forEach((m) => {\n getBaseRecursively(m, modelMeta, result);\n });\n\n return [...result];\n}\n\nfunction collectDeleteCascades(model: string, modelMeta: ModelMeta, result: Set<string>, visited: Set<string>) {\n if (visited.has(model)) {\n // break circle\n return;\n }\n visited.add(model);\n\n const cascades = modelMeta.deleteCascade?.[lowerCaseFirst(model)];\n\n if (!cascades) {\n return;\n }\n\n cascades.forEach((m) => {\n result.add(m);\n collectDeleteCascades(m, modelMeta, result, visited);\n });\n}\n\nfunction getBaseRecursively(model: string, modelMeta: ModelMeta, result: Set<string>) {\n const bases = getModelInfo(modelMeta, model)?.baseTypes;\n if (bases) {\n bases.forEach((base) => {\n result.add(base);\n getBaseRecursively(base, modelMeta, result);\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,qBAAqB;AAKvB,SAAS,MAAS,OAAa;AAClC,MAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,WAAO,MAAM,IAAI,CAAC,MAAM,MAAM,CAAC,CAAC;AAAA,EACpC;AAEA,MAAI,OAAO,UAAU,UAAU;AAC3B,QAAI,CAAC,SAAS,CAAC,cAAc,KAAK,GAAG;AACjC,aAAO;AAAA,IACX;AAGA,UAAM,SAAc,CAAC;AACrB,eAAW,OAAO,OAAO,KAAK,KAAK,GAAG;AAClC,aAAO,GAAG,IAAI,MAAM,MAAM,GAAc,CAAC;AAAA,IAC7C;AACA,WAAO;AAAA,EACX;AAEA,SAAO;AACX;;;ACZO,IAAM,mBAAN,MAAuB;AAAA,EAC1B,YAAoB,WAAsB;AAAtB;AAAA,EAAuB;AAAA;AAAA;AAAA;AAAA,EAK3C,MAAM,OAAe,MAAW,UAAoC;AAChE,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACnC;AAAA,IACJ;AAEA,UAAM,aAAsC,CAAC;AAC7C,UAAM,WAAgD,CAAC;AAEvD,eAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,GAAG;AACvC,YAAM,QAAQ,aAAa,KAAK,WAAW,OAAO,CAAC;AACnD,UAAI,SAAS,MAAM,aAAa;AAC5B,YAAI,MAAM,WAAW,MAAM,QAAQ,CAAC,GAAG;AACnC,mBAAS,KAAK,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,MAAM,MAAM,MAAM,KAAK,EAAE,CAAC;AAAA,QACzE,OAAO;AACH,mBAAS,KAAK,EAAE,OAAO,MAAM,MAAM,MAAM,EAAE,CAAC;AAAA,QAChD;AAAA,MACJ,OAAO;AACH,mBAAW,CAAC,IAAI;AAAA,MACpB;AAAA,IACJ;AAEA,aAAS,OAAO,MAAM,UAAU;AAChC,aAAS,QAAQ,CAAC,EAAE,OAAAA,QAAO,MAAAC,MAAK,MAAM,KAAK,MAAMD,QAAOC,OAAM,QAAQ,CAAC;AAAA,EAC3E;AACJ;;;AC1CA,SAAS,sBAAsB;AAoNxB,SAAS,aACZ,WACA,gBACA,OACA,YAAY,OACS;AAzNzB;AA0NI,QAAM,YAAY,YAAY,UAAU,WAAW,UAAU;AAC7D,UAAO,kDAAY,eAAe,cAAc,OAAzC,mBAA6C,WAA7C,mBAAsD;AACjE;AAKO,SAAS,aAAa,WAAsB,OAAe,OAAe,YAAY,OAAO;AAChG,QAAM,IAAI,aAAa,WAAW,OAAO,OAAO,SAAS;AACzD,MAAI,CAAC,GAAG;AACJ,UAAM,IAAI,MAAM,SAAS,KAAK,IAAI,KAAK,qBAAqB;AAAA,EAChE;AACA,SAAO;AACX;AAKO,SAAS,UAAU,WAAsB,OAAe;AA5O/D;AA6OI,UAAO,eAAU,OAAO,eAAe,KAAK,CAAC,MAAtC,mBAAyC;AACpD;AAKO,SAAS,qBAAqB,WAAsB,OAAe;AAnP1E;AAoPI,UAAO,eAAU,OAAO,eAAe,KAAK,CAAC,MAAtC,mBAAyC;AACpD;;;ACpPA,SAAS,MAAM,YAAY;AAyB3B,SAAsB,cAClB,YACA,SACA,WACA,eACA,YACA,cACA,WACA,SACF;AAAA;AACE,QAAI,CAAC,aAAc,OAAO,cAAc,YAAY,CAAC,MAAM,QAAQ,SAAS,GAAI;AAC5E,aAAO;AAAA,IACX;AAEA,QAAI,CAAC,QAAQ,WAAW,MAAM,GAAG;AAE7B,aAAO;AAAA,IACX;AAEA,WAAO,MAAM,gBAAgB,YAAY,WAAW,eAAe,YAAY,cAAc,WAAW,OAAO;AAAA,EACnH;AAAA;AAEA,SAAe,gBACX,YACA,WACA,eACA,YACA,cACA,WACA,SACF;AAAA;AACE,QAAI,aAAa;AACjB,QAAI,UAAU;AAEd,UAAM,UAAU,IAAI,mBAAmB,WAAW;AAAA,MAC9C,QAAQ,CAAC,OAAO,SAAS;AACrB,YACI,UAAU,cACV,MAAM,QAAQ,UAAU,GAC1B;AACE,gBAAM,IAAI,aAAa,YAAY,YAAY,MAAM,WAAW,OAAO;AACvE,cAAI,GAAG;AACH,yBAAa;AACb,sBAAU;AAAA,UACd;AAAA,QACJ;AAAA,MACJ;AAAA,MAEA,YAAY,CAAC,OAAO,SAAS;AACzB,YACI,UAAU,eACV,6BAAM,SACN,MAAM,QAAQ,UAAU,GAC1B;AACE,qBAAW,UAAU,UAAU,KAAK,IAAI,GAAG;AACvC,kBAAM,IAAI,aAAa,YAAY,YAAY,QAAQ,WAAW,OAAO;AACzE,gBAAI,GAAG;AACH,2BAAa;AACb,wBAAU;AAAA,YACd;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,MAEA,QAAQ,CAAC,OAAO,SAAS;AACrB,YACI,UAAU,cACV,CAAC,MAAM,QAAQ,UAAU,GAC3B;AACE,gBAAM,IAAI,aAAa,YAAY,YAAY,OAAO,MAAM,WAAW,OAAO;AAC9E,cAAI,GAAG;AACH,yBAAa;AACb,sBAAU;AAAA,UACd;AAAA,QACJ;AAAA,MACJ;AAAA,MAEA,QAAQ,CAAC,OAAO,SAAS;AACrB,YAAI,UAAU,eAAc,6BAAM,WAAS,6BAAM,YAAU,6BAAM,SAAQ;AACrE,gBAAM,IAAI,aAAa,YAAY,YAAY,OAAO,MAAM,WAAW,OAAO;AAC9E,cAAI,GAAG;AACH,yBAAa;AACb,sBAAU;AAAA,UACd;AAAA,QACJ;AAAA,MACJ;AAAA,MAEA,QAAQ,CAAC,OAAO,SAAS;AACrB,YAAI,UAAU,YAAY;AACtB,gBAAM,IAAI,aAAa,YAAY,YAAY,OAAO,MAAM,WAAW,OAAO;AAC9E,cAAI,GAAG;AACH,yBAAa;AACb,sBAAU;AAAA,UACd;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,CAAC;AAED,UAAM,QAAQ,MAAM,eAAe,YAAY,YAAY;AAE3D,UAAM,cAAc,UAAU,WAAW,UAAU;AAEnD,QAAI,MAAM,QAAQ,UAAU,GAAG;AAI3B,UAAI,cAAc;AAClB,eAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AACxC,cAAM,OAAO,WAAW,CAAC;AACzB,YACI,CAAC,QACD,OAAO,SAAS,YAChB,KAAK,aACP;AACE;AAAA,QACJ;AAEA,cAAM,IAAI,MAAM;AAAA,UACZ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACJ;AAEA,YAAI,KAAK,OAAO,MAAM,UAAU;AAC5B,cAAI,CAAC,aAAa;AACd,yBAAa,CAAC,GAAG,UAAU;AAC3B,0BAAc;AAAA,UAClB;AACA,qBAAW,CAAC,IAAI;AAChB,oBAAU;AAAA,QACd;AAAA,MACJ;AAAA,IACJ,WAAW,eAAe,QAAQ,OAAO,eAAe,UAAU;AAE9D,YAAM,cAAc,mBAAK;AAGzB,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,WAAW,GAAG;AACpD,cAAM,YAAY,YAAY,GAAG;AACjC,YAAI,EAAC,uCAAW,cAAa;AACzB;AAAA,QACJ;AAEA,cAAM,IAAI,MAAM;AAAA,UACZ,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACJ;AAEA,YAAI,KAAK,OAAO,MAAM,UAAU;AAC5B,uBAAa,iCAAK,aAAL,EAAiB,CAAC,GAAG,GAAG,EAAE;AACvC,oBAAU;AAAA,QACd;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO,UAAU,aAAa;AAAA,EAClC;AAAA;AAEA,SAAS,aAAa,YAAoB,aAAkB,SAAc,WAAsB,SAAkB;AAC9G,MAAI,CAAC,SAAS;AACV,WAAO;AAAA,EACX;AAEA,QAAM,cAAc,UAAU,WAAW,UAAU;AACnD,MAAI,CAAC,aAAa;AACd,WAAO;AAAA,EACX;AAEA,QAAM,SAAc,CAAC;AACrB,QAAM,gBAAgB,OAAO,KAAK,OAAO;AAEzC,SAAO,QAAQ,WAAW,EAAE,QAAQ,CAAC,CAAC,MAAM,KAAK,MAAM;AA9M3D;AA+MQ,QAAI,MAAM,eAAe,QAAQ,IAAI,GAAG;AAEpC,6BAAuB,OAAO,QAAQ,QAAQ,IAAI,CAAC;AACnD;AAAA,IACJ;AAEA,QAAI,cAAc,SAAS,IAAI,GAAG;AAC9B,aAAO,IAAI,IAAI,MAAM,QAAQ,IAAI,CAAC;AAAA,IACtC,OAAO;AACH,YAAM,eAAc,WAAM,eAAN,mBAAkB,KAAK,CAAC,SAAS,KAAK,SAAS;AACnE,UAAI,MAAM,SAAS,YAAY;AAE3B,YAAI,iBAAe,WAAM,eAAN,mBAAkB,KAAK,CAAC,SAAS,KAAK,SAAS,gBAAe;AAC7E,iBAAO,IAAI,IAAI,oBAAI,KAAK;AAAA,QAC5B;AAAA,MACJ,aAAW,sDAAa,SAAb,mBAAoB,OAApB,mBAAwB,WAAU,QAAW;AAEpD,eAAO,IAAI,IAAI,YAAY,KAAK,CAAC,EAAE;AAAA,MACvC;AAAA,IACJ;AAAA,EACJ,CAAC;AAGD,QAAM,WAAW,YAAY,WAAW,YAAY,KAAK;AACzD,WAAS,QAAQ,CAAC,MAAM;AACpB,QAAI,OAAO,EAAE,IAAI,MAAM,QAAW;AAC9B,UAAI,EAAE,SAAS,SAAS,EAAE,SAAS,UAAU;AACzC,cAAM,UAAU,MAAM,QAAQ,WAAW,IACnC,KAAK;AAAA,UACD,GAAG,CAAC,GAAG,WAAW,EAAE,IAAI,CAAC,SAAS;AAC9B,kBAAM,MAAM,SAAS,KAAK,EAAE,IAAI,CAAC;AACjC,mBAAO,MAAM,GAAG,IAAI,IAAI;AAAA,UAC5B,CAAC;AAAA,QACL,IACA;AACN,eAAO,EAAE,IAAI,IAAI,UAAU;AAAA,MAC/B,OAAO;AACH,eAAO,EAAE,IAAI,IAAI,KAAK;AAAA,MAC1B;AAAA,IACJ;AAAA,EACJ,CAAC;AAED,SAAO,cAAc;AAErB,MAAI,SAAS;AACT,YAAQ,IAAI,yBAAyB,UAAU,KAAK,MAAM;AAAA,EAC9D;AACA,SAAO,CAAC,QAAQ,GAAI,MAAM,QAAQ,WAAW,IAAI,cAAc,CAAC,CAAE;AACtE;AAEA,SAAS,aACL,YACA,aACA,aACA,YACA,WACA,SACF;AACE,MAAI,CAAC,eAAe,OAAO,gBAAgB,UAAU;AACjD,WAAO;AAAA,EACX;AAEA,MAAI,EAAC,yCAAY,UAAS,OAAO,WAAW,UAAU,UAAU;AAC5D,WAAO;AAAA,EACX;AAEA,MAAI,EAAC,yCAAY,SAAQ,OAAO,WAAW,SAAS,UAAU;AAC1D,WAAO;AAAA,EACX;AAEA,MAAI,CAAC,cAAc,aAAa,aAAa,WAAW,OAAO,SAAS,GAAG;AACvE,WAAO;AAAA,EACX;AAEA,QAAM,cAAc,UAAU,WAAW,UAAU;AACnD,MAAI,CAAC,aAAa;AACd,WAAO;AAAA,EACX;AAEA,MAAI,UAAU;AACd,MAAI,aAAa;AAEjB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAa,WAAW,IAAI,GAAG;AAC7D,UAAM,YAAY,YAAY,GAAG;AACjC,QAAI,CAAC,WAAW;AACZ;AAAA,IACJ;AAEA,QAAI,UAAU,eAAe,EAAC,+BAAO,UAAS;AAE1C;AAAA,IACJ;AAEA,QAAI,CAAC,SAAS;AAEV,mBAAa,mBAAK;AAAA,IACtB;AAEA,QAAI,UAAU,aAAa;AAEvB,6BAAuB,WAAW,YAAY,KAAK;AAAA,IACvD,OAAO;AACH,iBAAW,GAAG,IAAI,MAAM,KAAK;AAAA,IACjC;AACA,eAAW,cAAc;AACzB,cAAU;AAEV,QAAI,SAAS;AACT,cAAQ,IAAI,yBAAyB,UAAU,KAAK,UAAU;AAAA,IAClE;AAAA,EACJ;AAEA,SAAO,UAAU,aAAa;AAClC;AAEA,SAAS,aACL,YACA,aACA,OACA,MACA,WACA,SACF;AACE,MAAI,UAAU;AACd,MAAI,aAAa;AAEjB,MAAI,MAAM,QAAQ,UAAU,GAAG;AAE3B,UAAM,aAAa,WAAW,UAAU,CAAC,MAAM,cAAc,OAAO,GAAG,KAAK,OAAO,SAAS,CAAC;AAC7F,QAAI,cAAc,GAAG;AACjB,YAAM,eAAe;AAAA,QACjB;AAAA,QACA,WAAW,UAAU;AAAA,QACrB;AAAA,QACA,EAAE,OAAO,KAAK,OAAO,MAAM,KAAK,OAAO;AAAA,QACvC;AAAA,QACA;AAAA,MACJ;AACA,UAAI,cAAc;AAEd,qBAAa,CAAC,GAAG,WAAW,MAAM,GAAG,UAAU,GAAG,cAAc,GAAG,WAAW,MAAM,aAAa,CAAC,CAAC;AACnG,kBAAU;AAAA,MACd;AAAA,IACJ,OAAO;AACH,YAAM,eAAe,aAAa,YAAY,YAAY,KAAK,QAAQ,WAAW,OAAO;AACzF,UAAI,cAAc;AACd,qBAAa;AACb,kBAAU;AAAA,MACd;AAAA,IACJ;AAAA,EACJ,OAAO;AAEH,UAAM,eAAe;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA,EAAE,OAAO,KAAK,OAAO,MAAM,KAAK,OAAO;AAAA,MACvC;AAAA,MACA;AAAA,IACJ;AACA,QAAI,cAAc;AACd,mBAAa;AACb,gBAAU;AAAA,IACd;AAAA,EACJ;AAEA,SAAO,UAAU,aAAa;AAClC;AAEA,SAAS,aACL,YACA,aACA,aACA,YACA,WACA,SACF;AAGE,MAAI,CAAC,eAAe,CAAC,YAAY;AAC7B,WAAO;AAAA,EACX;AAEA,MAAI,eAAe,aAAa;AAC5B,WAAO;AAAA,EACX;AAEA,MAAI,UAAU;AACd,MAAI,SAAS;AAEb,MAAI,MAAM,QAAQ,WAAW,GAAG;AAC5B,eAAW,QAAQ,aAAa;AAC5B,UAAI,cAAc,aAAa,MAAM,YAAY,SAAS,GAAG;AACzD,iBAAU,OAAqB,OAAO,CAAC,MAAM,MAAM,IAAI;AACvD,kBAAU;AACV,YAAI,SAAS;AACT,kBAAQ,IAAI,yBAAyB,UAAU,KAAK,IAAI;AAAA,QAC5D;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,OAAO;AACH,QAAI,cAAc,aAAa,aAAa,YAAY,SAAS,GAAG;AAChE,eAAS;AACT,gBAAU;AACV,UAAI,SAAS;AACT,gBAAQ,IAAI,yBAAyB,UAAU,KAAK,WAAW;AAAA,MACnE;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO,UAAU,SAAS;AAC9B;AAEA,SAAS,cAAc,OAAe,GAAQ,GAAQ,WAAsB;AACxE,MAAI,CAAC,KAAK,CAAC,KAAK,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AAC5D,WAAO;AAAA,EACX;AACA,QAAM,WAAW,YAAY,WAAW,OAAO,KAAK;AACpD,MAAI,SAAS,WAAW,GAAG;AACvB,WAAO;AAAA,EACX;AACA,SAAO,SAAS,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,MAAM,EAAE,EAAE,IAAI,CAAC;AACxD;AAEA,SAAS,uBAAuB,OAAkB,YAAiB,cAAmB;AAGlF,MAAI,EAAC,6CAAc,UAAS;AACxB;AAAA,EACJ;AAEA,MAAI,CAAC,MAAM,mBAAmB;AAC1B;AAAA,EACJ;AAEA,aAAW,CAAC,SAAS,OAAO,KAAK,OAAO,QAAQ,MAAM,iBAAiB,GAAG;AACtE,QAAI,WAAW,aAAa,SAAS;AACjC,iBAAW,OAAO,IAAI,aAAa,QAAQ,OAAO;AAAA,IACtD;AAAA,EACJ;AACJ;;;AC/aO,IAAM,oBAAN,MAAwB;AAAA,EAC3B,YAA6B,WAAuC,UAAqC;AAA5E;AAAuC;AAAA,EAAsC;AAAA,EAE1G,QAAQ,OAAe,OAA8B,MAAwC,MAAe;AACxG,QAAI,KAAK,SAAS,OAAO;AACrB,YAAM,IAAI,KAAK,SAAS,MAAM,OAAO,OAAO,MAAM,IAAI;AACtD,UAAI,MAAM,OAAO;AACb;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACnC;AAAA,IACJ;AAEA,QAAI;AACJ,QAAI;AACJ,QAAK,KAAa,QAAQ;AACtB,sBAAiB,KAAa;AAC9B,iBAAW;AAAA,IACf,WAAY,KAAa,SAAS;AAC9B,sBAAiB,KAAa;AAC9B,iBAAW;AAAA,IACf;AAEA,QAAI,iBAAiB,OAAO,kBAAkB,UAAU;AACpD,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,aAAa,GAAG;AAChD,YAAI,MAAM,YAAY,OAAO,MAAM,YAAY,GAAG;AAE9C,eAAK,QAAQ,OAAO,OAAO,MAAM,CAAC;AAAA,QACtC,OAAO;AACH,gBAAMC,SAAQ,aAAa,KAAK,WAAW,OAAO,CAAC;AACnD,cAAIA,QAAO;AACP,iBAAK,QAAQA,OAAM,MAAMA,QAAO,UAAU,CAAC;AAAA,UAC/C;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,MAAM,OAAe,MAAe;AAChC,SAAK,QAAQ,OAAO,QAAW,QAAW,IAAI;AAAA,EAClD;AACJ;;;ACxDO,IAAM,qBAAqB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;;;ACjBA,SAAS,kBAAAC,uBAAsB;AAMxB,SAAS,eAAe,MAAc;AACzC,SAAO,OAAO,OAAO,KAAK,IAAI,IAAI,CAAC;AACvC;AAUO,SAAS,UAAa,GAAkB;AAC3C,MAAI,MAAM,QAAQ,MAAM,QAAW;AAC/B,WAAO,CAAC;AAAA,EACZ,WAAW,MAAM,QAAQ,CAAC,GAAG;AACzB,WAAO;AAAA,EACX,OAAO;AACH,WAAO,CAAC,CAAC;AAAA,EACb;AACJ;AAKO,SAAS,IAAY,GAAmB,GAAoC;AAC/E,MAAI,MAAM,QAAQ,CAAC,GAAG;AAClB,QAAI,CAAC,MAAM,QAAQ,CAAC,GAAG;AACnB,YAAM,IAAI,MAAM,6CAA6C;AAAA,IACjE;AACA,QAAI,EAAE,WAAW,EAAE,QAAQ;AACvB,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACzD;AACA,WAAO,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAa;AAAA,EACnD,OAAO;AACH,QAAI,MAAM,QAAQ,CAAC,GAAG;AAClB,YAAM,IAAI,MAAM,6CAA6C;AAAA,IACjE;AACA,WAAO,CAAC,CAAC,GAAG,CAAC,CAAC;AAAA,EAClB;AACJ;AAKO,SAAS,YAAY,WAAsB,OAAe,kBAAkB,OAAO;AAnD1F;AAoDI,QAAM,qBAAoB,qBAAU,OAAOC,gBAAe,KAAK,CAAC,MAAtC,mBAAyC,sBAAzC,YAA8D,CAAC;AAEzF,QAAM,UAAU,OAAO,OAAO,iBAAiB;AAC/C,MAAI,QAAQ,WAAW,GAAG;AACtB,QAAI,iBAAiB;AACjB,YAAM,IAAI,MAAM,SAAS,KAAK,6BAA6B;AAAA,IAC/D;AACA,WAAO,CAAC;AAAA,EACZ;AAEA,SAAO,QAAQ,CAAC,EAAE,OAAO,IAAI,CAAC,MAAM,aAAa,WAAW,OAAO,CAAC,CAAC;AACzE;AAKO,SAAS,aACZ,WACA,OACA,kBAAyB,OAC6B;AACtD,QAAM,OAAO,UAAU,OAAOA,gBAAe,KAAK,CAAC;AACnD,MAAI,CAAC,QAAQ,iBAAiB;AAC1B,UAAM,IAAI,MAAM,2BAA2B,KAAK,EAAE;AAAA,EACtD;AACA,SAAO;AACX;AAKO,SAAS,eACZ,WACA,SACA,kBAAyB,OACiC;AAvF9D;AAwFI,QAAM,QAAO,eAAU,aAAV,mBAAqBA,gBAAe,OAAO;AACxD,MAAI,CAAC,QAAQ,iBAAiB;AAC1B,UAAM,IAAI,MAAM,2BAA2B,OAAO,EAAE;AAAA,EACxD;AAEA,SAAO;AACX;AAKO,SAAS,gBAAgB,WAAsB,OAAe;AAnGrE;AAoGI,SAAO,CAAC,GAAC,wBAAa,WAAW,KAAK,MAA7B,mBAAgC,eAAhC,mBAA4C,KAAK,CAAC,SAAS,KAAK,SAAS;AACtF;;;ACAO,IAAM,qBAAN,MAAyB;AAAA,EAC5B,YAA6B,WAAuC,UAAuC;AAA9E;AAAuC;AAAA,EAAwC;AAAA,EAEpG,oBAAoB,OAA+C;AACvE,WAAO,mBAAmB,SAAS,KAA8B;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOM,MAAM,OAAe,QAA+B,MAA0B;AAAA;AAChF,UAAI,CAAC,MAAM;AACP;AAAA,MACJ;AAEA,UAAI,UAAU;AAEd,cAAQ,QAAQ;AAAA,QAEZ,KAAK;AACD,oBAAU,QAAQ;AAClB;AAAA,QAEJ,KAAK;AAAA,QACL,KAAK;AACD,oBAAU,QAAQ;AAClB;AAAA,MACR;AAEA,YAAM,KAAK,QAAQ,OAAO,QAAQ,SAAS,QAAW,QAAW,CAAC,CAAC;AAAA,IACvE;AAAA;AAAA,EAEc,QACV,OACA,QACA,MACA,QACA,OACA,aACa;AAAA;AACb,UAAI,CAAC,MAAM;AACP;AAAA,MACJ;AAEA,YAAM,WAAW,SAAS;AAE1B,YAAM,UAAU,EAAE,QAAQ,OAAO,aAAa,CAAC,GAAG,WAAW,EAAE;AAC/D,YAAM,iBAAiB,CAACC,QAA8BC,QAAe,OAAY,SAAS,UAAU;AAChG,eAAO,iCAAK,UAAL,EAAc,aAAa,CAAC,GAAG,QAAQ,aAAa,EAAE,OAAAD,QAAO,OAAAC,QAAO,OAAO,OAAO,CAAC,EAAE;AAAA,MAChG;AAGA,cAAQ,QAAQ;AAAA,QACZ,KAAK;AACD,qBAAW,QAAQ,KAAK,iBAAiB,IAAI,GAAG;AAC5C,kBAAM,aAAa,eAAe,OAAO,OAAO,CAAC,CAAC;AAClD,gBAAI;AACJ,gBAAI,KAAK,SAAS,QAAQ;AACtB,+BAAiB,MAAM,KAAK,SAAS,OAAO,OAAO,MAAM,UAAU;AAAA,YACvE;AACA,gBAAI,mBAAmB,OAAO;AAC1B,oBAAM,aAAa,OAAO,mBAAmB,WAAW,iBAAiB;AACzE,oBAAM,KAAK,gBAAgB,OAAO,QAAQ,YAAY,WAAW,WAAW;AAAA,YAChF;AAAA,UACJ;AACA;AAAA,QAEJ,KAAK;AAAA,QACL,KAAK;AACD,cAAI,MAAM;AACN,kBAAM,aAAa,eAAe,OAAO,OAAO,CAAC,CAAC;AAClD,gBAAI;AACJ,gBAAI,KAAK,SAAS,YAAY;AAC1B,+BAAiB,MAAM,KAAK,SAAS,WAAW,OAAO,MAAM,UAAU;AAAA,YAC3E;AACA,gBAAI,mBAAmB,OAAO;AAC1B,oBAAM,aAAa,OAAO,mBAAmB,WAAW,iBAAiB,KAAK;AAC9E,oBAAM,KAAK,gBAAgB,OAAO,QAAQ,YAAY,WAAW,WAAW;AAAA,YAChF;AAAA,UACJ;AACA;AAAA,QAEJ,KAAK;AACD,qBAAW,QAAQ,KAAK,iBAAiB,IAAI,GAAG;AAC5C,kBAAM,aAAa,eAAe,OAAO,OAAO,KAAK,KAAK;AAC1D,gBAAI;AACJ,gBAAI,KAAK,SAAS,iBAAiB;AAC/B,+BAAiB,MAAM,KAAK,SAAS,gBAAgB,OAAO,MAAM,UAAU;AAAA,YAChF;AACA,gBAAI,mBAAmB,OAAO;AAC1B,oBAAM,aAAa,OAAO,mBAAmB,WAAW,iBAAiB,KAAK;AAC9E,oBAAM,KAAK,gBAAgB,OAAO,QAAQ,YAAY,WAAW,WAAW;AAAA,YAChF;AAAA,UACJ;AACA;AAAA,QAEJ,KAAK;AACD,cAAI,KAAK,SAAS,SAAS;AACvB,uBAAW,QAAQ,KAAK,iBAAiB,IAAI,GAAG;AAC5C,oBAAM,aAAa,eAAe,OAAO,OAAO,MAAM,IAAI;AAC1D,oBAAM,KAAK,SAAS,QAAQ,OAAO,MAAM,UAAU;AAAA,YACvD;AAAA,UACJ;AACA;AAAA,QAEJ,KAAK;AAID,cAAI,KAAK,SAAS,YAAY;AAC1B,uBAAW,QAAQ,KAAK,iBAAiB,IAAI,GAAG;AAC5C,oBAAM,aAAa,eAAe,OAAO,OAAO,MAAM,OAAO,SAAS,QAAQ;AAC9E,oBAAM,KAAK,SAAS,WAAW,OAAO,MAAM,UAAU;AAAA,YAC1D;AAAA,UACJ;AACA;AAAA,QAEJ,KAAK;AACD,cAAI,KAAK,SAAS,KAAK;AACnB,uBAAW,QAAQ,KAAK,iBAAiB,IAAI,GAAG;AAC5C,oBAAM,aAAa,eAAe,OAAO,OAAO,MAAM,IAAI;AAC1D,oBAAM,KAAK,SAAS,IAAI,OAAO,MAAM,UAAU;AAAA,YACnD;AAAA,UACJ;AACA;AAAA,QAEJ,KAAK;AACD,qBAAW,QAAQ,KAAK,iBAAiB,IAAI,GAAG;AAC5C,kBAAM,aAAa,eAAe,OAAO,OAAO,KAAK,KAAK;AAC1D,gBAAI;AACJ,gBAAI,KAAK,SAAS,QAAQ;AACtB,+BAAiB,MAAM,KAAK,SAAS,OAAO,OAAO,MAAM,UAAU;AAAA,YACvE;AACA,gBAAI,mBAAmB,OAAO;AAC1B,oBAAM,aACF,OAAO,mBAAmB,WACpB,iBACA,OAAO,KAAK,SAAS,WACrB,KAAK,OACL;AACV,oBAAM,KAAK,gBAAgB,OAAO,QAAQ,YAAY,WAAW,WAAW;AAAA,YAChF;AAAA,UACJ;AACA;AAAA,QAEJ,KAAK;AAAA,QACL,KAAK;AACD,qBAAW,QAAQ,KAAK,iBAAiB,IAAI,GAAG;AAC5C,kBAAM,aAAa,eAAe,OAAO,OAAO,KAAK,KAAK;AAC1D,gBAAI;AACJ,gBAAI,KAAK,SAAS,YAAY;AAC1B,+BAAiB,MAAM,KAAK,SAAS,WAAW,OAAO,MAAM,UAAU;AAAA,YAC3E;AACA,gBAAI,mBAAmB,OAAO;AAC1B,oBAAM,aAAa,OAAO,mBAAmB,WAAW,iBAAiB;AACzE,oBAAM,KAAK,gBAAgB,OAAO,QAAQ,YAAY,WAAW,WAAW;AAAA,YAChF;AAAA,UACJ;AACA;AAAA,QAEJ,KAAK,UAAU;AACX,qBAAW,QAAQ,KAAK,iBAAiB,IAAI,GAAG;AAC5C,kBAAM,aAAa,eAAe,OAAO,OAAO,KAAK,KAAK;AAC1D,gBAAI;AACJ,gBAAI,KAAK,SAAS,QAAQ;AACtB,+BAAiB,MAAM,KAAK,SAAS,OAAO,OAAO,MAAM,UAAU;AAAA,YACvE;AACA,gBAAI,mBAAmB,OAAO;AAC1B,kBAAI,OAAO,mBAAmB,UAAU;AACpC,sBAAM,KAAK,gBAAgB,OAAO,QAAQ,gBAAgB,WAAW,WAAW;AAAA,cACpF,OAAO;AACH,sBAAM,KAAK,gBAAgB,OAAO,QAAQ,KAAK,QAAQ,WAAW,WAAW;AAC7E,sBAAM,KAAK,gBAAgB,OAAO,QAAQ,KAAK,QAAQ,WAAW,WAAW;AAAA,cACjF;AAAA,YACJ;AAAA,UACJ;AACA;AAAA,QACJ;AAAA,QAEA,KAAK,UAAU;AACX,cAAI,KAAK,SAAS,QAAQ;AACtB,uBAAW,QAAQ,KAAK,iBAAiB,IAAI,GAAG;AAC5C,oBAAM,aAAa,eAAe,OAAO,OAAO,WAAW,KAAK,QAAQ,IAAI;AAC5E,oBAAM,KAAK,SAAS,OAAO,OAAO,MAAM,UAAU;AAAA,YACtD;AAAA,UACJ;AACA;AAAA,QACJ;AAAA,QAEA,KAAK;AACD,cAAI,KAAK,SAAS,YAAY;AAC1B,uBAAW,QAAQ,KAAK,iBAAiB,IAAI,GAAG;AAC5C,oBAAM,aAAa,eAAe,OAAO,OAAO,WAAW,KAAK,QAAQ,IAAI;AAC5E,oBAAM,KAAK,SAAS,WAAW,OAAO,MAAM,UAAU;AAAA,YAC1D;AAAA,UACJ;AACA;AAAA,QAEJ,SAAS;AACL,gBAAM,IAAI,MAAM,yBAAyB,MAAM,EAAE;AAAA,QACrD;AAAA,MACJ;AAAA,IACJ;AAAA;AAAA,EAEc,gBACV,OACA,QACA,SACA,aACF;AAAA;AACE,iBAAW,QAAQ,UAAU,OAAO,GAAG;AACnC,mBAAW,SAAS,eAAe,IAAI,GAAG;AACtC,gBAAM,YAAY,aAAa,KAAK,WAAW,OAAO,KAAK;AAC3D,cAAI,CAAC,WAAW;AACZ;AAAA,UACJ;AAEA,cAAI,UAAU,aAAa;AACvB,gBAAI,KAAK,KAAK,GAAG;AAEb,yBAAW,CAAC,WAAW,OAAO,KAAK,OAAO,QAAa,KAAK,KAAK,CAAC,GAAG;AACjE,oBAAI,KAAK,oBAAoB,SAAS,KAAK,SAAS;AAChD,wBAAM,KAAK,QAAQ,UAAU,MAAM,WAAW,SAAS,KAAK,KAAK,GAAG,WAAW;AAAA,oBAC3E,GAAG;AAAA,kBACP,CAAC;AAAA,gBACL;AAAA,cACJ;AAAA,YACJ;AAAA,UACJ,OAAO;AAEH,gBAAI,KAAK,SAAS,OAAO;AACrB,oBAAM,KAAK,SAAS,MAAM,WAAW,QAAQ,KAAK,KAAK,GAAG;AAAA,gBACtD,QAAQ;AAAA,gBACR;AAAA,gBACA,OAAO;AAAA,cACX,CAAC;AAAA,YACL;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA;AAAA;AAAA;AAAA,EAIA,CAAS,iBAAiB,MAAW;AACjC,QAAI,MAAM,QAAQ,IAAI,GAAG;AACrB,eAAS,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AACvC,cAAM,KAAK,CAAC;AAAA,MAChB;AAAA,IACJ,OAAO;AACH,YAAM;AAAA,IACV;AAAA,EACJ;AACJ;;;ACnWA,SAAS,kBAAAC,uBAAsB;AAexB,SAAS,cAAc,OAAe,WAAsB,MAAW;AAC1E,QAAM,SAAS,oBAAI,IAAY;AAC/B,SAAO,IAAI,KAAK;AAChB,QAAM,UAAU,IAAI,kBAAkB,WAAW;AAAA,IAC7C,OAAO,CAACC,WAAU;AACd,aAAO,IAAIA,MAAK;AAChB,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AACD,UAAQ,MAAM,OAAO,IAAI;AACzB,SAAO,CAAC,GAAG,MAAM;AACrB;AAKA,SAAsB,iBAClB,OACA,WACA,cACA,WACF;AAAA;AACE,UAAM,SAAS,oBAAI,IAAY;AAC/B,WAAO,IAAI,KAAK;AAEhB,QAAI,cAAc;AACd,YAAM,WAAW,CAACA,WAAkB,KAAK,OAAO,IAAIA,MAAK;AAGzD,YAAM,cAAc,CAACA,WAAkB;AACnC,cAAM,WAAW,oBAAI,IAAY;AACjC,cAAM,UAAU,oBAAI,IAAY;AAChC,8BAAsBA,QAAO,WAAW,UAAU,OAAO;AACzD,iBAAS,QAAQ,CAAC,MAAM,SAAS,CAAC,CAAC;AAAA,MACvC;AAEA,YAAM,UAAU,IAAI,mBAAmB,WAAW;AAAA,QAC9C,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,iBAAiB;AAAA,QACjB,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ,CAACA,WAAU;AACf,mBAASA,MAAK;AACd,sBAAYA,MAAK;AAAA,QACrB;AAAA,QACA,YAAY,CAACA,WAAU;AACnB,mBAASA,MAAK;AACd,sBAAYA,MAAK;AAAA,QACrB;AAAA,MACJ,CAAC;AACD,YAAM,QAAQ,MAAM,OAAO,WAAW,YAAY;AAAA,IACtD;AAGA,WAAO,QAAQ,CAAC,MAAM;AAClB,yBAAmB,GAAG,WAAW,MAAM;AAAA,IAC3C,CAAC;AAED,WAAO,CAAC,GAAG,MAAM;AAAA,EACrB;AAAA;AAEA,SAAS,sBAAsB,OAAe,WAAsB,QAAqB,SAAsB;AAlF/G;AAmFI,MAAI,QAAQ,IAAI,KAAK,GAAG;AAEpB;AAAA,EACJ;AACA,UAAQ,IAAI,KAAK;AAEjB,QAAM,YAAW,eAAU,kBAAV,mBAA0BC,gBAAe,KAAK;AAE/D,MAAI,CAAC,UAAU;AACX;AAAA,EACJ;AAEA,WAAS,QAAQ,CAAC,MAAM;AACpB,WAAO,IAAI,CAAC;AACZ,0BAAsB,GAAG,WAAW,QAAQ,OAAO;AAAA,EACvD,CAAC;AACL;AAEA,SAAS,mBAAmB,OAAe,WAAsB,QAAqB;AArGtF;AAsGI,QAAM,SAAQ,kBAAa,WAAW,KAAK,MAA7B,mBAAgC;AAC9C,MAAI,OAAO;AACP,UAAM,QAAQ,CAAC,SAAS;AACpB,aAAO,IAAI,IAAI;AACf,yBAAmB,MAAM,WAAW,MAAM;AAAA,IAC9C,CAAC;AAAA,EACL;AACJ;","names":["model","data","field","lowerCaseFirst","lowerCaseFirst","field","model","lowerCaseFirst","model","lowerCaseFirst"]}
@@ -56,6 +56,8 @@ export declare class DelegateProxyHandler extends DefaultPrismaProxyHandler {
56
56
  private doDeleteMany;
57
57
  private deleteBaseRecursively;
58
58
  private doDelete;
59
+ private getRelationDelegateEntitiesForCascadeDelete;
60
+ private isFieldCascadeDelete;
59
61
  aggregate(args: any): Promise<unknown>;
60
62
  count(args: any): Promise<unknown>;
61
63
  groupBy(args: any): Promise<unknown>;
@@ -71,4 +73,5 @@ export declare class DelegateProxyHandler extends DefaultPrismaProxyHandler {
71
73
  private assembleHierarchy;
72
74
  private assembleUp;
73
75
  private assembleDown;
76
+ private getUpdatedAtFromDelegateBases;
74
77
  }
@@ -655,11 +655,17 @@ class DelegateProxyHandler extends proxy_1.DefaultPrismaProxyHandler {
655
655
  if (!this.involvesDelegateModel(this.model)) {
656
656
  return _super.updateMany.call(this, args);
657
657
  }
658
- const simpleUpdateMany = Object.keys(args.data).every((key) => {
658
+ let simpleUpdateMany = Object.keys(args.data).every((key) => {
659
659
  // check if the `data` clause involves base fields
660
660
  const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, this.model, key);
661
661
  return !(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom);
662
662
  });
663
+ // check if there are any `@updatedAt` fields from delegate base models
664
+ if (simpleUpdateMany) {
665
+ if (this.getUpdatedAtFromDelegateBases(this.model).length > 0) {
666
+ simpleUpdateMany = false;
667
+ }
668
+ }
663
669
  return this.queryUtils.transaction(this.prisma, (tx) => this.doUpdateMany(tx, this.model, args, simpleUpdateMany));
664
670
  });
665
671
  }
@@ -759,6 +765,12 @@ class DelegateProxyHandler extends proxy_1.DefaultPrismaProxyHandler {
759
765
  const fieldInfo = (0, cross_1.resolveField)(this.options.modelMeta, model, key);
760
766
  return !(fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.inheritedFrom);
761
767
  });
768
+ // check if there are any `@updatedAt` fields from delegate base models
769
+ if (simpleUpdateMany) {
770
+ if (this.getUpdatedAtFromDelegateBases(model).length > 0) {
771
+ simpleUpdateMany = false;
772
+ }
773
+ }
762
774
  if (simpleUpdateMany) {
763
775
  // check if the `where` clause involves base fields
764
776
  simpleUpdateMany = Object.keys(args.where || {}).every((key) => {
@@ -845,6 +857,14 @@ class DelegateProxyHandler extends proxy_1.DefaultPrismaProxyHandler {
845
857
  delete data[field];
846
858
  }
847
859
  }
860
+ // if we're updating any field, we need to take care of updating `@updatedAt`
861
+ // fields inherited from delegate base models
862
+ if (Object.keys(data).length > 0) {
863
+ const updatedAtFields = this.getUpdatedAtFromDelegateBases(model);
864
+ for (const fieldInfo of updatedAtFields) {
865
+ this.injectBaseFieldData(model, fieldInfo, new Date(), data, 'update');
866
+ }
867
+ }
848
868
  }
849
869
  // #endregion
850
870
  // #region delete
@@ -912,20 +932,80 @@ class DelegateProxyHandler extends proxy_1.DefaultPrismaProxyHandler {
912
932
  }
913
933
  });
914
934
  }
915
- doDelete(db, model, args) {
916
- return __awaiter(this, void 0, void 0, function* () {
935
+ doDelete(db_1, model_1, args_1) {
936
+ return __awaiter(this, arguments, void 0, function* (db, model, args, readBack = true) {
917
937
  this.injectWhereHierarchy(model, args.where);
918
938
  yield this.injectSelectIncludeHierarchy(model, args);
939
+ // read relation entities that need to be cascade deleted before deleting the main entity
940
+ const cascadeDeletes = yield this.getRelationDelegateEntitiesForCascadeDelete(db, model, args.where);
941
+ let result = undefined;
942
+ if (cascadeDeletes.length > 0) {
943
+ // we'll need to do cascade deletes of relations, so first
944
+ // read the current entity before anything changes
945
+ if (readBack) {
946
+ result = yield this.doFind(db, model, 'findUnique', args);
947
+ }
948
+ // process cascade deletes of relations, this ensure their delegate base
949
+ // entities are deleted as well
950
+ yield Promise.all(cascadeDeletes.map(({ model, entity }) => this.doDelete(db, model, { where: entity }, false)));
951
+ }
919
952
  if (this.options.logPrismaQuery) {
920
953
  this.logger.info(`[delegate] \`delete\` ${this.getModelName(model)}: ${(0, utils_1.formatObject)(args)}`);
921
954
  }
922
- const result = yield db[model].delete(args);
923
- const idValues = this.queryUtils.getEntityIds(model, result);
955
+ const deleteResult = yield db[model].delete(args);
956
+ if (!result) {
957
+ result = this.assembleHierarchy(model, deleteResult);
958
+ }
924
959
  // recursively delete base entities (they all have the same id values)
960
+ const idValues = this.queryUtils.getEntityIds(model, deleteResult);
925
961
  yield this.deleteBaseRecursively(db, model, idValues);
926
- return this.assembleHierarchy(model, result);
962
+ return result;
963
+ });
964
+ }
965
+ getRelationDelegateEntitiesForCascadeDelete(db, model, where) {
966
+ return __awaiter(this, void 0, void 0, function* () {
967
+ if (!where || Object.keys(where).length === 0) {
968
+ throw new Error('where clause is required for cascade delete');
969
+ }
970
+ const cascadeDeletes = [];
971
+ const fields = (0, cross_1.getFields)(this.options.modelMeta, model);
972
+ if (fields) {
973
+ for (const fieldInfo of Object.values(fields)) {
974
+ if (!fieldInfo.isDataModel) {
975
+ continue;
976
+ }
977
+ if (fieldInfo.isRelationOwner) {
978
+ // this side of the relation owns the foreign key,
979
+ // so it won't cause cascade delete to the other side
980
+ continue;
981
+ }
982
+ if (fieldInfo.backLink) {
983
+ // get the opposite side of the relation
984
+ const backLinkField = this.queryUtils.getModelField(fieldInfo.type, fieldInfo.backLink);
985
+ if ((backLinkField === null || backLinkField === void 0 ? void 0 : backLinkField.isRelationOwner) && this.isFieldCascadeDelete(backLinkField)) {
986
+ // if the opposite side of the relation is to be cascade deleted,
987
+ // recursively delete the delegate base entities
988
+ const relationModel = (0, cross_1.getModelInfo)(this.options.modelMeta, fieldInfo.type);
989
+ if ((relationModel === null || relationModel === void 0 ? void 0 : relationModel.baseTypes) && relationModel.baseTypes.length > 0) {
990
+ // the relation model has delegate base, cascade the delete to the base
991
+ const relationEntities = yield db[relationModel.name].findMany({
992
+ where: { [backLinkField.name]: where },
993
+ select: this.queryUtils.makeIdSelection(relationModel.name),
994
+ });
995
+ relationEntities.forEach((entity) => {
996
+ cascadeDeletes.push({ model: fieldInfo.type, entity });
997
+ });
998
+ }
999
+ }
1000
+ }
1001
+ }
1002
+ }
1003
+ return cascadeDeletes;
927
1004
  });
928
1005
  }
1006
+ isFieldCascadeDelete(fieldInfo) {
1007
+ return fieldInfo.onDeleteAction === 'Cascade';
1008
+ }
929
1009
  // #endregion
930
1010
  // #region aggregation
931
1011
  aggregate(args) {
@@ -1193,6 +1273,22 @@ class DelegateProxyHandler extends proxy_1.DefaultPrismaProxyHandler {
1193
1273
  }
1194
1274
  return result;
1195
1275
  }
1276
+ getUpdatedAtFromDelegateBases(model) {
1277
+ var _a;
1278
+ const result = [];
1279
+ const modelFields = (0, cross_1.getFields)(this.options.modelMeta, model);
1280
+ if (!modelFields) {
1281
+ return result;
1282
+ }
1283
+ for (const fieldInfo of Object.values(modelFields)) {
1284
+ if (((_a = fieldInfo.attributes) === null || _a === void 0 ? void 0 : _a.some((attr) => attr.name === '@updatedAt')) &&
1285
+ fieldInfo.inheritedFrom &&
1286
+ (0, cross_1.isDelegateModel)(this.options.modelMeta, fieldInfo.inheritedFrom)) {
1287
+ result.push(fieldInfo);
1288
+ }
1289
+ }
1290
+ return result;
1291
+ }
1196
1292
  }
1197
1293
  exports.DelegateProxyHandler = DelegateProxyHandler;
1198
1294
  //# sourceMappingURL=delegate.js.map