manual backport (#24035)
This commit is contained in:
parent
2eff100d5d
commit
f9ab81e55f
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:improvement
|
||||||
|
ui: Update flat, shell-quote and swagger-ui-dist packages. Remove swagger-ui styling overrides.
|
||||||
|
```
|
|
@ -16,6 +16,9 @@
|
||||||
@import './utils/mixins';
|
@import './utils/mixins';
|
||||||
@import './utils/animations';
|
@import './utils/animations';
|
||||||
|
|
||||||
|
// Open-api styling
|
||||||
|
@import './utils/swagger';
|
||||||
|
|
||||||
// Core Styles: each file styles a class that is not associated with a component. Ex: box and not box-label.
|
// Core Styles: each file styles a class that is not associated with a component. Ex: box and not box-label.
|
||||||
@import './core/alert-banner';
|
@import './core/alert-banner';
|
||||||
@import './core/box';
|
@import './core/box';
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) HashiCorp, Inc.
|
||||||
|
* SPDX-License-Identifier: BUSL-1.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This file defines the scss for open-api-explorer.
|
||||||
|
|
||||||
|
/* align list items with container */
|
||||||
|
.swagger-ember .swagger-ui .wrapper {
|
||||||
|
padding: 0;
|
||||||
|
}
|
|
@ -1,109 +1,92 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) HashiCorp, Inc.
|
* Copyright (c) HashiCorp, Inc.
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: BUSL-1.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Component from '@ember/component';
|
import Component from '@glimmer/component';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
|
import { action } from '@ember/object';
|
||||||
|
import { tracked } from '@glimmer/tracking';
|
||||||
import parseURL from 'core/utils/parse-url';
|
import parseURL from 'core/utils/parse-url';
|
||||||
import config from 'open-api-explorer/config/environment';
|
import config from 'open-api-explorer/config/environment';
|
||||||
|
import { guidFor } from '@ember/object/internals';
|
||||||
|
|
||||||
const { APP } = config;
|
const { APP } = config;
|
||||||
|
|
||||||
const SearchFilterPlugin = () => {
|
export default class SwaggerUiComponent extends Component {
|
||||||
return {
|
@service auth;
|
||||||
fn: {
|
@service namespace;
|
||||||
opsFilter: (taggedOps, phrase) => {
|
|
||||||
// map over the options and filter out operations where the path doesn't match what's typed
|
@tracked swaggerLoading = true;
|
||||||
return (
|
|
||||||
taggedOps
|
inputId = `${guidFor(this)}-swagger`;
|
||||||
.map((tagObj) => {
|
|
||||||
const operations = tagObj.get('operations').filter((operationObj) => {
|
SearchFilterPlugin() {
|
||||||
return operationObj.get('path').includes(phrase);
|
return {
|
||||||
});
|
fn: {
|
||||||
return tagObj.set('operations', operations);
|
opsFilter: (taggedOps, phrase) => {
|
||||||
})
|
// map over the options and filter out operations where the path doesn't match what's typed
|
||||||
// then traverse again and remove the top level item if there are no operations left after filtering
|
return (
|
||||||
.filter((tagObj) => !!tagObj.get('operations').size)
|
taggedOps
|
||||||
);
|
.map((tagObj) => {
|
||||||
|
const operations = tagObj.get('operations').filter((operationObj) => {
|
||||||
|
return operationObj.get('path').includes(phrase);
|
||||||
|
});
|
||||||
|
return tagObj.set('operations', operations);
|
||||||
|
})
|
||||||
|
// then traverse again and remove the top level item if there are no operations left after filtering
|
||||||
|
.filter((tagObj) => !!tagObj.get('operations').size)
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
CONFIG = (SwaggerUIBundle, componentInstance) => {
|
||||||
|
return {
|
||||||
|
dom_id: `#${componentInstance.inputId}`,
|
||||||
|
url: '/v1/sys/internal/specs/openapi',
|
||||||
|
deepLinking: false,
|
||||||
|
presets: [SwaggerUIBundle.presets.apis],
|
||||||
|
plugins: [SwaggerUIBundle.plugins.DownloadUrl, this.SearchFilterPlugin],
|
||||||
|
// 'list' expands tags, but not operations
|
||||||
|
docExpansion: 'list',
|
||||||
|
operationsSorter: 'alpha',
|
||||||
|
filter: true,
|
||||||
|
// this makes sure we show the x-vault- options
|
||||||
|
showExtensions: true,
|
||||||
|
// we don't have any models defined currently
|
||||||
|
defaultModelsExpandDepth: -1,
|
||||||
|
defaultModelExpandDepth: 1,
|
||||||
|
requestInterceptor: (req) => {
|
||||||
|
// we need to add vault authorization header
|
||||||
|
// and namespace headers for things to work properly
|
||||||
|
req.headers['X-Vault-Token'] = componentInstance.auth.currentToken;
|
||||||
|
const namespace = componentInstance.namespace.path;
|
||||||
|
if (namespace && !APP.NAMESPACE_ROOT_URLS.some((str) => req.url.includes(str))) {
|
||||||
|
req.headers['X-Vault-Namespace'] = namespace;
|
||||||
|
}
|
||||||
|
// we want to link to the right JSON in swagger UI so
|
||||||
|
// it's already been pre-pended
|
||||||
|
if (!req.loadSpec) {
|
||||||
|
const { protocol, host, pathname, search } = parseURL(req.url);
|
||||||
|
//paths in the spec don't have /v1 in them, so we need to add that here
|
||||||
|
// http(s): vlt.io:4200 /sys/mounts
|
||||||
|
req.url = `${protocol}//${host}/v1${pathname}${search}`;
|
||||||
|
}
|
||||||
|
return req;
|
||||||
|
},
|
||||||
|
onComplete: () => {
|
||||||
|
componentInstance.swaggerLoading = false;
|
||||||
|
},
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
const CONFIG = (SwaggerUIBundle, componentInstance, initialFilter) => {
|
// using an action to bind the correct "this" context
|
||||||
return {
|
@action async swaggerInit() {
|
||||||
dom_id: `#${componentInstance.elementId}-swagger`,
|
|
||||||
url: '/v1/sys/internal/specs/openapi',
|
|
||||||
deepLinking: false,
|
|
||||||
presets: [SwaggerUIBundle.presets.apis],
|
|
||||||
plugins: [SwaggerUIBundle.plugins.DownloadUrl, SearchFilterPlugin],
|
|
||||||
// 'list' expands tags, but not operations
|
|
||||||
docExpansion: 'list',
|
|
||||||
operationsSorter: 'alpha',
|
|
||||||
filter: initialFilter || true,
|
|
||||||
// this makes sure we show the x-vault- options
|
|
||||||
showExtensions: true,
|
|
||||||
// we don't have any models defined currently
|
|
||||||
defaultModelsExpandDepth: -1,
|
|
||||||
defaultModelExpandDepth: 1,
|
|
||||||
requestInterceptor: (req) => {
|
|
||||||
// we need to add vault authorization header
|
|
||||||
// and namepace headers for things to work properly
|
|
||||||
req.headers['X-Vault-Token'] = componentInstance.auth.currentToken;
|
|
||||||
|
|
||||||
const namespace = componentInstance.namespaceService.path;
|
|
||||||
if (namespace && !APP.NAMESPACE_ROOT_URLS.some((str) => req.url.includes(str))) {
|
|
||||||
req.headers['X-Vault-Namespace'] = namespace;
|
|
||||||
}
|
|
||||||
// we want to link to the right JSON in swagger UI so
|
|
||||||
// it's already been pre-pended
|
|
||||||
if (!req.loadSpec) {
|
|
||||||
const { protocol, host, pathname, search } = parseURL(req.url);
|
|
||||||
//paths in the spec don't have /v1 in them, so we need to add that here
|
|
||||||
// http(s): vlt.io:4200 /sys/mounts
|
|
||||||
req.url = `${protocol}//${host}/v1${pathname}${search}`;
|
|
||||||
}
|
|
||||||
return req;
|
|
||||||
},
|
|
||||||
onComplete: () => {
|
|
||||||
componentInstance.set('swaggerLoading', false);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
auth: service(),
|
|
||||||
namespaceService: service('namespace'),
|
|
||||||
initialFilter: null,
|
|
||||||
onFilterChange() {},
|
|
||||||
swaggerLoading: true,
|
|
||||||
|
|
||||||
async didInsertElement() {
|
|
||||||
const { default: SwaggerUIBundle } = await import('swagger-ui-dist/swagger-ui-bundle.js');
|
const { default: SwaggerUIBundle } = await import('swagger-ui-dist/swagger-ui-bundle.js');
|
||||||
this._super(...arguments);
|
// trim any slashes on the filter value
|
||||||
// trim any initial slashes
|
const configSettings = this.CONFIG(SwaggerUIBundle, this);
|
||||||
const initialFilter = this.initialFilter.replace(/^(\/)+/, '');
|
SwaggerUIBundle(configSettings);
|
||||||
SwaggerUIBundle(CONFIG(SwaggerUIBundle, this, initialFilter));
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
actions: {
|
|
||||||
// sets the filter so the query param is updated so we get sharable URLs
|
|
||||||
updateFilter(e) {
|
|
||||||
this.onFilterChange(e.target.value || '');
|
|
||||||
},
|
|
||||||
proxyEvent(e) {
|
|
||||||
const swaggerInput = this.element.querySelector('.operation-filter-input');
|
|
||||||
// if this breaks because of a react upgrade,
|
|
||||||
// change this to
|
|
||||||
//let originalSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
|
|
||||||
//originalSetter.call(swaggerInput, e.target.value);
|
|
||||||
// see post on triggering react events externally for an explanation of
|
|
||||||
// why this works: https://stackoverflow.com/a/46012210
|
|
||||||
const evt = new Event('input', { bubbles: true });
|
|
||||||
evt.simulated = true;
|
|
||||||
swaggerInput.value = e.target.value.replace(/^(\/)+/, '');
|
|
||||||
swaggerInput.dispatchEvent(evt);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) HashiCorp, Inc.
|
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Controller from '@ember/controller';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
queryParams: ['filter'],
|
|
||||||
filter: '',
|
|
||||||
});
|
|
|
@ -1,16 +1,14 @@
|
||||||
/**
|
/**
|
||||||
* Copyright (c) HashiCorp, Inc.
|
* Copyright (c) HashiCorp, Inc.
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
* SPDX-License-Identifier: BUSL-1.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Route from '@ember/routing/route';
|
import Route from '@ember/routing/route';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
|
|
||||||
export default Route.extend({
|
export default class OpenApiExplorerIndex extends Route {
|
||||||
flashMessages: service(),
|
@service flashMessages;
|
||||||
// without an empty model hook here, ember likes to use the parent model, and then things get weird with
|
|
||||||
// query params, so here we're no-op'ing the model hook
|
|
||||||
model() {},
|
|
||||||
afterModel() {
|
afterModel() {
|
||||||
const warning = `The "Try it out" functionality in this API explorer will make requests to this Vault server on your behalf.
|
const warning = `The "Try it out" functionality in this API explorer will make requests to this Vault server on your behalf.
|
||||||
|
|
||||||
|
@ -21,5 +19,5 @@ Your token will also be shown on the screen in the example curl command output.`
|
||||||
sticky: true,
|
sticky: true,
|
||||||
preformatted: true,
|
preformatted: true,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
});
|
}
|
||||||
|
|
|
@ -1,157 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) HashiCorp, Inc.
|
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
.swagger-ember .swagger-ui .wrapper {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swagger-ember .swagger-ui .info {
|
|
||||||
margin: 25px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*hide the swagger-ui headers*/
|
|
||||||
.swagger-ember .swagger-ui .filter-container,
|
|
||||||
.swagger-ember .swagger-ui .information-container.wrapper {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*some general de-rounding and removing backgrounds and drop shadows*/
|
|
||||||
.swagger-ember .swagger-ui .btn {
|
|
||||||
border-width: 1px;
|
|
||||||
box-shadow: none;
|
|
||||||
border-radius: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swagger-ember .swagger-ui .opblock {
|
|
||||||
background: none;
|
|
||||||
border-width: 1px;
|
|
||||||
border-radius: 2px;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*customize method, path, description*/
|
|
||||||
.swagger-ember .swagger-ui .opblock .opblock-summary,
|
|
||||||
.swagger-ember .swagger-ui .opblock .opblock-summary-description {
|
|
||||||
display: block;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swagger-ember .swagger-ui .opblock .opblock-summary {
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swagger-ember .swagger-ui .opblock .opblock-summary-description {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swagger-ember .swagger-ui .opblock .opblock-summary-method,
|
|
||||||
.swagger-ember .swagger-ui .opblock .opblock-summary-path{
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swagger-ember .swagger-ui .opblock .opblock-summary-method {
|
|
||||||
border-radius: 1px;
|
|
||||||
min-width: auto;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 10px;
|
|
||||||
box-shadow: 0 0 0 1px currentColor;
|
|
||||||
position: relative;
|
|
||||||
top: -2px;
|
|
||||||
padding: 0 2px;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*make tags look like list items */
|
|
||||||
.swagger-ember .swagger-ui .opblock-tag{
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swagger-ember .swagger-ui .opblock-tag-section .opblock-tag {
|
|
||||||
color: #0a0a0a;
|
|
||||||
font-weight: 600 !important;
|
|
||||||
font-size: 1rem !important;
|
|
||||||
transition: box-shadow 150ms, margin 150ms, padding 150ms;
|
|
||||||
will-change: box-shadow, margin, padding;
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 0;
|
|
||||||
padding: 1.25rem;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.swagger-ember .swagger-ui .opblock-tag:hover,
|
|
||||||
.swagger-ember .swagger-ui .opblock-tag:focus,
|
|
||||||
.swagger-ember .swagger-ui .opblock-tag:active {
|
|
||||||
margin-left: -0.75rem !important;
|
|
||||||
margin-right: -0.75rem !important;
|
|
||||||
padding-left: 0.75rem;
|
|
||||||
padding-right: 0.75rem;
|
|
||||||
position: relative;
|
|
||||||
box-shadow: 0 2px 0 -1px #BAC1CC, 0 -2px 0 -1px #BAC1CC, 0 0 0 1px #BAC1CC, 0 8px 4px -4px rgba(10, 10, 10, 0.1), 0 6px 8px -2px rgba(10, 10, 10, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*shrink the size of the arrows*/
|
|
||||||
.swagger-ember .swagger-ui .expand-methods svg,
|
|
||||||
.swagger-ember .swagger-ui .expand-operation svg {
|
|
||||||
height: 12px;
|
|
||||||
width: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*operation box - GET (blue) */
|
|
||||||
.swagger-ember .swagger-ui .opblock.opblock-get {
|
|
||||||
background: #f5f8ff;
|
|
||||||
border: 1px solid #bfd4ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*operation label*/
|
|
||||||
.swagger-ember .swagger-ui .opblock.opblock-get .opblock-summary-method {
|
|
||||||
color: #1563ff;
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
/*and expanded tab highlight */
|
|
||||||
.swagger-ember .swagger-ui .opblock.opblock-get .tab-header .tab-item.active h4 span::after {
|
|
||||||
background: #1563ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*operation box - POST (green) */
|
|
||||||
.swagger-ember .swagger-ui .opblock.opblock-post {
|
|
||||||
background: #fafdfa;
|
|
||||||
border: 1px solid #c6e9c9;
|
|
||||||
}
|
|
||||||
.swagger-ember .swagger-ui .opblock.opblock-post .opblock-summary-method {
|
|
||||||
color: #2eb039;
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
.swagger-ember .swagger-ui .opblock.opblock-post .tab-header .tab-item.active h4 span::after {
|
|
||||||
background: #2eb039;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*operation box - POST (red) */
|
|
||||||
.swagger-ember .swagger-ui .opblock.opblock-delete {
|
|
||||||
background: #fdfafb;
|
|
||||||
border: 1px solid #f9ecee;
|
|
||||||
}
|
|
||||||
.swagger-ember .swagger-ui .opblock.opblock-delete .opblock-summary-method {
|
|
||||||
color: #c73445;
|
|
||||||
background: none;
|
|
||||||
}
|
|
||||||
.swagger-ember .swagger-ui .opblock.opblock-delete .tab-header .tab-item.active h4 span::after {
|
|
||||||
background: #c73445;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*remove "LOADING" from initial loading spinner*/
|
|
||||||
.swagger-ember .swagger-ui .loading-container .loading::after {
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/*add text about requests to a live vault server*/
|
|
||||||
.swagger-ember .swagger-ui .btn.execute::after {
|
|
||||||
content: " - send a request with your token to Vault."
|
|
||||||
}
|
|
|
@ -1,32 +1,7 @@
|
||||||
<PageHeader as |p|>
|
{{!
|
||||||
<p.levelLeft>
|
Copyright (c) HashiCorp, Inc.
|
||||||
<h1 class="title is-3">
|
SPDX-License-Identifier: BUSL-1.1
|
||||||
<Icon @name="code" class="has-text-grey-light" />
|
~}}
|
||||||
Vault API explorer
|
|
||||||
</h1>
|
|
||||||
</p.levelLeft>
|
|
||||||
</PageHeader>
|
|
||||||
<Toolbar>
|
|
||||||
<ToolbarFilters>
|
|
||||||
<div class="field is-marginless">
|
|
||||||
<p class="control has-icons-left">
|
|
||||||
<label for="swagger-result-filter" class="sr-only">Filter operations by path</label>
|
|
||||||
<input
|
|
||||||
id="swagger-result-filter"
|
|
||||||
{{on "input" (action "proxyEvent")}}
|
|
||||||
{{on "change" (action "updateFilter")}}
|
|
||||||
value={{@initialFilter}}
|
|
||||||
disabled={{this.swaggerLoading}}
|
|
||||||
class="filter input"
|
|
||||||
placeholder="Filter ops by path"
|
|
||||||
data-test-filter-input
|
|
||||||
/>
|
|
||||||
<Icon @name="search" class="search-icon has-text-grey-light" />
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<AlertInline @type="info" @message="All API paths are prefixed with /v1/" class="is-marginless input-hint" />
|
|
||||||
</ToolbarFilters>
|
|
||||||
</Toolbar>
|
|
||||||
|
|
||||||
<div class="box is-fullwidth is-sideless">
|
<div class="box is-fullwidth is-sideless">
|
||||||
<NamespaceReminder as |R|>
|
<NamespaceReminder as |R|>
|
||||||
|
@ -37,5 +12,5 @@
|
||||||
<DocLink @path="/vault/api-docs#namespaces">docs</DocLink>
|
<DocLink @path="/vault/api-docs#namespaces">docs</DocLink>
|
||||||
for examples.
|
for examples.
|
||||||
</NamespaceReminder>
|
</NamespaceReminder>
|
||||||
<div id="{{this.elementId}}-swagger" class="swagger-ember"></div>
|
<div id={{this.inputId}} class="swagger-ember" {{did-insert this.swaggerInit}} data-test-swagger-ui></div>
|
||||||
</div>
|
</div>
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) HashiCorp, Inc.
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Factory } from 'ember-cli-mirage';
|
||||||
|
/* eslint-disable ember/avoid-leaking-state-in-ember-objects */
|
||||||
|
export default Factory.extend({
|
||||||
|
openapi: '3.0.2',
|
||||||
|
info: {
|
||||||
|
title: 'HashiCorp Vault API',
|
||||||
|
description: 'HTTP API that gives you full access to Vault. All API routes are prefixed with `/v1/`.',
|
||||||
|
version: '1.0.0',
|
||||||
|
license: {
|
||||||
|
name: 'Mozilla Public License 2.0',
|
||||||
|
url: 'https://www.mozilla.org/en-US/MPL/2.0',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
paths: {
|
||||||
|
'/auth/token/create': {
|
||||||
|
description: 'The token create path is used to create new tokens.',
|
||||||
|
post: {
|
||||||
|
summary: 'The token create path is used to create new tokens.',
|
||||||
|
tags: ['auth'],
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: 'OK',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'/secret/data/{path}': {
|
||||||
|
description: 'Location of a secret.',
|
||||||
|
post: {
|
||||||
|
summary: 'Location of a secret.',
|
||||||
|
tags: ['secret'],
|
||||||
|
responses: {
|
||||||
|
200: {
|
||||||
|
description: 'OK',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -174,7 +174,7 @@
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"eslint-plugin-qunit": "^7.2.0",
|
"eslint-plugin-qunit": "^7.2.0",
|
||||||
"filesize": "^4.2.1",
|
"filesize": "^4.2.1",
|
||||||
"flat": "^4.1.0",
|
"flat": "^6.0.1",
|
||||||
"jsondiffpatch": "^0.4.1",
|
"jsondiffpatch": "^0.4.1",
|
||||||
"jsonlint": "^1.6.3",
|
"jsonlint": "^1.6.3",
|
||||||
"lint-staged": "^10.5.1",
|
"lint-staged": "^10.5.1",
|
||||||
|
@ -190,10 +190,10 @@
|
||||||
"qunit-dom": "^2.0.0",
|
"qunit-dom": "^2.0.0",
|
||||||
"sass": "^1.58.3",
|
"sass": "^1.58.3",
|
||||||
"sass-svg-uri": "^1.0.0",
|
"sass-svg-uri": "^1.0.0",
|
||||||
"shell-quote": "^1.6.1",
|
"shell-quote": "^1.8.1",
|
||||||
"string.prototype.endswith": "^0.2.0",
|
"string.prototype.endswith": "^0.2.0",
|
||||||
"string.prototype.startswith": "^0.2.0",
|
"string.prototype.startswith": "^0.2.0",
|
||||||
"swagger-ui-dist": "^3.36.2",
|
"swagger-ui-dist": "^5.9.0",
|
||||||
"text-encoder-lite": "2.0.0",
|
"text-encoder-lite": "2.0.0",
|
||||||
"typescript": "^4.8.4",
|
"typescript": "^4.8.4",
|
||||||
"walk-sync": "^2.0.2",
|
"walk-sync": "^2.0.2",
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) HashiCorp, Inc.
|
|
||||||
* SPDX-License-Identifier: MPL-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { find, fillIn, visit, waitUntil } from '@ember/test-helpers';
|
|
||||||
import { module, test } from 'qunit';
|
|
||||||
import { setupApplicationTest } from 'ember-qunit';
|
|
||||||
|
|
||||||
import authPage from 'vault/tests/pages/auth';
|
|
||||||
|
|
||||||
module('Acceptance | API Explorer', function (hooks) {
|
|
||||||
setupApplicationTest(hooks);
|
|
||||||
|
|
||||||
hooks.beforeEach(function () {
|
|
||||||
return authPage.login();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('it filters paths after swagger-ui is loaded', async function (assert) {
|
|
||||||
await visit('/vault/api-explorer');
|
|
||||||
await waitUntil(() => {
|
|
||||||
return find('[data-test-filter-input]').disabled === false;
|
|
||||||
});
|
|
||||||
await fillIn('[data-test-filter-input]', 'sys/health');
|
|
||||||
assert.dom('.opblock').exists({ count: 1 }, 'renders a single opblock for sys/health');
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { module, test } from 'qunit';
|
||||||
|
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||||
|
import { waitUntil, find } from '@ember/test-helpers';
|
||||||
|
import { setupEngine } from 'ember-engines/test-support';
|
||||||
|
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||||
|
import { render } from '@ember/test-helpers';
|
||||||
|
import { hbs } from 'ember-cli-htmlbars';
|
||||||
|
|
||||||
|
module('Integration | Component | open-api-explorer | swagger-ui', function (hooks) {
|
||||||
|
setupRenderingTest(hooks);
|
||||||
|
setupEngine(hooks, 'open-api-explorer');
|
||||||
|
setupMirage(hooks);
|
||||||
|
hooks.beforeEach(function () {
|
||||||
|
this.store = this.owner.lookup('service:store');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('it renders', async function (assert) {
|
||||||
|
assert.expect(2);
|
||||||
|
const openApiResponse = this.server.create('open-api-explorer');
|
||||||
|
this.server.get('sys/internal/specs/openapi', () => {
|
||||||
|
return openApiResponse;
|
||||||
|
});
|
||||||
|
|
||||||
|
await render(hbs`<SwaggerUi/>`, {
|
||||||
|
owner: this.engine,
|
||||||
|
});
|
||||||
|
|
||||||
|
await waitUntil(() => find('[data-test-swagger-ui]'));
|
||||||
|
assert.dom('[data-test-swagger-ui]').exists('renders component');
|
||||||
|
await waitUntil(() => find('.operation-filter-input'));
|
||||||
|
assert.dom('.opblock-post').exists({ count: 2 }, 'renders two blocks');
|
||||||
|
});
|
||||||
|
});
|
33
ui/yarn.lock
33
ui/yarn.lock
|
@ -14980,14 +14980,12 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"flat@npm:^4.1.0":
|
"flat@npm:^6.0.1":
|
||||||
version: 4.1.1
|
version: 6.0.1
|
||||||
resolution: "flat@npm:4.1.1"
|
resolution: "flat@npm:6.0.1"
|
||||||
dependencies:
|
|
||||||
is-buffer: ~2.0.3
|
|
||||||
bin:
|
bin:
|
||||||
flat: cli.js
|
flat: cli.js
|
||||||
checksum: 398be12185eb0f3c59797c3670a8c35d07020b673363175676afbaf53d6b213660e060488554cf82c25504986e1a6059bdbcc5d562e87ca3e972e8a33148e3ae
|
checksum: c7a5f2e7e3ba0bec28b9c3aca27e68ff74df446df15cdb77ddef9e3d4fd0e9321ca52e49ca8b861c46157215006666b0dad25457f231083fc7bd2f7fcb67d7eb
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -16590,7 +16588,7 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"is-buffer@npm:^2.0.0, is-buffer@npm:~2.0.3":
|
"is-buffer@npm:^2.0.0":
|
||||||
version: 2.0.5
|
version: 2.0.5
|
||||||
resolution: "is-buffer@npm:2.0.5"
|
resolution: "is-buffer@npm:2.0.5"
|
||||||
checksum: 764c9ad8b523a9f5a32af29bdf772b08eb48c04d2ad0a7240916ac2688c983bf5f8504bf25b35e66240edeb9d9085461f9b5dae1f3d2861c6b06a65fe983de42
|
checksum: 764c9ad8b523a9f5a32af29bdf772b08eb48c04d2ad0a7240916ac2688c983bf5f8504bf25b35e66240edeb9d9085461f9b5dae1f3d2861c6b06a65fe983de42
|
||||||
|
@ -22165,6 +22163,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"shell-quote@npm:^1.8.1":
|
||||||
|
version: 1.8.1
|
||||||
|
resolution: "shell-quote@npm:1.8.1"
|
||||||
|
checksum: 5f01201f4ef504d4c6a9d0d283fa17075f6770bfbe4c5850b074974c68062f37929ca61700d95ad2ac8822e14e8c4b990ca0e6e9272e64befd74ce5e19f0736b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"shellwords@npm:^0.1.1":
|
"shellwords@npm:^0.1.1":
|
||||||
version: 0.1.1
|
version: 0.1.1
|
||||||
resolution: "shellwords@npm:0.1.1"
|
resolution: "shellwords@npm:0.1.1"
|
||||||
|
@ -23059,10 +23064,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"swagger-ui-dist@npm:^3.36.2":
|
"swagger-ui-dist@npm:^5.9.0":
|
||||||
version: 3.48.0
|
version: 5.9.1
|
||||||
resolution: "swagger-ui-dist@npm:3.48.0"
|
resolution: "swagger-ui-dist@npm:5.9.1"
|
||||||
checksum: e059bb91589158abc7338a31494264bff8c4f46c847895888265e03947c5236ff4a48fdd0d2c6db0c71035d5224f5ffb111fe439b23461597e1c5b8313f6a833
|
checksum: 4e5cf278ef1725b0770124ef4ecc9f75cb6fbab5d3e68aefffa024131aaf7b904514dc07000bb6b6ecdb606892fe5fa6e5f55d8fec978a838a18d25a010dab5b
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -24313,7 +24318,7 @@ __metadata:
|
||||||
eslint-plugin-prettier: ^4.0.0
|
eslint-plugin-prettier: ^4.0.0
|
||||||
eslint-plugin-qunit: ^7.2.0
|
eslint-plugin-qunit: ^7.2.0
|
||||||
filesize: ^4.2.1
|
filesize: ^4.2.1
|
||||||
flat: ^4.1.0
|
flat: ^6.0.1
|
||||||
handlebars: 4.7.7
|
handlebars: 4.7.7
|
||||||
highlight.js: ^10.4.1
|
highlight.js: ^10.4.1
|
||||||
jsondiffpatch: ^0.4.1
|
jsondiffpatch: ^0.4.1
|
||||||
|
@ -24332,10 +24337,10 @@ __metadata:
|
||||||
qunit-dom: ^2.0.0
|
qunit-dom: ^2.0.0
|
||||||
sass: ^1.58.3
|
sass: ^1.58.3
|
||||||
sass-svg-uri: ^1.0.0
|
sass-svg-uri: ^1.0.0
|
||||||
shell-quote: ^1.6.1
|
shell-quote: ^1.8.1
|
||||||
string.prototype.endswith: ^0.2.0
|
string.prototype.endswith: ^0.2.0
|
||||||
string.prototype.startswith: ^0.2.0
|
string.prototype.startswith: ^0.2.0
|
||||||
swagger-ui-dist: ^3.36.2
|
swagger-ui-dist: ^5.9.0
|
||||||
text-encoder-lite: 2.0.0
|
text-encoder-lite: 2.0.0
|
||||||
typescript: ^4.8.4
|
typescript: ^4.8.4
|
||||||
uuid: ^9.0.0
|
uuid: ^9.0.0
|
||||||
|
|
Loading…
Reference in New Issue