import type { ReadonlyValue } from "@confect/core/SchemaToValidator"; import { pipe } from "effect/Function"; import * as Effect from "effect/Effect"; import * as Function from "effect/Function"; import * as Schema from "effect/Schema"; import type { ReadonlyRecord } from "effect/Record"; import type * as DatabaseSchema from "./DatabaseSchema"; import type * as DataModel from "./DataModel"; import type * as TableInfo from "./TableInfo"; import type * as Table from "./Table"; export type Document< Schema_ extends DatabaseSchema.AnyWithProps, TableName extends DatabaseSchema.TableNames, > = DataModel.DocumentByName, TableName>; export type WithoutSystemFields = Doc extends unknown ? Omit : never; export type Any = any; export type AnyEncoded = ReadonlyRecord; export const decode = Function.dual< ( table: Table_, ) => ( self: TableInfo.TableInfo["convexDocument"], ) => Effect.Effect< TableInfo.TableInfo["document"], DocumentDecodeError >, ( self: TableInfo.TableInfo["convexDocument"], table: Table_, ) => Effect.Effect< TableInfo.TableInfo["document"], DocumentDecodeError > >( 2, ( self: TableInfo.TableInfo["convexDocument"], table: Table_, ): Effect.Effect< TableInfo.TableInfo["document"], DocumentDecodeError > => pipe( self, Schema.decodeUnknownEffect(table.Doc), Effect.catchIf(Schema.isSchemaError, (schemaError) => Effect.fail( new DocumentDecodeError({ tableName: table.tableName, id: self._id, parseError: schemaError.message, }), ), ), ), ); export const encode = Function.dual< ( table: Table_, ) => ( self: Schema.Schema.Type>, ) => Effect.Effect< Schema.Codec.Encoded>, DocumentEncodeError >, ( self: Schema.Schema.Type>, table: Table_, ) => Effect.Effect< Schema.Codec.Encoded>, DocumentEncodeError > >( 2, ( self: Schema.Schema.Type>, table: Table_, ): Effect.Effect< Schema.Codec.Encoded>, DocumentEncodeError > => pipe( self, Schema.encodeEffect(table.Fields), Effect.catchIf(Schema.isSchemaError, (schemaError) => Effect.fail( new DocumentEncodeError({ tableName: table.tableName, id: self._id, parseError: schemaError.message, }), ), ), ), ); export class DocumentDecodeError extends Schema.TaggedError()( "DocumentDecodeError", { tableName: Schema.String, id: Schema.String, parseError: Schema.String, }, ) { override get message(): string { return documentErrorMessage({ id: this.id, tableName: this.tableName, message: `could not be decoded:\n\n${this.parseError}`, }); } } export class DocumentEncodeError extends Schema.TaggedError()( "DocumentEncodeError", { tableName: Schema.String, id: Schema.String, parseError: Schema.String, }, ) { override get message(): string { return documentErrorMessage({ id: this.id, tableName: this.tableName, message: `could not be encoded:\n\n${this.parseError}`, }); } } export const documentErrorMessage = ({ id, tableName, message, }: { id: string; tableName: string; message: string; }) => `Document with ID '${id}' in table '${tableName}' ${message}`;