From b071f1fb3c88d8ff105f3bd9580a25f3c8f8c325 Mon Sep 17 00:00:00 2001 From: Warren Parad Date: Thu, 15 Feb 2024 12:44:20 +0100 Subject: [PATCH] add additional methods. --- .github/workflows/build.yml | 14 ++--- .nvmrc | 2 +- package.json | 2 +- src/dynamoDbSafe.js | 115 ++++++++++++++++++++++++++++++------ 4 files changed, 107 insertions(+), 26 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0d59d9a..4a74464 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,14 +10,14 @@ on: jobs: nodejs: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Node.js - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: - node-version: 12.22.0 + node-version: 16 registry-url: 'https://registry.npmjs.org' - name: Install packages @@ -27,18 +27,18 @@ jobs: - name: Test run: yarn lint && yarn validate-types && yarn test - name: Deploy to NPM - if: github.ref != 'refs/heads/main' && github.event_name == 'push' + if: github.repository_owner == 'Authress-Engineering' && github.ref != 'refs/heads/main' && github.ref != 'refs/heads/master' && github.event_name == 'push' run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} - name: After build - if: github.ref != 'refs/heads/main' && github.event_name == 'push' + if: github.repository_owner == 'Authress-Engineering' && github.ref != 'refs/heads/main' && github.ref != 'refs/heads/master' && github.event_name == 'push' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: node make.js after_build - name: Create Github Release and Tag - if: github.ref != 'refs/heads/main' && github.event_name == 'push' + if: github.repository_owner == 'Authress-Engineering' && github.ref != 'refs/heads/main' && github.ref != 'refs/heads/master' && github.event_name == 'push' run: | git tag ${GITHUB_REF/refs\/heads\/release\//}.$GITHUB_RUN_NUMBER git push origin ${GITHUB_REF/refs\/heads\/release\//}.$GITHUB_RUN_NUMBER diff --git a/.nvmrc b/.nvmrc index 3cacc0b..19c7bdb 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -12 \ No newline at end of file +16 \ No newline at end of file diff --git a/package.json b/package.json index 02a2ea5..fff3155 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,6 @@ }, "homepage": "https://rhosys.ch", "engines": { - "node": ">=12.22" + "node": ">=16" } } diff --git a/src/dynamoDbSafe.js b/src/dynamoDbSafe.js index 5eecce5..e94ea86 100644 --- a/src/dynamoDbSafe.js +++ b/src/dynamoDbSafe.js @@ -26,8 +26,6 @@ function parseExpression(expression, isMultiExpression) { }, 'InvalidExpression'); } - // TODO: merge together repeated actions since DDB doesn't accept "SET operand SET operand" - const setExpression = partialExpressions.find(e => e.match(/^SET/i)); if (setExpression) { // validate the set expression @@ -66,10 +64,104 @@ class DynamoDB extends DynamoDbOriginal.DocumentClient { this.logger = args && args.logger || (() => {}); } - // get - // query - // delete - // put + get(originalParams) { + if (!originalParams || !originalParams.TableName) { throw new DynamoDbError({ error: 'TableName not specified', parameters: originalParams }, 'InvalidParameters'); } + if (!originalParams.Key) { throw new DynamoDbError({ error: 'Key not specified', parameters: originalParams }, 'InvalidParameters'); } + + const params = originalParams; + const capturedStack = { name: 'DynamoDB.update() Error:' }; + Error.captureStackTrace(capturedStack); + const resultAsync = super.get(params).promise().catch(error => { + const wrappedError = new DynamoDbError({ message: error.message, method: 'Get', parameters: originalParams, dynamoDbStack: error.stack }, error.code); + wrappedError.stack = capturedStack; + throw wrappedError; + }); + resultAsync.promise = () => resultAsync; + // Prevent unhandled promise rejections + resultAsync.catch(() => {}); + return resultAsync; + } + + query(originalParams) { + if (!originalParams || !originalParams.TableName) { throw new DynamoDbError({ error: 'TableName not specified', parameters: originalParams }, 'InvalidParameters'); } + if (!originalParams.Key) { throw new DynamoDbError({ error: 'Key not specified', parameters: originalParams }, 'InvalidParameters'); } + + const params = originalParams; + const capturedStack = { name: 'DynamoDB.update() Error:' }; + Error.captureStackTrace(capturedStack); + const resultAsync = super.delete(params).promise().catch(error => { + const wrappedError = new DynamoDbError({ message: error.message, method: 'Query', parameters: originalParams, dynamoDbStack: error.stack }, error.code); + wrappedError.stack = capturedStack; + throw wrappedError; + }); + resultAsync.promise = () => resultAsync; + // Prevent unhandled promise rejections + resultAsync.catch(() => {}); + return resultAsync; + } + + delete(originalParams) { + if (!originalParams || !originalParams.TableName) { throw new DynamoDbError({ error: 'TableName not specified', parameters: originalParams }, 'InvalidParameters'); } + if (!originalParams.Key) { throw new DynamoDbError({ error: 'Key not specified', parameters: originalParams }, 'InvalidParameters'); } + + const conditionExpressionTokens = parseExpression(originalParams.ConditionExpression); + if (conditionExpressionTokens) { + // Validate the tokens + } + + const params = originalParams; + const capturedStack = { name: 'DynamoDB.update() Error:' }; + Error.captureStackTrace(capturedStack); + const resultAsync = super.delete(params).promise().catch(error => { + const wrappedError = new DynamoDbError({ message: error.message, method: 'Delete', parameters: originalParams, dynamoDbStack: error.stack }, error.code); + wrappedError.stack = capturedStack; + throw wrappedError; + }); + resultAsync.promise = () => resultAsync; + // Prevent unhandled promise rejections + resultAsync.catch(() => {}); + return resultAsync; + } + + put(originalParams) { + if (!originalParams || !originalParams.TableName) { throw new DynamoDbError({ error: 'TableName not specified', parameters: originalParams }, 'InvalidParameters'); } + if (!originalParams.Key) { throw new DynamoDbError({ error: 'Key not specified', parameters: originalParams }, 'InvalidParameters'); } + + const conditionExpressionTokens = parseExpression(originalParams.ConditionExpression); + if (conditionExpressionTokens) { + // Validate the tokens + } + + const params = originalParams; + const capturedStack = { name: 'DynamoDB.update() Error:' }; + Error.captureStackTrace(capturedStack); + const resultAsync = super.put(params).promise().catch(error => { + const wrappedError = new DynamoDbError({ message: error.message, method: 'Put', parameters: originalParams, dynamoDbStack: error.stack }, error.code); + wrappedError.stack = capturedStack; + throw wrappedError; + }); + resultAsync.promise = () => resultAsync; + // Prevent unhandled promise rejections + resultAsync.catch(() => {}); + return resultAsync; + } + + scan(originalParams) { + if (!originalParams || !originalParams.TableName) { throw new DynamoDbError({ error: 'TableName not specified', parameters: originalParams }, 'InvalidParameters'); } + + const params = originalParams; + const capturedStack = { name: 'DynamoDB.update() Error:' }; + Error.captureStackTrace(capturedStack); + const resultAsync = super.scan(params).promise().catch(error => { + const wrappedError = new DynamoDbError({ message: error.message, method: 'Scan', parameters: originalParams, dynamoDbStack: error.stack }, error.code); + wrappedError.stack = capturedStack; + throw wrappedError; + }); + resultAsync.promise = () => resultAsync; + // Prevent unhandled promise rejections + resultAsync.catch(() => {}); + return resultAsync; + } update(originalParams) { if (!originalParams || !originalParams.TableName) { throw new DynamoDbError({ error: 'TableName not specified', parameters: originalParams }, 'InvalidParameters'); } @@ -82,17 +174,6 @@ class DynamoDB extends DynamoDbOriginal.DocumentClient { if (updateExpressionTokens || conditionExpressionTokens) { // Validate the tokens } - - // query related - // const keyExpressionTokens = parseExpression(originalParams.KeyConditionExpression); - // const filterExpressionTokens = parseExpression(originalParams.FilterExpression); - // const matchingFilterExpressionKey = Object.keys(filterExpressionTokens.keys).some(filterKey => Object.keys(keyExpressionTokens.keys) - // .some(keyKey => originalParams.ExpressionAttributeNames[keyKey] === originalParams.ExpressionAttributeNames[filterKey])); - - // // TODO: convert this from a error generation to in memory filtering - // if (matchingFilterExpressionKey) { - // throw new DynamoDbError({ title: 'DynamoDB disallows having a FilterExpression contain ', key: matchingFilterExpressionKey, parameters: originalParams }, 'InvalidExpression'); - // } const params = originalParams; const capturedStack = { name: 'DynamoDB.update() Error:' };