schema updates, custom fields
This commit is contained in:
parent
94ee5855a5
commit
01ff661f17
|
@ -8,7 +8,7 @@
|
||||||
{#each Object.keys(integration) as configKey}
|
{#each Object.keys(integration) as configKey}
|
||||||
<Input
|
<Input
|
||||||
thin
|
thin
|
||||||
type={configKey.type}
|
type={integration[configKey].type}
|
||||||
label={configKey}
|
label={configKey}
|
||||||
bind:value={integration[configKey]} />
|
bind:value={integration[configKey]} />
|
||||||
<Spacer medium />
|
<Spacer medium />
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
<Spacer medium />
|
<Spacer medium />
|
||||||
{/each}
|
{/each}
|
||||||
{#if schema.customisable}
|
{#if schema.customisable}
|
||||||
|
<Spacer large />
|
||||||
<Label>Add Custom Field</Label>
|
<Label>Add Custom Field</Label>
|
||||||
{#each Object.keys(customSchema) as field}
|
{#each Object.keys(customSchema) as field}
|
||||||
<Label extraSmall grey>{field}</Label>
|
<Label extraSmall grey>{field}</Label>
|
||||||
|
@ -54,7 +55,7 @@
|
||||||
<option value={"number"}>Number</option>
|
<option value={"number"}>Number</option>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
<Button small thin primary on:click={addField}>Add Field</Button>
|
<Button small thin secondary on:click={addField}>Add Field</Button>
|
||||||
{/if}
|
{/if}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,6 @@
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const QueryVerb = ["create", "read", "update", "delete"]
|
|
||||||
|
|
||||||
export let query
|
export let query
|
||||||
export let fields = []
|
export let fields = []
|
||||||
|
|
||||||
|
@ -128,25 +126,27 @@
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<Heading small>{query.name}</Heading>
|
<Heading small>{query.name}</Heading>
|
||||||
<div class="queryVerbs">
|
{#if config}
|
||||||
{#each QueryVerb as queryVerb}
|
<div class="queryVerbs">
|
||||||
<div
|
{#each Object.keys(config) as queryVerb}
|
||||||
class="queryVerb"
|
<div
|
||||||
class:selected={queryVerb === query.queryVerb}
|
class="queryVerb"
|
||||||
on:click={() => {
|
class:selected={queryVerb === query.queryVerb}
|
||||||
query.queryVerb = queryVerb
|
on:click={() => {
|
||||||
}}>
|
query.queryVerb = queryVerb
|
||||||
{queryVerb}
|
}}>
|
||||||
</div>
|
{queryVerb}
|
||||||
{/each}
|
</div>
|
||||||
</div>
|
|
||||||
{#if config && query.queryVerb}
|
|
||||||
<Select thin secondary bind:value={query.queryType}>
|
|
||||||
<option value={''}>Select an option</option>
|
|
||||||
{#each Object.keys(config[query.queryVerb]) as queryType}
|
|
||||||
<option value={queryType}>{queryType}</option>
|
|
||||||
{/each}
|
{/each}
|
||||||
</Select>
|
</div>
|
||||||
|
{#if query.queryVerb}
|
||||||
|
<Select thin secondary bind:value={query.queryType}>
|
||||||
|
<option value={''}>Select an option</option>
|
||||||
|
{#each Object.keys(config[query.queryVerb]) as queryType}
|
||||||
|
<option value={queryType}>{queryType}</option>
|
||||||
|
{/each}
|
||||||
|
</Select>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
export let schema
|
export let schema
|
||||||
|
|
||||||
function updateQuery({ detail }) {
|
function updateQuery({ detail }) {
|
||||||
query.fields.sql = detail.value
|
query.fields[schema.type] = detail.value
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -24,19 +24,21 @@
|
||||||
<Heading extraSmall black>Query</Heading>
|
<Heading extraSmall black>Query</Heading>
|
||||||
<Spacer large />
|
<Spacer large />
|
||||||
|
|
||||||
{#if schema.type === QueryTypes.SQL}
|
{#if schema}
|
||||||
<Editor
|
{#if schema.type === QueryTypes.SQL}
|
||||||
label="Query"
|
<Editor
|
||||||
mode="sql"
|
label="Query"
|
||||||
on:change={updateQuery}
|
mode="sql"
|
||||||
value={query.fields.sql} />
|
on:change={updateQuery}
|
||||||
{:else if schema.type === QueryTypes.JSON}
|
value={query.fields.sql} />
|
||||||
<Spacer large />
|
{:else if schema.type === QueryTypes.JSON}
|
||||||
<Editor
|
<Spacer large />
|
||||||
label="Query"
|
<Editor
|
||||||
mode="json"
|
label="Query"
|
||||||
on:change={updateQuery}
|
mode="json"
|
||||||
value={query.fields.json} />
|
on:change={updateQuery}
|
||||||
{:else if schema.type === QueryTypes.FIELDS}
|
value={query.fields.json} />
|
||||||
<FieldsBuilder bind:fields={query.fields} {schema} />
|
{:else if schema.type === QueryTypes.FIELDS}
|
||||||
|
<FieldsBuilder bind:fields={query.fields} {schema} />
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -26,9 +26,7 @@
|
||||||
<IntegrationConfigForm integration={datasource.config} />
|
<IntegrationConfigForm integration={datasource.config} />
|
||||||
<Spacer medium />
|
<Spacer medium />
|
||||||
<footer>
|
<footer>
|
||||||
<Button primary wide disabled={false} on:click={saveDatasource}>
|
<Button blue wide on:click={saveDatasource}>Save</Button>
|
||||||
Save
|
|
||||||
</Button>
|
|
||||||
</footer>
|
</footer>
|
||||||
</section>
|
</section>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
class Field {
|
exports.QUERY_TYPES = {
|
||||||
constructor(type, defaultValue, required) {
|
SQL: "sql",
|
||||||
this.type = type
|
JSON: "json",
|
||||||
this.default = defaultValue
|
FIELDS: "fields",
|
||||||
this.required = required
|
}
|
||||||
}
|
|
||||||
|
exports.FIELD_TYPES = {
|
||||||
|
STRING: "string",
|
||||||
|
NUMBER: "number",
|
||||||
|
PASSWORD: "password",
|
||||||
|
LIST: "list",
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
const Airtable = require("airtable")
|
const Airtable = require("airtable")
|
||||||
|
const { FIELD_TYPES, QUERY_TYPES } = require("./Integration")
|
||||||
|
|
||||||
const SCHEMA = {
|
const SCHEMA = {
|
||||||
datasource: {
|
datasource: {
|
||||||
apiKey: {
|
apiKey: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
default: "enter api key",
|
default: "enter api key",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
base: {
|
base: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
default: "mybase",
|
default: "mybase",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
@ -20,7 +21,7 @@ const SCHEMA = {
|
||||||
customisable: true,
|
customisable: true,
|
||||||
fields: {
|
fields: {
|
||||||
table: {
|
table: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -28,14 +29,14 @@ const SCHEMA = {
|
||||||
},
|
},
|
||||||
read: {
|
read: {
|
||||||
Table: {
|
Table: {
|
||||||
type: "fields",
|
type: QUERY_TYPES.FIELDS,
|
||||||
fields: {
|
fields: {
|
||||||
table: {
|
table: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
view: {
|
view: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -43,11 +44,11 @@ const SCHEMA = {
|
||||||
},
|
},
|
||||||
update: {
|
update: {
|
||||||
Fields: {
|
Fields: {
|
||||||
type: "fields",
|
type: QUERY_TYPES.FIELDS,
|
||||||
customisable: true,
|
customisable: true,
|
||||||
fields: {
|
fields: {
|
||||||
id: {
|
id: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -55,7 +56,7 @@ const SCHEMA = {
|
||||||
},
|
},
|
||||||
delete: {
|
delete: {
|
||||||
"Airtable Ids": {
|
"Airtable Ids": {
|
||||||
type: "list",
|
type: FIELD_TYPES.LIST,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,53 +1,46 @@
|
||||||
const AWS = require("aws-sdk")
|
const AWS = require("aws-sdk")
|
||||||
|
const { FIELD_TYPES, QUERY_TYPES } = require("./Integration")
|
||||||
|
|
||||||
const SCHEMA = {
|
const SCHEMA = {
|
||||||
datasource: {
|
datasource: {
|
||||||
table: {
|
|
||||||
type: "string",
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
region: {
|
region: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
required: true,
|
required: true,
|
||||||
default: "us-east-1",
|
default: "us-east-1",
|
||||||
},
|
},
|
||||||
accessKeyId: {
|
accessKeyId: {
|
||||||
type: "string",
|
type: FIELD_TYPES.PASSWORD,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
secretKey: {
|
secretKey: {
|
||||||
type: "secretKey",
|
type: FIELD_TYPES.PASSWORD,
|
||||||
required: true,
|
required: true,
|
||||||
default: 5432,
|
|
||||||
},
|
|
||||||
indexName: {
|
|
||||||
type: "string",
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
type: "fields",
|
read: {
|
||||||
fields: [
|
DynamoConfig: {
|
||||||
{
|
type: QUERY_TYPES.FIELDS,
|
||||||
name: "Index",
|
fields: {
|
||||||
key: "Index",
|
Table: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
Index: {
|
||||||
|
type: FIELD_TYPES.STRING,
|
||||||
|
},
|
||||||
|
KeyConditionExpression: {
|
||||||
|
type: FIELD_TYPES.STRING,
|
||||||
|
},
|
||||||
|
ExpressionAttributeNames: {
|
||||||
|
type: FIELD_TYPES.STRING,
|
||||||
|
},
|
||||||
|
ExpressionAttributeValues: {
|
||||||
|
type: FIELD_TYPES.STRING,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
name: "Key Condition Expression",
|
|
||||||
key: "KeyConditionExpression",
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Attribute Names",
|
|
||||||
key: "ExpressionAttributeNames",
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Attribute Values",
|
|
||||||
key: "ExpressionAttributeValues",
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,12 +55,12 @@ class DynamoDBIntegration {
|
||||||
AWS.config.update(this.config)
|
AWS.config.update(this.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
async read() {
|
async read(query) {
|
||||||
const response = await this.client.query({
|
const response = await this.client.query({
|
||||||
TableName: this.config.table,
|
TableName: query.Table,
|
||||||
KeyConditionExpression: this.config.KeyConditionExpression,
|
KeyConditionExpression: query.KeyConditionExpression,
|
||||||
ExpressionAttributeNames: this.config.ExpressionAttributeNames,
|
ExpressionAttributeNames: query.ExpressionAttributeNames,
|
||||||
ExpressionAttributeValues: this.config.ExpressionAttributeValues,
|
ExpressionAttributeValues: query.ExpressionAttributeValues,
|
||||||
})
|
})
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,11 @@ class ElasticSearchIntegration {
|
||||||
this.client = new Client({ node: config.url })
|
this.client = new Client({ node: config.url })
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(document) {
|
async create(query) {
|
||||||
try {
|
try {
|
||||||
const result = await this.client.index({
|
const result = await this.client.index({
|
||||||
index: this.config.index,
|
index: this.config.index,
|
||||||
body: JSON.parse(document),
|
body: JSON.parse(query.json),
|
||||||
})
|
})
|
||||||
return [result]
|
return [result]
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -45,7 +45,7 @@ class ElasticSearchIntegration {
|
||||||
try {
|
try {
|
||||||
const result = await this.client.search({
|
const result = await this.client.search({
|
||||||
index: this.config.index,
|
index: this.config.index,
|
||||||
body: JSON.parse(query),
|
body: JSON.parse(query.json),
|
||||||
})
|
})
|
||||||
return result.body.hits.hits.map(({ _source }) => _source)
|
return result.body.hits.hits.map(({ _source }) => _source)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
|
@ -1,28 +1,36 @@
|
||||||
const sqlServer = require("mssql")
|
const sqlServer = require("mssql")
|
||||||
|
const { FIELD_TYPES } = require("./Integration")
|
||||||
|
|
||||||
const SCHEMA = {
|
const SCHEMA = {
|
||||||
datasource: {
|
datasource: {
|
||||||
user: {
|
user: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
required: true,
|
required: true,
|
||||||
default: "localhost",
|
default: "localhost",
|
||||||
},
|
},
|
||||||
password: {
|
password: {
|
||||||
type: "password",
|
type: FIELD_TYPES.PASSWORD,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
default: "localhost",
|
default: "localhost",
|
||||||
},
|
},
|
||||||
database: {
|
database: {
|
||||||
type: "string",
|
type: FIELD_TYPES.STRING,
|
||||||
default: "root",
|
default: "root",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
sql: {
|
create: {
|
||||||
type: "sql",
|
SQL: {
|
||||||
|
type: "sql",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
read: {
|
||||||
|
SQL: {
|
||||||
|
type: "sql",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -37,10 +45,21 @@ class SqlServerIntegration {
|
||||||
return await this.client.connect(this.config)
|
return await this.client.connect(this.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
async read() {
|
async read(query) {
|
||||||
try {
|
try {
|
||||||
await this.connect()
|
await this.connect()
|
||||||
const response = await this.client.query(this.config.query)
|
const response = await this.client.query(query.sql)
|
||||||
|
return response.recordset
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error querying MS SQL Server", err)
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async create(query) {
|
||||||
|
try {
|
||||||
|
await this.connect()
|
||||||
|
const response = await this.client.query(query.sql)
|
||||||
return response.recordset
|
return response.recordset
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error querying MS SQL Server", err)
|
console.error("Error querying MS SQL Server", err)
|
||||||
|
|
|
@ -17,8 +17,15 @@ const SCHEMA = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
JSON: {
|
create: {
|
||||||
type: "json",
|
JSON: {
|
||||||
|
type: "json",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
read: {
|
||||||
|
JSON: {
|
||||||
|
type: "json",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -27,23 +34,35 @@ class MongoIntegration {
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
this.config = config
|
this.config = config
|
||||||
this.client = new MongoClient(config.connectionString)
|
this.client = new MongoClient(config.connectionString)
|
||||||
try {
|
|
||||||
this.config.query = JSON.parse(this.config.query)
|
|
||||||
} catch (err) {
|
|
||||||
this.config.query = {}
|
|
||||||
}
|
|
||||||
this.connect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async connect() {
|
async connect() {
|
||||||
return this.client.connect()
|
return this.client.connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
async read() {
|
async create(query) {
|
||||||
try {
|
try {
|
||||||
|
const mongoQuery = query.json ? JSON.parse(query.json) : {}
|
||||||
|
await this.connect()
|
||||||
const db = this.client.db(this.config.db)
|
const db = this.client.db(this.config.db)
|
||||||
const collection = db.collection(this.config.collection)
|
const collection = db.collection(this.config.collection)
|
||||||
const result = await collection.find(this.config.query).toArray()
|
const result = await collection.insertOne(mongoQuery)
|
||||||
|
return result
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error querying mongodb", err)
|
||||||
|
throw err
|
||||||
|
} finally {
|
||||||
|
await this.client.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async read(query) {
|
||||||
|
try {
|
||||||
|
const mongoQuery = query.json ? JSON.parse(query.json) : {}
|
||||||
|
await this.connect()
|
||||||
|
const db = this.client.db(this.config.db)
|
||||||
|
const collection = db.collection(this.config.collection)
|
||||||
|
const result = await collection.find(mongoQuery).toArray()
|
||||||
return result
|
return result
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error querying mongodb", err)
|
console.error("Error querying mongodb", err)
|
||||||
|
|
|
@ -2,25 +2,33 @@ const AWS = require("aws-sdk")
|
||||||
|
|
||||||
const SCHEMA = {
|
const SCHEMA = {
|
||||||
datasource: {
|
datasource: {
|
||||||
bucket: {
|
|
||||||
type: "string",
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
region: {
|
region: {
|
||||||
type: "string",
|
type: "string",
|
||||||
required: true,
|
required: true,
|
||||||
default: "us-east-1",
|
default: "us-east-1",
|
||||||
},
|
},
|
||||||
accessKeyId: {
|
accessKeyId: {
|
||||||
type: "string",
|
type: "password",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
secretAccessKey: {
|
secretAccessKey: {
|
||||||
type: "string",
|
type: "password",
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
query: {},
|
query: {
|
||||||
|
read: {
|
||||||
|
Bucket: {
|
||||||
|
type: "fields",
|
||||||
|
fields: {
|
||||||
|
bucket: {
|
||||||
|
type: "string",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
class S3Integration {
|
class S3Integration {
|
||||||
|
@ -34,10 +42,10 @@ class S3Integration {
|
||||||
AWS.config.update(this.config)
|
AWS.config.update(this.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
async query() {
|
async read(query) {
|
||||||
const response = await this.client
|
const response = await this.client
|
||||||
.listObjects({
|
.listObjects({
|
||||||
Bucket: this.config.bucket,
|
Bucket: query.bucket,
|
||||||
})
|
})
|
||||||
.promise()
|
.promise()
|
||||||
return response.Contents
|
return response.Contents
|
||||||
|
|
Loading…
Reference in New Issue