Skip to content

Commit

Permalink
fix type and runtime issue (#16563)
Browse files Browse the repository at this point in the history
  • Loading branch information
millsp authored and jkomyno committed Dec 21, 2022
1 parent bfda666 commit f5012da
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 18 deletions.
16 changes: 12 additions & 4 deletions packages/client/src/generation/TSClient/PrismaClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,28 +81,36 @@ function clientExtensionsQueryDefinition(this: PrismaClientClass) {
return `${acc}
${action}: {
args: Prisma.${getModelArgName(modelName, action)}<ExtArgs>,
result: Promise<runtime.Types.Utils.OptionalFlat<${modelName}>>
queryExtCbArgs: { model: '${modelName}', operation: '${action}', args: runtime.Types.Extensions.ReadonlySelector<TypeMap<ExtArgs>['${modelName}']['${action}']['args']>, query: (args: object) => PrismaPromise<runtime.Types.Utils.OptionalFlat<${modelName}>> },
result: runtime.Types.Utils.OptionalFlat<${modelName}>
}`
}, '')}
}`
},
'',
)}
}`
const queryCbDefinition = (modelName: string, operationName: string) => {
const queryArgs = `runtime.Types.Extensions.ReadonlySelector<Prisma.TypeMap<ExtArgs>[${modelName}][${operationName}]['args']>`
const queryResult = `Prisma.TypeMap<ExtArgs>[${modelName}][${operationName}]['result']`
const inputQuery = `{ model: ${modelName}, operation: ${operationName}, args: ${queryArgs} }`
const inputQueryCb = `${inputQuery} & { query: (args: ${queryArgs}) => PrismaPromise<${queryResult}> }`

return `(args: ${inputQueryCb}) => Promise<${queryResult}>`
}

const allOperationsParam = (modelNames: string[], indent: string) => {
const key = modelNames.length > 1 ? `keyof Prisma.TypeMap<ExtArgs>` : `'${modelNames[0]}'`

return `{
${indent}$allOperations?: (args: Prisma.TypeMap<ExtArgs>[${key}][keyof Prisma.TypeMap<ExtArgs>[${key}]]['queryExtCbArgs']) => Prisma.TypeMap<ExtArgs>[${key}][keyof Prisma.TypeMap<ExtArgs>[${key}]]['result']
${indent}$allOperations?: ${queryCbDefinition(key, `keyof Prisma.TypeMap<ExtArgs>[${key}]`)}
${indent}}`
}

const modelParam = (propName: string, modelNames: string[]) => {
const key = modelNames.length > 1 ? `keyof Prisma.TypeMap<ExtArgs>` : `'${modelNames[0]}'`

return `${propName}?: {
[K in keyof Prisma.TypeMap<ExtArgs>[${key}]]?: (args: Prisma.TypeMap<ExtArgs>[${key}][K]['queryExtCbArgs']) => Prisma.TypeMap<ExtArgs>[${key}][K]['result']
[K in keyof Prisma.TypeMap<ExtArgs>[${key}]]?: ${queryCbDefinition(key, `K`)}
} & ${allOperationsParam(modelNames, ' ')}`
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function iterateAndCallQueryCallbacks(
return queryCbs[i]({
model: params.model,
operation: params.action,
args: klona(params.args),
args: klona(params.args ?? {}),
query: (args) => {
params.args = args
return iterateAndCallQueryCallbacks(client, params, queryCbs, i + 1)
Expand Down
67 changes: 54 additions & 13 deletions packages/client/tests/functional/extensions/enabled/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ testMatrix.setupTestSuite(
await prisma.$disconnect()
})

testIf(process.platform !== 'win32')('extending a specific model query', async () => {
test('extending a specific model query', async () => {
const fnUser = jest.fn()
const fnPost = jest.fn()
const fnEmitter = jest.fn()
Expand Down Expand Up @@ -94,7 +94,7 @@ testMatrix.setupTestSuite(
await waitFor(() => expect(fnEmitter).toHaveBeenCalledTimes(1))
})

testIf(process.platform !== 'win32')('top to bottom execution order', async () => {
test('top to bottom execution order', async () => {
let i = 0
const fnUser1 = jest.fn()
const fnUser2 = jest.fn()
Expand Down Expand Up @@ -136,7 +136,7 @@ testMatrix.setupTestSuite(
await waitFor(() => expect(fnEmitter).toHaveBeenCalledTimes(1))
})

testIf(process.platform !== 'win32')('args mutation isolation', async () => {
test('args mutation isolation', async () => {
const fnEmitter = jest.fn()
const fnUser = jest.fn()

Expand Down Expand Up @@ -195,7 +195,7 @@ testMatrix.setupTestSuite(
await waitFor(() => expect(fnEmitter).toHaveBeenCalledTimes(1))
})

testIf(process.platform !== 'win32')('args mutation accumulation', async () => {
test('args mutation accumulation', async () => {
const fnUser = jest.fn()
const fnEmitter = jest.fn()

Expand Down Expand Up @@ -243,7 +243,7 @@ testMatrix.setupTestSuite(
await waitFor(() => expect(fnEmitter).toHaveBeenCalledTimes(1))
})

testIf(process.platform !== 'win32')('query result override with a simple call', async () => {
test('query result override with a simple call', async () => {
const fnEmitter = jest.fn()

prisma.$on('query', fnEmitter)
Expand Down Expand Up @@ -301,7 +301,7 @@ testMatrix.setupTestSuite(
await wait(() => expect(fnEmitter).not.toHaveBeenCalled())
})

testIf(process.platform !== 'win32')('query result override with extra extension before', async () => {
test('query result override with extra extension before', async () => {
const fnEmitter = jest.fn()
const fnUser = jest.fn()

Expand Down Expand Up @@ -337,7 +337,7 @@ testMatrix.setupTestSuite(
await wait(() => expect(fnEmitter).not.toHaveBeenCalled())
})

testIf(process.platform !== 'win32')('query result mutation with a simple call', async () => {
test('query result mutation with a simple call', async () => {
const fnEmitter = jest.fn()

prisma.$on('query', fnEmitter)
Expand Down Expand Up @@ -369,7 +369,7 @@ testMatrix.setupTestSuite(
await waitFor(() => expect(fnEmitter).toHaveBeenCalledTimes(1))
})

testIf(process.platform !== 'win32')('query result mutation with multiple calls', async () => {
test('query result mutation with multiple calls', async () => {
const fnEmitter = jest.fn()

prisma.$on('query', fnEmitter)
Expand Down Expand Up @@ -662,7 +662,7 @@ testMatrix.setupTestSuite(
},
)

testIf(process.platform !== 'win32')('extending with $allModels and a specific query', async () => {
test('extending with $allModels and a specific query', async () => {
const fnModel = jest.fn()
const fnEmitter = jest.fn()

Expand Down Expand Up @@ -705,7 +705,7 @@ testMatrix.setupTestSuite(
await waitFor(() => expect(fnEmitter).toHaveBeenCalledTimes(2))
})

testIf(process.platform !== 'win32')('extending with $allModels and $allOperations', async () => {
test('extending with $allModels and $allOperations', async () => {
const fnModel = jest.fn()
const fnEmitter = jest.fn()

Expand Down Expand Up @@ -769,7 +769,7 @@ testMatrix.setupTestSuite(
await waitFor(() => expect(fnEmitter).toHaveBeenCalledTimes(3))
})

testIf(process.platform !== 'win32')('extending with specific model and $allOperations', async () => {
test('extending with specific model and $allOperations', async () => {
const fnModel = jest.fn()
const fnEmitter = jest.fn()

Expand Down Expand Up @@ -830,7 +830,7 @@ testMatrix.setupTestSuite(
await waitFor(() => expect(fnEmitter).toHaveBeenCalledTimes(2))
})

testIf(process.platform !== 'win32')('errors in callback', async () => {
test('errors in callback', async () => {
const xprisma = prisma.$extends({
name: 'Faulty query ext',
query: {
Expand All @@ -847,7 +847,7 @@ testMatrix.setupTestSuite(
)
})

testIf(process.platform !== 'win32')('errors in with no extension name', async () => {
test('errors in with no extension name', async () => {
const xprisma = prisma.$extends({
query: {
user: {
Expand All @@ -862,6 +862,47 @@ testMatrix.setupTestSuite(
`Error caused by an extension: All is lost!`,
)
})

test('empty args becomes an empty object', async () => {
const fnUser1 = jest.fn()
const fnEmitter = jest.fn()

prisma.$on('query', fnEmitter)

const xprisma = prisma.$extends({
query: {
user: {
findFirst({ args, query, operation, model }) {
fnUser1(args)
return query(args)
},
},
},
})

const args = undefined

const data = await xprisma.user.findFirst(args)

expect(data).not.toBe(null)
expect(fnUser1).toHaveBeenCalledWith({})
expect(fnUser1).toHaveBeenCalledTimes(1)
await waitFor(() => expect(fnEmitter).toHaveBeenCalledTimes(1))
})

test('passing incorrect argument errors', () => {
prisma.$extends({
query: {
user: {
async findFirst({ args, query, operation, model }) {
const user = await query(args)
// @ts-expect-error
return query(user)
},
},
},
})
})
},
{
skipDefaultClientInstance: true,
Expand Down

0 comments on commit f5012da

Please sign in to comment.