@samchon/openapi
Version:
OpenAPI definitions and converters for 'typia' and 'nestia'.
197 lines (196 loc) • 7.26 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeminiTypeChecker = void 0;
/**
* Type checker for Gemini type schema.
*
* `GeminiTypeChecker` is a type checker of {@link IGeminiSchema}.
*
* @author Samchon
*/
var GeminiTypeChecker;
(function (GeminiTypeChecker) {
/* -----------------------------------------------------------
OPERATORS
----------------------------------------------------------- */
/**
* Visit every nested schemas.
*
* Visit every nested schemas of the target, and apply the `props.closure` function.
*
* Here is the list of occurring nested visitings:
*
* - {@link IGeminiSchema.IObject.properties}
* - {@link IGeminiSchema.IArray.items}
*
* @param props Properties for visiting
*/
GeminiTypeChecker.visit = (props) => {
var _a, _b;
const accessor = (_a = props.accessor) !== null && _a !== void 0 ? _a : "$input.schema";
props.closure(props.schema, accessor);
if (GeminiTypeChecker.isObject(props.schema))
Object.entries((_b = props.schema.properties) !== null && _b !== void 0 ? _b : {}).forEach(([key, value]) => GeminiTypeChecker.visit({
closure: props.closure,
schema: value,
accessor: `${accessor}.properties[${JSON.stringify(key)}]`,
}));
else if (GeminiTypeChecker.isArray(props.schema))
GeminiTypeChecker.visit({
closure: props.closure,
schema: props.schema.items,
accessor: `${accessor}.items`,
});
};
/**
* Test whether the `x` schema covers the `y` schema.
*
* @param props Properties for testing
* @returns Whether the `x` schema covers the `y` schema
*/
GeminiTypeChecker.covers = (x, y) => {
// CHECK EQUALITY
if (x === y)
return true;
else if (GeminiTypeChecker.isUnknown(x))
return true;
else if (GeminiTypeChecker.isUnknown(y))
return false;
else if (GeminiTypeChecker.isNullOnly(x))
return GeminiTypeChecker.isNullOnly(y);
else if (GeminiTypeChecker.isNullOnly(y))
return x.nullable === true;
else if (x.nullable === true && !!y.nullable === false)
return false;
// ATOMIC CASE
else if (GeminiTypeChecker.isBoolean(x))
return GeminiTypeChecker.isBoolean(y) && coverBoolean(x, y);
else if (GeminiTypeChecker.isInteger(x))
return GeminiTypeChecker.isInteger(y) && coverInteger(x, y);
else if (GeminiTypeChecker.isNumber(x))
return (GeminiTypeChecker.isNumber(y) || GeminiTypeChecker.isInteger(y)) && coverNumber(x, y);
else if (GeminiTypeChecker.isString(x))
return GeminiTypeChecker.isString(y) && covertString(x, y);
// INSTANCE CASE
else if (GeminiTypeChecker.isArray(x))
return GeminiTypeChecker.isArray(y) && coverArray(x, y);
else if (GeminiTypeChecker.isObject(x))
return GeminiTypeChecker.isObject(y) && coverObject(x, y);
return false;
};
/**
* @internal
*/
const coverBoolean = (x, y) => x.enum === undefined ||
(y.enum !== undefined && x.enum.every((v) => y.enum.includes(v)));
/**
* @internal
*/
const coverInteger = (x, y) => {
if (x.enum !== undefined)
return y.enum !== undefined && x.enum.every((v) => y.enum.includes(v));
return x.type === y.type;
};
/**
* @internal
*/
const coverNumber = (x, y) => {
if (x.enum !== undefined)
return y.enum !== undefined && x.enum.every((v) => y.enum.includes(v));
return x.type === y.type;
};
/**
* @internal
*/
const covertString = (x, y) => {
if (x.enum !== undefined)
return y.enum !== undefined && x.enum.every((v) => y.enum.includes(v));
return x.type === y.type;
};
/**
* @internal
*/
const coverArray = (x, y) => GeminiTypeChecker.covers(x.items, y.items);
/**
* @internal
*/
const coverObject = (x, y) => {
var _a;
return Object.entries((_a = y.properties) !== null && _a !== void 0 ? _a : {}).every(([key, b]) => {
var _a, _b, _c, _d, _e;
const a = (_a = x.properties) === null || _a === void 0 ? void 0 : _a[key];
if (a === undefined)
return false;
else if (((_c = (_b = x.required) === null || _b === void 0 ? void 0 : _b.includes(key)) !== null && _c !== void 0 ? _c : false) === true &&
((_e = (_d = y.required) === null || _d === void 0 ? void 0 : _d.includes(key)) !== null && _e !== void 0 ? _e : false) === false)
return false;
return GeminiTypeChecker.covers(a, b);
});
};
/* -----------------------------------------------------------
TYPE CHECKERS
----------------------------------------------------------- */
/**
* Test whether the schema is a boolean type.
*
* @param schema Target schema
* @returns Whether boolean type or not
*/
GeminiTypeChecker.isBoolean = (schema) => schema.type === "boolean";
/**
* Test whether the schema is an integer type.
*
* @param schema Target schema
* @returns Whether integer type or not
*/
GeminiTypeChecker.isInteger = (schema) => schema.type === "integer";
/**
* Test whether the schema is a number type.
*
* @param schema Target schema
* @returns Whether number type or not
*/
GeminiTypeChecker.isNumber = (schema) => schema.type === "number";
/**
* Test whether the schema is a string type.
*
* @param schema Target schema
* @returns Whether string type or not
*/
GeminiTypeChecker.isString = (schema) => schema.type === "string";
/**
* Test whether the schema is an array type.
*
* @param schema Target schema
* @returns Whether array type or not
*/
GeminiTypeChecker.isArray = (schema) => schema.type === "array";
/**
* Test whether the schema is an object type.
*
* @param schema Target schema
* @returns Whether object type or not
*/
GeminiTypeChecker.isObject = (schema) => schema.type === "object";
/**
* Test whether the schema is a null type.
*
* @param schema Target schema
* @returns Whether null type or not
*/
GeminiTypeChecker.isNullOnly = (schema) => schema.type === "null";
/**
* Test whether the schema is a nullable type.
*
* @param schema Target schema
* @returns Whether nullable type or not
*/
GeminiTypeChecker.isNullable = (schema) => !GeminiTypeChecker.isUnknown(schema) && (GeminiTypeChecker.isNullOnly(schema) || schema.nullable === true);
/**
* Test whether the schema is an unknown type.
*
* @param schema Target schema
* @returns Whether unknown type or not
*/
GeminiTypeChecker.isUnknown = (schema) => schema.type === undefined;
})(GeminiTypeChecker || (exports.GeminiTypeChecker = GeminiTypeChecker = {}));
;