diff --git a/docs/features/software-catalog/descriptor-format.md b/docs/features/software-catalog/descriptor-format.md index 68cee2352c..ba542d0fd1 100644 --- a/docs/features/software-catalog/descriptor-format.md +++ b/docs/features/software-catalog/descriptor-format.md @@ -14,6 +14,8 @@ humans. However, the structure and semantics is the same in both cases. - [Common to All Kinds: The Envelope](#common-to-all-kinds-the-envelope) - [Common to All Kinds: The Metadata](#common-to-all-kinds-the-metadata) - [Kind: Component](#kind-component) +- [Kind: Template](#kind-template) +- [Kind: API](#kind-api) ## Overall Shape Of An Entity @@ -252,6 +254,8 @@ spec: type: website lifecycle: production owner: artist-relations@example.com + implementsApis: + - artist-api ``` In addition to the [common envelope metadata](#common-to-all-kinds-the-metadata) @@ -312,6 +316,14 @@ Apart from being a string, the software catalog leaves the format of this field open to implementers to choose. Most commonly, it is set to the ID or email of a group of people in an organizational structure. +### `spec.implementsApis` [optional] + +Links APIs that are implemented by the component, e.g. `artist-api`. This field +is optional. + +The software catalog expects a list of one or more strings that references the +names of other entities of the `kind` `API`. + ## Kind: Template Describes the following entity kind: @@ -422,3 +434,76 @@ specify relative to the `template.yaml` definition. This is also particularly useful when you have multiple template definitions in the same repository but only a single `template.yaml` registered in backstage. + +## Kind: API + +Describes the following entity kind: + +| Field | Value | +| ------------ | ----------------------- | +| `apiVersion` | `backstage.io/v1alpha1` | +| `kind` | `API` | + +An API describes an interface that can be exposed by a component. The API can be +defined in different formats, like [OpenAPI](https://swagger.io/specification/), +[AsyncAPI](https://www.asyncapi.com/docs/specifications/latest/), +[gRPC](https://developers.google.com/protocol-buffers), or other formats. + +Descriptor files for this kind may look as follows. + +```yaml +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: artist-api + description: Retrieve artist details +spec: + type: openapi + definition: | + openapi: "3.0.0" + info: + version: 1.0.0 + title: Artist API + license: + name: MIT + servers: + - url: http://artist.spotify.net/v1 + paths: + /artists: + get: + summary: List all artists + ... +``` + +In addition to the [common envelope metadata](#common-to-all-kinds-the-metadata) +shape, this kind has the following structure. + +### `apiVersion` and `kind` [required] + +Exactly equal to `backstage.io/v1alpha1` and `API`, respectively. + +### `spec.type` [required] + +The type of the API definition as a string, e.g. `openapi`. This field is +required. + +The software catalog accepts any type value, but an organisation should take +great care to establish a proper taxonomy for these. Tools including Backstage +itself may read this field and behave differently depending on its value. For +example, an OpenAPI type API may be displayed using an OpenAPI viewer tooling in +the Backstage interface. + +The current set of well-known and common values for this field is: + +- `openapi` - An API definition in YAML or JSON format based on the + [OpenAPI](https://swagger.io/specification/) version 2 or version 3 spec. +- `asyncapi` - An API definition based on the + [AsyncAPI](https://www.asyncapi.com/docs/specifications/latest/) spec. +- `grpc` - An API definition based on + [Protocol Buffers](https://developers.google.com/protocol-buffers) to use with + [gRPC](https://grpc.io/). + +### `spec.definition` [required] + +The definition of the API, based on the format defined by `spec.type`. This +field is required. diff --git a/packages/app/package.json b/packages/app/package.json index f42456709c..0e2cb677a4 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -5,6 +5,7 @@ "dependencies": { "@backstage/cli": "^0.1.1-alpha.18", "@backstage/core": "^0.1.1-alpha.18", + "@backstage/plugin-api-docs": "^0.1.1-alpha.18", "@backstage/plugin-catalog": "^0.1.1-alpha.18", "@backstage/plugin-circleci": "^0.1.1-alpha.18", "@backstage/plugin-explore": "^0.1.1-alpha.18", diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx index a86b92ab43..1d32b6e16e 100644 --- a/packages/app/src/components/Root/Root.tsx +++ b/packages/app/src/components/Root/Root.tsx @@ -19,6 +19,7 @@ import PropTypes from 'prop-types'; import { Link, makeStyles } from '@material-ui/core'; import HomeIcon from '@material-ui/icons/Home'; import ExploreIcon from '@material-ui/icons/Explore'; +import ExtensionIcon from '@material-ui/icons/Extension'; import BuildIcon from '@material-ui/icons/BuildRounded'; import RuleIcon from '@material-ui/icons/AssignmentTurnedIn'; import MapIcon from '@material-ui/icons/MyLocation'; @@ -90,6 +91,7 @@ const Root: FC<{}> = ({ children }) => ( {/* Global nav, not org-specific */} + {/* End global nav */} diff --git a/packages/app/src/plugins.ts b/packages/app/src/plugins.ts index 7e803698fe..4ec19c74f3 100644 --- a/packages/app/src/plugins.ts +++ b/packages/app/src/plugins.ts @@ -30,3 +30,4 @@ export { plugin as Rollbar } from '@backstage/plugin-rollbar'; export { plugin as Newrelic } from '@backstage/plugin-newrelic'; export { plugin as TravisCI } from '@roadiehq/backstage-plugin-travis-ci'; export { plugin as Jenkins } from '@backstage/plugin-jenkins'; +export { plugin as ApiDocs } from '@backstage/plugin-api-docs'; diff --git a/packages/catalog-model/examples/hello-world-api.yaml b/packages/catalog-model/examples/hello-world-api.yaml new file mode 100644 index 0000000000..298b0cb835 --- /dev/null +++ b/packages/catalog-model/examples/hello-world-api.yaml @@ -0,0 +1,46 @@ +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: hello-world + description: Hello World example for gRPC +spec: + type: grpc + definition: | + // Copyright 2015 gRPC authors. + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + + syntax = "proto3"; + + option java_multiple_files = true; + option java_package = "io.grpc.examples.helloworld"; + option java_outer_classname = "HelloWorldProto"; + option objc_class_prefix = "HLW"; + + package helloworld; + + // The greeting service definition. + service Greeter { + // Sends a greeting + rpc SayHello (HelloRequest) returns (HelloReply) {} + } + + // The request message containing the user's name. + message HelloRequest { + string name = 1; + } + + // The response message containing the greetings + message HelloReply { + string message = 1; + } diff --git a/packages/catalog-model/examples/petstore-api.yaml b/packages/catalog-model/examples/petstore-api.yaml new file mode 100644 index 0000000000..01953a4a97 --- /dev/null +++ b/packages/catalog-model/examples/petstore-api.yaml @@ -0,0 +1,119 @@ +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: petstore + description: The petstore API +spec: + type: openapi + definition: | + openapi: "3.0.0" + info: + version: 1.0.0 + title: Swagger Petstore + license: + name: MIT + servers: + - url: http://petstore.swagger.io/v1 + paths: + /pets: + get: + summary: List all pets + operationId: listPets + tags: + - pets + parameters: + - name: limit + in: query + description: How many items to return at one time (max 100) + required: false + schema: + type: integer + format: int32 + responses: + '200': + description: A paged array of pets + headers: + x-next: + description: A link to the next page of responses + schema: + type: string + content: + application/json: + schema: + $ref: "#/components/schemas/Pets" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + post: + summary: Create a pet + operationId: createPets + tags: + - pets + responses: + '201': + description: Null response + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + /pets/{petId}: + get: + summary: Info for a specific pet + operationId: showPetById + tags: + - pets + parameters: + - name: petId + in: path + required: true + description: The id of the pet to retrieve + schema: + type: string + responses: + '200': + description: Expected response to a valid request + content: + application/json: + schema: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string diff --git a/packages/catalog-model/examples/petstore-component.yaml b/packages/catalog-model/examples/petstore-component.yaml new file mode 100644 index 0000000000..5cf0d1f270 --- /dev/null +++ b/packages/catalog-model/examples/petstore-component.yaml @@ -0,0 +1,13 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: petstore + description: Petstore +spec: + type: service + lifecycle: experimental + owner: pets@example.com + implementedApis: + - petstore + - streetlights + - hello-world diff --git a/packages/catalog-model/examples/streetlights-api.yaml b/packages/catalog-model/examples/streetlights-api.yaml new file mode 100644 index 0000000000..69a6d101cb --- /dev/null +++ b/packages/catalog-model/examples/streetlights-api.yaml @@ -0,0 +1,217 @@ +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: streetlights + description: The Smartylighting Streetlights API allows you to remotely manage the city lights. +spec: + type: asyncapi + definition: | + asyncapi: 2.0.0 + info: + title: Streetlights API + version: '1.0.0' + description: | + The Smartylighting Streetlights API allows you to remotely manage the city lights. + + ### Check out its awesome features: + + * Turn a specific streetlight on/off 🌃 + * Dim a specific streetlight šŸ˜Ž + * Receive real-time information about environmental lighting conditions šŸ“ˆ + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0 + + servers: + production: + url: api.streetlights.smartylighting.com:{port} + protocol: mqtt + description: Test broker + variables: + port: + description: Secure connection (TLS) is available through port 8883. + default: '1883' + enum: + - '1883' + - '8883' + security: + - apiKey: [] + - supportedOauthFlows: + - streetlights:on + - streetlights:off + - streetlights:dim + - openIdConnectWellKnown: [] + + defaultContentType: application/json + + channels: + smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured: + description: The topic on which measured values may be produced and consumed. + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + subscribe: + summary: Receive information about environmental lighting conditions of a particular streetlight. + operationId: receiveLightMeasurement + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/lightMeasured' + + smartylighting/streetlights/1/0/action/{streetlightId}/turn/on: + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + publish: + operationId: turnOn + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/turnOnOff' + + smartylighting/streetlights/1/0/action/{streetlightId}/turn/off: + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + publish: + operationId: turnOff + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/turnOnOff' + + smartylighting/streetlights/1/0/action/{streetlightId}/dim: + parameters: + streetlightId: + $ref: '#/components/parameters/streetlightId' + publish: + operationId: dimLight + traits: + - $ref: '#/components/operationTraits/kafka' + message: + $ref: '#/components/messages/dimLight' + + components: + messages: + lightMeasured: + name: lightMeasured + title: Light measured + summary: Inform about environmental lighting conditions for a particular streetlight. + contentType: application/json + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: "#/components/schemas/lightMeasuredPayload" + turnOnOff: + name: turnOnOff + title: Turn on/off + summary: Command a particular streetlight to turn the lights on or off. + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: "#/components/schemas/turnOnOffPayload" + dimLight: + name: dimLight + title: Dim light + summary: Command a particular streetlight to dim the lights. + traits: + - $ref: '#/components/messageTraits/commonHeaders' + payload: + $ref: "#/components/schemas/dimLightPayload" + + schemas: + lightMeasuredPayload: + type: object + properties: + lumens: + type: integer + minimum: 0 + description: Light intensity measured in lumens. + sentAt: + $ref: "#/components/schemas/sentAt" + turnOnOffPayload: + type: object + properties: + command: + type: string + enum: + - on + - off + description: Whether to turn on or off the light. + sentAt: + $ref: "#/components/schemas/sentAt" + dimLightPayload: + type: object + properties: + percentage: + type: integer + description: Percentage to which the light should be dimmed to. + minimum: 0 + maximum: 100 + sentAt: + $ref: "#/components/schemas/sentAt" + sentAt: + type: string + format: date-time + description: Date and time when the message was sent. + + securitySchemes: + apiKey: + type: apiKey + in: user + description: Provide your API key as the user and leave the password empty. + supportedOauthFlows: + type: oauth2 + description: Flows to support OAuth 2.0 + flows: + implicit: + authorizationUrl: 'https://authserver.example/auth' + scopes: + 'streetlights:on': Ability to switch lights on + 'streetlights:off': Ability to switch lights off + 'streetlights:dim': Ability to dim the lights + password: + tokenUrl: 'https://authserver.example/token' + scopes: + 'streetlights:on': Ability to switch lights on + 'streetlights:off': Ability to switch lights off + 'streetlights:dim': Ability to dim the lights + clientCredentials: + tokenUrl: 'https://authserver.example/token' + scopes: + 'streetlights:on': Ability to switch lights on + 'streetlights:off': Ability to switch lights off + 'streetlights:dim': Ability to dim the lights + authorizationCode: + authorizationUrl: 'https://authserver.example/auth' + tokenUrl: 'https://authserver.example/token' + refreshUrl: 'https://authserver.example/refresh' + scopes: + 'streetlights:on': Ability to switch lights on + 'streetlights:off': Ability to switch lights off + 'streetlights:dim': Ability to dim the lights + openIdConnectWellKnown: + type: openIdConnect + openIdConnectUrl: 'https://authserver.example/.well-known' + + parameters: + streetlightId: + description: The ID of the streetlight. + schema: + type: string + + messageTraits: + commonHeaders: + headers: + type: object + properties: + my-app-header: + type: integer + minimum: 0 + maximum: 100 + + operationTraits: + kafka: + bindings: + kafka: + clientId: my-app-id diff --git a/packages/catalog-model/src/EntityPolicies.ts b/packages/catalog-model/src/EntityPolicies.ts index 120de5152e..8cc51e5aa8 100644 --- a/packages/catalog-model/src/EntityPolicies.ts +++ b/packages/catalog-model/src/EntityPolicies.ts @@ -23,6 +23,7 @@ import { SchemaValidEntityPolicy, } from './entity'; import { + ApiEntityV1alpha1Policy, ComponentEntityV1alpha1Policy, GroupEntityV1alpha1Policy, LocationEntityV1alpha1Policy, @@ -78,6 +79,7 @@ export class EntityPolicies implements EntityPolicy { new GroupEntityV1alpha1Policy(), new LocationEntityV1alpha1Policy(), new TemplateEntityV1alpha1Policy(), + new ApiEntityV1alpha1Policy(), ]), ]); } diff --git a/packages/catalog-model/src/kinds/ApiEntityV1alpha1.test.ts b/packages/catalog-model/src/kinds/ApiEntityV1alpha1.test.ts new file mode 100644 index 0000000000..48de569213 --- /dev/null +++ b/packages/catalog-model/src/kinds/ApiEntityV1alpha1.test.ts @@ -0,0 +1,126 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EntityPolicy } from '../types'; +import { + ApiEntityV1alpha1, + ApiEntityV1alpha1Policy, +} from './ApiEntityV1alpha1'; + +describe('ApiV1alpha1Policy', () => { + let entity: ApiEntityV1alpha1; + let policy: EntityPolicy; + + beforeEach(() => { + entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'API', + metadata: { + name: 'test', + }, + spec: { + type: 'openapi', + definition: ` +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + summary: List all pets + operationId: listPets + responses: + '200': + description: A paged array of pets + content: + application/json: + schema: + $ref: "#/components/schemas/Pets" +components: + schemas: + Pet: + type: object + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Pets: + type: array + items: + $ref: "#/components/schemas/Pet" +`, + }, + }; + policy = new ApiEntityV1alpha1Policy(); + }); + + it('happy path: accepts valid data', async () => { + await expect(policy.enforce(entity)).resolves.toBe(entity); + }); + + it('silently accepts v1beta1 as well', async () => { + (entity as any).apiVersion = 'backstage.io/v1beta1'; + await expect(policy.enforce(entity)).resolves.toBe(entity); + }); + + it('rejects unknown apiVersion', async () => { + (entity as any).apiVersion = 'backstage.io/v1beta0'; + await expect(policy.enforce(entity)).rejects.toThrow(/apiVersion/); + }); + + it('rejects unknown kind', async () => { + (entity as any).kind = 'Wizard'; + await expect(policy.enforce(entity)).rejects.toThrow(/kind/); + }); + + it('rejects missing type', async () => { + delete (entity as any).spec.type; + await expect(policy.enforce(entity)).rejects.toThrow(/type/); + }); + + it('rejects wrong type', async () => { + (entity as any).spec.type = 7; + await expect(policy.enforce(entity)).rejects.toThrow(/type/); + }); + + it('rejects empty type', async () => { + (entity as any).spec.type = ''; + await expect(policy.enforce(entity)).rejects.toThrow(/type/); + }); + + it('rejects missing definition', async () => { + delete (entity as any).spec.definition; + await expect(policy.enforce(entity)).rejects.toThrow(/definition/); + }); + + it('rejects wrong definition', async () => { + (entity as any).spec.definition = 7; + await expect(policy.enforce(entity)).rejects.toThrow(/definition/); + }); + + it('rejects empty definition', async () => { + (entity as any).spec.definition = ''; + await expect(policy.enforce(entity)).rejects.toThrow(/definition/); + }); +}); diff --git a/packages/catalog-model/src/kinds/ApiEntityV1alpha1.ts b/packages/catalog-model/src/kinds/ApiEntityV1alpha1.ts new file mode 100644 index 0000000000..59e16df9a7 --- /dev/null +++ b/packages/catalog-model/src/kinds/ApiEntityV1alpha1.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as yup from 'yup'; +import type { Entity } from '../entity/Entity'; +import type { EntityPolicy } from '../types'; + +const API_VERSION = ['backstage.io/v1alpha1', 'backstage.io/v1beta1'] as const; +const KIND = 'API' as const; + +export interface ApiEntityV1alpha1 extends Entity { + apiVersion: typeof API_VERSION[number]; + kind: typeof KIND; + spec: { + type: string; + definition: string; + }; +} + +export class ApiEntityV1alpha1Policy implements EntityPolicy { + private schema: yup.Schema; + + constructor() { + this.schema = yup.object>({ + apiVersion: yup.string().required().oneOf(API_VERSION), + kind: yup.string().required().equals([KIND]), + spec: yup + .object({ + type: yup.string().required().min(1), + definition: yup.string().required().min(1), + }) + .required(), + }); + } + + async enforce(envelope: Entity): Promise { + return await this.schema.validate(envelope, { strict: true }); + } +} diff --git a/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.test.ts b/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.test.ts index a60bb2606b..e784934d48 100644 --- a/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.test.ts +++ b/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.test.ts @@ -35,6 +35,7 @@ describe('ComponentV1alpha1Policy', () => { type: 'service', lifecycle: 'production', owner: 'me', + implementsApis: ['api-0'], }, }; policy = new ComponentEntityV1alpha1Policy(); diff --git a/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts b/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts index 68cf0c61bb..38b9c27720 100644 --- a/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts +++ b/packages/catalog-model/src/kinds/ComponentEntityV1alpha1.ts @@ -28,6 +28,7 @@ export interface ComponentEntityV1alpha1 extends Entity { type: string; lifecycle: string; owner: string; + implementsApis?: string[]; }; } @@ -43,6 +44,7 @@ export class ComponentEntityV1alpha1Policy implements EntityPolicy { type: yup.string().required().min(1), lifecycle: yup.string().required().min(1), owner: yup.string().required().min(1), + implementsApis: yup.array(yup.string()).notRequired(), }) .required(), }); diff --git a/packages/catalog-model/src/kinds/index.ts b/packages/catalog-model/src/kinds/index.ts index 4526e99da4..6e8d27d204 100644 --- a/packages/catalog-model/src/kinds/index.ts +++ b/packages/catalog-model/src/kinds/index.ts @@ -34,3 +34,8 @@ export type { TemplateEntityV1alpha1 as TemplateEntity, TemplateEntityV1alpha1, } from './TemplateEntityV1alpha1'; +export { ApiEntityV1alpha1Policy } from './ApiEntityV1alpha1'; +export type { + ApiEntityV1alpha1 as ApiEntity, + ApiEntityV1alpha1, +} from './ApiEntityV1alpha1'; diff --git a/packages/cli/config/jest.js b/packages/cli/config/jest.js index da9b3ec3e6..77d3a84e82 100644 --- a/packages/cli/config/jest.js +++ b/packages/cli/config/jest.js @@ -48,8 +48,9 @@ async function getConfig() { // Default behaviour is to not apply transforms for node_modules, but we still want // to apply the esm-transformer to .esm.js files, since that's what we use in backstage packages. + // The @kyma-project/asyncapi-react library needs to be transformed. transformIgnorePatterns: [ - '/node_modules/(?!.*\\.(?:esm\\.js|bmp|gif|jpg|jpeg|png|frag|xml|svg)$)', + '/node_modules/(?!@kyma-project/asyncapi-react/)(?!.*\\.(?:esm\\.js|bmp|gif|jpg|jpeg|png|frag|xml|svg)$)', ], }; diff --git a/plugins/api-docs/.eslintrc.js b/plugins/api-docs/.eslintrc.js new file mode 100644 index 0000000000..13573efa9c --- /dev/null +++ b/plugins/api-docs/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [require.resolve('@backstage/cli/config/eslint')], +}; diff --git a/plugins/api-docs/README.md b/plugins/api-docs/README.md new file mode 100644 index 0000000000..7ea87004c3 --- /dev/null +++ b/plugins/api-docs/README.md @@ -0,0 +1,9 @@ +# API Documentation + +WORK IN PROGRESS + +This is an extension for the catalog plugin that provides components to discover and display API entities. + +## Links + +- (The Backstage homepage)[https://backstage.io] diff --git a/plugins/api-docs/dev/index.tsx b/plugins/api-docs/dev/index.tsx new file mode 100644 index 0000000000..812a5585d4 --- /dev/null +++ b/plugins/api-docs/dev/index.tsx @@ -0,0 +1,20 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createDevApp } from '@backstage/dev-utils'; +import { plugin } from '../src/plugin'; + +createDevApp().registerPlugin(plugin).render(); diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json new file mode 100644 index 0000000000..a599e7e322 --- /dev/null +++ b/plugins/api-docs/package.json @@ -0,0 +1,54 @@ +{ + "name": "@backstage/plugin-api-docs", + "version": "0.1.1-alpha.18", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": true, + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "scripts": { + "build": "backstage-cli plugin:build", + "start": "backstage-cli plugin:serve", + "lint": "backstage-cli lint", + "test": "backstage-cli test", + "diff": "backstage-cli plugin:diff", + "prepack": "backstage-cli prepack", + "postpack": "backstage-cli postpack", + "clean": "backstage-cli clean" + }, + "dependencies": { + "@backstage/catalog-model": "^0.1.1-alpha.18", + "@backstage/core": "^0.1.1-alpha.18", + "@backstage/plugin-catalog": "^0.1.1-alpha.18", + "@backstage/theme": "^0.1.1-alpha.18", + "@kyma-project/asyncapi-react": "^0.6.1", + "@material-icons/font": "^1.0.2", + "@material-ui/core": "^4.9.1", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "4.0.0-alpha.45", + "react": "^16.13.1", + "react-dom": "^16.13.1", + "react-router-dom": "6.0.0-beta.0", + "react-use": "^15.3.3", + "swagger-ui-react": "^3.31.1" + }, + "devDependencies": { + "@backstage/cli": "^0.1.1-alpha.18", + "@backstage/dev-utils": "^0.1.1-alpha.18", + "@backstage/test-utils": "^0.1.1-alpha.18", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^10.4.1", + "@testing-library/user-event": "^12.0.7", + "@types/jest": "^26.0.7", + "@types/node": "^12.0.0", + "@types/swagger-ui-react": "^3.23.3", + "jest-fetch-mock": "^3.0.3" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/api-docs/src/components/ApiCatalogPage/ApiCatalogLayout.tsx b/plugins/api-docs/src/components/ApiCatalogPage/ApiCatalogLayout.tsx new file mode 100644 index 0000000000..d846e2b0e2 --- /dev/null +++ b/plugins/api-docs/src/components/ApiCatalogPage/ApiCatalogLayout.tsx @@ -0,0 +1,37 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Header, Page, pageTheme } from '@backstage/core'; +import React from 'react'; + +type Props = { + children?: React.ReactNode; +}; + +const ApiCatalogLayout = ({ children }: Props) => { + return ( + +
+ {children} + + ); +}; + +export default ApiCatalogLayout; diff --git a/plugins/api-docs/src/components/ApiCatalogPage/ApiCatalogPage.test.tsx b/plugins/api-docs/src/components/ApiCatalogPage/ApiCatalogPage.test.tsx new file mode 100644 index 0000000000..19cbaf6038 --- /dev/null +++ b/plugins/api-docs/src/components/ApiCatalogPage/ApiCatalogPage.test.tsx @@ -0,0 +1,70 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { ApiProvider, ApiRegistry, storageApiRef } from '@backstage/core'; +// TODO: Circular ref! +import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog'; +import { MockStorageApi, wrapInTestApp } from '@backstage/test-utils'; +import { render } from '@testing-library/react'; +import React from 'react'; +import { ApiCatalogPage } from './ApiCatalogPage'; + +describe('ApiCatalogPage', () => { + const catalogApi: Partial = { + getEntities: () => + Promise.resolve([ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'API', + metadata: { + name: 'Entity1', + }, + }, + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'API', + metadata: { + name: 'Entity2', + }, + }, + ] as Entity[]), + getLocationByEntity: () => + Promise.resolve({ id: 'id', type: 'github', target: 'url' }), + }; + + const renderWrapped = (children: React.ReactNode) => + render( + wrapInTestApp( + + {children} + , + ), + ); + + // this test right now causes some red lines in the log output when running tests + // related to some theme issues in mui-table + // https://github.com/mbrn/material-table/issues/1293 + it('should render', async () => { + const { findByText } = renderWrapped(); + expect(await findByText(/APIs \(2\)/)).toBeInTheDocument(); + }); +}); diff --git a/plugins/api-docs/src/components/ApiCatalogPage/ApiCatalogPage.tsx b/plugins/api-docs/src/components/ApiCatalogPage/ApiCatalogPage.tsx new file mode 100644 index 0000000000..f624ec9f92 --- /dev/null +++ b/plugins/api-docs/src/components/ApiCatalogPage/ApiCatalogPage.tsx @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Content, useApi } from '@backstage/core'; +// TODO: Circular ref +import { catalogApiRef } from '@backstage/plugin-catalog'; +import React from 'react'; +import { useAsync } from 'react-use'; +import { ApiCatalogTable } from '../ApiCatalogTable/ApiCatalogTable'; +import ApiCatalogLayout from './ApiCatalogLayout'; + +const CatalogPageContents = () => { + const catalogApi = useApi(catalogApiRef); + const { loading, error, value: matchingEntities } = useAsync(() => { + return catalogApi.getEntities({ kind: 'API' }); + }, [catalogApi]); + + return ( + + + + + + ); +}; + +export const ApiCatalogPage = () => ; diff --git a/plugins/api-docs/src/components/ApiCatalogTable/ApiCatalogTable.test.tsx b/plugins/api-docs/src/components/ApiCatalogTable/ApiCatalogTable.test.tsx new file mode 100644 index 0000000000..67f6562a56 --- /dev/null +++ b/plugins/api-docs/src/components/ApiCatalogTable/ApiCatalogTable.test.tsx @@ -0,0 +1,74 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { wrapInTestApp } from '@backstage/test-utils'; +import { render } from '@testing-library/react'; +import * as React from 'react'; +import { ApiCatalogTable } from './ApiCatalogTable'; + +const entites: Entity[] = [ + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'API', + metadata: { name: 'api1' }, + }, + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'API', + metadata: { name: 'api2' }, + }, + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'API', + metadata: { name: 'api3' }, + }, +]; + +describe('ApiCatalogTable component', () => { + it('should render error message when error is passed in props', async () => { + const rendered = render( + wrapInTestApp( + , + ), + ); + const errorMessage = await rendered.findByText( + /Error encountered while fetching catalog entities./, + ); + expect(errorMessage).toBeInTheDocument(); + }); + + it('should display entity names when loading has finished and no error occurred', async () => { + const rendered = render( + wrapInTestApp( + , + ), + ); + expect(rendered.getByText(/APIs \(3\)/)).toBeInTheDocument(); + expect(rendered.getByText(/api1/)).toBeInTheDocument(); + expect(rendered.getByText(/api2/)).toBeInTheDocument(); + expect(rendered.getByText(/api3/)).toBeInTheDocument(); + }); +}); diff --git a/plugins/api-docs/src/components/ApiCatalogTable/ApiCatalogTable.tsx b/plugins/api-docs/src/components/ApiCatalogTable/ApiCatalogTable.tsx new file mode 100644 index 0000000000..e30583caed --- /dev/null +++ b/plugins/api-docs/src/components/ApiCatalogTable/ApiCatalogTable.tsx @@ -0,0 +1,89 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Entity } from '@backstage/catalog-model'; +import { Table, TableColumn } from '@backstage/core'; +import { Link } from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; +import React from 'react'; +import { generatePath, Link as RouterLink } from 'react-router-dom'; +import { entityRoute } from '../../routes'; + +const columns: TableColumn[] = [ + { + title: 'Name', + field: 'metadata.name', + highlight: true, + render: (entity: any) => ( + + {entity.metadata.name} + + ), + }, + { + title: 'Description', + field: 'metadata.description', + }, +]; + +type CatalogTableProps = { + entities: Entity[]; + titlePreamble: string; + loading: boolean; + error?: any; +}; + +export const ApiCatalogTable = ({ + entities, + loading, + error, + titlePreamble, +}: CatalogTableProps) => { + if (error) { + return ( +
+ + Error encountered while fetching catalog entities. {error.toString()} + +
+ ); + } + + return ( + + isLoading={loading} + columns={columns} + options={{ + paging: false, + actionsColumnIndex: -1, + loadingType: 'linear', + showEmptyDataSourceMessage: !loading, + }} + title={`${titlePreamble} (${(entities && entities.length) || 0})`} + data={entities} + /> + ); +}; diff --git a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.tsx b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.tsx new file mode 100644 index 0000000000..af101f0194 --- /dev/null +++ b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.tsx @@ -0,0 +1,34 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ApiEntityV1alpha1 } from '@backstage/catalog-model'; +import { InfoCard } from '@backstage/core'; +import React, { FC } from 'react'; +import { ApiDefinitionWidget } from '../ApiDefinitionWidget/ApiDefinitionWidget'; + +export const ApiDefinitionCard: FC<{ + title?: string; + apiEntity: ApiEntityV1alpha1; +}> = ({ title, apiEntity }) => { + const type = apiEntity?.spec?.type || ''; + const definition = apiEntity?.spec?.definition || ''; + + return ( + + + + ); +}; diff --git a/plugins/api-docs/src/components/ApiDefinitionWidget/ApiDefinitionWidget.tsx b/plugins/api-docs/src/components/ApiDefinitionWidget/ApiDefinitionWidget.tsx new file mode 100644 index 0000000000..5b1ddd7880 --- /dev/null +++ b/plugins/api-docs/src/components/ApiDefinitionWidget/ApiDefinitionWidget.tsx @@ -0,0 +1,36 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { FC } from 'react'; +import { AsyncApiDefinitionWidget } from '../AsyncApiDefinitionWidget/AsyncApiDefinitionWidget'; +import { OpenApiDefinitionWidget } from '../OpenApiDefinitionWidget/OpenApiDefinitionWidget'; +import { PlainApiDefinitionWidget } from '../PlainApiDefinitionWidget/PlainApiDefinitionWidget'; + +export const ApiDefinitionWidget: FC<{ + type: string; + definition: string; +}> = ({ type, definition }) => { + switch (type) { + case 'openapi': + return ; + + case 'asyncapi': + return ; + + default: + return ; + } +}; diff --git a/plugins/api-docs/src/components/ApiEntityPage/ApiEntityPage.test.tsx b/plugins/api-docs/src/components/ApiEntityPage/ApiEntityPage.test.tsx new file mode 100644 index 0000000000..af5213e3f1 --- /dev/null +++ b/plugins/api-docs/src/components/ApiEntityPage/ApiEntityPage.test.tsx @@ -0,0 +1,102 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { ApiProvider, ApiRegistry, errorApiRef } from '@backstage/core'; +import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog'; +import { wrapInTestApp } from '@backstage/test-utils'; +import { render, waitFor } from '@testing-library/react'; +import * as React from 'react'; +import { ApiEntityPage, getPageTheme } from './ApiEntityPage'; + +jest.mock('react-router-dom', () => { + const actual = jest.requireActual('react-router-dom'); + const mockNavigate = jest.fn(); + return { + ...actual, + useNavigate: jest.fn(() => mockNavigate), + useParams: jest.fn(), + }; +}); + +const { + useParams, + useNavigate, +}: { useParams: jest.Mock; useNavigate: () => jest.Mock } = jest.requireMock( + 'react-router-dom', +); + +const errorApi = { post: () => {} }; + +describe('ApiEntityPage', () => { + it('should redirect to catalog page when name is not provided', async () => { + useParams.mockReturnValue({ + kind: 'Component', + optionalNamespaceAndName: '', + }); + + render( + wrapInTestApp( + ) as CatalogApi, + ], + ])} + > + + , + ), + ); + + await waitFor(() => + expect(useNavigate()).toHaveBeenCalledWith('/api-docs'), + ); + }); +}); + +describe('getPageTheme', () => { + const defaultPageTheme = getPageTheme(); + it.each(['service', 'app', 'library', 'tool', 'documentation', 'website'])( + 'should select right theme for predefined type: %p ̰ ', + type => { + const theme = getPageTheme(({ + spec: { + type, + }, + } as any) as Entity); + expect(theme).toBeDefined(); + expect(theme).not.toBe(defaultPageTheme); + }, + ); + + it('should select default theme for unknown/unspecified types', () => { + const theme1 = getPageTheme(({ + spec: { + type: 'unknown-type', + }, + } as any) as Entity); + const theme2 = getPageTheme(({ + spec: {}, + } as any) as Entity); + expect(theme1).toBe(defaultPageTheme); + expect(theme2).toBe(defaultPageTheme); + }); +}); diff --git a/plugins/api-docs/src/components/ApiEntityPage/ApiEntityPage.tsx b/plugins/api-docs/src/components/ApiEntityPage/ApiEntityPage.tsx new file mode 100644 index 0000000000..5e08af7e8e --- /dev/null +++ b/plugins/api-docs/src/components/ApiEntityPage/ApiEntityPage.tsx @@ -0,0 +1,131 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ApiEntityV1alpha1, Entity } from '@backstage/catalog-model'; +import { + Content, + errorApiRef, + Header, + Page, + pageTheme, + PageTheme, + Progress, + useApi, +} from '@backstage/core'; +// TODO: Circular ref +import { catalogApiRef } from '@backstage/plugin-catalog'; +import { Box } from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; +import React, { FC, useEffect } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import { useAsync } from 'react-use'; +import { ApiDefinitionCard } from '../ApiDefinitionCard/ApiDefinitionCard'; + +const REDIRECT_DELAY = 1000; +function headerProps( + kind: string, + namespace: string | undefined, + name: string, + entity: Entity | undefined, +): { headerTitle: string; headerType: string } { + return { + headerTitle: `${name}${namespace ? ` in ${namespace}` : ''}`, + headerType: (() => { + let t = kind.toLowerCase(); + if (entity && entity.spec && 'type' in entity.spec) { + t += ' — '; + t += (entity.spec as { type: string }).type.toLowerCase(); + } + return t; + })(), + }; +} + +export const getPageTheme = (entity?: Entity): PageTheme => { + const themeKey = entity?.spec?.type?.toString() ?? 'home'; + return pageTheme[themeKey] ?? pageTheme.home; +}; + +const EntityPageTitle: FC<{ title: string; entity: Entity | undefined }> = ({ + title, +}) => ( + + {title} + +); + +export const ApiEntityPage: FC<{}> = () => { + const { optionalNamespaceAndName } = useParams() as { + optionalNamespaceAndName: string; + }; + const navigate = useNavigate(); + const [name, namespace] = optionalNamespaceAndName.split(':').reverse(); + + const errorApi = useApi(errorApiRef); + const catalogApi = useApi(catalogApiRef); + + const { value: entity, error, loading } = useAsync( + () => catalogApi.getEntityByName({ kind: 'API', namespace, name }), + [catalogApi, namespace, name], + ); + + useEffect(() => { + if (!error && !loading && !entity) { + errorApi.post(new Error('Entity not found!')); + setTimeout(() => { + navigate('/'); + }, REDIRECT_DELAY); + } + }, [errorApi, navigate, error, loading, entity]); + + if (!name) { + navigate('/api-docs'); + return null; + } + + const { headerTitle, headerType } = headerProps( + 'API', + namespace, + name, + entity, + ); + + return ( + +
} + pageTitleOverride={headerTitle} + type={headerType} + /> + + {loading && } + + {error && ( + + {error.toString()} + + )} + + {entity && ( + <> + + + + + )} + + ); +}; diff --git a/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx b/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx new file mode 100644 index 0000000000..2b5e697e51 --- /dev/null +++ b/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx @@ -0,0 +1,25 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import AsyncApi from '@kyma-project/asyncapi-react'; +import React, { FC } from 'react'; +import './style.css'; + +export const AsyncApiDefinitionWidget: FC<{ + definition: any; +}> = ({ definition }) => { + return ; +}; diff --git a/plugins/api-docs/src/components/AsyncApiDefinitionWidget/style.css b/plugins/api-docs/src/components/AsyncApiDefinitionWidget/style.css new file mode 100644 index 0000000000..0237c24d52 --- /dev/null +++ b/plugins/api-docs/src/components/AsyncApiDefinitionWidget/style.css @@ -0,0 +1,1273 @@ +/* + * Copyright (c) 2018-2019 SAP SE or an SAP affiliate company. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.asyncapi { + /*font-family: '72';*/ + font-size: 14px; + line-height: 20px; + font-weight: 400; + -webkit-font-smoothing: antialiased; + font-smoothing: antialiased; + /*background: #f3f4f5;*/ +} + +.asyncapi__toggle { + cursor: pointer; +} +.asyncapi__toggle > .asyncapi__toggle-body { + display: none; +} + +.asyncapi__toggle--expanded { + cursor: default; +} +.asyncapi__toggle--expanded > .asyncapi__toggle-body { + display: block; +} + +.asyncapi__toggle--no-children { +} +.asyncapi__toggle--no-children > .asyncapi__toggle-header { + cursor: default; +} + +.asyncapi__toggle-header { + position: relative; + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: center; + cursor: pointer; +} + +.asyncapi__toggle-header-content { + flex-grow: 1; + padding: 12px; +} +.asyncapi__toggle-header-content > h1, +.asyncapi__toggle-header-content > h2, +.asyncapi__toggle-header-content > h3, +.asyncapi__toggle-header-content > h4 { + margin: 0; + padding: 0; + display: flex; +} + +.asyncapi__toggle-button { + border: none; + height: 100%; + cursor: pointer; +} + +.asyncapi__toggle-arrow { + display: inline-block; + position: relative; + transform-origin: 50% 50%; + transition: 0.35s ease; + cursor: pointer; +} +.asyncapi__toggle-arrow:before { + content: '>'; + /*font-family: 'SAP-icons';*/ + font-size: 14px; +} +.asyncapi__toggle-arrow--expanded { + transform: rotate(-90deg); +} + +.asyncapi__components { +} + +.asyncapi__anchor { +} +.asyncapi__anchor:hover > .asyncapi__anchor-content { + text-decoration: underline; +} + +.asyncapi__anchor-content { + display: inline-block; +} + +.asyncapi__anchor-icon { + display: inline-block; + margin-left: 6px; +} +.asyncapi__anchor-icon:before { + content: 'šŸ”—'; + /*font-family: 'SAP-icons';*/ +} + +.asyncapi__markdown { +} +.asyncapi__markdown > div > ul { + margin: 0; + padding-left: 16px; +} +.asyncapi__markdown > div > ul { + margin: 0; + padding-left: 16px; +} +.asyncapi__markdown > div > p { + margin: 0; +} +.asyncapi__markdown > div > p > code { + display: inline-block; + font-weight: bold; + font-size: 10px; + line-height: 14px; + border-radius: 3px; + padding: 0px 5px; + text-align: center; + /*background: #e2eaf2;*/ + color: #18873d; +} + +.asyncapi__table { + margin: 0 0 20px 0; + width: 100%; + border-spacing: 0; + font-size: 13px; +} + +.asyncapi__table--nested { + margin: 10px 10px 10px auto; + width: calc(100% - 45px); + border-spacing: 0; + font-size: 13px; + border-radius: 5px; + border: solid 1px #d4d4d4; + /*background-color: #f9fafa;*/ +} + +.asyncapi__table-header { + width: 100%; + color: #939698; + /*background: #f9fafa;*/ + text-transform: uppercase; +} + +.asyncapi__table-header--nested { + color: #939698; + border-bottom: solid 1px #d4d4d4; + font-weight: bold; + text-align: left; + padding: 6px 0; + font-size: 12px; +} + +.asyncapi__table-header-title { + line-height: 30px; +} + +.asyncapi__table-header-title--nested { + color: #939698; +} +.asyncapi__table-header-title--nested > td { + border-bottom: solid 1px #d4d4d4; + padding: 8px 20px; + font-size: 12px; + color: #818487; +} + +.asyncapi__table-header-columns { + font-weight: lighter; + font-size: 11px; +} + +.asyncapi__table-header-columns--nested { + color: #939698; +} + +.asyncapi__table-header-column { + padding: 12px; + text-align: left; +} + +.asyncapi__table-header-column--nested { + width: 20%; + padding: 8px 20px; + font-size: 12px; + border-bottom: solid 1px #d4d4d4; +} + +.asyncapi__table-body { + color: #000; +} + +.asyncapi__table-body--nested { + color: #000; +} + +.asyncapi__table-row { +} + +.asyncapi__table-row--nested { + color: #333; + border-bottom: solid 1px #d4d4d4; +} +.asyncapi__table-row--nested:last-child > td { + border-bottom: none; +} + +.asyncapi__table-row-accordion { + display: none; +} + +.asyncapi__table-row-accordion--open { + display: table-row; +} + +.asyncapi__table-cell { + padding: 12px; + vertical-align: top; + border-bottom: 1px solid #efeff0; +} +.asyncapi__table-cell > p { + margin-top: 0; +} + +.asyncapi__table-cell--nested { + padding: 8px 20px; + vertical-align: top; + font-size: 13px; + border-bottom: solid 1px #d4d4d4; +} + +.asyncapi__tree-space { + display: inline-block; + width: 20px; +} + +.asyncapi__tree-leaf { + display: inline-block; + position: relative; + width: 25px; +} + +.asyncapi__tree-leaf:before { + content: ''; + position: absolute; + top: -15px; + width: 13px; + height: 10px; + border-left: #aaa 2px solid; + border-bottom: #aaa 2px solid; + border-radius: 0 0 0 70%; +} + +.asyncapi__badge { + display: inline-block; + font-weight: bold; + font-size: 11px; + line-height: 18px; + border-radius: 3px; + padding: 0px 5px; + text-align: center; + text-transform: uppercase; + /*background: #e2eaf2;*/ +} + +.asyncapi__badge--publish { + color: #18873d; +} + +.asyncapi__badge--subscribe { + color: #107ee3; +} + +.asyncapi__badge--deprecated { + margin-left: 10px; + color: #f59702; +} + +.asyncapi__badge--required { + font-size: 9px; + line-height: 14px; + color: #f59702; + border-radius: 3px; + margin-left: 10px; +} + +.asyncapi__badge--generated { + font-size: 9px; + line-height: 14px; + color: #18873d; + border-radius: 3px; + margin-left: 10px; +} + +.asyncapi__tag { + display: inline-block; + mix-blend-mode: multiply; + border-radius: 4px; + /*background-color: #e2eaf2;*/ + font-size: 11px; + font-family: 72; + font-weight: 300; + text-transform: uppercase; + font-weight: normal; + font-style: normal; + font-stretch: normal; + line-height: normal; + letter-spacing: normal; + color: #73787d; + padding: 3px 8px; + margin: 0 5px 0 0; +} + +.asyncapi__code { + border: solid 1px rgba(137, 145, 154, 0.675); + border-radius: 5px; + /*background: #fff;*/ +} + +.asyncapi__code-header { + padding: 12px 20px; + border-bottom: 1px solid rgba(137, 145, 154, 0.675); +} + +.asyncapi__code-header > h4 { + margin: 0; + color: #32363a; + font-size: 13px; +} + +.asyncapi__code-pre { + margin: 0; + font-size: 13px; + padding: 12px; + /*background: #fafafa;*/ + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; +} + +.asyncapi__code-body { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; + margin: 0; + font-size: 12px; +} + +.asyncapi__info { + /*background: #fff;*/ + border-radius: 5px; + padding: 16px; + box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.16); +} + +.asyncapi__info-header-main { + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: center; +} +.asyncapi__info-header-main > h1 { + flex-grow: 1; + margin-top: 10px; + margin-bottom: 10px; +} + +.asyncapi__collapse-button { + border-radius: 0.25rem; + border: 1px solid #0071d4; + display: inline-block; + color: #0b74de; + font-weight: 700; + transition: all 0.125s ease-in; + padding: 10px 12px; + font-size: 14px; + cursor: pointer; +} +.asyncapi__collapse-button:hover { + background-color: #085caf; + color: #fff; +} +.asyncapi__collapse-button:focus { + outline: none; +} + +.asyncapi__info-header-version { + display: inline-block; + margin-left: 6px; +} + +.asyncapi__info-description { +} + +.asyncapi__info-list { + margin: 0 0 20px 0; + padding: 0; + list-style-type: none; +} +.asyncapi__info-list > li { + border-radius: 0.25rem; + border: 1px solid #0071d4; + margin: 6px 6px 0 0; + display: inline-block; + color: #0b74de; + font-weight: 500; + transition: all 0.125s ease-in; +} +.asyncapi__info-list > li:hover { + background-color: #085caf; +} +.asyncapi__info-list > li a { + padding: 3px 12px; + display: inline-block; + text-decoration: none; + color: #0b74de; + transition: all 0.125s ease-in; +} +.asyncapi__info-list > li:hover, +.asyncapi__info-list > li:hover a { + color: #fff; +} +.asyncapi__info-list .asyncapi__anchor:hover > .asyncapi__anchor-content { + text-decoration: none; +} + +.asyncapi__messages { +} +.asyncapi__messages > div { + margin-top: 24px; + /*background: #fff;*/ + border-radius: 5px; + padding: 16px; + box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.16); +} + +.asyncapi__messages-toggle .asyncapi__toggle-header-content { + padding: 0; +} +.asyncapi__messages-toggle--expanded > .asyncapi__toggle-header { + padding-bottom: 12px; +} + +.asyncapi__messages-header { +} +.asyncapi__messages-header > h2 { + margin: 0 0 24px 0; +} + +.asyncapi__messages-list { + margin: 0; + padding: 0; + list-style-type: none; +} + +.asyncapi__messages-list-item { + margin-bottom: 16px; +} +.asyncapi__messages-list-item:last-child { + margin-bottom: 0; +} + +.asyncapi__messages-oneOf-list { + margin: 0; + padding: 0; + list-style-type: none; +} + +.asyncapi__messages-oneOf-list-item { +} + +.asyncapi__message { + position: relative; + border-radius: 4px; + border: solid 1px rgba(151, 151, 151, 0.26); + /*background-color: #ffffff;*/ +} +.asyncapi__message:last-child { + margin-bottom: 0; +} + +.asyncapi__message-header { + padding: 12px; +} +.asyncapi__message-header > h3 { + color: #0b74de; + font-size: 14px; +} + +.asyncapi__message-header-title { + font-size: 14px; + margin-right: 10px; +} + +.asyncapi__message-header-summary { + font-size: 14px; + font-weight: 500; +} + +.asyncapi__message-header-deprecated-badge { +} + +.asyncapi__message-summary { +} + +.asyncapi__message-description { + padding: 12px; + font-size: 14px; + border-top: solid 1px rgba(151, 151, 151, 0.26); +} + +.asyncapi__message-headers { +} + +.asyncapi__message-headers-header { + color: #32363a; + /*background-color: #fafafa;*/ + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__message-headers-header > h4 { + padding: 12px; + margin: 0; +} + +.asyncapi__message-headers-schema { + margin: 0; +} +.asyncapi__message-headers-schema > .asyncapi__schema { + padding: 0; + border: none; +} +.asyncapi__message-headers-schema > .asyncapi__schema:before { + content: ''; + position: relative; + border: none; +} + +.asyncapi__message-payload-oneOf { +} + +.asyncapi__message-payload-toggle > .asyncapi__message-payload-header { + padding: 12px; + border: none; +} +.asyncapi__message-payload-toggle .asyncapi__message-payload-header h4 { + padding: 0; +} +.asyncapi__message-payload-toggle .asyncapi__message-payload-header { + border: none; + background-color: inherit; +} + +.asyncapi__message-payload-oneOf-header { + color: #32363a; + /*background-color: #fafafa;*/ + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__message-payload-oneOf-header > h4 { + padding: 12px; + margin: 0; +} + +.asyncapi__message-payload-oneOf-list { + margin: 0; + padding: 16px; + list-style-type: none; +} + +.asyncapi__message-payload-oneOf-list-item { + margin-bottom: 16px; +} +.asyncapi__message-payload-oneOf-list-item:last-child { + margin-bottom: 0; +} +.asyncapi__message-payload-oneOf-list-item .asyncapi__message-payload { + position: relative; + border-radius: 4px; + border: solid 1px rgba(151, 151, 151, 0.26); + /*background-color: #ffffff;*/ +} +.asyncapi__message-payload-oneOf-list-item + .asyncapi__message-payload:last-child { + margin-bottom: 0; +} + +.asyncapi__message-payload-anyOf { +} + +.asyncapi__message-payload-anyOf-header { + color: #32363a; + /*background-color: #fafafa;*/ + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__message-payload-anyOf-header > h4 { + padding: 12px; + margin: 0; +} + +.asyncapi__message-payload-anyOf-list { + margin: 0; + padding: 16px; + list-style-type: none; +} + +.asyncapi__message-payload-anyOf-list-item { + margin-bottom: 16px; +} +.asyncapi__message-payload-anyOf-list-item:last-child { + margin-bottom: 0; +} +.asyncapi__message-payload-anyOf-list-item .asyncapi__message-payload { + position: relative; + border-radius: 4px; + border: solid 1px rgba(151, 151, 151, 0.26); + /*background-color: #ffffff;*/ +} +.asyncapi__message-payload-anyOf-list-item + .asyncapi__message-payload:last-child { + margin-bottom: 0; +} + +.asyncapi__message-payload { + margin: 0; +} + +.asyncapi__message-payload-header { + color: #32363a; + /*background-color: #fafafa;*/ + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__message-payload-header > h4 { + padding: 12px; + margin: 0; +} + +.asyncapi__message-payload-schema { + margin: 0; +} +.asyncapi__message-payload-schema > .asyncapi__schema { + padding: 0; + border: none; +} +.asyncapi__message-payload-schema > .asyncapi__schema:before { + content: ''; + position: relative; + border: none; +} + +.asyncapi__message-tags { + margin: 20px 0; +} + +.asyncapi__message-tags-header { + color: #32363a; +} +.asyncapi__message-tags-header > h4 { + margin: 0 0 8px 0; +} + +.asyncapi__message-tags-list { +} + +.asyncapi__message-tags-list-item { +} + +.asyncapi__schemas { +} +.asyncapi__schemas > div { + margin-top: 24px; + /*background: #fff;*/ + border-radius: 5px; + padding: 16px; + box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.16); +} + +.asyncapi__schemas-header { +} + +.asyncapi__schemas-toggle .asyncapi__toggle-header-content { + padding: 0; +} +.asyncapi__schemas-toggle--expanded .asyncapi__toggle-header { + padding-bottom: 12px; +} + +.asyncapi__schemas-list { + margin: 0; + padding: 0; + list-style-type: none; +} + +.asyncapi__schemas-list-item { + margin-bottom: 16px; +} +.asyncapi__schemas-list-item:last-child { + margin-bottom: 0; +} + +.asyncapi__schema { + position: relative; + border-radius: 4px; + border: solid 1px rgba(151, 151, 151, 0.26); + /*background-color: #ffffff;*/ +} +.asyncapi__schema:last-child { + margin-bottom: 0; +} + +.asyncapi__schema-header { + padding: 12px; +} + +.asyncapi__schema-header-title { + font-size: 14px; +} + +.asyncapi__schema-table { + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__schema-table > table { + margin: 0; +} + +.asyncapi__schema-example { + padding: 16px; +} + +.asyncapi__schema-example-header { +} + +.asyncapi__schema-example-header-title { +} + +.asyncapi__schema-example-header-generated-badge { + display: inline-block; +} + +.asyncapi__security { + margin-top: 24px; + /*background: #fff;*/ + border-radius: 5px; + padding: 16px; +} + +.asyncapi__security-header { +} +.asyncapi__security-header > h2 { + margin: 0 0 24px 0; +} + +.asyncapi__security-table { + margin: 0; +} + +.asyncapi__servers { +} +.asyncapi__servers > div { + margin-top: 24px; + /*background: #fff;*/ + border-radius: 5px; + padding: 16px; + box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.16); +} + +.asyncapi__servers-toggle .asyncapi__toggle-header-content { + padding: 0; +} +.asyncapi__servers-toggle--expanded .asyncapi__toggle-header { + padding-bottom: 12px; +} + +.asyncapi__servers-header { +} +.asyncapi__servers-header > h2 { + margin: 0 0 24px 0; +} + +.asyncapi__servers-list { + margin: 0; + padding: 0; + list-style-type: none; +} + +.asyncapi__servers-list-item { + margin-bottom: 16px; +} +.asyncapi__servers-list-item:last-child { + margin-bottom: 0; +} + +.asyncapi__server { + position: relative; + border-radius: 4px; + border: solid 1px rgba(151, 151, 151, 0.26); + /*background-color: #ffffff;*/ +} + +.asyncapi__server-header { + padding: 12px; +} + +.asyncapi__server-header-stage { + color: #107ee3; + margin-right: 6px; +} + +.asyncapi__server-header-protocol { + color: #18873d; + margin-right: 6px; +} + +.asyncapi__server-description { + border-top: solid 1px rgba(151, 151, 151, 0.26); + padding: 12px; +} + +.asyncapi__servers-table { + margin-bottom: 0; +} +.asyncapi__servers-table > .asyncapi__table { + margin: 0; +} + +.asyncapi__server-variables { +} + +.asyncapi__server-variables-header { + color: #32363a; + /*background-color: #fafafa;*/ + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__server-variables-header > h4 { + padding: 12px; + margin: 0; +} + +.asyncapi__server-variables-table { + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__server-variables-table > table { + margin: 0; +} +.asyncapi__server-variables-table .asyncapi__table-body > tr:last-child td { + border-bottom: none; +} + +.asyncapi__server-variables-table-cell { + padding: 0; + border-bottom: none; +} + +.asyncapi__server-expand-icon { + display: inline-block; + position: relative; + width: 10px; + height: 10px; + margin-right: 10px; + transform-origin: 50% 50%; + transition: 0.5s ease; + cursor: pointer; +} +.asyncapi__server-expand-icon:before { + content: '>'; + /*font-family: 'SAP-icons';*/ + position: absolute; + color: #0071d4; + font-size: 12px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.asyncapi__server-expand-icon--open { + transform: rotate(90deg); +} + +.asyncapi__server-variables-enum-list { + margin: 0 0 0 15px; + padding: 0; +} + +.asyncapi__server-variables-enum-list-item { +} + +.asyncapi__server-security { +} + +.asyncapi__server-security-header { + color: #32363a; + /*background-color: #fafafa;*/ + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__server-security-header > h4 { + padding: 12px; + margin: 0; +} + +.asyncapi__server-security-table { + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__server-security-table > table { + margin: 0; +} +.asyncapi__server-security-table .asyncapi__table-body > tr:last-child td { + border-bottom: none; +} + +.asyncapi__server-security-table-cell { + padding: 0; + border-bottom: none; +} + +.asyncapi__server-security-flows-list { + margin: 0; + padding: 0; + list-style-type: none; +} +.asyncapi__server-security-flows-list a { + color: #0b74de; +} + +.asyncapi__server-security-flows-list-item { + margin-top: 12px; +} +.asyncapi__server-security-flows-list-item:first-child { + margin-top: 0; +} + +.asyncapi__server-security-flow { + /*background: #fafafa;*/ + border: 1px solid #dae1e7; + padding: 12px; + border-radius: 5px; +} + +.asyncapi__server-security-flow-list { + margin: 0; + padding: 0; + list-style-type: none; +} + +.asyncapi__server-security-flow-list-item { + padding: 3px 0; +} +.asyncapi__server-security-flow-list-item > span { + margin-left: 12px; +} +.asyncapi__server-security-flow-list-item > a { + margin-left: 12px; +} + +.asyncapi__server-security-flows-table-cell { + border-bottom: solid 1px #d4d4d4; + padding: 12px; +} + +.asyncapi__server-security-oauth2 { + border-bottom: none; +} +.asyncapi__server-security-oauth2 > td { + border-bottom: none; +} + +.asyncapi__server-security-scopes-list { + margin: 0; + padding: 0; + list-style-type: none; + display: inline-block; + margin-left: 6px; +} + +.asyncapi__server-security-scopes-list-item { + display: inline-block; + margin-right: 6px; +} + +.asyncapi__server-security-scope { + display: inline-block; + font-weight: bold; + font-size: 11px; + line-height: 18px; + border-radius: 3px; + padding: 0px 5px; + text-align: center; + text-transform: uppercase; + /*background: #e2eaf2;*/ + color: #18873d; +} + +.asyncapi__channels { +} +.asyncapi__channels > div { + margin-top: 24px; + /*background: #fff;*/ + border-radius: 5px; + padding: 16px; + box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.16); +} + +.asyncapi__channels-toggle .asyncapi__toggle-header-content { + padding: 0; +} +.asyncapi__channels-toggle--expanded .asyncapi__toggle-header { + padding-bottom: 12px; +} + +.asyncapi__channels-header { +} +.asyncapi__channels-header > h2 { + margin: 0 0 24px 0; +} + +.asyncapi__channels-list { + padding: 0; + margin: 0; + list-style-type: none; +} + +.asyncapi__channels-list-item { + margin-bottom: 16px; +} +.asyncapi__channels-list-item:last-child { + margin-bottom: 0; +} + +.asyncapi__channel { + position: relative; + border-radius: 4px; + border: solid 1px rgba(151, 151, 151, 0.26); + /*background-color: #ffffff;*/ +} + +.asyncapi__channel-header { + padding: 12px; +} +.asyncapi__channel-header > h3 { + color: #0b74de; + font-size: 15px; +} + +.asyncapi__channel-header-badges { + margin: 0; + padding: 0; + list-style-type: none; + display: inline-block; +} + +.asyncapi__channel-header-badges > li { + display: inline-block; + margin-right: 6px; +} + +.asyncapi__channel-header-badges-deprecated-badge { + display: inline-block; + margin-right: 6px; +} + +.asyncapi__channel-header-badges-publish-badge { + display: inline-block; + margin-right: 6px; +} + +.asyncapi__channel-header-badges-subscribe-badge { + display: inline-block; + margin-right: 6px; +} + +.asyncapi__channel-header-title { + font-size: 14px; +} + +.asyncapi__channel-operations { +} +.asyncapi__channel-operations .asyncapi__message { + border: none; +} + +.asyncapi__channel-operations-header { + color: #32363a; + /*background-color: #fafafa;*/ + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__channel-operations-header > h4 { + padding: 12px; + margin: 0; +} + +.asyncapi__channel-operations-header-oneOf { + border-top: solid 1px rgba(151, 151, 151, 0.26); +} + +.asyncapi__channel-operations-list { + margin: 0; + padding: 0; + list-style-type: none; +} +.asyncapi__channel-operations-list .asyncapi__messages { + padding: 16px; +} +.asyncapi__channel-operations-list .asyncapi__messages-list { + margin: 0; + padding: 0; + list-style-type: none; +} +.asyncapi__channel-operations-list .asyncapi__messages-list-item { + margin-bottom: 16px; +} +.asyncapi__channel-operations-list .asyncapi__messages-list-item:last-child { + margin-bottom: 0; +} +.asyncapi__channel-operations-list + .asyncapi__messages-list-item + .asyncapi__message { + position: relative; + border-radius: 4px; + border: solid 1px rgba(151, 151, 151, 0.26); + /*background-color: #ffffff;*/ +} + +.asyncapi__channel-operations-list-item { +} + +.asyncapi__channel-operation-oneOf-subscribe-header { + color: #32363a; + /*background-color: #fafafa;*/ + border-top: solid 1px rgba(151, 151, 151, 0.26); + border-bottom: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__channel-operation-oneOf-subscribe-header > h4 { + padding: 12px; + margin: 0; +} +.asyncapi__channel-operation-oneOf-subscribe-header > h4 > .asyncapi__badge { + margin-right: 6px; +} + +.asyncapi__channel-operation-oneOf-publish-header { + color: #32363a; + /*background-color: #fafafa;*/ + border-top: solid 1px rgba(151, 151, 151, 0.26); + border-bottom: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__channel-operation-oneOf-publish-header > h4 { + padding: 12px; + margin: 0; +} +.asyncapi__channel-operation-oneOf-publish-header > h4 > .asyncapi__badge { + margin-right: 6px; +} + +.asyncapi__channel-operation { +} + +.asyncapi__channel-parameters { +} + +.asyncapi__channel-parameters-header { + color: #32363a; + /*background-color: #fafafa;*/ + border-top: solid 1px rgba(151, 151, 151, 0.26); +} +.asyncapi__channel-parameters-header > h4 { + padding: 12px; + margin: 0; +} + +.asyncapi__channel-parameters-list { + margin: 0; + padding: 0; + list-style-type: none; +} + +.asyncapi__channel-parameters-list-item { +} + +.asyncapi__channel-parameter { + position: relative; +} + +.asyncapi__channel-parameter-header { +} + +.asyncapi__channel-parameter-header-description { +} + +.asyncapi__channel-parameter-schema { +} +.asyncapi__channel-parameter-schema > .asyncapi__schema { + padding: 0; + border: none; +} +.asyncapi__channel-parameter-schema > .asyncapi__schema:before { + content: ''; + position: relative; + border: none; +} + +.asyncapi__error { + /*background-color: #ffffff;*/ + border-left: 6px solid #f44336; + border-radius: 4px; + color: #32363a; + font-family: '72'; + font-size: 13px; + margin-bottom: 24px; + box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.16); +} + +.asyncapi__error-header { + padding: 16px; + box-shadow: inset 0 -1px 0 0 rgba(115, 121, 128, 0.15); + font-weight: bold; + position: relative; + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: center; +} +.asyncapi__error-header h2 { + flex-grow: 1; + padding: 0; + margin: 0; +} +.asyncapi__error-header > .asyncapi__toggle-header-content { + padding: 0; +} + +.asyncapi__error-body { + font-weight: normal; + position: relative; +} + +.asyncapi__error-body-pre { + margin: 0; + padding: 12px; + background-color: #263238; + white-space: pre-wrap; + word-break: break-word; + color: #fff; + border-bottom-right-radius: 4px; + font-size: 11px; +} + +.asyncapi__error-body-code { + font-family: monospace; + display: block; +} + +.asyncapi__enum { + line-height: 2; + border-style: solid; + border-color: #dae1e7; + border-radius: 0.25rem; + border-width: 1px; + margin-left: 0.25rem; + padding: 0 0.5rem; + color: #f6993f; +} diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx new file mode 100644 index 0000000000..1cab3d194d --- /dev/null +++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx @@ -0,0 +1,40 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { FC, useEffect, useState } from 'react'; +import SwaggerUI from 'swagger-ui-react'; +import 'swagger-ui-react/swagger-ui.css'; + +export const OpenApiDefinitionWidget: FC<{ + definition: any; +}> = ({ definition }) => { + // Due to a bug in the swagger-ui-react component, the component needs + // to be created without content first. + const [def, setDef] = useState(''); + + useEffect(() => { + const timer = setTimeout(() => setDef(definition), 0); + return () => clearTimeout(timer); + }, [definition, setDef]); + + // TODO: This looks fine in the light theme, but wrong in dark mode. We need a custom stylesheet for swagger-ui. + // Till then, we add a white background to the swagger-ui to make it usable in dark mode. + return ( +
+ +
+ ); +}; diff --git a/plugins/api-docs/src/components/PlainApiDefinitionWidget/PlainApiDefinitionWidget.tsx b/plugins/api-docs/src/components/PlainApiDefinitionWidget/PlainApiDefinitionWidget.tsx new file mode 100644 index 0000000000..4ceeed06e1 --- /dev/null +++ b/plugins/api-docs/src/components/PlainApiDefinitionWidget/PlainApiDefinitionWidget.tsx @@ -0,0 +1,24 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { CodeSnippet } from '@backstage/core'; +import React, { FC } from 'react'; + +export const PlainApiDefinitionWidget: FC<{ + definition: any; +}> = ({ definition }) => { + return ; +}; diff --git a/plugins/api-docs/src/index.ts b/plugins/api-docs/src/index.ts new file mode 100644 index 0000000000..c82a2c263b --- /dev/null +++ b/plugins/api-docs/src/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { ApiDefinitionCard } from './components/ApiDefinitionCard/ApiDefinitionCard'; +export { plugin } from './plugin'; diff --git a/plugins/api-docs/src/plugin.test.ts b/plugins/api-docs/src/plugin.test.ts new file mode 100644 index 0000000000..054e804382 --- /dev/null +++ b/plugins/api-docs/src/plugin.test.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { plugin } from './plugin'; + +describe('api-docs', () => { + it('should export plugin', () => { + expect(plugin).toBeDefined(); + }); +}); diff --git a/plugins/api-docs/src/plugin.ts b/plugins/api-docs/src/plugin.ts new file mode 100644 index 0000000000..db58538b67 --- /dev/null +++ b/plugins/api-docs/src/plugin.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createPlugin } from '@backstage/core'; +import { ApiCatalogPage } from './components/ApiCatalogPage/ApiCatalogPage'; +import { ApiEntityPage } from './components/ApiEntityPage/ApiEntityPage'; +import { entityRoute, rootRoute } from './routes'; + +export const plugin = createPlugin({ + id: 'api-docs', + register({ router }) { + router.addRoute(rootRoute, ApiCatalogPage); + router.addRoute(entityRoute, ApiEntityPage); + }, +}); diff --git a/plugins/api-docs/src/routes.ts b/plugins/api-docs/src/routes.ts new file mode 100644 index 0000000000..48c530d4b5 --- /dev/null +++ b/plugins/api-docs/src/routes.ts @@ -0,0 +1,30 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createRouteRef } from '@backstage/core'; + +const NoIcon = () => null; + +export const rootRoute = createRouteRef({ + icon: NoIcon, + path: '/api-docs', + title: 'APIs', +}); +export const entityRoute = createRouteRef({ + icon: NoIcon, + path: '/api-docs/:optionalNamespaceAndName/', + title: 'API', +}); diff --git a/plugins/api-docs/src/setupTests.ts b/plugins/api-docs/src/setupTests.ts new file mode 100644 index 0000000000..8553642152 --- /dev/null +++ b/plugins/api-docs/src/setupTests.ts @@ -0,0 +1,19 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '@testing-library/jest-dom'; + +require('jest-fetch-mock').enableMocks(); diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 4fbe982de4..24e342882f 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -18,7 +18,8 @@ "prepack": "backstage-cli prepack", "postpack": "backstage-cli postpack", "clean": "backstage-cli clean", - "mock-data": "./scripts/mock-data.sh" + "mock-data": "./scripts/mock-data.sh", + "mock-data:local": "./scripts/mock-data-local.sh" }, "dependencies": { "@backstage/backend-common": "^0.1.1-alpha.18", diff --git a/plugins/catalog-backend/scripts/mock-data-local.sh b/plugins/catalog-backend/scripts/mock-data-local.sh new file mode 100755 index 0000000000..3bea819319 --- /dev/null +++ b/plugins/catalog-backend/scripts/mock-data-local.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +for FILE in \ + ../../packages/catalog-model/examples/*.yaml \ +; do \ + curl \ + --location \ + --request POST 'localhost:7000/catalog/locations' \ + --header 'Content-Type: application/json' \ + --data-raw "{\"type\": \"file\", \"target\": \"../catalog-model/${FILE}\"}" + echo +done diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 4f0e5df322..d91b8c03cc 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -23,6 +23,7 @@ "dependencies": { "@backstage/catalog-model": "^0.1.1-alpha.18", "@backstage/core": "^0.1.1-alpha.18", + "@backstage/plugin-api-docs": "^0.1.1-alpha.18", "@backstage/plugin-github-actions": "^0.1.1-alpha.18", "@backstage/plugin-jenkins": "^0.1.1-alpha.18", "@backstage/plugin-scaffolder": "^0.1.1-alpha.18", diff --git a/plugins/catalog/src/components/EntityPageApi/EntityPageApi.tsx b/plugins/catalog/src/components/EntityPageApi/EntityPageApi.tsx new file mode 100644 index 0000000000..b115539366 --- /dev/null +++ b/plugins/catalog/src/components/EntityPageApi/EntityPageApi.tsx @@ -0,0 +1,72 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ApiEntityV1alpha1, Entity } from '@backstage/catalog-model'; +import { Content, Progress, useApi } from '@backstage/core'; +import { ApiDefinitionCard } from '@backstage/plugin-api-docs'; +import { Grid } from '@material-ui/core'; +import { Alert } from '@material-ui/lab'; +import React, { FC } from 'react'; +import { useAsync } from 'react-use'; +import { catalogApiRef } from '../..'; + +export const EntityPageApi: FC<{ entity: Entity }> = ({ entity }) => { + const catalogApi = useApi(catalogApiRef); + + const { value: apiEntities, loading } = useAsync(async () => { + const a = await Promise.all( + ((entity?.spec?.implementedApis as string[]) || []).map(api => + catalogApi.getEntityByName({ + kind: 'API', + name: api, + }), + ), + ); + const b = new Map(); + + a.filter(api => !!api).forEach(api => { + b.set(api?.metadata?.name!, api as ApiEntityV1alpha1); + }); + return b; + }, [catalogApi, entity]); + + return ( + + {loading && } + {!loading && ( + + {((entity?.spec?.implementedApis as string[]) || []).map(api => { + const apiEntity = apiEntities && apiEntities.get(api); + + return ( + + {!apiEntity && ( + + Error on fetching the API: {api} + + )} + + {apiEntity && ( + + )} + + ); + })} + + )} + + ); +}; diff --git a/plugins/catalog/src/components/EntityPageOverview/EntityPageOverview.tsx b/plugins/catalog/src/components/EntityPageOverview/EntityPageOverview.tsx new file mode 100644 index 0000000000..f4faa8c574 --- /dev/null +++ b/plugins/catalog/src/components/EntityPageOverview/EntityPageOverview.tsx @@ -0,0 +1,61 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { Content } from '@backstage/core'; +import { SentryIssuesWidget } from '@backstage/plugin-sentry'; +import { Widget as GithubActionsWidget } from '@backstage/plugin-github-actions'; +import { JenkinsBuildsWidget, JenkinsLastBuildWidget, } from '@backstage/plugin-jenkins'; +import { Grid } from '@material-ui/core'; +import React, { FC } from 'react'; +import { EntityMetadataCard } from '../EntityMetadataCard/EntityMetadataCard'; + +export const EntityPageOverview: FC<{ entity: Entity }> = ({ entity }) => { + return ( + + + + + + {entity.metadata?.annotations?.[ + 'backstage.io/jenkins-github-folder' + ] && ( + + + + )} + {entity.metadata?.annotations?.[ + 'backstage.io/jenkins-github-folder' + ] && ( + + + + )} + {entity.metadata?.annotations?.['backstage.io/github-actions-id'] && ( + + + + )} + + + + + + ); +}; diff --git a/yarn.lock b/yarn.lock index f2af00c7fb..cfea0928b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -40,6 +40,18 @@ resolved "https://registry.npmjs.org/@ardatan/aggregate-error/-/aggregate-error-0.0.1.tgz#1403ac5de10d8ca689fc1f65844c27179ae1d44f" integrity sha512-UQ9BequOTIavs0pTHLMwQwKQF8tTV1oezY/H2O9chA+JNPFZSua55xpU5dPSjAU9/jLJ1VwU+HJuTVN8u7S6Fg== +"@asyncapi/parser@0.16.2": + version "0.16.2" + resolved "https://registry.npmjs.org/@asyncapi/parser/-/parser-0.16.2.tgz#6e0806d0a751e999499212e52926a6dc6ec251fe" + integrity sha512-dagGD6VFAgl/zLQuoWAfi48i74wv32naV6WcvazcpvEXshW3Q//OrUyRFa6EbY0lmIMXeasc7HKm40AUJ920ug== + dependencies: + ajv "^6.10.1" + asyncapi "^2.6.1" + js-yaml "^3.13.1" + json-schema-ref-parser "^7.1.0" + node-fetch "^2.6.0" + tiny-merge-patch "^0.1.2" + "@babel/code-frame@7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" @@ -1137,6 +1149,14 @@ "@babel/plugin-transform-react-jsx-source" "^7.10.4" "@babel/plugin-transform-react-pure-annotations" "^7.10.4" +"@babel/runtime-corejs2@^7.10.4": + version "7.11.2" + resolved "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.11.2.tgz#700a03945ebad0d31ba6690fc8a6bcc9040faa47" + integrity sha512-AC/ciV28adSSpEkBglONBWq4/Lvm6GAZuxIoyVtsnUpZMl0bxLtoChEnYAkP+47KyOCayZanojtflUEUJtR/6Q== + dependencies: + core-js "^2.6.5" + regenerator-runtime "^0.13.4" + "@babel/runtime-corejs2@^7.8.7": version "7.10.3" resolved "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.10.3.tgz#81bc99a96bfcb6db3f0dcf73fdc577cc554d341b" @@ -1239,6 +1259,11 @@ resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@braintree/sanitize-url@^4.0.0": + version "4.1.1" + resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-4.1.1.tgz#671b3cfdbcc40d1449036ce586e882ab6150828e" + integrity sha512-epVksusKVEpwBs2vRg3SWssxn9KXs9CxEYNOcgeSRLRjq070ABj5bLPxkmtQpVeSPCHj8kfAE9J6z2WsLr4wZg== + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1832,6 +1857,31 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@kyleshockey/object-assign-deep@^0.4.2": + version "0.4.2" + resolved "https://registry.npmjs.org/@kyleshockey/object-assign-deep/-/object-assign-deep-0.4.2.tgz#84900f0eefc372798f4751b5262830b8208922ec" + integrity sha1-hJAPDu/DcnmPR1G1JigwuCCJIuw= + +"@kyleshockey/xml@^1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@kyleshockey/xml/-/xml-1.0.2.tgz#81fad3d7c33da2ba2639db095db3db24c2921f70" + integrity sha512-iMo32MPLcI9cPxs3YL5kmKxKgDmkSZDCFEqIT5eRk7d/Ll8r4X3SwGYSigzALd6+RHWlFEmjL1QyaQ15xDZFlw== + dependencies: + stream "^0.0.2" + +"@kyma-project/asyncapi-react@^0.6.1": + version "0.6.2" + resolved "https://registry.npmjs.org/@kyma-project/asyncapi-react/-/asyncapi-react-0.6.2.tgz#99539f630b511d4f7298805dfaf545956192141c" + integrity sha512-yGgYv0XyxI5PxNv0GzTqABsXKwFETlZwBWDqwfUtwirTOTIFyLU69lHbMtM9gn0hPFciP09uHmKt8+8gOpMKvA== + dependencies: + "@asyncapi/parser" "0.16.2" + constate "^1.2.0" + dompurify "^1.0.11" + markdown-it "^9.1.0" + merge "^1.2.1" + openapi-sampler "^1.0.0-beta.15" + react-use "^12.2.0" + "@lerna/add@3.21.0": version "3.21.0" resolved "https://registry.npmjs.org/@lerna/add/-/add-3.21.0.tgz#27007bde71cc7b0a2969ab3c2f0ae41578b4577b" @@ -2517,6 +2567,11 @@ npmlog "^4.1.2" write-file-atomic "^2.3.0" +"@material-icons/font@^1.0.2": + version "1.0.3" + resolved "https://registry.npmjs.org/@material-icons/font/-/font-1.0.3.tgz#f722e5a69a03f20ef47d015cb69420bebeeaabe5" + integrity sha512-aIRd0Z9b/HJ/O24KOaP7dNsXypMnXhpWrpLVYvQB/JesVqXYSbioYND200sR+C14a0LSCp+qWnWCnSXmN1hWGw== + "@material-ui/core@^4.9.1": version "4.9.7" resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.9.7.tgz#0c1caf123278770f34c5d8e9ecd9e1314f87a621" @@ -4601,6 +4656,13 @@ dependencies: "@types/react" "*" +"@types/react-wait@^0.3.0": + version "0.3.1" + resolved "https://registry.npmjs.org/@types/react-wait/-/react-wait-0.3.1.tgz#193cbd8fe86baa53b6f65dfa73f03d562f462a27" + integrity sha512-BS9AEjWZItDgpx6LlICcuf53M27zBFCsHx/llCbrmrt/WI7ecG2LGquCss3n8O8bwEDiTX4yYLjy8yLeIfgYTg== + dependencies: + "@types/react" "*" + "@types/react@*", "@types/react@^16.9": version "16.9.37" resolved "https://registry.npmjs.org/@types/react/-/react-16.9.37.tgz#8fb93e7dbd5b1d3796f69aa979a7fe0439bc7bea" @@ -4609,6 +4671,13 @@ "@types/prop-types" "*" csstype "^2.2.0" +"@types/react@16.4.6": + version "16.4.6" + resolved "https://registry.npmjs.org/@types/react/-/react-16.4.6.tgz#5024957c6bcef4f02823accf5974faba2e54fada" + integrity sha512-9LDZdhsuKSc+DjY65SjBkA958oBWcTWSVWAd2cD9XqKBjhGw1KzAkRhWRw2eIsXvaIE/TOTjjKMFVC+JA1iU4g== + dependencies: + csstype "^2.2.0" + "@types/recursive-readdir@^2.2.0": version "2.2.0" resolved "https://registry.npmjs.org/@types/recursive-readdir/-/recursive-readdir-2.2.0.tgz#b39cd5474fd58ea727fe434d5c68b7a20ba9121c" @@ -4716,6 +4785,13 @@ dependencies: "@types/superagent" "*" +"@types/swagger-ui-react@^3.23.3": + version "3.23.3" + resolved "https://registry.npmjs.org/@types/swagger-ui-react/-/swagger-ui-react-3.23.3.tgz#56bcf3872d8655500e6d51d29ba3916397806fa3" + integrity sha512-JKWYWAliabBxMxURagpRR6RHLEZxxp2W2tf1IN7ftqye6dIxC2e4mh4eZzARPG8+2OpzKlodHIOIwueFTYWaag== + dependencies: + "@types/react" "*" + "@types/tapable@*", "@types/tapable@^1.0.5": version "1.0.5" resolved "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" @@ -5273,6 +5349,16 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.5.5, ajv@^6.7.0: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.10.1: + version "6.12.3" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz#18c5af38a111ddeb4f2697bd78d68abc1cabd706" + integrity sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -5594,7 +5680,7 @@ arg@^4.1.0: resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== -argparse@^1.0.7: +argparse@^1.0.10, argparse@^1.0.7: version "1.0.10" resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== @@ -5828,6 +5914,11 @@ async@^3.2.0: resolved "https://registry.npmjs.org/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== +asyncapi@^2.6.1: + version "2.6.1" + resolved "https://registry.npmjs.org/asyncapi/-/asyncapi-2.6.1.tgz#5e35124abfd416f050a239bf72cb8eef7ebeda66" + integrity sha512-ROszLQMYzyp/CzPyLhuT/9NpJXxI7wrjv6yW8JpA/XVMEWCqyVXr9jajJhs9d/863+ispS+ptGhg1PC17AnIzQ== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -5848,6 +5939,13 @@ atob@^2.1.2: resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +autolinker@^3.11.0: + version "3.14.1" + resolved "https://registry.npmjs.org/autolinker/-/autolinker-3.14.1.tgz#6ae4b812b6eaf42d4d68138b9e67757cbf2bc1e4" + integrity sha512-yvsRHIaY51EYDml6MGlbqyJGfl4n7zezGYf+R7gvM8c5LNpRGc4SISkvgAswSS8SWxk/OrGCylKV9mJyVstz7w== + dependencies: + tslib "^1.9.3" + autoprefixer@^9.7.2: version "9.7.4" resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz#f8bf3e06707d047f0641d87aee8cfb174b2a5378" @@ -6233,7 +6331,7 @@ base64-arraybuffer@^0.1.5: resolved "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= -base64-js@^1.0.2: +base64-js@^1.0.2, base64-js@^1.2.0: version "1.3.1" resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== @@ -6544,6 +6642,11 @@ btoa-lite@^1.0.0: resolved "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc= +btoa@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz#01a9909f8b2c93f6bf680ba26131eb30f7fa3d73" + integrity sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g== + buffer-alloc-unsafe@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" @@ -6601,7 +6704,7 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.5.0: +buffer@^5.5.0, buffer@^5.6.0: version "5.6.0" resolved "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== @@ -7483,6 +7586,11 @@ constants-browserify@^1.0.0: resolved "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= +constate@^1.2.0: + version "1.3.2" + resolved "https://registry.npmjs.org/constate/-/constate-1.3.2.tgz#fa5f0fc292207f1ec21b46a5eb81f59c8b0a8b84" + integrity sha512-aaILV4vXwGTUZaQZHS5F1xBV8wRCR0Ow1505fdkS5/BPg6hbQrhNqdHL4wgxWgaDeEj43mu/Fb+LhqOKTMcrgQ== + contains-path@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" @@ -7613,7 +7721,7 @@ cookie@0.4.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== -cookie@^0.4.1: +cookie@^0.4.1, cookie@~0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== @@ -7640,7 +7748,7 @@ copy-descriptor@^0.1.0: resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -copy-to-clipboard@^3.0.8, copy-to-clipboard@^3.2.0: +copy-to-clipboard@^3, copy-to-clipboard@^3.0.8, copy-to-clipboard@^3.1.0, copy-to-clipboard@^3.2.0: version "3.3.1" resolved "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae" integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw== @@ -7660,7 +7768,7 @@ core-js-pure@^3.0.0, core-js-pure@^3.0.1: resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.4.tgz#4bf1ba866e25814f149d4e9aaa08c36173506e3a" integrity sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw== -core-js@^2.4.0, core-js@^2.5.7, core-js@^2.6.5: +core-js@^2.4.0, core-js@^2.5.7, core-js@^2.6.11, core-js@^2.6.5: version "2.6.11" resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== @@ -7758,7 +7866,7 @@ cross-env@^7.0.0: dependencies: cross-spawn "^7.0.1" -cross-fetch@3.0.5: +cross-fetch@3.0.5, cross-fetch@^3.0.5: version "3.0.5" resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.5.tgz#2739d2981892e7ab488a7ad03b92df2816e03f4c" integrity sha512-FFLcLtraisj5eteosnX1gf01qYDCOc4fDy0+euOt8Kn9YBY2NtXL/pCoYPavw24NIQkQqm5ZOLsGD5Zzj0gyew== @@ -7958,7 +8066,7 @@ css-what@^3.2.1: resolved "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz#f4a8f12421064621b456755e34a03a2c22df5da1" integrity sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw== -css.escape@^1.5.1: +css.escape@1.5.1, css.escape@^1.5.1: version "1.5.1" resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= @@ -8323,7 +8431,7 @@ deep-equal@^1.0.1, deep-equal@^1.1.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" -deep-extend@^0.6.0: +deep-extend@0.6.0, deep-extend@^0.6.0, deep-extend@~0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== @@ -8736,6 +8844,16 @@ domhandler@^3.0, domhandler@^3.0.0: dependencies: domelementtype "^2.0.1" +dompurify@^1.0.11: + version "1.0.11" + resolved "https://registry.npmjs.org/dompurify/-/dompurify-1.0.11.tgz#fe0f4a40d147f7cebbe31a50a1357539cfc1eb4d" + integrity sha512-XywCTXZtc/qCX3iprD1pIklRVk/uhl8BKpkTxr+ZyMVUzSUg7wkQXRBp/euJ5J5moa1QvfpvaPQVP71z1O59dQ== + +dompurify@^2.0.7: + version "2.0.12" + resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.0.12.tgz#284a2b041e1c60b8e72d7b4d2fadad36141254ae" + integrity sha512-Fl8KseK1imyhErHypFPA8qpq9gPzlsJ/EukA6yk9o0gX23p1TzC+rh9LqNg1qvErRTc0UNMYlKxEGSfSh43NDg== + domutils@1.5.1: version "1.5.1" resolved "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" @@ -8892,6 +9010,11 @@ elliptic@^6.0.0: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.0" +emitter-component@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz#065e2dbed6959bf470679edabeaf7981d1003ab6" + integrity sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY= + "emoji-regex@>=6.0.0 <=6.1.1": version "6.1.1" resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e" @@ -8968,7 +9091,7 @@ enquirer@^2.3.5: dependencies: ansi-colors "^3.2.1" -entities@^1.1.1, entities@^1.1.2: +entities@^1.1.1, entities@^1.1.2, entities@~1.1.1: version "1.1.2" resolved "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== @@ -9063,7 +9186,7 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-ext@^0.10.35, es5-ext@^0.10.50: +es5-ext@^0.10.35, es5-ext@^0.10.45, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: version "0.10.53" resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q== @@ -9077,7 +9200,7 @@ es5-shim@^4.5.13: resolved "https://registry.npmjs.org/es5-shim/-/es5-shim-4.5.13.tgz#5d88062de049f8969f83783f4a4884395f21d28b" integrity sha512-xi6hh6gsvDE0MaW4Vp1lgNEBpVcCXRWfPXj5egDvtgLz4L9MEvNwYEMdJH+JJinWkwa8c3c3o5HduV7dB/e1Hw== -es6-iterator@~2.0.3: +es6-iterator@^2.0.3, es6-iterator@~2.0.3: version "2.0.3" resolved "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= @@ -9111,6 +9234,16 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.3: d "^1.0.1" ext "^1.1.2" +es6-weak-map@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" + integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== + dependencies: + d "1" + es5-ext "^0.10.46" + es6-iterator "^2.0.3" + es6-symbol "^3.1.1" + esbuild@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.6.3.tgz#a957e22f2503c745793514388110f9b55b3a6f83" @@ -9442,6 +9575,14 @@ etag@~1.8.1: resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + event-stream@=3.3.4: version "3.3.4" resolved "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" @@ -9737,6 +9878,13 @@ fast-glob@^3.0.3, fast-glob@^3.1.1: micromatch "^4.0.2" picomatch "^2.2.1" +fast-json-patch@^2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-2.2.1.tgz#18150d36c9ab65c7209e7d4eb113f4f8eaabe6d9" + integrity sha512-4j5uBaTnsYAV5ebkidvxiLUYOwjQ+JSFljeqfTxCrH9bDmlCQaOJFS84oDJ2rAXZq2yskmk3ORfoP9DCwqFNig== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -10087,6 +10235,11 @@ for-own@^1.0.0: dependencies: for-in "^1.0.1" +foreach@^2.0.4: + version "2.0.5" + resolved "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -10133,7 +10286,7 @@ fork-ts-checker-webpack-plugin@^4.0.5: tapable "^1.0.0" worker-rpc "^0.1.0" -form-data@^2.3.1: +form-data@^2.3.1, form-data@^2.3.2: version "2.5.1" resolved "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== @@ -11041,6 +11194,11 @@ highlight.js@~9.13.0: resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e" integrity sha512-Sc28JNQNDzaH6PORtRLMvif9RSn1mYuOoX3omVjnb0+HbpPygU2ALBI0R/wsiqCb4/fcp07Gdo8g+fhtFrQl6A== +highlight.js@~9.15.0, highlight.js@~9.15.1: + version "9.15.10" + resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.10.tgz#7b18ed75c90348c045eef9ed08ca1319a2219ad2" + integrity sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw== + history@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/history/-/history-5.0.0.tgz#0cabbb6c4bbf835addb874f8259f6d25101efd08" @@ -11387,7 +11545,7 @@ identity-obj-proxy@3.0.0: dependencies: harmony-reflect "^1.4.6" -ieee754@^1.1.4: +ieee754@^1.1.13, ieee754@^1.1.4: version "1.1.13" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== @@ -11429,7 +11587,7 @@ immer@1.10.0: resolved "https://registry.npmjs.org/immer/-/immer-1.10.0.tgz#bad67605ba9c810275d91e1c2a47d4582e98286d" integrity sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg== -immutable@>=3.8.2, immutable@^3.8.2: +immutable@>=3.8.2, immutable@^3.8.1, immutable@^3.8.2, immutable@^3.x.x: version "3.8.2" resolved "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= @@ -12069,6 +12227,11 @@ is-potential-custom-element-name@^1.0.0: resolved "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= +is-promise@^2.1: + version "2.2.2" + resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + is-promise@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -12242,6 +12405,13 @@ isobject@^4.0.0: resolved "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== +isomorphic-form-data@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isomorphic-form-data/-/isomorphic-form-data-2.0.0.tgz#9f6adf1c4c61ae3aefd8f110ab60fb9b143d6cec" + integrity sha512-TYgVnXWeESVmQSg4GLVbalmQ+B4NPi/H4eWxqALKj63KsUrcu301YDjBqaOw3h+cbak7Na4Xyps3BiptHtxTfg== + dependencies: + form-data "^2.3.2" + isstream@~0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -12749,6 +12919,11 @@ js-cookie@^2.2.1: resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== +js-file-download@^0.4.1: + version "0.4.12" + resolved "https://registry.npmjs.org/js-file-download/-/js-file-download-0.4.12.tgz#10c70ef362559a5b23cdbdc3bd6f399c3d91d821" + integrity sha512-rML+NkoD08p5Dllpjo0ffy4jRHeY6Zsapvr/W86N7E0yuzAO6qa5X9+xog6zQNlH102J7IXljNY2FtS6Lj3ucg== + js-string-escape@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" @@ -12772,6 +12947,14 @@ js-yaml@^3.13.1, js-yaml@^3.8.3: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^3.14.0: + version "3.14.0" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" + integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -12884,6 +13067,13 @@ json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-bet resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== +json-pointer@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.0.tgz#8e500550a6aac5464a473377da57aa6cc22828d7" + integrity sha1-jlAFUKaqxUZKRzN32leqbMIoKNc= + dependencies: + foreach "^2.0.4" + json-schema-compare@^0.2.2: version "0.2.2" resolved "https://registry.npmjs.org/json-schema-compare/-/json-schema-compare-0.2.2.tgz#dd601508335a90c7f4cfadb6b2e397225c908e56" @@ -12900,6 +13090,15 @@ json-schema-merge-allof@^0.6.0: json-schema-compare "^0.2.2" lodash "^4.17.4" +json-schema-ref-parser@^7.1.0: + version "7.1.4" + resolved "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-7.1.4.tgz#abb3f2613911e9060dc2268477b40591753facf0" + integrity sha512-AD7bvav0vak1/63w3jH8F7eHId/4E4EPdMAEZhGxtjktteUv9dnNB/cJy6nVnMyoTPBJnLwFK6tiQPSTeleCtQ== + dependencies: + call-me-maybe "^1.0.1" + js-yaml "^3.13.1" + ono "^6.0.0" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -13493,7 +13692,7 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= -lodash.debounce@^4.0.8: +lodash.debounce@^4, lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= @@ -13671,6 +13870,14 @@ lowercase-keys@^2.0.0: resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lowlight@1.12.1: + version "1.12.1" + resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.12.1.tgz#014acf8dd73a370e02ff1cc61debcde3bb1681eb" + integrity sha512-OqaVxMGIESnawn+TU/QMV5BJLbUghUfjDWPAtFqDYDmDtr4FnB+op8xM+pR7nKlauHNUHXGt0VgWatFB8voS5w== + dependencies: + fault "^1.0.2" + highlight.js "~9.15.0" + lowlight@^1.14.0: version "1.14.0" resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.14.0.tgz#83ebc143fec0f9e6c0d3deffe01be129ce56b108" @@ -13694,6 +13901,13 @@ lru-cache@^5.0.0, lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lru-queue@0.1: + version "0.1.0" + resolved "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" + integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM= + dependencies: + es5-ext "~0.10.2" + macos-release@^2.2.0: version "2.3.0" resolved "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f" @@ -13817,6 +14031,17 @@ markdown-it@^10.0.0: mdurl "^1.0.1" uc.micro "^1.0.5" +markdown-it@^9.1.0: + version "9.1.0" + resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-9.1.0.tgz#df9601c168568704d554b1fff9af0c5b561168d9" + integrity sha512-xHKG4C8iPriyfu/jc2hsCC045fKrMQ0VexX2F1FGYiRxDxqMB2aAhF8WauJ3fltn2kb90moGBkiiEdooGIg55w== + dependencies: + argparse "^1.0.7" + entities "~1.1.1" + linkify-it "^2.0.0" + mdurl "^1.0.1" + uc.micro "^1.0.5" + markdown-to-jsx@^6.11.4: version "6.11.4" resolved "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-6.11.4.tgz#b4528b1ab668aef7fe61c1535c27e837819392c5" @@ -13884,6 +14109,20 @@ memoize-one@^5.1.1: resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0" integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA== +memoizee@^0.4.12: + version "0.4.14" + resolved "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz#07a00f204699f9a95c2d9e77218271c7cd610d57" + integrity sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg== + dependencies: + d "1" + es5-ext "^0.10.45" + es6-weak-map "^2.0.2" + event-emitter "^0.3.5" + is-promise "^2.1" + lru-queue "0.1" + next-tick "1" + timers-ext "^0.1.5" + memoizerific@^1.11.3: version "1.11.3" resolved "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" @@ -13977,6 +14216,11 @@ merge2@^1.2.3, merge2@^1.3.0: resolved "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== +merge@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + methods@^1.0.0, methods@^1.1.1, methods@^1.1.2, methods@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -14397,7 +14641,7 @@ nan@^2.14.0: resolved "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== -nano-css@^5.2.1: +nano-css@^5.1.0, nano-css@^5.2.1: version "5.3.0" resolved "https://registry.npmjs.org/nano-css/-/nano-css-5.3.0.tgz#9d3cd29788d48b6a07f52aa4aec7cf4da427b6b5" integrity sha512-uM/9NGK9/E9/sTpbIZ/bQ9xOLOIHZwrrb/CRlbDHBU/GFS7Gshl24v/WJhwsVViWkpOXUmiZ66XO7fSB4Wd92Q== @@ -14457,6 +14701,11 @@ neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1: resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== +next-tick@1: + version "1.1.0" + resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + next-tick@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" @@ -15048,6 +15297,11 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" +ono@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/ono/-/ono-6.0.1.tgz#1bc14ffb8af1e5db3f7397f75b88e4a2d64bbd71" + integrity sha512-5rdYW/106kHqLeG22GE2MHKq+FlsxMERZev9DCzQX1zwkxnFwBivSn5i17a5O/rDmOJOdf4Wyt80UZljzx9+DA== + open@^6.3.0: version "6.4.0" resolved "https://registry.npmjs.org/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" @@ -15063,6 +15317,13 @@ open@^7.0.0, open@^7.0.2: is-docker "^2.0.0" is-wsl "^2.1.1" +openapi-sampler@^1.0.0-beta.15: + version "1.0.0-beta.16" + resolved "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.0.0-beta.16.tgz#7813524d5b88d222efb772ceb5a809075d6d9174" + integrity sha512-05+GvwMagTY7GxoDQoWJfmAUFlxfebciiEzqKmu4iq6+MqBEn62AMUkn0CTxyKhnUGIaR2KXjTeslxIeJwVIOw== + dependencies: + json-pointer "^0.6.0" + opencollective-postinstall@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" @@ -15712,6 +15973,11 @@ pend@~1.2.0: resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + integrity sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU= + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -16569,7 +16835,7 @@ promzard@^0.3.0: dependencies: read "1" -prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -16719,6 +16985,11 @@ qs@^6.5.1, qs@^6.6.0: resolved "https://registry.npmjs.org/qs/-/qs-6.9.3.tgz#bfadcd296c2d549f1dffa560619132c977f5008e" integrity sha512-EbZYNarm6138UKKq46tdx08Yo/q9ZhFoAXAI1meAFd2GtbRDhbZY2WQSICskT0c5q99aFzLG1D4nvTk9tqfXIw== +qs@^6.9.4: + version "6.9.4" + resolved "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz#9090b290d1f91728d3c22e54843ca44aea5ab687" + integrity sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ== + qs@~6.5.2: version "6.5.2" resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -16732,6 +17003,11 @@ query-string@^4.1.0: object-assign "^4.1.0" strict-uri-encode "^1.0.0" +querystring-browser@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/querystring-browser/-/querystring-browser-1.0.4.tgz#f2e35881840a819bc7b1bf597faf0979e6622dc6" + integrity sha1-8uNYgYQKgZvHsb9Zf68JeeZiLcY= + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -16762,7 +17038,7 @@ raf-schd@^4.0.2: resolved "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.2.tgz#bd44c708188f2e84c810bf55fcea9231bcaed8a0" integrity sha512-VhlMZmGy6A6hrkJWHLNTGl5gtgMUm+xfGza6wbwnE914yeQ5Ybm18vgM734RZhMgfw4tacUrWseGZlpUrrakEQ== -raf@^3.4.1: +raf@^3.1.0, raf@^3.4.1: version "3.4.1" resolved "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== @@ -16784,7 +17060,7 @@ ramda@^0.25.0: resolved "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9" integrity sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ== -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== @@ -16884,6 +17160,22 @@ react-clientside-effect@^1.2.2: dependencies: "@babel/runtime" "^7.0.0" +react-copy-to-clipboard@5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.1.tgz#8eae107bb400be73132ed3b6a7b4fb156090208e" + integrity sha512-ELKq31/E3zjFs5rDWNCfFL4NvNFQvGRoJdAKReD/rUPA+xxiLPQmZBZBvy2vgH7V0GE9isIQpT9WXbwIVErYdA== + dependencies: + copy-to-clipboard "^3" + prop-types "^15.5.8" + +react-debounce-input@^3.2.0: + version "3.2.2" + resolved "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.2.2.tgz#d2cc99c1ce47fae89037965f5699edc1b0317197" + integrity sha512-RIBu68Cq/gImKz/2h1cE042REDqyqj3D+7SJ3lnnIpJX0ht9D9PfH7KAnL+SgDz6hvKa9pZS2CnAxlkrLmnQlg== + dependencies: + lodash.debounce "^4" + prop-types "^15.7.2" + react-dev-utils@^10.2.1: version "10.2.1" resolved "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz#f6de325ae25fa4d546d09df4bb1befdc6dd19c19" @@ -17056,6 +17348,27 @@ react-hotkeys@2.0.0: dependencies: prop-types "^15.6.1" +react-immutable-proptypes@2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz#023d6f39bb15c97c071e9e60d00d136eac5fa0b4" + integrity sha1-Aj1vObsVyXwHHp5g0A0TbqxfoLQ= + +react-immutable-pure-component@^1.1.1: + version "1.2.3" + resolved "https://registry.npmjs.org/react-immutable-pure-component/-/react-immutable-pure-component-1.2.3.tgz#fa33638df68cfe9f73ccbee1d5861c17f3053f86" + integrity sha512-kNy2A/fDrSuR8TKwB+4ynmItmp1vgF87tWxxfmadwDYo2J3ANipHqTjDIBvJvJ7libvuh76jIbvmK0krjtKH1g== + optionalDependencies: + "@types/react" "16.4.6" + +react-inspector@^2.3.0: + version "2.3.1" + resolved "https://registry.npmjs.org/react-inspector/-/react-inspector-2.3.1.tgz#f0eb7f520669b545b441af9d38ec6d706e5f649c" + integrity sha512-tUUK7t3KWgZEIUktOYko5Ic/oYwvjEvQUFAGC1UeMeDaQ5za2yZFtItJa2RTwBJB//NxPr000WQK6sEbqC6y0Q== + dependencies: + babel-runtime "^6.26.0" + is-dom "^1.0.9" + prop-types "^15.6.1" + react-inspector@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/react-inspector/-/react-inspector-4.0.1.tgz#0f888f78ff7daccbc7be5d452b20c96dc6d5fbb8" @@ -17065,7 +17378,7 @@ react-inspector@^4.0.0: is-dom "^1.0.9" prop-types "^15.6.1" -react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: +react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -17085,7 +17398,7 @@ react-lazylog@^4.5.2: text-encoding-utf-8 "^1.0.1" whatwg-fetch "^2.0.4" -react-lifecycles-compat@^3.0.4: +react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== @@ -17104,6 +17417,15 @@ react-markdown@^4.3.1: unist-util-visit "^1.3.0" xtend "^4.0.1" +react-motion@^0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/react-motion/-/react-motion-0.5.2.tgz#0dd3a69e411316567927917c6626551ba0607316" + integrity sha512-9q3YAvHoUiWlP3cK0v+w1N5Z23HXMj4IF4YuvjvWegWqNPfLXsOBE/V7UvQGpXxHFKRQQcNcVQE31g9SB/6qgQ== + dependencies: + performance-now "^0.2.0" + prop-types "^15.5.8" + raf "^3.1.0" + react-popper-tooltip@^2.8.3: version "2.10.1" resolved "https://registry.npmjs.org/react-popper-tooltip/-/react-popper-tooltip-2.10.1.tgz#e10875f31916297c694d64a677d6f8fa0a48b4d1" @@ -17125,6 +17447,19 @@ react-popper@^1.3.6: typed-styles "^0.0.7" warning "^4.0.2" +react-redux@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/react-redux/-/react-redux-5.1.2.tgz#b19cf9e21d694422727bf798e934a916c4080f57" + integrity sha512-Ns1G0XXc8hDyH/OcBHOxNgQx9ayH3SPxBnFCOidGKSle8pKihysQw2rG/PmciUQRoclhVBO8HMhiRmGXnDja9Q== + dependencies: + "@babel/runtime" "^7.1.2" + hoist-non-react-statics "^3.3.0" + invariant "^2.2.4" + loose-envify "^1.1.0" + prop-types "^15.6.1" + react-is "^16.6.0" + react-lifecycles-compat "^3.0.0" + react-redux@^7.1.1: version "7.2.0" resolved "https://registry.npmjs.org/react-redux/-/react-redux-7.2.0.tgz#f970f62192b3981642fec46fd0db18a074fe879d" @@ -17180,6 +17515,17 @@ react-string-replace@^0.4.1: dependencies: lodash "^4.17.4" +react-syntax-highlighter@=12.2.1: + version "12.2.1" + resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-12.2.1.tgz#14d78352da1c1c3f93c6698b70ec7c706b83493e" + integrity sha512-CTsp0ZWijwKRYFg9xhkWD4DSpQqE4vb2NKVMdPAkomnILSmsNBHE0n5GuI5zB+PU3ySVvXvdt9jo+ViD9XibCA== + dependencies: + "@babel/runtime" "^7.3.1" + highlight.js "~9.15.1" + lowlight "1.12.1" + prismjs "^1.8.4" + refractor "^2.4.1" + react-syntax-highlighter@^11.0.2: version "11.0.2" resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz#4e3f376e752b20d2f54e4c55652fd663149e4029" @@ -17235,6 +17581,23 @@ react-universal-interface@^0.6.2: resolved "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b" integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw== +react-use@^12.2.0: + version "12.13.0" + resolved "https://registry.npmjs.org/react-use/-/react-use-12.13.0.tgz#dfefd8145552841f1c2213c2e79966b505a264ba" + integrity sha512-Kh0m9ezIn9xfRycx4jdAgvsYGstGfjTBO2ecIM3+G0RqrpMxTIL5jjYraHYfUzjGBHf7dUhNYBzm5vw5LItVZA== + dependencies: + "@types/react-wait" "^0.3.0" + copy-to-clipboard "^3.1.0" + nano-css "^5.1.0" + react-fast-compare "^2.0.4" + react-wait "^0.3.0" + resize-observer-polyfill "^1.5.1" + screenfull "^5.0.0" + set-harmonic-interval "^1.0.1" + throttle-debounce "^2.0.1" + ts-easing "^0.2.0" + tslib "^1.10.0" + react-use@^15.3.3: version "15.3.3" resolved "https://registry.npmjs.org/react-use/-/react-use-15.3.3.tgz#f16de7a16286c446388e8bd99680952fc3dc9a95" @@ -17267,6 +17630,11 @@ react-virtualized@^9.21.0: prop-types "^15.6.0" react-lifecycles-compat "^3.0.4" +react-wait@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/react-wait/-/react-wait-0.3.0.tgz#0cdd4d919012451a5bc3ab0a16d00c6fd9a8c10b" + integrity sha512-kB5x/kMKWcn0uVr9gBdNz21/oGbQwEQnF3P9p6E9yLfJ9DRcKS0fagbgYMFI0YFOoyKDj+2q6Rwax0kTYJF37g== + react@^16.0.0, react@^16.12.0, react@^16.13.1, react@^16.8.3: version "16.13.1" resolved "https://registry.npmjs.org/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" @@ -17486,7 +17854,14 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -redux@^4.0.4: +redux-immutable@3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/redux-immutable/-/redux-immutable-3.1.0.tgz#cafbd686e0711261119b9c28960935dc47a49d0a" + integrity sha1-yvvWhuBxEmERm5wolgk13EeknQo= + dependencies: + immutable "^3.8.1" + +redux@^4.0.4, redux@^4.0.5: version "4.0.5" resolved "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== @@ -17627,6 +18002,14 @@ remark-parse@^5.0.0: vfile-location "^2.0.0" xtend "^4.0.1" +remarkable@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/remarkable/-/remarkable-2.0.1.tgz#280ae6627384dfb13d98ee3995627ca550a12f31" + integrity sha512-YJyMcOH5lrR+kZdmB0aJJ4+93bEojRZ1HGDn9Eagu6ibg7aVZhc3OWbbShRid+Q5eAfsEqWxpe+g5W5nYNfNiA== + dependencies: + argparse "^1.0.10" + autolinker "^3.11.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -17648,7 +18031,7 @@ repeat-element@^1.1.2: resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== -repeat-string@^1.5.4, repeat-string@^1.6.1: +repeat-string@^1.5.2, repeat-string@^1.5.4, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -17743,6 +18126,11 @@ requires-port@^1.0.0: resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +reselect@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz#f2529830e5d3d0e021408b246a206ef4ea4437f7" + integrity sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA== + resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" @@ -18225,6 +18613,11 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" +serialize-error@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" + integrity sha1-ULZ51WNc34Rme9yOWa9OW4HV9go= + serialize-javascript@^2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61" @@ -18955,6 +19348,13 @@ stream-shift@^1.0.0: resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== +stream@^0.0.2: + version "0.0.2" + resolved "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz#7f5363f057f6592c5595f00bc80a27f5cec1f0ef" + integrity sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8= + dependencies: + emitter-component "^1.1.1" + streamsearch@0.1.2, streamsearch@~0.1.2: version "0.1.2" resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" @@ -19349,6 +19749,68 @@ svgo@^1.0.0, svgo@^1.2.2: unquote "~1.1.1" util.promisify "~1.0.0" +swagger-client@=3.10.12: + version "3.10.12" + resolved "https://registry.npmjs.org/swagger-client/-/swagger-client-3.10.12.tgz#f49beb7a6f91b6e5778cfbd3fd4064413be6e791" + integrity sha512-h2o7axvFViMc5sxwTjjza84Rhfz+C52wgMKPOT0P05jODjZhldBK7y9EvGt4zvqgzBJHS+FDQBmOT/dGf9SWdw== + dependencies: + "@babel/runtime-corejs2" "^7.10.4" + btoa "^1.2.1" + buffer "^5.6.0" + cookie "~0.4.1" + cross-fetch "^3.0.5" + deep-extend "~0.6.0" + fast-json-patch "^2.2.1" + isomorphic-form-data "~2.0.0" + js-yaml "^3.14.0" + lodash "^4.17.19" + qs "^6.9.4" + querystring-browser "^1.0.4" + traverse "~0.6.6" + url "~0.11.0" + +swagger-ui-react@^3.31.1: + version "3.31.1" + resolved "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-3.31.1.tgz#1770cfa1dc390f79887d641ea35ee654f4bf7d80" + integrity sha512-bGpNzizMT/7N4LTdw6yx+t3rpsEoalrn0VIfhUzv9zXVrUTl+3AKPLHpLBr0r4NvzvaZLrYuSjkatnLfngJ4vg== + dependencies: + "@babel/runtime-corejs2" "^7.10.4" + "@braintree/sanitize-url" "^4.0.0" + "@kyleshockey/object-assign-deep" "^0.4.2" + "@kyleshockey/xml" "^1.0.2" + base64-js "^1.2.0" + classnames "^2.2.6" + core-js "^2.6.11" + css.escape "1.5.1" + deep-extend "0.6.0" + dompurify "^2.0.7" + ieee754 "^1.1.13" + immutable "^3.x.x" + js-file-download "^0.4.1" + js-yaml "^3.13.1" + lodash "^4.17.19" + memoizee "^0.4.12" + prop-types "^15.7.2" + randombytes "^2.1.0" + react-copy-to-clipboard "5.0.1" + react-debounce-input "^3.2.0" + react-immutable-proptypes "2.1.0" + react-immutable-pure-component "^1.1.1" + react-inspector "^2.3.0" + react-motion "^0.5.2" + react-redux "^5.1.2" + react-syntax-highlighter "=12.2.1" + redux "^4.0.5" + redux-immutable "3.1.0" + remarkable "^2.0.1" + reselect "^4.0.0" + serialize-error "^2.1.0" + sha.js "^2.4.11" + swagger-client "=3.10.12" + url-parse "^1.4.7" + xml-but-prettier "^1.0.1" + zenscroll "^4.0.2" + swr@^0.2.2: version "0.2.3" resolved "https://registry.npmjs.org/swr/-/swr-0.2.3.tgz#e0fb260d27f12fafa2388312083368f45127480d" @@ -19611,6 +20073,11 @@ throat@^5.0.0: resolved "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" integrity sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA== +throttle-debounce@^2.0.1: + version "2.2.1" + resolved "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.2.1.tgz#fbd933ae6793448816f7d5b3cae259d464c98137" + integrity sha512-i9hAVld1f+woAiyNGqWelpDD5W1tpMroL3NofTz9xzwq6acWBlO2dC8k5EFSZepU6oOINtV5Q3aSPoRg7o4+fA== + throttle-debounce@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.1.0.tgz#257e648f0a56bd9e54fe0f132c4ab8611df4e1d5" @@ -19663,6 +20130,14 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +timers-ext@^0.1.5: + version "0.1.7" + resolved "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" + integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== + dependencies: + es5-ext "~0.10.46" + next-tick "1" + timsort@^0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" @@ -19678,6 +20153,11 @@ tiny-invariant@^1.0.6: resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== +tiny-merge-patch@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/tiny-merge-patch/-/tiny-merge-patch-0.1.2.tgz#2e8ded19c56ea15dbd3ad4ed5db1c8e5ad544c3c" + integrity sha1-Lo3tGcVuoV29OtTtXbHI5a1UTDw= + tiny-warning@^1.0.2: version "1.0.3" resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" @@ -19817,6 +20297,11 @@ tr46@~0.0.3: resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= +traverse@~0.6.6: + version "0.6.6" + resolved "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + integrity sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc= + tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -20335,7 +20820,7 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -url-parse@^1.4.3: +url-parse@^1.4.3, url-parse@^1.4.7: version "1.4.7" resolved "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== @@ -20343,7 +20828,7 @@ url-parse@^1.4.3: querystringify "^2.1.1" requires-port "^1.0.0" -url@0.11.0, url@^0.11.0: +url@0.11.0, url@^0.11.0, url@~0.11.0: version "0.11.0" resolved "https://registry.npmjs.org/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= @@ -21086,6 +21571,13 @@ xdg-basedir@^4.0.0: resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== +xml-but-prettier@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/xml-but-prettier/-/xml-but-prettier-1.0.1.tgz#f5a33267ed42ccd4e355c62557a5e39b01fb40f3" + integrity sha1-9aMyZ+1CzNTjVcYlV6XjmwH7QPM= + dependencies: + repeat-string "^1.5.2" + xml-crypto@^1.4.0: version "1.5.3" resolved "https://registry.npmjs.org/xml-crypto/-/xml-crypto-1.5.3.tgz#a8f500b90f0dfaf0efa3331c345ecb0fff993c34" @@ -21358,6 +21850,11 @@ zen-observable@^0.8.0, zen-observable@^0.8.15: resolved "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== +zenscroll@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz#e8d5774d1c0738a47bcfa8729f3712e2deddeb25" + integrity sha1-6NV3TRwHOKR7z6hynzcS4t7d6yU= + zombie@^6.1.4: version "6.1.4" resolved "https://registry.npmjs.org/zombie/-/zombie-6.1.4.tgz#9f0f53f3d9a032beb7f3fe5b382146a3475a4d47"