{"version":3,"file":"coercions.mjs","sourceRoot":"","sources":["../../src/structs/coercions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,sBAAqB;AAC1C,OAAO,EAAE,aAAa,EAAE,qBAAoB;AAC5C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAmB;AAE7C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,MAAM,CACpB,MAA4B,EAC5B,SAAoC,EACpC,OAA8B;IAE9B,OAAO,IAAI,MAAM,CAAC;QAChB,GAAG,MAAM;QACT,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACtB,OAAO,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC;gBACzB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC;gBAC1C,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CACvB,MAA4B,EAC5B,QAAa,EACb,UAEI,EAAE;IAEN,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAEtE,IAAI,KAAK,KAAK,SAAS,EAAE;YACvB,OAAO,MAAM,CAAC;SACf;QAED,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,EAAE;YACpE,MAAM,GAAG,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;YACzB,IAAI,OAAO,GAAG,KAAK,CAAC;YAEpB,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE;gBACxB,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE;oBAC1B,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;oBACvB,OAAO,GAAG,IAAI,CAAC;iBAChB;aACF;YAED,IAAI,OAAO,EAAE;gBACX,OAAO,GAAG,CAAC;aACZ;SACF;QAED,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,OAAO,CACrB,MAA4B;IAE5B,OAAO,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3D,CAAC","sourcesContent":["import type { Coercer } from '../struct.js';\nimport { Struct, is } from '../struct.js';\nimport { isPlainObject } from '../utils.js';\nimport { string, unknown } from './types.js';\n\n/**\n * Augment a `Struct` to add an additional coercion step to its input.\n *\n * This allows you to transform input data before validating it, to increase the\n * likelihood that it passes validation—for example for default values, parsing\n * different formats, etc.\n *\n * Note: You must use `create(value, Struct)` on the value to have the coercion\n * take effect! Using simply `assert()` or `is()` will not use coercion.\n *\n * @param struct - The struct to augment.\n * @param condition - A struct that the input must pass to be coerced.\n * @param coercer - A function that takes the input and returns the coerced\n * value.\n * @returns A new struct that will coerce its input before validating it.\n */\nexport function coerce<Type, Schema, CoercionType>(\n  struct: Struct<Type, Schema>,\n  condition: Struct<CoercionType, any>,\n  coercer: Coercer<CoercionType>,\n): Struct<Type, Schema> {\n  return new Struct({\n    ...struct,\n    coercer: (value, ctx) => {\n      return is(value, condition)\n        ? struct.coercer(coercer(value, ctx), ctx)\n        : struct.coercer(value, ctx);\n    },\n  });\n}\n\n/**\n * Augment a struct to replace `undefined` values with a default.\n *\n * Note: You must use `create(value, Struct)` on the value to have the coercion\n * take effect! Using simply `assert()` or `is()` will not use coercion.\n *\n * @param struct - The struct to augment.\n * @param fallback - The value to use when the input is `undefined`.\n * @param options - An optional options object.\n * @param options.strict - When `true`, the fallback will only be used when the\n * input is `undefined`. When `false`, the fallback will be used when the input\n * is `undefined` or when the input is a plain object and the fallback is a\n * plain object, and any keys in the fallback are missing from the input.\n * @returns A new struct that will replace `undefined` inputs with a default.\n */\nexport function defaulted<Type, Schema>(\n  struct: Struct<Type, Schema>,\n  fallback: any,\n  options: {\n    strict?: boolean | undefined;\n  } = {},\n): Struct<Type, Schema> {\n  return coerce(struct, unknown(), (value) => {\n    const result = typeof fallback === 'function' ? fallback() : fallback;\n\n    if (value === undefined) {\n      return result;\n    }\n\n    if (!options.strict && isPlainObject(value) && isPlainObject(result)) {\n      const ret = { ...value };\n      let changed = false;\n\n      for (const key in result) {\n        if (ret[key] === undefined) {\n          ret[key] = result[key];\n          changed = true;\n        }\n      }\n\n      if (changed) {\n        return ret;\n      }\n    }\n\n    return value;\n  });\n}\n\n/**\n * Augment a struct to trim string inputs.\n *\n * Note: You must use `create(value, Struct)` on the value to have the coercion\n * take effect! Using simply `assert()` or `is()` will not use coercion.\n *\n * @param struct - The struct to augment.\n * @returns A new struct that will trim string inputs before validating them.\n */\nexport function trimmed<Type, Schema>(\n  struct: Struct<Type, Schema>,\n): Struct<Type, Schema> {\n  return coerce(struct, string(), (value) => value.trim());\n}\n"]}