Created
August 26, 2025 23:11
-
-
Save jkomyno/30862bd7d0630d2a861538fcb843dc92 to your computer and use it in GitHub Desktop.
effect-smol + `@prisma/config` issue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { Option, Result, Struct, Tuple } from 'effect/data' | |
| import { identity, pipe } from 'effect/Function' | |
| import { Formatter, Schema } from 'effect/schema' | |
| import type { StandardSchemaV1 } from '@standard-schema/spec' | |
| /** | |
| * User-facing schema shapes. | |
| */ | |
| const ViewsConfigSchema = Schema.Struct({ | |
| path: Schema.optional(Schema.String), | |
| }) | |
| type ViewsConfigSchema = typeof ViewsConfigSchema.Type | |
| const DriverAdapterFactorySchema = Schema.declare( | |
| (input: any): input is () => Promise<{ type: 'driver-adapter-factory' }> => { | |
| return typeof input === 'function' | |
| }, | |
| { | |
| identifier: 'DriverAdapterFactory', | |
| encode: identity, | |
| decode: identity, | |
| }, | |
| ) | |
| const SchemaEngineClassicSchema = Schema.Struct({ | |
| engine: Schema.tag('classic'), | |
| datasource: Schema.optional( | |
| Schema.Struct({ | |
| url: Schema.String, | |
| shadowDatabaseUrl: Schema.optional(Schema.String), | |
| }), | |
| ), | |
| }).pipe( | |
| // TODO: try to uncomment the line below and see the errors. | |
| // Schema.withConstructorDefault(() => Option.some({ engine: 'classic' as const })) | |
| ) | |
| const SchemaEngineDriverAdapterSchema = Schema.Struct({ | |
| engine: Schema.tag('js'), | |
| adapter: DriverAdapterFactorySchema, | |
| }) | |
| const SchemaEngineConfigSchema = Schema.Union([ | |
| SchemaEngineClassicSchema, | |
| SchemaEngineDriverAdapterSchema, | |
| ], { mode: 'oneOf' }).pipe( | |
| Schema.asTaggedUnion('engine'), | |
| // TODO: try to uncomment the line below and see the errors. | |
| // Schema.withConstructorDefault(() => Option.some({ engine: 'classic' as const })) | |
| ) | |
| const PrismaConfigUnconditionalSchema = Schema.Struct({ | |
| schema: Schema.optional(Schema.String), | |
| views: Schema.optional(ViewsConfigSchema), | |
| }) | |
| type PrismaConfigUnconditionalSchema = typeof PrismaConfigUnconditionalSchema.Type | |
| /** | |
| * User-facing `PrismaConfig` type. | |
| */ | |
| const PrismaConfigSchema = SchemaEngineConfigSchema | |
| .mapMembers( | |
| Tuple.evolve([ | |
| (classic) => classic.mapFields(Struct.merge(PrismaConfigUnconditionalSchema.fields)), | |
| (js) => js.mapFields(Struct.merge(PrismaConfigUnconditionalSchema.fields)), | |
| ]) | |
| ).pipe( | |
| // TODO: try to uncomment the line below and see the errors. | |
| // Schema.withConstructorDefault(() => Option.some({ engine: 'classic' as const })) | |
| ) | |
| type PrismaConfig = typeof PrismaConfigSchema.Type | |
| /** | |
| * Internal schema shapes, not exposed to users, derived from user-facing schemas. | |
| */ | |
| const DriverAdapterInternalFactorySchema = Schema.declare( | |
| (input: any): input is () => Promise<{ type: 'driver-adapter-internal-factory' }> => { | |
| return typeof input === 'function' | |
| }, | |
| { | |
| identifier: 'DriverAdapterInternalFactory', | |
| encode: identity, | |
| decode: identity, | |
| }, | |
| ) | |
| const SchemaEngineDriverAdapterInternalSchema = Schema.Struct({ | |
| engine: Schema.tag('js'), | |
| adapter: DriverAdapterInternalFactorySchema, | |
| }) | |
| const SchemaEngineInternalConfigSchema = Schema.Union([ | |
| SchemaEngineClassicSchema, | |
| SchemaEngineDriverAdapterInternalSchema, | |
| ]).pipe( | |
| Schema.asTaggedUnion('engine'), | |
| // TODO: try to uncomment the line below and see the errors. | |
| // Schema.withConstructorDefault(() => Option.some({ engine: 'classic' as const })) | |
| ) | |
| const PrismaConfigUnconditionalInternalSchema = Schema.Struct({ | |
| ...PrismaConfigUnconditionalSchema.fields, | |
| loadedFromFile: Schema.NullOr(Schema.String), | |
| }) | |
| /** | |
| * Internal `PrismaConfigInternal` type. | |
| */ | |
| const PRISMA_CONFIG_INTERNAL_BRAND = Symbol.for('PrismaConfigInternal') | |
| const PrismaConfigInternalSchema = SchemaEngineInternalConfigSchema | |
| .mapMembers( | |
| Tuple.evolve([ | |
| (classic) => classic.mapFields(Struct.merge(PrismaConfigUnconditionalInternalSchema.fields)), | |
| (js) => js.mapFields(Struct.merge(PrismaConfigUnconditionalInternalSchema.fields)), | |
| ]) | |
| ) | |
| type _PrismaConfigInternal = typeof PrismaConfigInternalSchema.Type | |
| /** | |
| * The configuration for the Prisma Development Kit, after it has been parsed and processed | |
| * by the `defineConfig` function. | |
| * Thanks to the branding, this type is opaque and cannot be constructed directly. | |
| */ | |
| export type PrismaConfigInternal = _PrismaConfigInternal & { | |
| '~brand.type': typeof PRISMA_CONFIG_INTERNAL_BRAND | |
| } | |
| /** | |
| * Functions | |
| */ | |
| function brandPrismaConfigInternal(config: _PrismaConfigInternal): PrismaConfigInternal { | |
| Object.defineProperty(config, '~brand.type', { | |
| value: PRISMA_CONFIG_INTERNAL_BRAND, | |
| writable: true, | |
| configurable: true, | |
| enumerable: false, | |
| }) | |
| return config as PrismaConfigInternal | |
| } | |
| /** | |
| * Parse a given input object to ensure it conforms to the `PrismaConfig` type Schema. | |
| * This function may fail, but it will never throw. | |
| */ | |
| function parsePrismaConfigSchema(input: unknown): Result.Result<PrismaConfig, StandardSchemaV1.FailureResult> { | |
| return pipe( | |
| Schema.decodeUnknownResult(PrismaConfigSchema)(input, { | |
| onExcessProperty: 'error', | |
| }), | |
| Result.mapError((error) => Formatter.makeStandardSchemaV1().format(error.issue)) | |
| ) | |
| } | |
| /** | |
| * Parse a given input object to ensure it conforms to the `PrismaConfigInternal` type Schema. | |
| * This function may fail, but it will never throw. | |
| */ | |
| function parsePrismaConfigInternalSchema(input: unknown): Result.Result<PrismaConfigInternal, StandardSchemaV1.FailureResult> { | |
| // Bypass the parsing step when the input is already an object with the correct internal brand. | |
| if (typeof input === 'object' && input !== null && input['~brand.type'] === PRISMA_CONFIG_INTERNAL_BRAND) { | |
| console.warn('Short-circuit: input is already a PrismaConfigInternal object') | |
| return Result.succeed(input as PrismaConfigInternal) | |
| } | |
| return pipe( | |
| Schema.decodeUnknownResult(PrismaConfigInternalSchema)(input, { | |
| onExcessProperty: 'error', | |
| }), | |
| Result.map(brandPrismaConfigInternal), | |
| Result.mapError((error) => Formatter.makeStandardSchemaV1().format(error.issue)) | |
| ) | |
| } | |
| /** | |
| * Usage examples. | |
| */ | |
| function example01() { | |
| console.log('--- Example 01: Parsing PrismaConfig ---') | |
| const result = parsePrismaConfigSchema({ | |
| // TODO: try commenting out `engine` and to uncomment the `withConstructorDefault` lines above | |
| engine: 'classic' as const, | |
| schema: './schema.prisma', | |
| }) | |
| if (Result.isFailure(result)) { | |
| console.error('Failed to parse PrismaConfig:') | |
| console.dir(result.failure, { depth: null }) | |
| } else { | |
| console.log('Parsed PrismaConfig:') | |
| console.dir(result.success, { depth: null }) | |
| } | |
| console.log('\n') | |
| } | |
| function example02() { | |
| console.log('--- Example 02: Parsing _PrismaConfigInternal ---') | |
| const result = parsePrismaConfigInternalSchema({ | |
| // TODO: try commenting out `engine` and to uncomment the `withConstructorDefault` lines above | |
| engine: 'classic' as const, | |
| schema: './schema.prisma', | |
| loadedFromFile: '<path-to-file>', | |
| }) | |
| if (Result.isFailure(result)) { | |
| console.error('Failed to parse _PrismaConfigInternal:') | |
| console.error(result.failure) | |
| } else { | |
| console.log('Parsed _PrismaConfigInternal:') | |
| console.dir(result.success, { depth: null }) | |
| } | |
| console.log('\n') | |
| } | |
| function example03() { | |
| console.log('--- Example 03: Parsing PrismaConfigInternal ---') | |
| const config = brandPrismaConfigInternal({ | |
| engine: 'classic' as const, | |
| schema: './schema.prisma', | |
| loadedFromFile: '<path-to-file>', | |
| }) | |
| const result = parsePrismaConfigInternalSchema(config) | |
| if (Result.isFailure(result)) { | |
| console.error('Failed to parse PrismaConfigInternal:') | |
| console.error(result.failure) | |
| } else { | |
| console.log('Parsed PrismaConfigInternal:') | |
| console.dir(result.success, { depth: null }) | |
| } | |
| console.log('\n') | |
| } | |
| example01() | |
| example02() | |
| example03() |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See DIscord thread.