From 26838d902c5fa09f0916f3a08c35be34dcd6707e Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Mon, 30 Oct 2023 08:16:18 +0100 Subject: [PATCH] Rename `fieldsAuto` to `fields` (#45) --- CHANGELOG.md | 4 + README.md | 36 ++++----- examples/decode-constrained.test.ts | 6 +- examples/extra-fields.test.ts | 6 +- examples/readme.test.ts | 16 ++-- examples/recursive.test.ts | 8 +- .../taggedUnion-with-common-fields.test.ts | 4 +- examples/tuples.test.ts | 4 +- examples/type-annotations.test.ts | 12 +-- examples/type-inference.test.ts | 8 +- examples/untagged-union.test.ts | 8 +- index.ts | 6 +- tests/JSON.test.ts | 6 +- tests/codecs.test.ts | 73 +++++++++---------- 14 files changed, 98 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4310f3..b07c5cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ Note: I’m currently working on several breaking changes to tiny-decoders, but I’m trying out releasing them piece by piece. The idea is that you can either upgrade version by version only having to deal with one or a few breaking changes at a time, or wait and do a bunch of them at the same time. +### Version 23.0.0 (unreleased) + +This release renames `fieldsAuto` to `fields`. Both of those functions used to exist, but `fields` was deprecated in version 11.0.0 and removed in version 14.0.0. There’s no need for the `Auto` suffix anymore. + ### Version 22.0.0 (2023-10-30) This release renames `fieldsUnion` to `taggedUnion` since it better describes what it is, and it goes along better with the `tag` function. diff --git a/README.md b/README.md index effbebd..b31067a 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ import { array, boolean, field, - fieldsAuto, + fields, format, type Infer, number, @@ -35,7 +35,7 @@ import { // You can also import into a namespace if you want (conventionally called `Codec`): import * as Codec from "tiny-decoders"; -const userCodec = fieldsAuto({ +const userCodec = fields({ name: string, active: field(boolean, { renameFrom: "is_active" }), age: field(number, { optional: true }), @@ -115,7 +115,7 @@ Here’s a summary of all codecs (with slightly simplified type annotations) and - Codec type: [Codec and DecoderResult](#codect-and-decoderresultt) - Primitives: [unknown](#unknown), [boolean](#boolean), [number](#number), [bigint](#bigint), [string](#string) - Collections: [array](#array), [record](#record), [tuple](#tuple) -- Object literals: [fieldsAuto](#fieldsauto) with [field](#field) +- Object literals: [fields](#fields) with [field](#field) - Unions: - Of primitive literals: [primitiveUnion](#primitiveunion) - Of different types: [multi](#multi) @@ -210,7 +210,7 @@ Here’s a summary of all codecs (with slightly simplified type annotations) and Record<string, T> -fieldsAuto +fields
(mapping: {
   field1: Codec<T1>,
   field2: Field<T2, {optional: true}>,
@@ -247,14 +247,14 @@ Here’s a summary of all codecs (with slightly simplified type annotations) and
   meta: Meta,
 ): Field<Decoded, Meta>
n/a -n/a, only used with fieldsAuto +n/a, only used with fields taggedUnion
(
   decodedCommonField: string,
   variants: Array<
-    Parameters<typeof fieldsAuto>[0]
+    Parameters<typeof fields>[0]
   >,
 ) =>
   Codec<T1 | T2 | TN>
@@ -449,10 +449,10 @@ The passed `codec` is for each value of the object. For example, `record(number)` is a codec for an object where the keys can be anything and the values are numbers (`Record`). -### fieldsAuto +### fields ```ts -function fieldsAuto( +function fields( mapping: Mapping, { allowExtraFields = true }: { allowExtraFields?: boolean } = {}, ): Codec, InferEncodedFields>; @@ -491,7 +491,7 @@ type User = { active: boolean; }; -const userCodec: Codec = fieldsAuto({ +const userCodec: Codec = fields({ name: string, age: field(number, { optional: true }), active: field(boolean, { renameFrom: "is_active" }), @@ -532,14 +532,14 @@ This function takes a codec and lets you: - Rename a field: `field(string, { renameFrom: "some_name" })` - Both: `field(string, { optional: true, renameFrom: "some_name" })` -Use it with [fieldsAuto](#fieldsAuto). +Use it with [fields](#fields). The `tag` thing is handled by the [tag](#tag) function. It’s not something you’ll set manually using `field`. (That’s why the type annotation says `Omit`.) Here’s an example illustrating the difference between `field(string, { optional: true })` and `undefinedOr(string)`: ```ts -const exampleCodec = fieldsAuto({ +const exampleCodec = fields({ // Required field. a: string, @@ -571,7 +571,7 @@ type Example = { > Why? Let’s take this codec as an example: > > ```ts -> const exampleCodec = fieldsAuto({ +> const exampleCodec = fields({ > name: field(string, { optional: true }), > }); > ``` @@ -593,7 +593,7 @@ type Example = { > Notice the added `| undefined`. That allows also constructing `{ name: undefined }`. But if you run `exampleCodec.decoder({ name: undefined })`, the decoder will fail. The decoder only supports `name` existing and being set to a string, or `name` being missing. It does not support it being set to `undefined` explicitly. If you wanted to support that, use `undefinedOr`: > > ```ts -> const exampleCodec = fieldsAuto({ +> const exampleCodec = fields({ > name: field(undefinedOr(string), { optional: true }), > }); > ``` @@ -632,14 +632,14 @@ type InferFieldsUnion = magic; type InferEncodedFieldsUnion = magic; -// See `fieldsAuto` for the definitions of `Field`, `FieldMeta` and `FieldsMapping`. +// See `fields` for the definitions of `Field`, `FieldMeta` and `FieldsMapping`. ``` Codec for JSON objects with a common field (that tells them apart), and a TypeScript tagged union type. The `decodedCommonField` is the name of the common field. -`variants` is an array of objects. Those objects are “`fieldsAuto` objects” – they fit when passed to `fieldsAuto` as well. All of those objects must have `decodedCommonField` as a key, and use the [tag](#tag) function on that key. +`variants` is an array of objects. Those objects are “`fields` objects” – they fit when passed to `fields` as well. All of those objects must have `decodedCommonField` as a key, and use the [tag](#tag) function on that key. ```ts type Shape = @@ -659,7 +659,7 @@ const shapeCodec: Codec = taggedUnion("tag", [ ]); ``` -The `allowExtraFields` option works just like for [fieldsAuto](#fieldsauto). +The `allowExtraFields` option works just like for [fields](#fields). See also these examples: @@ -1121,7 +1121,7 @@ You can use ESLint’s [no-restricted-globals](https://eslint.org/docs/latest/ru Rather than first defining the type and then defining the codec (which often feels like writing the type twice), you can _only_ define the decoder and then infer the type. ```ts -const personCodec = fieldsAuto({ +const personCodec = fields({ name: string, age: number, }); @@ -1138,7 +1138,7 @@ This is a nice pattern (naming the type and the codec the same): ```ts type Person = Infer; -const Person = fieldsAuto({ +const Person = fields({ name: string, age: number, }); diff --git a/examples/decode-constrained.test.ts b/examples/decode-constrained.test.ts index a459b83..e353f62 100644 --- a/examples/decode-constrained.test.ts +++ b/examples/decode-constrained.test.ts @@ -5,18 +5,18 @@ import { expect, test } from "vitest"; import { Codec, DecoderResult, - fieldsAuto, + fields, format, primitiveUnion, string, } from "../"; test("decode constrained", () => { - const codec1 = fieldsAuto({ + const codec1 = fields({ status: string, // In a first codec, we have a pretty loose type. }); - const codec2 = fieldsAuto({ + const codec2 = fields({ status: primitiveUnion(["ok", "error"]), // In a second codec, we have a stricter type. }); diff --git a/examples/extra-fields.test.ts b/examples/extra-fields.test.ts index b10588a..9e3322c 100644 --- a/examples/extra-fields.test.ts +++ b/examples/extra-fields.test.ts @@ -1,6 +1,6 @@ import { expect, test } from "vitest"; -import { Codec, fieldsAuto, map, number, string } from ".."; +import { Codec, fields, map, number, string } from ".."; import { run } from "../tests/helpers"; test("adding extra fields to records", () => { @@ -16,7 +16,7 @@ test("adding extra fields to records", () => { // Use `map` to add it: const productCodec: Codec = map( - fieldsAuto({ + fields({ name: string, price: number, }), @@ -53,7 +53,7 @@ test("adding extra fields to records", () => { // In previous versions of tiny-decoders, another way of doing this was to add // a decoder that always succeeds (a function that ignores its input and // always returns the same value). - const productCodecBroken: Codec = fieldsAuto({ + const productCodecBroken: Codec = fields({ name: string, price: number, version: { diff --git a/examples/readme.test.ts b/examples/readme.test.ts index d0eff41..2609eff 100644 --- a/examples/readme.test.ts +++ b/examples/readme.test.ts @@ -7,7 +7,7 @@ import { Codec, DecoderResult, field, - fieldsAuto, + fields, Infer, number, string, @@ -23,7 +23,7 @@ test("the main readme example", () => { interests: Array; }; - const userCodec: Codec = fieldsAuto({ + const userCodec: Codec = fields({ name: string, active: field(boolean, { renameFrom: "is_active" }), age: field(number, { optional: true }), @@ -72,9 +72,9 @@ function getSomeInvalidJSON(): unknown { } test("default vs sensitive error messages", () => { - const userCodec = fieldsAuto({ + const userCodec = fields({ name: string, - details: fieldsAuto({ + details: fields({ email: string, ssn: string, }), @@ -102,8 +102,8 @@ test("default vs sensitive error messages", () => { `); }); -test("fieldsAuto exactOptionalPropertyTypes", () => { - const exampleCodec = fieldsAuto({ +test("fields exactOptionalPropertyTypes", () => { + const exampleCodec = fields({ name: field(string, { optional: true }), }); @@ -111,7 +111,7 @@ test("fieldsAuto exactOptionalPropertyTypes", () => { expectType, Example>>(true); - const exampleCodec2 = fieldsAuto({ + const exampleCodec2 = fields({ name: field(undefinedOr(string), { optional: true }), }); @@ -130,7 +130,7 @@ test("fieldsAuto exactOptionalPropertyTypes", () => { }); test("fieldAuto optional vs undefined", () => { - const exampleCodec = fieldsAuto({ + const exampleCodec = fields({ // Required field. a: string, diff --git a/examples/recursive.test.ts b/examples/recursive.test.ts index 0dcc5d1..3b33134 100644 --- a/examples/recursive.test.ts +++ b/examples/recursive.test.ts @@ -4,7 +4,7 @@ import { array, Codec, DecoderResult, - fieldsAuto, + fields, flatMap, multi, record, @@ -22,7 +22,7 @@ test("recursive data structure", () => { // This wouldn’t work to decode it, because we’re trying to use // `personDecoder` in the definition of `personDecoder` itself. /* - const personCodec = fieldsAuto({ + const personCodec = fields({ name: string, friends: array(personDecoder2), // ReferenceError: Cannot access 'personDecoder2' before initialization }); @@ -30,7 +30,7 @@ test("recursive data structure", () => { // `recursive` lets us delay when `personDecoder` is referenced, solving the // issue. - const personCodec: Codec = fieldsAuto({ + const personCodec: Codec = fields({ name: string, friends: array(recursive(() => personCodec)), }); @@ -139,7 +139,7 @@ test("circular objects", () => { likes: Person; }; - const personCodec: Codec = fieldsAuto({ + const personCodec: Codec = fields({ name: string, likes: recursive(() => personCodec), }); diff --git a/examples/taggedUnion-with-common-fields.test.ts b/examples/taggedUnion-with-common-fields.test.ts index c2da01f..dfb459e 100644 --- a/examples/taggedUnion-with-common-fields.test.ts +++ b/examples/taggedUnion-with-common-fields.test.ts @@ -4,7 +4,7 @@ import { expect, test } from "vitest"; import { boolean, Codec, - fieldsAuto, + fields, Infer, InferEncoded, number, @@ -72,7 +72,7 @@ test("taggedUnion with common fields", () => { ]); type EventMetadata = Infer; - const EventMetadata = fieldsAuto({ + const EventMetadata = fields({ id: string, timestamp: string, }); diff --git a/examples/tuples.test.ts b/examples/tuples.test.ts index a4933b4..7c963b0 100644 --- a/examples/tuples.test.ts +++ b/examples/tuples.test.ts @@ -1,6 +1,6 @@ import { expect, test } from "vitest"; -import { Codec, fieldsAuto, map, number, tuple } from "../"; +import { Codec, fields, map, number, tuple } from "../"; test("decoding tuples", () => { type PointTuple = [number, number]; @@ -64,7 +64,7 @@ test("decoding tuples", () => { // You can of course decode an object to a tuple as well: const obj: unknown = { x: 1, y: 2 }; const pointTupleCodec: Codec = map( - fieldsAuto({ + fields({ x: number, y: number, }), diff --git a/examples/type-annotations.test.ts b/examples/type-annotations.test.ts index 2ff8c8f..44b3b55 100644 --- a/examples/type-annotations.test.ts +++ b/examples/type-annotations.test.ts @@ -1,6 +1,6 @@ import { expect, test } from "vitest"; -import { Codec, DecoderResult, fieldsAuto, number, string } from "../"; +import { Codec, DecoderResult, fields, number, string } from "../"; test("type annotations", () => { // First, a small test type and a function that receives it: @@ -26,7 +26,7 @@ test("type annotations", () => { // TypeScript will infer what it decodes into (try hovering `personCodec1` // in your editor!), but it won’t know that you intended to decode a `Person`. // As you can see, I’ve misspelled `age` as `aye`. - const personCodec1 = fieldsAuto({ + const personCodec1 = fields({ name: string, aye: number, }); @@ -39,7 +39,7 @@ test("type annotations", () => { // The way to make the above type error more clear is to provide an explicit type // annotation, so that TypeScript knows what you’re trying to do. // @ts-expect-error Type '{ name: string; aye: number; }' is not assignable to type 'Person'. - const personCodec2: Codec = fieldsAuto({ + const personCodec2: Codec = fields({ name: string, aye: number, }); @@ -51,7 +51,7 @@ test("type annotations", () => { // TypeScript allows passing extra properties, so without type annotations // there are no errors: - const personCodec3 = fieldsAuto({ + const personCodec3 = fields({ name: string, age: number, extra: string, @@ -61,7 +61,7 @@ test("type annotations", () => { // Adding `Codec` helps TypeScript find the error: // @ts-expect-error Type 'Person' is not assignable to type '{ name: string; age: number; extra: string; }'. - const personCodec4: Codec = fieldsAuto({ + const personCodec4: Codec = fields({ name: string, age: number, extra: string, @@ -69,7 +69,7 @@ test("type annotations", () => { greet(personCodec4.decoder(testPerson)); // Finally, a compiling codec. - const personCodec5: Codec = fieldsAuto({ + const personCodec5: Codec = fields({ name: string, age: number, }); diff --git a/examples/type-inference.test.ts b/examples/type-inference.test.ts index 4dcf8e1..20c22a8 100644 --- a/examples/type-inference.test.ts +++ b/examples/type-inference.test.ts @@ -7,7 +7,7 @@ import { boolean, DecoderResult, field, - fieldsAuto, + fields, Infer, map, multi, @@ -19,10 +19,10 @@ import { run } from "../tests/helpers"; test("making a type from a codec", () => { // Rather than first typing out a `type` for `Person` and then essentially - // typing the same thing again in the codec (especially `fieldsAuto` codecs + // typing the same thing again in the codec (especially `fields` codecs // look almost identical to the `type` they decode to!), you can start with the // codec and extract the type afterwards with tiny-decoder’s `Infer` utility. - const personCodec = fieldsAuto({ + const personCodec = fields({ name: string, age: number, }); @@ -38,7 +38,7 @@ test("making a type from a codec", () => { // the “duplication,” but when you do – try out the `Infer` approach! // Here’s a more complex example for trying out TypeScript’s inference. - const userCodec = fieldsAuto({ + const userCodec = fields({ id: map(multi(["string", "number"]), { decoder: ({ value }) => value, encoder: (value) => diff --git a/examples/untagged-union.test.ts b/examples/untagged-union.test.ts index 1a7f84f..1b0b6eb 100644 --- a/examples/untagged-union.test.ts +++ b/examples/untagged-union.test.ts @@ -5,7 +5,7 @@ import { array, Codec, field, - fieldsAuto, + fields, Infer, InferEncoded, number, @@ -29,19 +29,19 @@ test("untagged union", () => { type UserResult = Failure | User; - const userCodec = fieldsAuto({ + const userCodec = fields({ name: string, followers: number, }); - const failureCodec = fieldsAuto({ + const failureCodec = fields({ error: string, errorCode: number, }); const userResultCodec: Codec = { decoder: (value) => - // This is a bit annoying to do. Prefer a tagged union and use `fieldsAuto`. + // This is a bit annoying to do. Prefer a tagged union and use `fields`. // But when that’s not possible, this is a simple way of “committing” to one // of the union variants and choosing a decoder based on that. // This approach results in much easier to understand error messages at diff --git a/index.ts b/index.ts index f253e6e..fb94a4c 100644 --- a/index.ts +++ b/index.ts @@ -301,7 +301,7 @@ type InferEncodedFields = Expand< } >; -export function fieldsAuto( +export function fields( mapping: Mapping, { allowExtraFields = true }: { allowExtraFields?: boolean } = {}, ): Codec, InferEncodedFields> { @@ -480,7 +480,7 @@ export function taggedUnion< )}) than before (${JSON.stringify(maybeEncodedCommonField)}).`, ); } - const fullCodec = fieldsAuto(variant, { allowExtraFields }); + const fullCodec = fields(variant, { allowExtraFields }); decoderMap.set(field_.tag.encoded, fullCodec.decoder); encoderMap.set(field_.tag.decoded, fullCodec.encoder); } @@ -497,7 +497,7 @@ export function taggedUnion< return { decoder: (value) => { - const encodedNameResult = fieldsAuto({ + const encodedNameResult = fields({ [encodedCommonField]: unknown, }).decoder(value); if (encodedNameResult.tag === "DecoderError") { diff --git a/tests/JSON.test.ts b/tests/JSON.test.ts index 868b441..3dd2f17 100644 --- a/tests/JSON.test.ts +++ b/tests/JSON.test.ts @@ -3,7 +3,7 @@ import { describe, expect, test } from "vitest"; import { DecoderResult, field, - fieldsAuto, + fields, format, JSON, map, @@ -34,7 +34,7 @@ function helper( describe("JSON.parse", () => { test("basic", () => { - const codec = fieldsAuto({ + const codec = fields({ lastName: field(string, { renameFrom: "last_name" }), port: map(number, { decoder: (value) => ({ tag: "Port" as const, value }), @@ -73,7 +73,7 @@ describe("JSON.parse", () => { describe("JSON.stringify", () => { test("basic", () => { - const codec = fieldsAuto({ + const codec = fields({ lastName: field(string, { renameFrom: "last_name" }), port: map(number, { decoder: (value) => ({ tag: "Port" as const, value }), diff --git a/tests/codecs.test.ts b/tests/codecs.test.ts index 939fc1c..69006e7 100644 --- a/tests/codecs.test.ts +++ b/tests/codecs.test.ts @@ -8,7 +8,7 @@ import { Codec, DecoderResult, field, - fieldsAuto, + fields, flatMap, Infer, InferEncoded, @@ -437,9 +437,8 @@ describe("record", () => { `, ); - expect( - cleanRegexError(run(fieldsAuto({ regexes: codec }), { regexes: bad })), - ).toMatchInlineSnapshot(` + expect(cleanRegexError(run(fields({ regexes: codec }), { regexes: bad }))) + .toMatchInlineSnapshot(` At root["regexes"]["\\\\d{4}:\\\\d{2"]: Invalid regular expression: (the regex error) Got: "\\\\d{4}:\\\\d{2" @@ -462,14 +461,14 @@ describe("record", () => { }); }); -describe("fieldsAuto", () => { +describe("fields", () => { // @ts-expect-error Argument of type 'Codec[]' is not assignable to parameter of type 'FieldsMapping'. // Index signature for type 'string' is missing in type 'Codec[]'. - fieldsAuto([string]); + fields([string]); test("basic", () => { type Person = Infer; - const Person = fieldsAuto({ + const Person = fields({ id: number, firstName: string, }); @@ -510,7 +509,7 @@ describe("fieldsAuto", () => { } `); - expect(run(fieldsAuto({ 0: number }), [1])).toMatchInlineSnapshot(` + expect(run(fields({ 0: number }), [1])).toMatchInlineSnapshot(` At root: Expected an object Got: [ @@ -521,7 +520,7 @@ describe("fieldsAuto", () => { test("optional and renamed fields", () => { type Person = Infer; - const Person = fieldsAuto({ + const Person = fields({ id: number, firstName: field(string, { renameFrom: "first_name" }), lastName: field(string, { renameFrom: "last_name", optional: true }), @@ -803,7 +802,7 @@ describe("fieldsAuto", () => { describe("allowExtraFields", () => { test("allows excess properties by default", () => { expect( - run(fieldsAuto({ one: string, two: boolean }), { + run(fields({ one: string, two: boolean }), { one: "a", two: true, three: 3, @@ -812,13 +811,15 @@ describe("fieldsAuto", () => { ).toStrictEqual({ one: "a", two: true }); expect( - run( - fieldsAuto({ one: string, two: boolean }, { allowExtraFields: true }), - { one: "a", two: true, three: 3, four: {} }, - ), + run(fields({ one: string, two: boolean }, { allowExtraFields: true }), { + one: "a", + two: true, + three: 3, + four: {}, + }), ).toStrictEqual({ one: "a", two: true }); - fieldsAuto({ one: string, two: boolean }).encoder({ + fields({ one: string, two: boolean }).encoder({ one: "", two: true, // @ts-expect-error Object literal may only specify known properties, and 'three' does not exist in type '{ one: string; two: boolean; }'. @@ -829,10 +830,7 @@ describe("fieldsAuto", () => { test("fail on excess properties", () => { expect( run( - fieldsAuto( - { one: string, two: boolean }, - { allowExtraFields: false }, - ), + fields({ one: string, two: boolean }, { allowExtraFields: false }), { one: "a", two: true, @@ -850,7 +848,7 @@ describe("fieldsAuto", () => { "four" `); - fieldsAuto( + fields( { one: string, two: boolean }, { allowExtraFields: false }, ).encoder({ @@ -865,10 +863,7 @@ describe("fieldsAuto", () => { test("large number of excess properties", () => { expect( run( - fieldsAuto( - { "1": boolean, "2": boolean }, - { allowExtraFields: false }, - ), + fields({ "1": boolean, "2": boolean }, { allowExtraFields: false }), Object.fromEntries(Array.from({ length: 100 }, (_, i) => [i, false])), ), ).toMatchInlineSnapshot(` @@ -887,7 +882,7 @@ describe("fieldsAuto", () => { }); test("always print the expected keys in full", () => { - const codec = fieldsAuto( + const codec = fields( { PrettyLongTagName1: string, PrettyLongTagName2: string, @@ -921,7 +916,7 @@ describe("fieldsAuto", () => { }); test("__proto__ is not allowed", () => { - const codec = fieldsAuto({ a: number, __proto__: string, b: number }); + const codec = fields({ a: number, __proto__: string, b: number }); expect( run(codec, JSON.parse(`{"a": 1, "__proto__": "a", "b": 3}`)), ).toStrictEqual({ a: 1, b: 3 }); @@ -933,7 +928,7 @@ describe("fieldsAuto", () => { const desc = Object.create(null) as { __proto__: Codec }; desc.__proto__ = string; - const codec2 = fieldsAuto(desc); + const codec2 = fields(desc); expect(run(codec2, JSON.parse(`{"__proto__": "a"}`))).toStrictEqual({}); expect( codec2.encoder(JSON.parse(`{"__proto__": "a"}`) as Infer), @@ -941,7 +936,7 @@ describe("fieldsAuto", () => { }); test("renaming from __proto__ is not allowed", () => { - const codec = fieldsAuto({ + const codec = fields({ a: number, b: field(string, { renameFrom: "__proto__" }), }); @@ -952,7 +947,7 @@ describe("fieldsAuto", () => { const desc = Object.create(null) as { __proto__: Codec }; desc.__proto__ = string; - const codec2 = fieldsAuto(desc); + const codec2 = fields(desc); expect(run(codec2, JSON.parse(`{"__proto__": "a"}`))).toStrictEqual({}); expect( codec2.encoder(JSON.parse(`{"__proto__": "a"}`) as Infer), @@ -960,7 +955,7 @@ describe("fieldsAuto", () => { }); test("empty object", () => { - const codec = fieldsAuto({}, { allowExtraFields: false }); + const codec = fields({}, { allowExtraFields: false }); expect(run(codec, {})).toStrictEqual({}); expect(codec.encoder({})).toStrictEqual({}); @@ -1969,7 +1964,7 @@ describe("tuple", () => { type Type = Infer; const codec = tuple([ map(boolean, { decoder: Number, encoder: Boolean }), - fieldsAuto({ decoded: field(string, { renameFrom: "encoded" }) }), + fields({ decoded: field(string, { renameFrom: "encoded" }) }), ]); expectType>(true); @@ -2271,7 +2266,7 @@ describe("recursive", () => { b: Array; }; - const codec: Codec = fieldsAuto({ + const codec: Codec = fields({ a: field( recursive(() => codec), { optional: true }, @@ -2327,9 +2322,9 @@ describe("undefinedOr", () => { expect(codec.encoder("a")).toBe("a"); }); - test("using with fieldsAuto does NOT result in an optional field", () => { + test("using with fields does NOT result in an optional field", () => { type Person = Infer; - const Person = fieldsAuto({ + const Person = fields({ name: string, age: undefinedOr(number), }); @@ -2412,8 +2407,8 @@ describe("undefinedOr", () => { }); test("undefinedOr higher up the chain makes no difference", () => { - const codec = fieldsAuto({ - test: undefinedOr(fieldsAuto({ inner: string })), + const codec = fields({ + test: undefinedOr(fields({ inner: string })), }); expect(run(codec, { test: 1 })).toMatchInlineSnapshot(` @@ -2495,7 +2490,7 @@ describe("nullOr", () => { test("nullOr field", () => { type Person = Infer; - const Person = fieldsAuto({ + const Person = fields({ name: string, age: nullOr(number), }); @@ -2581,8 +2576,8 @@ describe("nullOr", () => { }); test("nullOr higher up the chain makes no difference", () => { - const codec = fieldsAuto({ - test: nullOr(fieldsAuto({ inner: string })), + const codec = fields({ + test: nullOr(fields({ inner: string })), }); expect(run(codec, { test: 1 })).toMatchInlineSnapshot(`