diff --git a/.github/scripts/deploy_api.sh b/.github/scripts/deploy_api.sh new file mode 100755 index 000000000..456592f89 --- /dev/null +++ b/.github/scripts/deploy_api.sh @@ -0,0 +1,203 @@ +#!/usr/bin/env bash +set -eu pipefail + +echo "Specification path: ${SPEC_PATH}" +echo "Specification version: ${VERSION_NUMBER}" +echo "Stack name: ${STACK_NAME}" +echo "AWS environment: ${AWS_ENVIRONMENT}" +echo "Apigee environment: ${APIGEE_ENVIRONMENT}" +echo "Proxygen private key name: ${PROXYGEN_PRIVATE_KEY_NAME}" +echo "Proxygen KID: ${PROXYGEN_KID}" +echo "Dry run: ${DRY_RUN}" +echo "ENABLE_MUTUAL_TLS: ${ENABLE_MUTUAL_TLS}" +echo "is_pull_request: ${IS_PULL_REQUEST}" + +client_private_key=$(cat ~/.proxygen/tmp/client_private_key) +client_cert=$(cat ~/.proxygen/tmp/client_cert) + +if [ -z "${client_private_key}" ]; then + echo "client_private_key is unset or set to the empty string" + exit 1 +fi +if [ -z "${client_cert}" ]; then + echo "client_cert is unset or set to the empty string" + exit 1 +fi + +put_secret_lambda=lambda-resources-ProxygenPTLMTLSSecretPut +instance_put_lambda=lambda-resources-ProxygenPTLInstancePut +spec_publish_lambda=lambda-resources-ProxygenPTLSpecPublish + +if [[ "$APIGEE_ENVIRONMENT" =~ ^(int|sandbox|prod)$ ]]; then + put_secret_lambda=lambda-resources-ProxygenProdMTLSSecretPut + instance_put_lambda=lambda-resources-ProxygenProdInstancePut + spec_publish_lambda=lambda-resources-ProxygenProdSpecPublish +fi + +instance_suffix="" +if [[ "${IS_PULL_REQUEST}" == "true" ]]; then + # Extracting the PR ID from $STACK_NAME + pr_id=$(echo "$STACK_NAME" | awk -F'-' '{print $NF}') + instance_suffix=-"pr-${pr_id}" +fi + +# Determine the proxy instance based on the provided $STACK_NAME +apigee_api=prescriptions-for-patients-proxygen +apigee_client=prescriptions-for-patients-proxygen +instance="pfp-proxygen${instance_suffix}" + +echo "Proxy instance: ${instance}" +echo "Apigee api: ${apigee_api}" +echo "Apigee client: ${apigee_client}" + +echo + +echo "Fixing the spec" +# Find and replace the title +title=$(jq -r '.info.title' "${SPEC_PATH}") +if [[ "${IS_PULL_REQUEST}" == "true" ]]; then + jq --arg title "[PR-${pr_id}] $title" '.info.title = $title' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" + echo "disabling monitoring for pull request deployment" + jq '."x-nhsd-apim".monitoring = false' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" +fi + +# Find and replace the specification version number +jq --arg version "${VERSION_NUMBER}" '.info.version = $version' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" + +# Find and replace the x-nhsd-apim.target.url value +jq --arg stack_name "${STACK_NAME}" --arg aws_env "${AWS_ENVIRONMENT}" '.["x-nhsd-apim"].target.url = "https://\($stack_name).\($aws_env).eps.national.nhs.uk"' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" + +# Find and replace the servers object +if [[ "${APIGEE_ENVIRONMENT}" == "prod" ]]; then + jq --arg inst "${instance}" '.servers = [ { "url": "https://api.service.nhs.uk/\($inst)" } ]' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" +else + jq --arg env "${APIGEE_ENVIRONMENT}" --arg inst "${instance}" '.servers = [ { "url": "https://\($env).api.service.nhs.uk/\($inst)" } ]' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" +fi + +# Find and replace securitySchemes +if [[ "${APIGEE_ENVIRONMENT}" == "prod" ]]; then + jq '.components.securitySchemes."nhs-cis2-aal3" = {"$ref": "https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-cis2-aal3"}' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" + jq '.components.securitySchemes."nhs-login-p9" = {"$ref": "https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9"}' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" +else + jq '.components.securitySchemes."nhs-cis2-aal3" = {"$ref": "https://proxygen.ptl.api.platform.nhs.uk/components/securitySchemes/nhs-cis2-aal3"}' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" + jq '.components.securitySchemes."nhs-login-p9" = {"$ref": "https://proxygen.ptl.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9"}' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" +fi + +# Find and replace the x-nhsd-apim.target.secret value +jq --arg mtls_key "${MTLS_KEY}" '.["x-nhsd-apim"].target.security.secret = "\($mtls_key)"' "${SPEC_PATH}" > temp.json && mv temp.json "${SPEC_PATH}" + +# Remove target attributes if the environment is sandbox +if [[ "${APIGEE_ENVIRONMENT}" == *"sandbox"* ]]; then + echo "Removing target attributes for sandbox environment" + jq 'del(."x-nhsd-apim"."target-attributes")' "$SPEC_PATH" > temp.json && mv temp.json "${SPEC_PATH}" +fi + +echo + +echo "Retrieving proxygen credentials" + +# Retrieve the proxygen private key and client private key and cert from AWS Secrets Manager +proxygen_private_key_arn=$(aws cloudformation list-exports --query "Exports[?Name=='secrets:${PROXYGEN_PRIVATE_KEY_NAME}'].Value" --output text) + +if [[ "${ENABLE_MUTUAL_TLS}" == "true" ]]; then + echo + echo "Store the secret used for mutual TLS to AWS using Proxygen proxy lambda" + if [[ "${DRY_RUN}" == "false" ]]; then + jq -n --arg apiName "${apigee_api}" \ + --arg apiClient "${apigee_client}" \ + --arg environment "${APIGEE_ENVIRONMENT}" \ + --arg secretName "${MTLS_KEY}" \ + --arg secretKey "${client_private_key}" \ + --arg secretCert "${client_cert}" \ + --arg kid "${PROXYGEN_KID}" \ + --arg proxygenSecretName "${proxygen_private_key_arn}" \ + '{apiName: $apiName, apiClient: $apiClient, environment: $environment, secretName: $secretName, secretKey: $secretKey, secretCert: $secretCert, kid, $kid, proxygenSecretName: $proxygenSecretName}' > payload.json + + aws lambda invoke --function-name "${put_secret_lambda}" --cli-binary-format raw-in-base64-out --payload file://payload.json out.txt > response.json + if eval "cat response.json | jq -e '.FunctionError' >/dev/null"; then + echo 'Error calling lambda' + cat out.txt + exit 1 + fi + echo "Secret stored successfully" + else + echo "Would call ${put_secret_lambda}" + fi +fi + +echo +echo "Deploy the API instance using Proxygen proxy lambda" +if [[ "${DRY_RUN}" == "false" ]]; then + + jq -n --argfile spec "${SPEC_PATH}" \ + --arg apiName "${apigee_api}" \ + --arg apiClient "${apigee_client}" \ + --arg environment "${APIGEE_ENVIRONMENT}" \ + --arg instance "${instance}" \ + --arg kid "${PROXYGEN_KID}" \ + --arg proxygenSecretName "${proxygen_private_key_arn}" \ + '{apiName: $apiName, apiClient: $apiClient, environment: $environment, specDefinition: $spec, instance: $instance, kid: $kid, proxygenSecretName: $proxygenSecretName}' > payload.json + + aws lambda invoke --function-name "${instance_put_lambda}" --cli-binary-format raw-in-base64-out --payload file://payload.json out.txt > response.json + + if eval "cat response.json | jq -e '.FunctionError' >/dev/null"; then + echo 'Error calling lambda' + cat out.txt + exit 1 + fi + echo "Instance deployed" +else + echo "Would call ${instance_put_lambda}" +fi + +# if [[ "${APIGEE_ENVIRONMENT}" == "int" ]]; then +# echo +# echo "Deploy the API spec to prod catalogue as it is int environment" +# if [[ "${DRY_RUN}" == "false" ]]; then +# jq -n --argfile spec "${SPEC_PATH}" \ +# --arg apiName "${apigee_api}" \ +# --arg apiClient "${apigee_client}" \ +# --arg environment "prod" \ +# --arg instance "${instance}" \ +# --arg kid "${PROXYGEN_KID}" \ +# --arg proxygenSecretName "${proxygen_private_key_arn}" \ +# '{apiName: $apiName, apiClient: $apiClient, environment: $environment, specDefinition: $spec, instance: $instance, kid: $kid, proxygenSecretName: $proxygenSecretName}' > payload.json + +# aws lambda invoke --function-name "${spec_publish_lambda}" --cli-binary-format raw-in-base64-out --payload file://payload.json out.txt > response.json + +# if eval "cat response.json | jq -e '.FunctionError' >/dev/null"; then +# echo 'Error calling lambda' +# cat out.txt +# exit 1 +# fi +# echo "Spec deployed" +# else +# echo "Would call ${spec_publish_lambda}" +# fi +# fi + +if [[ "${APIGEE_ENVIRONMENT}" == "internal-dev" && "${IS_PULL_REQUEST}" == "false" ]]; then + echo + echo "Deploy the API spec to uat catalogue as it is internal-dev environment" + if [[ "${DRY_RUN}" == "false" ]]; then + jq -n --argfile spec "${SPEC_PATH}" \ + --arg apiName "${apigee_api}" \ + --arg apiClient "${apigee_client}" \ + --arg environment "uat" \ + --arg instance "${instance}" \ + --arg kid "${PROXYGEN_KID}" \ + --arg proxygenSecretName "${proxygen_private_key_arn}" \ + '{apiName: $apiName, apiClient: $apiClient, environment: $environment, specDefinition: $spec, instance: $instance, kid: $kid, proxygenSecretName: $proxygenSecretName}' > payload.json + + aws lambda invoke --function-name "${spec_publish_lambda}" --cli-binary-format raw-in-base64-out --payload file://payload.json out.txt > response.json + + if eval "cat response.json | jq -e '.FunctionError' >/dev/null"; then + echo 'Error calling lambda' + cat out.txt + exit 1 + fi + echo "Spec deployed" + else + echo "Would call ${spec_publish_lambda}" + fi +fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a1ee651aa..a6193fbab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,6 +67,7 @@ jobs: TARGET_ENVIRONMENT: dev APIGEE_ENVIRONMENT: internal-dev ENABLE_MUTUAL_TLS: true + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_code TRUSTSTORE_FILE: pfp-truststore.pem VERSION_NUMBER: ${{needs.tag_release.outputs.version_tag}} @@ -90,6 +91,7 @@ jobs: INT_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.INT_CLOUD_FORMATION_CHECK_VERSION_ROLE }} PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE }} DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} release_dev_sandbox: needs: [tag_release, package_code, get_commit_id] @@ -100,6 +102,7 @@ jobs: TARGET_ENVIRONMENT: dev APIGEE_ENVIRONMENT: internal-dev-sandbox ENABLE_MUTUAL_TLS: true + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_sandbox_code TRUSTSTORE_FILE: pfp-sandbox-truststore.pem VERSION_NUMBER: ${{needs.tag_release.outputs.version_tag}} @@ -114,6 +117,7 @@ jobs: CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }} TARGET_SPINE_SERVER: sandbox TARGET_SERVICE_SEARCH_SERVER: sandbox + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} release_qa: needs: @@ -131,6 +135,7 @@ jobs: TARGET_ENVIRONMENT: qa APIGEE_ENVIRONMENT: internal-qa ENABLE_MUTUAL_TLS: true + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_code TRUSTSTORE_FILE: pfp-truststore.pem VERSION_NUMBER: ${{needs.tag_release.outputs.version_tag}} @@ -148,3 +153,4 @@ jobs: CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.QA_CLOUD_FORMATION_DEPLOY_ROLE }} TARGET_SPINE_SERVER: ${{ secrets.QA_TARGET_SPINE_SERVER }} TARGET_SERVICE_SEARCH_SERVER: ${{ secrets.QA_TARGET_SERVICE_SEARCH_SERVER }} + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index b007d1ff3..4db38557d 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -100,13 +100,15 @@ jobs: needs: [get_issue_number, package_code, get_commit_id] uses: ./.github/workflows/sam_release_code.yml with: + IS_PULL_REQUEST: true STACK_NAME: pfp-pr-${{needs.get_issue_number.outputs.issue_number}} ARTIFACT_BUCKET_PREFIX: PR-${{needs.get_issue_number.outputs.issue_number}} - TARGET_ENVIRONMENT: dev-pr + TARGET_ENVIRONMENT: dev APIGEE_ENVIRONMENT: internal-dev ENABLE_MUTUAL_TLS: false + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_code - TRUSTSTORE_FILE: pfp-truststore.pem + TRUSTSTORE_FILE: pfp-truststore-pr.pem # temporary VERSION_NUMBER: PR-${{ needs.get_issue_number.outputs.issue_number }} COMMIT_ID: ${{ needs.get_commit_id.outputs.commit_id }} LOG_LEVEL: DEBUG @@ -117,32 +119,35 @@ jobs: RUN_REGRESSION_TESTS: true REGRESSION_TEST_PRODUCT: PFP-AWS FORWARD_CSOC_LOGS: false + DEPLOY_APIGEE: true # temporary secrets: REGRESSION_TESTS_PEM: ${{ secrets.REGRESSION_TESTS_PEM }} CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }} TARGET_SPINE_SERVER: ${{ secrets.DEV_TARGET_SPINE_SERVER }} TARGET_SERVICE_SEARCH_SERVER: ${{ secrets.DEV_TARGET_SERVICE_SEARCH_SERVER }} - - release_sandbox_code: - needs: [get_issue_number, package_code, get_commit_id] - uses: ./.github/workflows/sam_release_code.yml - with: - STACK_NAME: pfp-pr-${{needs.get_issue_number.outputs.issue_number}}-sandbox - ARTIFACT_BUCKET_PREFIX: PR-sandbox-${{needs.get_issue_number.outputs.issue_number}} - TARGET_ENVIRONMENT: dev-pr - APIGEE_ENVIRONMENT: internal-dev-sandbox - ENABLE_MUTUAL_TLS: false - BUILD_ARTIFACT: packaged_sandbox_code - TRUSTSTORE_FILE: pfp-sandbox-truststore.pem - VERSION_NUMBER: PR-${{ needs.get_issue_number.outputs.issue_number }} - COMMIT_ID: ${{ needs.get_commit_id.outputs.commit_id }} - LOG_LEVEL: DEBUG - LOG_RETENTION_DAYS: 30 - STATE_MACHINE_LOG_LEVEL: ALL - RUN_REGRESSION_TESTS: false - FORWARD_CSOC_LOGS: false - secrets: - REGRESSION_TESTS_PEM: ${{ secrets.REGRESSION_TESTS_PEM }} - CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }} - TARGET_SPINE_SERVER: sandbox - TARGET_SERVICE_SEARCH_SERVER: sandbox + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} +# release_sandbox_code: +# needs: [get_issue_number, package_code, get_commit_id] +# uses: ./.github/workflows/sam_release_code.yml +# with: +# STACK_NAME: pfp-pr-${{needs.get_issue_number.outputs.issue_number}}-sandbox +# ARTIFACT_BUCKET_PREFIX: PR-sandbox-${{needs.get_issue_number.outputs.issue_number}} +# TARGET_ENVIRONMENT: dev +# APIGEE_ENVIRONMENT: internal-dev-sandbox +# ENABLE_MUTUAL_TLS: false +# MTLS_KEY: prescriptions-for-patients-mtls-1 +# BUILD_ARTIFACT: packaged_sandbox_code +# TRUSTSTORE_FILE: pfp-sandbox-truststore.pem +# VERSION_NUMBER: PR-${{ needs.get_issue_number.outputs.issue_number }} +# COMMIT_ID: ${{ needs.get_commit_id.outputs.commit_id }} +# LOG_LEVEL: DEBUG +# LOG_RETENTION_DAYS: 30 +# STATE_MACHINE_LOG_LEVEL: ALL +# RUN_REGRESSION_TESTS: false +# FORWARD_CSOC_LOGS: false +# secrets: +# REGRESSION_TESTS_PEM: ${{ secrets.REGRESSION_TESTS_PEM }} +# CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }} +# TARGET_SPINE_SERVER: sandbox +# TARGET_SERVICE_SEARCH_SERVER: sandbox +# PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a19aa1472..d38acc8a8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -64,6 +64,7 @@ jobs: TARGET_ENVIRONMENT: dev APIGEE_ENVIRONMENT: internal-dev ENABLE_MUTUAL_TLS: true + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_code TRUSTSTORE_FILE: pfp-truststore.pem VERSION_NUMBER: ${{needs.tag_release.outputs.version_tag}} @@ -90,7 +91,7 @@ jobs: INT_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.INT_CLOUD_FORMATION_CHECK_VERSION_ROLE }} PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE }} DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} - + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} release_dev_sandbox: needs: [tag_release, package_code, get_commit_id] uses: ./.github/workflows/sam_release_code.yml @@ -99,7 +100,8 @@ jobs: STACK_NAME: pfp-sandbox TARGET_ENVIRONMENT: dev APIGEE_ENVIRONMENT: internal-dev-sandbox - ENABLE_MUTUAL_TLS: true + ENABLE_MUTUAL_TLS: false + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_sandbox_code TRUSTSTORE_FILE: pfp-sandbox-truststore.pem VERSION_NUMBER: ${{needs.tag_release.outputs.version_tag}} @@ -117,6 +119,7 @@ jobs: CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_DEPLOY_ROLE }} TARGET_SPINE_SERVER: sandbox TARGET_SERVICE_SEARCH_SERVER: sandbox + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} release_ref: needs: @@ -134,6 +137,7 @@ jobs: TARGET_ENVIRONMENT: ref APIGEE_ENVIRONMENT: ref ENABLE_MUTUAL_TLS: true + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_code TRUSTSTORE_FILE: pfp-truststore.pem VERSION_NUMBER: ${{needs.tag_release.outputs.version_tag}} @@ -153,7 +157,7 @@ jobs: CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.REF_CLOUD_FORMATION_DEPLOY_ROLE }} TARGET_SPINE_SERVER: ${{ secrets.REF_TARGET_SPINE_SERVER }} TARGET_SERVICE_SEARCH_SERVER: ${{ secrets.REF_TARGET_SERVICE_SEARCH_SERVER }} - + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} release_qa: needs: [ @@ -170,6 +174,7 @@ jobs: TARGET_ENVIRONMENT: qa APIGEE_ENVIRONMENT: internal-qa ENABLE_MUTUAL_TLS: true + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_code TRUSTSTORE_FILE: pfp-truststore.pem VERSION_NUMBER: ${{needs.tag_release.outputs.version_tag}} @@ -190,7 +195,7 @@ jobs: CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.QA_CLOUD_FORMATION_DEPLOY_ROLE }} TARGET_SPINE_SERVER: ${{ secrets.QA_TARGET_SPINE_SERVER }} TARGET_SERVICE_SEARCH_SERVER: ${{ secrets.QA_TARGET_SERVICE_SEARCH_SERVER }} - + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} release_int: needs: [tag_release, release_qa, package_code, get_commit_id] uses: ./.github/workflows/sam_release_code.yml @@ -200,6 +205,7 @@ jobs: TARGET_ENVIRONMENT: int APIGEE_ENVIRONMENT: int ENABLE_MUTUAL_TLS: true + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_code TRUSTSTORE_FILE: pfp-truststore.pem VERSION_NUMBER: ${{needs.tag_release.outputs.version_tag}} @@ -226,7 +232,7 @@ jobs: INT_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.INT_CLOUD_FORMATION_CHECK_VERSION_ROLE }} PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE }} DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} - + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} release_sandbox: needs: [tag_release, release_qa, package_code, get_commit_id] uses: ./.github/workflows/sam_release_code.yml @@ -236,6 +242,7 @@ jobs: TARGET_ENVIRONMENT: int APIGEE_ENVIRONMENT: int-sandbox ENABLE_MUTUAL_TLS: true + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_sandbox_code TRUSTSTORE_FILE: pfp-sandbox-truststore.pem VERSION_NUMBER: ${{needs.tag_release.outputs.version_tag}} @@ -250,6 +257,7 @@ jobs: CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.INT_CLOUD_FORMATION_DEPLOY_ROLE }} TARGET_SPINE_SERVER: sandbox TARGET_SERVICE_SEARCH_SERVER: sandbox + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PTL_ROLE }} release_prod: needs: @@ -261,6 +269,7 @@ jobs: TARGET_ENVIRONMENT: prod APIGEE_ENVIRONMENT: prod ENABLE_MUTUAL_TLS: true + MTLS_KEY: prescriptions-for-patients-mtls-1 BUILD_ARTIFACT: packaged_code TRUSTSTORE_FILE: pfp-truststore.pem VERSION_NUMBER: ${{needs.tag_release.outputs.version_tag}} @@ -283,3 +292,4 @@ jobs: INT_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.INT_CLOUD_FORMATION_CHECK_VERSION_ROLE }} PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE: ${{ secrets.PROD_CLOUD_FORMATION_CHECK_VERSION_ROLE }} DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE: ${{ secrets.DEV_CLOUD_FORMATION_EXECUTE_LAMBDA_ROLE }} + PROXYGEN_ROLE: ${{ secrets.PROXYGEN_PROD_ROLE }} diff --git a/.github/workflows/run_regression_tests.yml b/.github/workflows/run_regression_tests.yml index c2640ff97..089507de2 100644 --- a/.github/workflows/run_regression_tests.yml +++ b/.github/workflows/run_regression_tests.yml @@ -67,7 +67,7 @@ jobs: env: PYTHON_CONFIGURE_OPTS: --enable-shared - - name: Run Regression Testing + - name: Run Regression Testing Non-Proxygen working-directory: scripts env: TARGET_ENVIRONMENT: ${{ inputs.ENVIRONMENT }} @@ -75,14 +75,70 @@ jobs: GITHUB-TOKEN: ${{ steps.generate-token.outputs.token }} run: | if [[ "$TARGET_ENVIRONMENT" != "prod" && "$TARGET_ENVIRONMENT" != "ref" ]]; then - # this should be the tag of the tests you want to run - REGRESSION_TEST_REPO_TAG=v3.6.2 + REGRESSION_TEST_REPO_TAG="v3.7.0" # 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.7.0" # This is the tag of the github workflow to run, usually the same as REGRESSION_TEST_REPO_TAG - # this should be the tag of the regression test workflow you want to run - # This will normally be the same as REGRESSION_TEST_REPO_TAG - REGRESSION_TEST_WORKFLOW_TAG=v3.6.2 + if [[ -z "$REGRESSION_TEST_REPO_TAG" || -z "$REGRESSION_TEST_WORKFLOW_TAG" ]]; then + echo "Error: One or both tag variables are not set" >&2 + exit 1 + fi + + # HELPER IF STATEMENT - It will automatically determine the correct Git URL to use based on the REGRESSION_TEST_WORKFLOW_TAG value + if [[ "$REGRESSION_TEST_WORKFLOW_TAG" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then + echo "REGRESSION_TEST_WORKFLOW_TAG is a version tag, using tag link" + curl "https://raw.githubusercontent.com/NHSDigital/electronic-prescription-service-api-regression-tests/refs/tags/${REGRESSION_TEST_WORKFLOW_TAG}/scripts/run_regression_tests.py" -o run_regression_tests.py + else + echo "REGRESSION_TEST_WORKFLOW_TAG doesn't look like a version tag, using branch link" + curl "https://raw.githubusercontent.com/NHSDigital/electronic-prescription-service-api-regression-tests/refs/heads/${REGRESSION_TEST_REPO_TAG}/scripts/run_regression_tests.py" -o run_regression_tests.py + fi + + if [[ ! -f run_regression_tests.py ]]; then + echo "Error: run_regression_tests.py not found" >&2 + exit 1 + fi + + poetry install + echo Running regression tests in the "$TARGET_ENVIRONMENT" environment + poetry run python -u run_regression_tests.py \ + --env="$TARGET_ENVIRONMENT" \ + --pr_label="$VERSION_NUMBER" \ + --token=${{ steps.generate-token.outputs.token }} \ + --is_called_from_github=true \ + --product=${{ inputs.REGRESSION_TEST_PRODUCT }} \ + --regression_test_repo_tag "${REGRESSION_TEST_REPO_TAG}" \ + --regression_test_workflow_tag "${REGRESSION_TEST_WORKFLOW_TAG}" + fi + + - name: Run Regression Testing Proxygen + working-directory: scripts + env: + TARGET_ENVIRONMENT: ${{ inputs.ENVIRONMENT }} + VERSION_NUMBER: ${{ inputs.VERSION_NUMBER }} + GITHUB-TOKEN: ${{ steps.generate-token.outputs.token }} + run: | + if [[ "$TARGET_ENVIRONMENT" != "prod" && "$TARGET_ENVIRONMENT" != "ref" ]]; then + REGRESSION_TEST_REPO_TAG="v3.7.0" # 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.7.0" # 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 + echo "Error: One or both tag variables are not set" >&2 + exit 1 + fi + + # HELPER IF STATEMENT - It will automatically determine the correct Git URL to use based on the REGRESSION_TEST_WORKFLOW_TAG value + if [[ "$REGRESSION_TEST_WORKFLOW_TAG" =~ ^v([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then + echo "REGRESSION_TEST_WORKFLOW_TAG is a version tag, using tag link" + curl "https://raw.githubusercontent.com/NHSDigital/electronic-prescription-service-api-regression-tests/refs/tags/${REGRESSION_TEST_WORKFLOW_TAG}/scripts/run_regression_tests.py" -o run_regression_tests.py + else + echo "REGRESSION_TEST_WORKFLOW_TAG doesn't look like a version tag, using branch link" + curl "https://raw.githubusercontent.com/NHSDigital/electronic-prescription-service-api-regression-tests/refs/heads/${REGRESSION_TEST_REPO_TAG}/scripts/run_regression_tests.py" -o run_regression_tests.py + fi + + if [[ ! -f run_regression_tests.py ]]; then + echo "Error: run_regression_tests.py not found" >&2 + exit 1 + fi - curl https://raw.githubusercontent.com/NHSDigital/electronic-prescription-service-api-regression-tests/refs/tags/${REGRESSION_TEST_WORKFLOW_TAG}/scripts/run_regression_tests.py -o run_regression_tests.py poetry install echo Running regression tests in the "$TARGET_ENVIRONMENT" environment poetry run python -u run_regression_tests.py \ @@ -90,7 +146,7 @@ jobs: --pr_label="$VERSION_NUMBER" \ --token=${{ steps.generate-token.outputs.token }} \ --is_called_from_github=true \ - --product ${{ inputs.REGRESSION_TEST_PRODUCT }} \ + --product="PFP-PROXYGEN" \ --regression_test_repo_tag "${REGRESSION_TEST_REPO_TAG}" \ --regression_test_workflow_tag "${REGRESSION_TEST_WORKFLOW_TAG}" fi diff --git a/.github/workflows/sam_package_code.yml b/.github/workflows/sam_package_code.yml index c623ffea8..e466c66c8 100644 --- a/.github/workflows/sam_package_code.yml +++ b/.github/workflows/sam_package_code.yml @@ -53,6 +53,7 @@ jobs: - name: make install run: | make install + make compile - shell: bash name: package code @@ -71,6 +72,7 @@ jobs: path: | .aws-sam/build packages/getSecretLayer/lib/get-secrets-layer.zip + packages/specification/dist/prescriptions-for-patients.resolved.json SAMtemplates/state_machines/GetMyPrescriptionsStateMachine.asl.json - shell: bash @@ -90,3 +92,4 @@ jobs: path: | .aws-sam/build packages/getSecretLayer/lib/get-secrets-layer.zip + packages/specification/dist/prescriptions-for-patients.resolved.json diff --git a/.github/workflows/sam_release_code.yml b/.github/workflows/sam_release_code.yml index 3e087af3e..e145fe35c 100644 --- a/.github/workflows/sam_release_code.yml +++ b/.github/workflows/sam_release_code.yml @@ -3,6 +3,9 @@ name: sam release code on: workflow_call: inputs: + IS_PULL_REQUEST: + type: boolean + default: false STACK_NAME: required: true type: string @@ -75,6 +78,12 @@ on: TC009_NHS_NUMBERS: required: false type: string + DEPLOY_APIGEE: + type: boolean + default: true + MTLS_KEY: + type: string + required: true secrets: CLOUD_FORMATION_DEPLOY_ROLE: required: true @@ -92,6 +101,8 @@ on: required: false REGRESSION_TESTS_PEM: required: true + PROXYGEN_ROLE: + required: true jobs: sam_release_code: @@ -160,6 +171,48 @@ jobs: TC009_NHS_NUMBERS: ${{ inputs.TC009_NHS_NUMBERS || '9992387920' }} run: ./release_code.sh + - name: get mtls secrets + shell: bash + run: | + mkdir -p ~/.proxygen/tmp + client_private_key_arn=$(aws cloudformation list-exports --query "Exports[?Name=='account-resources:PfpClientKeySecret'].Value" --output text) + client_cert_arn=$(aws cloudformation list-exports --query "Exports[?Name=='account-resources:PfpClientCertSecret'].Value" --output text) + aws secretsmanager get-secret-value --secret-id "${client_private_key_arn}" --query SecretString --output text > ~/.proxygen/tmp/client_private_key + aws secretsmanager get-secret-value --secret-id "${client_cert_arn}" --query SecretString --output text > ~/.proxygen/tmp/client_cert + + - name: Configure AWS Credentials for api release + uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PROXYGEN_ROLE }} + role-session-name: pfp-api-proxygen + + - name: Deploy PFP API to Apigee + shell: bash + if: ${{ inputs.DEPLOY_APIGEE == true && always() && !failure() && !cancelled() }} + env: + API_TYPE: standard + VERSION_NUMBER: ${{ inputs.VERSION_NUMBER }} + SPEC_PATH: ./packages/specification/dist/prescriptions-for-patients.resolved.json + STACK_NAME: ${{ inputs.STACK_NAME }} + AWS_ENVIRONMENT: ${{ inputs.TARGET_ENVIRONMENT }} + APIGEE_ENVIRONMENT: ${{ inputs.APIGEE_ENVIRONMENT }} + PROXYGEN_PRIVATE_KEY_NAME: PrescriptionsForPatientsProxygenPrivateKey + PROXYGEN_KID: prescriptions-for-patients + DRY_RUN: false + ENABLE_MUTUAL_TLS: ${{ inputs.ENABLE_MUTUAL_TLS }} + MTLS_KEY: ${{ inputs.MTLS_KEY }} + IS_PULL_REQUEST: ${{ inputs.IS_PULL_REQUEST }} + run: ./.github/scripts/deploy_api.sh + + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 + if: always() && !cancelled() + name: Upload specs + with: + name: ${{ inputs.APIGEE_ENVIRONMENT }}-specs + path: | + ./.build/packages/specification/dist/prescriptions-for-patients.resolved.json + - name: create_int_release_notes uses: ./.github/actions/update_confluence_jira if: ${{ inputs.CREATE_INT_RELEASE_NOTES == true && always() && !failure() && !cancelled() }} @@ -196,7 +249,7 @@ jobs: path: gh-pages - name: update release tag in github pages - if: ${{ inputs.TARGET_ENVIRONMENT != 'dev-pr' }} + if: ${{ inputs.IS_PULL_REQUEST == false }} run: | cd gh-pages NOW=$(date +'%Y-%m-%dT%H:%M:%S') diff --git a/Makefile b/Makefile index 108f84eab..fd3834ca7 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,10 @@ sam-deploy-package: guard-artifact_bucket guard-artifact_bucket_prefix guard-sta compile-node: npx tsc --build tsconfig.build.json -compile: compile-node +compile: compile-node compile-specification + +compile-specification: + npm run compile --workspace packages/specification download-get-secrets-layer: mkdir -p packages/getSecretLayer/lib diff --git a/package-lock.json b/package-lock.json index 9e5a9c4fe..8460b28b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,8 @@ "packages/serviceSearchClient", "packages/common/utilities", "packages/common/testing", - "packages/distanceSelling" + "packages/distanceSelling", + "packages/specification" ], "dependencies": { "esbuild": "^0.27.1" @@ -302,7 +303,6 @@ "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.948.0.tgz", "integrity": "sha512-G3mLrNBCo2ZzBS/nM5YRgONBxXBqeU7sXREgM3GLRiozmZB5eNdill/AsvHwYTVp3hk+vAcU/fvKROrvqIna4A==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -857,7 +857,6 @@ "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", @@ -1288,6 +1287,16 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", @@ -1401,6 +1410,30 @@ "tslib": "^2.4.0" } }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.1", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz", @@ -2026,6 +2059,24 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@exodus/schemasafe": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", + "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@faker-js/faker": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz", + "integrity": "sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -2078,6 +2129,16 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@humanwhocodes/momoa": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/momoa/-/momoa-2.0.4.tgz", + "integrity": "sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.10.0" + } + }, "node_modules/@humanwhocodes/retry": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", @@ -2092,6 +2153,29 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2660,238 +2744,884 @@ "mustache": "^4.2.0" } }, - "node_modules/@pfp-common/testing": { - "resolved": "packages/common/testing", - "link": true - }, - "node_modules/@pfp-common/utilities": { - "resolved": "packages/common/utilities", - "link": true - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "dev": true, "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + "node": "^14.21.3 || >=16" }, "funding": { - "url": "https://opencollective.com/pkgr" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@prescriptionsforpatients/distanceSelling": { - "resolved": "packages/distanceSelling", - "link": true - }, - "node_modules/@prescriptionsforpatients/serviceSearchClient": { - "resolved": "packages/serviceSearchClient", - "link": true - }, - "node_modules/@sinclair/typebox": { - "version": "0.34.40", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.40.tgz", - "integrity": "sha512-gwBNIP8ZAYev/ORDWW0QvxdwPXwxBtLsdsJgSc7eDIRt8ubP+rxUBzPsrwnu16fgEF8Bx4lh/+mvQvJzcTM6Kw==", + "node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "node_modules/@opentelemetry/api-logs": { + "version": "0.202.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.202.0.tgz", + "integrity": "sha512-fTBjMqKCfotFWfLzaKyhjLvyEyq5vDKTTFfBmx21btv3gvy8Lq6N5Dh2OzqeuN4DjtpSvNT1uNVfg08eD2Rfxw==", "dev": true, - "license": "BSD-3-Clause", + "license": "Apache-2.0", "dependencies": { - "type-detect": "4.0.8" + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.0.1.tgz", + "integrity": "sha512-XuY23lSI3d4PEqKA+7SLtAgwqIfc6E/E9eAQWLN1vlpC53ybO3o6jW4BsXo1xvz9lYyyWItfQDDLzezER01mCw==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@smithy/abort-controller": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.5.tgz", - "integrity": "sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA==", + "node_modules/@opentelemetry/core": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.0.1.tgz", + "integrity": "sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", - "tslib": "^2.6.2" + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@smithy/config-resolver": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.3.tgz", - "integrity": "sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==", + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.202.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.202.0.tgz", + "integrity": "sha512-/hKE8DaFCJuaQqE1IxpgkcjOolUIwgi3TgHElPVKGdGRBSmJMTmN/cr6vWa55pCJIXPyhKvcMrbrya7DZ3VmzA==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.5", - "@smithy/types": "^4.9.0", - "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-endpoints": "^3.2.5", - "@smithy/util-middleware": "^4.2.5", - "tslib": "^2.6.2" + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-exporter-base": "0.202.0", + "@opentelemetry/otlp-transformer": "0.202.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@smithy/core": { - "version": "3.18.7", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.18.7.tgz", - "integrity": "sha512-axG9MvKhMWOhFbvf5y2DuyTxQueO0dkedY9QC3mAfndLosRI/9LJv8WaL0mw7ubNhsO4IuXX9/9dYGPFvHrqlw==", + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.202.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.202.0.tgz", + "integrity": "sha512-nMEOzel+pUFYuBJg2znGmHJWbmvMbdX5/RhoKNKowguMbURhz0fwik5tUKplLcUtl8wKPL1y9zPnPxeBn65N0Q==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.2.6", - "@smithy/protocol-http": "^5.3.5", - "@smithy/types": "^4.9.0", - "@smithy/util-base64": "^4.3.0", - "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-middleware": "^4.2.5", - "@smithy/util-stream": "^4.5.6", - "@smithy/util-utf8": "^4.2.0", - "@smithy/uuid": "^1.1.0", - "tslib": "^2.6.2" + "@opentelemetry/core": "2.0.1", + "@opentelemetry/otlp-transformer": "0.202.0" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@smithy/credential-provider-imds": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.5.tgz", - "integrity": "sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==", + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.202.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.202.0.tgz", + "integrity": "sha512-5XO77QFzs9WkexvJQL9ksxL8oVFb/dfi9NWQSq7Sv0Efr9x3N+nb1iklP1TeVgxqJ7m1xWiC/Uv3wupiQGevMw==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.5", - "@smithy/property-provider": "^4.2.5", - "@smithy/types": "^4.9.0", - "@smithy/url-parser": "^4.2.5", - "tslib": "^2.6.2" + "@opentelemetry/api-logs": "0.202.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-logs": "0.202.0", + "@opentelemetry/sdk-metrics": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1", + "protobufjs": "^7.3.0" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@smithy/fetch-http-handler": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.6.tgz", - "integrity": "sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg==", + "node_modules/@opentelemetry/resources": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.0.1.tgz", + "integrity": "sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.5", - "@smithy/querystring-builder": "^4.2.5", - "@smithy/types": "^4.9.0", - "@smithy/util-base64": "^4.3.0", - "tslib": "^2.6.2" + "@opentelemetry/core": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, - "node_modules/@smithy/hash-node": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.5.tgz", - "integrity": "sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA==", + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.202.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.202.0.tgz", + "integrity": "sha512-pv8QiQLQzk4X909YKm0lnW4hpuQg4zHwJ4XBd5bZiXcd9urvrJNoNVKnxGHPiDVX/GiLFvr5DMYsDBQbZCypRQ==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", - "@smithy/util-buffer-from": "^4.2.0", - "@smithy/util-utf8": "^4.2.0", - "tslib": "^2.6.2" + "@opentelemetry/api-logs": "0.202.0", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, - "node_modules/@smithy/invalid-dependency": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.5.tgz", - "integrity": "sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A==", + "node_modules/@opentelemetry/sdk-metrics": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.0.1.tgz", + "integrity": "sha512-wf8OaJoSnujMAHWR3g+/hGvNcsC16rf9s1So4JlMiFaFHiE4HpIA3oUh+uWZQ7CNuK8gVW/pQSkgoa5HkkOl0g==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", - "tslib": "^2.6.2" + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, - "node_modules/@smithy/is-array-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", - "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.0.1.tgz", + "integrity": "sha512-xYLlvk/xdScGx1aEqvxLwf6sXQLXCjk3/1SQT9X9AoN5rXRhkdvIFShuNNmtTEPRBqcsMbS4p/gJLNI2wXaDuQ==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "tslib": "^2.6.2" + "@opentelemetry/core": "2.0.1", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, - "node_modules/@smithy/middleware-content-length": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.5.tgz", - "integrity": "sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==", + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.0.1.tgz", + "integrity": "sha512-UhdbPF19pMpBtCWYP5lHbTogLWx9N0EBxtdagvkn5YtsAnCBZzL7SjktG+ZmupRgifsHMjwUaCCaVmqGfSADmA==", + "dev": true, "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.5", - "@smithy/types": "^4.9.0", - "tslib": "^2.6.2" + "@opentelemetry/context-async-hooks": "2.0.1", + "@opentelemetry/core": "2.0.1", + "@opentelemetry/sdk-trace-base": "2.0.1" }, "engines": { - "node": ">=18.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@smithy/middleware-endpoint": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.3.14.tgz", - "integrity": "sha512-v0q4uTKgBM8dsqGjqsabZQyH85nFaTnFcgpWU1uydKFsdyyMzfvOkNum9G7VK+dOP01vUnoZxIeRiJ6uD0kjIg==", + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.34.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.34.0.tgz", + "integrity": "sha512-aKcOkyrorBGlajjRdVoJWHTxfxO1vCNHLJVlSDaRHDIdjU+pX8IYQPvPDkYiujKLbRnWU+1TBwEt0QRgSm4SGA==", + "dev": true, "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.18.7", - "@smithy/middleware-serde": "^4.2.6", - "@smithy/node-config-provider": "^4.3.5", - "@smithy/shared-ini-file-loader": "^4.4.0", - "@smithy/types": "^4.9.0", - "@smithy/url-parser": "^4.2.5", - "@smithy/util-middleware": "^4.2.5", - "tslib": "^2.6.2" - }, "engines": { - "node": ">=18.0.0" + "node": ">=14" } }, - "node_modules/@smithy/middleware-retry": { - "version": "4.4.14", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.14.tgz", - "integrity": "sha512-Z2DG8Ej7FyWG1UA+7HceINtSLzswUgs2np3sZX0YBBxCt+CXG4QUxv88ZDS3+2/1ldW7LqtSY1UO/6VQ1pND8Q==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^4.3.5", - "@smithy/protocol-http": "^5.3.5", - "@smithy/service-error-classification": "^4.2.5", + "node_modules/@pfp-common/testing": { + "resolved": "packages/common/testing", + "link": true + }, + "node_modules/@pfp-common/utilities": { + "resolved": "packages/common/utilities", + "link": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@prescriptionsforpatients/distanceSelling": { + "resolved": "packages/distanceSelling", + "link": true + }, + "node_modules/@prescriptionsforpatients/serviceSearchClient": { + "resolved": "packages/serviceSearchClient", + "link": true + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@redocly/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-EDtsGZS964mf9zAUXAl9Ew16eYbeyAFWhsPr0fX6oaJxgd8rApYlPBf0joyhnUHz88WxrigyFtTaqqzXNzPgqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@redocly/ajv/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@redocly/cli": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-2.12.6.tgz", + "integrity": "sha512-GAg0JzSxK5ZXAHQAAGNwXpDCl82VuJssV+kN0PFVb4IzZDq4tXtkZeS7v8YrD7h7sP2TzMEpxxQWumRAFVb3Lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@opentelemetry/exporter-trace-otlp-http": "0.202.0", + "@opentelemetry/resources": "2.0.1", + "@opentelemetry/sdk-trace-node": "2.0.1", + "@opentelemetry/semantic-conventions": "1.34.0", + "@redocly/openapi-core": "2.12.6", + "@redocly/respect-core": "2.12.6", + "abort-controller": "^3.0.0", + "chokidar": "^3.5.1", + "colorette": "^1.2.0", + "cookie": "^0.7.2", + "dotenv": "16.4.7", + "form-data": "^4.0.4", + "glob": "^11.0.1", + "handlebars": "^4.7.6", + "https-proxy-agent": "^7.0.5", + "mobx": "^6.0.4", + "pluralize": "^8.0.0", + "react": "^17.0.0 || ^18.2.0 || ^19.2.1", + "react-dom": "^17.0.0 || ^18.2.0 || ^19.2.1", + "redoc": "2.5.1", + "semver": "^7.5.2", + "set-cookie-parser": "^2.3.5", + "simple-websocket": "^9.0.0", + "styled-components": "^6.0.7", + "ulid": "^3.0.1", + "undici": "^6.21.3", + "yargs": "17.0.1" + }, + "bin": { + "openapi": "bin/cli.js", + "redocly": "bin/cli.js" + }, + "engines": { + "node": ">=22.12.0 || >=20.19.0 <21.0.0", + "npm": ">=10" + } + }, + "node_modules/@redocly/cli/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@redocly/cli/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/@redocly/cli/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@redocly/cli/node_modules/glob": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz", + "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@redocly/cli/node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@redocly/cli/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@redocly/cli/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@redocly/cli/node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@redocly/cli/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@redocly/cli/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@redocly/cli/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@redocly/cli/node_modules/yargs": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz", + "integrity": "sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@redocly/cli/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/@redocly/config": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.41.0.tgz", + "integrity": "sha512-8yJ2e+ex8KVF25zijdpDbAEjyubk7NLfHsLI8h0MUnLEo2iEg6rTCDT9Qw71XDqd5UlXvfJb0Z0h6dd+Y6pWLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-schema-to-ts": "2.7.2" + } + }, + "node_modules/@redocly/openapi-core": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-2.12.6.tgz", + "integrity": "sha512-X4NK5wW0lr1Cdd5CB/St6hABU7OLw3kaI9gxVODENuxcMCIWa27v8AZwUJom5arp3f9kY0KJwNNqBghrWDQC+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@redocly/ajv": "^8.17.1", + "@redocly/config": "^0.41.0", + "ajv-formats": "^3.0.1", + "colorette": "^1.2.0", + "js-levenshtein": "^1.1.6", + "js-yaml": "^4.1.0", + "picomatch": "^4.0.3", + "pluralize": "^8.0.0", + "yaml-ast-parser": "0.0.43" + }, + "engines": { + "node": ">=22.12.0 || >=20.19.0 <21.0.0", + "npm": ">=10" + } + }, + "node_modules/@redocly/openapi-core/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/@redocly/openapi-core/node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@redocly/openapi-core/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", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@redocly/respect-core": { + "version": "2.12.6", + "resolved": "https://registry.npmjs.org/@redocly/respect-core/-/respect-core-2.12.6.tgz", + "integrity": "sha512-F9Zla4M9wGZGfgavWddC4AObHkfPzsTCNAmyBOAj/ub8ycjfI719MqnEZvurIMYxmVDoTv4maHnuich5IGVzlg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@faker-js/faker": "^7.6.0", + "@noble/hashes": "^1.8.0", + "@redocly/ajv": "8.17.1", + "@redocly/openapi-core": "2.12.6", + "better-ajv-errors": "^1.2.0", + "colorette": "^2.0.20", + "json-pointer": "^0.6.2", + "jsonpath-rfc9535": "1.3.0", + "openapi-sampler": "^1.6.1", + "outdent": "^0.8.0" + }, + "engines": { + "node": ">=22.12.0 || >=20.19.0 <21.0.0", + "npm": ">=10" + } + }, + "node_modules/@redocly/respect-core/node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.40", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.40.tgz", + "integrity": "sha512-gwBNIP8ZAYev/ORDWW0QvxdwPXwxBtLsdsJgSc7eDIRt8ubP+rxUBzPsrwnu16fgEF8Bx4lh/+mvQvJzcTM6Kw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@smithy/abort-controller": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.5.tgz", + "integrity": "sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.3.tgz", + "integrity": "sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.18.7", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.18.7.tgz", + "integrity": "sha512-axG9MvKhMWOhFbvf5y2DuyTxQueO0dkedY9QC3mAfndLosRI/9LJv8WaL0mw7ubNhsO4IuXX9/9dYGPFvHrqlw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-serde": "^4.2.6", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.5.tgz", + "integrity": "sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.6.tgz", + "integrity": "sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/querystring-builder": "^4.2.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.5.tgz", + "integrity": "sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.5.tgz", + "integrity": "sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", + "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.5.tgz", + "integrity": "sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.3.14.tgz", + "integrity": "sha512-v0q4uTKgBM8dsqGjqsabZQyH85nFaTnFcgpWU1uydKFsdyyMzfvOkNum9G7VK+dOP01vUnoZxIeRiJ6uD0kjIg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.18.7", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-middleware": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.4.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.14.tgz", + "integrity": "sha512-Z2DG8Ej7FyWG1UA+7HceINtSLzswUgs2np3sZX0YBBxCt+CXG4QUxv88ZDS3+2/1ldW7LqtSY1UO/6VQ1pND8Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/service-error-classification": "^4.2.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/util-middleware": "^4.2.5", @@ -3482,7 +4212,6 @@ "integrity": "sha512-czWPzKIAXucn9PtsttxmumiQ9N0ok9FrBwgRWrwmVLlp86BrMExzvXRLFYRJ+Ex3g6yqj+KuaxfX1JTgV2lpfg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -3494,6 +4223,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/stylis": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", + "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -3546,7 +4290,6 @@ "integrity": "sha512-N9lBGA9o9aqb1hVMc9hzySbhKibHmB+N3IpoShyV6HyQYRGIhlrO5rQgttypi+yEeKsKI4idxC8Jw6gXKD4THA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.49.0", "@typescript-eslint/types": "8.49.0", @@ -4028,13 +4771,25 @@ "dev": true, "license": "ISC" }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4065,6 +4820,16 @@ "node": ">=0.4.0" } }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -4082,6 +4847,48 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -4141,6 +4948,10 @@ "node": ">= 8" } }, + "node_modules/apim-spec": { + "resolved": "packages/specification", + "link": true + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -4237,7 +5048,6 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "license": "MIT", - "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", @@ -4396,6 +5206,39 @@ ], "license": "MIT" }, + "node_modules/better-ajv-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/better-ajv-errors/-/better-ajv-errors-1.2.0.tgz", + "integrity": "sha512-UW+IsFycygIo7bclP9h5ugkNH8EjCSgqyFB/yQ4Hqqa1OEYDtb0uFIkYE0b6+CjkgJYVM5UKI/pJPxjYe9EZlA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/code-frame": "^7.16.0", + "@humanwhocodes/momoa": "^2.0.2", + "chalk": "^4.1.2", + "jsonpointer": "^5.0.0", + "leven": "^3.1.0 < 4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "ajv": "4.11.8 - 8" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/bowser": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.12.1.tgz", @@ -4445,7 +5288,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001735", "electron-to-chromium": "^1.5.204", @@ -4547,6 +5389,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true, + "license": "MIT" + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -4567,6 +5416,16 @@ "node": ">=6" } }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001735", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001735.tgz", @@ -4619,6 +5478,44 @@ "node": ">=10" } }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/ci-info": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.0.tgz", @@ -4642,6 +5539,13 @@ "dev": true, "license": "MIT" }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "dev": true, + "license": "MIT" + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -4720,6 +5624,16 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -4758,6 +5672,13 @@ "dev": true, "license": "MIT" }, + "node_modules/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "dev": true, + "license": "MIT" + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -4790,6 +5711,29 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-js": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", + "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -4812,6 +5756,35 @@ "node": ">= 8" } }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-to-react-native": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true, + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -4841,6 +5814,12 @@ "node": "*" } }, + "node_modules/decko": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz", + "integrity": "sha512-m8FnyHXV1QX+S1cl+KPFDIl6NMkxtKsy6+U/aYyjrOqWMuwAwYWu7ePqrsUHtDR5Y8Yk2pi/KIDSgF+vT4cPOQ==", + "dev": true + }, "node_modules/dedent": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", @@ -4930,6 +5909,29 @@ "node": ">=0.3.1" } }, + "node_modules/dompurify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", + "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "dev": true, + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -5037,6 +6039,13 @@ "node": ">= 0.4" } }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true, + "license": "MIT" + }, "node_modules/esbuild": { "version": "0.27.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz", @@ -5107,7 +6116,6 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -5345,6 +6353,23 @@ "node": ">=0.10.0" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, "node_modules/events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", @@ -5447,6 +6472,30 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fast-xml-parser": { "version": "5.2.5", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", @@ -5574,6 +6623,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/foreach": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", + "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==", + "dev": true, + "license": "MIT" + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -5705,6 +6761,19 @@ "node": ">= 0.4" } }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/getMyPrescriptions": { "resolved": "packages/getMyPrescriptions", "link": true @@ -5877,6 +6946,27 @@ "dev": true, "license": "MIT" }, + "node_modules/http2-client": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", + "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==", + "dev": true, + "license": "MIT" + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -5991,6 +7081,19 @@ "dev": true, "license": "MIT" }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -6278,7 +7381,6 @@ "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "30.2.0", "@jest/types": "30.2.0", @@ -6924,6 +8026,16 @@ "node": ">= 0.6.0" } }, + "node_modules/js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6971,6 +8083,31 @@ "dev": true, "license": "MIT" }, + "node_modules/json-pointer": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.2.tgz", + "integrity": "sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "foreach": "^2.0.4" + } + }, + "node_modules/json-schema-to-ts": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-2.7.2.tgz", + "integrity": "sha512-R1JfqKqbBR4qE8UyBR56Ms30LL62/nlhoz+1UkfI/VE7p54Awu919FZ6ZUPG8zIa3XB65usPJgr1ONVncUGSaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@types/json-schema": "^7.0.9", + "ts-algebra": "^1.2.0" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -6998,6 +8135,26 @@ "node": ">=6" } }, + "node_modules/jsonpath-rfc9535": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsonpath-rfc9535/-/jsonpath-rfc9535-1.3.0.tgz", + "integrity": "sha512-3jFHya7oZ45aDxIIdx+/zQARahHXxFSMWBkcBUldfXpLS9VCXDJyTKt35kQfEXLqh0K3Ixw/9xFnvcDStaxh7Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -7201,6 +8358,26 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "license": "MIT" }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -7211,6 +8388,13 @@ "yallist": "^3.0.2" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true, + "license": "MIT" + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -7244,6 +8428,26 @@ "tmpl": "1.0.5" } }, + "node_modules/mark.js": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", + "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -7354,6 +8558,69 @@ "node": ">=10" } }, + "node_modules/mobx": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.15.0.tgz", + "integrity": "sha512-UczzB+0nnwGotYSgllfARAqWCJ5e/skuV2K/l+Zyck/H6pJIhLXuBnz+6vn2i211o7DtbE78HQtsYEKICHGI+g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mobx" + } + }, + "node_modules/mobx-react": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-9.2.0.tgz", + "integrity": "sha512-dkGWCx+S0/1mfiuFfHRH8D9cplmwhxOV5CkXMp38u6rQGG2Pv3FWYztS0M7ncR6TyPRQKaTG/pnitInoYE9Vrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mobx-react-lite": "^4.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mobx" + }, + "peerDependencies": { + "mobx": "^6.9.0", + "react": "^16.8.0 || ^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/mobx-react-lite": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-4.1.1.tgz", + "integrity": "sha512-iUxiMpsvNraCKXU+yPotsOncNNmyeS2B5DKL+TL6Tar/xm+wwNJAubJmtRSeAoYawdZqwv8Z/+5nPRHeQxTiXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.4.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mobx" + }, + "peerDependencies": { + "mobx": "^6.9.0", + "react": "^16.8.0 || ^17 || ^18 || ^19" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -7379,6 +8646,25 @@ "mustache": "bin/mustache" } }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/napi-postinstall": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.3.tgz", @@ -7413,6 +8699,40 @@ "resolved": "packages/nhsd-pfp-sandbox", "link": true }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch-h2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz", + "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "http2-client": "^1.2.5" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -7420,6 +8740,16 @@ "dev": true, "license": "MIT" }, + "node_modules/node-readfiles": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", + "integrity": "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es6-promise": "^3.2.1" + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -7459,39 +8789,124 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "ISC", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true, + "license": "ISC" + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/oas-kit-common": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", + "integrity": "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "fast-safe-stringify": "^2.0.7" + } + }, + "node_modules/oas-linter": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/oas-linter/-/oas-linter-3.2.2.tgz", + "integrity": "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@exodus/schemasafe": "^1.0.0-rc.2", + "should": "^13.2.1", + "yaml": "^1.10.0" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, + "node_modules/oas-resolver": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", + "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "node-fetch-h2": "^2.3.0", + "oas-kit-common": "^1.0.8", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + }, "bin": { - "semver": "bin/semver" + "resolve": "resolve.js" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/oas-schema-walker": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", + "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "license": "BSD-3-Clause", + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" } }, - "node_modules/npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "node_modules/oas-validator": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", + "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", "dev": true, - "license": "ISC" + "license": "BSD-3-Clause", + "dependencies": { + "call-me-maybe": "^1.0.1", + "oas-kit-common": "^1.0.8", + "oas-linter": "^3.2.2", + "oas-resolver": "^2.5.6", + "oas-schema-walker": "^1.1.5", + "reftools": "^1.1.9", + "should": "^13.2.1", + "yaml": "^1.10.0" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, "node_modules/once": { @@ -7520,6 +8935,50 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openapi-sampler": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.6.2.tgz", + "integrity": "sha512-NyKGiFKfSWAZr4srD/5WDhInOWDhfml32h/FKUqLpEwKJt0kG0LGUU0MdyNkKrVGuJnw6DuPWq/sHCwAMpiRxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.7", + "fast-xml-parser": "^4.5.0", + "json-pointer": "0.6.2" + } + }, + "node_modules/openapi-sampler/node_modules/fast-xml-parser": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.1.1" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/openapi-sampler/node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -7570,6 +9029,13 @@ "os-tmpdir": "^1.0.0" } }, + "node_modules/outdent": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.8.0.tgz", + "integrity": "sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==", + "dev": true, + "license": "MIT" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -7651,6 +9117,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7712,6 +9185,13 @@ "dev": true, "license": "ISC" }, + "node_modules/perfect-scrollbar": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.6.tgz", + "integrity": "sha512-rixgxw3SxyJbCaSpo1n35A/fwI1r2rdwMKOTCg/AcG+xOEyZcE8UHVjpZMFCVImzsFoCZeJTT+M/rdEIQYO2nw==", + "dev": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -7811,6 +9291,29 @@ "node": ">=8" } }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/polished": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", + "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.17.8" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", @@ -7820,6 +9323,42 @@ "node": ">= 0.4" } }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -7858,6 +9397,60 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "dev": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -7900,6 +9493,60 @@ "node": ">=0.4.x" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react": { + "version": "19.2.1", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.1.tgz", + "integrity": "sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.1.tgz", + "integrity": "sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.1" + } + }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -7907,6 +9554,20 @@ "dev": true, "license": "MIT" }, + "node_modules/react-tabs": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-6.1.0.tgz", + "integrity": "sha512-6QtbTRDKM+jA/MZTTefvigNxo0zz+gnBTVFw2CFVvq+f2BuH0nF0vDLNClL045nuTAdOoK/IL1vTP0ZLX0DAyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "clsx": "^2.0.0", + "prop-types": "^15.5.0" + }, + "peerDependencies": { + "react": "^18.0.0 || ^19.0.0" + } + }, "node_modules/read-installed": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz", @@ -7979,35 +9640,176 @@ "engines": { "node": "*" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/read-package-json/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-scoped-modules": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", + "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "license": "ISC", + "dependencies": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/redoc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.5.1.tgz", + "integrity": "sha512-LmqA+4A3CmhTllGG197F0arUpmChukAj9klfSdxNRemT9Hr07xXr7OGKu4PHzBs359sgrJ+4JwmOlM7nxLPGMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@redocly/openapi-core": "^1.4.0", + "classnames": "^2.3.2", + "decko": "^1.2.0", + "dompurify": "^3.2.4", + "eventemitter3": "^5.0.1", + "json-pointer": "^0.6.2", + "lunr": "^2.3.9", + "mark.js": "^8.11.1", + "marked": "^4.3.0", + "mobx-react": "9.2.0", + "openapi-sampler": "^1.5.0", + "path-browserify": "^1.0.1", + "perfect-scrollbar": "^1.5.5", + "polished": "^4.2.2", + "prismjs": "^1.29.0", + "prop-types": "^15.8.1", + "react-tabs": "^6.0.2", + "slugify": "~1.4.7", + "stickyfill": "^1.1.1", + "swagger2openapi": "^7.0.8", + "url-template": "^2.0.8" + }, + "engines": { + "node": ">=6.9", + "npm": ">=3.0.0" + }, + "peerDependencies": { + "core-js": "^3.1.4", + "mobx": "^6.0.4", + "react": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.4 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "styled-components": "^4.1.1 || ^5.1.1 || ^6.0.5" + } + }, + "node_modules/redoc/node_modules/@redocly/config": { + "version": "0.22.2", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.22.2.tgz", + "integrity": "sha512-roRDai8/zr2S9YfmzUfNhKjOF0NdcOIqF7bhf4MVC5UxpjIysDjyudvlAiVbpPHp3eDRWbdzUgtkK1a7YiDNyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/redoc/node_modules/@redocly/openapi-core": { + "version": "1.34.6", + "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.34.6.tgz", + "integrity": "sha512-2+O+riuIUgVSuLl3Lyh5AplWZyVMNuG2F98/o6NrutKJfW4/GTZdPpZlIphS0HGgcOHgmWcCSHj+dWFlZaGSHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@redocly/ajv": "^8.11.2", + "@redocly/config": "^0.22.0", + "colorette": "^1.2.0", + "https-proxy-agent": "^7.0.5", + "js-levenshtein": "^1.1.6", + "js-yaml": "^4.1.0", + "minimatch": "^5.0.1", + "pluralize": "^8.0.0", + "yaml-ast-parser": "0.0.43" + }, + "engines": { + "node": ">=18.17.0", + "npm": ">=9.5.0" + } + }, + "node_modules/redoc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/redoc/node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/read-package-json/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/redoc/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=10" } }, - "node_modules/readdir-scoped-modules": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz", - "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==", - "deprecated": "This functionality has been moved to @npmcli/fs", + "node_modules/reftools": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", + "integrity": "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==", "dev": true, - "license": "ISC", - "dependencies": { - "debuglog": "^1.0.1", - "dezalgo": "^1.0.0", - "graceful-fs": "^4.1.2", - "once": "^1.3.0" + "license": "BSD-3-Clause", + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" } }, "node_modules/require-directory": { @@ -8020,6 +9822,16 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -8074,6 +9886,37 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/safe-regex-test": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", @@ -8097,6 +9940,13 @@ "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==", "license": "ISC" }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/semver": { "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", @@ -8110,6 +9960,13 @@ "node": ">=10" } }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "dev": true, + "license": "MIT" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -8127,6 +9984,13 @@ "node": ">= 0.4" } }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", + "dev": true, + "license": "MIT" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8150,6 +10014,66 @@ "node": ">=8" } }, + "node_modules/should": { + "version": "13.2.3", + "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", + "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "should-equal": "^2.0.0", + "should-format": "^3.0.3", + "should-type": "^1.4.0", + "should-type-adaptors": "^1.0.1", + "should-util": "^1.0.0" + } + }, + "node_modules/should-equal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", + "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "should-type": "^1.4.0" + } + }, + "node_modules/should-format": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "should-type": "^1.3.0", + "should-type-adaptors": "^1.0.1" + } + }, + "node_modules/should-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/should-type-adaptors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", + "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "should-type": "^1.3.0", + "should-util": "^1.0.0" + } + }, + "node_modules/should-util": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", + "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", + "dev": true, + "license": "MIT" + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -8163,6 +10087,34 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-websocket": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/simple-websocket/-/simple-websocket-9.1.0.tgz", + "integrity": "sha512-8MJPnjRN6A8UCp1I+H/dSFyjwJhp6wta4hsVRhjf8w9qBHRzxYt14RaOcjvQnhD1N4yKOddEjflwMnQM4VtXjQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "debug": "^4.3.1", + "queue-microtask": "^1.2.2", + "randombytes": "^2.1.0", + "readable-stream": "^3.6.0", + "ws": "^7.4.2" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -8183,6 +10135,16 @@ "node": "*" } }, + "node_modules/slugify": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz", + "integrity": "sha512-tf+h5W1IrjNm/9rKKj0JU2MDMruiopx0jjVA5zCdBtcGjfp0+c5rHw/zADLC3IeKlGHtVbHtpfzvYA0OYT+HKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8193,6 +10155,16 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -8304,6 +10276,22 @@ "resolved": "packages/statusLambda", "link": true }, + "node_modules/stickyfill": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stickyfill/-/stickyfill-1.1.1.tgz", + "integrity": "sha512-GCp7vHAfpao+Qh/3Flh9DXEJ/qSi0KJwJw6zYlZOtRYXWUIpMM6mC2rIep/dK8RQqwW0KxGJIllmjPIBOGN8AA==", + "dev": true + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -8490,6 +10478,49 @@ ], "license": "MIT" }, + "node_modules/styled-components": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.19.tgz", + "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emotion/is-prop-valid": "1.2.2", + "@emotion/unitless": "0.8.1", + "@types/stylis": "4.2.5", + "css-to-react-native": "3.2.0", + "csstype": "3.1.3", + "postcss": "8.4.49", + "shallowequal": "1.1.0", + "stylis": "4.3.2", + "tslib": "2.6.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true, + "license": "0BSD" + }, + "node_modules/stylis": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", + "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "dev": true, + "license": "MIT" + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -8516,6 +10547,34 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swagger2openapi": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/swagger2openapi/-/swagger2openapi-7.0.8.tgz", + "integrity": "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "call-me-maybe": "^1.0.1", + "node-fetch": "^2.6.1", + "node-fetch-h2": "^2.3.0", + "node-readfiles": "^0.2.0", + "oas-kit-common": "^1.0.8", + "oas-resolver": "^2.5.6", + "oas-schema-walker": "^1.1.5", + "oas-validator": "^5.0.8", + "reftools": "^1.1.9", + "yaml": "^1.10.0", + "yargs": "^17.0.1" + }, + "bin": { + "boast": "boast.js", + "oas-validate": "oas-validate.js", + "swagger2openapi": "swagger2openapi.js" + }, + "funding": { + "url": "https://github.com/Mermade/oas-kit?sponsor=1" + } + }, "node_modules/synckit": { "version": "0.11.11", "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", @@ -8634,7 +10693,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -8662,6 +10720,13 @@ "node": ">=8.0" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, "node_modules/treeify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", @@ -8672,6 +10737,13 @@ "node": ">=0.6" } }, + "node_modules/ts-algebra": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-1.2.2.tgz", + "integrity": "sha512-kloPhf1hq3JbCPOTYoOWDKxebWjNb2o/LKnNfkWhxVVisFFmMJPPdJeGoGmM+iRLyoXAR61e08Pb+vUXINg8aA==", + "dev": true, + "license": "MIT" + }, "node_modules/ts-api-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", @@ -8757,7 +10829,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", @@ -8802,6 +10873,26 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8844,7 +10935,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8867,6 +10957,26 @@ "node": ">=0.8.0" } }, + "node_modules/ulid": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/ulid/-/ulid-3.0.2.tgz", + "integrity": "sha512-yu26mwteFYzBAot7KVMqFGCVpsF6g8wXfJzQUHvu1no3+rRRSFcSV2nKeYvNPLD2J4b08jYBDhHUjeH0ygIl9w==", + "dev": true, + "license": "MIT", + "bin": { + "ulid": "dist/cli.js" + } + }, + "node_modules/undici": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.22.0.tgz", + "integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/undici-types": { "version": "7.16.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", @@ -8960,12 +11070,29 @@ "querystring": "0.2.0" } }, + "node_modules/url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==", + "dev": true, + "license": "BSD" + }, "node_modules/url/node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", "license": "MIT" }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", @@ -8979,6 +11106,13 @@ "which-typed-array": "^1.1.2" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, "node_modules/util-extend": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz", @@ -9051,6 +11185,24 @@ "node": ">=10.13.0" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -9221,6 +11373,28 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xml": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", @@ -9267,6 +11441,23 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yaml-ast-parser": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -9492,6 +11683,19 @@ "axios-mock-adapter": "^2.1.0" } }, + "packages/specification": { + "name": "apim-spec", + "version": "0.0.1", + "license": "MIT", + "devDependencies": { + "@redocly/cli": "^2.12.3", + "tsx": "4.21.0" + }, + "engines": { + "node": "20.10.x", + "npm": "10.2.x" + } + }, "packages/statusLambda": { "version": "1.0.0", "license": "MIT", diff --git a/package.json b/package.json index 04dca7bc8..aad293d22 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "packages/serviceSearchClient", "packages/common/utilities", "packages/common/testing", - "packages/distanceSelling" + "packages/distanceSelling", + "packages/specification" ], "devDependencies": { "@types/aws-lambda": "^8.10.159", diff --git a/packages/common/testing/src/index.ts b/packages/common/testing/src/index.ts index 587f4819c..3fe760f9d 100644 --- a/packages/common/testing/src/index.ts +++ b/packages/common/testing/src/index.ts @@ -23,6 +23,7 @@ import _mockAPIResponseBody from "./mockAPIResponseBody.json" const mockAPIResponseBody = _mockAPIResponseBody import {createMockedPfPConfig, setupTestEnvironment} from "./test_fixtures" +import type {MockedPfPConfig} from "./test_fixtures" export { mockAPIGatewayProxyEvent, @@ -39,4 +40,4 @@ export { } // Type-only exports -export type {MockedPfPConfig} from "./test_fixtures" +export type {MockedPfPConfig} diff --git a/packages/enrichPrescriptions/tests/testStatusUpdate.test.ts b/packages/enrichPrescriptions/tests/testStatusUpdate.test.ts index ad94f1331..db8d3bd75 100644 --- a/packages/enrichPrescriptions/tests/testStatusUpdate.test.ts +++ b/packages/enrichPrescriptions/tests/testStatusUpdate.test.ts @@ -38,7 +38,8 @@ import { import {Bundle, MedicationRequest} from "fhir/r4" import {Logger} from "@aws-lambda-powertools/logger" import {isolateMedicationRequests, isolatePrescriptions} from "../src/fhirUtils" -import {createMockedPfPConfig, MockedPfPConfig, setupTestEnvironment} from "@pfp-common/testing" +import {createMockedPfPConfig, setupTestEnvironment} from "@pfp-common/testing" +import type {MockedPfPConfig} from "@pfp-common/testing" const TC007_NHS_NUMBER = "9992032499" diff --git a/packages/getMyPrescriptions/src/extractNHSNumber.ts b/packages/getMyPrescriptions/src/extractNHSNumber.ts index ea7071000..63f0eaf02 100644 --- a/packages/getMyPrescriptions/src/extractNHSNumber.ts +++ b/packages/getMyPrescriptions/src/extractNHSNumber.ts @@ -1,3 +1,5 @@ +import type {EventHeaders} from "./types" + export class NHSNumberValidationError extends Error { constructor(msg: string) { super(msg) @@ -7,7 +9,18 @@ export class NHSNumberValidationError extends Error { } } +export function extractNHSNumberFromHeaders(headers: EventHeaders): string { + if (headers["nhs-login-identity-proofing-level"]) { + // Proxygen spec will include proofing level header, whereas non-proxygen API will not + return validateNHSNumber(headers["nhsd-nhslogin-user"]!) + } else { + return extractNHSNumber(headers["nhsd-nhslogin-user"]) + } +} + export function extractNHSNumber(nhsloginUser: string | undefined): string { + // This function is only relevant for non-proxygen API which prepends proofing level + // to the front of the nhs number ie. P9:1234567890 if (nhsloginUser === undefined || nhsloginUser === null) { throw new NHSNumberValidationError("nhsdloginUser not passed in") } diff --git a/packages/getMyPrescriptions/src/getMyPrescriptions.ts b/packages/getMyPrescriptions/src/getMyPrescriptions.ts index 8ca4c9664..2c47fc719 100644 --- a/packages/getMyPrescriptions/src/getMyPrescriptions.ts +++ b/packages/getMyPrescriptions/src/getMyPrescriptions.ts @@ -23,11 +23,12 @@ import { TraceIDs, ResponseFunc } from "./responses" -import {extractNHSNumber, NHSNumberValidationError, validateNHSNumber} from "./extractNHSNumber" +import {extractNHSNumberFromHeaders, NHSNumberValidationError, validateNHSNumber} from "./extractNHSNumber" import {deepCopy, hasTimedOut, jobWithTimeout} from "./utils" import {buildStatusUpdateData, shouldGetStatusUpdates} from "./statusUpdate" import {extractOdsCodes, isolateOperationOutcome} from "./fhirUtils" import {pfpConfig, PfPConfig} from "@pfp-common/utilities" +import type {EventHeaders} from "./types" const LOG_LEVEL = process.env.LOG_LEVEL as LogLevel export const logger = new Logger({serviceName: "getMyPrescriptions", logLevel: LOG_LEVEL}) @@ -41,8 +42,6 @@ const SERVICE_SEARCH_TIMEOUT_MS = 5_000 export const DELEGATED_ACCESS_HDR = "delegatedaccess" export const DELEGATED_ACCESS_SUB_HDR = "x-nhsd-subject-nhs-number" -type EventHeaders = Record - export type GetMyPrescriptionsEvent = { rawHeaders: Record headers: EventHeaders @@ -149,6 +148,7 @@ async function eventHandler( params.pfpConfig, statusUpdateData ) } catch (error) { + logger.info("Error caught in getMyPrescriptions handler", {error}) if (error instanceof NHSNumberValidationError) { return INVALID_NHS_NUMBER_RESPONSE } else { @@ -162,7 +162,7 @@ export function adaptHeadersToSpine(headers: EventHeaders): EventHeaders { logger.debug("Testing if delegated access enabled", {headers}) if (!headers[DELEGATED_ACCESS_HDR] || headers[DELEGATED_ACCESS_HDR].toLowerCase() !== "true") { logger.info("Subject access request detected") - headers["nhsNumber"] = extractNHSNumber(headers["nhsd-nhslogin-user"]) + headers["nhsNumber"] = extractNHSNumberFromHeaders(headers) } else { logger.info("Delegated access request detected") let subjectNHSNumber = headers[DELEGATED_ACCESS_SUB_HDR] diff --git a/packages/getMyPrescriptions/src/types.ts b/packages/getMyPrescriptions/src/types.ts new file mode 100644 index 000000000..6cb83f96e --- /dev/null +++ b/packages/getMyPrescriptions/src/types.ts @@ -0,0 +1 @@ +export type EventHeaders = Record diff --git a/packages/getMyPrescriptions/tests/extractNHSNumber.test.ts b/packages/getMyPrescriptions/tests/extractNHSNumber.test.ts index 4821955ac..78cf82bf6 100644 --- a/packages/getMyPrescriptions/tests/extractNHSNumber.test.ts +++ b/packages/getMyPrescriptions/tests/extractNHSNumber.test.ts @@ -1,4 +1,9 @@ -import {extractNHSNumber, NHSNumberValidationError, validateNHSNumber} from "../src/extractNHSNumber" +import { + extractNHSNumber, + extractNHSNumberFromHeaders, + NHSNumberValidationError, + validateNHSNumber +} from "../src/extractNHSNumber" import "jest" type failureTestData = {nhsdLoginUser: string | undefined; errorMessage: string; scenarioDescription: string} @@ -61,3 +66,39 @@ describe("validateNHSNumber function", () => { }).toThrow(new NHSNumberValidationError(`Invalid check digit in NHS number ${nhsNumber}`)) }) }) + +describe("extractNHSNumberFromHeaders function", () => { + it("should extract NHS number using validateNHSNumber when proofing level header is present", () => { + const headers = { + "nhs-login-identity-proofing-level": "P9", + "nhsd-nhslogin-user": "9912003071" + } + const result = extractNHSNumberFromHeaders(headers) + expect(result).toBe("9912003071") + }) + + it("should extract NHS number using extractNHSNumber when proofing level header is absent", () => { + const headers = { + "nhsd-nhslogin-user": "P9:9912003071" + } + const result = extractNHSNumberFromHeaders(headers) + expect(result).toBe("9912003071") + }) + + it("should throw error when proofing level header is present but NHS number is invalid", () => { + const headers = { + "nhs-login-identity-proofing-level": "P9", + "nhsd-nhslogin-user": "9912003072" + } + expect(() => { + extractNHSNumberFromHeaders(headers) + }).toThrow(new NHSNumberValidationError("Invalid check digit in NHS number 9912003072")) + }) + + it("should throw error when proofing level header is absent and nhsd-nhslogin-user is undefined", () => { + const headers = {} + expect(() => { + extractNHSNumberFromHeaders(headers) + }).toThrow(new NHSNumberValidationError("nhsdloginUser not passed in")) + }) +}) diff --git a/packages/getMyPrescriptions/tests/statusUpdate.test.ts b/packages/getMyPrescriptions/tests/statusUpdate.test.ts index 9bf72f8b6..6d7365f93 100644 --- a/packages/getMyPrescriptions/tests/statusUpdate.test.ts +++ b/packages/getMyPrescriptions/tests/statusUpdate.test.ts @@ -30,7 +30,8 @@ import { stateMachineEventHandler } from "../src/getMyPrescriptions" import {EXPECTED_TRACE_IDS, SERVICE_SEARCH_PARAMS} from "./utils" -import {createMockedPfPConfig, MockedPfPConfig, setupTestEnvironment} from "@pfp-common/testing" +import {createMockedPfPConfig, setupTestEnvironment} from "@pfp-common/testing" +import type {MockedPfPConfig} from "@pfp-common/testing" import {LogLevel} from "@aws-lambda-powertools/logger/types" import {Logger} from "@aws-lambda-powertools/logger" import {createSpineClient} from "@NHSDigital/eps-spine-client" diff --git a/packages/getMyPrescriptions/tests/test-handler.test.ts b/packages/getMyPrescriptions/tests/test-handler.test.ts index dcca05001..728e6aa7a 100644 --- a/packages/getMyPrescriptions/tests/test-handler.test.ts +++ b/packages/getMyPrescriptions/tests/test-handler.test.ts @@ -31,7 +31,8 @@ import {EXPECTED_TRACE_IDS} from "./utils" import {LogLevel} from "@aws-lambda-powertools/logger/types" import {createSpineClient} from "@NHSDigital/eps-spine-client" import {MiddyfiedHandler} from "@middy/core" -import {createMockedPfPConfig, MockedPfPConfig, setupTestEnvironment} from "@pfp-common/testing" +import {createMockedPfPConfig, setupTestEnvironment} from "@pfp-common/testing" +import type {MockedPfPConfig} from "@pfp-common/testing" const TC008_NHS_NUMBER = "9992387920" diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/error/error-401.json b/packages/specification/examples/GetMyPrescriptions/Bundle/error/error-401.json new file mode 100644 index 000000000..ae3500f44 --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/error/error-401.json @@ -0,0 +1,19 @@ +{ + "resourceType": "OperationOutcome", + "issue": [ + { + "severity": "error", + "code": "forbidden", + "details": { + "coding": [ + { + "system": "https://fhir.nhs.uk/R4/CodeSystem/Spine-ErrorOrWarningCode", + "version": "1", + "code": "ACCESS_DENIED", + "display": "Invalid access token" + } + ] + } + } + ] +} diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/error/error-500.json b/packages/specification/examples/GetMyPrescriptions/Bundle/error/error-500.json new file mode 100644 index 000000000..480c58be7 --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/error/error-500.json @@ -0,0 +1,19 @@ +{ + "resourceType": "OperationOutcome", + "issue": [ + { + "code": "security", + "severity": "fatal", + "details": { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/http-error-codes", + "code": "SERVER_ERROR", + "display": "500: The Server has encountered an error processing the request." + } + ] + }, + "diagnostics": "Spine certificate is not configured" + } + ] +} diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-distance-selling.json b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-distance-selling.json new file mode 100644 index 000000000..a5946fa23 --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-distance-selling.json @@ -0,0 +1,232 @@ +{ + "resourceType": "Bundle", + "id": "155e1102-9e71-4f19-9453-b905c0bbc494", + "meta": { + "lastUpdated": "2022-11-21T14:00:00+00:00" + }, + "type": "searchset", + "link": [ + { + "relation": "self", + "url": "https://sandbox.api.service.nhs.uk/electronic-prescriptions/Bundle" + } + ], + "total": 1, + "entry": [ + { + "fullUrl": "urn:uuid:0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:a54219b8-f741-4c47-b662-e4f8dfa49ab6", + "resource": { + "resourceType": "MedicationRequest", + "status": "completed", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "39732311000001104", + "display": "Amoxicillin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-01-16" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-01-18T08:13:24Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Collected" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666", + "resource": { + "resourceType": "PractitionerRole", + "id": "56166769-c1c4-4d07-afa8-132b5dfca666", + "practitioner": { + "reference": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a" + }, + "organization": { + "reference": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8" + } + } + }, + { + "fullUrl": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "resource": { + "resourceType": "Practitioner", + "id": "a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "name": [ + { + "family": "BOIN", + "given": [ + "C" + ], + "prefix": [ + "DR" + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "resource": { + "resourceType": "Organization", + "id": "3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "A83008" + } + ], + "name": "HALLGARTH SURGERY", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9737320" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "HALLGARTH SURGERY", + "CHEAPSIDE" + ], + "city": "SHILDON", + "district": "COUNTY DURHAM", + "postalCode": "DL4 2HP" + } + ] + } + }, + { + "fullUrl": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "resource": { + "resourceType": "Organization", + "id": "afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "FLM49" + } + ], + "name": "PHARMACY2U", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9999999" + }, + { + "system": "url", + "use": "work", + "value": "www.pharmacy2u.co.uk" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "text": "Unit 4B, Victoria Road", + "postalCode": "TR1 3FF" + } + ] + } + } + ] + } + }, + { + "fullUrl": "urn:uuid:1a388581-dbbe-43e3-9054-f5976c0245e5", + "search": { + "mode": "outcome" + }, + "resource": { + "resourceType": "OperationOutcome", + "id": "1a388581-dbbe-43e3-9054-f5976c0245e5", + "meta": { + "lastUpdated": "2023-09-29T10:52:00+00:00" + }, + "issue": [ + { + "code": "business-rule", + "severity": "warning", + "details": { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode", + "code": "INVALIDATED_RESOURCE", + "display": "Invalidated resource" + } + ] + }, + "diagnostics": "Some prescriptions have been invalidated so could not be returned." + } + ] + } + } + ] +} diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-empty.json b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-empty.json new file mode 100644 index 000000000..2bf4a3ade --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-empty.json @@ -0,0 +1,10 @@ +{ + "resourceType": "Bundle", + "id": "155e1102-9e71-4f19-9453-b905c0bbc494", + "meta": { + "lastUpdated": "2022-11-21T14:00:00+00:00" + }, + "type": "searchset", + "total": 0, + "entry": [] +} diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-multiple-cancelled.json b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-multiple-cancelled.json new file mode 100644 index 000000000..b41304c3e --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-multiple-cancelled.json @@ -0,0 +1,686 @@ +{ + "resourceType": "Bundle", + "id": "155e1102-9e71-4f19-9453-b905c0bbc494", + "meta": { + "lastUpdated": "2022-11-21T14:00:00+00:00" + }, + "type": "searchset", + "total": 3, + "entry": [ + { + "fullUrl": "urn:uuid:0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:a54219b8-f741-4c47-b662-e4f8dfa49ab6", + "resource": { + "resourceType": "MedicationRequest", + "status": "cancelled", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "39732311000001104", + "display": "Amoxicillin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-02-27" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-03-02T14:04:36Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Prescriber Cancelled" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:6989b7bd-8db6-428c-a593-4022e3044c00", + "resource": { + "resourceType": "MedicationRequest", + "status": "stopped", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "322341003", + "display": "Co-codamol 30mg/500mg tablets" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-02-27" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-03-02T14:04:36Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Not Dispensed" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:2868554c-5565-4d31-b92a-c5b8dab8b90a", + "resource": { + "resourceType": "MedicationRequest", + "status": "cancelled", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "321080004", + "display": "Pseudoephedrine hydrochloride 60mg tablets" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-02-27" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-03-02T14:04:36Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Prescriber Cancelled" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:5cb17f5a-11ac-4e18-825f-6470467238b3", + "resource": { + "resourceType": "MedicationRequest", + "status": "stopped", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "324252006", + "display": "Azithromycin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-02-27" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-03-02T14:04:36Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Not Dispensed" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666", + "resource": { + "resourceType": "PractitionerRole", + "id": "56166769-c1c4-4d07-afa8-132b5dfca666", + "practitioner": { + "reference": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a" + }, + "organization": { + "reference": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8" + } + } + }, + { + "fullUrl": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "resource": { + "resourceType": "Practitioner", + "id": "a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "name": [ + { + "family": "BOIN", + "given": ["C"], + "prefix": ["DR"] + } + ] + } + }, + { + "fullUrl": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "resource": { + "resourceType": "Organization", + "id": "3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "A83008" + } + ], + "name": "HALLGARTH SURGERY", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9737320" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "HALLGARTH SURGERY", + "CHEAPSIDE", + "SHILDON", + "COUNTY DURHAM" + ], + "postalCode": "DL4 2HP" + } + ] + } + }, + { + "fullUrl": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "resource": { + "resourceType": "Organization", + "id": "afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "VNE51" + } + ], + "name": "Social Care Site - HEALTH AND CARE AT HOME", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9999999" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "text": "THE HEALTH AND WELLBEING INNOVATION C, TRELISKE, TRURO, CORNWALL", + "postalCode": "TR1 3FF" + } + ] + } + } + ] + } + }, + { + "fullUrl": "urn:uuid:5b77c3fa-8dc1-40eb-bd08-230c34f593f7", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "5b77c3fa-8dc1-40eb-bd08-230c34f593f7", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:ee035711-7aac-48c4-951a-62c07891d37d", + "resource": { + "resourceType": "MedicationRequest", + "status": "cancelled", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "324252006", + "display": "Azithromycin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:815c6eb3-41f8-4f48-9e0d-2983624d4f90" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "566946-B86044-FEFEFN" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-02-11" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-02-19T16:37:14Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Prescriber Cancelled" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:815c6eb3-41f8-4f48-9e0d-2983624d4f90", + "resource": { + "resourceType": "PractitionerRole", + "id": "815c6eb3-41f8-4f48-9e0d-2983624d4f90", + "practitioner": { + "reference": "urn:uuid:acd5b009-c78f-40f2-a48b-b38ac72de992" + }, + "organization": { + "reference": "urn:uuid:9683c147-ddad-41d9-9858-6e585c3f04df" + } + } + }, + { + "fullUrl": "urn:uuid:acd5b009-c78f-40f2-a48b-b38ac72de992", + "resource": { + "resourceType": "Practitioner", + "id": "acd5b009-c78f-40f2-a48b-b38ac72de992", + "name": [ + { + "family": "ROBINSON", + "given": ["C"], + "prefix": ["DR"] + } + ] + } + }, + { + "fullUrl": "urn:uuid:9683c147-ddad-41d9-9858-6e585c3f04df", + "resource": { + "resourceType": "Organization", + "id": "9683c147-ddad-41d9-9858-6e585c3f04df", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "B86044" + } + ], + "name": "IRELAND WOOD SURGERY", + "telecom": [ + { + "system": "phone", + "value": "0113 2303470" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "text": "IVESON APPROACH, LEEDS, WEST YORKSHIRE, ENGLAND, LS16 6FR" + } + ] + } + } + ] + } + }, + { + "fullUrl": "urn:uuid:37017443-4c6f-4c22-a46c-4362972e2008", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "37017443-4c6f-4c22-a46c-4362972e2008", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:5cb4600c-d758-42db-8091-16b030f6c00e", + "resource": { + "resourceType": "MedicationRequest", + "status": "stopped", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "324252006", + "display": "Azithromycin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:86affa2e-f6e9-4d39-831e-b9b132874cda" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "29AE98-C153C8-31BC6A" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2023-10-17" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2023-10-15T11:12:32Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Not Dispensed" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:86affa2e-f6e9-4d39-831e-b9b132874cda", + "resource": { + "resourceType": "PractitionerRole", + "id": "86affa2e-f6e9-4d39-831e-b9b132874cda", + "practitioner": { + "reference": "urn:uuid:01eca5b5-bf93-4c9e-ad70-abcfc39fc19e" + }, + "organization": { + "reference": "urn:uuid:0ef7bc64-5a55-4f96-9c5c-3b56c64819d5" + } + } + }, + { + "fullUrl": "urn:uuid:01eca5b5-bf93-4c9e-ad70-abcfc39fc19e", + "resource": { + "resourceType": "Practitioner", + "id": "01eca5b5-bf93-4c9e-ad70-abcfc39fc19e", + "name": [ + { + "family": "ROBINSON", + "given": ["C"], + "prefix": ["DR"] + } + ] + } + }, + { + "fullUrl": "urn:uuid:0ef7bc64-5a55-4f96-9c5c-3b56c64819d5", + "resource": { + "resourceType": "Organization", + "id": "0ef7bc64-5a55-4f96-9c5c-3b56c64819d5", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "B86044" + } + ], + "name": "IRELAND WOOD SURGERY", + "telecom": [ + { + "system": "phone", + "value": "0113 2303470" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "text": "IVESON APPROACH, LEEDS, WEST YORKSHIRE, ENGLAND, LS16 6FR" + } + ] + } + } + ] + } + } + ] +} diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-multiple-exclusion.json b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-multiple-exclusion.json new file mode 100644 index 000000000..ccebc5638 --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-multiple-exclusion.json @@ -0,0 +1,260 @@ +{ + "resourceType": "Bundle", + "id": "155e1102-9e71-4f19-9453-b905c0bbc494", + "meta": { + "lastUpdated": "2022-11-21T14:00:00+00:00" + }, + "type": "searchset", + "total": 1, + "entry": [ + { + "fullUrl": "urn:uuid:0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:a54219b8-f741-4c47-b662-e4f8dfa49ab6", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "39732311000001104", + "display": "Amoxicillin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-01-25" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-01-30T12:01:24Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Ready to Collect" + } + } + ] + } + ], + "note": [ + { + "text": "Located in Collection Locker 3. Access code '124564'" + } + ] + } + }, + { + "fullUrl": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666", + "resource": { + "resourceType": "PractitionerRole", + "id": "56166769-c1c4-4d07-afa8-132b5dfca666", + "practitioner": { + "reference": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a" + }, + "organization": { + "reference": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8" + } + } + }, + { + "fullUrl": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "resource": { + "resourceType": "Practitioner", + "id": "a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "name": [ + { + "family": "BOIN", + "given": [ + "C" + ], + "prefix": [ + "DR" + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "resource": { + "resourceType": "Organization", + "id": "3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "A83008" + } + ], + "name": "HALLGARTH SURGERY", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9737320" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "HALLGARTH SURGERY", + "CHEAPSIDE" + ], + "city": "SHILDON", + "district": "COUNTY DURHAM", + "postalCode": "DL4 2HP" + } + ] + } + }, + { + "fullUrl": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "resource": { + "resourceType": "Organization", + "id": "afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "VNE51" + } + ], + "name": "Social Care Site - HEALTH AND CARE AT HOME", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9999999" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "THE HEALTH AND WELLBEING INNOVATION C", + "TRELISKE" + ], + "city": "TRURO", + "district": "CORNWALL", + "postalCode": "TR1 3FF" + } + ] + } + } + ] + } + }, + { + "fullUrl": "urn:uuid:1a388581-dbbe-43e3-9054-f5976c0245e5", + "search": { + "mode": "outcome" + }, + "resource": { + "resourceType": "OperationOutcome", + "id": "1a388581-dbbe-43e3-9054-f5976c0245e5", + "meta": { + "lastUpdated": "2023-09-29T10:52:00+00:00" + }, + "issue": [ + { + "code": "business-rule", + "severity": "warning", + "details": { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode", + "code": "INVALIDATED_RESOURCE", + "display": "Invalidated resource" + } + ] + }, + "diagnostics": "Prescription with short form ID D7AC09-A99968-4BA59C has been invalidated so could not be returned." + } + ] + } + }, + { + "fullUrl": "urn:uuid:fedef61e-bc62-452e-91c0-6f44ad2d5c0c", + "search": { + "mode": "outcome" + }, + "resource": { + "resourceType": "OperationOutcome", + "id": "fedef61e-bc62-452e-91c0-6f44ad2d5c0c", + "meta": { + "lastUpdated": "2023-09-29T10:52:00+00:00" + }, + "issue": [ + { + "code": "business-rule", + "severity": "warning", + "details": { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode", + "code": "INVALIDATED_RESOURCE", + "display": "Invalidated resource" + } + ] + }, + "diagnostics": "Prescription with short form ID CDF34E-A99968-4FF3BQ has been invalidated so could not be returned." + } + ] + } + } + ] +} diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-multiple.json b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-multiple.json new file mode 100644 index 000000000..53b3693a2 --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-multiple.json @@ -0,0 +1,686 @@ +{ + "resourceType": "Bundle", + "id": "155e1102-9e71-4f19-9453-b905c0bbc494", + "meta": { + "lastUpdated": "2022-11-21T14:00:00+00:00" + }, + "type": "searchset", + "total": 3, + "entry": [ + { + "fullUrl": "urn:uuid:0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:a54219b8-f741-4c47-b662-e4f8dfa49ab6", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "39732311000001104", + "display": "Amoxicillin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-02-27" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-03-02T14:04:36Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "With Pharmacy - Preparing Remainder" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:6989b7bd-8db6-428c-a593-4022e3044c00", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "322341003", + "display": "Co-codamol 30mg/500mg tablets" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-02-27" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-03-02T14:04:36Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Ready to Collect - Partial" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:2868554c-5565-4d31-b92a-c5b8dab8b90a", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "321080004", + "display": "Pseudoephedrine hydrochloride 60mg tablets" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-02-27" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-03-02T14:04:36Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "With Pharmacy" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:5cb17f5a-11ac-4e18-825f-6470467238b3", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "324252006", + "display": "Azithromycin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-02-27" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-03-02T14:04:36Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Ready to Collect" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666", + "resource": { + "resourceType": "PractitionerRole", + "id": "56166769-c1c4-4d07-afa8-132b5dfca666", + "practitioner": { + "reference": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a" + }, + "organization": { + "reference": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8" + } + } + }, + { + "fullUrl": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "resource": { + "resourceType": "Practitioner", + "id": "a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "name": [ + { + "family": "BOIN", + "given": ["C"], + "prefix": ["DR"] + } + ] + } + }, + { + "fullUrl": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "resource": { + "resourceType": "Organization", + "id": "3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "A83008" + } + ], + "name": "HALLGARTH SURGERY", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9737320" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "HALLGARTH SURGERY", + "CHEAPSIDE", + "SHILDON", + "COUNTY DURHAM" + ], + "postalCode": "DL4 2HP" + } + ] + } + }, + { + "fullUrl": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "resource": { + "resourceType": "Organization", + "id": "afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "VNE51" + } + ], + "name": "Social Care Site - HEALTH AND CARE AT HOME", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9999999" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "text": "THE HEALTH AND WELLBEING INNOVATION C, TRELISKE, TRURO, CORNWALL", + "postalCode": "TR1 3FF" + } + ] + } + } + ] + } + }, + { + "fullUrl": "urn:uuid:5b77c3fa-8dc1-40eb-bd08-230c34f593f7", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "5b77c3fa-8dc1-40eb-bd08-230c34f593f7", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:ee035711-7aac-48c4-951a-62c07891d37d", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "324252006", + "display": "Azithromycin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:815c6eb3-41f8-4f48-9e0d-2983624d4f90" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "566946-B86044-FEFEFN" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-02-11" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-02-19T16:37:14Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Prescriber Approved" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:815c6eb3-41f8-4f48-9e0d-2983624d4f90", + "resource": { + "resourceType": "PractitionerRole", + "id": "815c6eb3-41f8-4f48-9e0d-2983624d4f90", + "practitioner": { + "reference": "urn:uuid:acd5b009-c78f-40f2-a48b-b38ac72de992" + }, + "organization": { + "reference": "urn:uuid:9683c147-ddad-41d9-9858-6e585c3f04df" + } + } + }, + { + "fullUrl": "urn:uuid:acd5b009-c78f-40f2-a48b-b38ac72de992", + "resource": { + "resourceType": "Practitioner", + "id": "acd5b009-c78f-40f2-a48b-b38ac72de992", + "name": [ + { + "family": "ROBINSON", + "given": ["C"], + "prefix": ["DR"] + } + ] + } + }, + { + "fullUrl": "urn:uuid:9683c147-ddad-41d9-9858-6e585c3f04df", + "resource": { + "resourceType": "Organization", + "id": "9683c147-ddad-41d9-9858-6e585c3f04df", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "B86044" + } + ], + "name": "IRELAND WOOD SURGERY", + "telecom": [ + { + "system": "phone", + "value": "0113 2303470" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "text": "IVESON APPROACH, LEEDS, WEST YORKSHIRE, ENGLAND, LS16 6FR" + } + ] + } + } + ] + } + }, + { + "fullUrl": "urn:uuid:37017443-4c6f-4c22-a46c-4362972e2008", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "37017443-4c6f-4c22-a46c-4362972e2008", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:5cb4600c-d758-42db-8091-16b030f6c00e", + "resource": { + "resourceType": "MedicationRequest", + "status": "completed", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "324252006", + "display": "Azithromycin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:86affa2e-f6e9-4d39-831e-b9b132874cda" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "29AE98-C153C8-31BC6A" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2023-10-17" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2023-10-15T11:12:32Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Dispatched" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:86affa2e-f6e9-4d39-831e-b9b132874cda", + "resource": { + "resourceType": "PractitionerRole", + "id": "86affa2e-f6e9-4d39-831e-b9b132874cda", + "practitioner": { + "reference": "urn:uuid:01eca5b5-bf93-4c9e-ad70-abcfc39fc19e" + }, + "organization": { + "reference": "urn:uuid:0ef7bc64-5a55-4f96-9c5c-3b56c64819d5" + } + } + }, + { + "fullUrl": "urn:uuid:01eca5b5-bf93-4c9e-ad70-abcfc39fc19e", + "resource": { + "resourceType": "Practitioner", + "id": "01eca5b5-bf93-4c9e-ad70-abcfc39fc19e", + "name": [ + { + "family": "ROBINSON", + "given": ["C"], + "prefix": ["DR"] + } + ] + } + }, + { + "fullUrl": "urn:uuid:0ef7bc64-5a55-4f96-9c5c-3b56c64819d5", + "resource": { + "resourceType": "Organization", + "id": "0ef7bc64-5a55-4f96-9c5c-3b56c64819d5", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "B86044" + } + ], + "name": "IRELAND WOOD SURGERY", + "telecom": [ + { + "system": "phone", + "value": "0113 2303470" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "text": "IVESON APPROACH, LEEDS, WEST YORKSHIRE, ENGLAND, LS16 6FR" + } + ] + } + } + ] + } + } + ] +} diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-ready-dispatch.json b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-ready-dispatch.json new file mode 100644 index 000000000..cb2e8c367 --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-ready-dispatch.json @@ -0,0 +1,414 @@ +{ + "resourceType": "Bundle", + "id": "155e1102-9e71-4f19-9453-b905c0bbc494", + "meta": { + "lastUpdated": "2022-11-21T14:00:00+00:00" + }, + "type": "searchset", + "total": 1, + "entry": [ + { + "fullUrl": "urn:uuid:0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:a54219b8-f741-4c47-b662-e4f8dfa49ab6", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "39732311000001104", + "display": "Amoxicillin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-01-17" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-02-01T11:14:21Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Ready to Dispatch" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:6989b7bd-8db6-428c-a593-4022e3044c00", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "322341003", + "display": "Co-codamol 30mg/500mg tablets" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-01-17" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-02-01T11:14:21Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Ready to Dispatch - Partial" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:2868554c-5565-4d31-b92a-c5b8dab8b90a", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "321080004", + "display": "Pseudoephedrine hydrochloride 60mg tablets" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-01-17" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-02-01T11:14:21Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Ready to Dispatch" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:5cb17f5a-11ac-4e18-825f-6470467238b3", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "324252006", + "display": "Azithromycin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-01-17" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-02-01T11:14:21Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Ready to Dispatch - Partial" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666", + "resource": { + "resourceType": "PractitionerRole", + "id": "56166769-c1c4-4d07-afa8-132b5dfca666", + "practitioner": { + "reference": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a" + }, + "organization": { + "reference": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8" + } + } + }, + { + "fullUrl": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "resource": { + "resourceType": "Practitioner", + "id": "a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "name": [ + { + "family": "BOIN", + "given": [ + "C" + ], + "prefix": [ + "DR" + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "resource": { + "resourceType": "Organization", + "id": "3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "A83008" + } + ], + "name": "HALLGARTH SURGERY", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9737320" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "HALLGARTH SURGERY", + "CHEAPSIDE", + "SHILDON", + "COUNTY DURHAM" + ], + "postalCode": "DL4 2HP" + } + ] + } + }, + { + "fullUrl": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "resource": { + "resourceType": "Organization", + "id": "afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "VNE51" + } + ], + "name": "Social Care Site - HEALTH AND CARE AT HOME", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9999999" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "text": "THE HEALTH AND WELLBEING INNOVATION C, TRELISKE, TRURO, CORNWALL", + "postalCode": "TR1 3FF" + } + ] + } + } + ] + } + } + ] +} diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-single-exclusion.json b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-single-exclusion.json new file mode 100644 index 000000000..31d0770af --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-single-exclusion.json @@ -0,0 +1,232 @@ +{ + "resourceType": "Bundle", + "id": "155e1102-9e71-4f19-9453-b905c0bbc494", + "meta": { + "lastUpdated": "2022-11-21T14:00:00+00:00" + }, + "type": "searchset", + "link": [ + { + "relation": "self", + "url": "https://sandbox.api.service.nhs.uk/electronic-prescriptions/Bundle" + } + ], + "total": 1, + "entry": [ + { + "fullUrl": "urn:uuid:0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:a54219b8-f741-4c47-b662-e4f8dfa49ab6", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "39732311000001104", + "display": "Amoxicillin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2023-11-14" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2023-12-02T15:27:53Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "With Pharmacy but Tracking not Supported" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666", + "resource": { + "resourceType": "PractitionerRole", + "id": "56166769-c1c4-4d07-afa8-132b5dfca666", + "practitioner": { + "reference": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a" + }, + "organization": { + "reference": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8" + } + } + }, + { + "fullUrl": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "resource": { + "resourceType": "Practitioner", + "id": "a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "name": [ + { + "family": "BOIN", + "given": [ + "C" + ], + "prefix": [ + "DR" + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "resource": { + "resourceType": "Organization", + "id": "3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "A83008" + } + ], + "name": "HALLGARTH SURGERY", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9737320" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "HALLGARTH SURGERY", + "CHEAPSIDE" + ], + "city": "SHILDON", + "district": "COUNTY DURHAM", + "postalCode": "DL4 2HP" + } + ] + } + }, + { + "fullUrl": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "resource": { + "resourceType": "Organization", + "id": "afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "VNE51" + } + ], + "name": "Social Care Site - HEALTH AND CARE AT HOME", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9999999" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "THE HEALTH AND WELLBEING INNOVATION C", + "TRELISKE" + ], + "city": "TRURO", + "district": "CORNWALL", + "postalCode": "TR1 3FF" + } + ] + } + } + ] + } + }, + { + "fullUrl": "urn:uuid:fedef61e-bc62-452e-91c0-6f44ad2d5c0c", + "search": { + "mode": "outcome" + }, + "resource": { + "resourceType": "OperationOutcome", + "id": "fedef61e-bc62-452e-91c0-6f44ad2d5c0c", + "meta": { + "lastUpdated": "2023-09-29T10:52:00+00:00" + }, + "issue": [ + { + "code": "business-rule", + "severity": "warning", + "details": { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode", + "code": "INVALIDATED_RESOURCE", + "display": "Invalidated resource" + } + ] + }, + "diagnostics": "Prescription with short form ID CDF34E-A99968-4FF3BQ has been invalidated so could not be returned." + } + ] + } + } + ] +} diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-tracking-temporarily-unavailable.json b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-tracking-temporarily-unavailable.json new file mode 100644 index 000000000..1184e7248 --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success-tracking-temporarily-unavailable.json @@ -0,0 +1,232 @@ +{ + "resourceType": "Bundle", + "id": "155e1102-9e71-4f19-9453-b905c0bbc494", + "meta": { + "lastUpdated": "2022-11-21T14:00:00+00:00" + }, + "type": "searchset", + "link": [ + { + "relation": "self", + "url": "https://sandbox.api.service.nhs.uk/electronic-prescriptions/Bundle" + } + ], + "total": 1, + "entry": [ + { + "fullUrl": "urn:uuid:0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:a54219b8-f741-4c47-b662-e4f8dfa49ab6", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "39732311000001104", + "display": "Amoxicillin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2023-11-14" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2023-12-02T15:27:53Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "Tracking Temporarily Unavailable" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666", + "resource": { + "resourceType": "PractitionerRole", + "id": "56166769-c1c4-4d07-afa8-132b5dfca666", + "practitioner": { + "reference": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a" + }, + "organization": { + "reference": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8" + } + } + }, + { + "fullUrl": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "resource": { + "resourceType": "Practitioner", + "id": "a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "name": [ + { + "family": "BOIN", + "given": [ + "C" + ], + "prefix": [ + "DR" + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "resource": { + "resourceType": "Organization", + "id": "3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "A83008" + } + ], + "name": "HALLGARTH SURGERY", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9737320" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "HALLGARTH SURGERY", + "CHEAPSIDE" + ], + "city": "SHILDON", + "district": "COUNTY DURHAM", + "postalCode": "DL4 2HP" + } + ] + } + }, + { + "fullUrl": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "resource": { + "resourceType": "Organization", + "id": "afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "VNE51" + } + ], + "name": "Social Care Site - HEALTH AND CARE AT HOME", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9999999" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "THE HEALTH AND WELLBEING INNOVATION C", + "TRELISKE" + ], + "city": "TRURO", + "district": "CORNWALL", + "postalCode": "TR1 3FF" + } + ] + } + } + ] + } + }, + { + "fullUrl": "urn:uuid:fedef61e-bc62-452e-91c0-6f44ad2d5c0c", + "search": { + "mode": "outcome" + }, + "resource": { + "resourceType": "OperationOutcome", + "id": "fedef61e-bc62-452e-91c0-6f44ad2d5c0c", + "meta": { + "lastUpdated": "2023-09-29T10:52:00+00:00" + }, + "issue": [ + { + "code": "business-rule", + "severity": "warning", + "details": { + "coding": [ + { + "system": "https://fhir.nhs.uk/CodeSystem/Spine-ErrorOrWarningCode", + "code": "INVALIDATED_RESOURCE", + "display": "Invalidated resource" + } + ] + }, + "diagnostics": "Prescription with short form ID CDF34E-A99968-4FF3BQ has been invalidated so could not be returned." + } + ] + } + } + ] +} diff --git a/packages/specification/examples/GetMyPrescriptions/Bundle/success/success.json b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success.json new file mode 100644 index 000000000..383f0060c --- /dev/null +++ b/packages/specification/examples/GetMyPrescriptions/Bundle/success/success.json @@ -0,0 +1,414 @@ +{ + "resourceType": "Bundle", + "id": "155e1102-9e71-4f19-9453-b905c0bbc494", + "meta": { + "lastUpdated": "2022-11-21T14:00:00+00:00" + }, + "type": "searchset", + "total": 1, + "entry": [ + { + "fullUrl": "urn:uuid:0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "search": { + "mode": "match" + }, + "resource": { + "resourceType": "Bundle", + "id": "0cb82cfa-76c8-4fb2-a08e-bf0e326e5487", + "type": "collection", + "entry": [ + { + "fullUrl": "urn:uuid:a54219b8-f741-4c47-b662-e4f8dfa49ab6", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "39732311000001104", + "display": "Amoxicillin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-01-17" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-02-01T11:14:21Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "With Pharmacy" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:6989b7bd-8db6-428c-a593-4022e3044c00", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "322341003", + "display": "Co-codamol 30mg/500mg tablets" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-01-17" + }, + "quantity": { + "value": 20, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-02-01T11:14:21Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "With Pharmacy" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:2868554c-5565-4d31-b92a-c5b8dab8b90a", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "321080004", + "display": "Pseudoephedrine hydrochloride 60mg tablets" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-01-17" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-02-01T11:14:21Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "With Pharmacy" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:5cb17f5a-11ac-4e18-825f-6470467238b3", + "resource": { + "resourceType": "MedicationRequest", + "status": "active", + "intent": "order", + "medicationCodeableConcept": { + "coding": [ + { + "system": "http://snomed.info/sct", + "code": "324252006", + "display": "Azithromycin 250mg capsules" + } + ] + }, + "subject": { + "identifier": { + "system": "https://fhir.nhs.uk/Id/nhs-number", + "value": "9449304130" + } + }, + "requester": { + "reference": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666" + }, + "groupIdentifier": { + "system": "https://fhir.nhs.uk/Id/prescription-order-number", + "value": "24F5DA-A83008-7EFE6Z" + }, + "courseOfTherapyType": { + "coding": [ + { + "system": "http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy", + "code": "acute", + "display": "Short course (acute) therapy" + } + ] + }, + "dispenseRequest": { + "validityPeriod": { + "start": "2024-01-17" + }, + "quantity": { + "value": 30, + "unit": "tablet", + "system": "http://snomed.info/sct", + "code": "428673006" + }, + "performer": { + "reference": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1" + } + }, + "substitution": { + "allowedBoolean": false + }, + "extension": [ + { + "url": "https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory", + "extension": [ + { + "url": "statusDate", + "valueDateTime": "2024-02-01T11:14:21Z" + }, + { + "url": "status", + "valueCoding": { + "system": "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt", + "code": "With Pharmacy" + } + } + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666", + "resource": { + "resourceType": "PractitionerRole", + "id": "56166769-c1c4-4d07-afa8-132b5dfca666", + "practitioner": { + "reference": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a" + }, + "organization": { + "reference": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8" + } + } + }, + { + "fullUrl": "urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "resource": { + "resourceType": "Practitioner", + "id": "a8c85454-f8cb-498d-9629-78e2cb5fa47a", + "name": [ + { + "family": "BOIN", + "given": [ + "C" + ], + "prefix": [ + "DR" + ] + } + ] + } + }, + { + "fullUrl": "urn:uuid:3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "resource": { + "resourceType": "Organization", + "id": "3b4b03a5-52ba-4ba6-9b82-70350aa109d8", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "A83008" + } + ], + "name": "HALLGARTH SURGERY", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9737320" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "line": [ + "HALLGARTH SURGERY", + "CHEAPSIDE", + "SHILDON", + "COUNTY DURHAM" + ], + "postalCode": "DL4 2HP" + } + ] + } + }, + { + "fullUrl": "urn:uuid:afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "resource": { + "resourceType": "Organization", + "id": "afb07f8b-e8d7-4cad-895d-494e6b35b2a1", + "identifier": [ + { + "system": "https://fhir.nhs.uk/Id/ods-organization-code", + "value": "VNE51" + } + ], + "name": "Social Care Site - HEALTH AND CARE AT HOME", + "telecom": [ + { + "system": "phone", + "use": "work", + "value": "0115 9999999" + } + ], + "address": [ + { + "use": "work", + "type": "both", + "text": "THE HEALTH AND WELLBEING INNOVATION C, TRELISKE, TRURO, CORNWALL", + "postalCode": "TR1 3FF" + } + ] + } + } + ] + } + } + ] +} diff --git a/packages/specification/package.json b/packages/specification/package.json new file mode 100644 index 000000000..e3f6f9005 --- /dev/null +++ b/packages/specification/package.json @@ -0,0 +1,23 @@ +{ + "name": "apim-spec", + "version": "0.0.1", + "description": "OAS (Swagger v3) API Definition for Prescriptions for Patients", + "homepage": "https://github.com/NHSDigital/prescriptionsforpatients", + "author": "NHS Digital", + "license": "MIT", + "type": "module", + "engines": { + "node": "20.10.x", + "npm": "10.2.x" + }, + "scripts": { + "lint": "redocly lint --extends=recommended --config ./redocly.yaml", + "compile": "redocly bundle prescriptions-for-patients.yaml -d -o dist/prescriptions-for-patients.resolved.json", + "clean": "rm -rf lib coverage", + "check-licenses": "license-checker --failOn GPL --failOn LGPL --start ../.." + }, + "devDependencies": { + "@redocly/cli": "^2.12.6", + "tsx": "4.21.0" + } +} diff --git a/packages/specification/prescriptions-for-patients.yaml b/packages/specification/prescriptions-for-patients.yaml new file mode 100644 index 000000000..4866ca17b --- /dev/null +++ b/packages/specification/prescriptions-for-patients.yaml @@ -0,0 +1,448 @@ +# This is an OpenAPI Specification (https://swagger.io/specification/) +# for the Prescriptions API +# owned by NHS Digital (https://digital.nhs.uk/) + +openapi: 3.0.3 +info: + title: Prescriptions for Patients API + version: "0.0.1" + contact: + name: Prescriptions for Patients API Support + url: https://digital.nhs.uk/developer/help-and-support + email: api.management@nhs.net + description: | + ## Overview + Use this API to retrieve prescriptions data for individual patients from the [Electronic Prescription Service (EPS)](https://digital.nhs.uk/developer/api-catalogue/electronic-prescription-service-fhir). + + For use in patient-facing applications such as NHS App, to allow patients to view their digital prescriptions. + + Patients can use their digital prescriptions to collect their medication at any pharmacy in England. + Patients will be able to view: + * repeat and acute prescriptions created using the [Electronic Prescription Service](https://digital.nhs.uk/developer/api-catalogue/electronic-prescription-service-fhir) + * information about the pharmacy their prescriptions can be collected from or will be delivered by + * limited information about the status of their prescriptions + + ## Who can use this API + Currently, this API is for [internal use only](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#statuses) - the only API consumer is the NHS App. + + It is not currently available for integration by external third parties. + + ## Related APIs + The following APIs are related to this API: + * [Electronic Prescriptions Service](https://digital.nhs.uk/developer/api-catalogue/electronic-prescription-service-fhir): The national service for creating and dispensing prescriptions across health and social care. + * [Personal Demographics Service](https://digital.nhs.uk/developer/api-catalogue/personal-demographics-service-fhir): the national service for storing and retrieving NHS patient details such as name, address, date of birth, related people, registered GP and NHS number. + + ## API status and roadmap + This API is in an [internal private beta](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#statuses), meaning the API is not currently available for integration by external third parties. + + If you want to use this API when it becomes available for external use, contact us at epsonboarding@nhs.net to register your interest. + + ## Service Level + This API is a silver service, meaning it is operational and supported between 8am and 6pm, Monday to Friday, but not bank holidays. + For more details, see [service levels](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#service-levels) + + ## Technology + This API is [RESTful](https://digital.nhs.uk/developer/guides-and-documentation/our-api-technologies#basic-rest). + + It conforms to the [FHIR](https://digital.nhs.uk/developer/guides-and-documentation/our-api-technologies#fhir) global standard for health care data exchange, specifically to [FHIR UK Core](https://digital.nhs.uk/services/fhir-uk-core). + + It includes some country-specific FHIR extensions, which are built against [FHIR UK Core, specifically [UKcore.stu1 0.5.1](https://simplifier.net/packages/fhir.r4.ukcore.stu1/0.5.1). + + You do not need to know much about FHIR to use this API. The API only supports GET requests and the responses will be FHIR. + + FHIR APIs are just RESTful APIs that follow specific rules. In particular: + * resource names are capitalised and singular, for example `/Bundle` not `/bundle` + * array names are singular, for example `line` not `lines` for address lines + * data items that are country-specific and thus not included in the FHIR global base resources are usually wrapped in an `extension` object + + There are [libraries and software development kits available](https://digital.nhs.uk/developer/guides-and-documentation/api-technologies-at-nhs-digital#fhir-libraries-and-sdks) to help with FHIR API integration. + + ## Network access + This API is available on the internet. + + For more details see [Network access for APIs](https://digital.nhs.uk/developer/guides-and-documentation/network-access-for-apis). + + ## Security and authorisation + This API is [user-restricted](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation#user-restricted-apis), meaning an end user must be present, authenticated and authorised. + + The end user must be: + * a patient who receives health and social care or makes use of NHS services + * strongly authenticated to a P9 level, using [NHS login - separate authentication and authorisation](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/user-restricted-restful-apis-nhs-login-separate-authentication-and-authorisation) + + To use this API, use the following security pattern: + + | Security pattern | Technical details | Advantages | Disadvantages | + |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ----------------------------------------------------| ------------------------------------------------------------|---------------------------------------------------------| + |[NHS login - separate authentication and authorisation](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation/user-restricted-restful-apis-nhs-login-separate-authentication-and-authorisation) |OAuth 2.0 token exchange with signed JWT |Gives access to user information. |Need to integrate and onboard separately with NHS login. | + + ## Environment and testing + | Environment | Base URL | + | --------------------- | ---------------------------------------------------------------------------- | + | Integration | `https://int.api.service.nhs.uk/prescriptions-for-patients` | + | Production | Not yet available | + | Sandbox | `https://sandbox.api.service.nhs.uk/prescriptions-for-patients` | + + ## Onboarding + This API is not currently available to external third parties for onboarding. + + ## Errors + We use standard HTTP status codes to show whether an API request succeeded or not. They are usually in the range: + + * 200 to 299 if it succeeded, including code 202 if it was accepted by an API that needs to wait for further action + * 400 to 499 if it failed because of a client error by your application + * 500 to 599 if it failed because of an error on our server + + Errors specific to each API are shown in the Endpoints section, under Response. See our [reference guide](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#http-status-codes) for more on errors. + +x-spec-publication: + operation-order: + - operations: + - method: GET + path: /Bundle + +servers: + - url: https://internal-dev.api.service.nhs.uk/prescriptions-for-patients + description: Internal Dev + - url: "https://sandbox.api.service.nhs.uk/prescriptions-for-patients" + description: Sandbox + - url: "https://int.api.service.nhs.uk/prescriptions-for-patients" + description: Integration + - url: "https://api.service.nhs.uk/prescriptions-for-patients" + description: Production + +paths: + /Bundle: + get: + operationId: prescriptions-for-patients-bundle + summary: Get prescriptions + description: | + ## Overview + Use this endpoint to get a list of a patient's prescriptions, expressed as a FHIR Bundle. + parameters: + - $ref: "#/components/parameters/BearerAuthorisation" + - $ref: "#/components/parameters/RequestID" + - $ref: "#/components/parameters/CorrelationID" + security: + - nhs-login-p9: [] + responses: + "200": + description: Successful retrieval. + content: + application/fhir+json: + schema: + $ref: "#/components/schemas/bundle-response" + examples: + prescriptions-present: + description: A successful response to a GetMyPrescriptions/Bundle request, containing one prescription. + value: + $ref: "examples/GetMyPrescriptions/Bundle/success/success.json" + prescriptions-present-multiple: + description: A successful response to a GetMyPrescriptions/Bundle request, containing multiple prescriptions. + value: + $ref: "examples/GetMyPrescriptions/Bundle/success/success-multiple.json" + prescriptions-not-present: + description: A successful response to a GetMyPrescriptions/Bundle request, where no prescriptions were found. + value: + $ref: "examples/GetMyPrescriptions/Bundle/success/success-empty.json" + prescriptions-ready-to-dispatch: + description: A successful response to a GetMyPrescriptions/Bundle request, where prescriptions are ready to be dispatched. + value: + $ref: "examples/GetMyPrescriptions/Bundle/success/success-ready-dispatch.json" + prescriptions-cancelled-not-dispensed: + description: A successful response to a GetMyPrescriptions/Bundle request, where prescriptions have been cancelled or not dispensed. + value: + $ref: "examples/GetMyPrescriptions/Bundle/success/success-multiple-cancelled.json" + prescription-excluded: + description: A successful response to a GetMyPrescriptions/Bundle request, with a single prescription excluded. + value: + $ref: "examples/GetMyPrescriptions/Bundle/success/success-single-exclusion.json" + prescriptions-excluded: + description: A successful response to a GetMyPrescriptions/Bundle request, with multiple prescriptions excluded. + value: + $ref: "examples/GetMyPrescriptions/Bundle/success/success-multiple-exclusion.json" + distance-selling-pharmacy: + description: A successful response to a GetMyPrescriptions/Bundle request, where the performer organisation is a distance selling pharmacy. + value: + $ref: "examples/GetMyPrescriptions/Bundle/success/success-distance-selling.json" + tracking-temporarily-unavailable: + description: A successful response to a GetMyPrescriptions/Bundle request, when tracking is temporarily unavailable. + value: + $ref: "examples/GetMyPrescriptions/Bundle/success/success-tracking-temporarily-unavailable.json" + + "4XX": + description: | + An error occurred as follows: + + | HTTP status | Error code | Description | + | ----------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | + | 401 | `ACCESS_DENIED` | Missing or invalid OAuth 2.0 bearer token in request | + | 408 | `timeout` | Request timed out | + | 429 | `throttled` | You have exceeded your application's [rate limit](https://digital.nhs.uk/developer/guides-and-documentation/reference-guide#rate-limits). | + + The error code will be included in the returned OperationOutcome (below). + content: + application/fhir+json: + schema: + $ref: "#/components/schemas/operation-outcome" + examples: + example: + description: | + An error response to a GetMyPrescriptions/Bundle request that invalidates the request. + value: + $ref: examples/GetMyPrescriptions/Bundle/error/error-401.json + "500": + description: | + An error occurred as follows: + + | HTTP status | Error code | Description | + | ----------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | + | 500 | `SERVER_ERROR` | An internal error has occurred when processing the request. | + + The error code will be included in the returned OperationOutcome (below). + content: + application/fhir+json: + schema: + $ref: "#/components/schemas/operation-outcome" + examples: + example: + description: | + An error response to a GetMyPrescriptions/Bundle request that invalidates the request. + value: + $ref: examples/GetMyPrescriptions/Bundle/error/error-500.json +components: + securitySchemes: + nhs-login-p9: + $ref: https://proxygen.prod.api.platform.nhs.uk/components/securitySchemes/nhs-login-p9 + parameters: + BearerAuthorisation: + in: header + name: Authorization + description: | + An [OAuth 2.0 bearer token](https://digital.nhs.uk/developer/guides-and-documentation/security-and-authorisation#user-restricted-apis). + required: true + schema: + type: string + format: '^Bearer\ [[:ascii:]]+$' + example: "Bearer g1112R_ccQ1Ebbb4gtHBP1aaaNM" + RequestID: + in: header + name: X-Request-ID + required: true + description: | + A globally unique identifier (GUID) for the request, which we use to correlate logs through different components. + Must be a universally unique identifier (UUID) (ideally version 4). + Mirrored back in a response header. + schema: + type: string + pattern: "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + example: 60E0B220-8136-4CA5-AE46-1D97EF59D068 + CorrelationID: + in: header + name: X-Correlation-ID + required: false + description: | + An optional ID which you can use to track transactions across multiple systems. If included, its value must be a valid GUID. + Mirrored back in a response header. + schema: + type: string + pattern: "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" + example: 11C46F5F-CDEF-4865-94B2-0EE0EDCC26DA + schemas: + bundle-response: + type: object + required: + - resourceType + - id + - meta + - type + - total + - entry + description: A FHIR searchset Bundle. + properties: + resourceType: + type: string + description: FHIR resource type. + default: Bundle + id: + type: string + description: Object ID for the Bundle. + example: 164996aa-29eb-4f14-a5ac-4b556a7baf6e + meta: + type: object + description: Metadata about the bundle + properties: + lastUpdated: + type: string + description: Datetime of the bundle's creation + example: "2022-11-21T14:00:00+00:00" + type: + type: string + description: Denotes that the bundle is a list of resources returned as a result of a search. + enum: [searchset] + total: + type: number + description: | + The number of prescription bundles contained within the searchset + + Note that this excludes OperationOutcomes. + entry: + type: array + description: | + A collection of resources contained within the Bundle. + + Note that the presence of an OperationOutcome resource as part of the bundle implies that one + of a patient's prescriptions have been excluded from the response due to a processing error. + An OperationOutcome resource will be included for each prescription that cannot be processed. + items: + oneOf: + - $ref: "#/components/schemas/PrescriptionBundle" + - $ref: "#/components/schemas/OperationOutcome-Resource" + PrescriptionBundle: + type: object + required: + - fullUrl + - search + - resource + properties: + fullUrl: + type: string + example: urn:uuid:fedef61e-bc62-452e-91c0-6f44ad2d5c0c + description: The FHIR urn of the contained Bundle + search: + type: object + properties: + mode: + type: string + example: match + resource: + $ref: "#/components/schemas/CollectionBundle" + CollectionBundle: + type: object + required: + - resourceType + - identifier + - type + - entry + description: A FHIR collection Bundle. + properties: + resourceType: + type: string + description: FHIR resource type. + default: Bundle + id: + type: string + description: Object ID for the Bundle. + example: 164996aa-29eb-4f14-a5ac-4b556a7baf6e + type: + type: string + description: Denotes that the bundle is a collection of resources. Representing a Prescription, in this case. + enum: [collection] + entry: + type: array + description: | + A collection of resources contained within the Bundle. + + Note that the presence of an OperationOutcome resource as part of the bundle implies that one + of a patient's prescriptions have been excluded from the response due to a processing error. + An OperationOutcome resource will be included for each prescription that cannot be processed. + items: + oneOf: + - $ref: "#/components/schemas/MedicationRequest-Resource" + - $ref: "#/components/schemas/OrganisationDispensing-Resource" + - $ref: "#/components/schemas/Practitioner-Resource" + - $ref: "#/components/schemas/PractitionerRole-Resource" + MedicationRequest-Resource: + type: object + description: MedicationRequest + properties: + fullUrl: + type: string + example: urn:uuid:fedef61e-bc62-452e-91c0-6f44ad2d5c0c + description: The FHIR urn of the contained resource + resource: + $ref: schemas/resources/MedicationRequest.yaml + OrganisationDispensing-Resource: + type: object + description: Dispensing Organisation + properties: + fullUrl: + type: string + example: urn:uuid:fedef61e-bc62-452e-91c0-6f44ad2d5c0c + description: The FHIR urn of the contained resource + resource: + $ref: schemas/resources/Organisation.yaml + OrganisationPrescribing-Resource: + type: object + description: Prescribing Organisation + properties: + fullUrl: + type: string + example: urn:uuid:fedef61e-bc62-452e-91c0-6f44ad2d5c0c + description: The FHIR urn of the contained resource + resource: + $ref: schemas/resources/Organisation.yaml + Practitioner-Resource: + type: object + description: Practitioner + properties: + fullUrl: + type: string + example: urn:uuid:fedef61e-bc62-452e-91c0-6f44ad2d5c0c + description: The FHIR urn of the contained resource + resource: + $ref: schemas/resources/Practitioner.yaml + PractitionerRole-Resource: + type: object + description: PractitionerRole + properties: + fullUrl: + type: string + example: urn:uuid:fedef61e-bc62-452e-91c0-6f44ad2d5c0c + description: The FHIR urn of the contained resource + resource: + $ref: schemas/resources/PractitionerRole.yaml + OperationOutcome-Resource: + type: object + description: OperationOutcome + properties: + fullUrl: + type: string + example: urn:uuid:fedef61e-bc62-452e-91c0-6f44ad2d5c0c + description: The FHIR urn of the contained resource + resource: + $ref: schemas/resources/OperationOutcome.yaml + operation-outcome: + $ref: schemas/resources/OperationOutcome.yaml +x-nhsd-apim: + temporary: false + monitoring: true + access: + - title: User Restricted + grants: + nhs-login-p9: [] + target: + type: external + healthcheck: /_status + url: https://internal-dev.api.service.nhs.uk/ + security: + type: mtls + secret: prescriptions-for-patients-mtls-1 + target-identity: + - name: nhs-login-nhs-number + header: "nhsd-nhslogin-user" + - name: nhs-login-identity-proofing-level + header: "nhs-login-identity-proofing-level" + target-attributes: + - name: developer.app.name + required: false + header: "nhsd-application-name" + - name: developer.app.id + required: false + header: "nhsd-application-id" + ratelimiting: + proxy: + limit: 20000 + timeunit: minute + app-default: + limit: 20000 + timeunit: minute diff --git a/packages/specification/redocly.yaml b/packages/specification/redocly.yaml new file mode 100644 index 000000000..2bfa4b078 --- /dev/null +++ b/packages/specification/redocly.yaml @@ -0,0 +1,3 @@ +apis: + pfp: + root: ./dist/prescriptions-for-patients.resolved.json diff --git a/packages/specification/schemas/fragments/address.yaml b/packages/specification/schemas/fragments/address.yaml new file mode 100644 index 000000000..41c4af9fd --- /dev/null +++ b/packages/specification/schemas/fragments/address.yaml @@ -0,0 +1,47 @@ +type: object +properties: + use: + type: string + description: The purpose of the address. + default: work + enum: [home, work, billing, temp] + type: + type: string + description: The type of address. + default: both + enum: [postal, physical, both] + line: + type: array + description: | + All lines of the address, and optionally postal code. + Systems will apply the following formatting convention when adding or replacing addresses lines: + If any of the lines are blank, they are not returned due to FHIR conformance constraints. + items: + type: string + example: + - 1 Trevelyan Square + - Boar Lane + - City Centre + text: + type: string + description: | + A plain text string address, optionally including the postal code. + example: IVESON APPROACH, LEEDS, WEST YORKSHIRE, ENGLAND, LS16 6FR + city: + type: string + description: | + The city of the address. + Note: This will not be populated by existing prescriptions. + example: Leeds + district: + type: string + description: | + The district of the address. + Note: This will not be populated by existing prescriptions. + example: West Yorkshire + postalCode: + type: string + description: | + The postal code of the address. + Note: This is an optionally populated field. Postal code may be included in line or text if absent. + example: LS1 6AE diff --git a/packages/specification/schemas/fragments/codes.yaml b/packages/specification/schemas/fragments/codes.yaml new file mode 100644 index 000000000..d4d408512 --- /dev/null +++ b/packages/specification/schemas/fragments/codes.yaml @@ -0,0 +1,54 @@ +MedicationRequestCourseOfTherapy: + type: object + required: [system, code] + properties: + system: + type: string + description: Codesystem URL for the prescription treatment type. + enum: + - http://terminology.hl7.org/CodeSystem/medicationrequest-course-of-therapy + code: + type: string + description: | + Code identifying the prescription treatment type. + * acute: one-off prescriptions + * continuous: repeat prescriptions + enum: [acute, continuous] + display: + type: string + description: Display value for the prescription treatment type. + enum: + - Short course (acute) therapy + - Continuous long term therapy +SnomedSctMedication: + type: object + required: [system, code] + properties: + system: + type: string + description: SNOMED codesystem URL. + enum: [http://snomed.info/sct] + code: + type: string + description: SNOMED code for the medication, as defined in the Dictionary of Medicines and Devices (DM+D). + example: "321196004" + display: + type: string + description: Human readable name for the medication. + example: Diazepam 2mg tablets +SpineErrorOrWarningCode: + type: object + required: [system, code] + properties: + system: + type: string + description: URI of the coding system specification. + enum: [https://fhir.nhs.uk/R4/CodeSystem/Spine-ErrorOrWarningCode] + code: + type: string + description: Symbol in syntax defined by the system. + example: INVALID_VALUE + display: + type: string + description: Representation defined by the system. + example: Provided value is invalid diff --git a/packages/specification/schemas/fragments/groupIdentifier.yaml b/packages/specification/schemas/fragments/groupIdentifier.yaml new file mode 100644 index 000000000..dbdb8c222 --- /dev/null +++ b/packages/specification/schemas/fragments/groupIdentifier.yaml @@ -0,0 +1,14 @@ +type: object +required: [value] +description: | + Prescription ID to be used by the client to generate a prescription barcode. + Can be used directly to facilitate accessing a prescription, in the event that a barcode scanner was inoperable. +properties: + system: + type: string + description: Codesystem URL for the short-form Prescription ID. + enum: [https://fhir.nhs.uk/Id/prescription-order-number] + value: + type: string + description: The short-form Prescription ID. + example: 04F4C2-A99968-7F717P diff --git a/packages/specification/schemas/fragments/identifiers.yaml b/packages/specification/schemas/fragments/identifiers.yaml new file mode 100644 index 000000000..8f42af27c --- /dev/null +++ b/packages/specification/schemas/fragments/identifiers.yaml @@ -0,0 +1,29 @@ +OdsOrganisationCode: + type: object + description: The Organisation Data Service (ODS) code. + required: [system, value] + properties: + system: + type: string + description: Codesystem URL for the ODS code. + enum: [https://fhir.nhs.uk/Id/ods-organization-code] + value: + type: string + description: ODS code. + example: A83008 +NhsNumber: + type: object + required: [system, value] + properties: + system: + type: string + format: url + description: Codesystem URL for the NHS number. + enum: [https://fhir.nhs.uk/Id/nhs-number] + value: + description: | + The patient's NHS number. The primary identifier of a patient, unique within NHS England and Wales. + Always 10 digits and must be a [valid NHS number](https://www.datadictionary.nhs.uk/attributes/nhs_number.html). + type: string + pattern: "^\\d{10}$" + example: "9000000009" diff --git a/packages/specification/schemas/fragments/medicationRequest/status.yaml b/packages/specification/schemas/fragments/medicationRequest/status.yaml new file mode 100644 index 000000000..4aee20b30 --- /dev/null +++ b/packages/specification/schemas/fragments/medicationRequest/status.yaml @@ -0,0 +1,50 @@ +type: object +description: | + The status of the line item within the prescription. + * 'Prescriber Approved' means the item has been approved by a prescriber and is waiting to be released from Spine by the pharmacy. + * 'Prescriber Cancelled' means the item has been cancelled by the prescriber. A cancelled item can be included in a prescription where other items have not been cancelled. The patient should be advised to contact their prescriber to find out the reason for cancellation. + * 'With Pharmacy' means the item has been downloaded by the pharmacy and is being prepared but is not ready to collect. + * 'With Pharmacy but Tracking not Supported' means that there is no prescription tracking data for the prescription item. This is because the pharmacy is not yet using a dispensing system which is onboarded to the National Patient Prescription Tracking Service. + * 'With Pharmacy - Preparing Remainder' means the prescription item has been partially dispensed, but the remaining part of the item is still with the pharmacy to prepare and dispense. + * 'Ready to Collect' means the pharmacy has prepared the prescription + item and it's ready to collect. + * 'Ready to Collect - Partial' means the prescription item has been partially dispensed and is ready to collect, but the remaining part of the item is still with the pharmacy to prepare and dispense. + * 'Ready to Dispatch' means the prescription item is in a holding area ready for collection by a delivery courier. This status will be set based on activity triggered by the pharmacy dispensing process. This might be the scanning of the prescription package barcode, or another action performed only against the item/s when they are placed in a holding area. + * 'Ready to Dispatch - Partial' means part of the prescription item is in a holding area ready for collection by a delivery courier. This status will be set based on activity triggered by the pharmacy dispensing process. This might be the scanning of the prescription package barcode, or another action performed only against the item/s when they are placed in a holding area. This status reflects the full medication item dosage isn't in stock. + * 'Not Dispensed' means the prescription item has not been dispensed, which may be for several reasons including the pharmacist deciding it's clinically unsuitable or the patient has reported side effects. The patient should be advised that the dispenser set the 'not dispensed' status so they know to contact their pharmacy should they have any questions. + * 'Dispatched' means the pharmacy has prepared the prescription item and it has been dispatched for delivery by a courier service. + * 'Collected' means that the patient or patient proxy has collected the prescription item. + * 'Tracking Temporarily Unavailable' means that the system was temporarily unable to obtain the status update for the item. This would happen in the event of the service going down. +required: + - url + - valueCoding +properties: + url: + type: string + enum: ["status"] + valueCoding: + type: object + required: + - code + - system + properties: + code: + type: string + enum: + - Prescriber Approved + - Prescriber Cancelled + - With Pharmacy + - With Pharmacy but Tracking not Supported + - With Pharmacy - Preparing Remainder + - Ready to Collect + - Ready to Collect - Partial + - Ready to Dispatch + - Ready to Dispatch - Partial + - Not Dispensed + - Dispatched + - Collected + - Tracking Temporarily Unavailable + + system: + type: string + enum: ["https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt"] diff --git a/packages/specification/schemas/fragments/medicationRequest/statusDate.yaml b/packages/specification/schemas/fragments/medicationRequest/statusDate.yaml new file mode 100644 index 000000000..c0d510029 --- /dev/null +++ b/packages/specification/schemas/fragments/medicationRequest/statusDate.yaml @@ -0,0 +1,14 @@ +type: object +description: | + Date and time at which the item status was updated +required: + - url + - valueDateTime +properties: + url: + type: string + enum: ["statusDate"] + valueDateTime: + type: string + format: date-time + example: "2024-03-01T08:27:14Z" diff --git a/packages/specification/schemas/fragments/structuredName.yaml b/packages/specification/schemas/fragments/structuredName.yaml new file mode 100644 index 000000000..db8a9d2ed --- /dev/null +++ b/packages/specification/schemas/fragments/structuredName.yaml @@ -0,0 +1,25 @@ +type: object +description: A structured name +properties: + family: + type: string + description: Family name (often called Surname). + example: Smith + given: + type: array + description: Given names, including any middle names. + items: + type: string + example: John + prefix: + type: array + description: Name prefixes, titles, and prenominals. + items: + type: string + example: Dr + suffix: + type: array + description: Part of the name that is acquired as a title due to academic, legal, employment or nobility status, etc. and that appears at the end of the name. + items: + type: string + example: MD diff --git a/packages/specification/schemas/fragments/telecom.yaml b/packages/specification/schemas/fragments/telecom.yaml new file mode 100644 index 000000000..063dd5e49 --- /dev/null +++ b/packages/specification/schemas/fragments/telecom.yaml @@ -0,0 +1,19 @@ +type: object +required: + - use + - value +properties: + system: + description: Means of communication, such as phone or URL. + type: string + enum: [phone, URL, other] + default: phone + use: + type: string + description: Location associated with the contact details provided. + enum: [home, work, temp, mobile] + default: work + value: + description: Phone number, URL. + type: string + example: "01234567890" diff --git a/packages/specification/schemas/resources/MedicationRequest.yaml b/packages/specification/schemas/resources/MedicationRequest.yaml new file mode 100644 index 000000000..365d7b80b --- /dev/null +++ b/packages/specification/schemas/resources/MedicationRequest.yaml @@ -0,0 +1,128 @@ +type: object +required: + - resourceType + - identifier + - status + - intent + - medicationCodeableConcept + - subject + - requester + - groupIdentifier + - courseOfTherapyType + - dispenseRequest + - substitution +description: Information about a specific line item within a prescription. +properties: + resourceType: + type: string + description: FHIR resource type. + enum: [MedicationRequest] + status: + type: string + description: | + Indicator to identify prescription items that are in a terminal state, + such as collected or dispatched + enum: [completed, active] + intent: + type: string + description: The intent of a MedicationRequest object. Required by the FHIR standard but offers no patient value and can be ignored. + enum: [order, original-order, instance-order] + medicationCodeableConcept: + type: object + description: The medication prescribed to a patient. + properties: + coding: + type: array + items: + $ref: ../fragments/codes.yaml#/SnomedSctMedication + subject: + type: object + description: The NHS number of the patient the prescription is for. + properties: + identifier: + $ref: ../fragments/identifiers.yaml#/NhsNumber + requester: + type: object + description: | + The prescriber who created the prescription. + Useful if the patient or dispenser has a query about the prescription. + properties: + reference: + type: string + description: A reference to a PractitionerRole resource within the Bundle. + example: urn:uuid:56166769-c1c4-4d07-afa8-132b5dfca666 + groupIdentifier: + $ref: ../fragments/groupIdentifier.yaml + courseOfTherapyType: + type: object + description: Whether this prescription is an acute or a repeat. + properties: + coding: + type: array + items: + $ref: ../fragments/codes.yaml#/MedicationRequestCourseOfTherapy + dispenseRequest: + type: object + required: [quantity] + properties: + validityPeriod: + type: object + properties: + start: + type: string + description: The prescription's start date, could be after the prescription is created for a post dated prescription. + format: date + example: "2024-02-27" + performer: + type: object + description: A reference to either the nominated dispensing organisation or the organisation currently processing the prescription if it has already been downloaded. + properties: + reference: + type: string + description: A reference to an Organisation resource within the Bundle. + example: urn:uuid:d16fe9ef-665a-4039-9e21-70bca37f8a4a + quantity: + type: object + description: The quantity of medication prescribed. + properties: + value: + type: integer + description: The numeric value of the quantity. + format: int32 + example: 20 + unit: + type: string + description: The units in which the quantity was prescribed, defined using Dictionary of Medicines and Devices (DM+D) units of measure. + example: tablet + system: + type: string + description: SNOMED codesystem URL. + enum: [http://snomed.info/sct] + code: + type: integer + description: The DM+D code associated with a given unit of measure. + example: 428673006 + substitution: + type: object + description: This is a boolean value that should always default to false because EPS does not support substitutions. + required: [allowedBoolean] + properties: + allowedBoolean: + type: boolean + enum: [false] + extension: + type: array + items: + type: object + description: Will contain the most recent status update for the prescription item provided in the prescription status update API. + required: [url, extension] + properties: + url: + type: string + enum: ["https://fhir.nhs.uk/StructureDefinition/Extension-DM-PrescriptionStatusHistory"] + extension: + type: array + items: + anyOf: + - $ref: ../fragments/medicationRequest/statusDate.yaml + - $ref: ../fragments/medicationRequest/status.yaml diff --git a/packages/specification/schemas/resources/OperationOutcome.yaml b/packages/specification/schemas/resources/OperationOutcome.yaml new file mode 100644 index 000000000..cc8b0db37 --- /dev/null +++ b/packages/specification/schemas/resources/OperationOutcome.yaml @@ -0,0 +1,83 @@ +type: object +description: | + Outcome of an operation that does not result in a resource or bundle being returned. + For example - error, async/batch submission. +properties: + resourceType: + type: string + description: FHIR Resource Type. + enum: [OperationOutcome] + id: + type: string + description: ID to link the request and response (Lambda request ID) + meta: + type: object + required: [lastUpdated] + description: Metadata regarding the request + properties: + lastUpdated: + type: string + description: Timestamp at which the response was generated + issue: + type: array + description: List of issues that have occurred. + minItems: 1 + items: + type: object + required: [severity, code] + properties: + severity: + type: string + enum: [fatal, error, warning, information] + description: Severity of the error. + code: + type: string + description: FHIR error code. + enum: + - business-rule + - code-invalid + - conflict + - deleted + - duplicate + - exception + - expired + - extension + - forbidden + - incomplete + - informational + - invalid + - invariant + - lock-error + - login + - multiple-matches + - no-store + - not-supported + - not-found + - processing + - required + - structure + - security + - suppressed + - throttled + - timeout + - too-costly + - too-long + - transient + - unknown + - value + details: + type: object + description: Internal error code. + properties: + coding: + type: array + items: + $ref: ../fragments/codes.yaml#/SpineErrorOrWarningCode + expression: + type: string + description: FHIR Path of element(s) related to the error. + example: Patient.name.given + diagnostics: + type: string + description: A description of the reasoning for including an OperationOutcome + example: Some prescriptions have been invalidated so could not be returned. diff --git a/packages/specification/schemas/resources/Organisation.yaml b/packages/specification/schemas/resources/Organisation.yaml new file mode 100644 index 000000000..eeb3ede13 --- /dev/null +++ b/packages/specification/schemas/resources/Organisation.yaml @@ -0,0 +1,30 @@ +type: object +description: Details of the organisation. +properties: + resourceType: + type: string + description: FHIR resource type. + default: Organization + identifier: + type: array + description: An array containing the ODS code of the organisation. + items: + $ref: ../fragments/identifiers.yaml#/OdsOrganisationCode + name: + type: string + description: Organisation name. + address: + type: array + description: | + Organisation address. + One of line or text, and optionally postalCode, will be populated. + If postalCode is not populated, the organization's postalCode may be included in line or text, if they are populated. + So address will contain use and type, along with one of: line, line and postalCode, text, text and postalCode, postalCode. + Note: city and district will not be populated by existing prescriptions. + items: + $ref: ../fragments/address.yaml + telecom: + type: array + description: The telephone number or Website URL associated with the organisation. + items: + $ref: ../fragments/telecom.yaml diff --git a/packages/specification/schemas/resources/Practitioner.yaml b/packages/specification/schemas/resources/Practitioner.yaml new file mode 100644 index 000000000..9be319973 --- /dev/null +++ b/packages/specification/schemas/resources/Practitioner.yaml @@ -0,0 +1,21 @@ +type: object +required: [resourceType, name] +description: Details of the prescriber of a prescription. +properties: + resourceType: + type: string + description: FHIR resource type. + enum: [Practitioner] + name: + type: array + description: The prescriber's name. + items: + oneOf: + - $ref: ../fragments/structuredName.yaml + - type: object + description: An unstructured name + properties: + text: + type: string + description: Text representation of the full name + example: Dr John Paul Smith MD diff --git a/packages/specification/schemas/resources/PractitionerRole.yaml b/packages/specification/schemas/resources/PractitionerRole.yaml new file mode 100644 index 000000000..2c1aa559f --- /dev/null +++ b/packages/specification/schemas/resources/PractitionerRole.yaml @@ -0,0 +1,26 @@ +type: object +required: + - practitioner + - organization +description: Role-specific details of the prescriber of a prescription. +properties: + resourceType: + type: string + description: FHIR resource type. + enum: [PractitionerRole] + practitioner: + type: object + description: A reference to a Practitioner resource for a given prescriber. + properties: + reference: + type: string + description: A FHIR reference object. + example: urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa47a + organization: + type: object + description: A reference to an Organization resource. + properties: + reference: + type: string + description: A FHIR reference object. + example: urn:uuid:a8c85454-f8cb-498d-9629-78e2cb5fa38b diff --git a/packages/specification/tsconfig.json b/packages/specification/tsconfig.json new file mode 100644 index 000000000..81eae7c5d --- /dev/null +++ b/packages/specification/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.defaults.json", + "compilerOptions": { + "rootDir": ".", + "outDir": "lib" + }, + "files": [], + "exclude": ["node_modules"] +} diff --git a/tsconfig.build.json b/tsconfig.build.json index 85939df41..879f030e1 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -12,6 +12,7 @@ { "path": "packages/enrichPrescriptions" }, { "path": "packages/nhsd-pfp-sandbox" }, { "path": "packages/statusLambda" }, - { "path": "packages/distanceSelling" } + { "path": "packages/distanceSelling" }, + { "path": "packages/specification" } ] }