@gaganref/confect-core 10.3.1-fork.41 → 10.3.1-fork.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Component.d.ts.map +1 -1
- package/dist/Component.js +1 -1
- package/dist/Component.js.map +1 -1
- package/dist/FunctionSpec.d.ts +35 -0
- package/dist/FunctionSpec.d.ts.map +1 -1
- package/dist/FunctionSpec.js +14 -9
- package/dist/FunctionSpec.js.map +1 -1
- package/dist/Ref.d.ts +2 -1
- package/dist/Ref.d.ts.map +1 -1
- package/dist/Ref.js +3 -2
- package/dist/Ref.js.map +1 -1
- package/dist/SchemaToValidator.d.ts +10 -1
- package/dist/SchemaToValidator.d.ts.map +1 -1
- package/dist/SchemaToValidator.js +18 -3
- package/dist/SchemaToValidator.js.map +1 -1
- package/package.json +1 -1
- package/src/Component.ts +1 -0
- package/src/FunctionSpec.ts +50 -10
- package/src/Ref.ts +4 -0
- package/src/SchemaToValidator.ts +22 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaToValidator.js","names":["IdScope.app","GenericId.tableName","GenericId.scope","scope"],"sources":["../src/SchemaToValidator.ts"],"sourcesContent":["import * as IdScope from \"./IdScope.js\";\nimport type {\n GenericId as ConvexGenericId,\n PropertyValidators,\n Validator,\n VAny,\n VArray,\n VBoolean,\n VBytes,\n VFloat64,\n VId,\n VInt64,\n VLiteral,\n VNull,\n VObject,\n VRecord,\n VString,\n VUnion,\n} from \"convex/values\";\nimport { v } from \"convex/values\";\nimport { pipe } from \"effect/Function\";\nimport * as Array from \"effect/Array\";\nimport * as Data from \"effect/Data\";\nimport * as Effect from \"effect/Effect\";\nimport * as Match from \"effect/Match\";\nimport * as Number from \"effect/Number\";\nimport * as Option from \"effect/Option\";\nimport * as Predicate from \"effect/Predicate\";\nimport * as Schema from \"effect/Schema\";\nimport * as SchemaAST from \"effect/SchemaAST\";\nimport * as String from \"effect/String\";\n\nimport * as GenericId from \"./GenericId.js\";\nimport type {\n IsAny,\n IsOptional,\n IsRecord,\n IsRecursive,\n IsUnion,\n TypeError,\n UnionToTuple,\n} from \"./Types.js\";\n\n// Args\n\nexport const compileArgsSchema = <ConfectValue, ConvexValue>(\n argsSchema: Schema.Codec<ConfectValue, ConvexValue>,\n scope: IdScope.IdScope = IdScope.app,\n): PropertyValidators => {\n const ast = Schema.toEncoded(argsSchema).ast;\n\n return pipe(\n ast,\n Match.value,\n Match.tag(\"Objects\", (objectsAst) =>\n Array.isReadonlyArrayEmpty(objectsAst.indexSignatures)\n ? handlePropertySignatures(objectsAst, scope)\n : Effect.fail(new IndexSignaturesAreNotSupportedError()),\n ),\n Match.orElse(() => Effect.fail(new TopLevelMustBeObjectError())),\n Effect.runSync,\n );\n};\n\n// Returns\n\nexport const compileReturnsSchema = <ConfectValue, ConvexValue>(\n schema: Schema.Codec<ConfectValue, ConvexValue>,\n scope: IdScope.IdScope = IdScope.app,\n): Validator<any, any, any> =>\n Effect.runSync(compileAst(Schema.toEncoded(schema).ast, false, scope));\n\n// Table\n\n/**\n * Convert a table `Schema` to a table `Validator`.\n */\nexport type TableSchemaToTableValidator<\n TableSchema extends Schema.Codec<any, any>,\n> =\n ValueToValidator<TableSchema[\"Encoded\"]> extends infer Vd extends\n | VObject<any, any, any, any>\n | VUnion<any, any, any, any>\n ? Vd\n : never;\n\nexport const compileTableSchema = <TableSchema extends Schema.Codec<any, any>>(\n schema: TableSchema,\n scope: IdScope.IdScope = IdScope.app,\n): TableSchemaToTableValidator<TableSchema> => {\n const ast = Schema.toEncoded(schema).ast;\n\n return pipe(\n ast,\n Match.value,\n Match.tag(\"Objects\", ({ indexSignatures }) =>\n Array.isReadonlyArrayEmpty(indexSignatures)\n ? // oxlint-disable-next-line effecttsgo/unsafe-effect-type-assertion -- The return type is derived from the input schema and cannot be recovered from the runtime AST.\n (compileAst(ast, false, scope) as Effect.Effect<any>)\n : Effect.fail(new IndexSignaturesAreNotSupportedError()),\n ),\n Match.tag(\"Union\", (unionAst) => compileAst(unionAst, false, scope)),\n Match.orElse(() => Effect.fail(new TopLevelMustBeObjectOrUnionError())),\n Effect.runSync,\n );\n};\n\n// Compiler\n\nexport type ReadonlyValue =\n | string\n | number\n | bigint\n | boolean\n | ArrayBuffer\n | ReadonlyArrayValue\n | ReadonlyRecordValue\n | null;\n\ntype ReadonlyArrayValue = readonly ReadonlyValue[];\n\nexport type ReadonlyRecordValue = {\n readonly [key: string]: ReadonlyValue | undefined;\n};\n\ntype MutableValue<T> =\n T extends ReadonlyArray<infer El>\n ? MutableValue<El>[]\n : T extends ReadonlyRecordValue\n ? { -readonly [K in keyof T]: MutableValue<Exclude<T[K], undefined>> }\n : T;\n\nexport type ValueToValidator<Vl> = [Vl] extends [never]\n ? never\n : IsAny<Vl> extends true\n ? VAny\n : [Vl] extends [string | number | bigint | boolean | null | ArrayBuffer]\n ? ConvertValueToValidator<Vl>\n : IsRecursive<Vl> extends true\n ? VAny\n : [Vl] extends [ReadonlyValue]\n ? ConvertValueToValidator<Vl>\n : TypeError<\"Provided value is not a valid Convex value\", Vl>;\n\ntype OptionalValue<Vl, Optionality> = Optionality extends \"optional\"\n ? Vl | undefined\n : Vl;\n\ntype ConvertValueToValidator<\n Vl,\n Optionality extends \"required\" | \"optional\" = \"required\",\n> = [Vl] extends [never]\n ? never\n : IsAny<Vl> extends true\n ? VAny<any, Optionality>\n : [Vl] extends [null]\n ? VNull<OptionalValue<null, Optionality>, Optionality>\n : [Vl] extends [boolean]\n ? [boolean] extends [Vl]\n ? VBoolean<OptionalValue<boolean, Optionality>, Optionality>\n : VLiteral<OptionalValue<Vl, Optionality>, Optionality>\n : IsUnion<Vl> extends true\n ? UnionValueToValidator<Vl, Optionality>\n : [Vl] extends [number]\n ? [number] extends [Vl]\n ? VFloat64<OptionalValue<number, Optionality>, Optionality>\n : VLiteral<OptionalValue<Vl, Optionality>, Optionality>\n : [Vl] extends [bigint]\n ? [bigint] extends [Vl]\n ? VInt64<OptionalValue<bigint, Optionality>, Optionality>\n : VLiteral<OptionalValue<Vl, Optionality>, Optionality>\n : [Vl] extends [string]\n ? StringValueToValidator<Vl, Optionality>\n : [Vl] extends [ArrayBuffer]\n ? VBytes<OptionalValue<ArrayBuffer, Optionality>, Optionality>\n : IsRecursive<Vl> extends true\n ? VAny<any, Optionality>\n : Vl extends ReadonlyArray<infer El>\n ? VArray<\n OptionalValue<MutableValue<El[]>, Optionality>,\n ConvertValueToValidator<El>,\n Optionality\n >\n : Vl extends object\n ? ObjectValueToValidator<Vl, Optionality>\n : never;\n\ntype StringValueToValidator<Vl, Optionality extends \"required\" | \"optional\"> =\n Vl extends ConvexGenericId<string>\n ? VId<OptionalValue<Vl, Optionality>, Optionality>\n : [string] extends [Vl]\n ? VString<OptionalValue<string, Optionality>, Optionality>\n : VLiteral<OptionalValue<Vl, Optionality>, Optionality>;\n\ntype ObjectValueToValidator<Vl, Optionality extends \"required\" | \"optional\"> =\n IsRecord<MutableValue<Vl>> extends true\n ? ValueToValidator<Vl[keyof Vl]> extends infer VdValue extends Validator<\n any,\n \"required\",\n any\n >\n ? VRecord<\n OptionalValue<MutableValue<Vl>, Optionality>,\n VString,\n VdValue,\n Optionality\n >\n : never\n : ObjectFieldsToValidators<Vl> extends infer VdFields extends Record<\n string,\n any\n >\n ? VObject<\n OptionalValue<MutableValue<Vl>, Optionality>,\n VdFields,\n Optionality\n >\n : never;\n\ntype ObjectFieldsToValidators<Vl> = {\n -readonly [K in keyof Vl]-?: IsAny<Vl[K]> extends true\n ? IsOptional<Vl, K> extends true\n ? VAny<any, \"optional\">\n : VAny\n : undefined extends Vl[K]\n ? OptionalValueToValidator<Vl[K]>\n : [Vl[K]] extends [ReadonlyValue]\n ? ConvertValueToValidator<Vl[K]>\n : never;\n};\n\nexport type UndefinedOrValueToValidator<Vl extends ReadonlyValue | undefined> =\n undefined extends Vl\n ? OptionalValueToValidator<Vl>\n : [Vl] extends [ReadonlyValue]\n ? ValueToValidator<Vl>\n : never;\n\ntype UnionValueToValidator<Vl, Optionality extends \"required\" | \"optional\"> =\n IsRecursive<Vl> extends true\n ? VAny<any, Optionality>\n : VUnion<\n OptionalValue<MutableValue<Vl>, Optionality>,\n ValueTupleToValidatorTuple<UnionToTuple<Vl>>,\n Optionality\n >;\n\ntype ValueTupleToValidatorTuple<\n VlTuple extends readonly unknown[],\n Acc extends Validator<any, \"required\", any>[] = [],\n> = VlTuple extends\n | [true, false, ...infer VlRest]\n | [false, true, ...infer VlRest]\n ? ValueTupleToValidatorTuple<VlRest, [...Acc, VBoolean]>\n : VlTuple extends [infer Vl, ...infer VlRest]\n ? ValueTupleToValidatorTuple<VlRest, [...Acc, ConvertValueToValidator<Vl>]>\n : Acc;\n\ntype OptionalValueToValidator<Vl> = [Vl] extends [\n (infer Val extends ReadonlyValue) | undefined,\n]\n ? ConvertValueToValidator<Val, \"optional\">\n : never;\n\nexport const compileSchema = <T, E>(\n schema: Schema.Codec<T, E>,\n): ValueToValidator<(typeof schema)[\"Encoded\"]> =>\n Effect.runSync(compileAst(schema.ast)) as any;\n\nexport const isRecursive = (ast: SchemaAST.AST): boolean =>\n pipe(\n ast,\n Match.value,\n Match.tag(\n \"Literal\",\n \"Null\",\n \"Boolean\",\n \"String\",\n \"Number\",\n \"BigInt\",\n \"Unknown\",\n \"Any\",\n \"Declaration\",\n \"UniqueSymbol\",\n \"Symbol\",\n \"Undefined\",\n \"Void\",\n \"Never\",\n \"Enum\",\n \"TemplateLiteral\",\n \"ObjectKeyword\",\n () => false,\n ),\n Match.tag(\"Union\", ({ types }) =>\n Array.some(types, (type) => isRecursive(type)),\n ),\n Match.tag(\"Objects\", ({ propertySignatures }) =>\n Array.some(propertySignatures, ({ type }) => isRecursive(type)),\n ),\n Match.tag(\n \"Arrays\",\n ({ elements, rest }) =>\n Array.some(elements, (element) => isRecursive(element)) ||\n Array.some(rest, (element) => isRecursive(element)),\n ),\n Match.tag(\"Suspend\", () => true),\n Match.exhaustive,\n );\n\nexport const compileAst = (\n ast: SchemaAST.AST,\n isOptionalPropertyOfTypeLiteral = false,\n scope: IdScope.IdScope = IdScope.app,\n): Effect.Effect<\n Validator<any, any, any>,\n | UnsupportedSchemaTypeError\n | UnsupportedPropertySignatureKeyTypeError\n | IndexSignaturesAreNotSupportedError\n | MixedIndexAndPropertySignaturesAreNotSupportedError\n | OptionalTupleElementsAreNotSupportedError\n | EmptyTupleIsNotSupportedError\n | EmptyUnionIsNotSupportedError\n> =>\n isRecursive(ast)\n ? Effect.succeed(v.any())\n : pipe(\n ast,\n Match.value,\n Match.tag(\"Literal\", ({ literal }) =>\n pipe(\n literal,\n Match.value,\n Match.whenOr(\n Match.string,\n Match.number,\n Match.bigint,\n Match.boolean,\n (l) => v.literal(l),\n ),\n Match.exhaustive,\n Effect.succeed,\n ),\n ),\n Match.tag(\"Null\", () => Effect.succeed(v.null())),\n Match.tag(\"Boolean\", () => Effect.succeed(v.boolean())),\n Match.tag(\"String\", (stringAst) =>\n GenericId.tableName(stringAst).pipe(\n Option.match({\n onNone: () => Effect.succeed(v.string()),\n onSome: (tableName) =>\n Effect.succeed(\n GenericId.scope(stringAst) === scope\n ? v.id(tableName)\n : v.string(),\n ),\n }),\n ),\n ),\n Match.tag(\"Number\", () => Effect.succeed(v.float64())),\n Match.tag(\"BigInt\", () => Effect.succeed(v.int64())),\n Match.tag(\"Union\", (unionAst) =>\n handleUnion(unionAst, isOptionalPropertyOfTypeLiteral, scope),\n ),\n Match.tag(\"Objects\", (objectsAst) => handleObjects(objectsAst, scope)),\n Match.tag(\"Arrays\", (arraysAst) => handleArrays(arraysAst, scope)),\n Match.tag(\"Unknown\", \"Any\", () => Effect.succeed(v.any())),\n Match.tag(\"Declaration\", (declaration) =>\n Effect.mapBoth(\n // oxlint-disable-next-line effecttsgo/any-unknown-in-error-context -- Codec inputs are context-free, but Effect's SchemaAST.DeclarationRun erases their requirements to `any`.\n declaration.run(declaration.typeParameters)(\n new ArrayBuffer(0),\n declaration,\n {},\n ) as Effect.Effect<ArrayBuffer, unknown, never>,\n {\n onSuccess: () => v.bytes(),\n onFailure: () =>\n new UnsupportedSchemaTypeError({\n schemaType: declaration._tag,\n }),\n },\n ),\n ),\n Match.tag(\"Suspend\", () => Effect.succeed(v.any())),\n Match.tag(\n \"UniqueSymbol\",\n \"Symbol\",\n \"Undefined\",\n \"Void\",\n \"Never\",\n \"Enum\",\n \"TemplateLiteral\",\n \"ObjectKeyword\",\n () =>\n Effect.fail(\n new UnsupportedSchemaTypeError({\n schemaType: ast._tag,\n }),\n ),\n ),\n Match.exhaustive,\n );\n\nconst handleUnion = (\n { types }: SchemaAST.Union,\n isOptionalPropertyOfTypeLiteral: boolean,\n scope: IdScope.IdScope,\n) => handleUnionTypes(types, isOptionalPropertyOfTypeLiteral, scope);\n\nconst handleUnionTypes = Effect.fnUntraced(function* (\n types: SchemaAST.Union[\"types\"],\n isOptionalPropertyOfTypeLiteral: boolean,\n scope: IdScope.IdScope,\n) {\n const members = isOptionalPropertyOfTypeLiteral\n ? Array.filter(types, Predicate.not(SchemaAST.isUndefined))\n : types;\n\n const [firstValidator, secondValidator, ...restValidators] =\n yield* Effect.all(\n Array.map(members, (type) => compileAst(type, false, scope)),\n );\n\n if (firstValidator === undefined) {\n return yield* new EmptyUnionIsNotSupportedError();\n } else if (secondValidator === undefined) {\n return firstValidator;\n } else {\n return v.union(firstValidator, secondValidator, ...restValidators);\n }\n});\n\nconst handleObjects = (objectsAst: SchemaAST.Objects, scope: IdScope.IdScope) =>\n pipe(\n objectsAst.indexSignatures,\n Array.head,\n Option.match({\n onNone: () =>\n Effect.map(handlePropertySignatures(objectsAst, scope), v.object),\n onSome: ({ parameter, type }) =>\n pipe(\n objectsAst.propertySignatures,\n Array.head,\n Option.match({\n onNone: () =>\n Effect.map(\n Effect.all({\n parameter_: compileAst(parameter, false, scope),\n type_: compileAst(type, false, scope),\n }),\n ({ parameter_, type_ }) => v.record(parameter_, type_),\n ),\n onSome: () =>\n Effect.fail(\n new MixedIndexAndPropertySignaturesAreNotSupportedError(),\n ),\n }),\n ),\n }),\n );\n\nconst handleArrays = (\n { elements, rest }: SchemaAST.Arrays,\n scope: IdScope.IdScope,\n) => handleArrayElements(elements, rest, scope);\n\nconst handleArrayElements = Effect.fnUntraced(function* (\n elements: SchemaAST.Arrays[\"elements\"],\n rest: SchemaAST.Arrays[\"rest\"],\n scope: IdScope.IdScope,\n) {\n const [f, s, ...r] = elements;\n\n const elementToValidator = (element: SchemaAST.AST) =>\n SchemaAST.isOptional(element)\n ? Effect.fail(new OptionalTupleElementsAreNotSupportedError())\n : compileAst(element, false, scope);\n\n const arrayItemsValidator = yield* f === undefined\n ? pipe(\n rest,\n Array.head,\n Option.match({\n onNone: () => Effect.fail(new EmptyTupleIsNotSupportedError()),\n onSome: (type) => compileAst(type, false, scope),\n }),\n )\n : s === undefined\n ? elementToValidator(f)\n : Effect.gen(function* () {\n const firstValidator = yield* elementToValidator(f);\n const secondValidator = yield* elementToValidator(s);\n const restValidators = yield* Effect.forEach(r, elementToValidator);\n\n return v.union(firstValidator, secondValidator, ...restValidators);\n });\n\n return v.array(arrayItemsValidator);\n});\n\nconst handlePropertySignatures = (\n objectsAst: SchemaAST.Objects,\n scope: IdScope.IdScope,\n) =>\n pipe(\n objectsAst.propertySignatures,\n Effect.forEach(({ type, name }) => {\n const isOptional = SchemaAST.isOptional(type);\n if (String.isString(name)) {\n // Somehow, somewhere, keys of type number are being coerced to strings…\n return Option.match(Number.parse(name), {\n onNone: () =>\n Effect.gen(function* () {\n const validator = yield* compileAst(type, isOptional, scope);\n\n return {\n propertyName: name,\n validator: isOptional ? v.optional(validator) : validator,\n };\n }),\n onSome: (number) =>\n Effect.fail(\n new UnsupportedPropertySignatureKeyTypeError({\n propertyKey: number,\n }),\n ),\n });\n } else {\n return Effect.fail(\n new UnsupportedPropertySignatureKeyTypeError({ propertyKey: name }),\n );\n }\n }),\n Effect.andThen((propertyNamesWithValidators) =>\n pipe(\n propertyNamesWithValidators,\n Array.reduce(\n {} as Record<string, Validator<any, any, any>>,\n (acc, { propertyName, validator }) => ({\n [propertyName]: validator,\n ...acc,\n }),\n ),\n Effect.succeed,\n ),\n ),\n );\n\n// Errors\n\nexport class TopLevelMustBeObjectError extends Data.TaggedError(\n \"TopLevelMustBeObjectError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Top level schema must be an object\";\n }\n /* v8 ignore stop */\n}\n\nexport class TopLevelMustBeObjectOrUnionError extends Data.TaggedError(\n \"TopLevelMustBeObjectOrUnionError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Top level schema must be an object or a union\";\n }\n /* v8 ignore stop */\n}\n\nexport class UnsupportedPropertySignatureKeyTypeError extends Data.TaggedError(\n \"UnsupportedPropertySignatureKeyTypeError\",\n)<{\n readonly propertyKey: number | symbol;\n}> {\n /* v8 ignore start */\n override get message() {\n return `Unsupported property signature '${this.propertyKey.toString()}'. Property is of type '${typeof this.propertyKey}' but only 'string' properties are supported.`;\n }\n /* v8 ignore stop */\n}\n\nexport class EmptyTupleIsNotSupportedError extends Data.TaggedError(\n \"EmptyTupleIsNotSupportedError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Tuple must have at least one element\";\n }\n /* v8 ignore stop */\n}\n\nexport class EmptyUnionIsNotSupportedError extends Data.TaggedError(\n \"EmptyUnionIsNotSupportedError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Union must have at least one member that compiles to a validator\";\n }\n /* v8 ignore stop */\n}\n\nexport class UnsupportedSchemaTypeError extends Data.TaggedError(\n \"UnsupportedSchemaTypeError\",\n)<{\n readonly schemaType: SchemaAST.AST[\"_tag\"];\n}> {\n /* v8 ignore start */\n override get message() {\n return `Unsupported schema type '${this.schemaType}'`;\n }\n /* v8 ignore stop */\n}\n\nexport class IndexSignaturesAreNotSupportedError extends Data.TaggedError(\n \"IndexSignaturesAreNotSupportedError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Index signatures are not supported\";\n }\n /* v8 ignore stop */\n}\n\nexport class MixedIndexAndPropertySignaturesAreNotSupportedError extends Data.TaggedError(\n \"MixedIndexAndPropertySignaturesAreNotSupportedError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Mixed index and property signatures are not supported\";\n }\n /* v8 ignore stop */\n}\n\nexport class OptionalTupleElementsAreNotSupportedError extends Data.TaggedError(\n \"OptionalTupleElementsAreNotSupportedError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Optional tuple elements are not supported\";\n }\n /* v8 ignore stop */\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,MAAa,qBACX,YACA,QAAyBA,QACF;CACvB,MAAM,MAAM,OAAO,UAAU,UAAU,CAAC,CAAC;CAEzC,OAAO,KACL,KACA,MAAM,OACN,MAAM,IAAI,YAAY,eACpB,MAAM,qBAAqB,WAAW,eAAe,IACjD,yBAAyB,YAAY,KAAK,IAC1C,OAAO,KAAK,IAAI,oCAAoC,CAAC,CAC3D,GACA,MAAM,aAAa,OAAO,KAAK,IAAI,0BAA0B,CAAC,CAAC,GAC/D,OAAO,OACT;AACF;AAIA,MAAa,wBACX,QACA,QAAyBA,QAEzB,OAAO,QAAQ,WAAW,OAAO,UAAU,MAAM,CAAC,CAAC,KAAK,OAAO,KAAK,CAAC;AAgBvE,MAAa,sBACX,QACA,QAAyBA,QACoB;CAC7C,MAAM,MAAM,OAAO,UAAU,MAAM,CAAC,CAAC;CAErC,OAAO,KACL,KACA,MAAM,OACN,MAAM,IAAI,YAAY,EAAE,sBACtB,MAAM,qBAAqB,eAAe,IAErC,WAAW,KAAK,OAAO,KAAK,IAC7B,OAAO,KAAK,IAAI,oCAAoC,CAAC,CAC3D,GACA,MAAM,IAAI,UAAU,aAAa,WAAW,UAAU,OAAO,KAAK,CAAC,GACnE,MAAM,aAAa,OAAO,KAAK,IAAI,iCAAiC,CAAC,CAAC,GACtE,OAAO,OACT;AACF;AA+JA,MAAa,iBACX,WAEA,OAAO,QAAQ,WAAW,OAAO,GAAG,CAAC;AAEvC,MAAa,eAAe,QAC1B,KACE,KACA,MAAM,OACN,MAAM,IACJ,WACA,QACA,WACA,UACA,UACA,UACA,WACA,OACA,eACA,gBACA,UACA,aACA,QACA,SACA,QACA,mBACA,uBACM,KACR,GACA,MAAM,IAAI,UAAU,EAAE,YACpB,MAAM,KAAK,QAAQ,SAAS,YAAY,IAAI,CAAC,CAC/C,GACA,MAAM,IAAI,YAAY,EAAE,yBACtB,MAAM,KAAK,qBAAqB,EAAE,WAAW,YAAY,IAAI,CAAC,CAChE,GACA,MAAM,IACJ,WACC,EAAE,UAAU,WACX,MAAM,KAAK,WAAW,YAAY,YAAY,OAAO,CAAC,KACtD,MAAM,KAAK,OAAO,YAAY,YAAY,OAAO,CAAC,CACtD,GACA,MAAM,IAAI,iBAAiB,IAAI,GAC/B,MAAM,UACR;AAEF,MAAa,cACX,KACA,kCAAkC,OAClC,UAAyBA,QAWzB,YAAY,GAAG,IACX,OAAO,QAAQ,EAAE,IAAI,CAAC,IACtB,KACE,KACA,MAAM,OACN,MAAM,IAAI,YAAY,EAAE,cACtB,KACE,SACA,MAAM,OACN,MAAM,OACJ,MAAM,QACN,MAAM,QACN,MAAM,QACN,MAAM,UACL,MAAM,EAAE,QAAQ,CAAC,CACpB,GACA,MAAM,YACN,OAAO,OACT,CACF,GACA,MAAM,IAAI,cAAc,OAAO,QAAQ,EAAE,KAAK,CAAC,CAAC,GAChD,MAAM,IAAI,iBAAiB,OAAO,QAAQ,EAAE,QAAQ,CAAC,CAAC,GACtD,MAAM,IAAI,WAAW,cACnBC,UAAoB,SAAS,CAAC,CAAC,KAC7B,OAAO,MAAM;CACX,cAAc,OAAO,QAAQ,EAAE,OAAO,CAAC;CACvC,SAAS,cACP,OAAO,QACLC,MAAgB,SAAS,MAAMC,UAC3B,EAAE,GAAG,SAAS,IACd,EAAE,OAAO,CACf;AACJ,CAAC,CACH,CACF,GACA,MAAM,IAAI,gBAAgB,OAAO,QAAQ,EAAE,QAAQ,CAAC,CAAC,GACrD,MAAM,IAAI,gBAAgB,OAAO,QAAQ,EAAE,MAAM,CAAC,CAAC,GACnD,MAAM,IAAI,UAAU,aAClB,YAAY,UAAU,iCAAiCA,OAAK,CAC9D,GACA,MAAM,IAAI,YAAY,eAAe,cAAc,YAAYA,OAAK,CAAC,GACrE,MAAM,IAAI,WAAW,cAAc,aAAa,WAAWA,OAAK,CAAC,GACjE,MAAM,IAAI,WAAW,aAAa,OAAO,QAAQ,EAAE,IAAI,CAAC,CAAC,GACzD,MAAM,IAAI,gBAAgB,gBACxB,OAAO,QAEL,YAAY,IAAI,YAAY,cAAc,CAAC,iBACzC,IAAI,YAAY,CAAC,GACjB,aACA,CAAC,CACH,GACA;CACE,iBAAiB,EAAE,MAAM;CACzB,iBACE,IAAI,2BAA2B,EAC7B,YAAY,YAAY,KAC1B,CAAC;AACL,CACF,CACF,GACA,MAAM,IAAI,iBAAiB,OAAO,QAAQ,EAAE,IAAI,CAAC,CAAC,GAClD,MAAM,IACJ,gBACA,UACA,aACA,QACA,SACA,QACA,mBACA,uBAEE,OAAO,KACL,IAAI,2BAA2B,EAC7B,YAAY,IAAI,KAClB,CAAC,CACH,CACJ,GACA,MAAM,UACR;AAEN,MAAM,eACJ,EAAE,SACF,iCACA,UACG,iBAAiB,OAAO,iCAAiC,KAAK;AAEnE,MAAM,mBAAmB,OAAO,WAAW,WACzC,OACA,iCACA,OACA;CACA,MAAM,UAAU,kCACZ,MAAM,OAAO,OAAO,UAAU,IAAI,UAAU,WAAW,CAAC,IACxD;CAEJ,MAAM,CAAC,gBAAgB,iBAAiB,GAAG,kBACzC,OAAO,OAAO,IACZ,MAAM,IAAI,UAAU,SAAS,WAAW,MAAM,OAAO,KAAK,CAAC,CAC7D;CAEF,IAAI,mBAAmB,KAAA,GACrB,OAAO,OAAO,IAAI,8BAA8B;MAC3C,IAAI,oBAAoB,KAAA,GAC7B,OAAO;MAEP,OAAO,EAAE,MAAM,gBAAgB,iBAAiB,GAAG,cAAc;AAErE,CAAC;AAED,MAAM,iBAAiB,YAA+B,UACpD,KACE,WAAW,iBACX,MAAM,MACN,OAAO,MAAM;CACX,cACE,OAAO,IAAI,yBAAyB,YAAY,KAAK,GAAG,EAAE,MAAM;CAClE,SAAS,EAAE,WAAW,WACpB,KACE,WAAW,oBACX,MAAM,MACN,OAAO,MAAM;EACX,cACE,OAAO,IACL,OAAO,IAAI;GACT,YAAY,WAAW,WAAW,OAAO,KAAK;GAC9C,OAAO,WAAW,MAAM,OAAO,KAAK;EACtC,CAAC,IACA,EAAE,YAAY,YAAY,EAAE,OAAO,YAAY,KAAK,CACvD;EACF,cACE,OAAO,KACL,IAAI,oDAAoD,CAC1D;CACJ,CAAC,CACH;AACJ,CAAC,CACH;AAEF,MAAM,gBACJ,EAAE,UAAU,QACZ,UACG,oBAAoB,UAAU,MAAM,KAAK;AAE9C,MAAM,sBAAsB,OAAO,WAAW,WAC5C,UACA,MACA,OACA;CACA,MAAM,CAAC,GAAG,GAAG,GAAG,KAAK;CAErB,MAAM,sBAAsB,YAC1B,UAAU,WAAW,OAAO,IACxB,OAAO,KAAK,IAAI,0CAA0C,CAAC,IAC3D,WAAW,SAAS,OAAO,KAAK;CAEtC,MAAM,sBAAsB,OAAO,MAAM,KAAA,IACrC,KACE,MACA,MAAM,MACN,OAAO,MAAM;EACX,cAAc,OAAO,KAAK,IAAI,8BAA8B,CAAC;EAC7D,SAAS,SAAS,WAAW,MAAM,OAAO,KAAK;CACjD,CAAC,CACH,IACA,MAAM,KAAA,IACJ,mBAAmB,CAAC,IACpB,OAAO,IAAI,aAAa;EACtB,MAAM,iBAAiB,OAAO,mBAAmB,CAAC;EAClD,MAAM,kBAAkB,OAAO,mBAAmB,CAAC;EACnD,MAAM,iBAAiB,OAAO,OAAO,QAAQ,GAAG,kBAAkB;EAElE,OAAO,EAAE,MAAM,gBAAgB,iBAAiB,GAAG,cAAc;CACnE,CAAC;CAEP,OAAO,EAAE,MAAM,mBAAmB;AACpC,CAAC;AAED,MAAM,4BACJ,YACA,UAEA,KACE,WAAW,oBACX,OAAO,SAAS,EAAE,MAAM,WAAW;CACjC,MAAM,aAAa,UAAU,WAAW,IAAI;CAC5C,IAAI,OAAO,SAAS,IAAI,GAEtB,OAAO,OAAO,MAAM,OAAO,MAAM,IAAI,GAAG;EACtC,cACE,OAAO,IAAI,aAAa;GACtB,MAAM,YAAY,OAAO,WAAW,MAAM,YAAY,KAAK;GAE3D,OAAO;IACL,cAAc;IACd,WAAW,aAAa,EAAE,SAAS,SAAS,IAAI;GAClD;EACF,CAAC;EACH,SAAS,WACP,OAAO,KACL,IAAI,yCAAyC,EAC3C,aAAa,OACf,CAAC,CACH;CACJ,CAAC;MAED,OAAO,OAAO,KACZ,IAAI,yCAAyC,EAAE,aAAa,KAAK,CAAC,CACpE;AAEJ,CAAC,GACD,OAAO,SAAS,gCACd,KACE,6BACA,MAAM,OACJ,CAAC,IACA,KAAK,EAAE,cAAc,iBAAiB;EACpC,eAAe;CAChB,GAAG;AACL,EACF,GACA,OAAO,OACT,CACF,CACF;AAIF,IAAa,4BAAb,cAA+C,KAAK,YAClD,2BACF,CAAC,CAAC;;CAEA,IAAa,UAAU;EACrB,OAAO;CACT;AAEF;AAEA,IAAa,mCAAb,cAAsD,KAAK,YACzD,kCACF,CAAC,CAAC;;CAEA,IAAa,UAAU;EACrB,OAAO;CACT;AAEF;AAEA,IAAa,2CAAb,cAA8D,KAAK,YACjE,0CACF,CAAC,CAEE;;CAED,IAAa,UAAU;EACrB,OAAO,mCAAmC,KAAK,YAAY,SAAS,EAAE,0BAA0B,OAAO,KAAK,YAAY;CAC1H;AAEF;AAEA,IAAa,gCAAb,cAAmD,KAAK,YACtD,+BACF,CAAC,CAAC;;CAEA,IAAa,UAAU;EACrB,OAAO;CACT;AAEF;AAEA,IAAa,gCAAb,cAAmD,KAAK,YACtD,+BACF,CAAC,CAAC;;CAEA,IAAa,UAAU;EACrB,OAAO;CACT;AAEF;AAEA,IAAa,6BAAb,cAAgD,KAAK,YACnD,4BACF,CAAC,CAEE;;CAED,IAAa,UAAU;EACrB,OAAO,4BAA4B,KAAK,WAAW;CACrD;AAEF;AAEA,IAAa,sCAAb,cAAyD,KAAK,YAC5D,qCACF,CAAC,CAAC;;CAEA,IAAa,UAAU;EACrB,OAAO;CACT;AAEF;AAEA,IAAa,sDAAb,cAAyE,KAAK,YAC5E,qDACF,CAAC,CAAC;;CAEA,IAAa,UAAU;EACrB,OAAO;CACT;AAEF;AAEA,IAAa,4CAAb,cAA+D,KAAK,YAClE,2CACF,CAAC,CAAC;;CAEA,IAAa,UAAU;EACrB,OAAO;CACT;AAEF"}
|
|
1
|
+
{"version":3,"file":"SchemaToValidator.js","names":["IdScope.app","GenericId.tableName","GenericId.scope","scope"],"sources":["../src/SchemaToValidator.ts"],"sourcesContent":["import * as IdScope from \"./IdScope.js\";\nimport type {\n GenericId as ConvexGenericId,\n PropertyValidators,\n Validator,\n VAny,\n VArray,\n VBoolean,\n VBytes,\n VFloat64,\n VId,\n VInt64,\n VLiteral,\n VNull,\n VObject,\n VRecord,\n VString,\n VUnion,\n} from \"convex/values\";\nimport { v } from \"convex/values\";\nimport { pipe } from \"effect/Function\";\nimport * as Array from \"effect/Array\";\nimport * as Data from \"effect/Data\";\nimport * as Effect from \"effect/Effect\";\nimport * as Match from \"effect/Match\";\nimport * as Number from \"effect/Number\";\nimport * as Option from \"effect/Option\";\nimport * as Predicate from \"effect/Predicate\";\nimport * as Schema from \"effect/Schema\";\nimport * as SchemaAST from \"effect/SchemaAST\";\nimport * as String from \"effect/String\";\n\nimport * as GenericId from \"./GenericId.js\";\nimport type {\n IsAny,\n IsOptional,\n IsRecord,\n IsRecursive,\n IsUnion,\n TypeError,\n UnionToTuple,\n} from \"./Types.js\";\n\n// Args\n\nexport const compileArgsSchema = <ConfectValue, ConvexValue>(\n argsSchema: Schema.Codec<ConfectValue, ConvexValue>,\n scope: IdScope.IdScope = IdScope.app,\n reservedArgument?: string,\n functionName?: string,\n): PropertyValidators => {\n const ast = Schema.toEncoded(argsSchema).ast;\n\n const validators = pipe(\n ast,\n Match.value,\n Match.tag(\"Objects\", (objectsAst) =>\n Array.isReadonlyArrayEmpty(objectsAst.indexSignatures)\n ? handlePropertySignatures(objectsAst, scope)\n : Effect.fail(new IndexSignaturesAreNotSupportedError()),\n ),\n Match.orElse(() => Effect.fail(new TopLevelMustBeObjectError())),\n Effect.runSync,\n );\n if (reservedArgument === undefined) return validators;\n if (Object.hasOwn(validators, reservedArgument)) {\n throw new ReservedArgumentCollision({\n functionName,\n argument: reservedArgument,\n });\n }\n return { ...validators, [reservedArgument]: v.optional(v.any()) };\n};\n\nexport class ReservedArgumentCollision extends Data.TaggedError(\n \"ReservedArgumentCollision\",\n)<{\n readonly functionName: string | undefined;\n readonly argument: string;\n}> {\n override get message() {\n return `${this.functionName} declares the argument \"${this.argument}\", which its profile reserves. Rename the argument.`;\n }\n}\n\n// Returns\n\nexport const compileReturnsSchema = <ConfectValue, ConvexValue>(\n schema: Schema.Codec<ConfectValue, ConvexValue>,\n scope: IdScope.IdScope = IdScope.app,\n): Validator<any, any, any> =>\n Effect.runSync(compileAst(Schema.toEncoded(schema).ast, false, scope));\n\n// Table\n\n/**\n * Convert a table `Schema` to a table `Validator`.\n */\nexport type TableSchemaToTableValidator<\n TableSchema extends Schema.Codec<any, any>,\n> =\n ValueToValidator<TableSchema[\"Encoded\"]> extends infer Vd extends\n | VObject<any, any, any, any>\n | VUnion<any, any, any, any>\n ? Vd\n : never;\n\nexport const compileTableSchema = <TableSchema extends Schema.Codec<any, any>>(\n schema: TableSchema,\n scope: IdScope.IdScope = IdScope.app,\n): TableSchemaToTableValidator<TableSchema> => {\n const ast = Schema.toEncoded(schema).ast;\n\n return pipe(\n ast,\n Match.value,\n Match.tag(\"Objects\", ({ indexSignatures }) =>\n Array.isReadonlyArrayEmpty(indexSignatures)\n ? // oxlint-disable-next-line effecttsgo/unsafe-effect-type-assertion -- The return type is derived from the input schema and cannot be recovered from the runtime AST.\n (compileAst(ast, false, scope) as Effect.Effect<any>)\n : Effect.fail(new IndexSignaturesAreNotSupportedError()),\n ),\n Match.tag(\"Union\", (unionAst) => compileAst(unionAst, false, scope)),\n Match.orElse(() => Effect.fail(new TopLevelMustBeObjectOrUnionError())),\n Effect.runSync,\n );\n};\n\n// Compiler\n\nexport type ReadonlyValue =\n | string\n | number\n | bigint\n | boolean\n | ArrayBuffer\n | ReadonlyArrayValue\n | ReadonlyRecordValue\n | null;\n\ntype ReadonlyArrayValue = readonly ReadonlyValue[];\n\nexport type ReadonlyRecordValue = {\n readonly [key: string]: ReadonlyValue | undefined;\n};\n\ntype MutableValue<T> =\n T extends ReadonlyArray<infer El>\n ? MutableValue<El>[]\n : T extends ReadonlyRecordValue\n ? { -readonly [K in keyof T]: MutableValue<Exclude<T[K], undefined>> }\n : T;\n\nexport type ValueToValidator<Vl> = [Vl] extends [never]\n ? never\n : IsAny<Vl> extends true\n ? VAny\n : [Vl] extends [string | number | bigint | boolean | null | ArrayBuffer]\n ? ConvertValueToValidator<Vl>\n : IsRecursive<Vl> extends true\n ? VAny\n : [Vl] extends [ReadonlyValue]\n ? ConvertValueToValidator<Vl>\n : TypeError<\"Provided value is not a valid Convex value\", Vl>;\n\ntype OptionalValue<Vl, Optionality> = Optionality extends \"optional\"\n ? Vl | undefined\n : Vl;\n\ntype ConvertValueToValidator<\n Vl,\n Optionality extends \"required\" | \"optional\" = \"required\",\n> = [Vl] extends [never]\n ? never\n : IsAny<Vl> extends true\n ? VAny<any, Optionality>\n : [Vl] extends [null]\n ? VNull<OptionalValue<null, Optionality>, Optionality>\n : [Vl] extends [boolean]\n ? [boolean] extends [Vl]\n ? VBoolean<OptionalValue<boolean, Optionality>, Optionality>\n : VLiteral<OptionalValue<Vl, Optionality>, Optionality>\n : IsUnion<Vl> extends true\n ? UnionValueToValidator<Vl, Optionality>\n : [Vl] extends [number]\n ? [number] extends [Vl]\n ? VFloat64<OptionalValue<number, Optionality>, Optionality>\n : VLiteral<OptionalValue<Vl, Optionality>, Optionality>\n : [Vl] extends [bigint]\n ? [bigint] extends [Vl]\n ? VInt64<OptionalValue<bigint, Optionality>, Optionality>\n : VLiteral<OptionalValue<Vl, Optionality>, Optionality>\n : [Vl] extends [string]\n ? StringValueToValidator<Vl, Optionality>\n : [Vl] extends [ArrayBuffer]\n ? VBytes<OptionalValue<ArrayBuffer, Optionality>, Optionality>\n : IsRecursive<Vl> extends true\n ? VAny<any, Optionality>\n : Vl extends ReadonlyArray<infer El>\n ? VArray<\n OptionalValue<MutableValue<El[]>, Optionality>,\n ConvertValueToValidator<El>,\n Optionality\n >\n : Vl extends object\n ? ObjectValueToValidator<Vl, Optionality>\n : never;\n\ntype StringValueToValidator<Vl, Optionality extends \"required\" | \"optional\"> =\n Vl extends ConvexGenericId<string>\n ? VId<OptionalValue<Vl, Optionality>, Optionality>\n : [string] extends [Vl]\n ? VString<OptionalValue<string, Optionality>, Optionality>\n : VLiteral<OptionalValue<Vl, Optionality>, Optionality>;\n\ntype ObjectValueToValidator<Vl, Optionality extends \"required\" | \"optional\"> =\n IsRecord<MutableValue<Vl>> extends true\n ? ValueToValidator<Vl[keyof Vl]> extends infer VdValue extends Validator<\n any,\n \"required\",\n any\n >\n ? VRecord<\n OptionalValue<MutableValue<Vl>, Optionality>,\n VString,\n VdValue,\n Optionality\n >\n : never\n : ObjectFieldsToValidators<Vl> extends infer VdFields extends Record<\n string,\n any\n >\n ? VObject<\n OptionalValue<MutableValue<Vl>, Optionality>,\n VdFields,\n Optionality\n >\n : never;\n\ntype ObjectFieldsToValidators<Vl> = {\n -readonly [K in keyof Vl]-?: IsAny<Vl[K]> extends true\n ? IsOptional<Vl, K> extends true\n ? VAny<any, \"optional\">\n : VAny\n : undefined extends Vl[K]\n ? OptionalValueToValidator<Vl[K]>\n : [Vl[K]] extends [ReadonlyValue]\n ? ConvertValueToValidator<Vl[K]>\n : never;\n};\n\nexport type UndefinedOrValueToValidator<Vl extends ReadonlyValue | undefined> =\n undefined extends Vl\n ? OptionalValueToValidator<Vl>\n : [Vl] extends [ReadonlyValue]\n ? ValueToValidator<Vl>\n : never;\n\ntype UnionValueToValidator<Vl, Optionality extends \"required\" | \"optional\"> =\n IsRecursive<Vl> extends true\n ? VAny<any, Optionality>\n : VUnion<\n OptionalValue<MutableValue<Vl>, Optionality>,\n ValueTupleToValidatorTuple<UnionToTuple<Vl>>,\n Optionality\n >;\n\ntype ValueTupleToValidatorTuple<\n VlTuple extends readonly unknown[],\n Acc extends Validator<any, \"required\", any>[] = [],\n> = VlTuple extends\n | [true, false, ...infer VlRest]\n | [false, true, ...infer VlRest]\n ? ValueTupleToValidatorTuple<VlRest, [...Acc, VBoolean]>\n : VlTuple extends [infer Vl, ...infer VlRest]\n ? ValueTupleToValidatorTuple<VlRest, [...Acc, ConvertValueToValidator<Vl>]>\n : Acc;\n\ntype OptionalValueToValidator<Vl> = [Vl] extends [\n (infer Val extends ReadonlyValue) | undefined,\n]\n ? ConvertValueToValidator<Val, \"optional\">\n : never;\n\nexport const compileSchema = <T, E>(\n schema: Schema.Codec<T, E>,\n): ValueToValidator<(typeof schema)[\"Encoded\"]> =>\n Effect.runSync(compileAst(schema.ast)) as any;\n\nexport const isRecursive = (ast: SchemaAST.AST): boolean =>\n pipe(\n ast,\n Match.value,\n Match.tag(\n \"Literal\",\n \"Null\",\n \"Boolean\",\n \"String\",\n \"Number\",\n \"BigInt\",\n \"Unknown\",\n \"Any\",\n \"Declaration\",\n \"UniqueSymbol\",\n \"Symbol\",\n \"Undefined\",\n \"Void\",\n \"Never\",\n \"Enum\",\n \"TemplateLiteral\",\n \"ObjectKeyword\",\n () => false,\n ),\n Match.tag(\"Union\", ({ types }) =>\n Array.some(types, (type) => isRecursive(type)),\n ),\n Match.tag(\"Objects\", ({ propertySignatures }) =>\n Array.some(propertySignatures, ({ type }) => isRecursive(type)),\n ),\n Match.tag(\n \"Arrays\",\n ({ elements, rest }) =>\n Array.some(elements, (element) => isRecursive(element)) ||\n Array.some(rest, (element) => isRecursive(element)),\n ),\n Match.tag(\"Suspend\", () => true),\n Match.exhaustive,\n );\n\nexport const compileAst = (\n ast: SchemaAST.AST,\n isOptionalPropertyOfTypeLiteral = false,\n scope: IdScope.IdScope = IdScope.app,\n): Effect.Effect<\n Validator<any, any, any>,\n | UnsupportedSchemaTypeError\n | UnsupportedPropertySignatureKeyTypeError\n | IndexSignaturesAreNotSupportedError\n | MixedIndexAndPropertySignaturesAreNotSupportedError\n | OptionalTupleElementsAreNotSupportedError\n | EmptyTupleIsNotSupportedError\n | EmptyUnionIsNotSupportedError\n> =>\n isRecursive(ast)\n ? Effect.succeed(v.any())\n : pipe(\n ast,\n Match.value,\n Match.tag(\"Literal\", ({ literal }) =>\n pipe(\n literal,\n Match.value,\n Match.whenOr(\n Match.string,\n Match.number,\n Match.bigint,\n Match.boolean,\n (l) => v.literal(l),\n ),\n Match.exhaustive,\n Effect.succeed,\n ),\n ),\n Match.tag(\"Null\", () => Effect.succeed(v.null())),\n Match.tag(\"Boolean\", () => Effect.succeed(v.boolean())),\n Match.tag(\"String\", (stringAst) =>\n GenericId.tableName(stringAst).pipe(\n Option.match({\n onNone: () => Effect.succeed(v.string()),\n onSome: (tableName) =>\n Effect.succeed(\n GenericId.scope(stringAst) === scope\n ? v.id(tableName)\n : v.string(),\n ),\n }),\n ),\n ),\n Match.tag(\"Number\", () => Effect.succeed(v.float64())),\n Match.tag(\"BigInt\", () => Effect.succeed(v.int64())),\n Match.tag(\"Union\", (unionAst) =>\n handleUnion(unionAst, isOptionalPropertyOfTypeLiteral, scope),\n ),\n Match.tag(\"Objects\", (objectsAst) => handleObjects(objectsAst, scope)),\n Match.tag(\"Arrays\", (arraysAst) => handleArrays(arraysAst, scope)),\n Match.tag(\"Unknown\", \"Any\", () => Effect.succeed(v.any())),\n Match.tag(\"Declaration\", (declaration) =>\n Effect.mapBoth(\n // oxlint-disable-next-line effecttsgo/any-unknown-in-error-context -- Codec inputs are context-free, but Effect's SchemaAST.DeclarationRun erases their requirements to `any`.\n declaration.run(declaration.typeParameters)(\n new ArrayBuffer(0),\n declaration,\n {},\n ) as Effect.Effect<ArrayBuffer, unknown, never>,\n {\n onSuccess: () => v.bytes(),\n onFailure: () =>\n new UnsupportedSchemaTypeError({\n schemaType: declaration._tag,\n }),\n },\n ),\n ),\n Match.tag(\"Suspend\", () => Effect.succeed(v.any())),\n Match.tag(\n \"UniqueSymbol\",\n \"Symbol\",\n \"Undefined\",\n \"Void\",\n \"Never\",\n \"Enum\",\n \"TemplateLiteral\",\n \"ObjectKeyword\",\n () =>\n Effect.fail(\n new UnsupportedSchemaTypeError({\n schemaType: ast._tag,\n }),\n ),\n ),\n Match.exhaustive,\n );\n\nconst handleUnion = (\n { types }: SchemaAST.Union,\n isOptionalPropertyOfTypeLiteral: boolean,\n scope: IdScope.IdScope,\n) => handleUnionTypes(types, isOptionalPropertyOfTypeLiteral, scope);\n\nconst handleUnionTypes = Effect.fnUntraced(function* (\n types: SchemaAST.Union[\"types\"],\n isOptionalPropertyOfTypeLiteral: boolean,\n scope: IdScope.IdScope,\n) {\n const members = isOptionalPropertyOfTypeLiteral\n ? Array.filter(types, Predicate.not(SchemaAST.isUndefined))\n : types;\n\n const [firstValidator, secondValidator, ...restValidators] =\n yield* Effect.all(\n Array.map(members, (type) => compileAst(type, false, scope)),\n );\n\n if (firstValidator === undefined) {\n return yield* new EmptyUnionIsNotSupportedError();\n } else if (secondValidator === undefined) {\n return firstValidator;\n } else {\n return v.union(firstValidator, secondValidator, ...restValidators);\n }\n});\n\nconst handleObjects = (objectsAst: SchemaAST.Objects, scope: IdScope.IdScope) =>\n pipe(\n objectsAst.indexSignatures,\n Array.head,\n Option.match({\n onNone: () =>\n Effect.map(handlePropertySignatures(objectsAst, scope), v.object),\n onSome: ({ parameter, type }) =>\n pipe(\n objectsAst.propertySignatures,\n Array.head,\n Option.match({\n onNone: () =>\n Effect.map(\n Effect.all({\n parameter_: compileAst(parameter, false, scope),\n type_: compileAst(type, false, scope),\n }),\n ({ parameter_, type_ }) => v.record(parameter_, type_),\n ),\n onSome: () =>\n Effect.fail(\n new MixedIndexAndPropertySignaturesAreNotSupportedError(),\n ),\n }),\n ),\n }),\n );\n\nconst handleArrays = (\n { elements, rest }: SchemaAST.Arrays,\n scope: IdScope.IdScope,\n) => handleArrayElements(elements, rest, scope);\n\nconst handleArrayElements = Effect.fnUntraced(function* (\n elements: SchemaAST.Arrays[\"elements\"],\n rest: SchemaAST.Arrays[\"rest\"],\n scope: IdScope.IdScope,\n) {\n const [f, s, ...r] = elements;\n\n const elementToValidator = (element: SchemaAST.AST) =>\n SchemaAST.isOptional(element)\n ? Effect.fail(new OptionalTupleElementsAreNotSupportedError())\n : compileAst(element, false, scope);\n\n const arrayItemsValidator = yield* f === undefined\n ? pipe(\n rest,\n Array.head,\n Option.match({\n onNone: () => Effect.fail(new EmptyTupleIsNotSupportedError()),\n onSome: (type) => compileAst(type, false, scope),\n }),\n )\n : s === undefined\n ? elementToValidator(f)\n : Effect.gen(function* () {\n const firstValidator = yield* elementToValidator(f);\n const secondValidator = yield* elementToValidator(s);\n const restValidators = yield* Effect.forEach(r, elementToValidator);\n\n return v.union(firstValidator, secondValidator, ...restValidators);\n });\n\n return v.array(arrayItemsValidator);\n});\n\nconst handlePropertySignatures = (\n objectsAst: SchemaAST.Objects,\n scope: IdScope.IdScope,\n) =>\n pipe(\n objectsAst.propertySignatures,\n Effect.forEach(({ type, name }) => {\n const isOptional = SchemaAST.isOptional(type);\n if (String.isString(name)) {\n // Somehow, somewhere, keys of type number are being coerced to strings…\n return Option.match(Number.parse(name), {\n onNone: () =>\n Effect.gen(function* () {\n const validator = yield* compileAst(type, isOptional, scope);\n\n return {\n propertyName: name,\n validator: isOptional ? v.optional(validator) : validator,\n };\n }),\n onSome: (number) =>\n Effect.fail(\n new UnsupportedPropertySignatureKeyTypeError({\n propertyKey: number,\n }),\n ),\n });\n } else {\n return Effect.fail(\n new UnsupportedPropertySignatureKeyTypeError({ propertyKey: name }),\n );\n }\n }),\n Effect.andThen((propertyNamesWithValidators) =>\n pipe(\n propertyNamesWithValidators,\n Array.reduce(\n {} as Record<string, Validator<any, any, any>>,\n (acc, { propertyName, validator }) => ({\n [propertyName]: validator,\n ...acc,\n }),\n ),\n Effect.succeed,\n ),\n ),\n );\n\n// Errors\n\nexport class TopLevelMustBeObjectError extends Data.TaggedError(\n \"TopLevelMustBeObjectError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Top level schema must be an object\";\n }\n /* v8 ignore stop */\n}\n\nexport class TopLevelMustBeObjectOrUnionError extends Data.TaggedError(\n \"TopLevelMustBeObjectOrUnionError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Top level schema must be an object or a union\";\n }\n /* v8 ignore stop */\n}\n\nexport class UnsupportedPropertySignatureKeyTypeError extends Data.TaggedError(\n \"UnsupportedPropertySignatureKeyTypeError\",\n)<{\n readonly propertyKey: number | symbol;\n}> {\n /* v8 ignore start */\n override get message() {\n return `Unsupported property signature '${this.propertyKey.toString()}'. Property is of type '${typeof this.propertyKey}' but only 'string' properties are supported.`;\n }\n /* v8 ignore stop */\n}\n\nexport class EmptyTupleIsNotSupportedError extends Data.TaggedError(\n \"EmptyTupleIsNotSupportedError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Tuple must have at least one element\";\n }\n /* v8 ignore stop */\n}\n\nexport class EmptyUnionIsNotSupportedError extends Data.TaggedError(\n \"EmptyUnionIsNotSupportedError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Union must have at least one member that compiles to a validator\";\n }\n /* v8 ignore stop */\n}\n\nexport class UnsupportedSchemaTypeError extends Data.TaggedError(\n \"UnsupportedSchemaTypeError\",\n)<{\n readonly schemaType: SchemaAST.AST[\"_tag\"];\n}> {\n /* v8 ignore start */\n override get message() {\n return `Unsupported schema type '${this.schemaType}'`;\n }\n /* v8 ignore stop */\n}\n\nexport class IndexSignaturesAreNotSupportedError extends Data.TaggedError(\n \"IndexSignaturesAreNotSupportedError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Index signatures are not supported\";\n }\n /* v8 ignore stop */\n}\n\nexport class MixedIndexAndPropertySignaturesAreNotSupportedError extends Data.TaggedError(\n \"MixedIndexAndPropertySignaturesAreNotSupportedError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Mixed index and property signatures are not supported\";\n }\n /* v8 ignore stop */\n}\n\nexport class OptionalTupleElementsAreNotSupportedError extends Data.TaggedError(\n \"OptionalTupleElementsAreNotSupportedError\",\n) {\n /* v8 ignore start */\n override get message() {\n return \"Optional tuple elements are not supported\";\n }\n /* v8 ignore stop */\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/Component.ts
CHANGED
package/src/FunctionSpec.ts
CHANGED
|
@@ -32,6 +32,7 @@ export interface FunctionSpec<
|
|
|
32
32
|
readonly runtimeAndFunctionType: RuntimeAndFunctionType_;
|
|
33
33
|
readonly functionVisibility: FunctionVisibility_;
|
|
34
34
|
readonly name: Name_;
|
|
35
|
+
readonly reservedArgument?: string;
|
|
35
36
|
readonly functionProvenance: FunctionProvenance_;
|
|
36
37
|
readonly middlewareSpecs: ReadonlyArray<MiddlewareSpecs_>;
|
|
37
38
|
readonly middlewareAttachments: ReadonlyArray<
|
|
@@ -402,6 +403,9 @@ const Proto = {
|
|
|
402
403
|
runtimeAndFunctionType: this.runtimeAndFunctionType,
|
|
403
404
|
functionVisibility: this.functionVisibility,
|
|
404
405
|
name: this.name,
|
|
406
|
+
...(this.reservedArgument === undefined
|
|
407
|
+
? {}
|
|
408
|
+
: { reservedArgument: this.reservedArgument }),
|
|
405
409
|
...("description" in this ? { description: this.description } : {}),
|
|
406
410
|
...("fields" in this ? { fields: this.fields } : {}),
|
|
407
411
|
functionProvenance: this.functionProvenance,
|
|
@@ -414,6 +418,7 @@ const Proto = {
|
|
|
414
418
|
} satisfies ThisType<AnyWithProps>;
|
|
415
419
|
|
|
416
420
|
interface Options {
|
|
421
|
+
readonly reservedArgument?: string;
|
|
417
422
|
readonly description?: string;
|
|
418
423
|
readonly name: string;
|
|
419
424
|
readonly args?: () => FunctionProvenance.ArgsFields;
|
|
@@ -434,6 +439,9 @@ const make = <
|
|
|
434
439
|
Returns_ extends Schema.Codec<any, any>,
|
|
435
440
|
Error_ extends Schema.Codec<any, any> = never,
|
|
436
441
|
>(options: {
|
|
442
|
+
reservedArgument?: RuntimeAndFunctionType_["functionType"] extends "query"
|
|
443
|
+
? never
|
|
444
|
+
: string;
|
|
437
445
|
name: Name_;
|
|
438
446
|
description?: never;
|
|
439
447
|
args: () => ArgsFields_;
|
|
@@ -450,6 +458,9 @@ const make = <
|
|
|
450
458
|
Returns_ extends Schema.Codec<any, any>,
|
|
451
459
|
Error_ extends Schema.Codec<any, any> = never,
|
|
452
460
|
>(options: {
|
|
461
|
+
reservedArgument?: RuntimeAndFunctionType_["functionType"] extends "query"
|
|
462
|
+
? never
|
|
463
|
+
: string;
|
|
453
464
|
name: Name_;
|
|
454
465
|
description?: never;
|
|
455
466
|
args?: never;
|
|
@@ -467,6 +478,9 @@ const make = <
|
|
|
467
478
|
Returns_ extends Schema.Codec<any, any>,
|
|
468
479
|
Error_ extends Schema.Codec<any, any> = never,
|
|
469
480
|
>(options: {
|
|
481
|
+
reservedArgument?: RuntimeAndFunctionType_["functionType"] extends "query"
|
|
482
|
+
? never
|
|
483
|
+
: string;
|
|
470
484
|
name: Name_;
|
|
471
485
|
description?: FunctionVisibility_ extends "public" ? string : never;
|
|
472
486
|
args: () => ArgsFields_;
|
|
@@ -483,6 +497,9 @@ const make = <
|
|
|
483
497
|
Returns_ extends Schema.Codec<any, any>,
|
|
484
498
|
Error_ extends Schema.Codec<any, any> = never,
|
|
485
499
|
>(options: {
|
|
500
|
+
reservedArgument?: RuntimeAndFunctionType_["functionType"] extends "query"
|
|
501
|
+
? never
|
|
502
|
+
: string;
|
|
486
503
|
name: Name_;
|
|
487
504
|
description?: FunctionVisibility_ extends "public" ? string : never;
|
|
488
505
|
args?: never;
|
|
@@ -494,13 +511,24 @@ const make = <
|
|
|
494
511
|
Name_,
|
|
495
512
|
FunctionProvenance.Confect<{}, Returns_, Error_>
|
|
496
513
|
>;
|
|
497
|
-
function makeSpec({
|
|
514
|
+
function makeSpec({
|
|
515
|
+
name,
|
|
516
|
+
description,
|
|
517
|
+
args,
|
|
518
|
+
returns,
|
|
519
|
+
error,
|
|
520
|
+
reservedArgument,
|
|
521
|
+
}: Options) {
|
|
498
522
|
validateConfectFunctionIdentifier(name);
|
|
499
523
|
|
|
500
524
|
return Object.assign(Object.create(Proto), {
|
|
501
525
|
runtimeAndFunctionType,
|
|
502
526
|
functionVisibility,
|
|
503
527
|
name,
|
|
528
|
+
...(runtimeAndFunctionType.functionType !== "query" &&
|
|
529
|
+
reservedArgument !== undefined
|
|
530
|
+
? { reservedArgument }
|
|
531
|
+
: {}),
|
|
504
532
|
...(description === undefined ? {} : { description }),
|
|
505
533
|
functionProvenance:
|
|
506
534
|
args === undefined
|
|
@@ -897,6 +925,7 @@ export type Extended<
|
|
|
897
925
|
>,
|
|
898
926
|
>(
|
|
899
927
|
config: {
|
|
928
|
+
readonly reservedArgument?: string;
|
|
900
929
|
readonly middleware: Middleware_ &
|
|
901
930
|
NotInherited<Middleware_, MiddlewareSpecs_>;
|
|
902
931
|
} & OptionFree<Extension["Type"]> &
|
|
@@ -921,9 +950,14 @@ type RuntimeWrappers = Partial<
|
|
|
921
950
|
const makeExtended = (
|
|
922
951
|
middleware: ReadonlyArray<ProfileMiddleware<any>>,
|
|
923
952
|
schemas: ReadonlyArray<RuntimeWrappers> = [],
|
|
953
|
+
reservedArgument?: string,
|
|
924
954
|
): Extended<any, any> => {
|
|
925
955
|
const extended =
|
|
926
|
-
(
|
|
956
|
+
(
|
|
957
|
+
makeSpec: (options: never) => object,
|
|
958
|
+
paginated = false,
|
|
959
|
+
reserves = false,
|
|
960
|
+
): any =>
|
|
927
961
|
({
|
|
928
962
|
name,
|
|
929
963
|
description,
|
|
@@ -962,25 +996,30 @@ const makeExtended = (
|
|
|
962
996
|
: spec.middleware(entry.spec, entry.options(info)),
|
|
963
997
|
Object.assign(makeSpec({ name, description, ...thunks } as never), {
|
|
964
998
|
fields,
|
|
999
|
+
...(reserves && reservedArgument !== undefined
|
|
1000
|
+
? { reservedArgument }
|
|
1001
|
+
: {}),
|
|
965
1002
|
}),
|
|
966
1003
|
);
|
|
967
1004
|
};
|
|
968
1005
|
|
|
969
1006
|
return {
|
|
970
1007
|
publicQuery: extended(publicQuery),
|
|
971
|
-
publicMutation: extended(publicMutation),
|
|
972
|
-
publicAction: extended(publicAction),
|
|
973
|
-
publicNodeAction: extended(publicNodeAction),
|
|
1008
|
+
publicMutation: extended(publicMutation, false, true),
|
|
1009
|
+
publicAction: extended(publicAction, false, true),
|
|
1010
|
+
publicNodeAction: extended(publicNodeAction, false, true),
|
|
974
1011
|
publicPaginatedQuery: extended(publicPaginatedQuery, true),
|
|
975
1012
|
extend:
|
|
976
1013
|
() =>
|
|
977
1014
|
(config: {
|
|
978
1015
|
middleware: ReadonlyArray<ProfileMiddleware<any>>;
|
|
979
1016
|
schemas?: RuntimeWrappers;
|
|
1017
|
+
reservedArgument?: string;
|
|
980
1018
|
}) =>
|
|
981
1019
|
makeExtended(
|
|
982
1020
|
[...middleware, ...config.middleware],
|
|
983
1021
|
[...schemas, config.schemas ?? {}],
|
|
1022
|
+
config.reservedArgument ?? reservedArgument,
|
|
984
1023
|
),
|
|
985
1024
|
};
|
|
986
1025
|
};
|
|
@@ -999,15 +1038,16 @@ export const extend =
|
|
|
999
1038
|
>,
|
|
1000
1039
|
>(
|
|
1001
1040
|
config: {
|
|
1041
|
+
readonly reservedArgument?: string;
|
|
1002
1042
|
readonly middleware: Middleware_;
|
|
1003
1043
|
} & OptionFree<Fields_["Type"]> &
|
|
1004
1044
|
Profile.SchemaConfig<Transforms, Profile.Apply<Fields_, string, any>>,
|
|
1005
1045
|
) =>
|
|
1006
|
-
makeExtended(
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
>;
|
|
1046
|
+
makeExtended(
|
|
1047
|
+
config.middleware,
|
|
1048
|
+
[config.schemas ?? {}],
|
|
1049
|
+
config.reservedArgument,
|
|
1050
|
+
) as Extended<Fields_, SpecOf<Middleware_[number]>, [Transforms]>;
|
|
1011
1051
|
|
|
1012
1052
|
type MatchingRegisteredFunction<
|
|
1013
1053
|
RuntimeAndFunctionType_ extends RuntimeAndFunctionType.RuntimeAndFunctionType,
|
package/src/Ref.ts
CHANGED
|
@@ -43,6 +43,7 @@ export interface Base<
|
|
|
43
43
|
readonly "~Error": Error_;
|
|
44
44
|
readonly functionType?: RuntimeAndFunctionType_["functionType"];
|
|
45
45
|
readonly convexFunctionName: string;
|
|
46
|
+
readonly reservedArgument?: string;
|
|
46
47
|
/**
|
|
47
48
|
* Preserved for component references and function handles, which have no
|
|
48
49
|
* local name.
|
|
@@ -459,6 +460,7 @@ export const make = <
|
|
|
459
460
|
[...groupMiddlewareAttachments, ...functionSpec.middlewareAttachments],
|
|
460
461
|
undefined,
|
|
461
462
|
functionSpec.runtimeAndFunctionType.functionType,
|
|
463
|
+
functionSpec.reservedArgument,
|
|
462
464
|
),
|
|
463
465
|
),
|
|
464
466
|
Match.exhaustive,
|
|
@@ -482,12 +484,14 @@ export const fromProvenance = (
|
|
|
482
484
|
middlewareAttachments: ReadonlyArray<MiddlewareAttachment.MiddlewareAttachment>,
|
|
483
485
|
functionReference?: ConvexFunctionReference<any, any>,
|
|
484
486
|
functionType?: "query" | "mutation" | "action",
|
|
487
|
+
reservedArgument?: string,
|
|
485
488
|
): AnyConfect => {
|
|
486
489
|
const ref = {
|
|
487
490
|
[TypeId]: TypeId as TypeId,
|
|
488
491
|
_tag: "Confect" as const,
|
|
489
492
|
...(functionType === undefined ? {} : { functionType }),
|
|
490
493
|
convexFunctionName,
|
|
494
|
+
...(reservedArgument === undefined ? {} : { reservedArgument }),
|
|
491
495
|
...(functionReference === undefined ? {} : { functionReference }),
|
|
492
496
|
kind: provenance.kind,
|
|
493
497
|
middlewareAttachments,
|
package/src/SchemaToValidator.ts
CHANGED
|
@@ -46,10 +46,12 @@ import type {
|
|
|
46
46
|
export const compileArgsSchema = <ConfectValue, ConvexValue>(
|
|
47
47
|
argsSchema: Schema.Codec<ConfectValue, ConvexValue>,
|
|
48
48
|
scope: IdScope.IdScope = IdScope.app,
|
|
49
|
+
reservedArgument?: string,
|
|
50
|
+
functionName?: string,
|
|
49
51
|
): PropertyValidators => {
|
|
50
52
|
const ast = Schema.toEncoded(argsSchema).ast;
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
const validators = pipe(
|
|
53
55
|
ast,
|
|
54
56
|
Match.value,
|
|
55
57
|
Match.tag("Objects", (objectsAst) =>
|
|
@@ -60,8 +62,27 @@ export const compileArgsSchema = <ConfectValue, ConvexValue>(
|
|
|
60
62
|
Match.orElse(() => Effect.fail(new TopLevelMustBeObjectError())),
|
|
61
63
|
Effect.runSync,
|
|
62
64
|
);
|
|
65
|
+
if (reservedArgument === undefined) return validators;
|
|
66
|
+
if (Object.hasOwn(validators, reservedArgument)) {
|
|
67
|
+
throw new ReservedArgumentCollision({
|
|
68
|
+
functionName,
|
|
69
|
+
argument: reservedArgument,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return { ...validators, [reservedArgument]: v.optional(v.any()) };
|
|
63
73
|
};
|
|
64
74
|
|
|
75
|
+
export class ReservedArgumentCollision extends Data.TaggedError(
|
|
76
|
+
"ReservedArgumentCollision",
|
|
77
|
+
)<{
|
|
78
|
+
readonly functionName: string | undefined;
|
|
79
|
+
readonly argument: string;
|
|
80
|
+
}> {
|
|
81
|
+
override get message() {
|
|
82
|
+
return `${this.functionName} declares the argument "${this.argument}", which its profile reserves. Rename the argument.`;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
65
86
|
// Returns
|
|
66
87
|
|
|
67
88
|
export const compileReturnsSchema = <ConfectValue, ConvexValue>(
|