{"version":3,"file":"required.mjs","sources":["../../src/record/required.mts"],"sourcesContent":["import { expectType } from 'ts-data-forge';\nimport {\n  type ArrayElement,\n  type NonEmptyTuple,\n  type PartiallyRequired,\n  type TypeEq,\n  type UnknownRecord,\n} from 'ts-type-forge';\nimport {\n  flattenShapeStructure,\n  hasRecordInternals,\n  type AnyType,\n  type ExcessPropertyOption,\n  type Type,\n  type TypeOf,\n  type UnknownShape,\n} from '../type.mjs';\nimport { toUnionKeyString } from '../utils/index.mjs';\nimport { isOptionalProperty, type RequiredPropertyType } from './optional.mjs';\nimport { record } from './record.mjs';\n\n/**\n * Creates a Required type. If keysToBeRequired is set, only those keys are\n * made required, otherwise, all properties are made required.\n */\nexport const required = <\n  const R extends UnknownRecord,\n  const KeysToBeRequired extends NonEmptyTuple<keyof R & string>,\n>(\n  recordType: Type<R>,\n  options?: Partial<\n    Readonly<{\n      keysToBeRequired: KeysToBeRequired;\n      typeName: string;\n      excessProperty: ExcessPropertyOption;\n    }>\n  >,\n): RequiredType<R, KeysToBeRequired> => {\n  if (!hasRecordInternals(recordType)) {\n    throw new Error(\n      `Expected a record type but received: ${recordType.typeName}`,\n    );\n  }\n\n  const shape = flattenShapeStructure(recordType.shapeStructure);\n\n  if (shape === undefined) {\n    throw new Error(\n      `required() requires a simple or intersection record type, but received a union type`,\n    );\n  }\n\n  const typeNameFilled: string =\n    options?.typeName ??\n    (options?.keysToBeRequired === undefined\n      ? `Required<${recordType.typeName}>`\n      : `PartiallyRequired<${recordType.typeName}, ${toUnionKeyString(options.keysToBeRequired)}>`);\n\n  const keysToBeRequired: ReadonlySet<string> = new Set(\n    options?.keysToBeRequired ?? Object.keys(shape),\n  );\n\n  const requiredShape = Object.fromEntries(\n    Object.entries(shape).map(\n      ([k, v]) => [k, keysToBeRequired.has(k) ? makeRequired(v) : v] as const,\n    ),\n  ) satisfies UnknownShape;\n\n  // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n  return record(requiredShape, {\n    typeName: typeNameFilled,\n    excessProperty: options?.excessProperty ?? recordType.excessProperty,\n  }) as unknown as Type<RequiredValue<R, KeysToBeRequired>>;\n};\n\ntype RequiredType<\n  R extends UnknownRecord,\n  KeysToBeRequired extends NonEmptyTuple<keyof R & string>,\n> = Type<RequiredValue<R, KeysToBeRequired>>;\n\n/** Compute the required value type. */\ntype RequiredValue<\n  R extends UnknownRecord,\n  KeysToBeRequired extends NonEmptyTuple<keyof R & string> | undefined,\n> =\n  TypeEq<KeysToBeRequired, undefined> extends true\n    ? Readonly<Required<R>>\n    : PartiallyRequired<R, ArrayElement<KeysToBeRequired>>;\n\n/**\n * Makes an optional property required by removing the optional flag.\n */\nconst makeRequired = <T extends AnyType>(t: T): RequiredPropertyType<T> => {\n  if (!isOptionalProperty(t)) {\n    // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n    return t as RequiredPropertyType<T>;\n  }\n\n  const { optional: _, ...rest } = t;\n\n  // eslint-disable-next-line total-functions/no-unsafe-type-assertion\n  return rest as RequiredPropertyType<T>;\n};\n\n// --- expectType assertions ---\n\n{\n  type Base = ReturnType<\n    typeof record<\n      Readonly<{ a: Type<0>; b: Type<1 | undefined>; c: Type<2 | undefined> }>\n    >\n  >;\n\n  // required with no keys makes all properties required\n  expectType<\n    TypeOf<ReturnType<typeof required<TypeOf<Base>, readonly ['a', 'b', 'c']>>>,\n    Readonly<Required<Readonly<{ a: 0; b: 1 | undefined; c: 2 | undefined }>>>\n  >('=');\n}\n"],"names":[],"mappings":";;;;;;;MAyBa,QAAA,GAAW,CAItB,UAAA,EACA,OAAA,KAOsC;AACtC,EAAA,IAAI,CAAC,kBAAA,CAAmB,UAAU,CAAA,EAAG;AACnC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,qCAAA,EAAwC,WAAW,QAAQ,CAAA;AAAA,KAC7D;AAAA,EAAA;AAGF,EAAA,MAAM,KAAA,GAAQ,qBAAA,CAAsB,UAAA,CAAW,cAAc,CAAA;AAE7D,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,mFAAA;AAAA,KACF;AAAA,EAAA;AAGF,EAAA,MAAM,iBACJ,OAAA,EAAS,QAAA,KACR,OAAA,EAAS,gBAAA,KAAqB,SAC3B,CAAA,SAAA,EAAY,UAAA,CAAW,QAAQ,CAAA,CAAA,CAAA,GAC/B,qBAAqB,UAAA,CAAW,QAAQ,KAAK,gBAAA,CAAiB,OAAA,CAAQ,gBAAgB,CAAC,CAAA,CAAA,CAAA,CAAA;AAE7F,EAAA,MAAM,mBAAwC,IAAI,GAAA;AAAA,IAChD,OAAA,EAAS,gBAAA,IAAoB,MAAA,CAAO,IAAA,CAAK,KAAK;AAAA,GAChD;AAEA,EAAA,MAAM,gBAAgB,MAAA,CAAO,WAAA;AAAA,IAC3B,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,GAAA;AAAA,MACpB,CAAC,CAAC,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA,EAAG,gBAAA,CAAiB,GAAA,CAAI,CAAC,CAAA,GAAI,YAAA,CAAa,CAAC,IAAI,CAAC;AAAA;AAC/D,GACF;AAGA,EAAA,OAAO,OAAO,aAAA,EAAe;AAAA,IAC3B,QAAA,EAAU,cAAA;AAAA,IACV,cAAA,EAAgB,OAAA,EAAS,cAAA,IAAkB,UAAA,CAAW;AAAA,GACvD,CAAA;AACH;AAmBA,MAAM,YAAA,GAAe,CAAoB,CAAA,KAAkC;AACzE,EAAA,IAAI,CAAC,kBAAA,CAAmB,CAAC,CAAA,EAAG;AAE1B,IAAA,OAAO,CAAA;AAAA,EAAA;AAGT,EAAA,MAAM,EAAE,QAAA,EAAU,CAAA,EAAG,GAAG,MAAK,GAAI,CAAA;AAGjC,EAAA,OAAO,IAAA;AACT,CAAA;;;;"}