diff --git a/benchmark/package.json b/benchmark/package.json index 1a2385d15d..b0c0d595cf 100644 --- a/benchmark/package.json +++ b/benchmark/package.json @@ -72,6 +72,6 @@ "suppress-warnings": "^1.0.2", "tstl": "^3.0.0", "uuid": "^9.0.1", - "typia": "../typia-7.0.0-dev.20241022-2.tgz" + "typia": "../typia-7.0.0-dev.20241022-3.tgz" } } \ No newline at end of file diff --git a/errors/package.json b/errors/package.json index 29b222e25b..d0395bd725 100644 --- a/errors/package.json +++ b/errors/package.json @@ -32,6 +32,6 @@ "typescript": "^5.3.2" }, "dependencies": { - "typia": "../typia-7.0.0-dev.20241022-2.tgz" + "typia": "../typia-7.0.0-dev.20241022-3.tgz" } } \ No newline at end of file diff --git a/package.json b/package.json index 2a62ddeb18..d986c651f4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typia", - "version": "7.0.0-dev.20241022-2", + "version": "7.0.0-dev.20241022-3", "description": "Superfast runtime validators with only one line", "main": "lib/index.js", "typings": "lib/index.d.ts", diff --git a/packages/typescript-json/package.json b/packages/typescript-json/package.json index 9f52efcf30..0947562ac6 100644 --- a/packages/typescript-json/package.json +++ b/packages/typescript-json/package.json @@ -1,6 +1,6 @@ { "name": "typescript-json", - "version": "7.0.0-dev.20241022-2", + "version": "7.0.0-dev.20241022-3", "description": "Superfast runtime validators with only one line", "main": "lib/index.js", "typings": "lib/index.d.ts", @@ -64,7 +64,7 @@ }, "homepage": "https://typia.io", "dependencies": { - "typia": "7.0.0-dev.20241022-2" + "typia": "7.0.0-dev.20241022-3" }, "peerDependencies": { "typescript": ">=4.8.0 <5.7.0" diff --git a/src/programmers/RandomProgrammer.ts b/src/programmers/RandomProgrammer.ts index c0f91381ac..8b517d23ed 100644 --- a/src/programmers/RandomProgrammer.ts +++ b/src/programmers/RandomProgrammer.ts @@ -30,12 +30,11 @@ import { StringUtil } from "../utils/StringUtil"; import { FeatureProgrammer } from "./FeatureProgrammer"; import { FunctionProgrammer } from "./helpers/FunctionProgrammer"; import { RandomJoiner } from "./helpers/RandomJoiner"; -import { application_array } from "./internal/application_array"; -import { application_bigint } from "./internal/application_bigint"; -import { application_boolean } from "./internal/application_boolean"; -import { application_number } from "./internal/application_number"; -import { application_string } from "./internal/application_string"; -import { application_v31_schema } from "./internal/application_v31_schema"; +import { json_schema_array } from "./internal/json_schema_array"; +import { json_schema_bigint } from "./internal/json_schema_bigint"; +import { json_schema_boolean } from "./internal/json_schema_boolean"; +import { json_schema_number } from "./internal/json_schema_number"; +import { json_schema_string } from "./internal/json_schema_string"; export namespace RandomProgrammer { export interface IProps { @@ -470,12 +469,12 @@ export namespace RandomProgrammer { }) => { const schemaList: OpenApi.IJsonSchema[] = props.atomic.type === "boolean" - ? application_boolean<"3.1">(props.atomic) + ? json_schema_boolean(props.atomic) : props.atomic.type === "string" - ? application_string<"3.1">(props.atomic) + ? json_schema_string(props.atomic) : props.atomic.type === "bigint" - ? application_bigint<"3.1">(props.atomic) - : application_number<"3.1">(props.atomic); + ? json_schema_bigint(props.atomic) + : json_schema_number(props.atomic); return schemaList.map((schema) => { interface IComposed { method: string; @@ -577,14 +576,7 @@ export namespace RandomProgrammer { array: MetadataArray; }): ts.Expression[] => { const components: OpenApi.IComponents = {}; - const schemaList: OpenApi.IJsonSchema.IArray[] = application_array<"3.1">({ - generator: (value) => - application_v31_schema({ - blockNever: true, - components, - attribute: {}, - metadata: value, - })!, + const schemaList: OpenApi.IJsonSchema.IArray[] = json_schema_array({ components, array: props.array, }) as OpenApi.IJsonSchema.IArray[]; diff --git a/src/programmers/internal/application_array.ts b/src/programmers/internal/application_array.ts deleted file mode 100644 index 2df75df367..0000000000 --- a/src/programmers/internal/application_array.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { OpenApi, OpenApiV3 } from "@samchon/openapi"; - -import { Metadata } from "../../schemas/metadata/Metadata"; -import { MetadataArray } from "../../schemas/metadata/MetadataArray"; - -import { application_plugin } from "./application_plugin"; - -/** - * @internal - */ -export const application_array = (props: { - generator: (value: Metadata) => Schema; - components: Version extends "3.0" - ? OpenApiV3.IComponents - : OpenApi.IComponents; - array: MetadataArray; -}): Array | OpenApiV3.IJsonSchema.IReference> => { - const factory = (): ArraySchema[] => - application_plugin>({ - schema: { - type: "array", - items: props.generator(props.array.type.value), - } as ArraySchema, - tags: props.array.tags, - }); - if (props.array.type.recursive === true) { - const out = () => [{ $ref }]; - const $ref: string = `#/components/schemas/${props.array.type.name}`; - if (props.components.schemas?.[$ref] !== undefined) return out(); - - props.components.schemas ??= {}; - props.components.schemas[$ref] ??= {}; - - const oneOf: ArraySchema[] = factory(); - Object.assign( - props.components.schemas[$ref]!, - oneOf.length === 1 ? oneOf[0] : { oneOf }, - ); - return out(); - } - return factory(); -}; - -/** - * @internal - */ -type ArraySchema = Version extends "3.0" - ? OpenApiV3.IJsonSchema.IArray - : OpenApi.IJsonSchema.IArray; - -/** - * @internal - */ -type Schema = Version extends "3.0" - ? OpenApiV3.IJsonSchema - : OpenApi.IJsonSchema; diff --git a/src/programmers/internal/application_bigint.ts b/src/programmers/internal/application_bigint.ts deleted file mode 100644 index 020ef86ec4..0000000000 --- a/src/programmers/internal/application_bigint.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { OpenApi, OpenApiV3 } from "@samchon/openapi"; - -import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; - -import { application_plugin } from "./application_plugin"; - -/** - * @internal - */ -export const application_bigint = ( - atomic: MetadataAtomic, -): Schema[] => - application_plugin({ - schema: { - type: "integer", - } satisfies Schema, - tags: atomic.tags, - }); - -/** - * @internal - */ -type Schema = Version extends "3.0" - ? OpenApiV3.IJsonSchema.IInteger - : OpenApi.IJsonSchema.IInteger; diff --git a/src/programmers/internal/application_boolean.ts b/src/programmers/internal/application_boolean.ts deleted file mode 100644 index da23ab5f6b..0000000000 --- a/src/programmers/internal/application_boolean.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { OpenApi, OpenApiV3 } from "@samchon/openapi"; - -import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; - -import { application_plugin } from "./application_plugin"; - -/** - * @internal - */ -export const application_boolean = ( - atomic: MetadataAtomic, -): Schema[] => - application_plugin({ - schema: { - type: "boolean", - } satisfies Schema, - tags: atomic.tags, - }); - -/** - * @internal - */ -type Schema = Version extends "3.0" - ? OpenApiV3.IJsonSchema.IBoolean - : OpenApi.IJsonSchema.IBoolean; diff --git a/src/programmers/internal/application_escaped.ts b/src/programmers/internal/application_escaped.ts deleted file mode 100644 index a4921fda4f..0000000000 --- a/src/programmers/internal/application_escaped.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { OpenApi, OpenApiV3 } from "@samchon/openapi"; - -import { Metadata } from "../../schemas/metadata/Metadata"; -import { MetadataEscaped } from "../../schemas/metadata/MetadataEscaped"; - -/** - * @internal - */ -export const application_escaped = (props: { - generator: (meta: Metadata) => Schema; - escaped: MetadataEscaped; -}): Schema[] => { - const output: Schema | null = props.generator(props.escaped.returns); - if (output === null) return []; - - if ( - is_date({ - visited: new Set(), - metadata: props.escaped.original, - }) - ) { - const string: StringSchema | undefined = is_string(output) - ? output - : is_one_of(output) - ? (output.oneOf.find(is_string) as StringSchema) - : undefined; - if ( - string !== undefined && - string.format !== "date" && - string.format !== "date-time" - ) - string.format = "date-time"; - } - return is_one_of(output) ? (output.oneOf as Schema[]) : [output]; -}; - -/** - * @internal - */ -const is_string = ( - schema: Schema, -): schema is StringSchema => - (schema as StringSchema).type === "string"; - -/** - * @internal - */ -const is_one_of = ( - schema: Schema, -): schema is OneOfSchema => - Array.isArray((schema as OneOfSchema).oneOf); - -/** - * @internal - */ -const is_date = (props: { - visited: Set; - metadata: Metadata; -}): boolean => { - if (props.visited.has(props.metadata)) return false; - props.visited.add(props.metadata); - - return ( - props.metadata.natives.some((native) => native.name === "Date") || - props.metadata.arrays.some((array) => - is_date({ - visited: props.visited, - metadata: array.type.value, - }), - ) || - props.metadata.tuples.some((tuple) => - tuple.type.elements.some((e) => - is_date({ - visited: props.visited, - metadata: e, - }), - ), - ) || - props.metadata.aliases.some((alias) => - is_date({ - visited: props.visited, - metadata: alias.type.value, - }), - ) - ); -}; - -type Schema = Version extends "3.0" - ? OpenApiV3.IJsonSchema - : OpenApi.IJsonSchema; -type StringSchema = Version extends "3.0" - ? OpenApiV3.IJsonSchema.IString - : OpenApi.IJsonSchema.IString; -type OneOfSchema = Version extends "3.0" - ? OpenApiV3.IJsonSchema.IOneOf - : OpenApi.IJsonSchema.IOneOf; diff --git a/src/programmers/internal/application_number.ts b/src/programmers/internal/application_number.ts deleted file mode 100644 index bd8d8f9ce0..0000000000 --- a/src/programmers/internal/application_number.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { OpenApi, OpenApiV3 } from "@samchon/openapi"; - -import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; - -import { application_plugin } from "./application_plugin"; - -/** - * @internal - */ -export const application_number = ( - atomic: MetadataAtomic, -): Schema[] => - application_plugin({ - schema: { - type: "number", - } satisfies Schema, - tags: atomic.tags, - }); - -/** - * @internal - */ -type Schema = Version extends "3.0" - ? OpenApiV3.IJsonSchema.IInteger | OpenApiV3.IJsonSchema.INumber - : OpenApi.IJsonSchema.IInteger | OpenApi.IJsonSchema.INumber; diff --git a/src/programmers/internal/application_string.ts b/src/programmers/internal/application_string.ts deleted file mode 100644 index e2053deeca..0000000000 --- a/src/programmers/internal/application_string.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { OpenApi, OpenApiV3 } from "@samchon/openapi"; - -import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; - -import { application_plugin } from "./application_plugin"; - -/** - * @internal - */ -export const application_string = ( - atomic: MetadataAtomic, -): Schema[] => - application_plugin({ - schema: { - type: "string", - } satisfies Schema, - tags: atomic.tags, - }); - -/** - * @internal - */ -type Schema = Version extends "3.0" - ? OpenApiV3.IJsonSchema.IString - : OpenApi.IJsonSchema.IString; diff --git a/src/programmers/internal/application_v30_alias.ts b/src/programmers/internal/application_v30_alias.ts deleted file mode 100644 index 0ac6173833..0000000000 --- a/src/programmers/internal/application_v30_alias.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { OpenApiV3 } from "@samchon/openapi"; - -import { CommentFactory } from "../../factories/CommentFactory"; - -import { IJsDocTagInfo } from "../../schemas/metadata/IJsDocTagInfo"; -import { MetadataAlias } from "../../schemas/metadata/MetadataAlias"; - -import { application_description } from "./application_description"; -import { application_plugin } from "./application_plugin"; -import { application_v30_object } from "./application_v30_object"; -import { application_v30_schema } from "./application_v30_schema"; - -/** - * @internal - */ -export const application_v30_alias = (props: { - blockNever: BlockNever; - components: OpenApiV3.IComponents; - alias: MetadataAlias; - nullable: boolean; -}): OpenApiV3.IJsonSchema.IReference[] => { - if ( - props.alias.type.value.size() === 1 && - props.alias.type.value.objects.length === 1 - ) - return application_v30_object({ - object: props.alias.type.value.objects[0]!, - components: props.components, - nullable: props.nullable, - }) as OpenApiV3.IJsonSchema.IReference[]; - - const key: string = `${props.alias.type.name}${props.nullable ? ".Nullable" : ""}`; - const $ref: string = `#/components/schemas/${key}`; - - if (props.components.schemas?.[key] === undefined) { - // TEMPORARY ASSIGNMENT - props.components.schemas ??= {}; - props.components.schemas[key] = {}; - - // GENERATE SCHEMA - const schema: OpenApiV3.IJsonSchema | null = application_v30_schema({ - blockNever: props.blockNever, - components: props.components, - attribute: { - deprecated: - props.alias.type.jsDocTags.some((tag) => tag.name === "deprecated") || - undefined, - title: (() => { - const info: IJsDocTagInfo | undefined = - props.alias.type.jsDocTags.find((tag) => tag.name === "title"); - return info?.text?.length - ? CommentFactory.merge(info.text) - : undefined; - })(), - description: application_description(props.alias.type), - }, - metadata: props.alias.type.value, - }); - if (schema !== null) Object.assign(props.components.schemas[key]!, schema); - } - return application_plugin({ - schema: { $ref }, - tags: props.alias.tags, - }); -}; diff --git a/src/programmers/internal/application_v30_constant.ts b/src/programmers/internal/application_v30_constant.ts deleted file mode 100644 index 2bff927b92..0000000000 --- a/src/programmers/internal/application_v30_constant.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { OpenApiV3 } from "@samchon/openapi"; - -import { MetadataConstant } from "../../schemas/metadata/MetadataConstant"; - -/** - * @internal - */ -export const application_v30_constant = ( - constant: MetadataConstant, -): - | OpenApiV3.IJsonSchema.IBoolean - | OpenApiV3.IJsonSchema.IInteger - | OpenApiV3.IJsonSchema.INumber - | OpenApiV3.IJsonSchema.IString => ({ - type: constant.type as "string" | "number" | "boolean" | "integer", - enum: constant.values.map((v) => v.value) as any, - // @todo default -}); diff --git a/src/programmers/internal/application_v30_native.ts b/src/programmers/internal/application_v30_native.ts deleted file mode 100644 index 417234cf37..0000000000 --- a/src/programmers/internal/application_v30_native.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { OpenApiV3 } from "@samchon/openapi"; - -import { MetadataNative } from "../../schemas/metadata/MetadataNative"; - -import { application_plugin } from "./application_plugin"; - -/** - * @internal - */ -export const application_v30_native = (props: { - components: OpenApiV3.IComponents; - native: MetadataNative; - nullable: boolean; -}): OpenApiV3.IJsonSchema[] => { - if (props.native.name === "Blob" || props.native.name === "File") - return application_plugin({ - schema: { - type: "string", - format: "binary", - nullable: props.nullable, - }, - tags: props.native.tags, - }); - const key: string = `${props.native.name}${props.nullable ? ".Nullable" : ""}`; - if (props.components.schemas?.[key] === undefined) { - props.components.schemas ??= {}; - props.components.schemas[key] ??= { - type: "object", - properties: {}, - nullable: props.nullable, - }; - } - return application_plugin({ - schema: { - $ref: `#/components/schemas/${key}`, - }, - tags: props.native.tags, - }); -}; diff --git a/src/programmers/internal/application_v30_object.ts b/src/programmers/internal/application_v30_object.ts deleted file mode 100644 index 270e08a919..0000000000 --- a/src/programmers/internal/application_v30_object.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { OpenApiV3 } from "@samchon/openapi"; - -import { CommentFactory } from "../../factories/CommentFactory"; - -import { IJsDocTagInfo } from "../../schemas/metadata/IJsDocTagInfo"; -import { Metadata } from "../../schemas/metadata/Metadata"; -import { MetadataObject } from "../../schemas/metadata/MetadataObject"; - -import { PatternUtil } from "../../utils/PatternUtil"; - -import { application_description } from "./application_description"; -import { application_plugin } from "./application_plugin"; -import { application_v30_schema } from "./application_v30_schema"; -import { metadata_to_pattern } from "./metadata_to_pattern"; - -/** - * @internal - */ -export const application_v30_object = (props: { - components: OpenApiV3.IComponents; - object: MetadataObject; - nullable: boolean; -}): Array => - application_plugin({ - schema: emplace_object(props), - tags: props.object.tags, - }); - -/** - * @internal - */ -const emplace_object = (props: { - components: OpenApiV3.IComponents; - object: MetadataObject; - nullable: boolean; -}): OpenApiV3.IJsonSchema.IReference | OpenApiV3.IJsonSchema.IObject => { - if (props.object.type.isLiteral() === true) - return create_object_schema(props); - - const key: string = `${props.object.type.name}${props.nullable ? ".Nullable" : ""}`; - const $ref: string = `#/components/schemas/${key}`; - if (props.components.schemas?.[key] !== undefined) return { $ref }; - - const object: OpenApiV3.IJsonSchema = {}; - props.components.schemas ??= {}; - props.components.schemas[key] = object; - Object.assign(object, create_object_schema(props)); - return { $ref }; -}; - -/** - * @internal - */ -const create_object_schema = (props: { - components: OpenApiV3.IComponents; - object: MetadataObject; - nullable: boolean; -}): OpenApiV3.IJsonSchema.IObject => { - // ITERATE PROPERTIES - const properties: Record = {}; - const extraMeta: ISuperfluous = { - patternProperties: {}, - additionalProperties: undefined, - }; - const required: string[] = []; - - for (const property of props.object.type.properties) { - if ( - // FUNCTIONAL TYPE - property.value.functions.length && - property.value.nullable === false && - property.value.isRequired() === true && - property.value.size() === 0 - ) - continue; - else if (property.jsDocTags.find((tag) => tag.name === "hidden")) continue; // THE HIDDEN TAG - - const key: string | null = property.key.getSoleLiteral(); - const schema: OpenApiV3.IJsonSchema | null = application_v30_schema({ - blockNever: true, - components: props.components, - attribute: { - deprecated: - property.jsDocTags.some((tag) => tag.name === "deprecated") || - undefined, - title: (() => { - const info: IJsDocTagInfo | undefined = property.jsDocTags.find( - (tag) => tag.name === "title", - ); - if (info?.text?.length) return CommentFactory.merge(info.text); - else if (!property.description?.length) return undefined; - - const index: number = property.description.indexOf("\n"); - const top: string = ( - index === -1 - ? property.description - : property.description.substring(0, index) - ).trim(); - return top.endsWith(".") - ? top.substring(0, top.length - 1) - : undefined; - })(), - description: application_description(property), - }, - metadata: property.value, - }); - - if (schema === null) continue; - if (key !== null) { - properties[key] = schema; - if (property.value.isRequired() === true) required.push(key); - } else { - const pattern: string = metadata_to_pattern({ - top: true, - metadata: property.key, - }); - if (pattern === PatternUtil.STRING) - extraMeta.additionalProperties = [property.value, schema]; - else extraMeta.patternProperties[pattern] = [property.value, schema]; - } - } - - return { - type: "object", - properties, - nullable: props.nullable, - required: required.length ? required : undefined, - title: (() => { - const info: IJsDocTagInfo | undefined = props.object.type.jsDocTags.find( - (tag) => tag.name === "title", - ); - return info?.text?.length ? CommentFactory.merge(info.text) : undefined; - })(), - description: application_description(props.object.type), - additionalProperties: join({ - components: props.components, - extra: extraMeta, - }), - }; -}; - -/** - * @internal - */ -const join = (props: { - components: OpenApiV3.IComponents; - extra: ISuperfluous; -}): OpenApiV3.IJsonSchema | undefined => { - // LIST UP METADATA - const elements: [Metadata, OpenApiV3.IJsonSchema][] = Object.values( - props.extra.patternProperties || {}, - ); - if (props.extra.additionalProperties) - elements.push(props.extra.additionalProperties); - - // SHORT RETURN - if (elements.length === 0) return undefined; - else if (elements.length === 1) return elements[0]![1]!; - - // MERGE METADATA AND GENERATE VULNERABLE SCHEMA - const metadata: Metadata = elements - .map((tuple) => tuple[0]) - .reduce((x, y) => Metadata.merge(x, y)); - return ( - application_v30_schema({ - blockNever: true, - components: props.components, - attribute: {}, - metadata, - }) ?? undefined - ); -}; - -/** - * @internal - */ -interface ISuperfluous { - additionalProperties?: undefined | [Metadata, OpenApiV3.IJsonSchema]; - patternProperties: Record; -} diff --git a/src/programmers/internal/application_v30_schema.ts b/src/programmers/internal/application_v30_schema.ts deleted file mode 100644 index e57f959dc2..0000000000 --- a/src/programmers/internal/application_v30_schema.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { OpenApiV3 } from "@samchon/openapi"; - -import { Metadata } from "../../schemas/metadata/Metadata"; -import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; -import { MetadataNative } from "../../schemas/metadata/MetadataNative"; - -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_v30_alias } from "./application_v30_alias"; -import { application_v30_constant } from "./application_v30_constant"; -import { application_v30_native } from "./application_v30_native"; -import { application_v30_object } from "./application_v30_object"; -import { application_v30_tuple } from "./application_v30_tuple"; - -/** - * @internal - */ -export const application_v30_schema = (props: { - blockNever: BlockNever; - components: OpenApiV3.IComponents; - attribute: OpenApiV3.IJsonSchema.__IAttribute; - metadata: Metadata; -}): BlockNever extends true - ? OpenApiV3.IJsonSchema | null - : OpenApiV3.IJsonSchema => { - // VULNERABLE CASE - if (props.metadata.any === true) - return { - ...props.attribute, - type: undefined, - }; - else if (props.metadata.nullable && props.metadata.empty()) - return { type: "null", ...props.attribute }; - - //---- - // GATHER UNION SCHEMAS - //---- - const union: OpenApiV3.IJsonSchema[] = []; - const insert = props.metadata.nullable - ? (schema: OpenApiV3.IJsonSchema) => - union.push({ - ...schema, - nullable: (schema as OpenApiV3.IJsonSchema.__ISignificant).type - ? true - : undefined, - } as OpenApiV3.IJsonSchema) - : (schema: OpenApiV3.IJsonSchema) => union.push(schema); - - // toJSON() METHOD - if (props.metadata.escaped !== null) - application_escaped<"3.0">({ - generator: (metadata) => - application_v30_schema({ - blockNever: false, - components: props.components, - attribute: {}, - metadata, - }), - escaped: props.metadata.escaped, - }).forEach(insert); - - // ATOMIC TYPES - if ( - props.metadata.templates.length && - AtomicPredicator.template(props.metadata) - ) - application_templates(props.metadata).forEach(insert); - for (const constant of props.metadata.constants) - if ( - AtomicPredicator.constant({ - metadata: props.metadata, - name: constant.type, - }) === false - ) - continue; - else insert(application_v30_constant(constant)); - for (const a of props.metadata.atomics) - if (a.type === "boolean") application_boolean(a).forEach(insert); - else if (a.type === "bigint") application_bigint(a).forEach(insert); - else if (a.type === "number") application_number(a).forEach(insert); - else if (a.type === "string") application_string(a).forEach(insert); - - // ARRAY - for (const array of props.metadata.arrays) - application_array<"3.0">({ - generator: (metadata) => - application_v30_schema({ - blockNever: false, - components: props.components, - attribute: {}, - metadata, - }), - components: props.components, - array, - }).forEach(insert); - - // TUPLE - for (const tuple of props.metadata.tuples) - insert( - application_v30_tuple({ - tuple, - components: props.components, - attribute: props.attribute, - }), - ); - - // NATIVES - for (const native of props.metadata.natives) - if (AtomicPredicator.native(native.name)) { - const type: string = native.name.toLowerCase(); - if (props.metadata.atomics.some((a) => a.type === type)) continue; - else if (type === "boolean") - insert( - application_boolean( - MetadataAtomic.create({ - type: "boolean", - tags: [], - }), - )[0]!, - ); - 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]!, - ); - else if (type === "string") - insert( - application_string( - MetadataAtomic.create({ - type: "string", - tags: [], - }), - )[0]!, - ); - } else - application_v30_native({ - native, - components: props.components, - nullable: props.metadata.nullable, - }).forEach(insert); - if (props.metadata.sets.length) - application_v30_native({ - native: MetadataNative.create({ - name: "Set", - tags: [], - }), - components: props.components, - nullable: props.metadata.nullable, - }).forEach(insert); - if (props.metadata.maps.length) - application_v30_native({ - native: MetadataNative.create({ - name: "Map", - tags: [], - }), - components: props.components, - nullable: props.metadata.nullable, - }).forEach(insert); - - // OBJECT - for (const object of props.metadata.objects) - application_v30_object({ - object, - components: props.components, - nullable: props.metadata.nullable, - }).forEach(insert); - - // ALIASES - for (const alias of props.metadata.aliases) - application_v30_alias({ - alias, - blockNever: props.blockNever, - components: props.components, - nullable: props.metadata.nullable, - }).forEach(insert); - - //---- - // RETURNS - //---- - if (union.length === 0 && props.blockNever === true) return null!; - const schema: OpenApiV3.IJsonSchema = - union.length === 0 - ? { type: undefined } - : union.length === 1 - ? union[0]! - : { - oneOf: union, - discriminator: application_union_discriminator(props.metadata), - }; - return { - ...schema, - ...props.attribute, - title: props.attribute.title ?? schema.title, - description: props.attribute.description ?? schema.description, - deprecated: props.attribute.deprecated ?? schema.deprecated, - }; -}; diff --git a/src/programmers/internal/application_v30_tuple.ts b/src/programmers/internal/application_v30_tuple.ts deleted file mode 100644 index 85bf4830d6..0000000000 --- a/src/programmers/internal/application_v30_tuple.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { OpenApiV3 } from "@samchon/openapi"; - -import { Metadata } from "../../schemas/metadata/Metadata"; -import { MetadataTuple } from "../../schemas/metadata/MetadataTuple"; - -import { application_v30_schema } from "./application_v30_schema"; - -/** - * @internal - */ -export const application_v30_tuple = (props: { - components: OpenApiV3.IComponents; - tuple: MetadataTuple; - attribute: OpenApiV3.IJsonSchema.__IAttribute; -}): OpenApiV3.IJsonSchema.IArray => ({ - ...props.attribute, - type: "array", - items: application_v30_schema({ - blockNever: false, - components: props.components, - attribute: props.tuple.type.recursive ? {} : props.attribute, - metadata: props.tuple.type.elements.reduce( - (x, y) => Metadata.merge(x.rest ?? x, y.rest ?? y), - Metadata.initialize(), - ), - }), - minItems: !!props.tuple.type.elements.at(-1)?.rest - ? props.tuple.type.elements.length - 1 - : props.tuple.type.elements.filter((x) => !x.optional).length, - maxItems: !!props.tuple.type.elements.at(-1)?.rest - ? undefined! - : props.tuple.type.elements.length, -}); diff --git a/src/programmers/internal/application_v31_tuple.ts b/src/programmers/internal/application_v31_tuple.ts deleted file mode 100644 index 557fd78d61..0000000000 --- a/src/programmers/internal/application_v31_tuple.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { OpenApi } from "@samchon/openapi"; - -import { Metadata } from "../../schemas/metadata/Metadata"; -import { MetadataTuple } from "../../schemas/metadata/MetadataTuple"; - -/** - * @internal - */ -export const application_v31_tuple = (props: { - generator: (metadata: Metadata) => OpenApi.IJsonSchema; - tuple: MetadataTuple; -}): OpenApi.IJsonSchema.ITuple => { - const tail: Metadata | null = props.tuple.type.elements.at(-1)?.rest ?? null; - const prefixItems: Metadata[] = props.tuple.type.isRest() - ? props.tuple.type.elements.slice(0, -1) - : props.tuple.type.elements; - return { - type: "array", - prefixItems: prefixItems.map(props.generator), - additionalItems: tail ? props.generator(tail) : false, - }; -}; diff --git a/src/programmers/internal/application_v31_alias.ts b/src/programmers/internal/json_schema_alias.ts similarity index 67% rename from src/programmers/internal/application_v31_alias.ts rename to src/programmers/internal/json_schema_alias.ts index 82999a0e28..16581934f1 100644 --- a/src/programmers/internal/application_v31_alias.ts +++ b/src/programmers/internal/json_schema_alias.ts @@ -2,15 +2,12 @@ import { OpenApi } from "@samchon/openapi"; import { MetadataAlias } from "../../schemas/metadata/MetadataAlias"; -import { application_description } from "./application_description"; -import { application_title } from "./application_title"; -import { application_v31_object } from "./application_v31_object"; -import { application_v31_schema } from "./application_v31_schema"; +import { json_schema_description } from "./json_schema_description"; +import { json_schema_object } from "./json_schema_object"; +import { json_schema_station } from "./json_schema_station"; +import { json_schema_title } from "./json_schema_title"; -/** - * @internal - */ -export const application_v31_alias = (props: { +export const json_schema_alias = (props: { blockNever: BlockNever; components: OpenApi.IComponents; alias: MetadataAlias; @@ -19,7 +16,7 @@ export const application_v31_alias = (props: { props.alias.type.value.size() === 1 && props.alias.type.value.objects.length === 1 ) - return application_v31_object({ + return json_schema_object({ components: props.components, object: props.alias.type.value.objects[0]!, }) as OpenApi.IJsonSchema.IReference[]; @@ -31,15 +28,15 @@ export const application_v31_alias = (props: { props.components.schemas[props.alias.type.name] = {}; // GENERATE SCHEMA - const schema: OpenApi.IJsonSchema | null = application_v31_schema({ + const schema: OpenApi.IJsonSchema | null = json_schema_station({ blockNever: props.blockNever, components: props.components, attribute: { deprecated: props.alias.type.jsDocTags.some((tag) => tag.name === "deprecated") || undefined, - title: application_title(props.alias.type), - description: application_description(props.alias.type), + title: json_schema_title(props.alias.type), + description: json_schema_description(props.alias.type), }, metadata: props.alias.type.value, }); diff --git a/src/programmers/internal/json_schema_array.ts b/src/programmers/internal/json_schema_array.ts new file mode 100644 index 0000000000..b1ae893485 --- /dev/null +++ b/src/programmers/internal/json_schema_array.ts @@ -0,0 +1,41 @@ +import { OpenApi } from "@samchon/openapi"; + +import { MetadataArray } from "../../schemas/metadata/MetadataArray"; + +import { json_schema_plugin } from "./json_schema_plugin"; +import { json_schema_station } from "./json_schema_station"; + +export const json_schema_array = (props: { + components: OpenApi.IComponents; + array: MetadataArray; +}): Array => { + const factory = (): OpenApi.IJsonSchema.IArray[] => + json_schema_plugin({ + schema: { + type: "array", + items: json_schema_station({ + blockNever: false, + components: props.components, + metadata: props.array.type.value, + attribute: {}, + }), + } satisfies OpenApi.IJsonSchema.IArray, + tags: props.array.tags, + }); + if (props.array.type.recursive === true) { + const out = () => [{ $ref }]; + const $ref: string = `#/components/schemas/${props.array.type.name}`; + if (props.components.schemas?.[$ref] !== undefined) return out(); + + props.components.schemas ??= {}; + props.components.schemas[$ref] ??= {}; + + const oneOf: OpenApi.IJsonSchema.IArray[] = factory(); + Object.assign( + props.components.schemas[$ref]!, + oneOf.length === 1 ? oneOf[0] : { oneOf }, + ); + return out(); + } + return factory(); +}; diff --git a/src/programmers/internal/json_schema_bigint.ts b/src/programmers/internal/json_schema_bigint.ts new file mode 100644 index 0000000000..aa7a643302 --- /dev/null +++ b/src/programmers/internal/json_schema_bigint.ts @@ -0,0 +1,15 @@ +import { OpenApi } from "@samchon/openapi"; + +import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; + +import { json_schema_plugin } from "./json_schema_plugin"; + +export const json_schema_bigint = ( + atomic: MetadataAtomic, +): OpenApi.IJsonSchema.IInteger[] => + json_schema_plugin({ + schema: { + type: "integer", + } satisfies OpenApi.IJsonSchema.IInteger, + tags: atomic.tags, + }); diff --git a/src/programmers/internal/json_schema_boolean.ts b/src/programmers/internal/json_schema_boolean.ts new file mode 100644 index 0000000000..fe718d9215 --- /dev/null +++ b/src/programmers/internal/json_schema_boolean.ts @@ -0,0 +1,15 @@ +import { OpenApi } from "@samchon/openapi"; + +import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; + +import { json_schema_plugin } from "./json_schema_plugin"; + +export const json_schema_boolean = ( + atomic: MetadataAtomic, +): OpenApi.IJsonSchema.IBoolean[] => + json_schema_plugin({ + schema: { + type: "boolean", + } satisfies OpenApi.IJsonSchema.IBoolean, + tags: atomic.tags, + }); diff --git a/src/programmers/internal/application_v31_constant.ts b/src/programmers/internal/json_schema_constant.ts similarity index 58% rename from src/programmers/internal/application_v31_constant.ts rename to src/programmers/internal/json_schema_constant.ts index 47f0c48204..f768b779ab 100644 --- a/src/programmers/internal/application_v31_constant.ts +++ b/src/programmers/internal/json_schema_constant.ts @@ -2,26 +2,23 @@ import { OpenApi } from "@samchon/openapi"; import { MetadataConstant } from "../../schemas/metadata/MetadataConstant"; -import { application_description } from "./application_description"; -import { application_plugin } from "./application_plugin"; -import { application_title } from "./application_title"; +import { json_schema_description } from "./json_schema_description"; +import { json_schema_plugin } from "./json_schema_plugin"; +import { json_schema_title } from "./json_schema_title"; -/** - * @internal - */ -export const application_v31_constant = ( +export const json_schema_constant = ( constant: MetadataConstant, ): OpenApi.IJsonSchema.IConstant[] => constant.values .map((value) => - application_plugin({ + json_schema_plugin({ schema: { const: typeof value.value === "bigint" ? Number(value.value) : (value.value as boolean | number | string), - title: application_title(value), - description: application_description(value), + title: json_schema_title(value), + description: json_schema_description(value), } satisfies OpenApi.IJsonSchema.IConstant, tags: value.tags ?? [], }), diff --git a/src/programmers/internal/application_description.ts b/src/programmers/internal/json_schema_description.ts similarity index 68% rename from src/programmers/internal/application_description.ts rename to src/programmers/internal/json_schema_description.ts index 4a1ff08bf3..080f0cbc4d 100644 --- a/src/programmers/internal/application_description.ts +++ b/src/programmers/internal/json_schema_description.ts @@ -1,6 +1,6 @@ -import { IJsDocTagInfo } from "../../module"; +import { IJsDocTagInfo } from "../../schemas/metadata/IJsDocTagInfo"; -export const application_description = (props: { +export const json_schema_description = (props: { description?: string | null | undefined; jsDocTags?: IJsDocTagInfo[]; }): string | undefined => diff --git a/src/programmers/internal/application_union_discriminator.ts b/src/programmers/internal/json_schema_discriminator.ts similarity index 95% rename from src/programmers/internal/application_union_discriminator.ts rename to src/programmers/internal/json_schema_discriminator.ts index fa9add9e68..061af72c0c 100644 --- a/src/programmers/internal/application_union_discriminator.ts +++ b/src/programmers/internal/json_schema_discriminator.ts @@ -4,7 +4,7 @@ import { Metadata } from "../../schemas/metadata/Metadata"; import { UnionPredicator } from "../helpers/UnionPredicator"; -export const application_union_discriminator = ( +export const json_schema_discriminator = ( metadata: Metadata, ): OpenApi.IJsonSchema.IOneOf.IDiscriminator | undefined => { if ( diff --git a/src/programmers/internal/llm_schema_escaped.ts b/src/programmers/internal/json_schema_escaped.ts similarity index 55% rename from src/programmers/internal/llm_schema_escaped.ts rename to src/programmers/internal/json_schema_escaped.ts index 5d77a2ea2c..075fd157d0 100644 --- a/src/programmers/internal/llm_schema_escaped.ts +++ b/src/programmers/internal/json_schema_escaped.ts @@ -1,31 +1,39 @@ -import { ILlmSchema } from "@samchon/openapi"; +import { OpenApi, OpenApiTypeChecker } from "@samchon/openapi"; import { Metadata } from "../../schemas/metadata/Metadata"; import { MetadataEscaped } from "../../schemas/metadata/MetadataEscaped"; -import { llm_schema_station } from "./llm_schema_station"; +import { json_schema_station } from "./json_schema_station"; /** * @internal */ -export const llm_schema_escaped = (escaped: MetadataEscaped): ILlmSchema[] => { - const output: ILlmSchema | null = llm_schema_station({ - metadata: escaped.returns, +export const json_schema_escaped = (props: { + components: OpenApi.IComponents; + escaped: MetadataEscaped; +}): OpenApi.IJsonSchema[] => { + const output: OpenApi.IJsonSchema | null = json_schema_station({ blockNever: false, + components: props.components, + metadata: props.escaped.returns, attribute: {}, }); if (output === null) return []; - else if ( + + if ( is_date({ visited: new Set(), - metadata: escaped.original, + metadata: props.escaped.original, }) ) { - const string: ILlmSchema.IString | undefined = is_string(output) - ? output - : is_one_of(output) - ? (output.oneOf.find(is_string) as ILlmSchema.IString) - : undefined; + const string: OpenApi.IJsonSchema.IString | undefined = + OpenApiTypeChecker.isString(output) + ? output + : OpenApiTypeChecker.isOneOf(output) + ? (output.oneOf.find( + OpenApiTypeChecker.isString, + ) as OpenApi.IJsonSchema.IString) + : undefined; if ( string !== undefined && string.format !== "date" && @@ -33,21 +41,11 @@ export const llm_schema_escaped = (escaped: MetadataEscaped): ILlmSchema[] => { ) string.format = "date-time"; } - return is_one_of(output) ? (output.oneOf as ILlmSchema[]) : [output]; + return OpenApiTypeChecker.isOneOf(output) + ? (output.oneOf as OpenApi.IJsonSchema[]) + : [output]; }; -/** - * @internal - */ -const is_string = (elem: ILlmSchema): elem is ILlmSchema.IString => - (elem as ILlmSchema.IString).type === "string"; - -/** - * @internal - */ -const is_one_of = (elem: ILlmSchema): elem is ILlmSchema.IOneOf => - Array.isArray((elem as ILlmSchema.IOneOf).oneOf); - /** * @internal */ @@ -67,10 +65,10 @@ const is_date = (props: { }), ) || props.metadata.tuples.some((tuple) => - tuple.type.elements.some((elem) => + tuple.type.elements.some((e) => is_date({ visited: props.visited, - metadata: elem, + metadata: e, }), ), ) || diff --git a/src/programmers/internal/application_v31_native.ts b/src/programmers/internal/json_schema_native.ts similarity index 79% rename from src/programmers/internal/application_v31_native.ts rename to src/programmers/internal/json_schema_native.ts index 4185190922..c4984625db 100644 --- a/src/programmers/internal/application_v31_native.ts +++ b/src/programmers/internal/json_schema_native.ts @@ -2,17 +2,14 @@ import { OpenApi } from "@samchon/openapi"; import { MetadataNative } from "../../schemas/metadata/MetadataNative"; -import { application_plugin } from "./application_plugin"; +import { json_schema_plugin } from "./json_schema_plugin"; -/** - * @internal - */ -export const application_v31_native = (props: { +export const json_schema_native = (props: { components: OpenApi.IComponents; native: MetadataNative; }): OpenApi.IJsonSchema[] => { if (props.native.name === "Blob" || props.native.name === "File") - return application_plugin({ + return json_schema_plugin({ schema: { type: "string", format: "binary", @@ -26,7 +23,7 @@ export const application_v31_native = (props: { properties: {}, }; } - return application_plugin({ + return json_schema_plugin({ schema: { $ref: `#/components/schemas/${props.native.name}`, }, diff --git a/src/programmers/internal/json_schema_number.ts b/src/programmers/internal/json_schema_number.ts new file mode 100644 index 0000000000..81253de567 --- /dev/null +++ b/src/programmers/internal/json_schema_number.ts @@ -0,0 +1,15 @@ +import { OpenApi } from "@samchon/openapi"; + +import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; + +import { json_schema_plugin } from "./json_schema_plugin"; + +export const json_schema_number = ( + atomic: MetadataAtomic, +): Array => + json_schema_plugin({ + schema: { + type: "number", + } satisfies OpenApi.IJsonSchema.INumber, + tags: atomic.tags, + }); diff --git a/src/programmers/internal/application_v31_object.ts b/src/programmers/internal/json_schema_object.ts similarity index 85% rename from src/programmers/internal/application_v31_object.ts rename to src/programmers/internal/json_schema_object.ts index 1f5bc93cfb..e30fcf0ebf 100644 --- a/src/programmers/internal/application_v31_object.ts +++ b/src/programmers/internal/json_schema_object.ts @@ -1,4 +1,4 @@ -import { OpenApi, OpenApiV3 } from "@samchon/openapi"; +import { OpenApi } from "@samchon/openapi"; import { CommentFactory } from "../../factories/CommentFactory"; @@ -8,20 +8,20 @@ import { MetadataObject } from "../../schemas/metadata/MetadataObject"; import { PatternUtil } from "../../utils/PatternUtil"; -import { application_description } from "./application_description"; -import { application_plugin } from "./application_plugin"; -import { application_title } from "./application_title"; -import { application_v31_schema } from "./application_v31_schema"; +import { json_schema_description } from "./json_schema_description"; +import { json_schema_plugin } from "./json_schema_plugin"; +import { json_schema_station } from "./json_schema_station"; +import { json_schema_title } from "./json_schema_title"; import { metadata_to_pattern } from "./metadata_to_pattern"; /** * @internal */ -export const application_v31_object = (props: { +export const json_schema_object = (props: { components: OpenApi.IComponents; object: MetadataObject; }): Array => - application_plugin({ + json_schema_plugin({ schema: emplace_object(props), tags: props.object.tags, }); @@ -37,7 +37,7 @@ const emplace_object = (props: { const $ref: string = `#/components/schemas/${key}`; if (props.components.schemas?.[key] !== undefined) return { $ref }; - const lazy: OpenApiV3.IJsonSchema = {}; + const lazy: OpenApi.IJsonSchema = {}; props.components.schemas ??= {}; props.components.schemas[key] = lazy; Object.assign(lazy, create_object_schema(props)); @@ -71,15 +71,15 @@ const create_object_schema = (props: { else if (property.jsDocTags.find((tag) => tag.name === "hidden")) continue; // THE HIDDEN TAG const key: string | null = property.key.getSoleLiteral(); - const schema: OpenApi.IJsonSchema | null = application_v31_schema({ + const schema: OpenApi.IJsonSchema | null = json_schema_station({ blockNever: true, components: props.components, attribute: { deprecated: property.jsDocTags.some((tag) => tag.name === "deprecated") || undefined, - title: application_title(property), - description: application_description(property), + title: json_schema_title(property), + description: json_schema_description(property), }, metadata: property.value, }); @@ -109,7 +109,7 @@ const create_object_schema = (props: { ); return info?.text?.length ? CommentFactory.merge(info.text) : undefined; })(), - description: application_description(props.object.type), + description: json_schema_description(props.object.type), additionalProperties: join({ components: props.components, extra: extraMeta, @@ -140,7 +140,7 @@ const join = (props: { .map((tuple) => tuple[0]) .reduce((x, y) => Metadata.merge(x, y)); return ( - application_v31_schema({ + json_schema_station({ blockNever: true, components: props.components, attribute: {}, diff --git a/src/programmers/internal/application_plugin.ts b/src/programmers/internal/json_schema_plugin.ts similarity index 80% rename from src/programmers/internal/application_plugin.ts rename to src/programmers/internal/json_schema_plugin.ts index 62f53bf3c1..ff9f9efcaa 100644 --- a/src/programmers/internal/application_plugin.ts +++ b/src/programmers/internal/json_schema_plugin.ts @@ -1,9 +1,8 @@ +import { OpenApi } from "@samchon/openapi"; + import { IMetadataTypeTag } from "../../schemas/metadata/IMetadataTypeTag"; -/** - * @internal - */ -export const application_plugin = (props: { +export const json_schema_plugin = (props: { schema: Schema; tags: IMetadataTypeTag[][]; }): Schema[] => { diff --git a/src/programmers/internal/application_v31_schema.ts b/src/programmers/internal/json_schema_station.ts similarity index 51% rename from src/programmers/internal/application_v31_schema.ts rename to src/programmers/internal/json_schema_station.ts index 9039d9b024..053d2aeddd 100644 --- a/src/programmers/internal/application_v31_schema.ts +++ b/src/programmers/internal/json_schema_station.ts @@ -5,24 +5,21 @@ import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; import { MetadataNative } from "../../schemas/metadata/MetadataNative"; 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"; +import { json_schema_alias } from "./json_schema_alias"; +import { json_schema_array } from "./json_schema_array"; +import { json_schema_bigint } from "./json_schema_bigint"; +import { json_schema_boolean } from "./json_schema_boolean"; +import { json_schema_constant } from "./json_schema_constant"; +import { json_schema_discriminator } from "./json_schema_discriminator"; +import { json_schema_escaped } from "./json_schema_escaped"; +import { json_schema_native } from "./json_schema_native"; +import { json_schema_number } from "./json_schema_number"; +import { json_schema_object } from "./json_schema_object"; +import { json_schema_string } from "./json_schema_string"; +import { json_schema_templates } from "./json_schema_template"; +import { json_schema_tuple } from "./json_schema_tuple"; -/** - * @internal - */ -export const application_v31_schema = (props: { +export const json_schema_station = (props: { blockNever: BlockNever; components: OpenApi.IComponents; attribute: OpenApi.IJsonSchema.__IAttribute; @@ -50,23 +47,17 @@ export const application_v31_schema = (props: { // toJSON() METHOD if (props.metadata.escaped !== null) - application_escaped({ - generator: (metadata) => - application_v31_schema({ - blockNever: false as const, - components: props.components, - attribute: {}, - metadata, - }), + json_schema_escaped({ + components: props.components, escaped: props.metadata.escaped, - }).forEach(insert as any); + }).forEach(insert); // ATOMIC TYPES if ( props.metadata.templates.length && AtomicPredicator.template(props.metadata) ) - application_templates(props.metadata).map(insert as any); + json_schema_templates(props.metadata).forEach(insert); for (const constant of props.metadata.constants) if ( AtomicPredicator.constant({ @@ -75,38 +66,25 @@ export const application_v31_schema = (props: { }) === false ) continue; - else application_v31_constant(constant).map(insert); + else json_schema_constant(constant).forEach(insert); for (const a of props.metadata.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); + if (a.type === "boolean") json_schema_boolean(a).forEach(insert); + else if (a.type === "bigint") json_schema_bigint(a).forEach(insert); + else if (a.type === "number") json_schema_number(a).forEach(insert); + else if (a.type === "string") json_schema_string(a).forEach(insert); // ARRAY for (const array of props.metadata.arrays) - application_array({ - generator: (metadata) => - application_v31_schema({ - blockNever: false as const, - components: props.components, - attribute: {}, - metadata, - }), + json_schema_array({ components: props.components, array, - }).forEach(insert as any); + }).forEach(insert); // TUPLE for (const tuple of props.metadata.tuples) insert( - application_v31_tuple({ - generator: (metadata) => - application_v31_schema({ - blockNever: false as const, - components: props.components, - attribute: {}, - metadata, - }), + json_schema_tuple({ + components: props.components, tuple, }), ); @@ -117,48 +95,40 @@ export const application_v31_schema = (props: { const type: string = native.name.toLowerCase(); if (props.metadata.atomics.some((a) => a.type === type)) continue; else if (type === "boolean") - insert( - application_boolean( - MetadataAtomic.create({ - type: "boolean", - tags: [], - }), - )[0]! as any, - ); + json_schema_boolean( + MetadataAtomic.create({ + type: "boolean", + tags: [], + }), + ).map(insert); else if (type === "bigint") - insert( - application_bigint( - MetadataAtomic.create({ - type: "bigint", - tags: [], - }), - )[0]! as any, - ); + json_schema_bigint( + MetadataAtomic.create({ + type: "bigint", + tags: [], + }), + ).map(insert); else if (type === "number") - insert( - application_number( - MetadataAtomic.create({ - type: "number", - tags: [], - }), - )[0]! as any, - ); + json_schema_number( + MetadataAtomic.create({ + type: "number", + tags: [], + }), + ).map(insert); else if (type === "string") - insert( - application_string( - MetadataAtomic.create({ - type: "string", - tags: [], - }), - )[0]! as any, - ); + json_schema_string( + MetadataAtomic.create({ + type: "string", + tags: [], + }), + ).map(insert); } else - application_v31_native({ + json_schema_native({ components: props.components, native, }).forEach(insert); if (props.metadata.sets.length) - application_v31_native({ + json_schema_native({ native: MetadataNative.create({ name: "Set", tags: [], @@ -166,7 +136,7 @@ export const application_v31_schema = (props: { components: props.components, }).forEach(insert); if (props.metadata.maps.length) - application_v31_native({ + json_schema_native({ native: MetadataNative.create({ name: "Map", tags: [], @@ -176,14 +146,14 @@ export const application_v31_schema = (props: { // OBJECT for (const object of props.metadata.objects) - application_v31_object({ + json_schema_object({ components: props.components, object, }).forEach(insert); // ALIASES for (const alias of props.metadata.aliases) - application_v31_alias({ + json_schema_alias({ alias, blockNever: props.blockNever, components: props.components, @@ -200,7 +170,7 @@ export const application_v31_schema = (props: { ? union[0]! : { oneOf: union, - discriminator: application_union_discriminator(props.metadata), + discriminator: json_schema_discriminator(props.metadata), }; return { ...schema, diff --git a/src/programmers/internal/json_schema_string.ts b/src/programmers/internal/json_schema_string.ts new file mode 100644 index 0000000000..6bdf0fc7c5 --- /dev/null +++ b/src/programmers/internal/json_schema_string.ts @@ -0,0 +1,15 @@ +import { OpenApi } from "@samchon/openapi"; + +import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; + +import { json_schema_plugin } from "./json_schema_plugin"; + +export const json_schema_string = ( + atomic: MetadataAtomic, +): OpenApi.IJsonSchema[] => + json_schema_plugin({ + schema: { + type: "string", + } satisfies OpenApi.IJsonSchema, + tags: atomic.tags, + }); diff --git a/src/programmers/internal/application_templates.ts b/src/programmers/internal/json_schema_template.ts similarity index 65% rename from src/programmers/internal/application_templates.ts rename to src/programmers/internal/json_schema_template.ts index 336e6c6d44..978f45b4d0 100644 --- a/src/programmers/internal/application_templates.ts +++ b/src/programmers/internal/json_schema_template.ts @@ -1,26 +1,23 @@ -import { OpenApi, OpenApiV3 } from "@samchon/openapi"; +import { OpenApi } from "@samchon/openapi"; import { IMetadataTypeTag } from "../../schemas/metadata/IMetadataTypeTag"; import { Metadata } from "../../schemas/metadata/Metadata"; import { MetadataTemplate } from "../../schemas/metadata/MetadataTemplate"; -import { application_plugin } from "./application_plugin"; +import { json_schema_plugin } from "./json_schema_plugin"; import { metadata_to_pattern } from "./metadata_to_pattern"; -/** - * @internal - */ -export const application_templates = ( - meta: Metadata, -): Schema[] => { - const pureTemplates: MetadataTemplate[] = meta.templates.filter( +export const json_schema_templates = ( + metadata: Metadata, +): OpenApi.IJsonSchema[] => { + const pureTemplates: MetadataTemplate[] = metadata.templates.filter( (t) => isPure(t.tags ?? []) === true, ); - const taggedTemplates: MetadataTemplate[] = meta.templates.filter( + const taggedTemplates: MetadataTemplate[] = metadata.templates.filter( (t) => isPure(t.tags ?? []) === false, ); - const output: Schema[] = []; + const output: OpenApi.IJsonSchema[] = []; if (pureTemplates.length) output.push({ type: "string", @@ -34,7 +31,7 @@ export const application_templates = ( }); for (const tpl of taggedTemplates) output.push( - application_plugin({ + ...json_schema_plugin({ schema: { type: "string", pattern: metadata_to_pattern({ @@ -46,19 +43,13 @@ export const application_templates = ( }), }, tags: tpl.tags ?? [], - }) as any, + }), ); return output; }; const isPure = (matrix: IMetadataTypeTag[][]) => matrix.every((tags) => filter(tags).length === 0); + const filter = (tags: IMetadataTypeTag[]) => tags.filter((t) => t.schema !== undefined); - -/** - * @internal - */ -type Schema = Version extends "3.0" - ? OpenApiV3.IJsonSchema.IString - : OpenApi.IJsonSchema.IString; diff --git a/src/programmers/internal/application_title.ts b/src/programmers/internal/json_schema_title.ts similarity index 85% rename from src/programmers/internal/application_title.ts rename to src/programmers/internal/json_schema_title.ts index 44fac1004d..b29a3a027a 100644 --- a/src/programmers/internal/application_title.ts +++ b/src/programmers/internal/json_schema_title.ts @@ -1,8 +1,8 @@ import { CommentFactory } from "../../factories/CommentFactory"; -import { IJsDocTagInfo } from "../../module"; +import { IJsDocTagInfo } from "../../schemas/metadata/IJsDocTagInfo"; -export const application_title = (schema: { +export const json_schema_title = (schema: { description?: string | null | undefined; jsDocTags?: IJsDocTagInfo[] | undefined; }): string | undefined => { diff --git a/src/programmers/internal/json_schema_tuple.ts b/src/programmers/internal/json_schema_tuple.ts new file mode 100644 index 0000000000..8f7bc37433 --- /dev/null +++ b/src/programmers/internal/json_schema_tuple.ts @@ -0,0 +1,35 @@ +import { OpenApi } from "@samchon/openapi"; + +import { Metadata } from "../../schemas/metadata/Metadata"; +import { MetadataTuple } from "../../schemas/metadata/MetadataTuple"; + +import { json_schema_station } from "./json_schema_station"; + +export const json_schema_tuple = (props: { + components: OpenApi.IComponents; + tuple: MetadataTuple; +}): OpenApi.IJsonSchema.ITuple => { + const tail: Metadata | null = props.tuple.type.elements.at(-1)?.rest ?? null; + const prefixItems: Metadata[] = props.tuple.type.isRest() + ? props.tuple.type.elements.slice(0, -1) + : props.tuple.type.elements; + return { + type: "array", + prefixItems: prefixItems.map((metadata) => + json_schema_station({ + blockNever: false, + components: props.components, + metadata, + attribute: {}, + }), + ), + additionalItems: tail + ? json_schema_station({ + blockNever: false, + components: props.components, + metadata: tail, + attribute: {}, + }) + : false, + }; +}; diff --git a/src/programmers/internal/llm_schema_array.ts b/src/programmers/internal/llm_schema_array.ts deleted file mode 100644 index a702807b81..0000000000 --- a/src/programmers/internal/llm_schema_array.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ILlmSchema } from "@samchon/openapi"; - -import { MetadataArray } from "../../schemas/metadata/MetadataArray"; - -import { application_plugin } from "./application_plugin"; -import { llm_schema_station } from "./llm_schema_station"; - -/** - * @internal - */ -export const llm_schema_array = (array: MetadataArray): ILlmSchema.IArray[] => - application_plugin({ - schema: { - type: "array", - items: llm_schema_station({ - metadata: array.type.value, - blockNever: false, - attribute: {}, - }), - }, - tags: array.tags, - }); diff --git a/src/programmers/internal/llm_schema_native.ts b/src/programmers/internal/llm_schema_native.ts deleted file mode 100644 index 0278602681..0000000000 --- a/src/programmers/internal/llm_schema_native.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ILlmSchema } from "@samchon/openapi"; - -/** - * @internal - */ -export const llm_schema_native = ( - name: string, -): ILlmSchema.IString | ILlmSchema.IObject => - name === "Blob" || name === "File" - ? { - type: "string", - format: "binary", - } - : { - type: "object", - properties: {}, - }; diff --git a/src/programmers/internal/llm_schema_object.ts b/src/programmers/internal/llm_schema_object.ts deleted file mode 100644 index 50024b9409..0000000000 --- a/src/programmers/internal/llm_schema_object.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { ILlmSchema } from "@samchon/openapi"; - -import { CommentFactory } from "../../factories/CommentFactory"; - -import { IJsDocTagInfo } from "../../schemas/metadata/IJsDocTagInfo"; -import { Metadata } from "../../schemas/metadata/Metadata"; -import { MetadataObject } from "../../schemas/metadata/MetadataObject"; - -import { PatternUtil } from "../../utils/PatternUtil"; - -import { application_description } from "./application_description"; -import { application_plugin } from "./application_plugin"; -import { llm_schema_station } from "./llm_schema_station"; -import { metadata_to_pattern } from "./metadata_to_pattern"; - -/** - * @internal - */ -export const llm_schema_object = (props: { - object: MetadataObject; - nullable: boolean; -}): ILlmSchema.IObject[] => { - // ITERATE PROPERTIES - const properties: Record = {}; - const extraMeta: ISuperfluous = { - patternProperties: {}, - additionalProperties: undefined, - }; - const required: string[] = []; - - for (const property of props.object.type.properties) { - if ( - // FUNCTIONAL TYPE - property.value.functions.length && - property.value.nullable === false && - property.value.isRequired() === true && - property.value.size() === 0 - ) - continue; - else if (property.jsDocTags.find((tag) => tag.name === "hidden")) continue; // THE HIDDEN TAG - - const key: string | null = property.key.getSoleLiteral(); - const schema: ILlmSchema | null = llm_schema_station({ - blockNever: true, - attribute: { - deprecated: - property.jsDocTags.some((tag) => tag.name === "deprecated") || - undefined, - title: (() => { - const info: IJsDocTagInfo | undefined = property.jsDocTags.find( - (tag) => tag.name === "title", - ); - if (info?.text?.length) return CommentFactory.merge(info.text); - else if (!property.description?.length) return undefined; - - const index: number = property.description.indexOf("\n"); - const top: string = ( - index === -1 - ? property.description - : property.description.substring(0, index) - ).trim(); - return top.endsWith(".") - ? top.substring(0, top.length - 1) - : undefined; - })(), - description: application_description(property), - }, - metadata: property.value, - }); - - if (schema === null) continue; - if (key !== null) { - properties[key] = schema; - if (property.value.isRequired() === true) required.push(key); - } else { - const pattern: string = metadata_to_pattern({ - top: true, - metadata: property.key, - }); - if (pattern === PatternUtil.STRING) - extraMeta.additionalProperties = [property.value, schema]; - else extraMeta.patternProperties[pattern] = [property.value, schema]; - } - } - - return application_plugin({ - schema: { - type: "object", - properties, - nullable: props.nullable, - required: required.length ? required : undefined, - title: (() => { - const info: IJsDocTagInfo | undefined = - props.object.type.jsDocTags.find((tag) => tag.name === "title"); - return info?.text?.length ? CommentFactory.merge(info.text) : undefined; - })(), - description: application_description(props.object.type), - additionalProperties: join(extraMeta), - }, - tags: props.object.tags, - }); -}; - -/** - * @internal - */ -const join = (extra: ISuperfluous): ILlmSchema | false => { - // LIST UP METADATA - const elements: [Metadata, ILlmSchema][] = Object.values( - extra.patternProperties || {}, - ); - if (extra.additionalProperties) elements.push(extra.additionalProperties); - - // SHORT RETURN - if (elements.length === 0) return false; - else if (elements.length === 1) return elements[0]![1]!; - - // MERGE METADATA AND GENERATE VULNERABLE SCHEMA - const meta: Metadata = elements - .map((tuple) => tuple[0]) - .reduce((x, y) => Metadata.merge(x, y)); - return llm_schema_station({ - blockNever: true, - attribute: {}, - metadata: meta, - }); -}; - -/** - * @internal - */ -interface ISuperfluous { - additionalProperties?: undefined | [Metadata, ILlmSchema]; - patternProperties: Record; -} diff --git a/src/programmers/internal/llm_schema_station.ts b/src/programmers/internal/llm_schema_station.ts deleted file mode 100644 index 8d199e032f..0000000000 --- a/src/programmers/internal/llm_schema_station.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { ILlmSchema } from "@samchon/openapi"; - -import { Metadata } from "../../schemas/metadata/Metadata"; -import { MetadataAtomic } from "../../schemas/metadata/MetadataAtomic"; - -import { AtomicPredicator } from "../helpers/AtomicPredicator"; -import { application_bigint } from "./application_bigint"; -import { application_boolean } from "./application_boolean"; -import { application_number } from "./application_number"; -import { application_string } from "./application_string"; -import { application_templates } from "./application_templates"; -import { application_v30_constant } from "./application_v30_constant"; -import { llm_schema_array } from "./llm_schema_array"; -import { llm_schema_escaped } from "./llm_schema_escaped"; -import { llm_schema_native } from "./llm_schema_native"; -import { llm_schema_object } from "./llm_schema_object"; -import { llm_schema_tuple } from "./llm_schema_tuple"; - -/** - * @internal - */ -export const llm_schema_station = (props: { - metadata: Metadata; - blockNever: boolean; - attribute: ILlmSchema.__IAttribute; -}): ILlmSchema => { - // VULNERABLE CASE - if (props.metadata.any === true) - return { - ...props.attribute, - type: undefined, - }; - else if (props.metadata.nullable === true && props.metadata.empty() === true) - return { - ...props.attribute, - type: "null", - }; - - //---- - // GATHER UNION SCHEMAS - //---- - const union: ILlmSchema[] = []; - const insert = props.metadata.nullable - ? (schema: ILlmSchema) => - union.push({ - ...schema, - nullable: (schema as ILlmSchema.__ISignificant).type - ? true - : undefined, - } as ILlmSchema) - : (schema: ILlmSchema) => union.push(schema); - - // toJSON() METHOD - if (props.metadata.escaped !== null) - llm_schema_escaped(props.metadata.escaped).forEach(insert); - - // ATOMIC TYPES - if ( - props.metadata.templates.length && - AtomicPredicator.template(props.metadata) - ) - application_templates<"3.0">(props.metadata).map(insert); - for (const constant of props.metadata.constants) - if ( - AtomicPredicator.constant({ - metadata: props.metadata, - name: constant.type, - }) === false - ) - continue; - else insert(application_v30_constant(constant)); - for (const a of props.metadata.atomics) - if (a.type === "boolean") application_boolean<"3.0">(a).forEach(insert); - else if (a.type === "bigint") application_bigint<"3.0">(a).forEach(insert); - else if (a.type === "number") application_number<"3.0">(a).forEach(insert); - else if (a.type === "string") application_string<"3.0">(a).forEach(insert); - - // ARRAY - for (const array of props.metadata.arrays) - if (array.type.recursive) - throw new Error( - "Error on LlmSchemaProgrammer.write(): LLM schema does not allow recursive array type.", - ); - else llm_schema_array(array).forEach(insert); - - // TUPLE - for (const tuple of props.metadata.tuples) - if (tuple.type.recursive) - throw new Error( - "Error on LlmSchemaProgrammer.write(): LLM schema does not allow recursive tuple type.", - ); - else - insert( - llm_schema_tuple({ - tuple, - attribute: props.attribute, - }), - ); - - // NATIVES - for (const native of props.metadata.natives) - if (AtomicPredicator.native(native.name)) { - const type: string = native.name.toLowerCase(); - if (props.metadata.atomics.some((a) => a.type === type)) continue; - else if (type === "boolean") - insert( - application_boolean<"3.0">( - MetadataAtomic.create({ - type: "boolean", - tags: [], - }), - )[0]!, - ); - else if (type === "bigint") - insert( - application_bigint( - MetadataAtomic.create({ - type: "bigint", - tags: [], - }), - )[0]!, - ); - else if (type === "number") - insert( - application_number( - MetadataAtomic.create({ - type: "number", - tags: [], - }), - )[0]!, - ); - else if (type === "string") - insert( - application_string( - MetadataAtomic.create({ - type: "string", - tags: [], - }), - )[0]!, - ); - } else insert(llm_schema_native(native.name)); - if (props.metadata.sets.length) insert(llm_schema_native("Set")); - if (props.metadata.maps.length) insert(llm_schema_native("Map")); - - // OBJECT - for (const object of props.metadata.objects) - if (object.type.recursive) - throw new Error( - "Error on LlmSchemaProgrammer.write(): LLM schema does not allow recursive object type.", - ); - else - llm_schema_object({ - object, - nullable: props.metadata.nullable, - }).forEach(insert); - - // ALIASES - for (const alias of props.metadata.aliases) - if (alias.type.recursive) - throw new Error( - "Error on LlmSchemaProgrammer.write(): LLM schema does not allow recursive alias type.", - ); - else - insert( - llm_schema_station({ - ...props, - metadata: alias.type.value, - }), - ); - - //---- - // RETURNS - //---- - if (union.length === 0 && props.blockNever === true) return null!; - const schema: ILlmSchema = - union.length === 0 - ? { type: undefined } - : union.length === 1 - ? union[0]! - : { oneOf: union }; - return { - ...schema, - ...props.attribute, - title: props.attribute.title ?? schema.title, - description: props.attribute.description ?? schema.description, - deprecated: props.attribute.deprecated ?? schema.deprecated, - }; -}; diff --git a/src/programmers/internal/llm_schema_tuple.ts b/src/programmers/internal/llm_schema_tuple.ts deleted file mode 100644 index 219920f0be..0000000000 --- a/src/programmers/internal/llm_schema_tuple.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { ILlmSchema } from "@samchon/openapi"; - -import { Metadata } from "../../schemas/metadata/Metadata"; -import { MetadataTuple } from "../../schemas/metadata/MetadataTuple"; - -import { llm_schema_station } from "./llm_schema_station"; - -/** - * @internal - */ -export const llm_schema_tuple = (props: { - tuple: MetadataTuple; - attribute: ILlmSchema.__IAttribute; -}): ILlmSchema.IArray => ({ - ...props.attribute, - type: "array", - items: llm_schema_station({ - blockNever: false, - attribute: props.attribute, - metadata: props.tuple.type.elements.reduce( - (x, y) => Metadata.merge(x.rest ?? x, y.rest ?? y), - Metadata.initialize(), - ), - }), - minItems: !!props.tuple.type.elements.at(-1)?.rest - ? props.tuple.type.elements.length - 1 - : props.tuple.type.elements.filter((x) => !x.optional).length, - maxItems: !!props.tuple.type.elements.at(-1)?.rest - ? undefined! - : props.tuple.type.elements.length, -}); diff --git a/src/programmers/json/JsonApplicationProgrammer.ts b/src/programmers/json/JsonApplicationProgrammer.ts index 50bf5899b9..2afde36316 100644 --- a/src/programmers/json/JsonApplicationProgrammer.ts +++ b/src/programmers/json/JsonApplicationProgrammer.ts @@ -1,11 +1,11 @@ import { MetadataFactory } from "../../factories/MetadataFactory"; import { IJsonApplication } from "../../schemas/json/IJsonApplication"; +import { IJsDocTagInfo } from "../../schemas/metadata/IJsDocTagInfo"; import { Metadata } from "../../schemas/metadata/Metadata"; import { MetadataFunction } from "../../schemas/metadata/MetadataFunction"; import { MetadataObjectType } from "../../schemas/metadata/MetadataObjectType"; -import { IJsDocTagInfo } from "../../module"; import { JsonSchemasProgrammer } from "./JsonSchemasProgrammer"; export namespace JsonApplicationProgrammer { @@ -107,9 +107,10 @@ export namespace JsonApplicationProgrammer { collect, }), ); - const { components, schemas } = JsonSchemasProgrammer.write(props.version)( - definitions, - ); + const { components, schemas } = JsonSchemasProgrammer.write({ + version: props.version, + metadatas: definitions, + }); schemas.forEach((s, i) => setters[i]?.(s as IJsonApplication.Schema), ); diff --git a/src/programmers/json/JsonSchemasProgrammer.ts b/src/programmers/json/JsonSchemasProgrammer.ts index ad34499b60..1ce42a3b4e 100644 --- a/src/programmers/json/JsonSchemasProgrammer.ts +++ b/src/programmers/json/JsonSchemasProgrammer.ts @@ -1,4 +1,5 @@ -import { OpenApi, OpenApiV3 } from "@samchon/openapi"; +import { OpenApi } from "@samchon/openapi"; +import { OpenApiV3Downgrader } from "@samchon/openapi/lib/converters/OpenApiV3Downgrader"; import { IJsonSchemaCollection } from "../../schemas/json/IJsonSchemaCollection"; import { Metadata } from "../../schemas/metadata/Metadata"; @@ -6,8 +7,7 @@ import { Metadata } from "../../schemas/metadata/Metadata"; import { TransformerError } from "../../transformers/TransformerError"; import { AtomicPredicator } from "../helpers/AtomicPredicator"; -import { application_v30_schema } from "../internal/application_v30_schema"; -import { application_v31_schema } from "../internal/application_v31_schema"; +import { json_schema_station } from "../internal/json_schema_station"; export namespace JsonSchemasProgrammer { export const validate = (metadata: Metadata): string[] => { @@ -39,39 +39,36 @@ export namespace JsonSchemasProgrammer { return output; }; - export const write = (version: Version) => - version === "3.0" ? v30 : v31; + export const write = (props: { + version: Version; + metadatas: Array; + }): IJsonSchemaCollection => + props.version === "3.0" + ? (writeV3_0(props.metadatas) as IJsonSchemaCollection) + : (writeV3_1(props.metadatas) as IJsonSchemaCollection); - const v30 = (medadataList: Array): IJsonSchemaCollection<"3.0"> => { - const components: OpenApiV3.IComponents = {}; - const generator = (metadata: Metadata): OpenApiV3.IJsonSchema | null => - application_v30_schema({ - blockNever: true, - components, - attribute: {}, - metadata, - }); + const writeV3_0 = ( + medadataList: Array, + ): IJsonSchemaCollection<"3.0"> => { + const collection: IJsonSchemaCollection<"3.1"> = writeV3_1(medadataList); + const asset: OpenApiV3Downgrader.IComponentsCollection = + OpenApiV3Downgrader.downgradeComponents(collection.components); + const caster = OpenApiV3Downgrader.downgradeSchema(asset); return { version: "3.0", - components, - schemas: medadataList.map((meta, i) => { - const schema: OpenApiV3.IJsonSchema | null = generator(meta); - if (schema === null) - throw new TransformerError({ - code: "typia.json.application", - message: `invalid type on argument - (${meta.getName()}, ${i})`, - }); - return schema; - }), + components: asset.downgraded, + schemas: collection.schemas.map(caster), }; }; - const v31 = (metadataList: Array): IJsonSchemaCollection<"3.1"> => { + const writeV3_1 = ( + metadataList: Array, + ): IJsonSchemaCollection<"3.1"> => { const components: OpenApi.IComponents = { schemas: {}, }; const generator = (metadata: Metadata): OpenApi.IJsonSchema | null => - application_v31_schema({ + json_schema_station({ blockNever: true, components, attribute: {}, diff --git a/src/programmers/llm/LlmApplicationProgrammer.ts b/src/programmers/llm/LlmApplicationProgrammer.ts index 8fbc2d4b01..4765f36b15 100644 --- a/src/programmers/llm/LlmApplicationProgrammer.ts +++ b/src/programmers/llm/LlmApplicationProgrammer.ts @@ -3,11 +3,11 @@ import { ILlmFunction } from "@samchon/openapi/lib/structures/ILlmFunction"; import { MetadataFactory } from "../../factories/MetadataFactory"; +import { IJsDocTagInfo } from "../../schemas/metadata/IJsDocTagInfo"; import { Metadata } from "../../schemas/metadata/Metadata"; import { MetadataFunction } from "../../schemas/metadata/MetadataFunction"; import { MetadataObjectType } from "../../schemas/metadata/MetadataObjectType"; -import { IJsDocTagInfo } from "../../module"; import { LlmSchemaProgrammer } from "./LlmSchemaProgrammer"; export namespace LlmApplicationProgrammer { diff --git a/src/programmers/llm/LlmSchemaProgrammer.ts b/src/programmers/llm/LlmSchemaProgrammer.ts index 1df60a18ca..53ceea14e7 100644 --- a/src/programmers/llm/LlmSchemaProgrammer.ts +++ b/src/programmers/llm/LlmSchemaProgrammer.ts @@ -1,9 +1,11 @@ import { ILlmSchema } from "@samchon/openapi"; +import { HttpLlmConverter } from "@samchon/openapi/lib/converters/HttpLlmConverter"; +import { IJsonSchemaCollection } from "../../schemas/json/IJsonSchemaCollection"; import { Metadata } from "../../schemas/metadata/Metadata"; import { AtomicPredicator } from "../helpers/AtomicPredicator"; -import { llm_schema_station } from "../internal/llm_schema_station"; +import { JsonSchemasProgrammer } from "../json/JsonSchemasProgrammer"; export namespace LlmSchemaProgrammer { export const validate = (metadata: Metadata): string[] => { @@ -42,10 +44,18 @@ export namespace LlmSchemaProgrammer { return output; }; - export const write = (metadata: Metadata): ILlmSchema => - llm_schema_station({ - metadata, - blockNever: true, - attribute: {}, + export const write = (metadata: Metadata): ILlmSchema => { + const collection: IJsonSchemaCollection<"3.1"> = + JsonSchemasProgrammer.write({ + version: "3.1", + metadatas: [metadata], + }); + const schema: ILlmSchema | null = HttpLlmConverter.schema({ + components: collection.components, + schema: collection.schemas[0]!, }); + if (schema === null) + throw new Error("Failed to convert JSON schema to LLM schema."); + return schema; + }; } diff --git a/src/transformers/features/json/JsonSchemasTransformer.ts b/src/transformers/features/json/JsonSchemasTransformer.ts index 2c72062f2d..54c76e52a6 100644 --- a/src/transformers/features/json/JsonSchemasTransformer.ts +++ b/src/transformers/features/json/JsonSchemasTransformer.ts @@ -89,8 +89,10 @@ export namespace JsonSchemasTransformer { }); // APPLICATION - const app: IJsonSchemaCollection = - JsonSchemasProgrammer.write(version)(metadatas); + const app: IJsonSchemaCollection = JsonSchemasProgrammer.write({ + version, + metadatas, + }); return LiteralFactory.write(app); }; diff --git a/test-esm/package.json b/test-esm/package.json index 94da5779af..8567c65f52 100644 --- a/test-esm/package.json +++ b/test-esm/package.json @@ -36,6 +36,6 @@ "typescript": "^5.4.5" }, "dependencies": { - "typia": "../typia-7.0.0-dev.20241022-2.tgz" + "typia": "../typia-7.0.0-dev.20241022-3.tgz" } } \ No newline at end of file diff --git a/test/package.json b/test/package.json index a7ec19a068..f7341328d2 100644 --- a/test/package.json +++ b/test/package.json @@ -53,6 +53,6 @@ "suppress-warnings": "^1.0.2", "tstl": "^3.0.0", "uuid": "^9.0.1", - "typia": "../typia-7.0.0-dev.20241022-2.tgz" + "typia": "../typia-7.0.0-dev.20241022-3.tgz" } } \ No newline at end of file diff --git a/test/schemas/json/v3_0/ArrayAny.json b/test/schemas/json/v3_0/ArrayAny.json index cb0f360f73..59d0b16e17 100644 --- a/test/schemas/json/v3_0/ArrayAny.json +++ b/test/schemas/json/v3_0/ArrayAny.json @@ -47,7 +47,6 @@ "items": {} } }, - "nullable": false, "required": [ "anys", "nullables1", diff --git a/test/schemas/json/v3_0/ArrayHierarchical.json b/test/schemas/json/v3_0/ArrayHierarchical.json index 4344ced5e9..18a79574e3 100644 --- a/test/schemas/json/v3_0/ArrayHierarchical.json +++ b/test/schemas/json/v3_0/ArrayHierarchical.json @@ -30,7 +30,6 @@ } } }, - "nullable": false, "required": [ "id", "serial", @@ -49,7 +48,6 @@ "type": "number" } }, - "nullable": false, "required": [ "time", "zone" @@ -77,7 +75,6 @@ } } }, - "nullable": false, "required": [ "id", "code", @@ -105,7 +102,6 @@ "$ref": "#/components/schemas/ArrayHierarchical.ITimestamp" } }, - "nullable": false, "required": [ "id", "name", diff --git a/test/schemas/json/v3_0/ArrayHierarchicalPointer.json b/test/schemas/json/v3_0/ArrayHierarchicalPointer.json index 9c257b48b5..cf1066996c 100644 --- a/test/schemas/json/v3_0/ArrayHierarchicalPointer.json +++ b/test/schemas/json/v3_0/ArrayHierarchicalPointer.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -39,7 +38,6 @@ } } }, - "nullable": false, "required": [ "id", "serial", @@ -58,7 +56,6 @@ "type": "number" } }, - "nullable": false, "required": [ "time", "zone" @@ -86,7 +83,6 @@ } } }, - "nullable": false, "required": [ "id", "code", @@ -114,7 +110,6 @@ "$ref": "#/components/schemas/ArrayHierarchicalPointer.ITimestamp" } }, - "nullable": false, "required": [ "id", "name", diff --git a/test/schemas/json/v3_0/ArrayRecursive.json b/test/schemas/json/v3_0/ArrayRecursive.json index 0685497e3f..274a0957ea 100644 --- a/test/schemas/json/v3_0/ArrayRecursive.json +++ b/test/schemas/json/v3_0/ArrayRecursive.json @@ -24,7 +24,6 @@ "$ref": "#/components/schemas/ArrayRecursive.ITimestamp" } }, - "nullable": false, "required": [ "children", "id", @@ -43,7 +42,6 @@ "type": "number" } }, - "nullable": false, "required": [ "time", "zone" diff --git a/test/schemas/json/v3_0/ArrayRecursiveUnionExplicit.json b/test/schemas/json/v3_0/ArrayRecursiveUnionExplicit.json index 470a1a65cb..de8ee4642a 100644 --- a/test/schemas/json/v3_0/ArrayRecursiveUnionExplicit.json +++ b/test/schemas/json/v3_0/ArrayRecursiveUnionExplicit.json @@ -52,7 +52,6 @@ ] } }, - "nullable": false, "required": [ "id", "name", @@ -98,7 +97,6 @@ ] } }, - "nullable": false, "required": [ "id", "name", @@ -142,7 +140,6 @@ ] } }, - "nullable": false, "required": [ "id", "name", @@ -184,7 +181,6 @@ ] } }, - "nullable": false, "required": [ "id", "name", @@ -223,7 +219,6 @@ ] } }, - "nullable": false, "required": [ "id", "name", diff --git a/test/schemas/json/v3_0/ArrayRecursiveUnionExplicitPointer.json b/test/schemas/json/v3_0/ArrayRecursiveUnionExplicitPointer.json index e49625b320..96ca22f928 100644 --- a/test/schemas/json/v3_0/ArrayRecursiveUnionExplicitPointer.json +++ b/test/schemas/json/v3_0/ArrayRecursiveUnionExplicitPointer.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -40,7 +39,6 @@ ] } }, - "nullable": false, "required": [ "value" ] @@ -70,7 +68,6 @@ ] } }, - "nullable": false, "required": [ "id", "name", @@ -116,7 +113,6 @@ ] } }, - "nullable": false, "required": [ "id", "name", @@ -160,7 +156,6 @@ ] } }, - "nullable": false, "required": [ "id", "name", @@ -202,7 +197,6 @@ ] } }, - "nullable": false, "required": [ "id", "name", @@ -241,7 +235,6 @@ ] } }, - "nullable": false, "required": [ "id", "name", diff --git a/test/schemas/json/v3_0/ArrayRecursiveUnionImplicit.json b/test/schemas/json/v3_0/ArrayRecursiveUnionImplicit.json index feb5938b79..a17a0ccaf2 100644 --- a/test/schemas/json/v3_0/ArrayRecursiveUnionImplicit.json +++ b/test/schemas/json/v3_0/ArrayRecursiveUnionImplicit.json @@ -49,7 +49,6 @@ } } }, - "nullable": false, "required": [ "id", "name", @@ -83,7 +82,6 @@ } } }, - "nullable": false, "required": [ "access", "id", @@ -117,7 +115,6 @@ "type": "number" } }, - "nullable": false, "required": [ "id", "name", @@ -147,7 +144,6 @@ "type": "string" } }, - "nullable": false, "required": [ "id", "name", @@ -175,7 +171,6 @@ "type": "number" } }, - "nullable": false, "required": [ "id", "name", @@ -200,7 +195,6 @@ "$ref": "#/components/schemas/ArrayRecursiveUnionImplicit.IBucket" } }, - "nullable": false, "required": [ "id", "name", diff --git a/test/schemas/json/v3_0/ArrayRepeatedNullable.json b/test/schemas/json/v3_0/ArrayRepeatedNullable.json index ede12f2abc..b843d08152 100644 --- a/test/schemas/json/v3_0/ArrayRepeatedNullable.json +++ b/test/schemas/json/v3_0/ArrayRepeatedNullable.json @@ -17,17 +17,32 @@ } ] }, + "ArrayRepeatedNullable.Nullable": { + "oneOf": [ + { + "type": "string", + "nullable": true + }, + { + "type": "number", + "nullable": true + }, + { + "$ref": "#/components/schemas/ArrayArrayRepeatedNullable" + } + ] + }, "#/components/schemas/ArrayArrayRepeatedNullable": { "type": "array", "items": { - "$ref": "#/components/schemas/ArrayRepeatedNullable" + "$ref": "#/components/schemas/ArrayRepeatedNullable.Nullable" } } } }, "schemas": [ { - "$ref": "#/components/schemas/ArrayRepeatedNullable" + "$ref": "#/components/schemas/ArrayRepeatedNullable.Nullable" } ] } \ No newline at end of file diff --git a/test/schemas/json/v3_0/ArrayRepeatedUnion.json b/test/schemas/json/v3_0/ArrayRepeatedUnion.json index 9b0248a89b..3c157093e2 100644 --- a/test/schemas/json/v3_0/ArrayRepeatedUnion.json +++ b/test/schemas/json/v3_0/ArrayRepeatedUnion.json @@ -49,7 +49,6 @@ "$ref": "#/components/schemas/ArrayRepeatedUnion.IPoint3D" } }, - "nullable": false, "required": [ "scale", "position", @@ -70,7 +69,6 @@ "type": "number" } }, - "nullable": false, "required": [ "x", "y", diff --git a/test/schemas/json/v3_0/ArrayRepeatedUnionWithTuple.json b/test/schemas/json/v3_0/ArrayRepeatedUnionWithTuple.json index 72c599404f..5bf31ebc36 100644 --- a/test/schemas/json/v3_0/ArrayRepeatedUnionWithTuple.json +++ b/test/schemas/json/v3_0/ArrayRepeatedUnionWithTuple.json @@ -82,7 +82,6 @@ "$ref": "#/components/schemas/ArrayRepeatedUnionWithTuple.IPoint3D" } }, - "nullable": false, "required": [ "scale", "position", @@ -103,7 +102,6 @@ "type": "number" } }, - "nullable": false, "required": [ "x", "y", diff --git a/test/schemas/json/v3_0/ArraySimple.json b/test/schemas/json/v3_0/ArraySimple.json index aad12d3c5c..1ede2a4f66 100644 --- a/test/schemas/json/v3_0/ArraySimple.json +++ b/test/schemas/json/v3_0/ArraySimple.json @@ -24,7 +24,6 @@ } } }, - "nullable": false, "required": [ "name", "email", @@ -44,7 +43,6 @@ "type": "number" } }, - "nullable": false, "required": [ "name", "body", diff --git a/test/schemas/json/v3_0/AtomicClass.json b/test/schemas/json/v3_0/AtomicClass.json index f43673184d..322b8a0d46 100644 --- a/test/schemas/json/v3_0/AtomicClass.json +++ b/test/schemas/json/v3_0/AtomicClass.json @@ -9,9 +9,27 @@ { "type": "boolean" }, + { + "type": "boolean" + }, + { + "type": "boolean" + }, + { + "type": "number" + }, { "type": "number" }, + { + "type": "number" + }, + { + "type": "string" + }, + { + "type": "string" + }, { "type": "string" } diff --git a/test/schemas/json/v3_0/AtomicUnion.json b/test/schemas/json/v3_0/AtomicUnion.json index f107973ba7..625f8ac7ab 100644 --- a/test/schemas/json/v3_0/AtomicUnion.json +++ b/test/schemas/json/v3_0/AtomicUnion.json @@ -2,10 +2,26 @@ "version": "3.0", "components": { "schemas": { + "AtomicUnion.Union.Nullable": { + "oneOf": [ + { + "type": "string", + "nullable": true + }, + { + "type": "number", + "nullable": true + }, + { + "type": "boolean", + "nullable": true + } + ] + }, "AtomicUnion": { "type": "array", "items": { - "$ref": "#/components/schemas/AtomicUnion.Union" + "$ref": "#/components/schemas/AtomicUnion.Union.Nullable" } }, "AtomicUnion.Union": { diff --git a/test/schemas/json/v3_0/ClassGetter.json b/test/schemas/json/v3_0/ClassGetter.json index 2ef0ef1bd3..9101fc7510 100644 --- a/test/schemas/json/v3_0/ClassGetter.json +++ b/test/schemas/json/v3_0/ClassGetter.json @@ -16,7 +16,6 @@ "nullable": true } }, - "nullable": false, "required": [ "id", "name", diff --git a/test/schemas/json/v3_0/ClassMethod.json b/test/schemas/json/v3_0/ClassMethod.json index 27b0dc19c7..d35c8ff49a 100644 --- a/test/schemas/json/v3_0/ClassMethod.json +++ b/test/schemas/json/v3_0/ClassMethod.json @@ -12,7 +12,6 @@ "type": "number" } }, - "nullable": false, "required": [ "name", "age" diff --git a/test/schemas/json/v3_0/ClassPropertyAssignment.json b/test/schemas/json/v3_0/ClassPropertyAssignment.json index 24eb19c6c7..aec776fbb0 100644 --- a/test/schemas/json/v3_0/ClassPropertyAssignment.json +++ b/test/schemas/json/v3_0/ClassPropertyAssignment.json @@ -27,7 +27,6 @@ "type": "boolean" } }, - "nullable": false, "required": [ "id", "name", diff --git a/test/schemas/json/v3_0/CommentTagArray.json b/test/schemas/json/v3_0/CommentTagArray.json index 128174a375..fa38284e3f 100644 --- a/test/schemas/json/v3_0/CommentTagArray.json +++ b/test/schemas/json/v3_0/CommentTagArray.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -59,7 +58,6 @@ "uniqueItems": true } }, - "nullable": false, "required": [ "items", "minItems", diff --git a/test/schemas/json/v3_0/CommentTagArrayUnion.json b/test/schemas/json/v3_0/CommentTagArrayUnion.json index f0b6269ab6..3184a415bc 100644 --- a/test/schemas/json/v3_0/CommentTagArrayUnion.json +++ b/test/schemas/json/v3_0/CommentTagArrayUnion.json @@ -49,7 +49,6 @@ "maxItems": 7 } }, - "nullable": false, "required": [ "items", "minItems", diff --git a/test/schemas/json/v3_0/CommentTagAtomicUnion.json b/test/schemas/json/v3_0/CommentTagAtomicUnion.json index 23b758455e..13528027c9 100644 --- a/test/schemas/json/v3_0/CommentTagAtomicUnion.json +++ b/test/schemas/json/v3_0/CommentTagAtomicUnion.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -34,7 +33,6 @@ ] } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/CommentTagDefault.json b/test/schemas/json/v3_0/CommentTagDefault.json index 67cbbd4092..8b7592a7cc 100644 --- a/test/schemas/json/v3_0/CommentTagDefault.json +++ b/test/schemas/json/v3_0/CommentTagDefault.json @@ -109,7 +109,6 @@ "description": "Default value on union typed property." } }, - "nullable": false, "required": [ "boolean", "number", diff --git a/test/schemas/json/v3_0/CommentTagFormat.json b/test/schemas/json/v3_0/CommentTagFormat.json index b16bdff302..5e60d67266 100644 --- a/test/schemas/json/v3_0/CommentTagFormat.json +++ b/test/schemas/json/v3_0/CommentTagFormat.json @@ -94,7 +94,6 @@ "format": "relative-json-pointer" } }, - "nullable": false, "required": [ "byte", "password", diff --git a/test/schemas/json/v3_0/CommentTagLength.json b/test/schemas/json/v3_0/CommentTagLength.json index 3834f9a5c7..2ef1665492 100644 --- a/test/schemas/json/v3_0/CommentTagLength.json +++ b/test/schemas/json/v3_0/CommentTagLength.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -44,7 +43,6 @@ "maxLength": 19 } }, - "nullable": false, "required": [ "fixed", "minimum", diff --git a/test/schemas/json/v3_0/CommentTagObjectUnion.json b/test/schemas/json/v3_0/CommentTagObjectUnion.json index cfebbf5b74..db7fd374b4 100644 --- a/test/schemas/json/v3_0/CommentTagObjectUnion.json +++ b/test/schemas/json/v3_0/CommentTagObjectUnion.json @@ -26,7 +26,6 @@ "minimum": 3 } }, - "nullable": false, "required": [ "value" ] @@ -40,7 +39,6 @@ "maxLength": 7 } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/CommentTagPattern.json b/test/schemas/json/v3_0/CommentTagPattern.json index 4357efa223..323691b0c0 100644 --- a/test/schemas/json/v3_0/CommentTagPattern.json +++ b/test/schemas/json/v3_0/CommentTagPattern.json @@ -22,7 +22,6 @@ "pattern": "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$" } }, - "nullable": false, "required": [ "uuid", "email", diff --git a/test/schemas/json/v3_0/CommentTagRange.json b/test/schemas/json/v3_0/CommentTagRange.json index a3680d5e8c..9167bd9a81 100644 --- a/test/schemas/json/v3_0/CommentTagRange.json +++ b/test/schemas/json/v3_0/CommentTagRange.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -68,7 +67,6 @@ "maximum": 10 } }, - "nullable": false, "required": [ "greater", "greater_equal", diff --git a/test/schemas/json/v3_0/CommentTagType.json b/test/schemas/json/v3_0/CommentTagType.json index bd8085c028..f4b5b83477 100644 --- a/test/schemas/json/v3_0/CommentTagType.json +++ b/test/schemas/json/v3_0/CommentTagType.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -46,7 +45,6 @@ "type": "number" } }, - "nullable": false, "required": [ "int", "uint", diff --git a/test/schemas/json/v3_0/ConstantAtomicAbsorbed.json b/test/schemas/json/v3_0/ConstantAtomicAbsorbed.json index 97e3e6c610..7527ee0d98 100644 --- a/test/schemas/json/v3_0/ConstantAtomicAbsorbed.json +++ b/test/schemas/json/v3_0/ConstantAtomicAbsorbed.json @@ -14,7 +14,6 @@ "default": 20 } }, - "nullable": false, "required": [ "id", "age" diff --git a/test/schemas/json/v3_0/ConstantAtomicSimple.json b/test/schemas/json/v3_0/ConstantAtomicSimple.json index 3dfdb2531e..d8390c9cb9 100644 --- a/test/schemas/json/v3_0/ConstantAtomicSimple.json +++ b/test/schemas/json/v3_0/ConstantAtomicSimple.json @@ -9,7 +9,12 @@ { "type": "boolean", "enum": [ - false, + false + ] + }, + { + "type": "boolean", + "enum": [ true ] }, diff --git a/test/schemas/json/v3_0/ConstantAtomicTagged.json b/test/schemas/json/v3_0/ConstantAtomicTagged.json index af9e8bb292..9487f93dec 100644 --- a/test/schemas/json/v3_0/ConstantAtomicTagged.json +++ b/test/schemas/json/v3_0/ConstantAtomicTagged.json @@ -6,35 +6,27 @@ "type": "object", "properties": { "id": { - "oneOf": [ - { - "type": "string", - "enum": [ - "latest" - ] - }, - { - "type": "string", - "format": "uuid" - } + "type": "string", + "format": "uuid", + "enum": [ + "latest" ] }, "age": { "oneOf": [ + { + "type": "integer", + "maximum": 100 + }, { "type": "number", "enum": [ -1 ] - }, - { - "type": "integer", - "maximum": 100 } ] } }, - "nullable": false, "required": [ "id", "age" diff --git a/test/schemas/json/v3_0/ConstantAtomicUnion.json b/test/schemas/json/v3_0/ConstantAtomicUnion.json index 80217d3157..0cdc8b9501 100644 --- a/test/schemas/json/v3_0/ConstantAtomicUnion.json +++ b/test/schemas/json/v3_0/ConstantAtomicUnion.json @@ -10,6 +10,20 @@ }, "ConstantAtomicUnion.Union": { "oneOf": [ + { + "type": "object", + "properties": { + "key": { + "type": "string", + "enum": [ + "key" + ] + } + }, + "required": [ + "key" + ] + }, { "type": "boolean", "enum": [ @@ -26,23 +40,8 @@ { "type": "string", "enum": [ - "three", - "four" - ] - }, - { - "type": "object", - "properties": { - "key": { - "type": "string", - "enum": [ - "key" - ] - } - }, - "nullable": false, - "required": [ - "key" + "four", + "three" ] } ] diff --git a/test/schemas/json/v3_0/ConstantAtomicWrapper.json b/test/schemas/json/v3_0/ConstantAtomicWrapper.json index 02a5d41b95..31efe48f06 100644 --- a/test/schemas/json/v3_0/ConstantAtomicWrapper.json +++ b/test/schemas/json/v3_0/ConstantAtomicWrapper.json @@ -27,7 +27,6 @@ "type": "boolean" } }, - "nullable": false, "required": [ "value" ] @@ -39,7 +38,6 @@ "type": "number" } }, - "nullable": false, "required": [ "value" ] @@ -51,7 +49,6 @@ "type": "string" } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/DynamicArray.json b/test/schemas/json/v3_0/DynamicArray.json index eaffafa8c2..76887bf5bd 100644 --- a/test/schemas/json/v3_0/DynamicArray.json +++ b/test/schemas/json/v3_0/DynamicArray.json @@ -8,7 +8,6 @@ "value": { "type": "object", "properties": {}, - "nullable": false, "additionalProperties": { "type": "array", "items": { @@ -17,7 +16,6 @@ } } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/DynamicComposite.json b/test/schemas/json/v3_0/DynamicComposite.json index 8e46b3b315..ca7b257990 100644 --- a/test/schemas/json/v3_0/DynamicComposite.json +++ b/test/schemas/json/v3_0/DynamicComposite.json @@ -12,7 +12,6 @@ "type": "string" } }, - "nullable": false, "required": [ "id", "name" diff --git a/test/schemas/json/v3_0/DynamicConstant.json b/test/schemas/json/v3_0/DynamicConstant.json index 99dc891981..85b04f5b5b 100644 --- a/test/schemas/json/v3_0/DynamicConstant.json +++ b/test/schemas/json/v3_0/DynamicConstant.json @@ -21,7 +21,6 @@ "type": "number" } }, - "nullable": false, "required": [ "a", "b", @@ -30,7 +29,6 @@ ] } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/DynamicEnumeration.json b/test/schemas/json/v3_0/DynamicEnumeration.json index 52661f172c..45e8e242e1 100644 --- a/test/schemas/json/v3_0/DynamicEnumeration.json +++ b/test/schemas/json/v3_0/DynamicEnumeration.json @@ -38,11 +38,9 @@ "ru": { "type": "string" } - }, - "nullable": false + } } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/DynamicNever.json b/test/schemas/json/v3_0/DynamicNever.json index ca434f90a3..a035c7b570 100644 --- a/test/schemas/json/v3_0/DynamicNever.json +++ b/test/schemas/json/v3_0/DynamicNever.json @@ -4,8 +4,7 @@ "schemas": { "DynamicNever": { "type": "object", - "properties": {}, - "nullable": false + "properties": {} } } }, diff --git a/test/schemas/json/v3_0/DynamicSimple.json b/test/schemas/json/v3_0/DynamicSimple.json index de7b67bf3d..4908cb8414 100644 --- a/test/schemas/json/v3_0/DynamicSimple.json +++ b/test/schemas/json/v3_0/DynamicSimple.json @@ -8,13 +8,11 @@ "value": { "type": "object", "properties": {}, - "nullable": false, "additionalProperties": { "type": "number" } } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/DynamicTemplate.json b/test/schemas/json/v3_0/DynamicTemplate.json index 2091d32c66..0ad2541f7e 100644 --- a/test/schemas/json/v3_0/DynamicTemplate.json +++ b/test/schemas/json/v3_0/DynamicTemplate.json @@ -5,7 +5,6 @@ "DynamicTemplate": { "type": "object", "properties": {}, - "nullable": false, "additionalProperties": { "oneOf": [ { diff --git a/test/schemas/json/v3_0/DynamicTree.json b/test/schemas/json/v3_0/DynamicTree.json index ce59b35271..3577796076 100644 --- a/test/schemas/json/v3_0/DynamicTree.json +++ b/test/schemas/json/v3_0/DynamicTree.json @@ -15,7 +15,6 @@ "$ref": "#/components/schemas/RecordstringDynamicTree" } }, - "nullable": false, "required": [ "id", "sequence", @@ -25,7 +24,6 @@ "RecordstringDynamicTree": { "type": "object", "properties": {}, - "nullable": false, "description": "Construct a type with a set of properties K of type T", "additionalProperties": { "$ref": "#/components/schemas/DynamicTree" diff --git a/test/schemas/json/v3_0/DynamicUndefined.json b/test/schemas/json/v3_0/DynamicUndefined.json index aabd00b948..30339cbcc4 100644 --- a/test/schemas/json/v3_0/DynamicUndefined.json +++ b/test/schemas/json/v3_0/DynamicUndefined.json @@ -4,8 +4,7 @@ "schemas": { "DynamicUndefined": { "type": "object", - "properties": {}, - "nullable": false + "properties": {} } } }, diff --git a/test/schemas/json/v3_0/DynamicUnion.json b/test/schemas/json/v3_0/DynamicUnion.json index d5902fee3a..02b8744c80 100644 --- a/test/schemas/json/v3_0/DynamicUnion.json +++ b/test/schemas/json/v3_0/DynamicUnion.json @@ -5,7 +5,6 @@ "DynamicUnion": { "type": "object", "properties": {}, - "nullable": false, "additionalProperties": { "oneOf": [ { diff --git a/test/schemas/json/v3_0/ObjectAlias.json b/test/schemas/json/v3_0/ObjectAlias.json index 065e6081a1..c9b1d58eac 100644 --- a/test/schemas/json/v3_0/ObjectAlias.json +++ b/test/schemas/json/v3_0/ObjectAlias.json @@ -50,7 +50,6 @@ "nullable": true } }, - "nullable": false, "required": [ "id", "email", diff --git a/test/schemas/json/v3_0/ObjectDate.json b/test/schemas/json/v3_0/ObjectDate.json index 3b5617b47b..87096d51cc 100644 --- a/test/schemas/json/v3_0/ObjectDate.json +++ b/test/schemas/json/v3_0/ObjectDate.json @@ -31,7 +31,6 @@ "nullable": true } }, - "nullable": false, "required": [ "date", "datetime", diff --git a/test/schemas/json/v3_0/ObjectDescription.json b/test/schemas/json/v3_0/ObjectDescription.json index f51d503aaf..886996454a 100644 --- a/test/schemas/json/v3_0/ObjectDescription.json +++ b/test/schemas/json/v3_0/ObjectDescription.json @@ -13,7 +13,6 @@ }, "deprecated": { "type": "boolean", - "deprecated": true, "title": "Deprecated property", "description": "Deprecated property.\n\nIf `@deprecated` comment tag being utilized, the property will be marked\nas deprecated in the JSON scheam." }, @@ -35,7 +34,6 @@ "description": "New line before dot character\n\nIf dot character (\".\") being used before the first new line, it would not\nbe considered as title in the JSON schema." } }, - "nullable": false, "required": [ "id", "deprecated", diff --git a/test/schemas/json/v3_0/ObjectDynamic.json b/test/schemas/json/v3_0/ObjectDynamic.json index 6b640bf289..0979356a2a 100644 --- a/test/schemas/json/v3_0/ObjectDynamic.json +++ b/test/schemas/json/v3_0/ObjectDynamic.json @@ -5,7 +5,6 @@ "ObjectDynamic": { "type": "object", "properties": {}, - "nullable": false, "additionalProperties": { "oneOf": [ { diff --git a/test/schemas/json/v3_0/ObjectGeneric.json b/test/schemas/json/v3_0/ObjectGeneric.json index a48d93cc15..69d1ee272b 100644 --- a/test/schemas/json/v3_0/ObjectGeneric.json +++ b/test/schemas/json/v3_0/ObjectGeneric.json @@ -36,7 +36,6 @@ } } }, - "nullable": false, "required": [ "value", "child", @@ -53,7 +52,6 @@ "type": "boolean" } }, - "nullable": false, "required": [ "child_value", "child_next" @@ -75,7 +73,6 @@ } } }, - "nullable": false, "required": [ "value", "child", @@ -92,7 +89,6 @@ "type": "number" } }, - "nullable": false, "required": [ "child_value", "child_next" @@ -114,7 +110,6 @@ } } }, - "nullable": false, "required": [ "value", "child", @@ -131,7 +126,6 @@ "type": "string" } }, - "nullable": false, "required": [ "child_value", "child_next" diff --git a/test/schemas/json/v3_0/ObjectGenericAlias.json b/test/schemas/json/v3_0/ObjectGenericAlias.json index f30c56b5fe..4785298d9d 100644 --- a/test/schemas/json/v3_0/ObjectGenericAlias.json +++ b/test/schemas/json/v3_0/ObjectGenericAlias.json @@ -9,7 +9,6 @@ "type": "string" } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/ObjectGenericArray.json b/test/schemas/json/v3_0/ObjectGenericArray.json index 4e323e7070..43f7a32169 100644 --- a/test/schemas/json/v3_0/ObjectGenericArray.json +++ b/test/schemas/json/v3_0/ObjectGenericArray.json @@ -15,7 +15,6 @@ } } }, - "nullable": false, "required": [ "pagination", "data" @@ -37,7 +36,6 @@ "type": "number" } }, - "nullable": false, "required": [ "page", "limit", @@ -55,7 +53,6 @@ "type": "number" } }, - "nullable": false, "required": [ "name", "age" diff --git a/test/schemas/json/v3_0/ObjectGenericUnion.json b/test/schemas/json/v3_0/ObjectGenericUnion.json index c51a501035..42829a15b5 100644 --- a/test/schemas/json/v3_0/ObjectGenericUnion.json +++ b/test/schemas/json/v3_0/ObjectGenericUnion.json @@ -9,7 +9,6 @@ "$ref": "#/components/schemas/ObjectGenericUnion.ISaleEntireArticle" } }, - "nullable": false, "required": [ "value" ] @@ -24,6 +23,32 @@ } ] }, + "ObjectGenericUnion.ISaleAnswer.Nullable": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "hit": { + "type": "number" + }, + "contents": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ObjectGenericUnion.ISaleArticle.IContent" + } + }, + "created_at": { + "type": "string" + } + }, + "required": [ + "id", + "hit", + "contents", + "created_at" + ] + }, "ObjectGenericUnion.ISaleQuestion": { "type": "object", "properties": { @@ -49,7 +74,6 @@ "type": "string" } }, - "nullable": false, "required": [ "writer", "answer", @@ -59,7 +83,7 @@ "created_at" ] }, - "ObjectGenericUnion.ISaleAnswer.Nullable": { + "ObjectGenericUnion.ISaleAnswer": { "type": "object", "properties": { "id": { @@ -78,7 +102,6 @@ "type": "string" } }, - "nullable": true, "required": [ "id", "hit", @@ -108,7 +131,6 @@ } } }, - "nullable": false, "required": [ "id", "created_at", @@ -131,7 +153,6 @@ "type": "string" } }, - "nullable": false, "required": [ "name", "extension", @@ -163,7 +184,6 @@ "type": "string" } }, - "nullable": false, "required": [ "writer", "answer", @@ -198,7 +218,6 @@ } } }, - "nullable": false, "required": [ "score", "id", diff --git a/test/schemas/json/v3_0/ObjectHierarchical.json b/test/schemas/json/v3_0/ObjectHierarchical.json index 7947c5df71..11901bc23a 100644 --- a/test/schemas/json/v3_0/ObjectHierarchical.json +++ b/test/schemas/json/v3_0/ObjectHierarchical.json @@ -2,6 +2,86 @@ "version": "3.0", "components": { "schemas": { + "ObjectHierarchical.IMember.Nullable": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "account": { + "$ref": "#/components/schemas/ObjectHierarchical.IAccount" + }, + "enterprise": { + "$ref": "#/components/schemas/ObjectHierarchical.IEnterprise.Nullable" + }, + "emails": { + "type": "array", + "items": { + "type": "string" + } + }, + "created_at": { + "$ref": "#/components/schemas/ObjectHierarchical.ITimestamp" + }, + "authorized": { + "type": "boolean" + } + }, + "required": [ + "id", + "account", + "enterprise", + "emails", + "created_at", + "authorized" + ] + }, + "ObjectHierarchical.IEnterprise.Nullable": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "account": { + "$ref": "#/components/schemas/ObjectHierarchical.IAccount" + }, + "name": { + "type": "string" + }, + "grade": { + "type": "number" + }, + "created_at": { + "$ref": "#/components/schemas/ObjectHierarchical.ITimestamp" + } + }, + "required": [ + "id", + "account", + "name", + "grade", + "created_at" + ] + }, + "ObjectHierarchical.IAccount.Nullable": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "code": { + "type": "string" + }, + "created_at": { + "$ref": "#/components/schemas/ObjectHierarchical.ITimestamp" + } + }, + "required": [ + "id", + "code", + "created_at" + ] + }, "ObjectHierarchical.ICustomer": { "type": "object", "properties": { @@ -26,7 +106,20 @@ "ip": { "type": "array", "items": { - "type": "number" + "oneOf": [ + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + }, + { + "type": "number" + } + ] }, "minItems": 4, "maxItems": 4 @@ -35,7 +128,6 @@ "$ref": "#/components/schemas/ObjectHierarchical.ITimestamp" } }, - "nullable": false, "required": [ "id", "channel", @@ -72,7 +164,6 @@ "$ref": "#/components/schemas/ObjectHierarchical.ITimestamp" } }, - "nullable": false, "required": [ "id", "code", @@ -93,13 +184,12 @@ "type": "number" } }, - "nullable": false, "required": [ "time", "zone" ] }, - "ObjectHierarchical.IMember.Nullable": { + "ObjectHierarchical.IMember": { "type": "object", "properties": { "id": { @@ -124,7 +214,6 @@ "type": "boolean" } }, - "nullable": true, "required": [ "id", "account", @@ -147,14 +236,13 @@ "$ref": "#/components/schemas/ObjectHierarchical.ITimestamp" } }, - "nullable": false, "required": [ "id", "code", "created_at" ] }, - "ObjectHierarchical.IEnterprise.Nullable": { + "ObjectHierarchical.IEnterprise": { "type": "object", "properties": { "id": { @@ -173,7 +261,6 @@ "$ref": "#/components/schemas/ObjectHierarchical.ITimestamp" } }, - "nullable": true, "required": [ "id", "account", @@ -181,26 +268,6 @@ "grade", "created_at" ] - }, - "ObjectHierarchical.IAccount.Nullable": { - "type": "object", - "properties": { - "id": { - "type": "number" - }, - "code": { - "type": "string" - }, - "created_at": { - "$ref": "#/components/schemas/ObjectHierarchical.ITimestamp" - } - }, - "nullable": true, - "required": [ - "id", - "code", - "created_at" - ] } } }, diff --git a/test/schemas/json/v3_0/ObjectInternal.json b/test/schemas/json/v3_0/ObjectInternal.json index 91c2df41d5..4395ec2cf4 100644 --- a/test/schemas/json/v3_0/ObjectInternal.json +++ b/test/schemas/json/v3_0/ObjectInternal.json @@ -12,7 +12,6 @@ "type": "string" } }, - "nullable": false, "required": [ "id", "name" diff --git a/test/schemas/json/v3_0/ObjectIntersection.json b/test/schemas/json/v3_0/ObjectIntersection.json index fe2f6988c8..6b51e05948 100644 --- a/test/schemas/json/v3_0/ObjectIntersection.json +++ b/test/schemas/json/v3_0/ObjectIntersection.json @@ -15,7 +15,6 @@ "type": "boolean" } }, - "nullable": false, "required": [ "email", "name", diff --git a/test/schemas/json/v3_0/ObjectJsonTag.json b/test/schemas/json/v3_0/ObjectJsonTag.json index 6ca85217da..c574c8c8f0 100644 --- a/test/schemas/json/v3_0/ObjectJsonTag.json +++ b/test/schemas/json/v3_0/ObjectJsonTag.json @@ -25,7 +25,6 @@ "description": "Complicate title." } }, - "nullable": false, "required": [ "vulnerable", "description", diff --git a/test/schemas/json/v3_0/ObjectLiteralProperty.json b/test/schemas/json/v3_0/ObjectLiteralProperty.json index 081a912cd5..92f7c3e7d7 100644 --- a/test/schemas/json/v3_0/ObjectLiteralProperty.json +++ b/test/schemas/json/v3_0/ObjectLiteralProperty.json @@ -12,7 +12,6 @@ "type": "string" } }, - "nullable": false, "required": [ "something-interesting-do-you-want?", "or-something-crazy-do-you-want?" diff --git a/test/schemas/json/v3_0/ObjectLiteralType.json b/test/schemas/json/v3_0/ObjectLiteralType.json index 430f7f767d..a92e5caefb 100644 --- a/test/schemas/json/v3_0/ObjectLiteralType.json +++ b/test/schemas/json/v3_0/ObjectLiteralType.json @@ -1,6 +1,8 @@ { "version": "3.0", - "components": {}, + "components": { + "schemas": {} + }, "schemas": [ { "type": "object", @@ -15,7 +17,6 @@ "type": "number" } }, - "nullable": false, "required": [ "id", "name", diff --git a/test/schemas/json/v3_0/ObjectNullable.json b/test/schemas/json/v3_0/ObjectNullable.json index c0248d71e8..b0945703f0 100644 --- a/test/schemas/json/v3_0/ObjectNullable.json +++ b/test/schemas/json/v3_0/ObjectNullable.json @@ -12,11 +12,46 @@ } } }, - "nullable": false, "required": [ "value" ] }, + "ObjectNullable.IBrand.Nullable": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "brand" + ] + }, + "name": { + "type": "string" + } + }, + "required": [ + "type", + "name" + ] + }, + "ObjectNullable.IManufacturer.Nullable": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "manufacturer" + ] + }, + "name": { + "type": "string" + } + }, + "required": [ + "type", + "name" + ] + }, "ObjectNullable.IProduct": { "type": "object", "properties": { @@ -37,17 +72,9 @@ { "$ref": "#/components/schemas/ObjectNullable.IManufacturer.Nullable" } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "brand": "#/components/schemas/ObjectNullable.IBrand", - "manufacturer": "#/components/schemas/ObjectNullable.IManufacturer" - } - } + ] } }, - "nullable": false, "required": [ "name", "manufacturer", @@ -68,13 +95,12 @@ "type": "string" } }, - "nullable": false, "required": [ "type", "name" ] }, - "ObjectNullable.IBrand.Nullable": { + "ObjectNullable.IBrand": { "type": "object", "properties": { "type": { @@ -87,26 +113,6 @@ "type": "string" } }, - "nullable": true, - "required": [ - "type", - "name" - ] - }, - "ObjectNullable.IManufacturer.Nullable": { - "type": "object", - "properties": { - "type": { - "type": "string", - "enum": [ - "manufacturer" - ] - }, - "name": { - "type": "string" - } - }, - "nullable": true, "required": [ "type", "name" diff --git a/test/schemas/json/v3_0/ObjectOptional.json b/test/schemas/json/v3_0/ObjectOptional.json index b0b4476cba..196fc1ab3f 100644 --- a/test/schemas/json/v3_0/ObjectOptional.json +++ b/test/schemas/json/v3_0/ObjectOptional.json @@ -17,8 +17,7 @@ "sequence": { "type": "number" } - }, - "nullable": false + } } } }, diff --git a/test/schemas/json/v3_0/ObjectPartial.json b/test/schemas/json/v3_0/ObjectPartial.json index 40586150b9..7c8902512b 100644 --- a/test/schemas/json/v3_0/ObjectPartial.json +++ b/test/schemas/json/v3_0/ObjectPartial.json @@ -2,6 +2,36 @@ "version": "3.0", "components": { "schemas": { + "ObjectPartial.IBase.Nullable": { + "type": "object", + "properties": { + "boolean": { + "type": "boolean" + }, + "number": { + "type": "number" + }, + "string": { + "type": "string" + }, + "array": { + "type": "array", + "items": { + "type": "number" + } + }, + "object": { + "$ref": "#/components/schemas/ObjectPartial.IBase.Nullable" + } + }, + "required": [ + "boolean", + "number", + "string", + "array", + "object" + ] + }, "PartialObjectPartial.IBase": { "type": "object", "properties": { @@ -24,10 +54,9 @@ "$ref": "#/components/schemas/ObjectPartial.IBase.Nullable" } }, - "nullable": false, "description": "Make all properties in T optional" }, - "ObjectPartial.IBase.Nullable": { + "ObjectPartial.IBase": { "type": "object", "properties": { "boolean": { @@ -49,7 +78,6 @@ "$ref": "#/components/schemas/ObjectPartial.IBase.Nullable" } }, - "nullable": true, "required": [ "boolean", "number", diff --git a/test/schemas/json/v3_0/ObjectPartialAndRequired.json b/test/schemas/json/v3_0/ObjectPartialAndRequired.json index f28fe1bdad..f9342ed096 100644 --- a/test/schemas/json/v3_0/ObjectPartialAndRequired.json +++ b/test/schemas/json/v3_0/ObjectPartialAndRequired.json @@ -2,7 +2,7 @@ "version": "3.0", "components": { "schemas": { - "ObjectPartialAndRequired": { + "ObjectPartialAndRequired.Nullable": { "type": "object", "properties": { "string": { @@ -24,13 +24,12 @@ } } }, - "nullable": false, "required": [ "object", "array" ] }, - "ObjectPartialAndRequired.Nullable": { + "ObjectPartialAndRequired": { "type": "object", "properties": { "string": { @@ -52,7 +51,6 @@ } } }, - "nullable": true, "required": [ "object", "array" diff --git a/test/schemas/json/v3_0/ObjectPrimitive.json b/test/schemas/json/v3_0/ObjectPrimitive.json index e4d9440b90..b44a36f2e2 100644 --- a/test/schemas/json/v3_0/ObjectPrimitive.json +++ b/test/schemas/json/v3_0/ObjectPrimitive.json @@ -35,7 +35,6 @@ "type": "string" } }, - "nullable": false, "required": [ "id", "extension", @@ -65,7 +64,6 @@ "type": "string" } }, - "nullable": false, "required": [ "id", "name", diff --git a/test/schemas/json/v3_0/ObjectPropertyNullable.json b/test/schemas/json/v3_0/ObjectPropertyNullable.json index cae006411f..8e84bca959 100644 --- a/test/schemas/json/v3_0/ObjectPropertyNullable.json +++ b/test/schemas/json/v3_0/ObjectPropertyNullable.json @@ -43,7 +43,6 @@ "nullable": true } }, - "nullable": false, "required": [ "value" ] @@ -56,7 +55,6 @@ "nullable": true } }, - "nullable": false, "required": [ "value" ] @@ -69,11 +67,38 @@ "nullable": true } }, - "nullable": false, "required": [ "value" ] }, + "ObjectPropertyNullable.IMember.Nullable": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string", + "nullable": true + }, + "grade": { + "type": "number" + }, + "serial": { + "type": "number", + "nullable": true + }, + "activated": { + "type": "boolean", + "nullable": true + } + }, + "required": [ + "id", + "name", + "activated" + ] + }, "ObjectPropertyNullable.IPointerObjectPropertyNullable.IMember": { "type": "object", "properties": { @@ -81,12 +106,11 @@ "$ref": "#/components/schemas/ObjectPropertyNullable.IMember.Nullable" } }, - "nullable": false, "required": [ "value" ] }, - "ObjectPropertyNullable.IMember.Nullable": { + "ObjectPropertyNullable.IMember": { "type": "object", "properties": { "id": { @@ -108,7 +132,6 @@ "nullable": true } }, - "nullable": true, "required": [ "id", "name", diff --git a/test/schemas/json/v3_0/ObjectRecursive.json b/test/schemas/json/v3_0/ObjectRecursive.json index a70f6cfadb..8588df9b45 100644 --- a/test/schemas/json/v3_0/ObjectRecursive.json +++ b/test/schemas/json/v3_0/ObjectRecursive.json @@ -2,7 +2,7 @@ "version": "3.0", "components": { "schemas": { - "ObjectRecursive.IDepartment": { + "ObjectRecursive.IDepartment.Nullable": { "type": "object", "properties": { "parent": { @@ -24,7 +24,6 @@ "$ref": "#/components/schemas/ObjectRecursive.ITimestamp" } }, - "nullable": false, "required": [ "parent", "id", @@ -34,7 +33,7 @@ "created_at" ] }, - "ObjectRecursive.IDepartment.Nullable": { + "ObjectRecursive.IDepartment": { "type": "object", "properties": { "parent": { @@ -56,7 +55,6 @@ "$ref": "#/components/schemas/ObjectRecursive.ITimestamp" } }, - "nullable": true, "required": [ "parent", "id", @@ -76,7 +74,6 @@ "type": "number" } }, - "nullable": false, "required": [ "time", "zone" diff --git a/test/schemas/json/v3_0/ObjectRequired.json b/test/schemas/json/v3_0/ObjectRequired.json index 9e026e2c74..1a57b9e134 100644 --- a/test/schemas/json/v3_0/ObjectRequired.json +++ b/test/schemas/json/v3_0/ObjectRequired.json @@ -2,6 +2,29 @@ "version": "3.0", "components": { "schemas": { + "ObjectRequired.IBase.Nullable": { + "type": "object", + "properties": { + "boolean": { + "type": "boolean" + }, + "number": { + "type": "number" + }, + "string": { + "type": "string" + }, + "array": { + "type": "array", + "items": { + "type": "number" + } + }, + "object": { + "$ref": "#/components/schemas/ObjectRequired.IBase.Nullable" + } + } + }, "RequiredObjectRequired.IBase": { "type": "object", "properties": { @@ -24,7 +47,6 @@ "$ref": "#/components/schemas/ObjectRequired.IBase.Nullable" } }, - "nullable": false, "required": [ "boolean", "number", @@ -34,7 +56,7 @@ ], "description": "Make all properties in T required" }, - "ObjectRequired.IBase.Nullable": { + "ObjectRequired.IBase": { "type": "object", "properties": { "boolean": { @@ -55,8 +77,7 @@ "object": { "$ref": "#/components/schemas/ObjectRequired.IBase.Nullable" } - }, - "nullable": true + } } } }, diff --git a/test/schemas/json/v3_0/ObjectSimple.json b/test/schemas/json/v3_0/ObjectSimple.json index 557505ff2d..cac1779b40 100644 --- a/test/schemas/json/v3_0/ObjectSimple.json +++ b/test/schemas/json/v3_0/ObjectSimple.json @@ -18,7 +18,6 @@ "$ref": "#/components/schemas/ObjectSimple.IPoint3D" } }, - "nullable": false, "required": [ "scale", "position", @@ -39,7 +38,6 @@ "type": "number" } }, - "nullable": false, "required": [ "x", "y", diff --git a/test/schemas/json/v3_0/ObjectTuple.json b/test/schemas/json/v3_0/ObjectTuple.json index 3b073055e0..6e55e48963 100644 --- a/test/schemas/json/v3_0/ObjectTuple.json +++ b/test/schemas/json/v3_0/ObjectTuple.json @@ -30,7 +30,6 @@ "type": "string" } }, - "nullable": false, "required": [ "id", "code", @@ -50,7 +49,6 @@ "type": "string" } }, - "nullable": false, "required": [ "id", "mobile", diff --git a/test/schemas/json/v3_0/ObjectUndefined.json b/test/schemas/json/v3_0/ObjectUndefined.json index 355a6771d1..1d41a23dab 100644 --- a/test/schemas/json/v3_0/ObjectUndefined.json +++ b/test/schemas/json/v3_0/ObjectUndefined.json @@ -32,7 +32,6 @@ }, "unknown": {} }, - "nullable": false, "required": [ "name", "unknown" @@ -48,7 +47,6 @@ "type": "string" } }, - "nullable": false, "required": [ "id", "name" diff --git a/test/schemas/json/v3_0/ObjectUnionComposite.json b/test/schemas/json/v3_0/ObjectUnionComposite.json index d655346b8d..d2d721c958 100644 --- a/test/schemas/json/v3_0/ObjectUnionComposite.json +++ b/test/schemas/json/v3_0/ObjectUnionComposite.json @@ -43,7 +43,6 @@ "type": "number" } }, - "nullable": false, "required": [ "x", "y" @@ -59,7 +58,6 @@ "$ref": "#/components/schemas/ObjectUnionComposite.IPoint" } }, - "nullable": false, "required": [ "p1", "p2" @@ -78,7 +76,6 @@ "$ref": "#/components/schemas/ObjectUnionComposite.IPoint" } }, - "nullable": false, "required": [ "p1", "p2", @@ -101,7 +98,6 @@ "$ref": "#/components/schemas/ObjectUnionComposite.IPoint" } }, - "nullable": false, "required": [ "p1", "p2", @@ -119,7 +115,6 @@ } } }, - "nullable": false, "required": [ "points" ] @@ -137,7 +132,6 @@ "$ref": "#/components/schemas/ObjectUnionComposite.IPoint" } }, - "nullable": false, "required": [ "outer", "inner" @@ -156,7 +150,6 @@ } } }, - "nullable": false, "required": [ "outer", "inner" @@ -172,7 +165,6 @@ "type": "number" } }, - "nullable": false, "required": [ "centroid", "radius" diff --git a/test/schemas/json/v3_0/ObjectUnionCompositePointer.json b/test/schemas/json/v3_0/ObjectUnionCompositePointer.json index 8811ad7bc5..6f379402e8 100644 --- a/test/schemas/json/v3_0/ObjectUnionCompositePointer.json +++ b/test/schemas/json/v3_0/ObjectUnionCompositePointer.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -49,7 +48,6 @@ ] } }, - "nullable": false, "required": [ "value" ] @@ -64,7 +62,6 @@ "type": "number" } }, - "nullable": false, "required": [ "x", "y" @@ -80,7 +77,6 @@ "$ref": "#/components/schemas/ObjectUnionCompositePointer.IPoint" } }, - "nullable": false, "required": [ "p1", "p2" @@ -99,7 +95,6 @@ "$ref": "#/components/schemas/ObjectUnionCompositePointer.IPoint" } }, - "nullable": false, "required": [ "p1", "p2", @@ -122,7 +117,6 @@ "$ref": "#/components/schemas/ObjectUnionCompositePointer.IPoint" } }, - "nullable": false, "required": [ "p1", "p2", @@ -140,7 +134,6 @@ } } }, - "nullable": false, "required": [ "points" ] @@ -158,7 +151,6 @@ "$ref": "#/components/schemas/ObjectUnionCompositePointer.IPoint" } }, - "nullable": false, "required": [ "outer", "inner" @@ -177,7 +169,6 @@ } } }, - "nullable": false, "required": [ "outer", "inner" @@ -193,7 +184,6 @@ "type": "number" } }, - "nullable": false, "required": [ "centroid", "radius" diff --git a/test/schemas/json/v3_0/ObjectUnionDouble.json b/test/schemas/json/v3_0/ObjectUnionDouble.json index c0cd6fb6b7..a8aa49db33 100644 --- a/test/schemas/json/v3_0/ObjectUnionDouble.json +++ b/test/schemas/json/v3_0/ObjectUnionDouble.json @@ -28,7 +28,6 @@ "type": "number" } }, - "nullable": false, "required": [ "x" ] @@ -44,7 +43,6 @@ ] } }, - "nullable": false, "required": [ "value", "child" @@ -60,13 +58,11 @@ "type": "number" } }, - "nullable": false, "required": [ "y" ] } }, - "nullable": false, "required": [ "value" ] @@ -81,13 +77,11 @@ "type": "boolean" } }, - "nullable": false, "required": [ "y" ] } }, - "nullable": false, "required": [ "value" ] @@ -102,7 +96,6 @@ "type": "string" } }, - "nullable": false, "required": [ "x" ] @@ -118,7 +111,6 @@ ] } }, - "nullable": false, "required": [ "value", "child" @@ -137,13 +129,11 @@ } } }, - "nullable": false, "required": [ "y" ] } }, - "nullable": false, "required": [ "value" ] @@ -158,13 +148,11 @@ "type": "string" } }, - "nullable": false, "required": [ "y" ] } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/ObjectUnionExplicit.json b/test/schemas/json/v3_0/ObjectUnionExplicit.json index 6128cb88ec..35e6d98880 100644 --- a/test/schemas/json/v3_0/ObjectUnionExplicit.json +++ b/test/schemas/json/v3_0/ObjectUnionExplicit.json @@ -46,7 +46,6 @@ ] } }, - "nullable": false, "required": [ "x", "y", @@ -69,7 +68,6 @@ ] } }, - "nullable": false, "required": [ "p1", "p2", @@ -86,7 +84,6 @@ "type": "number" } }, - "nullable": false, "required": [ "x", "y" @@ -111,7 +108,6 @@ ] } }, - "nullable": false, "required": [ "p1", "p2", @@ -141,7 +137,6 @@ ] } }, - "nullable": false, "required": [ "p1", "p2", @@ -166,7 +161,6 @@ ] } }, - "nullable": false, "required": [ "points", "type" @@ -191,7 +185,6 @@ ] } }, - "nullable": false, "required": [ "outer", "inner", @@ -208,7 +201,6 @@ } } }, - "nullable": false, "required": [ "points" ] @@ -229,7 +221,6 @@ ] } }, - "nullable": false, "required": [ "centroid", "radius", diff --git a/test/schemas/json/v3_0/ObjectUnionExplicitPointer.json b/test/schemas/json/v3_0/ObjectUnionExplicitPointer.json index 757451b120..eccb71bf2b 100644 --- a/test/schemas/json/v3_0/ObjectUnionExplicitPointer.json +++ b/test/schemas/json/v3_0/ObjectUnionExplicitPointer.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -24,7 +23,6 @@ "$ref": "#/components/schemas/ObjectUnionExplicitPointer.Shape" } }, - "nullable": false, "required": [ "value" ] @@ -70,7 +68,6 @@ ] } }, - "nullable": false, "required": [ "x", "y", @@ -93,7 +90,6 @@ ] } }, - "nullable": false, "required": [ "p1", "p2", @@ -110,7 +106,6 @@ "type": "number" } }, - "nullable": false, "required": [ "x", "y" @@ -135,7 +130,6 @@ ] } }, - "nullable": false, "required": [ "p1", "p2", @@ -165,7 +159,6 @@ ] } }, - "nullable": false, "required": [ "p1", "p2", @@ -190,7 +183,6 @@ ] } }, - "nullable": false, "required": [ "points", "type" @@ -215,7 +207,6 @@ ] } }, - "nullable": false, "required": [ "outer", "inner", @@ -232,7 +223,6 @@ } } }, - "nullable": false, "required": [ "points" ] @@ -253,7 +243,6 @@ ] } }, - "nullable": false, "required": [ "centroid", "radius", diff --git a/test/schemas/json/v3_0/ObjectUnionImplicit.json b/test/schemas/json/v3_0/ObjectUnionImplicit.json index 490b1c6819..5dabda94a8 100644 --- a/test/schemas/json/v3_0/ObjectUnionImplicit.json +++ b/test/schemas/json/v3_0/ObjectUnionImplicit.json @@ -44,7 +44,6 @@ "nullable": true } }, - "nullable": false, "required": [ "x", "y" @@ -68,7 +67,6 @@ "nullable": true } }, - "nullable": false, "required": [ "p1", "p2" @@ -99,7 +97,6 @@ "nullable": true } }, - "nullable": false, "required": [ "p1", "p2", @@ -134,7 +131,6 @@ "nullable": true } }, - "nullable": false, "required": [ "p1", "p2", @@ -156,7 +152,6 @@ "nullable": true } }, - "nullable": false, "required": [ "points" ] @@ -178,7 +173,6 @@ "nullable": true } }, - "nullable": false, "required": [ "outer" ] @@ -197,7 +191,6 @@ "nullable": true } }, - "nullable": false, "required": [ "radius" ] diff --git a/test/schemas/json/v3_0/ObjectUnionNonPredictable.json b/test/schemas/json/v3_0/ObjectUnionNonPredictable.json index 5e5a72f837..7d7e14cdb9 100644 --- a/test/schemas/json/v3_0/ObjectUnionNonPredictable.json +++ b/test/schemas/json/v3_0/ObjectUnionNonPredictable.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -24,7 +23,6 @@ "$ref": "#/components/schemas/IPointerObjectUnionNonPredictable.IUnion" } }, - "nullable": false, "required": [ "value" ] @@ -36,7 +34,6 @@ "$ref": "#/components/schemas/ObjectUnionNonPredictable.IUnion" } }, - "nullable": false, "required": [ "value" ] @@ -61,7 +58,6 @@ "$ref": "#/components/schemas/IPointerboolean" } }, - "nullable": false, "required": [ "value" ] @@ -73,7 +69,6 @@ "type": "boolean" } }, - "nullable": false, "required": [ "value" ] @@ -85,7 +80,6 @@ "$ref": "#/components/schemas/IPointernumber" } }, - "nullable": false, "required": [ "value" ] @@ -97,7 +91,6 @@ "type": "number" } }, - "nullable": false, "required": [ "value" ] @@ -109,7 +102,6 @@ "$ref": "#/components/schemas/IPointerstring" } }, - "nullable": false, "required": [ "value" ] @@ -121,7 +113,6 @@ "type": "string" } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/TemplateAtomic.json b/test/schemas/json/v3_0/TemplateAtomic.json index 009b533ed5..c4fedafd36 100644 --- a/test/schemas/json/v3_0/TemplateAtomic.json +++ b/test/schemas/json/v3_0/TemplateAtomic.json @@ -41,7 +41,6 @@ "pattern": "((.*)@(.*)\\.(.*))" } }, - "nullable": false, "required": [ "prefix", "postfix", diff --git a/test/schemas/json/v3_0/TemplateConstant.json b/test/schemas/json/v3_0/TemplateConstant.json index c39a182eae..bec5214a61 100644 --- a/test/schemas/json/v3_0/TemplateConstant.json +++ b/test/schemas/json/v3_0/TemplateConstant.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -51,7 +50,6 @@ ] } }, - "nullable": false, "required": [ "prefix", "postfix", diff --git a/test/schemas/json/v3_0/TemplateUnion.json b/test/schemas/json/v3_0/TemplateUnion.json index b81d086e1d..da1732a848 100644 --- a/test/schemas/json/v3_0/TemplateUnion.json +++ b/test/schemas/json/v3_0/TemplateUnion.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -29,28 +28,18 @@ "pattern": "(((.*)_postfix)|([+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?_postfix))$" }, "middle": { - "oneOf": [ - { - "type": "string", - "pattern": "^(the_[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?_value)$" - }, - { - "type": "string", - "enum": [ - "the_false_value", - "the_true_value" - ] - } + "type": "string", + "pattern": "^(the_[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?_value)$", + "enum": [ + "the_false_value", + "the_true_value" ] }, "mixed": { "oneOf": [ { "type": "string", - "pattern": "^(the_[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?_value)$" - }, - { - "type": "string", + "pattern": "^(the_[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?_value)$", "enum": [ "the_A_value", "the_B_value" @@ -69,7 +58,6 @@ "type": "string" } }, - "nullable": false, "required": [ "name" ] @@ -77,7 +65,6 @@ ] } }, - "nullable": false, "required": [ "prefix", "postfix", diff --git a/test/schemas/json/v3_0/ToJsonArray.json b/test/schemas/json/v3_0/ToJsonArray.json index c9f4eac453..dd8fc0d1f1 100644 --- a/test/schemas/json/v3_0/ToJsonArray.json +++ b/test/schemas/json/v3_0/ToJsonArray.json @@ -42,7 +42,6 @@ "type": "string" } }, - "nullable": false, "required": [ "id" ] diff --git a/test/schemas/json/v3_0/ToJsonDouble.json b/test/schemas/json/v3_0/ToJsonDouble.json index 84edc2a757..142f474724 100644 --- a/test/schemas/json/v3_0/ToJsonDouble.json +++ b/test/schemas/json/v3_0/ToJsonDouble.json @@ -12,7 +12,6 @@ "type": "boolean" } }, - "nullable": false, "required": [ "id", "flag" diff --git a/test/schemas/json/v3_0/ToJsonNull.json b/test/schemas/json/v3_0/ToJsonNull.json index 5515ac3288..9d789510b0 100644 --- a/test/schemas/json/v3_0/ToJsonNull.json +++ b/test/schemas/json/v3_0/ToJsonNull.json @@ -1,6 +1,8 @@ { "version": "3.0", - "components": {}, + "components": { + "schemas": {} + }, "schemas": [ { "type": "null" diff --git a/test/schemas/json/v3_0/ToJsonTuple.json b/test/schemas/json/v3_0/ToJsonTuple.json index 6f07597526..d104b96366 100644 --- a/test/schemas/json/v3_0/ToJsonTuple.json +++ b/test/schemas/json/v3_0/ToJsonTuple.json @@ -36,7 +36,6 @@ "type": "string" } }, - "nullable": false, "required": [ "code", "name" diff --git a/test/schemas/json/v3_0/ToJsonUnion.json b/test/schemas/json/v3_0/ToJsonUnion.json index 762eb8857a..5ff59f680b 100644 --- a/test/schemas/json/v3_0/ToJsonUnion.json +++ b/test/schemas/json/v3_0/ToJsonUnion.json @@ -40,7 +40,6 @@ "type": "string" } }, - "nullable": false, "required": [ "id", "mobile", @@ -60,7 +59,6 @@ "type": "string" } }, - "nullable": false, "required": [ "manufacturer", "brand", diff --git a/test/schemas/json/v3_0/TupleHierarchical.json b/test/schemas/json/v3_0/TupleHierarchical.json index e0a75a157f..d201dbf747 100644 --- a/test/schemas/json/v3_0/TupleHierarchical.json +++ b/test/schemas/json/v3_0/TupleHierarchical.json @@ -7,20 +7,23 @@ "items": { "oneOf": [ { - "type": "boolean", - "nullable": true + "type": "boolean" }, { - "type": "number", - "nullable": true + "type": "null" + }, + { + "type": "number" }, { "type": "array", "items": { "oneOf": [ { - "type": "boolean", - "nullable": true + "type": "boolean" + }, + { + "type": "null" }, { "type": "array", @@ -47,14 +50,12 @@ ] }, "minItems": 2, - "maxItems": 2, - "nullable": true + "maxItems": 2 } ] }, "minItems": 3, - "maxItems": 3, - "nullable": true + "maxItems": 3 }, { "type": "array", @@ -81,6 +82,9 @@ "type": "array", "items": { "oneOf": [ + { + "type": "number" + }, { "type": "number" }, @@ -114,8 +118,7 @@ ] }, "minItems": 2, - "maxItems": 2, - "nullable": true + "maxItems": 2 } ] }, diff --git a/test/schemas/json/v3_0/TupleRestObject.json b/test/schemas/json/v3_0/TupleRestObject.json index 5abe0e4dbf..a368fae0dd 100644 --- a/test/schemas/json/v3_0/TupleRestObject.json +++ b/test/schemas/json/v3_0/TupleRestObject.json @@ -26,7 +26,6 @@ "type": "string" } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/TypeTagArray.json b/test/schemas/json/v3_0/TypeTagArray.json index 8286dea0b0..621ec5f1fa 100644 --- a/test/schemas/json/v3_0/TypeTagArray.json +++ b/test/schemas/json/v3_0/TypeTagArray.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -64,7 +63,6 @@ "uniqueItems": true } }, - "nullable": false, "required": [ "items", "minItems", diff --git a/test/schemas/json/v3_0/TypeTagArrayUnion.json b/test/schemas/json/v3_0/TypeTagArrayUnion.json index 385621f035..e1537c21dc 100644 --- a/test/schemas/json/v3_0/TypeTagArrayUnion.json +++ b/test/schemas/json/v3_0/TypeTagArrayUnion.json @@ -54,7 +54,6 @@ "maxItems": 7 } }, - "nullable": false, "required": [ "items", "minItems", diff --git a/test/schemas/json/v3_0/TypeTagAtomicUnion.json b/test/schemas/json/v3_0/TypeTagAtomicUnion.json index 82f726c307..6ba721a316 100644 --- a/test/schemas/json/v3_0/TypeTagAtomicUnion.json +++ b/test/schemas/json/v3_0/TypeTagAtomicUnion.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -34,7 +33,6 @@ ] } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/TypeTagCustom.json b/test/schemas/json/v3_0/TypeTagCustom.json index 5a9cea97c7..4cda4159a2 100644 --- a/test/schemas/json/v3_0/TypeTagCustom.json +++ b/test/schemas/json/v3_0/TypeTagCustom.json @@ -22,7 +22,6 @@ "x-typia-powerOf": 2 } }, - "nullable": false, "required": [ "id", "dollar", diff --git a/test/schemas/json/v3_0/TypeTagDefault.json b/test/schemas/json/v3_0/TypeTagDefault.json index f9ab216575..33f225bdc9 100644 --- a/test/schemas/json/v3_0/TypeTagDefault.json +++ b/test/schemas/json/v3_0/TypeTagDefault.json @@ -92,7 +92,6 @@ ] } }, - "nullable": false, "required": [ "boolean", "number", diff --git a/test/schemas/json/v3_0/TypeTagFormat.json b/test/schemas/json/v3_0/TypeTagFormat.json index 00d68362f8..b4e0281cbc 100644 --- a/test/schemas/json/v3_0/TypeTagFormat.json +++ b/test/schemas/json/v3_0/TypeTagFormat.json @@ -94,7 +94,6 @@ "format": "relative-json-pointer" } }, - "nullable": false, "required": [ "byte", "password", diff --git a/test/schemas/json/v3_0/TypeTagLength.json b/test/schemas/json/v3_0/TypeTagLength.json index 665520c074..a7972c2e53 100644 --- a/test/schemas/json/v3_0/TypeTagLength.json +++ b/test/schemas/json/v3_0/TypeTagLength.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -44,7 +43,6 @@ "maxLength": 19 } }, - "nullable": false, "required": [ "fixed", "minimum", diff --git a/test/schemas/json/v3_0/TypeTagMatrix.json b/test/schemas/json/v3_0/TypeTagMatrix.json index 288947d1ed..4a3dd07724 100644 --- a/test/schemas/json/v3_0/TypeTagMatrix.json +++ b/test/schemas/json/v3_0/TypeTagMatrix.json @@ -20,7 +20,6 @@ "maxItems": 3 } }, - "nullable": false, "required": [ "matrix" ] diff --git a/test/schemas/json/v3_0/TypeTagObjectUnion.json b/test/schemas/json/v3_0/TypeTagObjectUnion.json index ffe52f9d0f..d54d6af502 100644 --- a/test/schemas/json/v3_0/TypeTagObjectUnion.json +++ b/test/schemas/json/v3_0/TypeTagObjectUnion.json @@ -26,7 +26,6 @@ "minimum": 3 } }, - "nullable": false, "required": [ "value" ] @@ -40,7 +39,6 @@ "maxLength": 7 } }, - "nullable": false, "required": [ "value" ] diff --git a/test/schemas/json/v3_0/TypeTagPattern.json b/test/schemas/json/v3_0/TypeTagPattern.json index 56a6e2539e..cefb89eb51 100644 --- a/test/schemas/json/v3_0/TypeTagPattern.json +++ b/test/schemas/json/v3_0/TypeTagPattern.json @@ -22,7 +22,6 @@ "pattern": "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$" } }, - "nullable": false, "required": [ "uuid", "email", diff --git a/test/schemas/json/v3_0/TypeTagRange.json b/test/schemas/json/v3_0/TypeTagRange.json index 9888c8b0cb..579197033c 100644 --- a/test/schemas/json/v3_0/TypeTagRange.json +++ b/test/schemas/json/v3_0/TypeTagRange.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -68,7 +67,6 @@ "maximum": 10 } }, - "nullable": false, "required": [ "greater", "greater_equal", diff --git a/test/schemas/json/v3_0/TypeTagTuple.json b/test/schemas/json/v3_0/TypeTagTuple.json index 50ba180bb4..ff0e18a42c 100644 --- a/test/schemas/json/v3_0/TypeTagTuple.json +++ b/test/schemas/json/v3_0/TypeTagTuple.json @@ -45,7 +45,6 @@ "maxItems": 4 } }, - "nullable": false, "required": [ "tuple" ] diff --git a/test/schemas/json/v3_0/TypeTagType.json b/test/schemas/json/v3_0/TypeTagType.json index 9369e06e64..fa506d3b7a 100644 --- a/test/schemas/json/v3_0/TypeTagType.json +++ b/test/schemas/json/v3_0/TypeTagType.json @@ -12,7 +12,6 @@ } } }, - "nullable": false, "required": [ "value" ] @@ -42,7 +41,6 @@ "type": "number" } }, - "nullable": false, "required": [ "int", "uint", diff --git a/test/schemas/json/v3_0/UltimateUnion.json b/test/schemas/json/v3_0/UltimateUnion.json index cdccf515b2..4bbd4e41d5 100644 --- a/test/schemas/json/v3_0/UltimateUnion.json +++ b/test/schemas/json/v3_0/UltimateUnion.json @@ -31,7 +31,6 @@ "items": {} } }, - "nullable": false, "required": [ "version", "components", @@ -52,13 +51,11 @@ "description": "An object to hold reusable security schemes.\n\nIn other words, a collection of named security schemes." } }, - "nullable": false, "description": "Reusable components in OpenAPI.\n\nA storage of reusable components in OpenAPI document.\n\nIn other words, it is a storage of named DTO schemas and security schemes." }, "RecordstringOpenApi.IJsonSchema": { "type": "object", "properties": {}, - "nullable": false, "description": "Construct a type with a set of properties K of type T", "additionalProperties": { "$ref": "#/components/schemas/OpenApi.IJsonSchema" @@ -103,6 +100,7 @@ "$ref": "#/components/schemas/OpenApi.IJsonSchema.IUnknown" } ], + "title": "Type schema info", "description": "Type schema info.\n\n`OpenApi.IJsonSchema` is a type schema info of the OpenAPI.\n\n`OpenApi.IJsonSchema` basically follows the JSON schema definition of\nOpenAPI v3.1, but a little bit shrinked to remove ambiguous and duplicated\nexpressions of OpenAPI v3.1 for the convenience and clarity.\n\n- Decompose mixed type: {@link OpenApiV3_1.IJsonSchema.IMixed}\n- Resolve nullable property: {@link OpenApiV3_1.IJsonSchema.__ISignificant.nullable}\n- Array type utilizes only single {@link OpenAPI.IJsonSchema.IArray.items}\n- Tuple type utilizes only {@link OpenApi.IJsonSchema.ITuple.prefixItems}\n- Merge {@link OpenApiV3_1.IJsonSchema.IAnyOf} to {@link OpenApi.IJsonSchema.IOneOf}\n- Merge {@link OpenApiV3_1.IJsonSchema.IRecursiveReference} to {@link OpenApi.IJsonSchema.IReference}\n- Merge {@link OpenApiV3_1.IJsonSchema.IAllOf} to {@link OpenApi.IJsonSchema.IObject}" }, "OpenApi.IJsonSchema.IString": { @@ -171,7 +169,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "type" ], @@ -180,7 +177,6 @@ "Recordstringany": { "type": "object", "properties": {}, - "nullable": false, "description": "Construct a type with a set of properties K of type T", "additionalProperties": {} }, @@ -252,7 +248,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "type" ], @@ -301,7 +296,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "const" ], @@ -348,7 +342,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "type" ], @@ -422,7 +415,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "type" ], @@ -484,7 +476,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "items", "type" @@ -595,7 +586,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "prefixItems", "type" @@ -696,7 +686,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "type" ], @@ -735,7 +724,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "$ref" ], @@ -816,7 +804,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "oneOf" ], @@ -863,7 +850,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "required": [ "type" ], @@ -897,7 +883,6 @@ "description": "List of example values as key-value pairs." } }, - "nullable": false, "description": "Unknown, `any` type." }, "OpenApi.IJsonSchema.IOneOf.IDiscriminator": { @@ -914,7 +899,6 @@ "description": "Mapping of the discriminator value to the schema name.\n\nThis property is valid only for {@link IReference} typed\n{@link IOneOf.oneof} elements. Therefore, `key` of `mapping` is\nthe discriminator value, and `value` of `mapping` is the\nschema name like `#/components/schemas/SomeObject`." } }, - "nullable": false, "required": [ "propertyName" ], @@ -923,7 +907,6 @@ "Recordstringstring": { "type": "object", "properties": {}, - "nullable": false, "description": "Construct a type with a set of properties K of type T", "additionalProperties": { "type": "string" @@ -932,7 +915,6 @@ "RecordstringOpenApi.ISecurityScheme": { "type": "object", "properties": {}, - "nullable": false, "description": "Construct a type with a set of properties K of type T", "additionalProperties": { "$ref": "#/components/schemas/OpenApi.ISecurityScheme" @@ -956,6 +938,7 @@ "$ref": "#/components/schemas/OpenApi.ISecurityScheme.IOpenId" } ], + "title": "Security scheme of Swagger Documents", "description": "Security scheme of Swagger Documents.\n\n`OpenApi.ISecurityScheme` is a data structure representing content of\n`securitySchemes` in `swagger.json` file. It is composed with 5 types of\nsecurity schemes as an union type like below." }, "OpenApi.ISecurityScheme.IApiKey": { @@ -982,7 +965,6 @@ "type": "string" } }, - "nullable": false, "required": [ "type" ], @@ -1007,7 +989,6 @@ "type": "string" } }, - "nullable": false, "required": [ "type", "scheme" @@ -1036,7 +1017,6 @@ "type": "string" } }, - "nullable": false, "required": [ "type", "scheme" @@ -1059,7 +1039,6 @@ "type": "string" } }, - "nullable": false, "required": [ "type", "flows" @@ -1081,8 +1060,7 @@ "clientCredentials": { "$ref": "#/components/schemas/OmitOpenApi.ISecurityScheme.IOAuth2.IFlowauthorizationUrl" } - }, - "nullable": false + } }, "OpenApi.ISecurityScheme.IOAuth2.IFlow": { "type": "object", @@ -1099,8 +1077,7 @@ "scopes": { "$ref": "#/components/schemas/Recordstringstring" } - }, - "nullable": false + } }, "OmitOpenApi.ISecurityScheme.IOAuth2.IFlowtokenUrl": { "type": "object", @@ -1115,7 +1092,6 @@ "$ref": "#/components/schemas/Recordstringstring" } }, - "nullable": false, "description": "Construct a type with the properties of T except for those in type K." }, "OmitOpenApi.ISecurityScheme.IOAuth2.IFlowauthorizationUrl": { @@ -1131,7 +1107,6 @@ "$ref": "#/components/schemas/Recordstringstring" } }, - "nullable": false, "description": "Construct a type with the properties of T except for those in type K." }, "OpenApi.ISecurityScheme.IOpenId": { @@ -1150,7 +1125,6 @@ "type": "string" } }, - "nullable": false, "required": [ "type", "openIdConnectUrl" diff --git a/test/schemas/json/v3_1/ConstantAtomicUnion.json b/test/schemas/json/v3_1/ConstantAtomicUnion.json index 841e9178e1..ae03f0f4b3 100644 --- a/test/schemas/json/v3_1/ConstantAtomicUnion.json +++ b/test/schemas/json/v3_1/ConstantAtomicUnion.json @@ -20,10 +20,10 @@ "const": 2 }, { - "const": "three" + "const": "four" }, { - "const": "four" + "const": "three" }, { "type": "object", diff --git a/test/schemas/llm/type/ConstantAtomicUnion.json b/test/schemas/llm/type/ConstantAtomicUnion.json index 329cfc5c67..b266786713 100644 --- a/test/schemas/llm/type/ConstantAtomicUnion.json +++ b/test/schemas/llm/type/ConstantAtomicUnion.json @@ -18,8 +18,8 @@ { "type": "string", "enum": [ - "three", - "four" + "four", + "three" ] }, { diff --git a/test/schemas/reflect/metadata/ConstantAtomicUnion.json b/test/schemas/reflect/metadata/ConstantAtomicUnion.json index a260df660c..af83af3395 100644 --- a/test/schemas/reflect/metadata/ConstantAtomicUnion.json +++ b/test/schemas/reflect/metadata/ConstantAtomicUnion.json @@ -139,11 +139,11 @@ "type": "string", "values": [ { - "value": "three", + "value": "four", "tags": [] }, { - "value": "four", + "value": "three", "tags": [] } ] diff --git a/test/schemas/reflect/metadata/ObjectHttpNullable.json b/test/schemas/reflect/metadata/ObjectHttpNullable.json index e130e34592..fea21d0ed4 100644 --- a/test/schemas/reflect/metadata/ObjectHttpNullable.json +++ b/test/schemas/reflect/metadata/ObjectHttpNullable.json @@ -523,11 +523,11 @@ "tags": [] }, { - "value": "three", + "value": "two", "tags": [] }, { - "value": "two", + "value": "three", "tags": [] } ] diff --git a/test/schemas/reflect/metadata/ObjectHttpUndefindable.json b/test/schemas/reflect/metadata/ObjectHttpUndefindable.json index d141306464..57f8114422 100644 --- a/test/schemas/reflect/metadata/ObjectHttpUndefindable.json +++ b/test/schemas/reflect/metadata/ObjectHttpUndefindable.json @@ -506,11 +506,11 @@ "tags": [] }, { - "value": "three", + "value": "two", "tags": [] }, { - "value": "two", + "value": "three", "tags": [] } ] diff --git a/test/src/debug/schema.ts b/test/src/debug/schema.ts new file mode 100644 index 0000000000..577042e3da --- /dev/null +++ b/test/src/debug/schema.ts @@ -0,0 +1,19 @@ +import typia, { tags } from "typia"; + +interface Something { + pure: `${number}/${number}` | `${string}-${string}`; + sole: `${number}/${number}` & tags.JsonSchemaPlugin<{ "x-typia-sole": true }>; + union: + | (`${number}/${number}` & + tags.JsonSchemaPlugin<{ "x-typia-something": true }>) + | (`${string}-${string}` & + tags.JsonSchemaPlugin<{ "x-typia-nothing": false }>); + mixed: + | `${number}/${number}` + | `${string}-${string}` + | (`${string}||${number}` & + tags.JsonSchemaPlugin<{ "x-typia-something": true }>); +} + +const collection = typia.json.schemas<[Something]>(); +console.log(JSON.stringify(collection, null, 2)); diff --git a/test/src/features/issues/test_issue_1112_template_literal_with_type_tag.ts b/test/src/features/issues/test_issue_1112_template_literal_with_type_tag.ts index e3baf3e9e8..ae3d122736 100644 --- a/test/src/features/issues/test_issue_1112_template_literal_with_type_tag.ts +++ b/test/src/features/issues/test_issue_1112_template_literal_with_type_tag.ts @@ -17,30 +17,24 @@ const validate = (collection: IJsonSchemaCollection<"3.0" | "3.1">) => { "^(([+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?\\/[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)|((.*)\\x2d(.*)))", }, sole: { - "0": { - type: "string", - pattern: - "([+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?\\/[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)", - "x-typia-sole": true, - }, + type: "string", + pattern: + "([+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?\\/[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)", + "x-typia-sole": true, }, union: { oneOf: [ - [ - { - type: "string", - pattern: - "([+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?\\/[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)", - "x-typia-something": true, - }, - ], - [ - { - type: "string", - pattern: "((.*)\\x2d(.*))", - "x-typia-nothing": false, - }, - ], + { + type: "string", + pattern: + "([+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?\\/[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)", + "x-typia-something": true, + }, + { + type: "string", + pattern: "((.*)\\x2d(.*))", + "x-typia-nothing": false, + }, ], }, mixed: { @@ -50,13 +44,11 @@ const validate = (collection: IJsonSchemaCollection<"3.0" | "3.1">) => { pattern: "^(([+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?\\/[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)|((.*)\\x2d(.*)))", }, - [ - { - type: "string", - pattern: "((.*)\\|\\|[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)", - "x-typia-something": true, - }, - ], + { + type: "string", + pattern: "((.*)\\|\\|[+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)", + "x-typia-something": true, + }, ], }, })(properties); diff --git a/test/src/features/issues/test_pr_1217_bigint_json_schema.ts b/test/src/features/issues/test_pr_1217_bigint_json_schema.ts index d2fc052cf0..dc67f911cf 100644 --- a/test/src/features/issues/test_pr_1217_bigint_json_schema.ts +++ b/test/src/features/issues/test_pr_1217_bigint_json_schema.ts @@ -14,9 +14,10 @@ export const test_pr_1217_bigint_json_schema = (): void => { ] >(); const app: MetadataApplication = MetadataApplication.from(raw); - const json: IJsonSchemaCollection = JsonSchemasProgrammer.write("3.1")( - app.metadatas, - ) as IJsonSchemaCollection; + const json: IJsonSchemaCollection = JsonSchemasProgrammer.write({ + version: "3.1", + metadatas: app.metadatas, + }); TestValidator.equals("bigint")(json.schemas)([ { type: "integer",