{"version":3,"file":"build-type.mjs","sources":["../../src/array/build-type.mts"],"sourcesContent":["import { Arr, Result } from 'ts-data-forge';\nimport { type Type } from '../type.mjs';\nimport {\n  createAssertFn,\n  createCastFn,\n  createIsFn,\n  prependIndexToValidationErrors,\n  type ValidationError,\n} from '../utils/index.mjs';\n\n/**\n * Validates each element of `a` against `elementType`, collecting any element\n * errors with their index prepended. Shared by the length-constrained array\n * validators.\n *\n * @internal Not part of the public package API.\n */\nexport const validateElements = <A,>(\n  a: readonly unknown[],\n  elementType: Type<A>,\n): Result<readonly A[], readonly ValidationError[]> => {\n  const errors: readonly ValidationError[] = Arr.generate(function* () {\n    for (const [index, el] of a.entries()) {\n      const res = elementType.validate(el);\n\n      if (Result.isErr(res)) {\n        yield* prependIndexToValidationErrors(res.value, index);\n      }\n    }\n  });\n\n  if (Arr.isNonEmpty(errors)) {\n    return Result.err(errors);\n  }\n\n  // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n  return Result.ok(a as readonly A[]);\n};\n\n/**\n * Assembles a structural `Type<readonly A[]>` from the length-specific pieces\n * (`typeName` / `getDefaultValue` / `validate` / `fill`). Shared internally by\n * the length-constrained array validators (`fixedLengthArray` etc.) and the\n * `nonEmptyArray` validator; their outer signatures narrow the structural\n * result to the branded array type.\n *\n * @internal Not part of the public package API.\n */\nexport const buildType = <Elm, T extends readonly Elm[] = readonly Elm[]>({\n  typeName,\n  getDefaultValue,\n  validate,\n  fill,\n  elementType,\n}: Readonly<{\n  typeName: string;\n  getDefaultValue: () => readonly Elm[];\n  validate: (a: unknown) => Result<readonly Elm[], readonly ValidationError[]>;\n  fill: (a: unknown) => readonly Elm[];\n  elementType: Type<Elm>;\n}>): Type<T> => {\n  const base: Type<readonly Elm[]> = {\n    typeName,\n    get defaultValue() {\n      return getDefaultValue();\n    },\n    fill,\n    prune: (a) => a.map((el) => elementType.prune(el)),\n    validate,\n    is: createIsFn(validate),\n    cast: createCastFn(validate),\n    assertIs: createAssertFn(validate),\n  } as const;\n\n  // The branded output type `T` (e.g. `NonEmptyArray` / `FixedLengthArray`) is\n  // a subtype of the structural `readonly Elm[]` the validator actually\n  // produces. The brand is guaranteed by the caller's `validate` / `fill` but\n  // cannot be proven structurally, so it is asserted here once, on behalf of\n  // every length-constrained array validator, instead of at each call site.\n  // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n  return base as Type<T>;\n};\n"],"names":[],"mappings":";;;;;;AAiBO,MAAM,gBAAA,GAAmB,CAC9B,CAAA,EACA,WAAA,KACqD;AACrD,EAAA,MAAM,MAAA,GAAqC,GAAA,CAAI,QAAA,CAAS,aAAa;AACnE,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,EAAE,CAAA,IAAK,CAAA,CAAE,SAAQ,EAAG;AACrC,MAAA,MAAM,GAAA,GAAM,WAAA,CAAY,QAAA,CAAS,EAAE,CAAA;AAEnC,MAAA,IAAI,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA,EAAG;AACrB,QAAA,OAAO,8BAAA,CAA+B,GAAA,CAAI,KAAA,EAAO,KAAK,CAAA;AAAA,MACxD;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAI,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,EAAG;AAC1B,IAAA,OAAO,MAAA,CAAO,IAAI,MAAM,CAAA;AAAA,EAC1B;AAGA,EAAA,OAAO,MAAA,CAAO,GAAG,CAAiB,CAAA;AACpC;AAWO,MAAM,YAAY,CAAiD;AAAA,EACxE,QAAA;AAAA,EACA,eAAA;AAAA,EACA,QAAA;AAAA,EACA,IAAA;AAAA,EACA;AACF,CAAA,KAMgB;AACd,EAAA,MAAM,IAAA,GAA6B;AAAA,IACjC,QAAA;AAAA,IACA,IAAI,YAAA,GAAe;AACjB,MAAA,OAAO,eAAA,EAAgB;AAAA,IACzB,CAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA,EAAO,CAAC,CAAA,KAAM,CAAA,CAAE,GAAA,CAAI,CAAC,EAAA,KAAO,WAAA,CAAY,KAAA,CAAM,EAAE,CAAC,CAAA;AAAA,IACjD,QAAA;AAAA,IACA,EAAA,EAAI,WAAW,QAAQ,CAAA;AAAA,IACvB,IAAA,EAAM,aAAa,QAAQ,CAAA;AAAA,IAC3B,QAAA,EAAU,eAAe,QAAQ;AAAA,GACnC;AAQA,EAAA,OAAO,IAAA;AACT;;;;"}