import type { Refinement } from "@effect-ts/core/Function" import { pipe } from "@effect-ts/core/Function" import * as S from "../_schema.js" import { customE } from "../_schema.js" import { brand } from "./brand.js" import type { NonEmptyString } from "./nonEmptyString.js" import { fromString, string } from "./string.js" import type { DefaultSchema } from "./withDefaults.js" export interface UUIDBrand { readonly UUID: unique symbol } export const regexUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i export type UUID = NonEmptyString & UUIDBrand export const UUIDFromStringIdentifier = S.makeAnnotation<{}>() const isUUID: Refinement = (s: string): s is UUID => { return regexUUID.test(s) } export const UUIDFromString: DefaultSchema = pipe( fromString, S.arbitrary(FC => FC.uuid()), S.refine(isUUID, n => S.leafE(customE(n, "a valid UUID"))), brand(), S.annotate(UUIDFromStringIdentifier, {}) ) export const UUIDIdentifier = S.makeAnnotation<{}>() export const UUID: DefaultSchema< unknown, UUID, string, string, S.ApiSelfType > = pipe(string[">>>"](UUIDFromString), brand(), S.annotate(UUIDIdentifier, {}))