Skip to content

Commit

Permalink
Merge pull request #40 from samchon/feature/enum-null
Browse files Browse the repository at this point in the history
Allow `null` value on `enum` properties.
  • Loading branch information
samchon authored Aug 20, 2024
2 parents 970c8c0 + 0dde015 commit a8414d1
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 29 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@samchon/openapi",
"version": "0.4.5",
"version": "0.4.6",
"description": "OpenAPI definitions and converters for 'typia' and 'nestia'.",
"main": "./lib/index.js",
"module": "./lib/index.mjs",
Expand Down
8 changes: 4 additions & 4 deletions src/OpenApiV3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,11 @@ export namespace OpenApiV3 {
export namespace IJsonSchema {
export interface IBoolean extends __ISignificant<"boolean"> {
default?: boolean | null;
enum?: boolean[];
enum?: Array<boolean | null>;
}
export interface IInteger extends __ISignificant<"integer"> {
/** @type int64 */ default?: number | null;
/** @type int64 */ enum?: number[];
/** @type int64 */ enum?: Array<number | null>;
/** @type int64 */ minimum?: number;
/** @type int64 */ maximum?: number;
exclusiveMinimum?: boolean;
Expand All @@ -199,7 +199,7 @@ export namespace OpenApiV3 {
}
export interface INumber extends __ISignificant<"number"> {
default?: number | null;
enum?: number[];
enum?: Array<number | null>;
minimum?: number;
maximum?: number;
exclusiveMinimum?: boolean;
Expand All @@ -208,7 +208,7 @@ export namespace OpenApiV3 {
}
export interface IString extends __ISignificant<"string"> {
default?: string | null;
enum?: string[];
enum?: Array<string | null>;
format?:
| "binary"
| "byte"
Expand Down
8 changes: 4 additions & 4 deletions src/OpenApiV3_1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,11 @@ export namespace OpenApiV3_1 {
}
export interface IBoolean extends __ISignificant<"boolean"> {
default?: boolean | null;
enum?: boolean[];
enum?: Array<boolean | null>;
}
export interface IInteger extends __ISignificant<"integer"> {
/** @type int64 */ default?: number | null;
/** @type int64 */ enum?: number[];
/** @type int64 */ enum?: Array<number | null>;
/** @type int64 */ minimum?: number;
/** @type int64 */ maximum?: number;
/** @type int64 */ exclusiveMinimum?: number | boolean;
Expand All @@ -234,7 +234,7 @@ export namespace OpenApiV3_1 {
}
export interface INumber extends __ISignificant<"number"> {
default?: number | null;
enum?: number[];
enum?: Array<number | null>;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number | boolean;
Expand All @@ -244,7 +244,7 @@ export namespace OpenApiV3_1 {
export interface IString extends __ISignificant<"string"> {
contentMediaType?: string;
default?: string | null;
enum?: string[];
enum?: Array<string | null>;
format?:
| "binary"
| "byte"
Expand Down
8 changes: 4 additions & 4 deletions src/SwaggerV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,11 @@ export namespace SwaggerV2 {
export namespace IJsonSchema {
export interface IBoolean extends __ISignificant<"boolean"> {
default?: boolean | null;
enum?: boolean[];
enum?: Array<boolean | null>;
}
export interface IInteger extends __ISignificant<"integer"> {
/** @type int64 */ default?: number | null;
/** @type int64 */ enum?: number[];
/** @type int64 */ enum?: Array<number | null>;
/** @type int64 */ minimum?: number;
/** @type int64 */ maximum?: number;
exclusiveMinimum?: boolean;
Expand All @@ -149,7 +149,7 @@ export namespace SwaggerV2 {
}
export interface INumber extends __ISignificant<"number"> {
default?: number | null;
enum?: number[];
enum?: Array<number | null>;
minimum?: number;
maximum?: number;
exclusiveMinimum?: boolean;
Expand All @@ -158,7 +158,7 @@ export namespace SwaggerV2 {
}
export interface IString extends __ISignificant<"string"> {
default?: string | null;
enum?: string[];
enum?: Array<string | null>;
format?:
| "binary"
| "byte"
Expand Down
19 changes: 17 additions & 2 deletions src/internal/OpenApiV3Converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,14 @@ export namespace OpenApiV3Converter {
if ((schema as OpenApiV3.IJsonSchema.INumber).default === null)
nullable.default = null;
}
if (
Array.isArray((schema as OpenApiV3.IJsonSchema.INumber).enum) &&
(schema as OpenApiV3.IJsonSchema.INumber).enum?.length &&
(schema as OpenApiV3.IJsonSchema.INumber).enum?.some(
(e) => e === null,
)
)
nullable.value ||= true;
// UNION TYPE CASE
if (TypeChecker.isAnyOf(schema)) schema.anyOf.forEach(visit);
else if (TypeChecker.isOneOf(schema)) schema.oneOf.forEach(visit);
Expand All @@ -280,8 +288,15 @@ export namespace OpenApiV3Converter {
TypeChecker.isNumber(schema) ||
TypeChecker.isString(schema)
)
if (schema.enum?.length)
union.push(...schema.enum.map((value) => ({ const: value })));
if (
schema.enum?.length &&
schema.enum.filter((e) => e !== null).length
)
union.push(
...schema.enum
.filter((v) => v !== null)
.map((value) => ({ const: value })),
);
else
union.push({
...schema,
Expand Down
46 changes: 34 additions & 12 deletions src/internal/OpenApiV3_1Converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,15 @@ export namespace OpenApiV3_1Converter {
if ((schema as OpenApiV3_1.IJsonSchema.INumber).default === null)
nullable.default = null;
}
if (
Array.isArray((schema as OpenApiV3_1.IJsonSchema.INumber).enum) &&
(schema as OpenApiV3_1.IJsonSchema.INumber).enum?.length &&
(schema as OpenApiV3_1.IJsonSchema.INumber).enum?.some(
(e) => e === null,
)
)
nullable.value ||= true;

// MIXED TYPE CASE
if (TypeChecker.isMixed(schema)) {
if (schema.const !== undefined)
Expand Down Expand Up @@ -345,19 +354,26 @@ export namespace OpenApiV3_1Converter {
visit({
...schema,
...{
enum: schema.enum?.length
? schema.enum.filter((x) => typeof x === type)
: undefined,
enum:
schema.enum?.length && schema.enum.filter((e) => e !== null)
? schema.enum.filter((x) => typeof x === type)
: undefined,
},
type: type as any,
});
else if (type === "integer")
visit({
...schema,
...{
enum: schema.enum?.length
? schema.enum.filter((x) => Number.isInteger(x))
: undefined,
enum:
schema.enum?.length && schema.enum.filter((e) => e !== null)
? schema.enum.filter(
(x) =>
x !== null &&
typeof x === "number" &&
Number.isInteger(x),
)
: undefined,
},
type: type as any,
});
Expand All @@ -370,8 +386,11 @@ export namespace OpenApiV3_1Converter {
union.push(convertAllOfSchema(components)(schema));
// ATOMIC TYPE CASE (CONSIDER ENUM VALUES)
else if (TypeChecker.isBoolean(schema))
if (schema.enum?.length)
for (const value of schema.enum)
if (
schema.enum?.length &&
schema.enum.filter((e) => e !== null).length
)
for (const value of schema.enum.filter((e) => e !== null))
union.push({
const: value,
...({
Expand All @@ -390,8 +409,8 @@ export namespace OpenApiV3_1Converter {
},
});
else if (TypeChecker.isInteger(schema) || TypeChecker.isNumber(schema))
if (schema.enum?.length)
for (const value of schema.enum)
if (schema.enum?.length && schema.enum.filter((e) => e !== null))
for (const value of schema.enum.filter((e) => e !== null))
union.push({
const: value,
...({
Expand Down Expand Up @@ -431,8 +450,11 @@ export namespace OpenApiV3_1Converter {
}),
});
else if (TypeChecker.isString(schema))
if (schema.enum?.length)
for (const value of schema.enum)
if (
schema.enum?.length &&
schema.enum.filter((e) => e !== null).length
)
for (const value of schema.enum.filter((e) => e !== null))
union.push({
const: value,
...({
Expand Down
14 changes: 12 additions & 2 deletions src/internal/SwaggerV2Converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ export namespace SwaggerV2Converter {
if ((schema as SwaggerV2.IJsonSchema.INumber).default === null)
nullable.default = null;
}
if (
Array.isArray((schema as SwaggerV2.IJsonSchema.INumber).enum) &&
(schema as SwaggerV2.IJsonSchema.INumber).enum?.length &&
(schema as SwaggerV2.IJsonSchema.INumber).enum?.some((e) => e === null)
)
nullable.value ||= true;
// UNION TYPE CASE
if (TypeChecker.isAnyOf(schema)) schema["x-anyOf"].forEach(visit);
else if (TypeChecker.isOneOf(schema)) schema["x-oneOf"].forEach(visit);
Expand All @@ -286,8 +292,12 @@ export namespace SwaggerV2Converter {
TypeChecker.isNumber(schema) ||
TypeChecker.isString(schema)
)
if (schema.enum?.length)
union.push(...schema.enum.map((value) => ({ const: value })));
if (schema.enum?.length && schema.enum.filter((e) => e !== null).length)
union.push(
...schema.enum
.filter((v) => v !== null)
.map((value) => ({ const: value })),
);
else
union.push({
...schema,
Expand Down

0 comments on commit a8414d1

Please sign in to comment.