ui: refactor the UI with the nav menu (#297)
Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
This commit is contained in:
parent
40f27c5ba9
commit
02f23fea7a
|
@ -8,6 +8,7 @@ describe('gRPC', () => {
|
||||||
it('Create Suite', () => {
|
it('Create Suite', () => {
|
||||||
cy.visit('/')
|
cy.visit('/')
|
||||||
cy.get('.introjs-skipbutton').click()
|
cy.get('.introjs-skipbutton').click()
|
||||||
|
cy.get('[test-id="testing-menu"]').click()
|
||||||
|
|
||||||
createTestSuite(store, 'gRPC', suiteName, sampleAPIAddress)
|
createTestSuite(store, 'gRPC', suiteName, sampleAPIAddress)
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,6 +10,7 @@ describe('Suite Manage', () => {
|
||||||
it('Create Suite', () => {
|
it('Create Suite', () => {
|
||||||
cy.visit('/')
|
cy.visit('/')
|
||||||
cy.get('.introjs-skipbutton').click()
|
cy.get('.introjs-skipbutton').click()
|
||||||
|
cy.get('[test-id="testing-menu"]').click()
|
||||||
|
|
||||||
cy.contains('span', 'Tool Box')
|
cy.contains('span', 'Tool Box')
|
||||||
createTestSuite(store, 'HTTP', suiteName, sampleAPIAddress)
|
createTestSuite(store, 'HTTP', suiteName, sampleAPIAddress)
|
||||||
|
|
|
@ -1,25 +1,20 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import WelcomePage from './views/WelcomePage.vue'
|
import {
|
||||||
import TestCase from './views/TestCase.vue'
|
Document,
|
||||||
import TestSuite from './views/TestSuite.vue'
|
Menu as IconMenu,
|
||||||
import StoreManager from './views/StoreManager.vue'
|
Location,
|
||||||
import SecretManager from './views/SecretManager.vue'
|
Share,
|
||||||
import TemplateFunctions from './views/TemplateFunctions.vue'
|
} from '@element-plus/icons-vue'
|
||||||
import { reactive, ref, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
import { ElTree, ElMessage } from 'element-plus'
|
|
||||||
import type { FormInstance, FormRules } from 'element-plus'
|
|
||||||
import { Edit, Share } from '@element-plus/icons-vue'
|
|
||||||
import type { Suite } from './types'
|
|
||||||
import { API } from './views/net'
|
import { API } from './views/net'
|
||||||
import { Cache } from './views/cache'
|
import { Cache } from './views/cache'
|
||||||
import { useI18n } from 'vue-i18n'
|
import TestingPanel from './views/TestingPanel.vue'
|
||||||
import ClientMonitor from 'skywalking-client-js'
|
import StoreManager from './views/StoreManager.vue'
|
||||||
import { name, version } from '../package'
|
import SecretManager from './views/SecretManager.vue'
|
||||||
|
import WelcomePage from './views/WelcomePage.vue'
|
||||||
|
|
||||||
import setAsDarkTheme from './theme'
|
import setAsDarkTheme from './theme'
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
const asDarkMode = ref(Cache.GetPreference().darkTheme)
|
const asDarkMode = ref(Cache.GetPreference().darkTheme)
|
||||||
setAsDarkTheme(asDarkMode.value)
|
setAsDarkTheme(asDarkMode.value)
|
||||||
watch(asDarkMode, Cache.WatchDarkTheme)
|
watch(asDarkMode, Cache.WatchDarkTheme)
|
||||||
|
@ -27,304 +22,6 @@ watch(asDarkMode, () => {
|
||||||
setAsDarkTheme(asDarkMode.value)
|
setAsDarkTheme(asDarkMode.value)
|
||||||
})
|
})
|
||||||
|
|
||||||
interface Tree {
|
|
||||||
id: string
|
|
||||||
label: string
|
|
||||||
parent: string
|
|
||||||
parentID: string
|
|
||||||
store: string
|
|
||||||
kind: string
|
|
||||||
children?: Tree[]
|
|
||||||
}
|
|
||||||
|
|
||||||
const testCaseName = ref('')
|
|
||||||
const testSuite = ref('')
|
|
||||||
const testSuiteKind = ref('')
|
|
||||||
const handleNodeClick = (data: Tree) => {
|
|
||||||
if (data.children) {
|
|
||||||
Cache.SetCurrentStore(data.store)
|
|
||||||
viewName.value = 'testsuite'
|
|
||||||
testSuite.value = data.label
|
|
||||||
testSuiteKind.value = data.kind
|
|
||||||
Cache.SetCurrentStore(data.store)
|
|
||||||
|
|
||||||
API.ListTestCase(data.label, data.store, (d) => {
|
|
||||||
if (d.items && d.items.length > 0) {
|
|
||||||
data.children = []
|
|
||||||
d.items.forEach((item: any) => {
|
|
||||||
data.children?.push({
|
|
||||||
id: data.label,
|
|
||||||
label: item.name,
|
|
||||||
kind: data.kind,
|
|
||||||
store: data.store,
|
|
||||||
parent: data.label,
|
|
||||||
parentID: data.id
|
|
||||||
} as Tree)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Cache.SetCurrentStore(data.store)
|
|
||||||
Cache.SetLastTestCaseLocation(data.parentID, data.id)
|
|
||||||
testCaseName.value = data.label
|
|
||||||
testSuite.value = data.parent
|
|
||||||
testSuiteKind.value = data.kind
|
|
||||||
viewName.value = 'testcase'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = ref([] as Tree[])
|
|
||||||
const treeRef = ref<InstanceType<typeof ElTree>>()
|
|
||||||
const currentNodekey = ref('')
|
|
||||||
|
|
||||||
function loadTestSuites(storeName: string) {
|
|
||||||
const requestOptions = {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-Store-Name': storeName,
|
|
||||||
'X-Auth': API.getToken()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return async () => {
|
|
||||||
await fetch('/server.Runner/GetSuites', requestOptions)
|
|
||||||
.then((response) => response.json())
|
|
||||||
.then((d) => {
|
|
||||||
if (!d.data) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Object.keys(d.data).map((k) => {
|
|
||||||
let suite = {
|
|
||||||
id: k,
|
|
||||||
label: k,
|
|
||||||
kind: d.data[k].kind,
|
|
||||||
store: storeName,
|
|
||||||
children: [] as Tree[]
|
|
||||||
} as Tree
|
|
||||||
|
|
||||||
d.data[k].data.forEach((item: any) => {
|
|
||||||
suite.children?.push({
|
|
||||||
id: k + item,
|
|
||||||
label: item,
|
|
||||||
store: storeName,
|
|
||||||
kind: suite.kind,
|
|
||||||
parent: k,
|
|
||||||
parentID: suite.id
|
|
||||||
} as Tree)
|
|
||||||
})
|
|
||||||
data.value.push(suite)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Store {
|
|
||||||
name: string,
|
|
||||||
description: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
const loginDialogVisible = ref(false)
|
|
||||||
const stores = ref([] as Store[])
|
|
||||||
const storesLoading = ref(false)
|
|
||||||
function loadStores() {
|
|
||||||
storesLoading.value = true
|
|
||||||
const requestOptions = {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'X-Auth': API.getToken()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fetch('/server.Runner/GetStores', requestOptions)
|
|
||||||
.then(API.DefaultResponseProcess)
|
|
||||||
.then(async (d) => {
|
|
||||||
stores.value = d.data
|
|
||||||
data.value = [] as Tree[]
|
|
||||||
Cache.SetStores(d.data)
|
|
||||||
|
|
||||||
for (const item of d.data) {
|
|
||||||
if (item.ready && !item.disabled) {
|
|
||||||
await loadTestSuites(item.name)()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.value.length > 0) {
|
|
||||||
const key = Cache.GetLastTestCaseLocation()
|
|
||||||
|
|
||||||
let targetSuite = {} as Tree
|
|
||||||
let targetChild = {} as Tree
|
|
||||||
if (key.suite !== '' && key.testcase !== '') {
|
|
||||||
for (var i = 0; i < data.value.length; i++) {
|
|
||||||
const item = data.value[i]
|
|
||||||
if (item.id === key.suite && item.children) {
|
|
||||||
for (var j = 0; j < item.children.length; j++) {
|
|
||||||
const child = item.children[j]
|
|
||||||
if (child.id === key.testcase) {
|
|
||||||
targetSuite = item
|
|
||||||
targetChild = child
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!targetChild.id || targetChild.id === '') {
|
|
||||||
targetSuite = data.value[0]
|
|
||||||
if (targetSuite.children && targetSuite.children.length > 0) {
|
|
||||||
targetChild = targetSuite.children[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewName.value = 'testsuite'
|
|
||||||
currentNodekey.value = targetChild.id
|
|
||||||
treeRef.value!.setCurrentKey(targetChild.id)
|
|
||||||
treeRef.value!.setCheckedKeys([targetChild.id], false)
|
|
||||||
testSuite.value = targetSuite.label
|
|
||||||
Cache.SetCurrentStore(targetSuite.store )
|
|
||||||
testSuiteKind.value = targetChild.kind
|
|
||||||
} else {
|
|
||||||
viewName.value = ""
|
|
||||||
}
|
|
||||||
}).catch((e) => {
|
|
||||||
if(e.message === "Unauthenticated") {
|
|
||||||
loginDialogVisible.value = true
|
|
||||||
} else {
|
|
||||||
ElMessage.error('Oops, ' + e)
|
|
||||||
}
|
|
||||||
}).finally(() => {
|
|
||||||
storesLoading.value = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
loadStores()
|
|
||||||
|
|
||||||
const dialogVisible = ref(false)
|
|
||||||
const importDialogVisible = ref(false)
|
|
||||||
const suiteCreatingLoading = ref(false)
|
|
||||||
const suiteFormRef = ref<FormInstance>()
|
|
||||||
const testSuiteForm = reactive({
|
|
||||||
name: '',
|
|
||||||
api: '',
|
|
||||||
store: '',
|
|
||||||
kind: ''
|
|
||||||
})
|
|
||||||
const importSuiteFormRef = ref<FormInstance>()
|
|
||||||
const importSuiteForm = reactive({
|
|
||||||
url: '',
|
|
||||||
store: ''
|
|
||||||
})
|
|
||||||
|
|
||||||
function openTestSuiteCreateDialog() {
|
|
||||||
dialogVisible.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function openTestSuiteImportDialog() {
|
|
||||||
importDialogVisible.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const rules = reactive<FormRules<Suite>>({
|
|
||||||
name: [{ required: true, message: 'Name is required', trigger: 'blur' }],
|
|
||||||
store: [{ required: true, message: 'Location is required', trigger: 'blur' }]
|
|
||||||
})
|
|
||||||
const submitForm = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return
|
|
||||||
await formEl.validate((valid: boolean, fields) => {
|
|
||||||
if (valid) {
|
|
||||||
suiteCreatingLoading.value = true
|
|
||||||
|
|
||||||
API.CreateTestSuite(testSuiteForm, (e) => {
|
|
||||||
suiteCreatingLoading.value = false
|
|
||||||
if (e.error !== "") {
|
|
||||||
ElMessage.error('Oops, ' + e.error)
|
|
||||||
} else {
|
|
||||||
loadStores()
|
|
||||||
dialogVisible.value = false
|
|
||||||
formEl.resetFields()
|
|
||||||
}
|
|
||||||
}, (e) => {
|
|
||||||
suiteCreatingLoading.value = false
|
|
||||||
ElMessage.error('Oops, ' + e)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const importSuiteFormRules = reactive<FormRules<Suite>>({
|
|
||||||
url: [
|
|
||||||
{ required: true, message: 'URL is required', trigger: 'blur' },
|
|
||||||
{ type: 'url', message: 'Should be a valid URL value', trigger: 'blur' }
|
|
||||||
],
|
|
||||||
store: [{ required: true, message: 'Location is required', trigger: 'blur' }]
|
|
||||||
})
|
|
||||||
const importSuiteFormSubmit = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return
|
|
||||||
await formEl.validate((valid: boolean, fields) => {
|
|
||||||
if (valid) {
|
|
||||||
suiteCreatingLoading.value = true
|
|
||||||
|
|
||||||
API.ImportTestSuite(importSuiteForm, () => {
|
|
||||||
loadStores()
|
|
||||||
importDialogVisible.value = false
|
|
||||||
formEl.resetFields()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const filterText = ref('')
|
|
||||||
watch(filterText, (val) => {
|
|
||||||
treeRef.value!.filter(val)
|
|
||||||
})
|
|
||||||
const filterTestCases = (value: string, data: Tree) => {
|
|
||||||
if (!value) return true
|
|
||||||
return data.label.includes(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
const viewName = ref('')
|
|
||||||
watch(viewName, (val) => {
|
|
||||||
ClientMonitor.setPerformance({
|
|
||||||
service: name,
|
|
||||||
serviceVersion: version,
|
|
||||||
pagePath: val,
|
|
||||||
useFmp: true,
|
|
||||||
enableSPA: true,
|
|
||||||
customTags: [{
|
|
||||||
key: 'theme', value: asDarkMode.value ? 'dark' : 'light'
|
|
||||||
}, {
|
|
||||||
key: 'store', value: Cache.GetCurrentStore().name
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
const deviceAuthActive = ref(0)
|
|
||||||
const deviceAuthResponse = ref({
|
|
||||||
user_code: '',
|
|
||||||
verification_uri: '',
|
|
||||||
device_code: ''
|
|
||||||
})
|
|
||||||
const deviceAuthNext = () => {
|
|
||||||
if (deviceAuthActive.value++ > 2) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deviceAuthActive.value === 1) {
|
|
||||||
fetch('/oauth2/getLocalCode')
|
|
||||||
.then(API.DefaultResponseProcess)
|
|
||||||
.then((d) => {
|
|
||||||
deviceAuthResponse.value = d
|
|
||||||
})
|
|
||||||
} else if (deviceAuthActive.value === 2) {
|
|
||||||
window.location.href = '/oauth2/getUserInfoFromLocalCode?device_code=' + deviceAuthResponse.value.device_code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const suiteKinds = [{
|
|
||||||
"name": "HTTP",
|
|
||||||
}, {
|
|
||||||
"name": "gRPC",
|
|
||||||
}, {
|
|
||||||
"name": "tRPC",
|
|
||||||
}]
|
|
||||||
|
|
||||||
const appVersion = ref('')
|
const appVersion = ref('')
|
||||||
const appVersionLink = ref('https://github.com/LinuxSuRen/api-testing')
|
const appVersionLink = ref('https://github.com/LinuxSuRen/api-testing')
|
||||||
API.GetVersion((d) => {
|
API.GetVersion((d) => {
|
||||||
|
@ -342,272 +39,64 @@ API.GetVersion((d) => {
|
||||||
appVersionLink.value = appVersionLink.value + '/releases/tag/' + version[0]
|
appVersionLink.value = appVersionLink.value + '/releases/tag/' + version[0]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const panelName = ref('')
|
||||||
|
const sideWidth = ref("width: 300px")
|
||||||
|
const isCollapse = ref(false)
|
||||||
|
watch(isCollapse, (e) => {
|
||||||
|
console.log(e)
|
||||||
|
if (e) {
|
||||||
|
sideWidth.value = "width: 80px"
|
||||||
|
} else {
|
||||||
|
sideWidth.value = "width: 300px"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const handleSelect = (key: string) => {
|
||||||
|
panelName.value = key
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="common-layout" data-title="Welcome!" data-intro="Welcome to use api-testing! 👋">
|
|
||||||
<el-container style="height: 100%">
|
<el-container style="height: 100%">
|
||||||
<el-header style="height: 30px;justify-content: flex-end;">
|
<el-aside :style="sideWidth">
|
||||||
<el-button type="primary" :icon="Edit" @click="viewName = 'secret'" data-intro="Manage the secrets."/>
|
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
|
||||||
<el-button type="primary" :icon="Share" @click="viewName = 'store'" data-intro="Manage the store backends." />
|
<el-radio-button :label="false">+</el-radio-button>
|
||||||
<el-form-item label="Dark Mode" style="margin-left:20px;">
|
<el-radio-button :label="true">-</el-radio-button>
|
||||||
<el-switch type="primary" data-intro="Switch light and dark modes" v-model="asDarkMode" />
|
</el-radio-group>
|
||||||
</el-form-item>
|
<el-menu
|
||||||
</el-header>
|
class="el-menu-vertical-demo"
|
||||||
|
default-active="welcome"
|
||||||
<el-main>
|
:collapse="isCollapse"
|
||||||
<el-container style="height: 100%">
|
@select="handleSelect"
|
||||||
<el-aside>
|
>
|
||||||
<el-button type="primary" @click="openTestSuiteCreateDialog"
|
<el-menu-item index="welcome">
|
||||||
data-intro="Click here to create a new test suite"
|
<el-icon><share /></el-icon>
|
||||||
test-id="open-new-suite-dialog" :icon="Edit">{{ t('button.new') }}</el-button>
|
<template #title>Welcome</template>
|
||||||
<el-button type="primary" @click="openTestSuiteImportDialog"
|
</el-menu-item>
|
||||||
data-intro="Click here to import from Postman"
|
<el-menu-item index="testing" test-id="testing-menu">
|
||||||
test-id="open-import-suite-dialog">{{ t('button.import') }}</el-button>
|
<el-icon><icon-menu /></el-icon>
|
||||||
<el-input v-model="filterText" placeholder="Filter keyword" test-id="search" />
|
<template #title>Testing</template>
|
||||||
|
</el-menu-item>
|
||||||
<el-tree
|
<el-menu-item index="secret">
|
||||||
v-loading="storesLoading"
|
<el-icon><document /></el-icon>
|
||||||
:data=data
|
<template #title>Secrets</template>
|
||||||
highlight-current
|
</el-menu-item>
|
||||||
:check-on-click-node="true"
|
<el-menu-item index="store">
|
||||||
:expand-on-click-node="false"
|
<el-icon><location /></el-icon>
|
||||||
:current-node-key="currentNodekey"
|
<template #title>Stores</template>
|
||||||
ref="treeRef"
|
</el-menu-item>
|
||||||
node-key="id"
|
</el-menu>
|
||||||
:filter-node-method="filterTestCases"
|
|
||||||
@node-click="handleNodeClick"
|
|
||||||
data-intro="This is the test suite tree. You can click the test suite to edit it."
|
|
||||||
/>
|
|
||||||
</el-aside>
|
</el-aside>
|
||||||
|
|
||||||
<el-main>
|
<el-main>
|
||||||
<WelcomePage
|
<TestingPanel v-if="panelName === 'testing'" />
|
||||||
v-if="viewName === ''"
|
<StoreManager v-else-if="panelName === 'store'" />
|
||||||
/>
|
<SecretManager v-else-if="panelName === 'secret'" />
|
||||||
<TestCase
|
<WelcomePage v-else />
|
||||||
v-else-if="viewName === 'testcase'"
|
|
||||||
:suite="testSuite"
|
|
||||||
:kindName="testSuiteKind"
|
|
||||||
:name="testCaseName"
|
|
||||||
@updated="loadStores"
|
|
||||||
data-intro="This is the test case editor. You can edit the test case here."
|
|
||||||
/>
|
|
||||||
<TestSuite
|
|
||||||
v-else-if="viewName === 'testsuite'"
|
|
||||||
:name="testSuite"
|
|
||||||
@updated="loadStores"
|
|
||||||
data-intro="This is the test suite editor. You can edit the test suite here."
|
|
||||||
/>
|
|
||||||
<StoreManager
|
|
||||||
v-else-if="viewName === 'store'"
|
|
||||||
/>
|
|
||||||
<SecretManager
|
|
||||||
v-else-if="viewName === 'secret'"
|
|
||||||
/>
|
|
||||||
</el-main>
|
|
||||||
</el-container>
|
|
||||||
</el-main>
|
</el-main>
|
||||||
|
|
||||||
<div style="position: absolute; bottom: 0px; right: 10px;">
|
<div style="position: absolute; bottom: 0px; right: 10px;">
|
||||||
<a :href=appVersionLink target="_blank" rel="noopener">{{appVersion}}</a>
|
<a :href=appVersionLink target="_blank" rel="noopener">{{appVersion}}</a>
|
||||||
</div>
|
</div>
|
||||||
<TemplateFunctions/>
|
|
||||||
</el-container>
|
</el-container>
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog v-model="dialogVisible" :title="t('title.createTestSuite')" width="30%" draggable>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-form
|
|
||||||
:rules="rules"
|
|
||||||
:model="testSuiteForm"
|
|
||||||
ref="suiteFormRef"
|
|
||||||
status-icon label-width="120px">
|
|
||||||
<el-form-item :label="t('field.storageLocation')" prop="store">
|
|
||||||
<el-select v-model="testSuiteForm.store" class="m-2"
|
|
||||||
test-id="suite-form-store"
|
|
||||||
filterable=true
|
|
||||||
default-first-option=true
|
|
||||||
placeholder="Storage Location" size="middle">
|
|
||||||
<el-option
|
|
||||||
v-for="item in stores"
|
|
||||||
:key="item.name"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.name"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="t('field.suiteKind')" prop="kind">
|
|
||||||
<el-select v-model="testSuiteForm.kind" class="m-2"
|
|
||||||
filterable=true
|
|
||||||
test-id="suite-form-kind"
|
|
||||||
default-first-option=true
|
|
||||||
size="middle">
|
|
||||||
<el-option
|
|
||||||
v-for="item in suiteKinds"
|
|
||||||
:key="item.name"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.name"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item :label="t('field.name')" prop="name">
|
|
||||||
<el-input v-model="testSuiteForm.name" test-id="suite-form-name" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="API" prop="api">
|
|
||||||
<el-input v-model="testSuiteForm.api" placeholder="http://foo" test-id="suite-form-api" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
@click="submitForm(suiteFormRef)"
|
|
||||||
:loading="suiteCreatingLoading"
|
|
||||||
test-id="suite-form-submit"
|
|
||||||
>{{ t('button.submit') }}</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</span>
|
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog v-model="importDialogVisible" title="Import Test Suite" width="30%" draggable>
|
|
||||||
<span>Supported source URL: Postman collection share link</span>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-form
|
|
||||||
:rules="importSuiteFormRules"
|
|
||||||
:model="importSuiteForm"
|
|
||||||
ref="importSuiteFormRef"
|
|
||||||
status-icon label-width="120px">
|
|
||||||
<el-form-item label="Location" prop="store">
|
|
||||||
<el-select v-model="importSuiteForm.store" class="m-2"
|
|
||||||
test-id="suite-import-form-store"
|
|
||||||
filterable=true
|
|
||||||
default-first-option=true
|
|
||||||
placeholder="Storage Location" size="middle">
|
|
||||||
<el-option
|
|
||||||
v-for="item in stores"
|
|
||||||
:key="item.name"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.name"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="URL" prop="url">
|
|
||||||
<el-input v-model="importSuiteForm.url" test-id="suite-import-form-api" placeholder="https://api.postman.com/collections/xxx" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
@click="importSuiteFormSubmit(importSuiteFormRef)"
|
|
||||||
test-id="suite-import-submit"
|
|
||||||
>{{ t('button.import') }}</el-button
|
|
||||||
>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog
|
|
||||||
v-model="loginDialogVisible"
|
|
||||||
title="You need to login first."
|
|
||||||
width="30%"
|
|
||||||
>
|
|
||||||
<el-collapse accordion="true">
|
|
||||||
<el-collapse-item title="Server in cloud" name="1">
|
|
||||||
<a href="/oauth2/token" target="_blank">
|
|
||||||
<svg height="32" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github v-align-middle color-fg-default">
|
|
||||||
<path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</el-collapse-item>
|
|
||||||
<el-collapse-item title="Server in local" name="2">
|
|
||||||
<el-steps :active="deviceAuthActive" finish-status="success">
|
|
||||||
<el-step title="Request Device Code" />
|
|
||||||
<el-step title="Input Code"/>
|
|
||||||
<el-step title="Finished" />
|
|
||||||
</el-steps>
|
|
||||||
|
|
||||||
<div v-if="deviceAuthActive===1">
|
|
||||||
Open <a :href="deviceAuthResponse.verification_uri" target="_blank">this link</a>, and type the code: <span>{{ deviceAuthResponse.user_code }}. Then click the next step button.</span>
|
|
||||||
</div>
|
|
||||||
<el-button style="margin-top: 12px" @click="deviceAuthNext">Next step</el-button>
|
|
||||||
</el-collapse-item>
|
|
||||||
</el-collapse>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
header {
|
|
||||||
line-height: 1.5;
|
|
||||||
max-height: 100vh;
|
|
||||||
}
|
|
||||||
.common-layout {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.logo {
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
|
||||||
width: 100%;
|
|
||||||
font-size: 12px;
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
nav a.router-link-exact-active {
|
|
||||||
color: var(--color-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
nav a.router-link-exact-active:hover {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav a {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0 1rem;
|
|
||||||
border-left: 1px solid var(--color-border);
|
|
||||||
}
|
|
||||||
|
|
||||||
nav a:first-of-type {
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
|
||||||
header {
|
|
||||||
display: flex;
|
|
||||||
place-items: center;
|
|
||||||
padding-right: calc(var(--section-gap) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
margin: 0 2rem 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
header .wrapper {
|
|
||||||
display: flex;
|
|
||||||
place-items: flex-start;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
|
||||||
text-align: left;
|
|
||||||
margin-left: -1rem;
|
|
||||||
font-size: 1rem;
|
|
||||||
|
|
||||||
padding: 1rem 0;
|
|
||||||
margin-top: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.demo-tabs > .el-tabs__content {
|
|
||||||
padding: 32px;
|
|
||||||
color: #6b778c;
|
|
||||||
font-size: 32px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -0,0 +1,549 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import WelcomePage from './WelcomePage.vue'
|
||||||
|
import TestCase from './TestCase.vue'
|
||||||
|
import TestSuite from './TestSuite.vue'
|
||||||
|
import TemplateFunctions from './TemplateFunctions.vue'
|
||||||
|
import { reactive, ref, watch } from 'vue'
|
||||||
|
import { ElTree, ElMessage } from 'element-plus'
|
||||||
|
import type { FormInstance, FormRules } from 'element-plus'
|
||||||
|
import { Edit } from '@element-plus/icons-vue'
|
||||||
|
import type { Suite } from './types'
|
||||||
|
import { API } from './net'
|
||||||
|
import { Cache } from './cache'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
interface Tree {
|
||||||
|
id: string
|
||||||
|
label: string
|
||||||
|
parent: string
|
||||||
|
parentID: string
|
||||||
|
store: string
|
||||||
|
kind: string
|
||||||
|
children?: Tree[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const testCaseName = ref('')
|
||||||
|
const testSuite = ref('')
|
||||||
|
const testSuiteKind = ref('')
|
||||||
|
const handleNodeClick = (data: Tree) => {
|
||||||
|
if (data.children) {
|
||||||
|
Cache.SetCurrentStore(data.store)
|
||||||
|
viewName.value = 'testsuite'
|
||||||
|
testSuite.value = data.label
|
||||||
|
testSuiteKind.value = data.kind
|
||||||
|
Cache.SetCurrentStore(data.store)
|
||||||
|
|
||||||
|
API.ListTestCase(data.label, data.store, (d) => {
|
||||||
|
if (d.items && d.items.length > 0) {
|
||||||
|
data.children = []
|
||||||
|
d.items.forEach((item: any) => {
|
||||||
|
data.children?.push({
|
||||||
|
id: data.label,
|
||||||
|
label: item.name,
|
||||||
|
kind: data.kind,
|
||||||
|
store: data.store,
|
||||||
|
parent: data.label,
|
||||||
|
parentID: data.id
|
||||||
|
} as Tree)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Cache.SetCurrentStore(data.store)
|
||||||
|
Cache.SetLastTestCaseLocation(data.parentID, data.id)
|
||||||
|
testCaseName.value = data.label
|
||||||
|
testSuite.value = data.parent
|
||||||
|
testSuiteKind.value = data.kind
|
||||||
|
viewName.value = 'testcase'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = ref([] as Tree[])
|
||||||
|
const treeRef = ref<InstanceType<typeof ElTree>>()
|
||||||
|
const currentNodekey = ref('')
|
||||||
|
|
||||||
|
function loadTestSuites(storeName: string) {
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'X-Store-Name': storeName,
|
||||||
|
'X-Auth': API.getToken()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return async () => {
|
||||||
|
await fetch('/server.Runner/GetSuites', requestOptions)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((d) => {
|
||||||
|
if (!d.data) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Object.keys(d.data).map((k) => {
|
||||||
|
let suite = {
|
||||||
|
id: k,
|
||||||
|
label: k,
|
||||||
|
kind: d.data[k].kind,
|
||||||
|
store: storeName,
|
||||||
|
children: [] as Tree[]
|
||||||
|
} as Tree
|
||||||
|
|
||||||
|
d.data[k].data.forEach((item: any) => {
|
||||||
|
suite.children?.push({
|
||||||
|
id: k + item,
|
||||||
|
label: item,
|
||||||
|
store: storeName,
|
||||||
|
kind: suite.kind,
|
||||||
|
parent: k,
|
||||||
|
parentID: suite.id
|
||||||
|
} as Tree)
|
||||||
|
})
|
||||||
|
data.value.push(suite)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Store {
|
||||||
|
name: string,
|
||||||
|
description: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
const loginDialogVisible = ref(false)
|
||||||
|
const stores = ref([] as Store[])
|
||||||
|
const storesLoading = ref(false)
|
||||||
|
function loadStores() {
|
||||||
|
storesLoading.value = true
|
||||||
|
const requestOptions = {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'X-Auth': API.getToken()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fetch('/server.Runner/GetStores', requestOptions)
|
||||||
|
.then(API.DefaultResponseProcess)
|
||||||
|
.then(async (d) => {
|
||||||
|
stores.value = d.data
|
||||||
|
data.value = [] as Tree[]
|
||||||
|
Cache.SetStores(d.data)
|
||||||
|
|
||||||
|
for (const item of d.data) {
|
||||||
|
if (item.ready && !item.disabled) {
|
||||||
|
await loadTestSuites(item.name)()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.value.length > 0) {
|
||||||
|
const key = Cache.GetLastTestCaseLocation()
|
||||||
|
|
||||||
|
let targetSuite = {} as Tree
|
||||||
|
let targetChild = {} as Tree
|
||||||
|
if (key.suite !== '' && key.testcase !== '') {
|
||||||
|
for (var i = 0; i < data.value.length; i++) {
|
||||||
|
const item = data.value[i]
|
||||||
|
if (item.id === key.suite && item.children) {
|
||||||
|
for (var j = 0; j < item.children.length; j++) {
|
||||||
|
const child = item.children[j]
|
||||||
|
if (child.id === key.testcase) {
|
||||||
|
targetSuite = item
|
||||||
|
targetChild = child
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetChild.id || targetChild.id === '') {
|
||||||
|
targetSuite = data.value[0]
|
||||||
|
if (targetSuite.children && targetSuite.children.length > 0) {
|
||||||
|
targetChild = targetSuite.children[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
viewName.value = 'testsuite'
|
||||||
|
currentNodekey.value = targetChild.id
|
||||||
|
treeRef.value!.setCurrentKey(targetChild.id)
|
||||||
|
treeRef.value!.setCheckedKeys([targetChild.id], false)
|
||||||
|
testSuite.value = targetSuite.label
|
||||||
|
Cache.SetCurrentStore(targetSuite.store )
|
||||||
|
testSuiteKind.value = targetChild.kind
|
||||||
|
} else {
|
||||||
|
viewName.value = ""
|
||||||
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
if(e.message === "Unauthenticated") {
|
||||||
|
loginDialogVisible.value = true
|
||||||
|
} else {
|
||||||
|
ElMessage.error('Oops, ' + e)
|
||||||
|
}
|
||||||
|
}).finally(() => {
|
||||||
|
storesLoading.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
loadStores()
|
||||||
|
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const importDialogVisible = ref(false)
|
||||||
|
const suiteCreatingLoading = ref(false)
|
||||||
|
const suiteFormRef = ref<FormInstance>()
|
||||||
|
const testSuiteForm = reactive({
|
||||||
|
name: '',
|
||||||
|
api: '',
|
||||||
|
store: '',
|
||||||
|
kind: ''
|
||||||
|
})
|
||||||
|
const importSuiteFormRef = ref<FormInstance>()
|
||||||
|
const importSuiteForm = reactive({
|
||||||
|
url: '',
|
||||||
|
store: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
function openTestSuiteCreateDialog() {
|
||||||
|
dialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function openTestSuiteImportDialog() {
|
||||||
|
importDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const rules = reactive<FormRules<Suite>>({
|
||||||
|
name: [{ required: true, message: 'Name is required', trigger: 'blur' }],
|
||||||
|
store: [{ required: true, message: 'Location is required', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const submitForm = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return
|
||||||
|
await formEl.validate((valid: boolean) => {
|
||||||
|
if (valid) {
|
||||||
|
suiteCreatingLoading.value = true
|
||||||
|
|
||||||
|
API.CreateTestSuite(testSuiteForm, (e) => {
|
||||||
|
suiteCreatingLoading.value = false
|
||||||
|
if (e.error !== "") {
|
||||||
|
ElMessage.error('Oops, ' + e.error)
|
||||||
|
} else {
|
||||||
|
loadStores()
|
||||||
|
dialogVisible.value = false
|
||||||
|
formEl.resetFields()
|
||||||
|
}
|
||||||
|
}, (e) => {
|
||||||
|
suiteCreatingLoading.value = false
|
||||||
|
ElMessage.error('Oops, ' + e)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const importSuiteFormRules = reactive<FormRules<Suite>>({
|
||||||
|
url: [
|
||||||
|
{ required: true, message: 'URL is required', trigger: 'blur' },
|
||||||
|
{ type: 'url', message: 'Should be a valid URL value', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
store: [{ required: true, message: 'Location is required', trigger: 'blur' }]
|
||||||
|
})
|
||||||
|
const importSuiteFormSubmit = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return
|
||||||
|
await formEl.validate((valid: boolean) => {
|
||||||
|
if (valid) {
|
||||||
|
suiteCreatingLoading.value = true
|
||||||
|
|
||||||
|
API.ImportTestSuite(importSuiteForm, () => {
|
||||||
|
loadStores()
|
||||||
|
importDialogVisible.value = false
|
||||||
|
formEl.resetFields()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const filterText = ref('')
|
||||||
|
watch(filterText, (val) => {
|
||||||
|
treeRef.value!.filter(val)
|
||||||
|
})
|
||||||
|
const filterTestCases = (value: string, data: Tree) => {
|
||||||
|
if (!value) return true
|
||||||
|
return data.label.includes(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const viewName = ref('')
|
||||||
|
|
||||||
|
const deviceAuthActive = ref(0)
|
||||||
|
const deviceAuthResponse = ref({
|
||||||
|
user_code: '',
|
||||||
|
verification_uri: '',
|
||||||
|
device_code: ''
|
||||||
|
})
|
||||||
|
const deviceAuthNext = () => {
|
||||||
|
if (deviceAuthActive.value++ > 2) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceAuthActive.value === 1) {
|
||||||
|
fetch('/oauth2/getLocalCode')
|
||||||
|
.then(API.DefaultResponseProcess)
|
||||||
|
.then((d) => {
|
||||||
|
deviceAuthResponse.value = d
|
||||||
|
})
|
||||||
|
} else if (deviceAuthActive.value === 2) {
|
||||||
|
window.location.href = '/oauth2/getUserInfoFromLocalCode?device_code=' + deviceAuthResponse.value.device_code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const suiteKinds = [{
|
||||||
|
"name": "HTTP",
|
||||||
|
}, {
|
||||||
|
"name": "gRPC",
|
||||||
|
}, {
|
||||||
|
"name": "tRPC",
|
||||||
|
}]
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="common-layout" data-title="Welcome!" data-intro="Welcome to use api-testing! 👋">
|
||||||
|
<el-container style="height: 100%">
|
||||||
|
<el-main>
|
||||||
|
<el-container style="height: 100%">
|
||||||
|
<el-aside>
|
||||||
|
<el-button type="primary" @click="openTestSuiteCreateDialog"
|
||||||
|
data-intro="Click here to create a new test suite"
|
||||||
|
test-id="open-new-suite-dialog" :icon="Edit">{{ t('button.new') }}</el-button>
|
||||||
|
<el-button type="primary" @click="openTestSuiteImportDialog"
|
||||||
|
data-intro="Click here to import from Postman"
|
||||||
|
test-id="open-import-suite-dialog">{{ t('button.import') }}</el-button>
|
||||||
|
<el-input v-model="filterText" placeholder="Filter keyword" test-id="search" />
|
||||||
|
|
||||||
|
<el-tree
|
||||||
|
v-loading="storesLoading"
|
||||||
|
:data=data
|
||||||
|
highlight-current
|
||||||
|
:check-on-click-node="true"
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
:current-node-key="currentNodekey"
|
||||||
|
ref="treeRef"
|
||||||
|
node-key="id"
|
||||||
|
:filter-node-method="filterTestCases"
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
data-intro="This is the test suite tree. You can click the test suite to edit it."
|
||||||
|
/>
|
||||||
|
</el-aside>
|
||||||
|
|
||||||
|
<el-main>
|
||||||
|
<TestCase
|
||||||
|
v-if="viewName === 'testcase'"
|
||||||
|
:suite="testSuite"
|
||||||
|
:kindName="testSuiteKind"
|
||||||
|
:name="testCaseName"
|
||||||
|
@updated="loadStores"
|
||||||
|
data-intro="This is the test case editor. You can edit the test case here."
|
||||||
|
/>
|
||||||
|
<TestSuite
|
||||||
|
v-else-if="viewName === 'testsuite'"
|
||||||
|
:name="testSuite"
|
||||||
|
@updated="loadStores"
|
||||||
|
data-intro="This is the test suite editor. You can edit the test suite here."
|
||||||
|
/>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</el-main>
|
||||||
|
|
||||||
|
<TemplateFunctions/>
|
||||||
|
</el-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog v-model="dialogVisible" :title="t('title.createTestSuite')" width="30%" draggable>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-form
|
||||||
|
:rules="rules"
|
||||||
|
:model="testSuiteForm"
|
||||||
|
ref="suiteFormRef"
|
||||||
|
status-icon label-width="120px">
|
||||||
|
<el-form-item :label="t('field.storageLocation')" prop="store">
|
||||||
|
<el-select v-model="testSuiteForm.store" class="m-2"
|
||||||
|
test-id="suite-form-store"
|
||||||
|
filterable=true
|
||||||
|
default-first-option=true
|
||||||
|
placeholder="Storage Location" size="middle">
|
||||||
|
<el-option
|
||||||
|
v-for="item in stores"
|
||||||
|
:key="item.name"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.name"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('field.suiteKind')" prop="kind">
|
||||||
|
<el-select v-model="testSuiteForm.kind" class="m-2"
|
||||||
|
filterable=true
|
||||||
|
test-id="suite-form-kind"
|
||||||
|
default-first-option=true
|
||||||
|
size="middle">
|
||||||
|
<el-option
|
||||||
|
v-for="item in suiteKinds"
|
||||||
|
:key="item.name"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.name"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="t('field.name')" prop="name">
|
||||||
|
<el-input v-model="testSuiteForm.name" test-id="suite-form-name" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="API" prop="api">
|
||||||
|
<el-input v-model="testSuiteForm.api" placeholder="http://foo" test-id="suite-form-api" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="submitForm(suiteFormRef)"
|
||||||
|
:loading="suiteCreatingLoading"
|
||||||
|
test-id="suite-form-submit"
|
||||||
|
>{{ t('button.submit') }}</el-button
|
||||||
|
>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog v-model="importDialogVisible" title="Import Test Suite" width="30%" draggable>
|
||||||
|
<span>Supported source URL: Postman collection share link</span>
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-form
|
||||||
|
:rules="importSuiteFormRules"
|
||||||
|
:model="importSuiteForm"
|
||||||
|
ref="importSuiteFormRef"
|
||||||
|
status-icon label-width="120px">
|
||||||
|
<el-form-item label="Location" prop="store">
|
||||||
|
<el-select v-model="importSuiteForm.store" class="m-2"
|
||||||
|
test-id="suite-import-form-store"
|
||||||
|
filterable=true
|
||||||
|
default-first-option=true
|
||||||
|
placeholder="Storage Location" size="middle">
|
||||||
|
<el-option
|
||||||
|
v-for="item in stores"
|
||||||
|
:key="item.name"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.name"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="URL" prop="url">
|
||||||
|
<el-input v-model="importSuiteForm.url" test-id="suite-import-form-api" placeholder="https://api.postman.com/collections/xxx" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="importSuiteFormSubmit(importSuiteFormRef)"
|
||||||
|
test-id="suite-import-submit"
|
||||||
|
>{{ t('button.import') }}</el-button
|
||||||
|
>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="loginDialogVisible"
|
||||||
|
title="You need to login first."
|
||||||
|
width="30%"
|
||||||
|
>
|
||||||
|
<el-collapse accordion="true">
|
||||||
|
<el-collapse-item title="Server in cloud" name="1">
|
||||||
|
<a href="/oauth2/token" target="_blank">
|
||||||
|
<svg height="32" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="32" data-view-component="true" class="octicon octicon-mark-github v-align-middle color-fg-default">
|
||||||
|
<path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</el-collapse-item>
|
||||||
|
<el-collapse-item title="Server in local" name="2">
|
||||||
|
<el-steps :active="deviceAuthActive" finish-status="success">
|
||||||
|
<el-step title="Request Device Code" />
|
||||||
|
<el-step title="Input Code"/>
|
||||||
|
<el-step title="Finished" />
|
||||||
|
</el-steps>
|
||||||
|
|
||||||
|
<div v-if="deviceAuthActive===1">
|
||||||
|
Open <a :href="deviceAuthResponse.verification_uri" target="_blank">this link</a>, and type the code: <span>{{ deviceAuthResponse.user_code }}. Then click the next step button.</span>
|
||||||
|
</div>
|
||||||
|
<el-button style="margin-top: 12px" @click="deviceAuthNext">Next step</el-button>
|
||||||
|
</el-collapse-item>
|
||||||
|
</el-collapse>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
header {
|
||||||
|
line-height: 1.5;
|
||||||
|
max-height: 100vh;
|
||||||
|
}
|
||||||
|
.common-layout {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a.router-link-exact-active {
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a.router-link-exact-active:hover {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 1rem;
|
||||||
|
border-left: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
nav a:first-of-type {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1024px) {
|
||||||
|
header {
|
||||||
|
display: flex;
|
||||||
|
place-items: center;
|
||||||
|
padding-right: calc(var(--section-gap) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin: 0 2rem 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header .wrapper {
|
||||||
|
display: flex;
|
||||||
|
place-items: flex-start;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
text-align: left;
|
||||||
|
margin-left: -1rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
|
||||||
|
padding: 1rem 0;
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.demo-tabs > .el-tabs__content {
|
||||||
|
padding: 32px;
|
||||||
|
color: #6b778c;
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
</style>
|
30
go.work.sum
30
go.work.sum
|
@ -251,13 +251,17 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUu
|
||||||
gioui.org v0.0.0-20210308172011-57750fc8a0a6 h1:K72hopUosKG3ntOPNG4OzzbuhxGuVf06fa2la1/H/Ho=
|
gioui.org v0.0.0-20210308172011-57750fc8a0a6 h1:K72hopUosKG3ntOPNG4OzzbuhxGuVf06fa2la1/H/Ho=
|
||||||
git.sr.ht/~sbinet/gg v0.3.1 h1:LNhjNn8DerC8f9DHLz6lS0YYul/b602DUxDgGkd/Aik=
|
git.sr.ht/~sbinet/gg v0.3.1 h1:LNhjNn8DerC8f9DHLz6lS0YYul/b602DUxDgGkd/Aik=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc=
|
||||||
github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
|
github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
|
||||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||||
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU=
|
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU=
|
||||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||||
|
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||||
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
|
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
|
||||||
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9 h1:7kQgkwGRoLzC9K0oyXdJo7nve/bynv/KwUsxbiTlzAM=
|
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9 h1:7kQgkwGRoLzC9K0oyXdJo7nve/bynv/KwUsxbiTlzAM=
|
||||||
github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19 h1:iXUgAaqDcIUGbRoy2TdeofRG/j1zpGRSEmNK05T+bi8=
|
github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19 h1:iXUgAaqDcIUGbRoy2TdeofRG/j1zpGRSEmNK05T+bi8=
|
||||||
|
@ -280,13 +284,16 @@ github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8
|
||||||
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||||
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||||
github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw=
|
github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw=
|
||||||
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
||||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||||
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE=
|
||||||
github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI=
|
github.com/chzyer/readline v1.5.0 h1:lSwwFrbNviGePhkewF1az4oLmcwqCZijQ2/Wi3BGHAI=
|
||||||
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
|
||||||
|
@ -310,10 +317,12 @@ github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byA
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
|
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
|
||||||
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||||
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=
|
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=
|
||||||
|
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
|
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
|
||||||
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||||
github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ=
|
github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ=
|
||||||
|
@ -329,16 +338,19 @@ github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj
|
||||||
github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 h1:6zl3BbBhdnMkpSj2YY30qV3gDcVBGtFgVsV3+/i+mKQ=
|
github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81 h1:6zl3BbBhdnMkpSj2YY30qV3gDcVBGtFgVsV3+/i+mKQ=
|
||||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
||||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-pdf/fpdf v0.6.0 h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8=
|
github.com/go-pdf/fpdf v0.6.0 h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8=
|
||||||
github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U=
|
github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U=
|
||||||
github.com/go-session/session v3.1.2+incompatible h1:yStchEObKg4nk2F7JGE7KoFIrA/1Y078peagMWcrncg=
|
github.com/go-session/session v3.1.2+incompatible h1:yStchEObKg4nk2F7JGE7KoFIrA/1Y078peagMWcrncg=
|
||||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||||
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
|
github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
|
||||||
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
|
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
|
||||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||||
github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
|
github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
|
||||||
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
|
||||||
|
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||||
github.com/google/cel-go v0.12.5 h1:DmzaiSgoaqGCjtpPQWl26/gND+yRpim56H1jCVev6d8=
|
github.com/google/cel-go v0.12.5 h1:DmzaiSgoaqGCjtpPQWl26/gND+yRpim56H1jCVev6d8=
|
||||||
github.com/google/cel-go v0.12.5/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw=
|
github.com/google/cel-go v0.12.5/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw=
|
||||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
|
@ -355,9 +367,13 @@ github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5i
|
||||||
github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA=
|
github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA=
|
||||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 h1:tlyzajkF3030q6M8SvmJSemC9DTHL/xaMa18b65+JM4=
|
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 h1:tlyzajkF3030q6M8SvmJSemC9DTHL/xaMa18b65+JM4=
|
||||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM=
|
||||||
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y=
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||||
github.com/grpc/grpc-go v1.55.0 h1:8UgTz8i19QobJ8MwLklNLqXDoMHRBGS0ZI7h2OrVqYc=
|
github.com/grpc/grpc-go v1.55.0 h1:8UgTz8i19QobJ8MwLklNLqXDoMHRBGS0ZI7h2OrVqYc=
|
||||||
github.com/grpc/grpc-go v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
|
github.com/grpc/grpc-go v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
|
||||||
|
@ -377,6 +393,8 @@ github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR3
|
||||||
github.com/hashicorp/serf v0.9.7 h1:hkdgbqizGQHuU5IPqYM1JdSMV8nKfpuOnZYXssk9muY=
|
github.com/hashicorp/serf v0.9.7 h1:hkdgbqizGQHuU5IPqYM1JdSMV8nKfpuOnZYXssk9muY=
|
||||||
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI=
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||||
|
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||||
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
|
||||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||||
github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI=
|
github.com/jhump/gopoet v0.0.0-20190322174617-17282ff210b3/go.mod h1:me9yfT6IJSlOL3FCfrg+L6yzUEZ+5jW6WHt4Sk+UPUI=
|
||||||
|
@ -386,6 +404,7 @@ github.com/jhump/goprotoc v0.5.0 h1:Y1UgUX+txUznfqcGdDef8ZOVlyQvnV0pKWZH08RmZuo=
|
||||||
github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ=
|
github.com/jhump/goprotoc v0.5.0/go.mod h1:VrbvcYrQOrTi3i0Vf+m+oqQWk9l72mjkJCYo7UvLHRQ=
|
||||||
github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E=
|
github.com/jhump/protoreflect v1.11.0/go.mod h1:U7aMIjN0NWq9swDP7xDdoMfRHb35uiuTd3Z9nFXJf5E=
|
||||||
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
||||||
|
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||||
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
||||||
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
|
||||||
|
@ -409,6 +428,7 @@ github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYt
|
||||||
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
|
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||||
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||||
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
|
||||||
|
@ -416,14 +436,17 @@ github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLv
|
||||||
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs=
|
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs=
|
||||||
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI=
|
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI=
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
|
github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
|
||||||
github.com/mmcloughlin/avo v0.5.0 h1:nAco9/aI9Lg2kiuROBY6BhCI/z0t5jEvJfjWbL8qXLU=
|
github.com/mmcloughlin/avo v0.5.0 h1:nAco9/aI9Lg2kiuROBY6BhCI/z0t5jEvJfjWbL8qXLU=
|
||||||
github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM=
|
github.com/mmcloughlin/avo v0.5.0/go.mod h1:ChHFdoV7ql95Wi7vuq2YT1bwCJqiWdZrQ1im3VujLYM=
|
||||||
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
|
||||||
|
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||||
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI=
|
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI=
|
||||||
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
|
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||||
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/nats-io/nats-server/v2 v2.9.15/go.mod h1:QlCTy115fqpx4KSOPFIxSV7DdI6OxtZsGOL1JLdeRlE=
|
github.com/nats-io/nats-server/v2 v2.9.15/go.mod h1:QlCTy115fqpx4KSOPFIxSV7DdI6OxtZsGOL1JLdeRlE=
|
||||||
github.com/nats-io/nats.go v1.25.0/go.mod h1:D2WALIhz7V8M0pH8Scx8JZXlg6Oqz5VG+nQkK8nJdvg=
|
github.com/nats-io/nats.go v1.25.0/go.mod h1:D2WALIhz7V8M0pH8Scx8JZXlg6Oqz5VG+nQkK8nJdvg=
|
||||||
github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y=
|
github.com/onsi/ginkgo v1.13.0 h1:M76yO2HkZASFjXL0HSoZJ1AYEmQxNJmY41Jx1zNUq1Y=
|
||||||
|
@ -431,6 +454,7 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
|
||||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||||
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
github.com/phpdave11/gofpdf v1.4.2 h1:KPKiIbfwbvC/wOncwhrpRdXVj2CZTCFlw4wnoyjtHfQ=
|
github.com/phpdave11/gofpdf v1.4.2 h1:KPKiIbfwbvC/wOncwhrpRdXVj2CZTCFlw4wnoyjtHfQ=
|
||||||
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
|
||||||
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
||||||
|
@ -448,20 +472,24 @@ github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5A
|
||||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
|
github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js=
|
||||||
|
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
||||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
|
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
|
||||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
|
||||||
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||||
github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc=
|
github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc=
|
||||||
github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4=
|
github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
|
||||||
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
|
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
|
||||||
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
|
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
|
||||||
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
|
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
|
||||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||||
|
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||||
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||||
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 h1:1JFLBqwIgdyHN1ZtgjTBwO+blA6gVOmZurpiMEsETKo=
|
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 h1:1JFLBqwIgdyHN1ZtgjTBwO+blA6gVOmZurpiMEsETKo=
|
||||||
go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8=
|
go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8=
|
||||||
|
@ -539,7 +567,9 @@ google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQf
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||||
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
|
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
|
||||||
|
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
|
||||||
honnef.co/go/tools v0.1.3 h1:qTakTkI6ni6LFD5sBwwsdSO+AQqbSIxOauHTTQKZ/7o=
|
honnef.co/go/tools v0.1.3 h1:qTakTkI6ni6LFD5sBwwsdSO+AQqbSIxOauHTTQKZ/7o=
|
||||||
k8s.io/apiserver v0.26.0 h1:q+LqIK5EZwdznGZb8bq0+a+vCqdeEEe4Ux3zsOjbc4o=
|
k8s.io/apiserver v0.26.0 h1:q+LqIK5EZwdznGZb8bq0+a+vCqdeEEe4Ux3zsOjbc4o=
|
||||||
k8s.io/apiserver v0.26.0/go.mod h1:aWhlLD+mU+xRo+zhkvP/gFNbShI4wBDHS33o0+JGI84=
|
k8s.io/apiserver v0.26.0/go.mod h1:aWhlLD+mU+xRo+zhkvP/gFNbShI4wBDHS33o0+JGI84=
|
||||||
|
|
Loading…
Reference in New Issue