UNPKG

infrastructure-components

Version:

Infrastructure-Components configure the infrastructure of your React-App as part of your React-Components.

398 lines (392 loc) • 15.7 kB
"use strict"; /** * Created by frank.zickert on 02.05.19. */ 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()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const aws_sdk_1 = __importDefault(require("aws-sdk")); const graphql_tag_1 = __importDefault(require("graphql-tag")); const universal_cookie_1 = __importDefault(require("universal-cookie")); const typed_graphqlify_1 = require("typed-graphqlify"); const auth_middleware_1 = require("../authentication/auth-middleware"); /** * transforms a function into a Promise */ const promisify = foo => new Promise((resolve, reject) => { foo((error, result) => { if (error) { reject(error); } else { resolve(result); } }); }); const applyOfflineConfig = (offline) => { return offline ? { region: 'localhost', endpoint: 'http://localhost:8000' } : {}; }; exports.setEntry = (tableName, pkEntity, pkId, skEntity, skId, jsonData, isOffline) => { //console.log("setEntry: ", pkEntity, "|", pkId, "|", skEntity, "|", skId ); return promisify(callback => new aws_sdk_1.default.DynamoDB.DocumentClient(applyOfflineConfig(isOffline)).update({ TableName: tableName, /** * ALL KEYS MUST BE SPECIFIED HERE! */ Key: { pk: `${pkEntity}|${pkId}`, sk: `${skEntity}|${skId}` }, UpdateExpression: `SET jsonData = :jsonData`, ExpressionAttributeValues: { ':jsonData': `${JSON.stringify(jsonData)}`, } }, callback)) .then(() => { //console.log("data stored!") var result = {}; result[pkEntity] = pkId; result[skEntity] = skId; result["data"] = `${JSON.stringify(jsonData).replace(/"/g, "\\\"")}`; return result; }).catch(error => { console.log(error); }); }; /** * Get all entries to a entity|value pair in the key-field whose range have the specified rangeEntity * * @param key specify which field is the key: pk or sk * @param entity specifies the entity of the key-field * @param value specify the id of the key-field * @param rangeEntity specify the entity of the range * @returns {Promise<string>|any} */ exports.ddbListEntries = (tableName, key, entity, value, rangeEntity, isOffline) => { //console.log("ddbListEntries: ", tableName, key, entity, value, rangeEntity, isOffline); const q = { // use the table_name as specified in the serverless.yml TableName: tableName, IndexName: key === "sk" ? "reverse" : undefined, /** * ALL KEYS MUST HAVE KEY-CONDITION-EXPRESSIONS! */ KeyConditionExpression: `${key} = :value and begins_with(${key === "pk" ? "sk" : "pk"}, :entity)`, ExpressionAttributeValues: { ":value": `${entity}|${value}`, ":entity": rangeEntity ? rangeEntity : "undefined" } }; //console.log("query: ", q); return promisify(callback => new aws_sdk_1.default.DynamoDB.DocumentClient(applyOfflineConfig(isOffline)).query(q, callback)) .then(result => { //console.log("ddb-result: ", result); return result["Items"]; /* if (result.Items) { return result.Items.map(item => JSON.stringify(item)); } return [];*/ //return result.Items.map(item => JSON.stringify(item)); }).catch(error => { console.log(error); }); }; exports.ddbGetEntry = (tableName, pkEntity, pkValue, skEntity, skValue, isOffline) => { //console.log("ddbGetEntry: ", `${pkEntity}|${pkValue}`, ` -- ${skEntity}|${skValue}`, " -- ", tableName); const q = { TableName: tableName, Key: { pk: `${pkEntity}|${pkValue}`, sk: `${skEntity}|${skValue}` } }; //console.log("ddbGetEntry-query: ", q); return promisify(callback => new aws_sdk_1.default.DynamoDB.DocumentClient(applyOfflineConfig(isOffline)).get(q, callback)) .then(result => { //console.log("ddbGetEntry result: ", result); return result["Item"] ? result["Item"] : result; }).catch(error => { console.log(error); }); }; exports.ddbScan = (tableName, key, entity, start_value, end_value, rangeEntity, isOffline) => { //console.log("scan: ", tableName, key, entity, start_value, end_value, rangeEntity, isOffline); const q = { // use the table_name as specified in the serverless.yml TableName: tableName, FilterExpression: `${key} between :sv and :ev and begins_with(${key === "pk" ? "sk" : "pk"}, :entity)`, ExpressionAttributeValues: { ":sv": `${entity}|${start_value}`, ":ev": `${entity}|${end_value}`, ":entity": rangeEntity ? rangeEntity : "undefined" } }; const allQ = { // use the table_name as specified in the serverless.yml TableName: tableName, FilterExpression: `begins_with(${key}, :entity) and begins_with(${key === "pk" ? "sk" : "pk"}, :rangeentity)`, ExpressionAttributeValues: { ":entity": entity, ":rangeentity": rangeEntity ? rangeEntity : "undefined" } }; //console.log("query: ", q); return promisify(callback => new aws_sdk_1.default.DynamoDB.DocumentClient(applyOfflineConfig(isOffline)).scan(start_value && end_value ? q : allQ, callback)) .then(result => { //console.log("ddb-result: ", result); return result["Items"]; /** * TODO return await client.select(Object.assign({ query: query, context: context }, params)).then(result => { //console.log("select result: ", result) return result.data.Items.concat(typeof result.data.LastEvaluatedKey != "undefined" ? scan( client, { query: query, context: context, params: { ExclusiveStartKey: result.data.LastEvaluatedKey } } ): []); // continue scanning if we have more movies, because // scan can retrieve a maximum of 1MB of data if (typeof data.LastEvaluatedKey != "undefined") { console.log("Scanning for more..."); params.ExclusiveStartKey = data.LastEvaluatedKey; docClient.scan(params, onScan); } return [];*/ //return result.Items.map(item => JSON.stringify(item)); }).catch(error => { console.log(error); }); }; exports.deleteEntry = (tableName, pkEntity, pkValue, skEntity, skValue, isOffline) => { //console.log("delete entry: ", pkEntity, pkValue, skEntity, skValue) //console.log("pk: ", `${pkEntity}|${pkValue}`); //console.log("sk: ", `${skEntity}|${skValue}`); return promisify(callback => new aws_sdk_1.default.DynamoDB.DocumentClient(applyOfflineConfig(isOffline)).delete({ // use the table_name as specified in the serverless.yml TableName: tableName, Key: { pk: `${pkEntity}|${pkValue}`, sk: `${skEntity}|${skValue}` } }, callback)) .then(result => { //console.log("result: ", result); return result["Item"] ? result["Item"] : result; }).catch(error => { console.log(error); }); }; /** * this function provides a executable graphql-query * TODO the fields must be taken from the data-layer, not requiring the user to provide them */ exports.setEntryMutation = (entryId, data, fields, context = {}) => { //console.log("setEntryMutation: ", entryId, data, fields); const mutationObj = {}; mutationObj[`set_${entryId}`] = typed_graphqlify_1.params(Object.keys(data).reduce((result, key) => { result[key] = `"${data[key]}"`; return result; }, {}), Object.keys(fields).reduce((result, key) => { result[key] = typed_graphqlify_1.types.string; return result; }, {})); return { mutation: graphql_tag_1.default `${typed_graphqlify_1.mutation(mutationObj)}`, context: context }; }; exports.deleteEntryMutation = (entryId, data, fields, context = {}) => { //console.log("deleteEntryMutation: ", entryId, data); const mutationObj = {}; mutationObj[`delete_${entryId}`] = typed_graphqlify_1.params(Object.keys(data).reduce((result, key) => { result[key] = `"${data[key]}"`; return result; }, {}), Object.keys(fields).reduce((result, key) => { result[key] = typed_graphqlify_1.types.string; return result; }, {})); return { mutation: graphql_tag_1.default `${typed_graphqlify_1.mutation(mutationObj)}`, context: context }; }; /** * this function provides a executable graphql-query */ exports.getEntryListQuery = (entryId, data, fields, context = {}) => { //console.log("getEntryListQuery: ", entryId, data, fields, context); if (data == undefined) { console.error("getEntryListQuery requires a data argument"); return undefined; } if (Object.keys(data).length !== 1) { console.error("getEntryListQuery requires exact 1 field provided in the data argument"); return undefined; } const queryKey = Object.keys(data)[0]; const queryObj = {}; queryObj[`list_${entryId}_${queryKey}`] = typed_graphqlify_1.params(Object.keys(data).filter(key => key === queryKey).reduce((result, key) => { result[key] = `"${data[key]}"`; return result; }, {}), Object.keys(fields).reduce((result, key) => { result[key] = typed_graphqlify_1.types.string; return result; }, {})); //console.log("listQuery string: ", query(queryObj)); return { query: graphql_tag_1.default `${typed_graphqlify_1.query(queryObj)}`, context: context }; }; exports.getEntryQuery = (entryId, data, fields, context = {}) => { //console.log("getEntryQuery: ", entryId, data, fields, context); if (data == undefined) { console.error("getEntryQuery requires a data argument"); return undefined; } if (Object.keys(data).length !== 2) { console.error("getEntryQuery requires exact 2 fields provided in the data argument"); return undefined; } const queryObj = {}; queryObj[`get_${entryId}`] = typed_graphqlify_1.params(Object.keys(data).reduce((result, key) => { result[key] = `"${data[key]}"`; return result; }, {}), Object.keys(fields).reduce((result, key) => { result[key] = typed_graphqlify_1.types.string; return result; }, {})); //console.log("listQuery string: ", query(queryObj)); return { query: graphql_tag_1.default `${typed_graphqlify_1.query(queryObj)}`, context: context }; }; exports.updateEntryQuery = (entryId, callback, context = {}) => { return { entryId: entryId, callback: callback, context: context }; }; /** * this function provides a executable graphql-query: "scan_{entryId}" * */ exports.getEntryScanQuery = (entryId, data, fields, context = {}) => { //console.log("getEntryScanQuery: ", entryId, data, fields, context); if (data == undefined) { console.error("getEntryScanQuery requires a data argument, this may be empty"); return undefined; } const queryObj = {}; if (Object.keys(data).length > 0) { const queryKey = Object.keys(data)[0]; queryObj[`scan_${entryId}_${queryKey}`] = typed_graphqlify_1.params(Object.keys(data).reduce((result, key) => { // when we have an array at the key-pos in data, then we want to get a range if (Array.isArray(data[key])) { if (data[key].length > 0 && data[key][0] !== undefined) { result[`start_${key}`] = `"${data[key][0]}"`; } if (data[key].length > 1 && data[key][1] !== undefined) { result[`end_${key}`] = `"${data[key][1]}"`; } } else { result[key] = `"${data[key]}"`; } return result; }, {}), Object.keys(fields).reduce((result, key) => { result[key] = typed_graphqlify_1.types.string; return result; }, {})); //console.log(gql`${query(queryObj)}`); return { query: graphql_tag_1.default `${typed_graphqlify_1.query(queryObj)}`, context: context }; } else { queryObj[`scan_${entryId}`] = typed_graphqlify_1.params({ scanall: `"yes"` }, Object.keys(fields).reduce((result, key) => { result[key] = typed_graphqlify_1.types.string; return result; }, {})); //console.log(gql`${query(queryObj)}`); return { query: graphql_tag_1.default `${typed_graphqlify_1.query(queryObj)}`, context: context }; } //console.log("scanQuery string: ", query(queryObj)); }; function select(client, { query, context = {} }) { return __awaiter(this, void 0, void 0, function* () { if (!context["userId"]) { context["userId"] = new universal_cookie_1.default().get(auth_middleware_1.IC_USER_ID); } //console.log("select: ", query, context); return yield client.query({ query: query, context: context }).then(result => { //console.log("select result: ", result) return result.data ? result.data : result; }).catch(error => { console.log(error); }); }); } exports.select = select; ; /** * uses this: https://github.com/acro5piano/typed-graphqlify * * TODO generalize to other data-types than string * * @param client * @param entryId * @param data * @returns {any|Promise<T>|Promise<U>} */ function mutate(client, { mutation, context = {} }) { return __awaiter(this, void 0, void 0, function* () { if (!context["userId"]) { context["userId"] = new universal_cookie_1.default().get(auth_middleware_1.IC_USER_ID); } console.log("mutate: ", mutation, context); //console.log("mutation string: ", mutation(mutationObj)); return yield client.mutate({ mutation: mutation, context: context }).then(result => { }).catch(error => { console.log(error); }); }); } exports.mutate = mutate; ; /** * * @param client * @param callback (oldData) => newData * @param context * @returns {Promise<any>} */ function update(client, { entryId, getEntryQuery, setEntryMutation }) { return __awaiter(this, void 0, void 0, function* () { //console.log("update: ", getEntryQuery, setEntryMutation); const oldData = yield select(client, getEntryQuery()); //console.log("oldData: ", oldData[`get_${entryId}`]) //console.log(setEntryMutation) return yield mutate(client, setEntryMutation(oldData[`get_${entryId}`])); }); } exports.update = update; ; //# sourceMappingURL=datalayer-libs.js.map