From 71ba024974fa5681865a42d88cf0114c2184d3a0 Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Thu, 25 Nov 2021 17:14:07 +0000
Subject: [PATCH 01/30] WIP: Rest API import
---
packages/bbui/src/Form/Core/Dropzone.svelte | 27 ++++
packages/bbui/src/Form/Dropzone.svelte | 2 +
packages/bbui/src/Modal/ModalContent.svelte | 25 ++++
.../modals/CreateDatasourceModal.svelte | 24 ++++
.../modals/ImportRestDatasourceModal.svelte | 103 ++++++++++++++
.../builder/src/stores/backend/datasources.js | 5 +
packages/builder/yarn.lock | 28 ++--
packages/server/src/api/controllers/query.js | 130 ++++++++++++++++++
packages/server/src/api/routes/query.js | 5 +
packages/server/src/integrations/index.ts | 4 +-
packages/server/src/integrations/oracle.ts | 29 ++--
packages/server/src/integrations/utils.ts | 8 +-
12 files changed, 364 insertions(+), 26 deletions(-)
create mode 100644 packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte
diff --git a/packages/bbui/src/Form/Core/Dropzone.svelte b/packages/bbui/src/Form/Core/Dropzone.svelte
index a543dea1d4..1595a2ea92 100644
--- a/packages/bbui/src/Form/Core/Dropzone.svelte
+++ b/packages/bbui/src/Form/Core/Dropzone.svelte
@@ -6,6 +6,8 @@
import { generateID } from "../../utils/helpers"
import Icon from "../../Icon/Icon.svelte"
import Link from "../../Link/Link.svelte"
+ import Tag from "../../Tags/Tag.svelte"
+ import Tags from "../../Tags/Tags.svelte"
const BYTES_IN_KB = 1000
const BYTES_IN_MB = 1000000
@@ -18,6 +20,7 @@
export let handleFileTooLarge = null
export let gallery = true
export let error = null
+ export let fileTags = []
const dispatch = createEventDispatcher()
const imageExtensions = [
@@ -278,6 +281,19 @@
from your computer
+ {#if fileTags.length}
+
+
+
+ {/if}
{/if}
@@ -390,4 +406,15 @@
.disabled .spectrum-Heading--sizeL {
color: var(--spectrum-alias-text-color-disabled);
}
+
+ .tags {
+ margin-top: 20px;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ }
+
+ .tag {
+ margin-top: 8px;
+ }
diff --git a/packages/bbui/src/Form/Dropzone.svelte b/packages/bbui/src/Form/Dropzone.svelte
index f8facaada9..a8a160010d 100644
--- a/packages/bbui/src/Form/Dropzone.svelte
+++ b/packages/bbui/src/Form/Dropzone.svelte
@@ -12,6 +12,7 @@
export let processFiles = undefined
export let handleFileTooLarge = undefined
export let gallery = true
+ export let fileTags = []
const dispatch = createEventDispatcher()
const onChange = e => {
@@ -29,6 +30,7 @@
{processFiles}
{handleFileTooLarge}
{gallery}
+ {fileTags}
on:change={onChange}
/>
diff --git a/packages/bbui/src/Modal/ModalContent.svelte b/packages/bbui/src/Modal/ModalContent.svelte
index 09cc4f6c52..7f2d7fbdb9 100644
--- a/packages/bbui/src/Modal/ModalContent.svelte
+++ b/packages/bbui/src/Modal/ModalContent.svelte
@@ -18,10 +18,22 @@
export let disabled = false
export let showDivider = true
+ export let showSecondaryButton = false
+ export let secondaryButtonText = undefined
+ export let secondaryAction = undefined
+
const { hide, cancel } = getContext(Context.Modal)
let loading = false
$: confirmDisabled = disabled || loading
+ async function secondary() {
+ loading = true
+ if (!secondaryAction || (await secondaryAction()) !== false) {
+ hide()
+ }
+ loading = false
+ }
+
async function confirm() {
loading = true
if (!onConfirm || (await onConfirm()) !== false) {
@@ -73,6 +85,15 @@
class="spectrum-ButtonGroup spectrum-Dialog-buttonGroup spectrum-Dialog-buttonGroup--noFooter"
>
+
+ {#if showSecondaryButton && secondaryButtonText && secondaryAction}
+
+
+
+ {/if}
+
{#if showCancelButton}
{/if}
@@ -136,4 +157,8 @@
display: flex;
justify-content: space-between;
}
+
+ .secondary-action {
+ margin-right: auto;
+ }
diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte
index 1a433785dc..1fc3937ba0 100644
--- a/packages/builder/src/components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte
+++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte
@@ -6,12 +6,18 @@
import { IntegrationNames } from "constants"
import CreateTableModal from "components/backend/TableNavigator/modals/CreateTableModal.svelte"
import DatasourceConfigModal from "components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte"
+ import ImportRestDatasourceModal from "./ImportRestDatasourceModal.svelte"
export let modal
let integrations = []
let integration = {}
let internalTableModal
let externalDatasourceModal
+ let importModal
+
+ $: showImportButton = false
+
+ checkShowImport()
const INTERNAL = "BUDIBASE"
@@ -33,6 +39,15 @@
config,
schema: selected.datasource,
}
+ checkShowImport()
+ }
+
+ function checkShowImport() {
+ showImportButton = integration.type === "REST"
+ }
+
+ function showImportModal() {
+ importModal.show()
}
function chooseNextModal() {
@@ -63,11 +78,20 @@
+
+ {#if integration.type === "REST"}
+
+ {/if}
+
+
showImportModal()}
showCancelButton={false}
size="M"
onConfirm={() => {
diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte
new file mode 100644
index 0000000000..dd25880491
--- /dev/null
+++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte
@@ -0,0 +1,103 @@
+
+
+ importDatasource()}
+ onCancel={() => modal.show()}
+ confirmText={"Import"}
+ cancelText="Back"
+ size="L"
+>
+
+ Import
+ Import your rest collection using one of the options below
+
+
+ (lastTouched = "url")}
+ label="Enter a URL"
+ placeholder="e.g. https://petstore.swagger.io/v2/swagger.json"
+ />
+
+
+ (lastTouched = "file")}
+ fileTags={["OpenAPI", "Swagger 2.0"]}
+ />
+
+
+
+
+
+
+
+
diff --git a/packages/builder/src/stores/backend/datasources.js b/packages/builder/src/stores/backend/datasources.js
index 7810c3a950..2d4fbdfb0b 100644
--- a/packages/builder/src/stores/backend/datasources.js
+++ b/packages/builder/src/stores/backend/datasources.js
@@ -84,6 +84,11 @@ export function createDatasourcesStore() {
return updateDatasource(response)
},
+ import: async body => {
+ let response
+ response = await api.post(`/api/queries/import/swagger2`, body)
+ return updateDatasource(response)
+ },
delete: async datasource => {
const response = await api.delete(
`/api/datasources/${datasource._id}/${datasource._rev}`
diff --git a/packages/builder/yarn.lock b/packages/builder/yarn.lock
index f3d3362bd3..b76300b9ea 100644
--- a/packages/builder/yarn.lock
+++ b/packages/builder/yarn.lock
@@ -969,10 +969,10 @@
svelte-flatpickr "^3.2.3"
svelte-portal "^1.0.0"
-"@budibase/bbui@^0.9.185-alpha.12", "@budibase/bbui@^0.9.188":
- version "0.9.188"
- resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.188.tgz#82c108172fbf81a84378e0ef4ca7cba61ea8d0ba"
- integrity sha512-KevJxHdASITX9RzLvm+b2K3VMwqYFTumvrlpStAP6UIoyPkls0xaAc2KiJJ7Kkq48UkkBtAbOYaMxsFbAaTsbQ==
+"@budibase/bbui@^0.9.185-alpha.21", "@budibase/bbui@^0.9.189":
+ version "0.9.189"
+ resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.189.tgz#d5802e9b6aabccdef4205f0edfa7ed5616ac1aff"
+ integrity sha512-YqM21mtrg8yTN9mqG4CnFfvoOelmhy3V69LyoITdQT6aGiwt/efHzknSlaUH3/0yLH9MuzwkHDzUmbe7QrsqEA==
dependencies:
"@adobe/spectrum-css-workflow-icons" "^1.2.1"
"@spectrum-css/actionbutton" "^1.0.1"
@@ -1018,14 +1018,14 @@
svelte-flatpickr "^3.2.3"
svelte-portal "^1.0.0"
-"@budibase/client@^0.9.185-alpha.12":
- version "0.9.188"
- resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.9.188.tgz#c5bf6f3bccdb370b236b9e69e0118334ad3eccfd"
- integrity sha512-yP2WLWb2yQAwPBxVzpNGjSHpATMZMzcxl2gK6vw662F7YC8xGFHNfZZqEwPvrVwnx+d7LFZR/kJxJOvvk7YCVw==
+"@budibase/client@^0.9.185-alpha.21":
+ version "0.9.189"
+ resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.9.189.tgz#8f96b607f36bbb7390fd53b04360851f0c12aaac"
+ integrity sha512-L2i3CaQt4aFL7JKkRrEWWx8NemHTEOKLXvXq7LGM4u3GlcFIIkcL113EkXQT1bIZcf6AuuC2CfNsmZKioOPh2A==
dependencies:
- "@budibase/bbui" "^0.9.188"
+ "@budibase/bbui" "^0.9.189"
"@budibase/standard-components" "^0.9.139"
- "@budibase/string-templates" "^0.9.188"
+ "@budibase/string-templates" "^0.9.189"
regexparam "^1.3.0"
shortid "^2.2.15"
svelte-spa-router "^3.0.5"
@@ -1080,10 +1080,10 @@
svelte-apexcharts "^1.0.2"
svelte-flatpickr "^3.1.0"
-"@budibase/string-templates@^0.9.185-alpha.12", "@budibase/string-templates@^0.9.188":
- version "0.9.188"
- resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-0.9.188.tgz#f37836ed23dbd2217cb157030ada7cd59f6a2165"
- integrity sha512-O/bL0I5OJO9W2OizIe9vBHowCLwwASPBrsGiAIB8L0x6AivYMq8j1mvNRwLXZjpHTjv86bU/LyG/3CP837oDsg==
+"@budibase/string-templates@^0.9.185-alpha.21", "@budibase/string-templates@^0.9.189":
+ version "0.9.189"
+ resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-0.9.189.tgz#515a4ce85da550ce19d78c4c592ab5839a8ebe3a"
+ integrity sha512-JmnpuPx1CItNIFCMUxBz+4DVpYu96QxteU2Vi17pjWb0B7qsWwHkmcMmYbd+iTW4oxgOufbP8slfyfbu2XhbzA==
dependencies:
"@budibase/handlebars-helpers" "^0.11.7"
dayjs "^1.10.4"
diff --git a/packages/server/src/api/controllers/query.js b/packages/server/src/api/controllers/query.js
index 502ef5e67b..13b14a6343 100644
--- a/packages/server/src/api/controllers/query.js
+++ b/packages/server/src/api/controllers/query.js
@@ -5,6 +5,10 @@ const { BaseQueryVerbs } = require("../../constants")
const env = require("../../environment")
const { Thread, ThreadType } = require("../../threads")
+const fetch = require("node-fetch")
+const Joi = require("joi")
+const { save: saveDatasource } = require("./datasource")
+
const Runner = new Thread(ThreadType.QUERY, { timeoutMs: 10000 })
// simple function to append "readable" to all read queries
@@ -30,6 +34,132 @@ exports.fetch = async function (ctx) {
ctx.body = enrichQueries(body.rows.map(row => row.doc))
}
+// const query = {
+// datasourceId: "datasource_b9a474302a174d1295e4c273cd72bde9",
+// name: "available pets (import)",
+// parameters: [],
+// fields: {
+// headers: {},
+// queryString: "status=available",
+// path: "v2/pet/findByStatus",
+// },
+// queryVerb: "read",
+// transformer: "return data",
+// schema: {},
+// readable: true
+// }
+
+function generateQueryValidation() {
+ // prettier-ignore
+ return Joi.object({
+ _id: Joi.string(),
+ _rev: Joi.string(),
+ name: Joi.string().required(),
+ fields: Joi.object().required(),
+ datasourceId: Joi.string().required(),
+ readable: Joi.boolean(),
+ parameters: Joi.array().items(Joi.object({
+ name: Joi.string(),
+ default: Joi.string().allow(""),
+ })),
+ queryVerb: Joi.string().allow().required(),
+ extra: Joi.object().optional(),
+ schema: Joi.object({}).required().unknown(true),
+ transformer: Joi.string().optional(),
+ })
+}
+
+const verbs = {
+ get: "read",
+ post: "create",
+ put: "update",
+ patch: "patch",
+ delete: "delete",
+}
+
+const constructQuery = (datasource, swagger, path, method, config) => {
+ const query = {
+ datasourceId: datasource._id,
+ }
+ query.name = config.operationId || path
+ query.parameters = []
+ query.fields = {
+ headers: {},
+ // queryString: "status=available",
+ path: path,
+ }
+ query.transformer = "return data"
+ query.schema = {}
+ query.readable = true
+ query.queryVerb = verbs[method]
+
+ return query
+}
+
+// {
+// "type": "url",
+// "data": "www.url.com/swagger.json"
+// }
+
+exports.import = async function (ctx) {
+ const importConfig = ctx.request.body
+
+ let data
+
+ if (importConfig.type === "url") {
+ data = await fetch(importConfig.data).then(res => res.json())
+ } else if (importConfig.type === "raw") {
+ data = JSON.parse(importConfig.data)
+ }
+
+ const db = new CouchDB(ctx.appId)
+ const schema = generateQueryValidation()
+
+ // create datasource
+ const scheme = data.schemes.includes("https") ? "https" : "http"
+ const url = `${scheme}://${data.host}${data.basePath}`
+ const name = data.info.title
+
+ // TODO: Refactor datasource creation into shared function
+ const datasourceCtx = {
+ ...ctx,
+ }
+ datasourceCtx.request.body.datasource = {
+ type: "datasource",
+ source: "REST",
+ config: {
+ url: url,
+ defaultHeaders: {},
+ },
+ name: name,
+ }
+ await saveDatasource(datasourceCtx)
+ const datasource = datasourceCtx.body.datasource
+
+ // create query
+
+ for (const [path, method] of Object.entries(data.paths)) {
+ for (const [methodName, config] of Object.entries(method)) {
+ const query = constructQuery(datasource, data, path, methodName, config)
+
+ // validate query
+ const { error } = schema.validate(query)
+ if (error) {
+ ctx.throw(400, `Invalid - ${error.message}`)
+ return
+ }
+
+ // persist query
+ query._id = generateQueryID(query.datasourceId)
+ await db.put(query)
+ }
+ }
+
+ // return the datasource
+ ctx.body = { datasource }
+ ctx.status = 200
+}
+
exports.save = async function (ctx) {
const db = new CouchDB(ctx.appId)
const query = ctx.request.body
diff --git a/packages/server/src/api/routes/query.js b/packages/server/src/api/routes/query.js
index 3fca0c1e0f..bc1c2204de 100644
--- a/packages/server/src/api/routes/query.js
+++ b/packages/server/src/api/routes/query.js
@@ -57,6 +57,11 @@ router
generateQueryValidation(),
queryController.save
)
+ .post(
+ "/api/queries/import/swagger2",
+ authorized(BUILDER),
+ queryController.import
+ )
.post(
"/api/queries/preview",
bodyResource("datasourceId"),
diff --git a/packages/server/src/integrations/index.ts b/packages/server/src/integrations/index.ts
index eff499f978..8f2f083fc5 100644
--- a/packages/server/src/integrations/index.ts
+++ b/packages/server/src/integrations/index.ts
@@ -40,9 +40,9 @@ const INTEGRATIONS = {
}
// optionally add oracle integration if the oracle binary can be installed
-if (!(process.arch === 'arm64' && process.platform === 'darwin')) {
+if (!(process.arch === "arm64" && process.platform === "darwin")) {
const oracle = require("./oracle")
- DEFINITIONS[SourceNames.ORACLE] = oracle.schema
+ DEFINITIONS[SourceNames.ORACLE] = oracle.schema
INTEGRATIONS[SourceNames.ORACLE] = oracle.integration
}
diff --git a/packages/server/src/integrations/oracle.ts b/packages/server/src/integrations/oracle.ts
index c74977bece..13658399db 100644
--- a/packages/server/src/integrations/oracle.ts
+++ b/packages/server/src/integrations/oracle.ts
@@ -352,14 +352,23 @@ module OracleModule {
* Knex default returning behaviour does not work with oracle
* Manually add the behaviour for the return column
*/
- private addReturning(query: SqlQuery, bindings: BindParameters, returnColumn: string) {
+ private addReturning(
+ query: SqlQuery,
+ bindings: BindParameters,
+ returnColumn: string
+ ) {
if (bindings instanceof Array) {
bindings.push({ dir: oracledb.BIND_OUT })
- query.sql = query.sql + ` returning \"${returnColumn}\" into :${bindings.length}`
+ query.sql =
+ query.sql + ` returning \"${returnColumn}\" into :${bindings.length}`
}
}
- private async internalQuery(query: SqlQuery, returnColum?: string, operation?: string): Promise> {
+ private async internalQuery(
+ query: SqlQuery,
+ returnColum?: string,
+ operation?: string
+ ): Promise> {
let connection
try {
connection = await this.getConnection()
@@ -367,7 +376,10 @@ module OracleModule {
const options: ExecuteOptions = { autoCommit: true }
const bindings: BindParameters = query.bindings || []
- if (returnColum && (operation === Operation.CREATE || operation === Operation.UPDATE)) {
+ if (
+ returnColum &&
+ (operation === Operation.CREATE || operation === Operation.UPDATE)
+ ) {
this.addReturning(query, bindings, returnColum)
}
@@ -414,14 +426,14 @@ module OracleModule {
return response.rows ? response.rows : []
}
- async update(query: SqlQuery | string): Promise {
+ async update(query: SqlQuery | string): Promise {
const response = await this.internalQuery(getSqlQuery(query))
return response.rows && response.rows.length
? response.rows
: [{ updated: true }]
}
- async delete(query: SqlQuery | string): Promise {
+ async delete(query: SqlQuery | string): Promise {
const response = await this.internalQuery(getSqlQuery(query))
return response.rows && response.rows.length
? response.rows
@@ -431,8 +443,9 @@ module OracleModule {
async query(json: QueryJson) {
const primaryKeys = json.meta!.table!.primary
const primaryKey = primaryKeys ? primaryKeys[0] : undefined
- const queryFn = (query: any, operation: string) => this.internalQuery(query, primaryKey, operation)
- const processFn = (response: any) => response.rows ? response.rows : []
+ const queryFn = (query: any, operation: string) =>
+ this.internalQuery(query, primaryKey, operation)
+ const processFn = (response: any) => (response.rows ? response.rows : [])
const output = await this.queryWithReturning(json, queryFn, processFn)
return output
}
diff --git a/packages/server/src/integrations/utils.ts b/packages/server/src/integrations/utils.ts
index 07cf0505bf..97380b1b5b 100644
--- a/packages/server/src/integrations/utils.ts
+++ b/packages/server/src/integrations/utils.ts
@@ -2,7 +2,11 @@ import { SqlQuery } from "../definitions/datasource"
import { Datasource, Table } from "../definitions/common"
import { SourceNames } from "../definitions/datasource"
const { DocumentTypes, SEPARATOR } = require("../db/utils")
-const { FieldTypes, BuildSchemaErrors, InvalidColumns } = require("../constants")
+const {
+ FieldTypes,
+ BuildSchemaErrors,
+ InvalidColumns,
+} = require("../constants")
const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
const ROW_ID_REGEX = /^\[.*]$/g
@@ -42,7 +46,7 @@ export enum SqlClients {
MS_SQL = "mssql",
POSTGRES = "pg",
MY_SQL = "mysql",
- ORACLE = "oracledb"
+ ORACLE = "oracledb",
}
export function isExternalTable(tableId: string) {
From 41fa958c78fbc6a80516db138a3a5094f5210ac6 Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Fri, 26 Nov 2021 09:51:56 +0000
Subject: [PATCH 02/30] File upload working
---
.../modals/ImportRestDatasourceModal.svelte | 26 ++++++++++++-------
packages/server/src/api/controllers/query.js | 2 ++
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte
index dd25880491..64cffb3f7f 100644
--- a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte
+++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte
@@ -25,24 +25,29 @@
let lastTouched = "url"
- $: {
- console.log({ data })
- console.log({ lastTouched })
- }
+ const getPayload = async () => {
+ let payloadData
+ let type
+
+ // parse the file into memory and send as string
+ if (lastTouched === "file") {
+ type = "raw"
+ payloadData = await data.file[0].text()
+ } else {
+ type = lastTouched
+ payloadData = data[lastTouched]
+ }
- const getPayload = () => {
return {
- type: lastTouched,
- data: data[lastTouched],
+ type: type,
+ data: payloadData,
}
}
async function importDatasource() {
try {
- // Create datasource
- const resp = await datasources.import(getPayload())
+ const resp = await datasources.import(await getPayload())
- // // update the tables incase data source plus
await queries.fetch()
await datasources.select(resp._id)
$goto(`./datasource/${resp._id}`)
@@ -82,6 +87,7 @@
(lastTouched = "file")}
fileTags={["OpenAPI", "Swagger 2.0"]}
diff --git a/packages/server/src/api/controllers/query.js b/packages/server/src/api/controllers/query.js
index 13b14a6343..40fc1adf21 100644
--- a/packages/server/src/api/controllers/query.js
+++ b/packages/server/src/api/controllers/query.js
@@ -110,6 +110,8 @@ exports.import = async function (ctx) {
data = await fetch(importConfig.data).then(res => res.json())
} else if (importConfig.type === "raw") {
data = JSON.parse(importConfig.data)
+ } else {
+ throw new Error("Invalid data type")
}
const db = new CouchDB(ctx.appId)
From c53f5e3d2bd4e8219192c5feb788da39a4ff7843 Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Mon, 29 Nov 2021 10:37:31 +0000
Subject: [PATCH 03/30] Update backend to be extensible for different import
sources
---
packages/builder/src/analytics/constants.js | 3 +
.../modals/CreateDatasourceModal.svelte | 4 +-
...l.svelte => ImportRestQueriesModal.svelte} | 59 +-
.../builder/src/stores/backend/datasources.js | 5 -
.../builder/src/stores/backend/queries.js | 4 +
packages/server/package.json | 1 +
.../src/api/controllers/query/import.ts | 275 ++++++
.../controllers/{query.js => query/index.js} | 167 +---
.../src/api/controllers/query/validation.js | 40 +
packages/server/src/api/routes/query.js | 44 +-
packages/server/yarn.lock | 807 +++++++++++++++++-
11 files changed, 1195 insertions(+), 214 deletions(-)
rename packages/builder/src/components/backend/DatasourceNavigator/modals/{ImportRestDatasourceModal.svelte => ImportRestQueriesModal.svelte} (60%)
create mode 100644 packages/server/src/api/controllers/query/import.ts
rename packages/server/src/api/controllers/{query.js => query/index.js} (52%)
create mode 100644 packages/server/src/api/controllers/query/validation.js
diff --git a/packages/builder/src/analytics/constants.js b/packages/builder/src/analytics/constants.js
index d38b7bba4f..177d5320a5 100644
--- a/packages/builder/src/analytics/constants.js
+++ b/packages/builder/src/analytics/constants.js
@@ -9,6 +9,9 @@ export const Events = {
CREATED: "Datasource Created",
UPDATED: "Datasource Updated",
},
+ QUERIES: {
+ REST: "REST Queries Imported",
+ },
TABLE: {
CREATED: "Table Created",
},
diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte
index 1fc3937ba0..d52bdb4785 100644
--- a/packages/builder/src/components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte
+++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/CreateDatasourceModal.svelte
@@ -6,7 +6,7 @@
import { IntegrationNames } from "constants"
import CreateTableModal from "components/backend/TableNavigator/modals/CreateTableModal.svelte"
import DatasourceConfigModal from "components/backend/DatasourceNavigator/modals/DatasourceConfigModal.svelte"
- import ImportRestDatasourceModal from "./ImportRestDatasourceModal.svelte"
+ import ImportRestQueriesModal from "./ImportRestQueriesModal.svelte"
export let modal
let integrations = []
@@ -80,7 +80,7 @@
{#if integration.type === "REST"}
-
+
{/if}
diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte
similarity index 60%
rename from packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte
rename to packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte
index 64cffb3f7f..8098e10fb4 100644
--- a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestDatasourceModal.svelte
+++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte
@@ -16,6 +16,8 @@
import { datasources, queries } from "stores/backend"
export let modal
+ export let datasourceId
+ export let createDatasource = false
let data = {
url: "",
@@ -25,47 +27,60 @@
let lastTouched = "url"
- const getPayload = async () => {
- let payloadData
- let type
+ const getData = async () => {
+ let dataString
// parse the file into memory and send as string
if (lastTouched === "file") {
- type = "raw"
- payloadData = await data.file[0].text()
- } else {
- type = lastTouched
- payloadData = data[lastTouched]
+ dataString = await data.file[0].text()
+ } else if (lastTouched === "url") {
+ const response = await fetch(data.url)
+ dataString = await response.text()
+ } else if (lastTouched === "raw") {
+ dataString = data.raw
}
- return {
- type: type,
- data: payloadData,
- }
+ return dataString
}
- async function importDatasource() {
+ async function importQueries() {
try {
- const resp = await datasources.import(await getPayload())
+ const dataString = await getData()
+ if (!datasourceId && !createDatasource) {
+ throw new Error("No datasource id")
+ }
+
+ const body = {
+ data: dataString,
+ datasourceId,
+ }
+
+ const resp = await queries.import(body)
+ datasourceId = resp.datasourceId
+
+ // reload
+ await datasources.fetch()
await queries.fetch()
- await datasources.select(resp._id)
- $goto(`./datasource/${resp._id}`)
- notifications.success(`Datasource imported successfully.`)
- analytics.captureEvent(Events.DATASOURCE.IMPORTED, {
- name: resp.name,
- source: resp.source,
+ await datasources.select(datasourceId)
+
+ $goto(`./datasource/${datasourceId}`)
+ notifications.success(`Imported successfully.`)
+ analytics.captureEvent(Events.QUERIES.REST.IMPORTED, {
+ importType: lastTouched,
+ newDatasource: createDatasource,
})
+
return true
} catch (err) {
- notifications.error(`Error importing datasource: ${err}`)
+ notifications.error(`Error importing: ${err}`)
return false
}
}
importDatasource()}
+ onConfirm={() => importQueries()}
onCancel={() => modal.show()}
confirmText={"Import"}
cancelText="Back"
diff --git a/packages/builder/src/stores/backend/datasources.js b/packages/builder/src/stores/backend/datasources.js
index 2d4fbdfb0b..7810c3a950 100644
--- a/packages/builder/src/stores/backend/datasources.js
+++ b/packages/builder/src/stores/backend/datasources.js
@@ -84,11 +84,6 @@ export function createDatasourcesStore() {
return updateDatasource(response)
},
- import: async body => {
- let response
- response = await api.post(`/api/queries/import/swagger2`, body)
- return updateDatasource(response)
- },
delete: async datasource => {
const response = await api.delete(
`/api/datasources/${datasource._id}/${datasource._rev}`
diff --git a/packages/builder/src/stores/backend/queries.js b/packages/builder/src/stores/backend/queries.js
index 020a0c9420..c03aea4052 100644
--- a/packages/builder/src/stores/backend/queries.js
+++ b/packages/builder/src/stores/backend/queries.js
@@ -53,6 +53,10 @@ export function createQueriesStore() {
})
return json
},
+ import: async body => {
+ const response = await api.post(`/api/queries/import`, body)
+ return response.json()
+ },
select: query => {
update(state => ({ ...state, selected: query._id }))
views.unselect()
diff --git a/packages/server/package.json b/packages/server/package.json
index 43fb5ab22b..040febe02c 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -77,6 +77,7 @@
"@koa/router": "8.0.0",
"@sendgrid/mail": "7.1.1",
"@sentry/node": "^6.0.0",
+ "@types/swagger-schema-official": "^2.0.22",
"airtable": "0.10.1",
"arangojs": "7.2.0",
"aws-sdk": "^2.767.0",
diff --git a/packages/server/src/api/controllers/query/import.ts b/packages/server/src/api/controllers/query/import.ts
new file mode 100644
index 0000000000..f860b28d8c
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import.ts
@@ -0,0 +1,275 @@
+import CouchDB from "../../../db"
+import { queryValidation } from "./validation"
+import { generateQueryID } from "../../../db/utils"
+import { Spec as Swagger2, Operation } from "swagger-schema-official"
+
+// {
+// "_id": "query_datasource_d62738f2d72a466997ffbf46f4952404_e7258ad382cd4c37961b81730633ff2d",
+// "_rev": "1-e702a18eaa96c7cb4be1b402c34eaa59",
+// "datasourceId": "datasource_d62738f2d72a466997ffbf46f4952404",
+// "parameters": [
+// {
+// "name": "paramtest",
+// "default": "defaultValue"
+// }
+// ],
+// "fields": {
+// "headers": {
+// "headertest": "test"
+// },
+// "queryString": "query=test",
+// "path": "/path/test"
+// },
+// "queryVerb": "read",
+// "transformer": "return data.test",
+// "schema": {},
+// "name": "name",
+// "readable": true
+// }
+
+// return joiValidator.body(Joi.object({
+// _id: Joi.string(),
+// _rev: Joi.string(),
+// name: Joi.string().required(),
+// fields: Joi.object().required(),
+// datasourceId: Joi.string().required(),
+// readable: Joi.boolean(),
+// parameters: Joi.array().items(Joi.object({
+// name: Joi.string(),
+// default: Joi.string().allow(""),
+// })),
+// queryVerb: Joi.string().allow().required(),
+// extra: Joi.object().optional(),
+// schema: Joi.object({}).required().unknown(true),
+// transformer: Joi.string().optional(),
+// }))
+
+interface Parameter {
+ name: string
+ default: string
+}
+
+interface Query {
+ _id?: string
+ datasourceId: string
+ name: string
+ parameters: Parameter[]
+ fields: {
+ headers: any
+ queryString: string
+ path: string
+ }
+ transformer: string | null
+ schema: any
+ readable: boolean
+ queryVerb: string
+}
+
+enum Strategy {
+ SWAGGER2,
+ OPENAPI3,
+ CURL,
+}
+
+enum MethodToVerb {
+ get = "read",
+ post = "create",
+ put = "update",
+ patch = "patch",
+ delete = "delete",
+}
+
+interface ImportResult {
+ errorQueries: Query[]
+}
+
+interface DatasourceInfo {
+ url: string
+ name: string
+ defaultHeaders: any[]
+}
+
+const parseImportStrategy = (data: string): Strategy => {
+ return Strategy.SWAGGER2
+}
+
+// SWAGGER
+
+const parseSwagger2Info = (swagger2: Swagger2): DatasourceInfo => {
+ return {
+ url: "http://localhost:3000",
+ name: "swagger",
+ defaultHeaders: [],
+ }
+}
+
+const parseSwagger2Queries = (
+ datasourceId: string,
+ swagger2: Swagger2
+): Query[] => {
+ const queries = []
+
+ for (let [pathName, path] of Object.entries(swagger2.paths)) {
+ for (let [methodName, op] of Object.entries(path)) {
+ let operation = op as Operation
+
+ const name = operation.operationId || pathName
+ const queryString = ""
+ const headers = {}
+ const parameters: Parameter[] = []
+
+ const query = constructQuery(
+ datasourceId,
+ name,
+ methodName,
+ pathName,
+ queryString,
+ headers,
+ parameters
+ )
+ queries.push(query)
+ }
+ }
+
+ return queries
+}
+
+// OPEN API
+
+const parseOpenAPI3Info = (data: any): DatasourceInfo => {
+ return {
+ url: "http://localhost:3000",
+ name: "swagger",
+ defaultHeaders: [],
+ }
+}
+
+const parseOpenAPI3Queries = (datasourceId: string, data: string): Query[] => {
+ return []
+}
+
+// CURL
+
+const parseCurlDatasourceInfo = (data: any): DatasourceInfo => {
+ return {
+ url: "http://localhost:3000",
+ name: "swagger",
+ defaultHeaders: [],
+ }
+}
+
+const parseCurlQueries = (datasourceId: string, data: string): Query[] => {
+ return []
+}
+
+const verbFromMethod = (method: string) => {
+ const verb = (MethodToVerb)[method]
+ if (!verb) {
+ throw new Error(`Unsupported method: ${method}`)
+ }
+ return verb
+}
+
+const constructQuery = (
+ datasourceId: string,
+ name: string,
+ method: string,
+ path: string,
+ queryString: string,
+ headers: any = {},
+ parameters: Parameter[] = []
+): Query => {
+ const readable = true
+ const queryVerb = verbFromMethod(method)
+ const transformer = "return data"
+ const schema = {}
+
+ const query: Query = {
+ datasourceId,
+ name,
+ parameters,
+ fields: {
+ headers,
+ queryString,
+ path,
+ },
+ transformer,
+ schema,
+ readable,
+ queryVerb,
+ }
+
+ return query
+}
+
+export const getDatasourceInfo = (data: string): DatasourceInfo => {
+ const strategy = parseImportStrategy(data)
+
+ let info: DatasourceInfo
+ switch (strategy) {
+ case Strategy.SWAGGER2:
+ info = parseSwagger2Info(JSON.parse(data))
+ break
+ case Strategy.OPENAPI3:
+ info = parseOpenAPI3Info(JSON.parse(data))
+ break
+ case Strategy.CURL:
+ info = parseCurlDatasourceInfo(data)
+ break
+ }
+
+ return info
+}
+
+export const importQueries = async (
+ appId: string,
+ datasourceId: string,
+ data: string
+): Promise => {
+ const strategy = parseImportStrategy(data)
+
+ // constuct the queries
+ let queries: Query[]
+ switch (strategy) {
+ case Strategy.SWAGGER2:
+ queries = parseSwagger2Queries(datasourceId, JSON.parse(data))
+ break
+ case Strategy.OPENAPI3:
+ queries = parseOpenAPI3Queries(datasourceId, JSON.parse(data))
+ break
+ case Strategy.CURL:
+ queries = parseCurlQueries(datasourceId, data)
+ break
+ }
+
+ // validate queries
+ const errorQueries = []
+ const schema = queryValidation()
+ queries = queries
+ .filter(query => {
+ const validation = schema.validate(query)
+ if (validation.error) {
+ errorQueries.push(query)
+ return false
+ }
+ return true
+ })
+ .map(query => {
+ query._id = generateQueryID(query.datasourceId)
+ return query
+ })
+
+ // persist queries
+ const db = new CouchDB(appId)
+ for (const query of queries) {
+ try {
+ await db.put(query)
+ } catch (error) {
+ errorQueries.push(query)
+ }
+ }
+
+ return {
+ errorQueries,
+ }
+}
diff --git a/packages/server/src/api/controllers/query.js b/packages/server/src/api/controllers/query/index.js
similarity index 52%
rename from packages/server/src/api/controllers/query.js
rename to packages/server/src/api/controllers/query/index.js
index 40fc1adf21..fb3d233c4e 100644
--- a/packages/server/src/api/controllers/query.js
+++ b/packages/server/src/api/controllers/query/index.js
@@ -1,13 +1,11 @@
const { processString } = require("@budibase/string-templates")
-const CouchDB = require("../../db")
-const { generateQueryID, getQueryParams } = require("../../db/utils")
-const { BaseQueryVerbs } = require("../../constants")
-const env = require("../../environment")
-const { Thread, ThreadType } = require("../../threads")
-
-const fetch = require("node-fetch")
-const Joi = require("joi")
-const { save: saveDatasource } = require("./datasource")
+const CouchDB = require("../../../db")
+const { generateQueryID, getQueryParams } = require("../../../db/utils")
+const { BaseQueryVerbs } = require("../../../constants")
+const env = require("../../../environment")
+const { Thread, ThreadType } = require("../../../threads")
+const { importQueries, getDatasourceInfo } = require("./import")
+const { save: saveDatasource } = require("../datasource")
const Runner = new Thread(ThreadType.QUERY, { timeoutMs: 10000 })
@@ -31,134 +29,43 @@ exports.fetch = async function (ctx) {
include_docs: true,
})
)
+
ctx.body = enrichQueries(body.rows.map(row => row.doc))
}
-// const query = {
-// datasourceId: "datasource_b9a474302a174d1295e4c273cd72bde9",
-// name: "available pets (import)",
-// parameters: [],
-// fields: {
-// headers: {},
-// queryString: "status=available",
-// path: "v2/pet/findByStatus",
-// },
-// queryVerb: "read",
-// transformer: "return data",
-// schema: {},
-// readable: true
-// }
+exports.import = async ctx => {
+ const body = ctx.request.body
+ const data = body.data
-function generateQueryValidation() {
- // prettier-ignore
- return Joi.object({
- _id: Joi.string(),
- _rev: Joi.string(),
- name: Joi.string().required(),
- fields: Joi.object().required(),
- datasourceId: Joi.string().required(),
- readable: Joi.boolean(),
- parameters: Joi.array().items(Joi.object({
- name: Joi.string(),
- default: Joi.string().allow(""),
- })),
- queryVerb: Joi.string().allow().required(),
- extra: Joi.object().optional(),
- schema: Joi.object({}).required().unknown(true),
- transformer: Joi.string().optional(),
- })
-}
-
-const verbs = {
- get: "read",
- post: "create",
- put: "update",
- patch: "patch",
- delete: "delete",
-}
-
-const constructQuery = (datasource, swagger, path, method, config) => {
- const query = {
- datasourceId: datasource._id,
- }
- query.name = config.operationId || path
- query.parameters = []
- query.fields = {
- headers: {},
- // queryString: "status=available",
- path: path,
- }
- query.transformer = "return data"
- query.schema = {}
- query.readable = true
- query.queryVerb = verbs[method]
-
- return query
-}
-
-// {
-// "type": "url",
-// "data": "www.url.com/swagger.json"
-// }
-
-exports.import = async function (ctx) {
- const importConfig = ctx.request.body
-
- let data
-
- if (importConfig.type === "url") {
- data = await fetch(importConfig.data).then(res => res.json())
- } else if (importConfig.type === "raw") {
- data = JSON.parse(importConfig.data)
- } else {
- throw new Error("Invalid data type")
- }
-
- const db = new CouchDB(ctx.appId)
- const schema = generateQueryValidation()
-
- // create datasource
- const scheme = data.schemes.includes("https") ? "https" : "http"
- const url = `${scheme}://${data.host}${data.basePath}`
- const name = data.info.title
-
- // TODO: Refactor datasource creation into shared function
- const datasourceCtx = {
- ...ctx,
- }
- datasourceCtx.request.body.datasource = {
- type: "datasource",
- source: "REST",
- config: {
- url: url,
- defaultHeaders: {},
- },
- name: name,
- }
- await saveDatasource(datasourceCtx)
- const datasource = datasourceCtx.body.datasource
-
- // create query
-
- for (const [path, method] of Object.entries(data.paths)) {
- for (const [methodName, config] of Object.entries(method)) {
- const query = constructQuery(datasource, data, path, methodName, config)
-
- // validate query
- const { error } = schema.validate(query)
- if (error) {
- ctx.throw(400, `Invalid - ${error.message}`)
- return
- }
-
- // persist query
- query._id = generateQueryID(query.datasourceId)
- await db.put(query)
+ let datasourceId
+ if (!body.datasourceId) {
+ // construct new datasource
+ const info = getDatasourceInfo(data)
+ let datasource = {
+ type: "datasource",
+ source: "REST",
+ config: {
+ url: info.url,
+ defaultHeaders: info.defaultHeaders,
+ },
+ name: info.name,
}
+ // save the datasource
+ const datasourceCtx = { ...ctx }
+ datasourceCtx.request.body.datasource = datasource
+ await saveDatasource(datasourceCtx)
+ datasourceId = datasourceCtx.body.datasource._id
+ } else {
+ // use existing datasource
+ datasourceId = body.datasourceId
}
- // return the datasource
- ctx.body = { datasource }
+ const importResult = await importQueries(ctx.appId, datasourceId, data)
+
+ ctx.body = {
+ ...importResult,
+ datasourceId,
+ }
ctx.status = 200
}
diff --git a/packages/server/src/api/controllers/query/validation.js b/packages/server/src/api/controllers/query/validation.js
new file mode 100644
index 0000000000..2613e6806a
--- /dev/null
+++ b/packages/server/src/api/controllers/query/validation.js
@@ -0,0 +1,40 @@
+const joiValidator = require("../../../middleware/joi-validator")
+const Joi = require("joi")
+
+exports.queryValidation = () => {
+ return Joi.object({
+ _id: Joi.string(),
+ _rev: Joi.string(),
+ name: Joi.string().required(),
+ fields: Joi.object().required(),
+ datasourceId: Joi.string().required(),
+ readable: Joi.boolean(),
+ parameters: Joi.array().items(
+ Joi.object({
+ name: Joi.string(),
+ default: Joi.string().allow(""),
+ })
+ ),
+ queryVerb: Joi.string().allow().required(),
+ extra: Joi.object().optional(),
+ schema: Joi.object({}).required().unknown(true),
+ transformer: Joi.string().optional(),
+ })
+}
+
+exports.generateQueryValidation = () => {
+ // prettier-ignore
+ return joiValidator.body(exports.queryValidation())
+}
+
+exports.generateQueryPreviewValidation = () => {
+ // prettier-ignore
+ return joiValidator.body(Joi.object({
+ fields: Joi.object().required(),
+ queryVerb: Joi.string().allow().required(),
+ extra: Joi.object().optional(),
+ datasourceId: Joi.string().required(),
+ transformer: Joi.string().optional(),
+ parameters: Joi.object({}).required().unknown(true)
+ }))
+}
diff --git a/packages/server/src/api/routes/query.js b/packages/server/src/api/routes/query.js
index bc1c2204de..4a3cfeeb97 100644
--- a/packages/server/src/api/routes/query.js
+++ b/packages/server/src/api/routes/query.js
@@ -1,53 +1,23 @@
const Router = require("@koa/router")
const queryController = require("../controllers/query")
const authorized = require("../../middleware/authorized")
-const Joi = require("joi")
const {
PermissionLevels,
PermissionTypes,
BUILDER,
} = require("@budibase/auth/permissions")
-const joiValidator = require("../../middleware/joi-validator")
const {
bodyResource,
bodySubResource,
paramResource,
} = require("../../middleware/resourceId")
+const {
+ generateQueryPreviewValidation,
+ generateQueryValidation,
+} = require("../controllers/query/validation")
const router = Router()
-function generateQueryValidation() {
- // prettier-ignore
- return joiValidator.body(Joi.object({
- _id: Joi.string(),
- _rev: Joi.string(),
- name: Joi.string().required(),
- fields: Joi.object().required(),
- datasourceId: Joi.string().required(),
- readable: Joi.boolean(),
- parameters: Joi.array().items(Joi.object({
- name: Joi.string(),
- default: Joi.string().allow(""),
- })),
- queryVerb: Joi.string().allow().required(),
- extra: Joi.object().optional(),
- schema: Joi.object({}).required().unknown(true),
- transformer: Joi.string().optional(),
- }))
-}
-
-function generateQueryPreviewValidation() {
- // prettier-ignore
- return joiValidator.body(Joi.object({
- fields: Joi.object().required(),
- queryVerb: Joi.string().allow().required(),
- extra: Joi.object().optional(),
- datasourceId: Joi.string().required(),
- transformer: Joi.string().optional(),
- parameters: Joi.object({}).required().unknown(true)
- }))
-}
-
router
.get("/api/queries", authorized(BUILDER), queryController.fetch)
.post(
@@ -57,11 +27,7 @@ router
generateQueryValidation(),
queryController.save
)
- .post(
- "/api/queries/import/swagger2",
- authorized(BUILDER),
- queryController.import
- )
+ .post("/api/queries/import", authorized(BUILDER), queryController.import)
.post(
"/api/queries/preview",
bodyResource("datasourceId"),
diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock
index f609651afa..3ef43963ef 100644
--- a/packages/server/yarn.lock
+++ b/packages/server/yarn.lock
@@ -951,6 +951,30 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
+"@budibase/auth@^0.9.185-alpha.21":
+ version "0.9.189"
+ resolved "https://registry.yarnpkg.com/@budibase/auth/-/auth-0.9.189.tgz#60d2b1ead017aa5a32f58ffd6f155a042c73dd2b"
+ integrity sha512-dKB6J8bEW7vFWLErd7q4eYO6pBwCg28GemkY3w40EFE+l+hPp/8Y8kRvsnoPIXkViKIr/6/oW3XOh3g+OUW/RQ==
+ dependencies:
+ "@techpass/passport-openidconnect" "^0.3.0"
+ aws-sdk "^2.901.0"
+ bcryptjs "^2.4.3"
+ cls-hooked "^4.2.2"
+ ioredis "^4.27.1"
+ jsonwebtoken "^8.5.1"
+ koa-passport "^4.1.4"
+ lodash "^4.17.21"
+ lodash.isarguments "^3.1.0"
+ node-fetch "^2.6.1"
+ passport-google-auth "^1.0.2"
+ passport-google-oauth "^2.0.0"
+ passport-jwt "^4.0.0"
+ passport-local "^1.0.0"
+ sanitize-s3-objectkey "^0.0.1"
+ tar-fs "^2.1.1"
+ uuid "^8.3.2"
+ zlib "^1.0.5"
+
"@budibase/bbui@^0.9.139":
version "0.9.187"
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.187.tgz#84f0a37301cfa41f50eaa335243ac08923d9e34f"
@@ -1000,6 +1024,94 @@
svelte-flatpickr "^3.2.3"
svelte-portal "^1.0.0"
+"@budibase/bbui@^0.9.189":
+ version "0.9.189"
+ resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.189.tgz#d5802e9b6aabccdef4205f0edfa7ed5616ac1aff"
+ integrity sha512-YqM21mtrg8yTN9mqG4CnFfvoOelmhy3V69LyoITdQT6aGiwt/efHzknSlaUH3/0yLH9MuzwkHDzUmbe7QrsqEA==
+ dependencies:
+ "@adobe/spectrum-css-workflow-icons" "^1.2.1"
+ "@spectrum-css/actionbutton" "^1.0.1"
+ "@spectrum-css/actiongroup" "^1.0.1"
+ "@spectrum-css/avatar" "^3.0.2"
+ "@spectrum-css/button" "^3.0.1"
+ "@spectrum-css/buttongroup" "^3.0.2"
+ "@spectrum-css/checkbox" "^3.0.2"
+ "@spectrum-css/dialog" "^3.0.1"
+ "@spectrum-css/divider" "^1.0.3"
+ "@spectrum-css/dropzone" "^3.0.2"
+ "@spectrum-css/fieldgroup" "^3.0.2"
+ "@spectrum-css/fieldlabel" "^3.0.1"
+ "@spectrum-css/icon" "^3.0.1"
+ "@spectrum-css/illustratedmessage" "^3.0.2"
+ "@spectrum-css/inputgroup" "^3.0.2"
+ "@spectrum-css/label" "^2.0.10"
+ "@spectrum-css/link" "^3.1.1"
+ "@spectrum-css/menu" "^3.0.1"
+ "@spectrum-css/modal" "^3.0.1"
+ "@spectrum-css/pagination" "^3.0.3"
+ "@spectrum-css/picker" "^1.0.1"
+ "@spectrum-css/popover" "^3.0.1"
+ "@spectrum-css/progressbar" "^1.0.2"
+ "@spectrum-css/progresscircle" "^1.0.2"
+ "@spectrum-css/radio" "^3.0.2"
+ "@spectrum-css/search" "^3.0.2"
+ "@spectrum-css/sidenav" "^3.0.2"
+ "@spectrum-css/statuslight" "^3.0.2"
+ "@spectrum-css/stepper" "^3.0.3"
+ "@spectrum-css/switch" "^1.0.2"
+ "@spectrum-css/table" "^3.0.1"
+ "@spectrum-css/tabs" "^3.0.1"
+ "@spectrum-css/tags" "^3.0.2"
+ "@spectrum-css/textfield" "^3.0.1"
+ "@spectrum-css/toast" "^3.0.1"
+ "@spectrum-css/tooltip" "^3.0.3"
+ "@spectrum-css/treeview" "^3.0.2"
+ "@spectrum-css/typography" "^3.0.1"
+ "@spectrum-css/underlay" "^2.0.9"
+ "@spectrum-css/vars" "^3.0.1"
+ dayjs "^1.10.4"
+ svelte-flatpickr "^3.2.3"
+ svelte-portal "^1.0.0"
+
+"@budibase/client@^0.9.185-alpha.21":
+ version "0.9.189"
+ resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.9.189.tgz#8f96b607f36bbb7390fd53b04360851f0c12aaac"
+ integrity sha512-L2i3CaQt4aFL7JKkRrEWWx8NemHTEOKLXvXq7LGM4u3GlcFIIkcL113EkXQT1bIZcf6AuuC2CfNsmZKioOPh2A==
+ dependencies:
+ "@budibase/bbui" "^0.9.189"
+ "@budibase/standard-components" "^0.9.139"
+ "@budibase/string-templates" "^0.9.189"
+ regexparam "^1.3.0"
+ shortid "^2.2.15"
+ svelte-spa-router "^3.0.5"
+
+"@budibase/handlebars-helpers@^0.11.7":
+ version "0.11.7"
+ resolved "https://registry.yarnpkg.com/@budibase/handlebars-helpers/-/handlebars-helpers-0.11.7.tgz#8e5f9843d7dd10503e9f608555a96ccf4d836c46"
+ integrity sha512-PvGHAv22cWSFExs1kc0WglwsmCEUEOqWvSp6JCFZwtc3qAAr5yMfLK8WGVQ63ALvyzWZiyxF+yrlzeeaohCMJw==
+ dependencies:
+ array-sort "^1.0.0"
+ define-property "^2.0.2"
+ extend-shallow "^3.0.2"
+ for-in "^1.0.2"
+ get-object "^0.2.0"
+ get-value "^3.0.1"
+ handlebars "^4.7.7"
+ handlebars-utils "^1.0.6"
+ has-value "^2.0.2"
+ helper-date "^1.0.1"
+ helper-markdown "^1.0.0"
+ helper-md "^0.2.2"
+ html-tag "^2.0.0"
+ is-even "^1.0.0"
+ is-glob "^4.0.1"
+ kind-of "^6.0.3"
+ micromatch "^3.1.5"
+ relative "^3.0.2"
+ striptags "^3.1.1"
+ to-gfm-code-block "^0.1.1"
+ year "^0.2.1"
+
"@budibase/standard-components@^0.9.139":
version "0.9.139"
resolved "https://registry.yarnpkg.com/@budibase/standard-components/-/standard-components-0.9.139.tgz#cf8e2b759ae863e469e50272b3ca87f2827e66e3"
@@ -1018,6 +1130,18 @@
svelte-apexcharts "^1.0.2"
svelte-flatpickr "^3.1.0"
+"@budibase/string-templates@^0.9.185-alpha.21", "@budibase/string-templates@^0.9.189":
+ version "0.9.189"
+ resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-0.9.189.tgz#515a4ce85da550ce19d78c4c592ab5839a8ebe3a"
+ integrity sha512-JmnpuPx1CItNIFCMUxBz+4DVpYu96QxteU2Vi17pjWb0B7qsWwHkmcMmYbd+iTW4oxgOufbP8slfyfbu2XhbzA==
+ dependencies:
+ "@budibase/handlebars-helpers" "^0.11.7"
+ dayjs "^1.10.4"
+ handlebars "^4.7.6"
+ handlebars-utils "^1.0.6"
+ lodash "^4.17.20"
+ vm2 "^3.9.4"
+
"@bull-board/api@3.7.0", "@bull-board/api@^3.7.0":
version "3.7.0"
resolved "https://registry.yarnpkg.com/@bull-board/api/-/api-3.7.0.tgz#231f687187c0cb34e0b97f463917b6aaeb4ef6af"
@@ -2053,6 +2177,17 @@
dependencies:
defer-to-connect "^1.0.1"
+"@techpass/passport-openidconnect@^0.3.0":
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/@techpass/passport-openidconnect/-/passport-openidconnect-0.3.2.tgz#f8fd5d97256286665dbf26dac92431f977ab1e63"
+ integrity sha512-fnCtEiexXSHA029B//hJcCJlLJrT3lhpNCyA0rnz58Qttz0BLGCVv6yMT8HmOnGThH6vcDOVwdgKM3kbCQtEhw==
+ dependencies:
+ base64url "^3.0.1"
+ oauth "^0.9.15"
+ passport-strategy "^1.0.0"
+ request "^2.88.0"
+ webfinger "^0.4.2"
+
"@tootallnate/once@1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
@@ -2347,6 +2482,11 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
+"@types/swagger-schema-official@^2.0.22":
+ version "2.0.22"
+ resolved "https://registry.yarnpkg.com/@types/swagger-schema-official/-/swagger-schema-official-2.0.22.tgz#f7e06168e6994574dfd86928ac04b196870ab043"
+ integrity sha512-7yQiX6MWSFSvc/1wW5smJMZTZ4fHOd+hqLr3qr/HONDxHEa2bnYAsOcGBOEqFIjd4yetwMOdEDdeW+udRAQnHA==
+
"@types/yargs-parser@*":
version "20.2.1"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129"
@@ -2695,7 +2835,7 @@ arg@^4.1.0:
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
-argparse@^1.0.7:
+argparse@^1.0.10, argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
@@ -2737,6 +2877,15 @@ array-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
+array-sort@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a"
+ integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==
+ dependencies:
+ default-compare "^1.0.0"
+ get-value "^2.0.6"
+ kind-of "^5.0.2"
+
array-union@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
@@ -2779,6 +2928,13 @@ astral-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
+async-hook-jl@^1.7.6:
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/async-hook-jl/-/async-hook-jl-1.7.6.tgz#4fd25c2f864dbaf279c610d73bf97b1b28595e68"
+ integrity sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==
+ dependencies:
+ stack-chain "^1.3.7"
+
async-limiter@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
@@ -2796,6 +2952,13 @@ async@^2.6.3:
dependencies:
lodash "^4.17.14"
+async@~2.1.4:
+ version "2.1.5"
+ resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc"
+ integrity sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw=
+ dependencies:
+ lodash "^4.14.0"
+
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -2811,6 +2974,13 @@ atomic-sleep@^1.0.0:
resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b"
integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==
+autolinker@~0.28.0:
+ version "0.28.1"
+ resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-0.28.1.tgz#0652b491881879f0775dace0cdca3233942a4e47"
+ integrity sha1-BlK0kYgYefB3XazgzcoyM5QqTkc=
+ dependencies:
+ gulp-header "^1.7.1"
+
aws-sdk@^2.767.0:
version "2.1030.0"
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1030.0.tgz#24a856af3d2b8b37c14a8f59974993661c66fd82"
@@ -2826,6 +2996,21 @@ aws-sdk@^2.767.0:
uuid "3.3.2"
xml2js "0.4.19"
+aws-sdk@^2.901.0:
+ version "2.1037.0"
+ resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1037.0.tgz#f397aea0aa2b7a862be89240e68c8138c959fb3c"
+ integrity sha512-z1IfFFvKg1ZKikyExhLeiax0jIe/YwFrBjIUhcPjBfh+c4otvuqp9RBp2iyXt3GamhEkKoPyvd6a5K7IGsTBMw==
+ dependencies:
+ buffer "4.9.2"
+ events "1.1.1"
+ ieee754 "1.1.13"
+ jmespath "0.15.0"
+ querystring "0.2.0"
+ sax "1.2.1"
+ url "0.10.3"
+ uuid "3.3.2"
+ xml2js "0.4.19"
+
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
@@ -3008,6 +3193,11 @@ base64-js@^1.0.2, base64-js@^1.3.1:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
+base64url@3.x.x, base64url@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
+ integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==
+
base@^0.11.1:
version "0.11.2"
resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
@@ -3028,7 +3218,7 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
-bcryptjs@2.4.3:
+bcryptjs@2.4.3, bcryptjs@^2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
@@ -3068,6 +3258,15 @@ bl@^3.0.0:
dependencies:
readable-stream "^3.0.1"
+bl@^4.0.3:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
+ integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
+ dependencies:
+ buffer "^5.5.0"
+ inherits "^2.0.4"
+ readable-stream "^3.4.0"
+
bluebird@^3.5.1, bluebird@^3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
@@ -3405,6 +3604,11 @@ chokidar@^3.5.2:
optionalDependencies:
fsevents "~2.3.2"
+chownr@^1.1.1:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
+ integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
+
ci-info@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
@@ -3477,6 +3681,15 @@ clone-response@1.0.2, clone-response@^1.0.2:
dependencies:
mimic-response "^1.0.0"
+cls-hooked@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
+ integrity sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==
+ dependencies:
+ async-hook-jl "^1.7.6"
+ emitter-listener "^1.0.1"
+ semver "^5.4.1"
+
cluster-key-slot@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
@@ -3593,6 +3806,13 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
+concat-with-sourcemaps@*:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz#d4ea93f05ae25790951b99e7b3b09e3908a4082e"
+ integrity sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==
+ dependencies:
+ source-map "^0.6.1"
+
condense-newlines@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f"
@@ -3826,6 +4046,13 @@ date-utils@*:
resolved "https://registry.yarnpkg.com/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64"
integrity sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=
+date.js@^0.3.1:
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/date.js/-/date.js-0.3.3.tgz#ef1e92332f507a638795dbb985e951882e50bbda"
+ integrity sha512-HgigOS3h3k6HnW011nAb43c5xx5rBXk8P2v/WIT9Zv4koIaVXiH2BURguI78VVp+5Qc076T7OR378JViCnZtBw==
+ dependencies:
+ debug "~3.1.0"
+
dateformat@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
@@ -3969,6 +4196,13 @@ deepmerge@^4.2.2:
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
+default-compare@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f"
+ integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==
+ dependencies:
+ kind-of "^5.0.2"
+
default-shell@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/default-shell/-/default-shell-1.0.1.tgz#752304bddc6174f49eb29cb988feea0b8813c8bc"
@@ -4228,6 +4462,13 @@ electron-to-chromium@^1.3.896:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.900.tgz#5be2c5818a2a012c511b4b43e87b6ab7a296d4f5"
integrity sha512-SuXbQD8D4EjsaBaJJxySHbC+zq8JrFfxtb4GIr4E9n1BcROyMcRrJCYQNpJ9N+Wjf5mFp7Wp0OHykd14JNEzzQ==
+emitter-listener@^1.0.1:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8"
+ integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==
+ dependencies:
+ shimmer "^1.2.0"
+
emittery@^0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860"
@@ -4258,7 +4499,7 @@ encoding-down@^6.3.0:
level-codec "^9.0.0"
level-errors "^2.0.0"
-end-of-stream@^1.0.0, end-of-stream@^1.1.0:
+end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@@ -4272,6 +4513,11 @@ end-stream@~0.1.0:
dependencies:
write-stream "~0.4.3"
+ent@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
+ integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0=
+
errno@~0.1.1, errno@~0.1.7:
version "0.1.8"
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"
@@ -5031,6 +5277,11 @@ fs-constants@^1.0.0:
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
+fs-exists-sync@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
+ integrity sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=
+
fs-extra@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
@@ -5094,6 +5345,14 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.1"
+get-object@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/get-object/-/get-object-0.2.0.tgz#d92ff7d5190c64530cda0543dac63a3d47fe8c0c"
+ integrity sha1-2S/31RkMZFMM2gVD2sY6PUf+jAw=
+ dependencies:
+ is-number "^2.0.2"
+ isobject "^0.2.0"
+
get-package-type@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
@@ -5156,6 +5415,13 @@ get-value@^2.0.3, get-value@^2.0.6:
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
+get-value@^3.0.0, get-value@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/get-value/-/get-value-3.0.1.tgz#5efd2a157f1d6a516d7524e124ac52d0a39ef5a8"
+ integrity sha512-mKZj9JLQrwMBtj5wxi6MH8Z5eSKaERpAwjg43dPtlGI1ZVEgH/qC7T8/6R2OBSUA+zzHBZgICsVJaEIV2tKTDA==
+ dependencies:
+ isobject "^3.0.1"
+
getopts@2.2.5:
version "2.2.5"
resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.5.tgz#67a0fe471cacb9c687d817cab6450b96dde8313b"
@@ -5245,6 +5511,32 @@ globby@^11.0.3:
merge2 "^1.3.0"
slash "^3.0.0"
+google-auth-library@~0.10.0:
+ version "0.10.0"
+ resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-0.10.0.tgz#6e15babee85fd1dd14d8d128a295b6838d52136e"
+ integrity sha1-bhW6vuhf0d0U2NEoopW2g41SE24=
+ dependencies:
+ gtoken "^1.2.1"
+ jws "^3.1.4"
+ lodash.noop "^3.0.1"
+ request "^2.74.0"
+
+google-p12-pem@^0.1.0:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-0.1.2.tgz#33c46ab021aa734fa0332b3960a9a3ffcb2f3177"
+ integrity sha1-M8RqsCGqc0+gMys5YKmj/8svMXc=
+ dependencies:
+ node-forge "^0.7.1"
+
+googleapis@^16.0.0:
+ version "16.1.0"
+ resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-16.1.0.tgz#0f19f2d70572d918881a0f626e3b1a2fa8629576"
+ integrity sha1-Dxny1wVy2RiIGg9ibjsaL6hilXY=
+ dependencies:
+ async "~2.1.4"
+ google-auth-library "~0.10.0"
+ string-template "~1.0.0"
+
got@^8.3.1:
version "8.3.2"
resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937"
@@ -5290,6 +5582,45 @@ graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
+gtoken@^1.2.1:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-1.2.3.tgz#5509571b8afd4322e124cf66cf68115284c476d8"
+ integrity sha512-wQAJflfoqSgMWrSBk9Fg86q+sd6s7y6uJhIvvIPz++RElGlMtEqsdAR2oWwZ/WTEtp7P9xFbJRrT976oRgzJ/w==
+ dependencies:
+ google-p12-pem "^0.1.0"
+ jws "^3.0.0"
+ mime "^1.4.1"
+ request "^2.72.0"
+
+gulp-header@^1.7.1:
+ version "1.8.12"
+ resolved "https://registry.yarnpkg.com/gulp-header/-/gulp-header-1.8.12.tgz#ad306be0066599127281c4f8786660e705080a84"
+ integrity sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==
+ dependencies:
+ concat-with-sourcemaps "*"
+ lodash.template "^4.4.0"
+ through2 "^2.0.0"
+
+handlebars-utils@^1.0.2, handlebars-utils@^1.0.4, handlebars-utils@^1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/handlebars-utils/-/handlebars-utils-1.0.6.tgz#cb9db43362479054782d86ffe10f47abc76357f9"
+ integrity sha512-d5mmoQXdeEqSKMtQQZ9WkiUcO1E3tPbWxluCK9hVgIDPzQa9WsKo3Lbe/sGflTe7TomHEeZaOgwIkyIr1kfzkw==
+ dependencies:
+ kind-of "^6.0.0"
+ typeof-article "^0.1.1"
+
+handlebars@^4.7.6, handlebars@^4.7.7:
+ version "4.7.7"
+ resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
+ integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
+ dependencies:
+ minimist "^1.2.5"
+ neo-async "^2.6.0"
+ source-map "^0.6.1"
+ wordwrap "^1.0.0"
+ optionalDependencies:
+ uglify-js "^3.1.4"
+
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
@@ -5360,6 +5691,14 @@ has-value@^1.0.0:
has-values "^1.0.0"
isobject "^3.0.0"
+has-value@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/has-value/-/has-value-2.0.2.tgz#d0f12e8780ba8e90e66ad1a21c707fdb67c25658"
+ integrity sha512-ybKOlcRsK2MqrM3Hmz/lQxXHZ6ejzSPzpNabKB45jb5qDgJvKPa3SdapTsTLwEb9WltgWpOmNax7i+DzNOk4TA==
+ dependencies:
+ get-value "^3.0.0"
+ has-values "^2.0.1"
+
has-values@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771"
@@ -5373,6 +5712,13 @@ has-values@^1.0.0:
is-number "^3.0.0"
kind-of "^4.0.0"
+has-values@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/has-values/-/has-values-2.0.1.tgz#3876200ff86d8a8546a9264a952c17d5fc17579d"
+ integrity sha512-+QdH3jOmq9P8GfdjFg0eJudqx1FqU62NQJ4P16rOEHeRdl7ckgwn6uqQjzYE0ZoHVV/e5E2esuJ5Gl5+HUW19w==
+ dependencies:
+ kind-of "^6.0.2"
+
has-yarn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77"
@@ -5385,6 +5731,39 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
+helper-date@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/helper-date/-/helper-date-1.0.1.tgz#12fedea3ad8e44a7ca4c4efb0ff4104a5120cffb"
+ integrity sha512-wU3VOwwTJvGr/w5rZr3cprPHO+hIhlblTJHD6aFBrKLuNbf4lAmkawd2iK3c6NbJEvY7HAmDpqjOFSI5/+Ey2w==
+ dependencies:
+ date.js "^0.3.1"
+ handlebars-utils "^1.0.4"
+ moment "^2.18.1"
+
+helper-markdown@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/helper-markdown/-/helper-markdown-1.0.0.tgz#ee7e9fc554675007d37eb90f7853b13ce74f3e10"
+ integrity sha512-AnDqMS4ejkQK0MXze7pA9TM3pu01ZY+XXsES6gEE0RmCGk5/NIfvTn0NmItfyDOjRAzyo9z6X7YHbHX4PzIvOA==
+ dependencies:
+ handlebars-utils "^1.0.2"
+ highlight.js "^9.12.0"
+ remarkable "^1.7.1"
+
+helper-md@^0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/helper-md/-/helper-md-0.2.2.tgz#c1f59d7e55bbae23362fd8a0e971607aec69d41f"
+ integrity sha1-wfWdflW7riM2L9ig6XFgeuxp1B8=
+ dependencies:
+ ent "^2.2.0"
+ extend-shallow "^2.0.1"
+ fs-exists-sync "^0.1.0"
+ remarkable "^1.6.2"
+
+highlight.js@^9.12.0:
+ version "9.18.5"
+ resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825"
+ integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==
+
hosted-git-info@^2.1.4:
version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
@@ -5414,6 +5793,14 @@ html-escaper@^2.0.0:
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
+html-tag@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/html-tag/-/html-tag-2.0.0.tgz#36c3bc8d816fd30b570d5764a497a641640c2fed"
+ integrity sha512-XxzooSo6oBoxBEUazgjdXj7VwTn/iSTSZzTYKzYY6I916tkaYzypHxy+pbVU1h+0UQ9JlVf5XkNQyxOAiiQO1g==
+ dependencies:
+ is-self-closing "^1.0.1"
+ kind-of "^6.0.0"
+
http-assert@^1.3.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f"
@@ -5677,6 +6064,23 @@ ioredis@^4.27.0:
redis-parser "^3.0.0"
standard-as-callback "^2.1.0"
+ioredis@^4.27.1:
+ version "4.28.1"
+ resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.1.tgz#c2a7038d6a187e020d7045e11d6a677e8b51f785"
+ integrity sha512-7gcrUJEcPHWy+eEyq6wIZpXtfHt8crhbc5+z0sqrnHUkwBblXinygfamj+/jx83Qo+2LW3q87Nj2VsuH6BF2BA==
+ dependencies:
+ cluster-key-slot "^1.1.0"
+ debug "^4.3.1"
+ denque "^1.1.0"
+ lodash.defaults "^4.2.0"
+ lodash.flatten "^4.4.0"
+ lodash.isarguments "^3.1.0"
+ p-map "^2.1.0"
+ redis-commands "1.7.0"
+ redis-errors "^1.2.0"
+ redis-parser "^3.0.0"
+ standard-as-callback "^2.1.0"
+
ip-regex@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
@@ -5796,6 +6200,13 @@ is-docker@^2.0.0:
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
+is-even@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-even/-/is-even-1.0.0.tgz#76b5055fbad8d294a86b6a949015e1c97b717c06"
+ integrity sha1-drUFX7rY0pSoa2qUkBXhyXtxfAY=
+ dependencies:
+ is-odd "^0.1.2"
+
is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
@@ -5885,6 +6296,13 @@ is-number-object@^1.0.4:
dependencies:
has-tostringtag "^1.0.0"
+is-number@^2.0.2:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
+ integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=
+ dependencies:
+ kind-of "^3.0.2"
+
is-number@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
@@ -5907,6 +6325,13 @@ is-object@^1.0.1:
resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf"
integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==
+is-odd@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-0.1.2.tgz#bc573b5ce371ef2aad6e6f49799b72bef13978a7"
+ integrity sha1-vFc7XONx7yqtbm9JeZtyvvE5eKc=
+ dependencies:
+ is-number "^3.0.0"
+
is-path-inside@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
@@ -5952,6 +6377,13 @@ is-retry-allowed@^2.2.0:
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz#88f34cbd236e043e71b6932d09b0c65fb7b4d71d"
integrity sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==
+is-self-closing@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-self-closing/-/is-self-closing-1.0.1.tgz#5f406b527c7b12610176320338af0fa3896416e4"
+ integrity sha512-E+60FomW7Blv5GXTlYee2KDrnG6srxF7Xt1SjrhWUGUEsTFIqY/nq2y3DaftCsgUMdh89V07IVfhY9KIJhLezg==
+ dependencies:
+ self-closing-tags "^1.0.1"
+
is-shared-array-buffer@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
@@ -6044,6 +6476,11 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
+isobject@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/isobject/-/isobject-0.2.0.tgz#a3432192f39b910b5f02cc989487836ec70aa85e"
+ integrity sha1-o0MhkvObkQtfAsyYlIeDbscKqF4=
+
isobject@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
@@ -7064,6 +7501,22 @@ jsonschema@1.4.0:
resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2"
integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==
+jsonwebtoken@^8.2.0, jsonwebtoken@^8.5.1:
+ version "8.5.1"
+ resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
+ integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
+ dependencies:
+ jws "^3.2.2"
+ lodash.includes "^4.3.0"
+ lodash.isboolean "^3.0.3"
+ lodash.isinteger "^4.0.4"
+ lodash.isnumber "^3.0.3"
+ lodash.isplainobject "^4.0.6"
+ lodash.isstring "^4.0.1"
+ lodash.once "^4.0.0"
+ ms "^2.1.1"
+ semver "^5.6.0"
+
jsprim@^1.2.2:
version "1.4.0"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918"
@@ -7103,7 +7556,7 @@ jwa@^1.4.1:
ecdsa-sig-formatter "1.0.11"
safe-buffer "^5.0.1"
-jws@3.x.x:
+jws@3.x.x, jws@^3.0.0, jws@^3.1.4, jws@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
@@ -7130,7 +7583,7 @@ keyv@3.0.0, keyv@^3.0.0:
dependencies:
json-buffer "3.0.0"
-kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
+kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.1.0, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=
@@ -7144,12 +7597,12 @@ kind-of@^4.0.0:
dependencies:
is-buffer "^1.1.5"
-kind-of@^5.0.0:
+kind-of@^5.0.0, kind-of@^5.0.2:
version "5.1.0"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d"
integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==
-kind-of@^6.0.0, kind-of@^6.0.2:
+kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
@@ -7244,6 +7697,13 @@ koa-mount@^4.0.0:
debug "^4.0.1"
koa-compose "^4.1.0"
+koa-passport@^4.1.4:
+ version "4.1.4"
+ resolved "https://registry.yarnpkg.com/koa-passport/-/koa-passport-4.1.4.tgz#5f1665c1c2a37ace79af9f970b770885ca30ccfa"
+ integrity sha512-dJBCkl4X+zdYxbI2V2OtoGy0PUenpvp2ZLLWObc8UJhsId0iQpTFT8RVcuA0709AL2txGwRHnSPoT1bYNGa6Kg==
+ dependencies:
+ passport "^0.4.0"
+
koa-pino-logger@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/koa-pino-logger/-/koa-pino-logger-3.0.0.tgz#27600b4f3639e8767dfc6b66493109c5457f53ba"
@@ -7560,6 +8020,11 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
+lodash._reinterpolate@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
+ integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
+
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
@@ -7575,16 +8040,46 @@ lodash.flatten@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
+lodash.includes@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
+ integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
+
lodash.isarguments@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=
+lodash.isboolean@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
+ integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
+
lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
+lodash.isinteger@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
+ integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
+
+lodash.isnumber@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
+ integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
+
+lodash.isplainobject@^4.0.6:
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
+ integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
+
+lodash.isstring@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
+ integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
+
lodash.keys@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-4.2.0.tgz#a08602ac12e4fb83f91fc1fb7a360a4d9ba35205"
@@ -7600,11 +8095,21 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
+lodash.noop@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-3.0.1.tgz#38188f4d650a3a474258439b96ec45b32617133c"
+ integrity sha1-OBiPTWUKOkdCWEObluxFsyYXEzw=
+
lodash.omit@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=
+lodash.once@^4.0.0:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
+ integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
+
lodash.pick@^4.0.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
@@ -7615,6 +8120,21 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
+lodash.template@^4.4.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
+ integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==
+ dependencies:
+ lodash._reinterpolate "^3.0.0"
+ lodash.templatesettings "^4.0.0"
+
+lodash.templatesettings@^4.0.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33"
+ integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==
+ dependencies:
+ lodash._reinterpolate "^3.0.0"
+
lodash.without@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac"
@@ -7625,7 +8145,7 @@ lodash.xor@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.xor/-/lodash.xor-4.5.0.tgz#4d48ed7e98095b0632582ba714d3ff8ae8fb1db6"
integrity sha1-TUjtfpgJWwYyWCunFNP/iuj7HbY=
-lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.7.0:
+lodash@4.17.21, lodash@^4.14.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -7795,7 +8315,7 @@ methods@^1.0.1, methods@^1.1.1, methods@^1.1.2:
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
-micromatch@^3.1.10, micromatch@^3.1.4:
+micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.5:
version "3.1.10"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
@@ -7896,6 +8416,11 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
+mkdirp-classic@^0.5.2:
+ version "0.5.3"
+ resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
+ integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
+
mkdirp@^0.5.0, mkdirp@^0.5.1:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
@@ -7915,7 +8440,7 @@ moment-timezone@^0.5.31:
dependencies:
moment ">= 2.9.0"
-"moment@>= 2.9.0":
+"moment@>= 2.9.0", moment@^2.18.1:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
@@ -8015,6 +8540,11 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
+nanoid@^2.1.0:
+ version "2.1.11"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
+ integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
+
nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@@ -8062,6 +8592,11 @@ negotiator@0.6.2:
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
+neo-async@^2.6.0:
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
+ integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
+
nice-try@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
@@ -8084,6 +8619,11 @@ node-fetch@^2.6.1:
dependencies:
whatwg-url "^5.0.0"
+node-forge@^0.7.1:
+ version "0.7.6"
+ resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac"
+ integrity sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==
+
node-gyp-build@~4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb"
@@ -8202,6 +8742,11 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
+oauth@0.9.x, oauth@^0.9.15:
+ version "0.9.15"
+ resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"
+ integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE=
+
object-assign@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa"
@@ -8499,6 +9044,84 @@ pascalcase@^0.1.1:
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
+passport-google-auth@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/passport-google-auth/-/passport-google-auth-1.0.2.tgz#8b300b5aa442ef433de1d832ed3112877d0b2938"
+ integrity sha1-izALWqRC70M94dgy7TESh30LKTg=
+ dependencies:
+ googleapis "^16.0.0"
+ passport-strategy "1.x"
+
+passport-google-oauth1@1.x.x:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/passport-google-oauth1/-/passport-google-oauth1-1.0.0.tgz#af74a803df51ec646f66a44d82282be6f108e0cc"
+ integrity sha1-r3SoA99R7GRvZqRNgigr5vEI4Mw=
+ dependencies:
+ passport-oauth1 "1.x.x"
+
+passport-google-oauth20@2.x.x:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz#0d241b2d21ebd3dc7f2b60669ec4d587e3a674ef"
+ integrity sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==
+ dependencies:
+ passport-oauth2 "1.x.x"
+
+passport-google-oauth@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/passport-google-oauth/-/passport-google-oauth-2.0.0.tgz#f6eb4bc96dd6c16ec0ecfdf4e05ec48ca54d4dae"
+ integrity sha512-JKxZpBx6wBQXX1/a1s7VmdBgwOugohH+IxCy84aPTZNq/iIPX6u7Mqov1zY7MKRz3niFPol0KJz8zPLBoHKtYA==
+ dependencies:
+ passport-google-oauth1 "1.x.x"
+ passport-google-oauth20 "2.x.x"
+
+passport-jwt@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065"
+ integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==
+ dependencies:
+ jsonwebtoken "^8.2.0"
+ passport-strategy "^1.0.0"
+
+passport-local@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/passport-local/-/passport-local-1.0.0.tgz#1fe63268c92e75606626437e3b906662c15ba6ee"
+ integrity sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=
+ dependencies:
+ passport-strategy "1.x.x"
+
+passport-oauth1@1.x.x:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/passport-oauth1/-/passport-oauth1-1.2.0.tgz#5229d431781bf5b265bec86ce9a9cce58a756cf9"
+ integrity sha512-Sv2YWodC6jN12M/OXwmR4BIXeeIHjjbwYTQw4kS6tHK4zYzSEpxBgSJJnknBjICA5cj0ju3FSnG1XmHgIhYnLg==
+ dependencies:
+ oauth "0.9.x"
+ passport-strategy "1.x.x"
+ utils-merge "1.x.x"
+
+passport-oauth2@1.x.x:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.6.1.tgz#c5aee8f849ce8bd436c7f81d904a3cd1666f181b"
+ integrity sha512-ZbV43Hq9d/SBSYQ22GOiglFsjsD1YY/qdiptA+8ej+9C1dL1TVB+mBE5kDH/D4AJo50+2i8f4bx0vg4/yDDZCQ==
+ dependencies:
+ base64url "3.x.x"
+ oauth "0.9.x"
+ passport-strategy "1.x.x"
+ uid2 "0.0.x"
+ utils-merge "1.x.x"
+
+passport-strategy@1.x, passport-strategy@1.x.x, passport-strategy@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4"
+ integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=
+
+passport@^0.4.0:
+ version "0.4.1"
+ resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270"
+ integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==
+ dependencies:
+ passport-strategy "1.x.x"
+ pause "0.0.1"
+
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
@@ -8553,6 +9176,11 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
+pause@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d"
+ integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=
+
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
@@ -9249,7 +9877,7 @@ readable-stream@1.1.14, readable-stream@^1.0.27-1:
isarray "0.0.1"
string_decoder "~0.10.x"
-"readable-stream@2 || 3", readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
+"readable-stream@2 || 3", readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@@ -9383,6 +10011,16 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"
+regexparam@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-2.0.0.tgz#059476767d5f5f87f735fc7922d133fd1a118c8c"
+ integrity sha512-gJKwd2MVPWHAIFLsaYDZfyKzHNS4o7E/v8YmNf44vmeV2e4YfVoDToTOKTvE7ab68cRJ++kLuEXJBaEeJVt5ow==
+
+regexparam@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f"
+ integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==
+
regexpp@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
@@ -9426,6 +10064,21 @@ regjsparser@^0.7.0:
dependencies:
jsesc "~0.5.0"
+relative@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/relative/-/relative-3.0.2.tgz#0dcd8ec54a5d35a3c15e104503d65375b5a5367f"
+ integrity sha1-Dc2OxUpdNaPBXhBFA9ZTdbWlNn8=
+ dependencies:
+ isobject "^2.0.0"
+
+remarkable@^1.6.2, remarkable@^1.7.1:
+ version "1.7.4"
+ resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.4.tgz#19073cb960398c87a7d6546eaa5e50d2022fcd00"
+ integrity sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg==
+ dependencies:
+ argparse "^1.0.10"
+ autolinker "~0.28.0"
+
remove-trailing-separator@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
@@ -9462,7 +10115,7 @@ request-promise-native@^1.0.5:
stealthy-require "^1.1.1"
tough-cookie "^2.3.3"
-request@^2.87.0:
+request@^2.72.0, request@^2.74.0, request@^2.87.0, request@^2.88.0:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
@@ -9664,6 +10317,11 @@ sane@^4.0.3:
minimist "^1.1.1"
walker "~1.0.5"
+sanitize-s3-objectkey@^0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/sanitize-s3-objectkey/-/sanitize-s3-objectkey-0.0.1.tgz#efa9887cd45275b40234fb4bb12fc5754fe64e7e"
+ integrity sha512-ZTk7aqLxy4sD40GWcYWoLfbe05XLmkKvh6vGKe13ADlei24xlezcvjgKy1qRArlaIbIMYaqK7PCalvZtulZlaQ==
+
saslprep@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226"
@@ -9676,7 +10334,7 @@ sax@1.2.1:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o=
-sax@>=0.6.0, sax@^1.2.4:
+sax@>=0.1.1, sax@>=0.6.0, sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
@@ -9700,6 +10358,11 @@ seek-bzip@^1.0.5:
dependencies:
commander "^2.8.1"
+self-closing-tags@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/self-closing-tags/-/self-closing-tags-1.0.1.tgz#6c5fa497994bb826b484216916371accee490a5d"
+ integrity sha512-7t6hNbYMxM+VHXTgJmxwgZgLGktuXtVVD5AivWzNTdJBM4DBjnDKDzkf2SrNjihaArpeJYNjxkELBu1evI4lQA==
+
semver-diff@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
@@ -9707,7 +10370,7 @@ semver-diff@^3.1.1:
dependencies:
semver "^6.3.0"
-"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
+"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -9804,6 +10467,18 @@ shell-path@^2.1.0:
dependencies:
shell-env "^0.3.0"
+shimmer@^1.2.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
+ integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
+
+shortid@^2.2.15:
+ version "2.2.16"
+ resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.16.tgz#b742b8f0cb96406fd391c76bfc18a67a57fe5608"
+ integrity sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==
+ dependencies:
+ nanoid "^2.1.0"
+
side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
@@ -10053,6 +10728,11 @@ sshpk@^1.7.0:
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
+stack-chain@^1.3.7:
+ version "1.3.7"
+ resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
+ integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=
+
stack-utils@^1.0.1:
version "1.0.5"
resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.5.tgz#a19b0b01947e0029c8e451d5d61a498f5bb1471b"
@@ -10095,6 +10775,11 @@ stealthy-require@^1.1.1:
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
+step@0.0.x:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/step/-/step-0.0.6.tgz#143e7849a5d7d3f4a088fe29af94915216eeede2"
+ integrity sha1-FD54SaXX0/SgiP4pr5SRUhbu7eI=
+
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
@@ -10108,6 +10793,11 @@ string-length@^4.0.1:
char-regex "^1.0.2"
strip-ansi "^6.0.0"
+string-template@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96"
+ integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y=
+
string-width@^3.0.0, string-width@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
@@ -10233,6 +10923,11 @@ strip-outer@^1.0.0:
dependencies:
escape-string-regexp "^1.0.2"
+striptags@^3.1.1:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.2.0.tgz#cc74a137db2de8b0b9a370006334161f7dd67052"
+ integrity sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw==
+
sublevel-pouchdb@7.2.2:
version "7.2.2"
resolved "https://registry.yarnpkg.com/sublevel-pouchdb/-/sublevel-pouchdb-7.2.2.tgz#49e46cd37883bf7ff5006d7c5b9bcc7bcc1f422f"
@@ -10322,6 +11017,13 @@ svelte-portal@^1.0.0:
resolved "https://registry.yarnpkg.com/svelte-portal/-/svelte-portal-1.0.0.tgz#36a47c5578b1a4d9b4dc60fa32a904640ec4cdd3"
integrity sha512-nHf+DS/jZ6jjnZSleBMSaZua9JlG5rZv9lOGKgJuaZStfevtjIlUJrkLc3vbV8QdBvPPVmvcjTlazAzfKu0v3Q==
+svelte-spa-router@^3.0.5:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/svelte-spa-router/-/svelte-spa-router-3.2.0.tgz#fae3311d292451236cb57131262406cf312b15ee"
+ integrity sha512-igemo5Vs82TGBBw+DjWt6qKameXYzNs6aDXcTxou5XbEvOjiRcAM6MLkdVRCatn6u8r42dE99bt/br7T4qe/AQ==
+ dependencies:
+ regexparam "2.0.0"
+
svelte@^3.38.2:
version "3.44.1"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.44.1.tgz#5cc772a8340f4519a4ecd1ac1a842325466b1a63"
@@ -10397,6 +11099,16 @@ table@^5.2.3:
slice-ansi "^2.1.0"
string-width "^3.0.0"
+tar-fs@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
+ integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==
+ dependencies:
+ chownr "^1.1.1"
+ mkdirp-classic "^0.5.2"
+ pump "^3.0.0"
+ tar-stream "^2.1.4"
+
tar-stream@^1.5.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555"
@@ -10410,6 +11122,17 @@ tar-stream@^1.5.2:
to-buffer "^1.1.1"
xtend "^4.0.0"
+tar-stream@^2.1.4:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
+ integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
+ dependencies:
+ bl "^4.0.3"
+ end-of-stream "^1.4.1"
+ fs-constants "^1.0.0"
+ inherits "^2.0.3"
+ readable-stream "^3.1.1"
+
tarn@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/tarn/-/tarn-1.1.5.tgz#7be88622e951738b9fa3fb77477309242cdddc2d"
@@ -10576,6 +11299,11 @@ to-fast-properties@^2.0.0:
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
+to-gfm-code-block@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/to-gfm-code-block/-/to-gfm-code-block-0.1.1.tgz#25d045a5fae553189e9637b590900da732d8aa82"
+ integrity sha1-JdBFpfrlUxielje1kJANpzLYqoI=
+
to-json-schema@0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/to-json-schema/-/to-json-schema-0.2.5.tgz#ef3c3f11ad64460dcfbdbafd0fd525d69d62a98f"
@@ -10802,11 +11530,28 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"
+typeof-article@^0.1.1:
+ version "0.1.1"
+ resolved "https://registry.yarnpkg.com/typeof-article/-/typeof-article-0.1.1.tgz#9f07e733c3fbb646ffa9e61c08debacd460e06af"
+ integrity sha1-nwfnM8P7tkb/qeYcCN66zUYOBq8=
+ dependencies:
+ kind-of "^3.1.0"
+
typescript@^4.3.5:
version "4.3.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==
+uglify-js@^3.1.4:
+ version "3.14.3"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf"
+ integrity sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==
+
+uid2@0.0.x:
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.4.tgz#033f3b1d5d32505f5ce5f888b9f3b667123c0a44"
+ integrity sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==
+
unbox-primitive@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"
@@ -10997,6 +11742,11 @@ util.promisify@^1.0.0, util.promisify@^1.0.1:
has-symbols "^1.0.1"
object.getownpropertydescriptors "^2.1.1"
+utils-merge@1.x.x:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
+ integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
+
uuid@3.3.2, uuid@^3.1.0, uuid@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
@@ -11056,7 +11806,7 @@ verror@1.3.6:
dependencies:
extsprintf "1.0.2"
-vm2@^3.9.3:
+vm2@^3.9.3, vm2@^3.9.4:
version "3.9.5"
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.5.tgz#5288044860b4bbace443101fcd3bddb2a0aa2496"
integrity sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==
@@ -11087,6 +11837,14 @@ walker@^1.0.7, walker@~1.0.5:
dependencies:
makeerror "1.0.12"
+webfinger@^0.4.2:
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/webfinger/-/webfinger-0.4.2.tgz#3477a6d97799461896039fcffc650b73468ee76d"
+ integrity sha1-NHem2XeZRhiWA5/P/GULc0aO520=
+ dependencies:
+ step "0.0.x"
+ xml2js "0.1.x"
+
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
@@ -11196,6 +11954,11 @@ word-wrap@~1.2.3:
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
+wordwrap@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+ integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
+
worker-farm@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"
@@ -11301,6 +12064,13 @@ xml-parse-from-string@^1.0.0:
resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28"
integrity sha1-qQKekp09vN7RafPG4oI42VpdWig=
+xml2js@0.1.x:
+ version "0.1.14"
+ resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.1.14.tgz#5274e67f5a64c5f92974cd85139e0332adc6b90c"
+ integrity sha1-UnTmf1pkxfkpdM2FE54DMq3GuQw=
+ dependencies:
+ sax ">=0.1.1"
+
xml2js@0.4.19:
version "0.4.19"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
@@ -11434,6 +12204,11 @@ yauzl@^2.4.2:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"
+year@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/year/-/year-0.2.1.tgz#4083ae520a318b23ec86037f3000cb892bdf9bb0"
+ integrity sha1-QIOuUgoxiyPshgN/MADLiSvfm7A=
+
ylru@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f"
@@ -11444,7 +12219,7 @@ yn@3.1.1:
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
-zlib@1.0.5:
+zlib@1.0.5, zlib@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/zlib/-/zlib-1.0.5.tgz#6e7c972fc371c645a6afb03ab14769def114fcc0"
integrity sha1-bnyXL8NxxkWmr7A6sUdp3vEU/MA=
From c421499a4645166efd303da4d3bd0c7bbd7306e1 Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Mon, 29 Nov 2021 17:21:30 +0000
Subject: [PATCH 04/30] cURL import working
---
.../modals/ImportRestQueriesModal.svelte | 3 +-
.../builder/src/stores/backend/queries.js | 5 +
packages/server/package.json | 1 +
.../src/api/controllers/query/import.ts | 71 +++++++++++-
packages/server/yarn.lock | 103 +++++++++++++++++-
5 files changed, 174 insertions(+), 9 deletions(-)
diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte
index 8098e10fb4..4e8ba4fd77 100644
--- a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte
+++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte
@@ -56,8 +56,7 @@
datasourceId,
}
- const resp = await queries.import(body)
- datasourceId = resp.datasourceId
+ await queries.import(body)
// reload
await datasources.fetch()
diff --git a/packages/builder/src/stores/backend/queries.js b/packages/builder/src/stores/backend/queries.js
index c03aea4052..6dfffc3d39 100644
--- a/packages/builder/src/stores/backend/queries.js
+++ b/packages/builder/src/stores/backend/queries.js
@@ -55,6 +55,11 @@ export function createQueriesStore() {
},
import: async body => {
const response = await api.post(`/api/queries/import`, body)
+
+ if (response.status !== 200) {
+ throw new Error(response.message)
+ }
+
return response.json()
},
select: query => {
diff --git a/packages/server/package.json b/packages/server/package.json
index 040febe02c..c73fe874ae 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -85,6 +85,7 @@
"bull": "^3.22.4",
"chmodr": "1.2.0",
"csvtojson": "2.0.10",
+ "curlconverter": "^3.21.0",
"dotenv": "8.2.0",
"download": "8.0.0",
"fix-path": "3.0.0",
diff --git a/packages/server/src/api/controllers/query/import.ts b/packages/server/src/api/controllers/query/import.ts
index f860b28d8c..93f4b27ab1 100644
--- a/packages/server/src/api/controllers/query/import.ts
+++ b/packages/server/src/api/controllers/query/import.ts
@@ -2,6 +2,8 @@ import CouchDB from "../../../db"
import { queryValidation } from "./validation"
import { generateQueryID } from "../../../db/utils"
import { Spec as Swagger2, Operation } from "swagger-schema-official"
+const curlconverter = require("curlconverter")
+import { URL } from "url"
// {
// "_id": "query_datasource_d62738f2d72a466997ffbf46f4952404_e7258ad382cd4c37961b81730633ff2d",
@@ -90,15 +92,45 @@ interface DatasourceInfo {
}
const parseImportStrategy = (data: string): Strategy => {
- return Strategy.SWAGGER2
+ try {
+ const json = JSON.parse(data)
+ if (json.swagger === "2.0") {
+ return Strategy.CURL
+ } else if (json.openapi?.includes("3.0")) {
+ return Strategy.OPENAPI3
+ }
+ } catch (jsonError) {
+ try {
+ parseCurl(data)
+ return Strategy.CURL
+ } catch (curlError) {
+ // do nothing
+ }
+ }
+
+ throw new Error(`The import data could not be processed`)
+}
+
+const processPath = (path: string): string => {
+ if (path?.startsWith("/")) {
+ return path.substring(1)
+ }
+
+ return path
}
// SWAGGER
const parseSwagger2Info = (swagger2: Swagger2): DatasourceInfo => {
+ const scheme = swagger2.schemes?.includes("https") ? "https" : "http"
+ const basePath = swagger2.basePath || ""
+ const host = swagger2.host || ""
+ const url = `${scheme}://${host}${basePath}`
+ const name = swagger2.info.title || "Swagger Import"
+
return {
- url: "http://localhost:3000",
- name: "swagger",
+ url: url,
+ name: name,
defaultHeaders: [],
}
}
@@ -150,16 +182,42 @@ const parseOpenAPI3Queries = (datasourceId: string, data: string): Query[] => {
// CURL
+const parseCurl = (data: string): any => {
+ const curlJson = curlconverter.toJsonString(data)
+ return JSON.parse(curlJson)
+}
+
const parseCurlDatasourceInfo = (data: any): DatasourceInfo => {
+ const curl = parseCurl(data)
+
+ const url = new URL(curl.url)
+
return {
- url: "http://localhost:3000",
- name: "swagger",
+ url: url.origin,
+ name: url.hostname,
defaultHeaders: [],
}
}
const parseCurlQueries = (datasourceId: string, data: string): Query[] => {
- return []
+ const curl = parseCurl(data)
+
+ const url = new URL(curl.url)
+ const name = url.pathname
+ const path = url.pathname
+ const method = curl.method
+ const queryString = url.search
+ const headers = curl.headers
+
+ const query = constructQuery(
+ datasourceId,
+ name,
+ method,
+ path,
+ queryString,
+ headers
+ )
+ return [query]
}
const verbFromMethod = (method: string) => {
@@ -183,6 +241,7 @@ const constructQuery = (
const queryVerb = verbFromMethod(method)
const transformer = "return data"
const schema = {}
+ path = processPath(path)
const query: Query = {
datasourceId,
diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock
index 3ef43963ef..997a856f6f 100644
--- a/packages/server/yarn.lock
+++ b/packages/server/yarn.lock
@@ -1190,6 +1190,24 @@
dependencies:
"@cspotcode/source-map-consumer" "0.8.0"
+"@curlconverter/yargs-parser@^0.0.1":
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/@curlconverter/yargs-parser/-/yargs-parser-0.0.1.tgz#62a360cea3d62b9b5805e61e8110cea98da8d140"
+ integrity sha512-DbEVRYqrorzwqc63MQ3RODflut1tNla8ZCKo1h83lF7+fbntgubZsDfRDBv5Lxj3vkKuvAolysNM2ekwJev8wA==
+
+"@curlconverter/yargs@^0.0.2":
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/@curlconverter/yargs/-/yargs-0.0.2.tgz#a8ad4a2a2d0b0f897f8c117f664199165b59fd8a"
+ integrity sha512-Q1YEebpCY61kxme4wvU0/IN/uMBfG5pZOKCo9FU+w20ElPvN+eH2qEVbK1C12t3Tee3qeYLLEU6HkiUeO1gc4A==
+ dependencies:
+ "@curlconverter/yargs-parser" "^0.0.1"
+ cliui "^7.0.2"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
+ require-directory "^2.1.1"
+ string-width "^4.2.0"
+ y18n "^5.0.5"
+
"@elastic/elasticsearch@7.10.0":
version "7.10.0"
resolved "https://registry.yarnpkg.com/@elastic/elasticsearch/-/elasticsearch-7.10.0.tgz#da105a9c1f14146f9f2cab4e7026cb7949121b8d"
@@ -2562,6 +2580,11 @@
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d"
integrity sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==
+a-sync-waterfall@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz#75b6b6aa72598b497a125e7a2770f14f4c8a1fa7"
+ integrity sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==
+
abab@^2.0.0, abab@^2.0.3, abab@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a"
@@ -2896,6 +2919,11 @@ array-unique@^0.3.2:
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428"
integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=
+asap@^2.0.3:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
+ integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
+
asn1@~0.2.3:
version "0.2.6"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d"
@@ -3764,6 +3792,11 @@ commander@^2.19.0, commander@^2.5.0, commander@^2.8.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+commander@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
+ integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
+
commander@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
@@ -4016,6 +4049,19 @@ csvtojson@2.0.10:
lodash "^4.17.3"
strip-bom "^2.0.0"
+curlconverter@^3.21.0:
+ version "3.21.0"
+ resolved "https://registry.yarnpkg.com/curlconverter/-/curlconverter-3.21.0.tgz#50b9568b8d24967ef55a0fcd872e7a18eea4cbc2"
+ integrity sha512-DXCnp1A/Xa69FujksUfdvWQFAnIn/C+4Wuv8t+UVdZkF/lY5bzj98GGKOGme7V/ckSHDLxE29Xp76sJ5Cpsp5A==
+ dependencies:
+ "@curlconverter/yargs" "^0.0.2"
+ cookie "^0.4.1"
+ jsesc "^3.0.2"
+ nunjucks "^3.2.3"
+ query-string "^7.0.1"
+ string.prototype.startswith "^1.0.0"
+ yamljs "^0.3.0"
+
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@@ -4537,7 +4583,7 @@ error-inject@^1.0.0:
resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37"
integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc=
-es-abstract@^1.19.1:
+es-abstract@^1.17.5, es-abstract@^1.19.1:
version "1.19.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3"
integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==
@@ -5147,6 +5193,11 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
+filter-obj@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b"
+ integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs=
+
find-up@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
@@ -7447,6 +7498,11 @@ jsesc@^2.5.1:
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
+jsesc@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e"
+ integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==
+
jsesc@~0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
@@ -8732,6 +8788,15 @@ npm-run-path@^4.0.1:
dependencies:
path-key "^3.0.0"
+nunjucks@^3.2.3:
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/nunjucks/-/nunjucks-3.2.3.tgz#1b33615247290e94e28263b5d855ece765648a31"
+ integrity sha512-psb6xjLj47+fE76JdZwskvwG4MYsQKXUtMsPh6U0YMvmyjRtKRFcxnlXGWglNybtNTNVmGdp94K62/+NjF5FDQ==
+ dependencies:
+ a-sync-waterfall "^1.0.0"
+ asap "^2.0.3"
+ commander "^5.1.0"
+
nwsapi@^2.0.7, nwsapi@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
@@ -9795,6 +9860,16 @@ query-string@^5.0.1:
object-assign "^4.1.0"
strict-uri-encode "^1.0.0"
+query-string@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.0.1.tgz#45bd149cf586aaa582dffc7ec7a8ad97dd02f75d"
+ integrity sha512-uIw3iRvHnk9to1blJCG3BTc+Ro56CBowJXKmNNAm3RulvPBzWLRqKSiiDk+IplJhsydwtuNMHi8UGQFcCLVfkA==
+ dependencies:
+ decode-uri-component "^0.2.0"
+ filter-obj "^1.1.0"
+ split-on-first "^1.0.0"
+ strict-uri-encode "^2.0.0"
+
querystring@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
@@ -10677,6 +10752,11 @@ spdx-license-ids@^3.0.0:
resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95"
integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==
+split-on-first@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
+ integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
+
split-string@^3.0.1, split-string@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2"
@@ -10785,6 +10865,11 @@ strict-uri-encode@^1.0.0:
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
+strict-uri-encode@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546"
+ integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY=
+
string-length@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
@@ -10816,6 +10901,14 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
+string.prototype.startswith@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/string.prototype.startswith/-/string.prototype.startswith-1.0.0.tgz#92a361fb1ac172033d53eb1db3d659b0cfab6280"
+ integrity sha512-VHhsDkuf8gsw4JNRK9cIZjYe6r7PsVUutVohaBhqYAoPaRADoQH+mMgUg7Cs/TgQeDGEvI+PzPEMOdvdsCMvpg==
+ dependencies:
+ define-properties "^1.1.3"
+ es-abstract "^1.17.5"
+
string.prototype.trimend@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80"
@@ -12137,6 +12230,14 @@ yaml@^1.10.2:
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
+yamljs@^0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/yamljs/-/yamljs-0.3.0.tgz#dc060bf267447b39f7304e9b2bfbe8b5a7ddb03b"
+ integrity sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==
+ dependencies:
+ argparse "^1.0.7"
+ glob "^7.0.5"
+
yargs-parser@20.x, yargs-parser@^20.2.2:
version "20.2.9"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
From 3923fd683132c5088d6ef2a4948c41075d0e5a76 Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Wed, 1 Dec 2021 09:48:52 +0000
Subject: [PATCH 05/30] Add type hierarchy for importers
---
packages/server/package.json | 3 +-
.../src/api/controllers/query/import.ts | 334 ------------------
.../src/api/controllers/query/import/index.ts | 78 ++++
.../query/import/sources/base/index.ts | 92 +++++
.../query/import/sources/base/openapi.ts | 13 +
.../controllers/query/import/sources/curl.ts | 54 +++
.../query/import/sources/openapi2.ts | 104 ++++++
.../query/import/sources/openapi3.ts | 40 +++
.../query/import/sources/tests/curl.spec.js | 71 ++++
.../import/sources/tests/openapi.spec.js | 0
.../import/sources/tests/openapi2.spec.js | 0
.../server/src/api/controllers/query/index.js | 11 +-
packages/server/yarn.lock | 92 ++++-
13 files changed, 547 insertions(+), 345 deletions(-)
delete mode 100644 packages/server/src/api/controllers/query/import.ts
create mode 100644 packages/server/src/api/controllers/query/import/index.ts
create mode 100644 packages/server/src/api/controllers/query/import/sources/base/index.ts
create mode 100644 packages/server/src/api/controllers/query/import/sources/base/openapi.ts
create mode 100644 packages/server/src/api/controllers/query/import/sources/curl.ts
create mode 100644 packages/server/src/api/controllers/query/import/sources/openapi2.ts
create mode 100644 packages/server/src/api/controllers/query/import/sources/openapi3.ts
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl.spec.js
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/openapi.spec.js
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/openapi2.spec.js
diff --git a/packages/server/package.json b/packages/server/package.json
index c73fe874ae..63669e5b2f 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -68,6 +68,7 @@
"author": "Budibase",
"license": "AGPL-3.0-or-later",
"dependencies": {
+ "@apidevtools/swagger-parser": "^10.0.3",
"@budibase/auth": "^0.9.185-alpha.21",
"@budibase/client": "^0.9.185-alpha.21",
"@budibase/string-templates": "^0.9.185-alpha.21",
@@ -77,7 +78,6 @@
"@koa/router": "8.0.0",
"@sendgrid/mail": "7.1.1",
"@sentry/node": "^6.0.0",
- "@types/swagger-schema-official": "^2.0.22",
"airtable": "0.10.1",
"arangojs": "7.2.0",
"aws-sdk": "^2.767.0",
@@ -109,6 +109,7 @@
"mysql2": "^2.3.1",
"node-fetch": "2.6.0",
"open": "7.3.0",
+ "openapi-types": "^9.3.1",
"pg": "8.5.1",
"pino-pretty": "4.0.0",
"posthog-node": "^1.1.4",
diff --git a/packages/server/src/api/controllers/query/import.ts b/packages/server/src/api/controllers/query/import.ts
deleted file mode 100644
index 93f4b27ab1..0000000000
--- a/packages/server/src/api/controllers/query/import.ts
+++ /dev/null
@@ -1,334 +0,0 @@
-import CouchDB from "../../../db"
-import { queryValidation } from "./validation"
-import { generateQueryID } from "../../../db/utils"
-import { Spec as Swagger2, Operation } from "swagger-schema-official"
-const curlconverter = require("curlconverter")
-import { URL } from "url"
-
-// {
-// "_id": "query_datasource_d62738f2d72a466997ffbf46f4952404_e7258ad382cd4c37961b81730633ff2d",
-// "_rev": "1-e702a18eaa96c7cb4be1b402c34eaa59",
-// "datasourceId": "datasource_d62738f2d72a466997ffbf46f4952404",
-// "parameters": [
-// {
-// "name": "paramtest",
-// "default": "defaultValue"
-// }
-// ],
-// "fields": {
-// "headers": {
-// "headertest": "test"
-// },
-// "queryString": "query=test",
-// "path": "/path/test"
-// },
-// "queryVerb": "read",
-// "transformer": "return data.test",
-// "schema": {},
-// "name": "name",
-// "readable": true
-// }
-
-// return joiValidator.body(Joi.object({
-// _id: Joi.string(),
-// _rev: Joi.string(),
-// name: Joi.string().required(),
-// fields: Joi.object().required(),
-// datasourceId: Joi.string().required(),
-// readable: Joi.boolean(),
-// parameters: Joi.array().items(Joi.object({
-// name: Joi.string(),
-// default: Joi.string().allow(""),
-// })),
-// queryVerb: Joi.string().allow().required(),
-// extra: Joi.object().optional(),
-// schema: Joi.object({}).required().unknown(true),
-// transformer: Joi.string().optional(),
-// }))
-
-interface Parameter {
- name: string
- default: string
-}
-
-interface Query {
- _id?: string
- datasourceId: string
- name: string
- parameters: Parameter[]
- fields: {
- headers: any
- queryString: string
- path: string
- }
- transformer: string | null
- schema: any
- readable: boolean
- queryVerb: string
-}
-
-enum Strategy {
- SWAGGER2,
- OPENAPI3,
- CURL,
-}
-
-enum MethodToVerb {
- get = "read",
- post = "create",
- put = "update",
- patch = "patch",
- delete = "delete",
-}
-
-interface ImportResult {
- errorQueries: Query[]
-}
-
-interface DatasourceInfo {
- url: string
- name: string
- defaultHeaders: any[]
-}
-
-const parseImportStrategy = (data: string): Strategy => {
- try {
- const json = JSON.parse(data)
- if (json.swagger === "2.0") {
- return Strategy.CURL
- } else if (json.openapi?.includes("3.0")) {
- return Strategy.OPENAPI3
- }
- } catch (jsonError) {
- try {
- parseCurl(data)
- return Strategy.CURL
- } catch (curlError) {
- // do nothing
- }
- }
-
- throw new Error(`The import data could not be processed`)
-}
-
-const processPath = (path: string): string => {
- if (path?.startsWith("/")) {
- return path.substring(1)
- }
-
- return path
-}
-
-// SWAGGER
-
-const parseSwagger2Info = (swagger2: Swagger2): DatasourceInfo => {
- const scheme = swagger2.schemes?.includes("https") ? "https" : "http"
- const basePath = swagger2.basePath || ""
- const host = swagger2.host || ""
- const url = `${scheme}://${host}${basePath}`
- const name = swagger2.info.title || "Swagger Import"
-
- return {
- url: url,
- name: name,
- defaultHeaders: [],
- }
-}
-
-const parseSwagger2Queries = (
- datasourceId: string,
- swagger2: Swagger2
-): Query[] => {
- const queries = []
-
- for (let [pathName, path] of Object.entries(swagger2.paths)) {
- for (let [methodName, op] of Object.entries(path)) {
- let operation = op as Operation
-
- const name = operation.operationId || pathName
- const queryString = ""
- const headers = {}
- const parameters: Parameter[] = []
-
- const query = constructQuery(
- datasourceId,
- name,
- methodName,
- pathName,
- queryString,
- headers,
- parameters
- )
- queries.push(query)
- }
- }
-
- return queries
-}
-
-// OPEN API
-
-const parseOpenAPI3Info = (data: any): DatasourceInfo => {
- return {
- url: "http://localhost:3000",
- name: "swagger",
- defaultHeaders: [],
- }
-}
-
-const parseOpenAPI3Queries = (datasourceId: string, data: string): Query[] => {
- return []
-}
-
-// CURL
-
-const parseCurl = (data: string): any => {
- const curlJson = curlconverter.toJsonString(data)
- return JSON.parse(curlJson)
-}
-
-const parseCurlDatasourceInfo = (data: any): DatasourceInfo => {
- const curl = parseCurl(data)
-
- const url = new URL(curl.url)
-
- return {
- url: url.origin,
- name: url.hostname,
- defaultHeaders: [],
- }
-}
-
-const parseCurlQueries = (datasourceId: string, data: string): Query[] => {
- const curl = parseCurl(data)
-
- const url = new URL(curl.url)
- const name = url.pathname
- const path = url.pathname
- const method = curl.method
- const queryString = url.search
- const headers = curl.headers
-
- const query = constructQuery(
- datasourceId,
- name,
- method,
- path,
- queryString,
- headers
- )
- return [query]
-}
-
-const verbFromMethod = (method: string) => {
- const verb = (MethodToVerb)[method]
- if (!verb) {
- throw new Error(`Unsupported method: ${method}`)
- }
- return verb
-}
-
-const constructQuery = (
- datasourceId: string,
- name: string,
- method: string,
- path: string,
- queryString: string,
- headers: any = {},
- parameters: Parameter[] = []
-): Query => {
- const readable = true
- const queryVerb = verbFromMethod(method)
- const transformer = "return data"
- const schema = {}
- path = processPath(path)
-
- const query: Query = {
- datasourceId,
- name,
- parameters,
- fields: {
- headers,
- queryString,
- path,
- },
- transformer,
- schema,
- readable,
- queryVerb,
- }
-
- return query
-}
-
-export const getDatasourceInfo = (data: string): DatasourceInfo => {
- const strategy = parseImportStrategy(data)
-
- let info: DatasourceInfo
- switch (strategy) {
- case Strategy.SWAGGER2:
- info = parseSwagger2Info(JSON.parse(data))
- break
- case Strategy.OPENAPI3:
- info = parseOpenAPI3Info(JSON.parse(data))
- break
- case Strategy.CURL:
- info = parseCurlDatasourceInfo(data)
- break
- }
-
- return info
-}
-
-export const importQueries = async (
- appId: string,
- datasourceId: string,
- data: string
-): Promise => {
- const strategy = parseImportStrategy(data)
-
- // constuct the queries
- let queries: Query[]
- switch (strategy) {
- case Strategy.SWAGGER2:
- queries = parseSwagger2Queries(datasourceId, JSON.parse(data))
- break
- case Strategy.OPENAPI3:
- queries = parseOpenAPI3Queries(datasourceId, JSON.parse(data))
- break
- case Strategy.CURL:
- queries = parseCurlQueries(datasourceId, data)
- break
- }
-
- // validate queries
- const errorQueries = []
- const schema = queryValidation()
- queries = queries
- .filter(query => {
- const validation = schema.validate(query)
- if (validation.error) {
- errorQueries.push(query)
- return false
- }
- return true
- })
- .map(query => {
- query._id = generateQueryID(query.datasourceId)
- return query
- })
-
- // persist queries
- const db = new CouchDB(appId)
- for (const query of queries) {
- try {
- await db.put(query)
- } catch (error) {
- errorQueries.push(query)
- }
- }
-
- return {
- errorQueries,
- }
-}
diff --git a/packages/server/src/api/controllers/query/import/index.ts b/packages/server/src/api/controllers/query/import/index.ts
new file mode 100644
index 0000000000..808959798d
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/index.ts
@@ -0,0 +1,78 @@
+import CouchDB from "../../../../db"
+import { queryValidation } from "../validation"
+import { generateQueryID } from "../../../../db/utils"
+import { Query, ImportInfo, ImportSource } from "./sources/base"
+import { OpenAPI2 } from "./sources/openapi2"
+import { OpenAPI3 } from "./sources/openapi3"
+import { Curl } from "./sources/curl"
+
+interface ImportResult {
+ errorQueries: Query[]
+}
+
+export class RestImporter {
+ data: string
+ sources: ImportSource[]
+ source!: ImportSource
+
+ constructor(data: string) {
+ this.data = data
+ this.sources = [new OpenAPI2(), new OpenAPI3(), new Curl()]
+ }
+
+ init = async () => {
+ for (let source of this.sources) {
+ if (await source.isSupported(this.data)){
+ this.source = source
+ break
+ }
+ }
+ }
+
+ getInfo = async (): Promise => {
+ return this.source.getInfo()
+ }
+
+ importQueries = async (
+ appId: string,
+ datasourceId: string,
+ ): Promise => {
+
+ // constuct the queries
+ let queries = await this.source.getQueries(datasourceId)
+
+ // validate queries
+ const errorQueries = []
+ const schema = queryValidation()
+ queries = queries
+ .filter(query => {
+ const validation = schema.validate(query)
+ if (validation.error) {
+ errorQueries.push(query)
+ return false
+ }
+ return true
+ })
+ .map(query => {
+ query._id = generateQueryID(query.datasourceId)
+ return query
+ })
+
+ // persist queries
+ const db = new CouchDB(appId)
+ for (const query of queries) {
+ try {
+ await db.put(query)
+ } catch (error) {
+ errorQueries.push(query)
+ }
+ }
+
+ return {
+ errorQueries,
+ }
+ }
+
+}
+
+
diff --git a/packages/server/src/api/controllers/query/import/sources/base/index.ts b/packages/server/src/api/controllers/query/import/sources/base/index.ts
new file mode 100644
index 0000000000..f6a6b2b57c
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/base/index.ts
@@ -0,0 +1,92 @@
+export interface ImportInfo {
+ url: string
+ name: string
+}
+
+export interface QueryParameter {
+ name: string
+ default: string
+}
+
+export interface Query {
+ _id?: string
+ datasourceId: string
+ name: string
+ parameters: QueryParameter[]
+ fields: {
+ headers: object
+ queryString: string | null
+ path: string
+ requestBody?: object
+ }
+ transformer: string | null
+ schema: any
+ readable: boolean
+ queryVerb: string
+}
+
+enum MethodToVerb {
+ get = "read",
+ post = "create",
+ put = "update",
+ patch = "patch",
+ delete = "delete",
+}
+
+export abstract class ImportSource {
+
+ abstract isSupported(data: string): Promise
+ abstract getInfo(): Promise
+ abstract getQueries(datasourceId: string): Promise
+
+ constructQuery = (
+ datasourceId: string,
+ name: string,
+ method: string,
+ path: string,
+ queryString: string,
+ headers: object = {},
+ parameters: QueryParameter[] = [],
+ requestBody: object | undefined = undefined,
+ ): Query => {
+ const readable = true
+ const queryVerb = this.verbFromMethod(method)
+ const transformer = "return data"
+ const schema = {}
+ path = this.processPath(path)
+
+ const query: Query = {
+ datasourceId,
+ name,
+ parameters,
+ fields: {
+ headers,
+ queryString,
+ path,
+ requestBody
+ },
+ transformer,
+ schema,
+ readable,
+ queryVerb,
+ }
+
+ return query
+ }
+
+ verbFromMethod = (method: string) => {
+ const verb = (MethodToVerb)[method]
+ if (!verb) {
+ throw new Error(`Unsupported method: ${method}`)
+ }
+ return verb
+ }
+
+ processPath = (path: string): string => {
+ if (path?.startsWith("/")) {
+ return path.substring(1)
+ }
+
+ return path
+ }
+}
diff --git a/packages/server/src/api/controllers/query/import/sources/base/openapi.ts b/packages/server/src/api/controllers/query/import/sources/base/openapi.ts
new file mode 100644
index 0000000000..dfe3c68c08
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/base/openapi.ts
@@ -0,0 +1,13 @@
+
+import { ImportSource } from "."
+import SwaggerParser from "@apidevtools/swagger-parser";
+import { OpenAPI } from "openapi-types";
+
+export abstract class OpenAPISource extends ImportSource {
+
+ parseData = async (data: string): Promise => {
+ const json = JSON.parse(data)
+ return SwaggerParser.validate(json, {})
+ }
+
+}
diff --git a/packages/server/src/api/controllers/query/import/sources/curl.ts b/packages/server/src/api/controllers/query/import/sources/curl.ts
new file mode 100644
index 0000000000..b5a3e624d9
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/curl.ts
@@ -0,0 +1,54 @@
+import { ImportSource, ImportInfo, Query } from "./base"
+import { URL } from 'url'
+const curlconverter = require("curlconverter")
+
+const parseCurl = (data: string): any => {
+ const curlJson = curlconverter.toJsonString(data)
+ return JSON.parse(curlJson)
+}
+
+/**
+ * Curl
+ * https://curl.se/docs/manpage.html
+ */
+export class Curl extends ImportSource {
+ curl: any
+
+ isSupported = async (data: string): Promise => {
+ try {
+ const curl = parseCurl(data)
+ this.curl = curl
+ } catch (err) {
+ return false
+ }
+ return true
+ }
+
+ getInfo = async (): Promise => {
+ const url = new URL(this.curl.url)
+ return {
+ url: url.origin,
+ name: url.hostname,
+ }
+ }
+
+ getQueries = async (datasourceId: string): Promise => {
+ const url = new URL(this.curl.url)
+ const name = url.pathname
+ const path = url.pathname
+ const method = this.curl.method
+ const queryString = url.search
+ const headers = this.curl.headers
+
+ const query = this.constructQuery(
+ datasourceId,
+ name,
+ method,
+ path,
+ queryString,
+ headers
+ )
+
+ return [query]
+ }
+}
diff --git a/packages/server/src/api/controllers/query/import/sources/openapi2.ts b/packages/server/src/api/controllers/query/import/sources/openapi2.ts
new file mode 100644
index 0000000000..05ee41d531
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/openapi2.ts
@@ -0,0 +1,104 @@
+import { ImportInfo, QueryParameter, Query } from "./base"
+import { OpenAPIV2 } from "openapi-types"
+import { OpenAPISource } from "./base/openapi";
+
+const isBodyParameter = (param: OpenAPIV2.Parameter): param is OpenAPIV2.InBodyParameterObject => {
+ return param.in === "body"
+}
+
+const isParameter = (param: OpenAPIV2.Parameter | OpenAPIV2.ReferenceObject): param is OpenAPIV2.Parameter => {
+ // we can guarantee this is not a reference object
+ // due to the deferencing done by the parser library
+ return true
+}
+
+const isOpenAPI2 = (document: any): document is OpenAPIV2.Document => {
+ if (document.swagger === "2.0") {
+ return true
+ } else {
+ return false
+ }
+}
+
+/**
+ * OpenAPI Version 2.0 - aka "Swagger"
+ * https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md
+ */
+export class OpenAPI2 extends OpenAPISource {
+ document!: OpenAPIV2.Document
+
+ isSupported = async (data: string): Promise => {
+ try {
+ const document: any = await this.parseData(data)
+ if (isOpenAPI2(document)) {
+ this.document = document
+ return true
+ } else {
+ return false
+ }
+ } catch (err) {
+ return false
+ }
+ }
+
+ getInfo = async (): Promise => {
+ const scheme = this.document.schemes?.includes("https") ? "https" : "http"
+ const basePath = this.document.basePath || ""
+ const host = this.document.host || ""
+ const url = `${scheme}://${host}${basePath}`
+ const name = this.document.info.title || "Swagger Import"
+
+ return {
+ url: url,
+ name: name,
+ }
+ }
+
+ getQueries = async (datasourceId: string): Promise => {
+ const queries = []
+
+ let pathName: string
+ let path: OpenAPIV2.PathItemObject
+
+ for ([pathName, path] of Object.entries(this.document.paths)) {
+ for (let [methodName, op] of Object.entries(path)) {
+ let operation = op as OpenAPIV2.OperationObject
+
+ const name = operation.operationId || pathName
+ const queryString = ""
+ const headers = {}
+ let requestBody = undefined
+ const parameters: QueryParameter[] = []
+
+ if (operation.parameters) {
+ for (let param of operation.parameters) {
+ if (isParameter(param)) {
+ if (isBodyParameter(param)) {
+ requestBody = {}
+ } else {
+ parameters.push({
+ name: param.name,
+ default: "",
+ })
+ }
+ }
+ }
+ }
+
+ const query = this.constructQuery(
+ datasourceId,
+ name,
+ methodName,
+ pathName,
+ queryString,
+ headers,
+ parameters,
+ requestBody
+ )
+ queries.push(query)
+ }
+ }
+
+ return queries
+ }
+}
diff --git a/packages/server/src/api/controllers/query/import/sources/openapi3.ts b/packages/server/src/api/controllers/query/import/sources/openapi3.ts
new file mode 100644
index 0000000000..655c680ed4
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/openapi3.ts
@@ -0,0 +1,40 @@
+import { ImportInfo, Query } from "./base"
+import { OpenAPISource } from "./base/openapi"
+import { OpenAPIV3 } from "openapi-types"
+
+const isOpenAPI3 = (document: any): document is OpenAPIV3.Document => {
+ return document.openapi === "3.0.0"
+}
+
+/**
+ * OpenAPI Version 3.0.0
+ * https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md
+ */
+export class OpenAPI3 extends OpenAPISource {
+ document!: OpenAPIV3.Document
+
+ isSupported = async (data: string): Promise => {
+ try {
+ const document: any = await this.parseData(data)
+ if (isOpenAPI3(document)) {
+ this.document = document
+ return true
+ } else {
+ return false
+ }
+ } catch (err) {
+ return false
+ }
+ }
+
+ getInfo = async (): Promise => {
+ return {
+ url: "http://localhost:3000",
+ name: "swagger",
+ }
+ }
+
+ getQueries = async (datasourceId: string): Promise => {
+ return []
+ }
+}
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/curl.spec.js
new file mode 100644
index 0000000000..da90f4a61c
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl.spec.js
@@ -0,0 +1,71 @@
+// const Airtable = require("airtable")
+// const AirtableIntegration = require("../airtable")
+
+jest.mock("airtable")
+
+// class TestConfiguration {
+// constructor(config = {}) {
+// this.integration = new AirtableIntegration.integration(config)
+// this.client = {
+// create: jest.fn(),
+// select: jest.fn(),
+// update: jest.fn(),
+// destroy: jest.fn(),
+// }
+// this.integration.client = () => this.client
+// }
+// }
+
+describe("Airtable Integration", () => {
+ let config
+
+ beforeEach(() => {
+ config = new TestConfiguration()
+ })
+
+ it("calls the create method with the correct params", async () => {
+ const response = await config.integration.create({
+ table: "test",
+ json: {}
+ })
+ expect(config.client.create).toHaveBeenCalledWith([
+ {
+ fields: {}
+ }
+ ])
+ })
+
+ it("calls the read method with the correct params", async () => {
+ const response = await config.integration.read({
+ table: "test",
+ view: "Grid view"
+ })
+ expect(config.client.select).toHaveBeenCalledWith({
+ maxRecords: 10, view: "Grid view"
+ })
+ })
+
+ it("calls the update method with the correct params", async () => {
+ const response = await config.integration.update({
+ table: "test",
+ id: "123",
+ json: {
+ name: "test"
+ }
+ })
+ expect(config.client.update).toHaveBeenCalledWith([
+ {
+ id: "123",
+ fields: { name: "test" }
+ }
+ ])
+ })
+
+ it("calls the delete method with the correct params", async () => {
+ const ids = [1,2,3,4]
+ const response = await config.integration.delete({
+ ids
+ })
+ expect(config.client.destroy).toHaveBeenCalledWith(ids)
+ })
+})
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/openapi.spec.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/openapi2.spec.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/server/src/api/controllers/query/index.js b/packages/server/src/api/controllers/query/index.js
index fb3d233c4e..17d2b8aa36 100644
--- a/packages/server/src/api/controllers/query/index.js
+++ b/packages/server/src/api/controllers/query/index.js
@@ -4,8 +4,8 @@ const { generateQueryID, getQueryParams } = require("../../../db/utils")
const { BaseQueryVerbs } = require("../../../constants")
const env = require("../../../environment")
const { Thread, ThreadType } = require("../../../threads")
-const { importQueries, getDatasourceInfo } = require("./import")
const { save: saveDatasource } = require("../datasource")
+const { RestImporter } = require("./import")
const Runner = new Thread(ThreadType.QUERY, { timeoutMs: 10000 })
@@ -37,16 +37,19 @@ exports.import = async ctx => {
const body = ctx.request.body
const data = body.data
+ const importer = new RestImporter(data)
+ await importer.init()
+
let datasourceId
if (!body.datasourceId) {
// construct new datasource
- const info = getDatasourceInfo(data)
+ const info = await importer.getInfo()
let datasource = {
type: "datasource",
source: "REST",
config: {
url: info.url,
- defaultHeaders: info.defaultHeaders,
+ defaultHeaders: [],
},
name: info.name,
}
@@ -60,7 +63,7 @@ exports.import = async ctx => {
datasourceId = body.datasourceId
}
- const importResult = await importQueries(ctx.appId, datasourceId, data)
+ const importResult = await importer.importQueries(ctx.appId, datasourceId)
ctx.body = {
...importResult,
diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock
index 997a856f6f..fb9c3a3baa 100644
--- a/packages/server/yarn.lock
+++ b/packages/server/yarn.lock
@@ -7,6 +7,38 @@
resolved "https://registry.yarnpkg.com/@adobe/spectrum-css-workflow-icons/-/spectrum-css-workflow-icons-1.2.1.tgz#7e2cb3fcfb5c8b12d7275afafbb6ec44913551b4"
integrity sha512-uVgekyBXnOVkxp+CUssjN/gefARtudZC8duEn1vm0lBQFwGRZFlDEzU1QC+aIRWCrD1Z8OgRpmBYlSZ7QS003w==
+"@apidevtools/json-schema-ref-parser@^9.0.6":
+ version "9.0.9"
+ resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz#d720f9256e3609621280584f2b47ae165359268b"
+ integrity sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==
+ dependencies:
+ "@jsdevtools/ono" "^7.1.3"
+ "@types/json-schema" "^7.0.6"
+ call-me-maybe "^1.0.1"
+ js-yaml "^4.1.0"
+
+"@apidevtools/openapi-schemas@^2.0.4":
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz#9fa08017fb59d80538812f03fc7cac5992caaa17"
+ integrity sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==
+
+"@apidevtools/swagger-methods@^3.0.2":
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz#b789a362e055b0340d04712eafe7027ddc1ac267"
+ integrity sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==
+
+"@apidevtools/swagger-parser@^10.0.3":
+ version "10.0.3"
+ resolved "https://registry.yarnpkg.com/@apidevtools/swagger-parser/-/swagger-parser-10.0.3.tgz#32057ae99487872c4dd96b314a1ab4b95d89eaf5"
+ integrity sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==
+ dependencies:
+ "@apidevtools/json-schema-ref-parser" "^9.0.6"
+ "@apidevtools/openapi-schemas" "^2.0.4"
+ "@apidevtools/swagger-methods" "^3.0.2"
+ "@jsdevtools/ono" "^7.1.3"
+ call-me-maybe "^1.0.1"
+ z-schema "^5.0.1"
+
"@azure/abort-controller@^1.0.0":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.0.4.tgz#fd3c4d46c8ed67aace42498c8e2270960250eafd"
@@ -1826,6 +1858,11 @@
"@babel/runtime" "^7.7.2"
regenerator-runtime "^0.13.3"
+"@jsdevtools/ono@^7.1.3":
+ version "7.1.3"
+ resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796"
+ integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==
+
"@koa/router@8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@koa/router/-/router-8.0.0.tgz#fd4ffa6f03d8293a04c023cb4a22b612401fbe70"
@@ -2393,6 +2430,11 @@
jest-diff "^26.0.0"
pretty-format "^26.0.0"
+"@types/json-schema@^7.0.6":
+ version "7.0.9"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
+ integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
+
"@types/keygrip@*":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72"
@@ -2500,11 +2542,6 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
-"@types/swagger-schema-official@^2.0.22":
- version "2.0.22"
- resolved "https://registry.yarnpkg.com/@types/swagger-schema-official/-/swagger-schema-official-2.0.22.tgz#f7e06168e6994574dfd86928ac04b196870ab043"
- integrity sha512-7yQiX6MWSFSvc/1wW5smJMZTZ4fHOd+hqLr3qr/HONDxHEa2bnYAsOcGBOEqFIjd4yetwMOdEDdeW+udRAQnHA==
-
"@types/yargs-parser@*":
version "20.2.1"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129"
@@ -2865,6 +2902,11 @@ argparse@^1.0.10, argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
+argparse@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
+ integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+
args@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/args/-/args-5.0.1.tgz#4bf298df90a4799a09521362c579278cc2fdd761"
@@ -3535,6 +3577,11 @@ call-bind@^1.0.0, call-bind@^1.0.2:
function-bind "^1.1.1"
get-intrinsic "^1.0.2"
+call-me-maybe@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b"
+ integrity sha1-JtII6onje1y95gJQoV8DHBak1ms=
+
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
@@ -3787,7 +3834,7 @@ combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
-commander@^2.19.0, commander@^2.5.0, commander@^2.8.1:
+commander@^2.19.0, commander@^2.5.0, commander@^2.7.1, commander@^2.8.1:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -7418,6 +7465,13 @@ js-yaml@^3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
+js-yaml@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
+ integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
+ dependencies:
+ argparse "^2.0.1"
+
jsbi@^3.1.1:
version "3.2.5"
resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-3.2.5.tgz#b37bb90e0e5c2814c1c2a1bcd8c729888a2e37d6"
@@ -8096,6 +8150,11 @@ lodash.flatten@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=
+lodash.get@^4.4.2:
+ version "4.4.2"
+ resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
+ integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
+
lodash.includes@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
@@ -8913,6 +8972,11 @@ open@7.3.0:
is-docker "^2.0.0"
is-wsl "^2.1.1"
+openapi-types@^9.3.1:
+ version "9.3.1"
+ resolved "https://registry.yarnpkg.com/openapi-types/-/openapi-types-9.3.1.tgz#617ae6db3efd3e3f68e849f65ced58801d01d3cf"
+ integrity sha512-/Yvsd2D7miYB4HLJ3hOOS0+vnowQpaT75FsHzr/y5M9P4q9bwa7RcbW2YdH6KZBn8ceLbKGnHxMZ1CHliGHUFw==
+
opencollective-postinstall@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259"
@@ -11887,6 +11951,11 @@ validate.js@0.13.1:
resolved "https://registry.yarnpkg.com/validate.js/-/validate.js-0.13.1.tgz#b58bfac04a0f600a340f62e5227e70d95971e92a"
integrity sha512-PnFM3xiZ+kYmLyTiMgTYmU7ZHkjBZz2/+F0DaALc/uUtVzdCt1wAosvYJ5hFQi/hz8O4zb52FQhHZRC+uVkJ+g==
+validator@^13.7.0:
+ version "13.7.0"
+ resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857"
+ integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==
+
vary@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
@@ -12320,6 +12389,17 @@ yn@3.1.1:
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
+z-schema@^5.0.1:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-5.0.2.tgz#f410394b2c9fcb9edaf6a7511491c0bb4e89a504"
+ integrity sha512-40TH47ukMHq5HrzkeVE40Ad7eIDKaRV2b+Qpi2prLc9X9eFJFzV7tMe5aH12e6avaSS/u5l653EQOv+J9PirPw==
+ dependencies:
+ lodash.get "^4.4.2"
+ lodash.isequal "^4.5.0"
+ validator "^13.7.0"
+ optionalDependencies:
+ commander "^2.7.1"
+
zlib@1.0.5, zlib@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/zlib/-/zlib-1.0.5.tgz#6e7c972fc371c645a6afb03ab14769def114fcc0"
From 6f254d3a3ba5851903f732df3b712547fbcb7058 Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Wed, 1 Dec 2021 10:51:21 +0000
Subject: [PATCH 06/30] Tests WIP
---
.../query/import/sources/tests/curl.spec.js | 71 ---------------
.../import/sources/tests/curl/curl.spec.js | 88 +++++++++++++++++++
.../import/sources/tests/curl/data/delete.txt | 1 +
.../import/sources/tests/curl/data/get.txt | 1 +
.../sources/tests/curl/data/headers.txt | 3 +
.../import/sources/tests/curl/data/patch.txt | 2 +
.../import/sources/tests/curl/data/path.txt | 1 +
.../import/sources/tests/curl/data/post.txt | 2 +
.../import/sources/tests/curl/data/put.txt | 2 +
.../import/sources/tests/curl/data/query.txt | 1 +
.../tests/{ => openapi2}/openapi2.spec.js | 0
.../openapi3.spec.js} | 0
12 files changed, 101 insertions(+), 71 deletions(-)
delete mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl.spec.js
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl/data/delete.txt
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl/data/get.txt
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl/data/headers.txt
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl/data/patch.txt
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl/data/path.txt
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl/data/post.txt
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl/data/put.txt
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl/data/query.txt
rename packages/server/src/api/controllers/query/import/sources/tests/{ => openapi2}/openapi2.spec.js (100%)
rename packages/server/src/api/controllers/query/import/sources/tests/{openapi.spec.js => openapi3/openapi3.spec.js} (100%)
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/curl.spec.js
deleted file mode 100644
index da90f4a61c..0000000000
--- a/packages/server/src/api/controllers/query/import/sources/tests/curl.spec.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// const Airtable = require("airtable")
-// const AirtableIntegration = require("../airtable")
-
-jest.mock("airtable")
-
-// class TestConfiguration {
-// constructor(config = {}) {
-// this.integration = new AirtableIntegration.integration(config)
-// this.client = {
-// create: jest.fn(),
-// select: jest.fn(),
-// update: jest.fn(),
-// destroy: jest.fn(),
-// }
-// this.integration.client = () => this.client
-// }
-// }
-
-describe("Airtable Integration", () => {
- let config
-
- beforeEach(() => {
- config = new TestConfiguration()
- })
-
- it("calls the create method with the correct params", async () => {
- const response = await config.integration.create({
- table: "test",
- json: {}
- })
- expect(config.client.create).toHaveBeenCalledWith([
- {
- fields: {}
- }
- ])
- })
-
- it("calls the read method with the correct params", async () => {
- const response = await config.integration.read({
- table: "test",
- view: "Grid view"
- })
- expect(config.client.select).toHaveBeenCalledWith({
- maxRecords: 10, view: "Grid view"
- })
- })
-
- it("calls the update method with the correct params", async () => {
- const response = await config.integration.update({
- table: "test",
- id: "123",
- json: {
- name: "test"
- }
- })
- expect(config.client.update).toHaveBeenCalledWith([
- {
- id: "123",
- fields: { name: "test" }
- }
- ])
- })
-
- it("calls the delete method with the correct params", async () => {
- const ids = [1,2,3,4]
- const response = await config.integration.delete({
- ids
- })
- expect(config.client.destroy).toHaveBeenCalledWith(ids)
- })
-})
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js
new file mode 100644
index 0000000000..6fc6008b0d
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js
@@ -0,0 +1,88 @@
+// const Airtable = require("airtable")
+// const AirtableIntegration = require("../airtable")
+const { Curl } = require("../../curl")
+const fs = require("fs")
+const path = require('path')
+jest.mock("airtable")
+
+// class TestConfiguration {
+// constructor(config = {}) {
+// this.integration = new AirtableIntegration.integration(config)
+// this.client = {
+// create: jest.fn(),
+// select: jest.fn(),
+// update: jest.fn(),
+// destroy: jest.fn(),
+// }
+// this.integration.client = () => this.client
+// }
+// }
+
+const getData = (file) => {
+ return fs.readFileSync(path.join(__dirname, `./data/${file}.txt`), "utf8")
+}
+describe("Curl Import", () => {
+ let curl
+
+ beforeEach(() => {
+ curl = new Curl()
+ })
+
+ it("validates unsupported data", async () => {
+ let data
+ let supported
+
+ // JSON
+ data = "{}"
+ supported = await curl.isSupported(data)
+ expect(supported).toBe(false)
+
+ // Empty
+ data = ""
+ supported = await curl.isSupported(data)
+ expect(supported).toBe(false)
+ })
+
+ it("returns import info", async () => {
+ const data = getData()
+ await curl.isSupported(data)
+ const info = await curl.getInfo()
+ expect(info.url).toBe("http://example.com")
+ expect(info.name).toBe("example.com")
+ })
+
+ describe("Returns queries", () => {
+ describe("populates verb", () => {
+ const testVerb = async (file, verb) => {
+ const data = getData(file)
+ await curl.isSupported(data)
+ const queries = await curl.getQueries(data)
+ expect(queries.length).toBe(1)
+ expect(queries[0].verb).toBe(verb)
+ }
+ it("populates verb", async () => {
+ await testVerb("get", "read")
+ await testVerb("post", "create")
+ await testVerb("put", "update")
+ await testVerb("delete", "delete")
+ await testVerb("patch", "patch")
+ })
+ })
+
+ it("populates path", async () => {
+
+ })
+
+ it("populates headers", async () => {
+
+ })
+
+ it("populates query", async () => {
+
+ })
+
+ it("populates body", async () => {
+
+ })
+ })
+})
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/delete.txt b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/delete.txt
new file mode 100644
index 0000000000..93e70d2460
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/delete.txt
@@ -0,0 +1 @@
+curl -X DELETE 'http://example.com'
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/get.txt b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/get.txt
new file mode 100644
index 0000000000..6ac7b0e3d1
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/get.txt
@@ -0,0 +1 @@
+curl 'http://example.com'
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/headers.txt b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/headers.txt
new file mode 100644
index 0000000000..aba6d05cbf
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/headers.txt
@@ -0,0 +1,3 @@
+curl 'http://example.com' \
+ -H 'x-bb-header-1: 123' \
+ -H 'x-bb-header-2: 1456'
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/patch.txt b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/patch.txt
new file mode 100644
index 0000000000..0556f5b2d2
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/patch.txt
@@ -0,0 +1,2 @@
+curl -X PATCH 'http://example.com/paths/abc' \
+ --data-raw '{ "key" : "val" }'
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/path.txt b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/path.txt
new file mode 100644
index 0000000000..d4c18f49b5
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/path.txt
@@ -0,0 +1 @@
+curl 'http://example.com/paths/abc'
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/post.txt b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/post.txt
new file mode 100644
index 0000000000..f86c43e1d3
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/post.txt
@@ -0,0 +1,2 @@
+curl -X POST 'http://example.com' \
+ --data-raw '{ "key" : "val" }'
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/put.txt b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/put.txt
new file mode 100644
index 0000000000..7e4aef4835
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/put.txt
@@ -0,0 +1,2 @@
+curl -X PUT 'http://example.com/paths/abc' \
+ --data-raw '{ "key" : "val" }'
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/query.txt b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/query.txt
new file mode 100644
index 0000000000..cb031e7537
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/query.txt
@@ -0,0 +1 @@
+curl 'http://example.com/paths/abc?q1=v1&q1=v2'
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js
similarity index 100%
rename from packages/server/src/api/controllers/query/import/sources/tests/openapi2.spec.js
rename to packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/openapi3/openapi3.spec.js
similarity index 100%
rename from packages/server/src/api/controllers/query/import/sources/tests/openapi.spec.js
rename to packages/server/src/api/controllers/query/import/sources/tests/openapi3/openapi3.spec.js
From 72ad470c0fbcd1730ed0ebef5ce9f451155ddbb3 Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Wed, 1 Dec 2021 11:58:53 +0000
Subject: [PATCH 07/30] Curl tests finished
---
.../query/import/sources/base/index.ts | 9 ++
.../controllers/query/import/sources/curl.ts | 26 +++++-
.../import/sources/tests/curl/curl.spec.js | 92 +++++++++++--------
.../sources/tests/curl/data/empty-body.txt | 2 +
.../sources/tests/curl/data/headers.txt | 2 +-
5 files changed, 90 insertions(+), 41 deletions(-)
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt
diff --git a/packages/server/src/api/controllers/query/import/sources/base/index.ts b/packages/server/src/api/controllers/query/import/sources/base/index.ts
index f6a6b2b57c..747b7b3d66 100644
--- a/packages/server/src/api/controllers/query/import/sources/base/index.ts
+++ b/packages/server/src/api/controllers/query/import/sources/base/index.ts
@@ -54,6 +54,7 @@ export abstract class ImportSource {
const transformer = "return data"
const schema = {}
path = this.processPath(path)
+ queryString = this.processQuery(queryString)
const query: Query = {
datasourceId,
@@ -89,4 +90,12 @@ export abstract class ImportSource {
return path
}
+
+ processQuery = (queryString: string): string => {
+ if (queryString?.startsWith("?")) {
+ return queryString.substring(1)
+ }
+
+ return queryString
+ }
}
diff --git a/packages/server/src/api/controllers/query/import/sources/curl.ts b/packages/server/src/api/controllers/query/import/sources/curl.ts
index b5a3e624d9..6dbbe012af 100644
--- a/packages/server/src/api/controllers/query/import/sources/curl.ts
+++ b/packages/server/src/api/controllers/query/import/sources/curl.ts
@@ -7,6 +7,25 @@ const parseCurl = (data: string): any => {
return JSON.parse(curlJson)
}
+/**
+ * The curl converter parses the request body into the key field of an object
+ * e.g. --d '{"key":"val"}' produces an object { "{"key":"val"}" : "" }
+ */
+const parseBody = (curl: any) => {
+ if (curl.data) {
+ const keys = Object.keys(curl.data)
+ if (keys.length) {
+ const key = keys[0]
+ try {
+ return JSON.parse(key)
+ } catch (e) {
+ // do nothing
+ }
+ }
+ }
+ return undefined
+}
+
/**
* Curl
* https://curl.se/docs/manpage.html
@@ -33,12 +52,13 @@ export class Curl extends ImportSource {
}
getQueries = async (datasourceId: string): Promise => {
- const url = new URL(this.curl.url)
+ const url = new URL(this.curl.raw_url)
const name = url.pathname
const path = url.pathname
const method = this.curl.method
const queryString = url.search
const headers = this.curl.headers
+ const requestBody = parseBody(this.curl)
const query = this.constructQuery(
datasourceId,
@@ -46,7 +66,9 @@ export class Curl extends ImportSource {
method,
path,
queryString,
- headers
+ headers,
+ [],
+ requestBody
)
return [query]
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js
index 6fc6008b0d..0ce8465277 100644
--- a/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js
@@ -1,26 +1,11 @@
-// const Airtable = require("airtable")
-// const AirtableIntegration = require("../airtable")
const { Curl } = require("../../curl")
const fs = require("fs")
const path = require('path')
-jest.mock("airtable")
-
-// class TestConfiguration {
-// constructor(config = {}) {
-// this.integration = new AirtableIntegration.integration(config)
-// this.client = {
-// create: jest.fn(),
-// select: jest.fn(),
-// update: jest.fn(),
-// destroy: jest.fn(),
-// }
-// this.integration.client = () => this.client
-// }
-// }
const getData = (file) => {
return fs.readFileSync(path.join(__dirname, `./data/${file}.txt`), "utf8")
}
+
describe("Curl Import", () => {
let curl
@@ -43,46 +28,77 @@ describe("Curl Import", () => {
expect(supported).toBe(false)
})
+ const init = async (file) => {
+ await curl.isSupported(getData(file))
+ }
+
it("returns import info", async () => {
- const data = getData()
- await curl.isSupported(data)
+ await init("get")
const info = await curl.getInfo()
expect(info.url).toBe("http://example.com")
expect(info.name).toBe("example.com")
})
describe("Returns queries", () => {
- describe("populates verb", () => {
- const testVerb = async (file, verb) => {
- const data = getData(file)
- await curl.isSupported(data)
- const queries = await curl.getQueries(data)
- expect(queries.length).toBe(1)
- expect(queries[0].verb).toBe(verb)
- }
- it("populates verb", async () => {
- await testVerb("get", "read")
- await testVerb("post", "create")
- await testVerb("put", "update")
- await testVerb("delete", "delete")
- await testVerb("patch", "patch")
- })
- })
+
+ const getQueries = async (file) => {
+ await init(file)
+ const queries = await curl.getQueries()
+ expect(queries.length).toBe(1)
+ return queries
+ }
+
+ const testVerb = async (file, verb) => {
+ const queries = await getQueries(file)
+ expect(queries[0].queryVerb).toBe(verb)
+ }
+
+ it("populates verb", async () => {
+ await testVerb("get", "read")
+ await testVerb("post", "create")
+ await testVerb("put", "update")
+ await testVerb("delete", "delete")
+ await testVerb("patch", "patch")
+ })
+
+ const testPath = async (file, urlPath) => {
+ const queries = await getQueries(file)
+ expect(queries[0].fields.path).toBe(urlPath)
+ }
it("populates path", async () => {
-
+ await testPath("get", "")
+ await testPath("path", "paths/abc")
})
+ const testHeaders = async (file, headers) => {
+ const queries = await getQueries(file)
+ expect(queries[0].fields.headers).toStrictEqual(headers)
+ }
+
it("populates headers", async () => {
-
+ await testHeaders("get", {})
+ await testHeaders("headers", { "x-bb-header-1" : "123", "x-bb-header-2" : "456"} )
})
+ const testQuery = async (file, queryString) => {
+ const queries = await getQueries(file)
+ expect(queries[0].fields.queryString).toBe(queryString)
+ }
it("populates query", async () => {
-
+ await testQuery("get", "")
+ await testQuery("query", "q1=v1&q1=v2")
})
+ const testBody = async (file, queryString) => {
+ const queries = await getQueries(file)
+ expect(queries[0].fields.requestBody).toStrictEqual(queryString)
+ }
+
it("populates body", async () => {
-
+ await testBody("get", undefined)
+ await testBody("post", { "key" : "val" })
+ await testBody("empty-body", {})
})
})
})
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt
new file mode 100644
index 0000000000..3ae78cea6f
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/empty-body.txt
@@ -0,0 +1,2 @@
+curl -X POST 'http://example.com' \
+ --data-raw '{}'
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/headers.txt b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/headers.txt
index aba6d05cbf..82ca16f496 100644
--- a/packages/server/src/api/controllers/query/import/sources/tests/curl/data/headers.txt
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/data/headers.txt
@@ -1,3 +1,3 @@
curl 'http://example.com' \
-H 'x-bb-header-1: 123' \
- -H 'x-bb-header-2: 1456'
\ No newline at end of file
+ -H 'x-bb-header-2: 456'
\ No newline at end of file
From fd1b762410e7421f338edae3e43f7ba904bbb744 Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Wed, 1 Dec 2021 13:40:40 +0000
Subject: [PATCH 08/30] start swagger tests
---
.../controllers/query/import/sources/curl.ts | 1 +
.../tests/openapi2/data/crud/crud.json | 969 +++++++++++++++
.../openapi2/data/petstore/petstore.json | 1054 +++++++++++++++++
.../openapi2/data/petstore/petstore.yaml | 711 +++++++++++
.../sources/tests/openapi2/openapi2.spec.js | 113 ++
5 files changed, 2848 insertions(+)
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml
diff --git a/packages/server/src/api/controllers/query/import/sources/curl.ts b/packages/server/src/api/controllers/query/import/sources/curl.ts
index 6dbbe012af..6b8b6c3425 100644
--- a/packages/server/src/api/controllers/query/import/sources/curl.ts
+++ b/packages/server/src/api/controllers/query/import/sources/curl.ts
@@ -10,6 +10,7 @@ const parseCurl = (data: string): any => {
/**
* The curl converter parses the request body into the key field of an object
* e.g. --d '{"key":"val"}' produces an object { "{"key":"val"}" : "" }
+ * This is not what we want, so we need to parse out the key from the object
*/
const parseBody = (curl: any) => {
if (curl.data) {
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json
new file mode 100644
index 0000000000..ed16af32bd
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json
@@ -0,0 +1,969 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "description": "A basic swagger file",
+ "version": "1.0.0",
+ "title": "CRUD"
+ },
+ "host": "example.com",
+ "tags": [
+ {
+ "name": "entity"
+ }
+ ],
+ "schemes": [
+ "http"
+ ],
+ "paths": {
+ "/entities": {
+ "post": {
+ "tags": [
+ "entity"
+ ],
+ "operationId": "create",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "schema": {
+ "$ref": "#/definitions/CreateEntity"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/ApiResponse"
+ }
+ }
+ },
+ "security": [
+ {
+ "auth": [
+ "write:entities",
+ "read:entites"
+ ]
+ }
+ ]
+ }
+ },
+ "/pet": {
+ "put": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Update an existing pet",
+ "description": "",
+ "operationId": "updatePet",
+ "consumes": [
+ "application/json",
+ "application/xml"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "Pet object that needs to be added to the store",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/Pet"
+ }
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "404": {
+ "description": "Pet not found"
+ },
+ "405": {
+ "description": "Validation exception"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/pet/findByStatus": {
+ "get": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Finds Pets by status",
+ "description": "Multiple status values can be provided with comma separated strings",
+ "operationId": "findPetsByStatus",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "status",
+ "in": "query",
+ "description": "Status values that need to be considered for filter",
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "available",
+ "pending",
+ "sold"
+ ],
+ "default": "available"
+ },
+ "collectionFormat": "multi"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Pet"
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid status value"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/pet/findByTags": {
+ "get": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Finds Pets by tags",
+ "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
+ "operationId": "findPetsByTags",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "tags",
+ "in": "query",
+ "description": "Tags to filter by",
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "collectionFormat": "multi"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Pet"
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid tag value"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ],
+ "deprecated": true
+ }
+ },
+ "/pet/{petId}": {
+ "get": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Find pet by ID",
+ "description": "Returns a single pet",
+ "operationId": "getPetById",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "petId",
+ "in": "path",
+ "description": "ID of pet to return",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/Pet"
+ }
+ },
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "404": {
+ "description": "Pet not found"
+ }
+ },
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ },
+ "post": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Updates a pet in the store with form data",
+ "description": "",
+ "operationId": "updatePetWithForm",
+ "consumes": [
+ "application/x-www-form-urlencoded"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "petId",
+ "in": "path",
+ "description": "ID of pet that needs to be updated",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "name",
+ "in": "formData",
+ "description": "Updated name of the pet",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "status",
+ "in": "formData",
+ "description": "Updated status of the pet",
+ "required": false,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "405": {
+ "description": "Invalid input"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Deletes a pet",
+ "description": "",
+ "operationId": "deletePet",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "api_key",
+ "in": "header",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "petId",
+ "in": "path",
+ "description": "Pet id to delete",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "404": {
+ "description": "Pet not found"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/store/inventory": {
+ "get": {
+ "tags": [
+ "store"
+ ],
+ "summary": "Returns pet inventories by status",
+ "description": "Returns a map of status codes to quantities",
+ "operationId": "getInventory",
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer",
+ "format": "int32"
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ }
+ },
+ "/store/order": {
+ "post": {
+ "tags": [
+ "store"
+ ],
+ "summary": "Place an order for a pet",
+ "description": "",
+ "operationId": "placeOrder",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "order placed for purchasing the pet",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/Order"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/Order"
+ }
+ },
+ "400": {
+ "description": "Invalid Order"
+ }
+ }
+ }
+ },
+ "/store/order/{orderId}": {
+ "get": {
+ "tags": [
+ "store"
+ ],
+ "summary": "Find purchase order by ID",
+ "description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions",
+ "operationId": "getOrderById",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "orderId",
+ "in": "path",
+ "description": "ID of pet that needs to be fetched",
+ "required": true,
+ "type": "integer",
+ "maximum": 10,
+ "minimum": 1,
+ "format": "int64"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/Order"
+ }
+ },
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "404": {
+ "description": "Order not found"
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "store"
+ ],
+ "summary": "Delete purchase order by ID",
+ "description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors",
+ "operationId": "deleteOrder",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "orderId",
+ "in": "path",
+ "description": "ID of the order that needs to be deleted",
+ "required": true,
+ "type": "integer",
+ "minimum": 1,
+ "format": "int64"
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "404": {
+ "description": "Order not found"
+ }
+ }
+ }
+ },
+ "/user/createWithList": {
+ "post": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Creates list of users with given input array",
+ "description": "",
+ "operationId": "createUsersWithListInput",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "List of user object",
+ "required": true,
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/User"
+ }
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ }
+ }
+ },
+ "/user/{username}": {
+ "get": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Get user by user name",
+ "description": "",
+ "operationId": "getUserByName",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "username",
+ "in": "path",
+ "description": "The name that needs to be fetched. Use user1 for testing. ",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/User"
+ }
+ },
+ "400": {
+ "description": "Invalid username supplied"
+ },
+ "404": {
+ "description": "User not found"
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Updated user",
+ "description": "This can only be done by the logged in user.",
+ "operationId": "updateUser",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "username",
+ "in": "path",
+ "description": "name that need to be updated",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "Updated user object",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/User"
+ }
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid user supplied"
+ },
+ "404": {
+ "description": "User not found"
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Delete user",
+ "description": "This can only be done by the logged in user.",
+ "operationId": "deleteUser",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "username",
+ "in": "path",
+ "description": "The name that needs to be deleted",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid username supplied"
+ },
+ "404": {
+ "description": "User not found"
+ }
+ }
+ }
+ },
+ "/user/login": {
+ "get": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Logs user into the system",
+ "description": "",
+ "operationId": "loginUser",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "username",
+ "in": "query",
+ "description": "The user name for login",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "password",
+ "in": "query",
+ "description": "The password for login in clear text",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "headers": {
+ "X-Expires-After": {
+ "type": "string",
+ "format": "date-time",
+ "description": "date in UTC when token expires"
+ },
+ "X-Rate-Limit": {
+ "type": "integer",
+ "format": "int32",
+ "description": "calls per hour allowed by the user"
+ }
+ },
+ "schema": {
+ "type": "string"
+ }
+ },
+ "400": {
+ "description": "Invalid username/password supplied"
+ }
+ }
+ }
+ },
+ "/user/logout": {
+ "get": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Logs out current logged in user session",
+ "description": "",
+ "operationId": "logoutUser",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [],
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ }
+ }
+ },
+ "/user/createWithArray": {
+ "post": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Creates list of users with given input array",
+ "description": "",
+ "operationId": "createUsersWithArrayInput",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "List of user object",
+ "required": true,
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/User"
+ }
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ }
+ }
+ },
+ "/user": {
+ "post": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Create user",
+ "description": "This can only be done by the logged in user.",
+ "operationId": "createUser",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "Created user object",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/User"
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ }
+ }
+ }
+ },
+ "securityDefinitions": {
+ "api_key": {
+ "type": "apiKey",
+ "name": "api_key",
+ "in": "header"
+ },
+ "petstore_auth": {
+ "type": "oauth2",
+ "authorizationUrl": "https://petstore.swagger.io/oauth/authorize",
+ "flow": "implicit",
+ "scopes": {
+ "read:pets": "read your pets",
+ "write:pets": "modify pets in your account"
+ }
+ }
+ },
+ "definitions": {
+ "ApiResponse": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "type": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ }
+ }
+ },
+ "Category": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "name": {
+ "type": "string"
+ }
+ },
+ "xml": {
+ "name": "Category"
+ }
+ },
+ "Pet": {
+ "type": "object",
+ "required": [
+ "name",
+ "photoUrls"
+ ],
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "category": {
+ "$ref": "#/definitions/Category"
+ },
+ "name": {
+ "type": "string",
+ "example": "doggie"
+ },
+ "photoUrls": {
+ "type": "array",
+ "xml": {
+ "wrapped": true
+ },
+ "items": {
+ "type": "string",
+ "xml": {
+ "name": "photoUrl"
+ }
+ }
+ },
+ "tags": {
+ "type": "array",
+ "xml": {
+ "wrapped": true
+ },
+ "items": {
+ "xml": {
+ "name": "tag"
+ },
+ "$ref": "#/definitions/Tag"
+ }
+ },
+ "status": {
+ "type": "string",
+ "description": "pet status in the store",
+ "enum": [
+ "available",
+ "pending",
+ "sold"
+ ]
+ }
+ },
+ "xml": {
+ "name": "Pet"
+ }
+ },
+ "Tag": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "name": {
+ "type": "string"
+ }
+ },
+ "xml": {
+ "name": "Tag"
+ }
+ },
+ "Order": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "petId": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "quantity": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "shipDate": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "status": {
+ "type": "string",
+ "description": "Order Status",
+ "enum": [
+ "placed",
+ "approved",
+ "delivered"
+ ]
+ },
+ "complete": {
+ "type": "boolean"
+ }
+ },
+ "xml": {
+ "name": "Order"
+ }
+ },
+ "User": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "username": {
+ "type": "string"
+ },
+ "firstName": {
+ "type": "string"
+ },
+ "lastName": {
+ "type": "string"
+ },
+ "email": {
+ "type": "string"
+ },
+ "password": {
+ "type": "string"
+ },
+ "phone": {
+ "type": "string"
+ },
+ "userStatus": {
+ "type": "integer",
+ "format": "int32",
+ "description": "User Status"
+ }
+ },
+ "xml": {
+ "name": "User"
+ }
+ }
+ },
+ "externalDocs": {
+ "description": "Find out more about Swagger",
+ "url": "http://swagger.io"
+ }
+}
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json
new file mode 100644
index 0000000000..6cbd65f3db
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json
@@ -0,0 +1,1054 @@
+{
+ "swagger": "2.0",
+ "info": {
+ "description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
+ "version": "1.0.5",
+ "title": "Swagger Petstore",
+ "termsOfService": "http://swagger.io/terms/",
+ "contact": {
+ "email": "apiteam@swagger.io"
+ },
+ "license": {
+ "name": "Apache 2.0",
+ "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
+ }
+ },
+ "host": "petstore.swagger.io",
+ "basePath": "/v2",
+ "tags": [
+ {
+ "name": "pet",
+ "description": "Everything about your Pets",
+ "externalDocs": {
+ "description": "Find out more",
+ "url": "http://swagger.io"
+ }
+ },
+ {
+ "name": "store",
+ "description": "Access to Petstore orders"
+ },
+ {
+ "name": "user",
+ "description": "Operations about user",
+ "externalDocs": {
+ "description": "Find out more about our store",
+ "url": "http://swagger.io"
+ }
+ }
+ ],
+ "schemes": [
+ "https",
+ "http"
+ ],
+ "paths": {
+ "/pet/{petId}/uploadImage": {
+ "post": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "uploads an image",
+ "description": "",
+ "operationId": "uploadFile",
+ "consumes": [
+ "multipart/form-data"
+ ],
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [
+ {
+ "name": "petId",
+ "in": "path",
+ "description": "ID of pet to update",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "additionalMetadata",
+ "in": "formData",
+ "description": "Additional data to pass to server",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "file",
+ "in": "formData",
+ "description": "file to upload",
+ "required": false,
+ "type": "file"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/ApiResponse"
+ }
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/pet": {
+ "post": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Add a new pet to the store",
+ "description": "",
+ "operationId": "addPet",
+ "consumes": [
+ "application/json",
+ "application/xml"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "Pet object that needs to be added to the store",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/Pet"
+ }
+ }
+ ],
+ "responses": {
+ "405": {
+ "description": "Invalid input"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ },
+ "put": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Update an existing pet",
+ "description": "",
+ "operationId": "updatePet",
+ "consumes": [
+ "application/json",
+ "application/xml"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "Pet object that needs to be added to the store",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/Pet"
+ }
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "404": {
+ "description": "Pet not found"
+ },
+ "405": {
+ "description": "Validation exception"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/pet/findByStatus": {
+ "get": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Finds Pets by status",
+ "description": "Multiple status values can be provided with comma separated strings",
+ "operationId": "findPetsByStatus",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "status",
+ "in": "query",
+ "description": "Status values that need to be considered for filter",
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "available",
+ "pending",
+ "sold"
+ ],
+ "default": "available"
+ },
+ "collectionFormat": "multi"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Pet"
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid status value"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/pet/findByTags": {
+ "get": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Finds Pets by tags",
+ "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
+ "operationId": "findPetsByTags",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "tags",
+ "in": "query",
+ "description": "Tags to filter by",
+ "required": true,
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "collectionFormat": "multi"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Pet"
+ }
+ }
+ },
+ "400": {
+ "description": "Invalid tag value"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ],
+ "deprecated": true
+ }
+ },
+ "/pet/{petId}": {
+ "get": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Find pet by ID",
+ "description": "Returns a single pet",
+ "operationId": "getPetById",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "petId",
+ "in": "path",
+ "description": "ID of pet to return",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/Pet"
+ }
+ },
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "404": {
+ "description": "Pet not found"
+ }
+ },
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ },
+ "post": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Updates a pet in the store with form data",
+ "description": "",
+ "operationId": "updatePetWithForm",
+ "consumes": [
+ "application/x-www-form-urlencoded"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "petId",
+ "in": "path",
+ "description": "ID of pet that needs to be updated",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ },
+ {
+ "name": "name",
+ "in": "formData",
+ "description": "Updated name of the pet",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "status",
+ "in": "formData",
+ "description": "Updated status of the pet",
+ "required": false,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "405": {
+ "description": "Invalid input"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ },
+ "delete": {
+ "tags": [
+ "pet"
+ ],
+ "summary": "Deletes a pet",
+ "description": "",
+ "operationId": "deletePet",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "api_key",
+ "in": "header",
+ "required": false,
+ "type": "string"
+ },
+ {
+ "name": "petId",
+ "in": "path",
+ "description": "Pet id to delete",
+ "required": true,
+ "type": "integer",
+ "format": "int64"
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "404": {
+ "description": "Pet not found"
+ }
+ },
+ "security": [
+ {
+ "petstore_auth": [
+ "write:pets",
+ "read:pets"
+ ]
+ }
+ ]
+ }
+ },
+ "/store/inventory": {
+ "get": {
+ "tags": [
+ "store"
+ ],
+ "summary": "Returns pet inventories by status",
+ "description": "Returns a map of status codes to quantities",
+ "operationId": "getInventory",
+ "produces": [
+ "application/json"
+ ],
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer",
+ "format": "int32"
+ }
+ }
+ }
+ },
+ "security": [
+ {
+ "api_key": []
+ }
+ ]
+ }
+ },
+ "/store/order": {
+ "post": {
+ "tags": [
+ "store"
+ ],
+ "summary": "Place an order for a pet",
+ "description": "",
+ "operationId": "placeOrder",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "order placed for purchasing the pet",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/Order"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/Order"
+ }
+ },
+ "400": {
+ "description": "Invalid Order"
+ }
+ }
+ }
+ },
+ "/store/order/{orderId}": {
+ "get": {
+ "tags": [
+ "store"
+ ],
+ "summary": "Find purchase order by ID",
+ "description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions",
+ "operationId": "getOrderById",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "orderId",
+ "in": "path",
+ "description": "ID of pet that needs to be fetched",
+ "required": true,
+ "type": "integer",
+ "maximum": 10,
+ "minimum": 1,
+ "format": "int64"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/Order"
+ }
+ },
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "404": {
+ "description": "Order not found"
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "store"
+ ],
+ "summary": "Delete purchase order by ID",
+ "description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors",
+ "operationId": "deleteOrder",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "orderId",
+ "in": "path",
+ "description": "ID of the order that needs to be deleted",
+ "required": true,
+ "type": "integer",
+ "minimum": 1,
+ "format": "int64"
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid ID supplied"
+ },
+ "404": {
+ "description": "Order not found"
+ }
+ }
+ }
+ },
+ "/user/createWithList": {
+ "post": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Creates list of users with given input array",
+ "description": "",
+ "operationId": "createUsersWithListInput",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "List of user object",
+ "required": true,
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/User"
+ }
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ }
+ }
+ },
+ "/user/{username}": {
+ "get": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Get user by user name",
+ "description": "",
+ "operationId": "getUserByName",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "username",
+ "in": "path",
+ "description": "The name that needs to be fetched. Use user1 for testing. ",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/User"
+ }
+ },
+ "400": {
+ "description": "Invalid username supplied"
+ },
+ "404": {
+ "description": "User not found"
+ }
+ }
+ },
+ "put": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Updated user",
+ "description": "This can only be done by the logged in user.",
+ "operationId": "updateUser",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "username",
+ "in": "path",
+ "description": "name that need to be updated",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "body",
+ "name": "body",
+ "description": "Updated user object",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/User"
+ }
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid user supplied"
+ },
+ "404": {
+ "description": "User not found"
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Delete user",
+ "description": "This can only be done by the logged in user.",
+ "operationId": "deleteUser",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "username",
+ "in": "path",
+ "description": "The name that needs to be deleted",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "400": {
+ "description": "Invalid username supplied"
+ },
+ "404": {
+ "description": "User not found"
+ }
+ }
+ }
+ },
+ "/user/login": {
+ "get": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Logs user into the system",
+ "description": "",
+ "operationId": "loginUser",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "name": "username",
+ "in": "query",
+ "description": "The user name for login",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "name": "password",
+ "in": "query",
+ "description": "The password for login in clear text",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "headers": {
+ "X-Expires-After": {
+ "type": "string",
+ "format": "date-time",
+ "description": "date in UTC when token expires"
+ },
+ "X-Rate-Limit": {
+ "type": "integer",
+ "format": "int32",
+ "description": "calls per hour allowed by the user"
+ }
+ },
+ "schema": {
+ "type": "string"
+ }
+ },
+ "400": {
+ "description": "Invalid username/password supplied"
+ }
+ }
+ }
+ },
+ "/user/logout": {
+ "get": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Logs out current logged in user session",
+ "description": "",
+ "operationId": "logoutUser",
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [],
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ }
+ }
+ },
+ "/user/createWithArray": {
+ "post": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Creates list of users with given input array",
+ "description": "",
+ "operationId": "createUsersWithArrayInput",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "List of user object",
+ "required": true,
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/User"
+ }
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ }
+ }
+ },
+ "/user": {
+ "post": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Create user",
+ "description": "This can only be done by the logged in user.",
+ "operationId": "createUser",
+ "consumes": [
+ "application/json"
+ ],
+ "produces": [
+ "application/json",
+ "application/xml"
+ ],
+ "parameters": [
+ {
+ "in": "body",
+ "name": "body",
+ "description": "Created user object",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/User"
+ }
+ }
+ ],
+ "responses": {
+ "default": {
+ "description": "successful operation"
+ }
+ }
+ }
+ }
+ },
+ "securityDefinitions": {
+ "api_key": {
+ "type": "apiKey",
+ "name": "api_key",
+ "in": "header"
+ },
+ "petstore_auth": {
+ "type": "oauth2",
+ "authorizationUrl": "https://petstore.swagger.io/oauth/authorize",
+ "flow": "implicit",
+ "scopes": {
+ "read:pets": "read your pets",
+ "write:pets": "modify pets in your account"
+ }
+ }
+ },
+ "definitions": {
+ "ApiResponse": {
+ "type": "object",
+ "properties": {
+ "code": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "type": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ }
+ }
+ },
+ "Category": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "name": {
+ "type": "string"
+ }
+ },
+ "xml": {
+ "name": "Category"
+ }
+ },
+ "Pet": {
+ "type": "object",
+ "required": [
+ "name",
+ "photoUrls"
+ ],
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "category": {
+ "$ref": "#/definitions/Category"
+ },
+ "name": {
+ "type": "string",
+ "example": "doggie"
+ },
+ "photoUrls": {
+ "type": "array",
+ "xml": {
+ "wrapped": true
+ },
+ "items": {
+ "type": "string",
+ "xml": {
+ "name": "photoUrl"
+ }
+ }
+ },
+ "tags": {
+ "type": "array",
+ "xml": {
+ "wrapped": true
+ },
+ "items": {
+ "xml": {
+ "name": "tag"
+ },
+ "$ref": "#/definitions/Tag"
+ }
+ },
+ "status": {
+ "type": "string",
+ "description": "pet status in the store",
+ "enum": [
+ "available",
+ "pending",
+ "sold"
+ ]
+ }
+ },
+ "xml": {
+ "name": "Pet"
+ }
+ },
+ "Tag": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "name": {
+ "type": "string"
+ }
+ },
+ "xml": {
+ "name": "Tag"
+ }
+ },
+ "Order": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "petId": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "quantity": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "shipDate": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "status": {
+ "type": "string",
+ "description": "Order Status",
+ "enum": [
+ "placed",
+ "approved",
+ "delivered"
+ ]
+ },
+ "complete": {
+ "type": "boolean"
+ }
+ },
+ "xml": {
+ "name": "Order"
+ }
+ },
+ "User": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "username": {
+ "type": "string"
+ },
+ "firstName": {
+ "type": "string"
+ },
+ "lastName": {
+ "type": "string"
+ },
+ "email": {
+ "type": "string"
+ },
+ "password": {
+ "type": "string"
+ },
+ "phone": {
+ "type": "string"
+ },
+ "userStatus": {
+ "type": "integer",
+ "format": "int32",
+ "description": "User Status"
+ }
+ },
+ "xml": {
+ "name": "User"
+ }
+ }
+ },
+ "externalDocs": {
+ "description": "Find out more about Swagger",
+ "url": "http://swagger.io"
+ }
+}
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml
new file mode 100644
index 0000000000..0087b5aba1
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.yaml
@@ -0,0 +1,711 @@
+swagger: "2.0"
+info:
+ description: "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters."
+ version: 1.0.5
+ title: Swagger Petstore
+ termsOfService: http://swagger.io/terms/
+ contact:
+ email: apiteam@swagger.io
+ license:
+ name: Apache 2.0
+ url: http://www.apache.org/licenses/LICENSE-2.0.html
+host: petstore.swagger.io
+basePath: /v2
+tags:
+ - name: pet
+ description: Everything about your Pets
+ externalDocs:
+ description: Find out more
+ url: http://swagger.io
+ - name: store
+ description: Access to Petstore orders
+ - name: user
+ description: Operations about user
+ externalDocs:
+ description: Find out more about our store
+ url: http://swagger.io
+schemes:
+ - https
+ - http
+paths:
+ /pet/{petId}/uploadImage:
+ post:
+ tags:
+ - pet
+ summary: uploads an image
+ description: ""
+ operationId: uploadFile
+ consumes:
+ - multipart/form-data
+ produces:
+ - application/json
+ parameters:
+ - name: petId
+ in: path
+ description: ID of pet to update
+ required: true
+ type: integer
+ format: int64
+ - name: additionalMetadata
+ in: formData
+ description: Additional data to pass to server
+ required: false
+ type: string
+ - name: file
+ in: formData
+ description: file to upload
+ required: false
+ type: file
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ $ref: "#/definitions/ApiResponse"
+ security:
+ - petstore_auth:
+ - write:pets
+ - read:pets
+ /pet:
+ post:
+ tags:
+ - pet
+ summary: Add a new pet to the store
+ description: ""
+ operationId: addPet
+ consumes:
+ - application/json
+ - application/xml
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - in: body
+ name: body
+ description: Pet object that needs to be added to the store
+ required: true
+ schema:
+ $ref: "#/definitions/Pet"
+ responses:
+ "405":
+ description: Invalid input
+ security:
+ - petstore_auth:
+ - write:pets
+ - read:pets
+ put:
+ tags:
+ - pet
+ summary: Update an existing pet
+ description: ""
+ operationId: updatePet
+ consumes:
+ - application/json
+ - application/xml
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - in: body
+ name: body
+ description: Pet object that needs to be added to the store
+ required: true
+ schema:
+ $ref: "#/definitions/Pet"
+ responses:
+ "400":
+ description: Invalid ID supplied
+ "404":
+ description: Pet not found
+ "405":
+ description: Validation exception
+ security:
+ - petstore_auth:
+ - write:pets
+ - read:pets
+ /pet/findByStatus:
+ get:
+ tags:
+ - pet
+ summary: Finds Pets by status
+ description: Multiple status values can be provided with comma separated strings
+ operationId: findPetsByStatus
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: status
+ in: query
+ description: Status values that need to be considered for filter
+ required: true
+ type: array
+ items:
+ type: string
+ enum:
+ - available
+ - pending
+ - sold
+ default: available
+ collectionFormat: multi
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ type: array
+ items:
+ $ref: "#/definitions/Pet"
+ "400":
+ description: Invalid status value
+ security:
+ - petstore_auth:
+ - write:pets
+ - read:pets
+ /pet/findByTags:
+ get:
+ tags:
+ - pet
+ summary: Finds Pets by tags
+ description: Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+ operationId: findPetsByTags
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: tags
+ in: query
+ description: Tags to filter by
+ required: true
+ type: array
+ items:
+ type: string
+ collectionFormat: multi
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ type: array
+ items:
+ $ref: "#/definitions/Pet"
+ "400":
+ description: Invalid tag value
+ security:
+ - petstore_auth:
+ - write:pets
+ - read:pets
+ deprecated: true
+ /pet/{petId}:
+ get:
+ tags:
+ - pet
+ summary: Find pet by ID
+ description: Returns a single pet
+ operationId: getPetById
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: petId
+ in: path
+ description: ID of pet to return
+ required: true
+ type: integer
+ format: int64
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ $ref: "#/definitions/Pet"
+ "400":
+ description: Invalid ID supplied
+ "404":
+ description: Pet not found
+ security:
+ - api_key: []
+ post:
+ tags:
+ - pet
+ summary: Updates a pet in the store with form data
+ description: ""
+ operationId: updatePetWithForm
+ consumes:
+ - application/x-www-form-urlencoded
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: petId
+ in: path
+ description: ID of pet that needs to be updated
+ required: true
+ type: integer
+ format: int64
+ - name: name
+ in: formData
+ description: Updated name of the pet
+ required: false
+ type: string
+ - name: status
+ in: formData
+ description: Updated status of the pet
+ required: false
+ type: string
+ responses:
+ "405":
+ description: Invalid input
+ security:
+ - petstore_auth:
+ - write:pets
+ - read:pets
+ delete:
+ tags:
+ - pet
+ summary: Deletes a pet
+ description: ""
+ operationId: deletePet
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: api_key
+ in: header
+ required: false
+ type: string
+ - name: petId
+ in: path
+ description: Pet id to delete
+ required: true
+ type: integer
+ format: int64
+ responses:
+ "400":
+ description: Invalid ID supplied
+ "404":
+ description: Pet not found
+ security:
+ - petstore_auth:
+ - write:pets
+ - read:pets
+ /store/inventory:
+ get:
+ tags:
+ - store
+ summary: Returns pet inventories by status
+ description: Returns a map of status codes to quantities
+ operationId: getInventory
+ produces:
+ - application/json
+ parameters: []
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ type: object
+ additionalProperties:
+ type: integer
+ format: int32
+ security:
+ - api_key: []
+ /store/order:
+ post:
+ tags:
+ - store
+ summary: Place an order for a pet
+ description: ""
+ operationId: placeOrder
+ consumes:
+ - application/json
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - in: body
+ name: body
+ description: order placed for purchasing the pet
+ required: true
+ schema:
+ $ref: "#/definitions/Order"
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ $ref: "#/definitions/Order"
+ "400":
+ description: Invalid Order
+ /store/order/{orderId}:
+ get:
+ tags:
+ - store
+ summary: Find purchase order by ID
+ description: For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions
+ operationId: getOrderById
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: orderId
+ in: path
+ description: ID of pet that needs to be fetched
+ required: true
+ type: integer
+ maximum: 10
+ minimum: 1
+ format: int64
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ $ref: "#/definitions/Order"
+ "400":
+ description: Invalid ID supplied
+ "404":
+ description: Order not found
+ delete:
+ tags:
+ - store
+ summary: Delete purchase order by ID
+ description: For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors
+ operationId: deleteOrder
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: orderId
+ in: path
+ description: ID of the order that needs to be deleted
+ required: true
+ type: integer
+ minimum: 1
+ format: int64
+ responses:
+ "400":
+ description: Invalid ID supplied
+ "404":
+ description: Order not found
+ /user/createWithList:
+ post:
+ tags:
+ - user
+ summary: Creates list of users with given input array
+ description: ""
+ operationId: createUsersWithListInput
+ consumes:
+ - application/json
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - in: body
+ name: body
+ description: List of user object
+ required: true
+ schema:
+ type: array
+ items:
+ $ref: "#/definitions/User"
+ responses:
+ default:
+ description: successful operation
+ /user/{username}:
+ get:
+ tags:
+ - user
+ summary: Get user by user name
+ description: ""
+ operationId: getUserByName
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: username
+ in: path
+ description: "The name that needs to be fetched. Use user1 for testing. "
+ required: true
+ type: string
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ $ref: "#/definitions/User"
+ "400":
+ description: Invalid username supplied
+ "404":
+ description: User not found
+ put:
+ tags:
+ - user
+ summary: Updated user
+ description: This can only be done by the logged in user.
+ operationId: updateUser
+ consumes:
+ - application/json
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: username
+ in: path
+ description: name that need to be updated
+ required: true
+ type: string
+ - in: body
+ name: body
+ description: Updated user object
+ required: true
+ schema:
+ $ref: "#/definitions/User"
+ responses:
+ "400":
+ description: Invalid user supplied
+ "404":
+ description: User not found
+ delete:
+ tags:
+ - user
+ summary: Delete user
+ description: This can only be done by the logged in user.
+ operationId: deleteUser
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: username
+ in: path
+ description: The name that needs to be deleted
+ required: true
+ type: string
+ responses:
+ "400":
+ description: Invalid username supplied
+ "404":
+ description: User not found
+ /user/login:
+ get:
+ tags:
+ - user
+ summary: Logs user into the system
+ description: ""
+ operationId: loginUser
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - name: username
+ in: query
+ description: The user name for login
+ required: true
+ type: string
+ - name: password
+ in: query
+ description: The password for login in clear text
+ required: true
+ type: string
+ responses:
+ "200":
+ description: successful operation
+ headers:
+ X-Expires-After:
+ type: string
+ format: date-time
+ description: date in UTC when token expires
+ X-Rate-Limit:
+ type: integer
+ format: int32
+ description: calls per hour allowed by the user
+ schema:
+ type: string
+ "400":
+ description: Invalid username/password supplied
+ /user/logout:
+ get:
+ tags:
+ - user
+ summary: Logs out current logged in user session
+ description: ""
+ operationId: logoutUser
+ produces:
+ - application/json
+ - application/xml
+ parameters: []
+ responses:
+ default:
+ description: successful operation
+ /user/createWithArray:
+ post:
+ tags:
+ - user
+ summary: Creates list of users with given input array
+ description: ""
+ operationId: createUsersWithArrayInput
+ consumes:
+ - application/json
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - in: body
+ name: body
+ description: List of user object
+ required: true
+ schema:
+ type: array
+ items:
+ $ref: "#/definitions/User"
+ responses:
+ default:
+ description: successful operation
+ /user:
+ post:
+ tags:
+ - user
+ summary: Create user
+ description: This can only be done by the logged in user.
+ operationId: createUser
+ consumes:
+ - application/json
+ produces:
+ - application/json
+ - application/xml
+ parameters:
+ - in: body
+ name: body
+ description: Created user object
+ required: true
+ schema:
+ $ref: "#/definitions/User"
+ responses:
+ default:
+ description: successful operation
+securityDefinitions:
+ api_key:
+ type: apiKey
+ name: api_key
+ in: header
+ petstore_auth:
+ type: oauth2
+ authorizationUrl: https://petstore.swagger.io/oauth/authorize
+ flow: implicit
+ scopes:
+ read:pets: read your pets
+ write:pets: modify pets in your account
+definitions:
+ ApiResponse:
+ type: object
+ properties:
+ code:
+ type: integer
+ format: int32
+ type:
+ type: string
+ message:
+ type: string
+ Category:
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ xml:
+ name: Category
+ Pet:
+ type: object
+ required:
+ - name
+ - photoUrls
+ properties:
+ id:
+ type: integer
+ format: int64
+ category:
+ $ref: "#/definitions/Category"
+ name:
+ type: string
+ example: doggie
+ photoUrls:
+ type: array
+ xml:
+ wrapped: true
+ items:
+ type: string
+ xml:
+ name: photoUrl
+ tags:
+ type: array
+ xml:
+ wrapped: true
+ items:
+ xml:
+ name: tag
+ $ref: "#/definitions/Tag"
+ status:
+ type: string
+ description: pet status in the store
+ enum:
+ - available
+ - pending
+ - sold
+ xml:
+ name: Pet
+ Tag:
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ name:
+ type: string
+ xml:
+ name: Tag
+ Order:
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ petId:
+ type: integer
+ format: int64
+ quantity:
+ type: integer
+ format: int32
+ shipDate:
+ type: string
+ format: date-time
+ status:
+ type: string
+ description: Order Status
+ enum:
+ - placed
+ - approved
+ - delivered
+ complete:
+ type: boolean
+ xml:
+ name: Order
+ User:
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ username:
+ type: string
+ firstName:
+ type: string
+ lastName:
+ type: string
+ email:
+ type: string
+ password:
+ type: string
+ phone:
+ type: string
+ userStatus:
+ type: integer
+ format: int32
+ description: User Status
+ xml:
+ name: User
+externalDocs:
+ description: Find out more about Swagger
+ url: http://swagger.io
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js
index e69de29bb2..5b99360176 100644
--- a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js
+++ b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js
@@ -0,0 +1,113 @@
+const { OpenAPI2 } = require("../../openapi2")
+const fs = require("fs")
+const path = require('path')
+
+const getData = (file, extension) => {
+ return fs.readFileSync(path.join(__dirname, `./data/${file}/${file}.${extension}`), "utf8")
+}
+
+describe("OpenAPI2 Import", () => {
+ let openapi2
+
+ beforeEach(() => {
+ openapi2 = new OpenAPI2()
+ })
+
+ it("validates unsupported data", async () => {
+ let data
+ let supported
+
+ // non json / yaml
+ data = "curl http://example.com"
+ supported = await openapi2.isSupported(data)
+ expect(supported).toBe(false)
+
+ // Empty
+ data = ""
+ supported = await openapi2.isSupported(data)
+ expect(supported).toBe(false)
+ })
+
+ const init = async (file, extension) => {
+ await openapi2.isSupported(getData(file, extension))
+ }
+
+ const runTests = async (filename, test) => {
+ for (let extension of ["json", "yaml"]) {
+ await test(filename, extension)
+ }
+ }
+
+ const testImportInfo = async (file, extension) => {
+ await init(file, extension)
+ const info = await openapi2.getInfo()
+ expect(info.url).toBe("https://petstore.swagger.io/v2")
+ expect(info.name).toBe("Swagger Petstore")
+ }
+
+ it("returns import info", async () => {
+ await runTests("petstore", testImportInfo)
+ })
+
+ describe("Returns queries", () => {
+ const getQueries = async (file) => {
+ await init(file)
+ const queries = await openapi2.getQueries()
+ expect(queries.length).toBe(1)
+ return queries
+ }
+
+ const testVerb = async (file, verb) => {
+ const queries = await getQueries(file)
+ expect(queries[0].queryVerb).toBe(verb)
+ }
+
+ it("populates verb", async () => {
+ await testVerb("get", "read")
+ await testVerb("post", "create")
+ await testVerb("put", "update")
+ await testVerb("delete", "delete")
+ await testVerb("patch", "patch")
+ })
+
+ const testPath = async (file, urlPath) => {
+ const queries = await getQueries(file)
+ expect(queries[0].fields.path).toBe(urlPath)
+ }
+
+ it("populates path", async () => {
+ await testPath("get", "")
+ await testPath("path", "paths/abc")
+ })
+
+ const testHeaders = async (file, headers) => {
+ const queries = await getQueries(file)
+ expect(queries[0].fields.headers).toStrictEqual(headers)
+ }
+
+ it("populates headers", async () => {
+ await testHeaders("get", {})
+ await testHeaders("headers", { "x-bb-header-1" : "123", "x-bb-header-2" : "456"} )
+ })
+
+ const testQuery = async (file, queryString) => {
+ const queries = await getQueries(file)
+ expect(queries[0].fields.queryString).toBe(queryString)
+ }
+ it("populates query", async () => {
+ await testQuery("get", "")
+ await testQuery("query", "q1=v1&q1=v2")
+ })
+
+ const testBody = async (file, queryString) => {
+ const queries = await getQueries(file)
+ expect(queries[0].fields.requestBody).toStrictEqual(queryString)
+ }
+
+ it("populates body", async () => {
+ await testBody("get", undefined)
+ await testBody("post", { "key" : "val" })
+ await testBody("empty-body", {})
+ })
+ })
+})
\ No newline at end of file
From a5b86afa60f7a699862665d81e7830eb597a2ca5 Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Thu, 2 Dec 2021 11:55:13 +0000
Subject: [PATCH 09/30] OAPI2 (swagger) complete + tests
---
packages/server/package.json | 1 +
.../src/api/controllers/query/import/index.ts | 32 +-
.../query/import/sources/base/index.ts | 13 +-
.../query/import/sources/base/openapi.ts | 16 +-
.../query/import/sources/openapi2.ts | 103 +-
.../query/import/sources/openapi3.ts | 40 -
.../import/sources/tests/curl/curl.spec.js | 4 +-
.../tests/openapi2/data/crud/crud.json | 986 +++---------------
.../tests/openapi2/data/crud/crud.yaml | 160 +++
.../sources/tests/openapi2/openapi2.spec.js | 198 +++-
.../sources/tests/openapi3/openapi3.spec.js | 0
.../query/import/tests/index.spec.js | 115 ++
12 files changed, 694 insertions(+), 974 deletions(-)
delete mode 100644 packages/server/src/api/controllers/query/import/sources/openapi3.ts
create mode 100644 packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml
delete mode 100644 packages/server/src/api/controllers/query/import/sources/tests/openapi3/openapi3.spec.js
create mode 100644 packages/server/src/api/controllers/query/import/tests/index.spec.js
diff --git a/packages/server/package.json b/packages/server/package.json
index 63669e5b2f..046f07de7a 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -92,6 +92,7 @@
"fs-extra": "8.1.0",
"jimp": "0.16.1",
"joi": "17.2.1",
+ "js-yaml": "^4.1.0",
"jsonschema": "1.4.0",
"knex": "^0.95.6",
"koa": "2.7.0",
diff --git a/packages/server/src/api/controllers/query/import/index.ts b/packages/server/src/api/controllers/query/import/index.ts
index 808959798d..7f52fbb0a8 100644
--- a/packages/server/src/api/controllers/query/import/index.ts
+++ b/packages/server/src/api/controllers/query/import/index.ts
@@ -3,11 +3,11 @@ import { queryValidation } from "../validation"
import { generateQueryID } from "../../../../db/utils"
import { Query, ImportInfo, ImportSource } from "./sources/base"
import { OpenAPI2 } from "./sources/openapi2"
-import { OpenAPI3 } from "./sources/openapi3"
import { Curl } from "./sources/curl"
interface ImportResult {
errorQueries: Query[]
+ queries: Query[]
}
export class RestImporter {
@@ -17,7 +17,7 @@ export class RestImporter {
constructor(data: string) {
this.data = data
- this.sources = [new OpenAPI2(), new OpenAPI3(), new Curl()]
+ this.sources = [new OpenAPI2(), new Curl()]
}
init = async () => {
@@ -37,12 +37,11 @@ export class RestImporter {
appId: string,
datasourceId: string,
): Promise => {
-
// constuct the queries
let queries = await this.source.getQueries(datasourceId)
// validate queries
- const errorQueries = []
+ const errorQueries: Query[] = []
const schema = queryValidation()
queries = queries
.filter(query => {
@@ -57,19 +56,30 @@ export class RestImporter {
query._id = generateQueryID(query.datasourceId)
return query
})
-
+
// persist queries
const db = new CouchDB(appId)
- for (const query of queries) {
- try {
- await db.put(query)
- } catch (error) {
- errorQueries.push(query)
+ const response = await db.bulkDocs(queries)
+
+ // create index to seperate queries and errors
+ const queryIndex = queries.reduce((acc, query) => {
+ if (query._id) {
+ acc[query._id] = query
}
- }
+ return acc
+ }, ({} as { [key: string]: Query; }))
+
+ // check for failed writes
+ response.forEach((query: any) => {
+ if (!query.ok) {
+ errorQueries.push(queryIndex[query.id])
+ delete queryIndex[query.id]
+ }
+ });
return {
errorQueries,
+ queries: Object.values(queryIndex)
}
}
diff --git a/packages/server/src/api/controllers/query/import/sources/base/index.ts b/packages/server/src/api/controllers/query/import/sources/base/index.ts
index 747b7b3d66..db36067985 100644
--- a/packages/server/src/api/controllers/query/import/sources/base/index.ts
+++ b/packages/server/src/api/controllers/query/import/sources/base/index.ts
@@ -17,7 +17,7 @@ export interface Query {
headers: object
queryString: string | null
path: string
- requestBody?: object
+ requestBody: string | undefined
}
transformer: string | null
schema: any
@@ -47,7 +47,7 @@ export abstract class ImportSource {
queryString: string,
headers: object = {},
parameters: QueryParameter[] = [],
- requestBody: object | undefined = undefined,
+ body: object | undefined = undefined,
): Query => {
const readable = true
const queryVerb = this.verbFromMethod(method)
@@ -55,6 +55,7 @@ export abstract class ImportSource {
const schema = {}
path = this.processPath(path)
queryString = this.processQuery(queryString)
+ const requestBody = JSON.stringify(body, null, 2)
const query: Query = {
datasourceId,
@@ -85,9 +86,13 @@ export abstract class ImportSource {
processPath = (path: string): string => {
if (path?.startsWith("/")) {
- return path.substring(1)
+ path = path.substring(1)
}
-
+
+ // add extra braces around params for binding
+ path = path.replace(/[{]/g, "{{");
+ path = path.replace(/[}]/g, "}}");
+
return path
}
diff --git a/packages/server/src/api/controllers/query/import/sources/base/openapi.ts b/packages/server/src/api/controllers/query/import/sources/base/openapi.ts
index dfe3c68c08..74f0b48c42 100644
--- a/packages/server/src/api/controllers/query/import/sources/base/openapi.ts
+++ b/packages/server/src/api/controllers/query/import/sources/base/openapi.ts
@@ -2,11 +2,25 @@
import { ImportSource } from "."
import SwaggerParser from "@apidevtools/swagger-parser";
import { OpenAPI } from "openapi-types";
+const yaml = require('js-yaml');
export abstract class OpenAPISource extends ImportSource {
parseData = async (data: string): Promise => {
- const json = JSON.parse(data)
+ let json: OpenAPI.Document;
+ try {
+ json = JSON.parse(data)
+ } catch (jsonErr) {
+ // couldn't parse json
+ // try to convert yaml -> json
+ try {
+ json = yaml.load(data)
+ } catch (yamlErr) {
+ // couldn't parse yaml
+ throw new Error("Could not parse JSON or YAML")
+ }
+ }
+
return SwaggerParser.validate(json, {})
}
diff --git a/packages/server/src/api/controllers/query/import/sources/openapi2.ts b/packages/server/src/api/controllers/query/import/sources/openapi2.ts
index 05ee41d531..b144892191 100644
--- a/packages/server/src/api/controllers/query/import/sources/openapi2.ts
+++ b/packages/server/src/api/controllers/query/import/sources/openapi2.ts
@@ -2,13 +2,8 @@ import { ImportInfo, QueryParameter, Query } from "./base"
import { OpenAPIV2 } from "openapi-types"
import { OpenAPISource } from "./base/openapi";
-const isBodyParameter = (param: OpenAPIV2.Parameter): param is OpenAPIV2.InBodyParameterObject => {
- return param.in === "body"
-}
-
-const isParameter = (param: OpenAPIV2.Parameter | OpenAPIV2.ReferenceObject): param is OpenAPIV2.Parameter => {
- // we can guarantee this is not a reference object
- // due to the deferencing done by the parser library
+const parameterNotRef = (param: OpenAPIV2.Parameter | OpenAPIV2.ReferenceObject): param is OpenAPIV2.Parameter => {
+ // all refs are deferenced by parser library
return true
}
@@ -20,6 +15,16 @@ const isOpenAPI2 = (document: any): document is OpenAPIV2.Document => {
}
}
+const methods: string[] = Object.values(OpenAPIV2.HttpMethods)
+
+const isOperation = (key: string, pathItem: any): pathItem is OpenAPIV2.OperationObject => {
+ return methods.includes(key)
+}
+
+const isParameter = (key: string, pathItem: any): pathItem is OpenAPIV2.Parameter => {
+ return !isOperation(key, pathItem)
+}
+
/**
* OpenAPI Version 2.0 - aka "Swagger"
* https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md
@@ -57,30 +62,70 @@ export class OpenAPI2 extends OpenAPISource {
getQueries = async (datasourceId: string): Promise => {
const queries = []
- let pathName: string
- let path: OpenAPIV2.PathItemObject
+ for (let [path, pathItem] of Object.entries(this.document.paths)) {
+ // parameters that apply to every operation in the path
+ let pathParams: OpenAPIV2.Parameter[] = []
+
+ for (let [key, opOrParams] of Object.entries(pathItem)) {
+ if (isParameter(key, opOrParams)) {
+ const pathParameters = opOrParams as OpenAPIV2.Parameter[]
+ pathParams.push(...pathParameters)
+ continue
+ }
+ // can not be a parameter, must be an operation
+ const operation = opOrParams as OpenAPIV2.OperationObject
- for ([pathName, path] of Object.entries(this.document.paths)) {
- for (let [methodName, op] of Object.entries(path)) {
- let operation = op as OpenAPIV2.OperationObject
-
- const name = operation.operationId || pathName
- const queryString = ""
- const headers = {}
+ const methodName = key
+ const name = operation.operationId || path
+ let queryString = ""
+ const headers: any = {}
let requestBody = undefined
const parameters: QueryParameter[] = []
-
- if (operation.parameters) {
- for (let param of operation.parameters) {
- if (isParameter(param)) {
- if (isBodyParameter(param)) {
- requestBody = {}
- } else {
- parameters.push({
- name: param.name,
- default: "",
- })
- }
+
+ if (operation.consumes) {
+ headers["Content-Type"] = operation.consumes[0]
+ }
+
+ // combine the path parameters with the operation parameters
+ const operationParams = operation.parameters || []
+ const allParams = [...pathParams, ...operationParams]
+
+ for (let param of allParams) {
+ if (parameterNotRef(param)) {
+ switch (param.in) {
+ case "query":
+ let prefix = ""
+ if (queryString) {
+ prefix = "&"
+ }
+ queryString = `${queryString}${prefix}${param.name}={{${param.name}}}`
+ break
+ case "header":
+ headers[param.name] = `{{${param.name}}}`
+ break
+ case "path":
+ // do nothing: param is already in the path
+ break
+ case "formData":
+ // future enhancement
+ break
+ case "body":
+ // set the request body to the example provided
+ // future enhancement: generate an example from the schema
+ let bodyParam: OpenAPIV2.InBodyParameterObject = param as OpenAPIV2.InBodyParameterObject
+ if (param.schema.example) {
+ const schema = bodyParam.schema as OpenAPIV2.SchemaObject
+ requestBody = schema.example
+ }
+ break;
+ }
+
+ // add the parameter if it can be bound in our config
+ if (['query', 'header', 'path'].includes(param.in)) {
+ parameters.push({
+ name: param.name,
+ default: param.default || "",
+ })
}
}
}
@@ -89,7 +134,7 @@ export class OpenAPI2 extends OpenAPISource {
datasourceId,
name,
methodName,
- pathName,
+ path,
queryString,
headers,
parameters,
diff --git a/packages/server/src/api/controllers/query/import/sources/openapi3.ts b/packages/server/src/api/controllers/query/import/sources/openapi3.ts
deleted file mode 100644
index 655c680ed4..0000000000
--- a/packages/server/src/api/controllers/query/import/sources/openapi3.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import { ImportInfo, Query } from "./base"
-import { OpenAPISource } from "./base/openapi"
-import { OpenAPIV3 } from "openapi-types"
-
-const isOpenAPI3 = (document: any): document is OpenAPIV3.Document => {
- return document.openapi === "3.0.0"
-}
-
-/**
- * OpenAPI Version 3.0.0
- * https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.0.md
- */
-export class OpenAPI3 extends OpenAPISource {
- document!: OpenAPIV3.Document
-
- isSupported = async (data: string): Promise => {
- try {
- const document: any = await this.parseData(data)
- if (isOpenAPI3(document)) {
- this.document = document
- return true
- } else {
- return false
- }
- } catch (err) {
- return false
- }
- }
-
- getInfo = async (): Promise => {
- return {
- url: "http://localhost:3000",
- name: "swagger",
- }
- }
-
- getQueries = async (datasourceId: string): Promise => {
- return []
- }
-}
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js
index 0ce8465277..11869862f7 100644
--- a/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js
+++ b/packages/server/src/api/controllers/query/import/sources/tests/curl/curl.spec.js
@@ -90,9 +90,9 @@ describe("Curl Import", () => {
await testQuery("query", "q1=v1&q1=v2")
})
- const testBody = async (file, queryString) => {
+ const testBody = async (file, body) => {
const queries = await getQueries(file)
- expect(queries[0].fields.requestBody).toStrictEqual(queryString)
+ expect(queries[0].fields.requestBody).toStrictEqual(JSON.stringify(body, null, 2))
}
it("populates body", async () => {
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json
index ed16af32bd..abe07f136f 100644
--- a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json
+++ b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json
@@ -20,7 +20,7 @@
"tags": [
"entity"
],
- "operationId": "create",
+ "operationId": "createEntity",
"consumes": [
"application/json"
],
@@ -29,941 +29,225 @@
],
"parameters": [
{
- "in": "body",
- "schema": {
- "$ref": "#/definitions/CreateEntity"
- }
+ "$ref": "#/parameters/CreateEntity"
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
- "$ref": "#/definitions/ApiResponse"
+ "$ref": "#/definitions/Entity"
}
}
- },
- "security": [
- {
- "auth": [
- "write:entities",
- "read:entites"
- ]
- }
- ]
- }
- },
- "/pet": {
- "put": {
- "tags": [
- "pet"
- ],
- "summary": "Update an existing pet",
- "description": "",
- "operationId": "updatePet",
- "consumes": [
- "application/json",
- "application/xml"
- ],
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "in": "body",
- "name": "body",
- "description": "Pet object that needs to be added to the store",
- "required": true,
- "schema": {
- "$ref": "#/definitions/Pet"
- }
- }
- ],
- "responses": {
- "400": {
- "description": "Invalid ID supplied"
- },
- "404": {
- "description": "Pet not found"
- },
- "405": {
- "description": "Validation exception"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ]
- }
- },
- "/pet/findByStatus": {
- "get": {
- "tags": [
- "pet"
- ],
- "summary": "Finds Pets by status",
- "description": "Multiple status values can be provided with comma separated strings",
- "operationId": "findPetsByStatus",
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "name": "status",
- "in": "query",
- "description": "Status values that need to be considered for filter",
- "required": true,
- "type": "array",
- "items": {
- "type": "string",
- "enum": [
- "available",
- "pending",
- "sold"
- ],
- "default": "available"
- },
- "collectionFormat": "multi"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/Pet"
- }
- }
- },
- "400": {
- "description": "Invalid status value"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ]
- }
- },
- "/pet/findByTags": {
- "get": {
- "tags": [
- "pet"
- ],
- "summary": "Finds Pets by tags",
- "description": "Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
- "operationId": "findPetsByTags",
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "name": "tags",
- "in": "query",
- "description": "Tags to filter by",
- "required": true,
- "type": "array",
- "items": {
- "type": "string"
- },
- "collectionFormat": "multi"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/Pet"
- }
- }
- },
- "400": {
- "description": "Invalid tag value"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ],
- "deprecated": true
- }
- },
- "/pet/{petId}": {
- "get": {
- "tags": [
- "pet"
- ],
- "summary": "Find pet by ID",
- "description": "Returns a single pet",
- "operationId": "getPetById",
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "name": "petId",
- "in": "path",
- "description": "ID of pet to return",
- "required": true,
- "type": "integer",
- "format": "int64"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "$ref": "#/definitions/Pet"
- }
- },
- "400": {
- "description": "Invalid ID supplied"
- },
- "404": {
- "description": "Pet not found"
- }
- },
- "security": [
- {
- "api_key": []
- }
- ]
- },
- "post": {
- "tags": [
- "pet"
- ],
- "summary": "Updates a pet in the store with form data",
- "description": "",
- "operationId": "updatePetWithForm",
- "consumes": [
- "application/x-www-form-urlencoded"
- ],
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "name": "petId",
- "in": "path",
- "description": "ID of pet that needs to be updated",
- "required": true,
- "type": "integer",
- "format": "int64"
- },
- {
- "name": "name",
- "in": "formData",
- "description": "Updated name of the pet",
- "required": false,
- "type": "string"
- },
- {
- "name": "status",
- "in": "formData",
- "description": "Updated status of the pet",
- "required": false,
- "type": "string"
- }
- ],
- "responses": {
- "405": {
- "description": "Invalid input"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ]
- },
- "delete": {
- "tags": [
- "pet"
- ],
- "summary": "Deletes a pet",
- "description": "",
- "operationId": "deletePet",
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "name": "api_key",
- "in": "header",
- "required": false,
- "type": "string"
- },
- {
- "name": "petId",
- "in": "path",
- "description": "Pet id to delete",
- "required": true,
- "type": "integer",
- "format": "int64"
- }
- ],
- "responses": {
- "400": {
- "description": "Invalid ID supplied"
- },
- "404": {
- "description": "Pet not found"
- }
- },
- "security": [
- {
- "petstore_auth": [
- "write:pets",
- "read:pets"
- ]
- }
- ]
- }
- },
- "/store/inventory": {
- "get": {
- "tags": [
- "store"
- ],
- "summary": "Returns pet inventories by status",
- "description": "Returns a map of status codes to quantities",
- "operationId": "getInventory",
- "produces": [
- "application/json"
- ],
- "parameters": [],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "type": "object",
- "additionalProperties": {
- "type": "integer",
- "format": "int32"
- }
- }
- }
- },
- "security": [
- {
- "api_key": []
- }
- ]
- }
- },
- "/store/order": {
- "post": {
- "tags": [
- "store"
- ],
- "summary": "Place an order for a pet",
- "description": "",
- "operationId": "placeOrder",
- "consumes": [
- "application/json"
- ],
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "in": "body",
- "name": "body",
- "description": "order placed for purchasing the pet",
- "required": true,
- "schema": {
- "$ref": "#/definitions/Order"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "$ref": "#/definitions/Order"
- }
- },
- "400": {
- "description": "Invalid Order"
- }
- }
- }
- },
- "/store/order/{orderId}": {
- "get": {
- "tags": [
- "store"
- ],
- "summary": "Find purchase order by ID",
- "description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions",
- "operationId": "getOrderById",
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "name": "orderId",
- "in": "path",
- "description": "ID of pet that needs to be fetched",
- "required": true,
- "type": "integer",
- "maximum": 10,
- "minimum": 1,
- "format": "int64"
- }
- ],
- "responses": {
- "200": {
- "description": "successful operation",
- "schema": {
- "$ref": "#/definitions/Order"
- }
- },
- "400": {
- "description": "Invalid ID supplied"
- },
- "404": {
- "description": "Order not found"
- }
}
},
- "delete": {
- "tags": [
- "store"
- ],
- "summary": "Delete purchase order by ID",
- "description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors",
- "operationId": "deleteOrder",
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "name": "orderId",
- "in": "path",
- "description": "ID of the order that needs to be deleted",
- "required": true,
- "type": "integer",
- "minimum": 1,
- "format": "int64"
- }
- ],
- "responses": {
- "400": {
- "description": "Invalid ID supplied"
- },
- "404": {
- "description": "Order not found"
- }
- }
- }
- },
- "/user/createWithList": {
- "post": {
- "tags": [
- "user"
- ],
- "summary": "Creates list of users with given input array",
- "description": "",
- "operationId": "createUsersWithListInput",
- "consumes": [
- "application/json"
- ],
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "in": "body",
- "name": "body",
- "description": "List of user object",
- "required": true,
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/User"
- }
- }
- }
- ],
- "responses": {
- "default": {
- "description": "successful operation"
- }
- }
- }
- },
- "/user/{username}": {
"get": {
"tags": [
- "user"
+ "entity"
],
- "summary": "Get user by user name",
- "description": "",
- "operationId": "getUserByName",
+ "operationId": "getEntities",
"produces": [
- "application/json",
- "application/xml"
+ "application/json"
],
"parameters": [
{
- "name": "username",
- "in": "path",
- "description": "The name that needs to be fetched. Use user1 for testing. ",
- "required": true,
- "type": "string"
+ "$ref": "#/parameters/Page"
+ },
+ {
+ "$ref": "#/parameters/Size"
}
],
"responses": {
"200": {
"description": "successful operation",
"schema": {
- "$ref": "#/definitions/User"
+ "$ref": "#/definitions/Entities"
+ }
+ }
+ }
+ }
+ },
+ "/entities/{entityId}": {
+ "parameters": [
+ {
+ "$ref": "#/parameters/EntityId"
+ }
+ ],
+ "get": {
+ "tags": [
+ "entity"
+ ],
+ "operationId": "getEntity",
+ "produces": [
+ "application/json"
+ ],
+ "responses": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/Entity"
}
- },
- "400": {
- "description": "Invalid username supplied"
- },
- "404": {
- "description": "User not found"
}
}
},
"put": {
"tags": [
- "user"
+ "entity"
],
- "summary": "Updated user",
- "description": "This can only be done by the logged in user.",
- "operationId": "updateUser",
+ "operationId": "updateEntity",
"consumes": [
"application/json"
],
"produces": [
- "application/json",
- "application/xml"
+ "application/json"
],
"parameters": [
{
- "name": "username",
- "in": "path",
- "description": "name that need to be updated",
- "required": true,
- "type": "string"
- },
- {
- "in": "body",
- "name": "body",
- "description": "Updated user object",
- "required": true,
- "schema": {
- "$ref": "#/definitions/User"
- }
- }
- ],
- "responses": {
- "400": {
- "description": "Invalid user supplied"
- },
- "404": {
- "description": "User not found"
- }
- }
- },
- "delete": {
- "tags": [
- "user"
- ],
- "summary": "Delete user",
- "description": "This can only be done by the logged in user.",
- "operationId": "deleteUser",
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "name": "username",
- "in": "path",
- "description": "The name that needs to be deleted",
- "required": true,
- "type": "string"
- }
- ],
- "responses": {
- "400": {
- "description": "Invalid username supplied"
- },
- "404": {
- "description": "User not found"
- }
- }
- }
- },
- "/user/login": {
- "get": {
- "tags": [
- "user"
- ],
- "summary": "Logs user into the system",
- "description": "",
- "operationId": "loginUser",
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "name": "username",
- "in": "query",
- "description": "The user name for login",
- "required": true,
- "type": "string"
- },
- {
- "name": "password",
- "in": "query",
- "description": "The password for login in clear text",
- "required": true,
- "type": "string"
+ "$ref": "#/parameters/Entity"
}
],
"responses": {
"200": {
"description": "successful operation",
- "headers": {
- "X-Expires-After": {
- "type": "string",
- "format": "date-time",
- "description": "date in UTC when token expires"
- },
- "X-Rate-Limit": {
- "type": "integer",
- "format": "int32",
- "description": "calls per hour allowed by the user"
- }
- },
"schema": {
- "type": "string"
+ "$ref": "#/definitions/Entity"
}
- },
- "400": {
- "description": "Invalid username/password supplied"
}
}
- }
- },
- "/user/logout": {
- "get": {
+ },
+ "patch": {
"tags": [
- "user"
+ "entity"
],
- "summary": "Logs out current logged in user session",
- "description": "",
- "operationId": "logoutUser",
- "produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [],
- "responses": {
- "default": {
- "description": "successful operation"
- }
- }
- }
- },
- "/user/createWithArray": {
- "post": {
- "tags": [
- "user"
- ],
- "summary": "Creates list of users with given input array",
- "description": "",
- "operationId": "createUsersWithArrayInput",
+ "operationId": "patchEntity",
"consumes": [
"application/json"
],
"produces": [
- "application/json",
- "application/xml"
- ],
- "parameters": [
- {
- "in": "body",
- "name": "body",
- "description": "List of user object",
- "required": true,
- "schema": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/User"
- }
- }
- }
- ],
- "responses": {
- "default": {
- "description": "successful operation"
- }
- }
- }
- },
- "/user": {
- "post": {
- "tags": [
- "user"
- ],
- "summary": "Create user",
- "description": "This can only be done by the logged in user.",
- "operationId": "createUser",
- "consumes": [
"application/json"
],
- "produces": [
- "application/json",
- "application/xml"
- ],
"parameters": [
{
- "in": "body",
- "name": "body",
- "description": "Created user object",
- "required": true,
- "schema": {
- "$ref": "#/definitions/User"
- }
+ "$ref": "#/parameters/Entity"
}
],
"responses": {
- "default": {
+ "200": {
+ "description": "successful operation",
+ "schema": {
+ "$ref": "#/definitions/Entity"
+ }
+ }
+ }
+ },
+ "delete": {
+ "tags": [
+ "entity"
+ ],
+ "parameters": [
+ {
+ "$ref": "#/parameters/APIKey"
+ }
+ ],
+ "operationId": "deleteEntity",
+ "produces": [
+ "application/json"
+ ],
+ "responses": {
+ "204": {
"description": "successful operation"
}
}
}
}
},
- "securityDefinitions": {
- "api_key": {
- "type": "apiKey",
- "name": "api_key",
- "in": "header"
+ "parameters": {
+ "EntityId": {
+ "type": "integer",
+ "format": "int64",
+ "name": "entityId",
+ "in": "path",
+ "required": true
},
- "petstore_auth": {
- "type": "oauth2",
- "authorizationUrl": "https://petstore.swagger.io/oauth/authorize",
- "flow": "implicit",
- "scopes": {
- "read:pets": "read your pets",
- "write:pets": "modify pets in your account"
+ "CreateEntity": {
+ "name": "entity",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/CreateEntity"
}
+ },
+ "Entity": {
+ "name": "entity",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/Entity"
+ }
+ },
+ "Page": {
+ "type": "integer",
+ "format": "int32",
+ "name": "page",
+ "in": "query",
+ "required": false
+ },
+ "Size": {
+ "type": "integer",
+ "format": "int32",
+ "name": "size",
+ "in": "query",
+ "required": false
+ },
+ "APIKey": {
+ "type": "string",
+ "name": "x-api-key",
+ "in": "header",
+ "required": false
}
},
"definitions": {
- "ApiResponse": {
+ "CreateEntity": {
"type": "object",
"properties": {
- "code": {
- "type": "integer",
- "format": "int32"
+ "name": {
+ "type": "string"
},
"type": {
"type": "string"
- },
- "message": {
- "type": "string"
- }
- }
- },
- "Category": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "format": "int64"
- },
- "name": {
- "type": "string"
}
},
- "xml": {
- "name": "Category"
+ "example": {
+ "name": "name",
+ "type": "type"
}
},
- "Pet": {
- "type": "object",
- "required": [
- "name",
- "photoUrls"
- ],
- "properties": {
- "id": {
- "type": "integer",
- "format": "int64"
- },
- "category": {
- "$ref": "#/definitions/Category"
- },
- "name": {
- "type": "string",
- "example": "doggie"
- },
- "photoUrls": {
- "type": "array",
- "xml": {
- "wrapped": true
- },
- "items": {
- "type": "string",
- "xml": {
- "name": "photoUrl"
+ "Entity": {
+ "allOf": [
+ {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
}
}
},
- "tags": {
- "type": "array",
- "xml": {
- "wrapped": true
- },
- "items": {
- "xml": {
- "name": "tag"
- },
- "$ref": "#/definitions/Tag"
- }
- },
- "status": {
- "type": "string",
- "description": "pet status in the store",
- "enum": [
- "available",
- "pending",
- "sold"
- ]
- }
- },
- "xml": {
- "name": "Pet"
+ {
+ "$ref": "#/definitions/CreateEntity"
+ }
+ ],
+ "example": {
+ "id": 1,
+ "name": "name",
+ "type": "type"
}
},
- "Tag": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "format": "int64"
- },
- "name": {
- "type": "string"
- }
- },
- "xml": {
- "name": "Tag"
- }
- },
- "Order": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "format": "int64"
- },
- "petId": {
- "type": "integer",
- "format": "int64"
- },
- "quantity": {
- "type": "integer",
- "format": "int32"
- },
- "shipDate": {
- "type": "string",
- "format": "date-time"
- },
- "status": {
- "type": "string",
- "description": "Order Status",
- "enum": [
- "placed",
- "approved",
- "delivered"
- ]
- },
- "complete": {
- "type": "boolean"
- }
- },
- "xml": {
- "name": "Order"
- }
- },
- "User": {
- "type": "object",
- "properties": {
- "id": {
- "type": "integer",
- "format": "int64"
- },
- "username": {
- "type": "string"
- },
- "firstName": {
- "type": "string"
- },
- "lastName": {
- "type": "string"
- },
- "email": {
- "type": "string"
- },
- "password": {
- "type": "string"
- },
- "phone": {
- "type": "string"
- },
- "userStatus": {
- "type": "integer",
- "format": "int32",
- "description": "User Status"
- }
- },
- "xml": {
- "name": "User"
+ "Entities" : {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Entity"
}
}
- },
- "externalDocs": {
- "description": "Find out more about Swagger",
- "url": "http://swagger.io"
}
}
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml
new file mode 100644
index 0000000000..7568c2f18f
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.yaml
@@ -0,0 +1,160 @@
+---
+swagger: "2.0"
+info:
+ description: A basic swagger file
+ version: 1.0.0
+ title: CRUD
+host: example.com
+tags:
+ - name: entity
+schemes:
+ - http
+paths:
+ "/entities":
+ post:
+ tags:
+ - entity
+ operationId: createEntity
+ consumes:
+ - application/json
+ produces:
+ - application/json
+ parameters:
+ - "$ref": "#/parameters/CreateEntity"
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ "$ref": "#/definitions/Entity"
+ get:
+ tags:
+ - entity
+ operationId: getEntities
+ produces:
+ - application/json
+ parameters:
+ - "$ref": "#/parameters/Page"
+ - "$ref": "#/parameters/Size"
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ "$ref": "#/definitions/Entities"
+ "/entities/{entityId}":
+ parameters:
+ - "$ref": "#/parameters/EntityId"
+ get:
+ tags:
+ - entity
+ operationId: getEntity
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ "$ref": "#/definitions/Entity"
+ put:
+ tags:
+ - entity
+ operationId: updateEntity
+ consumes:
+ - application/json
+ produces:
+ - application/json
+ parameters:
+ - "$ref": "#/parameters/Entity"
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ "$ref": "#/definitions/Entity"
+ patch:
+ tags:
+ - entity
+ operationId: patchEntity
+ consumes:
+ - application/json
+ produces:
+ - application/json
+ parameters:
+ - "$ref": "#/parameters/Entity"
+ responses:
+ "200":
+ description: successful operation
+ schema:
+ "$ref": "#/definitions/Entity"
+ delete:
+ tags:
+ - entity
+ parameters:
+ - "$ref": "#/parameters/APIKey"
+ operationId: deleteEntity
+ produces:
+ - application/json
+ responses:
+ "204":
+ description: successful operation
+parameters:
+ EntityId:
+ type: integer
+ format: int64
+ name: entityId
+ in: path
+ required: true
+ CreateEntity:
+ name: entity
+ in: body
+ required: true
+ schema:
+ "$ref": "#/definitions/CreateEntity"
+ Entity:
+ name: entity
+ in: body
+ required: true
+ schema:
+ "$ref": "#/definitions/Entity"
+ Page:
+ type: integer
+ format: int32
+ name: page
+ in: query
+ required: false
+ Size:
+ type: integer
+ format: int32
+ name: size
+ in: query
+ required: false
+ APIKey:
+ type: string
+ name: x-api-key
+ in: header
+ required: false
+definitions:
+ CreateEntity:
+ type: object
+ properties:
+ name:
+ type: string
+ type:
+ type: string
+ example:
+ name: name
+ type: type
+ Entity:
+ allOf:
+ - type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ - "$ref": "#/definitions/CreateEntity"
+ example:
+ id: 1
+ name: name
+ type: type
+ Entities:
+ type: array
+ items:
+ "$ref": "#/definitions/Entity"
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js
index 5b99360176..845c4f38f6 100644
--- a/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js
+++ b/packages/server/src/api/controllers/query/import/sources/tests/openapi2/openapi2.spec.js
@@ -32,9 +32,9 @@ describe("OpenAPI2 Import", () => {
await openapi2.isSupported(getData(file, extension))
}
- const runTests = async (filename, test) => {
+ const runTests = async (filename, test, assertions) => {
for (let extension of ["json", "yaml"]) {
- await test(filename, extension)
+ await test(filename, extension, assertions)
}
}
@@ -50,64 +50,190 @@ describe("OpenAPI2 Import", () => {
})
describe("Returns queries", () => {
- const getQueries = async (file) => {
- await init(file)
- const queries = await openapi2.getQueries()
- expect(queries.length).toBe(1)
- return queries
+ const indexQueries = (queries) => {
+ return queries.reduce((acc, query) => {
+ acc[query.name] = query
+ return acc
+ }, {})
}
- const testVerb = async (file, verb) => {
- const queries = await getQueries(file)
- expect(queries[0].queryVerb).toBe(verb)
+ const getQueries = async (file, extension) => {
+ await init(file, extension)
+ const queries = await openapi2.getQueries()
+ expect(queries.length).toBe(6)
+ return indexQueries(queries)
+ }
+
+ const testVerb = async (file, extension, assertions) => {
+ const queries = await getQueries(file, extension)
+ for (let [operationId, method] of Object.entries(assertions)) {
+ expect(queries[operationId].queryVerb).toBe(method)
+ }
}
it("populates verb", async () => {
- await testVerb("get", "read")
- await testVerb("post", "create")
- await testVerb("put", "update")
- await testVerb("delete", "delete")
- await testVerb("patch", "patch")
+ const assertions = {
+ "createEntity" : "create",
+ "getEntities" : "read",
+ "getEntity" : "read",
+ "updateEntity" : "update",
+ "patchEntity" : "patch",
+ "deleteEntity" : "delete"
+ }
+ await runTests("crud", testVerb, assertions)
})
- const testPath = async (file, urlPath) => {
- const queries = await getQueries(file)
- expect(queries[0].fields.path).toBe(urlPath)
+ const testPath = async (file, extension, assertions) => {
+ const queries = await getQueries(file, extension)
+ for (let [operationId, urlPath] of Object.entries(assertions)) {
+ expect(queries[operationId].fields.path).toBe(urlPath)
+ }
}
it("populates path", async () => {
- await testPath("get", "")
- await testPath("path", "paths/abc")
+ const assertions = {
+ "createEntity" : "entities",
+ "getEntities" : "entities",
+ "getEntity" : "entities/{{entityId}}",
+ "updateEntity" : "entities/{{entityId}}",
+ "patchEntity" : "entities/{{entityId}}",
+ "deleteEntity" : "entities/{{entityId}}"
+ }
+ await runTests("crud", testPath, assertions)
})
- const testHeaders = async (file, headers) => {
- const queries = await getQueries(file)
- expect(queries[0].fields.headers).toStrictEqual(headers)
+ const testHeaders = async (file, extension, assertions) => {
+ const queries = await getQueries(file, extension)
+ for (let [operationId, headers] of Object.entries(assertions)) {
+ expect(queries[operationId].fields.headers).toStrictEqual(headers)
+ }
+ }
+
+ const contentTypeHeader = {
+ "Content-Type" : "application/json",
}
it("populates headers", async () => {
- await testHeaders("get", {})
- await testHeaders("headers", { "x-bb-header-1" : "123", "x-bb-header-2" : "456"} )
+ const assertions = {
+ "createEntity" : {
+ ...contentTypeHeader
+ },
+ "getEntities" : {
+ },
+ "getEntity" : {
+ },
+ "updateEntity" : {
+ ...contentTypeHeader
+ },
+ "patchEntity" : {
+ ...contentTypeHeader
+ },
+ "deleteEntity" : {
+ "x-api-key" : "{{x-api-key}}",
+ }
+ }
+
+ await runTests("crud", testHeaders, assertions)
})
- const testQuery = async (file, queryString) => {
- const queries = await getQueries(file)
- expect(queries[0].fields.queryString).toBe(queryString)
+ const testQuery = async (file, extension, assertions) => {
+ const queries = await getQueries(file, extension)
+ for (let [operationId, queryString] of Object.entries(assertions)) {
+ expect(queries[operationId].fields.queryString).toStrictEqual(queryString)
+ }
}
+
it("populates query", async () => {
- await testQuery("get", "")
- await testQuery("query", "q1=v1&q1=v2")
+ const assertions = {
+ "createEntity" : "",
+ "getEntities" : "page={{page}}&size={{size}}",
+ "getEntity" : "",
+ "updateEntity" : "",
+ "patchEntity" : "",
+ "deleteEntity" : ""
+ }
+ await runTests("crud", testQuery, assertions)
})
- const testBody = async (file, queryString) => {
- const queries = await getQueries(file)
- expect(queries[0].fields.requestBody).toStrictEqual(queryString)
+ const testParameters = async (file, extension, assertions) => {
+ const queries = await getQueries(file, extension)
+ for (let [operationId, parameters] of Object.entries(assertions)) {
+ expect(queries[operationId].parameters).toStrictEqual(parameters)
+ }
}
+ it("populates parameters", async () => {
+ const assertions = {
+ "createEntity" : [],
+ "getEntities" : [
+ {
+ "name" : "page",
+ "default" : "",
+ },
+ {
+ "name" : "size",
+ "default" : "",
+ }
+ ],
+ "getEntity" : [
+ {
+ "name" : "entityId",
+ "default" : "",
+ }
+ ],
+ "updateEntity" : [
+ {
+ "name" : "entityId",
+ "default" : "",
+ }
+ ],
+ "patchEntity" : [
+ {
+ "name" : "entityId",
+ "default" : "",
+ }
+ ],
+ "deleteEntity" : [
+ {
+ "name" : "entityId",
+ "default" : "",
+ },
+ {
+ "name" : "x-api-key",
+ "default" : "",
+ }
+ ]
+ }
+ await runTests("crud", testParameters, assertions)
+ })
+
+ const testBody = async (file, extension, assertions) => {
+ const queries = await getQueries(file, extension)
+ for (let [operationId, body] of Object.entries(assertions)) {
+ expect(queries[operationId].fields.requestBody).toStrictEqual(JSON.stringify(body, null, 2))
+ }
+ }
it("populates body", async () => {
- await testBody("get", undefined)
- await testBody("post", { "key" : "val" })
- await testBody("empty-body", {})
+ const assertions = {
+ "createEntity" : {
+ "name" : "name",
+ "type" : "type",
+ },
+ "getEntities" : undefined,
+ "getEntity" : undefined,
+ "updateEntity" : {
+ "id": 1,
+ "name" : "name",
+ "type" : "type",
+ },
+ "patchEntity" : {
+ "id": 1,
+ "name" : "name",
+ "type" : "type",
+ },
+ "deleteEntity" : undefined
+ }
+ await runTests("crud", testBody, assertions)
})
})
})
\ No newline at end of file
diff --git a/packages/server/src/api/controllers/query/import/sources/tests/openapi3/openapi3.spec.js b/packages/server/src/api/controllers/query/import/sources/tests/openapi3/openapi3.spec.js
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/packages/server/src/api/controllers/query/import/tests/index.spec.js b/packages/server/src/api/controllers/query/import/tests/index.spec.js
new file mode 100644
index 0000000000..32f3b43b44
--- /dev/null
+++ b/packages/server/src/api/controllers/query/import/tests/index.spec.js
@@ -0,0 +1,115 @@
+
+const bulkDocs = jest.fn()
+const db = jest.fn(() => {
+ return {
+ bulkDocs
+ }
+})
+jest.mock("../../../../../db", () => db)
+
+const { RestImporter } = require("../index")
+
+const fs = require("fs")
+const path = require('path')
+
+const getData = (file) => {
+ return fs.readFileSync(path.join(__dirname, `../sources/tests/${file}`), "utf8")
+}
+
+// openapi2 (swagger)
+const oapi2CrudJson = getData("openapi2/data/crud/crud.json")
+const oapi2CrudYaml = getData("openapi2/data/crud/crud.json")
+const oapi2PetstoreJson = getData("openapi2/data/petstore/petstore.json")
+const oapi2PetstoreYaml = getData("openapi2/data/petstore/petstore.json")
+
+// curl
+const curl = getData("curl/data/post.txt")
+
+const datasets = {
+ oapi2CrudJson,
+ oapi2CrudYaml,
+ oapi2PetstoreJson,
+ oapi2PetstoreYaml,
+ curl
+}
+
+describe("Rest Importer", () => {
+ let restImporter
+
+ const init = async (data) => {
+ restImporter = new RestImporter(data)
+ await restImporter.init()
+ }
+
+ const runTest = async (test, assertions) => {
+ for (let [key, data] of Object.entries(datasets)) {
+ await test(key, data, assertions)
+ }
+ }
+
+ const testGetInfo = async (key, data, assertions) => {
+ await init(data)
+ const info = await restImporter.getInfo()
+ expect(info.name).toBe(assertions[key].name)
+ expect(info.url).toBe(assertions[key].url)
+ }
+
+ it("gets info", async () => {
+ const assertions = {
+ "oapi2CrudJson" : {
+ name: "CRUD",
+ url: "http://example.com"
+ },
+ "oapi2CrudYaml" : {
+ name: "CRUD",
+ url: "http://example.com"
+ },
+ "oapi2PetstoreJson" : {
+ name: "Swagger Petstore",
+ url: "https://petstore.swagger.io/v2"
+ },
+ "oapi2PetstoreYaml" :{
+ name: "Swagger Petstore",
+ url: "https://petstore.swagger.io/v2"
+ },
+ "curl": {
+ name: "example.com",
+ url: "http://example.com"
+ }
+ }
+ await runTest(testGetInfo, assertions)
+ })
+
+ const testImportQueries = async (key, data, assertions) => {
+ await init(data)
+ bulkDocs.mockReturnValue([])
+ const importResult = await restImporter.importQueries("appId", "datasourceId")
+ expect(importResult.errorQueries.length).toBe(0)
+ expect(importResult.queries.length).toBe(assertions[key].count)
+ expect(bulkDocs).toHaveBeenCalledTimes(1)
+ jest.clearAllMocks()
+ }
+
+ it("imports queries", async () => {
+ // simple sanity assertions that the whole dataset
+ // makes it through the importer
+ const assertions = {
+ "oapi2CrudJson" : {
+ count: 6,
+ },
+ "oapi2CrudYaml" :{
+ count: 6,
+ },
+ "oapi2PetstoreJson" : {
+ count: 20,
+ },
+ "oapi2PetstoreYaml" :{
+ count: 20,
+ },
+ "curl": {
+ count: 1
+ }
+ }
+ await runTest(testImportQueries, assertions)
+ })
+})
\ No newline at end of file
From 5e6c967d642ab6482c114456fd89404f6489ee5a Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Thu, 2 Dec 2021 14:24:10 +0000
Subject: [PATCH 10/30] Update supported file tags
---
.../DatasourceNavigator/modals/ImportRestQueriesModal.svelte | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte
index 4e8ba4fd77..ec26663777 100644
--- a/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte
+++ b/packages/builder/src/components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte
@@ -104,7 +104,7 @@
gallery={false}
bind:value={data.file}
on:change={() => (lastTouched = "file")}
- fileTags={["OpenAPI", "Swagger 2.0"]}
+ fileTags={["OpenAPI 2.0", "Swagger 2.0", "cURL", "YAML", "JSON"]}
/>
From cadd3cf2592879ad8303a5b5d8c36c89c0e7630b Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Thu, 2 Dec 2021 15:20:03 +0000
Subject: [PATCH 11/30] Fix merge import
---
.../server/src/api/controllers/query/index.js | 8 +-
packages/server/yarn.lock | 783 +-----------------
2 files changed, 21 insertions(+), 770 deletions(-)
diff --git a/packages/server/src/api/controllers/query/index.js b/packages/server/src/api/controllers/query/index.js
index 35c07a6902..a9a29fd60e 100644
--- a/packages/server/src/api/controllers/query/index.js
+++ b/packages/server/src/api/controllers/query/index.js
@@ -1,12 +1,12 @@
const { processString } = require("@budibase/string-templates")
-const CouchDB = require("../../db")
+const CouchDB = require("../../../db")
const {
generateQueryID,
getQueryParams,
isProdAppID,
-} = require("../../db/utils")
-const { BaseQueryVerbs } = require("../../constants")
-const { Thread, ThreadType } = require("../../threads")
+} = require("../../../db/utils")
+const { BaseQueryVerbs } = require("../../../constants")
+const { Thread, ThreadType } = require("../../../threads")
const { save: saveDatasource } = require("../datasource")
const { RestImporter } = require("./import")
diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock
index d4ac72f196..fb453d21ca 100644
--- a/packages/server/yarn.lock
+++ b/packages/server/yarn.lock
@@ -983,30 +983,6 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
-"@budibase/auth@^1.0.5-alpha.1":
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/@budibase/auth/-/auth-1.0.5.tgz#214372b3be115eadcb22a3624fa1e20c66fc4c54"
- integrity sha512-WxARWwkbcOmvGb1mLUbnpfqfPdArrwUJTmzUcbayRelif4uKXK3r0X/b+erL4uQPJy7rhxQxcBSrjuuKOmZbpw==
- dependencies:
- "@techpass/passport-openidconnect" "^0.3.0"
- aws-sdk "^2.901.0"
- bcryptjs "^2.4.3"
- cls-hooked "^4.2.2"
- ioredis "^4.27.1"
- jsonwebtoken "^8.5.1"
- koa-passport "^4.1.4"
- lodash "^4.17.21"
- lodash.isarguments "^3.1.0"
- node-fetch "^2.6.1"
- passport-google-auth "^1.0.2"
- passport-google-oauth "^2.0.0"
- passport-jwt "^4.0.0"
- passport-local "^1.0.0"
- sanitize-s3-objectkey "^0.0.1"
- tar-fs "^2.1.1"
- uuid "^8.3.2"
- zlib "^1.0.5"
-
"@budibase/bbui@^0.9.139":
version "0.9.187"
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.187.tgz#84f0a37301cfa41f50eaa335243ac08923d9e34f"
@@ -1056,95 +1032,6 @@
svelte-flatpickr "^3.2.3"
svelte-portal "^1.0.0"
-"@budibase/bbui@^1.0.5":
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.0.5.tgz#d56b2de07b24a8b5376bdcc9eafa594798cf6853"
- integrity sha512-XjdrBw4uVXspI26aMlGO8AZdzJYxJjGrXrrKgDDEtb3HNg82QRWxLr2GQSyj2dBJ+a90huLClv+jOD1D/rOIuQ==
- dependencies:
- "@adobe/spectrum-css-workflow-icons" "^1.2.1"
- "@spectrum-css/actionbutton" "^1.0.1"
- "@spectrum-css/actiongroup" "^1.0.1"
- "@spectrum-css/avatar" "^3.0.2"
- "@spectrum-css/button" "^3.0.1"
- "@spectrum-css/buttongroup" "^3.0.2"
- "@spectrum-css/checkbox" "^3.0.2"
- "@spectrum-css/dialog" "^3.0.1"
- "@spectrum-css/divider" "^1.0.3"
- "@spectrum-css/dropzone" "^3.0.2"
- "@spectrum-css/fieldgroup" "^3.0.2"
- "@spectrum-css/fieldlabel" "^3.0.1"
- "@spectrum-css/icon" "^3.0.1"
- "@spectrum-css/illustratedmessage" "^3.0.2"
- "@spectrum-css/inlinealert" "^2.0.1"
- "@spectrum-css/inputgroup" "^3.0.2"
- "@spectrum-css/label" "^2.0.10"
- "@spectrum-css/link" "^3.1.1"
- "@spectrum-css/menu" "^3.0.1"
- "@spectrum-css/modal" "^3.0.1"
- "@spectrum-css/pagination" "^3.0.3"
- "@spectrum-css/picker" "^1.0.1"
- "@spectrum-css/popover" "^3.0.1"
- "@spectrum-css/progressbar" "^1.0.2"
- "@spectrum-css/progresscircle" "^1.0.2"
- "@spectrum-css/radio" "^3.0.2"
- "@spectrum-css/search" "^3.0.2"
- "@spectrum-css/sidenav" "^3.0.2"
- "@spectrum-css/statuslight" "^3.0.2"
- "@spectrum-css/stepper" "^3.0.3"
- "@spectrum-css/switch" "^1.0.2"
- "@spectrum-css/table" "^3.0.1"
- "@spectrum-css/tabs" "^3.0.1"
- "@spectrum-css/tags" "^3.0.2"
- "@spectrum-css/textfield" "^3.0.1"
- "@spectrum-css/toast" "^3.0.1"
- "@spectrum-css/tooltip" "^3.0.3"
- "@spectrum-css/treeview" "^3.0.2"
- "@spectrum-css/typography" "^3.0.1"
- "@spectrum-css/underlay" "^2.0.9"
- "@spectrum-css/vars" "^3.0.1"
- dayjs "^1.10.4"
- svelte-flatpickr "^3.2.3"
- svelte-portal "^1.0.0"
-
-"@budibase/client@^1.0.5-alpha.1":
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/@budibase/client/-/client-1.0.5.tgz#6765ac8cddd824481e0a5d57f2d75b43d2cd49a4"
- integrity sha512-HcwpbvHn0FsMDmBC0HskzPt4M13BWWuAM72eBiJxzWC4RgUBqsj1KKA6Du6wM7CO7a6837iDAA+NaZBFJbxdCQ==
- dependencies:
- "@budibase/bbui" "^1.0.5"
- "@budibase/standard-components" "^0.9.139"
- "@budibase/string-templates" "^1.0.5"
- regexparam "^1.3.0"
- shortid "^2.2.15"
- svelte-spa-router "^3.0.5"
-
-"@budibase/handlebars-helpers@^0.11.7":
- version "0.11.7"
- resolved "https://registry.yarnpkg.com/@budibase/handlebars-helpers/-/handlebars-helpers-0.11.7.tgz#8e5f9843d7dd10503e9f608555a96ccf4d836c46"
- integrity sha512-PvGHAv22cWSFExs1kc0WglwsmCEUEOqWvSp6JCFZwtc3qAAr5yMfLK8WGVQ63ALvyzWZiyxF+yrlzeeaohCMJw==
- dependencies:
- array-sort "^1.0.0"
- define-property "^2.0.2"
- extend-shallow "^3.0.2"
- for-in "^1.0.2"
- get-object "^0.2.0"
- get-value "^3.0.1"
- handlebars "^4.7.7"
- handlebars-utils "^1.0.6"
- has-value "^2.0.2"
- helper-date "^1.0.1"
- helper-markdown "^1.0.0"
- helper-md "^0.2.2"
- html-tag "^2.0.0"
- is-even "^1.0.0"
- is-glob "^4.0.1"
- kind-of "^6.0.3"
- micromatch "^3.1.5"
- relative "^3.0.2"
- striptags "^3.1.1"
- to-gfm-code-block "^0.1.1"
- year "^0.2.1"
-
"@budibase/standard-components@^0.9.139":
version "0.9.139"
resolved "https://registry.yarnpkg.com/@budibase/standard-components/-/standard-components-0.9.139.tgz#cf8e2b759ae863e469e50272b3ca87f2827e66e3"
@@ -1163,18 +1050,6 @@
svelte-apexcharts "^1.0.2"
svelte-flatpickr "^3.1.0"
-"@budibase/string-templates@^1.0.5", "@budibase/string-templates@^1.0.5-alpha.1":
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-1.0.5.tgz#72652d1c87872dedd7850d2c4e727fe1dca8a78e"
- integrity sha512-UjwbMW40GTwhB2Z/tQp9iSPsAEF1cdJ404N7nBzzWBir9uJKTAkO5iAa5L9dRGpfsF4UFEiiOHNbJqikiTFTZg==
- dependencies:
- "@budibase/handlebars-helpers" "^0.11.7"
- dayjs "^1.10.4"
- handlebars "^4.7.6"
- handlebars-utils "^1.0.6"
- lodash "^4.17.20"
- vm2 "^3.9.4"
-
"@bull-board/api@3.7.0", "@bull-board/api@^3.7.0":
version "3.7.0"
resolved "https://registry.yarnpkg.com/@bull-board/api/-/api-3.7.0.tgz#231f687187c0cb34e0b97f463917b6aaeb4ef6af"
@@ -2098,11 +1973,6 @@
resolved "https://registry.yarnpkg.com/@spectrum-css/illustratedmessage/-/illustratedmessage-3.0.8.tgz#69ef0c935bcc5027f233a78de5aeb0064bf033cb"
integrity sha512-HvC4dywDi11GdrXQDCvKQ0vFlrXLTyJuc9UKf7meQLCGoJbGYDBwe+tHXNK1c6gPMD9BoL6pPMP1K/vRzR4EBQ==
-"@spectrum-css/inlinealert@^2.0.1":
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/@spectrum-css/inlinealert/-/inlinealert-2.0.5.tgz#76b50495c0ad0cd675d7df2f73fb0e9cd5cff4e9"
- integrity sha512-Z37CDhoFX0cePjoyi5igRCi4/rIU7ETDpV8cwHjbTYj4IXpHmOCllxftncE8SJ3PZrQW2gB9mmXvfg+TBy3g2Q==
-
"@spectrum-css/inputgroup@^3.0.2":
version "3.0.8"
resolved "https://registry.yarnpkg.com/@spectrum-css/inputgroup/-/inputgroup-3.0.8.tgz#fc23afc8a73c24d17249c9d2337e8b42085b298b"
@@ -2252,17 +2122,6 @@
dependencies:
defer-to-connect "^1.0.1"
-"@techpass/passport-openidconnect@^0.3.0":
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/@techpass/passport-openidconnect/-/passport-openidconnect-0.3.2.tgz#f8fd5d97256286665dbf26dac92431f977ab1e63"
- integrity sha512-fnCtEiexXSHA029B//hJcCJlLJrT3lhpNCyA0rnz58Qttz0BLGCVv6yMT8HmOnGThH6vcDOVwdgKM3kbCQtEhw==
- dependencies:
- base64url "^3.0.1"
- oauth "^0.9.15"
- passport-strategy "^1.0.0"
- request "^2.88.0"
- webfinger "^0.4.2"
-
"@tootallnate/once@1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
@@ -3127,7 +2986,7 @@ arg@^4.1.0:
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
-argparse@^1.0.10, argparse@^1.0.7:
+argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
@@ -3174,15 +3033,6 @@ array-equal@^1.0.0:
resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93"
integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=
-array-sort@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/array-sort/-/array-sort-1.0.0.tgz#e4c05356453f56f53512a7d1d6123f2c54c0a88a"
- integrity sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==
- dependencies:
- default-compare "^1.0.0"
- get-value "^2.0.6"
- kind-of "^5.0.2"
-
array-union@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
@@ -3230,13 +3080,6 @@ astral-regex@^1.0.0:
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9"
integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==
-async-hook-jl@^1.7.6:
- version "1.7.6"
- resolved "https://registry.yarnpkg.com/async-hook-jl/-/async-hook-jl-1.7.6.tgz#4fd25c2f864dbaf279c610d73bf97b1b28595e68"
- integrity sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==
- dependencies:
- stack-chain "^1.3.7"
-
async-limiter@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd"
@@ -3259,13 +3102,6 @@ async@^3.1.0:
resolved "https://registry.yarnpkg.com/async/-/async-3.2.2.tgz#2eb7671034bb2194d45d30e31e24ec7e7f9670cd"
integrity sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==
-async@~2.1.4:
- version "2.1.5"
- resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc"
- integrity sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw=
- dependencies:
- lodash "^4.14.0"
-
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -3281,13 +3117,6 @@ atomic-sleep@^1.0.0:
resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b"
integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==
-autolinker@~0.28.0:
- version "0.28.1"
- resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-0.28.1.tgz#0652b491881879f0775dace0cdca3233942a4e47"
- integrity sha1-BlK0kYgYefB3XazgzcoyM5QqTkc=
- dependencies:
- gulp-header "^1.7.1"
-
aws-sdk@^2.767.0:
version "2.1030.0"
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1030.0.tgz#24a856af3d2b8b37c14a8f59974993661c66fd82"
@@ -3303,21 +3132,6 @@ aws-sdk@^2.767.0:
uuid "3.3.2"
xml2js "0.4.19"
-aws-sdk@^2.901.0:
- version "2.1036.0"
- resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1036.0.tgz#47f0d0a38b5bfbd4a7a382a6756a6aa7af627aad"
- integrity sha512-K0f4uXL32ZdoPmWiuSQEAC5ae5v7gNmhjzoEB7VonE5E8l2umWsoU0Ahm8WPr14LgsvtkeyBuqBjphbxLz6hIw==
- dependencies:
- buffer "4.9.2"
- events "1.1.1"
- ieee754 "1.1.13"
- jmespath "0.15.0"
- querystring "0.2.0"
- sax "1.2.1"
- url "0.10.3"
- uuid "3.3.2"
- xml2js "0.4.19"
-
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
@@ -3500,11 +3314,6 @@ base64-js@^1.0.2, base64-js@^1.3.1:
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
-base64url@3.x.x, base64url@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d"
- integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==
-
base@^0.11.1:
version "0.11.2"
resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f"
@@ -3525,7 +3334,7 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
-bcryptjs@2.4.3, bcryptjs@^2.4.3:
+bcryptjs@2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
@@ -3570,15 +3379,6 @@ bl@^3.0.0:
dependencies:
readable-stream "^3.0.1"
-bl@^4.0.3:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
- integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
- dependencies:
- buffer "^5.5.0"
- inherits "^2.0.4"
- readable-stream "^3.4.0"
-
bluebird@^3.5.1, bluebird@^3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
@@ -3926,11 +3726,6 @@ chokidar@^3.5.2:
optionalDependencies:
fsevents "~2.3.2"
-chownr@^1.1.1:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
- integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
-
chrome-trace-event@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
@@ -4017,15 +3812,6 @@ clone-response@1.0.2, clone-response@^1.0.2:
dependencies:
mimic-response "^1.0.0"
-cls-hooked@^4.2.2:
- version "4.2.2"
- resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
- integrity sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==
- dependencies:
- async-hook-jl "^1.7.6"
- emitter-listener "^1.0.1"
- semver "^5.4.1"
-
cluster-key-slot@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
@@ -4181,13 +3967,6 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
-concat-with-sourcemaps@*:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz#d4ea93f05ae25790951b99e7b3b09e3908a4082e"
- integrity sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==
- dependencies:
- source-map "^0.6.1"
-
condense-newlines@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/condense-newlines/-/condense-newlines-0.2.1.tgz#3de985553139475d32502c83b02f60684d24c55f"
@@ -4434,13 +4213,6 @@ date-utils@*:
resolved "https://registry.yarnpkg.com/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64"
integrity sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q=
-date.js@^0.3.1:
- version "0.3.3"
- resolved "https://registry.yarnpkg.com/date.js/-/date.js-0.3.3.tgz#ef1e92332f507a638795dbb985e951882e50bbda"
- integrity sha512-HgigOS3h3k6HnW011nAb43c5xx5rBXk8P2v/WIT9Zv4koIaVXiH2BURguI78VVp+5Qc076T7OR378JViCnZtBw==
- dependencies:
- debug "~3.1.0"
-
dateformat@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
@@ -4584,13 +4356,6 @@ deepmerge@^4.2.2:
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
-default-compare@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/default-compare/-/default-compare-1.0.0.tgz#cb61131844ad84d84788fb68fd01681ca7781a2f"
- integrity sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==
- dependencies:
- kind-of "^5.0.2"
-
default-shell@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/default-shell/-/default-shell-1.0.1.tgz#752304bddc6174f49eb29cb988feea0b8813c8bc"
@@ -4860,13 +4625,6 @@ electron-to-chromium@^1.3.896:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.900.tgz#5be2c5818a2a012c511b4b43e87b6ab7a296d4f5"
integrity sha512-SuXbQD8D4EjsaBaJJxySHbC+zq8JrFfxtb4GIr4E9n1BcROyMcRrJCYQNpJ9N+Wjf5mFp7Wp0OHykd14JNEzzQ==
-emitter-listener@^1.0.1:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8"
- integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==
- dependencies:
- shimmer "^1.2.0"
-
emittery@^0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860"
@@ -4907,7 +4665,7 @@ encoding-down@^6.3.0:
level-codec "^9.0.0"
level-errors "^2.0.0"
-end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1:
+end-of-stream@^1.0.0, end-of-stream@^1.1.0:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
@@ -4929,11 +4687,6 @@ enhanced-resolve@^5.8.3:
graceful-fs "^4.2.4"
tapable "^2.2.0"
-ent@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d"
- integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0=
-
entities@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
@@ -5859,11 +5612,6 @@ fs-constants@^1.0.0:
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
-fs-exists-sync@^0.1.0:
- version "0.1.0"
- resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
- integrity sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=
-
fs-extra@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
@@ -5936,14 +5684,6 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.1"
-get-object@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/get-object/-/get-object-0.2.0.tgz#d92ff7d5190c64530cda0543dac63a3d47fe8c0c"
- integrity sha1-2S/31RkMZFMM2gVD2sY6PUf+jAw=
- dependencies:
- is-number "^2.0.2"
- isobject "^0.2.0"
-
get-package-type@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
@@ -6006,13 +5746,6 @@ get-value@^2.0.3, get-value@^2.0.6:
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
-get-value@^3.0.0, get-value@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/get-value/-/get-value-3.0.1.tgz#5efd2a157f1d6a516d7524e124ac52d0a39ef5a8"
- integrity sha512-mKZj9JLQrwMBtj5wxi6MH8Z5eSKaERpAwjg43dPtlGI1ZVEgH/qC7T8/6R2OBSUA+zzHBZgICsVJaEIV2tKTDA==
- dependencies:
- isobject "^3.0.1"
-
getopts@2.2.5:
version "2.2.5"
resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.5.tgz#67a0fe471cacb9c687d817cab6450b96dde8313b"
@@ -6107,32 +5840,6 @@ globby@^11.0.3:
merge2 "^1.3.0"
slash "^3.0.0"
-google-auth-library@~0.10.0:
- version "0.10.0"
- resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-0.10.0.tgz#6e15babee85fd1dd14d8d128a295b6838d52136e"
- integrity sha1-bhW6vuhf0d0U2NEoopW2g41SE24=
- dependencies:
- gtoken "^1.2.1"
- jws "^3.1.4"
- lodash.noop "^3.0.1"
- request "^2.74.0"
-
-google-p12-pem@^0.1.0:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-0.1.2.tgz#33c46ab021aa734fa0332b3960a9a3ffcb2f3177"
- integrity sha1-M8RqsCGqc0+gMys5YKmj/8svMXc=
- dependencies:
- node-forge "^0.7.1"
-
-googleapis@^16.0.0:
- version "16.1.0"
- resolved "https://registry.yarnpkg.com/googleapis/-/googleapis-16.1.0.tgz#0f19f2d70572d918881a0f626e3b1a2fa8629576"
- integrity sha1-Dxny1wVy2RiIGg9ibjsaL6hilXY=
- dependencies:
- async "~2.1.4"
- google-auth-library "~0.10.0"
- string-template "~1.0.0"
-
got@^8.3.1:
version "8.3.2"
resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937"
@@ -6178,34 +5885,7 @@ graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
-gtoken@^1.2.1:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-1.2.3.tgz#5509571b8afd4322e124cf66cf68115284c476d8"
- integrity sha512-wQAJflfoqSgMWrSBk9Fg86q+sd6s7y6uJhIvvIPz++RElGlMtEqsdAR2oWwZ/WTEtp7P9xFbJRrT976oRgzJ/w==
- dependencies:
- google-p12-pem "^0.1.0"
- jws "^3.0.0"
- mime "^1.4.1"
- request "^2.72.0"
-
-gulp-header@^1.7.1:
- version "1.8.12"
- resolved "https://registry.yarnpkg.com/gulp-header/-/gulp-header-1.8.12.tgz#ad306be0066599127281c4f8786660e705080a84"
- integrity sha512-lh9HLdb53sC7XIZOYzTXM4lFuXElv3EVkSDhsd7DoJBj7hm+Ni7D3qYbb+Rr8DuM8nRanBvkVO9d7askreXGnQ==
- dependencies:
- concat-with-sourcemaps "*"
- lodash.template "^4.4.0"
- through2 "^2.0.0"
-
-handlebars-utils@^1.0.2, handlebars-utils@^1.0.4, handlebars-utils@^1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/handlebars-utils/-/handlebars-utils-1.0.6.tgz#cb9db43362479054782d86ffe10f47abc76357f9"
- integrity sha512-d5mmoQXdeEqSKMtQQZ9WkiUcO1E3tPbWxluCK9hVgIDPzQa9WsKo3Lbe/sGflTe7TomHEeZaOgwIkyIr1kfzkw==
- dependencies:
- kind-of "^6.0.0"
- typeof-article "^0.1.1"
-
-handlebars@^4.7.6, handlebars@^4.7.7:
+handlebars@^4.7.7:
version "4.7.7"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
@@ -6287,14 +5967,6 @@ has-value@^1.0.0:
has-values "^1.0.0"
isobject "^3.0.0"
-has-value@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/has-value/-/has-value-2.0.2.tgz#d0f12e8780ba8e90e66ad1a21c707fdb67c25658"
- integrity sha512-ybKOlcRsK2MqrM3Hmz/lQxXHZ6ejzSPzpNabKB45jb5qDgJvKPa3SdapTsTLwEb9WltgWpOmNax7i+DzNOk4TA==
- dependencies:
- get-value "^3.0.0"
- has-values "^2.0.1"
-
has-values@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771"
@@ -6308,13 +5980,6 @@ has-values@^1.0.0:
is-number "^3.0.0"
kind-of "^4.0.0"
-has-values@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/has-values/-/has-values-2.0.1.tgz#3876200ff86d8a8546a9264a952c17d5fc17579d"
- integrity sha512-+QdH3jOmq9P8GfdjFg0eJudqx1FqU62NQJ4P16rOEHeRdl7ckgwn6uqQjzYE0ZoHVV/e5E2esuJ5Gl5+HUW19w==
- dependencies:
- kind-of "^6.0.2"
-
has-yarn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77"
@@ -6327,39 +5992,6 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"
-helper-date@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/helper-date/-/helper-date-1.0.1.tgz#12fedea3ad8e44a7ca4c4efb0ff4104a5120cffb"
- integrity sha512-wU3VOwwTJvGr/w5rZr3cprPHO+hIhlblTJHD6aFBrKLuNbf4lAmkawd2iK3c6NbJEvY7HAmDpqjOFSI5/+Ey2w==
- dependencies:
- date.js "^0.3.1"
- handlebars-utils "^1.0.4"
- moment "^2.18.1"
-
-helper-markdown@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/helper-markdown/-/helper-markdown-1.0.0.tgz#ee7e9fc554675007d37eb90f7853b13ce74f3e10"
- integrity sha512-AnDqMS4ejkQK0MXze7pA9TM3pu01ZY+XXsES6gEE0RmCGk5/NIfvTn0NmItfyDOjRAzyo9z6X7YHbHX4PzIvOA==
- dependencies:
- handlebars-utils "^1.0.2"
- highlight.js "^9.12.0"
- remarkable "^1.7.1"
-
-helper-md@^0.2.2:
- version "0.2.2"
- resolved "https://registry.yarnpkg.com/helper-md/-/helper-md-0.2.2.tgz#c1f59d7e55bbae23362fd8a0e971607aec69d41f"
- integrity sha1-wfWdflW7riM2L9ig6XFgeuxp1B8=
- dependencies:
- ent "^2.2.0"
- extend-shallow "^2.0.1"
- fs-exists-sync "^0.1.0"
- remarkable "^1.6.2"
-
-highlight.js@^9.12.0:
- version "9.18.5"
- resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825"
- integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA==
-
hosted-git-info@^2.1.4:
version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
@@ -6389,14 +6021,6 @@ html-escaper@^2.0.0:
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
-html-tag@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/html-tag/-/html-tag-2.0.0.tgz#36c3bc8d816fd30b570d5764a497a641640c2fed"
- integrity sha512-XxzooSo6oBoxBEUazgjdXj7VwTn/iSTSZzTYKzYY6I916tkaYzypHxy+pbVU1h+0UQ9JlVf5XkNQyxOAiiQO1g==
- dependencies:
- is-self-closing "^1.0.1"
- kind-of "^6.0.0"
-
http-assert@^1.3.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.5.0.tgz#c389ccd87ac16ed2dfa6246fd73b926aa00e6b8f"
@@ -6660,23 +6284,6 @@ ioredis@^4.27.0:
redis-parser "^3.0.0"
standard-as-callback "^2.1.0"
-ioredis@^4.27.1:
- version "4.28.1"
- resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.28.1.tgz#c2a7038d6a187e020d7045e11d6a677e8b51f785"
- integrity sha512-7gcrUJEcPHWy+eEyq6wIZpXtfHt8crhbc5+z0sqrnHUkwBblXinygfamj+/jx83Qo+2LW3q87Nj2VsuH6BF2BA==
- dependencies:
- cluster-key-slot "^1.1.0"
- debug "^4.3.1"
- denque "^1.1.0"
- lodash.defaults "^4.2.0"
- lodash.flatten "^4.4.0"
- lodash.isarguments "^3.1.0"
- p-map "^2.1.0"
- redis-commands "1.7.0"
- redis-errors "^1.2.0"
- redis-parser "^3.0.0"
- standard-as-callback "^2.1.0"
-
ip-regex@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9"
@@ -6801,13 +6408,6 @@ is-docker@^2.0.0, is-docker@^2.1.1:
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
-is-even@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-even/-/is-even-1.0.0.tgz#76b5055fbad8d294a86b6a949015e1c97b717c06"
- integrity sha1-drUFX7rY0pSoa2qUkBXhyXtxfAY=
- dependencies:
- is-odd "^0.1.2"
-
is-extendable@^0.1.0, is-extendable@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
@@ -6897,13 +6497,6 @@ is-number-object@^1.0.4:
dependencies:
has-tostringtag "^1.0.0"
-is-number@^2.0.2:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
- integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=
- dependencies:
- kind-of "^3.0.2"
-
is-number@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
@@ -6926,13 +6519,6 @@ is-object@^1.0.1:
resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf"
integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==
-is-odd@^0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-0.1.2.tgz#bc573b5ce371ef2aad6e6f49799b72bef13978a7"
- integrity sha1-vFc7XONx7yqtbm9JeZtyvvE5eKc=
- dependencies:
- is-number "^3.0.0"
-
is-path-inside@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283"
@@ -6978,13 +6564,6 @@ is-retry-allowed@^2.2.0:
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-2.2.0.tgz#88f34cbd236e043e71b6932d09b0c65fb7b4d71d"
integrity sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==
-is-self-closing@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-self-closing/-/is-self-closing-1.0.1.tgz#5f406b527c7b12610176320338af0fa3896416e4"
- integrity sha512-E+60FomW7Blv5GXTlYee2KDrnG6srxF7Xt1SjrhWUGUEsTFIqY/nq2y3DaftCsgUMdh89V07IVfhY9KIJhLezg==
- dependencies:
- self-closing-tags "^1.0.1"
-
is-shared-array-buffer@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
@@ -7077,11 +6656,6 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
-isobject@^0.2.0:
- version "0.2.0"
- resolved "https://registry.yarnpkg.com/isobject/-/isobject-0.2.0.tgz#a3432192f39b910b5f02cc989487836ec70aa85e"
- integrity sha1-o0MhkvObkQtfAsyYlIeDbscKqF4=
-
isobject@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
@@ -8133,22 +7707,6 @@ jsonschema@1.4.0:
resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.0.tgz#1afa34c4bc22190d8e42271ec17ac8b3404f87b2"
integrity sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==
-jsonwebtoken@^8.2.0, jsonwebtoken@^8.5.1:
- version "8.5.1"
- resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
- integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
- dependencies:
- jws "^3.2.2"
- lodash.includes "^4.3.0"
- lodash.isboolean "^3.0.3"
- lodash.isinteger "^4.0.4"
- lodash.isnumber "^3.0.3"
- lodash.isplainobject "^4.0.6"
- lodash.isstring "^4.0.1"
- lodash.once "^4.0.0"
- ms "^2.1.1"
- semver "^5.6.0"
-
jsprim@^1.2.2:
version "1.4.0"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918"
@@ -8188,7 +7746,7 @@ jwa@^1.4.1:
ecdsa-sig-formatter "1.0.11"
safe-buffer "^5.0.1"
-jws@3.x.x, jws@^3.0.0, jws@^3.1.4, jws@^3.2.2:
+jws@3.x.x:
version "3.2.2"
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
@@ -8215,7 +7773,7 @@ keyv@3.0.0, keyv@^3.0.0:
dependencies:
json-buffer "3.0.0"
-kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.1.0, kind-of@^3.2.0:
+kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=
@@ -8229,12 +7787,12 @@ kind-of@^4.0.0:
dependencies:
is-buffer "^1.1.5"
-kind-of@^5.0.0, kind-of@^5.0.2:
+kind-of@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d"
integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==
-kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3:
+kind-of@^6.0.0, kind-of@^6.0.2:
version "6.0.3"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
@@ -8336,13 +7894,6 @@ koa-mount@^4.0.0:
debug "^4.0.1"
koa-compose "^4.1.0"
-koa-passport@^4.1.4:
- version "4.1.4"
- resolved "https://registry.yarnpkg.com/koa-passport/-/koa-passport-4.1.4.tgz#5f1665c1c2a37ace79af9f970b770885ca30ccfa"
- integrity sha512-dJBCkl4X+zdYxbI2V2OtoGy0PUenpvp2ZLLWObc8UJhsId0iQpTFT8RVcuA0709AL2txGwRHnSPoT1bYNGa6Kg==
- dependencies:
- passport "^0.4.0"
-
koa-pino-logger@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/koa-pino-logger/-/koa-pino-logger-3.0.0.tgz#27600b4f3639e8767dfc6b66493109c5457f53ba"
@@ -8685,11 +8236,6 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
-lodash._reinterpolate@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
- integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=
-
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
@@ -8710,46 +8256,16 @@ lodash.get@^4.4.2:
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
-lodash.includes@^4.3.0:
- version "4.3.0"
- resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
- integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
-
lodash.isarguments@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=
-lodash.isboolean@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
- integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
-
lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
-lodash.isinteger@^4.0.4:
- version "4.0.4"
- resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
- integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
-
-lodash.isnumber@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
- integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
-
-lodash.isplainobject@^4.0.6:
- version "4.0.6"
- resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
- integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
-
-lodash.isstring@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
- integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
-
lodash.keys@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-4.2.0.tgz#a08602ac12e4fb83f91fc1fb7a360a4d9ba35205"
@@ -8765,21 +8281,11 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
-lodash.noop@^3.0.1:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-3.0.1.tgz#38188f4d650a3a474258439b96ec45b32617133c"
- integrity sha1-OBiPTWUKOkdCWEObluxFsyYXEzw=
-
lodash.omit@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"
integrity sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=
-lodash.once@^4.0.0:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
- integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
-
lodash.pick@^4.0.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
@@ -8790,21 +8296,6 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
-lodash.template@^4.4.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab"
- integrity sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==
- dependencies:
- lodash._reinterpolate "^3.0.0"
- lodash.templatesettings "^4.0.0"
-
-lodash.templatesettings@^4.0.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz#e481310f049d3cf6d47e912ad09313b154f0fb33"
- integrity sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==
- dependencies:
- lodash._reinterpolate "^3.0.0"
-
lodash.without@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac"
@@ -8815,7 +8306,7 @@ lodash.xor@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.xor/-/lodash.xor-4.5.0.tgz#4d48ed7e98095b0632582ba714d3ff8ae8fb1db6"
integrity sha1-TUjtfpgJWwYyWCunFNP/iuj7HbY=
-lodash@4.17.21, lodash@^4.14.0, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.7.0:
+lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.3, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -9012,7 +8503,7 @@ methods@^1.0.1, methods@^1.1.1, methods@^1.1.2:
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=
-micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.5:
+micromatch@^3.1.10, micromatch@^3.1.4:
version "3.1.10"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
@@ -9113,11 +8604,6 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
-mkdirp-classic@^0.5.2:
- version "0.5.3"
- resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113"
- integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
-
mkdirp@^0.5.0, mkdirp@^0.5.1:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
@@ -9137,7 +8623,7 @@ moment-timezone@^0.5.31:
dependencies:
moment ">= 2.9.0"
-"moment@>= 2.9.0", moment@^2.18.1:
+"moment@>= 2.9.0":
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
@@ -9237,11 +8723,6 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
-nanoid@^2.1.0:
- version "2.1.11"
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
- integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
-
nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@@ -9316,11 +8797,6 @@ node-fetch@^2.6.1:
dependencies:
whatwg-url "^5.0.0"
-node-forge@^0.7.1:
- version "0.7.6"
- resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac"
- integrity sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==
-
node-gyp-build@~4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.1.1.tgz#d7270b5d86717068d114cc57fff352f96d745feb"
@@ -9448,11 +8924,6 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
-oauth@0.9.x, oauth@^0.9.15:
- version "0.9.15"
- resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"
- integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE=
-
object-assign@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa"
@@ -9763,84 +9234,6 @@ pascalcase@^0.1.1:
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
-passport-google-auth@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/passport-google-auth/-/passport-google-auth-1.0.2.tgz#8b300b5aa442ef433de1d832ed3112877d0b2938"
- integrity sha1-izALWqRC70M94dgy7TESh30LKTg=
- dependencies:
- googleapis "^16.0.0"
- passport-strategy "1.x"
-
-passport-google-oauth1@1.x.x:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/passport-google-oauth1/-/passport-google-oauth1-1.0.0.tgz#af74a803df51ec646f66a44d82282be6f108e0cc"
- integrity sha1-r3SoA99R7GRvZqRNgigr5vEI4Mw=
- dependencies:
- passport-oauth1 "1.x.x"
-
-passport-google-oauth20@2.x.x:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz#0d241b2d21ebd3dc7f2b60669ec4d587e3a674ef"
- integrity sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==
- dependencies:
- passport-oauth2 "1.x.x"
-
-passport-google-oauth@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/passport-google-oauth/-/passport-google-oauth-2.0.0.tgz#f6eb4bc96dd6c16ec0ecfdf4e05ec48ca54d4dae"
- integrity sha512-JKxZpBx6wBQXX1/a1s7VmdBgwOugohH+IxCy84aPTZNq/iIPX6u7Mqov1zY7MKRz3niFPol0KJz8zPLBoHKtYA==
- dependencies:
- passport-google-oauth1 "1.x.x"
- passport-google-oauth20 "2.x.x"
-
-passport-jwt@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065"
- integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg==
- dependencies:
- jsonwebtoken "^8.2.0"
- passport-strategy "^1.0.0"
-
-passport-local@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/passport-local/-/passport-local-1.0.0.tgz#1fe63268c92e75606626437e3b906662c15ba6ee"
- integrity sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=
- dependencies:
- passport-strategy "1.x.x"
-
-passport-oauth1@1.x.x:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/passport-oauth1/-/passport-oauth1-1.2.0.tgz#5229d431781bf5b265bec86ce9a9cce58a756cf9"
- integrity sha512-Sv2YWodC6jN12M/OXwmR4BIXeeIHjjbwYTQw4kS6tHK4zYzSEpxBgSJJnknBjICA5cj0ju3FSnG1XmHgIhYnLg==
- dependencies:
- oauth "0.9.x"
- passport-strategy "1.x.x"
- utils-merge "1.x.x"
-
-passport-oauth2@1.x.x:
- version "1.6.1"
- resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.6.1.tgz#c5aee8f849ce8bd436c7f81d904a3cd1666f181b"
- integrity sha512-ZbV43Hq9d/SBSYQ22GOiglFsjsD1YY/qdiptA+8ej+9C1dL1TVB+mBE5kDH/D4AJo50+2i8f4bx0vg4/yDDZCQ==
- dependencies:
- base64url "3.x.x"
- oauth "0.9.x"
- passport-strategy "1.x.x"
- uid2 "0.0.x"
- utils-merge "1.x.x"
-
-passport-strategy@1.x, passport-strategy@1.x.x, passport-strategy@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4"
- integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=
-
-passport@^0.4.0:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270"
- integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==
- dependencies:
- passport-strategy "1.x.x"
- pause "0.0.1"
-
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
@@ -9895,11 +9288,6 @@ path-type@^4.0.0:
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
-pause@0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d"
- integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=
-
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
@@ -10623,7 +10011,7 @@ readable-stream@1.1.14, readable-stream@^1.0.27-1:
isarray "0.0.1"
string_decoder "~0.10.x"
-"readable-stream@2 || 3", readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
+"readable-stream@2 || 3", readable-stream@^3.0.0, readable-stream@^3.0.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@@ -10764,16 +10152,6 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"
-regexparam@2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-2.0.0.tgz#059476767d5f5f87f735fc7922d133fd1a118c8c"
- integrity sha512-gJKwd2MVPWHAIFLsaYDZfyKzHNS4o7E/v8YmNf44vmeV2e4YfVoDToTOKTvE7ab68cRJ++kLuEXJBaEeJVt5ow==
-
-regexparam@^1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f"
- integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==
-
regexpp@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f"
@@ -10817,21 +10195,6 @@ regjsparser@^0.7.0:
dependencies:
jsesc "~0.5.0"
-relative@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/relative/-/relative-3.0.2.tgz#0dcd8ec54a5d35a3c15e104503d65375b5a5367f"
- integrity sha1-Dc2OxUpdNaPBXhBFA9ZTdbWlNn8=
- dependencies:
- isobject "^2.0.0"
-
-remarkable@^1.6.2, remarkable@^1.7.1:
- version "1.7.4"
- resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.4.tgz#19073cb960398c87a7d6546eaa5e50d2022fcd00"
- integrity sha512-e6NKUXgX95whv7IgddywbeN/ItCkWbISmc2DiqHJb0wTrqZIexqdco5b8Z3XZoo/48IdNVKM9ZCvTPJ4F5uvhg==
- dependencies:
- argparse "^1.0.10"
- autolinker "~0.28.0"
-
remove-trailing-separator@^1.0.1:
version "1.1.0"
resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef"
@@ -10868,7 +10231,7 @@ request-promise-native@^1.0.5:
stealthy-require "^1.1.1"
tough-cookie "^2.3.3"
-request@^2.72.0, request@^2.74.0, request@^2.87.0, request@^2.88.0:
+request@^2.87.0:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
@@ -11080,11 +10443,6 @@ sane@^4.0.3:
minimist "^1.1.1"
walker "~1.0.5"
-sanitize-s3-objectkey@^0.0.1:
- version "0.0.1"
- resolved "https://registry.yarnpkg.com/sanitize-s3-objectkey/-/sanitize-s3-objectkey-0.0.1.tgz#efa9887cd45275b40234fb4bb12fc5754fe64e7e"
- integrity sha512-ZTk7aqLxy4sD40GWcYWoLfbe05XLmkKvh6vGKe13ADlei24xlezcvjgKy1qRArlaIbIMYaqK7PCalvZtulZlaQ==
-
saslprep@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/saslprep/-/saslprep-1.0.3.tgz#4c02f946b56cf54297e347ba1093e7acac4cf226"
@@ -11097,7 +10455,7 @@ sax@1.2.1:
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o=
-sax@>=0.1.1, sax@>=0.6.0, sax@^1.2.4:
+sax@>=0.6.0, sax@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
@@ -11130,11 +10488,6 @@ seek-bzip@^1.0.5:
dependencies:
commander "^2.8.1"
-self-closing-tags@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/self-closing-tags/-/self-closing-tags-1.0.1.tgz#6c5fa497994bb826b484216916371accee490a5d"
- integrity sha512-7t6hNbYMxM+VHXTgJmxwgZgLGktuXtVVD5AivWzNTdJBM4DBjnDKDzkf2SrNjihaArpeJYNjxkELBu1evI4lQA==
-
semver-diff@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b"
@@ -11142,7 +10495,7 @@ semver-diff@^3.1.1:
dependencies:
semver "^6.3.0"
-"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
+"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -11253,18 +10606,6 @@ shell-path@^2.1.0:
dependencies:
shell-env "^0.3.0"
-shimmer@^1.2.0:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
- integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
-
-shortid@^2.2.15:
- version "2.2.16"
- resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.16.tgz#b742b8f0cb96406fd391c76bfc18a67a57fe5608"
- integrity sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==
- dependencies:
- nanoid "^2.1.0"
-
side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
@@ -11539,11 +10880,6 @@ sshpk@^1.7.0:
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
-stack-chain@^1.3.7:
- version "1.3.7"
- resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
- integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=
-
stack-trace@0.0.x:
version "0.0.10"
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
@@ -11591,11 +10927,6 @@ stealthy-require@^1.1.1:
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
-step@0.0.x:
- version "0.0.6"
- resolved "https://registry.yarnpkg.com/step/-/step-0.0.6.tgz#143e7849a5d7d3f4a088fe29af94915216eeede2"
- integrity sha1-FD54SaXX0/SgiP4pr5SRUhbu7eI=
-
strict-uri-encode@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
@@ -11614,11 +10945,6 @@ string-length@^4.0.1:
char-regex "^1.0.2"
strip-ansi "^6.0.0"
-string-template@~1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96"
- integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y=
-
string-width@^3.0.0, string-width@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
@@ -11752,11 +11078,6 @@ strip-outer@^1.0.0:
dependencies:
escape-string-regexp "^1.0.2"
-striptags@^3.1.1:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/striptags/-/striptags-3.2.0.tgz#cc74a137db2de8b0b9a370006334161f7dd67052"
- integrity sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw==
-
style-loader@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.1.tgz#057dfa6b3d4d7c7064462830f9113ed417d38575"
@@ -11851,13 +11172,6 @@ svelte-portal@^1.0.0:
resolved "https://registry.yarnpkg.com/svelte-portal/-/svelte-portal-1.0.0.tgz#36a47c5578b1a4d9b4dc60fa32a904640ec4cdd3"
integrity sha512-nHf+DS/jZ6jjnZSleBMSaZua9JlG5rZv9lOGKgJuaZStfevtjIlUJrkLc3vbV8QdBvPPVmvcjTlazAzfKu0v3Q==
-svelte-spa-router@^3.0.5:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/svelte-spa-router/-/svelte-spa-router-3.2.0.tgz#fae3311d292451236cb57131262406cf312b15ee"
- integrity sha512-igemo5Vs82TGBBw+DjWt6qKameXYzNs6aDXcTxou5XbEvOjiRcAM6MLkdVRCatn6u8r42dE99bt/br7T4qe/AQ==
- dependencies:
- regexparam "2.0.0"
-
svelte@^3.38.2:
version "3.44.1"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.44.1.tgz#5cc772a8340f4519a4ecd1ac1a842325466b1a63"
@@ -11938,16 +11252,6 @@ tapable@^2.1.1, tapable@^2.2.0:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
-tar-fs@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784"
- integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==
- dependencies:
- chownr "^1.1.1"
- mkdirp-classic "^0.5.2"
- pump "^3.0.0"
- tar-stream "^2.1.4"
-
tar-stream@^1.5.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555"
@@ -11961,17 +11265,6 @@ tar-stream@^1.5.2:
to-buffer "^1.1.1"
xtend "^4.0.0"
-tar-stream@^2.1.4:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
- integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
- dependencies:
- bl "^4.0.3"
- end-of-stream "^1.4.1"
- fs-constants "^1.0.0"
- inherits "^2.0.3"
- readable-stream "^3.1.1"
-
tarn@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/tarn/-/tarn-1.1.5.tgz#7be88622e951738b9fa3fb77477309242cdddc2d"
@@ -12163,11 +11456,6 @@ to-fast-properties@^2.0.0:
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
-to-gfm-code-block@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/to-gfm-code-block/-/to-gfm-code-block-0.1.1.tgz#25d045a5fae553189e9637b590900da732d8aa82"
- integrity sha1-JdBFpfrlUxielje1kJANpzLYqoI=
-
to-json-schema@0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/to-json-schema/-/to-json-schema-0.2.5.tgz#ef3c3f11ad64460dcfbdbafd0fd525d69d62a98f"
@@ -12404,13 +11692,6 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"
-typeof-article@^0.1.1:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/typeof-article/-/typeof-article-0.1.1.tgz#9f07e733c3fbb646ffa9e61c08debacd460e06af"
- integrity sha1-nwfnM8P7tkb/qeYcCN66zUYOBq8=
- dependencies:
- kind-of "^3.1.0"
-
typescript@^4.3.5:
version "4.3.5"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4"
@@ -12426,11 +11707,6 @@ uglify-js@^3.1.4:
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf"
integrity sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==
-uid2@0.0.x:
- version "0.0.4"
- resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.4.tgz#033f3b1d5d32505f5ce5f888b9f3b667123c0a44"
- integrity sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==
-
unbox-primitive@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471"
@@ -12634,11 +11910,6 @@ util.promisify@^1.0.0, util.promisify@^1.0.1:
has-symbols "^1.0.1"
object.getownpropertydescriptors "^2.1.1"
-utils-merge@1.x.x:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
- integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
-
uuid@3.3.2, uuid@^3.1.0, uuid@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
@@ -12703,7 +11974,7 @@ verror@1.3.6:
dependencies:
extsprintf "1.0.2"
-vm2@^3.9.3, vm2@^3.9.4:
+vm2@^3.9.3:
version "3.9.5"
resolved "https://registry.yarnpkg.com/vm2/-/vm2-3.9.5.tgz#5288044860b4bbace443101fcd3bddb2a0aa2496"
integrity sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng==
@@ -12742,14 +12013,6 @@ watchpack@^2.2.0:
glob-to-regexp "^0.4.1"
graceful-fs "^4.1.2"
-webfinger@^0.4.2:
- version "0.4.2"
- resolved "https://registry.yarnpkg.com/webfinger/-/webfinger-0.4.2.tgz#3477a6d97799461896039fcffc650b73468ee76d"
- integrity sha1-NHem2XeZRhiWA5/P/GULc0aO520=
- dependencies:
- step "0.0.x"
- xml2js "0.1.x"
-
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
@@ -13066,13 +12329,6 @@ xml-parse-from-string@^1.0.0:
resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28"
integrity sha1-qQKekp09vN7RafPG4oI42VpdWig=
-xml2js@0.1.x:
- version "0.1.14"
- resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.1.14.tgz#5274e67f5a64c5f92974cd85139e0332adc6b90c"
- integrity sha1-UnTmf1pkxfkpdM2FE54DMq3GuQw=
- dependencies:
- sax ">=0.1.1"
-
xml2js@0.4.19:
version "0.4.19"
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7"
@@ -13214,11 +12470,6 @@ yauzl@^2.4.2:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"
-year@^0.2.1:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/year/-/year-0.2.1.tgz#4083ae520a318b23ec86037f3000cb892bdf9bb0"
- integrity sha1-QIOuUgoxiyPshgN/MADLiSvfm7A=
-
ylru@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f"
@@ -13240,7 +12491,7 @@ z-schema@^5.0.1:
optionalDependencies:
commander "^2.7.1"
-zlib@1.0.5, zlib@^1.0.5:
+zlib@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/zlib/-/zlib-1.0.5.tgz#6e7c972fc371c645a6afb03ab14769def114fcc0"
integrity sha1-bnyXL8NxxkWmr7A6sUdp3vEU/MA=
From 9d5866e7470bb1e03484c30b8707bfb012b80f3e Mon Sep 17 00:00:00 2001
From: Rory Powell
Date: Thu, 2 Dec 2021 16:51:13 +0000
Subject: [PATCH 12/30] Fix datasource selection after import and add maxmimum
files support to dropzone
---
packages/bbui/src/Form/Core/Dropzone.svelte | 215 +++++++++---------
packages/bbui/src/Form/Dropzone.svelte | 2 +
.../modals/ImportRestQueriesModal.svelte | 30 ++-
3 files changed, 130 insertions(+), 117 deletions(-)
diff --git a/packages/bbui/src/Form/Core/Dropzone.svelte b/packages/bbui/src/Form/Core/Dropzone.svelte
index 1595a2ea92..bbaf5a3ff9 100644
--- a/packages/bbui/src/Form/Core/Dropzone.svelte
+++ b/packages/bbui/src/Form/Core/Dropzone.svelte
@@ -21,6 +21,7 @@
export let gallery = true
export let error = null
export let fileTags = []
+ export let maximum = null
const dispatch = createEventDispatcher()
const imageExtensions = [
@@ -187,116 +188,118 @@
{/each}
{/if}
{/if}
-
-
-
-
-
+ {/if}