{"version":3,"sources":["/Users/rbell/Development/jsonous/dist/index.cjs","../src/base.ts","../src/Decoder.ts","../src/utils.ts","../src/containers.ts","../src/associative.ts","../src/presence.ts","../src/dates.ts","../src/predicates.ts","../src/structures.ts","../src/strings.ts"],"names":["err"],"mappings":"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","file":"/Users/rbell/Development/jsonous/dist/index.cjs","sourcesContent":[null,"import { err, ok } from 'resulty';\nimport Decoder from './Decoder';\nimport { safeStringify } from './utils';\n\n/**\n * Creates a decoder that always succeeds with the given value.\n *\n * @template A - The type of the value to be returned by the decoder.\n * @param value - The value to be returned by the decoder.\n * @returns A new decoder that always returns the provided value.\n */\nexport const succeed = <A>(value: A) => new Decoder((_) => ok(value));\n\n/**\n * Creates a decoder that always fails with the given message.\n *\n * @template A - The type of the value to be returned by the decoder.\n * @param message - The error message to be returned by the decoder.\n * @returns A new decoder that always fails with the provided message.\n */\nexport const fail = <A>(message: string): Decoder<A> => new Decoder((_) => err(message));\n\n/**\n * A decoder that validates if a given value is a string.\n *\n * @constant\n * @type {Decoder<string>}\n *\n * @example\n * const result = string.decode(\"hello\");\n * // result is Ok(\"hello\")\n *\n * const result = string.decode(123);\n * // result is Err(\"I expected to find a string but instead I found 123\")\n *\n * @param {any} value - The value to be decoded.\n * @returns {Result<string, string>} - Returns an Ok with the string value if the value is a string,\n * otherwise returns an Err with an error message.\n */\nexport const string: Decoder<string> = new Decoder<string>((value) => {\n  if (typeof value !== 'string') {\n    const stringified = safeStringify(value);\n    const errorMsg = `I expected to find a string but instead I found ${stringified}`;\n    return err(errorMsg);\n  }\n\n  return ok(value);\n});\n\n/**\n * A decoder that validates if a given value is a number.\n *\n * This decoder checks the type of the input value. If the value is not a number,\n * it returns an error with a message indicating the expected type and the actual value.\n * If the value is a number, it returns the value wrapped in an `ok` result.\n *\n * @constant\n * @type {Decoder<number>}\n * @example\n * const result = number.decode(42); // ok(42)\n * const result = number.decode(\"42\"); // err(\"I expected to find a number but instead I found \\\"42\\\"\")\n */\nexport const number: Decoder<number> = new Decoder<number>((value) => {\n  if (typeof value !== 'number') {\n    const errorMsg = `I expected to find a number but instead I found ${safeStringify(value)}`;\n    return err(errorMsg);\n  }\n\n  return ok(value);\n});\n\n/**\n * A decoder that validates if a given value is a boolean.\n *\n * @constant\n * @type {Decoder<boolean>}\n * @example\n * const result = boolean.decode(true); // ok(true)\n * const result = boolean.decode(\"true\"); // err(\"I expected to find a boolean but instead I found \\\"true\\\"\")\n */\nexport const boolean: Decoder<boolean> = new Decoder<boolean>((value) => {\n  if (typeof value !== 'boolean') {\n    const errorMsg = `I expected to find a boolean but instead found ${safeStringify(value)}`;\n    return err(errorMsg);\n  }\n\n  return ok(value);\n});\n","import { err, Result } from 'resulty';\nimport { safeStringify } from './utils';\n\n/**\n * A function type that represents a decoder which takes an input of any type\n * and returns a `Result` containing either a string error message or a value of type `A`.\n *\n * @template A - The type of the successfully decoded value.\n * @param thing - The input value to be decoded.\n * @returns A `Result` object containing either a string error message or a value of type `A`.\n */\nexport type DecoderFn<A> = (thing: any) => Result<string, A>;\n\n/**\n * A class representing a Decoder that can be used to decode values of type `A`.\n *\n * @template A - The type of the value that this decoder will decode.\n */\nexport default class Decoder<A> {\n  /**\n   * The constructor for the Decoder class.\n   *\n   * @param fn - The decoder function that will be used to decode values of type `A`.\n   */\n  constructor(private fn: DecoderFn<A>) {}\n\n  /**\n   * Transforms the output of this decoder using the provided function.\n   *\n   * @template B - The type of the output after applying the transformation function.\n   * @param {function(A): B} f - A function that takes a value of type A and returns a value of type B.\n   * @returns {Decoder<B>} A new decoder that applies the transformation function to the output of this decoder.\n   */\n  public map = <B>(f: (a: A) => B): Decoder<B> => {\n    return new Decoder((value) => {\n      return this.fn(value).map(f);\n    });\n  };\n\n  /**\n   * Chains the current decoder with another decoder that depends on the result of the current decoder.\n   *\n   * @template B - The type of the value that the resulting decoder will decode to.\n   * @param f - A function that takes the result of the current decoder and returns a new decoder.\n   * @returns A new decoder that first decodes the value using the current decoder,\n   *          and then uses the result to decode further using the provided function.\n   */\n  public andThen = <B>(f: (a: A) => Decoder<B>): Decoder<B> => {\n    return new Decoder((value) => {\n      return this.fn(value).andThen((v) => f(v).decodeAny(value));\n    });\n  };\n\n  /**\n   * Assigns a new key-value pair to the decoded object.\n   *\n   * The idea for assign came from this blog:\n   * https://medium.com/@dhruvrajvanshi/simulating-haskells-do-notation-in-typescript-e48a9501751c\n   *\n   * @template K - The type of the key to be added.\n   * @template B - The type of the value to be added.\n   * @param {K} k - The key to be added to the decoded object.\n   * @param {Decoder<B> | ((a: A) => Decoder<B>)} other - A decoder for the value to be added, or a function that takes the current decoded object and returns a decoder for the value.\n   * @returns {Decoder<A & { [k in K]: B }>} A new decoder that decodes an object with the new key-value pair added.\n   */\n  public assign = <K extends string, B>(\n    k: K,\n    other: Decoder<B> | ((a: A) => Decoder<B>)\n  ): Decoder<A & { [k in K]: B }> => {\n    return this.andThen((a) => {\n      const decoder = other instanceof Decoder ? other : other(a);\n      return decoder.map<A & { [k in K]: B }>((b) => ({\n        ...Object(a),\n        [k.toString()]: b,\n      }));\n    });\n  };\n\n  /**\n   * Applies a given function to the decoded value and returns the original value.\n   *\n   * @param fn - A function that takes the decoded value as an argument and performs some operation on it.\n   * @returns A new Decoder instance with the same value.\n   */\n  public do = (fn: (a: A) => void): Decoder<A> => {\n    return this.map((v) => {\n      fn(v);\n      return v;\n    });\n  };\n\n  /**\n   * Transforms the error message of the decoder using the provided function.\n   *\n   * @param f - A function that takes an error message string and returns a transformed error message string.\n   * @returns A new `Decoder` instance with the transformed error message.\n   */\n  public mapError = (f: (e: string) => string): Decoder<A> => {\n    return new Decoder((value) => {\n      return this.fn(value).mapError(f);\n    });\n  };\n\n  /**\n   * Provides an alternative decoder to use if the current decoder fails.\n   *\n   * @param f - A function that takes an error message and returns an alternative decoder.\n   * @returns A new decoder that attempts to decode the value using the current decoder,\n   *          and if it fails, uses the alternative decoder provided by the function `f`.\n   */\n  public orElse = (f: (e: string) => Decoder<A>): Decoder<A> => {\n    return new Decoder((value) => {\n      return this.fn(value).orElse((e) => f(e).decodeAny(value));\n    });\n  };\n\n  /**\n   * Registers a callback function to be executed if the decoding process fails.\n   *\n   * @param f - A function that takes an error message as a parameter and returns void.\n   * @returns A new `Decoder` instance with the registered callback function.\n   */\n  public elseDo = (f: (e: string) => void): Decoder<A> => {\n    return new Decoder((value) => {\n      return this.fn(value).elseDo(f);\n    });\n  };\n\n  /**\n   * Decodes any given value using the provided decoding function.\n   *\n   * @param value - The value to be decoded.\n   * @returns The result of the decoding function applied to the given value.\n   */\n  public decodeAny = (value: any) => this.fn(value);\n\n  /**\n   * Decodes a JSON string into a Result type.\n   *\n   * @param json - The JSON string to decode.\n   * @returns A Result containing either the decoded value of type `A` or an error message.\n   *\n   * @template A - The type of the decoded value.\n   */\n  public decodeJson = (json: string): Result<string, A> => {\n    try {\n      const value = JSON.parse(json);\n      return this.decodeAny(value);\n    } catch (e) {\n      if (e instanceof Error) {\n        return err(e.message);\n      } else if (typeof e === 'string') {\n        return err(e);\n      }\n      return err(safeStringify(e));\n    }\n  };\n\n  /**\n   * Converts the current decoder into a function that can decode any value.\n   *\n   * @returns A function that takes any value and returns a `Result` containing either a string error message or a decoded value of type `A`.\n   */\n  public toAnyFn = (): ((value: any) => Result<string, A>) => {\n    return (value: any) => this.decodeAny(value);\n  };\n\n  /**\n   * Converts the current decoder into a function that takes a JSON string\n   * and returns a `Result` containing either a decoded value of type `A` or an error message.\n   *\n   * @returns A function that takes a JSON string and returns a `Result<string, A>`.\n   */\n  public toJsonFn = (): ((json: string) => Result<string, A>) => {\n    return (json: string) => this.decodeJson(json);\n  };\n}\n","/**\n * Safely converts a JavaScript value to a JSON string, handling cyclical references.\n *\n * @param value - The value to be stringified.\n * @returns The JSON string representation of the value.\n */\nexport function safeStringify(value: any): string {\n  return JSON.stringify(value, cyclicalReferenceReplacer());\n}\n\n/**\n * Creates a replacer function for JSON.stringify that handles cyclical references.\n *\n * This function returns a replacer function that can be used with JSON.stringify\n * to replace cyclical references with the string '[Cyclical Reference]'. It uses\n * a WeakSet to keep track of objects that have already been seen during the\n * stringification process.\n *\n * Based on this code: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value\n *\n * @returns A replacer function for JSON.stringify that replaces cyclical references.\n */\nfunction cyclicalReferenceReplacer() {\n  const seen = new WeakSet();\n  return (_: string, value: any) => {\n    if (typeof value === 'object' && value !== null) {\n      if (seen.has(value)) {\n        return '[Cyclical Reference]';\n      }\n      seen.add(value);\n    }\n    return value;\n  };\n}\n\n/**\n * A generic function that returns the value it receives as an argument.\n *\n * @template T - The type of the value.\n * @param {T} value - The value to be returned.\n * @returns {T} The same value that was passed as an argument.\n */\nexport function identity<T>(value: T): T {\n  return value;\n}\n\n/**\n * Converts a snake_case string to camelCase.\n *\n * @param str - The snake_case string to be converted.\n * @returns The converted camelCase string.\n */\nexport function camelCase(str: string): string {\n  return str.replace(/(_\\w)/g, (m) => m[1].toUpperCase());\n}\n\n/**\n * Converts a camelCase string to snake_case.\n *\n * @param str - The camelCase string to be converted.\n * @returns The converted snake_case string.\n *\n * @example\n * ```typescript\n * const result = camelCaseToSnakeCase('camelCaseString');\n * console.log(result); // Outputs: camel_case_string\n * ```\n */\nexport function snakeCase(str: string): string {\n  return str.replace(/([A-Z])/g, (m) => `_${m.toLowerCase()}`);\n}\n","import { err, ok, Result } from 'resulty';\nimport Decoder from './Decoder';\nimport { safeStringify } from './utils';\n\n/**\n * Applies the `decoder` to all of the elements of an array.\n */\nexport const array = <A>(decoder: Decoder<A>): Decoder<A[]> =>\n  new Decoder<A[]>((value) => {\n    if (!(value instanceof Array)) {\n      const errorMsg = `I expected an array but instead I found ${safeStringify(value)}`;\n      return err(errorMsg);\n    }\n\n    let result: Result<string, A[]> = ok([]);\n\n    for (let idx = 0; idx < value.length; idx++) {\n      result = decoder\n        .decodeAny(value[idx])\n        .andThen((v) => result.map((vs) => vs.concat([v])))\n        .mapError((e) => `${e}:\\nerror found in an array at [${idx}]`);\n      if (result.isErr()) {\n        break;\n      }\n    }\n\n    return result;\n  });\n\n/**\n * Decodes the value at a particular field in a JavaScript object.\n */\nexport const field = <A>(name: string, decoder: Decoder<A>): Decoder<A> =>\n  new Decoder<A>((value) => {\n    const errorMsg = () => {\n      const stringified = safeStringify(value);\n      const msg = `I expected to find an object with key '${name}' but instead I found ${stringified}`;\n      return err<string, A>(msg);\n    };\n    if (value == null) {\n      return errorMsg();\n    }\n    if (!value.hasOwnProperty(name)) {\n      return errorMsg();\n    }\n\n    const v = value[name];\n    return decoder.decodeAny(v).mapError((e) => `${e}:\\noccurred in a field named '${name}'`);\n  });\n\n/**\n * Decodes the value at a particular path in a nested JavaScript object.\n */\nexport const at = <A>(path: Array<number | string>, decoder: Decoder<A>): Decoder<A> =>\n  new Decoder<A>((value) => {\n    if (value == null) {\n      return err(`I found an error. Could not apply 'at' path to an undefined or null value.`);\n    }\n    let val = value;\n    let idx = 0;\n    while (idx < path.length) {\n      val = val[path[idx]];\n      if (val === undefined) {\n        const pathStr = safeStringify(path.slice(0, idx + 1));\n        const valueStr = safeStringify(value);\n        return err(\n          `I found an error in the 'at' path. I could not find path '${pathStr}' in ${valueStr}`\n        );\n      }\n      idx += 1;\n    }\n    return decoder.decodeAny(val);\n  });\n","import { err, ok, Result } from 'resulty';\nimport Decoder from './Decoder';\nimport { safeStringify } from './utils';\n\n/**\n * Converts a JSON object to an array of key value pairs ((string, A)[]). The\n * passed in decoder is applied to the object value. The key will always be\n * converted to a string.\n *\n * @param decoder The internal decoder to be applied to the object values\n */\nexport const keyValuePairs = <A>(decoder: Decoder<A>): Decoder<[string, A][]> =>\n  new Decoder((value) => {\n    if (typeof value !== 'object' || value === null || value instanceof Array) {\n      return err<string, [string, A][]>(\n        `Expected to find an object and instead found '${safeStringify(value)}'`\n      );\n    }\n\n    return Object.keys(value).reduce(\n      (memo, key) =>\n        memo.andThen((pairs) =>\n          decoder\n            .decodeAny(value[key])\n            .mapError((err) => `Key '${key}' failed to decode: ${err}`)\n            .map((v) => pairs.concat([[key, v]]))\n        ),\n      ok([]) as Result<string, [string, A][]>\n    );\n  });\n\n/**\n * Converts a JSON object to a Map<string, A>.\n *\n * I would reccomend using this as a decoder of last resort. For correctness, you are\n * probably better off using field decoders and explicitly declaring the shape of the\n * objects you are expecting.\n *\n * @param decoder The internal decoder to be applied to the object values\n */\nexport const dict = <A>(decoder: Decoder<A>): Decoder<Map<string, A>> =>\n  keyValuePairs(decoder).map((pairs) =>\n    pairs.reduce((memo, [key, value]) => {\n      memo.set(key, value);\n      return memo;\n    }, new Map<string, A>())\n  );\n\n/**\n * Creates a decoder for objects where all keys are strings and all values\n * conform to a specific type.\n *\n * This function is a higher-order decoder factory. It takes a `valueDecoder`\n * as an argument, which is responsible for decoding the individual values\n * within the object. The `objectOf` function then creates a new decoder that\n * can decode an entire object, ensuring that all keys are strings and all\n * values are successfully decoded by the provided `valueDecoder`.\n *\n * @param valueDecoder - A decoder that will be used to decode each value\n *   within the object. This decoder determines the type of the values in the\n *   resulting object.\n * @returns A decoder that can decode objects with string keys and values\n *   of the type specified by `valueDecoder`.\n *\n * @example\n * ```typescript\n * import { string, number, objectOf } from './associative'; // Assuming these are in the same file\n * import { InferType } from './base'; // Assuming InferType is defined in base.ts\n *\n * // Decoder for an object where values are strings\n * const stringObjectDecoder = objectOf(string);\n * type StringObject = InferType<typeof stringObjectDecoder>;\n *\n * // Decoder for an object where values are numbers\n * const numberObjectDecoder = objectOf(number);\n * type NumberObject = InferType<typeof numberObjectDecoder>;\n *\n * // Example usage\n * const validStringObject: StringObject = { a: 'hello', b: 'world' };\n * const validNumberObject: NumberObject = { x: 1, y: 2, z: 3 };\n *\n * // Example of invalid data\n * const invalidStringObject = { a: 'hello', b: 123 }; // Error: 'b' is not a string\n * const invalidNumberObject = { x: 1, y: '2', z: 3 }; // Error: 'y' is not a number\n * ```\n */\nexport function objectOf<T>(valueDecoder: Decoder<T>): Decoder<{ [key: string]: T }> {\n  return new Decoder<{ [key: string]: T }>((value) => {\n    if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n      return err(`I expected to find an object but instead found '${safeStringify(value)}'`);\n    }\n\n    const result: { [key: string]: T } = {};\n    for (const key of Object.keys(value)) {\n      const decodedValue = valueDecoder.decodeAny(value[key]);\n      if (decodedValue.state.kind === 'err') {\n        return err(\n          `I expected the value for key \"${key}\" to be a valid value, but found: ${safeStringify(\n            value[key]\n          )}`\n        );\n      }\n      result[key] = decodedValue.state.value;\n    }\n    return ok(result);\n  });\n}\n","import { just, Maybe, nothing } from 'maybeasy';\nimport { ok } from 'resulty';\nimport Decoder from './Decoder';\n\n/**\n * Makes any decoder optional. Be aware that this can mask a failing\n * decoder because it makes any failed decoder result a nothing.\n */\nexport const maybe = <A>(decoder: Decoder<A>): Decoder<Maybe<A>> =>\n  new Decoder((value) => {\n    return decoder.decodeAny(value).cata({\n      Err: (e) => ok(nothing()),\n      Ok: (v) => ok(just(v)),\n    });\n  });\n\n/**\n * Decodes possibly null or undefined values into types.\n * There is overlap between `nullable` and `maybe` decoders.\n * The difference is that `maybe` will always succeed, even if\n * there is an error in the decoder.\n *\n * Maybe example:\n *\n *     maybe(string).decodeAny('foo') // => Ok('foo')\n *     maybe(string).decodeAny(null)  // => Ok(Nothing)\n *     maybe(string).decodeAny(42)    // => Ok(Nothing)\n *\n * Nullable example:\n *\n *     nullable(string).decodeAny('foo') // => Ok('foo')\n *     nullable(string).decodeAny(null)  // => Ok(Nothing)\n *     nullable(string).decodeAny(42)    // => Err...\n */\nexport const nullable = <A>(decoder: Decoder<A>): Decoder<Maybe<A>> =>\n  new Decoder((value) => {\n    if (value == null) {\n      return ok(nothing());\n    }\n    return decoder.decodeAny(value).map(just);\n  });\n","import { isValid, parseISO, parseJSON } from 'date-fns';\nimport { err, ok } from 'resulty';\nimport { number, string } from './base';\nimport Decoder from './Decoder';\nimport { safeStringify } from './utils';\n\n/**\n * Date decoder.\n *\n * Date decoder expects a value that is a number or a string. It will then try\n * to construct a JavaScript date object from the value.\n *\n * This decoder use the Date constructor, and so assumes the same cross browser\n * inconsistencies.\n */\nexport const date: Decoder<Date> = new Decoder<Date>((value) => {\n  const errMsg = (v: any): string => `I expected a date but instead I found ${safeStringify(v)}`;\n  return ok(value)\n    .andThen((s) => string.map((v) => new Date(v)).decodeAny(s))\n    .orElse((n) => number.map((v) => new Date(v)).decodeAny(n))\n    .andThen((d) => (isNaN(d.getTime()) ? err<any, Date>(value) : ok(d)))\n    .mapError(() => errMsg(value));\n});\n\n/**\n * Date ISO decoder\n *\n * The Date ISO decoder expects a value that is a string formatted in some\n * variation of ISO 8601. It will fail if the date is invalid or is not a\n * recognized ISO 8601 format.\n *\n * Relies on parseISO from date-fns\n * https://date-fns.org/v2.16.1/docs/parseISO\n */\nexport const dateISO: Decoder<Date> = new Decoder<Date>((value) => {\n  return ok<string, unknown>(value)\n    .andThen((v) => string.decodeAny(v))\n    .map(parseISO)\n    .andThen((d) =>\n      isValid(d) ? ok(d) : err(`I expected an ISO date but instead I found ${safeStringify(value)}`)\n    );\n});\n\n/**\n * Date JSON decoder\n *\n * This decoder parses date formats common in JSON APIs\n *\n * See parseJSON from date-fns for more information on supported formats\n * https://date-fns.org/v2.16.1/docs/parseJSON\n *\n */\nexport const dateJSON: Decoder<Date> = new Decoder<Date>((value) => {\n  return ok<string, unknown>(value)\n    .andThen((v) => string.decodeAny(v))\n    .map(parseJSON)\n    .andThen((d) =>\n      isValid(d)\n        ? ok(d)\n        : err(`I expected an JSON date but instead I found ${safeStringify(value)}`)\n    );\n});\n","import { err, ok } from 'resulty';\nimport Decoder from './Decoder';\nimport { safeStringify } from './utils';\n\n/**\n * Creates a decoder that checks if the input value is equal to the specified value.\n *\n * @typeParam T - The type of the value to compare.\n * @param t - The value to compare against the input.\n * @returns A `Decoder` that succeeds if the input value is equal to `t`, otherwise fails with an error message.\n */\nexport const eql = <T>(t: T): Decoder<T> =>\n  new Decoder<T>((v) => {\n    return t === v ? ok(v) : err(`Expected ${t} but got ${safeStringify(v)}`);\n  });\n","import { err, Result } from 'resulty';\nimport Decoder from './Decoder';\nimport { string, succeed } from './base';\nimport { field } from './containers';\nimport { identity, safeStringify } from './utils';\nimport { eql } from './predicates';\nimport { InferType } from './types';\n\n/**\n * Creates a decoder that checks if the input is equal to the specified string literal.\n *\n * @template T - The type of the string literal.\n * @param t - The string literal to compare against.\n * @returns A decoder that validates if the input matches the string literal.\n */\nexport const stringLiteral = <T extends string>(t: T): Decoder<T> => eql<T>(t);\n\n/**\n * Creates a decoder that tries to decode a value using a list of provided decoders.\n * If none of the decoders succeed, it returns an error with a combined message of all errors.\n *\n * @template A - The type of the value to decode.\n * @param {Array<Decoder<A>>} decoders - An array of decoders to try.\n * @returns {Decoder<A>} A decoder that tries each provided decoder in order.\n */\nexport function oneOf<A>(decoders: Decoder<A>[]): Decoder<A> {\n  return new Decoder((value) => {\n    if (decoders.length === 0) {\n      return err<string, A>('No decoders specified.');\n    }\n\n    const results = decoders.map((decoder) => decoder.decodeAny(value));\n    const errors = results\n      .filter((r) => r.isErr())\n      .map((r) => r.cata({ Err: (e) => e, Ok: () => '' }));\n\n    if (results.some((r) => r.isOk())) {\n      return results.find((r) => r.isOk()) as Result<string, A>;\n    }\n\n    return err<string, A>(`I found the following problems:\\n${errors.join('\\n')}`);\n  });\n}\n\n/**\n * Creates a decoder from a given structure of decoders or nested structures.\n *\n * This function takes a structure where each value is either a `Decoder` or another\n * nested structure of decoders, and returns a `Decoder` that can decode objects\n * matching the given structure.\n *\n * @template T - The type of the structure, which is a record where each value is either\n * a `Decoder` or another nested structure.\n *\n * @param {T} structure - The structure of decoders or nested structures.\n *\n * @returns {Decoder<InferStructure<T>>} - A decoder that can decode objects matching the given structure.\n */\nexport function createDecoderFromStructure<T extends Structure>(\n  structure: T,\n  keyToLookup: (key: string) => string = identity\n): Decoder<InferStructure<T>> {\n  return Object.entries(structure).reduce((acc, [key, decoderOrStructure]) => {\n    const decoder = isDecoder(decoderOrStructure)\n      ? field(keyToLookup(key), decoderOrStructure)\n      : field(keyToLookup(key), createDecoderFromStructure(decoderOrStructure));\n    return acc.assign(key, decoder);\n  }, succeed({}) as Decoder<any>);\n}\n\n/**\n * Checks if the provided value is an instance of the Decoder class.\n *\n * @param value - The value to check.\n * @returns A boolean indicating whether the value is a Decoder instance.\n */\nfunction isDecoder(value: any): value is Decoder<any> {\n  return value instanceof Decoder;\n}\n\n/**\n * Represents a structure where each key is associated with either a `Decoder` of any type or another nested `Structure`.\n * This allows for the creation of complex, nested data structures that can be decoded.\n *\n * @typeParam key - The key of the structure, which is a string.\n * @typeParam Decoder - A generic type representing a decoder for any type.\n */\ntype Structure = { [key: string]: Decoder<any> | Structure };\n\n/**\n * Infers the TypeScript type from a given `Structure` type.\n *\n * This utility type recursively maps over the keys of the `Structure` type `T`\n * and infers the corresponding TypeScript type for each key.\n *\n * - If the value of a key is a `Decoder` type, it infers the type `U` that the `Decoder` decodes to.\n * - If the value of a key is another `Structure`, it recursively infers the structure of that nested `Structure`.\n * - Otherwise, it results in `never`.\n *\n * @template T - The `Structure` type from which to infer the TypeScript type.\n */\ntype InferStructure<T extends Structure> = {\n  [K in keyof T]: T[K] extends Decoder<infer U>\n    ? U\n    : T[K] extends Structure\n    ? InferStructure<T[K]>\n    : never;\n};\n\n// Helper type to infer the union type from the mapping values\ntype InferUnionFromMapping<T extends { [K in string]: Decoder<any> }> = {\n  [K in keyof T]: InferType<T[K]>;\n}[keyof T]; // This extracts the types of all decoders in the mapping and creates a union\n\n/**\n * Creates a decoder for a discriminated union type. A discriminated union is a union of object types\n * where each object type is identified by a specific value in a shared discriminator field.\n *\n * @template DiscriminatorKey - The name of the discriminator field (e.g., `'type'`).\n * @template Mapping - A mapping object where keys are discriminator values and values are decoders\n *                     for the corresponding object types.\n *\n * @param discriminatorField - The name of the field used to discriminate between union variants.\n * @param mapping - An object mapping discriminator values to their respective decoders.\n *\n * @returns A `Decoder` that decodes values into the appropriate union variant based on the discriminator field.\n *\n * @throws If the discriminator field is missing, has an invalid value, or if the value does not match\n *         any key in the mapping, an error is returned.\n *\n * @example\n * ```typescript\n * const userDecoder = object({ type: stringLiteral('user'), name: string });\n * const adminDecoder = object({ type: stringLiteral('admin'), permissions: array(string) });\n *\n * const unionDecoder = discriminatedUnion('type', {\n *   user: userDecoder,\n *   admin: adminDecoder,\n * });\n *\n * const result = unionDecoder.decode({\n *   type: 'user',\n *   name: 'Alice',\n * });\n * // result: { type: 'user', name: 'Alice' }\n * ```\n */\nexport function discriminatedUnion<\n  DiscriminatorKey extends string, // The name of the discriminator field (e.g., 'type')\n  Mapping extends { [K in string]: Decoder<any> } // The map from discriminator value to decoder\n>(discriminatorField: DiscriminatorKey, mapping: Mapping): Decoder<InferUnionFromMapping<Mapping>> {\n  // Return type is the union of all variant types\n\n  // Pre-decode the discriminator field to check its type (usually string)\n  const discriminatorDecoder = field(discriminatorField, string); // Assuming string discriminator\n\n  return new Decoder((value) => {\n    // 1. Decode the discriminator value first\n    const discriminatorResult = discriminatorDecoder.decodeAny(value);\n\n    if (discriminatorResult.state.kind === 'err') {\n      // Error if the discriminator field is missing or not a string\n      return err(\n        `Missing or invalid discriminator field '${discriminatorField}' in ${safeStringify(value)}`\n      );\n    }\n\n    const discriminatorValue = discriminatorResult.state.value; // e.g., 'user', 'admin'\n\n    // 2. Find the corresponding decoder in the mapping\n    const selectedDecoder = mapping[discriminatorValue];\n\n    if (!selectedDecoder) {\n      // Error if the discriminator value doesn't match any key in the mapping\n      const knownTypes = Object.keys(mapping).join(', ');\n      return err(\n        `Unexpected discriminator value '${discriminatorValue}' for field '${discriminatorField}'. Expected one of: ${knownTypes}. Found in: ${safeStringify(\n          value\n        )}`\n      );\n    }\n\n    // 3. Apply the selected decoder to the original value\n    // We apply it to the whole value, assuming the variant decoder expects the discriminator field too\n    // (which is common if using createDecoderFromStructure with stringLiteral)\n    return selectedDecoder\n      .decodeAny(value)\n      .mapError(\n        (e) => `Error decoding variant with ${discriminatorField}='${discriminatorValue}': ${e}`\n      );\n  });\n}\n","import { err, ok } from 'resulty';\nimport Decoder from './Decoder';\nimport { safeStringify } from './utils';\n\n/**\n * Creates a decoder that validates if a string matches a given regular expression.\n *\n * @param regex - The regular expression to test against the input string.\n * @returns A `Decoder` that checks if the input string matches the provided regular expression.\n *\n * The decoder will return:\n * - `ok(RegExpExecArray)` if the input string matches the regular expression.\n * - `err(string)` if the input is not a string or does not match the regular expression.\n *\n * @example\n * ```typescript\n * const emailDecoder = regex(/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/);\n * const result = emailDecoder.decode(\"example@example.com\");\n * // result is ok([\"example@example.com\"])\n *\n * const invalidResult = emailDecoder.decode(\"invalid-email\");\n * // invalidResult is err('The string \"invalid-email\" does not match the regular expression: /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/')\n * ```\n */\nexport const regex = (regex: RegExp): Decoder<RegExpExecArray> =>\n  new Decoder((value) => {\n    // Explicitly handle null and undefined values\n    if (value === null || value === undefined) {\n      return err(`Expected a string, but received: ${safeStringify(value)}`);\n    }\n\n    if (typeof value !== 'string') {\n      return err(`Expected a string, but received: ${safeStringify(value)}`);\n    }\n\n    const match = regex.exec(value);\n    if (match) {\n      return ok(match);\n    } else {\n      return err(\n        `The string \"${value}\" does not match the regular expression: ${regex.toString()}`\n      );\n    }\n  });\n"]}