mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-26 10:33:44 +03:00
feat: Add support for minLength and maxLength constraint humanization (#700)
According to #42 , `minItems` and `maxItems` are not yet rendered in the documentation. This pull request shows the humazined form of `minItems` and `maxItems` next to the type description. The [suggestion of fgabolde](https://github.com/Rebilly/ReDoc/issues/42#issuecomment-371883853) is followed and "characters" is simply replaced with "items". ![image](https://user-images.githubusercontent.com/1814807/47999845-0a13f900-e104-11e8-9ddc-adab701ec0bb.png) Some examples are added to the demo.
This commit is contained in:
parent
b5f32247be
commit
f40568b79e
|
@ -296,6 +296,8 @@ paths:
|
||||||
style: form
|
style: form
|
||||||
schema:
|
schema:
|
||||||
type: array
|
type: array
|
||||||
|
minItems: 1
|
||||||
|
maxItems: 3
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
|
@ -784,6 +786,7 @@ components:
|
||||||
photoUrls:
|
photoUrls:
|
||||||
description: The list of URL to a cute photos featuring pet
|
description: The list of URL to a cute photos featuring pet
|
||||||
type: array
|
type: array
|
||||||
|
maxItems: 20
|
||||||
xml:
|
xml:
|
||||||
name: photoUrl
|
name: photoUrl
|
||||||
wrapped: true
|
wrapped: true
|
||||||
|
@ -796,6 +799,7 @@ components:
|
||||||
tags:
|
tags:
|
||||||
description: Tags attached to the pet
|
description: Tags attached to the pet
|
||||||
type: array
|
type: array
|
||||||
|
minItems: 1
|
||||||
xml:
|
xml:
|
||||||
name: tag
|
name: tag
|
||||||
wrapped: true
|
wrapped: true
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {
|
||||||
detectType,
|
detectType,
|
||||||
getOperationSummary,
|
getOperationSummary,
|
||||||
getStatusCodeType,
|
getStatusCodeType,
|
||||||
|
humanizeConstraints,
|
||||||
isOperationName,
|
isOperationName,
|
||||||
isPrimitiveType,
|
isPrimitiveType,
|
||||||
mergeParams,
|
mergeParams,
|
||||||
|
@ -321,4 +322,35 @@ describe('Utils', () => {
|
||||||
expect(servers[2].url).toEqual('http://127.0.0.3');
|
expect(servers[2].url).toEqual('http://127.0.0.3');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('openapi humanizeConstraints', () => {
|
||||||
|
const itemConstraintSchema = (
|
||||||
|
min: number | undefined = undefined,
|
||||||
|
max: number | undefined = undefined,
|
||||||
|
) => ({ type: 'array', minItems: min, maxItems: max });
|
||||||
|
|
||||||
|
it('should not have a humanized constraint without schema constraints', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema())).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a humanized constraint when minItems is set', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema(2))).toContain('>= 2 items');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a humanized constraint when maxItems is set', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema(undefined, 8))).toContain('<= 8 items');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a humanized constraint when minItems and maxItems are both set', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema(2, 8))).toContain('[ 2 .. 8 ] items');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a humanized constraint when minItems and maxItems are the same', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema(7, 7))).toContain('7 items');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a humazined constraint when justMinItems is set, and it is equal to 1', () => {
|
||||||
|
expect(humanizeConstraints(itemConstraintSchema(1))).toContain('non-empty');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -141,29 +141,44 @@ export function isNamedDefinition(pointer?: string): boolean {
|
||||||
return /^#\/components\/schemas\/[^\/]+$/.test(pointer || '');
|
return /^#\/components\/schemas\/[^\/]+$/.test(pointer || '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function humanizeRangeConstraint(
|
||||||
|
description: string,
|
||||||
|
min: number | undefined,
|
||||||
|
max: number | undefined,
|
||||||
|
): string | undefined {
|
||||||
|
let stringRange;
|
||||||
|
if (min !== undefined && max !== undefined) {
|
||||||
|
if (min === max) {
|
||||||
|
stringRange = `${min} ${description}`;
|
||||||
|
} else {
|
||||||
|
stringRange = `[ ${min} .. ${max} ] ${description}`;
|
||||||
|
}
|
||||||
|
} else if (max !== undefined) {
|
||||||
|
stringRange = `<= ${max} ${description}`;
|
||||||
|
} else if (min !== undefined) {
|
||||||
|
if (min === 1) {
|
||||||
|
stringRange = 'non-empty';
|
||||||
|
} else {
|
||||||
|
stringRange = `>= ${min} ${description}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringRange;
|
||||||
|
}
|
||||||
|
|
||||||
export function humanizeConstraints(schema: OpenAPISchema): string[] {
|
export function humanizeConstraints(schema: OpenAPISchema): string[] {
|
||||||
const res: string[] = [];
|
const res: string[] = [];
|
||||||
|
|
||||||
let stringRange;
|
const stringRange = humanizeRangeConstraint('characters', schema.minLength, schema.maxLength);
|
||||||
if (schema.minLength !== undefined && schema.maxLength !== undefined) {
|
|
||||||
if (schema.minLength === schema.maxLength) {
|
|
||||||
stringRange = `${schema.minLength} characters`;
|
|
||||||
} else {
|
|
||||||
stringRange = `[ ${schema.minLength} .. ${schema.maxLength} ] characters`;
|
|
||||||
}
|
|
||||||
} else if (schema.maxLength !== undefined) {
|
|
||||||
stringRange = `<= ${schema.maxLength} characters`;
|
|
||||||
} else if (schema.minLength !== undefined) {
|
|
||||||
if (schema.minLength === 1) {
|
|
||||||
stringRange = 'non-empty';
|
|
||||||
} else {
|
|
||||||
stringRange = `>= ${schema.minLength} characters`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (stringRange !== undefined) {
|
if (stringRange !== undefined) {
|
||||||
res.push(stringRange);
|
res.push(stringRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const arrayRange = humanizeRangeConstraint('items', schema.minItems, schema.maxItems);
|
||||||
|
if (arrayRange !== undefined) {
|
||||||
|
res.push(arrayRange);
|
||||||
|
}
|
||||||
|
|
||||||
let numberRange;
|
let numberRange;
|
||||||
if (schema.minimum !== undefined && schema.maximum !== undefined) {
|
if (schema.minimum !== undefined && schema.maximum !== undefined) {
|
||||||
numberRange = schema.exclusiveMinimum ? '( ' : '[ ';
|
numberRange = schema.exclusiveMinimum ? '( ' : '[ ';
|
||||||
|
|
Loading…
Reference in New Issue
Block a user