Merge pull request #10680 from Budibase/budi-6933-verify-data-source-connection-during
Verify data source connection before saves
This commit is contained in:
commit
77a619945b
|
@ -2,6 +2,7 @@ import { datasources, tables } from "../stores/backend"
|
||||||
import { IntegrationNames } from "../constants/backend"
|
import { IntegrationNames } from "../constants/backend"
|
||||||
import { get } from "svelte/store"
|
import { get } from "svelte/store"
|
||||||
import cloneDeep from "lodash/cloneDeepWith"
|
import cloneDeep from "lodash/cloneDeepWith"
|
||||||
|
import { API } from "api"
|
||||||
|
|
||||||
function prepareData(config) {
|
function prepareData(config) {
|
||||||
let datasource = {}
|
let datasource = {}
|
||||||
|
@ -37,3 +38,9 @@ export async function createRestDatasource(integration) {
|
||||||
const config = cloneDeep(integration)
|
const config = cloneDeep(integration)
|
||||||
return saveDatasource(config)
|
return saveDatasource(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function validateDatasourceConfig(config) {
|
||||||
|
const datasource = prepareData(config)
|
||||||
|
const resp = await API.validateDatasource(datasource)
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
config,
|
config,
|
||||||
schema: selected.datasource,
|
schema: selected.datasource,
|
||||||
auth: selected.auth,
|
auth: selected.auth,
|
||||||
|
features: selected.features || [],
|
||||||
}
|
}
|
||||||
if (selected.friendlyName) {
|
if (selected.friendlyName) {
|
||||||
integration.name = selected.friendlyName
|
integration.name = selected.friendlyName
|
||||||
|
|
|
@ -4,55 +4,68 @@
|
||||||
import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte"
|
import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte"
|
||||||
import { IntegrationNames } from "constants/backend"
|
import { IntegrationNames } from "constants/backend"
|
||||||
import cloneDeep from "lodash/cloneDeepWith"
|
import cloneDeep from "lodash/cloneDeepWith"
|
||||||
import { saveDatasource as save } from "builderStore/datasource"
|
import {
|
||||||
import { onMount } from "svelte"
|
saveDatasource as save,
|
||||||
|
validateDatasourceConfig,
|
||||||
|
} from "builderStore/datasource"
|
||||||
|
import { DatasourceFeature } from "@budibase/types"
|
||||||
|
|
||||||
export let integration
|
export let integration
|
||||||
export let modal
|
export let modal
|
||||||
|
|
||||||
// kill the reference so the input isn't saved
|
// kill the reference so the input isn't saved
|
||||||
let datasource = cloneDeep(integration)
|
let datasource = cloneDeep(integration)
|
||||||
let skipFetch = false
|
|
||||||
let isValid = false
|
let isValid = false
|
||||||
|
|
||||||
$: name =
|
$: name =
|
||||||
IntegrationNames[datasource.type] || datasource.name || datasource.type
|
IntegrationNames[datasource.type] || datasource.name || datasource.type
|
||||||
|
|
||||||
|
async function validateConfig() {
|
||||||
|
const displayError = message =>
|
||||||
|
notifications.error(message ?? "Error validating datasource")
|
||||||
|
|
||||||
|
let connected = false
|
||||||
|
try {
|
||||||
|
const resp = await validateDatasourceConfig(datasource)
|
||||||
|
if (!resp.connected) {
|
||||||
|
displayError(`Unable to connect - ${resp.error}`)
|
||||||
|
}
|
||||||
|
connected = resp.connected
|
||||||
|
} catch (err) {
|
||||||
|
displayError(err?.message)
|
||||||
|
}
|
||||||
|
return connected
|
||||||
|
}
|
||||||
|
|
||||||
async function saveDatasource() {
|
async function saveDatasource() {
|
||||||
|
if (integration.features[DatasourceFeature.CONNECTION_CHECKING]) {
|
||||||
|
const valid = await validateConfig()
|
||||||
|
if (!valid) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (!datasource.name) {
|
if (!datasource.name) {
|
||||||
datasource.name = name
|
datasource.name = name
|
||||||
}
|
}
|
||||||
const resp = await save(datasource, skipFetch)
|
const resp = await save(datasource)
|
||||||
$goto(`./datasource/${resp._id}`)
|
$goto(`./datasource/${resp._id}`)
|
||||||
notifications.success(`Datasource updated successfully.`)
|
notifications.success(`Datasource created successfully.`)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
notifications.error(err?.message ?? "Error saving datasource")
|
notifications.error(err?.message ?? "Error saving datasource")
|
||||||
// prevent the modal from closing
|
// prevent the modal from closing
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
skipFetch = false
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ModalContent
|
<ModalContent
|
||||||
title={`Connect to ${name}`}
|
title={`Connect to ${name}`}
|
||||||
onConfirm={() => saveDatasource()}
|
onConfirm={() => saveDatasource()}
|
||||||
onCancel={() => modal.show()}
|
onCancel={() => modal.show()}
|
||||||
confirmText={datasource.plus
|
confirmText={datasource.plus ? "Connect" : "Save and continue to query"}
|
||||||
? "Save and fetch tables"
|
|
||||||
: "Save and continue to query"}
|
|
||||||
cancelText="Back"
|
cancelText="Back"
|
||||||
showSecondaryButton={datasource.plus}
|
showSecondaryButton={datasource.plus}
|
||||||
secondaryButtonText={datasource.plus ? "Skip table fetch" : undefined}
|
|
||||||
secondaryAction={() => {
|
|
||||||
skipFetch = true
|
|
||||||
saveDatasource()
|
|
||||||
return true
|
|
||||||
}}
|
|
||||||
size="L"
|
size="L"
|
||||||
disabled={!isValid}
|
disabled={!isValid}
|
||||||
>
|
>
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
import { isEqual } from "lodash"
|
import { isEqual } from "lodash"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import ImportRestQueriesModal from "components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte"
|
import ImportRestQueriesModal from "components/backend/DatasourceNavigator/modals/ImportRestQueriesModal.svelte"
|
||||||
|
import { API } from "api"
|
||||||
|
import { DatasourceFeature } from "@budibase/types"
|
||||||
|
|
||||||
const querySchema = {
|
const querySchema = {
|
||||||
name: {},
|
name: {},
|
||||||
|
@ -45,7 +47,30 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function validateConfig() {
|
||||||
|
const displayError = message =>
|
||||||
|
notifications.error(message ?? "Error validating datasource")
|
||||||
|
|
||||||
|
let connected = false
|
||||||
|
try {
|
||||||
|
const resp = await API.validateDatasource(datasource)
|
||||||
|
if (!resp.connected) {
|
||||||
|
displayError(`Unable to connect - ${resp.error}`)
|
||||||
|
}
|
||||||
|
connected = resp.connected
|
||||||
|
} catch (err) {
|
||||||
|
displayError(err?.message)
|
||||||
|
}
|
||||||
|
return connected
|
||||||
|
}
|
||||||
|
|
||||||
const saveDatasource = async () => {
|
const saveDatasource = async () => {
|
||||||
|
if (integration.features[DatasourceFeature.CONNECTION_CHECKING]) {
|
||||||
|
const valid = await validateConfig()
|
||||||
|
if (!valid) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
// Create datasource
|
// Create datasource
|
||||||
await datasources.save(datasource)
|
await datasources.save(datasource)
|
||||||
|
|
|
@ -31,6 +31,18 @@
|
||||||
return "Invalid URL"
|
return "Invalid URL"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$: urlManuallySet = false
|
||||||
|
|
||||||
|
const updateUrl = event => {
|
||||||
|
const appName = event.detail
|
||||||
|
if (urlManuallySet) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const parsedUrl = appName.toLowerCase().replace(/\s+/g, "-")
|
||||||
|
url = encodeURI(parsedUrl)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
@ -43,11 +55,13 @@
|
||||||
bind:value={name}
|
bind:value={name}
|
||||||
bind:error={nameError}
|
bind:error={nameError}
|
||||||
validate={validateName}
|
validate={validateName}
|
||||||
|
on:change={updateUrl}
|
||||||
label="Name"
|
label="Name"
|
||||||
/>
|
/>
|
||||||
<FancyInput
|
<FancyInput
|
||||||
bind:value={url}
|
bind:value={url}
|
||||||
bind:error={urlError}
|
bind:error={urlError}
|
||||||
|
on:change={() => (urlManuallySet = true)}
|
||||||
validate={validateUrl}
|
validate={validateUrl}
|
||||||
label="URL"
|
label="URL"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
import { Roles } from "constants/backend"
|
import { Roles } from "constants/backend"
|
||||||
import Spinner from "components/common/Spinner.svelte"
|
import Spinner from "components/common/Spinner.svelte"
|
||||||
import { helpers } from "@budibase/shared-core"
|
import { helpers } from "@budibase/shared-core"
|
||||||
|
import { validateDatasourceConfig } from "builderStore/datasource"
|
||||||
|
import { DatasourceFeature } from "@budibase/types"
|
||||||
|
|
||||||
let name = "My first app"
|
let name = "My first app"
|
||||||
let url = "my-first-app"
|
let url = "my-first-app"
|
||||||
|
@ -108,7 +110,24 @@
|
||||||
isGoogle,
|
isGoogle,
|
||||||
}) => {
|
}) => {
|
||||||
let app
|
let app
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (
|
||||||
|
datasourceConfig &&
|
||||||
|
plusIntegrations[stage].features[DatasourceFeature.CONNECTION_CHECKING]
|
||||||
|
) {
|
||||||
|
const resp = await validateDatasourceConfig({
|
||||||
|
config: datasourceConfig,
|
||||||
|
type: stage,
|
||||||
|
})
|
||||||
|
if (!resp.connected) {
|
||||||
|
notifications.error(
|
||||||
|
`Unable to connect - ${resp.error ?? "Error validating datasource"}`
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
app = await createApp(useSampleData)
|
app = await createApp(useSampleData)
|
||||||
|
|
||||||
let datasource
|
let datasource
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
import { API } from "api"
|
import { API } from "api"
|
||||||
import { licensing } from "./licensing"
|
import { licensing } from "./licensing"
|
||||||
import { ConfigType } from "../../../../types/src/documents"
|
import { ConfigType } from "@budibase/types"
|
||||||
|
|
||||||
export const createFeatureStore = () => {
|
export const createFeatureStore = () => {
|
||||||
const internalStore = writable({
|
const internalStore = writable({
|
||||||
|
|
|
@ -58,4 +58,15 @@ export const buildDatasourceEndpoints = API => ({
|
||||||
url: `/api/datasources/${datasourceId}/${datasourceRev}`,
|
url: `/api/datasources/${datasourceId}/${datasourceRev}`,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a datasource configuration
|
||||||
|
* @param datasource the datasource configuration to validate
|
||||||
|
*/
|
||||||
|
validateDatasource: async datasource => {
|
||||||
|
return await API.post({
|
||||||
|
url: `/api/datasources/verify`,
|
||||||
|
body: { datasource },
|
||||||
|
})
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -20,7 +20,9 @@ const SCHEMA: Integration = {
|
||||||
"Airtable is a spreadsheet-database hybrid, with the features of a database but applied to a spreadsheet.",
|
"Airtable is a spreadsheet-database hybrid, with the features of a database but applied to a spreadsheet.",
|
||||||
friendlyName: "Airtable",
|
friendlyName: "Airtable",
|
||||||
type: "Spreadsheet",
|
type: "Spreadsheet",
|
||||||
features: [DatasourceFeature.CONNECTION_CHECKING],
|
features: {
|
||||||
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
apiKey: {
|
apiKey: {
|
||||||
type: DatasourceFieldType.PASSWORD,
|
type: DatasourceFieldType.PASSWORD,
|
||||||
|
|
|
@ -23,7 +23,9 @@ const SCHEMA: Integration = {
|
||||||
type: "Non-relational",
|
type: "Non-relational",
|
||||||
description:
|
description:
|
||||||
"ArangoDB is a scalable open-source multi-model database natively supporting graph, document and search. All supported data models & access patterns can be combined in queries allowing for maximal flexibility. ",
|
"ArangoDB is a scalable open-source multi-model database natively supporting graph, document and search. All supported data models & access patterns can be combined in queries allowing for maximal flexibility. ",
|
||||||
features: [DatasourceFeature.CONNECTION_CHECKING],
|
features: {
|
||||||
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
url: {
|
url: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
|
|
|
@ -20,7 +20,9 @@ const SCHEMA: Integration = {
|
||||||
type: "Non-relational",
|
type: "Non-relational",
|
||||||
description:
|
description:
|
||||||
"Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang.",
|
"Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang.",
|
||||||
features: [DatasourceFeature.CONNECTION_CHECKING],
|
features: {
|
||||||
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
url: {
|
url: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
|
|
|
@ -25,7 +25,9 @@ const SCHEMA: Integration = {
|
||||||
"Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale.",
|
"Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale.",
|
||||||
friendlyName: "DynamoDB",
|
friendlyName: "DynamoDB",
|
||||||
type: "Non-relational",
|
type: "Non-relational",
|
||||||
features: [DatasourceFeature.CONNECTION_CHECKING],
|
features: {
|
||||||
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
region: {
|
region: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
|
|
|
@ -22,7 +22,9 @@ const SCHEMA: Integration = {
|
||||||
"Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.",
|
"Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.",
|
||||||
friendlyName: "ElasticSearch",
|
friendlyName: "ElasticSearch",
|
||||||
type: "Non-relational",
|
type: "Non-relational",
|
||||||
features: [DatasourceFeature.CONNECTION_CHECKING],
|
features: {
|
||||||
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
url: {
|
url: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
|
|
|
@ -20,7 +20,9 @@ const SCHEMA: Integration = {
|
||||||
type: "Non-relational",
|
type: "Non-relational",
|
||||||
description:
|
description:
|
||||||
"Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.",
|
"Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.",
|
||||||
features: [DatasourceFeature.CONNECTION_CHECKING],
|
features: {
|
||||||
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
email: {
|
email: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
|
|
|
@ -66,10 +66,10 @@ const SCHEMA: Integration = {
|
||||||
"Create and collaborate on online spreadsheets in real-time and from any device.",
|
"Create and collaborate on online spreadsheets in real-time and from any device.",
|
||||||
friendlyName: "Google Sheets",
|
friendlyName: "Google Sheets",
|
||||||
type: "Spreadsheet",
|
type: "Spreadsheet",
|
||||||
features: [
|
features: {
|
||||||
DatasourceFeature.CONNECTION_CHECKING,
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
DatasourceFeature.FETCH_TABLE_NAMES,
|
[DatasourceFeature.FETCH_TABLE_NAMES]: true,
|
||||||
],
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
spreadsheetId: {
|
spreadsheetId: {
|
||||||
display: "Google Sheet URL",
|
display: "Google Sheet URL",
|
||||||
|
|
|
@ -40,10 +40,10 @@ const SCHEMA: Integration = {
|
||||||
"Microsoft SQL Server is a relational database management system developed by Microsoft. ",
|
"Microsoft SQL Server is a relational database management system developed by Microsoft. ",
|
||||||
friendlyName: "MS SQL Server",
|
friendlyName: "MS SQL Server",
|
||||||
type: "Relational",
|
type: "Relational",
|
||||||
features: [
|
features: {
|
||||||
DatasourceFeature.CONNECTION_CHECKING,
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
DatasourceFeature.FETCH_TABLE_NAMES,
|
[DatasourceFeature.FETCH_TABLE_NAMES]: true,
|
||||||
],
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
user: {
|
user: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
|
|
|
@ -40,7 +40,9 @@ const getSchema = () => {
|
||||||
type: "Non-relational",
|
type: "Non-relational",
|
||||||
description:
|
description:
|
||||||
"MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.",
|
"MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.",
|
||||||
features: [DatasourceFeature.CONNECTION_CHECKING],
|
features: {
|
||||||
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
connectionString: {
|
connectionString: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
|
|
|
@ -36,10 +36,10 @@ const SCHEMA: Integration = {
|
||||||
type: "Relational",
|
type: "Relational",
|
||||||
description:
|
description:
|
||||||
"MySQL Database Service is a fully managed database service to deploy cloud-native applications. ",
|
"MySQL Database Service is a fully managed database service to deploy cloud-native applications. ",
|
||||||
features: [
|
features: {
|
||||||
DatasourceFeature.CONNECTION_CHECKING,
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
DatasourceFeature.FETCH_TABLE_NAMES,
|
[DatasourceFeature.FETCH_TABLE_NAMES]: true,
|
||||||
],
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
host: {
|
host: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
|
|
|
@ -50,10 +50,10 @@ const SCHEMA: Integration = {
|
||||||
type: "Relational",
|
type: "Relational",
|
||||||
description:
|
description:
|
||||||
"Oracle Database is an object-relational database management system developed by Oracle Corporation",
|
"Oracle Database is an object-relational database management system developed by Oracle Corporation",
|
||||||
features: [
|
features: {
|
||||||
DatasourceFeature.CONNECTION_CHECKING,
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
DatasourceFeature.FETCH_TABLE_NAMES,
|
[DatasourceFeature.FETCH_TABLE_NAMES]: true,
|
||||||
],
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
host: {
|
host: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
|
|
|
@ -52,10 +52,10 @@ const SCHEMA: Integration = {
|
||||||
type: "Relational",
|
type: "Relational",
|
||||||
description:
|
description:
|
||||||
"PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.",
|
"PostgreSQL, also known as Postgres, is a free and open-source relational database management system emphasizing extensibility and SQL compliance.",
|
||||||
features: [
|
features: {
|
||||||
DatasourceFeature.CONNECTION_CHECKING,
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
DatasourceFeature.FETCH_TABLE_NAMES,
|
[DatasourceFeature.FETCH_TABLE_NAMES]: true,
|
||||||
],
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
host: {
|
host: {
|
||||||
type: DatasourceFieldType.STRING,
|
type: DatasourceFieldType.STRING,
|
||||||
|
|
|
@ -21,7 +21,9 @@ const SCHEMA: Integration = {
|
||||||
"Redis is a caching tool, providing powerful key-value store capabilities.",
|
"Redis is a caching tool, providing powerful key-value store capabilities.",
|
||||||
friendlyName: "Redis",
|
friendlyName: "Redis",
|
||||||
type: "Non-relational",
|
type: "Non-relational",
|
||||||
features: [DatasourceFeature.CONNECTION_CHECKING],
|
features: {
|
||||||
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
host: {
|
host: {
|
||||||
type: "string",
|
type: "string",
|
||||||
|
|
|
@ -24,7 +24,9 @@ const SCHEMA: Integration = {
|
||||||
"Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.",
|
"Amazon Simple Storage Service (Amazon S3) is an object storage service that offers industry-leading scalability, data availability, security, and performance.",
|
||||||
friendlyName: "Amazon S3",
|
friendlyName: "Amazon S3",
|
||||||
type: "Object store",
|
type: "Object store",
|
||||||
features: [DatasourceFeature.CONNECTION_CHECKING],
|
features: {
|
||||||
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
region: {
|
region: {
|
||||||
type: "string",
|
type: "string",
|
||||||
|
|
|
@ -22,7 +22,9 @@ const SCHEMA: Integration = {
|
||||||
"Snowflake is a solution for data warehousing, data lakes, data engineering, data science, data application development, and securely sharing and consuming shared data.",
|
"Snowflake is a solution for data warehousing, data lakes, data engineering, data science, data application development, and securely sharing and consuming shared data.",
|
||||||
friendlyName: "Snowflake",
|
friendlyName: "Snowflake",
|
||||||
type: "Relational",
|
type: "Relational",
|
||||||
features: [DatasourceFeature.CONNECTION_CHECKING],
|
features: {
|
||||||
|
[DatasourceFeature.CONNECTION_CHECKING]: true,
|
||||||
|
},
|
||||||
datasource: {
|
datasource: {
|
||||||
account: {
|
account: {
|
||||||
type: "string",
|
type: "string",
|
||||||
|
|
|
@ -116,7 +116,7 @@ export interface Integration {
|
||||||
docs: string
|
docs: string
|
||||||
plus?: boolean
|
plus?: boolean
|
||||||
auth?: { type: string }
|
auth?: { type: string }
|
||||||
features?: DatasourceFeature[]
|
features?: Partial<Record<DatasourceFeature, boolean>>
|
||||||
relationships?: boolean
|
relationships?: boolean
|
||||||
description: string
|
description: string
|
||||||
friendlyName: string
|
friendlyName: string
|
||||||
|
|
Loading…
Reference in New Issue