{"version":3,"file":"structs.mjs","sourceRoot":"","sources":["../../src/internals/structs.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AnyStruct, Infer, InferStructTuple } from '@metamask/superstruct';\nimport {\n  Struct,\n  define,\n  record,\n  refine,\n  literal as superstructLiteral,\n  union as superstructUnion,\n} from '@metamask/superstruct';\nimport type { PlainObject } from '@metamask/utils';\nimport { hasProperty, isObject } from '@metamask/utils';\n\nimport type { EnumToUnion } from './helpers';\n\n/**\n * A wrapper of `superstruct`'s `literal` struct that also defines the name of\n * the struct as the literal value.\n *\n * This is useful for improving the error messages returned by `superstruct`.\n * For example, instead of returning an error like:\n *\n * ```\n * Expected the value to satisfy a union of `literal | literal`, but received: \\\"baz\\\"\n * ```\n *\n * This struct will return an error like:\n *\n * ```\n * Expected the value to satisfy a union of `\"foo\" | \"bar\"`, but received: \\\"baz\\\"\n * ```\n *\n * @param value - The literal value.\n * @returns The `superstruct` struct, which validates that the value is equal\n * to the literal value.\n */\nexport function literal<Type extends string | number | boolean>(value: Type) {\n  return define<Type>(\n    JSON.stringify(value),\n    superstructLiteral(value).validator,\n  );\n}\n\n/**\n * A wrapper of `superstruct`'s `union` struct that also defines the schema as\n * the union of the schemas of the structs.\n *\n * This is useful for improving the error messages returned by `superstruct`.\n *\n * @param structs - The structs to union.\n * @param structs.\"0\" - The first struct.\n * @param structs.\"1\" - The remaining structs.\n * @returns The `superstruct` struct, which validates that the value satisfies\n * one of the structs.\n */\nexport function union<Head extends AnyStruct, Tail extends AnyStruct[]>([\n  head,\n  ...tail\n]: [head: Head, ...tail: Tail]): Struct<\n  Infer<Head> | InferStructTuple<Tail>[number],\n  [head: Head, ...tail: Tail]\n> {\n  const struct = superstructUnion([head, ...tail]);\n\n  return new Struct({\n    ...struct,\n    schema: [head, ...tail],\n  });\n}\n\n/**\n * Superstruct struct for validating an enum value. This allows using both the\n * enum string values and the enum itself as values.\n *\n * @param constant - The enum to validate against.\n * @returns The superstruct struct.\n */\nexport function enumValue<Type extends string>(\n  constant: Type,\n): Struct<EnumToUnion<Type>, null> {\n  return literal(constant as EnumToUnion<Type>);\n}\n\n/**\n * Create a custom union struct that validates exclusively based on a `type` field.\n *\n * This should improve error messaging for unions with many structs in them.\n *\n * @param structs - The structs to union.\n * @returns The `superstruct` struct, which validates that the value satisfies\n * one of the structs.\n */\nexport function typedUnion<Head extends AnyStruct, Tail extends AnyStruct[]>(\n  structs: [head: Head, ...tail: Tail],\n): Struct<Infer<Head> | InferStructTuple<Tail>[number], null> {\n  const flatStructs = structs\n    .map((struct) =>\n      struct.type === 'union' && Array.isArray(struct.schema)\n        ? struct.schema\n        : struct,\n    )\n    .flat(Infinity);\n  const types = flatStructs.map(({ schema }) => schema.type.type);\n  const structMap = flatStructs.reduce<Record<string, Struct>>(\n    (accumulator, struct) => {\n      accumulator[JSON.parse(struct.schema.type.type)] = struct;\n      return accumulator;\n    },\n    {},\n  );\n  return new Struct({\n    type: 'union',\n    schema: flatStructs,\n    *entries(value, context) {\n      if (\n        !isObject(value) ||\n        !hasProperty(value, 'type') ||\n        typeof value.type !== 'string'\n      ) {\n        return;\n      }\n\n      const { type } = value;\n      const struct = structMap[type];\n\n      if (!struct) {\n        return;\n      }\n\n      for (const entry of struct.entries(value, context)) {\n        yield entry;\n      }\n    },\n    coercer(value, context) {\n      if (\n        !isObject(value) ||\n        !hasProperty(value, 'type') ||\n        typeof value.type !== 'string'\n      ) {\n        return value;\n      }\n\n      const { type } = value;\n      const struct = structMap[type];\n      if (struct) {\n        return struct.coercer(value, context);\n      }\n\n      return value;\n    },\n    // At this point we know the value to be an object.\n    *refiner(value: PlainObject & { type: string }, context) {\n      const struct = structMap[value.type];\n\n      yield* struct.refiner(value, context);\n    },\n    validator(value, context) {\n      if (\n        !isObject(value) ||\n        !hasProperty(value, 'type') ||\n        typeof value.type !== 'string'\n      ) {\n        return `Expected type to be one of: ${types.join(\n          ', ',\n        )}, but received: undefined`;\n      }\n\n      const { type } = value;\n\n      const struct = structMap[type];\n\n      if (struct) {\n        // This only validates the root of the struct, entries does the rest of the work.\n        return struct.validator(value, context);\n      }\n\n      return `Expected type to be one of: ${types.join(\n        ', ',\n      )}, but received: \"${type}\"`;\n    },\n  }) as unknown as Struct<Infer<Head> | InferStructTuple<Tail>[number], null>;\n}\n\n/**\n * Create a custom union struct that uses a `selector` function for choosing\n * the validation path.\n *\n * @param selector - The selector function choosing the struct to validate with.\n * @returns The `superstruct` struct, which validates that the value satisfies\n * one of the structs.\n */\nexport function selectiveUnion<Selector extends (value: any) => AnyStruct>(\n  selector: Selector,\n): Struct<Infer<ReturnType<Selector>>, null> {\n  return new Struct({\n    type: 'union',\n    schema: null,\n    *entries(value, context) {\n      const struct = selector(value);\n\n      for (const entry of struct.entries(value, context)) {\n        yield entry;\n      }\n    },\n    *refiner(value, context) {\n      const struct = selector(value);\n\n      yield* struct.refiner(value, context);\n    },\n    coercer(value, context) {\n      const struct = selector(value);\n\n      return struct.coercer(value, context);\n    },\n    validator(value, context) {\n      const struct = selector(value);\n\n      // This only validates the root of the struct, entries does the rest of the work.\n      return struct.validator(value, context);\n    },\n  });\n}\n\n/**\n * Refine a struct to be a non-empty record and disallows usage of arrays.\n *\n * @param Key - The struct for the record key.\n * @param Value - The struct for the record value.\n * @returns The refined struct.\n */\nexport function nonEmptyRecord<Key extends string, Value>(\n  Key: Struct<Key>,\n  Value: Struct<Value>,\n) {\n  return refine(record(Key, Value), 'Non-empty record', (value) => {\n    return !Array.isArray(value) && Object.keys(value).length > 0;\n  });\n}\n"]}