diff --git a/packages/openapi-model/src/3.0.3/model/BasicNode.ts b/packages/openapi-model/src/3.0.3/model/BasicNode.ts index 0273e558..0282b29e 100644 --- a/packages/openapi-model/src/3.0.3/model/BasicNode.ts +++ b/packages/openapi-model/src/3.0.3/model/BasicNode.ts @@ -12,7 +12,7 @@ export interface TreeParent { readonly root: OpenAPIModel; } -export class BasicNode +export abstract class BasicNode implements TreeNode, Disposable, SpecificationExtensionsModel { readonly root: OpenAPIModel; @@ -25,6 +25,8 @@ export class BasicNode this.extensions = new Map(); } + abstract children(): IterableIterator>; + // eslint-disable-next-line class-methods-use-this dispose(): void {} diff --git a/packages/openapi-model/src/3.0.3/model/Callback.ts b/packages/openapi-model/src/3.0.3/model/Callback.ts index f3d27fdb..b1baf8e0 100644 --- a/packages/openapi-model/src/3.0.3/model/Callback.ts +++ b/packages/openapi-model/src/3.0.3/model/Callback.ts @@ -5,7 +5,7 @@ import { BidiMap } from '../../BidiMap'; import { BasicNode } from './BasicNode'; import { PathItem } from './PathItem'; -import type { CallbackModel, CallbackModelParent, PathItemModel } from './types'; +import type { CallbackModel, CallbackModelParent, PathItemModel, TreeNode } from './types'; import type { ParametrisedURLString } from '@fresha/api-tools-core'; /** @@ -19,6 +19,10 @@ export class Callback extends BasicNode implements Callback this.paths = new BidiMap(); } + children(): IterableIterator> { + return this.paths.values(); + } + getItemUrl(pathItem: PathItemModel): string | undefined { return this.paths.getKey(pathItem); } diff --git a/packages/openapi-model/src/3.0.3/model/Components.ts b/packages/openapi-model/src/3.0.3/model/Components.ts index 956eb2a9..9bf5c247 100644 --- a/packages/openapi-model/src/3.0.3/model/Components.ts +++ b/packages/openapi-model/src/3.0.3/model/Components.ts @@ -29,6 +29,7 @@ import type { CreateSchemaOptions, SchemaModel, SecuritySchemaModel, + TreeNode, } from './types'; import type { CommonMarkString } from '@fresha/api-tools-core'; @@ -59,6 +60,36 @@ export class Components extends BasicNode implements Comp this.callbacks = new Map(); } + *children(): IterableIterator> { + for (const schema of this.schemas.values()) { + yield schema; + } + for (const response of this.responses.values()) { + yield response; + } + for (const parameter of this.parameters.values()) { + yield parameter; + } + for (const example of this.examples.values()) { + yield example; + } + for (const requestBody of this.requestBodies.values()) { + yield requestBody; + } + for (const header of this.headers.values()) { + yield header; + } + for (const securitySchema of this.securitySchemes.values()) { + yield securitySchema; + } + for (const link of this.links.values()) { + yield link; + } + for (const callback of this.callbacks.values()) { + yield callback; + } + } + isEmpty(): boolean { return ( !this.schemas.size && diff --git a/packages/openapi-model/src/3.0.3/model/Contact.ts b/packages/openapi-model/src/3.0.3/model/Contact.ts index 0714f06b..6cd45d23 100644 --- a/packages/openapi-model/src/3.0.3/model/Contact.ts +++ b/packages/openapi-model/src/3.0.3/model/Contact.ts @@ -1,6 +1,6 @@ import { BasicNode } from './BasicNode'; -import type { ContactModel, ContactModelParent } from './types'; +import type { ContactModel, ContactModelParent, TreeNode } from './types'; import type { Nullable, URLString, EmailString } from '@fresha/api-tools-core'; /** @@ -17,4 +17,8 @@ export class Contact extends BasicNode implements ContactMod this.url = null; this.email = null; } + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + } } diff --git a/packages/openapi-model/src/3.0.3/model/Discriminator.ts b/packages/openapi-model/src/3.0.3/model/Discriminator.ts index 2eee8156..42db4c3c 100644 --- a/packages/openapi-model/src/3.0.3/model/Discriminator.ts +++ b/packages/openapi-model/src/3.0.3/model/Discriminator.ts @@ -1,6 +1,6 @@ import { BasicNode } from './BasicNode'; -import type { DiscriminatorModel, DiscriminatorModelParent } from './types'; +import type { DiscriminatorModel, DiscriminatorModelParent, TreeNode } from './types'; /** * @see http://spec.openapis.org/oas/v3.0.3#discriminator-object @@ -17,4 +17,8 @@ export class Discriminator this.propertyName = propertyName; this.mapping = new Map(); } + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + } } diff --git a/packages/openapi-model/src/3.0.3/model/Encoding.ts b/packages/openapi-model/src/3.0.3/model/Encoding.ts index b9cb84b2..0a8f1684 100644 --- a/packages/openapi-model/src/3.0.3/model/Encoding.ts +++ b/packages/openapi-model/src/3.0.3/model/Encoding.ts @@ -8,6 +8,7 @@ import type { EncodingModelParent, EncodingSerializationStyle, HeaderModel, + TreeNode, } from './types'; import type { Nullable } from '@fresha/api-tools-core'; @@ -30,6 +31,10 @@ export class Encoding extends BasicNode implements Encoding this.allowReserved = false; } + children(): IterableIterator> { + return this.headers.values(); + } + getHeader(name: string): HeaderModel | undefined { return this.headers.get(name); } diff --git a/packages/openapi-model/src/3.0.3/model/Example.ts b/packages/openapi-model/src/3.0.3/model/Example.ts index 2e35542c..14cf3386 100644 --- a/packages/openapi-model/src/3.0.3/model/Example.ts +++ b/packages/openapi-model/src/3.0.3/model/Example.ts @@ -1,6 +1,6 @@ import { BasicNode } from './BasicNode'; -import type { ExampleModel, ExampleModelParent } from './types'; +import type { ExampleModel, ExampleModelParent, TreeNode } from './types'; import type { Nullable, URLString, JSONValue } from '@fresha/api-tools-core'; /** @@ -19,4 +19,9 @@ export class Example extends BasicNode implements ExampleMod this.value = null; this.externalValue = null; } + + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + } } diff --git a/packages/openapi-model/src/3.0.3/model/ExternalDocumentation.ts b/packages/openapi-model/src/3.0.3/model/ExternalDocumentation.ts index a4e86b4a..faa755aa 100644 --- a/packages/openapi-model/src/3.0.3/model/ExternalDocumentation.ts +++ b/packages/openapi-model/src/3.0.3/model/ExternalDocumentation.ts @@ -1,6 +1,6 @@ import { BasicNode } from './BasicNode'; -import type { ExternalDocumentationModel, ExternalDocumentationModelParent } from './types'; +import type { ExternalDocumentationModel, ExternalDocumentationModelParent, TreeNode } from './types'; import type { CommonMarkString, Nullable, URLString } from '@fresha/api-tools-core'; /** @@ -18,4 +18,8 @@ export class ExternalDocumentation this.url = url; this.description = null; } + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + } } diff --git a/packages/openapi-model/src/3.0.3/model/Header.ts b/packages/openapi-model/src/3.0.3/model/Header.ts index cd5adfdb..bd84b46e 100644 --- a/packages/openapi-model/src/3.0.3/model/Header.ts +++ b/packages/openapi-model/src/3.0.3/model/Header.ts @@ -11,6 +11,7 @@ import type { HeaderParameterSerializationStyle, MediaTypeModel, SchemaModel, + TreeNode, } from './types'; import type { Nullable, JSONValue, MIMETypeString, CommonMarkString } from '@fresha/api-tools-core'; @@ -41,6 +42,18 @@ export class Header extends BasicNode implements HeaderModel this.content = new Map(); } + *children(): IterableIterator> { + if (this.schema) { + yield this.schema; + } + for (const example of this.examples.values()) { + yield example; + } + for (const mediaType of this.content.values()) { + yield mediaType; + } + } + getExample(name: string): ExampleModel | undefined { return this.examples.get(name); } diff --git a/packages/openapi-model/src/3.0.3/model/Info.ts b/packages/openapi-model/src/3.0.3/model/Info.ts index de183701..96cec493 100644 --- a/packages/openapi-model/src/3.0.3/model/Info.ts +++ b/packages/openapi-model/src/3.0.3/model/Info.ts @@ -2,7 +2,7 @@ import { BasicNode } from './BasicNode'; import { Contact } from './Contact'; import { License } from './License'; -import type { InfoModel, InfoModelParent } from './types'; +import type { InfoModel, InfoModelParent, TreeNode } from './types'; import type { CommonMarkString, Nullable, URLString, VersionString } from '@fresha/api-tools-core'; /** @@ -25,4 +25,9 @@ export class Info extends BasicNode implements InfoModel { this.license = new License(this, 'UNLICENSED'); this.version = version; } + + *children(): IterableIterator> { + yield this.contact; + yield this.license; + } } diff --git a/packages/openapi-model/src/3.0.3/model/License.ts b/packages/openapi-model/src/3.0.3/model/License.ts index e60dbb8b..0975e384 100644 --- a/packages/openapi-model/src/3.0.3/model/License.ts +++ b/packages/openapi-model/src/3.0.3/model/License.ts @@ -1,6 +1,6 @@ import { BasicNode } from './BasicNode'; -import type { LicenseModel, LicenseModelParent } from './types'; +import type { LicenseModel, LicenseModelParent, TreeNode } from './types'; import type { Nullable } from '@fresha/api-tools-core'; /** @@ -15,4 +15,7 @@ export class License extends BasicNode implements LicenseMod this.name = name; this.url = null; } + + *children(): IterableIterator> { + } } diff --git a/packages/openapi-model/src/3.0.3/model/Link.ts b/packages/openapi-model/src/3.0.3/model/Link.ts index 352e692e..67aabec9 100644 --- a/packages/openapi-model/src/3.0.3/model/Link.ts +++ b/packages/openapi-model/src/3.0.3/model/Link.ts @@ -3,7 +3,7 @@ import assert from 'assert'; import { BasicNode } from './BasicNode'; import type { Server } from './Server'; -import type { LinkModel, LinkModelParent } from './types'; +import type { LinkModel, LinkModelParent, TreeNode } from './types'; import type { Nullable, JSONValue } from '@fresha/api-tools-core'; /** @@ -27,6 +27,9 @@ export class Link extends BasicNode implements LinkModel { this.server = null; } + *children(): IterableIterator> { + } + getParameter(key: string): JSONValue | undefined { return this.parameters.get(key); } diff --git a/packages/openapi-model/src/3.0.3/model/MediaType.ts b/packages/openapi-model/src/3.0.3/model/MediaType.ts index 75f52ded..7a96c07b 100644 --- a/packages/openapi-model/src/3.0.3/model/MediaType.ts +++ b/packages/openapi-model/src/3.0.3/model/MediaType.ts @@ -12,6 +12,7 @@ import type { MediaTypeModelParent, CreateOrSetSchemaOptions, SchemaModel, + TreeNode, } from './types'; import type { Nullable, JSONValue } from '@fresha/api-tools-core'; @@ -32,6 +33,18 @@ export class MediaType extends BasicNode implements MediaT this.encoding = new Map(); } + *children(): IterableIterator> { + if (this.schema) { + yield this.schema; + } + for (const example of this.examples.values()) { + yield example; + } + for (const encoding of this.encoding.values()) { + yield encoding; + } + } + setSchema(options: CreateOrSetSchemaOptions): SchemaModel { const result = SchemaFactory.createOrGet(this, options); this.schema = result; diff --git a/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthAuthorisationCodeFlow.ts b/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthAuthorisationCodeFlow.ts index df53028d..e064b58c 100644 --- a/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthAuthorisationCodeFlow.ts +++ b/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthAuthorisationCodeFlow.ts @@ -1,6 +1,6 @@ import { OAuthFlowBase } from './OAuthFlowBase'; -import type { OAuthAuthorizationCodeFlowModel, OAuthFlowModelParent } from '../types'; +import type { OAuthAuthorizationCodeFlowModel, OAuthFlowModelParent, TreeNode } from '../types'; import type { URLString } from '@fresha/api-tools-core'; /** @@ -19,4 +19,9 @@ export class OAuthAuthorisationCodeFlow this.authorizationUrl = authorizationUrl; this.tokenUrl = tokenUrl; } + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + + } } diff --git a/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthClientCredentialsFlow.ts b/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthClientCredentialsFlow.ts index 3ed6ada2..720b2b9d 100644 --- a/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthClientCredentialsFlow.ts +++ b/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthClientCredentialsFlow.ts @@ -1,6 +1,6 @@ import { OAuthFlowBase } from './OAuthFlowBase'; -import type { OAuthClientCredentialsFlowModel, OAuthFlowModelParent } from '../types'; +import type { OAuthClientCredentialsFlowModel, OAuthFlowModelParent, TreeNode } from '../types'; import type { URLString } from '@fresha/api-tools-core'; /** @@ -17,4 +17,9 @@ export class OAuthClientCredentialsFlow super(parent, 'clientCredentials'); this.tokenUrl = tokenUrl; } + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + + } } diff --git a/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthFlows.ts b/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthFlows.ts index ebb53cc9..f0c908ef 100644 --- a/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthFlows.ts +++ b/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthFlows.ts @@ -7,6 +7,7 @@ import type { OAuthFlowsModelParent, OAuthImplicitFlowModel, OAuthPasswordFlowModel, + TreeNode, } from '../types'; import type { Nullable } from '@fresha/api-tools-core'; @@ -26,4 +27,19 @@ export class OAuthFlows extends BasicNode implements OAut this.clientCredentials = null; this.authorizationCode = null; } + + *children(): IterableIterator> { + if (this.implicit) { + yield this.implicit; + } + if (this.password) { + yield this.password; + } + if (this.clientCredentials) { + yield this.clientCredentials; + } + if (this.authorizationCode) { + yield this.authorizationCode; + } + } } diff --git a/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthImplicitFlow.ts b/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthImplicitFlow.ts index 036e3a2c..bd75952c 100644 --- a/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthImplicitFlow.ts +++ b/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthImplicitFlow.ts @@ -1,6 +1,6 @@ import { OAuthFlowBase } from './OAuthFlowBase'; -import type { OAuthFlowModelParent, OAuthImplicitFlowModel } from '../types'; +import type { OAuthFlowModelParent, OAuthImplicitFlowModel, TreeNode } from '../types'; import type { URLString } from '@fresha/api-tools-core'; /** @@ -14,4 +14,9 @@ export class OAuthImplicitFlow extends OAuthFlowBase implements OAuthImplicitFlo super(parent, 'implicit'); this.authorizationUrl = authorizationUrl; } + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + + } } diff --git a/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthPasswordFlow.ts b/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthPasswordFlow.ts index 99720e76..eddf32da 100644 --- a/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthPasswordFlow.ts +++ b/packages/openapi-model/src/3.0.3/model/OAuthFlow/OAuthPasswordFlow.ts @@ -1,6 +1,6 @@ import { OAuthFlowBase } from './OAuthFlowBase'; -import type { OAuthFlowModelParent, OAuthPasswordFlowModel } from '../types'; +import type { OAuthFlowModelParent, OAuthPasswordFlowModel, TreeNode } from '../types'; import type { URLString } from '@fresha/api-tools-core'; /** @@ -14,4 +14,9 @@ export class OAuthPasswordFlow extends OAuthFlowBase implements OAuthPasswordFlo super(parent, 'password'); this.tokenUrl = tokenUrl; } + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + + } } diff --git a/packages/openapi-model/src/3.0.3/model/OpenAPI.ts b/packages/openapi-model/src/3.0.3/model/OpenAPI.ts index e8aad1a0..0c542d76 100644 --- a/packages/openapi-model/src/3.0.3/model/OpenAPI.ts +++ b/packages/openapi-model/src/3.0.3/model/OpenAPI.ts @@ -18,6 +18,7 @@ import type { SpecificationExtensionsModel, OpenAPIModelFactory, SecurityRequirementModel, + TreeNode, } from './types'; import type { CommonMarkString, @@ -59,6 +60,24 @@ export class OpenAPI implements OpenAPIModel, SpecificationExtensionsModel { this.extensions = new Map(); } + *children(): IterableIterator> { + yield this.info; + for (const server of this.servers) { + yield server; + } + yield this.paths; + yield this.components; + for (const security of this.security) { + yield security; + } + for (const tag of this.tags) { + yield tag; + } + if (this.externalDocs) { + yield this.externalDocs; + } + } + get root(): OpenAPIModel { return this; } diff --git a/packages/openapi-model/src/3.0.3/model/Operation.ts b/packages/openapi-model/src/3.0.3/model/Operation.ts index 3c4973ee..3f0a08c7 100644 --- a/packages/openapi-model/src/3.0.3/model/Operation.ts +++ b/packages/openapi-model/src/3.0.3/model/Operation.ts @@ -21,6 +21,7 @@ import type { ResponseModel, SecurityRequirementModel, ServerModel, + TreeNode, } from './types'; import type { CommonMarkString, Nullable, ParametrisedURLString } from '@fresha/api-tools-core'; @@ -57,6 +58,30 @@ export class Operation extends BasicNode implements Operat this.servers = []; } + *children(): IterableIterator> { + if (this.externalDocumentation) { + yield this.externalDocumentation; + } + for (const parameter of this.parameters) { + yield parameter; + } + if (this.requestBody) { + yield this.requestBody; + } + yield this.responses; + for (const callback of this.callbacks.values()) { + yield callback; + } + if (this.security) { + for (const security of this.security) { + yield security; + } + } + for (const server of this.servers) { + yield server; + } + } + get httpMethod(): PathItemOperationKey { return this.parent.getOperationKeyOrThrow(this); } diff --git a/packages/openapi-model/src/3.0.3/model/Parameter/ParameterBase.ts b/packages/openapi-model/src/3.0.3/model/Parameter/ParameterBase.ts index 85e77db5..7b3094b9 100644 --- a/packages/openapi-model/src/3.0.3/model/Parameter/ParameterBase.ts +++ b/packages/openapi-model/src/3.0.3/model/Parameter/ParameterBase.ts @@ -12,6 +12,7 @@ import type { ParameterLocation, ParameterModelParent, SchemaModel, + TreeNode, } from '../types'; import type { JSONValue, MIMETypeString, Nullable } from '@fresha/api-tools-core'; @@ -42,6 +43,18 @@ export abstract class ParameterBase extends BasicNode { this.required = false; } + *children(): IterableIterator> { + if (this.schema) { + yield this.schema; + } + for (const mediaType of this.content.values()) { + yield mediaType; + } + for (const example of this.examples.values()) { + yield example; + } + } + getExample(name: string): ExampleModel | undefined { return this.examples.get(name); } diff --git a/packages/openapi-model/src/3.0.3/model/PathItem.ts b/packages/openapi-model/src/3.0.3/model/PathItem.ts index 6948b343..0c312236 100644 --- a/packages/openapi-model/src/3.0.3/model/PathItem.ts +++ b/packages/openapi-model/src/3.0.3/model/PathItem.ts @@ -13,6 +13,7 @@ import type { PathItemModelParent, ParameterModel, ServerModel, + TreeNode, } from './types'; import type { Nullable, ParametrisedURLString } from '@fresha/api-tools-core'; @@ -35,6 +36,12 @@ export class PathItem extends BasicNode implements PathItem this.parameters = []; } + *children(): IterableIterator> { + for (const [, operation] of this.operations()) { + yield operation; + } + } + get pathUrl(): ParametrisedURLString { return this.parent.getItemUrlOrThrow(this); } diff --git a/packages/openapi-model/src/3.0.3/model/Paths.ts b/packages/openapi-model/src/3.0.3/model/Paths.ts index 8405de8d..85bf42f6 100644 --- a/packages/openapi-model/src/3.0.3/model/Paths.ts +++ b/packages/openapi-model/src/3.0.3/model/Paths.ts @@ -4,7 +4,7 @@ import { BidiMap } from '../../BidiMap'; import { BasicNode } from './BasicNode'; -import type { PathItemModel, PathsModel, PathsModelParent } from './types'; +import type { PathItemModel, PathsModel, PathsModelParent, TreeNode } from './types'; import type { ParametrisedURLString } from '@fresha/api-tools-core'; /** @@ -18,6 +18,10 @@ export class Paths extends BasicNode implements PathsModel { this.items = new BidiMap(); } + children(): IterableIterator> { + return this.items.values(); + } + getItem(url: ParametrisedURLString): PathItemModel | undefined { return this.items.get(url); } diff --git a/packages/openapi-model/src/3.0.3/model/RequestBody.ts b/packages/openapi-model/src/3.0.3/model/RequestBody.ts index c3750051..78439e2c 100644 --- a/packages/openapi-model/src/3.0.3/model/RequestBody.ts +++ b/packages/openapi-model/src/3.0.3/model/RequestBody.ts @@ -3,7 +3,7 @@ import assert from 'assert'; import { BasicNode } from './BasicNode'; import { MediaType } from './MediaType'; -import type { MediaTypeModel, RequestBodyModel, RequestBodyModelParent } from './types'; +import type { MediaTypeModel, RequestBodyModel, RequestBodyModelParent, TreeNode } from './types'; import type { MIMETypeString, Nullable } from '@fresha/api-tools-core'; /** @@ -21,6 +21,10 @@ export class RequestBody extends BasicNode implements Re this.required = false; } + children(): IterableIterator> { + return this.content.values(); + } + getContent(mimeType: MIMETypeString): MediaTypeModel | undefined { return this.content.get(mimeType); } diff --git a/packages/openapi-model/src/3.0.3/model/Response.ts b/packages/openapi-model/src/3.0.3/model/Response.ts index c1ac9fd4..d5da5ee0 100644 --- a/packages/openapi-model/src/3.0.3/model/Response.ts +++ b/packages/openapi-model/src/3.0.3/model/Response.ts @@ -11,6 +11,7 @@ import type { MediaTypeModel, ResponseModel, ResponseModelParent, + TreeNode, } from './types'; import type { MIMETypeString } from '@fresha/api-tools-core'; @@ -31,6 +32,18 @@ export class Response extends BasicNode implements Response this.links = new Map(); } + *children(): IterableIterator> { + for (const header of this.headers.values()) { + yield header + } + for (const content of this.content.values()) { + yield content; + } + for (const link of this.links.values()) { + yield link; + } + } + getHeader(name: string): HeaderModel | undefined { return this.headers.get(name); } diff --git a/packages/openapi-model/src/3.0.3/model/Responses.ts b/packages/openapi-model/src/3.0.3/model/Responses.ts index 2c403d8d..fb0c1b31 100644 --- a/packages/openapi-model/src/3.0.3/model/Responses.ts +++ b/packages/openapi-model/src/3.0.3/model/Responses.ts @@ -3,7 +3,7 @@ import assert from 'assert'; import { BasicNode } from './BasicNode'; import { Response } from './Response'; -import type { HTTPStatusCode, ResponseModel, ResponsesModel, ResponsesModelParent } from './types'; +import type { HTTPStatusCode, ResponseModel, ResponsesModel, ResponsesModelParent, TreeNode } from './types'; import type { CommonMarkString, Nullable } from '@fresha/api-tools-core'; /** @@ -19,6 +19,15 @@ export class Responses extends BasicNode implements Respon this.codes = new Map(); } + *children(): IterableIterator> { + if (this.default) { + yield this.default; + } + for (const response of this.codes.values()) { + yield response; + } + } + setDefaultResponse(description: string): ResponseModel { const response = new Response(this, description); this.default = response; diff --git a/packages/openapi-model/src/3.0.3/model/Schema.ts b/packages/openapi-model/src/3.0.3/model/Schema.ts index 214f2f22..b3956cc1 100644 --- a/packages/openapi-model/src/3.0.3/model/Schema.ts +++ b/packages/openapi-model/src/3.0.3/model/Schema.ts @@ -17,6 +17,7 @@ import type { SchemaPropertyObject, SchemaType, XMLModel, + TreeNode, } from './types'; import type { CommonMarkString, JSONValue, Nullable } from '@fresha/api-tools-core'; @@ -301,6 +302,39 @@ export class Schema extends BasicNode implements SchemaModel this.deprecated = false; } + *children(): IterableIterator> { + for (const alt of this.allOf) { + yield alt; + } + for (const alt of this.oneOf) { + yield alt; + } + for (const alt of this.anyOf) { + yield alt; + } + if (this.not) { + yield this.not; + } + if (this.items) { + yield this.items; + } + for (const prop of this.properties.values()) { + yield prop; + } + if (this.additionalProperties && typeof this.additionalProperties !== 'boolean') { + yield this.additionalProperties; + } + if (this.discriminator) { + yield this.discriminator; + } + if (this.xml) { + yield this.xml; + } + if (this.externalDocs) { + yield this.externalDocs; + } + } + isComposite(): boolean { return !!(this.allOf.length || this.oneOf.length || this.anyOf.length); } diff --git a/packages/openapi-model/src/3.0.3/model/SecurityRequirement.ts b/packages/openapi-model/src/3.0.3/model/SecurityRequirement.ts index bc186116..021cecf9 100644 --- a/packages/openapi-model/src/3.0.3/model/SecurityRequirement.ts +++ b/packages/openapi-model/src/3.0.3/model/SecurityRequirement.ts @@ -2,7 +2,7 @@ import assert from 'assert'; import { BasicNode } from './BasicNode'; -import type { SecurityRequirementModel, SecurityRequirementModelParent } from './types'; +import type { SecurityRequirementModel, SecurityRequirementModelParent, TreeNode } from './types'; /** * @see http://spec.openapis.org/oas/v3.0.3#security-requirement-object @@ -18,6 +18,9 @@ export class SecurityRequirement this.scopes = new Map(); } + *children(): IterableIterator> { + } + getScopes(schemeName: string): string[] | undefined { return this.scopes.get(schemeName); } diff --git a/packages/openapi-model/src/3.0.3/model/SecurityScheme/APIKeySecurityScheme.ts b/packages/openapi-model/src/3.0.3/model/SecurityScheme/APIKeySecurityScheme.ts index 7a304c9f..01cb7eb3 100644 --- a/packages/openapi-model/src/3.0.3/model/SecurityScheme/APIKeySecurityScheme.ts +++ b/packages/openapi-model/src/3.0.3/model/SecurityScheme/APIKeySecurityScheme.ts @@ -1,6 +1,6 @@ import { SecuritySchemeBase } from './SecuritySchemeBase'; -import type { APIKeySecuritySchemaModel, SecuritySchemaModelParent } from '../types'; +import type { APIKeySecuritySchemaModel, SecuritySchemaModelParent, TreeNode } from '../types'; /** * @see http://spec.openapis.org/oas/v3.0.3#security-scheme-object @@ -19,4 +19,9 @@ export class APIKeySecurityScheme extends SecuritySchemeBase implements APIKeySe this.name = name; this.in = location; } + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + + } } diff --git a/packages/openapi-model/src/3.0.3/model/SecurityScheme/HTTPSecurityScheme.ts b/packages/openapi-model/src/3.0.3/model/SecurityScheme/HTTPSecurityScheme.ts index 6527bb38..c9f192ef 100644 --- a/packages/openapi-model/src/3.0.3/model/SecurityScheme/HTTPSecurityScheme.ts +++ b/packages/openapi-model/src/3.0.3/model/SecurityScheme/HTTPSecurityScheme.ts @@ -2,7 +2,7 @@ import { Schema, SchemaFactory } from '../Schema'; import { SecuritySchemeBase } from './SecuritySchemeBase'; -import type { HTTPSecuritySchemaModel, SchemaModel, SecuritySchemaModelParent } from '../types'; +import type { HTTPSecuritySchemaModel, SchemaModel, SecuritySchemaModelParent, TreeNode } from '../types'; import type { Nullable } from '@fresha/api-tools-core'; /** @@ -18,4 +18,9 @@ export class HTTPSecurityScheme extends SecuritySchemeBase implements HTTPSecuri this.scheme = scheme ?? SchemaFactory.create(this, null); this.bearerFormat = null; } + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + + } } diff --git a/packages/openapi-model/src/3.0.3/model/SecurityScheme/OAuth2SecurityScheme.ts b/packages/openapi-model/src/3.0.3/model/SecurityScheme/OAuth2SecurityScheme.ts index bc8abb5e..35094e65 100644 --- a/packages/openapi-model/src/3.0.3/model/SecurityScheme/OAuth2SecurityScheme.ts +++ b/packages/openapi-model/src/3.0.3/model/SecurityScheme/OAuth2SecurityScheme.ts @@ -2,7 +2,7 @@ import { OAuthFlows } from '../OAuthFlow'; import { SecuritySchemeBase } from './SecuritySchemeBase'; -import type { OAuth2SecuritySchemaModel, SecuritySchemaModelParent } from '../types'; +import type { OAuth2SecuritySchemaModel, SecuritySchemaModelParent, TreeNode } from '../types'; /** * @see http://spec.openapis.org/oas/v3.0.3#security-scheme-object @@ -15,4 +15,8 @@ export class OAuth2SecurityScheme extends SecuritySchemeBase implements OAuth2Se super(parent, 'oauth2'); this.flows = new OAuthFlows(this); } + + *children(): IterableIterator> { + yield this.flows; + } } diff --git a/packages/openapi-model/src/3.0.3/model/SecurityScheme/OpenIdConnectSecurityScheme.ts b/packages/openapi-model/src/3.0.3/model/SecurityScheme/OpenIdConnectSecurityScheme.ts index 7b529aa9..49e584cd 100644 --- a/packages/openapi-model/src/3.0.3/model/SecurityScheme/OpenIdConnectSecurityScheme.ts +++ b/packages/openapi-model/src/3.0.3/model/SecurityScheme/OpenIdConnectSecurityScheme.ts @@ -1,6 +1,6 @@ import { SecuritySchemeBase } from './SecuritySchemeBase'; -import type { OpenIDConnectSecuritySchemaModel, SecuritySchemaModelParent } from '../types'; +import type { OpenIDConnectSecuritySchemaModel, SecuritySchemaModelParent, TreeNode } from '../types'; import type { URLString } from '@fresha/api-tools-core'; /** @@ -17,4 +17,9 @@ export class OpenIdConnectSecurityScheme super(parent, 'openIdConnect'); this.openIdConnectUrl = openIdConnectUrl; } + + // eslint-disable-next-line class-methods-use-this + *children(): IterableIterator> { + + } } diff --git a/packages/openapi-model/src/3.0.3/model/Server.ts b/packages/openapi-model/src/3.0.3/model/Server.ts index 8940ee96..497592f2 100644 --- a/packages/openapi-model/src/3.0.3/model/Server.ts +++ b/packages/openapi-model/src/3.0.3/model/Server.ts @@ -3,7 +3,7 @@ import assert from 'assert'; import { BasicNode } from './BasicNode'; import { ServerVariable } from './ServerVariable'; -import type { ServerModel, ServerModelParent, ServerVariableModel } from './types'; +import type { ServerModel, ServerModelParent, ServerVariableModel, TreeNode } from './types'; import type { Nullable } from '@fresha/api-tools-core'; const isValidVariableName = (str: string): boolean => !!str; @@ -31,6 +31,10 @@ export class Server extends BasicNode implements ServerModel } } + children(): IterableIterator> { + return this.mVariables.values(); + } + get url(): string { return this.mUrl; } diff --git a/packages/openapi-model/src/3.0.3/model/ServerVariable.ts b/packages/openapi-model/src/3.0.3/model/ServerVariable.ts index 76674577..de55271c 100644 --- a/packages/openapi-model/src/3.0.3/model/ServerVariable.ts +++ b/packages/openapi-model/src/3.0.3/model/ServerVariable.ts @@ -1,6 +1,6 @@ import { BasicNode } from './BasicNode'; -import type { ServerVariableModel, ServerVariableModelParent } from './types'; +import type { ServerVariableModel, ServerVariableModelParent, TreeNode } from './types'; import type { Nullable } from '@fresha/api-tools-core'; /** @@ -21,6 +21,10 @@ export class ServerVariable this.description = null; } + *children(): IterableIterator> { + + } + addEnum(...values: string[]): void { for (const value of values) { this.enum.add(value); diff --git a/packages/openapi-model/src/3.0.3/model/Tag.ts b/packages/openapi-model/src/3.0.3/model/Tag.ts index dd740603..2d3f6fd8 100644 --- a/packages/openapi-model/src/3.0.3/model/Tag.ts +++ b/packages/openapi-model/src/3.0.3/model/Tag.ts @@ -2,7 +2,7 @@ import { CommonMarkString, Nullable } from '@fresha/api-tools-core'; import { BasicNode } from './BasicNode'; -import type { ExternalDocumentationModel, TagModel, TagModelParent } from './types'; +import type { ExternalDocumentationModel, TagModel, TagModelParent, TreeNode } from './types'; /** * @see http://spec.openapis.org/oas/v3.0.3#tag-object @@ -18,4 +18,10 @@ export class Tag extends BasicNode implements TagModel { this.description = null; this.externalDocs = null; } + + *children(): IterableIterator> { + if (this.externalDocs) { + yield this.externalDocs; + } + } } diff --git a/packages/openapi-model/src/3.0.3/model/TreeNodeVisitor.test.ts b/packages/openapi-model/src/3.0.3/model/TreeNodeVisitor.test.ts new file mode 100644 index 00000000..78fba80d --- /dev/null +++ b/packages/openapi-model/src/3.0.3/model/TreeNodeVisitor.test.ts @@ -0,0 +1,35 @@ +import fs from 'fs'; +import path from 'path'; + +import yaml from 'yaml'; + +import { OpenAPIReader } from './OpenAPIReader'; + +import type { OpenAPIObject } from '../types'; +import { TreeNode } from './types'; + +const lines: string[] = []; + +const visit = (obj: { children: () => IterableIterator>; }, indent: number = 0): void => { + lines.push(`${obj.constructor.name}`.padStart(indent)); + for (const child of obj.children()) { + visit(child, indent + 2); + } +}; + +test('example api', + () => { + const reader = new OpenAPIReader(); + + const inputText = fs.readFileSync( + path.join(__dirname, '..', '..', '..', 'examples', 'json-api.yaml'), + 'utf-8', + ); + const inputData = yaml.parse(inputText) as OpenAPIObject; + + const openapi = reader.parse(inputData); + visit(openapi); + + global.console.log(lines.join('\n')); + }, +); diff --git a/packages/openapi-model/src/3.0.3/model/XML.ts b/packages/openapi-model/src/3.0.3/model/XML.ts index 784b9936..903b5557 100644 --- a/packages/openapi-model/src/3.0.3/model/XML.ts +++ b/packages/openapi-model/src/3.0.3/model/XML.ts @@ -1,6 +1,6 @@ import { BasicNode } from './BasicNode'; -import type { XMLModel, XMLModelParent } from './types'; +import type { TreeNode, XMLModel, XMLModelParent } from './types'; import type { Nullable } from '@fresha/api-tools-core'; /** @@ -21,4 +21,8 @@ export class XML extends BasicNode implements XMLModel { this.attribute = false; this.wrapped = false; } + + *children(): IterableIterator> { + + } } diff --git a/packages/openapi-model/src/3.0.3/model/types.ts b/packages/openapi-model/src/3.0.3/model/types.ts index d1578a50..3ca057bf 100644 --- a/packages/openapi-model/src/3.0.3/model/types.ts +++ b/packages/openapi-model/src/3.0.3/model/types.ts @@ -35,6 +35,8 @@ export type ExtensionFields = Map; export interface TreeNode extends Disposable { readonly root: OpenAPIModel; readonly parent: TParent; + + children(): IterableIterator>; } /** @@ -1145,6 +1147,8 @@ export interface OpenAPIModel extends Disposable, SpecificationExtensionsModel { readonly tags: ReadonlyArray; readonly externalDocs: Nullable; + children(): IterableIterator>; + getServer(url: ParametrisedURLString): ServerModel | undefined; getServerOrThrow(url: ParametrisedURLString): ServerModel; addServer(