From 0f8a8f14e21a72b503ee3304a30aa4b6c2d6e1ff Mon Sep 17 00:00:00 2001 From: Giulio Canti Date: Sun, 24 Dec 2023 14:44:58 +0100 Subject: [PATCH] Schema: add annotations argument to `attachPropertySignature` (#679) --- .changeset/thin-ways-arrive.md | 5 ++ docs/modules/Schema.ts.md | 6 ++- src/Schema.ts | 54 ++++++++++++--------- test/Schema/attachPropertySignature.test.ts | 18 +++++++ 4 files changed, 58 insertions(+), 25 deletions(-) create mode 100644 .changeset/thin-ways-arrive.md diff --git a/.changeset/thin-ways-arrive.md b/.changeset/thin-ways-arrive.md new file mode 100644 index 000000000..bb26d6a4c --- /dev/null +++ b/.changeset/thin-ways-arrive.md @@ -0,0 +1,5 @@ +--- +"@effect/schema": patch +--- + +Schema: add annotations argument to `attachPropertySignature` diff --git a/docs/modules/Schema.ts.md b/docs/modules/Schema.ts.md index b1e0cc206..93bf13a42 100644 --- a/docs/modules/Schema.ts.md +++ b/docs/modules/Schema.ts.md @@ -1855,12 +1855,14 @@ but rather maps to another schema, for example when you want to add a discrimina export declare const attachPropertySignature: { ( key: K, - value: V + value: V, + options?: DocAnnotations ): (schema: Schema) => Schema> ( schema: Schema, key: K, - value: V + value: V, + options?: DocAnnotations ): Schema> } ``` diff --git a/src/Schema.ts b/src/Schema.ts index 747a91fe1..b06a95016 100644 --- a/src/Schema.ts +++ b/src/Schema.ts @@ -1481,39 +1481,47 @@ export const transformLiterals = < export const attachPropertySignature: { ( key: K, - value: V + value: V, + options?: DocAnnotations ): ( schema: Schema ) => Schema> ( schema: Schema, key: K, - value: V + value: V, + options?: DocAnnotations ): Schema> -} = dual(3, ( - schema: Schema, - key: K, - value: V -): Schema> => - make(AST.createTransform( - schema.ast, - extend( +} = dual( + (args) => isSchema(args[0]), + ( + schema: Schema, + key: K, + value: V, + options?: DocAnnotations + ): Schema> => { + const attached = extend( to(schema), struct({ [key]: Predicate.isSymbol(value) ? uniqueSymbol(value) : literal(value) }) - ).ast, - AST.createTypeLiteralTransformation( - [ - AST.createPropertySignatureTransform( - key, - key, - AST.createFinalPropertySignatureTransformation( - () => Option.some(value), - () => Option.none() + ).ast + return make(AST.createTransform( + schema.ast, + options ? AST.mergeAnnotations(attached, toAnnotations(options)) : attached, + AST.createTypeLiteralTransformation( + [ + AST.createPropertySignatureTransform( + key, + key, + AST.createFinalPropertySignatureTransformation( + () => Option.some(value), + () => Option.none() + ) ) - ) - ] - ) - ))) + ] + ) + )) + } +) const toAnnotations = ( options?: FilterAnnotations diff --git a/test/Schema/attachPropertySignature.test.ts b/test/Schema/attachPropertySignature.test.ts index ae7cb07ae..b26f58fb1 100644 --- a/test/Schema/attachPropertySignature.test.ts +++ b/test/Schema/attachPropertySignature.test.ts @@ -101,4 +101,22 @@ describe("Schema/attachPropertySignature", () => { radius: 10 }) }) + + it("annotations", async () => { + const schema1 = S.struct({ + a: S.string + }).pipe( + S.attachPropertySignature("_tag", "a", { identifier: "MyIdentifier" }) + ) + await Util.expectEncodeFailure(schema1, null as any, "Expected MyIdentifier, actual null") + const schema2 = S.attachPropertySignature( + S.struct({ + a: S.string + }), + "_tag", + "a", + { identifier: "MyIdentifier" } + ) + await Util.expectEncodeFailure(schema2, null as any, "Expected MyIdentifier, actual null") + }) })