quidproquo-actionprocessor-awslambda 0.0.101 → 0.0.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/lib/getActionProcessor/core/keyValueStore/getKeyValueStoreQueryActionProcessor.d.ts +6 -0
  2. package/lib/getActionProcessor/core/keyValueStore/getKeyValueStoreQueryActionProcessor.js +31 -0
  3. package/lib/getActionProcessor/core/keyValueStore/getKeyValueStoreScanActionProcessor.d.ts +6 -0
  4. package/lib/getActionProcessor/core/keyValueStore/getKeyValueStoreScanActionProcessor.js +30 -0
  5. package/lib/getActionProcessor/core/keyValueStore/getKeyValueStoreUpsertActionProcessor.d.ts +1 -2
  6. package/lib/getActionProcessor/core/keyValueStore/getKeyValueStoreUpsertActionProcessor.js +17 -15
  7. package/lib/getActionProcessor/core/keyValueStore/index.d.ts +3 -1
  8. package/lib/getActionProcessor/core/keyValueStore/index.js +3 -1
  9. package/lib/logic/cache/memoFunc.d.ts +7 -0
  10. package/lib/logic/cache/memoFunc.js +35 -0
  11. package/lib/logic/cloudformation/getExportedValue.js +3 -3
  12. package/lib/logic/cognito/utils/calculateSecretHash.js +3 -3
  13. package/lib/logic/dynamo/convertObjectToDynamoMap.d.ts +2 -0
  14. package/lib/logic/dynamo/convertObjectToDynamoMap.js +69 -0
  15. package/lib/logic/dynamo/index.d.ts +1 -0
  16. package/lib/logic/dynamo/index.js +1 -0
  17. package/lib/logic/dynamo/putItem.d.ts +1 -1
  18. package/lib/logic/dynamo/putItem.js +3 -2
  19. package/lib/logic/dynamo/qpqDynamoOrm/buildDynamoQuery.d.ts +7 -0
  20. package/lib/logic/dynamo/qpqDynamoOrm/buildDynamoQuery.js +187 -0
  21. package/lib/logic/dynamo/qpqDynamoOrm/index.d.ts +1 -0
  22. package/lib/logic/dynamo/qpqDynamoOrm/index.js +17 -0
  23. package/lib/logic/dynamo/qpqDynamoOrm/thing.d.ts +2 -0
  24. package/lib/logic/dynamo/qpqDynamoOrm/thing.js +26 -0
  25. package/lib/logic/dynamo/query.d.ts +2 -0
  26. package/lib/logic/dynamo/query.js +38 -0
  27. package/lib/logic/dynamo/scan.d.ts +2 -0
  28. package/lib/logic/dynamo/scan.js +35 -0
  29. package/lib/logic/parametersManager/getParameter.js +3 -3
  30. package/lib/logic/parametersManager/getParameters.js +3 -3
  31. package/lib/logic/secretsManager/getSecret.js +3 -3
  32. package/package.json +2 -1
@@ -0,0 +1,6 @@
1
+ import { QPQConfig } from 'quidproquo-core';
2
+ import { KeyValueStoreQueryActionProcessor } from 'quidproquo-core';
3
+ declare const _default: (qpqConfig: QPQConfig) => {
4
+ "@quidproquo-core/KeyValueStore/Query": KeyValueStoreQueryActionProcessor<any>;
5
+ };
6
+ export default _default;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const quidproquo_core_1 = require("quidproquo-core");
13
+ const awsNamingUtils_1 = require("../../../awsNamingUtils");
14
+ const quidproquo_core_2 = require("quidproquo-core");
15
+ const dynamo_1 = require("../../../logic/dynamo");
16
+ const thing_1 = require("../../../logic/dynamo/qpqDynamoOrm/thing");
17
+ const getProcessKeyValueStoreQuery = (qpqConfig) => {
18
+ return ({ keyValueStoreName, keyCondition, filterCondition }) => __awaiter(void 0, void 0, void 0, function* () {
19
+ const dynamoTableName = (0, awsNamingUtils_1.getQpqRuntimeResourceNameFromConfig)(keyValueStoreName, qpqConfig, 'kvs');
20
+ const region = quidproquo_core_1.qpqCoreUtils.getApplicationModuleDeployRegion(qpqConfig);
21
+ const storeConfig = quidproquo_core_1.qpqCoreUtils.getKeyValueStoreByName(qpqConfig, keyValueStoreName);
22
+ if (!storeConfig) {
23
+ return (0, quidproquo_core_1.actionResultError)(quidproquo_core_1.ErrorTypeEnum.NotFound, `Could not find key value store with name "${keyValueStoreName}"`);
24
+ }
25
+ const items = yield (0, dynamo_1.query)(dynamoTableName, region, keyCondition, filterCondition, (0, thing_1.getDynamoTableIndexByConfigAndQuery)(storeConfig, keyCondition));
26
+ return (0, quidproquo_core_2.actionResult)(items);
27
+ });
28
+ };
29
+ exports.default = (qpqConfig) => ({
30
+ [quidproquo_core_2.KeyValueStoreActionType.Query]: getProcessKeyValueStoreQuery(qpqConfig),
31
+ });
@@ -0,0 +1,6 @@
1
+ import { QPQConfig } from 'quidproquo-core';
2
+ import { KeyValueStoreScanActionProcessor } from 'quidproquo-core';
3
+ declare const _default: (qpqConfig: QPQConfig) => {
4
+ "@quidproquo-core/KeyValueStore/Scan": KeyValueStoreScanActionProcessor<any>;
5
+ };
6
+ export default _default;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const quidproquo_core_1 = require("quidproquo-core");
13
+ const awsNamingUtils_1 = require("../../../awsNamingUtils");
14
+ const quidproquo_core_2 = require("quidproquo-core");
15
+ const scan_1 = require("../../../logic/dynamo/scan");
16
+ const getProcessKeyValueStoreScan = (qpqConfig) => {
17
+ return ({ keyValueStoreName, filterCondition }) => __awaiter(void 0, void 0, void 0, function* () {
18
+ const dynamoTableName = (0, awsNamingUtils_1.getQpqRuntimeResourceNameFromConfig)(keyValueStoreName, qpqConfig, 'kvs');
19
+ const region = quidproquo_core_1.qpqCoreUtils.getApplicationModuleDeployRegion(qpqConfig);
20
+ const storeConfig = quidproquo_core_1.qpqCoreUtils.getKeyValueStoreByName(qpqConfig, keyValueStoreName);
21
+ if (!storeConfig) {
22
+ return (0, quidproquo_core_1.actionResultError)(quidproquo_core_1.ErrorTypeEnum.NotFound, `Could not find key value store with name "${keyValueStoreName}"`);
23
+ }
24
+ const items = yield (0, scan_1.scan)(dynamoTableName, region, filterCondition);
25
+ return (0, quidproquo_core_2.actionResult)(items);
26
+ });
27
+ };
28
+ exports.default = (qpqConfig) => ({
29
+ [quidproquo_core_2.KeyValueStoreActionType.Scan]: getProcessKeyValueStoreScan(qpqConfig),
30
+ });
@@ -1,5 +1,4 @@
1
- import { QPQConfig } from 'quidproquo-core';
2
- import { KeyValueStoreUpsertActionProcessor } from 'quidproquo-core';
1
+ import { QPQConfig, KeyValueStoreUpsertActionProcessor } from 'quidproquo-core';
3
2
  declare const _default: (qpqConfig: QPQConfig) => {
4
3
  "@quidproquo-core/KeyValueStore/Upsert": KeyValueStoreUpsertActionProcessor<any>;
5
4
  };
@@ -10,23 +10,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const quidproquo_core_1 = require("quidproquo-core");
13
+ const awsNamingUtils_1 = require("../../../awsNamingUtils");
14
+ const dynamo_1 = require("../../../logic/dynamo");
13
15
  const getProcessKeyValueStoreUpsert = (qpqConfig) => {
14
16
  return ({ keyValueStoreName, item, options }) => __awaiter(void 0, void 0, void 0, function* () {
15
- // const dynamoTableName = getQpqRuntimeResourceNameFromConfig(
16
- // keyValueStoreName,
17
- // qpqConfig,
18
- // 'kvs',
19
- // );
20
- // const region = qpqCoreUtils.getApplicationModuleDeployRegion(qpqConfig);
21
- // await putItem(
22
- // dynamoTableName,
23
- // key,
24
- // value,
25
- // {
26
- // expires: options?.ttlInSeconds,
27
- // },
28
- // region,
29
- // );
17
+ const dynamoTableName = (0, awsNamingUtils_1.getQpqRuntimeResourceNameFromConfig)(keyValueStoreName, qpqConfig, 'kvs');
18
+ const region = quidproquo_core_1.qpqCoreUtils.getApplicationModuleDeployRegion(qpqConfig);
19
+ const storeConfig = quidproquo_core_1.qpqCoreUtils.getKeyValueStoreByName(qpqConfig, keyValueStoreName);
20
+ if (!storeConfig) {
21
+ return (0, quidproquo_core_1.actionResultError)(quidproquo_core_1.ErrorTypeEnum.NotFound, `Could not find key value store with name "${keyValueStoreName}"`);
22
+ }
23
+ const keys = [
24
+ storeConfig.partitionKey,
25
+ ...storeConfig.sortKeys,
26
+ ...storeConfig.indexes.map((i) => i.partitionKey),
27
+ ...storeConfig.indexes.filter((i) => !!i.sortKey).map((i) => i.sortKey),
28
+ ];
29
+ yield (0, dynamo_1.putItem)(dynamoTableName, item, keys, {
30
+ expires: options === null || options === void 0 ? void 0 : options.ttlInSeconds,
31
+ }, region);
30
32
  return (0, quidproquo_core_1.actionResult)(void 0);
31
33
  });
32
34
  };
@@ -1,7 +1,9 @@
1
1
  import { QPQConfig } from 'quidproquo-core';
2
2
  declare const _default: (qpqConfig: QPQConfig) => {
3
- "@quidproquo-core/KeyValueStore/Update": import("quidproquo-core").KeyValueStoreUpdateActionProcessor<any>;
3
+ "@quidproquo-core/KeyValueStore/Scan": import("quidproquo-core").KeyValueStoreScanActionProcessor<any>;
4
4
  "@quidproquo-core/KeyValueStore/Upsert": import("quidproquo-core").KeyValueStoreUpsertActionProcessor<any>;
5
+ "@quidproquo-core/KeyValueStore/Update": import("quidproquo-core").KeyValueStoreUpdateActionProcessor<any>;
6
+ "@quidproquo-core/KeyValueStore/Query": import("quidproquo-core").KeyValueStoreQueryActionProcessor<any>;
5
7
  "@quidproquo-core/KeyValueStore/Get": import("quidproquo-core").KeyValueStoreGetActionProcessor<any>;
6
8
  "@quidproquo-core/KeyValueStore/Delete": import("quidproquo-core").KeyValueStoreDeleteActionProcessor;
7
9
  };
@@ -7,4 +7,6 @@ const getKeyValueStoreDeleteActionProcessor_1 = __importDefault(require("./getKe
7
7
  const getKeyValueStoreGetActionProcessor_1 = __importDefault(require("./getKeyValueStoreGetActionProcessor"));
8
8
  const getKeyValueStoreUpsertActionProcessor_1 = __importDefault(require("./getKeyValueStoreUpsertActionProcessor"));
9
9
  const getKeyValueStoreUpdateActionProcessor_1 = __importDefault(require("./getKeyValueStoreUpdateActionProcessor"));
10
- exports.default = (qpqConfig) => (Object.assign(Object.assign(Object.assign(Object.assign({}, (0, getKeyValueStoreDeleteActionProcessor_1.default)(qpqConfig)), (0, getKeyValueStoreGetActionProcessor_1.default)(qpqConfig)), (0, getKeyValueStoreUpsertActionProcessor_1.default)(qpqConfig)), (0, getKeyValueStoreUpdateActionProcessor_1.default)(qpqConfig)));
10
+ const getKeyValueStoreQueryActionProcessor_1 = __importDefault(require("./getKeyValueStoreQueryActionProcessor"));
11
+ const getKeyValueStoreScanActionProcessor_1 = __importDefault(require("./getKeyValueStoreScanActionProcessor"));
12
+ exports.default = (qpqConfig) => (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (0, getKeyValueStoreDeleteActionProcessor_1.default)(qpqConfig)), (0, getKeyValueStoreGetActionProcessor_1.default)(qpqConfig)), (0, getKeyValueStoreQueryActionProcessor_1.default)(qpqConfig)), (0, getKeyValueStoreUpdateActionProcessor_1.default)(qpqConfig)), (0, getKeyValueStoreUpsertActionProcessor_1.default)(qpqConfig)), (0, getKeyValueStoreScanActionProcessor_1.default)(qpqConfig)));
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Memoizes a function by caching its return values.
3
+ * @param func The function to memoize.
4
+ * @param ttlInSeconds Time-to-live for the cached values in seconds.
5
+ * @returns The memoized function.
6
+ */
7
+ export declare const memoFunc: <T extends (...args: any[]) => any>(func: T, ttlInSeconds?: number) => T;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.memoFunc = void 0;
7
+ const node_cache_1 = __importDefault(require("node-cache"));
8
+ const cache = new WeakMap();
9
+ /**
10
+ * Memoizes a function by caching its return values.
11
+ * @param func The function to memoize.
12
+ * @param ttlInSeconds Time-to-live for the cached values in seconds.
13
+ * @returns The memoized function.
14
+ */
15
+ const memoFunc = (func, ttlInSeconds = 3600) => {
16
+ return ((...args) => {
17
+ // Check if the function has a corresponding cache entry
18
+ if (!cache.has(func)) {
19
+ // Create a new NodeCache instance and store it in the cache
20
+ cache.set(func, new node_cache_1.default({ stdTTL: ttlInSeconds }));
21
+ }
22
+ const cacheKey = JSON.stringify(args);
23
+ const nodeCache = cache.get(func);
24
+ const cachedValue = nodeCache.get(cacheKey);
25
+ if (cachedValue) {
26
+ return cachedValue;
27
+ }
28
+ // Call the original function if the value is not cached
29
+ const result = func(...args);
30
+ // Cache the result for future use
31
+ nodeCache.set(cacheKey, result);
32
+ return result;
33
+ });
34
+ };
35
+ exports.memoFunc = memoFunc;
@@ -11,7 +11,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.getExportedValue = void 0;
13
13
  const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
14
- const getExportedValue = (variableName, region) => __awaiter(void 0, void 0, void 0, function* () {
14
+ const memoFunc_1 = require("../cache/memoFunc");
15
+ exports.getExportedValue = (0, memoFunc_1.memoFunc)((variableName, region) => __awaiter(void 0, void 0, void 0, function* () {
15
16
  var _a;
16
17
  const cloudformation = new client_cloudformation_1.CloudFormationClient({ region });
17
18
  const listCommandParams = {};
@@ -25,5 +26,4 @@ const getExportedValue = (variableName, region) => __awaiter(void 0, void 0, voi
25
26
  listCommandParams.NextToken = result.NextToken;
26
27
  } while (!!listCommandParams.NextToken);
27
28
  throw new Error(`CF could not find: [${variableName}]`);
28
- });
29
- exports.getExportedValue = getExportedValue;
29
+ }));
@@ -2,12 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.calculateSecretHash = void 0;
4
4
  const crypto_1 = require("crypto");
5
- const calculateSecretHash = (username, clientId, clientSecret) => {
5
+ const memoFunc_1 = require("../../cache/memoFunc");
6
+ exports.calculateSecretHash = (0, memoFunc_1.memoFunc)((username, clientId, clientSecret) => {
6
7
  // create the hmac with the sha256 algorithm and a secret key
7
8
  const hasher = (0, crypto_1.createHmac)('sha256', clientSecret);
8
9
  // add the value we want to hash
9
10
  hasher.update(`${username}${clientId}`);
10
11
  // get the hashed value as base64
11
12
  return hasher.digest('base64');
12
- };
13
- exports.calculateSecretHash = calculateSecretHash;
13
+ });
@@ -0,0 +1,2 @@
1
+ export declare function convertObjectToDynamoMap(obj: any): any;
2
+ export declare function convertDynamoMapToObject(dynamoMap: any): any;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertDynamoMapToObject = exports.convertObjectToDynamoMap = void 0;
4
+ function convertObjectToDynamoMap(obj) {
5
+ const map = {};
6
+ for (const property in obj) {
7
+ const value = obj[property];
8
+ const valueType = typeof value;
9
+ switch (valueType) {
10
+ case 'string':
11
+ map[property] = { S: value };
12
+ break;
13
+ case 'number':
14
+ map[property] = { N: value.toString() };
15
+ break;
16
+ case 'boolean':
17
+ map[property] = { BOOL: value };
18
+ break;
19
+ case 'object':
20
+ if (Array.isArray(value)) {
21
+ map[property] = {
22
+ L: value.map((item) => convertObjectToDynamoMap({ temp: item }).temp),
23
+ };
24
+ }
25
+ else if (value !== null) {
26
+ map[property] = { M: convertObjectToDynamoMap(value) };
27
+ }
28
+ else {
29
+ map[property] = { NULL: true };
30
+ }
31
+ break;
32
+ default:
33
+ throw new Error(`Unsupported data type: ${valueType}`);
34
+ }
35
+ }
36
+ return map;
37
+ }
38
+ exports.convertObjectToDynamoMap = convertObjectToDynamoMap;
39
+ function convertDynamoMapToObject(dynamoMap) {
40
+ const obj = {};
41
+ for (const property in dynamoMap) {
42
+ const value = dynamoMap[property];
43
+ const valueType = Object.keys(value)[0];
44
+ switch (valueType) {
45
+ case 'S':
46
+ obj[property] = value.S;
47
+ break;
48
+ case 'N':
49
+ obj[property] = parseFloat(value.N);
50
+ break;
51
+ case 'BOOL':
52
+ obj[property] = value.BOOL;
53
+ break;
54
+ case 'NULL':
55
+ obj[property] = null;
56
+ break;
57
+ case 'L':
58
+ obj[property] = value.L.map((item) => convertDynamoMapToObject({ temp: item }).temp);
59
+ break;
60
+ case 'M':
61
+ obj[property] = convertDynamoMapToObject(value.M);
62
+ break;
63
+ default:
64
+ throw new Error(`Unsupported DynamoDB data type: ${valueType}`);
65
+ }
66
+ }
67
+ return obj;
68
+ }
69
+ exports.convertDynamoMapToObject = convertDynamoMapToObject;
@@ -3,3 +3,4 @@ export * from './getAllItems';
3
3
  export * from './getItem';
4
4
  export * from './putItem';
5
5
  export * from './updateItem';
6
+ export * from './query';
@@ -19,3 +19,4 @@ __exportStar(require("./getAllItems"), exports);
19
19
  __exportStar(require("./getItem"), exports);
20
20
  __exportStar(require("./putItem"), exports);
21
21
  __exportStar(require("./updateItem"), exports);
22
+ __exportStar(require("./query"), exports);
@@ -9,4 +9,4 @@ export type KvsKeyValue<T> = {
9
9
  export type DynamoAttributeType = 'S' | 'N' | 'B';
10
10
  export declare const readKvsAttributeValue: <T, K extends keyof T>(item: T, key: KvsKey) => KvsKeyValue<T[K]>;
11
11
  export declare const getDynamoValueTypeFromKvsKey: (key: KvsKey) => DynamoAttributeType;
12
- export declare function putItem<Item>(tableName: string, key: string, item: Item, attributes: KvsKey[], options: PutItemOptions, region: string): Promise<void>;
12
+ export declare function putItem<Item>(tableName: string, item: Item, attributes: KvsKey[], options: PutItemOptions, region: string): Promise<void>;
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.putItem = exports.getDynamoValueTypeFromKvsKey = exports.readKvsAttributeValue = void 0;
13
13
  const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
14
14
  const lodash_1 = require("lodash");
15
+ const convertObjectToDynamoMap_1 = require("./convertObjectToDynamoMap");
15
16
  const readKvsAttributeValue = (item, key) => {
16
17
  const value = (0, lodash_1.get)(item, key.key);
17
18
  return {
@@ -31,7 +32,7 @@ const getDynamoValueTypeFromKvsKey = (key) => {
31
32
  }
32
33
  };
33
34
  exports.getDynamoValueTypeFromKvsKey = getDynamoValueTypeFromKvsKey;
34
- function putItem(tableName, key, item, attributes, options, region) {
35
+ function putItem(tableName, item, attributes, options, region) {
35
36
  return __awaiter(this, void 0, void 0, function* () {
36
37
  const dynamoClient = new client_dynamodb_1.DynamoDBClient({ region });
37
38
  // Read all the values from the item
@@ -47,7 +48,7 @@ function putItem(tableName, key, item, attributes, options, region) {
47
48
  }, {});
48
49
  yield dynamoClient.send(new client_dynamodb_1.PutItemCommand({
49
50
  TableName: tableName,
50
- Item: Object.assign({}, dynamoProps),
51
+ Item: (0, convertObjectToDynamoMap_1.convertObjectToDynamoMap)(item),
51
52
  }));
52
53
  });
53
54
  }
@@ -0,0 +1,7 @@
1
+ import { KvsQueryOperation, KvsQueryCondition, KvsLogicalOperator } from 'quidproquo-core';
2
+ import { AttributeValue } from '@aws-sdk/client-dynamodb';
3
+ export declare const isKvsQueryCondition: (query: KvsQueryOperation) => query is KvsQueryCondition;
4
+ export declare const isKvsLogicalOperator: (query: KvsQueryOperation) => query is KvsLogicalOperator;
5
+ export declare const buildDynamoQueryExpression: (query?: KvsQueryOperation) => string | undefined;
6
+ export declare const buildExpressionAttributeValues: (queries: (KvsQueryOperation | undefined)[]) => Record<string, AttributeValue>;
7
+ export declare const buildExpressionAttributeNames: (queries: (KvsQueryOperation | undefined)[]) => Record<string, string>;
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildExpressionAttributeNames = exports.buildExpressionAttributeValues = exports.buildDynamoQueryExpression = exports.isKvsLogicalOperator = exports.isKvsQueryCondition = void 0;
7
+ const crypto_1 = __importDefault(require("crypto"));
8
+ const quidproquo_core_1 = require("quidproquo-core");
9
+ // TODO: Come up with a better way of generating item name / values
10
+ // probably a map ~ however this will most likely never fail.
11
+ const getHash = (name) => {
12
+ const c = crypto_1.default.createHash('md5').update(name).digest('hex');
13
+ return c;
14
+ };
15
+ const getItemName = (name) => {
16
+ return `#${getHash(name)}`;
17
+ };
18
+ const getValueName = (value) => {
19
+ return `:${getHash(`${typeof value}-${JSON.stringify(value)}`)}`;
20
+ };
21
+ const buildDynamoQueryExpressionBetween = (query) => {
22
+ if (!query.key || !query.valueB || !query.valueB) {
23
+ throw new Error(`Invalid query condition ${quidproquo_core_1.KvsQueryOperationType.Between}`);
24
+ }
25
+ return `${getItemName(query.key)} BETWEEN ${getValueName(query.valueA)} AND ${getValueName(query.valueB)}`;
26
+ };
27
+ const buildDynamoQueryExpressionEqual = (query) => {
28
+ return `${getItemName(query.key)} = ${getValueName(query.valueA)}`;
29
+ };
30
+ const buildDynamoQueryExpressionNotEqual = (query) => {
31
+ return `${getItemName(query.key)} <> ${getValueName(query.valueA)}`;
32
+ };
33
+ const buildDynamoQueryExpressionLessThan = (query) => {
34
+ return `${getItemName(query.key)} < ${getValueName(query.valueA)}`;
35
+ };
36
+ const buildDynamoQueryExpressionLessThanOrEqual = (query) => {
37
+ return `${getItemName(query.key)} <= ${getValueName(query.valueA)}`;
38
+ };
39
+ const buildDynamoQueryExpressionGreaterThan = (query) => {
40
+ return `${getItemName(query.key)} > ${getValueName(query.valueA)}`;
41
+ };
42
+ const buildDynamoQueryExpressionGreaterThanOrEqual = (query) => {
43
+ return `${getItemName(query.key)} >= ${getValueName(query.valueA)}`;
44
+ };
45
+ const buildDynamoQueryExpressionIn = (query) => {
46
+ return `${getItemName(query.key)} IN (${query.valueA
47
+ .map((v) => getValueName(v))
48
+ .join(', ')})`;
49
+ };
50
+ const buildDynamoQueryExpressionExists = (query) => {
51
+ return `attribute_exists(${getItemName(query.key)})`;
52
+ };
53
+ const buildDynamoQueryExpressionNotExists = (query) => {
54
+ return `attribute_not_exists(${getItemName(query.key)})`;
55
+ };
56
+ const buildDynamoQueryExpressionBeginsWith = (query) => {
57
+ return `begins_with(${getItemName(query.key)}, ${getValueName(query.valueA)})`;
58
+ };
59
+ const buildDynamoQueryExpressionContains = (query) => {
60
+ return `contains(${getItemName(query.key)}, ${getValueName(query.valueA)})`;
61
+ };
62
+ const buildDynamoQueryExpressionNotContains = (query) => {
63
+ return `NOT contains(${getItemName(query.key)}, ${getValueName(query.valueA)})`;
64
+ };
65
+ const buildDynamoQueryExpressionOr = (query) => {
66
+ return query.conditions.map((c) => `(${buildDynamoQueryExpressionRoot(c)})`).join(' OR ');
67
+ };
68
+ const buildDynamoQueryExpressionAnd = (query) => {
69
+ return query.conditions.map((c) => `(${buildDynamoQueryExpressionRoot(c)})`).join(' AND ');
70
+ };
71
+ const isKvsQueryCondition = (query) => {
72
+ return 'key' in query && 'operation' in query;
73
+ };
74
+ exports.isKvsQueryCondition = isKvsQueryCondition;
75
+ const isKvsLogicalOperator = (query) => {
76
+ return 'conditions' in query && 'operation' in query;
77
+ };
78
+ exports.isKvsLogicalOperator = isKvsLogicalOperator;
79
+ const buildDynamoQueryExpressionRoot = (query) => {
80
+ if ((0, exports.isKvsQueryCondition)(query)) {
81
+ switch (query.operation) {
82
+ case quidproquo_core_1.KvsQueryOperationType.Equal:
83
+ return buildDynamoQueryExpressionEqual(query);
84
+ case quidproquo_core_1.KvsQueryOperationType.NotEqual:
85
+ return buildDynamoQueryExpressionNotEqual(query);
86
+ case quidproquo_core_1.KvsQueryOperationType.LessThan:
87
+ return buildDynamoQueryExpressionLessThan(query);
88
+ case quidproquo_core_1.KvsQueryOperationType.LessThanOrEqual:
89
+ return buildDynamoQueryExpressionLessThanOrEqual(query);
90
+ case quidproquo_core_1.KvsQueryOperationType.GreaterThan:
91
+ return buildDynamoQueryExpressionGreaterThan(query);
92
+ case quidproquo_core_1.KvsQueryOperationType.GreaterThanOrEqual:
93
+ return buildDynamoQueryExpressionGreaterThanOrEqual(query);
94
+ case quidproquo_core_1.KvsQueryOperationType.Between:
95
+ return buildDynamoQueryExpressionBetween(query);
96
+ case quidproquo_core_1.KvsQueryOperationType.In:
97
+ return buildDynamoQueryExpressionIn(query);
98
+ case quidproquo_core_1.KvsQueryOperationType.Exists:
99
+ return buildDynamoQueryExpressionExists(query);
100
+ case quidproquo_core_1.KvsQueryOperationType.NotExists:
101
+ return buildDynamoQueryExpressionNotExists(query);
102
+ case quidproquo_core_1.KvsQueryOperationType.BeginsWith:
103
+ return buildDynamoQueryExpressionBeginsWith(query);
104
+ case quidproquo_core_1.KvsQueryOperationType.Contains:
105
+ return buildDynamoQueryExpressionContains(query);
106
+ case quidproquo_core_1.KvsQueryOperationType.NotContains:
107
+ return buildDynamoQueryExpressionNotContains(query);
108
+ }
109
+ }
110
+ else if ((0, exports.isKvsLogicalOperator)(query)) {
111
+ switch (query.operation) {
112
+ case quidproquo_core_1.KvsLogicalOperatorType.And:
113
+ return buildDynamoQueryExpressionAnd(query);
114
+ case quidproquo_core_1.KvsLogicalOperatorType.Or:
115
+ return buildDynamoQueryExpressionOr(query);
116
+ }
117
+ }
118
+ throw new Error(`Invalid query operation: ${JSON.stringify(query)}`);
119
+ };
120
+ const buildAttributeValue = (value) => {
121
+ switch (typeof value) {
122
+ case 'string':
123
+ return { S: value };
124
+ case 'number':
125
+ return { N: value.toString() };
126
+ case 'boolean':
127
+ return { BOOL: value };
128
+ case 'object':
129
+ if (Array.isArray(value)) {
130
+ // check if all elements in the array are strings
131
+ if (value.every((item) => typeof item === 'string')) {
132
+ return { L: value.map((item) => ({ S: item })) };
133
+ }
134
+ throw new Error(`Invalid attribute value array content: ${JSON.stringify(value)}`);
135
+ }
136
+ throw new Error(`Invalid attribute value type: ${typeof value}`);
137
+ default:
138
+ throw new Error(`Invalid attribute value type: ${typeof value}`);
139
+ }
140
+ };
141
+ const buildDynamoQueryExpression = (query) => {
142
+ if (!query) {
143
+ return undefined;
144
+ }
145
+ return buildDynamoQueryExpressionRoot(query);
146
+ };
147
+ exports.buildDynamoQueryExpression = buildDynamoQueryExpression;
148
+ const buildExpressionAttributeValues = (queries) => {
149
+ const values = {};
150
+ const traverse = (query) => {
151
+ if ((0, exports.isKvsQueryCondition)(query)) {
152
+ if (query.valueA !== undefined) {
153
+ const valueNameA = getValueName(query.valueA);
154
+ values[valueNameA] = buildAttributeValue(query.valueA);
155
+ }
156
+ if (query.valueB !== undefined) {
157
+ const valueNameB = getValueName(query.valueB);
158
+ values[valueNameB] = buildAttributeValue(query.valueB);
159
+ }
160
+ }
161
+ else if ((0, exports.isKvsLogicalOperator)(query)) {
162
+ for (const condition of query.conditions) {
163
+ traverse(condition);
164
+ }
165
+ }
166
+ };
167
+ queries.filter((q) => !!q).forEach((q) => traverse(q));
168
+ return values;
169
+ };
170
+ exports.buildExpressionAttributeValues = buildExpressionAttributeValues;
171
+ const buildExpressionAttributeNames = (queries) => {
172
+ const names = {};
173
+ const traverse = (query) => {
174
+ if ((0, exports.isKvsQueryCondition)(query)) {
175
+ const itemName = getItemName(query.key);
176
+ names[itemName] = query.key;
177
+ }
178
+ else if ((0, exports.isKvsLogicalOperator)(query)) {
179
+ for (const condition of query.conditions) {
180
+ traverse(condition);
181
+ }
182
+ }
183
+ };
184
+ queries.filter((q) => !!q).forEach((q) => traverse(q));
185
+ return names;
186
+ };
187
+ exports.buildExpressionAttributeNames = buildExpressionAttributeNames;
@@ -0,0 +1 @@
1
+ export * from './buildDynamoQuery';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./buildDynamoQuery"), exports);
@@ -0,0 +1,2 @@
1
+ import { KeyValueStoreQPQConfigSetting, KvsQueryOperation } from 'quidproquo-core';
2
+ export declare const getDynamoTableIndexByConfigAndQuery: (setting: KeyValueStoreQPQConfigSetting, query: KvsQueryOperation) => string | undefined;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDynamoTableIndexByConfigAndQuery = void 0;
4
+ const buildDynamoQuery_1 = require("./buildDynamoQuery");
5
+ const getDynamoTableIndexByConfigAndQuery = (setting, query) => {
6
+ // Function to extract keys from a query
7
+ const extractKeysFromQuery = (query) => {
8
+ if ((0, buildDynamoQuery_1.isKvsQueryCondition)(query)) {
9
+ return [query.key];
10
+ }
11
+ else if ((0, buildDynamoQuery_1.isKvsLogicalOperator)(query)) {
12
+ return query.conditions.flatMap(extractKeysFromQuery);
13
+ }
14
+ return [];
15
+ };
16
+ const queriedKeys = extractKeysFromQuery(query);
17
+ // Find a matching index
18
+ for (const index of setting.indexes) {
19
+ if (queriedKeys.includes(index.partitionKey.key)) {
20
+ return index.partitionKey.key;
21
+ }
22
+ }
23
+ // No matching index found
24
+ return undefined;
25
+ };
26
+ exports.getDynamoTableIndexByConfigAndQuery = getDynamoTableIndexByConfigAndQuery;
@@ -0,0 +1,2 @@
1
+ import { KvsQueryOperation } from 'quidproquo-core';
2
+ export declare function query<Item>(tableName: string, region: string, keyExpression: KvsQueryOperation, filterExpression?: KvsQueryOperation, indexName?: string): Promise<Item[]>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.query = void 0;
13
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
14
+ const convertObjectToDynamoMap_1 = require("./convertObjectToDynamoMap");
15
+ const qpqDynamoOrm_1 = require("./qpqDynamoOrm");
16
+ function query(tableName, region, keyExpression, filterExpression, indexName) {
17
+ var _a;
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ // Instantiate DynamoDB client
20
+ const dynamoClient = new client_dynamodb_1.DynamoDBClient({ region });
21
+ const params = {
22
+ TableName: tableName,
23
+ KeyConditionExpression: (0, qpqDynamoOrm_1.buildDynamoQueryExpression)(keyExpression),
24
+ FilterExpression: (0, qpqDynamoOrm_1.buildDynamoQueryExpression)(filterExpression),
25
+ ExpressionAttributeValues: (0, qpqDynamoOrm_1.buildExpressionAttributeValues)([keyExpression, filterExpression]),
26
+ ExpressionAttributeNames: (0, qpqDynamoOrm_1.buildExpressionAttributeNames)([keyExpression, filterExpression]),
27
+ IndexName: indexName,
28
+ };
29
+ // TODO: Remove this log
30
+ console.log(params);
31
+ // Create QueryCommand
32
+ const command = new client_dynamodb_1.QueryCommand(params);
33
+ // TODO: Catch errors and throw QPQ ones
34
+ const data = yield dynamoClient.send(command);
35
+ return (((_a = data.Items) === null || _a === void 0 ? void 0 : _a.map((i) => (0, convertObjectToDynamoMap_1.convertDynamoMapToObject)(i))) || []);
36
+ });
37
+ }
38
+ exports.query = query;
@@ -0,0 +1,2 @@
1
+ import { KvsQueryOperation } from 'quidproquo-core';
2
+ export declare function scan<Item>(tableName: string, region: string, filterExpression?: KvsQueryOperation): Promise<Item[]>;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.scan = void 0;
13
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
14
+ const convertObjectToDynamoMap_1 = require("./convertObjectToDynamoMap");
15
+ const qpqDynamoOrm_1 = require("./qpqDynamoOrm");
16
+ function scan(tableName, region, filterExpression) {
17
+ var _a;
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ // Instantiate DynamoDB client
20
+ const dynamoClient = new client_dynamodb_1.DynamoDBClient({ region });
21
+ const params = {
22
+ TableName: tableName,
23
+ FilterExpression: (0, qpqDynamoOrm_1.buildDynamoQueryExpression)(filterExpression),
24
+ ExpressionAttributeValues: (0, qpqDynamoOrm_1.buildExpressionAttributeValues)([filterExpression]),
25
+ ExpressionAttributeNames: (0, qpqDynamoOrm_1.buildExpressionAttributeNames)([filterExpression]),
26
+ };
27
+ console.log(params);
28
+ // Create ScanCommand
29
+ const command = new client_dynamodb_1.ScanCommand(params);
30
+ // TODO: Catch errors and throw QPQ ones
31
+ const data = yield dynamoClient.send(command);
32
+ return (((_a = data.Items) === null || _a === void 0 ? void 0 : _a.map((i) => (0, convertObjectToDynamoMap_1.convertDynamoMapToObject)(i))) || []);
33
+ });
34
+ }
35
+ exports.scan = scan;
@@ -11,7 +11,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.getParameter = void 0;
13
13
  const client_ssm_1 = require("@aws-sdk/client-ssm");
14
- const getParameter = (parameterName, region) => __awaiter(void 0, void 0, void 0, function* () {
14
+ const memoFunc_1 = require("../cache/memoFunc");
15
+ exports.getParameter = (0, memoFunc_1.memoFunc)((parameterName, region) => __awaiter(void 0, void 0, void 0, function* () {
15
16
  var _a;
16
17
  const smClient = new client_ssm_1.SSMClient({
17
18
  region,
@@ -20,5 +21,4 @@ const getParameter = (parameterName, region) => __awaiter(void 0, void 0, void 0
20
21
  Name: parameterName,
21
22
  }));
22
23
  return ((_a = response.Parameter) === null || _a === void 0 ? void 0 : _a.Value) || '';
23
- });
24
- exports.getParameter = getParameter;
24
+ }), 60);
@@ -11,12 +11,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.getParameters = void 0;
13
13
  const client_ssm_1 = require("@aws-sdk/client-ssm");
14
- const getParameters = (parameterNames, region) => __awaiter(void 0, void 0, void 0, function* () {
14
+ const memoFunc_1 = require("../cache/memoFunc");
15
+ exports.getParameters = (0, memoFunc_1.memoFunc)((parameterNames, region) => __awaiter(void 0, void 0, void 0, function* () {
15
16
  const smClient = new client_ssm_1.SSMClient({ region });
16
17
  const response = yield smClient.send(new client_ssm_1.GetParametersCommand({
17
18
  Names: parameterNames,
18
19
  }));
19
20
  const resolvedParams = response.Parameters || [];
20
21
  return parameterNames.map((pn) => { var _a; return ((_a = resolvedParams.find((rp) => rp.Name == pn)) === null || _a === void 0 ? void 0 : _a.Value) || ''; });
21
- });
22
- exports.getParameters = getParameters;
22
+ }), 60);
@@ -11,7 +11,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.getSecret = void 0;
13
13
  const client_secrets_manager_1 = require("@aws-sdk/client-secrets-manager");
14
- const getSecret = (secretName, region) => __awaiter(void 0, void 0, void 0, function* () {
14
+ const memoFunc_1 = require("../cache/memoFunc");
15
+ exports.getSecret = (0, memoFunc_1.memoFunc)((secretName, region) => __awaiter(void 0, void 0, void 0, function* () {
15
16
  const smClient = new client_secrets_manager_1.SecretsManagerClient({
16
17
  region,
17
18
  });
@@ -19,5 +20,4 @@ const getSecret = (secretName, region) => __awaiter(void 0, void 0, void 0, func
19
20
  SecretId: secretName,
20
21
  }));
21
22
  return response.SecretString || '';
22
- });
23
- exports.getSecret = getSecret;
23
+ }), 60);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "quidproquo-actionprocessor-awslambda",
3
- "version": "0.0.101",
3
+ "version": "0.0.103",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.js",
@@ -41,6 +41,7 @@
41
41
  "jsonwebtoken": "^9.0.0",
42
42
  "jwks-rsa": "^3.0.1",
43
43
  "lodash": "^4.17.21",
44
+ "node-cache": "^5.1.2",
44
45
  "node-match-path": "^0.6.3",
45
46
  "quidproquo-core": "*",
46
47
  "quidproquo-webserver": "*"