{"version":3,"file":"refined.types-B1JhgNW4.cjs","names":["_data: unknown","err: z.ZodError","tag: sym","schema: U","errConst?: (data: U[\"_input\"], err: z.ZodError) => E","data: unknown","extensions: Extensions<U, sym, E>","Email: TEmail","UUIDInner: TUUIDInner","UUID: TUUID","DTInner: TDTInner","DateTime: TDateTime","tag: string | symbol","msg: string","err: ZodError","tag: Tag","enumValues: T","innerType: InnerType","extended: ExtendedType","a: T[number] | (T[number] & z.BRAND<Tag>)","b: T[number] | (T[number] & z.BRAND<Tag>)","value: EnumType[\"$infer\"]","_enumType: EnumType","actions: Actions"],"sources":["../src/domain/refined.types.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { Result } from \"@carbonteq/fp\";\nimport z, { type ZodEnum, type ZodError } from \"zod\";\nimport { fromZodError } from \"zod-validation-error\";\nimport { extend } from \"../shared/misc.utils.js\";\nimport { unsafeCast } from \"../shared/type.utils.js\";\nimport { type DomainError, ValidationError } from \"./base.errors.js\";\n\n// type OverwriteValueOf<T, Schema extends z.ZodTypeAny> = Omit<T, \"valueOf\"> & {\n// \tvalueOf(): Schema[\"_output\"];\n// };\ntype Extensions<\n  Schema extends z.ZodTypeAny,\n  Tag extends string | symbol,\n  Err extends DomainError,\n> = {\n  create: (data: unknown) => Result<Schema[\"_output\"] & z.BRAND<Tag>, Err>;\n  $infer: Schema[\"_output\"] & z.BRAND<Tag>;\n  $inferPrimitive: Schema[\"_output\"];\n  primitive(branded: Schema[\"_output\"] & z.BRAND<Tag>): Schema[\"_output\"];\n};\n\ntype ZodBrandedWithFactory<\n  Schema extends z.ZodTypeAny,\n  Tag extends string | symbol,\n  Err extends DomainError,\n> = z.ZodBranded<Schema, Tag> & Extensions<Schema, Tag, Err>;\n\nconst defaultFromZodErr = (_data: unknown, err: z.ZodError) =>\n  new ValidationError(fromZodError(err).message);\n\nexport function createRefinedType<\n  Tag extends string | symbol,\n  Schema extends z.ZodTypeAny,\n>(\n  _tag: Tag,\n  schema: Schema,\n): ZodBrandedWithFactory<Schema, Tag, ValidationError>;\nexport function createRefinedType<\n  Tag extends string | symbol,\n  Schema extends z.ZodTypeAny,\n  Err extends DomainError,\n>(\n  _tag: Tag,\n  schema: Schema,\n  errTransformer: (data: Schema[\"_input\"], err: z.ZodError) => Err,\n): ZodBrandedWithFactory<Schema, Tag, Err>;\nexport function createRefinedType<\n  sym extends string | symbol,\n  U extends z.ZodTypeAny,\n  E extends DomainError,\n>(\n  tag: sym,\n  schema: U,\n  errConst?: (data: U[\"_input\"], err: z.ZodError) => E,\n): ZodBrandedWithFactory<U, sym, E> {\n  const errTransformer = errConst ?? defaultFromZodErr;\n  const branded = schema.brand<sym>();\n\n  const factory = (data: unknown): Result<U[\"_output\"], E> => {\n    const res = branded.safeParse(data);\n\n    if (res.success) return Result.Ok(res.data);\n    const err = errTransformer(data, res.error) as E;\n    return Result.Err(err);\n  };\n\n  const extensions: Extensions<U, sym, E> = {\n    create: factory,\n    //@ts-expect-error\n    $infer: tag,\n    $inferPrimitive: tag,\n    // get $infer(): U[\"_output\"] & z.BRAND<sym> {\n    // \tthrow new Error(\"$infer not meant to be called at runtime\");\n    // },\n    // get $inferInner(): U[\"_output\"] {\n    // \tthrow new Error(\"$inferInner not meant to be called at runtime\");\n    // },\n    primitive(branded) {\n      return branded;\n    },\n  };\n  const finalBranded = extend(branded, extensions);\n\n  return finalBranded;\n}\n\nexport type Unbrand<T> = T extends z.ZodType<unknown, z.ZodTypeDef, infer U>\n  ? U\n  : T;\n\nexport class InvalidUUID extends ValidationError {\n  constructor(data: unknown) {\n    super(`Invalid UUID: ${data}`);\n  }\n}\n\n// Example of how to use refined branded types with Zod\n// Custom error type not mandatory\nexport class InvalidEmail extends ValidationError {\n  constructor(data: unknown) {\n    super(`Invalid Email: ${data}`);\n  }\n}\n\ntype TEmail = ZodBrandedWithFactory<z.ZodString, \"Email\", InvalidEmail>;\nexport const Email: TEmail = createRefinedType(\n  \"Email\",\n  z.string().email(),\n\n  (data, _err) => new InvalidEmail(data),\n);\nexport type Email = typeof Email.$infer;\n\n// Not a good example as I wanted to add some custom stuff\ntype TUUIDSchema = z.ZodString;\ntype TUUIDInner = ZodBrandedWithFactory<TUUIDSchema, \"UUID\", InvalidUUID>;\nconst UUIDInner: TUUIDInner = createRefinedType(\n  \"UUID\",\n  z.string().uuid(),\n  (data, _err) => new InvalidUUID(data),\n);\nexport type UUID = typeof UUIDInner.$infer;\ntype TUUID = TUUIDInner & {\n  init: () => UUID;\n  fromTrusted: (s: string) => UUID;\n};\nexport const UUID: TUUID = extend(UUIDInner, {\n  init: () => randomUUID() as UUID,\n  fromTrusted: unsafeCast<UUID, string>,\n});\n\nexport class InvalidDateTime extends ValidationError {\n  constructor(data: unknown) {\n    super(`Invalid DateTime: ${data}`);\n  }\n}\n\ntype TDTInnerSchema = z.ZodPipeline<\n  z.ZodUnion<[z.ZodNumber, z.ZodString, z.ZodDate]>,\n  z.ZodDate\n>;\ntype TDTInner = ZodBrandedWithFactory<\n  TDTInnerSchema,\n  \"DateTime\",\n  InvalidDateTime\n>;\nconst DTInner: TDTInner = createRefinedType(\n  \"DateTime\",\n  z.union([z.number(), z.string(), z.date()]).pipe(z.coerce.date()),\n  (data, _err) => new InvalidDateTime(data),\n);\nexport type DateTime = typeof DTInner.$infer;\ntype TDateTime = TDTInner & {\n  now: () => DateTime;\n  from: (d: Date | DateTime) => DateTime;\n};\nexport const DateTime: TDateTime = extend(DTInner, {\n  now: () => new Date() as DateTime,\n  from: unsafeCast<DateTime, Date | DateTime>,\n});\n\n// Enum types\nexport class EnumValidationError extends ValidationError {\n  constructor(\n    readonly tag: string | symbol,\n    msg: string,\n    readonly data: unknown,\n    readonly err: ZodError,\n  ) {\n    super(msg);\n  }\n}\n\ntype EnumTypeUtil<\n  Tag extends string | symbol,\n  U extends string,\n  T extends [U, ...U[]],\n> = ZodBrandedWithFactory<\n  z.ZodEnum<z.Writeable<T>>,\n  Tag,\n  EnumValidationError\n> & {\n  from: (v: T[number]) => z.Writeable<T>[number] & z.BRAND<Tag>;\n  values: Readonly<T>;\n  eq: (\n    a: T[number] | (T[number] & z.BRAND<Tag>),\n    b: T[number] | (T[number] & z.BRAND<Tag>),\n  ) => boolean;\n};\n\nexport const createEnumType = <\n  Tag extends string | symbol,\n  U extends string,\n  T extends [U, ...U[]],\n>(\n  tag: Tag,\n  enumValues: T,\n): EnumTypeUtil<Tag, U, T> => {\n  type InnerType = ZodBrandedWithFactory<\n    z.ZodEnum<z.Writeable<T>>,\n    Tag,\n    EnumValidationError\n  >;\n  const innerType: InnerType = createRefinedType(\n    tag,\n    z.enum(enumValues),\n    (data, err) =>\n      new EnumValidationError(\n        tag,\n        `<${data.valueOf()}> must be one of ${enumValues.valueOf()}`,\n        data,\n        err,\n      ),\n  );\n\n  type ExtendedType = InnerType & {\n    from: (v: T[number]) => z.Writeable<T>[number] & z.BRAND<Tag>;\n    values: Readonly<T>;\n    eq: (\n      a: T[number] | (T[number] & z.BRAND<Tag>),\n      b: T[number] | (T[number] & z.BRAND<Tag>),\n    ) => boolean;\n  };\n\n  const extended: ExtendedType = extend(innerType, {\n    from: unsafeCast<typeof innerType.$infer, T[number]>,\n    get values(): Readonly<T> {\n      return enumValues;\n    },\n    eq(\n      a: T[number] | (T[number] & z.BRAND<Tag>),\n      b: T[number] | (T[number] & z.BRAND<Tag>),\n    ): boolean {\n      return a === b;\n    },\n  });\n\n  return extended;\n};\n\ntype MatchActions<T extends string | symbol | number, R> = {\n  [K in T]: () => R;\n};\n\nexport function matchEnum<\n  Tag extends string | symbol,\n  U extends string,\n  T extends [U, ...U[]],\n  EnumType extends ZodBrandedWithFactory<ZodEnum<T>, Tag, EnumValidationError>,\n  // biome-ignore lint/suspicious/noExplicitAny: <explanation>\n  Actions extends MatchActions<EnumType[\"$inferPrimitive\"], any>,\n>(\n  value: EnumType[\"$infer\"],\n  _enumType: EnumType,\n  actions: Actions,\n): ReturnType<Actions[EnumType[\"$inferPrimitive\"]]> {\n  const key = value as unknown as keyof typeof actions;\n  if (key in actions) {\n    return actions[key]();\n  }\n  throw new Error(`Unhandled enum value: ${value.valueOf()}`);\n}\n"],"mappings":";;;;;;;;;;;AA4BA,MAAM,oBAAoB,CAACA,OAAgBC,QACzC,IAAI,oCAAgB,uCAAa,IAAI,CAAC;AAkBxC,SAAgB,kBAKdC,KACAC,QACAC,UACkC;CAClC,MAAM,iBAAiB,YAAY;CACnC,MAAM,UAAU,OAAO,OAAY;CAEnC,MAAM,UAAU,CAACC,SAA2C;EAC1D,MAAM,MAAM,QAAQ,UAAU,KAAK;AAEnC,MAAI,IAAI,QAAS,QAAO,sBAAO,GAAG,IAAI,KAAK;EAC3C,MAAM,MAAM,eAAe,MAAM,IAAI,MAAM;AAC3C,SAAO,sBAAO,IAAI,IAAI;CACvB;CAED,MAAMC,aAAoC;EACxC,QAAQ;EAER,QAAQ;EACR,iBAAiB;EAOjB,UAAU,WAAS;AACjB,UAAO;EACR;CACF;CACD,MAAM,eAAe,0BAAO,SAAS,WAAW;AAEhD,QAAO;AACR;AAMD,IAAa,cAAb,cAAiC,oCAAgB;CAC/C,YAAYD,MAAe;AACzB,SAAO,gBAAgB,KAAK,EAAE;CAC/B;AACF;AAID,IAAa,eAAb,cAAkC,oCAAgB;CAChD,YAAYA,MAAe;AACzB,SAAO,iBAAiB,KAAK,EAAE;CAChC;AACF;AAGD,MAAaE,QAAgB,kBAC3B,SACA,YAAE,QAAQ,CAAC,OAAO,EAElB,CAAC,MAAM,SAAS,IAAI,aAAa,MAClC;AAMD,MAAMC,YAAwB,kBAC5B,QACA,YAAE,QAAQ,CAAC,MAAM,EACjB,CAAC,MAAM,SAAS,IAAI,YAAY,MACjC;AAMD,MAAaC,OAAc,0BAAO,WAAW;CAC3C,MAAM,MAAM,6BAAY;CACxB,aAAa;AACd,EAAC;AAEF,IAAa,kBAAb,cAAqC,oCAAgB;CACnD,YAAYJ,MAAe;AACzB,SAAO,oBAAoB,KAAK,EAAE;CACnC;AACF;AAWD,MAAMK,UAAoB,kBACxB,YACA,YAAE,MAAM;CAAC,YAAE,QAAQ;CAAE,YAAE,QAAQ;CAAE,YAAE,MAAM;AAAC,EAAC,CAAC,KAAK,YAAE,OAAO,MAAM,CAAC,EACjE,CAAC,MAAM,SAAS,IAAI,gBAAgB,MACrC;AAMD,MAAaC,WAAsB,0BAAO,SAAS;CACjD,KAAK,MAAM,IAAI;CACf,MAAM;AACP,EAAC;AAGF,IAAa,sBAAb,cAAyC,oCAAgB;CACvD,YACWC,KACTC,KACSR,MACAS,KACT;AACA,QAAM,IAAI;AALD,OAAA,MAAA;AAEA,OAAA,OAAA;AACA,OAAA,MAAA;CAGV;AACF;AAmBD,MAAa,iBAAiB,CAK5BC,KACAC,eAC4B;CAM5B,MAAMC,YAAuB,kBAC3B,KACA,YAAE,KAAK,WAAW,EAClB,CAAC,MAAM,QACL,IAAI,oBACF,MACC,GAAG,KAAK,SAAS,CAAC,mBAAmB,WAAW,SAAS,CAAC,GAC3D,MACA,KAEL;CAWD,MAAMC,WAAyB,0BAAO,WAAW;EAC/C,MAAM;EACN,IAAI,SAAsB;AACxB,UAAO;EACR;EACD,GACEC,GACAC,GACS;AACT,UAAO,MAAM;EACd;CACF,EAAC;AAEF,QAAO;AACR;AAMD,SAAgB,UAQdC,OACAC,WACAC,SACkD;CAClD,MAAM,MAAM;AACZ,KAAI,OAAO,QACT,QAAO,QAAQ,MAAM;AAEvB,OAAM,IAAI,OAAO,wBAAwB,MAAM,SAAS,CAAC;AAC1D"}