typia
Version:
Superfast runtime validators with only one line
160 lines (146 loc) • 5.25 kB
text/typescript
import { OpenApi } from "@samchon/openapi";
import { Metadata } from "../../schemas/metadata/Metadata";
import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic";
import { AtomicPredicator } from "../helpers/AtomicPredicator";
import { application_array } from "./application_array";
import { application_bigint } from "./application_bigint";
import { application_boolean } from "./application_boolean";
import { application_escaped } from "./application_escaped";
import { application_number } from "./application_number";
import { application_string } from "./application_string";
import { application_templates } from "./application_templates";
import { application_union_discriminator } from "./application_union_discriminator";
import { application_v31_alias } from "./application_v31_alias";
import { application_v31_constant } from "./application_v31_constant";
import { application_v31_native } from "./application_v31_native";
import { application_v31_object } from "./application_v31_object";
import { application_v31_tuple } from "./application_v31_tuple";
/**
* @internal
*/
export const application_v31_schema =
<BlockNever extends boolean>(blockNever: BlockNever) =>
(components: OpenApi.IComponents) =>
(attribute: OpenApi.IJsonSchema.__IAttribute) =>
(
meta: Metadata,
): BlockNever extends true
? OpenApi.IJsonSchema | null
: OpenApi.IJsonSchema => {
if (meta.any === true)
return {
...attribute,
type: undefined,
};
//----
// GATHER UNION SCHEMAS
//----
const union: OpenApi.IJsonSchema[] = [];
const insert = (schema: OpenApi.IJsonSchema) => union.push(schema);
// NULLABLE
if (meta.nullable === true)
insert({
type: "null",
});
// toJSON() METHOD
if (meta.escaped !== null)
application_escaped(application_v31_schema(false)(components)({}))(
meta.escaped,
).forEach(insert as any);
// ATOMIC TYPES
if (meta.templates.length && AtomicPredicator.template(meta))
application_templates(meta).map(insert as any);
for (const constant of meta.constants)
if (AtomicPredicator.constant(meta)(constant.type) === false) continue;
else application_v31_constant(constant).map(insert);
for (const a of meta.atomics)
if (a.type === "boolean") application_boolean(a).forEach(insert as any);
else if (a.type === "bigint")
application_bigint(a).forEach(insert as any);
else if (a.type === "number")
application_number(a).forEach(insert as any);
else if (a.type === "string")
application_string(a).forEach(insert as any);
// ARRAY
for (const array of meta.arrays)
application_array(application_v31_schema(false)(components)({}))(
components,
)(array).forEach(insert as any);
// TUPLE
for (const tuple of meta.tuples)
insert(
application_v31_tuple(application_v31_schema(false)(components)({}))(
tuple,
),
);
// NATIVES
for (const native of meta.natives)
if (AtomicPredicator.native(native)) {
const type: string = native.toLowerCase();
if (meta.atomics.some((a) => a.type === type)) continue;
else if (type === "boolean")
insert(
application_boolean(
MetadataAtomic.create({
type: "boolean",
tags: [],
}),
)[0]! as any,
);
else if (type === "bigint")
insert(
application_bigint(
MetadataAtomic.create({
type: "bigint",
tags: [],
}),
)[0]! as any,
);
else if (type === "number")
insert(
application_number(
MetadataAtomic.create({
type: "number",
tags: [],
}),
)[0]! as any,
);
else if (type === "string")
insert(
application_string(
MetadataAtomic.create({
type: "string",
tags: [],
}),
)[0]! as any,
);
} else insert(application_v31_native(components)(native));
if (meta.sets.length) insert(application_v31_native(components)(`Set`));
if (meta.maps.length) insert(application_v31_native(components)(`Map`));
// OBJECT
for (const obj of meta.objects)
insert(application_v31_object(components)(obj));
// ALIASES
for (const alias of meta.aliases)
insert(application_v31_alias(blockNever)(components)(alias));
//----
// RETURNS
//----
if (union.length === 0 && blockNever === true) return null!;
const schema: OpenApi.IJsonSchema =
union.length === 0
? { type: undefined }
: union.length === 1
? union[0]!
: {
oneOf: union,
discriminator: application_union_discriminator(meta),
};
return {
...schema,
...attribute,
title: attribute.title ?? schema.title,
description: attribute.description ?? schema.description,
deprecated: attribute.deprecated ?? schema.deprecated,
};
};