diff --git a/contentlake-shared.code-workspace b/contentlake-shared.code-workspace index 1da94de..5a5563f 100644 --- a/contentlake-shared.code-workspace +++ b/contentlake-shared.code-workspace @@ -15,6 +15,9 @@ { "path": "packages/functions" }, + { + "path": "packages/queue-client" + }, { "path": "packages/request-handler" }, diff --git a/package-lock.json b/package-lock.json index 28dcf0f..b387d45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,6 +92,10 @@ "resolved": "packages/logger", "link": true }, + "node_modules/@adobe/contentlake-shared-queue-client": { + "resolved": "packages/queue-client", + "link": true + }, "node_modules/@adobe/contentlake-shared-request-handler": { "resolved": "packages/request-handler", "link": true @@ -168,8 +172,7 @@ }, "node_modules/@adobe/helix-universal": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@adobe/helix-universal/-/helix-universal-4.3.0.tgz", - "integrity": "sha512-f13i/cL82R/hGZ7Ibs7w2RCcITBJt55OQF5/lg0mQDhleALXYsrDlDeLCbnLb2naeYj9dyd1Xn3aoetG0ZjfZQ==", + "license": "Apache-2.0", "dependencies": { "@adobe/fetch": "4.0.13", "aws4": "1.12.0" @@ -2487,205 +2490,1013 @@ "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-sdk-sts": { - "version": "3.370.0", + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-sdk-sts": { + "version": "3.370.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-signing": "3.370.0", + "@aws-sdk/types": "3.370.0", + "@smithy/types": "^1.1.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-signing": { + "version": "3.370.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.370.0", + "@smithy/property-provider": "^1.0.1", + "@smithy/protocol-http": "^1.1.0", + "@smithy/signature-v4": "^1.0.1", + "@smithy/types": "^1.1.0", + "@smithy/util-middleware": "^1.0.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.370.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.370.0", + "@aws-sdk/util-endpoints": "3.370.0", + "@smithy/protocol-http": "^1.1.0", + "@smithy/types": "^1.1.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/token-providers": { + "version": "3.370.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso-oidc": "3.370.0", + "@aws-sdk/types": "3.370.0", + "@smithy/property-provider": "^1.0.1", + "@smithy/shared-ini-file-loader": "^1.0.1", + "@smithy/types": "^1.1.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/types": { + "version": "3.370.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^1.1.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-endpoints": { + "version": "3.370.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.370.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.370.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.370.0", + "@smithy/types": "^1.1.0", + "bowser": "^2.11.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.370.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.370.0", + "@smithy/node-config-provider": "^1.0.1", + "@smithy/types": "^1.1.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/client-secrets-manager": { + "version": "3.360.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.360.0", + "@aws-sdk/config-resolver": "3.357.0", + "@aws-sdk/credential-provider-node": "3.360.0", + "@aws-sdk/fetch-http-handler": "3.357.0", + "@aws-sdk/hash-node": "3.357.0", + "@aws-sdk/invalid-dependency": "3.357.0", + "@aws-sdk/middleware-content-length": "3.357.0", + "@aws-sdk/middleware-endpoint": "3.357.0", + "@aws-sdk/middleware-host-header": "3.357.0", + "@aws-sdk/middleware-logger": "3.357.0", + "@aws-sdk/middleware-recursion-detection": "3.357.0", + "@aws-sdk/middleware-retry": "3.357.0", + "@aws-sdk/middleware-serde": "3.357.0", + "@aws-sdk/middleware-signing": "3.357.0", + "@aws-sdk/middleware-stack": "3.357.0", + "@aws-sdk/middleware-user-agent": "3.357.0", + "@aws-sdk/node-config-provider": "3.357.0", + "@aws-sdk/node-http-handler": "3.360.0", + "@aws-sdk/smithy-client": "3.360.0", + "@aws-sdk/types": "3.357.0", + "@aws-sdk/url-parser": "3.357.0", + "@aws-sdk/util-base64": "3.310.0", + "@aws-sdk/util-body-length-browser": "3.310.0", + "@aws-sdk/util-body-length-node": "3.310.0", + "@aws-sdk/util-defaults-mode-browser": "3.360.0", + "@aws-sdk/util-defaults-mode-node": "3.360.0", + "@aws-sdk/util-endpoints": "3.357.0", + "@aws-sdk/util-retry": "3.357.0", + "@aws-sdk/util-user-agent-browser": "3.357.0", + "@aws-sdk/util-user-agent-node": "3.357.0", + "@aws-sdk/util-utf8": "3.310.0", + "@smithy/protocol-http": "^1.0.1", + "@smithy/types": "^1.0.0", + "tslib": "^2.5.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/client-sts": "3.391.0", + "@aws-sdk/credential-provider-node": "3.391.0", + "@aws-sdk/middleware-host-header": "3.391.0", + "@aws-sdk/middleware-logger": "3.391.0", + "@aws-sdk/middleware-recursion-detection": "3.391.0", + "@aws-sdk/middleware-sdk-sqs": "3.391.0", + "@aws-sdk/middleware-signing": "3.391.0", + "@aws-sdk/middleware-user-agent": "3.391.0", + "@aws-sdk/types": "3.391.0", + "@aws-sdk/util-endpoints": "3.391.0", + "@aws-sdk/util-user-agent-browser": "3.391.0", + "@aws-sdk/util-user-agent-node": "3.391.0", + "@smithy/config-resolver": "^2.0.3", + "@smithy/fetch-http-handler": "^2.0.3", + "@smithy/hash-node": "^2.0.3", + "@smithy/invalid-dependency": "^2.0.3", + "@smithy/md5-js": "^2.0.3", + "@smithy/middleware-content-length": "^2.0.3", + "@smithy/middleware-endpoint": "^2.0.3", + "@smithy/middleware-retry": "^2.0.3", + "@smithy/middleware-serde": "^2.0.3", + "@smithy/middleware-stack": "^2.0.0", + "@smithy/node-config-provider": "^2.0.3", + "@smithy/node-http-handler": "^2.0.3", + "@smithy/protocol-http": "^2.0.3", + "@smithy/smithy-client": "^2.0.3", + "@smithy/types": "^2.2.0", + "@smithy/url-parser": "^2.0.3", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.0.0", + "@smithy/util-defaults-mode-browser": "^2.0.3", + "@smithy/util-defaults-mode-node": "^2.0.3", + "@smithy/util-retry": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "fast-xml-parser": "4.2.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/client-sso": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/middleware-host-header": "3.391.0", + "@aws-sdk/middleware-logger": "3.391.0", + "@aws-sdk/middleware-recursion-detection": "3.391.0", + "@aws-sdk/middleware-user-agent": "3.391.0", + "@aws-sdk/types": "3.391.0", + "@aws-sdk/util-endpoints": "3.391.0", + "@aws-sdk/util-user-agent-browser": "3.391.0", + "@aws-sdk/util-user-agent-node": "3.391.0", + "@smithy/config-resolver": "^2.0.3", + "@smithy/fetch-http-handler": "^2.0.3", + "@smithy/hash-node": "^2.0.3", + "@smithy/invalid-dependency": "^2.0.3", + "@smithy/middleware-content-length": "^2.0.3", + "@smithy/middleware-endpoint": "^2.0.3", + "@smithy/middleware-retry": "^2.0.3", + "@smithy/middleware-serde": "^2.0.3", + "@smithy/middleware-stack": "^2.0.0", + "@smithy/node-config-provider": "^2.0.3", + "@smithy/node-http-handler": "^2.0.3", + "@smithy/protocol-http": "^2.0.3", + "@smithy/smithy-client": "^2.0.3", + "@smithy/types": "^2.2.0", + "@smithy/url-parser": "^2.0.3", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.0.0", + "@smithy/util-defaults-mode-browser": "^2.0.3", + "@smithy/util-defaults-mode-node": "^2.0.3", + "@smithy/util-retry": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/client-sts": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/credential-provider-node": "3.391.0", + "@aws-sdk/middleware-host-header": "3.391.0", + "@aws-sdk/middleware-logger": "3.391.0", + "@aws-sdk/middleware-recursion-detection": "3.391.0", + "@aws-sdk/middleware-sdk-sts": "3.391.0", + "@aws-sdk/middleware-signing": "3.391.0", + "@aws-sdk/middleware-user-agent": "3.391.0", + "@aws-sdk/types": "3.391.0", + "@aws-sdk/util-endpoints": "3.391.0", + "@aws-sdk/util-user-agent-browser": "3.391.0", + "@aws-sdk/util-user-agent-node": "3.391.0", + "@smithy/config-resolver": "^2.0.3", + "@smithy/fetch-http-handler": "^2.0.3", + "@smithy/hash-node": "^2.0.3", + "@smithy/invalid-dependency": "^2.0.3", + "@smithy/middleware-content-length": "^2.0.3", + "@smithy/middleware-endpoint": "^2.0.3", + "@smithy/middleware-retry": "^2.0.3", + "@smithy/middleware-serde": "^2.0.3", + "@smithy/middleware-stack": "^2.0.0", + "@smithy/node-config-provider": "^2.0.3", + "@smithy/node-http-handler": "^2.0.3", + "@smithy/protocol-http": "^2.0.3", + "@smithy/smithy-client": "^2.0.3", + "@smithy/types": "^2.2.0", + "@smithy/url-parser": "^2.0.3", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.0.0", + "@smithy/util-defaults-mode-browser": "^2.0.3", + "@smithy/util-defaults-mode-node": "^2.0.3", + "@smithy/util-retry": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "fast-xml-parser": "4.2.5", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-env": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.391.0", + "@aws-sdk/credential-provider-process": "3.391.0", + "@aws-sdk/credential-provider-sso": "3.391.0", + "@aws-sdk/credential-provider-web-identity": "3.391.0", + "@aws-sdk/types": "3.391.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.0", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.391.0", + "@aws-sdk/credential-provider-ini": "3.391.0", + "@aws-sdk/credential-provider-process": "3.391.0", + "@aws-sdk/credential-provider-sso": "3.391.0", + "@aws-sdk/credential-provider-web-identity": "3.391.0", + "@aws-sdk/types": "3.391.0", + "@smithy/credential-provider-imds": "^2.0.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.0", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-process": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.0", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.391.0", + "@aws-sdk/token-providers": "3.391.0", + "@aws-sdk/types": "3.391.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/shared-ini-file-loader": "^2.0.0", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/middleware-host-header": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "@smithy/protocol-http": "^2.0.3", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/middleware-logger": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "@smithy/protocol-http": "^2.0.3", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/middleware-sdk-sts": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-signing": "3.391.0", + "@aws-sdk/types": "3.391.0", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/middleware-signing": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^2.0.3", + "@smithy/signature-v4": "^2.0.0", + "@smithy/types": "^2.2.0", + "@smithy/util-middleware": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "@aws-sdk/util-endpoints": "3.391.0", + "@smithy/protocol-http": "^2.0.3", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/token-providers": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "3.0.0", + "@aws-crypto/sha256-js": "3.0.0", + "@aws-sdk/middleware-host-header": "3.391.0", + "@aws-sdk/middleware-logger": "3.391.0", + "@aws-sdk/middleware-recursion-detection": "3.391.0", + "@aws-sdk/middleware-user-agent": "3.391.0", + "@aws-sdk/types": "3.391.0", + "@aws-sdk/util-endpoints": "3.391.0", + "@aws-sdk/util-user-agent-browser": "3.391.0", + "@aws-sdk/util-user-agent-node": "3.391.0", + "@smithy/config-resolver": "^2.0.3", + "@smithy/fetch-http-handler": "^2.0.3", + "@smithy/hash-node": "^2.0.3", + "@smithy/invalid-dependency": "^2.0.3", + "@smithy/middleware-content-length": "^2.0.3", + "@smithy/middleware-endpoint": "^2.0.3", + "@smithy/middleware-retry": "^2.0.3", + "@smithy/middleware-serde": "^2.0.3", + "@smithy/middleware-stack": "^2.0.0", + "@smithy/node-config-provider": "^2.0.3", + "@smithy/node-http-handler": "^2.0.3", + "@smithy/property-provider": "^2.0.0", + "@smithy/protocol-http": "^2.0.3", + "@smithy/shared-ini-file-loader": "^2.0.0", + "@smithy/smithy-client": "^2.0.3", + "@smithy/types": "^2.2.0", + "@smithy/url-parser": "^2.0.3", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-body-length-browser": "^2.0.0", + "@smithy/util-body-length-node": "^2.0.0", + "@smithy/util-defaults-mode-browser": "^2.0.3", + "@smithy/util-defaults-mode-node": "^2.0.3", + "@smithy/util-retry": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/types": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/util-endpoints": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "@smithy/types": "^2.2.0", + "bowser": "^2.11.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.391.0", + "@smithy/node-config-provider": "^2.0.3", + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/abort-controller": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/config-resolver": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "@smithy/util-config-provider": "^2.0.0", + "@smithy/util-middleware": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/credential-provider-imds": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^2.0.4", + "@smithy/property-provider": "^2.0.4", + "@smithy/types": "^2.2.1", + "@smithy/url-parser": "^2.0.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/eventstream-codec": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "3.0.0", + "@smithy/types": "^2.2.1", + "@smithy/util-hex-encoding": "^2.0.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/fetch-http-handler": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^2.0.4", + "@smithy/querystring-builder": "^2.0.4", + "@smithy/types": "^2.2.1", + "@smithy/util-base64": "^2.0.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/hash-node": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "@smithy/util-buffer-from": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/invalid-dependency": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/is-array-buffer": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/md5-js": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/middleware-content-length": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^2.0.4", + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/middleware-endpoint": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-serde": "^2.0.4", + "@smithy/types": "^2.2.1", + "@smithy/url-parser": "^2.0.4", + "@smithy/util-middleware": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/middleware-retry": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^2.0.4", + "@smithy/service-error-classification": "^2.0.0", + "@smithy/types": "^2.2.1", + "@smithy/util-middleware": "^2.0.0", + "@smithy/util-retry": "^2.0.0", + "tslib": "^2.5.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/middleware-serde": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/middleware-stack": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/node-config-provider": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^2.0.4", + "@smithy/shared-ini-file-loader": "^2.0.4", + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/node-http-handler": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^2.0.4", + "@smithy/protocol-http": "^2.0.4", + "@smithy/querystring-builder": "^2.0.4", + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/property-provider": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/protocol-http": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/querystring-builder": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "@smithy/util-uri-escape": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/querystring-parser": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/service-error-classification": { + "version": "2.0.0", + "license": "Apache-2.0", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/shared-ini-file-loader": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/signature-v4": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^2.0.4", + "@smithy/is-array-buffer": "^2.0.0", + "@smithy/types": "^2.2.1", + "@smithy/util-hex-encoding": "^2.0.0", + "@smithy/util-middleware": "^2.0.0", + "@smithy/util-uri-escape": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/smithy-client": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-stack": "^2.0.0", + "@smithy/types": "^2.2.1", + "@smithy/util-stream": "^2.0.4", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/types": { + "version": "2.2.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/url-parser": { + "version": "2.0.4", + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^2.0.4", + "@smithy/types": "^2.2.1", + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-base64": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-body-length-browser": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-body-length-node": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-buffer-from": { + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-signing": "3.370.0", - "@aws-sdk/types": "3.370.0", - "@smithy/types": "^1.1.0", + "@smithy/is-array-buffer": "^2.0.0", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-signing": { - "version": "3.370.0", + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-config-provider": { + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.370.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/protocol-http": "^1.1.0", - "@smithy/signature-v4": "^1.0.1", - "@smithy/types": "^1.1.0", - "@smithy/util-middleware": "^1.0.1", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.370.0", + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-defaults-mode-browser": { + "version": "2.0.4", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.370.0", - "@aws-sdk/util-endpoints": "3.370.0", - "@smithy/protocol-http": "^1.1.0", - "@smithy/types": "^1.1.0", + "@smithy/property-provider": "^2.0.4", + "@smithy/types": "^2.2.1", + "bowser": "^2.11.0", "tslib": "^2.5.0" }, "engines": { - "node": ">=14.0.0" + "node": ">= 10.0.0" } }, - "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/token-providers": { - "version": "3.370.0", + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-defaults-mode-node": { + "version": "2.0.4", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso-oidc": "3.370.0", - "@aws-sdk/types": "3.370.0", - "@smithy/property-provider": "^1.0.1", - "@smithy/shared-ini-file-loader": "^1.0.1", - "@smithy/types": "^1.1.0", + "@smithy/config-resolver": "^2.0.4", + "@smithy/credential-provider-imds": "^2.0.4", + "@smithy/node-config-provider": "^2.0.4", + "@smithy/property-provider": "^2.0.4", + "@smithy/types": "^2.2.1", "tslib": "^2.5.0" }, "engines": { - "node": ">=14.0.0" + "node": ">= 10.0.0" } }, - "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/types": { - "version": "3.370.0", + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-hex-encoding": { + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^1.1.0", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-endpoints": { - "version": "3.370.0", + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-middleware": { + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.370.0", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.370.0", + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-retry": { + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.370.0", - "@smithy/types": "^1.1.0", - "bowser": "^2.11.0", + "@smithy/service-error-classification": "^2.0.0", "tslib": "^2.5.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@aws-sdk/client-s3/node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.370.0", + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-stream": { + "version": "2.0.4", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.370.0", - "@smithy/node-config-provider": "^1.0.1", - "@smithy/types": "^1.1.0", + "@smithy/fetch-http-handler": "^2.0.4", + "@smithy/node-http-handler": "^2.0.4", + "@smithy/types": "^2.2.1", + "@smithy/util-base64": "^2.0.0", + "@smithy/util-buffer-from": "^2.0.0", + "@smithy/util-hex-encoding": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } } }, - "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.360.0", + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-uri-escape": { + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.360.0", - "@aws-sdk/config-resolver": "3.357.0", - "@aws-sdk/credential-provider-node": "3.360.0", - "@aws-sdk/fetch-http-handler": "3.357.0", - "@aws-sdk/hash-node": "3.357.0", - "@aws-sdk/invalid-dependency": "3.357.0", - "@aws-sdk/middleware-content-length": "3.357.0", - "@aws-sdk/middleware-endpoint": "3.357.0", - "@aws-sdk/middleware-host-header": "3.357.0", - "@aws-sdk/middleware-logger": "3.357.0", - "@aws-sdk/middleware-recursion-detection": "3.357.0", - "@aws-sdk/middleware-retry": "3.357.0", - "@aws-sdk/middleware-serde": "3.357.0", - "@aws-sdk/middleware-signing": "3.357.0", - "@aws-sdk/middleware-stack": "3.357.0", - "@aws-sdk/middleware-user-agent": "3.357.0", - "@aws-sdk/node-config-provider": "3.357.0", - "@aws-sdk/node-http-handler": "3.360.0", - "@aws-sdk/smithy-client": "3.360.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/url-parser": "3.357.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.360.0", - "@aws-sdk/util-defaults-mode-node": "3.360.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@aws-sdk/util-retry": "3.357.0", - "@aws-sdk/util-user-agent-browser": "3.357.0", - "@aws-sdk/util-user-agent-node": "3.357.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "tslib": "^2.5.0", - "uuid": "^8.3.2" + "tslib": "^2.5.0" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/client-sqs": { - "version": "3.360.0", + "node_modules/@aws-sdk/client-sqs/node_modules/@smithy/util-utf8": { + "version": "2.0.0", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha256-browser": "3.0.0", - "@aws-crypto/sha256-js": "3.0.0", - "@aws-sdk/client-sts": "3.360.0", - "@aws-sdk/config-resolver": "3.357.0", - "@aws-sdk/credential-provider-node": "3.360.0", - "@aws-sdk/fetch-http-handler": "3.357.0", - "@aws-sdk/hash-node": "3.357.0", - "@aws-sdk/invalid-dependency": "3.357.0", - "@aws-sdk/md5-js": "3.357.0", - "@aws-sdk/middleware-content-length": "3.357.0", - "@aws-sdk/middleware-endpoint": "3.357.0", - "@aws-sdk/middleware-host-header": "3.357.0", - "@aws-sdk/middleware-logger": "3.357.0", - "@aws-sdk/middleware-recursion-detection": "3.357.0", - "@aws-sdk/middleware-retry": "3.357.0", - "@aws-sdk/middleware-sdk-sqs": "3.357.0", - "@aws-sdk/middleware-serde": "3.357.0", - "@aws-sdk/middleware-signing": "3.357.0", - "@aws-sdk/middleware-stack": "3.357.0", - "@aws-sdk/middleware-user-agent": "3.357.0", - "@aws-sdk/node-config-provider": "3.357.0", - "@aws-sdk/node-http-handler": "3.360.0", - "@aws-sdk/smithy-client": "3.360.0", - "@aws-sdk/types": "3.357.0", - "@aws-sdk/url-parser": "3.357.0", - "@aws-sdk/util-base64": "3.310.0", - "@aws-sdk/util-body-length-browser": "3.310.0", - "@aws-sdk/util-body-length-node": "3.310.0", - "@aws-sdk/util-defaults-mode-browser": "3.360.0", - "@aws-sdk/util-defaults-mode-node": "3.360.0", - "@aws-sdk/util-endpoints": "3.357.0", - "@aws-sdk/util-retry": "3.357.0", - "@aws-sdk/util-user-agent-browser": "3.357.0", - "@aws-sdk/util-user-agent-node": "3.357.0", - "@aws-sdk/util-utf8": "3.310.0", - "@smithy/protocol-http": "^1.0.1", - "@smithy/types": "^1.0.0", - "fast-xml-parser": "4.2.5", + "@smithy/util-buffer-from": "^2.0.0", "tslib": "^2.5.0" }, "engines": { @@ -3012,15 +3823,6 @@ "node": ">=14.0.0" } }, - "node_modules/@aws-sdk/md5-js": { - "version": "3.357.0", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-utf8": "3.310.0", - "tslib": "^2.5.0" - } - }, "node_modules/@aws-sdk/middleware-bucket-endpoint": { "version": "3.370.0", "license": "Apache-2.0", @@ -3271,12 +4073,76 @@ } }, "node_modules/@aws-sdk/middleware-sdk-sqs": { - "version": "3.357.0", + "version": "3.391.0", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.357.0", - "@aws-sdk/util-hex-encoding": "3.310.0", - "@aws-sdk/util-utf8": "3.310.0", + "@aws-sdk/types": "3.391.0", + "@smithy/types": "^2.2.0", + "@smithy/util-hex-encoding": "^2.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-sqs/node_modules/@aws-sdk/types": { + "version": "3.391.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^2.2.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-sqs/node_modules/@smithy/is-array-buffer": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-sqs/node_modules/@smithy/types": { + "version": "2.2.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-sqs/node_modules/@smithy/util-buffer-from": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.0.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-sqs/node_modules/@smithy/util-hex-encoding": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-sqs/node_modules/@smithy/util-utf8": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.0.0", "tslib": "^2.5.0" }, "engines": { @@ -4282,9 +5148,8 @@ }, "node_modules/@eslint/eslintrc": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -4305,9 +5170,8 @@ }, "node_modules/@eslint/eslintrc/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4321,15 +5185,13 @@ }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@eslint/js": { "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true, + "license": "MIT", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -7980,9 +8842,8 @@ }, "node_modules/acorn": { "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -7992,9 +8853,8 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -8276,9 +9136,8 @@ }, "node_modules/aws-sdk-client-mock": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aws-sdk-client-mock/-/aws-sdk-client-mock-3.0.0.tgz", - "integrity": "sha512-4mBiWhuLYLZe1+K/iB8eYy5SAZyW2se+Keyh5u9QouMt6/qJ5SRZhss68xvUX5g3ApzROJ06QPRziYHP6buuvQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/sinon": "^10.0.10", "sinon": "^14.0.2", @@ -9361,9 +10220,8 @@ }, "node_modules/eslint": { "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -9573,9 +10431,8 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -9605,9 +10462,8 @@ }, "node_modules/espree": { "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -10178,9 +11034,8 @@ }, "node_modules/globals": { "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -14234,9 +15089,8 @@ }, "node_modules/type-fest": { "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -14669,7 +15523,7 @@ }, "packages/blob-storage": { "name": "@adobe/contentlake-shared-blob-storage", - "version": "1.2.0", + "version": "1.2.1", "license": "Apache-2.0", "dependencies": { "@aws-sdk/client-s3": "^3.373.0", @@ -14680,19 +15534,6 @@ "dotenv": "^16.3.1" } }, - "packages/custom-secrets": { - "name": "@adobe/contentlake-shared-custom-secrets", - "version": "1.0.0", - "extraneous": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/client-secrets-manager": "^3.290.0" - }, - "devDependencies": { - "aws-sdk-client-mock": "^3.0.0", - "dotenv": "^16.3.1" - } - }, "packages/extractor-helpers": { "name": "@adobe/contentlake-shared-extractor-helpers", "version": "1.4.0", @@ -14746,6 +15587,19 @@ "@adobe/helix-shared-wrap": "^2.0.0" } }, + "packages/queue-client": { + "name": "@adobe/contentlake-shared-queue-client", + "version": "1.2.0", + "license": "Apache-2.0", + "dependencies": { + "@adobe/contentlake-shared-blob-storage": "^1.2.0", + "@aws-sdk/client-sqs": "^3.391.0" + }, + "devDependencies": { + "aws-sdk-client-mock": "^3.0.0", + "dotenv": "^16.3.1" + } + }, "packages/request-handler": { "name": "@adobe/contentlake-shared-request-handler", "version": "1.0.0", diff --git a/packages/queue-client/.nycrc.json b/packages/queue-client/.nycrc.json new file mode 100644 index 0000000..ecafcea --- /dev/null +++ b/packages/queue-client/.nycrc.json @@ -0,0 +1,11 @@ +{ + "reporter": [ + "lcov", + "text" + ], + "exclude": ["it/*", "test/*", "src/mock*", "scripts/*"], + "check-coverage": true, + "lines": 80, + "branches": 80, + "statements": 80 +} diff --git a/packages/queue-client/.prettierrc b/packages/queue-client/.prettierrc new file mode 100644 index 0000000..56d4876 --- /dev/null +++ b/packages/queue-client/.prettierrc @@ -0,0 +1,6 @@ +{ + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "trailingComma": "all" +} \ No newline at end of file diff --git a/packages/queue-client/LICENSE.txt b/packages/queue-client/LICENSE.txt new file mode 100644 index 0000000..883ab09 --- /dev/null +++ b/packages/queue-client/LICENSE.txt @@ -0,0 +1,264 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +APACHE JACKRABBIT SUBCOMPONENTS + +Apache Jackrabbit includes parts with separate copyright notices and license +terms. Your use of these subcomponents is subject to the terms and conditions +of the following licenses: + + XPath 2.0/XQuery 1.0 Parser: + http://www.w3.org/2002/11/xquery-xpath-applets/xgrammar.zip + + Copyright (C) 2002 World Wide Web Consortium, (Massachusetts Institute of + Technology, European Research Consortium for Informatics and Mathematics, + Keio University). All Rights Reserved. + + This work is distributed under the W3C(R) Software License in the hope + that it will be useful, but WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + W3C(R) SOFTWARE NOTICE AND LICENSE + http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + + This work (and included software, documentation such as READMEs, or + other related items) is being provided by the copyright holders under + the following license. By obtaining, using and/or copying this work, + you (the licensee) agree that you have read, understood, and will comply + with the following terms and conditions. + + Permission to copy, modify, and distribute this software and its + documentation, with or without modification, for any purpose and + without fee or royalty is hereby granted, provided that you include + the following on ALL copies of the software and documentation or + portions thereof, including modifications: + + 1. The full text of this NOTICE in a location viewable to users + of the redistributed or derivative work. + + 2. Any pre-existing intellectual property disclaimers, notices, + or terms and conditions. If none exist, the W3C Software Short + Notice should be included (hypertext is preferred, text is + permitted) within the body of any redistributed or derivative code. + + 3. Notice of any changes or modifications to the files, including + the date changes were made. (We recommend you provide URIs to the + location from which the code is derived.) + + THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT + HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS + FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR + DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, + TRADEMARKS OR OTHER RIGHTS. + + COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL + OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR + DOCUMENTATION. + + The name and trademarks of copyright holders may NOT be used in + advertising or publicity pertaining to the software without specific, + written prior permission. Title to copyright in this software and + any associated documentation will at all times remain with + copyright holders. diff --git a/packages/queue-client/README.md b/packages/queue-client/README.md new file mode 100644 index 0000000..3783633 --- /dev/null +++ b/packages/queue-client/README.md @@ -0,0 +1,26 @@ +# Content Lake Shared - Queue Client + +> Queue library for Asset Catalog + +This is one of the [Content Lake Shared](https://github.com/adobe/contentlake-shared) libraries. + +## Status + +[![GitHub license](https://img.shields.io/github/license/adobe/contentlake-shared.svg)](https://github.com/adobe/contentlake-shared/blob/main/LICENSE.txt) + +## Usage + +Install using: + +``` +npm install @adobe/contentlake-shared-queue-client +``` + +``` +import { QueueClient } from '@adobe/contentlake-shared-queue-client' + +const queueClient = new QueueClient({ + queueUrl: 'https://somequeue.com' +}); +await queueClient.sendMessage({ message: 'Hello World' }); +``` diff --git a/packages/queue-client/it/index.test.js b/packages/queue-client/it/index.test.js new file mode 100644 index 0000000..d4ccd42 --- /dev/null +++ b/packages/queue-client/it/index.test.js @@ -0,0 +1,141 @@ +/* + * Copyright 2023 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ + +/* eslint-env mocha */ +import assert from 'assert'; +import dotenv from 'dotenv'; +import { + PurgeQueueCommand, + ReceiveMessageCommand, + SendMessageCommand, +} from '@aws-sdk/client-sqs'; +import util from 'util'; +import { BlobStorage } from '@adobe/contentlake-shared-blob-storage'; +import { QueueClient } from '../src/index.js'; + +dotenv.config(); + +const sleep = util.promisify(setTimeout); + +const DEFAULT_CONFIG = { + log: console, + queueUrl: process.env.QUEUE_URL, +}; + +const SLOW_TEST_TIMEOUT = 5000; + +function generateLargeMessage() { + const message = []; + for (let i = 0; i < 4086; i += 1) { + message.push( + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse nec nisl massa. Morbi at erat elementum, dignissim quam at.', + ); + } + return message; +} + +describe('Queue Integration Tests', () => { + it('will use default logger', async () => { + const queueClient = new QueueClient({ + ...DEFAULT_CONFIG, + log: undefined, + }); + const id = await queueClient.sendMessage({ message: 'Hello World' }); + assert.ok(id); + }); + + describe('send message', () => { + it('can send message', async () => { + const queueClient = new QueueClient(DEFAULT_CONFIG); + const id = await queueClient.sendMessage({ message: 'Hello World' }); + assert.ok(id); + }); + + it('will fail with invalid queue', async () => { + const queueClient = new QueueClient({ + ...DEFAULT_CONFIG, + queueUrl: 'http://notaqueue.com', + }); + await assert.rejects(() => queueClient.sendMessage({ message: 'Hello World' })); + }); + + it('will fail on oversized message with no blob storage', async () => { + const queueClient = new QueueClient(DEFAULT_CONFIG); + await assert.rejects(() => queueClient.sendMessage(generateLargeMessage())); + }).timeout(SLOW_TEST_TIMEOUT); + + it('can send oversized message with blob storage', async () => { + const queueClient = new QueueClient({ + ...DEFAULT_CONFIG, + blobStorage: new BlobStorage({ + ...DEFAULT_CONFIG, + bucket: 'cl-commons-it-files', + }), + }); + const messageId = await queueClient.sendMessage(generateLargeMessage()); + assert.ok(messageId); + }).timeout(SLOW_TEST_TIMEOUT); + + after(async () => { + const queueClient = new QueueClient(DEFAULT_CONFIG); + await queueClient.client + .send( + new PurgeQueueCommand({ + QueueUrl: process.env.QUEUE_URL, + }), + ) + .catch(() => {}); + }); + }); + + describe('remove message', () => { + it('will fail on invalid recieptHandle', async () => { + const queueClient = new QueueClient(DEFAULT_CONFIG); + await assert.rejects(() => queueClient.removeMessage('notvalid')); + }); + + it('can remove message by recieptHandle', async () => { + const queueClient = new QueueClient(DEFAULT_CONFIG); + await queueClient.client.send( + new SendMessageCommand({ + QueueUrl: process.env.QUEUE_URL, + MessageBody: JSON.stringify({ message: 'Hello world' }), + }), + ); + await sleep(2000); + const messages = await queueClient.client.send( + new ReceiveMessageCommand({ + QueueUrl: process.env.QUEUE_URL, + }), + ); + const { ReceiptHandle } = messages.Messages[0]; + assert.ok(ReceiptHandle); + await queueClient.removeMessage(ReceiptHandle); + }).timeout(SLOW_TEST_TIMEOUT); + }); + + after(async () => { + const queueClient = new QueueClient(DEFAULT_CONFIG); + const messages = await queueClient.client.send( + new ReceiveMessageCommand({ + QueueUrl: process.env.QUEUE_URL, + }), + ); + Promise.all( + messages.Messages?.map(async (msg) => { + const { ReceiptHandle } = msg; + assert.ok(ReceiptHandle); + await queueClient.removeMessage(ReceiptHandle); + }), + ); + }); +}); diff --git a/packages/queue-client/package.json b/packages/queue-client/package.json new file mode 100644 index 0000000..c637de7 --- /dev/null +++ b/packages/queue-client/package.json @@ -0,0 +1,38 @@ +{ + "name": "@adobe/contentlake-shared-queue-client", + "version": "1.2.0", + "description": "Queue library for Asset Catalog", + "main": "src/index.js", + "type": "module", + "scripts": { + "test": "c8 mocha test", + "test:integration": "mocha it", + "lint": "eslint .", + "clean": "rm -rf package-lock.json node_modules" + }, + "mocha": { + "reporter": "mocha-multi-reporters", + "reporter-options": "configFile=../../.mocha-multi.json" + }, + "repository": { + "type": "git", + "url": "https://github.com/adobe/contentlake-shared" + }, + "author": "", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/adobe/contentlake-shared/issues" + }, + "homepage": "https://github.com/adobe/contentlake-shared/tree/main/packages/queue-client#readme", + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@adobe/contentlake-shared-blob-storage": "^1.2.0", + "@aws-sdk/client-sqs": "^3.391.0" + }, + "devDependencies": { + "aws-sdk-client-mock": "^3.0.0", + "dotenv": "^16.3.1" + } +} diff --git a/packages/queue-client/src/index.js b/packages/queue-client/src/index.js new file mode 100644 index 0000000..c9b0dbb --- /dev/null +++ b/packages/queue-client/src/index.js @@ -0,0 +1,209 @@ +/* + * Copyright 2023 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +import { + DeleteMessageCommand, + SQSClient, + SendMessageCommand, +} from '@aws-sdk/client-sqs'; +import { randomUUID } from 'crypto'; + +export * from './mock.js'; + +/** + * @typedef QueueConfig + * @property {import('@adobe/contentlake-shared-blob-storage').BlobStorage} [blobStorage] + * @property {SQSClient} [client] + * @property {*} [log] + * @property {string} queueUrl + */ + +/** + * @typedef {Object} QueueRecord + * @property {string} messageId + * @property {string} receiptHandle + * @property {string} body + * @property {Record} attributes + * @property {Record} messageAttributes + * @property {string} eventSource + */ + +const MAX_MESSAGE_LEN = 127000; // 127 KB + +export class QueueClient { + /** + * @type {import('@adobe/contentlake-shared-blob-storage').BlobStorage} + */ + #blobStorage; + + /** + * @type {SQSClient} + */ + client; + + #log; + + /** + * @type {string} + */ + #queueUrl; + + /** + * Check whether or not the context contains Records from a queue + * @param {import('@adobe/helix-universal').UniversalContext} context + * @returns {boolean} + */ + static isQueueRequest(context) { + return typeof context.invocation?.event?.Records !== 'undefined'; + } + + /** + * Gets the queue records from the context + * @param {import('@adobe/helix-universal').UniversalContext} context + * @returns {Array} the queue records + */ + static extractQueueRecords(context) { + return context.invocation?.event?.Records || []; + } + + /** + * @param {QueueConfig} config + */ + constructor(config) { + this.#log = config.log || console; + this.client = config.client || new SQSClient(); + this.#blobStorage = config.blobStorage; + this.#queueUrl = config.queueUrl; + } + + /** + * Serializes the specified message to a string, saving to blob storage + * if the message exceeds the max size + * @param {Object} message the message to serialize + * @returns {Promise} the message serialized as a string + */ + async #serializeMessage(message) { + const json = JSON.stringify(message); + const size = Buffer.byteLength(json); + if (size < MAX_MESSAGE_LEN) { + this.#log.debug('Message size is below max size, returning JSON', { + size, + }); + return json; + } else if (this.#blobStorage) { + const key = randomUUID(); + this.#log.debug( + 'Message size is above max size, saving to blob storage', + { + size, + key, + }, + ); + await this.#blobStorage.save(key, Buffer.from(json)); + return JSON.stringify({ blobStorage: true, key }); + } else { + this.#log.error( + 'Message size exceeds maximum and no blob storage provided', + { size }, + ); + throw new Error( + `Message size ${size} exceeds maximum and no blob storage provided`, + ); + } + } + + /** + * Reads the message, reading from blob storage if required + * @param {string} messageBody + * @returns {Promise} + */ + async readMessageBody(messageBody) { + const json = JSON.parse(messageBody); + if (!json.blobStorage) { + this.#log.debug('Message does not use blob storage'); + return json; + } else if (this.#blobStorage) { + const { key } = json; + this.#log.debug('Retrieving message from blob storage', { key }); + return JSON.parse(await this.#blobStorage.getString(key)); + } else { + throw new Error( + 'Message stored in blob storage, but no blob storage client provided', + ); + } + } + + /** + * Sends the specified message to the queue + * @param {Object} message the message to send + * @returns {Promise} the message id + */ + async sendMessage(message) { + try { + this.#log.debug('Enqueuing message', { + message, + queueUrl: this.#queueUrl, + }); + const messageBody = await this.#serializeMessage(message); + const res = await this.client.send( + new SendMessageCommand({ + QueueUrl: this.#queueUrl, + MessageBody: messageBody, + }), + ); + const { MessageId } = res; + this.#log.debug('Message enqueued successfully', { + message, + queueUrl: this.#queueUrl, + MessageId, + }); + return MessageId; + } catch (err) { + this.#log.error('Failed to queue message', { + err, + message, + queueUrl: this.#queueUrl, + }); + throw err; + } + } + + /** + * Removes a message by it's receipt handle + * @param {string} receiptHandle + */ + async removeMessage(receiptHandle) { + const queueUrl = this.#queueUrl; + try { + this.#log.debug('Removing message', { + receiptHandle, + queueUrl, + }); + await this.client.send( + new DeleteMessageCommand({ + QueueUrl: this.#queueUrl, + ReceiptHandle: receiptHandle, + }), + ); + this.#log.debug('Message removed successfully', { + receiptHandle, + queueUrl, + }); + } catch (err) { + this.#log.error('Failed to remove message', { + err, + receiptHandle, + queueUrl, + }); + throw err; + } + } +} diff --git a/packages/queue-client/src/mock.js b/packages/queue-client/src/mock.js new file mode 100644 index 0000000..e8097d2 --- /dev/null +++ b/packages/queue-client/src/mock.js @@ -0,0 +1,40 @@ +/* + * Copyright 2023 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +export class MockQueueClient { + messages = []; + + removed = []; + + async sendMessage(message) { + const id = this.messages.push(message); + return id.toString(); + } + + /** + * Reads the message, reading from blob storage if required + * @param {string} messageBody + * @returns {Promise} + */ + // eslint-disable-next-line class-methods-use-this + async readMessageBody(messageBody) { + return JSON.parse(messageBody); + } + + async removeMessage(receiptHandle) { + this.removed.push(receiptHandle); + } + + reset() { + this.messages = []; + this.removed = []; + } +} diff --git a/packages/queue-client/test/index.test.js b/packages/queue-client/test/index.test.js new file mode 100644 index 0000000..93c6073 --- /dev/null +++ b/packages/queue-client/test/index.test.js @@ -0,0 +1,239 @@ +/* + * Copyright 2023 Adobe. All rights reserved. + * This file is licensed to you under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under + * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + * OF ANY KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + */ +/* eslint-env mocha */ + +/* eslint-env mocha */ +import assert from 'assert'; +import { mockClient } from 'aws-sdk-client-mock'; +import { + DeleteMessageCommand, + SQSClient, + SendMessageCommand, +} from '@aws-sdk/client-sqs'; +import { QueueClient } from '../src/index.js'; + +const mockSqsClient = mockClient(SQSClient); + +const LARGE_MESSAGE = { + // generates a 128KB string by joining the alphabet 5120 times + msg: [...Array(5120)].map(() => 'abcdefghijklmnopqrstuvwxyz').join(''), +}; + +describe('QueueClient Unit Tests', () => { + afterEach(() => mockSqsClient.reset()); + + it('can get client', () => { + const client = new QueueClient({}); + assert.ok(client); + }); + + it('can send message', async () => { + mockSqsClient.on(SendMessageCommand).callsFake((input) => { + assert.deepStrictEqual(input, { + MessageBody: '{"message":"Hello World!"}', + QueueUrl: 'http://www.queue.com', + }); + return { + MessageId: 'test-id', + }; + }); + const client = new QueueClient({ + client: mockSqsClient, + queueUrl: 'http://www.queue.com', + }); + const resp = await client.sendMessage({ message: 'Hello World!' }); + assert.strictEqual(resp, 'test-id'); + }); + + it('throws on create message failure', async () => { + mockSqsClient.on(SendMessageCommand).rejects(); + const client = new QueueClient({ + client: mockSqsClient, + queueUrl: 'http://www.queue.com', + }); + let caught; + try { + await client.sendMessage({ message: 'Hello World!' }); + } catch (err) { + caught = err; + } + assert.ok(caught); + }); + + it('can remove message', async () => { + mockSqsClient.on(DeleteMessageCommand).callsFake((input) => { + assert.strictEqual(input.ReceiptHandle, 'test-handle'); + }); + const client = new QueueClient({ + client: mockSqsClient, + queueUrl: 'http://www.queue.com', + }); + await client.removeMessage('test-handle'); + }); + + it('remove handles throws', async () => { + mockSqsClient.on(DeleteMessageCommand).rejects(); + const client = new QueueClient({ + client: mockSqsClient, + queueUrl: 'http://www.queue.com', + }); + await assert.rejects(() => client.removeMessage('test-handle')); + }); + + it('fails on large message if no blob storage provided', async () => { + const client = new QueueClient({ + client: mockSqsClient, + queueUrl: 'http://www.queue.com', + }); + + await assert.rejects(() => client.sendMessage(LARGE_MESSAGE)); + }); + + it('can send large messages', async () => { + const blobs = {}; + const mockBlobStorage = { + save: (key, buf) => { + blobs[key] = buf.toString('utf-8'); + }, + }; + mockSqsClient.on(SendMessageCommand).callsFake((input) => { + const { blobStorage, key } = JSON.parse(input.MessageBody); + assert.strictEqual(blobStorage, true); + assert.strictEqual(blobs[key].message, LARGE_MESSAGE.message); + assert.ok(blobs[key]); + return { + MessageId: 'test-message-id', + }; + }); + + const client = new QueueClient({ + client: mockSqsClient, + queueUrl: 'http://www.queue.com', + blobStorage: mockBlobStorage, + }); + + const id = await client.sendMessage(LARGE_MESSAGE); + assert.strictEqual(id, 'test-message-id'); + }); + + it('can read large messages', async () => { + const blobs = { test: JSON.stringify(LARGE_MESSAGE) }; + const mockBlobStorage = { + getString: (key) => blobs[key], + }; + const client = new QueueClient({ + queueUrl: 'http://www.queue.com', + blobStorage: mockBlobStorage, + }); + + const messageBody = await client.readMessageBody( + JSON.stringify({ + blobStorage: true, + key: 'test', + }), + ); + assert.strictEqual(messageBody.message, LARGE_MESSAGE.message); + }); + + it('can read normal sized messages', async () => { + const client = new QueueClient({ + queueUrl: 'http://www.queue.com', + }); + + const messageBody = await client.readMessageBody( + JSON.stringify({ + message: 'Hello World!', + }), + ); + assert.strictEqual(messageBody.message, 'Hello World!'); + }); + + it('will fail to read large message if no blob storage provided', async () => { + const client = new QueueClient({ + client: mockSqsClient, + queueUrl: 'http://www.queue.com', + }); + + await assert.rejects(() => client.readMessageBody( + JSON.stringify({ + blobStorage: true, + key: 'test', + }), + )); + }); + + describe('isQueueRequest', () => { + it('will not fail if undefined', () => { + assert.ok(!QueueClient.isQueueRequest({})); + }); + + it('will not fail if not present', () => { + assert.ok( + !QueueClient.isQueueRequest({ + invocation: { event: {} }, + }), + ); + }); + + it('will return true on empty records array', () => { + assert.ok( + QueueClient.isQueueRequest({ + invocation: { + event: { + Records: [], + }, + }, + }), + ); + }); + }); + + describe('get sqs records', () => { + it('will not fail if not present', () => { + assert.ok(QueueClient.extractQueueRecords({})); + }); + + it('will extract records', () => { + const res = QueueClient.extractQueueRecords({ + invocation: { + event: { + Records: [ + { + messageId: 'af88e691-c3a6-4b46-b4d2-1c897b41b600', + receiptHandle: + 'AQEBJCLTpWgDm+oaeBAlSKWumzIoFRHeJglHCwWEfJANgc7GSWQBcYTiLPfbO1IuxAIkJagUIEkqgmszqnj2a7hLZjoIcv0AWCQfL0tmje/hhnDWYKdQmrUmfITdPDIg49XI+n+Ub/gKjXEy3VvunLsp0bxuF33OCsR8+N0Skff+U+zan+42GcHtn8lacm6ZQIF9msoFxszourA+zpJ/DJ1DTMlEpr9cSPxa6nsbg7JHOOwBzWknn7d3Zkimuo/J3shMyb+4fBYFRNpzXt9o9l8rfQpi9JZDwGIFRqDYFvpI0Emqv9ke1V2uBAJPiiGS0h1MIKO6dZZ/ejfWAR0Rug3zMEH9SEa6N+hT4gF5Pu2IN6WmcRhE4sh0jW/ImAAunuIo/OZ1FhNjqp+keK3AvBiPiQ==', + body: '{"message":"Hello World"}', + attributes: { + ApproximateReceiveCount: '1', + SentTimestamp: '1678764328689', + SenderId: 'AIDAXXYBVS2FJDJXJ56HK', + ApproximateFirstReceiveTimestamp: '1678764328690', + }, + messageAttributes: {}, + md5OfBody: 'd7e5fb40d1b43e304158449c3ecd6e5c', + eventSource: 'aws:sqs', + eventSourceARN: + 'arn:aws:sqs:us-east-1:532042585738:content-lake-it', + awsRegion: 'us-east-1', + }, + ], + }, + }, + }); + assert.strictEqual(res.length, 1); + assert.strictEqual( + res[0].messageId, + 'af88e691-c3a6-4b46-b4d2-1c897b41b600', + ); + }); + }); +});