Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(client): types oom and inferred length errors #20161

Merged
merged 22 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions helpers/compile/plugins/tscPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@ export const tscPlugin: (emitTypes?: boolean) => esbuild.Plugin = (emitTypes?: b
if (options.incremental !== true && process.env.DEV !== 'true') {
// we get the types generated by tsc and bundle them near the output
bundleTypeDefinitions(typeOutPath, bundlePath)

// when types are already exported by us, it is not always guaranteed
// that the type bundler will also export them. It won't be able to
// trace them correctly back to runtime module and fail with either
// "... is using the type X but can not be named" or "The inferred
// type of this node exceeds the maximum length" error, or even worse
// the compiler could inline the types in the users' project causing
// very bad performance issues. To fix this, we export all the types.
millsp marked this conversation as resolved.
Show resolved Hide resolved
let dtsContents = await fs.readFile(`${bundlePath}.d.ts`, 'utf-8')
dtsContents = dtsContents.replace(/(?<!export )declare (type|interface|const)/g, 'export declare $1')
await fs.outputFile(`${bundlePath}.d.ts`, dtsContents)
} else {
// in watch mode, it wouldn't be viable to bundle the types every time
// we haven't built any types with tsc at this stage, but we want types
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions packages/client/src/generation/TSClient/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ export type ${getAggregateGetName(model.name)}<T extends ${getAggregateArgsName(
.moduleExport(
ts.typeDeclaration(
model.name,
ts.namedType(`runtime.Types.DefaultSelection`).addGenericArgument(ts.namedType(getPayloadName(model.name))),
ts.namedType(`$Result.DefaultSelection`).addGenericArgument(ts.namedType(getPayloadName(model.name))),
),
)
.setDocComment(ts.docComment(docs))
Expand Down Expand Up @@ -313,7 +313,7 @@ ${ts.stringify(buildModelPayload(this.model, this.dmmf), { newLine: 'both' })}

type ${model.name}GetPayload<S extends boolean | null | undefined | ${getModelArgName(
model.name,
)}> = $Types.GetResult<${getPayloadName(model.name)}, S>
)}> = $Result.GetResult<${getPayloadName(model.name)}, S>

${isComposite ? '' : new ModelDelegate(this.type, this.context).toTS()}

Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/generation/TSClient/PrismaClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { GeneratorConfig } from '@prisma/generator-helper'
import { assertNever } from '@prisma/internals'
import indent from 'indent-string'

import { Operation } from '../../runtime/core/types/GetResult'
import { Operation } from '../../runtime/core/types/Result'
import { InternalDatasource } from '../../runtime/utils/printDatasources'
import { DMMFHelper } from '../dmmf'
import * as ts from '../ts-builders'
Expand Down
11 changes: 6 additions & 5 deletions packages/client/src/generation/TSClient/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ import $Types = runtime.Types // general types
import $Public = runtime.Types.Public
import $Utils = runtime.Types.Utils
import $Extensions = runtime.Types.Extensions
import $Result = runtime.Types.Result

export type PrismaPromise<T> = $Public.PrismaPromise<T>
`,
Expand Down Expand Up @@ -201,12 +202,12 @@ export type MetricHistogramBucket = runtime.MetricHistogramBucket
/**
* Extensions
*/
export type Extension = $Extensions.UserArgs
export import Extension = $Extensions.UserArgs
export import getExtensionContext = runtime.Extensions.getExtensionContext
export type Args<T, F extends $Public.Operation> = $Public.Args<T, F>
export type Payload<T, F extends $Public.Operation> = $Public.Payload<T, F>
export type Result<T, A, F extends $Public.Operation> = $Public.Result<T, A, F>
export type Exact<T, W> = $Public.Exact<T, W>
export import Args = $Public.Args
export import Payload = $Public.Payload
export import Result = $Public.Result
export import Exact = $Public.Exact
millsp marked this conversation as resolved.
Show resolved Hide resolved

/**
* Prisma Client JS version: ${clientVersion}
Expand Down
10 changes: 5 additions & 5 deletions packages/client/src/generation/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,34 +190,34 @@ export function getReturnType({
const promiseOpen = renderPromise ? 'Prisma.PrismaPromise<' : ''
const promiseClose = renderPromise ? '>' : ''

return `${promiseOpen}$Types.GetResult<${getPayloadName(name)}<ExtArgs>, T, '${actionName}'>${
return `${promiseOpen}$Result.GetResult<${getPayloadName(name)}<ExtArgs>, T, '${actionName}'>${
isChaining ? ' | Null' : ''
}${promiseClose}`
}

if (isChaining && actionName === 'findUniqueOrThrow') {
return `Prisma__${name}Client<${getType(
`$Types.GetResult<${getPayloadName(name)}<ExtArgs>, T, '${actionName}'>`,
`$Result.GetResult<${getPayloadName(name)}<ExtArgs>, T, '${actionName}'>`,
isList,
)} | ${isNullable ? 'null' : 'Null'}, ${isNullable ? 'null' : 'Null'}, ExtArgs>`
}

if (actionName === 'findFirstOrThrow' || actionName === 'findUniqueOrThrow') {
return `Prisma__${name}Client<${getType(
`$Types.GetResult<${getPayloadName(name)}<ExtArgs>, T, '${actionName}'>`,
`$Result.GetResult<${getPayloadName(name)}<ExtArgs>, T, '${actionName}'>`,
isList,
)}, never, ExtArgs>`
}

if (actionName === 'findFirst' || actionName === 'findUnique') {
return `Prisma__${name}Client<${getType(
`$Types.GetResult<${getPayloadName(name)}<ExtArgs>, T, '${actionName}'>`,
`$Result.GetResult<${getPayloadName(name)}<ExtArgs>, T, '${actionName}'>`,
isList,
)} | null, null, ExtArgs>`
}

return `Prisma__${name}Client<${getType(
`$Types.GetResult<${getPayloadName(name)}<ExtArgs>, T, '${actionName}'>`,
`$Result.GetResult<${getPayloadName(name)}<ExtArgs>, T, '${actionName}'>`,
isList,
)}, never, ExtArgs>`
}
Expand Down
16 changes: 8 additions & 8 deletions packages/client/src/runtime/core/types/Extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Sql } from 'sql-template-tag'

import { ITXClientDenyList } from '../../itxClientDenyList'
import { RequiredArgs as UserArgs } from '../extensions/$extends'
import { FluentOperation, GetFindResult, GetResult as GetOperationResult, Operation } from './GetResult'
import { Payload } from './Payload'
import { PrismaPromise } from './Public'
import { FluentOperation, GetFindResult, GetResult as GetOperationResult, Operation } from './Result'
import { Call, ComputeDeep, Exact, Fn, Optional, Path, Return, Select, ToTuple, UnwrapTuple } from './Utils'

/* eslint-disable prettier/prettier */
Expand Down Expand Up @@ -34,7 +34,7 @@ export type GetSelect<Base extends Record<any, any>, R extends Args['result'][st

/** Query */

export type DynamicQueryExtensionArgs<Q_, TypeMap extends TypeMapDef> = {
type DynamicQueryExtensionArgs<Q_, TypeMap extends TypeMapDef> = {
[K in keyof Q_]:
K extends '$allOperations'
? (args: { model?: string, operation: string, args: any, query: (args: any) => PrismaPromise<any> }) => Promise<any>
Expand Down Expand Up @@ -86,7 +86,7 @@ type DynamicQueryExtensionCbArgsArgs<TypeMap extends TypeMapDef, _0 extends Prop

/** Result */

export type DynamicResultExtensionArgs<R_, TypeMap extends TypeMapDef> = {
type DynamicResultExtensionArgs<R_, TypeMap extends TypeMapDef> = {
[K in keyof R_]: {
[P in keyof R_[K]]?: {
needs?: DynamicResultExtensionNeeds<TypeMap, ModelKey<TypeMap, K>, R_[K][P]>
Expand All @@ -106,7 +106,7 @@ type DynamicResultExtensionData<TypeMap extends TypeMapDef, M extends PropertyKe

/** Model */

export type DynamicModelExtensionArgs<M_, TypeMap extends TypeMapDef, ExtArgs extends Record<string, any>> = {
type DynamicModelExtensionArgs<M_, TypeMap extends TypeMapDef, ExtArgs extends Record<string, any>> = {
[K in keyof M_]:
K extends '$allModels'
? & { [P in keyof M_[K]]?: unknown }
Expand All @@ -117,7 +117,7 @@ export type DynamicModelExtensionArgs<M_, TypeMap extends TypeMapDef, ExtArgs ex
: never
}

export type DynamicModelExtensionThis<TypeMap extends TypeMapDef, M extends PropertyKey, ExtArgs extends Record<string, any>> = {
type DynamicModelExtensionThis<TypeMap extends TypeMapDef, M extends PropertyKey, ExtArgs extends Record<string, any>> = {
[P in keyof ExtArgs['model'][Uncapitalize<M & string>]]:
Return<ExtArgs['model'][Uncapitalize<M & string>][P]>
} & {
Expand Down Expand Up @@ -158,13 +158,13 @@ type DynamicModelExtensionFnResultNull<P extends PropertyKey> =

/** Client */

export type DynamicClientExtensionArgs<C_, TypeMap extends TypeMapDef, TypeMapCb extends TypeMapCbDef, ExtArgs extends Record<string, any>> = {
type DynamicClientExtensionArgs<C_, TypeMap extends TypeMapDef, TypeMapCb extends TypeMapCbDef, ExtArgs extends Record<string, any>> = {
[P in keyof C_]: unknown
} & {
[K: symbol]: { ctx: Optional<DynamicClientExtensionThis<TypeMap, TypeMapCb, ExtArgs>, ITXClientDenyList> }
}

export type DynamicClientExtensionThis<TypeMap extends TypeMapDef, TypeMapCb extends TypeMapCbDef, ExtArgs extends Record<string, any>> = {
type DynamicClientExtensionThis<TypeMap extends TypeMapDef, TypeMapCb extends TypeMapCbDef, ExtArgs extends Record<string, any>> = {
[P in keyof ExtArgs['client']]: Return<ExtArgs['client'][P]>
} & {
[P in Exclude<TypeMap['meta']['modelProps'], keyof ExtArgs['client']>]:
Expand Down Expand Up @@ -253,7 +253,7 @@ type DevTypeMapFnDef = {
payload: Payload
}

type TypeMapCbDef = Fn<{ extArgs: Args }, TypeMapDef>
export type TypeMapCbDef = Fn<{ extArgs: Args }, TypeMapDef>

type ModelKey<TypeMap extends TypeMapDef, M extends PropertyKey> =
M extends keyof TypeMap['model']
Expand Down
2 changes: 1 addition & 1 deletion packages/client/src/runtime/core/types/Public.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable prettier/prettier */

import { GetResult, Operation } from './GetResult'
import { GetResult, Operation } from './Result'
import { Exact } from './Utils'

/*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable prettier/prettier */

import { Payload } from './Payload'
import { JsonObject } from './Utils'
import { Equals, JsonObject, Select } from './Utils'

// prettier-ignore
export type Operation =
Expand Down Expand Up @@ -48,13 +48,12 @@ export type FluentOperation =
type Count<O> = { [K in keyof O]: Count<number> } & {}

// prettier-ignore
export type GetFindResult<P extends Payload, A> =
{} extends A ? DefaultSelection<P> :
A extends
export type GetFindResult<P extends Payload, _A, A = { 0: _A, 1: { select: undefined } }[Equals<_A, any>]> =
A extends
| { select: infer S } & Record<string, unknown>
| { include: infer S } & Record<string, unknown>
? S extends undefined ? DefaultSelection<P> :
{
? S extends undefined ? DefaultSelection<P>
: {
[K in keyof S as S[K] extends false | undefined | null ? never : K]:
S[K] extends object
? P extends SelectablePayloadFields<K, (infer O)[]>
Expand Down Expand Up @@ -82,31 +81,25 @@ type SelectablePayloadFields<K extends PropertyKey, O> =
| { composites: { [k in K]: O } }

// prettier-ignore
type SelectField<P extends SelectablePayloadFields<any, any>, K extends PropertyKey> =
type SelectField<P extends SelectablePayloadFields<any, any>, K extends PropertyKey> =
P extends { objects: Record<K, any> }
? P['objects'][K]
: P extends { composites: Record<K, any> }
? P['composites'][K]
: never

// prettier-ignore
export type DefaultSelection<P> = P extends Payload
? P['scalars'] & UnwrapPayload<P['composites']>
: P
export type DefaultSelection<P> = UnwrapPayload<{ default: P }>['default']

// prettier-ignore
type UnwrapPayload<P> = {
[K in keyof P]:
P[K] extends Payload[]
? UnwrapPayload<P[K]>
: P[K] extends Payload
? P[K]['scalars'] & UnwrapPayload<P[K]['composites']>
: P[K] extends infer O | null
? O extends Payload
? (O['scalars'] & UnwrapPayload<O['composites']>) | null
: P[K]
: P[K]
} & unknown
type UnwrapPayload<P> = {} extends P ? unknown : {
[K in keyof P]:
P[K] extends { scalars: infer S, composites: infer C }[]
? Array<S & UnwrapPayload<C>>
: P[K] extends { scalars: infer S, composites: infer C } | null
? S & UnwrapPayload<C> | Select<P[K], null>
: never
millsp marked this conversation as resolved.
Show resolved Hide resolved
};

type GetCountResult<A> = A extends { select: infer S } ? (S extends true ? number : Count<S>) : number

Expand Down
12 changes: 3 additions & 9 deletions packages/client/src/runtime/core/types/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,6 @@ export type Exact<A, W> = (A extends unknown ? (W extends A ? {

export type Cast<A, W> = A extends W ? A : W

type LegacyNarrowable = string | number | boolean | bigint

// prettier-ignore
export type LegacyExact<A, W = unknown> =
W extends unknown ? A extends LegacyNarrowable ? Cast<A, W> : Cast<
{ [K in keyof A]: K extends keyof W ? LegacyExact<A[K], W[K]> : never },
{ [K in keyof W]: K extends keyof A ? LegacyExact<A[K], W[K]> : W[K] }>
: never;

export type JsonObject = { [Key in string]?: JsonValue }
export interface JsonArray extends Array<JsonValue> {}
export type JsonValue = string | number | boolean | JsonObject | JsonArray | null
Expand Down Expand Up @@ -118,6 +109,9 @@ export type PayloadToResult<P, O extends Record<any, any> = RenameAndNestPayload

export type Select<T, U> = T extends U ? T : never

// prettier-ignore
export type Equals<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2) ? 1 : 0
millsp marked this conversation as resolved.
Show resolved Hide resolved

// This alias is necessary to allow to use `Promise` as a model name.
// It's used in generated client instead of global `Promise`.
// Why conditional intersection with {}?. Without it, in the error messages
Expand Down
5 changes: 2 additions & 3 deletions packages/client/src/runtime/core/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import * as Extensions from './Extensions'
import { DefaultSelection, GetResult } from './GetResult'
import { Payload } from './Payload'
import * as Public from './Public'
import * as Result from './Result'
import * as Utils from './Utils'

/** Specific types */
export { Result }
export { Extensions }
export { Utils }
export { Public }

/** General types */
export { type GetResult }
export { type Payload }
export { type DefaultSelection }
14 changes: 1 addition & 13 deletions packages/client/src/runtime/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import * as Extensions from './core/extensions'
import * as Public from './core/public'
import * as Types from './core/types'
import { Payload } from './core/types'
import type { PrismaPromise } from './core/types/Public'

export { DMMFHelper as DMMFClass } from '../generation/dmmf'
export { type BaseDMMF, DMMF } from '../generation/dmmf-types'
Expand Down Expand Up @@ -35,16 +33,6 @@ export { empty, join, raw, Sql, default as sqltag } from 'sql-template-tag'
export { Types }
export { Extensions }
export { Public }
export { warnOnce } from '@prisma/internals'

/**
* Payload, PrismaPromise and Extensions types are already exported via Types but tsc
* won't be able to trace them correctly back to runtime module and fail with either
* "... is using the type X but can not be named" or "The inferred type of this node exceeds the maximum length" error.
* The issue lies with the type bundler which does not add exports for dependent types
* TODO: Maybe simply exporting all types in runtime will do the trick
millsp marked this conversation as resolved.
Show resolved Hide resolved
*/
export { type Payload, type PrismaPromise }

export * from './core/types/Extensions'
export type { ITXClientDenyList } from './itxClientDenyList'
export { warnOnce } from '@prisma/internals'
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ void executeSteps({
await $`pnpm exec prisma generate`
},
test: async () => {
await $`pnpm exec prisma -v`
await $`ts-node src/index.ts`
await $`pnpm exec tsc src/index.ts`
await $`pnpm exec tsc`
},
finish: async () => {
await $`echo "done"`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { $ } from 'zx'

import { executeSteps } from '../../_utils/executeSteps'

void executeSteps({
setup: async () => {
await $`pnpm install`
await $`pnpm exec prisma db push --force-reset`
await $`pnpm exec prisma generate`
},
test: async () => {
await $`ts-node src/index.ts`
await $`pnpm exec tsc`
},
finish: async () => {
await $`echo "done"`
},
// keep: true, // keep docker open to debug it
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"private": true,
"version": "0.0.0",
"main": "index.js",
"scripts": {},
"dependencies": {
"@prisma/client": "../../prisma-client-0.0.0.tgz"
},
"devDependencies": {
"@types/node": "16.18.11",
"prisma": "../../prisma-0.0.0.tgz",
"typescript": "4.9.4"
}
}