From ed2bbe8506f4fc9a9fe91360f02be33b388b6bb3 Mon Sep 17 00:00:00 2001 From: Adam Brown Date: Fri, 30 Jan 2026 09:50:52 +0000 Subject: [PATCH 01/12] New: [AEA-6072] - Reduce auth session check timing (#1710) ## Summary - Routine Change - :sparkles: New Feature ### Details - Reduces the auth check timer from 5 to 1 min --------- Signed-off-by: Adam Brown --- .../cpt-ui/__tests__/AccessProvider.test.tsx | 47 ++++++++++++------ packages/cpt-ui/__tests__/LogoutPage.test.tsx | 3 +- .../cpt-ui/src/context/AccessProvider.tsx | 48 +++++++++++-------- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/packages/cpt-ui/__tests__/AccessProvider.test.tsx b/packages/cpt-ui/__tests__/AccessProvider.test.tsx index 9a4c4ede0c..f4b3dff230 100644 --- a/packages/cpt-ui/__tests__/AccessProvider.test.tsx +++ b/packages/cpt-ui/__tests__/AccessProvider.test.tsx @@ -307,10 +307,28 @@ describe("AccessProvider", () => { renderWithProvider() - expect(setIntervalSpy).toHaveBeenCalledWith(expect.any(Function), 300000) + expect(setIntervalSpy).toHaveBeenCalledWith(expect.any(Function), 60000) setIntervalSpy.mockRestore() }) + it("should check user info when component mounts", () => { + mockUpdateTrackerUserInfo.mockResolvedValue({error: null}) + + mockAuthHook.mockReturnValue({ + isSignedIn: true, + isSigningIn: false, + selectedRole: {name: "TestRole"}, + updateTrackerUserInfo: mockUpdateTrackerUserInfo + }) + mockLocationHook.mockReturnValue({pathname: "/search-by-prescription-id"}) + + renderWithProvider() + + expect(logger.debug).toHaveBeenCalledWith("On load user info check") + expect(logger.debug).toHaveBeenCalledWith("Refreshing user info") + expect(mockUpdateTrackerUserInfo).toHaveBeenCalledTimes(1) + }) + it("should clear interval on component unmount", () => { const clearIntervalSpy = jest.spyOn(globalThis, "clearInterval") @@ -346,7 +364,7 @@ describe("AccessProvider", () => { renderWithProvider() act(() => { - jest.advanceTimersByTime(300001) + jest.advanceTimersByTime(60001) }) expect(logger.debug).toHaveBeenCalledWith( @@ -368,7 +386,7 @@ describe("AccessProvider", () => { renderWithProvider() act(() => { - jest.advanceTimersByTime(300001) + jest.advanceTimersByTime(60001) }) expect(logger.debug).toHaveBeenCalledWith( @@ -390,11 +408,11 @@ describe("AccessProvider", () => { renderWithProvider() await act(async () => { - jest.advanceTimersByTime(300001) + jest.advanceTimersByTime(60001) }) - expect(logger.info).toHaveBeenCalledWith("Periodic user info check") - expect(logger.info).toHaveBeenCalledWith("Refreshing user info") + expect(logger.debug).toHaveBeenCalledWith("Periodic user info check") + expect(logger.debug).toHaveBeenCalledWith("Refreshing user info") expect(mockUpdateTrackerUserInfo).toHaveBeenCalled() }) @@ -413,7 +431,7 @@ describe("AccessProvider", () => { renderWithProvider() await act(async () => { - jest.advanceTimersByTime(300001) + jest.advanceTimersByTime(60001) }) expect(mockUpdateTrackerUserInfo).toHaveBeenCalled() @@ -433,7 +451,7 @@ describe("AccessProvider", () => { renderWithProvider() await act(async () => { - jest.advanceTimersByTime(300001) + jest.advanceTimersByTime(60001) }) expect(logger.debug).toHaveBeenCalledWith("Not checking user info") @@ -452,7 +470,7 @@ describe("AccessProvider", () => { renderWithProvider() await act(async () => { - jest.advanceTimersByTime(300001) + jest.advanceTimersByTime(60001) }) // Should call updateTrackerUserInfo when not on restricted paths @@ -461,8 +479,9 @@ describe("AccessProvider", () => { it("should continue running interval after error occurs", async () => { mockUpdateTrackerUserInfo - .mockResolvedValueOnce({error: "First error", invalidSessionCause: "InvalidSession"}) - .mockResolvedValueOnce({error: null}) + .mockResolvedValueOnce({error: null}) // on load check + .mockResolvedValueOnce({error: "First error", invalidSessionCause: "InvalidSession"}) // first periodic check + .mockResolvedValueOnce({error: null}) // second periodic check const authContext = { isSignedIn: true, @@ -477,17 +496,17 @@ describe("AccessProvider", () => { // First interval execution - should error and navigate await act(async () => { - jest.advanceTimersByTime(300001) + jest.advanceTimersByTime(60001) }) expect(handleRestartLogin).toHaveBeenCalledWith(authContext, "InvalidSession") - expect(mockUpdateTrackerUserInfo).toHaveBeenCalledTimes(1) + expect(mockUpdateTrackerUserInfo).toHaveBeenCalledTimes(2) jest.clearAllMocks() // Second interval execution - should succeed await act(async () => { - jest.advanceTimersByTime(300001) + jest.advanceTimersByTime(60001) }) expect(mockUpdateTrackerUserInfo).toHaveBeenCalledTimes(1) diff --git a/packages/cpt-ui/__tests__/LogoutPage.test.tsx b/packages/cpt-ui/__tests__/LogoutPage.test.tsx index fa0fe04880..dabf2a3e8c 100644 --- a/packages/cpt-ui/__tests__/LogoutPage.test.tsx +++ b/packages/cpt-ui/__tests__/LogoutPage.test.tsx @@ -46,7 +46,8 @@ jest.mock("@/helpers/utils", () => ({ // Mock logger jest.mock("@/helpers/logger", () => ({ logger: { - info: jest.fn() + info: jest.fn(), + debug: jest.fn() } })) diff --git a/packages/cpt-ui/src/context/AccessProvider.tsx b/packages/cpt-ui/src/context/AccessProvider.tsx index 64db3b1262..2281647f88 100644 --- a/packages/cpt-ui/src/context/AccessProvider.tsx +++ b/packages/cpt-ui/src/context/AccessProvider.tsx @@ -92,6 +92,26 @@ export const AccessProvider = ({children}: { children: ReactNode }) => { } } + const checkUserInfo = () => { + // Check if a user is signed in, if it fails sign the user out. + if (auth.isSigningIn === true || ALLOWED_NO_ROLE_PATHS.includes(location.pathname)) { + logger.debug("Not checking user info") + return + } + + if (auth.isSignedIn) { + logger.debug("Refreshing user info") + auth.updateTrackerUserInfo().then((response) => { + if (response.error) { + logger.debug("Restarting login") + handleRestartLogin(auth, response.invalidSessionCause) + } + }) + } + + return + } + useEffect(() => { const currentPath = location.pathname const onSelectYourRole = currentPath === FRONTEND_PATHS.SELECT_YOUR_ROLE @@ -109,27 +129,17 @@ export const AccessProvider = ({children}: { children: ReactNode }) => { ]) useEffect(() => { - // If user is signedIn, every 5 minutes call tracker user info. If it fails, sign the user out. - const internalId = setInterval(() => { - const currentPath = location.pathname + // Check if user is logged in on page load. + logger.debug("On load user info check") + checkUserInfo() - if (auth.isSigningIn === true || ALLOWED_NO_ROLE_PATHS.includes(currentPath)) { - logger.debug("Not checking user info") - return - } - - logger.info("Periodic user info check") - if (auth.isSignedIn) { - logger.info("Refreshing user info") - auth.updateTrackerUserInfo().then((response) => { - if (response.error) { - handleRestartLogin(auth, response.invalidSessionCause) - } - }) - } - }, 300000) // 300000 ms = 5 minutes + // Then check every minute + const interval = setInterval(() => { + logger.debug("Periodic user info check") + checkUserInfo() + }, 60000) // 60000 ms = 1 minute - return () => clearInterval(internalId) + return () => clearInterval(interval) }, [auth.isSignedIn, auth.isSigningIn, location.pathname]) if (shouldBlockChildren()) { From 3dbd34332ff6fe56d8f2d717debb6cbdedd89f53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 21:26:51 +0000 Subject: [PATCH 02/12] Upgrade: [dependabot] - bump @aws-sdk/client-lambda from 3.975.0 to 3.978.0 (#1744) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@aws-sdk/client-lambda](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-lambda) from 3.975.0 to 3.978.0.
Release notes

Sourced from @​aws-sdk/client-lambda's releases.

v3.978.0

3.978.0(2026-01-28)

Chores
  • codegen:
New Features
  • client-s3-control: Adds support for the UpdateObjectEncryption API to change the server-side encryption type of objects in general purpose buckets. (8248439e)
  • client-mediaconvert: This release adds a follow source mode for audio output channel count, an AES audio frame wrapping option for MXF outputs, and an option to signal DolbyVision compatibility using the SUPPLEMENTAL-CODECS tag in HLS manifests. (9ee45457)
  • client-cognito-identity-provider: This release adds support for a new lambda trigger to transform federated user attributes during the authentication with external identity providers on Cognito Managed Login. (a291daef)
  • client-connect: Adds support for filtering search results based on tags assigned to contacts. (c3e7a41b)
  • client-ec2: SearchTransitGatewayRoutes API response now includes a NextToken field, enabling pagination when retrieving large sets of transit gateway routes. Pass the returned NextToken value in subsequent requests to retrieve the next page of results. (11fdee1e)
  • client-mediaconnect: This release adds support for NDI flow sources in AWS Elemental MediaConnect. You can now send content to your MediaConnect transport streams directly from your NDI environment using the new NDI source type. Also adds support for LARGE 4X flow size, which can be used when creating CDI JPEG-XS flows. (a5e075c8)
  • client-s3: Adds support for the UpdateObjectEncryption API to change the server-side encryption type of objects in general purpose buckets. (b56cea55)
  • client-lambda: We are launching ESM Metrics and logging for Kafka ESM to allow customers to monitor Kafka event processing using CloudWatch Metrics and Logs. (af7d3d55)
Tests
  • client-s3: add test for aggregate client paginator/waiter methods (#7687) (75ba48bc)

For list of updated packages, view updated-packages.md in assets-3.978.0.zip

v3.977.0

3.977.0(2026-01-27)

Chores
New Features
  • clients: update client endpoints as of 2026-01-27 (04a9ab71)
  • client-ec2: Releasing new EC2 instances. C8gb and M8gb with highest EBS performance, M8gn with 600 Gbps network bandwidth, X8aedz and M8azn with 5GHz AMD processors, X8i with Intel Xeon 6 processors and up to 6TB memory, and Mac-m4max with Apple M4 Max chip for 25 percent faster builds. (8c83ff92)
  • client-connect: Added support for task attachments. The StartTaskContact API now accepts file attachments, enabling customers to include files (.csv, .doc, .docx, .heic, .jfif, .jpeg, .jpg, .mov, .mp4, .pdf, .png, .ppt, .pptx, .rtf, .txt, etc.) when creating Task contacts. Supports up to 5 attachments per task. (12e1a94a)
  • client-medialive: AWS Elemental MediaLive released two new features that allows customers 1) to set Output Timecode for AV1 encoder, 2) to set a Custom Epoch for CMAF Ingest and MediaPackage V2 output groups when using Pipeline Locking or Disabled Locking modes. (58a0492c)
  • client-deadline: AWS Deadline Cloud now supports editing job names and descriptions after submission. (fd6d1d4b)
  • client-sagemaker: Idle resource sharing enables teams to borrow unused compute resources in your SageMaker HyperPod cluster. This capability maximizes resource utilization by allowing teams to borrow idle compute capacity beyond their allocated compute quotas. (3f52b92b)

For list of updated packages, view updated-packages.md in assets-3.977.0.zip

... (truncated)

Changelog

Sourced from @​aws-sdk/client-lambda's changelog.

3.978.0 (2026-01-28)

Features

  • client-lambda: We are launching ESM Metrics and logging for Kafka ESM to allow customers to monitor Kafka event processing using CloudWatch Metrics and Logs. (af7d3d5)
Commits
  • a1794f7 Publish v3.978.0
  • af7d3d5 feat(client-lambda): We are launching ESM Metrics and logging for Kafka ESM t...
  • 024c073 chore(codegen): update for aggregated paginators and waiters (#7685)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@aws-sdk/client-lambda&package-manager=npm_and_yarn&previous-version=3.975.0&new-version=3.978.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 92 +++++++------------ .../prescriptionDetailsLambda/package.json | 2 +- 2 files changed, 32 insertions(+), 62 deletions(-) diff --git a/package-lock.json b/package-lock.json index a1422f11b8..540d56fffb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -222,7 +222,6 @@ "resolved": "https://registry.npmjs.org/@aws-amplify/core/-/core-6.16.0.tgz", "integrity": "sha512-YpEtvdXcC06/j3PEsQiN/AYiJh3yLK5aPijFY1SbE0rgSLt9iPPalCOh65vDjybe7SW8qdIlctcR/rROMA88ag==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/types": "3.723.0", @@ -1620,26 +1619,26 @@ "license": "MIT" }, "node_modules/@aws-sdk/client-lambda": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.975.0.tgz", - "integrity": "sha512-55+/Ku+fd1HY3TVKep/4GqgiR65p09/Xfgebknx8mqy18lTohO/8VFn7AusoZGOVypfRv3yVuYktCvINBBrkKw==", + "version": "3.978.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.978.0.tgz", + "integrity": "sha512-R3XJh7r0m7iimku6IgDJ6mS/s2CUJVA1oicIf9/YVudEVkU3drOV3MZpzBHJwmBvBXVM8jDOA7qkfDmgVHHJSA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/credential-provider-node": "^3.972.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", + "@aws-sdk/core": "^3.973.4", + "@aws-sdk/credential-provider-node": "^3.972.2", + "@aws-sdk/middleware-host-header": "^3.972.2", + "@aws-sdk/middleware-logger": "^3.972.2", + "@aws-sdk/middleware-recursion-detection": "^3.972.2", + "@aws-sdk/middleware-user-agent": "^3.972.4", + "@aws-sdk/region-config-resolver": "^3.972.2", + "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", + "@aws-sdk/util-user-agent-browser": "^3.972.2", + "@aws-sdk/util-user-agent-node": "^3.972.2", "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", + "@smithy/core": "^3.22.0", "@smithy/eventstream-serde-browser": "^4.2.8", "@smithy/eventstream-serde-config-resolver": "^4.3.8", "@smithy/eventstream-serde-node": "^4.2.8", @@ -1647,21 +1646,21 @@ "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", + "@smithy/middleware-endpoint": "^4.4.12", + "@smithy/middleware-retry": "^4.4.29", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", + "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.26", - "@smithy/util-defaults-mode-node": "^4.2.29", + "@smithy/util-defaults-mode-browser": "^4.3.28", + "@smithy/util-defaults-mode-node": "^4.2.31", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", @@ -2326,7 +2325,6 @@ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.723.0.tgz", "integrity": "sha512-9IH90m4bnHogBctVna2FnXaIGVORncfdxcqeEIovOxjIJJyHDmEAtA7B91dAM4sruddTbVzOYnqfPVst3odCbA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -2838,7 +2836,6 @@ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.723.0.tgz", "integrity": "sha512-YyN8x4MI/jMb4LpHsLf+VYqvbColMK8aZeGWVk2fTFsmt8lpTYGaGC1yybSwGX42mZ4W8ucu8SAYSbUraJZEjA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -3306,19 +3303,19 @@ "license": "MIT" }, "node_modules/@aws-sdk/core": { - "version": "3.973.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.3.tgz", - "integrity": "sha512-ZbM2Xy8ytAcfnNpkBltr6Qdw36W/4NW5nZdZieCuTfacoBFpi/NYiwb8U05KNJvLKeZnrV9Vi696i+r2DQFORg==", + "version": "3.973.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.4.tgz", + "integrity": "sha512-8Rk+kPP74YiR47x54bxYlKZswsaSh0a4XvvRUMLvyS/koNawhsGu/+qSZxREqUeTO+GkKpFvSQIsAZR+deUP+g==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.1", "@aws-sdk/xml-builder": "^3.972.2", - "@smithy/core": "^3.21.1", + "@smithy/core": "^3.22.0", "@smithy/node-config-provider": "^4.3.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", "@smithy/signature-v4": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", + "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.8", @@ -3965,15 +3962,15 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.3.tgz", - "integrity": "sha512-zq6aTiO/BiAIOA8EH8nB+wYvvnZ14Md9Gomm5DDhParshVEVglAyNPO5ADK4ZXFQbftIoO+Vgcvf4gewW/+iYQ==", + "version": "3.972.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.4.tgz", + "integrity": "sha512-6sU8jrSJvY/lqSnU6IYsa8SrCKwOZ4Enl6O4xVJo8RCq9Bdr5Giuw2eUaJAk9GPcpr4OFcmSFv3JOLhpKGeRZA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", + "@aws-sdk/core": "^3.973.4", "@aws-sdk/types": "^3.973.1", "@aws-sdk/util-endpoints": "3.972.0", - "@smithy/core": "^3.21.1", + "@smithy/core": "^3.22.0", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" @@ -4483,7 +4480,6 @@ "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", @@ -5122,7 +5118,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -5146,7 +5141,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } @@ -8705,7 +8699,6 @@ "dev": true, "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" @@ -8949,7 +8942,6 @@ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -9273,7 +9265,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -9291,7 +9282,6 @@ "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -9303,7 +9293,6 @@ "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/react": "*" } @@ -9414,7 +9403,6 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -9919,7 +9907,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -10943,7 +10930,6 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz", "integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==", "license": "MIT", - "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", @@ -11171,7 +11157,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -11580,8 +11565,7 @@ "version": "10.4.5", "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.5.tgz", "integrity": "sha512-fOoP70YLevMZr5avJHx2DU3LNYmC6wM8OwdrNewMZou1kZnPGOeVzBrRjZNgFDHUlulYUjkpFRSpTE3D+n+ZSg==", - "license": "Apache-2.0", - "peer": true + "license": "Apache-2.0" }, "node_modules/conventional-changelog-eslint": { "version": "6.0.0", @@ -12267,7 +12251,6 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -12328,7 +12311,6 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", - "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -14217,7 +14199,6 @@ "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "30.2.0", "@jest/types": "30.2.0", @@ -14921,7 +14902,6 @@ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", @@ -15837,7 +15817,6 @@ "resolved": "https://registry.npmjs.org/nhsuk-frontend/-/nhsuk-frontend-9.6.4.tgz", "integrity": "sha512-y0fi91jhgS1whD7jhNXKbpJ2Lmje/h5qBZ0aXmBbZdNo56805u7SsPJYxq7Uw6ffT86zQzQIxEwPwrjgSm5Whg==", "license": "MIT", - "peer": true, "workspaces": [ "." ], @@ -15850,7 +15829,6 @@ "resolved": "https://registry.npmjs.org/nhsuk-react-components/-/nhsuk-react-components-5.0.0.tgz", "integrity": "sha512-9QbYNEgLXdFaaEbrGs3IR9Gfn3M0a/6VH8a8fjPLWofl9FaP9HArpXh+eKz6D5YzUP6SmA0+0M8b84stJyBqdQ==", "license": "MIT", - "peer": true, "dependencies": { "classnames": "^2.2.6" }, @@ -16798,7 +16776,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -16811,7 +16788,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", - "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -17291,7 +17267,6 @@ "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "chokidar": "^4.0.0", "immutable": "^5.0.2", @@ -18223,7 +18198,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -18412,7 +18386,6 @@ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -18587,7 +18560,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -18865,7 +18837,6 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -18959,7 +18930,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -19760,7 +19730,7 @@ "@aws-lambda-powertools/logger": "^2.30.1", "@aws-lambda-powertools/parameters": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.956.0", - "@aws-sdk/client-lambda": "^3.975.0", + "@aws-sdk/client-lambda": "^3.978.0", "@aws-sdk/client-secrets-manager": "^3.975.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", diff --git a/packages/prescriptionDetailsLambda/package.json b/packages/prescriptionDetailsLambda/package.json index 4267abbd47..9998533c63 100644 --- a/packages/prescriptionDetailsLambda/package.json +++ b/packages/prescriptionDetailsLambda/package.json @@ -17,7 +17,7 @@ "@aws-lambda-powertools/logger": "^2.30.1", "@aws-lambda-powertools/parameters": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.956.0", - "@aws-sdk/client-lambda": "^3.975.0", + "@aws-sdk/client-lambda": "^3.978.0", "@aws-sdk/client-secrets-manager": "^3.975.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", From 2325e1c7e7dd495a1678eae9c8aef7e36bf643f7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 22:15:27 +0000 Subject: [PATCH 03/12] Upgrade: [dependabot] - bump @aws-sdk/client-dynamodb from 3.975.0 to 3.978.0 (#1737) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@aws-sdk/client-dynamodb](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-dynamodb) from 3.975.0 to 3.978.0.
Release notes

Sourced from @​aws-sdk/client-dynamodb's releases.

v3.978.0

3.978.0(2026-01-28)

Chores
  • codegen:
New Features
  • client-s3-control: Adds support for the UpdateObjectEncryption API to change the server-side encryption type of objects in general purpose buckets. (8248439e)
  • client-mediaconvert: This release adds a follow source mode for audio output channel count, an AES audio frame wrapping option for MXF outputs, and an option to signal DolbyVision compatibility using the SUPPLEMENTAL-CODECS tag in HLS manifests. (9ee45457)
  • client-cognito-identity-provider: This release adds support for a new lambda trigger to transform federated user attributes during the authentication with external identity providers on Cognito Managed Login. (a291daef)
  • client-connect: Adds support for filtering search results based on tags assigned to contacts. (c3e7a41b)
  • client-ec2: SearchTransitGatewayRoutes API response now includes a NextToken field, enabling pagination when retrieving large sets of transit gateway routes. Pass the returned NextToken value in subsequent requests to retrieve the next page of results. (11fdee1e)
  • client-mediaconnect: This release adds support for NDI flow sources in AWS Elemental MediaConnect. You can now send content to your MediaConnect transport streams directly from your NDI environment using the new NDI source type. Also adds support for LARGE 4X flow size, which can be used when creating CDI JPEG-XS flows. (a5e075c8)
  • client-s3: Adds support for the UpdateObjectEncryption API to change the server-side encryption type of objects in general purpose buckets. (b56cea55)
  • client-lambda: We are launching ESM Metrics and logging for Kafka ESM to allow customers to monitor Kafka event processing using CloudWatch Metrics and Logs. (af7d3d55)
Tests
  • client-s3: add test for aggregate client paginator/waiter methods (#7687) (75ba48bc)

For list of updated packages, view updated-packages.md in assets-3.978.0.zip

v3.977.0

3.977.0(2026-01-27)

Chores
New Features
  • clients: update client endpoints as of 2026-01-27 (04a9ab71)
  • client-ec2: Releasing new EC2 instances. C8gb and M8gb with highest EBS performance, M8gn with 600 Gbps network bandwidth, X8aedz and M8azn with 5GHz AMD processors, X8i with Intel Xeon 6 processors and up to 6TB memory, and Mac-m4max with Apple M4 Max chip for 25 percent faster builds. (8c83ff92)
  • client-connect: Added support for task attachments. The StartTaskContact API now accepts file attachments, enabling customers to include files (.csv, .doc, .docx, .heic, .jfif, .jpeg, .jpg, .mov, .mp4, .pdf, .png, .ppt, .pptx, .rtf, .txt, etc.) when creating Task contacts. Supports up to 5 attachments per task. (12e1a94a)
  • client-medialive: AWS Elemental MediaLive released two new features that allows customers 1) to set Output Timecode for AV1 encoder, 2) to set a Custom Epoch for CMAF Ingest and MediaPackage V2 output groups when using Pipeline Locking or Disabled Locking modes. (58a0492c)
  • client-deadline: AWS Deadline Cloud now supports editing job names and descriptions after submission. (fd6d1d4b)
  • client-sagemaker: Idle resource sharing enables teams to borrow unused compute resources in your SageMaker HyperPod cluster. This capability maximizes resource utilization by allowing teams to borrow idle compute capacity beyond their allocated compute quotas. (3f52b92b)

For list of updated packages, view updated-packages.md in assets-3.977.0.zip

... (truncated)

Changelog

Sourced from @​aws-sdk/client-dynamodb's changelog.

3.978.0 (2026-01-28)

Note: Version bump only for package @​aws-sdk/client-dynamodb

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@aws-sdk/client-dynamodb&package-manager=npm_and_yarn&previous-version=3.975.0&new-version=3.978.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 420 ++++++++++-------- packages/CIS2SignOutLambda/package.json | 2 +- packages/cognito/package.json | 2 +- packages/common/authFunctions/package.json | 2 +- packages/patientSearchLambda/package.json | 2 +- .../prescriptionDetailsLambda/package.json | 2 +- packages/prescriptionListLambda/package.json | 2 +- packages/selectedRoleLambda/package.json | 2 +- .../clearActiveSessions/package.json | 2 +- packages/trackerUserInfoLambda/package.json | 2 +- 10 files changed, 251 insertions(+), 187 deletions(-) diff --git a/package-lock.json b/package-lock.json index 540d56fffb..5b5b7da7b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -580,47 +580,47 @@ } }, "node_modules/@aws-sdk/client-dynamodb": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.975.0.tgz", - "integrity": "sha512-Cq6oGb8XswG56YhF2kHmxuyEnMNayDpL8xDxp9E4zIUqDeSLCKE6lCaqZzo5zpngzqLluFsJbCC9jrMzZejMAA==", + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.980.0.tgz", + "integrity": "sha512-1rGhAx4cHZy3pMB3R3r84qMT5WEvQ6ajr2UksnD48fjQxwaUcpI6NsPvU5j/5BI5LqGiUO6ThOrMwSMm95twQA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/credential-provider-node": "^3.972.1", - "@aws-sdk/dynamodb-codec": "^3.972.2", - "@aws-sdk/middleware-endpoint-discovery": "^3.972.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", + "@aws-sdk/core": "^3.973.5", + "@aws-sdk/credential-provider-node": "^3.972.4", + "@aws-sdk/dynamodb-codec": "^3.972.5", + "@aws-sdk/middleware-endpoint-discovery": "^3.972.3", + "@aws-sdk/middleware-host-header": "^3.972.3", + "@aws-sdk/middleware-logger": "^3.972.3", + "@aws-sdk/middleware-recursion-detection": "^3.972.3", + "@aws-sdk/middleware-user-agent": "^3.972.5", + "@aws-sdk/region-config-resolver": "^3.972.3", + "@aws-sdk/types": "^3.973.1", + "@aws-sdk/util-endpoints": "3.980.0", + "@aws-sdk/util-user-agent-browser": "^3.972.3", + "@aws-sdk/util-user-agent-node": "^3.972.3", "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", + "@smithy/core": "^3.22.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", + "@smithy/middleware-endpoint": "^4.4.12", + "@smithy/middleware-retry": "^4.4.29", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", + "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.26", - "@smithy/util-defaults-mode-node": "^4.2.29", + "@smithy/util-defaults-mode-browser": "^4.3.28", + "@smithy/util-defaults-mode-node": "^4.2.31", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", @@ -645,6 +645,22 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/client-dynamodb/node_modules/@aws-sdk/util-endpoints": { + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.980.0.tgz", + "integrity": "sha512-AjKBNEc+rjOZQE1HwcD9aCELqg1GmUj1rtICKuY8cgwB73xJ4U/kNyqKKpN2k9emGqlfDY2D8itIp/vDc6OKpw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.1", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/client-dynamodb/node_modules/@smithy/types": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", @@ -2272,44 +2288,44 @@ } }, "node_modules/@aws-sdk/client-sso": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.975.0.tgz", - "integrity": "sha512-HpgJuleH7P6uILxzJKQOmlHdwaCY+xYC6VgRDzlwVEqU/HXjo4m2gOAyjUbpXlBOCWfGgMUzfBlNJ9z3MboqEQ==", + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.980.0.tgz", + "integrity": "sha512-AhNXQaJ46C1I+lQ+6Kj+L24il5K9lqqIanJd8lMszPmP7bLnmX0wTKK0dxywcvrLdij3zhWttjAKEBNgLtS8/A==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", + "@aws-sdk/core": "^3.973.5", + "@aws-sdk/middleware-host-header": "^3.972.3", + "@aws-sdk/middleware-logger": "^3.972.3", + "@aws-sdk/middleware-recursion-detection": "^3.972.3", + "@aws-sdk/middleware-user-agent": "^3.972.5", + "@aws-sdk/region-config-resolver": "^3.972.3", + "@aws-sdk/types": "^3.973.1", + "@aws-sdk/util-endpoints": "3.980.0", + "@aws-sdk/util-user-agent-browser": "^3.972.3", + "@aws-sdk/util-user-agent-node": "^3.972.3", "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", + "@smithy/core": "^3.22.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", + "@smithy/middleware-endpoint": "^4.4.12", + "@smithy/middleware-retry": "^4.4.29", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", + "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.26", - "@smithy/util-defaults-mode-node": "^4.2.29", + "@smithy/util-defaults-mode-browser": "^4.3.28", + "@smithy/util-defaults-mode-node": "^4.2.31", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", @@ -2806,6 +2822,22 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/client-sso/node_modules/@aws-sdk/util-endpoints": { + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.980.0.tgz", + "integrity": "sha512-AjKBNEc+rjOZQE1HwcD9aCELqg1GmUj1rtICKuY8cgwB73xJ4U/kNyqKKpN2k9emGqlfDY2D8itIp/vDc6OKpw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.1", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/client-sso/node_modules/@smithy/types": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", @@ -3303,9 +3335,9 @@ "license": "MIT" }, "node_modules/@aws-sdk/core": { - "version": "3.973.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.4.tgz", - "integrity": "sha512-8Rk+kPP74YiR47x54bxYlKZswsaSh0a4XvvRUMLvyS/koNawhsGu/+qSZxREqUeTO+GkKpFvSQIsAZR+deUP+g==", + "version": "3.973.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.5.tgz", + "integrity": "sha512-IMM7xGfLGW6lMvubsA4j6BHU5FPgGAxoQ/NA63KqNLMwTS+PeMBcx8DPHL12Vg6yqOZnqok9Mu4H2BdQyq7gSA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.1", @@ -3365,12 +3397,12 @@ } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.2.tgz", - "integrity": "sha512-wzH1EdrZsytG1xN9UHaK12J9+kfrnd2+c8y0LVoS4O4laEjPoie1qVK3k8/rZe7KOtvULzyMnO3FT4Krr9Z0Dg==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.3.tgz", + "integrity": "sha512-OBYNY4xQPq7Rx+oOhtyuyO0AQvdJSpXRg7JuPNBJH4a1XXIzJQl4UHQTPKZKwfJXmYLpv4+OkcFen4LYmDPd3g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", + "@aws-sdk/core": "^3.973.5", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/types": "^4.12.0", @@ -3406,18 +3438,18 @@ } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.3.tgz", - "integrity": "sha512-IbBGWhaxiEl64fznwh5PDEB0N7YJEAvK5b6nRtPVUKdKAHlOPgo6B9XB8mqWDs8Ct0oF/E34ZLiq2U0L5xDkrg==", + "version": "3.972.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.5.tgz", + "integrity": "sha512-GpvBgEmSZPvlDekd26Zi+XsI27Qz7y0utUx0g2fSTSiDzhnd1FSa1owuodxR0BcUKNL7U2cOVhhDxgZ4iSoPVg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", + "@aws-sdk/core": "^3.973.5", "@aws-sdk/types": "^3.973.1", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/node-http-handler": "^4.4.8", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", + "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "@smithy/util-stream": "^4.5.10", "tslib": "^2.6.2" @@ -3452,19 +3484,19 @@ } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.2.tgz", - "integrity": "sha512-Jrb8sLm6k8+L7520irBrvCtdLxNtrG7arIxe9TCeMJt/HxqMGJdbIjw8wILzkEHLMIi4MecF2FbXCln7OT1Tag==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/credential-provider-env": "^3.972.2", - "@aws-sdk/credential-provider-http": "^3.972.3", - "@aws-sdk/credential-provider-login": "^3.972.2", - "@aws-sdk/credential-provider-process": "^3.972.2", - "@aws-sdk/credential-provider-sso": "^3.972.2", - "@aws-sdk/credential-provider-web-identity": "^3.972.2", - "@aws-sdk/nested-clients": "3.975.0", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.3.tgz", + "integrity": "sha512-rMQAIxstP7cLgYfsRGrGOlpyMl0l8JL2mcke3dsIPLWke05zKOFyR7yoJzWCsI/QiIxjRbxpvPiAeKEA6CoYkg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.5", + "@aws-sdk/credential-provider-env": "^3.972.3", + "@aws-sdk/credential-provider-http": "^3.972.5", + "@aws-sdk/credential-provider-login": "^3.972.3", + "@aws-sdk/credential-provider-process": "^3.972.3", + "@aws-sdk/credential-provider-sso": "^3.972.3", + "@aws-sdk/credential-provider-web-identity": "^3.972.3", + "@aws-sdk/nested-clients": "3.980.0", "@aws-sdk/types": "^3.973.1", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", @@ -3502,13 +3534,13 @@ } }, "node_modules/@aws-sdk/credential-provider-login": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.2.tgz", - "integrity": "sha512-mlaw2aiI3DrimW85ZMn3g7qrtHueidS58IGytZ+mbFpsYLK5wMjCAKZQtt7VatLMtSBG/dn/EY4njbnYXIDKeQ==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.3.tgz", + "integrity": "sha512-Gc3O91iVvA47kp2CLIXOwuo5ffo1cIpmmyIewcYjAcvurdFHQ8YdcBe1KHidnbbBO4/ZtywGBACsAX5vr3UdoA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/nested-clients": "3.975.0", + "@aws-sdk/core": "^3.973.5", + "@aws-sdk/nested-clients": "3.980.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/protocol-http": "^5.3.8", @@ -3546,17 +3578,17 @@ } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.2.tgz", - "integrity": "sha512-Lz1J5IZdTjLYTVIcDP5DVDgi1xlgsF3p1cnvmbfKbjCRhQpftN2e2J4NFfRRvPD54W9+bZ8l5VipPXtTYK7aEg==", + "version": "3.972.4", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.4.tgz", + "integrity": "sha512-UwerdzosMSY7V5oIZm3NsMDZPv2aSVzSkZxYxIOWHBeKTZlUqW7XpHtJMZ4PZpJ+HMRhgP+MDGQx4THndgqJfQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "^3.972.2", - "@aws-sdk/credential-provider-http": "^3.972.3", - "@aws-sdk/credential-provider-ini": "^3.972.2", - "@aws-sdk/credential-provider-process": "^3.972.2", - "@aws-sdk/credential-provider-sso": "^3.972.2", - "@aws-sdk/credential-provider-web-identity": "^3.972.2", + "@aws-sdk/credential-provider-env": "^3.972.3", + "@aws-sdk/credential-provider-http": "^3.972.5", + "@aws-sdk/credential-provider-ini": "^3.972.3", + "@aws-sdk/credential-provider-process": "^3.972.3", + "@aws-sdk/credential-provider-sso": "^3.972.3", + "@aws-sdk/credential-provider-web-identity": "^3.972.3", "@aws-sdk/types": "^3.973.1", "@smithy/credential-provider-imds": "^4.2.8", "@smithy/property-provider": "^4.2.8", @@ -3594,12 +3626,12 @@ } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.2.tgz", - "integrity": "sha512-NLKLTT7jnUe9GpQAVkPTJO+cs2FjlQDt5fArIYS7h/Iw/CvamzgGYGFRVD2SE05nOHCMwafUSi42If8esGFV+g==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.3.tgz", + "integrity": "sha512-xkSY7zjRqeVc6TXK2xr3z1bTLm0wD8cj3lAkproRGaO4Ku7dPlKy843YKnHrUOUzOnMezdZ4xtmFc0eKIDTo2w==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", + "@aws-sdk/core": "^3.973.5", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", @@ -3636,14 +3668,14 @@ } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.2.tgz", - "integrity": "sha512-YpwDn8g3gCGUl61cCV0sRxP2pFIwg+ZsMfWQ/GalSyjXtRkctCMFA+u0yPb/Q4uTfNEiya1Y4nm0C5rIHyPW5Q==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.3.tgz", + "integrity": "sha512-8Ww3F5Ngk8dZ6JPL/V5LhCU1BwMfQd3tLdoEuzaewX8FdnT633tPr+KTHySz9FK7fFPcz5qG3R5edVEhWQD4AA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.975.0", - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/token-providers": "3.975.0", + "@aws-sdk/client-sso": "3.980.0", + "@aws-sdk/core": "^3.973.5", + "@aws-sdk/token-providers": "3.980.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", @@ -3680,13 +3712,13 @@ } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.2.tgz", - "integrity": "sha512-x9DAiN9Qz+NjJ99ltDiVQ8d511M/tuF/9MFbe2jUgo7HZhD6+x4S3iT1YcP07ndwDUjmzKGmeOEgE24k4qvfdg==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.3.tgz", + "integrity": "sha512-62VufdcH5rRfiRKZRcf1wVbbt/1jAntMj1+J0qAd+r5pQRg2t0/P9/Rz16B1o5/0Se9lVL506LRjrhIJAhYBfA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@aws-sdk/nested-clients": "3.975.0", + "@aws-sdk/core": "^3.973.5", + "@aws-sdk/nested-clients": "3.980.0", "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", @@ -3723,14 +3755,14 @@ } }, "node_modules/@aws-sdk/dynamodb-codec": { - "version": "3.972.3", - "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.972.3.tgz", - "integrity": "sha512-ZkCxaFHN/v30ZLU/F/lok7yNNVwavaAM8IwDVmCAnCvb4bNIueCw40w5iI8DNGMmnRPa+mfp+rM1LIYVSjuMDQ==", + "version": "3.972.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/dynamodb-codec/-/dynamodb-codec-3.972.5.tgz", + "integrity": "sha512-gFR4w3dIkaZ82kFFjil7RFtukS2y2fXrDNDfgc94DhKjjOQMJEcHM5o1GGaQE4jd2mOQfHvbeQ0ktU8xGXhHjQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.2", - "@smithy/core": "^3.21.1", - "@smithy/smithy-client": "^4.10.12", + "@aws-sdk/core": "^3.973.5", + "@smithy/core": "^3.22.0", + "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" @@ -3739,7 +3771,7 @@ "node": ">=20.0.0" }, "peerDependencies": { - "@aws-sdk/client-dynamodb": "3.975.0" + "@aws-sdk/client-dynamodb": "3.980.0" } }, "node_modules/@aws-sdk/dynamodb-codec/node_modules/@smithy/types": { @@ -3787,6 +3819,21 @@ "@aws-sdk/client-dynamodb": "3.975.0" } }, + "node_modules/@aws-sdk/lib-dynamodb/node_modules/@aws-sdk/util-dynamodb": { + "version": "3.975.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.975.0.tgz", + "integrity": "sha512-ZsziF8m5Syn+kA2YJLEG2kk6zfxea8yRl/7SkSFpAls8RFYkt8EUmVUMBhX2hBpGw+nbZL7+AcRi4S2LxAcYWA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-dynamodb": "3.975.0" + } + }, "node_modules/@aws-sdk/lib-dynamodb/node_modules/@smithy/types": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", @@ -3800,9 +3847,9 @@ } }, "node_modules/@aws-sdk/middleware-endpoint-discovery": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.2.tgz", - "integrity": "sha512-Pzz/j7wiKibTHVfPDhqjdlhL+GqP/Nsd6mbeG56uc8BsmZGHBrz5TrwLAQXE1mWBliiEDs9fsh0W62CsX/Qy1g==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-endpoint-discovery/-/middleware-endpoint-discovery-3.972.3.tgz", + "integrity": "sha512-xAxA8/TOygQmMrzcw9CrlpTHCGWSG/lvzrHCySfSZpDN4/yVSfXO+gUwW9WxeskBmuv9IIFATOVpzc9EzfTZ0Q==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/endpoint-cache": "^3.972.2", @@ -3842,9 +3889,9 @@ } }, "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.2.tgz", - "integrity": "sha512-42hZ8jEXT2uR6YybCzNq9OomqHPw43YIfRfz17biZjMQA4jKSQUaHIl6VvqO2Ddl5904pXg2Yd/ku78S0Ikgog==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.3.tgz", + "integrity": "sha512-aknPTb2M+G3s+0qLCx4Li/qGZH8IIYjugHMv15JTYMe6mgZO8VBpYgeGYsNMGCqCZOcWzuf900jFBG5bopfzmA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.1", @@ -3882,9 +3929,9 @@ } }, "node_modules/@aws-sdk/middleware-logger": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.2.tgz", - "integrity": "sha512-iUzdXKOgi4JVDDEG/VvoNw50FryRCEm0qAudw12DcZoiNJWl0rN6SYVLcL1xwugMfQncCXieK5UBlG6mhH7iYA==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.3.tgz", + "integrity": "sha512-Ftg09xNNRqaz9QNzlfdQWfpqMCJbsQdnZVJP55jfhbKi1+FTWxGuvfPoBhDHIovqWKjqbuiew3HuhxbJ0+OjgA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.1", @@ -3921,9 +3968,9 @@ } }, "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.2.tgz", - "integrity": "sha512-/mzlyzJDtngNFd/rAYvqx29a2d0VuiYKN84Y/Mu9mGw7cfMOCyRK+896tb9wV6MoPRHUX7IXuKCIL8nzz2Pz5A==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.3.tgz", + "integrity": "sha512-PY57QhzNuXHnwbJgbWYTrqIDHYSeOlhfYERTAuc16LKZpTZRJUjzBFokp9hF7u1fuGeE3D70ERXzdbMBOqQz7Q==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.1", @@ -3962,14 +4009,14 @@ } }, "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.972.4", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.4.tgz", - "integrity": "sha512-6sU8jrSJvY/lqSnU6IYsa8SrCKwOZ4Enl6O4xVJo8RCq9Bdr5Giuw2eUaJAk9GPcpr4OFcmSFv3JOLhpKGeRZA==", + "version": "3.972.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.5.tgz", + "integrity": "sha512-TVZQ6PWPwQbahUI8V+Er+gS41ctIawcI/uMNmQtQ7RMcg3JYn6gyKAFKUb3HFYx2OjYlx1u11sETSwwEUxVHTg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.4", + "@aws-sdk/core": "^3.973.5", "@aws-sdk/types": "^3.973.1", - "@aws-sdk/util-endpoints": "3.972.0", + "@aws-sdk/util-endpoints": "3.980.0", "@smithy/core": "^3.22.0", "@smithy/protocol-http": "^5.3.8", "@smithy/types": "^4.12.0", @@ -3992,6 +4039,22 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/middleware-user-agent/node_modules/@aws-sdk/util-endpoints": { + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.980.0.tgz", + "integrity": "sha512-AjKBNEc+rjOZQE1HwcD9aCELqg1GmUj1rtICKuY8cgwB73xJ4U/kNyqKKpN2k9emGqlfDY2D8itIp/vDc6OKpw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.1", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/middleware-user-agent/node_modules/@smithy/types": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", @@ -4005,44 +4068,44 @@ } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.975.0.tgz", - "integrity": "sha512-OkeFHPlQj2c/Y5bQGkX14pxhDWUGUFt3LRHhjcDKsSCw6lrxKcxN3WFZN0qbJwKNydP+knL5nxvfgKiCLpTLRA==", + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.980.0.tgz", + "integrity": "sha512-/dONY5xc5/CCKzOqHZCTidtAR4lJXWkGefXvTRKdSKMGaYbbKsxDckisd6GfnvPSLxWtvQzwgRGRutMRoYUApQ==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", + "@aws-sdk/core": "^3.973.5", + "@aws-sdk/middleware-host-header": "^3.972.3", + "@aws-sdk/middleware-logger": "^3.972.3", + "@aws-sdk/middleware-recursion-detection": "^3.972.3", + "@aws-sdk/middleware-user-agent": "^3.972.5", + "@aws-sdk/region-config-resolver": "^3.972.3", + "@aws-sdk/types": "^3.973.1", + "@aws-sdk/util-endpoints": "3.980.0", + "@aws-sdk/util-user-agent-browser": "^3.972.3", + "@aws-sdk/util-user-agent-node": "^3.972.3", "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", + "@smithy/core": "^3.22.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", + "@smithy/middleware-endpoint": "^4.4.12", + "@smithy/middleware-retry": "^4.4.29", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", + "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.26", - "@smithy/util-defaults-mode-node": "^4.2.29", + "@smithy/util-defaults-mode-browser": "^4.3.28", + "@smithy/util-defaults-mode-node": "^4.2.31", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", @@ -4066,6 +4129,22 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/nested-clients/node_modules/@aws-sdk/util-endpoints": { + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.980.0.tgz", + "integrity": "sha512-AjKBNEc+rjOZQE1HwcD9aCELqg1GmUj1rtICKuY8cgwB73xJ4U/kNyqKKpN2k9emGqlfDY2D8itIp/vDc6OKpw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.1", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/nested-clients/node_modules/@smithy/types": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", @@ -4131,9 +4210,9 @@ } }, "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.2.tgz", - "integrity": "sha512-/7vRBsfmiOlg2X67EdKrzzQGw5/SbkXb7ALHQmlQLkZh8qNgvS2G2dDC6NtF3hzFlpP3j2k+KIEtql/6VrI6JA==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.3.tgz", + "integrity": "sha512-v4J8qYAWfOMcZ4MJUyatntOicTzEMaU7j3OpkRCGGFSL2NgXQ5VbxauIyORA+pxdKZ0qQG2tCQjQjZDlXEC3Ow==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.1", @@ -4172,14 +4251,14 @@ } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.975.0.tgz", - "integrity": "sha512-AWQt64hkVbDQ+CmM09wnvSk2mVyH4iRROkmYkr3/lmUtFNbE2L/fnw26sckZnUcFCsHPqbkQrcsZAnTcBLbH4w==", + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.980.0.tgz", + "integrity": "sha512-1nFileg1wAgDmieRoj9dOawgr2hhlh7xdvcH57b1NnqfPaVlcqVJyPc6k3TLDUFPY69eEwNxdGue/0wIz58vjA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/nested-clients": "3.975.0", - "@aws-sdk/types": "^3.973.0", + "@aws-sdk/core": "^3.973.5", + "@aws-sdk/nested-clients": "3.980.0", + "@aws-sdk/types": "^3.973.1", "@smithy/property-provider": "^4.2.8", "@smithy/shared-ini-file-loader": "^4.4.3", "@smithy/types": "^4.12.0", @@ -4239,21 +4318,6 @@ "node": ">=18.0.0" } }, - "node_modules/@aws-sdk/util-dynamodb": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.975.0.tgz", - "integrity": "sha512-ZsziF8m5Syn+kA2YJLEG2kk6zfxea8yRl/7SkSFpAls8RFYkt8EUmVUMBhX2hBpGw+nbZL7+AcRi4S2LxAcYWA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-dynamodb": "3.975.0" - } - }, "node_modules/@aws-sdk/util-endpoints": { "version": "3.972.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.972.0.tgz", @@ -4320,9 +4384,9 @@ } }, "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.2.tgz", - "integrity": "sha512-gz76bUyebPZRxIsBHJUd/v+yiyFzm9adHbr8NykP2nm+z/rFyvQneOHajrUejtmnc5tTBeaDPL4X25TnagRk4A==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.3.tgz", + "integrity": "sha512-JurOwkRUcXD/5MTDBcqdyQ9eVedtAsZgw5rBwktsPTN7QtPiS2Ld1jkJepNgYoCufz1Wcut9iup7GJDoIHp8Fw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.1", @@ -4357,12 +4421,12 @@ } }, "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.972.2", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.2.tgz", - "integrity": "sha512-vnxOc4C6AR7hVbwyFo1YuH0GB6dgJlWt8nIOOJpnzJAWJPkUMPJ9Zv2lnKsSU7TTZbhP2hEO8OZ4PYH59XFv8Q==", + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.972.3.tgz", + "integrity": "sha512-gqG+02/lXQtO0j3US6EVnxtwwoXQC5l2qkhLCrqUrqdtcQxV7FDMbm9wLjKqoronSHyELGTjbFKK/xV5q1bZNA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-user-agent": "^3.972.3", + "@aws-sdk/middleware-user-agent": "^3.972.5", "@aws-sdk/types": "^3.973.1", "@smithy/node-config-provider": "^4.3.8", "@smithy/types": "^4.12.0", @@ -19485,7 +19549,7 @@ "license": "MIT", "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", @@ -19518,7 +19582,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-lambda-powertools/parameters": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", @@ -19552,7 +19616,7 @@ "jwks-rsa": "^3.2.2" }, "devDependencies": { - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "axios": "^1.13.2", "mock-jwks": "3.2.2" } @@ -19704,7 +19768,7 @@ "license": "MIT", "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", @@ -19729,7 +19793,7 @@ "@aws-lambda-powertools/commons": "^2.30.0", "@aws-lambda-powertools/logger": "^2.30.1", "@aws-lambda-powertools/parameters": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/client-lambda": "^3.978.0", "@aws-sdk/client-secrets-manager": "^3.975.0", "@aws-sdk/lib-dynamodb": "^3.975.0", @@ -19759,7 +19823,7 @@ "license": "MIT", "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", @@ -19784,7 +19848,7 @@ "license": "MIT", "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", @@ -19820,7 +19884,7 @@ "license": "MIT", "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", @@ -19842,7 +19906,7 @@ "license": "MIT", "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", diff --git a/packages/CIS2SignOutLambda/package.json b/packages/CIS2SignOutLambda/package.json index 887531f868..aa88bf92ab 100644 --- a/packages/CIS2SignOutLambda/package.json +++ b/packages/CIS2SignOutLambda/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", diff --git a/packages/cognito/package.json b/packages/cognito/package.json index a7103ef3b8..b7327fbded 100644 --- a/packages/cognito/package.json +++ b/packages/cognito/package.json @@ -15,7 +15,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-lambda-powertools/parameters": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", diff --git a/packages/common/authFunctions/package.json b/packages/common/authFunctions/package.json index ac98fe7a67..57e1cedc5d 100644 --- a/packages/common/authFunctions/package.json +++ b/packages/common/authFunctions/package.json @@ -13,7 +13,7 @@ "check-licenses": "license-checker --failOn GPL --failOn LGPL --start ../.." }, "devDependencies": { - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "axios": "^1.13.2", "mock-jwks": "3.2.2" }, diff --git a/packages/patientSearchLambda/package.json b/packages/patientSearchLambda/package.json index b5a774d164..d75898c039 100644 --- a/packages/patientSearchLambda/package.json +++ b/packages/patientSearchLambda/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", diff --git a/packages/prescriptionDetailsLambda/package.json b/packages/prescriptionDetailsLambda/package.json index 9998533c63..122cf6838e 100644 --- a/packages/prescriptionDetailsLambda/package.json +++ b/packages/prescriptionDetailsLambda/package.json @@ -16,7 +16,7 @@ "@aws-lambda-powertools/commons": "^2.30.0", "@aws-lambda-powertools/logger": "^2.30.1", "@aws-lambda-powertools/parameters": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/client-lambda": "^3.978.0", "@aws-sdk/client-secrets-manager": "^3.975.0", "@aws-sdk/lib-dynamodb": "^3.975.0", diff --git a/packages/prescriptionListLambda/package.json b/packages/prescriptionListLambda/package.json index 0a46dd7904..ab14e82aa0 100644 --- a/packages/prescriptionListLambda/package.json +++ b/packages/prescriptionListLambda/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", diff --git a/packages/selectedRoleLambda/package.json b/packages/selectedRoleLambda/package.json index f86f0a6a8a..fdb7f9838b 100644 --- a/packages/selectedRoleLambda/package.json +++ b/packages/selectedRoleLambda/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", diff --git a/packages/testingSupport/clearActiveSessions/package.json b/packages/testingSupport/clearActiveSessions/package.json index be684eb41b..f107cec525 100644 --- a/packages/testingSupport/clearActiveSessions/package.json +++ b/packages/testingSupport/clearActiveSessions/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", diff --git a/packages/trackerUserInfoLambda/package.json b/packages/trackerUserInfoLambda/package.json index 4b5b691263..f5c36ba756 100644 --- a/packages/trackerUserInfoLambda/package.json +++ b/packages/trackerUserInfoLambda/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/client-dynamodb": "^3.956.0", + "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", From 11dccd1e36099349048260816675bece3cc68ba4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 Jan 2026 08:40:48 +0000 Subject: [PATCH 04/12] Upgrade: [dependabot] - bump @aws-sdk/client-secrets-manager from 3.975.0 to 3.978.0 (#1741) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@aws-sdk/client-secrets-manager](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-secrets-manager) from 3.975.0 to 3.978.0.
Release notes

Sourced from @​aws-sdk/client-secrets-manager's releases.

v3.978.0

3.978.0(2026-01-28)

Chores
  • codegen:
New Features
  • client-s3-control: Adds support for the UpdateObjectEncryption API to change the server-side encryption type of objects in general purpose buckets. (8248439e)
  • client-mediaconvert: This release adds a follow source mode for audio output channel count, an AES audio frame wrapping option for MXF outputs, and an option to signal DolbyVision compatibility using the SUPPLEMENTAL-CODECS tag in HLS manifests. (9ee45457)
  • client-cognito-identity-provider: This release adds support for a new lambda trigger to transform federated user attributes during the authentication with external identity providers on Cognito Managed Login. (a291daef)
  • client-connect: Adds support for filtering search results based on tags assigned to contacts. (c3e7a41b)
  • client-ec2: SearchTransitGatewayRoutes API response now includes a NextToken field, enabling pagination when retrieving large sets of transit gateway routes. Pass the returned NextToken value in subsequent requests to retrieve the next page of results. (11fdee1e)
  • client-mediaconnect: This release adds support for NDI flow sources in AWS Elemental MediaConnect. You can now send content to your MediaConnect transport streams directly from your NDI environment using the new NDI source type. Also adds support for LARGE 4X flow size, which can be used when creating CDI JPEG-XS flows. (a5e075c8)
  • client-s3: Adds support for the UpdateObjectEncryption API to change the server-side encryption type of objects in general purpose buckets. (b56cea55)
  • client-lambda: We are launching ESM Metrics and logging for Kafka ESM to allow customers to monitor Kafka event processing using CloudWatch Metrics and Logs. (af7d3d55)
Tests
  • client-s3: add test for aggregate client paginator/waiter methods (#7687) (75ba48bc)

For list of updated packages, view updated-packages.md in assets-3.978.0.zip

v3.977.0

3.977.0(2026-01-27)

Chores
New Features
  • clients: update client endpoints as of 2026-01-27 (04a9ab71)
  • client-ec2: Releasing new EC2 instances. C8gb and M8gb with highest EBS performance, M8gn with 600 Gbps network bandwidth, X8aedz and M8azn with 5GHz AMD processors, X8i with Intel Xeon 6 processors and up to 6TB memory, and Mac-m4max with Apple M4 Max chip for 25 percent faster builds. (8c83ff92)
  • client-connect: Added support for task attachments. The StartTaskContact API now accepts file attachments, enabling customers to include files (.csv, .doc, .docx, .heic, .jfif, .jpeg, .jpg, .mov, .mp4, .pdf, .png, .ppt, .pptx, .rtf, .txt, etc.) when creating Task contacts. Supports up to 5 attachments per task. (12e1a94a)
  • client-medialive: AWS Elemental MediaLive released two new features that allows customers 1) to set Output Timecode for AV1 encoder, 2) to set a Custom Epoch for CMAF Ingest and MediaPackage V2 output groups when using Pipeline Locking or Disabled Locking modes. (58a0492c)
  • client-deadline: AWS Deadline Cloud now supports editing job names and descriptions after submission. (fd6d1d4b)
  • client-sagemaker: Idle resource sharing enables teams to borrow unused compute resources in your SageMaker HyperPod cluster. This capability maximizes resource utilization by allowing teams to borrow idle compute capacity beyond their allocated compute quotas. (3f52b92b)

For list of updated packages, view updated-packages.md in assets-3.977.0.zip

... (truncated)

Changelog

Sourced from @​aws-sdk/client-secrets-manager's changelog.

3.978.0 (2026-01-28)

Note: Version bump only for package @​aws-sdk/client-secrets-manager

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@aws-sdk/client-secrets-manager&package-manager=npm_and_yarn&previous-version=3.975.0&new-version=3.978.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 58 ++++++++++++------- .../prescriptionDetailsLambda/package.json | 2 +- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5b5b7da7b9..2a2052fb1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2200,45 +2200,45 @@ "license": "MIT" }, "node_modules/@aws-sdk/client-secrets-manager": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.975.0.tgz", - "integrity": "sha512-KY67ghh2BBBhfaCvOquazOWWTe8CEaEsKOFtNVtECIttRlmm1YAuIDUTk7reaQhTqb+wwuS2xoGsu5z1FZkFyA==", + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-secrets-manager/-/client-secrets-manager-3.980.0.tgz", + "integrity": "sha512-TeDBmkR8x3toPnvkFMBG73QqxsWjksFUMJyR0C4tZjVXjFq9igGwq8nHYDrQA0Hony6tGvH0SyNsjsL5w5qTww==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/credential-provider-node": "^3.972.1", - "@aws-sdk/middleware-host-header": "^3.972.1", - "@aws-sdk/middleware-logger": "^3.972.1", - "@aws-sdk/middleware-recursion-detection": "^3.972.1", - "@aws-sdk/middleware-user-agent": "^3.972.2", - "@aws-sdk/region-config-resolver": "^3.972.1", - "@aws-sdk/types": "^3.973.0", - "@aws-sdk/util-endpoints": "3.972.0", - "@aws-sdk/util-user-agent-browser": "^3.972.1", - "@aws-sdk/util-user-agent-node": "^3.972.1", + "@aws-sdk/core": "^3.973.5", + "@aws-sdk/credential-provider-node": "^3.972.4", + "@aws-sdk/middleware-host-header": "^3.972.3", + "@aws-sdk/middleware-logger": "^3.972.3", + "@aws-sdk/middleware-recursion-detection": "^3.972.3", + "@aws-sdk/middleware-user-agent": "^3.972.5", + "@aws-sdk/region-config-resolver": "^3.972.3", + "@aws-sdk/types": "^3.973.1", + "@aws-sdk/util-endpoints": "3.980.0", + "@aws-sdk/util-user-agent-browser": "^3.972.3", + "@aws-sdk/util-user-agent-node": "^3.972.3", "@smithy/config-resolver": "^4.4.6", - "@smithy/core": "^3.21.1", + "@smithy/core": "^3.22.0", "@smithy/fetch-http-handler": "^5.3.9", "@smithy/hash-node": "^4.2.8", "@smithy/invalid-dependency": "^4.2.8", "@smithy/middleware-content-length": "^4.2.8", - "@smithy/middleware-endpoint": "^4.4.11", - "@smithy/middleware-retry": "^4.4.27", + "@smithy/middleware-endpoint": "^4.4.12", + "@smithy/middleware-retry": "^4.4.29", "@smithy/middleware-serde": "^4.2.9", "@smithy/middleware-stack": "^4.2.8", "@smithy/node-config-provider": "^4.3.8", "@smithy/node-http-handler": "^4.4.8", "@smithy/protocol-http": "^5.3.8", - "@smithy/smithy-client": "^4.10.12", + "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "@smithy/url-parser": "^4.2.8", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", - "@smithy/util-defaults-mode-browser": "^4.3.26", - "@smithy/util-defaults-mode-node": "^4.2.29", + "@smithy/util-defaults-mode-browser": "^4.3.28", + "@smithy/util-defaults-mode-node": "^4.2.31", "@smithy/util-endpoints": "^3.2.8", "@smithy/util-middleware": "^4.2.8", "@smithy/util-retry": "^4.2.8", @@ -2262,6 +2262,22 @@ "node": ">=20.0.0" } }, + "node_modules/@aws-sdk/client-secrets-manager/node_modules/@aws-sdk/util-endpoints": { + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.980.0.tgz", + "integrity": "sha512-AjKBNEc+rjOZQE1HwcD9aCELqg1GmUj1rtICKuY8cgwB73xJ4U/kNyqKKpN2k9emGqlfDY2D8itIp/vDc6OKpw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.1", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/client-secrets-manager/node_modules/@smithy/types": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", @@ -19795,7 +19811,7 @@ "@aws-lambda-powertools/parameters": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/client-lambda": "^3.978.0", - "@aws-sdk/client-secrets-manager": "^3.975.0", + "@aws-sdk/client-secrets-manager": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/common-types": "^1.0.0", diff --git a/packages/prescriptionDetailsLambda/package.json b/packages/prescriptionDetailsLambda/package.json index 122cf6838e..8cf3f05a23 100644 --- a/packages/prescriptionDetailsLambda/package.json +++ b/packages/prescriptionDetailsLambda/package.json @@ -18,7 +18,7 @@ "@aws-lambda-powertools/parameters": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/client-lambda": "^3.978.0", - "@aws-sdk/client-secrets-manager": "^3.975.0", + "@aws-sdk/client-secrets-manager": "^3.980.0", "@aws-sdk/lib-dynamodb": "^3.975.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/common-types": "^1.0.0", From a54263df699f3e8f949cc4440cb04a65b177344d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 Jan 2026 12:20:07 +0000 Subject: [PATCH 05/12] Upgrade: [dependabot] - bump @aws-sdk/lib-dynamodb from 3.975.0 to 3.978.0 (#1740) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@aws-sdk/lib-dynamodb](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/lib/lib-dynamodb) from 3.975.0 to 3.978.0.
Release notes

Sourced from @​aws-sdk/lib-dynamodb's releases.

v3.978.0

3.978.0(2026-01-28)

Chores
  • codegen:
New Features
  • client-s3-control: Adds support for the UpdateObjectEncryption API to change the server-side encryption type of objects in general purpose buckets. (8248439e)
  • client-mediaconvert: This release adds a follow source mode for audio output channel count, an AES audio frame wrapping option for MXF outputs, and an option to signal DolbyVision compatibility using the SUPPLEMENTAL-CODECS tag in HLS manifests. (9ee45457)
  • client-cognito-identity-provider: This release adds support for a new lambda trigger to transform federated user attributes during the authentication with external identity providers on Cognito Managed Login. (a291daef)
  • client-connect: Adds support for filtering search results based on tags assigned to contacts. (c3e7a41b)
  • client-ec2: SearchTransitGatewayRoutes API response now includes a NextToken field, enabling pagination when retrieving large sets of transit gateway routes. Pass the returned NextToken value in subsequent requests to retrieve the next page of results. (11fdee1e)
  • client-mediaconnect: This release adds support for NDI flow sources in AWS Elemental MediaConnect. You can now send content to your MediaConnect transport streams directly from your NDI environment using the new NDI source type. Also adds support for LARGE 4X flow size, which can be used when creating CDI JPEG-XS flows. (a5e075c8)
  • client-s3: Adds support for the UpdateObjectEncryption API to change the server-side encryption type of objects in general purpose buckets. (b56cea55)
  • client-lambda: We are launching ESM Metrics and logging for Kafka ESM to allow customers to monitor Kafka event processing using CloudWatch Metrics and Logs. (af7d3d55)
Tests
  • client-s3: add test for aggregate client paginator/waiter methods (#7687) (75ba48bc)

For list of updated packages, view updated-packages.md in assets-3.978.0.zip

v3.977.0

3.977.0(2026-01-27)

Chores
New Features
  • clients: update client endpoints as of 2026-01-27 (04a9ab71)
  • client-ec2: Releasing new EC2 instances. C8gb and M8gb with highest EBS performance, M8gn with 600 Gbps network bandwidth, X8aedz and M8azn with 5GHz AMD processors, X8i with Intel Xeon 6 processors and up to 6TB memory, and Mac-m4max with Apple M4 Max chip for 25 percent faster builds. (8c83ff92)
  • client-connect: Added support for task attachments. The StartTaskContact API now accepts file attachments, enabling customers to include files (.csv, .doc, .docx, .heic, .jfif, .jpeg, .jpg, .mov, .mp4, .pdf, .png, .ppt, .pptx, .rtf, .txt, etc.) when creating Task contacts. Supports up to 5 attachments per task. (12e1a94a)
  • client-medialive: AWS Elemental MediaLive released two new features that allows customers 1) to set Output Timecode for AV1 encoder, 2) to set a Custom Epoch for CMAF Ingest and MediaPackage V2 output groups when using Pipeline Locking or Disabled Locking modes. (58a0492c)
  • client-deadline: AWS Deadline Cloud now supports editing job names and descriptions after submission. (fd6d1d4b)
  • client-sagemaker: Idle resource sharing enables teams to borrow unused compute resources in your SageMaker HyperPod cluster. This capability maximizes resource utilization by allowing teams to borrow idle compute capacity beyond their allocated compute quotas. (3f52b92b)

For list of updated packages, view updated-packages.md in assets-3.977.0.zip

... (truncated)

Changelog

Sourced from @​aws-sdk/lib-dynamodb's changelog.

3.978.0 (2026-01-28)

Note: Version bump only for package @​aws-sdk/lib-dynamodb

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@aws-sdk/lib-dynamodb&package-manager=npm_and_yarn&previous-version=3.975.0&new-version=3.978.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Anthony Brown --- .trivyignore.yaml | 5 ++ package-lock.json | 66 +++++++++---------- packages/CIS2SignOutLambda/package.json | 2 +- packages/cognito/package.json | 2 +- packages/common/authFunctions/package.json | 2 +- packages/common/dynamoFunctions/package.json | 2 +- packages/patientSearchLambda/package.json | 2 +- .../prescriptionDetailsLambda/package.json | 2 +- packages/prescriptionListLambda/package.json | 2 +- packages/selectedRoleLambda/package.json | 2 +- .../clearActiveSessions/package.json | 2 +- packages/trackerUserInfoLambda/package.json | 2 +- 12 files changed, 48 insertions(+), 43 deletions(-) diff --git a/.trivyignore.yaml b/.trivyignore.yaml index c2260d5d38..cc00f1064e 100644 --- a/.trivyignore.yaml +++ b/.trivyignore.yaml @@ -9,3 +9,8 @@ vulnerabilities: - "package-lock.json" statement: downstream dependency just used in build stage expired_at: 2026-06-01 + - id: CVE-2026-25128 + paths: + - "package-lock.json" + statement: downstream dependency of fast-xml-parser + expired_at: 2026-06-01 diff --git a/package-lock.json b/package-lock.json index 2a2052fb1a..c2f2fe7077 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3816,15 +3816,15 @@ } }, "node_modules/@aws-sdk/lib-dynamodb": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.975.0.tgz", - "integrity": "sha512-BEhzr8atBFT8mJ8KuFne3OHj81zsqQWLP1Is2zzbzbZy4Mjbm1nRceNEwZ603tp9oFrV2mwTNLagFDPEudJC/g==", + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.980.0.tgz", + "integrity": "sha512-rot+9bSIUCjCJCh+BnH++ZYHCEUtTDVKkrBpN+WxbrEEGUvU1RNhkQEPXcLaf57UobRjoTI4m3LNBJCH7E6MCw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "^3.973.1", - "@aws-sdk/util-dynamodb": "3.975.0", - "@smithy/core": "^3.21.1", - "@smithy/smithy-client": "^4.10.12", + "@aws-sdk/core": "^3.973.5", + "@aws-sdk/util-dynamodb": "3.980.0", + "@smithy/core": "^3.22.0", + "@smithy/smithy-client": "^4.11.1", "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, @@ -3832,22 +3832,7 @@ "node": ">=20.0.0" }, "peerDependencies": { - "@aws-sdk/client-dynamodb": "3.975.0" - } - }, - "node_modules/@aws-sdk/lib-dynamodb/node_modules/@aws-sdk/util-dynamodb": { - "version": "3.975.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.975.0.tgz", - "integrity": "sha512-ZsziF8m5Syn+kA2YJLEG2kk6zfxea8yRl/7SkSFpAls8RFYkt8EUmVUMBhX2hBpGw+nbZL7+AcRi4S2LxAcYWA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@aws-sdk/client-dynamodb": "3.975.0" + "@aws-sdk/client-dynamodb": "3.980.0" } }, "node_modules/@aws-sdk/lib-dynamodb/node_modules/@smithy/types": { @@ -4334,6 +4319,21 @@ "node": ">=18.0.0" } }, + "node_modules/@aws-sdk/util-dynamodb": { + "version": "3.980.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-dynamodb/-/util-dynamodb-3.980.0.tgz", + "integrity": "sha512-jG/yzr/JLFl7II9TTDWRKJRHThTXYNDYy694bRTj7JCXCU/Gb11ir5fJ7sV6FhlR9LrIaDb7Fft3RifvEnZcSQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@aws-sdk/client-dynamodb": "3.980.0" + } + }, "node_modules/@aws-sdk/util-endpoints": { "version": "3.972.0", "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.972.0.tgz", @@ -19566,7 +19566,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", @@ -19599,7 +19599,7 @@ "@aws-lambda-powertools/logger": "^2.30.1", "@aws-lambda-powertools/parameters": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", @@ -19624,7 +19624,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-lambda-powertools/parameters": "^2.30.1", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@middy/core": "^7.0.2", "aws-lambda": "^1.0.7", @@ -19663,7 +19663,7 @@ "license": "MIT", "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/common-types": "^1.0.0" } }, @@ -19785,7 +19785,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", @@ -19812,7 +19812,7 @@ "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/client-lambda": "^3.978.0", "@aws-sdk/client-secrets-manager": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/common-types": "^1.0.0", "@cpt-ui-common/doHSClient": "^1.0.0", @@ -19840,7 +19840,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", @@ -19865,7 +19865,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", @@ -19901,7 +19901,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", @@ -19923,7 +19923,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", diff --git a/packages/CIS2SignOutLambda/package.json b/packages/CIS2SignOutLambda/package.json index aa88bf92ab..1e0cda1978 100644 --- a/packages/CIS2SignOutLambda/package.json +++ b/packages/CIS2SignOutLambda/package.json @@ -15,7 +15,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", diff --git a/packages/cognito/package.json b/packages/cognito/package.json index b7327fbded..3d8487f6a6 100644 --- a/packages/cognito/package.json +++ b/packages/cognito/package.json @@ -16,7 +16,7 @@ "@aws-lambda-powertools/logger": "^2.30.1", "@aws-lambda-powertools/parameters": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", diff --git a/packages/common/authFunctions/package.json b/packages/common/authFunctions/package.json index 57e1cedc5d..f4c47e9b38 100644 --- a/packages/common/authFunctions/package.json +++ b/packages/common/authFunctions/package.json @@ -20,7 +20,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-lambda-powertools/parameters": "^2.30.1", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@middy/core": "^7.0.2", "aws-lambda": "^1.0.7", diff --git a/packages/common/dynamoFunctions/package.json b/packages/common/dynamoFunctions/package.json index 9831febaaf..be0b5478b3 100644 --- a/packages/common/dynamoFunctions/package.json +++ b/packages/common/dynamoFunctions/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/common-types": "^1.0.0" } } diff --git a/packages/patientSearchLambda/package.json b/packages/patientSearchLambda/package.json index d75898c039..1caeb38356 100644 --- a/packages/patientSearchLambda/package.json +++ b/packages/patientSearchLambda/package.json @@ -15,7 +15,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", diff --git a/packages/prescriptionDetailsLambda/package.json b/packages/prescriptionDetailsLambda/package.json index 8cf3f05a23..76a138db7f 100644 --- a/packages/prescriptionDetailsLambda/package.json +++ b/packages/prescriptionDetailsLambda/package.json @@ -19,7 +19,7 @@ "@aws-sdk/client-dynamodb": "^3.980.0", "@aws-sdk/client-lambda": "^3.978.0", "@aws-sdk/client-secrets-manager": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/common-types": "^1.0.0", "@cpt-ui-common/doHSClient": "^1.0.0", diff --git a/packages/prescriptionListLambda/package.json b/packages/prescriptionListLambda/package.json index ab14e82aa0..375cf1612f 100644 --- a/packages/prescriptionListLambda/package.json +++ b/packages/prescriptionListLambda/package.json @@ -15,7 +15,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", diff --git a/packages/selectedRoleLambda/package.json b/packages/selectedRoleLambda/package.json index fdb7f9838b..b430f77908 100644 --- a/packages/selectedRoleLambda/package.json +++ b/packages/selectedRoleLambda/package.json @@ -15,7 +15,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", diff --git a/packages/testingSupport/clearActiveSessions/package.json b/packages/testingSupport/clearActiveSessions/package.json index f107cec525..f0127311c0 100644 --- a/packages/testingSupport/clearActiveSessions/package.json +++ b/packages/testingSupport/clearActiveSessions/package.json @@ -15,7 +15,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", diff --git a/packages/trackerUserInfoLambda/package.json b/packages/trackerUserInfoLambda/package.json index f5c36ba756..6a1c90feef 100644 --- a/packages/trackerUserInfoLambda/package.json +++ b/packages/trackerUserInfoLambda/package.json @@ -15,7 +15,7 @@ "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", "@aws-sdk/client-dynamodb": "^3.980.0", - "@aws-sdk/lib-dynamodb": "^3.975.0", + "@aws-sdk/lib-dynamodb": "^3.980.0", "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/dynamoFunctions": "^1.0.0", "@cpt-ui-common/middyErrorHandler": "^1.0.0", From 60606477424fe5f81415f10a6e7a93c7b25ce7ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 Jan 2026 13:33:56 +0000 Subject: [PATCH 06/12] Upgrade: [dependabot] - bump @types/node from 25.0.10 to 25.1.0 (#1739) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 25.0.10 to 25.1.0.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=25.0.10&new-version=25.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index c2f2fe7077..7fe64dddac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "@eslint/js": "^9.38.0", "@jest/globals": "^30.1.1", "@types/jest": "^30.0.0", - "@types/node": "^25.0.9", + "@types/node": "^25.1.0", "@typescript-eslint/eslint-plugin": "^8.48.0", "@typescript-eslint/parser": "^8.50.1", "aws-sdk-client-mock": "^4.1.0", @@ -9341,9 +9341,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "25.0.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", - "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.1.0.tgz", + "integrity": "sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==", "license": "MIT", "dependencies": { "undici-types": "~7.16.0" diff --git a/package.json b/package.json index 27eea993b8..fba597ec32 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@eslint/js": "^9.38.0", "@jest/globals": "^30.1.1", "@types/jest": "^30.0.0", - "@types/node": "^25.0.9", + "@types/node": "^25.1.0", "@typescript-eslint/eslint-plugin": "^8.48.0", "@typescript-eslint/parser": "^8.50.1", "aws-sdk-client-mock": "^4.1.0", From caa5a8ac420cbbbb5ff2c284634c45f013d62260 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 Jan 2026 15:20:54 +0000 Subject: [PATCH 07/12] Upgrade: [dependabot] - bump NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml from 5.3.3 to 5.3.5 (#1735) Bumps [NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml](https://github.com/nhsdigital/eps-common-workflows) from 5.3.3 to 5.3.5.
Release notes

Sourced from NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml's releases.

v5.3.5

5.3.5 (2026-01-30)

Chore

Info

See code diff Release workflow run - Workflow ID: 21522186096

It was initialized by anthony-nhs

v5.3.4

5.3.4 (2026-01-28)

Chore

  • [AEA-0000] - fix mavan cache before running sonar (#53) (27a44fb)

Info

See code diff Release workflow run - Workflow ID: 21432532525

It was initialized by anthony-nhs

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml&package-manager=github_actions&previous-version=5.3.3&new-version=5.3.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: anthony-nhs <121869075+anthony-nhs@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/pull_request.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 633834be3a..7c4ce7d699 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: echo "TAG_FORMAT=$TAG_FORMAT" >> "$GITHUB_OUTPUT" quality_checks: - uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml@b933ef1bb3527fd7e7d5a7629fbd4e4dd94bf1b4 + uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml@e31e25273fb87450be4ef763ddbed4f531c45f8e needs: [get_asdf_version] with: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 316fbd5b8f..6480fd6400 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -50,7 +50,7 @@ jobs: quality_checks: # always run, but only block in the non-skip case needs: [get_commit_message, get_asdf_version] - uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml@b933ef1bb3527fd7e7d5a7629fbd4e4dd94bf1b4 + uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml@e31e25273fb87450be4ef763ddbed4f531c45f8e with: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} secrets: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3be4ed34bc..430c994034 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,7 +25,7 @@ jobs: TAG_FORMAT=$(yq '.TAG_FORMAT' .github/config/settings.yml) echo "TAG_FORMAT=$TAG_FORMAT" >> "$GITHUB_OUTPUT" quality_checks: - uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml@b933ef1bb3527fd7e7d5a7629fbd4e4dd94bf1b4 + uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml@e31e25273fb87450be4ef763ddbed4f531c45f8e needs: [get_asdf_version] with: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} From 6c9a0adbc1ec90f0f32475a7d77cd306758a4d65 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 31 Jan 2026 16:07:31 +0000 Subject: [PATCH 08/12] Upgrade: [dependabot] - bump NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml from 5.3.3 to 5.3.5 (#1731) Bumps [NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml](https://github.com/nhsdigital/eps-common-workflows) from 5.3.3 to 5.3.5.
Release notes

Sourced from NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml's releases.

v5.3.5

5.3.5 (2026-01-30)

Chore

Info

See code diff Release workflow run - Workflow ID: 21522186096

It was initialized by anthony-nhs

v5.3.4

5.3.4 (2026-01-28)

Chore

  • [AEA-0000] - fix mavan cache before running sonar (#53) (27a44fb)

Info

See code diff Release workflow run - Workflow ID: 21432532525

It was initialized by anthony-nhs

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml&package-manager=github_actions&previous-version=5.3.3&new-version=5.3.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- .github/workflows/pull_request.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c4ce7d699..5cc663dae1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,7 +46,7 @@ jobs: tag_release: needs: [quality_checks, get_commit_id, get_asdf_version] - uses: NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml@b933ef1bb3527fd7e7d5a7629fbd4e4dd94bf1b4 + uses: NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml@e31e25273fb87450be4ef763ddbed4f531c45f8e with: dry_run: true asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 6480fd6400..fe83926c0c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -150,7 +150,7 @@ jobs: tag_release: needs: [get_asdf_version] - uses: NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml@b933ef1bb3527fd7e7d5a7629fbd4e4dd94bf1b4 + uses: NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml@e31e25273fb87450be4ef763ddbed4f531c45f8e with: dry_run: true asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 430c994034..5edc698308 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,7 +44,7 @@ jobs: tag_release: needs: [quality_checks, get_commit_id, get_asdf_version] - uses: NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml@b933ef1bb3527fd7e7d5a7629fbd4e4dd94bf1b4 + uses: NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml@e31e25273fb87450be4ef763ddbed4f531c45f8e with: dry_run: false asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} From be980f04f3e2ce64bde50666648e910ddbf7fa6e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Feb 2026 14:11:04 +0000 Subject: [PATCH 09/12] Upgrade: [dependabot] - bump NHSDigital/eps-common-workflows/.github/workflows/pr_title_check.yml from 5.3.3 to 5.3.5 (#1734) Bumps [NHSDigital/eps-common-workflows/.github/workflows/pr_title_check.yml](https://github.com/nhsdigital/eps-common-workflows) from 5.3.3 to 5.3.5.
Release notes

Sourced from NHSDigital/eps-common-workflows/.github/workflows/pr_title_check.yml's releases.

v5.3.5

5.3.5 (2026-01-30)

Chore

Info

See code diff Release workflow run - Workflow ID: 21522186096

It was initialized by anthony-nhs

v5.3.4

5.3.4 (2026-01-28)

Chore

  • [AEA-0000] - fix mavan cache before running sonar (#53) (27a44fb)

Info

See code diff Release workflow run - Workflow ID: 21432532525

It was initialized by anthony-nhs

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=NHSDigital/eps-common-workflows/.github/workflows/pr_title_check.yml&package-manager=github_actions&previous-version=5.3.3&new-version=5.3.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index fe83926c0c..f1a8a10a95 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -120,7 +120,7 @@ jobs: run: echo "Skipping QC gate per commit message." pr_title_format_check: - uses: NHSDigital/eps-common-workflows/.github/workflows/pr_title_check.yml@b933ef1bb3527fd7e7d5a7629fbd4e4dd94bf1b4 + uses: NHSDigital/eps-common-workflows/.github/workflows/pr_title_check.yml@e31e25273fb87450be4ef763ddbed4f531c45f8e get_issue_number: runs-on: ubuntu-22.04 From 8af4fd80791d5f7187aafb81128b72531619a01a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 1 Feb 2026 15:23:36 +0000 Subject: [PATCH 10/12] Upgrade: [dependabot] - bump NHSDigital/eps-common-workflows/.github/workflows/dependabot-auto-approve-and-merge.yml from 5.3.3 to 5.3.5 (#1733) Bumps [NHSDigital/eps-common-workflows/.github/workflows/dependabot-auto-approve-and-merge.yml](https://github.com/nhsdigital/eps-common-workflows) from 5.3.3 to 5.3.5.
Release notes

Sourced from NHSDigital/eps-common-workflows/.github/workflows/dependabot-auto-approve-and-merge.yml's releases.

v5.3.5

5.3.5 (2026-01-30)

Chore

Info

See code diff Release workflow run - Workflow ID: 21522186096

It was initialized by anthony-nhs

v5.3.4

5.3.4 (2026-01-28)

Chore

  • [AEA-0000] - fix mavan cache before running sonar (#53) (27a44fb)

Info

See code diff Release workflow run - Workflow ID: 21432532525

It was initialized by anthony-nhs

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=NHSDigital/eps-common-workflows/.github/workflows/dependabot-auto-approve-and-merge.yml&package-manager=github_actions&previous-version=5.3.3&new-version=5.3.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index f1a8a10a95..5d1fc53342 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -10,7 +10,7 @@ env: jobs: dependabot-auto-approve-and-merge: needs: quality_checks - uses: NHSDigital/eps-common-workflows/.github/workflows/dependabot-auto-approve-and-merge.yml@b933ef1bb3527fd7e7d5a7629fbd4e4dd94bf1b4 + uses: NHSDigital/eps-common-workflows/.github/workflows/dependabot-auto-approve-and-merge.yml@e31e25273fb87450be4ef763ddbed4f531c45f8e secrets: AUTOMERGE_APP_ID: ${{ secrets.AUTOMERGE_APP_ID }} AUTOMERGE_PEM: ${{ secrets.AUTOMERGE_PEM }} From 264a8e891bf89451cd0cc4544ed083b854ee30bb Mon Sep 17 00:00:00 2001 From: jonathanwelch1-nhs <148754575+jonathanwelch1-nhs@users.noreply.github.com> Date: Tue, 3 Feb 2026 09:50:24 +0000 Subject: [PATCH 11/12] Fix: [AEA-5935] - privacy notice (#1713) ## Summary https://nhsd-jira.digital.nhs.uk/browse/AEA-5935 - Routine Change ### Details changed hyphens to en dashes made it so that interacting with the page can affect the tabbing order for skip link --- .github/workflows/run_regression_tests.yml | 4 +- packages/cpt-ui/__tests__/App.test.tsx | 300 +++++++++++++++++- packages/cpt-ui/src/App.tsx | 20 +- .../ui-strings/PrivacyNoticeStrings.ts | 22 +- 4 files changed, 315 insertions(+), 31 deletions(-) diff --git a/.github/workflows/run_regression_tests.yml b/.github/workflows/run_regression_tests.yml index 7af591cba5..02229286f5 100644 --- a/.github/workflows/run_regression_tests.yml +++ b/.github/workflows/run_regression_tests.yml @@ -73,8 +73,8 @@ jobs: GITHUB-TOKEN: ${{ steps.generate-token.outputs.token }} run: | if [[ "$TARGET_ENVIRONMENT" != "prod" && "$TARGET_ENVIRONMENT" != "ref" ]]; then - REGRESSION_TEST_REPO_TAG="v3.8.10" # This is the tag or branch of the regression test code to run, usually a version tag like v3.1.0 or a branch name - REGRESSION_TEST_WORKFLOW_TAG="v3.8.10" # This is the tag of the github workflow to run, usually the same as REGRESSION_TEST_REPO_TAG + REGRESSION_TEST_REPO_TAG="v3.8.20" # This is the tag or branch of the regression test code to run, usually a version tag like v3.1.0 or a branch name + REGRESSION_TEST_WORKFLOW_TAG="v3.8.20" # This is the tag of the github workflow to run, usually the same as REGRESSION_TEST_REPO_TAG if [[ -z "$REGRESSION_TEST_REPO_TAG" || -z "$REGRESSION_TEST_WORKFLOW_TAG" ]]; then diff --git a/packages/cpt-ui/__tests__/App.test.tsx b/packages/cpt-ui/__tests__/App.test.tsx index 9d04688544..904a0dddce 100644 --- a/packages/cpt-ui/__tests__/App.test.tsx +++ b/packages/cpt-ui/__tests__/App.test.tsx @@ -1,8 +1,15 @@ import "@testing-library/jest-dom" -import {render, screen} from "@testing-library/react" -import {BrowserRouter} from "react-router-dom" +import +{render, + screen, + fireEvent, + waitFor, + act} + from "@testing-library/react" +import {BrowserRouter, MemoryRouter} from "react-router-dom" import React from "react" import App from "@/App" +import {FRONTEND_PATHS} from "@/constants/environment" // Mock all the context providers jest.mock("@/context/AuthProvider", () => ({ @@ -64,19 +71,284 @@ jest.mock("@/pages/SessionLoggedOut", () => () =>
Session Logged Out
) // Mock EPSCookieBanner jest.mock("@/components/EPSCookieBanner", () => () =>
Cookie Banner
) +jest.mock("@/pages/TooManySearchResultsPage", () => () =>
Too Many Search Results
) +jest.mock("@/pages/NoPrescriptionsFoundPage", () => () =>
No Prescriptions Found
) +jest.mock("@/pages/NoPatientsFoundPage", () => () =>
No Patients Found
) + +// Mock HEADER_STRINGS to avoid dependency on constants +jest.mock("@/constants/ui-strings/HeaderStrings", () => ({ + HEADER_STRINGS: { + SKIP_TO_MAIN_CONTENT: "Skip to main content" + } +})) + +// Test helper function to render App with specific route +const renderAppAtRoute = (route: string) => { + return render( + + + + ) +} describe("App", () => { - it("renders the skip link for regular pages", () => { - render( - - - - ) - - const skipLink = screen.getByTestId("eps_header_skipLink") - expect(skipLink).toBeInTheDocument() - expect(skipLink).toHaveAttribute("href", "#main-content") - expect(skipLink).toHaveTextContent("Skip to main content") - expect(skipLink).toHaveClass("nhsuk-skip-link") + // Setup function to clear focus before each test + beforeEach(() => { + // Reset focus to body + if (document.activeElement && document.activeElement !== document.body) { + (document.activeElement as HTMLElement).blur?.() + } + // Clear any existing event listeners + jest.clearAllMocks() + }) + + describe("Skip link rendering", () => { + it("renders the skip link for regular pages", () => { + render( + + + + ) + + const skipLink = screen.getByTestId("eps_header_skipLink") + expect(skipLink).toBeInTheDocument() + expect(skipLink).toHaveAttribute("href", "#main-content") + expect(skipLink).toHaveTextContent("Skip to main content") + expect(skipLink).toHaveClass("nhsuk-skip-link") + }) + + it("renders skip link with patient details banner target for prescription list current page", () => { + renderAppAtRoute(FRONTEND_PATHS.PRESCRIPTION_LIST_CURRENT) + + const skipLink = screen.getByTestId("eps_header_skipLink") + expect(skipLink).toHaveAttribute("href", "#patient-details-banner") + }) + + it("renders skip link with patient details banner target for prescription list future page", () => { + renderAppAtRoute(FRONTEND_PATHS.PRESCRIPTION_LIST_FUTURE) + + const skipLink = screen.getByTestId("eps_header_skipLink") + expect(skipLink).toHaveAttribute("href", "#patient-details-banner") + }) + + it("renders skip link with patient details banner target for prescription list past page", () => { + renderAppAtRoute(FRONTEND_PATHS.PRESCRIPTION_LIST_PAST) + + const skipLink = screen.getByTestId("eps_header_skipLink") + expect(skipLink).toHaveAttribute("href", "#patient-details-banner") + }) + + it("renders skip link with patient details banner target for prescription details page", () => { + renderAppAtRoute(`${FRONTEND_PATHS.PRESCRIPTION_DETAILS_PAGE}/123`) + + const skipLink = screen.getByTestId("eps_header_skipLink") + expect(skipLink).toHaveAttribute("href", "#patient-details-banner") + }) + + it("renders skip link with main content target for non-prescription pages", () => { + renderAppAtRoute(FRONTEND_PATHS.SEARCH_BY_PRESCRIPTION_ID) + + const skipLink = screen.getByTestId("eps_header_skipLink") + expect(skipLink).toHaveAttribute("href", "#main-content") + }) + }) + + describe("Skip link keyboard navigation", () => { + it("focuses skip link on first Tab press when page loads without user interaction", async () => { + renderAppAtRoute("/") + + const skipLink = screen.getByTestId("eps_header_skipLink") + + // Simulate Tab key press + fireEvent.keyDown(document, {key: "Tab", code: "Tab"}) + + await waitFor(() => { + expect(skipLink).toHaveFocus() + }) + }) + + it("does not focus skip link on Tab press when user has already clicked on page", async () => { + renderAppAtRoute("/") + + const skipLink = screen.getByTestId("eps_header_skipLink") + + // Simulate user clicking on the page + fireEvent.click(document.body) + + // Simulate Tab key press + fireEvent.keyDown(document, {key: "Tab", code: "Tab"}) + + await waitFor(() => { + expect(skipLink).not.toHaveFocus() + }) + }) + + it("does not focus skip link on Tab press when user has already focused an element", async () => { + renderAppAtRoute("/") + + const skipLink = screen.getByTestId("eps_header_skipLink") + + // Create a focusable element and simulate user focusing it + const button = document.createElement("button") + button.setAttribute("data-testid", "test-button") + document.body.appendChild(button) + fireEvent.focusIn(button) + + // Simulate Tab key press + fireEvent.keyDown(document, {key: "Tab", code: "Tab"}) + + await waitFor(() => { + expect(skipLink).not.toHaveFocus() + }) + + // Cleanup + document.body.removeChild(button) + }) + + it("does not focus skip link on Shift+Tab press", async () => { + renderAppAtRoute("/") + + const skipLink = screen.getByTestId("eps_header_skipLink") + + // Simulate Shift+Tab key press + fireEvent.keyDown(document, {key: "Tab", code: "Tab", shiftKey: true}) + + await waitFor(() => { + expect(skipLink).not.toHaveFocus() + }) + }) + + it("does not trigger skip link behavior on non-Tab key press", async () => { + renderAppAtRoute("/") + + const skipLink = screen.getByTestId("eps_header_skipLink") + + // Simulate Enter key press + fireEvent.keyDown(document, {key: "Enter", code: "Enter"}) + + await waitFor(() => { + expect(skipLink).not.toHaveFocus() + }) + }) + + it("only triggers skip link behavior once per page load", async () => { + renderAppAtRoute("/") + + const skipLink = screen.getByTestId("eps_header_skipLink") + + // First Tab press should focus skip link + fireEvent.keyDown(document, {key: "Tab", code: "Tab"}) + await waitFor(() => { + expect(skipLink).toHaveFocus() + }) + + // Blur the skip link + skipLink.blur() + + // Second Tab press should not focus skip link again + fireEvent.keyDown(document, {key: "Tab", code: "Tab"}) + + // Give some time to ensure focus doesn't change + await new Promise(resolve => setTimeout(resolve, 50)) + expect(skipLink).not.toHaveFocus() + }) + + it("resets skip link behavior when navigating to a new page", async () => { + const {rerender} = render( + + + + ) + + let skipLink = screen.getByTestId("eps_header_skipLink") + + // First Tab press should focus skip link + fireEvent.keyDown(document, {key: "Tab", code: "Tab"}) + await waitFor(() => { + expect(skipLink).toHaveFocus() + }) + + // Navigate to a new page by re-rendering with a different route + await act(async () => { + rerender( + + + + ) + }) + + // Get the new skip link element after rerender + skipLink = screen.getByTestId("eps_header_skipLink") + + // Tab press should focus skip link again after navigation + fireEvent.keyDown(document, {key: "Tab", code: "Tab"}) + await waitFor(() => { + expect(skipLink).toHaveFocus() + }) + }) + + it("handles case when skip link element is not found", async () => { + renderAppAtRoute("/") + + // Mock querySelector to return null + const originalQuerySelector = document.querySelector + document.querySelector = jest.fn().mockReturnValue(null) + + // This should not throw an error + fireEvent.keyDown(document, {key: "Tab", code: "Tab"}) + + // Restore original querySelector + document.querySelector = originalQuerySelector + }) + + it("detects user interaction when an element already has focus on page load", async () => { + // Create a focusable element and focus it before rendering + const input = document.createElement("input") + input.setAttribute("data-testid", "pre-focused-input") + document.body.appendChild(input) + input.focus() + + renderAppAtRoute("/") + + const skipLink = screen.getByTestId("eps_header_skipLink") + + // Tab press should not focus skip link since user has already interacted + fireEvent.keyDown(document, {key: "Tab", code: "Tab"}) + + await waitFor(() => { + expect(skipLink).not.toHaveFocus() + }) + + // Cleanup + document.body.removeChild(input) + }) + }) + + describe("Route handling", () => { + it("renders the app with routing components", () => { + render( + + + + ) + + // Verify the basic app structure is rendered + expect(screen.getByTestId("eps_header_skipLink")).toBeInTheDocument() + expect(screen.getByTestId("layout")).toBeInTheDocument() + }) + + it("handles different route paths without errors", () => { + expect(() => { + render( + + + + ) + }).not.toThrow() + + expect(screen.getByTestId("eps_header_skipLink")).toBeInTheDocument() + }) }) }) + +// Removed duplicate describe block diff --git a/packages/cpt-ui/src/App.tsx b/packages/cpt-ui/src/App.tsx index 67c2b9caef..20121daa86 100644 --- a/packages/cpt-ui/src/App.tsx +++ b/packages/cpt-ui/src/App.tsx @@ -34,17 +34,23 @@ import {HEADER_STRINGS} from "@/constants/ui-strings/HeaderStrings" function AppContent() { const location = useLocation() - // this useEffect ensures that focus starts with skip link when using tab navigation + // this useEffect ensures that focus starts with skip link when using tab navigation, + // unless the user has already interacted with the page useEffect(() => { let hasTabbed = false + let hasUserInteracted = false const activeElement = document.activeElement as HTMLElement - if (activeElement && activeElement !== document.body) { - activeElement.blur() + if (activeElement && activeElement !== document.body && activeElement.tagName !== "HTML") { + hasUserInteracted = true + } + + const handleUserInteraction = () => { + hasUserInteracted = true } const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === "Tab" && !hasTabbed && !e.shiftKey) { + if (e.key === "Tab" && !hasTabbed && !hasUserInteracted && !e.shiftKey) { hasTabbed = true e.preventDefault() const skipLink = document.querySelector(".nhsuk-skip-link") as HTMLElement @@ -52,13 +58,19 @@ function AppContent() { skipLink.focus() } document.removeEventListener("keydown", handleKeyDown) + document.removeEventListener("click", handleUserInteraction) + document.removeEventListener("focusin", handleUserInteraction) } } + document.addEventListener("click", handleUserInteraction) + document.addEventListener("focusin", handleUserInteraction) document.addEventListener("keydown", handleKeyDown) return () => { document.removeEventListener("keydown", handleKeyDown) + document.removeEventListener("click", handleUserInteraction) + document.removeEventListener("focusin", handleUserInteraction) } }, [location.pathname]) diff --git a/packages/cpt-ui/src/constants/ui-strings/PrivacyNoticeStrings.ts b/packages/cpt-ui/src/constants/ui-strings/PrivacyNoticeStrings.ts index 1a23f2d2c6..6eac044ffb 100644 --- a/packages/cpt-ui/src/constants/ui-strings/PrivacyNoticeStrings.ts +++ b/packages/cpt-ui/src/constants/ui-strings/PrivacyNoticeStrings.ts @@ -1,5 +1,5 @@ export const PrivacyNoticeStrings = { - pageTitle: "Privacy notice - Prescription tracker", + pageTitle: "Privacy notice – Prescription tracker", home: "Home", privacyNotice: "Privacy Notice", header: "Privacy notice for the Prescription Tracker", @@ -22,12 +22,12 @@ export const PrivacyNoticeStrings = { dataCollected: { header: "What data we collect", explanation: "We collect a range of your personal data, including:", - identifiable: "identifiable data - through signing in using ", + identifiable: "identifiable data – through signing in using ", cis2Link: "NHS CIS2 Authentication (opens in new tab)", stores: ", we store your CIS2 Unique User ID (UUID), name, role and organisation name", - usage: "usage data - information about how you interact with the Prescription Tracker, including your IP address," + usage: "usage data – information about how you interact with the Prescription Tracker, including your IP address," + " browser type, operating system and activity logs", - device: "device information - information about the device you use to access the Prescription Tracker," + device: "device information – information about the device you use to access the Prescription Tracker," + " such as device type and device identifiers" }, dataSource: { @@ -38,22 +38,22 @@ export const PrivacyNoticeStrings = { usage: { header: "How we use your data", explanation: "We use your personal data for the following purposes: ", - functionality: "to provide core functionality -" + functionality: "to provide core functionality –" + " we process your data to enable you to use the Prescription Tracker", - serviceImprovement: "service improvement - we analyse your usage patterns to understand how you use" + serviceImprovement: "service improvement – we analyse your usage patterns to understand how you use" + " the Prescription Tracker and improve its functionality." + " To do this, we put small files called 'analytic cookies' on your device using software called" + " Amazon CloudWatch RUM. These cookies are optional. The information collected includes:" + " the type of device you used, your browser type, your operating system, the date and time" + " you used the service and how you interacted with the service. For more information, see our ", cookie: "cookie policy", - audit: "audit and security - we collect activity logs of actions you have taken for monitoring and audit purposes." + audit: "audit and security – we collect activity logs of actions you have taken for monitoring and audit purposes." + " We process your authentication credentials, usage data and device information to ensure the security" + " of the service", - answer: "answer enquiries and investigate issues with the service -" + answer: "answer enquiries and investigate issues with the service –" + " if you contact us about any issues you are having with the service, we need to process your data to investigate" + " and resolve the issue you raised", - legal: "to comply with our legal obligations -" + legal: "to comply with our legal obligations –" + " we process your data to comply with our legal obligation to operate the service and any" + " other applicable laws or regulations" }, @@ -74,9 +74,9 @@ export const PrivacyNoticeStrings = { sharing: { header: "Who we share data with", mayShare: "We may share your data with:", - share1: "your employing organisation - if misuse is detected or reported," + share1: "your employing organisation – if misuse is detected or reported," + " we may need to share your data with your employing organisation for investigation purposes", - share2: "legal authorities - if required by law, we may disclose your personal data" + share2: "legal authorities – if required by law, we may disclose your personal data" + " to law enforcement or other legal entities" }, retention: { From cd417127e0c09ac9829e5ddcf48a1bce361dcaa7 Mon Sep 17 00:00:00 2001 From: anthony-nhs <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:37:18 +0000 Subject: [PATCH 12/12] Chore: [AEA-0000] - move some packages to vitest (#1681) ## Summary - Routine Change ### Details - move to vitest for - - packages/cognito - - packages/common/authFunctions - - packages/prescriptionDetailsLambda - move to latest mock-jwks --- ...eps-prescription-tracker-ui.code-workspace | 12 +- Makefile | 40 +- package-lock.json | 487 +++++++++++++++++- package.json | 4 +- packages/cognito/.jest/setEnvVars.js | 22 - packages/cognito/jest.config.ts | 10 - packages/cognito/jest.debug.config.ts | 9 - packages/cognito/package.json | 4 +- packages/cognito/tests/test_authorize.test.ts | 16 +- .../cognito/tests/test_authorizeMock.test.ts | 16 +- packages/cognito/tests/test_callback.test.ts | 16 +- .../cognito/tests/test_callbackMock.test.ts | 18 +- .../cognito/tests/test_rewriteBody.test.ts | 13 +- .../cognito/tests/test_token.cis2.test.ts | 66 ++- .../cognito/tests/test_token.failure.test.ts | 44 +- .../cognito/tests/test_token.mock.test.ts | 67 ++- packages/cognito/vitest.config.ts | 40 ++ .../common/authFunctions/.jest/setEnvVars.js | 32 -- packages/common/authFunctions/package.json | 4 +- .../tests/test_apigeeUtils.test.ts | 61 +-- .../tests/test_authenticateRequest.test.ts | 117 +++-- ...nticationConcurrentAwareMiddleware.test.ts | 48 +- .../test_authenticationMiddleware.test.ts | 46 +- .../tests/test_cis2TokenHelpers.test.ts | 50 +- .../tests/test_constructSignedJWTBody.test.ts | 19 +- .../tests/test_userInfoHelpers.test.ts | 75 +-- .../common/authFunctions/vitest.config.ts | 43 ++ .../.jest/setEnvVars.js | 28 - .../prescriptionDetailsLambda/jest.config.ts | 10 - .../jest.debug.config.ts | 9 - .../prescriptionDetailsLambda/package.json | 6 +- .../tests/test_extensionUtils.test.ts | 2 + .../tests/test_getPatientDetails.test.ts | 60 ++- .../tests/test_handler.test.ts | 49 +- .../tests/test_prescriptionService.test.ts | 62 ++- .../tests/test_responseMapper.test.ts | 7 + .../vitest.config.ts | 38 ++ sonar-project.properties | 6 +- vitest.shared.config.ts | 18 + 39 files changed, 1134 insertions(+), 540 deletions(-) delete mode 100644 packages/cognito/.jest/setEnvVars.js delete mode 100644 packages/cognito/jest.config.ts delete mode 100644 packages/cognito/jest.debug.config.ts create mode 100644 packages/cognito/vitest.config.ts delete mode 100644 packages/common/authFunctions/.jest/setEnvVars.js create mode 100644 packages/common/authFunctions/vitest.config.ts delete mode 100644 packages/prescriptionDetailsLambda/.jest/setEnvVars.js delete mode 100644 packages/prescriptionDetailsLambda/jest.config.ts delete mode 100644 packages/prescriptionDetailsLambda/jest.debug.config.ts create mode 100644 packages/prescriptionDetailsLambda/vitest.config.ts create mode 100644 vitest.shared.config.ts diff --git a/.vscode/eps-prescription-tracker-ui.code-workspace b/.vscode/eps-prescription-tracker-ui.code-workspace index 4dd24e7aee..ea4e4dcf8b 100644 --- a/.vscode/eps-prescription-tracker-ui.code-workspace +++ b/.vscode/eps-prescription-tracker-ui.code-workspace @@ -96,7 +96,11 @@ "packages/staticContent", "packages/common/testing", "packages/common/commonTypes", - "packages/staticContent" + "packages/staticContent", + "packages/cognito", + "packages/prescriptionDetailsLambda", + "packages/common/authFunctions", + "packages/testingSupport" ], "jest.useJest30": true, "python.testing.pytestEnabled": false, @@ -207,7 +211,8 @@ }, "[scss]": { "editor.defaultFormatter": "vscode.css-language-features" - } + }, + "vitest.configSearchPatternExclude": "{**/node_modules/**,**/.*/**,**/*.d.ts,**/lib/*}" }, "extensions": { "recommendations": [ @@ -229,7 +234,8 @@ "streetsidesoftware.code-spell-checker", "timonwong.shellcheck", "mkhl.direnv", - "tamasfe.even-better-toml" + "tamasfe.even-better-toml", + "vitest.explorer" ] } } diff --git a/Makefile b/Makefile index d880ec03e8..b0d7062e04 100644 --- a/Makefile +++ b/Makefile @@ -72,44 +72,8 @@ test: compile npm run test --workspace packages/testingSupport/clearActiveSessions clean: - rm -rf packages/cdk/coverage - rm -rf packages/cdk/lib - rm -rf packages/CIS2SignOutLambda/coverage - rm -rf packages/CIS2SignOutLambda/lib - rm -rf packages/cloudfrontFunctions/coverage - rm -rf packages/cloudfrontFunctions/lib - rm -rf packages/cognito/coverage - rm -rf packages/cognito/lib - rm -rf packages/cpt-ui/dist - rm -rf packages/cpt-ui/coverage - rm -rf packages/patientSearchLambda/coverage - rm -rf packages/patientSearchLambda/lib - rm -rf packages/prescriptionDetailsLambda/coverage - rm -rf packages/prescriptionDetailsLambda/lib - rm -rf packages/prescriptionListLambda/coverage - rm -rf packages/prescriptionListLambda/lib - rm -rf packages/selectedRoleLambda/coverage - rm -rf packages/selectedRoleLambda/lib - rm -rf packages/trackerUserInfoLambda/coverage - rm -rf packages/trackerUserInfoLambda/lib - rm -rf packages/sessionManagementLambda/coverage - rm -rf packages/sessionManagementLambda/lib - rm -rf packages/common/authFunctions/coverage - rm -rf packages/common/authFunctions/lib - rm -rf packages/common/commonTypes/coverage - rm -rf packages/common/commonTypes/lib - rm -rf packages/common/doHSClient/coverage - rm -rf packages/common/doHSClient/lib - rm -rf packages/common/dynamoFunctions/coverage - rm -rf packages/common/dynamoFunctions/lib - rm -rf packages/common/lambdaUtils/coverage - rm -rf packages/common/lambdaUtils/lib - rm -rf packages/common/middyErrorHandler/coverage - rm -rf packages/common/middyErrorHandler/lib - rm -rf packages/common/pdsClient/coverage - rm -rf packages/common/pdsClient/lib - rm -rf packages/common/testing/coverage - rm -rf packages/common/testing/lib + find . -name 'coverage' -type d -prune -exec rm -rf '{}' + + find . -name 'lib' -type d -prune -exec rm -rf '{}' + rm -rf cdk.out rm -rf .local_config rm -rf cfn_guard_output diff --git a/package-lock.json b/package-lock.json index 7fe64dddac..81e02be57d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,6 +41,7 @@ "@types/node": "^25.1.0", "@typescript-eslint/eslint-plugin": "^8.48.0", "@typescript-eslint/parser": "^8.50.1", + "@vitest/coverage-v8": "^4.0.18", "aws-sdk-client-mock": "^4.1.0", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", @@ -55,7 +56,8 @@ "ts-jest": "^29.4.6", "ts-node": "^10.9.2", "typescript": "^5.9.3", - "typescript-eslint": "^8.52.0" + "typescript-eslint": "^8.52.0", + "vitest": "^4.0.18" } }, "node_modules/@adobe/css-tools": { @@ -222,6 +224,7 @@ "resolved": "https://registry.npmjs.org/@aws-amplify/core/-/core-6.16.0.tgz", "integrity": "sha512-YpEtvdXcC06/j3PEsQiN/AYiJh3yLK5aPijFY1SbE0rgSLt9iPPalCOh65vDjybe7SW8qdIlctcR/rROMA88ag==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/types": "3.723.0", @@ -2357,6 +2360,7 @@ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.723.0.tgz", "integrity": "sha512-9IH90m4bnHogBctVna2FnXaIGVORncfdxcqeEIovOxjIJJyHDmEAtA7B91dAM4sruddTbVzOYnqfPVst3odCbA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -2884,6 +2888,7 @@ "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.723.0.tgz", "integrity": "sha512-YyN8x4MI/jMb4LpHsLf+VYqvbColMK8aZeGWVk2fTFsmt8lpTYGaGC1yybSwGX42mZ4W8ucu8SAYSbUraJZEjA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -4560,6 +4565,7 @@ "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", @@ -5198,6 +5204,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -5221,6 +5228,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" } @@ -8772,6 +8780,13 @@ "node": ">=18.0.0" } }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, "node_modules/@swc/core": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.11.tgz", @@ -8779,6 +8794,7 @@ "dev": true, "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.25" @@ -9022,6 +9038,7 @@ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -9247,6 +9264,24 @@ "@babel/types": "^7.28.2" } }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -9345,6 +9380,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.1.0.tgz", "integrity": "sha512-t7frlewr6+cbx+9Ohpl0NOTKXZNV9xHRmNOvql47BFJKcEG1CxtxlPEEe+gR9uhVWM4DwhnvTF110mIL4yP9RA==", "license": "MIT", + "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -9362,6 +9398,7 @@ "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -9373,6 +9410,7 @@ "integrity": "sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/react": "*" } @@ -9483,6 +9521,7 @@ "integrity": "sha512-BtE0k6cjwjLZoZixN0t5AKP0kSzlGu7FctRXYuPAm//aaiZhmfq1JwdYpYr1brzEspYyFeF+8XF5j2VK6oalrA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.54.0", "@typescript-eslint/types": "8.54.0", @@ -9974,6 +10013,158 @@ "vite": "^4 || ^5 || ^6 || ^7" } }, + "node_modules/@vitest/coverage-v8": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.18.tgz", + "integrity": "sha512-7i+N2i0+ME+2JFZhfuz7Tg/FqKtilHjGyGvoHYQ6iLV0zahbsJ9sljC9OcFcPDbhYKCet+sG8SsVqlyGvPflZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.0.18", + "ast-v8-to-istanbul": "^0.3.10", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.1", + "obug": "^2.1.1", + "std-env": "^3.10.0", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "4.0.18", + "vitest": "4.0.18" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } + } + }, + "node_modules/@vitest/coverage-v8/node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@vitest/expect": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.18.tgz", + "integrity": "sha512-8sCWUyckXXYvx4opfzVY03EOiYVxyNrHS5QxX3DAIi5dpJAAkyJezHCP77VMX4HKA2LDT/Jpfo8i2r5BE3GnQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.18", + "@vitest/utils": "4.0.18", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.18.tgz", + "integrity": "sha512-HhVd0MDnzzsgevnOWCBj5Otnzobjy5wLBe4EdeeFGv8luMsGcYqDuFRMcttKWZA5vVO8RFjexVovXvAM4JoJDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.0.18", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.18.tgz", + "integrity": "sha512-P24GK3GulZWC5tz87ux0m8OADrQIUVDPIjjj65vBXYG17ZeU3qD7r+MNZ1RNv4l8CGU2vtTRqixrOi9fYk/yKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.18.tgz", + "integrity": "sha512-rpk9y12PGa22Jg6g5M3UVVnTS7+zycIGk9ZNGN+m6tZHKQb7jrP7/77WfZy13Y/EUDd52NDsLRQhYKtv7XfPQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.18", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.18.tgz", + "integrity": "sha512-PCiV0rcl7jKQjbgYqjtakly6T1uwv/5BQ9SwBLekVg/EaYeQFPiXcgrC2Y7vDMA8dM1SUEAEV82kgSQIlXNMvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.18", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.18.tgz", + "integrity": "sha512-cbQt3PTSD7P2OARdVW3qWER5EGq7PHlvE+QfzSC0lbwO+xnt7+XH06ZzFjFRgzUX//JmpxrCu92VdwvEPlWSNw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.18.tgz", + "integrity": "sha512-msMRKLMVLWygpK3u2Hybgi4MNjcYJvwTb0Ru09+fOyCXIgT5raYP041DRRdiJiI3k/2U6SEbAETB3YtBrUkCFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.18", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -9987,6 +10178,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -10292,6 +10484,35 @@ "safer-buffer": "~2.1.0" } }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-v8-to-istanbul": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.11.tgz", + "integrity": "sha512-Qya9fkoofMjCBNVdWINMjB5KZvkYfaO9/anwkWnjxibpWUxo5iHl2sOdP7/uAqaRuUYuoo8rDwnbaaKVFxoUvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" + } + }, + "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/async-function": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", @@ -11010,6 +11231,7 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz", "integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==", "license": "MIT", + "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", @@ -11237,6 +11459,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -11406,6 +11629,16 @@ "constructs": "^10.0.5" } }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -11645,7 +11878,8 @@ "version": "10.4.5", "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.5.tgz", "integrity": "sha512-fOoP70YLevMZr5avJHx2DU3LNYmC6wM8OwdrNewMZou1kZnPGOeVzBrRjZNgFDHUlulYUjkpFRSpTE3D+n+ZSg==", - "license": "Apache-2.0" + "license": "Apache-2.0", + "peer": true }, "node_modules/conventional-changelog-eslint": { "version": "6.0.0", @@ -12203,6 +12437,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -12331,6 +12572,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -12391,6 +12633,7 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -12672,6 +12915,16 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -12750,6 +13003,16 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -14279,6 +14542,7 @@ "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "30.2.0", "@jest/types": "30.2.0", @@ -14982,6 +15246,7 @@ "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", @@ -15512,6 +15777,28 @@ "lz-string": "bin/bin.js" } }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.1.tgz", + "integrity": "sha512-xrHS24IxaLrvuo613F719wvOIv9xPHFWQHuvGUBmPnCA/3MQxKI3b+r7n1jAoDHmsbC5bRhTZYR77invLAxVnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "source-map-js": "^1.2.1" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -15682,9 +15969,9 @@ } }, "node_modules/mock-jwks": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/mock-jwks/-/mock-jwks-3.2.2.tgz", - "integrity": "sha512-FEeBqYzO/pPuVe9LuaIn2oR6mzgxfQylLARMDcpQyHQOOQIrw53SEM3FdH26126RfwTfqO93kcr5hKpKxtF4rQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/mock-jwks/-/mock-jwks-3.3.5.tgz", + "integrity": "sha512-dINtHCQ5l4NTbTHHpibIjaJJw+nP7dSn5DbsgervyqwcM8mJsvdbYNV8OSrdOHKnckwbeijy7o55dCgNmhxyRQ==", "dev": true, "license": "MIT", "dependencies": { @@ -15897,6 +16184,7 @@ "resolved": "https://registry.npmjs.org/nhsuk-frontend/-/nhsuk-frontend-9.6.4.tgz", "integrity": "sha512-y0fi91jhgS1whD7jhNXKbpJ2Lmje/h5qBZ0aXmBbZdNo56805u7SsPJYxq7Uw6ffT86zQzQIxEwPwrjgSm5Whg==", "license": "MIT", + "peer": true, "workspaces": [ "." ], @@ -15909,6 +16197,7 @@ "resolved": "https://registry.npmjs.org/nhsuk-react-components/-/nhsuk-react-components-5.0.0.tgz", "integrity": "sha512-9QbYNEgLXdFaaEbrGs3IR9Gfn3M0a/6VH8a8fjPLWofl9FaP9HArpXh+eKz6D5YzUP6SmA0+0M8b84stJyBqdQ==", "license": "MIT", + "peer": true, "dependencies": { "classnames": "^2.2.6" }, @@ -16213,6 +16502,17 @@ "integrity": "sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==", "license": "MIT" }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, "node_modules/on-exit-leak-free": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", @@ -16489,6 +16789,13 @@ "url": "https://opencollective.com/express" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, "node_modules/patientSearchLambda": { "resolved": "packages/patientSearchLambda", "link": true @@ -16856,6 +17163,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -16868,6 +17176,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -17563,6 +17872,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, "node_modules/sign-out-lambda": { "resolved": "packages/CIS2SignOutLambda", "link": true @@ -17774,6 +18090,13 @@ "node": ">=8" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -17784,6 +18107,13 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", @@ -18237,6 +18567,23 @@ "node": ">=20" } }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -18278,6 +18625,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -18285,6 +18633,16 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/tinyrainbow": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", + "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tldts": { "version": "6.1.86", "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", @@ -18466,6 +18824,7 @@ "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -18640,6 +18999,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -18917,6 +19277,7 @@ "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", @@ -19005,6 +19366,99 @@ } }, "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest": { + "version": "4.0.18", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.18.tgz", + "integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@vitest/expect": "4.0.18", + "@vitest/mocker": "4.0.18", + "@vitest/pretty-format": "4.0.18", + "@vitest/runner": "4.0.18", + "@vitest/snapshot": "4.0.18", + "@vitest/spy": "4.0.18", + "@vitest/utils": "4.0.18", + "es-module-lexer": "^1.7.0", + "expect-type": "^1.2.2", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.0.18", + "@vitest/browser-preview": "4.0.18", + "@vitest/browser-webdriverio": "4.0.18", + "@vitest/ui": "4.0.18", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/picomatch": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", @@ -19220,6 +19674,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -19613,7 +20084,7 @@ }, "devDependencies": { "@types/aws-lambda": "^8.10.159", - "mock-jwks": "3.2.2", + "mock-jwks": "^3.3.5", "nock": "^14.0.10" } }, @@ -19634,7 +20105,7 @@ "devDependencies": { "@aws-sdk/client-dynamodb": "^3.980.0", "axios": "^1.13.2", - "mock-jwks": "3.2.2" + "mock-jwks": "^3.3.5" } }, "packages/common/commonTypes": { @@ -19830,7 +20301,7 @@ "@types/aws-lambda": "^8.10.159", "@types/fhir": "^0.0.41", "axios-mock-adapter": "^2.0.0", - "mock-jwks": "^3.2.2", + "mock-jwks": "^3.3.5", "nock": "^14.0.10" } }, diff --git a/package.json b/package.json index fba597ec32..6599768f27 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@types/node": "^25.1.0", "@typescript-eslint/eslint-plugin": "^8.48.0", "@typescript-eslint/parser": "^8.50.1", + "@vitest/coverage-v8": "^4.0.18", "aws-sdk-client-mock": "^4.1.0", "eslint": "^9.39.2", "eslint-config-prettier": "^10.1.8", @@ -60,7 +61,8 @@ "ts-jest": "^29.4.6", "ts-node": "^10.9.2", "typescript": "^5.9.3", - "typescript-eslint": "^8.52.0" + "typescript-eslint": "^8.52.0", + "vitest": "^4.0.18" }, "dependencies": { "conventional-changelog-eslint": "^6.0.0", diff --git a/packages/cognito/.jest/setEnvVars.js b/packages/cognito/.jest/setEnvVars.js deleted file mode 100644 index 5fe8c5a047..0000000000 --- a/packages/cognito/.jest/setEnvVars.js +++ /dev/null @@ -1,22 +0,0 @@ -process.env.TokenMappingTableName = "dummyTable" -process.env.jwtPrivateKeyArn = "dummy_jwtPrivateKeyArn" -process.env.jwtKid = "jwt_kid" -process.env.useMock = "false" - -process.env.CIS2_OIDC_ISSUER = "valid_cis2_iss" -process.env.CIS2_OIDC_CLIENT_ID = "valid_cis2_aud" -process.env.CIS2_OIDC_HOST = "https://dummy_cis2_auth.com" -process.env.CIS2_OIDCJWKS_ENDPOINT = `${process.env.CIS2_OIDC_HOST}/.well-known/jwks.json` -process.env.CIS2_USER_INFO_ENDPOINT = `${process.env.CIS2_OIDC_HOST}/userinfo` -process.env.CIS2_USER_POOL_IDP = "CIS2DummyPoolIdentityProvider" -process.env.CIS2_IDP_TOKEN_PATH = `${process.env.CIS2_OIDC_HOST}/token` - -process.env.MOCK_OIDC_ISSUER = "valid_mock_iss" -process.env.MOCK_OIDC_CLIENT_ID = "valid_mock_aud" -process.env.MOCK_OIDC_HOST = "https://dummy_mock_auth.com" -process.env.MOCK_OIDCJWKS_ENDPOINT = `${process.env.MOCK_OIDC_HOST}/.well-known/jwks.json` -process.env.MOCK_USER_INFO_ENDPOINT = `${process.env.MOCK_OIDC_HOST}/userinfo` -process.env.MOCK_USER_POOL_IDP = "MockDummyPoolIdentityProvider" -process.env.MOCK_IDP_TOKEN_PATH = `${process.env.MOCK_OIDC_HOST}/token` -process.env.APIGEE_API_KEY = "apigee_api_key" -process.env.FULL_CLOUDFRONT_DOMAIN = "cpt-ui-pr-854.dev.eps.national.nhs.uk" diff --git a/packages/cognito/jest.config.ts b/packages/cognito/jest.config.ts deleted file mode 100644 index 6865f4dc5c..0000000000 --- a/packages/cognito/jest.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import defaultConfig from "../../jest.default.config.ts" -import type {JestConfigWithTsJest} from "ts-jest" - -const jestConfig: JestConfigWithTsJest = { - ...defaultConfig, - "rootDir": "./", - setupFiles: ["/.jest/setEnvVars.js"] -} - -export default jestConfig diff --git a/packages/cognito/jest.debug.config.ts b/packages/cognito/jest.debug.config.ts deleted file mode 100644 index a306273831..0000000000 --- a/packages/cognito/jest.debug.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import config from "./jest.config" -import type {JestConfigWithTsJest} from "ts-jest" - -const debugConfig: JestConfigWithTsJest = { - ...config, - "preset": "ts-jest" -} - -export default debugConfig diff --git a/packages/cognito/package.json b/packages/cognito/package.json index 3d8487f6a6..7db6ddc0f5 100644 --- a/packages/cognito/package.json +++ b/packages/cognito/package.json @@ -6,7 +6,7 @@ "author": "NHS Digital", "license": "MIT", "scripts": { - "unit": "POWERTOOLS_DEV=true NODE_OPTIONS=--experimental-vm-modules jest --no-cache --coverage", + "unit": "POWERTOOLS_DEV=true vitest run", "lint": "eslint --max-warnings 0 --fix --config ../../eslint.config.mjs .", "compile": "tsc --build", "test": "npm run compile && npm run unit", @@ -30,7 +30,7 @@ }, "devDependencies": { "@types/aws-lambda": "^8.10.159", - "mock-jwks": "3.2.2", + "mock-jwks": "^3.3.5", "nock": "^14.0.10" } } diff --git a/packages/cognito/tests/test_authorize.test.ts b/packages/cognito/tests/test_authorize.test.ts index 92b5328321..1b0f71f934 100644 --- a/packages/cognito/tests/test_authorize.test.ts +++ b/packages/cognito/tests/test_authorize.test.ts @@ -1,19 +1,21 @@ -import {jest} from "@jest/globals" +import { + beforeEach, + describe, + expect, + it, + vi +} from "vitest" // Set environment variables before importing the handler. -process.env.IDP_AUTHORIZE_PATH = "https://example.com/authorize" -process.env.OIDC_CLIENT_ID = "cis2Client123" process.env.useMock = "true" -process.env.COGNITO_CLIENT_ID = "userPoolClient123" -process.env.FULL_CLOUDFRONT_DOMAIN = "d111111abcdef8.cloudfront.net" // Import the handler after setting the env variables and mocks. import {mockAPIGatewayProxyEvent, mockContext} from "./mockObjects" -const {handler} = await import("../src/authorize") +import {handler} from "../src/authorize" describe("authorize handler", () => { beforeEach(() => { - jest.restoreAllMocks() + vi.restoreAllMocks() }) it("should redirect to CIS2 with correct parameters", async () => { diff --git a/packages/cognito/tests/test_authorizeMock.test.ts b/packages/cognito/tests/test_authorizeMock.test.ts index 775a9b2ea7..72fac5754d 100644 --- a/packages/cognito/tests/test_authorizeMock.test.ts +++ b/packages/cognito/tests/test_authorizeMock.test.ts @@ -1,19 +1,21 @@ -import {jest} from "@jest/globals" +import { + beforeEach, + describe, + expect, + it, + vi +} from "vitest" // Set environment variables before importing the handler. -process.env.IDP_AUTHORIZE_PATH = "https://example.com/authorize" -process.env.OIDC_CLIENT_ID = "cis2Client123" process.env.useMock = "true" -process.env.COGNITO_CLIENT_ID = "userPoolClient123" -process.env.FULL_CLOUDFRONT_DOMAIN = "cpt-ui-pr-854.dev.eps.national.nhs.uk" // Import the handler after setting the env variables and mocks. import {mockAPIGatewayProxyEvent, mockContext} from "./mockObjects" -const {handler} = await import("../src/authorizeMock") +import {handler} from "../src/authorizeMock" describe("authorize mock handler", () => { beforeEach(() => { - jest.restoreAllMocks() + vi.restoreAllMocks() }) it("should redirect to CIS2 with correct parameters", async () => { diff --git a/packages/cognito/tests/test_callback.test.ts b/packages/cognito/tests/test_callback.test.ts index 62da4e6274..ae8875433d 100644 --- a/packages/cognito/tests/test_callback.test.ts +++ b/packages/cognito/tests/test_callback.test.ts @@ -1,17 +1,19 @@ -import {jest} from "@jest/globals" - import {APIGatewayProxyEvent} from "aws-lambda" - -// Set required environment variables before importing the handler. -process.env.COGNITO_DOMAIN = "cognito.example.com" +import { + beforeEach, + describe, + expect, + it, + vi +} from "vitest" // Import the handler after setting env variables and mocks. import {mockAPIGatewayProxyEvent, mockContext} from "./mockObjects" -const {handler} = await import("../src/callback") +import {handler} from "../src/callback" describe("callback handler", () => { beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("should redirect to Cognito with correct parameters", async () => { diff --git a/packages/cognito/tests/test_callbackMock.test.ts b/packages/cognito/tests/test_callbackMock.test.ts index 8808c3588a..f8e68201e1 100644 --- a/packages/cognito/tests/test_callbackMock.test.ts +++ b/packages/cognito/tests/test_callbackMock.test.ts @@ -1,17 +1,21 @@ -import {jest} from "@jest/globals" import {APIGatewayProxyEvent} from "aws-lambda" - -// Set required environment variables before importing the handler. -process.env.COGNITO_DOMAIN = "cognito.example.com" +import { + beforeEach, + describe, + expect, + it, + test, + vi +} from "vitest" // Import the handler after setting env variables and mocks. import {mockAPIGatewayProxyEvent, mockContext} from "./mockObjects" import {Logger} from "@aws-lambda-powertools/logger" -const {handler} = await import("../src/callbackMock") +import {handler} from "../src/callbackMock" describe("Callback mock handler", () => { beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) it("should redirect to pull request with correct parameters", async () => { @@ -64,7 +68,7 @@ describe("Callback mock handler", () => { test("should handle state not being a JSON object", async () => { const state = "non_json_state" - const loggerWarnSpy = jest.spyOn(Logger.prototype, "warn") + const loggerWarnSpy = vi.spyOn(Logger.prototype, "warn") const event: APIGatewayProxyEvent = { ...mockAPIGatewayProxyEvent, queryStringParameters: { diff --git a/packages/cognito/tests/test_rewriteBody.test.ts b/packages/cognito/tests/test_rewriteBody.test.ts index c7116c5506..4f1cfcf7a1 100644 --- a/packages/cognito/tests/test_rewriteBody.test.ts +++ b/packages/cognito/tests/test_rewriteBody.test.ts @@ -1,15 +1,18 @@ -import {jest} from "@jest/globals" - import jwt from "jsonwebtoken" import {Logger} from "@aws-lambda-powertools/logger" import {ParsedUrlQuery} from "querystring" +import { + describe, + expect, + it, + vi +} from "vitest" +import {rewriteRequestBody} from "../src/helpers" // mock jwt.sign before importing rewriteRequestBody -const sign = jest.spyOn(jwt, "sign") +const sign = vi.spyOn(jwt, "sign") sign.mockImplementation(() => "mocked-jwt-token") -const {rewriteRequestBody} = await import("../src/helpers") - describe("rewriteRequestBody tests", () => { const logger = new Logger() const jwtPrivateKey = "mockPrivateKey" diff --git a/packages/cognito/tests/test_token.cis2.test.ts b/packages/cognito/tests/test_token.cis2.test.ts index 25a1f89a9d..4da2c38b15 100644 --- a/packages/cognito/tests/test_token.cis2.test.ts +++ b/packages/cognito/tests/test_token.cis2.test.ts @@ -1,16 +1,37 @@ /* eslint-disable no-console */ import { - expect, + afterEach, + beforeEach, describe, + expect, it, - jest -} from "@jest/globals" + vi +} from "vitest" import createJWKSMock from "mock-jwks" import nock from "nock" import {generateKeyPairSync} from "crypto" import jwksClient from "jwks-rsa" import {OidcConfig} from "@cpt-ui-common/authFunctions" +import {handler} from "../src/token" + +const { + mockVerifyIdToken, + mockInitializeOidcConfig, + mockGetSecret, + mockInsertTokenMapping, + mockGetTokenMapping, + mockTryGetTokenMapping +} = vi.hoisted(() => { + return { + mockVerifyIdToken: vi.fn(), + mockInitializeOidcConfig: vi.fn(), + mockGetSecret: vi.fn(), + mockInsertTokenMapping: vi.fn(), + mockGetTokenMapping: vi.fn(), + mockTryGetTokenMapping: vi.fn() + } +}) // redefining readonly property of the performance object const dummyContext = { @@ -32,22 +53,7 @@ const dummyContext = { const CIS2_OIDC_ISSUER = process.env.CIS2_OIDC_ISSUER const CIS2_OIDC_CLIENT_ID = process.env.CIS2_OIDC_CLIENT_ID const CIS2_OIDC_HOST = process.env.CIS2_OIDC_HOST ?? "" -//const CIS2_OIDCJWKS_ENDPOINT = process.env.CIS2_OIDCJWKS_ENDPOINT -//const CIS2_USER_INFO_ENDPOINT = process.env.CIS2_USER_INFO_ENDPOINT const CIS2_USER_POOL_IDP = process.env.CIS2_USER_POOL_IDP -//const CIS2_IDP_TOKEN_PATH = process.env.CIS2_IDP_TOKEN_PATH ?? "" - -//const MOCK_OIDC_ISSUER = process.env.MOCK_OIDC_ISSUER -//const MOCK_OIDC_CLIENT_ID = process.env.MOCK_OIDC_CLIENT_ID -//const MOCK_OIDC_HOST = process.env.MOCK_OIDC_HOST ?? "" -//const MOCK_OIDCJWKS_ENDPOINT = process.env.MOCK_OIDCJWKS_ENDPOINT -//const MOCK_USER_INFO_ENDPOINT = process.env.MOCK_USER_INFO_ENDPOINT -//const MOCK_USER_POOL_IDP = process.env.MOCK_USER_POOL_IDP -//const MOCK_IDP_TOKEN_PATH = process.env.MOCK_IDP_TOKEN_PATH - -const mockVerifyIdToken = jest.fn() -const mockInitializeOidcConfig = jest.fn() -const mockGetSecret = jest.fn() const { privateKey @@ -63,17 +69,14 @@ const { } }) -const mockInsertTokenMapping = jest.fn() -const mockGetTokenMapping = jest.fn() -const mockTryGetTokenMapping = jest.fn() -jest.unstable_mockModule("@cpt-ui-common/dynamoFunctions", () => { +vi.mock("@cpt-ui-common/dynamoFunctions", () => { return { insertTokenMapping: mockInsertTokenMapping, getTokenMapping: mockGetTokenMapping, tryGetTokenMapping: mockTryGetTokenMapping } }) -jest.unstable_mockModule("@cpt-ui-common/authFunctions", () => { +vi.mock("@cpt-ui-common/authFunctions", () => { const verifyIdToken = mockVerifyIdToken.mockImplementation(async () => { return { sub: "foo", @@ -134,7 +137,7 @@ jest.unstable_mockModule("@cpt-ui-common/authFunctions", () => { } }) -jest.unstable_mockModule("@aws-lambda-powertools/parameters/secrets", () => { +vi.mock("@aws-lambda-powertools/parameters/secrets", () => { const getSecret = mockGetSecret.mockImplementation(async () => { return privateKey }) @@ -144,16 +147,11 @@ jest.unstable_mockModule("@aws-lambda-powertools/parameters/secrets", () => { } }) -process.env.useMock = "false" -process.env.TokenMappingTableName = "test-token-mapping-table" -process.env.SessionManagementTableName = "test-session-management-table" -const {handler} = await import("../src/token") - describe("cis2 token handler", () => { const jwks = createJWKSMock("https://dummyauth.com/") beforeEach(() => { - jest.resetModules() - jest.clearAllMocks() + vi.resetModules() + vi.clearAllMocks() jwks.start() }) @@ -291,7 +289,7 @@ describe("cis2 token handler", () => { // Should insert into token mapping table (not concurrent session) expect(mockInsertTokenMapping).toHaveBeenCalledWith( expect.anything(), - "test-token-mapping-table", // token mapping table + "dummyTable", // token mapping table { username: `${CIS2_USER_POOL_IDP}_foo`, sessionId: "session-id", @@ -339,7 +337,7 @@ describe("cis2 token handler", () => { // Should insert into token mapping table (new user) expect(mockInsertTokenMapping).toHaveBeenCalledWith( expect.anything(), - "test-token-mapping-table", // token mapping table + "dummyTable", // token mapping table { username: `${CIS2_USER_POOL_IDP}_foo`, sessionId: "session-id", @@ -356,7 +354,7 @@ describe("cis2 token handler", () => { it("creates concurrent session when user exists and last activity exactly at 15 minute boundary", async () => { // Mock Date.now() to ensure consistent timing for boundary test const fixedTime = 1000000000000 // Fixed timestamp - const dateNowSpy = jest.spyOn(Date, "now").mockReturnValue(fixedTime) + const dateNowSpy = vi.spyOn(Date, "now").mockReturnValue(fixedTime) const fifteenMinutes = 15 * 60 * 1000 mockTryGetTokenMapping.mockImplementationOnce(() => { diff --git a/packages/cognito/tests/test_token.failure.test.ts b/packages/cognito/tests/test_token.failure.test.ts index c70a379777..f9435768a0 100644 --- a/packages/cognito/tests/test_token.failure.test.ts +++ b/packages/cognito/tests/test_token.failure.test.ts @@ -1,15 +1,18 @@ /* eslint-disable no-console */ import { - expect, + afterEach, + beforeEach, describe, + expect, it, - jest -} from "@jest/globals" + vi +} from "vitest" import createJWKSMock from "mock-jwks" import {generateKeyPairSync} from "crypto" import jwksClient from "jwks-rsa" import {OidcConfig} from "@cpt-ui-common/authFunctions" +import {handler} from "../src/token" // redefining readonly property of the performance object const dummyContext = { @@ -28,9 +31,23 @@ const dummyContext = { succeed: () => console.log("Succeeded!") } -const mockVerifyIdToken = jest.fn() -const mockInitializeOidcConfig = jest.fn() -const mockGetSecret = jest.fn() +const { + mockVerifyIdToken, + mockInitializeOidcConfig, + mockGetSecret, + mockInsertTokenMapping, + mockGetTokenMapping, + mockTryGetTokenMapping +} = vi.hoisted(() => { + return { + mockVerifyIdToken: vi.fn(), + mockInitializeOidcConfig: vi.fn(), + mockGetSecret: vi.fn(), + mockInsertTokenMapping: vi.fn(), + mockGetTokenMapping: vi.fn(), + mockTryGetTokenMapping: vi.fn() + } +}) const { privateKey @@ -45,17 +62,14 @@ const { format: "pem" } }) -const mockInsertTokenMapping = jest.fn() -const mockGetTokenMapping = jest.fn() -const mockTryGetTokenMapping = jest.fn() -jest.unstable_mockModule("@cpt-ui-common/dynamoFunctions", () => { +vi.mock("@cpt-ui-common/dynamoFunctions", () => { return { insertTokenMapping: mockInsertTokenMapping, getTokenMapping: mockGetTokenMapping, tryGetTokenMapping: mockTryGetTokenMapping } }) -jest.unstable_mockModule("@cpt-ui-common/authFunctions", () => { +vi.mock("@cpt-ui-common/authFunctions", () => { const verifyIdToken = mockVerifyIdToken.mockImplementation(async () => { return { sub: "foo", @@ -115,7 +129,7 @@ jest.unstable_mockModule("@cpt-ui-common/authFunctions", () => { } }) -jest.unstable_mockModule("@aws-lambda-powertools/parameters/secrets", () => { +vi.mock("@aws-lambda-powertools/parameters/secrets", () => { const getSecret = mockGetSecret.mockImplementation(async () => { return privateKey }) @@ -125,13 +139,11 @@ jest.unstable_mockModule("@aws-lambda-powertools/parameters/secrets", () => { } }) -const {handler} = await import("../src/token") - describe("cis2 token handler tests - failures", () => { const jwks = createJWKSMock("https://dummyauth.com/") beforeEach(() => { - jest.resetModules() - jest.clearAllMocks() + vi.resetModules() + vi.clearAllMocks() jwks.start() }) diff --git a/packages/cognito/tests/test_token.mock.test.ts b/packages/cognito/tests/test_token.mock.test.ts index 86e562d14b..feb7f0d38f 100644 --- a/packages/cognito/tests/test_token.mock.test.ts +++ b/packages/cognito/tests/test_token.mock.test.ts @@ -1,28 +1,36 @@ /* eslint-disable no-console */ import { - expect, + afterEach, + beforeEach, describe, + expect, it, - jest -} from "@jest/globals" + vi +} from "vitest" import createJWKSMock from "mock-jwks" import {generateKeyPairSync} from "crypto" import jwksClient from "jwks-rsa" import {OidcConfig} from "@cpt-ui-common/authFunctions" +import {handler} from "../src/tokenMock" -process.env.MOCK_USER_INFO_ENDPOINT = "https://dummy_mock_auth.com/userinfo" -process.env.MOCK_OIDC_ISSUER = "https://dummy_mock_auth.com" -process.env.MOCK_OIDC_CLIENT_ID = "test-client-id" -process.env.MOCK_USER_POOL_IDP = "test-idp" -process.env.TokenMappingTableName = "test-token-mapping-table" -process.env.SessionManagementTableName = "test-session-management-table" -process.env.FULL_CLOUDFRONT_DOMAIN = "test.cloudfront.net" -process.env.jwtPrivateKeyArn = "test-private-key-arn" -process.env.jwtKid = "test-kid" -process.env.APIGEE_API_KEY = "test-api-key" -process.env.APIGEE_API_SECRET = "test-api-secret" -process.env.MOCK_OIDC_TOKEN_ENDPOINT = "https://internal-dev.api.service.nhs.uk/oauth2-mock/token" +const { + mockInitializeOidcConfig, + mockGetSecret, + mockInsertTokenMapping, + mockTryGetTokenMapping, + mockFetchUserInfo, + mockExchangeTokenForApigeeAccessToken +} = vi.hoisted(() => { + return { + mockInitializeOidcConfig: vi.fn(), + mockGetSecret: vi.fn(), + mockInsertTokenMapping: vi.fn().mockName("mockInsertTokenMapping"), + mockTryGetTokenMapping: vi.fn().mockName("mockTryGetTokenMapping"), + mockFetchUserInfo: vi.fn().mockName("mockFetchUserInfo"), + mockExchangeTokenForApigeeAccessToken: vi.fn().mockName("mockExchangeTokenForApigeeAccessToken") + } +}) // redefining readonly property of the performance object const dummyContext = { @@ -41,11 +49,6 @@ const dummyContext = { succeed: () => console.log("Succeeded!") } -const MOCK_OIDC_TOKEN_ENDPOINT = "https://internal-dev.api.service.nhs.uk/oauth2-mock/token" - -const mockInitializeOidcConfig = jest.fn() -const mockGetSecret = jest.fn() - const { privateKey } = generateKeyPairSync("rsa", { @@ -60,19 +63,14 @@ const { } }) -const mockInsertTokenMapping = jest.fn().mockName("mockInsertTokenMapping") -const mockTryGetTokenMapping = jest.fn().mockName("mockTryGetTokenMapping") - -jest.unstable_mockModule("@cpt-ui-common/dynamoFunctions", () => { +vi.mock("@cpt-ui-common/dynamoFunctions", () => { return { insertTokenMapping: mockInsertTokenMapping, tryGetTokenMapping: mockTryGetTokenMapping } }) -const mockFetchUserInfo = jest.fn().mockName("mockFetchUserInfo") -const mockExchangeTokenForApigeeAccessToken = jest.fn().mockName("mockExchangeTokenForApigeeAccessToken") -jest.unstable_mockModule("@cpt-ui-common/authFunctions", () => { +vi.mock("@cpt-ui-common/authFunctions", () => { const initializeOidcConfig = mockInitializeOidcConfig.mockImplementation( () => { // Create a JWKS client for cis2 and mock // this is outside functions so it can be re-used @@ -103,6 +101,7 @@ jest.unstable_mockModule("@cpt-ui-common/authFunctions", () => { cacheMaxEntries: 5, cacheMaxAge: 3600000 // 1 hour }) + const MOCK_OIDC_TOKEN_ENDPOINT = "https://internal-dev.api.service.nhs.uk/oauth2-mock/token" const mockOidcConfig: OidcConfig = { oidcIssuer: process.env["MOCK_OIDC_ISSUER"] ?? "", @@ -126,7 +125,7 @@ jest.unstable_mockModule("@cpt-ui-common/authFunctions", () => { } }) -jest.unstable_mockModule("@aws-lambda-powertools/parameters/secrets", () => { +vi.mock("@aws-lambda-powertools/parameters/secrets", () => { const getSecret = mockGetSecret.mockImplementation(async () => { return privateKey }) @@ -136,14 +135,12 @@ jest.unstable_mockModule("@aws-lambda-powertools/parameters/secrets", () => { } }) -const {handler} = await import("../src/tokenMock") - describe("token mock handler", () => { const jwks = createJWKSMock("https://dummy_mock_auth.com/") beforeEach(() => { - jest.resetModules() - jest.clearAllMocks() + vi.resetModules() + vi.clearAllMocks() jwks.start() }) @@ -344,7 +341,7 @@ describe("token mock handler", () => { // check call expect(mockInsertTokenMapping).toHaveBeenCalledWith( expect.anything(), // documentClient - "test-token-mapping-table", // tableName + "dummyTable", // tableName { username: "Mock_user_details_sub", apigeeAccessToken: "new-access-token", @@ -447,7 +444,7 @@ describe("token mock handler", () => { expect.anything(), "https://internal-dev.api.service.nhs.uk/oauth2-mock/token", expect.objectContaining({ - redirect_uri: "https://test.cloudfront.net/oauth2/mock-callback" // PR part removed + redirect_uri: "https://cpt-ui.dev.eps.national.nhs.uk/oauth2/mock-callback" // PR part removed }), expect.anything() ) @@ -491,7 +488,7 @@ describe("token mock handler", () => { // Should insert into token mapping table (not session management table) expect(mockInsertTokenMapping).toHaveBeenCalledWith( expect.anything(), - "test-token-mapping-table", // Should use token mapping table + "dummyTable", // Should use token mapping table expect.anything(), expect.anything() ) diff --git a/packages/cognito/vitest.config.ts b/packages/cognito/vitest.config.ts new file mode 100644 index 0000000000..06fcd25937 --- /dev/null +++ b/packages/cognito/vitest.config.ts @@ -0,0 +1,40 @@ +import {defineConfig, mergeConfig} from "vitest/config" +import sharedVitestConfig from "../../vitest.shared.config" + +const CIS2_OIDC_HOST = "https://dummy_cis2_auth.com" +const MOCK_OIDC_HOST = "https://dummy_mock_auth.com" + +const viteConfig = defineConfig({ + test: { + env: { + TokenMappingTableName: "dummyTable", + jwtPrivateKeyArn: "dummy_jwtPrivateKeyArn", + jwtKid: "jwt_kid", + useMock: "false", + CIS2_OIDC_ISSUER: "valid_cis2_iss", + CIS2_OIDC_CLIENT_ID: "valid_cis2_aud", + CIS2_OIDC_HOST: CIS2_OIDC_HOST, + CIS2_OIDCJWKS_ENDPOINT: `${CIS2_OIDC_HOST}/.well-known/jwks.json`, + CIS2_USER_INFO_ENDPOINT: `${CIS2_OIDC_HOST}/userinfo`, + CIS2_USER_POOL_IDP: "CIS2DummyPoolIdentityProvider", + CIS2_IDP_TOKEN_PATH: `${CIS2_OIDC_HOST}/token`, + MOCK_OIDC_ISSUER: "valid_mock_iss", + MOCK_OIDC_CLIENT_ID: "valid_mock_aud", + MOCK_OIDC_HOST: MOCK_OIDC_HOST, + MOCK_OIDCJWKS_ENDPOINT: `${MOCK_OIDC_HOST}/.well-known/jwks.json`, + MOCK_USER_INFO_ENDPOINT: `${MOCK_OIDC_HOST}/userinfo`, + MOCK_USER_POOL_IDP: "MockDummyPoolIdentityProvider", + MOCK_IDP_TOKEN_PATH: `${MOCK_OIDC_HOST}/token`, + APIGEE_API_KEY: "apigee_api_key", + FULL_CLOUDFRONT_DOMAIN: "cpt-ui-pr-854.dev.eps.national.nhs.uk", + IDP_AUTHORIZE_PATH: "https://example.com/authorize", + OIDC_CLIENT_ID: "cis2Client123", + COGNITO_CLIENT_ID: "userPoolClient123", + COGNITO_DOMAIN: "cognito.example.com", + SessionManagementTableName: "test-session-management-table", + MOCK_OIDC_TOKEN_ENDPOINT: "https://internal-dev.api.service.nhs.uk/oauth2-mock/token" + } + } +}) + +export default mergeConfig(sharedVitestConfig, viteConfig) diff --git a/packages/common/authFunctions/.jest/setEnvVars.js b/packages/common/authFunctions/.jest/setEnvVars.js deleted file mode 100644 index fb09b8ce7c..0000000000 --- a/packages/common/authFunctions/.jest/setEnvVars.js +++ /dev/null @@ -1,32 +0,0 @@ -// put any environment variable setup in here - -process.env.apigeeHost = "https://dummyApigee" -process.env.apigeeCIS2TokenEndpoint = `${process.env.apigeeHost}/cis2_token` -process.env.apigeeMockTokenEndpoint = `${process.env.apigeeHost}/mock_token` -process.env.apigeePrescriptionsEndpoint = `${process.env.apigeeHost}/prescriptions` -process.env.apigeePersonalDemographicsEndpoint = `${process.env.apigeeHost}/Patient` - -process.env.TokenMappingTableName = "dummyTable" -process.env.jwtPrivateKeyArn = "dummy_jwtPrivateKeyArn" -process.env.jwtKid = "jwt_kid" -process.env.roleId = "dummy_role" -process.env.MOCK_MODE_ENABLED = "true" - -process.env.CIS2_OIDC_ISSUER = "valid_cis2_iss" -process.env.CIS2_OIDC_CLIENT_ID = "valid_cis2_aud" -process.env.CIS2_OIDC_HOST = "https://dummyauth.com" -process.env.CIS2_OIDCJWKS_ENDPOINT = `${process.env.CIS2_OIDC_HOST}/.well-known/jwks.json` -process.env.CIS2_USER_INFO_ENDPOINT = `${process.env.CIS2_OIDC_HOST}/userinfo` -process.env.CIS2_USER_POOL_IDP = "CIS2DummyPoolIdentityProvider" -process.env.CIS2_IDP_TOKEN_PATH = `${process.env.CIS2_OIDC_HOST}/token` - -process.env.MOCK_OIDC_ISSUER = "valid_mock_iss" -process.env.MOCK_OIDC_CLIENT_ID = "valid_mock_aud" -process.env.MOCK_OIDC_HOST = "https://dummyauth.com" -process.env.MOCK_OIDCJWKS_ENDPOINT = `${process.env.MOCK_OIDC_HOST}/.well-known/jwks.json` -process.env.MOCK_USER_INFO_ENDPOINT = `${process.env.MOCK_OIDC_HOST}/userinfo` -process.env.MOCK_USER_POOL_IDP = "MockDummyPoolIdentityProvider" -process.env.MOCK_IDP_TOKEN_PATH = `${process.env.MOCK_OIDC_HOST}/token` -process.env.CIS2_IDP_TOKEN_PATH = `${process.env.CIS2_OIDC_HOST}/token` -process.env.MOCK_IDP_TOKEN_PATH = `${process.env.MOCK_OIDC_HOST}/token` -process.env.FULL_CLOUDFRONT_DOMAIN = "cpt-ui-pr-854.dev.eps.national.nhs.uk" diff --git a/packages/common/authFunctions/package.json b/packages/common/authFunctions/package.json index f4c47e9b38..1b6694ee57 100644 --- a/packages/common/authFunctions/package.json +++ b/packages/common/authFunctions/package.json @@ -6,7 +6,7 @@ "license": "MIT", "main": "lib/src/index.js", "scripts": { - "unit": "POWERTOOLS_DEV=true NODE_OPTIONS=--experimental-vm-modules jest --no-cache --coverage", + "unit": "POWERTOOLS_DEV=true vitest run --coverage", "lint": "eslint --max-warnings 0 --fix --config ../../../eslint.config.mjs .", "compile": "tsc --build", "test": "npm run compile && npm run unit", @@ -15,7 +15,7 @@ "devDependencies": { "@aws-sdk/client-dynamodb": "^3.980.0", "axios": "^1.13.2", - "mock-jwks": "3.2.2" + "mock-jwks": "^3.3.5" }, "dependencies": { "@aws-lambda-powertools/logger": "^2.30.1", diff --git a/packages/common/authFunctions/tests/test_apigeeUtils.test.ts b/packages/common/authFunctions/tests/test_apigeeUtils.test.ts index ed758d1f66..1a878db524 100644 --- a/packages/common/authFunctions/tests/test_apigeeUtils.test.ts +++ b/packages/common/authFunctions/tests/test_apigeeUtils.test.ts @@ -1,44 +1,39 @@ /* eslint-disable @typescript-eslint/consistent-type-assertions */ -import {jest} from "@jest/globals" - -import axios from "axios" +import { + afterAll, + beforeAll, + beforeEach, + describe, + expect, + it, + vi +} from "vitest" + +import type {AxiosInstance} from "axios" import {Logger} from "@aws-lambda-powertools/logger" - -jest.mock("axios") -jest.mock("jsonwebtoken") - -const mockGetTokenMapping = jest.fn() -const mockUpdateTokenMapping = jest.fn() - -jest.unstable_mockModule("@cpt-ui-common/dynamoFunctions", () => { - return { - updateTokenMapping: mockUpdateTokenMapping, - getTokenMapping: mockGetTokenMapping - } -}) +import {exchangeTokenForApigeeAccessToken, refreshApigeeAccessToken, buildApigeeHeaders} from "../src/apigee" const mockLogger: Partial = { - info: jest.fn(), - debug: jest.fn(), - error: jest.fn() + info: vi.fn(), + debug: vi.fn(), + error: vi.fn() } -const {exchangeTokenForApigeeAccessToken, - refreshApigeeAccessToken, - buildApigeeHeaders} = await import("../src/apigee") +const mockAxiosPost = vi.fn() +const axiosInstance = { + post: mockAxiosPost +} as unknown as AxiosInstance describe("apigeeUtils", () => { - const mockAxiosPost = jest.fn(); - (axios.post as unknown as jest.Mock) = mockAxiosPost beforeAll(() => { - jest.spyOn(global.crypto, "randomUUID").mockReturnValue("test-uuid-in-uuid-format") + vi.spyOn(globalThis.crypto, "randomUUID").mockReturnValue("test-uuid-in-uuid-format") }) afterAll(() => { - jest.restoreAllMocks() + vi.restoreAllMocks() }) beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() }) describe("buildApigeeHeaders", () => { @@ -68,7 +63,7 @@ describe("apigeeUtils", () => { mockAxiosPost.mockResolvedValueOnce({data: {access_token: "testToken", expires_in: 3600}} as never) const result = await exchangeTokenForApigeeAccessToken( - axios, + axiosInstance, "https://mock-endpoint", {param: "test"}, mockLogger as Logger @@ -86,7 +81,7 @@ describe("apigeeUtils", () => { mockAxiosPost.mockResolvedValueOnce({data: {}} as never) await expect( exchangeTokenForApigeeAccessToken( - axios, + axiosInstance, "https://mock-endpoint", {param: "test"}, mockLogger as Logger @@ -104,7 +99,7 @@ describe("apigeeUtils", () => { await expect( exchangeTokenForApigeeAccessToken( - axios, + axiosInstance, "https://mock-endpoint", {param: "test"}, mockLogger as Logger @@ -130,7 +125,7 @@ describe("apigeeUtils", () => { })) const result = await refreshApigeeAccessToken( - axios, + axiosInstance, "https://mock-endpoint", "old-refresh-token", "mock-api-key", @@ -161,7 +156,7 @@ describe("apigeeUtils", () => { } as never) const result = await refreshApigeeAccessToken( - axios, + axiosInstance, "https://mock-endpoint", "old-refresh-token", "mock-api-key", @@ -182,7 +177,7 @@ describe("apigeeUtils", () => { await expect( refreshApigeeAccessToken( - axios, + axiosInstance, "https://mock-endpoint", "old-refresh-token", "mock-api-key", diff --git a/packages/common/authFunctions/tests/test_authenticateRequest.test.ts b/packages/common/authFunctions/tests/test_authenticateRequest.test.ts index d0db653833..a3012fc99a 100644 --- a/packages/common/authFunctions/tests/test_authenticateRequest.test.ts +++ b/packages/common/authFunctions/tests/test_authenticateRequest.test.ts @@ -1,60 +1,86 @@ -import {jest} from "@jest/globals" +import { + beforeEach, + describe, + expect, + it, + vi +} from "vitest" import {Logger} from "@aws-lambda-powertools/logger" import {DynamoDBClient} from "@aws-sdk/client-dynamodb" import {DynamoDBDocumentClient} from "@aws-sdk/lib-dynamodb" import {AxiosInstance} from "axios" - -// Mock the jwt module -jest.mock("jsonwebtoken", () => ({ - decode: jest.fn().mockReturnValue({ - header: {kid: "test-kid"}, - payload: { - sub: "test-subject", - exp: Math.floor(Date.now() / 1000) + 3600, - acr: "AAL3_ANY" - } - }), - verify: jest.fn().mockReturnValue({ +import {authenticateRequest} from "../src/authenticateRequest" + +const { + mockJwtDecode, + mockJwtVerify, + mockJwtSign, + mockGetSecret, + mockGetUsernameFromEvent, + mockRefreshApigeeAccessToken, + mockExchangeTokenForApigeeAccessToken, + mockConstructSignedJWTBody, + mockDecodeToken, + mockVerifyIdToken, + mockUpdateTokenMapping, + mockGetTokenMapping, + mockDeleteTokenMapping +} = vi.hoisted(() => { + const jwtPayload = { sub: "test-subject", exp: Math.floor(Date.now() / 1000) + 3600, acr: "AAL3_ANY" - }), - sign: jest.fn().mockReturnValue("signed-jwt-token") -})) + } + + return { + mockJwtDecode: vi.fn().mockReturnValue({ + header: {kid: "test-kid"}, + payload: jwtPayload + }), + mockJwtVerify: vi.fn().mockReturnValue(jwtPayload), + mockJwtSign: vi.fn().mockReturnValue("signed-jwt-token"), + mockGetSecret: vi.fn().mockReturnValue("test-private-key"), + mockGetUsernameFromEvent: vi.fn().mockName("mockGetUsernameFromEvent"), + mockRefreshApigeeAccessToken: vi.fn().mockName("mockRefreshApigeeAccessToken"), + mockExchangeTokenForApigeeAccessToken: vi.fn().mockName("mockExchangeTokenForApigeeAccessToken"), + mockConstructSignedJWTBody: vi.fn().mockName("mockConstructSignedJWTBody"), + mockDecodeToken: vi.fn().mockName("mockDecodeToken"), + mockVerifyIdToken: vi.fn().mockName("mockVerifyIdToken"), + mockUpdateTokenMapping: vi.fn(), + mockGetTokenMapping: vi.fn(), + mockDeleteTokenMapping: vi.fn() + } +}) -const mockGetSecret = jest.fn().mockReturnValue("test-private-key") +vi.mock("jsonwebtoken", () => ({ + default: { + decode: mockJwtDecode, + verify: mockJwtVerify, + sign: mockJwtSign + }, + decode: mockJwtDecode, + verify: mockJwtVerify, + sign: mockJwtSign +})) -jest.unstable_mockModule("@aws-lambda-powertools/parameters/secrets", () => ({ +vi.mock("@aws-lambda-powertools/parameters/secrets", () => ({ getSecret: mockGetSecret })) -// Create mocks for the functions from the index module -const mockGetUsernameFromEvent = jest.fn().mockName("mockGetUsernameFromEvent") -const mockRefreshApigeeAccessToken = jest.fn().mockName("mockRefreshApigeeAccessToken") -const mockExchangeTokenForApigeeAccessToken = jest.fn().mockName("mockExchangeTokenForApigeeAccessToken") -const mockConstructSignedJWTBody = jest.fn().mockName("mockConstructSignedJWTBody") -const mockDecodeToken = jest.fn().mockName("mockDecodeToken") -const mockVerifyIdToken = jest.fn().mockName("mockVerifyIdToken") const dynamoClient = new DynamoDBClient() const documentClient = DynamoDBDocumentClient.from(dynamoClient) const axiosInstance = { - post: jest.fn().mockReturnValue({data: {}}), - get: jest.fn().mockReturnValue({data: {}}) + post: vi.fn().mockReturnValue({data: {}}), + get: vi.fn().mockReturnValue({data: {}}) } as unknown as AxiosInstance -const mockUpdateTokenMapping = jest.fn() -const mockGetTokenMapping = jest.fn() -const mockDeleteTokenMapping = jest.fn() -jest.unstable_mockModule("@cpt-ui-common/dynamoFunctions", () => { - return { - updateTokenMapping: mockUpdateTokenMapping, - getTokenMapping: mockGetTokenMapping, - deleteTokenMapping: mockDeleteTokenMapping - } -}) +vi.mock("@cpt-ui-common/dynamoFunctions", () => ({ + updateTokenMapping: mockUpdateTokenMapping, + getTokenMapping: mockGetTokenMapping, + deleteTokenMapping: mockDeleteTokenMapping +})) -// Mock the index module -jest.unstable_mockModule("../src/index", () => ({ +vi.mock("../src/index", () => ({ getUsernameFromEvent: mockGetUsernameFromEvent, refreshApigeeAccessToken: mockRefreshApigeeAccessToken, exchangeTokenForApigeeAccessToken: mockExchangeTokenForApigeeAccessToken, @@ -63,17 +89,14 @@ jest.unstable_mockModule("../src/index", () => ({ verifyIdToken: mockVerifyIdToken })) -const authModule = await import("../src/authenticateRequest") -const {authenticateRequest} = authModule - describe("authenticateRequest", () => { // Common test setup const mockLogger = { - info: jest.fn(), - debug: jest.fn(), - warn: jest.fn(), - error: jest.fn() + info: vi.fn(), + debug: vi.fn(), + warn: vi.fn(), + error: vi.fn() } as unknown as Logger const mockOptions = { @@ -97,7 +120,7 @@ describe("authenticateRequest", () => { beforeEach(() => { // Clear all mock implementations - jest.clearAllMocks() + vi.clearAllMocks() // Set up default mocks for all tests mockGetUsernameFromEvent.mockReturnValue("test-user") diff --git a/packages/common/authFunctions/tests/test_authenticationConcurrentAwareMiddleware.test.ts b/packages/common/authFunctions/tests/test_authenticationConcurrentAwareMiddleware.test.ts index 13d8627a62..77064f99bb 100644 --- a/packages/common/authFunctions/tests/test_authenticationConcurrentAwareMiddleware.test.ts +++ b/packages/common/authFunctions/tests/test_authenticationConcurrentAwareMiddleware.test.ts @@ -1,32 +1,42 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import {jest} from "@jest/globals" +import { + beforeEach, + describe, + expect, + it, + vi +} from "vitest" import {Logger} from "@aws-lambda-powertools/logger" import {DynamoDBClient} from "@aws-sdk/client-dynamodb" import {DynamoDBDocumentClient} from "@aws-sdk/lib-dynamodb" import {AxiosInstance} from "axios" +import {authenticationConcurrentAwareMiddleware} from "../src/authenticationConcurrentAwareMiddleware" + +const { + mockGetUsernameFromEvent, + mockGetSessionIdFromEvent, + mockAuthenticateRequest, + mockTryGetTokenMapping +} = vi.hoisted(() => ({ + mockGetUsernameFromEvent: vi.fn(), + mockGetSessionIdFromEvent: vi.fn(), + mockAuthenticateRequest: vi.fn(), + mockTryGetTokenMapping: vi.fn() +})) -// Mock dependencies -const mockGetUsernameFromEvent = jest.fn() as jest.MockedFunction -const mockGetSessionIdFromEvent = jest.fn() as jest.MockedFunction -const mockAuthenticateRequest = jest.fn() as jest.MockedFunction -const mockTryGetTokenMapping = jest.fn() as jest.MockedFunction - -jest.unstable_mockModule("../src/event", () => ({ +vi.mock("../src/event", () => ({ getUsernameFromEvent: mockGetUsernameFromEvent, getSessionIdFromEvent: mockGetSessionIdFromEvent })) -jest.unstable_mockModule("../src/authenticateRequest", () => ({ +vi.mock("../src/authenticateRequest", () => ({ authenticateRequest: mockAuthenticateRequest })) -jest.unstable_mockModule("@cpt-ui-common/dynamoFunctions", () => ({ +vi.mock("@cpt-ui-common/dynamoFunctions", () => ({ tryGetTokenMapping: mockTryGetTokenMapping })) -// Import the middleware after mocking -const {authenticationConcurrentAwareMiddleware} = await import("../src/authenticationConcurrentAwareMiddleware") - describe("authenticationConcurrentAwareMiddleware", () => { let logger: Logger let ddbClient: DynamoDBDocumentClient @@ -36,7 +46,7 @@ describe("authenticationConcurrentAwareMiddleware", () => { let mockRequest: any beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() // Reset all mock implementations and return values mockGetUsernameFromEvent.mockReset() @@ -45,16 +55,16 @@ describe("authenticationConcurrentAwareMiddleware", () => { mockTryGetTokenMapping.mockReset() logger = new Logger({serviceName: "test"}) - logger.info = jest.fn() - logger.debug = jest.fn() - logger.error = jest.fn() + logger.info = vi.fn() + logger.debug = vi.fn() + logger.error = vi.fn() const dynamoClient = new DynamoDBClient({}) ddbClient = DynamoDBDocumentClient.from(dynamoClient) axiosInstance = { - post: jest.fn(), - get: jest.fn() + post: vi.fn(), + get: vi.fn() } as unknown as AxiosInstance authOptions = { diff --git a/packages/common/authFunctions/tests/test_authenticationMiddleware.test.ts b/packages/common/authFunctions/tests/test_authenticationMiddleware.test.ts index cffb86695b..f66ec7d4cb 100644 --- a/packages/common/authFunctions/tests/test_authenticationMiddleware.test.ts +++ b/packages/common/authFunctions/tests/test_authenticationMiddleware.test.ts @@ -1,32 +1,42 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import {jest} from "@jest/globals" +import { + beforeEach, + describe, + expect, + it, + vi +} from "vitest" import {Logger} from "@aws-lambda-powertools/logger" import {DynamoDBClient} from "@aws-sdk/client-dynamodb" import {DynamoDBDocumentClient} from "@aws-sdk/lib-dynamodb" import {AxiosInstance} from "axios" +import {authenticationMiddleware} from "../src/authenticationMiddleware" + +const { + mockGetUsernameFromEvent, + mockGetSessionIdFromEvent, + mockAuthenticateRequest, + mockGetTokenMapping +} = vi.hoisted(() => ({ + mockGetUsernameFromEvent: vi.fn(), + mockGetSessionIdFromEvent: vi.fn(), + mockAuthenticateRequest: vi.fn(), + mockGetTokenMapping: vi.fn() +})) -// Mock dependencies -const mockGetUsernameFromEvent = jest.fn() as jest.MockedFunction -const mockGetSessionIdFromEvent = jest.fn() as jest.MockedFunction -const mockAuthenticateRequest = jest.fn() as jest.MockedFunction -const mockGetTokenMapping = jest.fn() as jest.MockedFunction - -jest.unstable_mockModule("../src/event", () => ({ +vi.mock("../src/event", () => ({ getUsernameFromEvent: mockGetUsernameFromEvent, getSessionIdFromEvent: mockGetSessionIdFromEvent })) -jest.unstable_mockModule("../src/authenticateRequest", () => ({ +vi.mock("../src/authenticateRequest", () => ({ authenticateRequest: mockAuthenticateRequest })) -jest.unstable_mockModule("@cpt-ui-common/dynamoFunctions", () => ({ +vi.mock("@cpt-ui-common/dynamoFunctions", () => ({ getTokenMapping: mockGetTokenMapping })) -// Import the middleware after mocking -const {authenticationMiddleware} = await import("../src/authenticationMiddleware") - describe("authenticationMiddleware", () => { let logger: Logger let ddbClient: DynamoDBDocumentClient @@ -36,18 +46,18 @@ describe("authenticationMiddleware", () => { let mockRequest: any beforeEach(() => { - jest.clearAllMocks() + vi.clearAllMocks() logger = new Logger({serviceName: "test"}) - logger.info = jest.fn() - logger.error = jest.fn() + logger.info = vi.fn() + logger.error = vi.fn() const dynamoClient = new DynamoDBClient({}) ddbClient = DynamoDBDocumentClient.from(dynamoClient) axiosInstance = { - post: jest.fn(), - get: jest.fn() + post: vi.fn(), + get: vi.fn() } as unknown as AxiosInstance authOptions = { diff --git a/packages/common/authFunctions/tests/test_cis2TokenHelpers.test.ts b/packages/common/authFunctions/tests/test_cis2TokenHelpers.test.ts index 3c006fde8d..9bbe758454 100644 --- a/packages/common/authFunctions/tests/test_cis2TokenHelpers.test.ts +++ b/packages/common/authFunctions/tests/test_cis2TokenHelpers.test.ts @@ -1,30 +1,26 @@ -import {jest} from "@jest/globals" +import { + afterAll, + beforeAll, + beforeEach, + describe, + expect, + it, + vi +} from "vitest" import {APIGatewayProxyEvent} from "aws-lambda" import {Logger} from "@aws-lambda-powertools/logger" import jwksClient from "jwks-rsa" import jwt from "jsonwebtoken" import createJWKSMock from "mock-jwks" +import {getSigningKey, verifyIdToken} from "../src/cis2" +import {getUsernameFromEvent} from "../src/event" -const mockUpdateTokenMapping = jest.fn() -const mockGetTokenMapping = jest.fn() -jest.unstable_mockModule("@cpt-ui-common/dynamoFunctions", () => { - - return { - updateTokenMapping: mockUpdateTokenMapping, - getTokenMapping: mockGetTokenMapping - } -}) - -const {getSigningKey, - verifyIdToken} = await import("../src/cis2") - -const {getUsernameFromEvent} = await import("../src/event") // Common test setup const logger = new Logger() -const oidcClientId = "valid_aud" -const oidcIssuer = "valid_iss" -const jwksEndpoint = "https://dummyauth.com/.well-known/jwks.json" +const oidcClientId = process.env["CIS2_OIDC_CLIENT_ID"] +const oidcIssuer = process.env["CIS2_OIDC_ISSUER"] +const jwksEndpoint = process.env["CIS2_OIDCJWKS_ENDPOINT"] let jwksMock: ReturnType let stopJwksMock: () => void @@ -39,7 +35,7 @@ afterAll(() => { }) beforeEach(() => { - jest.restoreAllMocks() + vi.restoreAllMocks() }) interface TokenPayload { @@ -87,7 +83,7 @@ describe("getSigningKey", () => { }) beforeEach(() => { - jest.restoreAllMocks() + vi.restoreAllMocks() }) // it("should return the signing key when key is found", async () => { @@ -139,19 +135,19 @@ describe("getUsernameFromEvent", () => { describe("verifyIdToken", () => { beforeAll(() => { - jest.resetAllMocks() + vi.resetAllMocks() }) it("should verify a valid ID token", async () => { const payload = createPayload() const token = createToken(payload) - jest.spyOn(jwt, "verify").mockImplementation(() => payload) + vi.spyOn(jwt, "verify").mockImplementation(() => payload) await expect(verifyIdToken(token, logger)).resolves.toMatchObject(expect.objectContaining( { "acr": "AAL3_ANY", - "aud": ["valid_aud"], - "iss": "valid_iss" + "aud": ["valid_cis2_aud"], + "iss": "valid_cis2_iss" } )) }) @@ -168,7 +164,7 @@ describe("verifyIdToken", () => { const payload = createPayload() const token = createToken(payload) - jest.spyOn(jwt, "decode").mockReturnValueOnce({header: {}}) + vi.spyOn(jwt, "decode").mockReturnValueOnce({header: {}}) await expect(verifyIdToken(token, logger)).rejects.toThrow("Invalid token - no KID present") }) @@ -177,7 +173,7 @@ describe("verifyIdToken", () => { const payload = createPayload() const token = createToken(payload) - jest.spyOn(jwt, "verify").mockImplementation(() => { + vi.spyOn(jwt, "verify").mockImplementation(() => { throw new Error("Invalid signature") }) @@ -217,7 +213,7 @@ describe("verifyIdToken", () => { it("should throw an error when ACR claim is invalid", async () => { const payload = createPayload({acr: "INVALID_ACR"}) const token = createToken(payload) - jest.spyOn(jwt, "verify").mockImplementation(() => payload) + vi.spyOn(jwt, "verify").mockImplementation(() => payload) await expect(verifyIdToken(token, logger)).rejects.toThrow( "Invalid ACR claim in ID token" diff --git a/packages/common/authFunctions/tests/test_constructSignedJWTBody.test.ts b/packages/common/authFunctions/tests/test_constructSignedJWTBody.test.ts index ff18a5d54a..87f9f2a2ff 100644 --- a/packages/common/authFunctions/tests/test_constructSignedJWTBody.test.ts +++ b/packages/common/authFunctions/tests/test_constructSignedJWTBody.test.ts @@ -1,21 +1,18 @@ -import {jest} from "@jest/globals" +import { + describe, + expect, + it, + vi +} from "vitest" import jwt from "jsonwebtoken" import {Logger} from "@aws-lambda-powertools/logger" - -const mockGetTokenMapping = jest.fn() -jest.unstable_mockModule("@cpt-ui-common/dynamoFunctions", () => { - return { - getTokenMapping: mockGetTokenMapping - } -}) +import {constructSignedJWTBody} from "../src/apigee" // mock jwt.sign before importing constructSignedJWTBody -const sign = jest.spyOn(jwt, "sign") +const sign = vi.spyOn(jwt, "sign") sign.mockImplementation(() => "mocked-jwt-token") -const {constructSignedJWTBody} = await import("../src/apigee") - describe("constructSignedJWTBody tests", () => { const logger = new Logger() const jwtPrivateKey = "mockPrivateKey" diff --git a/packages/common/authFunctions/tests/test_userInfoHelpers.test.ts b/packages/common/authFunctions/tests/test_userInfoHelpers.test.ts index 8682e5ef2a..74df3a36b9 100644 --- a/packages/common/authFunctions/tests/test_userInfoHelpers.test.ts +++ b/packages/common/authFunctions/tests/test_userInfoHelpers.test.ts @@ -1,56 +1,59 @@ -import {jest} from "@jest/globals" +import { + afterEach, + beforeEach, + describe, + expect, + it, + vi +} from "vitest" import {Logger} from "@aws-lambda-powertools/logger" import axios from "axios" import jwksClient from "jwks-rsa" +import {fetchUserInfo} from "../src/userInfoHelpers" const oidcClientId = "valid_aud" const oidcIssuer = "valid_iss" const jwksEndpoint = "https://dummyauth.com/.well-known/jwks.json" +const { + mockExtractRoleInformation, + mockVerifyIdToken, + mockDecodeToken +} = vi.hoisted(() => ({ + mockExtractRoleInformation: vi.fn(), + mockVerifyIdToken: vi.fn(), + mockDecodeToken: vi.fn() +})) + const mockLogger: Partial = { - info: jest.fn(), - debug: jest.fn(), - error: jest.fn(), - warn: jest.fn() + info: vi.fn(), + debug: vi.fn(), + error: vi.fn(), + warn: vi.fn() } -const mockExtractRoleInformation = jest.fn() - -jest.unstable_mockModule("@cpt-ui-common/dynamoFunctions", () => { - return { - extractRoleInformation: mockExtractRoleInformation - } -}) - -const mockVerifyIdToken = jest.fn() -const mockDecodeToken = jest.fn() +vi.mock("@cpt-ui-common/dynamoFunctions", () => ({ + extractRoleInformation: mockExtractRoleInformation +})) // We need a dummy verification to pass so we can decode out the selected role ID -jest.unstable_mockModule("../src/cis2", async () => { - const verifyIdToken = mockVerifyIdToken.mockImplementation(async () => { - return { - selected_roleid: "role-id-1" - } - }) +vi.mock("../src/cis2", () => { + mockVerifyIdToken.mockImplementation(async () => ({ + selected_roleid: "role-id-1" + })) - const decodeToken = mockDecodeToken.mockImplementation(() => { - return { - selected_roleid: "role-id-1" - } - }) + mockDecodeToken.mockImplementation(() => ({ + selected_roleid: "role-id-1" + })) return { __esModule: true, - // This will need to be made to return the decoded ID token, which should be like: - // { selected_roleid: "foo" } - verifyIdToken: verifyIdToken, - decodeToken: decodeToken + verifyIdToken: mockVerifyIdToken, + decodeToken: mockDecodeToken } }) -const {fetchUserInfo} = await import("../src/userInfoHelpers") - describe("fetchUserInfo", () => { const accessToken = "test-access-token" const idToken = "test-id-token" @@ -75,7 +78,7 @@ describe("fetchUserInfo", () => { } beforeEach(() => { - jest.restoreAllMocks() + vi.restoreAllMocks() }) afterEach(() => { @@ -136,7 +139,7 @@ describe("fetchUserInfo", () => { ] } - const getSpy = jest.spyOn(axios, "get").mockResolvedValue({data}) + const getSpy = vi.spyOn(axios, "get").mockResolvedValue({data}) mockVerifyIdToken.mockImplementation(async () => { return { @@ -281,7 +284,7 @@ describe("fetchUserInfo", () => { ] } - const getSpy = jest.spyOn(axios, "get").mockResolvedValue({data}) + const getSpy = vi.spyOn(axios, "get").mockResolvedValue({data}) mockVerifyIdToken.mockImplementation(async () => { return { @@ -390,7 +393,7 @@ describe("fetchUserInfo", () => { }) it("should throw an error if axios request fails", async () => { - jest.spyOn(axios, "get").mockRejectedValue(new Error("Network error")) + vi.spyOn(axios, "get").mockRejectedValue(new Error("Network error")) await expect( fetchUserInfo( diff --git a/packages/common/authFunctions/vitest.config.ts b/packages/common/authFunctions/vitest.config.ts new file mode 100644 index 0000000000..2d790760a4 --- /dev/null +++ b/packages/common/authFunctions/vitest.config.ts @@ -0,0 +1,43 @@ +import {defineConfig, mergeConfig} from "vitest/config" +import sharedVitestConfig from "../../../vitest.shared.config" + +const apigeeHost = "https://dummyApigee" +const CIS2_OIDC_HOST = "https://dummy_cis2_auth.com" +const MOCK_OIDC_HOST = "https://dummy_mock_auth.com" + +const viteConfig = defineConfig({ + test: { + env: { + apigeeHost: apigeeHost, + apigeeCIS2TokenEndpoint: `${apigeeHost}/cis2_token`, + apigeeMockTokenEndpoint: `${apigeeHost}/mock_token`, + apigeePrescriptionsEndpoint: `${apigeeHost}/prescriptions`, + apigeePersonalDemographicsEndpoint: `${apigeeHost}/Patient`, + + TokenMappingTableName: "dummyTable", + jwtPrivateKeyArn: "dummy_jwtPrivateKeyArn", + jwtKid: "jwt_kid", + roleId: "dummy_role", + MOCK_MODE_ENABLED: "true", + + CIS2_OIDC_ISSUER: "valid_cis2_iss", + CIS2_OIDC_CLIENT_ID: "valid_cis2_aud", + CIS2_OIDC_HOST: CIS2_OIDC_HOST, + CIS2_OIDCJWKS_ENDPOINT: `${CIS2_OIDC_HOST}/.well-known/jwks.json`, + CIS2_USER_INFO_ENDPOINT: `${CIS2_OIDC_HOST}/userinfo`, + CIS2_USER_POOL_IDP: "CIS2DummyPoolIdentityProvider", + CIS2_IDP_TOKEN_PATH: `${CIS2_OIDC_HOST}/token`, + + MOCK_OIDC_ISSUER: "valid_mock_iss", + MOCK_OIDC_CLIENT_ID: "valid_mock_aud", + MOCK_OIDC_HOST: MOCK_OIDC_HOST, + MOCK_OIDCJWKS_ENDPOINT: `${MOCK_OIDC_HOST}/.well-known/jwks.json`, + MOCK_USER_INFO_ENDPOINT: `${MOCK_OIDC_HOST}/userinfo`, + MOCK_USER_POOL_IDP: "MockDummyPoolIdentityProvider", + MOCK_IDP_TOKEN_PATH: `${MOCK_OIDC_HOST}/token`, + FULL_CLOUDFRONT_DOMAIN: "cpt-ui-pr-854.dev.eps.national.nhs.uk" + } + } +}) + +export default mergeConfig(sharedVitestConfig, viteConfig) diff --git a/packages/prescriptionDetailsLambda/.jest/setEnvVars.js b/packages/prescriptionDetailsLambda/.jest/setEnvVars.js deleted file mode 100644 index 1a68ba2808..0000000000 --- a/packages/prescriptionDetailsLambda/.jest/setEnvVars.js +++ /dev/null @@ -1,28 +0,0 @@ - -process.env.apigeeHost = "https://dummyApigee" -process.env.apigeeCIS2TokenEndpoint = `${process.env.apigeeHost}/cis2_token` -process.env.apigeeMockTokenEndpoint = `${process.env.apigeeHost}/mock_token` -process.env.apigeePrescriptionsEndpoint = `${process.env.apigeeHost}/prescriptions` -process.env.apigeePersonalDemographicsEndpoint = `${process.env.apigeeHost}/Patient` - -process.env.TokenMappingTableName = "dummyTable" -process.env.jwtPrivateKeyArn = "dummy_jwtPrivateKeyArn" -process.env.jwtKid = "jwt_kid" -process.env.roleId = "dummy_role" -process.env.MOCK_MODE_ENABLED = "true" - -process.env.CIS2_OIDC_ISSUER = "valid_cis2_iss" -process.env.CIS2_OIDC_CLIENT_ID = "valid_cis2_aud" -process.env.CIS2_OIDC_HOST = "https://dummy_cis2_auth.com" -process.env.CIS2_OIDCJWKS_ENDPOINT = `${process.env.CIS2_OIDC_HOST}/.well-known/jwks.json` -process.env.CIS2_USER_INFO_ENDPOINT = `${process.env.CIS2_OIDC_HOST}/userinfo` -process.env.CIS2_USER_POOL_IDP = "CIS2DummyPoolIdentityProvider" -process.env.CIS2_IDP_TOKEN_PATH = `${process.env.CIS2_OIDC_HOST}/token` - -process.env.MOCK_OIDC_ISSUER = "valid_mock_iss" -process.env.MOCK_OIDC_CLIENT_ID = "valid_mock_aud" -process.env.MOCK_OIDC_HOST = "https://dummy_mock_auth.com" -process.env.MOCK_OIDCJWKS_ENDPOINT = `${process.env.MOCK_OIDC_HOST}/.well-known/jwks.json` -process.env.MOCK_USER_INFO_ENDPOINT = `${process.env.MOCK_OIDC_HOST}/userinfo` -process.env.MOCK_USER_POOL_IDP = "MockDummyPoolIdentityProvider" -process.env.MOCK_IDP_TOKEN_PATH = `${process.env.MOCK_OIDC_HOST}/token` diff --git a/packages/prescriptionDetailsLambda/jest.config.ts b/packages/prescriptionDetailsLambda/jest.config.ts deleted file mode 100644 index 1ad45dd190..0000000000 --- a/packages/prescriptionDetailsLambda/jest.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -import defaultConfig from "../../jest.default.config.ts" -import type {JestConfigWithTsJest} from "ts-jest" - -const jestConfig: JestConfigWithTsJest = { - ...defaultConfig, - rootDir: "./", - setupFiles: ["/.jest/setEnvVars.js"] -} - -export default jestConfig diff --git a/packages/prescriptionDetailsLambda/jest.debug.config.ts b/packages/prescriptionDetailsLambda/jest.debug.config.ts deleted file mode 100644 index a306273831..0000000000 --- a/packages/prescriptionDetailsLambda/jest.debug.config.ts +++ /dev/null @@ -1,9 +0,0 @@ -import config from "./jest.config" -import type {JestConfigWithTsJest} from "ts-jest" - -const debugConfig: JestConfigWithTsJest = { - ...config, - "preset": "ts-jest" -} - -export default debugConfig diff --git a/packages/prescriptionDetailsLambda/package.json b/packages/prescriptionDetailsLambda/package.json index 76a138db7f..efab63791c 100644 --- a/packages/prescriptionDetailsLambda/package.json +++ b/packages/prescriptionDetailsLambda/package.json @@ -6,7 +6,7 @@ "author": "NHS Digital", "license": "MIT", "scripts": { - "unit": "POWERTOOLS_DEV=true NODE_OPTIONS=--experimental-vm-modules jest --no-cache --coverage", + "unit": "POWERTOOLS_DEV=true vitest run --coverage", "lint": "eslint --max-warnings 0 --fix --config ../../eslint.config.mjs .", "compile": "tsc --build", "test": "npm run compile && npm run unit", @@ -23,8 +23,8 @@ "@cpt-ui-common/authFunctions": "^1.0.0", "@cpt-ui-common/common-types": "^1.0.0", "@cpt-ui-common/doHSClient": "^1.0.0", - "@cpt-ui-common/middyErrorHandler": "^1.0.0", "@cpt-ui-common/lambdaUtils": "^1.0.0", + "@cpt-ui-common/middyErrorHandler": "^1.0.0", "@cpt-ui-common/pdsClient": "^1.0.0", "@middy/core": "^7.0.2", "@middy/input-output-logger": "^7.0.2", @@ -37,7 +37,7 @@ "@types/aws-lambda": "^8.10.159", "@types/fhir": "^0.0.41", "axios-mock-adapter": "^2.0.0", - "mock-jwks": "^3.2.2", + "mock-jwks": "^3.3.5", "nock": "^14.0.10" } } diff --git a/packages/prescriptionDetailsLambda/tests/test_extensionUtils.test.ts b/packages/prescriptionDetailsLambda/tests/test_extensionUtils.test.ts index 7463799573..920495d471 100644 --- a/packages/prescriptionDetailsLambda/tests/test_extensionUtils.test.ts +++ b/packages/prescriptionDetailsLambda/tests/test_extensionUtils.test.ts @@ -1,4 +1,6 @@ +import {describe, expect, it} from "vitest" + import {Extension} from "fhir/r4" import { findExtensionByKey, diff --git a/packages/prescriptionDetailsLambda/tests/test_getPatientDetails.test.ts b/packages/prescriptionDetailsLambda/tests/test_getPatientDetails.test.ts index 705a9f0c50..833c616aca 100644 --- a/packages/prescriptionDetailsLambda/tests/test_getPatientDetails.test.ts +++ b/packages/prescriptionDetailsLambda/tests/test_getPatientDetails.test.ts @@ -1,4 +1,10 @@ -import {jest} from "@jest/globals" +import { + afterAll, + describe, + expect, + it, + vi +} from "vitest" import {Logger} from "@aws-lambda-powertools/logger" import {PatientSummary} from "@cpt-ui-common/common-types" @@ -6,19 +12,41 @@ import {PatientSummary} from "@cpt-ui-common/common-types" const apigeePersonalDemographicsEndpoint = process.env.apigeePersonalDemographicsEndpoint as string ?? "" const logger: Logger = new Logger({serviceName: "getPatientDetails", logLevel: "DEBUG"}) -const mockGetPatientDetails = jest.fn() -jest.unstable_mockModule("@cpt-ui-common/pdsClient", () => ({ - Client: jest.fn().mockImplementation(() => ({ - with_access_token: jest.fn().mockImplementation(() => ({ - with_role_id: jest.fn().mockImplementation(() => ({ - with_org_code: jest.fn().mockImplementation(() => ({ - with_correlation_id:jest.fn().mockImplementation(() => ({ - getPatientDetails: mockGetPatientDetails - })) - })) - })) - })) - })), +const { + mockGetPatientDetails, + mockClient +} = vi.hoisted(() => { + const mockGetPatientDetails = vi.fn() + const mockWithCorrelationId = vi.fn().mockImplementation(() => ({ + getPatientDetails: mockGetPatientDetails + })) + const mockWithOrgCode = vi.fn().mockImplementation(() => ({ + with_correlation_id: mockWithCorrelationId + })) + const mockWithRoleId = vi.fn().mockImplementation(() => ({ + with_org_code: mockWithOrgCode + })) + const mockWithAccessToken = vi.fn().mockImplementation(() => ({ + with_role_id: mockWithRoleId + })) + const mockClient = vi.fn().mockImplementation(function () { + return { + with_access_token: mockWithAccessToken + } + }) + + return { + mockGetPatientDetails, + mockClient, + mockWithAccessToken, + mockWithRoleId, + mockWithOrgCode, + mockWithCorrelationId + } +}) + +vi.mock("@cpt-ui-common/pdsClient", () => ({ + Client: mockClient, patientDetails: { OutcomeType: { SUCCESS: "SUCCESS", @@ -48,8 +76,8 @@ const {getPatientDetails} = await import("../src/services/getPatientDetails") describe("Get Patient Details", () => { afterAll(() => { - jest.resetModules() - jest.resetAllMocks() + vi.resetModules() + vi.clearAllMocks() }) it("returns patient details when PDS called successfully", async () => { diff --git a/packages/prescriptionDetailsLambda/tests/test_handler.test.ts b/packages/prescriptionDetailsLambda/tests/test_handler.test.ts index 7ab8bf5110..d8cd32d205 100644 --- a/packages/prescriptionDetailsLambda/tests/test_handler.test.ts +++ b/packages/prescriptionDetailsLambda/tests/test_handler.test.ts @@ -1,34 +1,51 @@ -import {jest} from "@jest/globals" +import { + beforeEach, + describe, + expect, + it, + vi +} from "vitest" import {mockAPIGatewayProxyEvent, mockContext, mockMergedResponse} from "./mockObjects" import {Logger} from "@aws-lambda-powertools/logger" import {AxiosInstance} from "axios" import {AuthenticateRequestOptions} from "@cpt-ui-common/authFunctions" import {DynamoDBDocumentClient} from "@aws-sdk/lib-dynamodb" +import {newHandler} from "../src/handler" + +const { + mockProcessPrescriptionRequest, + mockAuthParametersFromEnv, + mockBuildApigeeHeaders, + mockAuthenticationMiddleware +} = vi.hoisted(() => { + return { + mockProcessPrescriptionRequest: vi.fn(() => Promise.resolve(mockMergedResponse)), + mockAuthParametersFromEnv: vi.fn(), + mockBuildApigeeHeaders: vi.fn(), + mockAuthenticationMiddleware: vi.fn(() => ({before: () => {}})) + } +}) -const mockProcessPrescriptionRequest = jest.fn(() => Promise.resolve(mockMergedResponse)) -jest.unstable_mockModule("../src/services/prescriptionService", () => { +vi.mock("../src/services/prescriptionService", () => { return { processPrescriptionRequest: mockProcessPrescriptionRequest } }) -// Needed to avoid issues with ESM imports in jest -jest.unstable_mockModule("@cpt-ui-common/authFunctions", () => ({ - authParametersFromEnv: jest.fn(), - buildApigeeHeaders: jest.fn(), - authenticationMiddleware: () => ({before: () => {}}) +// Needed to avoid issues with ESM imports in vitest +vi.mock("@cpt-ui-common/authFunctions", () => ({ + authParametersFromEnv: mockAuthParametersFromEnv, + buildApigeeHeaders: mockBuildApigeeHeaders, + authenticationMiddleware: mockAuthenticationMiddleware })) -// Import the handler after the mocks have been defined. -const {newHandler} = await import("../src/handler") - describe("Lambda Handler Tests", () => { // Create copy of the event for testing. let logger = new Logger({serviceName: "prescriptionDetailsLambda"}) - logger.warn = jest.fn() - logger.error = jest.fn() - logger.info = jest.fn() + logger.warn = vi.fn() + logger.error = vi.fn() + logger.info = vi.fn() const handler = newHandler({ errorResponseBody: {message: "A system error has occurred"}, logger: logger, @@ -43,8 +60,8 @@ describe("Lambda Handler Tests", () => { beforeEach(() => { // Reset mocks before each test. - jest.resetModules() - jest.clearAllMocks() + vi.resetModules() + vi.clearAllMocks() event.pathParameters = {prescriptionId: "dummy_prescription_id"} event.requestContext.authorizer = {roleId: "dummy_role", orgCode: "dummy_org"} }) diff --git a/packages/prescriptionDetailsLambda/tests/test_prescriptionService.test.ts b/packages/prescriptionDetailsLambda/tests/test_prescriptionService.test.ts index 8aabae7f75..7b84375eed 100644 --- a/packages/prescriptionDetailsLambda/tests/test_prescriptionService.test.ts +++ b/packages/prescriptionDetailsLambda/tests/test_prescriptionService.test.ts @@ -1,38 +1,60 @@ /* eslint-disable max-len */ -import {jest} from "@jest/globals" +import { + afterEach, + beforeEach, + describe, + expect, + it, + vi +} from "vitest" import nock from "nock" import type {Logger} from "@aws-lambda-powertools/logger" +const { + mockUuid, + mockDoHSClient, + mockGetPatient, + mockMergePrescriptionDetails, + mockAuthParametersFromEnv, + mockBuildApigeeHeaders, + mockAuthenticationMiddleware +} = vi.hoisted(() => ({ + mockUuid: vi.fn(() => "test-uuid"), + mockDoHSClient: vi.fn(), + mockGetPatient: vi.fn(), + mockMergePrescriptionDetails: vi.fn(), + mockAuthParametersFromEnv: vi.fn(), + mockBuildApigeeHeaders: vi.fn().mockImplementation(() => ({ + Authorization: "Bearer someAccessToken" + })), + mockAuthenticationMiddleware: vi.fn(() => ({before: () => {}})) +})) + // Mock uuid so that it is predictable. -jest.unstable_mockModule("uuid", () => ({ - v4: jest.fn(() => "test-uuid") +vi.mock("uuid", () => ({ + v4: mockUuid })) // Create a mock for the doHSClient function. -const mockDoHSClient = jest.fn() -jest.unstable_mockModule("@cpt-ui-common/doHSClient", () => ({ +vi.mock("@cpt-ui-common/doHSClient", () => ({ doHSClient: mockDoHSClient })) -const mockGetPatient = jest.fn() -jest.unstable_mockModule("../src/services/getPatientDetails", () => ({ +vi.mock("../src/services/getPatientDetails", () => ({ getPatientDetails: mockGetPatient })) // Mock mergePrescriptionDetails from responseMapper. -const mockMergePrescriptionDetails = jest.fn() -jest.unstable_mockModule("../src/utils/responseMapper", () => ({ +vi.mock("../src/utils/responseMapper", () => ({ mergePrescriptionDetails: mockMergePrescriptionDetails })) -// Needed to avoid issues with ESM imports in jest -jest.unstable_mockModule("@cpt-ui-common/authFunctions", () => ({ - authParametersFromEnv: jest.fn(), - buildApigeeHeaders: jest.fn().mockImplementation(() => ({ - Authorization: `Bearer someAccessToken` - })), - authenticationMiddleware: () => ({before: () => {}}) +// Needed to avoid issues with ESM imports in vitest +vi.mock("@cpt-ui-common/authFunctions", () => ({ + authParametersFromEnv: mockAuthParametersFromEnv, + buildApigeeHeaders: mockBuildApigeeHeaders, + authenticationMiddleware: mockAuthenticationMiddleware })) // Import some mock objects to use in our tests. @@ -70,13 +92,13 @@ describe("prescriptionService", () => { let logger: Logger beforeEach(() => { - jest.restoreAllMocks() + vi.clearAllMocks() // Clean up any pending nock interceptors nock.cleanAll() logger = { - info: jest.fn(), - warn: jest.fn(), - error: jest.fn() + info: vi.fn(), + warn: vi.fn(), + error: vi.fn() } as unknown as Logger }) diff --git a/packages/prescriptionDetailsLambda/tests/test_responseMapper.test.ts b/packages/prescriptionDetailsLambda/tests/test_responseMapper.test.ts index 2109facd8d..238c8d1d10 100644 --- a/packages/prescriptionDetailsLambda/tests/test_responseMapper.test.ts +++ b/packages/prescriptionDetailsLambda/tests/test_responseMapper.test.ts @@ -1,3 +1,10 @@ +import { + beforeEach, + describe, + expect, + it +} from "vitest" + import { Bundle, FhirResource, diff --git a/packages/prescriptionDetailsLambda/vitest.config.ts b/packages/prescriptionDetailsLambda/vitest.config.ts new file mode 100644 index 0000000000..fa6978adda --- /dev/null +++ b/packages/prescriptionDetailsLambda/vitest.config.ts @@ -0,0 +1,38 @@ +import {defineConfig, mergeConfig} from "vitest/config" +import sharedVitestConfig from "../../vitest.shared.config" + +const apigeeHost = "https://dummyApigee" +const CIS2_OIDC_HOST = "https://dummy_cis2_auth.com" +const MOCK_OIDC_HOST = "https://dummy_mock_auth.com" +const viteConfig = defineConfig({ + test: { + env: { + apigeeHost: apigeeHost, + apigeeCIS2TokenEndpoint: `${apigeeHost}/cis2_token`, + apigeeMockTokenEndpoint: `${apigeeHost}/mock_token`, + apigeePrescriptionsEndpoint: `${apigeeHost}/prescriptions`, + apigeePersonalDemographicsEndpoint: `${apigeeHost}/Patient`, + TokenMappingTableName: "dummyTable", + jwtPrivateKeyArn: "dummy_jwtPrivateKeyArn", + jwtKid: "jwt_kid", + roleId: "dummy_role", + MOCK_MODE_ENABLED: "true", + CIS2_OIDC_ISSUER: "valid_cis2_iss", + CIS2_OIDC_CLIENT_ID: "valid_cis2_aud", + CIS2_OIDC_HOST: CIS2_OIDC_HOST, + CIS2_OIDCJWKS_ENDPOINT: `${CIS2_OIDC_HOST}/.well-known/jwks.json`, + CIS2_USER_INFO_ENDPOINT: `${CIS2_OIDC_HOST}/userinfo`, + CIS2_USER_POOL_IDP: "CIS2DummyPoolIdentityProvider", + CIS2_IDP_TOKEN_PATH: `${CIS2_OIDC_HOST}/token`, + MOCK_OIDC_ISSUER: "valid_mock_iss", + MOCK_OIDC_CLIENT_ID: "valid_mock_aud", + MOCK_OIDC_HOST: MOCK_OIDC_HOST, + MOCK_OIDCJWKS_ENDPOINT: `${MOCK_OIDC_HOST}/.well-known/jwks.json`, + MOCK_USER_INFO_ENDPOINT: `${MOCK_OIDC_HOST}/userinfo`, + MOCK_USER_POOL_IDP: "MockDummyPoolIdentityProvider", + MOCK_IDP_TOKEN_PATH: `${MOCK_OIDC_HOST}/token` + } + } +}) + +export default mergeConfig(sharedVitestConfig, viteConfig) diff --git a/sonar-project.properties b/sonar-project.properties index daea086451..b9c9a102ba 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -12,14 +12,16 @@ sonar.coverage.exclusions=\ release.config.js, \ packages/cdk/**, \ packages/cpt-ui/next.config.js, \ - packages/common/commonTypes/** + packages/common/commonTypes/**, \ + **/vitest.config.ts sonar.cpd.exclusions=\ packages/cloudfrontFunctions/tests/**, \ packages/cdk/nagSuppressions.ts, \ **/mock*, \ **/__mocks__*, \ - **/*.test.ts* + **/*.test.ts*, \ + **/vitest.config.ts # Define the modules sonar.modules=\ diff --git a/vitest.shared.config.ts b/vitest.shared.config.ts new file mode 100644 index 0000000000..708fcc732f --- /dev/null +++ b/vitest.shared.config.ts @@ -0,0 +1,18 @@ +import {defineConfig} from "vitest/config" + +const sharedVitestConfig = defineConfig({ + test: { + environment: "node", + globals: true, + reporters: "default", + coverage: { + "enabled": true, + provider: "v8", + reporter: ["text", "lcov"], + reportsDirectory: "./coverage" + }, + exclude: ["**/lib/**", "**/node_modules/**", "**/packages/**"] + } +}) + +export default sharedVitestConfig