diff --git a/src/utils/__tests__/getValidations.spec.ts b/src/utils/__tests__/getValidations.spec.ts index a8acf845..ecf373fb 100644 --- a/src/utils/__tests__/getValidations.spec.ts +++ b/src/utils/__tests__/getValidations.spec.ts @@ -18,6 +18,40 @@ describe('getValidations util', () => { }); }); + describe('when oas format is specified', () => { + test('given default range, should not ignore both minimum and maximum values', () => { + expect( + getValidations({ + type: 'integer', + format: 'int64', + minimum: 0 - Math.pow(2, 63), + maximum: Math.pow(2, 63) - 1, + }), + ).toStrictEqual({ format: 'int64' }); + }); + + test('given customized range, should include changed values', () => { + expect( + getValidations({ type: 'integer', format: 'int32', minimum: 20, maximum: Math.pow(2, 31) - 1 }), + ).toStrictEqual({ + format: 'int32', + minimum: 20, + }); + + expect( + getValidations({ + type: 'number', + format: 'float', + minimum: 0 - Math.pow(2, 128), + maximum: Math.pow(2, 16) - 1, + }), + ).toStrictEqual({ + format: 'float', + maximum: Math.pow(2, 16) - 1, + }); + }); + }); + test('should support integer type', () => { expect( getValidations({ diff --git a/src/utils/getValidations.ts b/src/utils/getValidations.ts index 1854c636..4f3c4c41 100644 --- a/src/utils/getValidations.ts +++ b/src/utils/getValidations.ts @@ -25,6 +25,44 @@ const VALIDATION_TYPES = { array: ['additionalItems', 'minItems', 'maxItems', 'uniqueItems'], }; +const OAS_FORMATS = { + int32: { + minimum: 0 - Math.pow(2, 31), + maximum: Math.pow(2, 31) - 1, + }, + int64: { + minimum: 0 - Math.pow(2, 63), + maximum: Math.pow(2, 63) - 1, + }, + float: { + minimum: 0 - Math.pow(2, 128), + maximum: Math.pow(2, 128) - 1, + }, + double: { + minimum: 0 - Number.MAX_VALUE, + maximum: Number.MAX_VALUE, + }, + byte: { + pattern: '^[\\w\\d+\\/=]*$', + }, +}; + +function filterOutFormatValidations(values: Dictionary) { + const { format } = values; + + if (typeof format !== 'string' || !(format in OAS_FORMATS)) return values; + + const newValues = { ...values }; + + for (const [key, value] of Object.entries(OAS_FORMATS[format])) { + if (value === newValues[key]) { + delete newValues[key]; + } + } + + return newValues; +} + function getDeprecatedValue(node: JSONSchema4): Optional { if ('x-deprecated' in node) { return !!node['x-deprecated']; @@ -48,9 +86,9 @@ function getTypeValidations(type: JSONSchema4TypeName | JSONSchema4TypeName[]): export const getValidations = (node: JSONSchema4): Dictionary => { const extraValidations = node.type && getTypeValidations(node.type); const deprecated = getDeprecatedValue(node); - return { + return filterOutFormatValidations({ ..._pick(node, COMMON_VALIDATION_TYPES), ...(extraValidations && _pick(node, extraValidations)), ...(deprecated !== void 0 && { deprecated }), - }; + }); };