"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const datasource_1 = require("../definitions/datasource");
var DynamoModule;
(function (DynamoModule) {
    const AWS = require("aws-sdk");
    const { AWS_REGION } = require("../db/dynamoClient");
    const SCHEMA = {
        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: datasource_1.DatasourceFieldTypes.STRING,
                required: true,
                default: "us-east-1",
            },
            accessKeyId: {
                type: datasource_1.DatasourceFieldTypes.PASSWORD,
                required: true,
            },
            secretAccessKey: {
                type: datasource_1.DatasourceFieldTypes.PASSWORD,
                required: true,
            },
            endpoint: {
                type: datasource_1.DatasourceFieldTypes.STRING,
                required: false,
                default: "https://dynamodb.us-east-1.amazonaws.com",
            },
        },
        query: {
            create: {
                type: datasource_1.QueryTypes.FIELDS,
                customisable: true,
                fields: {
                    table: {
                        type: datasource_1.DatasourceFieldTypes.STRING,
                        required: true,
                    },
                },
            },
            read: {
                type: datasource_1.QueryTypes.FIELDS,
                customisable: true,
                readable: true,
                fields: {
                    table: {
                        type: datasource_1.DatasourceFieldTypes.STRING,
                        required: true,
                    },
                    index: {
                        type: datasource_1.DatasourceFieldTypes.STRING,
                    },
                },
            },
            scan: {
                type: datasource_1.QueryTypes.FIELDS,
                customisable: true,
                readable: true,
                fields: {
                    table: {
                        type: datasource_1.DatasourceFieldTypes.STRING,
                        required: true,
                    },
                    index: {
                        type: datasource_1.DatasourceFieldTypes.STRING,
                    },
                },
            },
            describe: {
                type: datasource_1.QueryTypes.FIELDS,
                customisable: true,
                readable: true,
                fields: {
                    table: {
                        type: datasource_1.DatasourceFieldTypes.STRING,
                        required: true,
                    },
                },
            },
            get: {
                type: datasource_1.QueryTypes.FIELDS,
                customisable: true,
                readable: true,
                fields: {
                    table: {
                        type: datasource_1.DatasourceFieldTypes.STRING,
                        required: true,
                    },
                },
            },
            update: {
                type: datasource_1.QueryTypes.FIELDS,
                customisable: true,
                fields: {
                    table: {
                        type: datasource_1.DatasourceFieldTypes.STRING,
                        required: true,
                    },
                },
            },
            delete: {
                type: datasource_1.QueryTypes.FIELDS,
                customisable: true,
                fields: {
                    table: {
                        type: datasource_1.DatasourceFieldTypes.STRING,
                        required: true,
                    },
                },
            },
        },
    };
    class DynamoDBIntegration {
        constructor(config) {
            this.config = config;
            if (this.config.endpoint && !this.config.endpoint.includes("localhost")) {
                this.connect();
            }
            let options = {
                correctClockSkew: true,
                region: this.config.region || AWS_REGION,
                endpoint: config.endpoint ? config.endpoint : undefined,
            };
            this.client = new AWS.DynamoDB.DocumentClient(options);
        }
        end() {
            this.disconnect();
        }
        connect() {
            AWS.config.update(this.config);
        }
        disconnect() {
            AWS.config.update({
                secretAccessKey: undefined,
                accessKeyId: undefined,
                region: AWS_REGION,
            });
        }
        create(query) {
            return __awaiter(this, void 0, void 0, function* () {
                const params = Object.assign({ TableName: query.table }, query.json);
                return this.client.put(params).promise();
            });
        }
        read(query) {
            return __awaiter(this, void 0, void 0, function* () {
                const params = Object.assign({ TableName: query.table, IndexName: query.index ? query.index : undefined }, query.json);
                const response = yield this.client.query(params).promise();
                if (response.Items) {
                    return response.Items;
                }
                return response;
            });
        }
        scan(query) {
            return __awaiter(this, void 0, void 0, function* () {
                const params = Object.assign({ TableName: query.table, IndexName: query.index ? query.index : undefined }, query.json);
                const response = yield this.client.scan(params).promise();
                if (response.Items) {
                    return response.Items;
                }
                return response;
            });
        }
        describe(query) {
            return __awaiter(this, void 0, void 0, function* () {
                const params = {
                    TableName: query.table,
                };
                return new AWS.DynamoDB().describeTable(params).promise();
            });
        }
        get(query) {
            return __awaiter(this, void 0, void 0, function* () {
                const params = Object.assign({ TableName: query.table }, query.json);
                return this.client.get(params).promise();
            });
        }
        update(query) {
            return __awaiter(this, void 0, void 0, function* () {
                const params = Object.assign({ TableName: query.table }, query.json);
                return this.client.update(params).promise();
            });
        }
        delete(query) {
            return __awaiter(this, void 0, void 0, function* () {
                const params = Object.assign({ TableName: query.table }, query.json);
                return this.client.delete(params).promise();
            });
        }
    }
    module.exports = {
        schema: SCHEMA,
        integration: DynamoDBIntegration,
    };
})(DynamoModule || (DynamoModule = {}));
