diff --git a/.changeset/lovely-mice-slide.md b/.changeset/lovely-mice-slide.md new file mode 100644 index 0000000000..a7c62de4a7 --- /dev/null +++ b/.changeset/lovely-mice-slide.md @@ -0,0 +1,5 @@ +--- +"@redocly/openapi-core": patch +--- + +Added description and documentationLink properties to Node Types. diff --git a/packages/core/src/types/arazzo.ts b/packages/core/src/types/arazzo.ts index 2a96de503c..1642dede18 100755 --- a/packages/core/src/types/arazzo.ts +++ b/packages/core/src/types/arazzo.ts @@ -3,7 +3,11 @@ import { Oas3_2Types } from './oas3_2.js'; const Root: NodeType = { properties: { - arazzo: { type: 'string' }, + arazzo: { + type: 'string', + description: + 'REQUIRED. This string MUST be the version number of the Arazzo Specification that the Arazzo Description uses. The arazzo field MUST be used by tooling to interpret the Arazzo Description.', + }, info: 'Info', sourceDescriptions: 'SourceDescriptions', workflows: 'Workflows', @@ -36,13 +40,30 @@ const Components: NodeType = { const NamedInputs: NodeType = mapOf('Schema'); const Info: NodeType = { properties: { - title: { type: 'string' }, - description: { type: 'string' }, - summary: { type: 'string' }, - version: { type: 'string' }, + title: { + type: 'string', + description: 'REQUIRED. A human readable title of the Arazzo Description.', + }, + description: { + type: 'string', + description: + 'A description of the purpose of the workflows defined. CommonMark syntax MAY be used for rich text representation.', + }, + summary: { + type: 'string', + description: 'A short summary of the Arazzo Description.', + }, + version: { + type: 'string', + description: + 'REQUIRED. The version identifier of the Arazzo document (which is distinct from the Arazzo Specification version).', + }, }, required: ['title', 'version'], extensionsPrefix: 'x-', + description: + 'The object provides metadata about API workflows defined in this Arazzo document. The metadata MAY be used by the clients if needed.', + documentationLink: `https://spec.openapis.org/arazzo/latest.html#info-object`, }; const SourceDescriptions: NodeType = { properties: {}, @@ -56,39 +77,84 @@ const SourceDescriptions: NodeType = { }; const OpenAPISourceDescription: NodeType = { properties: { - name: { type: 'string' }, - type: { type: 'string', enum: ['openapi'] }, - url: { type: 'string' }, + name: { + type: 'string', + description: `REQUIRED. A unique name for the source description. Tools and libraries MAY use the name to uniquely identify a source description, therefore, it is RECOMMENDED to follow common programming naming conventions. SHOULD conform to the regular expression [A-Za-z0-9_-]+.`, + }, + type: { + type: 'string', + enum: ['openapi'], + description: 'The type of source description. Possible values are "openapi".', + }, + url: { + type: 'string', + description: + 'REQUIRED. A URL to a source description to be used by a workflow. If a relative reference is used, it MUST be in the form of a URI-reference as defined by [RFC3986] Section 4.2.', + }, 'x-serverUrl': { type: 'string' }, }, required: ['name', 'type', 'url'], extensionsPrefix: 'x-', + description: + 'Describes a source description (such as an OpenAPI description) that will be referenced by one or more workflows described within an Arazzo Description.', + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#source-description-object', }; const ArazzoSourceDescription: NodeType = { properties: { - name: { type: 'string' }, - type: { type: 'string', enum: ['arazzo'] }, - url: { type: 'string' }, + name: { + type: 'string', + description: `REQUIRED. A unique name for the source description. Tools and libraries MAY use the name to uniquely identify a source description, therefore, it is RECOMMENDED to follow common programming naming conventions. SHOULD conform to the regular expression [A-Za-z0-9_-]+.`, + }, + type: { + type: 'string', + enum: ['arazzo'], + description: 'The type of source description. Possible values are "arazzo".', + }, + url: { + type: 'string', + description: + 'REQUIRED. A URL to a source description to be used by a workflow. If a relative reference is used, it MUST be in the form of a URI-reference as defined by [RFC3986] Section 4.2.', + }, }, required: ['name', 'type', 'url'], extensionsPrefix: 'x-', + description: + 'Describes a source description (such as an OpenAPI description) that will be referenced by one or more workflows described within an Arazzo Description.', + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#source-description-object', }; const ReusableObject: NodeType = { properties: { - reference: { type: 'string' }, + reference: { + type: 'string', + description: 'REQUIRED. A Runtime Expression used to reference the desired object.', + }, value: {}, // any }, required: ['reference'], extensionsPrefix: 'x-', + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#reusable-object', + description: + 'A simple object to allow referencing of objects contained within the Components Object. It can be used from locations within steps or workflows in the Arazzo Description. Note - Input Objects MUST use standard JSON Schema referencing via the $ref keyword while all non JSON Schema objects use this object and its expression based referencing mechanism.', }; const Parameter: NodeType = { properties: { - in: { type: 'string', enum: ['header', 'query', 'path', 'cookie'] }, - name: { type: 'string' }, + in: { + type: 'string', + enum: ['header', 'query', 'path', 'cookie'], + description: + 'The location of the parameter. Possible values are "path", "query", "header", or "cookie". When the step in context specifies a workflowId, then all parameters map to workflow inputs. In all other scenarios (e.g., a step specifies an operationId), the in field MUST be specified.', + }, + name: { + type: 'string', + description: 'REQUIRED. The name of the parameter. Parameter names are case sensitive.', + }, value: {}, // any }, required: ['name', 'value'], extensionsPrefix: 'x-', + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#parameter-object', + description: + 'Describes a single step parameter. A unique parameter is defined by the combination of a name and in fields.', }; const Parameters: NodeType = { properties: {}, @@ -102,11 +168,26 @@ const Parameters: NodeType = { }; const Workflow: NodeType = { properties: { - workflowId: { type: 'string' }, - summary: { type: 'string' }, - description: { type: 'string' }, + workflowId: { + type: 'string', + description: 'REQUIRED. The unique identifier of the workflow.', + }, + summary: { + type: 'string', + description: 'A short summary of what the workflow does.', + }, + description: { + type: 'string', + description: + 'A verbose explanation of the workflow behavior. CommonMark syntax MAY be used for rich text representation.', + }, parameters: 'Parameters', - dependsOn: { type: 'array', items: { type: 'string' } }, + dependsOn: { + type: 'array', + items: { type: 'string' }, + description: + 'A list of workflows that MUST be completed before this workflow can be processed. Each value provided MUST be a workflowId.', + }, inputs: 'Schema', outputs: 'Outputs', steps: 'Steps', @@ -116,18 +197,43 @@ const Workflow: NodeType = { }, required: ['workflowId', 'steps'], extensionsPrefix: 'x-', + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#workflow-object', + description: + 'Describes the steps to be taken across one or more APIs to achieve an objective. The workflow object MAY define inputs needed in order to execute workflow steps, where the defined steps represent a call to an API operation or another workflow, and a set of outputs.', }; const Workflows: NodeType = listOf('Workflow'); const Steps: NodeType = listOf('Step'); const Step: NodeType = { properties: { - stepId: { type: 'string' }, - description: { type: 'string' }, - operationId: { type: 'string' }, - operationPath: { type: 'string' }, - workflowId: { type: 'string' }, + stepId: { + type: 'string', + description: `REQUIRED. Unique string to represent the step. The stepId MUST be unique amongst all steps described in the workflow. The stepId value is case-sensitive. Tools and libraries MAY use the stepId to uniquely identify a workflow step, therefore, it is RECOMMENDED to follow common programming naming conventions. SHOULD conform to the regular expression [A-Za-z0-9_-]+.`, + }, + description: { + type: 'string', + description: + 'A description of the step. CommonMark syntax MAY be used for rich text representation.', + }, + operationId: { + type: 'string', + description: + 'The name of an existing, resolvable operation, as defined with a unique operationId and existing within one of the sourceDescriptions. The referenced operation will be invoked by this workflow step. If multiple (non arazzo type) sourceDescriptions are defined, then the operationId MUST be specified using a Runtime Expression (e.g., $sourceDescriptions..) to avoid ambiguity or potential clashes. This field is mutually exclusive of the operationPath and workflowId fields respectively.', + }, + operationPath: { + type: 'string', + description: + 'A reference to a Source Description Object combined with a JSON Pointer to reference an operation. This field is mutually exclusive of the operationId and workflowId fields respectively. The operation being referenced MUST be described within one of the sourceDescriptions descriptions. A Runtime Expression syntax MUST be used to identify the source description document. If the referenced operation has an operationId defined then the operationId SHOULD be preferred over the operationPath.', + }, + workflowId: { + type: 'string', + description: + 'The workflowId referencing an existing workflow within the Arazzo Description. If the referenced workflow is contained within an arazzo type sourceDescription, then the workflowId MUST be specified using a Runtime Expression (e.g., $sourceDescriptions..) to avoid ambiguity or potential clashes. The field is mutually exclusive of the operationId and operationPath fields respectively.', + }, parameters: 'Parameters', - successCriteria: listOf('CriterionObject'), + successCriteria: listOf('CriterionObject', { + description: + 'A list of assertions to determine the success of the step. Each assertion is described using a Criterion Object. All assertions MUST be satisfied for the step to be deemed successful.', + }), onSuccess: 'OnSuccessActionList', onFailure: 'OnFailureActionList', outputs: 'Outputs', @@ -138,43 +244,74 @@ const Step: NodeType = { required: ['stepId'], requiredOneOf: ['x-operation', 'operationId', 'operationPath', 'workflowId'], extensionsPrefix: 'x-', + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#step-object', + description: + 'Describes a single workflow step which MAY be a call to an API operation (OpenAPI Operation Object) or another Workflow Object.', }; const Outputs: NodeType = { properties: {}, additionalProperties: { type: 'string', }, + description: + 'A map between a friendly name and a dynamic output value defined using a Runtime Expression. The name MUST use keys that match the regular expression: ^[a-zA-Z0-9_.-]+$.', }; const RequestBody: NodeType = { properties: { - contentType: { type: 'string' }, + contentType: { + type: 'string', + description: + 'The Content-Type for the request content. If omitted then refer to Content-Type specified at the targeted operation to understand serialization requirements.', + }, payload: {}, - replacements: listOf('Replacement'), + replacements: listOf('Replacement', { + description: 'A list of locations and values to set within a payload.', + }), }, required: ['payload'], extensionsPrefix: 'x-', + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#request-body-object', + description: + 'A single request body describing the Content-Type and request body content to be passed by a step to an operation.', }; const Replacement: NodeType = { properties: { - target: { type: 'string' }, + target: { + type: 'string', + description: + 'REQUIRED. A JSON Pointer or XPath Expression which MUST be resolved against the request body. Used to identify the location to inject the value.', + }, value: {}, }, required: ['target', 'value'], extensionsPrefix: 'x-', + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#payload-replacement-object', + description: + 'Describes a location within a payload (e.g., a request body) and a value to set within the location.', }; - const ExtendedSecurity: NodeType = { properties: { - schemeName: { type: 'string' }, + schemeName: { + type: 'string', + description: + 'REQUIRED. Name of the security scheme from your OpenAPI specification. Use with operationId or operationPath at the step level.', + }, values: {}, scheme: 'SecurityScheme', }, required: ['values'], requiredOneOf: ['schemeName', 'scheme'], + documentationLink: 'https://redocly.com/docs/respect/extensions/x-security#x-security-extension', + description: + 'Use the x-security extension to define authorization flows based on OpenAPI security schemes. Respect automatically constructs appropriate authorization headers, queries, or cookies based on your parameters.', }; const ExtendedOperation: NodeType = { properties: { - url: { type: 'string' }, + url: { + type: 'string', + description: + 'REQUIRED. A valid url including the protocol (such as http://localhost:4000/my-api or https://example.com/api/my-api).', + }, method: { enum: [ 'get', @@ -198,19 +335,35 @@ const ExtendedOperation: NodeType = { 'CONNECT', 'QUERY', ], + description: + 'REQUIRED. HTTP operation method. Possible values: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, CONNECT, TRACE. You can also use their lowercase equivalents.', }, }, required: ['url', 'method'], + documentationLink: 'https://redocly.com/docs/respect/extensions/x-operation', + description: + 'x-operation enables you to specify a URL and HTTP method for an operation that is not described in the Arazzo sourceDescriptions section. The primary application of the x-operation extension is to facilitate calls to third-party APIs or other endpoints that are needed in a sequence of API calls.', }; const CriterionObject: NodeType = { properties: { - condition: { type: 'string' }, - context: { type: 'string' }, + condition: { + type: 'string', + description: + 'REQUIRED. The condition to apply. Conditions can be simple (e.g. $statusCode == 200 which applies an operator on a value obtained from a runtime expression), or a regex, or a JSONPath expression. For regex or JSONPath, the type and context MUST be specified.', + }, + context: { + type: 'string', + description: + 'A Runtime Expression used to set the context for the condition to be applied on. If type is specified, then the context MUST be provided (e.g. $response.body would set the context that a JSONPath query expression could be applied to).', + }, type: (value: any) => { if (!value) { return undefined; } else if (typeof value === 'string') { - return { enum: ['regex', 'jsonpath', 'simple', 'xpath'] }; + return { + enum: ['regex', 'jsonpath', 'simple', 'xpath'], + description: 'The type of condition to be applied.', + }; } else if (value?.type === 'jsonpath') { return 'JSONPathCriterion'; } else { @@ -219,6 +372,9 @@ const CriterionObject: NodeType = { }, }, required: ['condition'], + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#criterion-object', + description: + 'An object used to specify the context, conditions, and condition types that can be used to prove or satisfy assertions specified in Step Object successCriteria, Success Action Object criteria, and Failure Action Object criteria.', }; const JSONPathCriterion: NodeType = { properties: { @@ -234,13 +390,34 @@ const XPathCriterion: NodeType = { }; const SuccessActionObject: NodeType = { properties: { - name: { type: 'string' }, - type: { type: 'string', enum: ['goto', 'end'] }, - stepId: { type: 'string' }, - workflowId: { type: 'string' }, - criteria: listOf('CriterionObject'), + name: { + type: 'string', + description: 'REQUIRED. The name of the success action. Names are case sensitive.', + }, + type: { + type: 'string', + enum: ['goto', 'end'], + description: 'REQUIRED. The type of action to take. Possible values are "end" or "goto".', + }, + stepId: { + type: 'string', + description: + 'The stepId to transfer to upon success of the step. This field is only relevant when the type field value is "goto". The referenced stepId MUST be within the current workflow. This field is mutually exclusive to workflowId.', + }, + workflowId: { + type: 'string', + description: + 'The workflowId referencing an existing workflow within the Arazzo Description to transfer to upon success of the step. This field is only relevant when the type field value is "goto". If the referenced workflow is contained within an arazzo type sourceDescription, then the workflowId MUST be specified using a Runtime Expression (e.g., $sourceDescriptions..) to avoid ambiguity or potential clashes. This field is mutually exclusive to stepId.', + }, + criteria: listOf('CriterionObject', { + description: + 'A list of assertions to determine if this action SHALL be executed. Each assertion is described using a Criterion Object. All criteria assertions MUST be satisfied for the action to be executed.', + }), }, required: ['type', 'name'], + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#success-action-object', + description: + 'A single success action which describes an action to take upon success of a workflow step.', }; const OnSuccessActionList: NodeType = { properties: {}, @@ -254,15 +431,47 @@ const OnSuccessActionList: NodeType = { }; const FailureActionObject: NodeType = { properties: { - name: { type: 'string' }, - type: { type: 'string', enum: ['goto', 'retry', 'end'] }, - workflowId: { type: 'string' }, - stepId: { type: 'string' }, - retryAfter: { type: 'number', minimum: 0 }, - retryLimit: { type: 'number', minimum: 0 }, - criteria: listOf('CriterionObject'), + name: { + type: 'string', + description: 'REQUIRED. The name of the failure action. Names are case sensitive.', + }, + type: { + type: 'string', + enum: ['goto', 'retry', 'end'], + description: + 'REQUIRED. The type of action to take. Possible values are "end", "retry", or "goto".', + }, + workflowId: { + type: 'string', + description: + 'The workflowId referencing an existing workflow within the Arazzo Description to transfer to upon failure of the step. This field is only relevant when the type field value is "goto" or "retry". If the referenced workflow is contained within an arazzo type sourceDescription, then the workflowId MUST be specified using a Runtime Expression (e.g., $sourceDescriptions..) to avoid ambiguity or potential clashes. This field is mutually exclusive to stepId. When used with "retry", context transfers back upon completion of the specified workflow.', + }, + stepId: { + type: 'string', + description: + 'The stepId to transfer to upon failure of the step. This field is only relevant when the type field value is "goto" or "retry". The referenced stepId MUST be within the current workflow. This field is mutually exclusive to workflowId. When used with "retry", context transfers back upon completion of the specified step.', + }, + retryAfter: { + type: 'number', + minimum: 0, + description: + 'A non-negative decimal indicating the seconds to delay after the step failure before another attempt SHALL be made. Note: if an HTTP Retry-After response header was returned to a step from a targeted operation, then it SHOULD overrule this particular field value. This field only applies when the type field value is "retry".', + }, + retryLimit: { + type: 'number', + minimum: 0, + description: + 'A non-negative integer indicating how many attempts to retry the step MAY be attempted before failing the overall step. If not specified then a single retry SHALL be attempted. This field only applies when the type field value is "retry". The retryLimit MUST be exhausted prior to executing subsequent failure actions.', + }, + criteria: listOf('CriterionObject', { + description: + 'A list of assertions to determine if this action SHALL be executed. Each assertion is described using a Criterion Object.', + }), }, required: ['type', 'name'], + documentationLink: 'https://spec.openapis.org/arazzo/latest.html#failure-action-object', + description: + 'A single failure action which describes an action to take upon failure of a workflow step.', }; const OnFailureActionList: NodeType = { properties: {}, diff --git a/packages/core/src/types/asyncapi2.ts b/packages/core/src/types/asyncapi2.ts index 835fc4ae36..dc129ecace 100644 --- a/packages/core/src/types/asyncapi2.ts +++ b/packages/core/src/types/asyncapi2.ts @@ -13,7 +13,10 @@ const Root: NodeType = { properties: { asyncapi: null, // TODO: validate semver format and supported version info: 'Info', - id: { type: 'string' }, + id: { + type: 'string', + description: 'Identifier of the application the AsyncAPI document is defining.', + }, servers: 'ServerMap', channels: 'ChannelMap', components: 'Components', @@ -22,17 +25,29 @@ const Root: NodeType = { defaultContentType: { type: 'string' }, }, required: ['asyncapi', 'channels', 'info'], + documentationLink: 'https://v2.asyncapi.com/docs/reference/specification/v2.0.0', }; const Channel: NodeType = { properties: { - description: { type: 'string' }, + description: { + type: 'string', + description: + 'An optional description of this channel item. CommonMark syntax can be used for rich text representation.', + }, subscribe: 'Operation', publish: 'Operation', parameters: 'ParametersMap', bindings: 'ChannelBindings', - servers: { type: 'array', items: { type: 'string' } }, + servers: { + type: 'array', + items: { type: 'string' }, + description: + 'The servers on which this channel is available, specified as an optional unordered list of names (string keys) of Server Objects defined in the Servers Object (a map).', + }, }, + description: 'Describes the operations available on a single channel.', + documentationLink: 'https://v2.asyncapi.com/docs/concepts/channel', }; const ChannelMap: NodeType = { @@ -67,28 +82,52 @@ const ChannelBindings: NodeType = { ]; }, additionalProperties: { type: 'object' }, + documentationLink: + 'https://v2.asyncapi.com/docs/reference/specification/v2.6.0#channelBindingsObject', + description: 'Map describing protocol-specific definitions for a channel.', }; export const Tag: NodeType = { properties: { - name: { type: 'string' }, - description: { type: 'string' }, + name: { type: 'string', description: 'REQUIRED. The name of the tag.' }, + description: { + type: 'string', + description: + 'A short description for the tag. CommonMark syntax can be used for rich text representation.', + }, externalDocs: 'ExternalDocs', }, required: ['name'], + description: 'Allows adding meta data to a single tag.', + documentationLink: 'https://v2.asyncapi.com/docs/reference/specification/v2.6.0#tagObject', }; export const ExternalDocs: NodeType = { properties: { - description: { type: 'string' }, - url: { type: 'string' }, + description: { + type: 'string', + description: + 'A short description of the target documentation. CommonMark syntax can be used for rich text representation.', + }, + url: { + type: 'string', + description: + 'REQUIRED. The URL for the target documentation. This MUST be in the form of an absolute URL.', + }, }, required: ['url'], + documentationLink: + 'https://v2.asyncapi.com/docs/reference/specification/v2.6.0#externalDocumentationObject', + description: 'Allows referencing an external resource for extended documentation.', }; const SecurityRequirement: NodeType = { properties: {}, additionalProperties: { type: 'array', items: { type: 'string' } }, + documentationLink: + 'https://v2.asyncapi.com/docs/reference/specification/v2.6.0#securityRequirementObject', + description: + 'Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the Security Schemes under the Components Object.', }; const ServerBindings: NodeType = { @@ -118,20 +157,42 @@ const ServerBindings: NodeType = { ]; }, additionalProperties: { type: 'object' }, + documentationLink: + 'https://v2.asyncapi.com/docs/reference/specification/v2.6.0#serverBindingsObject', + description: 'Map describing protocol-specific definitions for a server.', }; const Server: NodeType = { properties: { - url: { type: 'string' }, - protocol: { type: 'string' }, - protocolVersion: { type: 'string' }, - description: { type: 'string' }, + url: { + type: 'string', + description: + 'REQUIRED. A URL to the target host. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the AsyncAPI document is being served. Variable substitutions will be made when a variable is named in {braces}.', + }, + protocol: { + type: 'string', + description: + 'REQUIRED. The protocol this URL supports for connection. Supported protocol include, but are not limited to: amqp, amqps, http, https, ibmmq, jms, kafka, kafka-secure, anypointmq, mqtt, secure-mqtt, solace, stomp, stomps, ws, wss, mercure, googlepubsub, pulsar.', + }, + protocolVersion: { + type: 'string', + description: + 'The version of the protocol used for connection. For instance: AMQP 0.9.1, HTTP 2.0, Kafka 1.0.0, etc.', + }, + description: { + type: 'string', + description: + 'An optional string describing the host designated by the URL. CommonMark syntax MAY be used for rich text representation.', + }, variables: 'ServerVariablesMap', security: 'SecurityRequirementList', bindings: 'ServerBindings', tags: 'TagList', }, required: ['url', 'protocol'], + documentationLink: 'https://v2.asyncapi.com/docs/reference/specification/v2.6.0#serverObject', + description: + 'An object representing a message broker, a server or any other kind of computer program capable of sending and/or receiving data. This object is used to capture details such as URIs, protocols and security configuration. Variable substitution can be used so that some details, for example usernames and passwords, can be injected by code generation tools.', }; export const ServerMap: NodeType = { @@ -146,15 +207,29 @@ export const ServerVariable: NodeType = { enum: { type: 'array', items: { type: 'string' }, + description: + 'An enumeration of string values to be used if the substitution options are from a limited set.', + }, + default: { + type: 'string', + description: + 'The default value to use for substitution, and to send, if an alternate value is not supplied.', + }, + description: { + type: 'string', + description: + 'An optional description for the server variable. CommonMark syntax MAY be used for rich text representation.', }, - default: { type: 'string' }, - description: { type: 'string' }, examples: { type: 'array', items: { type: 'string' }, + description: 'An array of examples of the server variable.', }, }, required: [], + documentationLink: + 'https://v2.asyncapi.com/docs/reference/specification/v2.6.0#serverVariableObject', + description: 'An object representing a Server Variable for server URL template substitution.', }; const Info: NodeType = { diff --git a/packages/core/src/types/index.ts b/packages/core/src/types/index.ts index 3b9d025baa..89f6c1dce4 100755 --- a/packages/core/src/types/index.ts +++ b/packages/core/src/types/index.ts @@ -27,6 +27,8 @@ export type NodeType = { requiredOneOf?: string[]; allowed?: (value: any) => string[] | undefined; extensionsPrefix?: string; + description?: string; + documentationLink?: string; }; export type PropType = string | NodeType | ScalarSchema | undefined | null; export type ResolveTypeFn = (value: any, key: string) => string | PropType; @@ -46,19 +48,27 @@ export type NormalizedNodeType = { type NormalizedPropType = NormalizedNodeType | NormalizedScalarSchema | null | undefined; type NormalizedResolveTypeFn = (value: any, key: string) => NormalizedPropType; -export function listOf(typeName: string) { +export function listOf( + typeName: string, + opts: { description?: string; documentationLink?: string } = {} +) { return { name: `${typeName}List`, properties: {}, items: typeName, + ...opts, }; } -export function mapOf(typeName: string) { +export function mapOf( + typeName: string, + opts: { description?: string; documentationLink?: string } = {} +) { return { name: `${typeName}Map`, properties: {}, additionalProperties: () => typeName, + ...opts, }; } diff --git a/packages/core/src/types/oas3.ts b/packages/core/src/types/oas3.ts index d68c200f12..6bdcc60bc0 100755 --- a/packages/core/src/types/oas3.ts +++ b/packages/core/src/types/oas3.ts @@ -19,45 +19,84 @@ const Root: NodeType = { }, required: ['openapi', 'paths', 'info'], extensionsPrefix: 'x-', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/openapi#openapi', + description: + 'REQUIRED. This string MUST be the semantic version number of the OpenAPI Specification version that the OpenAPI document uses. The openapi field SHOULD be used by tooling specifications and clients to interpret the OpenAPI document. This is not related to the API info.version string.', }; const Tag: NodeType = { properties: { - name: { type: 'string' }, - description: { type: 'string' }, + name: { + type: 'string', + description: 'REQUIRED. The name of the tag.', + }, + description: { + type: 'string', + description: 'A description for the tag.', + }, externalDocs: 'ExternalDocs', 'x-traitTag': { type: 'boolean' }, 'x-displayName': { type: 'string' }, }, required: ['name'], extensionsPrefix: 'x-', + description: `The Tag Object represents a tag used by the OAS. It is not mandatory to have a tag object per tag used by the OAS but each tag object can contain additional metadata.`, + documentationLink: `https://spec.openapis.org/oas/v3.1.0#tag-object`, }; const TagGroup: NodeType = { properties: { - name: { type: 'string' }, - tags: { type: 'array', items: { type: 'string' } }, + name: { + type: 'string', + description: + 'The display name for the tag, used in the navigation bar and as a section heading.', + }, + tags: { + type: 'array', + description: 'List of tags to include in this group.', + items: { type: 'string' }, + }, }, extensionsPrefix: 'x-', + description: 'The x-tagGroups extension is used at the top level of an OpenAPI description.', + documentationLink: + 'https://redocly.com/docs/realm/content/api-docs/openapi-extensions/x-tag-groups#taggroup-object', }; const ExternalDocs: NodeType = { properties: { - description: { type: 'string' }, - url: { type: 'string' }, + description: { + type: 'string', + description: + 'A description of the target documentation. Used as the link anchor text in Redocly. If not provided, the url is used as the link anchor text.', + }, + url: { + type: 'string', + description: 'REQUIRED. The URL for the target documentation.', + }, }, required: ['url'], extensionsPrefix: 'x-', + description: 'Additional external documentation for this operation.', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/external-docs', }; const Server: NodeType = { properties: { - url: { type: 'string' }, - description: { type: 'string' }, + url: { + type: 'string', + description: + 'REQUIRED. A URL to the target host. This URL supports Server Variables and MAY be relative, to indicate that the host location is relative to the location where the OpenAPI document is being served. Variable substitutions are made when a variable is named in { curly braces }.', + }, + description: { + type: 'string', + description: 'An optional string describing the host designated by the URL.', + }, variables: 'ServerVariablesMap', }, required: ['url'], extensionsPrefix: 'x-', + description: 'A server object to be used by the target operation.', }; const ServerVariable: NodeType = { @@ -65,31 +104,63 @@ const ServerVariable: NodeType = { enum: { type: 'array', items: { type: 'string' }, + description: + 'An enumeration of string values to be used if the substitution options are from a limited set. The array MUST NOT be empty. If defined, the array MUST contain the default value.', + }, + default: { + type: 'string', + description: `REQUIRED. The default value to use for substitution, which SHALL be sent if an alternate value is not supplied. Note this behavior is different than the Schema Object's treatment of default values, because in those cases parameter values are optional. If the enum is defined, the value MUST exist in the enum's values.`, + }, + description: { + type: 'string', + description: 'An optional description for the server variable.', }, - default: { type: 'string' }, - description: { type: 'string' }, }, required: ['default'], extensionsPrefix: 'x-', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/server-variables#server-variables', + description: + 'Server variables are used when you need to make a substitution into the server URL such as when the subdomain is unique per tenant.', }; const SecurityRequirement: NodeType = { properties: {}, additionalProperties: { type: 'array', items: { type: 'string' } }, + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/security#security-requirement-object', + description: + 'A declaration of which security mechanisms can be used across the API. The list of values includes alternative security requirement objects that can be used. Only one of the security requirement objects need to be satisfied to authorize a request. Individual operations can override this definition. To make security optional, an empty security requirement ({}) can be included in the array.', }; const Info: NodeType = { properties: { - title: { type: 'string' }, - version: { type: 'string' }, - description: { type: 'string' }, - termsOfService: { type: 'string' }, + title: { + type: 'string', + description: 'REQUIRED. The title of the API.', + }, + version: { + type: 'string', + description: + 'REQUIRED. The version of the OpenAPI document (which is distinct from the OpenAPI Specification version or the API implementation version).', + }, + description: { + type: 'string', + description: 'RECOMMENDED. A description of the API (Markdown may be used).', + }, + termsOfService: { + type: 'string', + description: 'A URL to the Terms of Service for the API.', + }, contact: 'Contact', license: 'License', 'x-logo': 'Logo', }, required: ['title', 'version'], extensionsPrefix: 'x-', + description: + 'REQUIRED. Provides metadata about the API. The metadata MAY be used by tooling as required.', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/info#info', }; const Logo: NodeType = { @@ -99,44 +170,84 @@ const Logo: NodeType = { backgroundColor: { type: 'string' }, href: { type: 'string' }, }, + documentationLink: + 'https://redocly.com/docs-legacy/api-reference-docs/specification-extensions/x-logo#x-logo', + description: + 'A commonly used specification extension containing the information about the API logo.', }; const Contact: NodeType = { properties: { - name: { type: 'string' }, - url: { type: 'string' }, - email: { type: 'string' }, + name: { + type: 'string', + description: 'The identifying name of the contact person or organization.', + }, + url: { + type: 'string', + description: 'The URL pointing to the contact information.', + }, + email: { + type: 'string', + description: 'The email address of the contact person or organization.', + }, }, extensionsPrefix: 'x-', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/contact', + description: 'The contact information for the exposed API.', }; const License: NodeType = { properties: { - name: { type: 'string' }, - url: { type: 'string' }, + name: { + type: 'string', + description: 'REQUIRED. The license name used for the API.', + }, + url: { + type: 'string', + description: 'The URL pointing to the contact information.', + }, }, required: ['name'], extensionsPrefix: 'x-', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/license#license', + description: 'The license information for the exposed API.', }; const Paths: NodeType = { properties: {}, additionalProperties: (_value: any, key: string) => key.startsWith('/') ? 'PathItem' : undefined, + description: + 'The Paths Object is a map of a paths to the path item object. A path starts with a /.', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/paths#paths-object', }; const WebhooksMap: NodeType = { properties: {}, additionalProperties: () => 'PathItem', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/webhooks#types', }; const PathItem: NodeType = { properties: { - $ref: { type: 'string' }, // TODO: verify special $ref handling for Path Item + $ref: { + type: 'string', + description: + 'Allows for a referenced definition of this path item. The referenced structure MUST be in the form of a Path Item Object. In case a Path Item Object field appears both in the defined object and the referenced object, the behavior is undefined. See the rules for resolving Relative References.', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/reference', + }, // TODO: verify special $ref handling for Path Item servers: 'ServerList', parameters: 'ParameterList', - summary: { type: 'string' }, - description: { type: 'string' }, + summary: { + type: 'string', + description: 'An optional, string summary, intended to apply to all operations in this path.', + }, + description: { + type: 'string', + description: + 'An optional, string description, intended to apply to all operations in this path.', + }, get: 'Operation', put: 'Operation', @@ -148,21 +259,56 @@ const PathItem: NodeType = { trace: 'Operation', }, extensionsPrefix: 'x-', + description: + 'Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available.', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/path-item#path-item-object', }; const Parameter: NodeType = { properties: { - name: { type: 'string' }, - in: { enum: ['query', 'header', 'path', 'cookie'] }, - description: { type: 'string' }, - required: { type: 'boolean' }, - deprecated: { type: 'boolean' }, - allowEmptyValue: { type: 'boolean' }, + name: { + type: 'string', + description: 'REQUIRED. The name of the parameter. Parameter names are case sensitive.', + }, + in: { + enum: ['query', 'header', 'path', 'cookie'], + description: + 'REQUIRED. The location of the parameter. Possible values are "query", "header", "path", or "cookie".', + }, + description: { + type: 'string', + description: 'A brief description of the parameter. This could contain examples of use.', + }, + required: { + type: 'boolean', + description: + 'Determines whether this parameter is mandatory. If the parameter location is "path", this property is REQUIRED and its value MUST be true. Otherwise, the property MAY be included and its default value is false.', + }, + deprecated: { + type: 'boolean', + description: + 'Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. Default value is false.', + }, + allowEmptyValue: { + type: 'boolean', + description: + 'Sets the ability to pass empty-valued parameters. This is valid only for query parameters and allows sending a parameter with an empty value. Default value is false. If style is used, and if behavior is n/a (cannot be serialized), the value of allowEmptyValue SHALL be ignored. Use of this property is NOT RECOMMENDED, as it is likely to be removed in a later revision.', + }, style: { enum: ['form', 'simple', 'label', 'matrix', 'spaceDelimited', 'pipeDelimited', 'deepObject'], + description: + 'Describes how the parameter value will be serialized depending on the type of the parameter value. Default values (based on value of in): for query - form; for path - simple; for header - simple; for cookie - form.', + }, + explode: { + type: 'boolean', + description: + 'When this is true, parameter values of type array or object generate separate parameters for each value of the array or key-value pair of the map. For other types of parameters this property has no effect. When style is form, the default value is true. For all other styles, the default value is false.', + }, + allowReserved: { + type: 'boolean', + description: `Determines whether the parameter value SHOULD allow reserved characters, as defined by RFC3986 :/?#[]@!$&'()*+,;= to be included without percent-encoding. This property only applies to parameters with an in value of query. The default value is false.`, }, - explode: { type: 'boolean' }, - allowReserved: { type: 'boolean' }, schema: 'Schema', example: { isExample: true }, examples: 'ExamplesMap', @@ -171,6 +317,9 @@ const Parameter: NodeType = { required: ['name', 'in'], requiredOneOf: ['schema', 'content'], extensionsPrefix: 'x-', + description: + 'Describes a request parameter, which excludes the request body. A unique parameter is defined by a unique combination of the name and in values.', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/parameter', }; const Operation: NodeType = { @@ -178,11 +327,29 @@ const Operation: NodeType = { tags: { type: 'array', items: { type: 'string' }, + description: + 'A list of tags for API documentation control. Tags can be used for logical grouping of operations by resources or any other qualifier.', + }, + summary: { + type: 'string', + description: 'A short summary of what the operation does.', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/operation#summary', + }, + description: { + type: 'string', + description: 'A verbose explanation of the operation behavior.', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/operation#description', }, - summary: { type: 'string' }, - description: { type: 'string' }, externalDocs: 'ExternalDocs', - operationId: { type: 'string' }, + operationId: { + type: 'string', + description: + 'The operationId is path segment or path fragment in deep links to a specific operation.', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/operation#operationid', + }, parameters: 'ParameterList', security: 'SecurityRequirementList', servers: 'ServerList', @@ -196,6 +363,8 @@ const Operation: NodeType = { }, required: ['responses'], extensionsPrefix: 'x-', + description: `The Operation Object describes a single API operation on a path, including its parameters, responses, and request body (if applicable). Each path can support more than one operation, but those operations must be unique. A unique operation is a combination of a path and an HTTP method, so two GET or two POST methods for the same path are not allowed.`, + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/operation', }; const XCodeSample: NodeType = { @@ -204,85 +373,153 @@ const XCodeSample: NodeType = { label: { type: 'string' }, source: { type: 'string' }, }, + documentationLink: + 'https://redocly.com/docs/realm/content/api-docs/openapi-extensions/x-code-samples', + description: + 'Code samples are snippets of code shown alongside API operations in reference documentation, giving users a quick way to start to interact with an API from their own code. The x-codeSamples addition to OpenAPI allows you to add or override any existing code samples for a particular language or endpoint.', }; const RequestBody: NodeType = { properties: { - description: { type: 'string' }, - required: { type: 'boolean' }, + description: { + type: 'string', + description: 'A brief description of the request body. This could contain examples of use.', + }, + required: { + type: 'boolean', + description: 'Determines if the request body is required in the request. Defaults to false.', + }, content: 'MediaTypesMap', }, required: ['content'], extensionsPrefix: 'x-', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/request-body', + description: + 'The request body is defined inside of operations (including paths and webhooks). The request body can also be defined inside of the named requestBodies object in components.', }; const MediaTypesMap: NodeType = { properties: {}, additionalProperties: 'MediaType', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/media-type#types', }; const MediaType: NodeType = { properties: { schema: 'Schema', - example: { isExample: true }, + example: { + isExample: true, + description: + 'Example of the media type. The example object SHOULD be in the correct format as specified by the media type. The example field is mutually exclusive of the examples field. Furthermore, if referencing a schema which contains an example, the example value SHALL override the example provided by the schema.', + }, examples: 'ExamplesMap', encoding: 'EncodingMap', }, extensionsPrefix: 'x-', + description: 'The Media Type Object is one of the important building blocks of OpenAPI.', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/media-type', }; const Example: NodeType = { properties: { - value: { resolvable: false }, + value: { + resolvable: false, + description: + 'Embedded literal example. The value field and externalValue field are mutually exclusive. To represent examples of media types that cannot naturally represented in JSON or YAML, use a string value to contain the example, escaping where necessary.', + }, summary: { type: 'string' }, - description: { type: 'string' }, - externalValue: { type: 'string' }, + description: { type: 'string', description: 'Long description for the example.' }, + externalValue: { + type: 'string', + description: + 'A URL that points to the literal example. This provides the capability to reference examples that cannot easily be included in JSON or YAML documents. The value field and externalValue field are mutually exclusive.', + }, }, extensionsPrefix: 'x-', + description: + 'Example of the media type. The example object SHOULD be in the correct format as specified by the media type. The example field is mutually exclusive of the examples field. Furthermore, if referencing a schema which contains an example, the example value SHALL override the example provided by the schema.', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/example', }; const Encoding: NodeType = { properties: { - contentType: { type: 'string' }, + contentType: { + type: 'string', + description: `The Content-Type for encoding a specific property. Default value depends on the property type: for string with format being binary – application/octet-stream; for other primitive types – text/plain; for object - application/json; for array – the default is defined based on the inner type. The value can be a specific media type (e.g. application/json), a wildcard media type (e.g. image/*), or a comma-separated list of the two types.`, + }, headers: 'HeadersMap', style: { enum: ['form', 'simple', 'label', 'matrix', 'spaceDelimited', 'pipeDelimited', 'deepObject'], + description: + 'Describes how a specific property value will be serialized depending on its type. See Parameter Object for details on the style property. The behavior follows the same values as query parameters, including default values. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded.', + }, + explode: { + type: 'boolean', + description: + 'When this is true, property values of type array or object generate separate parameters for each value of the array, or key-value-pair of the map. For other types of properties this property has no effect. When style is form, the default value is true. For all other styles, the default value is false. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded.', + }, + allowReserved: { + type: 'boolean', + description: `Determines whether the parameter value SHOULD allow reserved characters, as defined by [RFC3986] Section 2.2 :/?#[]@!$&'()*+,;= to be included without percent-encoding. The default value is false. This property SHALL be ignored if the request body media type is not application/x-www-form-urlencoded.`, }, - explode: { type: 'boolean' }, - allowReserved: { type: 'boolean' }, }, extensionsPrefix: 'x-', + description: 'A single encoding definition applied to a single schema property.', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/encoding#types', }; const EnumDescriptions: NodeType = { properties: {}, additionalProperties: { type: 'string' }, + description: + 'The enum (short for "enumeration") fields in OpenAPI allow you to restrict the value of a field to a list of allowed values. These values need to be short and machine-readable, but that can make them harder for humans to parse and work with.', + documentationLink: + 'https://redocly.com/docs/realm/content/api-docs/openapi-extensions/x-enum-descriptions', }; const Header: NodeType = { properties: { - description: { type: 'string' }, - required: { type: 'boolean' }, + description: { + type: 'string', + description: + 'A brief description of the parameter. This could contain examples of use. CommonMark syntax MAY be used for rich text representation.', + }, + required: { + type: 'boolean', + description: 'Determines whether this parameter is mandatory. Its default value is false.', + }, deprecated: { type: 'boolean' }, - allowEmptyValue: { type: 'boolean' }, + allowEmptyValue: { + type: 'boolean', + description: + 'Specifies that a parameter is deprecated and SHOULD be transitioned out of usage. Default value is false.', + }, style: { enum: ['form', 'simple', 'label', 'matrix', 'spaceDelimited', 'pipeDelimited', 'deepObject'], }, explode: { type: 'boolean' }, allowReserved: { type: 'boolean' }, schema: 'Schema', - example: { isExample: true }, + example: { + isExample: true, + description: `Example of the header's potential value. The example SHOULD match the specified schema and encoding properties if present. The example field is mutually exclusive of the examples field. Furthermore, if referencing a schema that contains an example, the example value SHALL override the example provided by the schema. To represent examples of media types that cannot naturally be represented in JSON or YAML, a string value can contain the example with escaping where necessary.`, + }, examples: 'ExamplesMap', content: 'MediaTypesMap', }, requiredOneOf: ['schema', 'content'], extensionsPrefix: 'x-', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/header#header-object', + description: 'The header object is used to describe a response header in the headers map.', }; const Responses: NodeType = { properties: { default: 'Response' }, additionalProperties: (_v: any, key: string) => responseCodeRegexp.test(key) ? 'Response' : undefined, + description: 'The list of possible responses as they are returned from executing this operation.', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/named-responses', }; const Response: NodeType = { @@ -291,22 +528,41 @@ const Response: NodeType = { headers: 'HeadersMap', content: 'MediaTypesMap', links: 'LinksMap', - 'x-summary': { type: 'string' }, + 'x-summary': { + type: 'string', + documentationLink: + 'https://redocly.com/docs/realm/content/api-docs/openapi-extensions/x-summary#openapi-extension-x-summary', + description: + 'Use x-summary to add a short custom text to describe the response in the API documentation.', + }, }, required: ['description'], extensionsPrefix: 'x-', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/response', + description: 'The response object describes a single response in the Responses Map.', }; const Link: NodeType = { properties: { - operationRef: { type: 'string' }, - operationId: { type: 'string' }, + operationRef: { + type: 'string', + description: + 'A relative or absolute reference to an OAS operation. This field is mutually exclusive of the operationId field, and MUST point to an Operation Object. Relative operationRef values MAY be used to locate an existing Operation Object in the OpenAPI definition.', + }, + operationId: { + type: 'string', + description: + 'The name of an existing, resolvable OAS operation, as defined with a unique operationId. This field is mutually exclusive of the operationRef field.', + }, parameters: null, // TODO: figure out how to describe/validate this requestBody: null, // TODO: figure out how to describe/validate this - description: { type: 'string' }, + description: { type: 'string', description: 'A description of the link.' }, server: 'Server', }, extensionsPrefix: 'x-', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/links', + description: + 'The Link object represents a possible design-time link for a response. The presence of a link does not guarantee the caller’s ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations.', }; // draft-00 @@ -314,7 +570,10 @@ const Schema: NodeType = { properties: { externalDocs: 'ExternalDocs', discriminator: 'Discriminator', - title: { type: 'string' }, + title: { + type: 'string', + description: 'Value MUST be a string. Multiple types via an array are not supported.', + }, multipleOf: { type: 'number', minimum: 0 }, maximum: { type: 'number' }, minimum: { type: 'number' }, @@ -322,7 +581,11 @@ const Schema: NodeType = { exclusiveMinimum: { type: 'boolean' }, maxLength: { type: 'integer', minimum: 0 }, minLength: { type: 'integer', minimum: 0 }, - pattern: { type: 'string' }, + pattern: { + type: 'string', + description: + '(This string SHOULD be a valid regular expression, according to the Ecma-262 Edition 5.1 regular expression dialect)', + }, maxItems: { type: 'integer', minimum: 0 }, minItems: { type: 'integer', minimum: 0 }, uniqueItems: { type: 'boolean' }, @@ -332,10 +595,20 @@ const Schema: NodeType = { enum: { type: 'array' }, type: { enum: ['object', 'array', 'string', 'number', 'integer', 'boolean'], + description: 'Value MUST be a string. Multiple types via an array are not supported.', }, - allOf: listOf('Schema'), - anyOf: listOf('Schema'), - oneOf: listOf('Schema'), + allOf: listOf('Schema', { + description: + 'Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema.', + }), + anyOf: listOf('Schema', { + description: + 'Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema.', + }), + oneOf: listOf('Schema', { + description: + 'Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema.', + }), not: 'Schema', properties: 'SchemaProperties', items: (value: any) => { @@ -352,8 +625,14 @@ const Schema: NodeType = { return 'Schema'; } }, - description: { type: 'string' }, - format: { type: 'string' }, + description: { + type: 'string', + description: 'CommonMark syntax MAY be used for rich text representation.', + }, + format: { + type: 'string', + description: `See Data Type Formats for further details. While relying on JSON Schema's defined formats, the OAS offers a few additional predefined formats.`, + }, default: null, nullable: { type: 'boolean' }, readOnly: { type: 'boolean' }, @@ -366,6 +645,8 @@ const Schema: NodeType = { 'x-explicitMappingOnly': { type: 'boolean' }, }, extensionsPrefix: 'x-', + description: 'The schema defining the content of the request, response, or parameter.', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/schemas', }; const Xml: NodeType = { @@ -377,6 +658,8 @@ const Xml: NodeType = { wrapped: { type: 'boolean' }, }, extensionsPrefix: 'x-', + description: + 'This MAY be used only on properties schemas. It has no effect on root schemas. Adds additional metadata to describe the XML representation of this property.', }; const SchemaProperties: NodeType = { @@ -393,15 +676,25 @@ const DiscriminatorMapping: NodeType = { return { type: 'string' }; } }, + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/discriminator#types', }; const Discriminator: NodeType = { properties: { - propertyName: { type: 'string' }, + propertyName: { + type: 'string', + description: + 'REQUIRED. The name of the property in the payload that will hold the discriminator value.', + }, mapping: 'DiscriminatorMapping', }, required: ['propertyName'], extensionsPrefix: 'x-', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/discriminator#discriminator-object', + description: + 'When request bodies or response payloads may be one of a number of different schemas, a discriminator object can be used to aid in serialization, deserialization, and validation. The discriminator is a specific object in a schema which is used to inform the consumer of the document of an alternative schema based on the value associated with it.', }; const Components: NodeType = { @@ -417,6 +710,8 @@ const Components: NodeType = { callbacks: 'NamedCallbacks', }, extensionsPrefix: 'x-', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/components#components', }; const ImplicitFlow: NodeType = { @@ -427,6 +722,7 @@ const ImplicitFlow: NodeType = { }, required: ['authorizationUrl', 'scopes'], extensionsPrefix: 'x-', + description: 'Configuration for the OAuth Implicit flow.', }; const PasswordFlow: NodeType = { @@ -437,6 +733,7 @@ const PasswordFlow: NodeType = { }, required: ['tokenUrl', 'scopes'], extensionsPrefix: 'x-', + description: 'Object Configuration for the OAuth Resource Owner Password flow.', }; const ClientCredentials: NodeType = { @@ -447,6 +744,8 @@ const ClientCredentials: NodeType = { }, required: ['tokenUrl', 'scopes'], extensionsPrefix: 'x-', + description: + 'Configuration for the OAuth Client Credentials flow. Previously called application in OpenAPI 2.0.', }; const AuthorizationCode: NodeType = { @@ -465,6 +764,8 @@ const AuthorizationCode: NodeType = { }, required: ['authorizationUrl', 'tokenUrl', 'scopes'], extensionsPrefix: 'x-', + description: + 'Configuration for the OAuth Authorization Code flow. Previously called accessCode in OpenAPI 2.0.', }; const OAuth2Flows: NodeType = { @@ -475,18 +776,45 @@ const OAuth2Flows: NodeType = { authorizationCode: 'AuthorizationCode', }, extensionsPrefix: 'x-', + description: 'Configuration details for a supported OAuth Flow.', }; const SecurityScheme: NodeType = { properties: { - type: { enum: ['apiKey', 'http', 'oauth2', 'openIdConnect'] }, - description: { type: 'string' }, - name: { type: 'string' }, - in: { type: 'string', enum: ['query', 'header', 'cookie'] }, - scheme: { type: 'string' }, - bearerFormat: { type: 'string' }, + type: { + enum: ['apiKey', 'http', 'oauth2', 'openIdConnect'], + description: + 'REQUIRED. The type of the security scheme. Valid values are "apiKey", "http", "oauth2", "openIdConnect".', + }, + description: { + type: 'string', + description: 'A short description for security scheme.', + }, + name: { + type: 'string', + description: 'REQUIRED. The name of the header, query or cookie parameter to be used.', + }, + in: { + type: 'string', + enum: ['query', 'header', 'cookie'], + description: + 'REQUIRED. The location of the API key. Valid values are "query", "header" or "cookie".', + }, + scheme: { + type: 'string', + description: 'A short description for security scheme.', + }, + bearerFormat: { + type: 'string', + description: + 'A hint to the client to identify how the bearer token is formatted. Bearer tokens are usually generated by an authorization server, so this information is primarily for documentation purposes.', + }, flows: 'OAuth2Flows', - openIdConnectUrl: { type: 'string' }, + openIdConnectUrl: { + type: 'string', + description: + 'REQUIRED. OpenId Connect URL to discover OAuth2 configuration values. This MUST be in the form of a URL.', + }, 'x-defaultClientId': { type: 'string' }, }, required(value) { @@ -525,19 +853,31 @@ const XUsePkce: NodeType = { disableManualConfiguration: { type: 'boolean' }, hideClientSecretInput: { type: 'boolean' }, }, + description: + 'The x-usePkce allows you to enable Proof Key for Code Exchange (PKCE) for the Oauth2 or OpenID Connect authorization code flow in the Replay.', + documentationLink: + 'https://redocly.com/docs/realm/content/api-docs/openapi-extensions/x-use-pkce#openapi-extension-x-usepkce', }; export const Oas3Types = { Root, Tag, - TagList: listOf('Tag'), + TagList: listOf('Tag', { + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/tags', + description: `A list of tags used by the document with additional metadata. The order of the tags can be used to reflect on their order by the parsing tools. Not all tags that are used by the Operation Object must be declared. The tags that are not declared MAY be organized randomly or based on the tools' logic. Each tag name in the list MUST be unique.`, + }), TagGroups: listOf('TagGroup'), TagGroup, ExternalDocs, Server, - ServerList: listOf('Server'), + ServerList: listOf('Server', { + description: 'A list of servers available to the API.', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/servers#servers', + }), ServerVariable, - ServerVariablesMap: mapOf('ServerVariable'), + ServerVariablesMap: mapOf('ServerVariable', { + description: `A map between a variable name and its value. The value is used for substitution in the server's URL template.`, + }), SecurityRequirement, SecurityRequirementList: listOf('SecurityRequirement'), Info, @@ -546,9 +886,15 @@ export const Oas3Types = { Paths, PathItem, Parameter, - ParameterList: listOf('Parameter'), + ParameterList: listOf('Parameter', { + description: + 'A list of parameters that are applicable for this operation. If a parameter is already defined at the Path Item, the new definition will override it but can never remove it. The list MUST NOT include duplicated parameters. A unique parameter is defined by a combination of a name and location. The list can use the Reference Object to link to parameters that are defined at the OpenAPI Object’s components/parameters.', + }), Operation, - Callback: mapOf('PathItem'), + Callback: mapOf('PathItem', { + description: + 'https://redocly.com/learn/openapi/openapi-visual-reference/callbacks#callback-object', + }), CallbacksMap: mapOf('Callback'), RequestBody, MediaTypesMap, diff --git a/packages/core/src/types/oas3_1.ts b/packages/core/src/types/oas3_1.ts index 159e5a4c60..fd1f15957c 100755 --- a/packages/core/src/types/oas3_1.ts +++ b/packages/core/src/types/oas3_1.ts @@ -12,52 +12,49 @@ const Root: NodeType = { paths: 'Paths', webhooks: 'WebhooksMap', components: 'Components', - jsonSchemaDialect: { type: 'string' }, + jsonSchemaDialect: { + type: 'string', + description: + 'The default value for the $schema keyword within Schema Objects contained within this OAS document. This MUST be in the form of a URI.', + }, }, required: ['openapi', 'info'], requiredOneOf: ['paths', 'components', 'webhooks'], extensionsPrefix: 'x-', + documentationLink: 'https://redocly.com/learn/openapi/openapi-visual-reference/openapi#openapi', + description: + 'REQUIRED. This string MUST be the semantic version number of the OpenAPI Specification version that the OpenAPI document uses. The openapi field SHOULD be used by tooling specifications and clients to interpret the OpenAPI document. This is not related to the API info.version string.', }; const License: NodeType = { + ...Oas3Types.License, properties: { - name: { type: 'string' }, - url: { type: 'string' }, - identifier: { type: 'string' }, + ...Oas3Types.License.properties, + identifier: { + type: 'string', + description: + 'An [SPDX-Licenses] expression for the API. The identifier field is mutually exclusive of the url field.', + }, }, - required: ['name'], - extensionsPrefix: 'x-', }; const Info: NodeType = { + ...Oas3Types.Info, properties: { - title: { type: 'string' }, - version: { type: 'string' }, - description: { type: 'string' }, - termsOfService: { type: 'string' }, - summary: { type: 'string' }, - contact: 'Contact', - license: 'License', - 'x-logo': 'Logo', + ...Oas3Types.Info.properties, + summary: { + type: 'string', + description: 'A short summary of the API. This field MAY be used by tooling as required.', + }, }, - required: ['title', 'version'], - extensionsPrefix: 'x-', }; const Components: NodeType = { + ...Oas3Types.Components, properties: { - parameters: 'NamedParameters', - schemas: 'NamedSchemas', - responses: 'NamedResponses', - examples: 'NamedExamples', - requestBodies: 'NamedRequestBodies', - headers: 'NamedHeaders', - securitySchemes: 'NamedSecuritySchemes', - links: 'NamedLinks', - callbacks: 'NamedCallbacks', + ...Oas3Types.Components.properties, pathItems: 'NamedPathItems', }, - extensionsPrefix: 'x-', }; const Operation: NodeType = { @@ -65,11 +62,29 @@ const Operation: NodeType = { tags: { type: 'array', items: { type: 'string' }, + description: + 'A list of tags for API documentation control. Tags can be used for logical grouping of operations by resources or any other qualifier.', + }, + summary: { + type: 'string', + description: 'A short summary of what the operation does.', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/operation#summary', + }, + description: { + type: 'string', + description: 'A verbose explanation of the operation behavior.', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/operation#description', }, - summary: { type: 'string' }, - description: { type: 'string' }, externalDocs: 'ExternalDocs', - operationId: { type: 'string' }, + operationId: { + type: 'string', + description: + 'The operationId is path segment or path fragment in deep links to a specific operation.', + documentationLink: + 'https://redocly.com/learn/openapi/openapi-visual-reference/operation#operationid', + }, parameters: 'ParameterList', security: 'SecurityRequirementList', servers: 'ServerList', @@ -82,6 +97,8 @@ const Operation: NodeType = { 'x-hideTryItPanel': { type: 'boolean' }, }, extensionsPrefix: 'x-', + description: `The Operation Object describes a single API operation on a path, including its parameters, responses, and request body (if applicable). Each path can support more than one operation, but those operations must be unique. A unique operation is a combination of a path and an HTTP method, so two GET or two POST methods for the same path are not allowed.`, + documentationLink: `https://spec.openapis.org/oas/v3.1.0#operation-object`, }; // draft-2020-12 diff --git a/packages/core/src/types/oas3_2.ts b/packages/core/src/types/oas3_2.ts index c0bd1cf1c5..9a9f92329a 100755 --- a/packages/core/src/types/oas3_2.ts +++ b/packages/core/src/types/oas3_2.ts @@ -6,34 +6,65 @@ const Root: NodeType = { ...Oas3_1Types.Root, properties: { ...Oas3_1Types.Root.properties, - $self: { type: 'string' }, + $self: { + type: 'string', + description: + 'This string MUST be in the form of a URI reference as defined by [RFC3986] Section 4.1. The $self field provides the self-assigned URI of this document, which also serves as its base URI in accordance with [RFC3986] Section 5.1.1. Implementations MUST support identifying the targets of API description URIs using the URI defined by this field when it is present. See Establishing the Base URI for the base URI behavior when $self is absent or relative, and see Appendix F for examples of using $self to resolve references.', + }, }, + documentationLink: 'https://spec.openapis.org/oas/v3.2.0.html#security-scheme-object', }; const Tag: NodeType = { ...Oas3_1Types.Tag, properties: { ...Oas3_1Types.Tag.properties, - kind: { type: 'string' }, - parent: { type: 'string' }, - summary: { type: 'string' }, + kind: { + type: 'string', + description: + 'A machine-readable string to categorize what sort of tag it is. Any string value can be used; common uses are nav for Navigation, badge for visible badges, audience for APIs used by different groups. A registry of the most commonly used values is available.', + }, + parent: { + type: 'string', + description: + 'The name of a tag that this tag is nested under. The named tag MUST exist in the API description, and circular references between parent and child tags MUST NOT be used.', + }, + summary: { + type: 'string', + description: 'A short summary of the tag, used for display purposes.', + }, }, + documentationLink: 'https://spec.openapis.org/oas/v3.2.0.html#tag-object', + description: + 'Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.', }; const Server: NodeType = { ...Oas3_1Types.Server, properties: { ...Oas3_1Types.Server.properties, - name: { type: 'string' }, + name: { + type: 'string', + description: 'An optional unique string to refer to the host designated by the URL.', + }, }, + documentationLink: 'https://spec.openapis.org/oas/v3.2.0.html#server-object', + description: 'An object representing a Server.', }; const SecurityScheme: NodeType = { ...Oas3_1Types.SecurityScheme, properties: { ...Oas3_1Types.SecurityScheme.properties, - deprecated: { type: 'boolean' }, // added in OAS 3.2 - oauth2MetadataUrl: { type: 'string' }, // added in OAS 3.2 + deprecated: { + type: 'boolean', + description: + 'Declares this security scheme to be deprecated. Consumers SHOULD refrain from usage of the declared scheme. Default value is false.', + }, // added in OAS 3.2 + oauth2MetadataUrl: { + type: 'string', + description: 'URL to the OAuth2 authorization server metadata [RFC8414]. TLS is required.', + }, // added in OAS 3.2 }, allowed(value) { switch (value?.type) { @@ -126,6 +157,8 @@ const SecurityScheme: NodeType = { ]; } }, + documentationLink: 'https://spec.openapis.org/oas/v3.2.0.html#security-scheme-object', + description: 'Defines a security scheme that can be used by the operations.', }; const OAuth2Flows: NodeType = { @@ -138,13 +171,29 @@ const OAuth2Flows: NodeType = { const DeviceAuthorization: NodeType = { properties: { - deviceAuthorizationUrl: { type: 'string' }, - tokenUrl: { type: 'string' }, - refreshUrl: { type: 'string' }, - scopes: mapOf('string'), + deviceAuthorizationUrl: { + type: 'string', + description: + 'REQUIRED. The device authorization URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS.', + }, + tokenUrl: { + type: 'string', + description: + 'REQUIRED. The token URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS.', + }, + refreshUrl: { + type: 'string', + description: + 'The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. The OAuth2 standard requires the use of TLS.', + }, + scopes: mapOf('string', { + description: + 'REQUIRED. The available scopes for the OAuth2 security scheme. A map between the scope name and a short description for it. The map MAY be empty.', + }), }, required: ['deviceAuthorizationUrl', 'tokenUrl', 'scopes'], extensionsPrefix: 'x-', + description: 'Configuration for the OAuth Device Authorization flow.', }; const PathItem: NodeType = { @@ -160,7 +209,11 @@ const Parameter: NodeType = { ...Oas3_1Types.Parameter, properties: { ...Oas3_1Types.Parameter.properties, - in: { enum: ['query', 'header', 'path', 'cookie', 'querystring'] }, + in: { + description: + 'REQUIRED. The location of the parameter. Possible values are "query", "querystring", "header", "path" or "cookie".', + enum: ['query', 'header', 'path', 'cookie', 'querystring'], + }, }, }; @@ -168,7 +221,10 @@ const Response: Omit = { ...Oas3_1Types.Response, properties: { ...Oas3_1Types.Response.properties, - summary: { type: 'string' }, + summary: { + type: 'string', + description: 'A short summary of the meaning of the response.', + }, }, }; @@ -177,7 +233,10 @@ const MediaType: NodeType = { properties: { ...Oas3_1Types.MediaType.properties, itemSchema: 'Schema', - prefixEncoding: listOf('Encoding'), + prefixEncoding: listOf('Encoding', { + description: + 'A map between a property name and its encoding information, as defined under Encoding By Name. The encoding field SHALL only apply when the media type is multipart or application/x-www-form-urlencoded. If no Encoding Object is provided for a property, the behavior is determined by the default values documented for the Encoding Object. This field MUST NOT be present if prefixEncoding or itemEncoding are present.', + }), itemEncoding: 'Encoding', }, }; @@ -186,7 +245,11 @@ const Discriminator: NodeType = { ...Oas3_1Types.Discriminator, properties: { ...Oas3_1Types.Discriminator.properties, - defaultMapping: { type: 'string' }, + defaultMapping: { + type: 'string', + description: + 'The schema name or URI reference to a schema that is expected to validate the structure of the model when the discriminating property is not present in the payload or contains a value for which there is no explicit or implicit mapping.', + }, }, }; @@ -194,21 +257,56 @@ const Example: NodeType = { ...Oas3_1Types.Example, properties: { ...Oas3_1Types.Example.properties, - dataValue: { resolvable: false }, - serializedValue: { type: 'string' }, + dataValue: { + resolvable: false, + description: + 'An example of the data structure that MUST be valid according to the relevant Schema Object. If this field is present, value MUST be absent.', + }, + serializedValue: { + type: 'string', + description: + 'An example of the serialized form of the value, including encoding and escaping as described under Validating Examples. If dataValue is present, then this field SHOULD contain the serialization of the given data. Otherwise, it SHOULD be the valid serialization of a data value that itself MUST be valid as described for dataValue. This field SHOULD NOT be used if the serialization format is JSON, as the data form is easier to work with. If this field is present, value, and externalValue MUST be absent.', + }, }, }; const Xml: NodeType = { properties: { - nodeType: { type: 'string', enum: ['element', 'attribute', 'text', 'cdata', 'none'] }, - name: { type: 'string' }, - namespace: { type: 'string' }, - prefix: { type: 'string' }, - attribute: { type: 'boolean' }, // Deprecated in OAS 3.2: Use nodeType: "attribute" instead - wrapped: { type: 'boolean' }, // Deprecated in OAS 3.2: Use nodeType: "element" instead + nodeType: { + type: 'string', + enum: ['element', 'attribute', 'text', 'cdata', 'none'], + description: + 'One of element, attribute, text, cdata, or none, as explained under XML Node Types. The default value is none if $ref, $dynamicRef, or type: "array" is present in the Schema Object containing the XML Object, and element otherwise.', + }, + name: { + type: 'string', + description: + 'Sets the name of the element/attribute corresponding to the schema, replacing the name that was inferred as described under XML Node Names. This field SHALL be ignored if the nodeType is text, cdata, or none.', + }, + namespace: { + type: 'string', + description: + 'The IRI ([RFC3987]) of the namespace definition. Value MUST be in the form of a non-relative IRI.', + }, + prefix: { + type: 'string', + description: 'The prefix to be used for the name.', + }, + attribute: { + type: 'boolean', + description: + 'Declares whether the property definition translates to an attribute instead of an element. Default value is false. If nodeType is present, this field MUST NOT be present.Deprecated: Use nodeType: "attribute" instead of attribute: true.', + }, + wrapped: { + type: 'boolean', + description: + 'MAY be used only for an array definition. Signifies whether the array is wrapped (for example, ) or unwrapped (). Default value is false. The definition takes effect only when defined alongside type being "array" (outside the items). If nodeType is present, this field MUST NOT be present. Deprecated: Use nodeType: "element" instead of wrapped: true.', + }, // Deprecated in OAS 3.2: Use nodeType: "element" instead }, extensionsPrefix: 'x-', + documentationLink: 'https://spec.openapis.org/oas/v3.2.0.html#xml-object', + description: + 'A metadata object that allows for more fine-tuned XML model definitions. When using a Schema Object with XML, if no XML Object is present, the behavior is determined by the XML Object’s default field values.', }; // based on draft-2020-12 diff --git a/tests/smoke/basic/pre-built/redoc.html b/tests/smoke/basic/pre-built/redoc.html index a2dab9643b..5675a287c8 100644 --- a/tests/smoke/basic/pre-built/redoc.html +++ b/tests/smoke/basic/pre-built/redoc.html @@ -12,284 +12,284 @@ margin: 0; } - -

Sample API (1.0.0)

Download OpenAPI specification:

Get a greeting message

Responses

Response samples

Content type
application/json
{
  • "message": "string"
}
+ " fill="currentColor">

Sample API (1.0.0)

Download OpenAPI specification:

Get a greeting message

Responses

Response samples

Content type
application/json
{
  • "message": "string"
}