import { Integration, DatasourceFieldType, QueryType, IntegrationBase, } from "@budibase/types" const AWS = require("aws-sdk") const { AWS_REGION } = require("../db/dynamoClient") interface DynamoDBConfig { region: string accessKeyId: string secretAccessKey: string endpoint?: string currentClockSkew?: boolean } const SCHEMA: Integration = { docs: "https://github.com/dabit3/dynamodb-documentclient-cheat-sheet", description: "Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale.", friendlyName: "DynamoDB", type: "Non-relational", datasource: { region: { type: DatasourceFieldType.STRING, required: true, default: "us-east-1", }, accessKeyId: { type: DatasourceFieldType.PASSWORD, required: true, }, secretAccessKey: { type: DatasourceFieldType.PASSWORD, required: true, }, endpoint: { type: DatasourceFieldType.STRING, required: false, default: "https://dynamodb.us-east-1.amazonaws.com", }, }, query: { create: { type: QueryType.FIELDS, customisable: true, fields: { table: { type: DatasourceFieldType.STRING, required: true, }, }, }, read: { type: QueryType.FIELDS, customisable: true, readable: true, fields: { table: { type: DatasourceFieldType.STRING, required: true, }, index: { type: DatasourceFieldType.STRING, }, }, }, scan: { type: QueryType.FIELDS, customisable: true, readable: true, fields: { table: { type: DatasourceFieldType.STRING, required: true, }, index: { type: DatasourceFieldType.STRING, }, }, }, describe: { type: QueryType.FIELDS, customisable: true, readable: true, fields: { table: { type: DatasourceFieldType.STRING, required: true, }, }, }, get: { type: QueryType.FIELDS, customisable: true, readable: true, fields: { table: { type: DatasourceFieldType.STRING, required: true, }, }, }, update: { type: QueryType.FIELDS, customisable: true, fields: { table: { type: DatasourceFieldType.STRING, required: true, }, }, }, delete: { type: QueryType.FIELDS, customisable: true, fields: { table: { type: DatasourceFieldType.STRING, required: true, }, }, }, }, } class DynamoDBIntegration implements IntegrationBase { private config: DynamoDBConfig private client: any constructor(config: DynamoDBConfig) { this.config = config // User is using a local dynamoDB endpoint, don't auth with remote if (this.config?.endpoint?.includes("localhost")) { // @ts-ignore this.config = {} } this.config = { ...this.config, currentClockSkew: true, region: config.region || AWS_REGION, endpoint: config.endpoint || undefined, } this.client = new AWS.DynamoDB.DocumentClient(this.config) } async create(query: { table: string; json: object }) { const params = { TableName: query.table, ...query.json, } return this.client.put(params).promise() } async read(query: { table: string; json: object; index: null | string }) { const params = { TableName: query.table, IndexName: query.index ? query.index : undefined, ...query.json, } const response = await this.client.query(params).promise() if (response.Items) { return response.Items } return response } async scan(query: { table: string; json: object; index: null | string }) { const params = { TableName: query.table, IndexName: query.index ? query.index : undefined, ...query.json, } const response = await this.client.scan(params).promise() if (response.Items) { return response.Items } return response } async describe(query: { table: string }) { const params = { TableName: query.table, } return new AWS.DynamoDB(this.config).describeTable(params).promise() } async get(query: { table: string; json: object }) { const params = { TableName: query.table, ...query.json, } return this.client.get(params).promise() } async update(query: { table: string; json: object }) { const params = { TableName: query.table, ...query.json, } return this.client.update(params).promise() } async delete(query: { table: string; json: object }) { const params = { TableName: query.table, ...query.json, } return this.client.delete(params).promise() } } export default { schema: SCHEMA, integration: DynamoDBIntegration, }