{"version":3,"file":"utilities.cjs","sourceRoot":"","sources":["../../src/structs/utilities.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, Validator } from '../struct.js';\nimport { Struct } from '../struct.js';\nimport type {\n  Assign,\n  ObjectSchema,\n  ObjectType,\n  PartialObjectSchema,\n} from '../utils.js';\nimport { object, optional, type } from './types.js';\n\n/**\n * Create a new struct that combines the properties from multiple object or type\n * structs. Its return type will match the first parameter's type.\n *\n * Like JavaScript's `Object.assign` utility.\n *\n * @param First - The first struct to combine.\n * @param Second - The second struct to combine.\n * @returns A new struct that combines the properties of the input structs.\n */\nexport function assign<First extends ObjectSchema, Second extends ObjectSchema>(\n  First: Struct<ObjectType<First>, First>,\n  Second: Struct<ObjectType<Second>, Second>,\n): Struct<ObjectType<Assign<First, Second>>, Assign<First, Second>>;\n\n/**\n * Create a new struct that combines the properties from multiple object or type\n * structs. Its return type will match the first parameter's type.\n *\n * @param First - The first struct to combine.\n * @param Second - The second struct to combine.\n * @param Third - The third struct to combine.\n * @returns A new struct that combines the properties of the input structs.\n */\nexport function assign<\n  First extends ObjectSchema,\n  Second extends ObjectSchema,\n  Third extends ObjectSchema,\n>(\n  First: Struct<ObjectType<First>, First>,\n  Second: Struct<ObjectType<Second>, Second>,\n  Third: Struct<ObjectType<Third>, Third>,\n): Struct<\n  ObjectType<Assign<Assign<First, Second>, Third>>,\n  Assign<Assign<First, Second>, Third>\n>;\n\n/**\n * Create a new struct that combines the properties from multiple object or type\n * structs. Its return type will match the first parameter's type.\n *\n * @param First - The first struct to combine.\n * @param Second - The second struct to combine.\n * @param Third - The third struct to combine.\n * @param Fourth - The fourth struct to combine.\n * @returns A new struct that combines the properties of the input structs.\n */\nexport function assign<\n  First extends ObjectSchema,\n  Second extends ObjectSchema,\n  Third extends ObjectSchema,\n  Fourth extends ObjectSchema,\n>(\n  First: Struct<ObjectType<First>, First>,\n  Second: Struct<ObjectType<Second>, Second>,\n  Third: Struct<ObjectType<Third>, Third>,\n  Fourth: Struct<ObjectType<Fourth>, Fourth>,\n): Struct<\n  ObjectType<Assign<Assign<Assign<First, Second>, Third>, Fourth>>,\n  Assign<Assign<Assign<First, Second>, Third>, Fourth>\n>;\n\n/**\n * Create a new struct that combines the properties from multiple object or type\n * structs. Its return type will match the first parameter's type.\n *\n * @param First - The first struct to combine.\n * @param Second - The second struct to combine.\n * @param Third - The third struct to combine.\n * @param Fourth - The fourth struct to combine.\n * @param Fifth - The fifth struct to combine.\n * @returns A new struct that combines the properties of the input structs.\n */\nexport function assign<\n  First extends ObjectSchema,\n  Second extends ObjectSchema,\n  Third extends ObjectSchema,\n  Fourth extends ObjectSchema,\n  Fifth extends ObjectSchema,\n>(\n  First: Struct<ObjectType<First>, First>,\n  Second: Struct<ObjectType<Second>, Second>,\n  Third: Struct<ObjectType<Third>, Third>,\n  Fourth: Struct<ObjectType<Fourth>, Fourth>,\n  Fifth: Struct<ObjectType<Fifth>, Fifth>,\n): Struct<\n  ObjectType<\n    Assign<Assign<Assign<Assign<First, Second>, Third>, Fourth>, Fifth>\n  >,\n  Assign<Assign<Assign<Assign<First, Second>, Third>, Fourth>, Fifth>\n>;\n\n/**\n * Create a new struct that combines the properties from multiple object or type\n * structs. Its return type will match the first parameter's type.\n *\n * @param Structs - The structs to combine.\n * @returns A new struct that combines the properties of the input structs.\n */\nexport function assign(...Structs: Struct<any>[]): any {\n  const isType = Structs[0]?.type === 'type';\n  const schemas = Structs.map(({ schema }) => schema);\n  const schema = Object.assign({}, ...schemas);\n  return isType ? type(schema) : object(schema);\n}\n\n/**\n * Define a new struct type with a custom validation function.\n *\n * @param name - The name of the struct type.\n * @param validator - The validation function.\n * @returns A new struct type.\n */\nexport function define<Type>(\n  name: string,\n  validator: Validator,\n): Struct<Type, null> {\n  return new Struct({ type: name, schema: null, validator });\n}\n\n/**\n * Create a new struct based on an existing struct, but the value is allowed to\n * be `undefined`. `log` will be called if the value is not `undefined`.\n *\n * @param struct - The struct to augment.\n * @param log - The function to call when the value is not `undefined`.\n * @returns A new struct that will only accept `undefined` or values that pass\n * the input struct.\n */\nexport function deprecated<Type>(\n  struct: Struct<Type>,\n  log: (value: unknown, ctx: Context) => void,\n): Struct<Type> {\n  return new Struct({\n    ...struct,\n    refiner: (value, ctx) => value === undefined || struct.refiner(value, ctx),\n    validator(value, ctx) {\n      if (value === undefined) {\n        return true;\n      }\n      log(value, ctx);\n      return struct.validator(value, ctx);\n    },\n  });\n}\n\n/**\n * Create a struct with dynamic validation logic.\n *\n * The callback will receive the value currently being validated, and must\n * return a struct object to validate it with. This can be useful to model\n * validation logic that changes based on its input.\n *\n * @param fn - The callback to create the struct.\n * @returns A new struct with dynamic validation logic.\n */\nexport function dynamic<Type>(\n  fn: (value: unknown, ctx: Context) => Struct<Type, any>,\n): Struct<Type, null> {\n  return new Struct({\n    type: 'dynamic',\n    schema: null,\n    *entries(value, ctx) {\n      const struct = fn(value, ctx);\n      yield* struct.entries(value, ctx);\n    },\n    validator(value, ctx) {\n      const struct = fn(value, ctx);\n      return struct.validator(value, ctx);\n    },\n    coercer(value, ctx) {\n      const struct = fn(value, ctx);\n      return struct.coercer(value, ctx);\n    },\n    refiner(value, ctx) {\n      const struct = fn(value, ctx);\n      return struct.refiner(value, ctx);\n    },\n  });\n}\n\n/**\n * Create a struct with lazily evaluated validation logic.\n *\n * The first time validation is run with the struct, the callback will be called\n * and must return a struct object to use. This is useful for cases where you\n * want to have self-referential structs for nested data structures to avoid a\n * circular definition problem.\n *\n * @param fn - The callback to create the struct.\n * @returns A new struct with lazily evaluated validation logic.\n */\nexport function lazy<Type>(fn: () => Struct<Type, any>): Struct<Type, null> {\n  let struct: Struct<Type, any> | undefined;\n  return new Struct({\n    type: 'lazy',\n    schema: null,\n    *entries(value, ctx) {\n      struct ??= fn();\n      yield* struct.entries(value, ctx);\n    },\n    validator(value, ctx) {\n      struct ??= fn();\n      return struct.validator(value, ctx);\n    },\n    coercer(value, ctx) {\n      struct ??= fn();\n      return struct.coercer(value, ctx);\n    },\n    refiner(value, ctx) {\n      struct ??= fn();\n      return struct.refiner(value, ctx);\n    },\n  });\n}\n\n/**\n * Create a new struct based on an existing object struct, but excluding\n * specific properties.\n *\n * Like TypeScript's `Omit` utility.\n *\n * @param struct - The struct to augment.\n * @param keys - The keys to omit.\n * @returns A new struct that will not accept the input keys.\n */\nexport function omit<Schema extends ObjectSchema, Key extends keyof Schema>(\n  struct: Struct<ObjectType<Schema>, Schema>,\n  keys: Key[],\n): Struct<ObjectType<Omit<Schema, Key>>, Omit<Schema, Key>> {\n  const { schema } = struct;\n  const subschema: any = { ...schema };\n\n  for (const key of keys) {\n    delete subschema[key];\n  }\n\n  switch (struct.type) {\n    case 'type':\n      return type(subschema as Omit<Schema, Key>);\n    default:\n      return object(subschema as Omit<Schema, Key>);\n  }\n}\n\n/**\n * Create a new struct based on an existing object struct, but with all of its\n * properties allowed to be `undefined`.\n *\n * Like TypeScript's `Partial` utility.\n *\n * @param struct - The struct to augment.\n * @returns A new struct that will accept the input keys as `undefined`.\n */\nexport function partial<Schema extends ObjectSchema>(\n  struct: Struct<ObjectType<Schema>, Schema> | Schema,\n): Struct<\n  ObjectType<PartialObjectSchema<Schema>>,\n  PartialObjectSchema<Schema>\n> {\n  const isStruct = struct instanceof Struct;\n  const schema: any = isStruct ? { ...struct.schema } : { ...struct };\n\n  // eslint-disable-next-line guard-for-in\n  for (const key in schema) {\n    schema[key] = optional(schema[key]);\n  }\n\n  if (isStruct && struct.type === 'type') {\n    return type(schema) as any;\n  }\n\n  return object(schema) as any;\n}\n\n/**\n * Create a new struct based on an existing object struct, but only including\n * specific properties.\n *\n * Like TypeScript's `Pick` utility.\n *\n * @param struct - The struct to augment.\n * @param keys - The keys to pick.\n * @returns A new struct that will only accept the input keys.\n */\nexport function pick<Schema extends ObjectSchema, Key extends keyof Schema>(\n  struct: Struct<ObjectType<Schema>, Schema>,\n  keys: Key[],\n): Struct<ObjectType<Pick<Schema, Key>>, Pick<Schema, Key>> {\n  const { schema } = struct;\n  const subschema: any = {};\n\n  for (const key of keys) {\n    subschema[key] = schema[key];\n  }\n\n  switch (struct.type) {\n    case 'type':\n      return type(subschema) as any;\n\n    default:\n      return object(subschema) as any;\n  }\n}\n"]}