Skip to content

Commit

Permalink
fix(client): types oom and inferred length errors (#20161)
Browse files Browse the repository at this point in the history
  • Loading branch information
millsp committed Jul 26, 2023
1 parent f3bde5f commit ec07b49
Show file tree
Hide file tree
Showing 28 changed files with 1,774 additions and 1,056 deletions.
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.
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
/**
* 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 { JsonObject, Select } from './Utils'

// prettier-ignore
export type Operation =
Expand Down Expand Up @@ -81,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
};

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

Expand Down
9 changes: 0 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
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
*/
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"
}
}

0 comments on commit ec07b49

Please sign in to comment.