UNPKG

15.5 kBJavaScriptView Raw
1"use strict";
2/**
3 * Created by frank.zickert on 02.05.19.
4 */
5var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6 return new (P || (P = Promise))(function (resolve, reject) {
7 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
9 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
10 step((generator = generator.apply(thisArg, _arguments || [])).next());
11 });
12};
13var __importDefault = (this && this.__importDefault) || function (mod) {
14 return (mod && mod.__esModule) ? mod : { "default": mod };
15};
16Object.defineProperty(exports, "__esModule", { value: true });
17const aws_sdk_1 = __importDefault(require("aws-sdk"));
18const graphql_tag_1 = __importDefault(require("graphql-tag"));
19const universal_cookie_1 = __importDefault(require("universal-cookie"));
20const typed_graphqlify_1 = require("typed-graphqlify");
21const auth_middleware_1 = require("../authentication/auth-middleware");
22/**
23 * transforms a function into a Promise
24 */
25const promisify = foo => new Promise((resolve, reject) => {
26 foo((error, result) => {
27 if (error) {
28 reject(error);
29 }
30 else {
31 resolve(result);
32 }
33 });
34});
35const applyOfflineConfig = (offline) => {
36 return offline ? {
37 region: 'localhost',
38 endpoint: 'http://localhost:8000'
39 } : {};
40};
41exports.setEntry = (tableName, pkEntity, pkId, skEntity, skId, jsonData, isOffline) => {
42 //console.log("setEntry: ", pkEntity, "|", pkId, "|", skEntity, "|", skId );
43 return promisify(callback => new aws_sdk_1.default.DynamoDB.DocumentClient(applyOfflineConfig(isOffline)).update({
44 TableName: tableName,
45 /**
46 * ALL KEYS MUST BE SPECIFIED HERE!
47 */
48 Key: {
49 pk: `${pkEntity}|${pkId}`,
50 sk: `${skEntity}|${skId}`
51 },
52 UpdateExpression: `SET jsonData = :jsonData`,
53 ExpressionAttributeValues: {
54 ':jsonData': `${JSON.stringify(jsonData)}`,
55 }
56 }, callback))
57 .then(() => {
58 //console.log("data stored!")
59 var result = {};
60 result[pkEntity] = pkId;
61 result[skEntity] = skId;
62 result["data"] = `${JSON.stringify(jsonData).replace(/"/g, "\\\"")}`;
63 return result;
64 }).catch(error => { console.log(error); });
65};
66/**
67 * Get all entries to a entity|value pair in the key-field whose range have the specified rangeEntity
68 *
69 * @param key specify which field is the key: pk or sk
70 * @param entity specifies the entity of the key-field
71 * @param value specify the id of the key-field
72 * @param rangeEntity specify the entity of the range
73 * @returns {Promise<string>|any}
74 */
75exports.ddbListEntries = (tableName, key, entity, value, rangeEntity, isOffline) => {
76 //console.log("ddbListEntries: ", tableName, key, entity, value, rangeEntity, isOffline);
77 const q = {
78 // use the table_name as specified in the serverless.yml
79 TableName: tableName,
80 IndexName: key === "sk" ? "reverse" : undefined,
81 /**
82 * ALL KEYS MUST HAVE KEY-CONDITION-EXPRESSIONS!
83 */
84 KeyConditionExpression: `${key} = :value and begins_with(${key === "pk" ? "sk" : "pk"}, :entity)`,
85 ExpressionAttributeValues: {
86 ":value": `${entity}|${value}`,
87 ":entity": rangeEntity ? rangeEntity : "undefined"
88 }
89 };
90 //console.log("query: ", q);
91 return promisify(callback => new aws_sdk_1.default.DynamoDB.DocumentClient(applyOfflineConfig(isOffline)).query(q, callback))
92 .then(result => {
93 //console.log("ddb-result: ", result);
94 return result["Items"];
95 /*
96 if (result.Items) {
97
98 return result.Items.map(item => JSON.stringify(item));
99 }
100
101 return [];*/
102 //return result.Items.map(item => JSON.stringify(item));
103 }).catch(error => { console.log(error); });
104};
105exports.ddbGetEntry = (tableName, pkEntity, pkValue, skEntity, skValue, isOffline) => {
106 //console.log("ddbGetEntry: ", `${pkEntity}|${pkValue}`, ` -- ${skEntity}|${skValue}`, " -- ", tableName);
107 const q = {
108 TableName: tableName,
109 Key: {
110 pk: `${pkEntity}|${pkValue}`,
111 sk: `${skEntity}|${skValue}`
112 }
113 };
114 //console.log("ddbGetEntry-query: ", q);
115 return promisify(callback => new aws_sdk_1.default.DynamoDB.DocumentClient(applyOfflineConfig(isOffline)).get(q, callback))
116 .then(result => {
117 //console.log("ddbGetEntry result: ", result);
118 return result["Item"] ? result["Item"] : result;
119 }).catch(error => { console.log(error); });
120};
121exports.ddbScan = (tableName, key, entity, start_value, end_value, rangeEntity, isOffline) => {
122 //console.log("scan: ", tableName, key, entity, start_value, end_value, rangeEntity, isOffline);
123 const q = {
124 // use the table_name as specified in the serverless.yml
125 TableName: tableName,
126 FilterExpression: `${key} between :sv and :ev and begins_with(${key === "pk" ? "sk" : "pk"}, :entity)`,
127 ExpressionAttributeValues: {
128 ":sv": `${entity}|${start_value}`,
129 ":ev": `${entity}|${end_value}`,
130 ":entity": rangeEntity ? rangeEntity : "undefined"
131 }
132 };
133 const allQ = {
134 // use the table_name as specified in the serverless.yml
135 TableName: tableName,
136 FilterExpression: `begins_with(${key}, :entity) and begins_with(${key === "pk" ? "sk" : "pk"}, :rangeentity)`,
137 ExpressionAttributeValues: {
138 ":entity": entity,
139 ":rangeentity": rangeEntity ? rangeEntity : "undefined"
140 }
141 };
142 //console.log("query: ", q);
143 return promisify(callback => new aws_sdk_1.default.DynamoDB.DocumentClient(applyOfflineConfig(isOffline)).scan(start_value && end_value ? q : allQ, callback))
144 .then(result => {
145 //console.log("ddb-result: ", result);
146 return result["Items"];
147 /**
148 * TODO
149
150
151 return await client.select(Object.assign({
152 query: query,
153 context: context
154 }, params)).then(result => {
155 //console.log("select result: ", result)
156
157 return result.data.Items.concat(typeof result.data.LastEvaluatedKey != "undefined" ?
158 scan(
159 client, {
160 query: query,
161 context: context,
162 params: {
163 ExclusiveStartKey: result.data.LastEvaluatedKey
164 }
165 }
166 ): []);
167 // continue scanning if we have more movies, because
168 // scan can retrieve a maximum of 1MB of data
169 if (typeof data.LastEvaluatedKey != "undefined") {
170 console.log("Scanning for more...");
171 params.ExclusiveStartKey = data.LastEvaluatedKey;
172 docClient.scan(params, onScan);
173 }
174
175 return [];*/
176 //return result.Items.map(item => JSON.stringify(item));
177 }).catch(error => { console.log(error); });
178};
179exports.deleteEntry = (tableName, pkEntity, pkValue, skEntity, skValue, isOffline) => {
180 //console.log("delete entry: ", pkEntity, pkValue, skEntity, skValue)
181 //console.log("pk: ", `${pkEntity}|${pkValue}`);
182 //console.log("sk: ", `${skEntity}|${skValue}`);
183 return promisify(callback => new aws_sdk_1.default.DynamoDB.DocumentClient(applyOfflineConfig(isOffline)).delete({
184 // use the table_name as specified in the serverless.yml
185 TableName: tableName,
186 Key: {
187 pk: `${pkEntity}|${pkValue}`,
188 sk: `${skEntity}|${skValue}`
189 }
190 }, callback))
191 .then(result => {
192 //console.log("result: ", result);
193 return result["Item"] ? result["Item"] : result;
194 }).catch(error => { console.log(error); });
195};
196/**
197 * this function provides a executable graphql-query
198 * TODO the fields must be taken from the data-layer, not requiring the user to provide them
199 */
200exports.setEntryMutation = (entryId, data, fields, context = {}) => {
201 //console.log("setEntryMutation: ", entryId, data, fields);
202 const mutationObj = {};
203 mutationObj[`set_${entryId}`] = typed_graphqlify_1.params(Object.keys(data).reduce((result, key) => {
204 result[key] = `"${data[key]}"`;
205 return result;
206 }, {}), Object.keys(fields).reduce((result, key) => {
207 result[key] = typed_graphqlify_1.types.string;
208 return result;
209 }, {}));
210 return {
211 mutation: graphql_tag_1.default `${typed_graphqlify_1.mutation(mutationObj)}`,
212 context: context
213 };
214};
215exports.deleteEntryMutation = (entryId, data, fields, context = {}) => {
216 //console.log("deleteEntryMutation: ", entryId, data);
217 const mutationObj = {};
218 mutationObj[`delete_${entryId}`] = typed_graphqlify_1.params(Object.keys(data).reduce((result, key) => {
219 result[key] = `"${data[key]}"`;
220 return result;
221 }, {}), Object.keys(fields).reduce((result, key) => {
222 result[key] = typed_graphqlify_1.types.string;
223 return result;
224 }, {}));
225 return {
226 mutation: graphql_tag_1.default `${typed_graphqlify_1.mutation(mutationObj)}`,
227 context: context
228 };
229};
230/**
231 * this function provides a executable graphql-query
232 */
233exports.getEntryListQuery = (entryId, data, fields, context = {}) => {
234 //console.log("getEntryListQuery: ", entryId, data, fields, context);
235 if (data == undefined) {
236 console.error("getEntryListQuery requires a data argument");
237 return undefined;
238 }
239 if (Object.keys(data).length !== 1) {
240 console.error("getEntryListQuery requires exact 1 field provided in the data argument");
241 return undefined;
242 }
243 const queryKey = Object.keys(data)[0];
244 const queryObj = {};
245 queryObj[`list_${entryId}_${queryKey}`] = typed_graphqlify_1.params(Object.keys(data).filter(key => key === queryKey).reduce((result, key) => {
246 result[key] = `"${data[key]}"`;
247 return result;
248 }, {}), Object.keys(fields).reduce((result, key) => {
249 result[key] = typed_graphqlify_1.types.string;
250 return result;
251 }, {}));
252 //console.log("listQuery string: ", query(queryObj));
253 return {
254 query: graphql_tag_1.default `${typed_graphqlify_1.query(queryObj)}`,
255 context: context
256 };
257};
258exports.getEntryQuery = (entryId, data, fields, context = {}) => {
259 //console.log("getEntryQuery: ", entryId, data, fields, context);
260 if (data == undefined) {
261 console.error("getEntryQuery requires a data argument");
262 return undefined;
263 }
264 if (Object.keys(data).length !== 2) {
265 console.error("getEntryQuery requires exact 2 fields provided in the data argument");
266 return undefined;
267 }
268 const queryObj = {};
269 queryObj[`get_${entryId}`] = typed_graphqlify_1.params(Object.keys(data).reduce((result, key) => {
270 result[key] = `"${data[key]}"`;
271 return result;
272 }, {}), Object.keys(fields).reduce((result, key) => {
273 result[key] = typed_graphqlify_1.types.string;
274 return result;
275 }, {}));
276 //console.log("listQuery string: ", query(queryObj));
277 return {
278 query: graphql_tag_1.default `${typed_graphqlify_1.query(queryObj)}`,
279 context: context
280 };
281};
282exports.updateEntryQuery = (entryId, callback, context = {}) => {
283 return { entryId: entryId, callback: callback, context: context };
284};
285/**
286 * this function provides a executable graphql-query: "scan_{entryId}"
287 *
288 */
289exports.getEntryScanQuery = (entryId, data, fields, context = {}) => {
290 //console.log("getEntryScanQuery: ", entryId, data, fields, context);
291 if (data == undefined) {
292 console.error("getEntryScanQuery requires a data argument, this may be empty");
293 return undefined;
294 }
295 const queryObj = {};
296 if (Object.keys(data).length > 0) {
297 const queryKey = Object.keys(data)[0];
298 queryObj[`scan_${entryId}_${queryKey}`] = typed_graphqlify_1.params(Object.keys(data).reduce((result, key) => {
299 // when we have an array at the key-pos in data, then we want to get a range
300 if (Array.isArray(data[key])) {
301 if (data[key].length > 0 && data[key][0] !== undefined) {
302 result[`start_${key}`] = `"${data[key][0]}"`;
303 }
304 if (data[key].length > 1 && data[key][1] !== undefined) {
305 result[`end_${key}`] = `"${data[key][1]}"`;
306 }
307 }
308 else {
309 result[key] = `"${data[key]}"`;
310 }
311 return result;
312 }, {}), Object.keys(fields).reduce((result, key) => {
313 result[key] = typed_graphqlify_1.types.string;
314 return result;
315 }, {}));
316 //console.log(gql`${query(queryObj)}`);
317 return {
318 query: graphql_tag_1.default `${typed_graphqlify_1.query(queryObj)}`,
319 context: context
320 };
321 }
322 else {
323 queryObj[`scan_${entryId}`] = typed_graphqlify_1.params({ scanall: `"yes"` }, Object.keys(fields).reduce((result, key) => {
324 result[key] = typed_graphqlify_1.types.string;
325 return result;
326 }, {}));
327 //console.log(gql`${query(queryObj)}`);
328 return {
329 query: graphql_tag_1.default `${typed_graphqlify_1.query(queryObj)}`,
330 context: context
331 };
332 }
333 //console.log("scanQuery string: ", query(queryObj));
334};
335function select(client, { query, context = {} }) {
336 return __awaiter(this, void 0, void 0, function* () {
337 if (!context["userId"]) {
338 context["userId"] = new universal_cookie_1.default().get(auth_middleware_1.IC_USER_ID);
339 }
340 //console.log("select: ", query, context);
341 return yield client.query({
342 query: query,
343 context: context
344 }).then(result => {
345 //console.log("select result: ", result)
346 return result.data ? result.data : result;
347 }).catch(error => {
348 console.log(error);
349 });
350 });
351}
352exports.select = select;
353;
354/**
355 * uses this: https://github.com/acro5piano/typed-graphqlify
356 *
357 * TODO generalize to other data-types than string
358 *
359 * @param client
360 * @param entryId
361 * @param data
362 * @returns {any|Promise<T>|Promise<U>}
363 */
364function mutate(client, { mutation, context = {} }) {
365 return __awaiter(this, void 0, void 0, function* () {
366 if (!context["userId"]) {
367 context["userId"] = new universal_cookie_1.default().get(auth_middleware_1.IC_USER_ID);
368 }
369 //console.log("mutate: ", mutation, context);
370 //console.log("mutation string: ", mutation(mutationObj));
371 return yield client.mutate({
372 mutation: mutation,
373 context: context
374 }).then(result => { }).catch(error => { console.log(error); });
375 });
376}
377exports.mutate = mutate;
378;
379/**
380 *
381 * @param client
382 * @param callback (oldData) => newData
383 * @param context
384 * @returns {Promise<any>}
385 */
386function update(client, { entryId, getEntryQuery, setEntryMutation }) {
387 return __awaiter(this, void 0, void 0, function* () {
388 const oldData = yield select(client, getEntryQuery());
389 return yield mutate(client, setEntryMutation(oldData[`get_${entryId}`]));
390 });
391}
392exports.update = update;
393;
394//# sourceMappingURL=datalayer-libs.js.map
\No newline at end of file