{"version":3,"file":"GeminiTypeChecker.mjs","sources":["../../src/utils/GeminiTypeChecker.ts"],"sourcesContent":["import { IGeminiSchema } from \"../structures/IGeminiSchema\";\n\n/**\n * Type checker for Gemini type schema.\n *\n * `GeminiTypeChecker` is a type checker of {@link IGeminiSchema}.\n *\n * @author Samchon\n */\nexport namespace GeminiTypeChecker {\n  /* -----------------------------------------------------------\n    OPERATORS\n  ----------------------------------------------------------- */\n  /**\n   * Visit every nested schemas.\n   *\n   * Visit every nested schemas of the target, and apply the `props.closure` function.\n   *\n   * Here is the list of occurring nested visitings:\n   *\n   * - {@link IGeminiSchema.IObject.properties}\n   * - {@link IGeminiSchema.IArray.items}\n   *\n   * @param props Properties for visiting\n   */\n  export const visit = (props: {\n    closure: (schema: IGeminiSchema, accessor: string) => void;\n    schema: IGeminiSchema;\n    accessor?: string;\n  }): void => {\n    const accessor: string = props.accessor ?? \"$input.schema\";\n    props.closure(props.schema, accessor);\n    if (isObject(props.schema))\n      Object.entries(props.schema.properties ?? {}).forEach(([key, value]) =>\n        visit({\n          closure: props.closure,\n          schema: value,\n          accessor: `${accessor}.properties[${JSON.stringify(key)}]`,\n        }),\n      );\n    else if (isArray(props.schema))\n      visit({\n        closure: props.closure,\n        schema: props.schema.items,\n        accessor: `${accessor}.items`,\n      });\n  };\n\n  /**\n   * Test whether the `x` schema covers the `y` schema.\n   *\n   * @param props Properties for testing\n   * @returns Whether the `x` schema covers the `y` schema\n   */\n  export const covers = (x: IGeminiSchema, y: IGeminiSchema): boolean => {\n    // CHECK EQUALITY\n    if (x === y) return true;\n    else if (isUnknown(x)) return true;\n    else if (isUnknown(y)) return false;\n    else if (isNullOnly(x)) return isNullOnly(y);\n    else if (isNullOnly(y)) return x.nullable === true;\n    else if (x.nullable === true && !!y.nullable === false) return false;\n    // ATOMIC CASE\n    else if (isBoolean(x)) return isBoolean(y) && coverBoolean(x, y);\n    else if (isInteger(x)) return isInteger(y) && coverInteger(x, y);\n    else if (isNumber(x))\n      return (isNumber(y) || isInteger(y)) && coverNumber(x, y);\n    else if (isString(x)) return isString(y) && covertString(x, y);\n    // INSTANCE CASE\n    else if (isArray(x)) return isArray(y) && coverArray(x, y);\n    else if (isObject(x)) return isObject(y) && coverObject(x, y);\n    return false;\n  };\n\n  /**\n   * @internal\n   */\n  const coverBoolean = (\n    x: IGeminiSchema.IBoolean,\n    y: IGeminiSchema.IBoolean,\n  ): boolean =>\n    x.enum === undefined ||\n    (y.enum !== undefined && x.enum.every((v) => y.enum!.includes(v)));\n\n  /**\n   * @internal\n   */\n  const coverInteger = (\n    x: IGeminiSchema.IInteger,\n    y: IGeminiSchema.IInteger,\n  ): boolean => {\n    if (x.enum !== undefined)\n      return y.enum !== undefined && x.enum.every((v) => y.enum!.includes(v));\n    return x.type === y.type;\n  };\n\n  /**\n   * @internal\n   */\n  const coverNumber = (\n    x: IGeminiSchema.INumber,\n    y: IGeminiSchema.INumber | IGeminiSchema.IInteger,\n  ): boolean => {\n    if (x.enum !== undefined)\n      return y.enum !== undefined && x.enum.every((v) => y.enum!.includes(v));\n    return x.type === y.type;\n  };\n\n  /**\n   * @internal\n   */\n  const covertString = (\n    x: IGeminiSchema.IString,\n    y: IGeminiSchema.IString,\n  ): boolean => {\n    if (x.enum !== undefined)\n      return y.enum !== undefined && x.enum.every((v) => y.enum!.includes(v));\n    return x.type === y.type;\n  };\n\n  /**\n   * @internal\n   */\n  const coverArray = (\n    x: IGeminiSchema.IArray,\n    y: IGeminiSchema.IArray,\n  ): boolean => covers(x.items, y.items);\n\n  /**\n   * @internal\n   */\n  const coverObject = (\n    x: IGeminiSchema.IObject,\n    y: IGeminiSchema.IObject,\n  ): boolean =>\n    Object.entries(y.properties ?? {}).every(([key, b]) => {\n      const a: IGeminiSchema | undefined = x.properties?.[key];\n      if (a === undefined) return false;\n      else if (\n        (x.required?.includes(key) ?? false) === true &&\n        (y.required?.includes(key) ?? false) === false\n      )\n        return false;\n      return covers(a, b);\n    });\n\n  /* -----------------------------------------------------------\n    TYPE CHECKERS\n  ----------------------------------------------------------- */\n  /**\n   * Test whether the schema is a boolean type.\n   *\n   * @param schema Target schema\n   * @returns Whether boolean type or not\n   */\n  export const isBoolean = (\n    schema: IGeminiSchema,\n  ): schema is IGeminiSchema.IBoolean =>\n    (schema as IGeminiSchema.IBoolean).type === \"boolean\";\n\n  /**\n   * Test whether the schema is an integer type.\n   *\n   * @param schema Target schema\n   * @returns Whether integer type or not\n   */\n  export const isInteger = (\n    schema: IGeminiSchema,\n  ): schema is IGeminiSchema.IInteger =>\n    (schema as IGeminiSchema.IInteger).type === \"integer\";\n\n  /**\n   * Test whether the schema is a number type.\n   *\n   * @param schema Target schema\n   * @returns Whether number type or not\n   */\n  export const isNumber = (\n    schema: IGeminiSchema,\n  ): schema is IGeminiSchema.INumber =>\n    (schema as IGeminiSchema.INumber).type === \"number\";\n\n  /**\n   * Test whether the schema is a string type.\n   *\n   * @param schema Target schema\n   * @returns Whether string type or not\n   */\n  export const isString = (\n    schema: IGeminiSchema,\n  ): schema is IGeminiSchema.IString =>\n    (schema as IGeminiSchema.IString).type === \"string\";\n\n  /**\n   * Test whether the schema is an array type.\n   *\n   * @param schema Target schema\n   * @returns Whether array type or not\n   */\n  export const isArray = (\n    schema: IGeminiSchema,\n  ): schema is IGeminiSchema.IArray =>\n    (schema as IGeminiSchema.IArray).type === \"array\";\n\n  /**\n   * Test whether the schema is an object type.\n   *\n   * @param schema Target schema\n   * @returns Whether object type or not\n   */\n  export const isObject = (\n    schema: IGeminiSchema,\n  ): schema is IGeminiSchema.IObject =>\n    (schema as IGeminiSchema.IObject).type === \"object\";\n\n  /**\n   * Test whether the schema is a null type.\n   *\n   * @param schema Target schema\n   * @returns Whether null type or not\n   */\n  export const isNullOnly = (\n    schema: IGeminiSchema,\n  ): schema is IGeminiSchema.INullOnly =>\n    (schema as IGeminiSchema.INullOnly).type === \"null\";\n\n  /**\n   * Test whether the schema is a nullable type.\n   *\n   * @param schema Target schema\n   * @returns Whether nullable type or not\n   */\n  export const isNullable = (schema: IGeminiSchema): boolean =>\n    !isUnknown(schema) && (isNullOnly(schema) || schema.nullable === true);\n\n  /**\n   * Test whether the schema is an unknown type.\n   *\n   * @param schema Target schema\n   * @returns Whether unknown type or not\n   */\n  export const isUnknown = (\n    schema: IGeminiSchema,\n  ): schema is IGeminiSchema.IUnknown =>\n    (schema as IGeminiSchema.IUnknown).type === undefined;\n}\n"],"names":["GeminiTypeChecker","visit","props","accessor","closure","schema","isObject","Object","entries","properties","forEach","key","value","JSON","stringify","isArray","items","covers","x","y","isUnknown","isNullOnly","nullable","isBoolean","coverBoolean","isInteger","coverInteger","isNumber","coverNumber","isString","covertString","coverArray","coverObject","enum","undefined","every","v","includes","type","b","a","required","isNullable"],"mappings":"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"}