Some fixes for integrations, making Dynamo work correctly and allow local usage as well as using the API to try and make responses that are objects work better.

This commit is contained in:
mike12345567 2021-02-02 16:26:15 +00:00
parent 15b3e5a24f
commit c74f1011d0
3 changed files with 1003 additions and 44 deletions

View File

@ -1,8 +1,18 @@
const handlebars = require("handlebars") const { processString } = require("@budibase/string-templates")
const CouchDB = require("../../db") const CouchDB = require("../../db")
const { generateQueryID, getQueryParams } = require("../../db/utils") const { generateQueryID, getQueryParams } = require("../../db/utils")
const { integrations } = require("../../integrations") const { integrations } = require("../../integrations")
function formatResponse(resp) {
if (typeof resp === "string") {
resp = JSON.parse(resp)
}
if (!Array.isArray(resp)) {
resp = [resp]
}
return resp
}
exports.fetch = async function(ctx) { exports.fetch = async function(ctx) {
const db = new CouchDB(ctx.user.appId) const db = new CouchDB(ctx.user.appId)
@ -29,13 +39,12 @@ exports.save = async function(ctx) {
ctx.message = `Query ${query.name} saved successfully.` ctx.message = `Query ${query.name} saved successfully.`
} }
function enrichQueryFields(fields, parameters) { async function enrichQueryFields(fields, parameters) {
const enrichedQuery = {} const enrichedQuery = {}
// enrich the fields with dynamic parameters // enrich the fields with dynamic parameters
for (let key in fields) { for (let key of Object.keys(fields)) {
const template = handlebars.compile(fields[key]) enrichedQuery[key] = await processString(fields[key], parameters)
enrichedQuery[key] = template(parameters)
} }
if (enrichedQuery.json || enrichedQuery.customData) { if (enrichedQuery.json || enrichedQuery.customData) {
@ -62,9 +71,11 @@ exports.preview = async function(ctx) {
const { fields, parameters, queryVerb } = ctx.request.body const { fields, parameters, queryVerb } = ctx.request.body
const enrichedQuery = enrichQueryFields(fields, parameters) const enrichedQuery = await enrichQueryFields(fields, parameters)
ctx.body = await new Integration(datasource.config)[queryVerb](enrichedQuery) ctx.body = formatResponse(
await new Integration(datasource.config)[queryVerb](enrichedQuery)
)
} }
exports.execute = async function(ctx) { exports.execute = async function(ctx) {
@ -80,17 +91,15 @@ exports.execute = async function(ctx) {
return return
} }
const enrichedQuery = enrichQueryFields( const enrichedQuery = await enrichQueryFields(
query.fields, query.fields,
ctx.request.body.parameters ctx.request.body.parameters
) )
// call the relevant CRUD method on the integration class // call the relevant CRUD method on the integration class
const response = await new Integration(datasource.config)[query.queryVerb]( ctx.body = formatResponse(
enrichedQuery await new Integration(datasource.config)[query.queryVerb](enrichedQuery)
) )
ctx.body = response
} }
exports.destroy = async function(ctx) { exports.destroy = async function(ctx) {

View File

@ -17,20 +17,26 @@ const SCHEMA = {
type: FIELD_TYPES.PASSWORD, type: FIELD_TYPES.PASSWORD,
required: true, required: true,
}, },
endpoint: {
type: FIELD_TYPES.STRING,
required: false,
default: "https://dynamodb.us-east-1.amazonaws.com",
},
}, },
query: { query: {
create: { create: {
type: QUERY_TYPES.FIELDS, type: QUERY_TYPES.FIELDS,
customisable: true,
fields: { fields: {
table: { table: {
type: FIELD_TYPES.STRING, type: FIELD_TYPES.STRING,
required: true, required: true,
}, },
customisable: true,
}, },
}, },
read: { read: {
type: QUERY_TYPES.FIELDS, type: QUERY_TYPES.FIELDS,
customisable: true,
fields: { fields: {
table: { table: {
type: FIELD_TYPES.STRING, type: FIELD_TYPES.STRING,
@ -39,30 +45,49 @@ const SCHEMA = {
index: { index: {
type: FIELD_TYPES.STRING, type: FIELD_TYPES.STRING,
}, },
},
},
scan: {
type: QUERY_TYPES.FIELDS,
customisable: true, customisable: true,
fields: {
table: {
type: FIELD_TYPES.STRING,
required: true,
},
index: {
type: FIELD_TYPES.STRING,
},
},
},
get: {
type: QUERY_TYPES.FIELDS,
customisable: true,
fields: {
table: {
type: FIELD_TYPES.STRING,
required: true,
},
}, },
}, },
update: { update: {
type: QUERY_TYPES.FIELDS, type: QUERY_TYPES.FIELDS,
customisable: true,
fields: { fields: {
table: { table: {
type: FIELD_TYPES.STRING, type: FIELD_TYPES.STRING,
required: true, required: true,
}, },
customisable: true,
}, },
}, },
delete: { delete: {
type: QUERY_TYPES.FIELDS, type: QUERY_TYPES.FIELDS,
customisable: true,
fields: { fields: {
table: { table: {
type: FIELD_TYPES.STRING, type: FIELD_TYPES.STRING,
required: true, required: true,
}, },
key: {
type: FIELD_TYPES.STRING,
required: true,
},
}, },
}, },
}, },
@ -72,7 +97,15 @@ class DynamoDBIntegration {
constructor(config) { constructor(config) {
this.config = config this.config = config
this.connect() this.connect()
this.client = new AWS.DynamoDB.DocumentClient() let options = {
correctClockSkew: true,
}
if (config.endpoint) {
options.endpoint = config.endpoint
}
this.client = new AWS.DynamoDB.DocumentClient({
correctClockSkew: true,
})
} }
async connect() { async connect() {
@ -80,37 +113,65 @@ class DynamoDBIntegration {
} }
async create(query) { async create(query) {
const response = await this.client.query({ const params = {
TableName: query.table, TableName: query.table,
Item: query.json, ...query.json,
}) }
return response return this.client.put(params).promise()
} }
async read(query) { async read(query) {
const response = await this.client.query({ const params = {
TableName: query.Table, TableName: query.table,
...query.json, ...query.json,
}) }
if (query.index) {
params.IndexName = query.index
}
const response = await this.client.query(params).promise()
if (response.Items) {
return response.Items
}
return response return response
} }
async scan(query) {
const params = {
TableName: query.table,
...query.json,
}
if (query.index) {
params.IndexName = query.index
}
const response = await this.client.scan(params).promise()
if (response.Items) {
return response.Items
}
return response
}
async get(query) {
const params = {
TableName: query.table,
...query.json,
}
return this.client.get(params).promise()
}
async update(query) { async update(query) {
const response = await this.client.query({ const params = {
TableName: query.Table, TableName: query.Table,
...query.json, ...query.json,
}) }
return response return this.client.update(params).promise()
} }
async delete(query) { async delete(query) {
const response = await this.client.query({ const params = {
TableName: query.Table, TableName: query.table,
Key: { ...query.json,
id: query.key, }
}, return this.client.delete(params).promise()
})
return response
} }
} }

File diff suppressed because it is too large Load Diff