diff --git a/.circleci/account-data-deleter.yml b/.circleci/account-data-deleter.yml deleted file mode 100644 index 69597e7c3..000000000 --- a/.circleci/account-data-deleter.yml +++ /dev/null @@ -1,299 +0,0 @@ - -workflows: - account-data-deleter: - jobs: - - - test_integrations: - <<: *not_dev_main - for: account_data_deleter - context: pocket - name: account-data-deleter_test_integrations - scope: account-data-deleter - - - test_integrations: - <<: *not_dev_main - for: account_data_deleter - context: pocket - name: account-data-deleter_batch-delete_test_integrations - scope: account-data-deleter-batch-delete - - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: account_data_deleter - name: account-data-deleter_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: accountdatadeleter-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=account-data-deleter --build-arg APP_PATH=servers/account-data-deleter --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=account-data-deleter --build-arg PORT=4015 - - ###### - # Every PR Jobs - ###### - - build_lambda: - <<: *not_dev_main - context: pocket - for: account_data_deleter - name: account-data-deleter_build_events - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: account-data-deleter-events - sentry_project_name: account-data-deleter - sentry_env: development - sentry_org: pocket - - - build_lambda: - <<: *not_dev_main - context: pocket - for: account_data_deleter - name: account-data-deleter_build_batch-delete - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: account-data-deleter-batch-delete - sentry_project_name: account-data-deleter - sentry_env: development - sentry_org: pocket - - - infrastructure: - <<: *not_dev_main - context: pocket - for: account_data_deleter - name: account-data-deleter_infrastructure_plan_prod - scope: account-data-deleter-cdk - stack-output-path: infrastructure/account-data-deleter/cdktf.out/stacks/account-data-deleter - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: account_data_deleter - name: account-data-deleter_infrastructure_apply_dev - scope: account-data-deleter-cdk - stack-output-path: infrastructure/account-data-deleter/cdktf.out/stacks/account-data-deleter - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: account_data_deleter - name: account-data-deleter_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: accountdatadeleter-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=account-data-deleter --build-arg APP_PATH=servers/account-data-deleter --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=account-data-deleter --build-arg PORT=4015 - requires: - - account-data-deleter_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: account_data_deleter - name: account-data-deleter_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - account-data-deleter_build_docker_dev - - - build_lambda: - <<: *only_dev - context: pocket - for: account_data_deleter - name: account-data-deleter_events_build_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: account-data-deleter-events - sentry_project_name: account-data-deleter - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-accountdatadeleter-dev-sqs-event-consumer - requires: - - account-data-deleter_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: account_data_deleter - name: account-data-deleter_events_code_deploy_dev - resource-class: pocket/default-dev - codedeploy-app-name: AccountDataDeleter-Dev-Sqs-Event-Consumer-Lambda - codedeploy-group-name: AccountDataDeleter-Dev-Sqs-Event-Consumer-Lambda - function-name: AccountDataDeleter-Dev-Sqs-Event-Consumer-Function - s3-bucket: pocket-accountdatadeleter-dev-sqs-event-consumer - requires: - - account-data-deleter_events_build_dev - - - build_lambda: - <<: *only_dev - context: pocket - for: account_data_deleter - name: account-data-deleter_batch-delete_build_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: account-data-deleter-batch-delete - sentry_project_name: account-data-deleter - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-accountdatadeleter-dev-batchdeletelambda - requires: - - account-data-deleter_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: account_data_deleter - name: account-data-deleter_batch-delete_code_deploy_dev - resource-class: pocket/default-dev - codedeploy-app-name: AccountDataDeleter-Dev-BatchDeleteLambda-Lambda - codedeploy-group-name: AccountDataDeleter-Dev-BatchDeleteLambda-Lambda - function-name: AccountDataDeleter-Dev-BatchDeleteLambda-Function - s3-bucket: pocket-accountdatadeleter-dev-batchdeletelambda - requires: - - account-data-deleter_batch-delete_build_dev - - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: account-data-deleter_sentry-release-notification-dev - context: pocket - for: account_data_deleter - sentry_project_name: account-data-deleter - sentry_env: development - sentry_org: pocket - requires: - - account-data-deleter_events_code_deploy_dev - - account-data-deleter_batch-delete_code_deploy_dev - - account-data-deleter_code_deploy_ecs_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: account_data_deleter - name: account-data-deleter_infrastructure_apply_prod - scope: account-data-deleter-cdk - stack-output-path: infrastructure/account-data-deleter/cdktf.out/stacks/account-data-deleter - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: account_data_deleter - name: account-data-deleter_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: accountdatadeleter-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=account-data-deleter --build-arg APP_PATH=servers/account-data-deleter --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=account-data-deleter --build-arg PORT=4015 - requires: - - account-data-deleter_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: account_data_deleter - name: account-data-deleter_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - account-data-deleter_build_docker_prod - - - build_lambda: - <<: *only_main - context: pocket - for: account_data_deleter - name: account-data-deleter_events_build_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: account-data-deleter-events - sentry_project_name: account-data-deleter - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-accountdatadeleter-prod-sqs-event-consumer - requires: - - account-data-deleter_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: account_data_deleter - name: account-data-deleter_events_code_deploy_prod - resource-class: pocket/default-prod - codedeploy-app-name: AccountDataDeleter-Prod-Sqs-Event-Consumer-Lambda - codedeploy-group-name: AccountDataDeleter-Prod-Sqs-Event-Consumer-Lambda - function-name: AccountDataDeleter-Prod-Sqs-Event-Consumer-Function - s3-bucket: pocket-accountdatadeleter-prod-sqs-event-consumer - requires: - - account-data-deleter_events_build_prod - - - build_lambda: - <<: *only_main - context: pocket - for: account_data_deleter - name: account-data-deleter_batch-delete_build_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: account-data-deleter-batch-delete - sentry_project_name: account-data-deleter - sentry_env: prodelopment - sentry_org: pocket - s3-bucket: pocket-accountdatadeleter-prod-batchdeletelambda - requires: - - account-data-deleter_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: account_data_deleter - name: account-data-deleter_batch-delete_code_deploy_prod - resource-class: pocket/default-prod - codedeploy-app-name: AccountDataDeleter-Prod-BatchDeleteLambda-Lambda - codedeploy-group-name: AccountDataDeleter-Prod-BatchDeleteLambda-Lambda - function-name: AccountDataDeleter-Prod-BatchDeleteLambda-Function - s3-bucket: pocket-accountdatadeleter-prod-batchdeletelambda - requires: - - account-data-deleter_batch-delete_build_prod - - - # Notify sentry of prod deployment - - sentry_release_notification: - <<: *only_main - name: account-data-deleter_sentry-release-notification-prod - context: pocket - for: account_data_deleter - sentry_project_name: account-data-deleter - sentry_env: prodelopment - sentry_org: pocket - requires: - - account-data-deleter_events_code_deploy_prod - - account-data-deleter_batch-delete_code_deploy_prod - - account-data-deleter_code_deploy_ecs_prod - diff --git a/.circleci/account-delete-monitor.yml b/.circleci/account-delete-monitor.yml deleted file mode 100644 index a70bc6efc..000000000 --- a/.circleci/account-delete-monitor.yml +++ /dev/null @@ -1,149 +0,0 @@ - -workflows: - account-delete-monitor: - jobs: - - ###### - # Every PR Jobs - ###### - - test_integrations: - <<: *not_dev_main - for: account_delete_monitor - context: pocket - name: account-delete-monitor_test_integrations - scope: account-delete-monitor - - - build_lambda: - <<: *not_dev_main - context: pocket - for: account_delete_monitor - name: account-delete-monitor_build_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: account-delete-monitor - sentry_project_name: account-delete-monitor - sentry_env: development - sentry_org: pocket - - - infrastructure: - <<: *not_dev_main - context: pocket - for: account_delete_monitor - name: account-delete-monitor_infrastructure_plan_prod - scope: account-delete-monitor-cdk - stack-output-path: infrastructure/account-delete-monitor/cdktf.out/stacks/account-delete-monitor - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: account_delete_monitor - name: account-delete-monitor_infrastructure_apply_dev - scope: account-delete-monitor-cdk - stack-output-path: infrastructure/account-delete-monitor/cdktf.out/stacks/account-delete-monitor - resource-class: pocket/default-dev - apply: true - dev: true - - - build_lambda: - <<: *only_dev - context: pocket - for: account_delete_monitor - name: account-delete-monitor_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: account-delete-monitor - sentry_project_name: account-delete-monitor - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-accountdeletemonitor-dev-eventtracker - requires: - - account-delete-monitor_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: account_delete_monitor - name: account-delete-monitor_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: AccountDeleteMonitor-Dev-EventTracker-Lambda - codedeploy-group-name: AccountDeleteMonitor-Dev-EventTracker-Lambda - function-name: AccountDeleteMonitor-Dev-EventTracker-Function - s3-bucket: pocket-accountdeletemonitor-dev-eventtracker - requires: - - account-delete-monitor_build_lambda_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: account-delete-monitor_sentry-release-notification-dev - context: pocket - for: account_delete_monitor - sentry_project_name: account-delete-monitor - sentry_env: development - sentry_org: pocket - requires: - - account-delete-monitor_code_deploy_lambda_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: account_delete_monitor - name: account-delete-monitor_infrastructure_apply_prod - scope: account-delete-monitor-cdk - stack-output-path: infrastructure/account-delete-monitor/cdktf.out/stacks/account-delete-monitor - resource-class: pocket/default-prod - apply: true - dev: false - - - build_lambda: - <<: *only_main - context: pocket - for: account_delete_monitor - name: account-delete-monitor_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: account-delete-monitor - sentry_project_name: account-delete-monitor - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-accountdeletemonitor-prod-eventtracker - requires: - - account-delete-monitor_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: account_delete_monitor - name: account-delete-monitor_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: AccountDeleteMonitor-Prod-EventTracker-Lambda - codedeploy-group-name: AccountDeleteMonitor-Prod-EventTracker-Lambda - function-name: AccountDeleteMonitor-Prod-EventTracker-Function - s3-bucket: pocket-accountdeletemonitor-prod-eventtracker - requires: - - account-delete-monitor_build_lambda_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: account-delete-monitor_sentry-release-notification-prod - context: pocket - for: account_delete_monitor - sentry_project_name: account-delete-monitor - sentry_env: production - sentry_org: pocket - requires: - - account-delete-monitor_code_deploy_lambda_prod diff --git a/.circleci/annotations-api.yml b/.circleci/annotations-api.yml deleted file mode 100644 index 5d0131fad..000000000 --- a/.circleci/annotations-api.yml +++ /dev/null @@ -1,225 +0,0 @@ - -workflows: - annotations-api: - jobs: - - ###### - # Every PR Jobs - ###### - - apollo: - name: annotations-api_apollo - fed_graph_name: pocket-client-api - graph_name: annotations-api - schema_file_path: servers/annotations-api/dist/schema-generated.graphql - prod_graph_url: https://annotations-api.readitlater.com - dev_graph_url: https://annotations-api.getpocket.dev - build_command: pnpm run build --filter=annotations-api... - scope: annotations-api - - - test_integrations: - <<: *not_dev_main - for: annotations_api - context: pocket - name: annotations-api_test_integrations - scope: annotations-api - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: annotations_api - name: annotations-api_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: annotationsapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=annotations-api --build-arg APP_PATH=servers/annotations-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=annotations-api --build-arg PORT=4008 - - - build_lambda: - <<: *not_dev_main - context: pocket - for: annotations_api - name: annotations-api_build_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: annotations-api-events-lambda - sentry_project_name: annotations-api - sentry_env: development - sentry_org: pocket - - - infrastructure: - <<: *not_dev_main - context: pocket - for: annotations_api - name: annotations-api_infrastructure_plan_prod - scope: annotations-api-cdk - stack-output-path: infrastructure/annotations-api/cdktf.out/stacks/annotations-api - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: annotations_api - name: annotations-api_infrastructure_apply_dev - scope: annotations-api-cdk - stack-output-path: infrastructure/annotations-api/cdktf.out/stacks/annotations-api - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: annotations_api - name: annotations-api_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: annotationsapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=annotations-api --build-arg APP_PATH=servers/annotations-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=annotations-api --build-arg PORT=4008 - requires: - - annotations-api_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: annotations_api - name: annotations-api_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - annotations-api_build_docker_dev - - - build_lambda: - <<: *only_dev - context: pocket - for: annotations_api - name: annotations-api_events_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: annotations-api-events-lambda - sentry_project_name: annotations-api - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-annotationsapi-dev-sqs-event-consumer - requires: - - annotations-api_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: annotations_api - name: annotations-api_events_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: AnnotationsAPI-Dev-Sqs-Event-Consumer-Lambda - codedeploy-group-name: AnnotationsAPI-Dev-Sqs-Event-Consumer-Lambda - function-name: AnnotationsAPI-Dev-Sqs-Event-Consumer-Function - s3-bucket: pocket-annotationsapi-dev-sqs-event-consumer - requires: - - annotations-api_events_build_lambda_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: annotations-api_sentry-release-notification-dev - context: pocket - for: annotations_api - sentry_project_name: annotations-api - sentry_env: development - sentry_org: pocket - requires: - - annotations-api_code_deploy_ecs_dev - - annotations-api_events_code_deploy_lambda_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: annotations_api - name: annotations-api_infrastructure_apply_prod - scope: annotations-api-cdk - stack-output-path: infrastructure/annotations-api/cdktf.out/stacks/annotations-api - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: annotations_api - name: annotations-api_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: annotationsapi-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=annotations-api --build-arg APP_PATH=servers/annotations-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=annotations-api --build-arg PORT=4008 - requires: - - annotations-api_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: annotations_api - name: annotations-api_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - annotations-api_build_docker_prod - - - build_lambda: - <<: *only_main - context: pocket - for: annotations_api - name: annotations-api_events_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: annotations-api-events-lambda - sentry_project_name: annotations-api - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-annotationsapi-prod-sqs-event-consumer - requires: - - annotations-api_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: annotations_api - name: annotations-api_events_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: AnnotationsAPI-Prod-Sqs-Event-Consumer-Lambda - codedeploy-group-name: AnnotationsAPI-Prod-Sqs-Event-Consumer-Lambda - function-name: AnnotationsAPI-Prod-Sqs-Event-Consumer-Function - s3-bucket: pocket-annotationsapi-prod-sqs-event-consumer - requires: - - annotations-api_events_build_lambda_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: annotations-api_sentry-release-notification-prod - context: pocket - for: annotations_api - sentry_project_name: annotations-api - sentry_env: production - sentry_org: pocket - requires: - - annotations-api_code_deploy_ecs_prod - - annotations-api_events_code_deploy_lambda_prod diff --git a/.circleci/braze.yml b/.circleci/braze.yml deleted file mode 100644 index c7d9f88c1..000000000 --- a/.circleci/braze.yml +++ /dev/null @@ -1,49 +0,0 @@ - -workflows: - braze: - jobs: - - ###### - # Every PR Jobs - ###### - - - infrastructure: - <<: *not_dev_main - context: pocket - for: braze - name: braze_infrastructure_plan_prod - scope: braze-cdk - stack-output-path: infrastructure/braze/cdktf.out/stacks/braze - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: braze - name: braze_infrastructure_apply_dev - scope: braze-cdk - stack-output-path: infrastructure/braze/cdktf.out/stacks/braze - resource-class: pocket/default-dev - apply: true - dev: true - - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: braze - name: braze_infrastructure_apply_prod - scope: braze-cdk - stack-output-path: infrastructure/braze/cdktf.out/stacks/braze - resource-class: pocket/default-prod - apply: true - dev: false diff --git a/.circleci/client-api.yml b/.circleci/client-api.yml deleted file mode 100644 index 245e8cfd0..000000000 --- a/.circleci/client-api.yml +++ /dev/null @@ -1,113 +0,0 @@ - -workflows: - client-api: - jobs: - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: client_api - name: client-api_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: clientapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - app_path: 'servers/client-api' - layer_caching: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} - - - infrastructure: - <<: *not_dev_main - context: pocket - for: client_api - name: client-api_infrastructure_plan_prod - scope: client-api-cdk - stack-output-path: infrastructure/client-api/cdktf.out/stacks/client-api - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: client_api - name: client-api_infrastructure_apply_dev - scope: client-api-cdk - stack-output-path: infrastructure/client-api/cdktf.out/stacks/client-api - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: client_api - name: client-api_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: clientapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - app_path: 'servers/client-api' - layer_caching: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} - requires: - - client-api_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: client_api - name: client-api_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - client-api_build_docker_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: client_api - name: client-api_infrastructure_apply_prod - scope: client-api-cdk - stack-output-path: infrastructure/client-api/cdktf.out/stacks/client-api - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: client_api - name: client-api_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: clientapi-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - app_path: 'servers/client-api' - layer_caching: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} - requires: - - client-api_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: client_api - name: client-api_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - client-api_build_docker_prod diff --git a/.circleci/common.yml b/.circleci/common.yml deleted file mode 100644 index ff5df296a..000000000 --- a/.circleci/common.yml +++ /dev/null @@ -1,949 +0,0 @@ -version: 2.1 - -orbs: - aws-cli: circleci/aws-cli@4.1.3 - aws-ecr: circleci/aws-ecr@7.3.0 - aws-code-deploy: circleci/aws-code-deploy@3.0.0 - aws-ecs: circleci/aws-ecs@4.0.0 - -# This is an enum that is used within all our jobs and our exit early job. -# As a new "service/deployment" is added you should add to the enum. -# Then each job you pass a "for" to, so that we can determine if this job is for this "commit" -repo_for_enum: &repo_for_enum - for: - description: which repo this job is relevant for - type: enum - enum: - - image_api - - annotations_api - - shared_snowplow_consumer - - parser_graphql_wrapper - - transactional_emails - - fxa_webhook_proxy - - user_api - - list_api - - client_api - - feature_flags - - sendgrid_data - - account_data_deleter - - account_delete_monitor - - shareable_lists_api - - pocket_event_bridge - - user_list_search - - corpus_embeddings - - braze - - v3_proxy_api - - push_server - - instant_sync_events - - shares_api - -resource_class_enmum: &resource_class_enmum - resource-class: - description: The self hosted runnner to run on - type: enum - enum: - - pocket/default-dev - - pocket/default-prod - - -parameters: - image_api: - type: boolean - default: false - annotations_api: - type: boolean - default: false - shared_snowplow_consumer: - type: boolean - default: false - parser_graphql_wrapper: - type: boolean - default: false - transactional_emails: - type: boolean - default: false - fxa_webhook_proxy: - type: boolean - default: false - user_api: - type: boolean - default: false - client_api: - type: boolean - default: false - corpus_embeddings: - type: boolean - default: false - list_api: - type: boolean - default: false - feature_flags: - type: boolean - default: false - sendgrid_data: - type: boolean - default: false - account_data_deleter: - type: boolean - default: false - account_delete_monitor: - type: boolean - default: false - shareable_lists_api: - type: boolean - default: false - pocket_event_bridge: - type: boolean - default: false - user_list_search: - type: boolean - default: false - braze: - type: boolean - default: false - v3_proxy_api: - type: boolean - default: false - push_server: - type: boolean - default: false - instant_sync_events: - type: boolean - default: false - shares_api: - type: boolean - default: false - -commands: - # Refrenced from https://github.com/kelvintaywl-cci/dynamic-config-showcase/blob/main/.circleci/next.yml - exit-early-if-irrelevant: - parameters: - <<: *repo_for_enum - steps: - - run: - name: stop early unless relevant - command: | - # looks up the relevant pipeline parameter via the env var - export RELEVANT=$(eval echo "\$<< parameters.for >>") - - # NOTE: env var values are strings (not boolean) - if [ "${RELEVANT}" = "1" ]; then - echo "continuing, since job is for << parameters.for >>" - else - echo "stopping early!" - circleci-agent step halt - fi - environment: - image_api: << pipeline.parameters.image_api >> - annotations_api: << pipeline.parameters.annotations_api >> - shared_snowplow_consumer: << pipeline.parameters.shared_snowplow_consumer >> - parser_graphql_wrapper: << pipeline.parameters.parser_graphql_wrapper >> - transactional_emails: << pipeline.parameters.transactional_emails >> - fxa_webhook_proxy: << pipeline.parameters.fxa_webhook_proxy >> - user_api: << pipeline.parameters.user_api >> - list_api: << pipeline.parameters.list_api >> - client_api: << pipeline.parameters.client_api >> - corpus_embeddings: << pipeline.parameters.corpus_embeddings >> - feature_flags: << pipeline.parameters.feature_flags >> - sendgrid_data: << pipeline.parameters.sendgrid_data >> - account_data_deleter: << pipeline.parameters.account_data_deleter >> - account_delete_monitor: << pipeline.parameters.account_delete_monitor >> - shareable_lists_api: << pipeline.parameters.shareable_lists_api >> - pocket_event_bridge: << pipeline.parameters.pocket_event_bridge >> - user_list_search: << pipeline.parameters.user_list_search >> - braze: << pipeline.parameters.braze >> - v3_proxy_api: << pipeline.parameters.v3_proxy_api >> - push_server: << pipeline.parameters.push_server >> - instant_sync_events: << pipeline.parameters.instant_sync_events >> - shares_api: << pipeline.parameters.shares_api >> - - install_pnpm: - parameters: - scope: - description: The pnpm scope to build for - type: string - default: "" - steps: - - run: - name: Install pnpm package manager - command: | - corepack prepare pnpm@9.1.4 --activate - corepack pnpm config set store-dir .pnpm-store - - when: - # Only compile if we do not use raw hcl - condition: <> - steps: - - restore_cache: - name: Restore pnpm Package Cache - keys: - - pnpm-packages-<< parameters.scope >>-{{ checksum "pnpm-lock.yaml" }} - - run: - # Need to set peer-deps to false for pnpmv8 https://github.com/pnpm/pnpm/issues/6300 - name: Install Dependencies - command: | - corepack pnpm install --filter=<< parameters.scope >>... --frozen-lockfile - - save_cache: - name: Save pnpm Package Cache - key: pnpm-packages-<< parameters.scope >>-{{ checksum "pnpm-lock.yaml" }} - paths: - - .pnpm-store - - unless: - # Only compile if we do not use raw hcl - condition: <> - steps: - - restore_cache: - name: Restore pnpm Package Cache - keys: - - pnpm-packages-{{ checksum "pnpm-lock.yaml" }} - - run: - # Need to set peer-deps to false for pnpmv8 https://github.com/pnpm/pnpm/issues/6300 - name: Install Dependencies - command: | - corepack pnpm install - - save_cache: - name: Save pnpm Package Cache - key: pnpm-packages-{{ checksum "pnpm-lock.yaml" }} - paths: - - .pnpm-store - install_infrastructure_pnpm: - parameters: - scope: - description: The pnpm scope to build for - type: string - steps: - - run: - name: Install and setup node - command: | - nvm install - nvm use - npm install -g pnpm@9.1.4 - pnpm config set store-dir .pnpm-store - pnpm install --filter=<< parameters.scope >>... --frozen-lockfile - install_codebuild_secrets: - steps: - - run: - name: Setup our secrets from AWS Secret Manager - command: | - echo 'export SECRET_VALUE="$(aws secretsmanager get-secret-value --secret-id CodeBuild/Default --query SecretString --output text)"' >> "$BASH_ENV" - echo 'export TERRAFORM_TOKEN="$(echo $SECRET_VALUE | jq -r '.terraform_token')"' >> "$BASH_ENV" - echo 'export PAGERDUTY_TOKEN="$(echo $SECRET_VALUE | jq -r '.mozilla_pagerduty_token')"' >> "$BASH_ENV" - - run: - name: Save off terraform token - command: | - echo Setting Up Terraform Token - rc="credentials \"app.terraform.io\" { " - rc="${rc} token=\"$TERRAFORM_TOKEN\" " - rc="${rc}}" - echo "$rc" > ~/.terraformrc - - setup_github_bot: - steps: - - run: - name: Get Github Bot Token - command: | - app_id=$GITHUB_APP_ID - pem="$(echo "$GITHUB_APP_PRIVATE_KEY" | base64 -d)" - installation_id=$GITHUB_INSTALLATION_APP_ID - - now=$(date +%s) - iat=$((${now} - 60)) # Issues 60 seconds in the past - exp=$((${now} + 600)) # Expires 15 minutes in the future - - b64enc() { openssl base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n'; } - - header_json='{ - "typ":"JWT", - "alg":"RS256" - }' - # Header encode - header=$( echo -n "${header_json}" | b64enc ) - - payload_json='{ - "iat":'"${iat}"', - "exp":'"${exp}"', - "iss":'"${app_id}"' - }' - # Payload encode - payload=$( echo -n "${payload_json}" | b64enc ) - - # Signature - header_payload="${header}"."${payload}" - signature=$( - openssl dgst -sha256 -sign <(echo -n "${pem}") \ - <(echo -n "${header_payload}") | b64enc - ) - - # Create JWT - JWT="${header_payload}"."${signature}" - - # Make a POST request to GitHub API to get the installation token - response=$(curl -s -X POST \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: Bearer $JWT" \ - -d "{}" \ - "https://api.github.com/app/installations/$installation_id/access_tokens") - - # Extract the token from the response - token=$(echo "$response" | jq -r '.token') - echo "export GITHUB_TOKEN=$token" >> $BASH_ENV - echo "export GH_TOKEN=$token" >> $BASH_ENV - echo "export GITHUB_ACCESS_TOKEN=$token" >> $BASH_ENV - - -jobs: - - infrastructure: - description: Build and optionally deploy the infratructure - parameters: - scope: - description: The pnpm scope to build for - type: string - default: '' - stack-output-path: - description: The pnpm output path - type: string - apply: - description: If you should apply - type: boolean - default: false - dev: - description: Whether or not its a dev build - type: boolean - default: false - uses_raw_hcl: - description: Signals that we do not need to compile the app code - type: boolean - default: false - <<: [*repo_for_enum, *resource_class_enmum] - # Our self hosted runners dont support docker images, cause its not deployed in kubernetes, so we have some special steps - machine: true - shell: /bin/bash --login -eo pipefail - resource_class: << parameters.resource-class >> - steps: - - exit-early-if-irrelevant: - for: << parameters.for >> - - checkout - - run: - name: Install tfcmt - command: | - if ! command -v tfcmt &> /dev/null; then - echo "tfcmt does not exist, installing" - curl -L https://github.com/suzuki-shunsuke/tfcmt/releases/download/v4.9.1/tfcmt_linux_amd64.tar.gz | tar xvzf - tfcmt - mv tfcmt /home/circleci/tfcmt - chmod a+x /home/circleci/tfcmt - fi - - install_codebuild_secrets - - setup_github_bot - - unless: - # Only compile if we do not use raw hcl - condition: <> - steps: - - install_infrastructure_pnpm: - scope: << parameters.scope >> - - when: - condition: <> - steps: - - run: - name: Build Dev Infra - command: | - nvm use - export NODE_ENV=development - pnpm run synth --filter=<< parameters.scope >>... - - unless: - condition: <> - steps: - - run: - name: Build Prod Infra - command: | - nvm use - export NODE_ENV=production - pnpm run synth --filter=<< parameters.scope >>... - - when: - condition: <> - steps: - - when: - condition: <> - steps: - - run: - name: Copy Dev tfvars - command: | - cd << parameters.stack-output-path >> - cp dev_backend.tfvars backend.tf - - unless: - condition: <> - steps: - - run: - name: Copy Prod tfvars - command: | - cd << parameters.stack-output-path >> - cp prod_backend.tfvars backend.tf - - run: - name: Setup terraform - command: | - cd << parameters.stack-output-path >> - tfenv use - terraform init - - when: - condition: <> - steps: - - run: - name: Terraform apply - # Re-add this when tfcmt supports ignoring no change applies - # https://github.com/suzuki-shunsuke/tfcmt/issues/1184 - # /home/circleci/tfcmt --var target:<< parameters.scope >><<#parameters.dev>>-dev<> apply -- terraform apply -auto-approve -lock-timeout=10m - command: | - cd << parameters.stack-output-path >> - terraform apply -auto-approve -lock-timeout=10m - mkdir -p /tmp/workspace - echo "$(terraform output -json)" > /tmp/workspace/tf_output.json - # Persist TF_OUTPUT using workspace - - persist_to_workspace: - root: /tmp/workspace - paths: - - tf_output.json - - unless: - condition: <> - steps: - - run: - name: Terraform plan - command: | - cd << parameters.stack-output-path >> - tfcmt --var target:<< parameters.scope >><<#parameters.dev>>-dev<> plan --skip-no-changes --patch -- terraform plan -lock-timeout=10m - - code_deploy_ecs: - parameters: - <<: [*repo_for_enum, *resource_class_enmum] - # Our self hosted runners dont support docker images, cause its not deployed in kubernetes, so we have some special steps - machine: true - shell: /bin/bash --login -eo pipefail - resource_class: << parameters.resource-class >> - steps: - - exit-early-if-irrelevant: - for: << parameters.for >> - # Restore TF_OUTPUT from workspace - - attach_workspace: - at: /tmp/workspace - - run: - # Pulls out the terraform params needed for CodeDeploy and then re-saves them to be used in the CodeDeploy ORB - name: CodeDeploy Load Env - command: | - TF_OUTPUT=$(cat /tmp/workspace/tf_output.json) - ECS_TASK_ARN=$(echo "$TF_OUTPUT" | jq -r '.["ecs-task-arn"].value') - ECS_TASK_CONTAINER_NAME=$(echo "$TF_OUTPUT" | jq -r '.["ecs-task-containerName"].value') - ECS_TASK_CONTAINER_PORT=$(echo "$TF_OUTPUT" | jq -r '.["ecs-task-containerPort"].value') - ECS_TASK_FAMILY=$(echo "$TF_OUTPUT" | jq -r '.["ecs-task-family"].value') - ECS_CODEDEPLOY_GROUP=$(echo "$TF_OUTPUT" | jq -r '.["ecs-codedeploy-group"].value') - ECS_CODEDEPLOY_APP=$(echo "$TF_OUTPUT" | jq -r '.["ecs-codedeploy-app"].value') - - echo "export ECS_TASK_ARN=$ECS_TASK_ARN" >> $BASH_ENV - echo "export ECS_TASK_CONTAINER_NAME=$ECS_TASK_CONTAINER_NAME" >> $BASH_ENV - echo "export ECS_TASK_CONTAINER_PORT=$ECS_TASK_CONTAINER_PORT" >> $BASH_ENV - echo "export ECS_TASK_FAMILY=$ECS_TASK_FAMILY" >> $BASH_ENV - echo "export ECS_CODEDEPLOY_GROUP=$ECS_CODEDEPLOY_GROUP" >> $BASH_ENV - echo "export ECS_CODEDEPLOY_APP=$ECS_CODEDEPLOY_APP" >> $BASH_ENV - - ## All the following steps are copied from https://github.com/CircleCI-Public/aws-ecs-orb/blob/master/src/commands/update_service.yml but we manually run them so we can pass env variables that we otherwise couldn't since it relies on parameter steps. - ## See open issue to clean up when we can. https://github.com/CircleCI-Public/aws-ecs-orb/issues/211 - ## Once the above issue is fixed we can remove the included script and these commands and replace it with the below. - # - aws-ecs/update_service: - # name: Deploy ECS Service - # codedeploy_application_name: ${ECS_CODEDEPLOY_APP} - # codedeploy_deployment_group_name: ${ECS_CODEDEPLOY_GROUP} - # codedeploy_load_balanced_container_name: ${ECS_TASK_CONTAINER_NAME} - # codedeploy_load_balanced_container_port: ${ECS_TASK_CONTAINER_PORT} - # family: ${ECS_TASK_FAMILY} - # container_image_name_updates: tag=${CIRCLE_SHA1}, container=${ECS_TASK_CONTAINER_NAME} - # deployment_controller: CODE_DEPLOY - # verify_revision_is_deployed: true - - - aws-cli/install - ## Set the AWS CLI to use the Ecs Container credentials since this is in a hosted runner on AWS. - - run: - name: Setup AWS Auth - command: | - aws configure set profile.default.credential_source EcsContainer - - ## This will use the last revision in AWS to create a new task definition with the container image pointed to the sha of this commit - ## If the task def was changed in terraform, that will be the latest revision that this will then over - - aws-ecs/update_task_definition: - family: ${ECS_TASK_FAMILY} - container_image_name_updates: container=${ECS_TASK_CONTAINER_NAME},tag=${CIRCLE_SHA1} - ## We need to checkout the code, because that contains our copied script from the aws-ecs orb repo. - - checkout - - run: - name: Update ECS Blue/Green service with registered task definition. - command: | - .circleci/scripts/update_bluegreen_service_via_task_def.sh - no_output_timeout: 10m - environment: - DEPLOYMENT_CONTROLLER: CODE_DEPLOY - ORB_STR_CD_APP_NAME: ${ECS_CODEDEPLOY_APP} - ORB_STR_CD_DEPLOY_GROUP_NAME: ${ECS_CODEDEPLOY_GROUP} - ORB_STR_CD_LOAD_BALANCED_CONTAINER_NAME: ${ECS_TASK_CONTAINER_NAME} - ORB_INT_CD_LOAD_BALANCED_CONTAINER_PORT: ${ECS_TASK_CONTAINER_PORT} - # Dont wait for a successful deploy, we will get alerts in slack for those. - ORB_BOOL_VERIFY_REV_DEPLOY: false - ORB_STR_PROFILE_NAME: default - ORB_BOOL_ENABLE_CIRCUIT_BREAKER: false - ORB_STR_CD_CAPACITY_PROVIDER_NAME: - ORB_STR_CD_CAPACITY_PROVIDER_WEIGHT: - ORB_STR_CD_CAPACITY_PROVIDER_BASE: - ORB_STR_CD_DEPLOYMENT_CONFIG_NAME: - - code_deploy_lambda: - parameters: - codedeploy-app-name: - description: CodeDeploy app name - type: string - codedeploy-group-name: - description: CodeDeploy group name - type: string - function-name: - description: > - The name of the Lambda Function to deploy to - type: string - s3-bucket: - type: string - description: The name of the bucket to deploy from - s3-key: - type: string - description: The name of the s3 key that contains the code to deploy - default: "" - function-alias: - type: string - description: The name of the lambda alias to use - default: DEPLOYED - <<: [*repo_for_enum, *resource_class_enmum] - # Our self hosted runners dont support docker images, cause its not deployed in kubernetes, so we have some special steps - machine: true - shell: /bin/bash --login -eo pipefail - resource_class: << parameters.resource-class >> - steps: - - exit-early-if-irrelevant: - for: << parameters.for >> - - run: - name: Deploy Lambda - command: | - export AWS_PAGER="" - aws lambda wait function-updated --function-name '<< parameters.function-name >>' - - s3Key="<< parameters.s3-key >>" - if [[ -z $s3Key ]]; then - s3Key="$CIRCLE_SHA1.zip" - fi - - aws lambda update-function-code \ - --function-name '<< parameters.function-name >>' \ - --s3-bucket '<< parameters.s3-bucket >>' \ - --s3-key "$s3Key" - - aws lambda wait function-updated --function-name '<< parameters.function-name >>' - - NEW_ENVVARS=$(aws lambda get-function-configuration --function-name '<< parameters.function-name >>' --query "Environment.Variables | merge(@, \`{\"GIT_SHA\":\"$CIRCLE_SHA1\"}\`)") - aws lambda update-function-configuration --function-name '<< parameters.function-name >>' --environment "{ \"Variables\": $NEW_ENVVARS }" - aws lambda wait function-updated --function-name '<< parameters.function-name >>' - - versionId=$(aws lambda publish-version \ - --function-name '<< parameters.function-name >>' | jq -r .Version) - - currentVersion=$(aws lambda get-alias \ - --function-name '<< parameters.function-name >>' \ - --name DEPLOYED | jq -r .FunctionVersion) - - app_spec_content_string="{'version':0.0,'Resources':[{'<< parameters.function-name >>':{'Type':'AWS::Lambda::Function','Properties':{'Name':'<< parameters.function-name >>','Alias':'<< parameters.function-alias >>','TargetVersion':'$versionId', 'CurrentVersion': '$currentVersion'}}}]}" - echo "$app_spec_content_string" - app_spec_content_sha256=$(echo -n "$app_spec_content_string" | shasum -a 256 | sed 's/ .*$//') - revision="revisionType=AppSpecContent,appSpecContent={content=\"$app_spec_content_string\",sha256=$app_spec_content_sha256}" - - aws lambda wait function-updated --function-name '<< parameters.function-name >>' - - aws deploy create-deployment \ - --application-name="<< parameters.codedeploy-app-name >>" \ - --deployment-group-name="<< parameters.codedeploy-group-name >>" \ - --description="Triggered build $CIRCLE_SHA1 from CircleCI" \ - --revision="$revision" - - test_integrations: - description: Run integration tests against external services, e.g. MySQL - parameters: - scope: - description: The pnpm scope to run tests for - type: string - <<: *repo_for_enum - docker: - - image: *node_image - auth: - username: $DOCKERHUB_USERNAME - password: $DOCKERHUB_PASSWORD - environment: - AWS_XRAY_LOG_LEVEL: silent - AWS_XRAY_CONTEXT_MISSING: LOG_ERROR - - image: redis:latest@sha256:d6ecc832969a4827645a083da38345327b3447772fe907e7d4311c79b4e3a06e - auth: - username: $DOCKERHUB_USERNAME - password: $DOCKERHUB_PASSWORD - - image: mysql:8.0.36@sha256:ce628295ff5aa269e4d0241e0552476fa0de3af263daedf196ccb6fc0834fa6b - auth: - username: $DOCKERHUB_USERNAME - password: $DOCKERHUB_PASSWORD - environment: - - MYSQL_ALLOW_EMPTY_PASSWORD=yes - - TZ=UTC - command: --default_authentication_plugin=mysql_native_password --sql-mode="NO_ENGINE_SUBSTITUTION" --character-set-server=UTF8MB3 --collation-server=utf8_unicode_ci - - image: localstack/localstack:3.2.0@sha256:167eb023e07eef65f1e490d7a77cf45124e7a24395e4736dd2582e8ea0618ecb - auth: - username: $DOCKERHUB_USERNAME - password: $DOCKERHUB_PASSWORD - environment: - SERVICES: s3,kinesis,sqs,dynamodb,sts,events,firehose,es - - image: pocket/snowplow-micro:prod - auth: - username: $DOCKERHUB_USERNAME - password: $DOCKERHUB_PASSWORD - steps: - - exit-early-if-irrelevant: - for: << parameters.for >> - - checkout - - install_pnpm: - scope: << parameters.scope >> - - run: - name: run setup.sh - command: | - export $(egrep -v '^#' .docker/local.env | xargs -0) && ./.circleci/scripts/setup.sh --db --aws=<< parameters.scope >> - - run: - # Note there is a bug in turbo repo requiring a build https://github.com/vercel/turbo/issues/1609 - name: run tests - command: | - export $(egrep -v '^#' .docker/local.env | xargs -0) - corepack pnpm run test-integrations --filter=<< parameters.scope >>... - - build_image: - description: Build and/or push docker image to ECR. - - parameters: - aws-access-key-id: - description: 'AWS access key id environment variable' - type: string - aws-region: - description: 'AWS region value' - type: string - aws-secret-access-key: - description: 'AWS secret access key environment variable' - type: string - ecr-url: - description: 'The ecr url' - type: string - extra-build-args: - description: 'Extra flags to pass to docker build. For examples, see https://docs.docker.com/engine/reference/commandline/build' - type: string - default: --build-arg GIT_SHA=${CIRCLE_SHA1} - push: - description: 'Whether or not to push the code' - type: boolean - default: false - repo-name: - description: 'The ecr repo name' - type: string - tag: - description: 'The docker tag name' - type: string - default: latest,$CIRCLE_SHA1 - app_path: - description: 'The path needed for building the Docker image' - type: string - default: '.' - layer_caching: - description: 'Whether to use docker layer caching' - type: boolean - default: true - <<: *repo_for_enum - executor: aws-cli/default - - steps: - - exit-early-if-irrelevant: - for: << parameters.for >> - - checkout - - aws-cli/setup: - aws_access_key_id: << parameters.aws-access-key-id >> - aws_secret_access_key: << parameters.aws-secret-access-key >> - region: << parameters.aws-region >> - - run: - name: Setup common environment variables - command: | - { \ - echo 'export AWS_ECR_ACCOUNT_URL="<< parameters.ecr-url >>"'; \ - echo 'export REPO_NAME="<< parameters.repo-name >>"'; \ - } >> "$BASH_ENV" - - when: - condition: <> - steps: - - aws-ecr/build-and-push-image: - checkout: false - repo: << parameters.repo-name >> - path: << parameters.app_path >> - setup-remote-docker: true - remote-docker-layer-caching: << parameters.layer_caching >> - aws-access-key-id: << parameters.aws-access-key-id >> - aws-secret-access-key: << parameters.aws-secret-access-key >> - tag: << parameters.tag >> - remote-docker-version: default - extra-build-args: << parameters.extra-build-args >> - - unless: - condition: <> - steps: - - setup_remote_docker: - version: default - docker-layer-caching: << parameters.layer_caching >> - - aws-ecr/build-image: - repo: << parameters.repo-name >> - tag: << parameters.tag >> - path: << parameters.app_path >> - extra-build-args: << parameters.extra-build-args >> - - build_lambda: - description: Build and/or push lambda function. - parameters: - aws-access-key-id: - description: 'AWS access key id environment variable' - type: string - aws-region: - description: 'AWS region value' - type: string - aws-secret-access-key: - description: 'AWS secret access key environment variable' - type: string - s3-bucket: - description: 'The s3 bucket name' - type: string - default: "" - scope: - description: The pnpm scope to build for - type: string - sentry_project_name: - type: string - description: the Sentry project name - default: "" - sentry_env: - type: string - default: Prod - description: Which environment the release is going to - sentry_org: - type: string - description: The sentry org to upload source maps to - s3-key: - type: string - description: The name of the s3 key that contains the code to deploy - default: "" - <<: *repo_for_enum - docker: - - image: *node_image - auth: - username: $DOCKERHUB_USERNAME - password: $DOCKERHUB_PASSWORD - steps: - - exit-early-if-irrelevant: - for: << parameters.for >> - - run: - name: Setup Environment variables - command: | - echo "export SENTRY_AUTH_TOKEN="$SENTRY_BEARER"" >> "$BASH_ENV" - - checkout - - install_pnpm: - scope: << parameters.scope >> - - run: - # Theres a really annoying bug in PNPM deploy command that will try and create a folder at /home/pruned which we are not allowed to do, - # so we move it under 1 directory to let it do its thing. - # https://github.com/pnpm/pnpm/issues/5086 - name: Build lambda - command: | - corepack pnpm run build --filter=<< parameters.scope >>... - mkdir -p ~/bug/project - cp -R . ~/bug/project/ - cd ~/bug/project/ - corepack pnpm deploy --filter=<< parameters.scope >> --prod pruned - - when: - condition: << parameters.sentry_project_name >> - steps: - - run: - name: Inject Sentry & Upload Sourcemaps - command: | - cd ~/bug/project/ - corepack pnpx @sentry/cli sourcemaps inject pruned/dist - corepack pnpx @sentry/cli sourcemaps upload pruned/dist --release ${CIRCLE_SHA1} --auth-token ${SENTRY_AUTH_TOKEN} --org << parameters.sentry_org >> --project << parameters.sentry_project_name >> - - run: - name: Package Lambda - command: | - cd ~/bug/project/pruned - cp -r package.json dist/ - cp -r node_modules/ dist/node_modules/ - - cd dist - zip --symlinks -r9 ~/project/${CIRCLE_SHA1}.zip . - mkdir /tmp/artifacts - cp ~/project/${CIRCLE_SHA1}.zip /tmp/artifacts/ - cd .. - maxFileSize=256000 # Get the size of the directory in kilobytes - export dirSize=$(du -s dist | cut -f1) - echo "Size is: $dirSize" - if ((dirSize > maxFileSize)); then - echo "Directory size is equal to or larger than $maxFileSize KB. which is the lambda limit" - exit 1 - fi - - when: - condition: << parameters.s3-bucket >> - steps: - - aws-cli/setup: - aws_access_key_id: << parameters.aws-access-key-id >> - aws_secret_access_key: << parameters.aws-secret-access-key >> - region: << parameters.aws-region >> - - run: - name: Upload Package - command: | - s3Key="<< parameters.s3-key >>" - if [[ -z $s3Key ]]; then - s3Key="$CIRCLE_SHA1.zip" - fi - aws s3 cp $CIRCLE_SHA1.zip s3://<< parameters.s3-bucket >>/${s3Key} - - store_artifacts: - path: /tmp/artifacts - - apollo: - description: > - Runs Apollo rover schema check on the production graphql federated schema. - If it is the production branch will deploy the subgraph to the production federated graph. - If the branch is the development branch, will deploy the subgraph to the development federated graph. - - parameters: - fed_graph_name: - type: string - description: The name of federated graph to check - graph_name: - type: string - description: The name of this subgraph - schema_file_path: - type: string - description: The patht to the schema file - default: ./schema.graphql - prod_graph_url: - type: string - description: The production subgraph url - dev_graph_url: - type: string - description: The development subgraph url - prod_graph_variant_name: - type: string - description: The production variant graph name - default: "current" - dev_graph_variant_name: - type: string - description: The development variant graph name - default: "development" - prod_branch: - type: string - description: The production git branch - default: "main" - dev_branch: - type: string - description: The development git branch - default: "dev" - apollo_key_env: - type: env_var_name - default: APOLLO_KEY - description: The environment variable name of the apollo key to user - build_command: - description: 'build command to use if we need to' - type: string - default: "" - scope: - description: The pnpm scope to build for - type: string - docker: - - image: *node_image - auth: - username: $DOCKER_LOGIN - password: $DOCKER_PASSWORD - - steps: - - checkout - - run: - name: install rover - command: | - # download and install Rover - curl -sSL https://rover.apollo.dev/nix/latest | sh - - # This allows the PATH changes to persist to the next `run` step - echo "export PATH=$HOME/.rover/bin:$PATH" >> "$BASH_ENV" - - when: - condition: << parameters.build_command >> - steps: - - install_pnpm: - scope: << parameters.scope >> - - run: - name: build schema - command: | - corepack << parameters.build_command >> - - run: - name: check service - command: | - export APOLLO_KEY=$<< parameters.apollo_key_env >> - rover subgraph check << parameters.fed_graph_name >>@<< parameters.prod_graph_variant_name >> --schema << parameters.schema_file_path >> --name=<< parameters.graph_name >> - - when: - condition: - equal: [<< parameters.prod_branch >>, << pipeline.git.branch >>] - steps: - - run: - name: push service to prod - command: | - export APOLLO_KEY=$<< parameters.apollo_key_env >> - rover subgraph publish << parameters.fed_graph_name >>@<< parameters.prod_graph_variant_name >> --schema << parameters.schema_file_path >> --routing-url << parameters.prod_graph_url >> --name=<< parameters.graph_name >> - - when: - condition: - equal: [<< parameters.dev_branch >>, << pipeline.git.branch >>] - steps: - - run: - name: push service to dev - command: | - export APOLLO_KEY=$<< parameters.apollo_key_env >> - rover subgraph publish << parameters.fed_graph_name >>@<< parameters.dev_graph_variant_name >> --schema << parameters.schema_file_path >> --routing-url << parameters.dev_graph_url >> --name=<< parameters.graph_name >> - - sentry_release_notification: - description: Create new release in Sentry - resource_class: small - parameters: - sentry_project_name: - type: string - description: the Sentry project name - sentry_env: - type: string - default: Prod - description: Which environment the release is going to - sentry_org: - type: string - description: The sentry org - <<: *repo_for_enum - docker: - - image: getsentry/sentry-cli@sha256:67e30136fc6c4b38c7b93df802d03507f5afbcf6307ddfbaa4ebf98a640c6d02 - auth: - username: $DOCKER_LOGIN - password: $DOCKER_PASSWORD - steps: - - exit-early-if-irrelevant: - for: << parameters.for >> - - run: - name: Setup Environment variables - command: | - echo "export SENTRY_AUTH_TOKEN="$SENTRY_BEARER"" >> "$BASH_ENV" - echo "export SENTRY_ORG=<< parameters.sentry_org >>" >> "$BASH_ENV" - echo "export SENTRY_PROJECT=<< parameters.sentry_project_name >>" >> "$BASH_ENV" - - run: - name: Sentry Release Notification - command: | - source "$BASH_ENV" - sentry-cli releases new "$CIRCLE_SHA1" - sentry-cli releases set-commits "$CIRCLE_SHA1" --commit "Pocket/pocket-monorepo@$CIRCLE_SHA1" - sentry-cli releases finalize "$CIRCLE_SHA1" - - run: - name: Sentry Deploy Notification - command: | - source "$BASH_ENV" - sentry-cli releases deploys "$CIRCLE_SHA1" new -e "<< parameters.sentry_env >>" \ No newline at end of file diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 0fdae5fc8..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,106 +0,0 @@ -version: 2.1 - -# this allows you to use CircleCI's dynamic configuration feature -setup: true - -orbs: - path-filtering: circleci/path-filtering@1.0.0 - continuation: circleci/continuation@1.0.0 - -# our defined job, and its steps -jobs: - setup: - executor: path-filtering/default - steps: - - checkout # checkout code - - run: - name: Generate List of Configs to Merge - command: | - # Generate a list of all the circleci configs we want to run - file_list=( - ".circleci/common.yml" - ".circleci/repo-jobs.yml" - ".circleci/image-api.yml" - ".circleci/annotations-api.yml" - ".circleci/shared-snowplow-consumer.yml" - ".circleci/parser-graphql-wrapper.yml" - ".circleci/transactional-emails.yml" - ".circleci/fxa-webhook-proxy.yml" - ".circleci/user-api.yml" - ".circleci/client-api.yml" - ".circleci/list-api.yml" - ".circleci/feature-flags.yml" - ".circleci/sendgrid-data.yml" - ".circleci/account-data-deleter.yml" - ".circleci/account-delete-monitor.yml" - ".circleci/shareable-lists-api.yml" - ".circleci/pocket-event-bridge.yml" - ".circleci/user-list-search.yml" - ".circleci/braze.yml" - ".circleci/v3-proxy-api.yml" - ".circleci/push-server.yml" - ".circleci/instant-sync-events.yml" - ".circleci/shares-api.yml" - ".circleci/corpus-embeddings.yml" - ) - touch /tmp/configs.txt - - # Add file header to each file and dump it to the config list - for file in "${file_list[@]}"; do - echo "$file" >> /tmp/configs.txt - awk -v new_content="$(cat .circleci/header.yml)" 'BEGIN {print new_content} {print}' "$file" > temp_file && mv temp_file "$file" - done - - path-filtering/generate-config: - config-list-path: /tmp/configs.txt - generated-config-path: /tmp/generated-config.yml - - run: - name: Reset Git - command: | - git reset --hard - # Set up path mapping, in the future we should generate this as a conf file, and pass it to the option. - # We will need to set this to true when ever the packages folder changes as well. - # Right now though, we will only deploy if the actual servers/infra change, - # as its likely any change in the packages will change the underlying code. - # Worst case, bump the version in package.json to triger a deploy - # - # The router is just rhai scripts and yaml files without dependencies on node or any other - # packages, so we don't trigger it unless a change occurs specifically in the subfolder - # - # NOTE: we use _ for the parameters to the pipeline because - # circleci uses it as an ENV down the pipe and ENV vars can't be used with a - - - path-filtering/set-parameters: - config-path: /tmp/generated-config.yml - output-path: /tmp/pipeline-parameters.json - mapping: | - ((servers|infrastructure)/image-api/.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/common.yml) image_api true - ((servers|infrastructure|lambdas)/annotations-api.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/common.yml) annotations_api true - ((servers|infrastructure)/shared-snowplow-consumer/.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/common.yml) shared_snowplow_consumer true - ((servers|infrastructure)/parser-graphql-wrapper/.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/common.yml) parser_graphql_wrapper true - ((lambdas|infrastructure)/transactional-emails.*)|(packages/.*)|(pnpm-lock\.yaml)|(.circleci/common.yml) transactional_emails true - ((lambdas|infrastructure)/fxa-webhook-proxy-.*)|(packages/.*)|(pnpm-lock\.yaml)|(.circleci/common.yml) fxa_webhook_proxy true - ((servers|infrastructure)/user-api/.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/common.yml) user_api true - ((servers|infrastructure)/list-api/.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/common.yml) list_api true - ((servers|infrastructure)/client-api/.*)|(.circleci/common.yml) client_api true - ((servers|infrastructure)/feature-flags/.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/common.yml) feature_flags true - ((lambdas|infrastructure)/sendgrid-data/.*)|(.circleci/common.yml) sendgrid_data true - ((lambdas|infrastructure|servers)/account-data-deleter/.*)|(packages/.*)|(pnpm-lock\.yaml)|(.circleci/account-data-deleter.yml)|(.circleci/common.yml) account_data_deleter true - ((lambdas|infrastructure)/account-delete-monitor/.*)|(packages/.*)|(pnpm-lock\.yaml)|(.circleci/account-delete-monitor.yml)|(.circleci/common.yml) account_delete_monitor true - ((servers|infrastructure|lambdas)/shareable-lists-api/.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/common.yml) shareable_lists_api true - ((infrastructure)/pocket-event-bridge/.*)|(packages/.*)|(pnpm-lock\.yaml)|(.circleci/pocket-event-bridge.yml)|(.circleci/common.yml) pocket_event_bridge true - ((servers|infrastructure|lambdas)/user-list-search.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/user-list-search.yml)|(.circleci/common.yml) user_list_search true - ((infrastructure)/braze/.*)|(packages/.*)|(pnpm-lock\.yaml)|(.circleci/braze.yml)|(.circleci/common.yml) braze true - ((servers|infrastructure)/v3-proxy-api/.*)|(packages/.*)|(pnpm-lock\.yaml)|(.circleci/v3-proxy-api.yml)|(.circleci/common.yml) v3_proxy_api true - ((servers|infrastructure)/push-server/.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/push-server.yml)|(.circleci/common.yml) push_server true - ((lambda|infrastructure)/instant-sync-events/.*)|(packages/.*)|(pnpm-lock\.yaml)|(.circleci/instant-sync-events.yml)|(.circleci/common.yml) instant_sync_events true - ((servers|infrastructure)/shares-api.*)|(packages/.*)|(pnpm-lock\.yaml)|(Dockerfile)|(.circleci/common.yml) shares_api true - ((infrastructure|lambdas)/corpus-embeddings.*)|(.circleci/corpus-embeddings.yml)|(.circleci/common.yml) corpus_embeddings true - - - continuation/continue: - configuration_path: /tmp/generated-config.yml - parameters: /tmp/pipeline-parameters.json - -# our single workflow, that triggers the setup job defined above -workflows: - setup: - jobs: - - setup diff --git a/.circleci/corpus-embeddings.yml b/.circleci/corpus-embeddings.yml deleted file mode 100644 index 8d3002b07..000000000 --- a/.circleci/corpus-embeddings.yml +++ /dev/null @@ -1,150 +0,0 @@ -workflows: - corpus-embeddings: - jobs: - - - ###### - # Every PR Jobs - ###### - - infrastructure: - <<: *not_dev_main - context: pocket - for: corpus_embeddings - name: corpus-embeddings_infrastructure_plan_prod - stack-output-path: infrastructure/corpus-embeddings - scope: corpus-embeddings-cdk - resource-class: pocket/default-prod - dev: false - apply: false - uses_raw_hcl: true - - - build_lambda: - <<: *not_dev_main - context: pocket - for: corpus_embeddings - name: corpus-embeddings-connector_build_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: corpus-embeddings-connector-creator - sentry_project_name: corpus-embeddings - sentry_env: development - sentry_org: pocket - - # ###### - # # Dev Branch Deployment (Dev Environment) - # ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: corpus_embeddings - name: corpus-embeddings_infrastructure_apply_dev - stack-output-path: infrastructure/corpus-embeddings - scope: corpus-embeddings-cdk - resource-class: pocket/default-dev - apply: true - dev: true - uses_raw_hcl: true - - - build_lambda: - <<: *only_dev - context: pocket - for: corpus_embeddings - name: corpus-embeddings-connector_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: corpus-embeddings-connector-creator - sentry_project_name: corpus-embeddings - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-corpusembeddings-dev-lambdas - s3-key: corpus-embeddings-connector-creator-$CIRCLE_SHA1.zip - requires: - - corpus-embeddings_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: corpus_embeddings - name: corpus-embeddings-connector_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: CorpusEmbeddings-Dev-CreateMlConnector - codedeploy-group-name: CorpusEmbeddings-Dev-CreateMlConnector - function-name: CorpusEmbeddings-Dev-CreateMlConnector - s3-bucket: pocket-corpusembeddings-dev-lambdas - s3-key: corpus-embeddings-connector-creator-$CIRCLE_SHA1.zip - requires: - - corpus-embeddings-connector_build_lambda_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: corpus-embeddings_sentry-release-notification-dev - context: pocket - for: corpus_embeddings - sentry_project_name: corpus-embeddings - sentry_env: development - sentry_org: pocket - requires: - - corpus-embeddings-connector_code_deploy_lambda_dev - - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: corpus_embeddings - name: corpus-embeddings_infrastructure_apply_prod - scope: corpus-embeddings-cdk - stack-output-path: infrastructure/corpus-embeddings - resource-class: pocket/default-prod - apply: true - dev: false - uses_raw_hcl: true - - - build_lambda: - <<: *only_main - context: pocket - for: corpus_embeddings - name: corpus-embeddings-connector_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: corpus-embeddings-connector-creator - sentry_project_name: corpus-embeddings - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-corpusembeddings-prod-lambdas - s3-key: corpus-embeddings-connector-creator-$CIRCLE_SHA1.zip - requires: - - corpus-embeddings_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: corpus-embeddings-connector_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: CorpusEmbeddings-Prod-CreateMlConnector - codedeploy-group-name: CorpusEmbeddings-Prod-CreateMlConnector - function-name: CorpusEmbeddings-Prod-CreateMlConnector - s3-bucket: pocket-corpusembeddings-prod-lambdas - s3-key: corpus-embeddings-connector-creator-$CIRCLE_SHA1.zip - requires: - - corpus-embeddings-connector_build_lambda_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: corpus-embeddings_sentry-release-notification-prod - context: pocket - for: corpus_embeddings - sentry_project_name: corpus-embeddings - sentry_env: production - sentry_org: pocket - requires: - - corpus-embeddings-connector_code_deploy_lambda_prod diff --git a/.circleci/feature-flags.yml b/.circleci/feature-flags.yml deleted file mode 100644 index feb330962..000000000 --- a/.circleci/feature-flags.yml +++ /dev/null @@ -1,144 +0,0 @@ - -workflows: - feature-flags: - jobs: - - ###### - # Every PR Jobs - ###### - - apollo: - name: feature-flags_apollo - fed_graph_name: pocket-client-api - graph_name: featureflags - schema_file_path: servers/feature-flags/schema.graphql - prod_graph_url: https://featureflags.readitlater.com/graphql - dev_graph_url: https://featureflags.getpocket.dev/graphql - scope: feature-flags - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: feature_flags - name: feature-flags_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: featureflags-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=feature-flags --build-arg APP_PATH=servers/feature-flags --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=feature-flags --build-arg PORT=4242 - - - infrastructure: - <<: *not_dev_main - context: pocket - for: feature_flags - name: feature-flags_infrastructure_plan_prod - scope: feature-flags-cdk - stack-output-path: infrastructure/feature-flags/cdktf.out/stacks/feature-flags - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: feature_flags - name: feature-flags_infrastructure_apply_dev - scope: feature-flags-cdk - stack-output-path: infrastructure/feature-flags/cdktf.out/stacks/feature-flags - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: feature_flags - name: feature-flags_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: featureflags-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=feature-flags --build-arg APP_PATH=servers/feature-flags --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=feature-flags --build-arg PORT=4242 - requires: - - feature-flags_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: feature_flags - name: feature-flags_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - feature-flags_build_docker_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: feature-flags_sentry-release-notification-dev - context: pocket - for: feature_flags - sentry_project_name: feature-flags - sentry_env: development - sentry_org: pocket - requires: - - feature-flags_code_deploy_ecs_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: feature_flags - name: feature-flags_infrastructure_apply_prod - scope: feature-flags-cdk - stack-output-path: infrastructure/feature-flags/cdktf.out/stacks/feature-flags - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: feature_flags - name: feature-flags_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: featureflags-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=feature-flags --build-arg APP_PATH=servers/feature-flags --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=feature-flags --build-arg PORT=4242 - requires: - - feature-flags_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: feature_flags - name: feature-flags_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - feature-flags_build_docker_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: feature-flags_sentry-release-notification-prod - context: pocket - for: feature_flags - sentry_project_name: feature-flags - sentry_env: production - sentry_org: pocket - requires: - - feature-flags_code_deploy_ecs_prod diff --git a/.circleci/fxa-webhook-proxy.yml b/.circleci/fxa-webhook-proxy.yml deleted file mode 100644 index 073753c7d..000000000 --- a/.circleci/fxa-webhook-proxy.yml +++ /dev/null @@ -1,217 +0,0 @@ - -workflows: - fxa-webhook-proxy: - jobs: - - ###### - # Every PR Jobs - ###### - - build_lambda: - <<: *not_dev_main - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_build_sqs_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: fxa-webhook-proxy-sqs - sentry_project_name: fxa-webhook-proxy - sentry_env: development - sentry_org: pocket - - - build_lambda: - <<: *not_dev_main - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_build_gateway_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: fxa-webhook-proxy-gateway - sentry_project_name: fxa-webhook-proxy - sentry_env: development - sentry_org: pocket - - - infrastructure: - <<: *not_dev_main - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_infrastructure_plan_prod - scope: fxa-webhook-proxy-cdk - stack-output-path: infrastructure/fxa-webhook-proxy/cdktf.out/stacks/fxa-webhook-proxy - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_infrastructure_apply_dev - scope: fxa-webhook-proxy-cdk - stack-output-path: infrastructure/fxa-webhook-proxy/cdktf.out/stacks/fxa-webhook-proxy - resource-class: pocket/default-dev - apply: true - dev: true - - - build_lambda: - <<: *only_dev - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_events_build_gateway_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: fxa-webhook-proxy-gateway - sentry_project_name: fxa-webhook-proxy - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-fxawebhookproxy-dev-apigateway-fxa-events - requires: - - fxa-webhook-proxy_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_gateway_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: FxAWebhookProxy-Dev-ApiGateway-FxA-Events-Lambda - codedeploy-group-name: FxAWebhookProxy-Dev-ApiGateway-FxA-Events-Lambda - function-name: FxAWebhookProxy-Dev-ApiGateway-FxA-Events-Function - s3-bucket: pocket-fxawebhookproxy-dev-apigateway-fxa-events - requires: - - fxa-webhook-proxy_events_build_gateway_lambda_dev - - - build_lambda: - <<: *only_dev - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_events_build_sqs_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: fxa-webhook-proxy-sqs - sentry_project_name: fxa-webhook-proxy - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-fxawebhookproxy-dev-sqs-fxa-events - requires: - - fxa-webhook-proxy_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_sqs_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: FxAWebhookProxy-Dev-Sqs-FxA-Events-Lambda - codedeploy-group-name: FxAWebhookProxy-Dev-Sqs-FxA-Events-Lambda - function-name: FxAWebhookProxy-Dev-Sqs-FxA-Events-Function - s3-bucket: pocket-fxawebhookproxy-dev-sqs-fxa-events - requires: - - fxa-webhook-proxy_events_build_sqs_lambda_dev - - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: fxa-webhook-proxy_sentry-release-notification-dev - context: pocket - for: fxa_webhook_proxy - sentry_project_name: fxa-webhook-proxy - sentry_env: development - sentry_org: pocket - requires: - - fxa-webhook-proxy_sqs_code_deploy_lambda_dev - - fxa-webhook-proxy_gateway_code_deploy_lambda_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_infrastructure_apply_prod - scope: fxa-webhook-proxy-cdk - stack-output-path: infrastructure/fxa-webhook-proxy/cdktf.out/stacks/fxa-webhook-proxy - resource-class: pocket/default-prod - apply: true - dev: false - - - build_lambda: - <<: *only_main - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_events_build_gateway_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: fxa-webhook-proxy-gateway - sentry_project_name: fxa-webhook-proxy - sentry_env: prodelopment - sentry_org: pocket - s3-bucket: pocket-fxawebhookproxy-prod-apigateway-fxa-events - requires: - - fxa-webhook-proxy_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_gateway_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: FxAWebhookProxy-Prod-ApiGateway-FxA-Events-Lambda - codedeploy-group-name: FxAWebhookProxy-Prod-ApiGateway-FxA-Events-Lambda - function-name: FxAWebhookProxy-Prod-ApiGateway-FxA-Events-Function - s3-bucket: pocket-fxawebhookproxy-prod-apigateway-fxa-events - requires: - - fxa-webhook-proxy_events_build_gateway_lambda_prod - - - build_lambda: - <<: *only_main - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_events_build_sqs_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: fxa-webhook-proxy-sqs - sentry_project_name: fxa-webhook-proxy - sentry_env: prodelopment - sentry_org: pocket - s3-bucket: pocket-fxawebhookproxy-prod-sqs-fxa-events - requires: - - fxa-webhook-proxy_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: fxa_webhook_proxy - name: fxa-webhook-proxy_sqs_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: FxAWebhookProxy-Prod-Sqs-FxA-Events-Lambda - codedeploy-group-name: FxAWebhookProxy-Prod-Sqs-FxA-Events-Lambda - function-name: FxAWebhookProxy-Prod-Sqs-FxA-Events-Function - s3-bucket: pocket-fxawebhookproxy-prod-sqs-fxa-events - requires: - - fxa-webhook-proxy_events_build_sqs_lambda_prod - - - # Notify sentry of prod deployment - - sentry_release_notification: - <<: *only_main - name: fxa-webhook-proxy_sentry-release-notification-prod - context: pocket - for: fxa_webhook_proxy - sentry_project_name: fxa-webhook-proxy - sentry_env: prodelopment - sentry_org: pocket - requires: - - fxa-webhook-proxy_sqs_code_deploy_lambda_prod - - fxa-webhook-proxy_gateway_code_deploy_lambda_prod diff --git a/.circleci/header.yml b/.circleci/header.yml deleted file mode 100644 index 3db565362..000000000 --- a/.circleci/header.yml +++ /dev/null @@ -1,45 +0,0 @@ -# Workflow shortcuts -# Anything in this file will be added to all the yaml files, before CircleCI merges them. -# This is because yaml files need to be valid before merge and that means things like anchors must be defined in each file. - -node_image: &node_image cimg/node:20.15 -node_version: &node_version 20.15 -base_image: &base_image cimg/base:2024.07 - -not_main: ¬_main - filters: - branches: - ignore: - - main - -only_main: &only_main - filters: - branches: - only: - - main - -not_dev: ¬_dev - filters: - branches: - ignore: - - dev - -only_dev_main: &only_dev_main - filters: - branches: - only: - - dev - - main - -not_dev_main: ¬_dev_main - filters: - branches: - ignore: - - dev - - main - -only_dev: &only_dev - filters: - branches: - only: - - dev \ No newline at end of file diff --git a/.circleci/image-api.yml b/.circleci/image-api.yml deleted file mode 100644 index 7c4f295dc..000000000 --- a/.circleci/image-api.yml +++ /dev/null @@ -1,161 +0,0 @@ - -workflows: - image-api: - jobs: - - ###### - # Every PR Jobs - ###### - - apollo: - name: image-api_apollo - fed_graph_name: pocket-client-api - graph_name: image-api - schema_file_path: servers/image-api/schema.graphql - prod_graph_url: https://image-api.readitlater.com - dev_graph_url: https://image-api.getpocket.dev - scope: image-api - - - apollo: - name: image-api_apollo_admin - fed_graph_name: pocket-admin-api - schema_file_path: servers/image-api/schema.graphql - graph_name: image-api - prod_graph_url: https://image-api.readitlater.com - dev_graph_url: https://image-api.getpocket.dev - apollo_key_env: APOLLO_ADMIN_KEY - scope: image-api - - - test_integrations: - <<: *not_dev_main - for: image_api - context: pocket - name: image-api_test_integrations - scope: image-api - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: image_api - name: image-api_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: imageapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=image-api --build-arg APP_PATH=servers/image-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=image-api --build-arg PORT=4867 - - - infrastructure: - <<: *not_dev_main - context: pocket - for: image_api - name: image-api_infrastructure_plan_prod - scope: image-api-cdk - stack-output-path: infrastructure/image-api/cdktf.out/stacks/image-api - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: image_api - name: image-api_infrastructure_apply_dev - scope: image-api-cdk - stack-output-path: infrastructure/image-api/cdktf.out/stacks/image-api - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: image_api - name: image-api_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: imageapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=image-api --build-arg APP_PATH=servers/image-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=image-api --build-arg PORT=4867 - requires: - - image-api_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: image_api - name: image-api_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - image-api_build_docker_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: image-api_sentry-release-notification-dev - context: pocket - for: image_api - sentry_project_name: image-api - sentry_env: development - sentry_org: pocket - requires: - - image-api_code_deploy_ecs_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: image_api - name: image-api_infrastructure_apply_prod - scope: image-api-cdk - stack-output-path: infrastructure/image-api/cdktf.out/stacks/image-api - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: image_api - name: image-api_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: imageapi-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=image-api --build-arg APP_PATH=servers/image-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=image-api --build-arg PORT=4867 - requires: - - image-api_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: image_api - name: image-api_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - image-api_build_docker_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: image-api_sentry-release-notification-prod - context: pocket - for: image_api - sentry_project_name: image-api - sentry_env: production - sentry_org: pocket - requires: - - image-api_code_deploy_ecs_prod diff --git a/.circleci/instant-sync-events.yml b/.circleci/instant-sync-events.yml deleted file mode 100644 index eb0576ab9..000000000 --- a/.circleci/instant-sync-events.yml +++ /dev/null @@ -1,149 +0,0 @@ - -workflows: - instant-sync-events: - jobs: - - ###### - # Every PR Jobs - ###### - - test_integrations: - <<: *not_dev_main - for: instant_sync_events - context: pocket - name: instant-sync-events_test_integrations - scope: instant-sync-events - - - build_lambda: - <<: *not_dev_main - context: pocket - for: instant_sync_events - name: instant-sync-events_build_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: instant-sync-events - sentry_project_name: instant-sync-events - sentry_env: development - sentry_org: pocket - - - infrastructure: - <<: *not_dev_main - context: pocket - for: instant_sync_events - name: instant-sync-events_infrastructure_plan_prod - scope: instant-sync-events-cdk - stack-output-path: infrastructure/instant-sync-events/cdktf.out/stacks/instant-sync-events - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: instant_sync_events - name: instant-sync-events_infrastructure_apply_dev - scope: instant-sync-events-cdk - stack-output-path: infrastructure/instant-sync-events/cdktf.out/stacks/instant-sync-events - resource-class: pocket/default-dev - apply: true - dev: true - - - build_lambda: - <<: *only_dev - context: pocket - for: instant_sync_events - name: instant-sync-events_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: instant-sync-events - sentry_project_name: instant-sync-events - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-instantsyncevents-dev-eventtracker - requires: - - instant-sync-events_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: instant_sync_events - name: instant-sync-events_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: InstantSyncEvents-Dev-EventTracker-Lambda - codedeploy-group-name: InstantSyncEvents-Dev-EventTracker-Lambda - function-name: InstantSyncEvents-Dev-EventTracker-Function - s3-bucket: pocket-instantsyncevents-dev-eventtracker - requires: - - instant-sync-events_build_lambda_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: instant-sync-events_sentry-release-notification-dev - context: pocket - for: instant_sync_events - sentry_project_name: instant-sync-events - sentry_env: development - sentry_org: pocket - requires: - - instant-sync-events_code_deploy_lambda_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: instant_sync_events - name: instant-sync-events_infrastructure_apply_prod - scope: instant-sync-events-cdk - stack-output-path: infrastructure/instant-sync-events/cdktf.out/stacks/instant-sync-events - resource-class: pocket/default-prod - apply: true - dev: false - - - build_lambda: - <<: *only_main - context: pocket - for: instant_sync_events - name: instant-sync-events_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: instant-sync-events - sentry_project_name: instant-sync-events - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-instantsyncevents-prod-eventtracker - requires: - - instant-sync-events_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: instant_sync_events - name: instant-sync-events_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: InstantSyncEvents-Prod-EventTracker-Lambda - codedeploy-group-name: InstantSyncEvents-Prod-EventTracker-Lambda - function-name: InstantSyncEvents-Prod-EventTracker-Function - s3-bucket: pocket-instantsyncevents-prod-eventtracker - requires: - - instant-sync-events_build_lambda_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: instant-sync-events_sentry-release-notification-prod - context: pocket - for: instant_sync_events - sentry_project_name: instant-sync-events - sentry_env: production - sentry_org: pocket - requires: - - instant-sync-events_code_deploy_lambda_prod diff --git a/.circleci/list-api.yml b/.circleci/list-api.yml deleted file mode 100644 index a3445b72b..000000000 --- a/.circleci/list-api.yml +++ /dev/null @@ -1,152 +0,0 @@ - -workflows: - list-api: - jobs: - - ###### - # Every PR Jobs - ###### - - apollo: - name: list-api_apollo - fed_graph_name: pocket-client-api - graph_name: list - schema_file_path: servers/list-api/dist/schema-generated.graphql - prod_graph_url: https://list-api.readitlater.com - dev_graph_url: https://list-api.getpocket.dev - build_command: pnpm run build --filter=list-api... - scope: list-api - - - test_integrations: - <<: *not_dev_main - for: list_api - context: pocket - name: list-api_test_integrations - scope: list-api - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: list_api - name: list-api_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: listapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=list-api --build-arg APP_PATH=servers/list-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=list-api --build-arg PORT=4005 - - - infrastructure: - <<: *not_dev_main - context: pocket - for: list_api - name: list-api_infrastructure_plan_prod - scope: list-api-cdk - stack-output-path: infrastructure/list-api/cdktf.out/stacks/list-api - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: list_api - name: list-api_infrastructure_apply_dev - scope: list-api-cdk - stack-output-path: infrastructure/list-api/cdktf.out/stacks/list-api - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: list_api - name: list-api_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: listapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=list-api --build-arg APP_PATH=servers/list-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=list-api --build-arg PORT=4005 - requires: - - list-api_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: list_api - name: list-api_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - list-api_build_docker_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: list-api_sentry-release-notification-dev - context: pocket - for: list_api - sentry_project_name: list-api - sentry_env: development - sentry_org: pocket - requires: - - list-api_code_deploy_ecs_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: list_api - name: list-api_infrastructure_apply_prod - scope: list-api-cdk - stack-output-path: infrastructure/list-api/cdktf.out/stacks/list-api - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: list_api - name: list-api_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: listapi-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=list-api --build-arg APP_PATH=servers/list-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=list-api --build-arg PORT=4005 - requires: - - list-api_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: list_api - name: list-api_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - list-api_build_docker_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: list-api_sentry-release-notification-prod - context: pocket - for: list_api - sentry_project_name: list-api - sentry_env: production - sentry_org: pocket - requires: - - list-api_code_deploy_ecs_prod diff --git a/.circleci/parser-graphql-wrapper.yml b/.circleci/parser-graphql-wrapper.yml deleted file mode 100644 index 547d9d690..000000000 --- a/.circleci/parser-graphql-wrapper.yml +++ /dev/null @@ -1,161 +0,0 @@ - -workflows: - parser-graphql-wrapper: - jobs: - - ###### - # Every PR Jobs - ###### - - apollo: - name: parser-graphql-wrapper_apollo - fed_graph_name: pocket-client-api - graph_name: parser - schema_file_path: servers/parser-graphql-wrapper/schema.graphql - prod_graph_url: https://parser-graphql-wrapper.readitlater.com - dev_graph_url: https://parser-graphql-wrapper.getpocket.dev - scope: parser-graphql-wrapper - - - apollo: - name: parser-graphql-wrapper_apollo_admin - fed_graph_name: pocket-admin-api - schema_file_path: servers/parser-graphql-wrapper/schema.graphql - graph_name: parser - prod_graph_url: https://parser-graphql-wrapper.readitlater.com - dev_graph_url: https://parser-graphql-wrapper.getpocket.dev - apollo_key_env: APOLLO_ADMIN_KEY - scope: parser-graphql-wrapper - - - test_integrations: - <<: *not_dev_main - for: parser_graphql_wrapper - context: pocket - name: parser-graphql-wrapper_test_integrations - scope: parser-graphql-wrapper - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: parser_graphql_wrapper - name: parser-graphql-wrapper_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: parsergraphqlwrapper-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=parser-graphql-wrapper --build-arg APP_PATH=servers/parser-graphql-wrapper --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=parser-graphql-wrapper --build-arg PORT=4001 - - - infrastructure: - <<: *not_dev_main - context: pocket - for: parser_graphql_wrapper - name: parser-graphql-wrapper_infrastructure_plan_prod - scope: parser-graphql-wrapper-cdk - stack-output-path: infrastructure/parser-graphql-wrapper/cdktf.out/stacks/parser-graphql-wrapper - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: parser_graphql_wrapper - name: parser-graphql-wrapper_infrastructure_apply_dev - scope: parser-graphql-wrapper-cdk - stack-output-path: infrastructure/parser-graphql-wrapper/cdktf.out/stacks/parser-graphql-wrapper - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: parser_graphql_wrapper - name: parser-graphql-wrapper_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: parsergraphqlwrapper-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=parser-graphql-wrapper --build-arg APP_PATH=servers/parser-graphql-wrapper --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=parser-graphql-wrapper --build-arg PORT=4001 - requires: - - parser-graphql-wrapper_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: parser_graphql_wrapper - name: parser-graphql-wrapper_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - parser-graphql-wrapper_build_docker_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: parser-graphql-wrapper_sentry-release-notification-dev - context: pocket - for: parser_graphql_wrapper - sentry_project_name: parser-graphql-wrapper - sentry_env: development - sentry_org: pocket - requires: - - parser-graphql-wrapper_code_deploy_ecs_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: parser_graphql_wrapper - name: parser-graphql-wrapper_infrastructure_apply_prod - scope: parser-graphql-wrapper-cdk - stack-output-path: infrastructure/parser-graphql-wrapper/cdktf.out/stacks/parser-graphql-wrapper - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: parser_graphql_wrapper - name: parser-graphql-wrapper_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: parsergraphqlwrapper-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=parser-graphql-wrapper --build-arg APP_PATH=servers/parser-graphql-wrapper --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=parser-graphql-wrapper --build-arg PORT=4001 - requires: - - parser-graphql-wrapper_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: parser_graphql_wrapper - name: parser-graphql-wrapper_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - parser-graphql-wrapper_build_docker_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: parser-graphql-wrapper_sentry-release-notification-prod - context: pocket - for: parser_graphql_wrapper - sentry_project_name: parser-graphql-wrapper - sentry_env: production - sentry_org: pocket - requires: - - parser-graphql-wrapper_code_deploy_ecs_prod diff --git a/.circleci/pocket-event-bridge.yml b/.circleci/pocket-event-bridge.yml deleted file mode 100644 index b5d954b36..000000000 --- a/.circleci/pocket-event-bridge.yml +++ /dev/null @@ -1,49 +0,0 @@ - -workflows: - pocket-event-bridge: - jobs: - - ###### - # Every PR Jobs - ###### - - - infrastructure: - <<: *not_dev_main - context: pocket - for: pocket_event_bridge - name: pocket-event-bridge_infrastructure_plan_prod - scope: pocket-event-bridge-cdk - stack-output-path: infrastructure/pocket-event-bridge/cdktf.out/stacks/pocket-event-bridge - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: pocket_event_bridge - name: pocket-event-bridge_infrastructure_apply_dev - scope: pocket-event-bridge-cdk - stack-output-path: infrastructure/pocket-event-bridge/cdktf.out/stacks/pocket-event-bridge - resource-class: pocket/default-dev - apply: true - dev: true - - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: pocket_event_bridge - name: pocket-event-bridge_infrastructure_apply_prod - scope: pocket-event-bridge-cdk - stack-output-path: infrastructure/pocket-event-bridge/cdktf.out/stacks/pocket-event-bridge - resource-class: pocket/default-prod - apply: true - dev: false diff --git a/.circleci/push-server.yml b/.circleci/push-server.yml deleted file mode 100644 index b724841be..000000000 --- a/.circleci/push-server.yml +++ /dev/null @@ -1,124 +0,0 @@ - -workflows: - push-server: - jobs: - - ###### - # Every PR Jobs - ###### - - test_integrations: - <<: *not_dev_main - for: push_server - context: pocket - name: push-server_test_integrations - scope: push-server - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: push_server - name: push-server_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: push-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=push-server --build-arg APP_PATH=servers/push-server --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=push-server - - - infrastructure: - <<: *not_dev_main - context: pocket - for: push_server - name: push-server_infrastructure_plan_prod - scope: push-server-cdk - stack-output-path: infrastructure/push-server/cdktf.out/stacks/push-server - resource-class: pocket/default-prod - dev: false - apply: false - - # ###### - # # Dev Branch Deployment (Dev Environment) - # ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: push_server - name: push-server_infrastructure_apply_dev - scope: push-server-cdk - stack-output-path: infrastructure/push-server/cdktf.out/stacks/push-server - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: push_server - name: push-server_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: push-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=push-server --build-arg APP_PATH=servers/push-server --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=push-server - requires: - - push-server_infrastructure_apply_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: push-server_sentry-release-notification-dev - context: pocket - for: push_server - sentry_project_name: push-server - sentry_env: development - sentry_org: pocket - requires: - - push-server_infrastructure_apply_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: push_server - name: push-server_infrastructure_apply_prod - scope: push-server-cdk - stack-output-path: infrastructure/push-server/cdktf.out/stacks/push-server - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: push_server - name: push-server_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: push-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=push-server --build-arg APP_PATH=servers/push-server --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=push-server - requires: - - push-server_infrastructure_apply_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: push-server_sentry-release-notification-prod - context: pocket - for: push_server - sentry_project_name: push-server - sentry_env: production - sentry_org: pocket - requires: - - push-server_infrastructure_apply_prod diff --git a/.circleci/repo-jobs.yml b/.circleci/repo-jobs.yml deleted file mode 100644 index d53984dec..000000000 --- a/.circleci/repo-jobs.yml +++ /dev/null @@ -1,48 +0,0 @@ -jobs: - lint: - docker: - - image: *node_image - steps: - - checkout - - install_pnpm - - run: - name: Lint - command: | - corepack pnpm run lint - - mismatched_versions: - docker: - - image: *node_image - steps: - - checkout - - install_pnpm - - run: - name: Check for Mismatch - command: | - corepack pnpm list-mismatches - - test: - docker: - - image: *node_image - resource_class: xlarge - steps: - - checkout - - install_pnpm - - run: - name: Test - # Following uses a 2 concurrency because terraform modules seems to fail with an OOM error on CI if we do more. - command: | - corepack pnpm run test --concurrency=2 - -workflows: - repo: - jobs: - - lint: - <<: *not_dev_main - context: pocket - - test: - <<: *not_dev_main - context: pocket - - mismatched_versions: - <<: *not_dev_main - context: pocket \ No newline at end of file diff --git a/.circleci/scripts/setup.sh b/.circleci/scripts/setup.sh deleted file mode 100755 index a730ec0fd..000000000 --- a/.circleci/scripts/setup.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -set -e - -dir=$(dirname "$0") -while [[ "$1" ]]; do - case "$1" in - --db) - "${dir}"/setup_db.sh - ;; - --aws=*) - # Extract the value after '=' - "${dir}"/setup_aws.sh --scope="${1#*=}" - ;; - esac - shift -done diff --git a/.circleci/scripts/setup_aws.sh b/.circleci/scripts/setup_aws.sh deleted file mode 100755 index cd393ea8d..000000000 --- a/.circleci/scripts/setup_aws.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash -set -e - -sudo apt-get update && sudo apt-get install -y python3-pip -pip3 install boto3 awscli-local awscli --no-build-isolation - -# Default value for scope -scope="" -# Loop through the arguments -while [ "$#" -gt 0 ]; do - case $1 in - --scope=*) - # Extract the value after '=' - scope="${1#*=}" - ;; - esac - shift -done - -script=".docker/aws-resources/${scope}.sh" - -# Check if the script exists -if [ -f "$script" ]; then - echo "Executing script: $script" - # Execute the script - bash "$script" -fi diff --git a/.circleci/scripts/setup_db.sh b/.circleci/scripts/setup_db.sh deleted file mode 100755 index 963580e0e..000000000 --- a/.circleci/scripts/setup_db.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# shellcheck disable=SC1090 - -echo "Setting up database" - -sudo apt-get update && sudo apt-get install -y default-mysql-client - -set -e -mysql=( mysql -uroot -h127.0.0.1 ) - -# Wait for mysql to respond -for _ in {30..0}; do - if echo 'SELECT 1' | "${mysql[@]}" &> /dev/null; then - break - fi - echo 'MySQL init process in progress...' - sleep 1 -done - -for f in .docker/mysql-8-resources/schema/*; do - echo "$f" - case "$f" in - *.sh) echo "$0: running $f"; . "$f" ;; - *.sql) echo "$0: running $f"; "${mysql[@]}" < "$f"; echo ;; - *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${mysql[@]}"; echo ;; - *) echo "$0: ignoring $f" ;; - esac - echo -done \ No newline at end of file diff --git a/.circleci/scripts/update_bluegreen_service_via_task_def.sh b/.circleci/scripts/update_bluegreen_service_via_task_def.sh deleted file mode 100755 index 662285d8e..000000000 --- a/.circleci/scripts/update_bluegreen_service_via_task_def.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -# From https://github.com/CircleCI-Public/aws-ecs-orb/blob/master/src/scripts/update_bluegreen_service_via_task_def.sh -set -o noglob - -# These variables are evaluated so the config file may contain and pass in environment variables to the parameters. -ORB_STR_CD_APP_NAME="$(circleci env subst "$ORB_STR_CD_APP_NAME")" -ORB_STR_CD_DEPLOY_GROUP_NAME="$(circleci env subst "$ORB_STR_CD_DEPLOY_GROUP_NAME")" -ORB_STR_CD_LOAD_BALANCED_CONTAINER_NAME="$(circleci env subst "$ORB_STR_CD_LOAD_BALANCED_CONTAINER_NAME")" -ORB_STR_CD_CAPACITY_PROVIDER_WEIGHT="$(circleci env subst "$ORB_STR_CD_CAPACITY_PROVIDER_WEIGHT")" -ORB_STR_CD_CAPACITY_PROVIDER_BASE="$(circleci env subst "$ORB_STR_CD_CAPACITY_PROVIDER_BASE")" -ORB_STR_CD_DEPLOYMENT_CONFIG_NAME="$(circleci env subst "$ORB_STR_CD_DEPLOYMENT_CONFIG_NAME")" -ORB_STR_PROFILE_NAME="$(circleci env subst "$ORB_STR_PROFILE_NAME")" -ORB_INT_CD_LOAD_BALANCED_CONTAINER_PORT="$(circleci env subst "$ORB_INT_CD_LOAD_BALANCED_CONTAINER_PORT")" - -DEPLOYED_REVISION="${CCI_ORB_AWS_ECS_REGISTERED_TASK_DFN}" - -if [ "$ORB_BOOL_ENABLE_CIRCUIT_BREAKER" == "1" ] && [ "$ORB_BOOL_VERIFY_REV_DEPLOY" == "0" ]; then - echo "enable-circuit-breaker is set to true, but verify-revision-deploy is set to false. verfiy-revision-deploy must be set to true to use enable-circuit-breaker." - exit 1 -fi - -if [ -n "$ORB_STR_CD_CAPACITY_PROVIDER_NAME" ]; then - if [ -z "$ORB_STR_CD_CAPACITY_PROVIDER_WEIGHT" ] || [ -z "$ORB_STR_CD_CAPACITY_PROVIDER_BASE" ]; then - echo "Capacity Provider base and weight parameter must all be provided. Please try again" - exit 1 - else - REVISION="{\"revisionType\": \"AppSpecContent\", \"appSpecContent\": {\"content\": \"{\\\"version\\\": 1, \\\"Resources\\\": [{\\\"TargetService\\\": {\\\"Type\\\": \\\"AWS::ECS::Service\\\", \\\"Properties\\\": {\\\"TaskDefinition\\\": \\\"${CCI_ORB_AWS_ECS_REGISTERED_TASK_DFN}\\\", \\\"LoadBalancerInfo\\\": {\\\"ContainerName\\\": \\\"$ORB_STR_CD_LOAD_BALANCED_CONTAINER_NAME\\\", \\\"ContainerPort\\\": $ORB_INT_CD_LOAD_BALANCED_CONTAINER_PORT},\\\"CapacityProviderStrategy\\\":[{\\\"CapacityProvider\\\":\\\"$ORB_STR_CD_CAPACITY_PROVIDER_NAME\\\", \\\"Base\\\":${ORB_STR_CD_CAPACITY_PROVIDER_BASE}, \\\"Weight\\\":${ORB_STR_CD_CAPACITY_PROVIDER_WEIGHT}}]}}}]}\"}}" - fi -else - REVISION="{\"revisionType\": \"AppSpecContent\", \"appSpecContent\": {\"content\": \"{\\\"version\\\": 1, \\\"Resources\\\": [{\\\"TargetService\\\": {\\\"Type\\\": \\\"AWS::ECS::Service\\\", \\\"Properties\\\": {\\\"TaskDefinition\\\": \\\"${CCI_ORB_AWS_ECS_REGISTERED_TASK_DFN}\\\", \\\"LoadBalancerInfo\\\": {\\\"ContainerName\\\": \\\"$ORB_STR_CD_LOAD_BALANCED_CONTAINER_NAME\\\", \\\"ContainerPort\\\": $ORB_INT_CD_LOAD_BALANCED_CONTAINER_PORT}}}}]}\"}}" -fi - -if [ -n "$ORB_STR_CD_DEPLOYMENT_CONFIG_NAME" ]; then - set -- "$@" --deployment-config-name "${ORB_STR_CD_DEPLOYMENT_CONFIG_NAME}" -fi - -DEPLOYMENT_ID=$(aws deploy create-deployment \ - --application-name "$ORB_STR_CD_APP_NAME" \ - --deployment-group-name "$ORB_STR_CD_DEPLOY_GROUP_NAME" \ - --profile "$ORB_STR_PROFILE_NAME" \ - --query deploymentId \ - --revision "${REVISION}" \ - "$@" \ - --output text) - -echo "Created CodeDeploy deployment: $DEPLOYMENT_ID" - -if [ "$ORB_BOOL_VERIFY_REV_DEPLOY" == "1" ]; then - echo "Waiting for deployment to succeed." - if aws deploy wait deployment-successful --deployment-id "${DEPLOYMENT_ID}" --profile "${ORB_STR_PROFILE_NAME}"; then - echo "Deployment succeeded." - elif [ "$ORB_BOOL_ENABLE_CIRCUIT_BREAKER" == "1" ]; then - echo "Deployment failed. Rolling back." - aws deploy stop-deployment --deployment-id "${DEPLOYMENT_ID}" --auto-rollback-enabled --profile "${ORB_STR_PROFILE_NAME}" - else - echo "Deployment failed. Exiting." - exit 1 - fi -fi - -echo "export CCI_ORB_AWS_ECS_DEPLOYED_REVISION='${DEPLOYED_REVISION}'" >> "$BASH_ENV" \ No newline at end of file diff --git a/.circleci/sendgrid-data.yml b/.circleci/sendgrid-data.yml deleted file mode 100644 index ee28dc46b..000000000 --- a/.circleci/sendgrid-data.yml +++ /dev/null @@ -1,143 +0,0 @@ - -workflows: - sendgrid-data: - jobs: - - ###### - # Every PR Jobs - ###### - - build_lambda: - <<: *not_dev_main - context: pocket - for: sendgrid_data - name: sendgrid-data_build_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: sendgrid-data - sentry_project_name: sendgrid-data - sentry_env: development - sentry_org: pocket - - - infrastructure: - <<: *not_dev_main - context: pocket - for: sendgrid_data - name: sendgrid-data_infrastructure_plan_prod - scope: sendgrid-data-cdk - stack-output-path: infrastructure/sendgrid-data/cdktf.out/stacks/sendgrid-data - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: sendgrid_data - name: sendgrid-data_infrastructure_apply_dev - scope: sendgrid-data-cdk - stack-output-path: infrastructure/sendgrid-data/cdktf.out/stacks/sendgrid-data - resource-class: pocket/default-dev - apply: true - dev: true - - - build_lambda: - <<: *only_dev - context: pocket - for: sendgrid_data - name: sendgrid-data_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: sendgrid-data - sentry_project_name: sendgrid-data - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-sendgriddata-dev-apigateway - requires: - - sendgrid-data_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: sendgrid_data - name: sendgrid-data_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: SendGridData-Dev-ApiGateway-Lambda - codedeploy-group-name: SendGridData-Dev-ApiGateway-Lambda - function-name: SendGridData-Dev-ApiGateway-Function - s3-bucket: pocket-sendgriddata-dev-apigateway - requires: - - sendgrid-data_build_lambda_dev - - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: sendgrid-data_sentry-release-notification-dev - context: pocket - for: sendgrid_data - sentry_project_name: sendgrid-data - sentry_env: development - sentry_org: pocket - requires: - - sendgrid-data_code_deploy_lambda_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: sendgrid_data - name: sendgrid-data_infrastructure_apply_prod - scope: sendgrid-data-cdk - stack-output-path: infrastructure/sendgrid-data/cdktf.out/stacks/sendgrid-data - resource-class: pocket/default-prod - apply: true - dev: false - - build_lambda: - <<: *only_main - context: pocket - for: sendgrid_data - name: sendgrid-data_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: sendgrid-data - sentry_project_name: sendgrid-data - sentry_env: prodelopment - sentry_org: pocket - s3-bucket: pocket-sendgriddata-prod-apigateway - requires: - - sendgrid-data_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: sendgrid_data - name: sendgrid-data_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: SendGridData-Prod-ApiGateway-Lambda - codedeploy-group-name: SendGridData-Prod-ApiGateway-Lambda - function-name: SendGridData-Prod-ApiGateway-Function - s3-bucket: pocket-sendgriddata-prod-apigateway - requires: - - sendgrid-data_build_lambda_prod - - - # Notify sentry of prod deployment - - sentry_release_notification: - <<: *only_main - name: sendgrid-data_sentry-release-notification-prod - context: pocket - for: sendgrid_data - sentry_project_name: sendgrid-data - sentry_env: prodelopment - sentry_org: pocket - requires: - - sendgrid-data_code_deploy_lambda_prod diff --git a/.circleci/shareable-lists-api.yml b/.circleci/shareable-lists-api.yml deleted file mode 100644 index 0018828ac..000000000 --- a/.circleci/shareable-lists-api.yml +++ /dev/null @@ -1,236 +0,0 @@ - -workflows: - shareable-lists-api: - jobs: - - ###### - # Every PR Jobs - ###### - - apollo: - name: shareable-lists-api_apollo - fed_graph_name: pocket-client-api - graph_name: shareable-lists-api - schema_file_path: servers/shareable-lists-api/schema-client-api.graphql - prod_graph_url: https://shareablelistsapi.readitlater.com - dev_graph_url: https://shareablelistsapi.getpocket.dev - build_command: pnpm run build --filter=shareable-lists-api... - scope: shareable-lists-api - - - apollo: - name: shareable-lists-api_apollo_admin - fed_graph_name: pocket-admin-api - graph_name: shareable-lists-api - schema_file_path: servers/shareable-lists-api/schema-admin-api.graphql - prod_graph_url: https://shareablelistsapi.readitlater.com - dev_graph_url: https://shareablelistsapi.getpocket.dev - build_command: pnpm run build --filter=shareable-lists-api... - apollo_key_env: APOLLO_ADMIN_KEY - scope: shareable-lists-api - - - test_integrations: - <<: *not_dev_main - for: shareable_lists_api - context: pocket - name: shareable-lists-api_test_integrations - scope: shareable-lists-api - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: shareable_lists_api - name: shareable-lists-api_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: shareablelistsapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=shareable-lists-api --build-arg APP_PATH=servers/shareable-lists-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=shareable-lists-api --build-arg PORT=4029 - - - build_lambda: - <<: *not_dev_main - context: pocket - for: shareable_lists_api - name: shareable-lists-api_build_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: shareable-lists-api-events-lambda - sentry_project_name: shareable-lists-api - sentry_env: development - sentry_org: pocket - - - infrastructure: - <<: *not_dev_main - context: pocket - for: shareable_lists_api - name: shareable-lists-api_infrastructure_plan_prod - scope: shareable-lists-api-cdk - stack-output-path: infrastructure/shareable-lists-api/cdktf.out/stacks/shareable-lists-api - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: shareable_lists_api - name: shareable-lists-api_infrastructure_apply_dev - scope: shareable-lists-api-cdk - stack-output-path: infrastructure/shareable-lists-api/cdktf.out/stacks/shareable-lists-api - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: shareable_lists_api - name: shareable-lists-api_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: shareablelistsapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=shareable-lists-api --build-arg APP_PATH=servers/shareable-lists-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=shareable-lists-api --build-arg PORT=4029 - requires: - - shareable-lists-api_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: shareable_lists_api - name: shareable-lists-api_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - shareable-lists-api_build_docker_dev - - - build_lambda: - <<: *only_dev - context: pocket - for: shareable_lists_api - name: shareable-lists-api_events_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: shareable-lists-api-events-lambda - sentry_project_name: shareable-lists-api - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-shareablelistsapi-dev-sqs-event-consumer - requires: - - shareable-lists-api_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: shareable_lists_api - name: shareable-lists-api_events_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: ShareableListsApi-Dev-Sqs-Event-Consumer-Lambda - codedeploy-group-name: ShareableListsApi-Dev-Sqs-Event-Consumer-Lambda - function-name: ShareableListsApi-Dev-Sqs-Event-Consumer-Function - s3-bucket: pocket-shareablelistsapi-dev-sqs-event-consumer - requires: - - shareable-lists-api_events_build_lambda_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: shareable-lists-api_sentry-release-notification-dev - context: pocket - for: shareable_lists_api - sentry_project_name: shareable-lists-api - sentry_env: development - sentry_org: pocket - requires: - - shareable-lists-api_code_deploy_ecs_dev - - shareable-lists-api_events_code_deploy_lambda_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: shareable_lists_api - name: shareable-lists-api_infrastructure_apply_prod - scope: shareable-lists-api-cdk - stack-output-path: infrastructure/shareable-lists-api/cdktf.out/stacks/shareable-lists-api - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: shareable_lists_api - name: shareable-lists-api_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: shareablelistsapi-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=shareable-lists-api --build-arg APP_PATH=servers/shareable-lists-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=shareable-lists-api --build-arg PORT=4029 - requires: - - shareable-lists-api_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: shareable_lists_api - name: shareable-lists-api_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - shareable-lists-api_build_docker_prod - - - build_lambda: - <<: *only_main - context: pocket - for: shareable_lists_api - name: shareable-lists-api_events_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: shareable-lists-api-events-lambda - sentry_project_name: shareable-lists-api - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-shareablelistsapi-prod-sqs-event-consumer - requires: - - shareable-lists-api_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: shareable_lists_api - name: shareable-lists-api_events_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: ShareableListsApi-Prod-Sqs-Event-Consumer-Lambda - codedeploy-group-name: ShareableListsApi-Prod-Sqs-Event-Consumer-Lambda - function-name: ShareableListsApi-Prod-Sqs-Event-Consumer-Function - s3-bucket: pocket-shareablelistsapi-prod-sqs-event-consumer - requires: - - shareable-lists-api_events_build_lambda_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: shareable-lists-api_sentry-release-notification-prod - context: pocket - for: shareable_lists_api - sentry_project_name: shareable-lists-api - sentry_env: production - sentry_org: pocket - requires: - - shareable-lists-api_code_deploy_ecs_prod - - shareable-lists-api_events_code_deploy_lambda_prod diff --git a/.circleci/shared-snowplow-consumer.yml b/.circleci/shared-snowplow-consumer.yml deleted file mode 100644 index 981153701..000000000 --- a/.circleci/shared-snowplow-consumer.yml +++ /dev/null @@ -1,143 +0,0 @@ - -workflows: - shared-snowplow-consumer: - jobs: - - ###### - # Every PR Jobs - ###### - - - test_integrations: - <<: *not_dev_main - for: shared_snowplow_consumer - context: pocket - name: shared-snowplow-consumer_test_integrations - scope: shared-snowplow-consumer - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: shared_snowplow_consumer - name: shared-snowplow-consumer_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: sharedsnowplowconsumer-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=shared-snowplow-consumer --build-arg APP_PATH=servers/shared-snowplow-consumer --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=shared-snowplow-consumer --build-arg PORT=4015 - - - infrastructure: - <<: *not_dev_main - context: pocket - for: shared_snowplow_consumer - name: shared-snowplow-consumer_infrastructure_plan_prod - scope: shared-snowplow-consumer-cdk - stack-output-path: infrastructure/shared-snowplow-consumer/cdktf.out/stacks/shared-snowplow-consumer - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: shared_snowplow_consumer - name: shared-snowplow-consumer_infrastructure_apply_dev - scope: shared-snowplow-consumer-cdk - stack-output-path: infrastructure/shared-snowplow-consumer/cdktf.out/stacks/shared-snowplow-consumer - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: shared_snowplow_consumer - name: shared-snowplow-consumer_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: sharedsnowplowconsumer-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=shared-snowplow-consumer --build-arg APP_PATH=servers/shared-snowplow-consumer --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=shared-snowplow-consumer --build-arg PORT=4015 - requires: - - shared-snowplow-consumer_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: shared_snowplow_consumer - name: shared-snowplow-consumer_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - shared-snowplow-consumer_build_docker_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: shared-snowplow-consumer_sentry-release-notification-dev - context: pocket - for: shared_snowplow_consumer - sentry_project_name: shared-snowplow-consumer - sentry_env: development - sentry_org: pocket - requires: - - shared-snowplow-consumer_code_deploy_ecs_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: shared_snowplow_consumer - name: shared-snowplow-consumer_infrastructure_apply_prod - scope: shared-snowplow-consumer-cdk - stack-output-path: infrastructure/shared-snowplow-consumer/cdktf.out/stacks/shared-snowplow-consumer - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: shared_snowplow_consumer - name: shared-snowplow-consumer_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: sharedsnowplowconsumer-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=shared-snowplow-consumer --build-arg APP_PATH=servers/shared-snowplow-consumer --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=shared-snowplow-consumer --build-arg PORT=4015 - requires: - - shared-snowplow-consumer_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: shared_snowplow_consumer - name: shared-snowplow-consumer_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - shared-snowplow-consumer_build_docker_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: shared-snowplow-consumer_sentry-release-notification-prod - context: pocket - for: shared_snowplow_consumer - sentry_project_name: shared-snowplow-consumer - sentry_env: production - sentry_org: pocket - requires: - - shared-snowplow-consumer_code_deploy_ecs_prod diff --git a/.circleci/shares-api.yml b/.circleci/shares-api.yml deleted file mode 100644 index e53a12d21..000000000 --- a/.circleci/shares-api.yml +++ /dev/null @@ -1,152 +0,0 @@ - -workflows: - shares-api: - jobs: - - ###### - # Every PR Jobs - ###### - - apollo: - name: shares-api_apollo - fed_graph_name: pocket-client-api - graph_name: shares-api - schema_file_path: servers/shares-api/dist/schema-generated.graphql - prod_graph_url: https://shares-api.readitlater.com - dev_graph_url: https://shares-api.getpocket.dev - build_command: pnpm run build --filter=shares-api... - scope: shares-api - - - test_integrations: - <<: *not_dev_main - for: shares_api - context: pocket - name: shares-api_test_integrations - scope: shares-api - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: shares_api - name: shares-api_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: sharesapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=shares-api --build-arg APP_PATH=servers/shares-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=shares-api --build-arg PORT=4031 - - - infrastructure: - <<: *not_dev_main - context: pocket - for: shares_api - name: shares-api_infrastructure_plan_prod - scope: shares-api-cdk - stack-output-path: infrastructure/shares-api/cdktf.out/stacks/shares-api - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: shares_api - name: shares-api_infrastructure_apply_dev - scope: shares-api-cdk - stack-output-path: infrastructure/shares-api/cdktf.out/stacks/shares-api - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: shares_api - name: shares-api_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: sharesapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=shares-api --build-arg APP_PATH=servers/shares-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=shares-api --build-arg PORT=4031 - requires: - - shares-api_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: shares_api - name: shares-api_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - shares-api_build_docker_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: shares-api_sentry-release-notification-dev - context: pocket - for: shares_api - sentry_project_name: shares-api - sentry_env: development - sentry_org: pocket - requires: - - shares-api_code_deploy_ecs_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: shares_api - name: shares-api_infrastructure_apply_prod - scope: shares-api-cdk - stack-output-path: infrastructure/shares-api/cdktf.out/stacks/shares-api - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: shares_api - name: shares-api_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: sharesapi-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=shares-api --build-arg APP_PATH=servers/shares-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=shares-api --build-arg PORT=4031 - requires: - - shares-api_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: shares_api - name: shares-api_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - shares-api_build_docker_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: shares-api_sentry-release-notification-prod - context: pocket - for: shares_api - sentry_project_name: shares-api - sentry_env: production - sentry_org: pocket - requires: - - shares-api_code_deploy_ecs_prod diff --git a/.circleci/transactional-emails.yml b/.circleci/transactional-emails.yml deleted file mode 100644 index b293f18a5..000000000 --- a/.circleci/transactional-emails.yml +++ /dev/null @@ -1,142 +0,0 @@ - -workflows: - transactional-emails: - jobs: - - ###### - # Every PR Jobs - ###### - - build_lambda: - <<: *not_dev_main - context: pocket - for: transactional_emails - name: transactional-emails_build_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: transactional-emails - sentry_project_name: transactional-emails - sentry_env: development - sentry_org: pocket - - - infrastructure: - <<: *not_dev_main - context: pocket - for: transactional_emails - name: transactional-emails_infrastructure_plan_prod - scope: transactional-emails-cdk - stack-output-path: infrastructure/transactional-emails/cdktf.out/stacks/transactional-emails - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: transactional_emails - name: transactional-emails_infrastructure_apply_dev - scope: transactional-emails-cdk - stack-output-path: infrastructure/transactional-emails/cdktf.out/stacks/transactional-emails - resource-class: pocket/default-dev - apply: true - dev: true - - - build_lambda: - <<: *only_dev - context: pocket - for: transactional_emails - name: transactional-emails_events_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: transactional-emails - sentry_project_name: transactional-emails - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-transactionalemails-dev-sqs-event-consumer - requires: - - transactional-emails_infrastructure_apply_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: transactional_emails - name: transactional-emails_events_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: TransactionalEmails-Dev-Sqs-Event-Consumer-Lambda - codedeploy-group-name: TransactionalEmails-Dev-Sqs-Event-Consumer-Lambda - function-name: TransactionalEmails-Dev-Sqs-Event-Consumer-Function - s3-bucket: pocket-transactionalemails-dev-sqs-event-consumer - requires: - - transactional-emails_events_build_lambda_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: transactional-emails_sentry-release-notification-dev - context: pocket - for: transactional_emails - sentry_project_name: transactional-emails - sentry_env: development - sentry_org: pocket - requires: - - transactional-emails_events_code_deploy_lambda_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: transactional_emails - name: transactional-emails_infrastructure_apply_prod - scope: transactional-emails-cdk - stack-output-path: infrastructure/transactional-emails/cdktf.out/stacks/transactional-emails - resource-class: pocket/default-prod - apply: true - dev: false - - - build_lambda: - <<: *only_main - context: pocket - for: transactional_emails - name: transactional-emails_events_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: transactional-emails - sentry_project_name: transactional-emails - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-transactionalemails-prod-sqs-event-consumer - requires: - - transactional-emails_infrastructure_apply_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: transactional_emails - name: transactional-emails_events_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: TransactionalEmails-Prod-Sqs-Event-Consumer-Lambda - codedeploy-group-name: TransactionalEmails-Prod-Sqs-Event-Consumer-Lambda - function-name: TransactionalEmails-Prod-Sqs-Event-Consumer-Function - s3-bucket: pocket-transactionalemails-prod-sqs-event-consumer - requires: - - transactional-emails_events_build_lambda_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: transactional-emails_sentry-release-notification-prod - context: pocket - for: transactional_emails - sentry_project_name: transactional-emails - sentry_env: production - sentry_org: pocket - requires: - - transactional-emails_events_code_deploy_lambda_prod diff --git a/.circleci/user-api.yml b/.circleci/user-api.yml deleted file mode 100644 index 4e2c17dec..000000000 --- a/.circleci/user-api.yml +++ /dev/null @@ -1,151 +0,0 @@ - -workflows: - user-api: - jobs: - - ###### - # Every PR Jobs - ###### - - apollo: - name: user-api_apollo - fed_graph_name: pocket-client-api - graph_name: user - schema_file_path: servers/user-api/schema.graphql - prod_graph_url: https://user-api.readitlater.com - dev_graph_url: https://user-api.getpocket.dev - scope: user-api - - - test_integrations: - <<: *not_dev_main - for: user_api - context: pocket - name: user-api_test_integrations - scope: user-api - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: user_api - name: user-api_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: userapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=user-api --build-arg APP_PATH=servers/user-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=user-api --build-arg PORT=4006 - - - infrastructure: - <<: *not_dev_main - context: pocket - for: user_api - name: user-api_infrastructure_plan_prod - scope: user-api-cdk - stack-output-path: infrastructure/user-api/cdktf.out/stacks/user-api - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: user_api - name: user-api_infrastructure_apply_dev - scope: user-api-cdk - stack-output-path: infrastructure/user-api/cdktf.out/stacks/user-api - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: user_api - name: user-api_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: userapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=user-api --build-arg APP_PATH=servers/user-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=user-api --build-arg PORT=4006 - requires: - - user-api_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: user_api - name: user-api_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - user-api_build_docker_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: user-api_sentry-release-notification-dev - context: pocket - for: user_api - sentry_project_name: user-api - sentry_env: development - sentry_org: pocket - requires: - - user-api_code_deploy_ecs_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: user_api - name: user-api_infrastructure_apply_prod - scope: user-api-cdk - stack-output-path: infrastructure/user-api/cdktf.out/stacks/user-api - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: user_api - name: user-api_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: userapi-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=user-api --build-arg APP_PATH=servers/user-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=user-api --build-arg PORT=4006 - requires: - - user-api_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: user_api - name: user-api_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - user-api_build_docker_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: user-api_sentry-release-notification-prod - context: pocket - for: user_api - sentry_project_name: user-api - sentry_env: production - sentry_org: pocket - requires: - - user-api_code_deploy_ecs_prod diff --git a/.circleci/user-list-search.yml b/.circleci/user-list-search.yml deleted file mode 100644 index 18bded6d0..000000000 --- a/.circleci/user-list-search.yml +++ /dev/null @@ -1,635 +0,0 @@ -workflows: - user-list-search: - jobs: - - ###### - # Every PR Jobs - ###### - - apollo: - name: user-list-search_apollo - fed_graph_name: pocket-client-api - graph_name: user-list-search - schema_file_path: servers/user-list-search/dist/schema-generated.graphql - prod_graph_url: https://user-list-search.readitlater.com/graphql - dev_graph_url: https://user-list-search.getpocket.dev/graphql - build_command: pnpm run build --filter=user-list-search... - scope: user-list-search - - - - test_integrations: - <<: *not_dev_main - for: user_list_search - context: pocket - name: user-list-search_test_integrations - scope: user-list-search - - - build_lambda: - <<: *not_dev_main - context: pocket - for: user_list_search - name: user-list-search_events_build_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: user-list-search-events - sentry_project_name: user-list-search - sentry_env: development - sentry_org: pocket - - - build_lambda: - <<: *not_dev_main - context: pocket - for: user_list_search - name: user-list-search_kinesis_to_sqs_build_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: user-list-search-kinesis-to-sqs - sentry_project_name: user-list-search - sentry_env: development - sentry_org: pocket - - - build_lambda: - <<: *not_dev_main - context: pocket - for: user_list_search - name: user-list-search_indexing_build_lambda - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: user-list-search-indexing - sentry_project_name: user-list-search - sentry_env: development - sentry_org: pocket - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: user_list_search - name: user-list-search_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: userlistsearch-dev - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=user-list-search --build-arg APP_PATH=servers/user-list-search --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=user-list-search --build-arg PORT=4000 - - - infrastructure: - <<: *not_dev_main - context: pocket - for: user_list_search - name: user-list-search_infrastructure_plan_prod - stack-output-path: infrastructure/user-list-search - scope: user-list-search-cdk - resource-class: pocket/default-prod - dev: false - apply: false - uses_raw_hcl: true - - # ###### - # # Dev Branch Deployment (Dev Environment) - # ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_infrastructure_apply_dev - stack-output-path: infrastructure/user-list-search - scope: user-list-search-cdk - resource-class: pocket/default-dev - apply: true - dev: true - uses_raw_hcl: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: userlistsearch-dev - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=user-list-search --build-arg APP_PATH=servers/user-list-search --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=user-list-search --build-arg PORT=4000 - requires: - - user-list-search_infrastructure_apply_dev - - - build_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_events_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: user-list-search-events - sentry_project_name: user-list-search - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: events-$CIRCLE_SHA1.zip - requires: - - user-list-search_infrastructure_apply_dev - - - build_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_kinesis_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: user-list-search-kinesis-to-sqs - sentry_project_name: user-list-search - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: kinesis-$CIRCLE_SHA1.zip - requires: - - user-list-search_infrastructure_apply_dev - - - build_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_indexing_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: user-list-search-indexing - sentry_project_name: user-list-search - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_infrastructure_apply_dev - - - build_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_corpus-indexing_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: user-list-search-corpus-indexing - sentry_project_name: user-list-search - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: corpus-indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_infrastructure_apply_dev - - - build_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_corpus-parser-hydration_build_lambda_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - scope: user-list-search-corpus-parser-hydration - sentry_project_name: user-list-search - sentry_env: development - sentry_org: pocket - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: corpus-parser-hydration-$CIRCLE_SHA1.zip - requires: - - user-list-search_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - user-list-search_build_docker_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_events_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: UserListSearch-Dev-EventHandler - codedeploy-group-name: UserListSearch-Dev-EventHandler - function-name: UserListSearch-Dev-EventHandler - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: events-$CIRCLE_SHA1.zip - requires: - - user-list-search_events_build_lambda_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_kinesis_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: UserListSearch-Dev-UnifiedEventsConsumer - codedeploy-group-name: UserListSearch-Dev-UnifiedEventsConsumer - function-name: UserListSearch-Dev-UnifiedEventsConsumer - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: kinesis-$CIRCLE_SHA1.zip - requires: - - user-list-search_kinesis_build_lambda_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_item-update_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: UserListSearch-Dev-ItemUpdate - codedeploy-group-name: UserListSearch-Dev-ItemUpdate - function-name: UserListSearch-Dev-ItemUpdate - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_indexing_build_lambda_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_item-delete_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: UserListSearch-Dev-ItemDelete - codedeploy-group-name: UserListSearch-Dev-ItemDelete - function-name: UserListSearch-Dev-ItemDelete - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_indexing_build_lambda_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_item-update-backfill_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: UserListSearch-Dev-ItemUpdateBackfill - codedeploy-group-name: UserListSearch-Dev-ItemUpdateBackfill - function-name: UserListSearch-Dev-ItemUpdateBackfill - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_indexing_build_lambda_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_user-list-import_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: UserListSearch-Dev-UserListImport - codedeploy-group-name: UserListSearch-Dev-UserListImport - function-name: UserListSearch-Dev-UserListImport - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_indexing_build_lambda_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_user-list-import-backfill_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: UserListSearch-Dev-UserListImportBackfill - codedeploy-group-name: UserListSearch-Dev-UserListImportBackfill - function-name: UserListSearch-Dev-UserListImportBackfill - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_indexing_build_lambda_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_corpus-indexing_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: UserListSearch-Dev-CorpusIndexer - codedeploy-group-name: UserListSearch-Dev-CorpusIndexer - function-name: UserListSearch-Dev-CorpusIndexer - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: corpus-indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_corpus-indexing_build_lambda_dev - - - code_deploy_lambda: - <<: *only_dev - context: pocket - for: user_list_search - name: user-list-search_corpus-parser-hydration_code_deploy_lambda_dev - resource-class: pocket/default-dev - codedeploy-app-name: UserListSearch-Dev-CorpusParserHydrator - codedeploy-group-name: UserListSearch-Dev-CorpusParserHydrator - function-name: UserListSearch-Dev-CorpusParserHydrator - s3-bucket: pocket-userlistsearch-dev-kinesis-consumer - s3-key: corpus-parser-hydration-$CIRCLE_SHA1.zip - requires: - - user-list-search_corpus-parser-hydration_build_lambda_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: user-list-search_sentry-release-notification-dev - context: pocket - for: user_list_search - sentry_project_name: user-list-search - sentry_env: development - sentry_org: pocket - requires: - - user-list-search_code_deploy_ecs_dev - - user-list-search_events_code_deploy_lambda_dev - - user-list-search_kinesis_code_deploy_lambda_dev - - user-list-search_item-update_code_deploy_lambda_dev - - user-list-search_item-delete_code_deploy_lambda_dev - - user-list-search_item-update-backfill_code_deploy_lambda_dev - - user-list-search_user-list-import_code_deploy_lambda_dev - - user-list-search_user-list-import-backfill_code_deploy_lambda_dev - - user-list-search_corpus-indexing_code_deploy_lambda_dev - - user-list-search_corpus-parser-hydration_code_deploy_lambda_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_infrastructure_apply_prod - scope: user-list-search-cdk - stack-output-path: infrastructure/user-list-search - resource-class: pocket/default-prod - apply: true - dev: false - uses_raw_hcl: true - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: userlistsearch-prod - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=user-list-search --build-arg APP_PATH=servers/user-list-search --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=user-list-search --build-arg PORT=4000 - requires: - - user-list-search_infrastructure_apply_prod - - - build_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_events_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: user-list-search-events - sentry_project_name: user-list-search - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: events-$CIRCLE_SHA1.zip - requires: - - user-list-search_infrastructure_apply_prod - - - build_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_kinesis_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: user-list-search-kinesis-to-sqs - sentry_project_name: user-list-search - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: kinesis-$CIRCLE_SHA1.zip - requires: - - user-list-search_infrastructure_apply_prod - - - build_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_indexing_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: user-list-search-indexing - sentry_project_name: user-list-search - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_infrastructure_apply_prod - - - - build_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_corpus-indexing_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: user-list-search-corpus-indexing - sentry_project_name: user-list-search - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: corpus-indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_infrastructure_apply_prod - - - build_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_corpus-parser-hydration_build_lambda_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - scope: user-list-search-corpus-parser-hydration - sentry_project_name: user-list-search - sentry_env: production - sentry_org: pocket - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: corpus-parser-hydration-$CIRCLE_SHA1.zip - requires: - - user-list-search_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - user-list-search_build_docker_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_events_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: UserListSearch-Prod-EventHandler - codedeploy-group-name: UserListSearch-Prod-EventHandler - function-name: UserListSearch-Prod-EventHandler - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: events-$CIRCLE_SHA1.zip - requires: - - user-list-search_events_build_lambda_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_kinesis_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: UserListSearch-Prod-UnifiedEventsConsumer - codedeploy-group-name: UserListSearch-Prod-UnifiedEventsConsumer - function-name: UserListSearch-Prod-UnifiedEventsConsumer - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: kinesis-$CIRCLE_SHA1.zip - requires: - - user-list-search_kinesis_build_lambda_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_item-update_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: UserListSearch-Prod-ItemUpdate - codedeploy-group-name: UserListSearch-Prod-ItemUpdate - function-name: UserListSearch-Prod-ItemUpdate - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_indexing_build_lambda_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_item-delete_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: UserListSearch-Prod-ItemDelete - codedeploy-group-name: UserListSearch-Prod-ItemDelete - function-name: UserListSearch-Prod-ItemDelete - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_indexing_build_lambda_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_item-update-backfill_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: UserListSearch-Prod-ItemUpdateBackfill - codedeploy-group-name: UserListSearch-Prod-ItemUpdateBackfill - function-name: UserListSearch-Prod-ItemUpdateBackfill - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_indexing_build_lambda_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_user-list-import_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: UserListSearch-Prod-UserListImport - codedeploy-group-name: UserListSearch-Prod-UserListImport - function-name: UserListSearch-Prod-UserListImport - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_indexing_build_lambda_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_user-list-import-backfill_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: UserListSearch-Prod-UserListImportBackfill - codedeploy-group-name: UserListSearch-Prod-UserListImportBackfill - function-name: UserListSearch-Prod-UserListImportBackfill - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_indexing_build_lambda_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_corpus-indexing_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: UserListSearch-Prod-CorpusIndexer - codedeploy-group-name: UserListSearch-Prod-CorpusIndexer - function-name: UserListSearch-Prod-CorpusIndexer - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: corpus-indexing-$CIRCLE_SHA1.zip - requires: - - user-list-search_corpus-indexing_build_lambda_prod - - - code_deploy_lambda: - <<: *only_main - context: pocket - for: user_list_search - name: user-list-search_corpus-parser-hydration_code_deploy_lambda_prod - resource-class: pocket/default-prod - codedeploy-app-name: UserListSearch-Prod-CorpusParserHydrator - codedeploy-group-name: UserListSearch-Prod-CorpusParserHydrator - function-name: UserListSearch-Prod-CorpusParserHydrator - s3-bucket: pocket-userlistsearch-prod-kinesis-consumer - s3-key: corpus-parser-hydration-$CIRCLE_SHA1.zip - requires: - - user-list-search_corpus-parser-hydration_build_lambda_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: user-list-search_sentry-release-notification-prod - context: pocket - for: user_list_search - sentry_project_name: user-list-search - sentry_env: production - sentry_org: pocket - requires: - - user-list-search_code_deploy_ecs_prod - - user-list-search_events_code_deploy_lambda_prod - - user-list-search_kinesis_code_deploy_lambda_prod - - user-list-search_item-update_code_deploy_lambda_prod - - user-list-search_item-delete_code_deploy_lambda_prod - - user-list-search_item-update-backfill_code_deploy_lambda_prod - - user-list-search_user-list-import_code_deploy_lambda_prod - - user-list-search_user-list-import-backfill_code_deploy_lambda_prod - - user-list-search_corpus-indexing_code_deploy_lambda_prod - - user-list-search_corpus-parser-hydration_code_deploy_lambda_prod diff --git a/.circleci/v3-proxy-api.yml b/.circleci/v3-proxy-api.yml deleted file mode 100644 index e7e69ab97..000000000 --- a/.circleci/v3-proxy-api.yml +++ /dev/null @@ -1,142 +0,0 @@ - -workflows: - v3-proxy-api: - jobs: - - ###### - # Every PR Jobs - ###### - - test_integrations: - <<: *not_dev_main - for: v3_proxy_api - context: pocket - name: v3-proxy-api_test_integrations - scope: v3-proxy-api - - # Try building the ECS docker image on each branch - - build_image: - <<: *not_dev_main - context: pocket - for: v3_proxy_api - name: v3-proxy-api_build_docker - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: v3proxyapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: false - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=v3-proxy-api --build-arg APP_PATH=servers/v3-proxy-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=v3-proxy-api --build-arg PORT=4030 - - - infrastructure: - <<: *not_dev_main - context: pocket - for: v3_proxy_api - name: v3-proxy-api_infrastructure_plan_prod - scope: v3-proxy-api-cdk - stack-output-path: infrastructure/v3-proxy-api/cdktf.out/stacks/v3-proxy-api - resource-class: pocket/default-prod - dev: false - apply: false - - ###### - # Dev Branch Deployment (Dev Environment) - ###### - - - infrastructure: - <<: *only_dev - context: pocket - for: v3_proxy_api - name: v3-proxy-api_infrastructure_apply_dev - scope: v3-proxy-api-cdk - stack-output-path: infrastructure/v3-proxy-api/cdktf.out/stacks/v3-proxy-api - resource-class: pocket/default-dev - apply: true - dev: true - - # Build & Deploy the Dev Docker Image - - build_image: - <<: *only_dev - context: pocket - for: v3_proxy_api - name: v3-proxy-api_build_docker_dev - aws-access-key-id: Dev_AWS_ACCESS_KEY - aws-secret-access-key: Dev_AWS_SECRET_ACCESS_KEY - aws-region: Dev_AWS_DEFAULT_REGION - repo-name: v3proxyapi-dev-app - ecr-url: 410318598490.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=v3-proxy-api --build-arg APP_PATH=servers/v3-proxy-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=v3-proxy-api --build-arg PORT=4030 - requires: - - v3-proxy-api_infrastructure_apply_dev - - - code_deploy_ecs: - <<: *only_dev - context: pocket - for: v3_proxy_api - name: v3-proxy-api_code_deploy_ecs_dev - resource-class: pocket/default-dev - requires: - - v3-proxy-api_build_docker_dev - - # Notify sentry of dev deployment - - sentry_release_notification: - <<: *only_dev - name: v3-proxy-api_sentry-release-notification-dev - context: pocket - for: v3_proxy_api - sentry_project_name: v3-proxy-api - sentry_env: development - sentry_org: pocket - requires: - - v3-proxy-api_code_deploy_ecs_dev - - ###### - # Main Branch Deployment (Prod Environment) - ###### - - infrastructure: - <<: *only_main - context: pocket - for: v3_proxy_api - name: v3-proxy-api_infrastructure_apply_prod - scope: v3-proxy-api-cdk - stack-output-path: infrastructure/v3-proxy-api/cdktf.out/stacks/v3-proxy-api - resource-class: pocket/default-prod - apply: true - dev: false - - # Build & Deploy the Prod Docker Image - - build_image: - <<: *only_main - context: pocket - for: v3_proxy_api - name: v3-proxy-api_build_docker_prod - aws-access-key-id: Prod_AWS_ACCESS_KEY - aws-secret-access-key: Prod_AWS_SECRET_ACCESS_KEY - aws-region: Prod_AWS_DEFAULT_REGION - repo-name: v3proxyapi-prod-app - ecr-url: 996905175585.dkr.ecr.us-east-1.amazonaws.com - push: true - extra-build-args: --build-arg GIT_SHA=${CIRCLE_SHA1} --build-arg SCOPE=v3-proxy-api --build-arg APP_PATH=servers/v3-proxy-api --build-arg SENTRY_AUTH_TOKEN=${SENTRY_BEARER} --build-arg SENTRY_ORG=pocket --build-arg SENTRY_PROJECT=v3-proxy-api --build-arg PORT=4030 - requires: - - v3-proxy-api_infrastructure_apply_prod - - - code_deploy_ecs: - <<: *only_main - context: pocket - for: v3_proxy_api - name: v3-proxy-api_code_deploy_ecs_prod - resource-class: pocket/default-prod - requires: - - v3-proxy-api_build_docker_prod - - # Notify sentry of main deployment - - sentry_release_notification: - <<: *only_main - name: v3-proxy-api_sentry-release-notification-prod - context: pocket - for: v3_proxy_api - sentry_project_name: v3-proxy-api - sentry_env: production - sentry_org: pocket - requires: - - v3-proxy-api_code_deploy_ecs_prod diff --git a/.github/actions/build-lambda/action.yml b/.github/actions/build-lambda/action.yml new file mode 100644 index 000000000..399c7ad39 --- /dev/null +++ b/.github/actions/build-lambda/action.yml @@ -0,0 +1,86 @@ +name: 'Re-usable Lambda Build and Upload Flow' +description: 'Used to setup and build a docker image' +inputs: + scope: + description: 'Turbo Repo scope to run the build for' + required: true + sentry-org: + description: 'The org name used in sentry. Used to upload source maps' + required: false + default: pocket + sentry-project: + description: 'The project name used in sentry. Used to upload source maps' + required: false + default: '' + sentry-token: + description: 'The token used for sentry. Used to upload source maps' + required: true + s3-bucket: + description: 'The s3 bucket to upload to' + required: false + default: '' + s3-key: + description: 'The s3 bucket key to upload to' + required: false + default: '' +runs: + using: 'composite' + steps: + - name: Install pnpm & node + uses: pocket/pocket-monorepo/.github/actions/install-pnpm-and-node@main + with: + scope: ${{ inputs['scope'] }} + # Theres a really annoying bug in PNPM deploy command that will try and create a folder at /home/pruned which we are not allowed to do, + # so we move it under 1 directory to let it do its thing. + # https://github.com/pnpm/pnpm/issues/5086 + - name: Build lambda + shell: bash + run: | + pnpm run build --filter=${{inputs.scope}}... + mkdir -p ~/bug/project + cp -R . ~/bug/project/ + cd ~/bug/project/ + pnpm deploy --filter=${{inputs.scope}} --prod pruned + - name: Upload Sentry Source maps + if: inputs.sentry-project != '' + shell: bash + run: | + cd ~/bug/project/ + pnpx @sentry/cli sourcemaps inject pruned/dist + pnpx @sentry/cli sourcemaps upload pruned/dist --release ${{ github.sha }} --auth-token ${{ inputs.sentry-token }} --org ${{ inputs.sentry-org }} --project ${{ inputs.sentry-project }} + - name: Package Lambda + shell: bash + run: | + cd ~/bug/project/pruned + cp -r package.json dist/ + cp -r node_modules/ dist/node_modules/ + + cd dist + zip --symlinks -r9 ~/${{ github.sha }}.zip . + cd .. + maxFileSize=256000 # Get the size of the directory in kilobytes + export dirSize=$(du -s dist | cut -f1) + echo "Size is: $dirSize" + if ((dirSize > maxFileSize)); then + echo "Directory size is equal to or larger than $maxFileSize KB. which is the lambda limit" + exit 1 + fi + - name: Upload to S3 + if: inputs.s3-bucket != '' + shell: bash + run: | + s3Key="${{inputs.s3-key}}" + if [[ -z $s3Key ]]; then + s3Key="${{ github.sha }}.zip" + fi + aws s3 cp ~/${{ github.sha }}.zip s3://${{inputs.s3-bucket}}/${s3Key} + - uses: actions/upload-artifact@v4 + if: inputs.s3-key == '' + with: + name: ${{inputs.scope}} + path: ~/${{ github.sha }}.zip + - uses: actions/upload-artifact@v4 + if: inputs.s3-key != '' + with: + name: ${{ inputs.s3-key }} + path: ~/${{ github.sha }}.zip \ No newline at end of file diff --git a/.github/actions/cdktf/action.yml b/.github/actions/cdktf/action.yml new file mode 100644 index 000000000..52c6fb973 --- /dev/null +++ b/.github/actions/cdktf/action.yml @@ -0,0 +1,95 @@ +name: 'Execute CDKTF' +description: 'Builds and either plans or applies a CDKTF environment' +inputs: + scope: + description: 'Turbo Repo scope to run the build for' + required: true + stack-output-path: + description: 'The path where CDKTF outputs the terraform json' + required: true + environment: + description: 'The node environment to build for' + required: true + default: 'development' + behavior: + description: The behavior that Terraform should use, either plan or apply + required: true + pagerduty-token: + description: Pagerduty Token to use in terraform + required: true + terraform-token: + description: Terraform Token to use in terraform + required: true + github-token: + description: Github Token to use for terraform comment + required: true + +runs: + using: 'composite' + steps: + - name: Install tfenv + shell: bash + run: | + git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv + echo "PATH=$HOME/.tfenv/bin:$PATH" >> $GITHUB_ENV + + # Setup Terraform Comment + - uses: shmokmt/actions-setup-tfcmt@v2 + + # Let's tell github actions we want to cache all the terraform verisons we install. + # We do this to speed up terraform installing, as the cache will cache the terraform versions we download. + - name: Cache tfenv installations + uses: actions/cache@v4 + with: + path: | + ~/.tfenv/versions + key: ${{ runner.os }}-tfenv-${{ hashFiles('**/.terraform-version') }} + restore-keys: | + ${{ runner.os }}-tfenv- + + - name: Install pnpm & node + uses: pocket/pocket-monorepo/.github/actions/install-pnpm-and-node@main + with: + scope: ${{ inputs['scope'] }} + + - name: Build CDKTF + shell: bash + run: | + export NODE_ENV=${{ inputs['environment'] }} + pnpm run synth --filter=${{ inputs['scope'] }}... + + - name: Init Terraform + shell: bash + run: | + cd ${{ inputs['stack-output-path'] }} + tfenv install + tfenv use + terraform init + - name: Save off terraform token + shell: bash + env: + TERRAFORM_TOKEN: ${{ inputs.terraform-token }} + run: | + rc="credentials \"app.terraform.io\" { " + rc="${rc} token=\"$TERRAFORM_TOKEN\" " + rc="${rc}}" + echo "$rc" > ~/.terraformrc + + # Once TFCMT supports no change applies, change terraform apply to + # tfcmt --var target:${{ inputs.scope }}-${{ inputs.environment }} apply -- terraform apply -auto-approve -lock-timeout=10m + # https://github.com/suzuki-shunsuke/tfcmt/issues/1184 + - name: Plan/Apply CDKTF + shell: bash + env: + TERRAFORM_TOKEN: ${{ inputs.pagerduty-token }} + GITHUB_TOKEN: ${{ inputs.github-token }} + PAGERDUTY_TOKEN: ${{ inputs.pagerduty-token }} + run: | + cd ${{ inputs.stack-output-path }} + if [ "${{ inputs.behavior }}" = "apply" ]; then + echo "Apply behavior specified, applying terraform configuration in ${{ inputs.environment }}." + terraform apply --auto-approve + else + echo "Plan behavior specified, planning terraform configuration in ${{ inputs.environment }}." + tfcmt --var target:${{ inputs.scope }}-${{ inputs.environment }} plan --skip-no-changes --patch -- terraform plan -lock-timeout=10m + fi diff --git a/.github/actions/containerize/action.yml b/.github/actions/containerize/action.yml new file mode 100644 index 000000000..52a2ff08b --- /dev/null +++ b/.github/actions/containerize/action.yml @@ -0,0 +1,88 @@ +name: 'Re-usable Docker Build Flow' +description: 'Used to setup and build a docker image' +inputs: + scope: + description: 'Turbo Repo scope to run the build for' + required: true + docker-repo-name: + description: 'Docker name of the repo .dkr.ecr.us-east-1.amazonaws.com/' + required: true + app-path: + description: 'The path of where the application is located in the monorepo ie servers/' + required: true + context: + description: 'The path of where to build from' + required: true + default: '.' + app-port: + description: 'The port the application runs on ie 4006' + required: true + sentry-org: + description: 'The org name used in sentry. Used to upload source maps' + required: false + default: pocket + sentry-project: + description: 'The project name used in sentry. Used to upload source maps' + required: true + sentry-token: + description: 'The token used for sentry. Used to upload source maps' + required: true + push: + description: Whether or not to push the image + required: true + default: 'false' + dockerhub-username: + description: Docker hub username + required: true + dockerhub-token: + description: Dockerhub Token + required: true + +outputs: + docker-image-name: + description: The full name with registry of the built docker image + value: ${{ steps.get-build-name.outputs.docker-image-name }} + +runs: + using: 'composite' + steps: + # can be useful if you want to add emulation support with QEMU to be able to build against more platforms. + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + # action will create and boot a builder using by default the docker-container driver. + # This is not required but recommended using it to be able to build multi-platform images, export cache, etc. + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ inputs.dockerhub-username }} + password: ${{ inputs.dockerhub-token }} + + - name: Login to Amazon ECR + if: inputs.push == 'true' + uses: aws-actions/amazon-ecr-login@v2 + + - name: Build docker image + id: docker-build-push + uses: docker/build-push-action@v6 + with: + push: ${{inputs.push}} + tags: ${{inputs.docker-repo-name}}:${{ github.sha }} + context: ${{ inputs.context }} + build-args: | + GIT_SHA=${{ github.sha }} + SCOPE=${{inputs.scope}} + APP_PATH=${{inputs.app-path}} + SENTRY_ORG=${{inputs.sentry-org}} + SENTRY_PROJECT=${{inputs.sentry-project}} + PORT=${{inputs.app-port}} + secrets: | + sentry_token=${{ inputs.sentry-token }} + - name: Output Build Name + id: get-build-name + shell: bash + run: | + echo "docker-image-name=${{inputs.docker-repo-name}}:${{ github.sha }}" >> $GITHUB_OUTPUT \ No newline at end of file diff --git a/.github/actions/ecs-codedeploy/action.yml b/.github/actions/ecs-codedeploy/action.yml new file mode 100644 index 000000000..f843fede5 --- /dev/null +++ b/.github/actions/ecs-codedeploy/action.yml @@ -0,0 +1,102 @@ +name: 'Re-usable ECS Codedeploy Flow' +description: 'Used to code deploy a docker image' +inputs: + terraform-output: + description: 'Output from Terraform in previous step used to get the ECS Service, Task Defintion' + required: true + docker-image-name: + required: true + description: Docker path/name of the image to deploy + name: + required: true + description: The name of the service to use with Github Deployments + +runs: + using: 'composite' + steps: + - name: Render Amazon ECS task definition + id: task-def + uses: aws-actions/amazon-ecs-render-task-definition@v1 + with: + task-definition-family: ${{ fromJSON(inputs.terraform-output).ecs-task-family.value }} + container-name: ${{ fromJSON(inputs.terraform-output).ecs-task-containerName.value }} + image: ${{ inputs.docker-image-name }} + - name: Render Amazon ECS App Spec + shell: bash + run: | + cat < appspec.json + { + "version": 0.0, + "Resources": [ + { + "TargetService": { + "Type": "AWS::ECS::Service", + "Properties": { + "TaskDefinition": "", + "LoadBalancerInfo": { + "ContainerName": "${{ fromJSON(inputs.terraform-output).ecs-task-containerName.value }}", + "ContainerPort": ${{ fromJSON(inputs.terraform-output).ecs-task-containerPort.value }} + } + } + } + } + ] + } + EOT + # Create the Deployment within Github for Status Monitoring + - uses: chrnorm/deployment-action@v2 + name: Create GitHub deployment + id: deployment + with: + token: ${{ github.token }} + environment-url: https://${{ fromJSON(inputs.terraform-output).ecs-application-url.value }} + environment: ${{ inputs.name }}${{ github.ref == 'refs/heads/dev' && '-dev' || '' }} + transient-environment: ${{ github.ref == 'refs/heads/main' && 'false' || 'true' }} + production-environment: ${{ github.ref == 'refs/heads/main' && 'true' || 'false' }} + initial-status: pending + + # Trigger CodeDeploy to start deploying + - name: Deploy to Amazon ECS + id: deploy-ecs + uses: aws-actions/amazon-ecs-deploy-task-definition@v2 + with: + task-definition: ${{ steps.task-def.outputs.task-definition }} + service: ${{ fromJSON(inputs.terraform-output).ecs-serviceName.value }} + cluster: ${{ fromJSON(inputs.terraform-output).ecs-clusterName.value }} + wait-for-service-stability: false + codedeploy-appspec: appspec.json + codedeploy-application: ${{ fromJSON(inputs.terraform-output).ecs-codedeploy-app.value }} + codedeploy-deployment-group: ${{ fromJSON(inputs.terraform-output).ecs-codedeploy-group.value }} + + # Now that we have our Deployment ID, lets use it to add the logs to the Github Deployment + - name: Add logs to deployment status + uses: chrnorm/deployment-status@v2 + with: + token: ${{ github.token }} + deployment-id: ${{ steps.deployment.outputs.deployment_id }} + state: 'in_progress' + ## NOTE: Hard coded to us-east 1 for now. + log-url: https://console.aws.amazon.com/codesuite/codedeploy/deployments/${{ steps.deploy-ecs.outputs.codedeploy-deployment-id }}?region=us-east-1 + + # Now lets Wait for ECS Blue/Green Deployment, so we can report on the status to Github after + # TODO: Discuss with @kschelonka if we want to have CI wait for codedeploy to finish, and if so should it still be 5 minute termination??? + # - name: Wait for blue instances to be ready + # uses: geekcell/github-action-aws-codedeploy-wait@v1.0.0 + # with: + # codedeploy-deployment-id: ${{ steps.deploy-ecs.outputs.codedeploy-deployment-id }} + + - name: Update deployment status (success) + if: success() + uses: chrnorm/deployment-status@v2 + with: + token: ${{ github.token }} + deployment-id: ${{ steps.deployment.outputs.deployment_id }} + state: 'success' + + - name: Update deployment status (failure) + if: failure() + uses: chrnorm/deployment-status@v2 + with: + token: ${{ github.token }} + deployment-id: ${{ steps.deployment.outputs.deployment_id }} + state: 'failure' \ No newline at end of file diff --git a/.github/actions/install-pnpm-and-node/action.yml b/.github/actions/install-pnpm-and-node/action.yml new file mode 100644 index 000000000..de239a555 --- /dev/null +++ b/.github/actions/install-pnpm-and-node/action.yml @@ -0,0 +1,33 @@ +name: 'Checkout & Install pnpm and node' +description: 'Install dependencies using pnpm' +inputs: + scope: + description: 'Package scope to use from turbo repo' + default: '' # Empty string as default value + required: false + +runs: + using: 'composite' + steps: + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + # Don't specify a pnpm version, to use the one defined in the top level package.json + run_install: false + - name: Install Node.js + uses: actions/setup-node@v4 + with: + # Use .nvmrc to determine our Node Version + node-version-file: '.nvmrc' + cache: 'pnpm' + + - name: Install dependencies + shell: bash + run: | + if [ -z "${{ inputs.scope }}" ]; then + echo "No scope provided. Using default behavior." + pnpm install --frozen-lockfile + else + echo "Scope provided: ${{ inputs.scope }}, only installing packages needed for it." + pnpm install --filter=${{inputs.scope}}... --frozen-lockfile + fi \ No newline at end of file diff --git a/.github/actions/lambda-codedeploy/action.yml b/.github/actions/lambda-codedeploy/action.yml new file mode 100644 index 000000000..503ece99e --- /dev/null +++ b/.github/actions/lambda-codedeploy/action.yml @@ -0,0 +1,67 @@ +name: 'Re-usable Lambda Codedeploy Flow' +description: 'Used to code deploy a lambda' +inputs: + codedeploy-app-name: + description: CodeDeploy app name + required: true + codedeploy-group-name: + description: CodeDeploy group name + required: true + function-name: + description: The name of the Lambda Function to deploy to + required: true + s3-bucket: + description: The name of the bucket to deploy from + required: true + s3-key: + description: The name of the s3 key that contains the code to deploy + default: "" + required: false + function-alias: + description: The name of the lambda alias to use + required: false + default: DEPLOYED + +runs: + using: 'composite' + steps: + - name: Codedeploy AWS Lambda + shell: bash + run: | + aws lambda wait function-updated --function-name '${{ inputs.function-name }}' + + s3Key="${{ inputs.s3-key }}" + if [[ -z $s3Key ]]; then + s3Key="${{ github.sha }}.zip" + fi + + aws lambda update-function-code \ + --function-name '${{ inputs.function-name }}' \ + --s3-bucket '${{ inputs.s3-bucket }}' \ + --s3-key "$s3Key" + + aws lambda wait function-updated --function-name '${{ inputs.function-name }}' + + NEW_ENVVARS=$(aws lambda get-function-configuration --function-name '${{ inputs.function-name }}' --query "Environment.Variables | merge(@, \`{\"GIT_SHA\":\"${{ github.sha }}\"}\`)") + aws lambda update-function-configuration --function-name '${{ inputs.function-name }}' --environment "{ \"Variables\": $NEW_ENVVARS }" + aws lambda wait function-updated --function-name '${{ inputs.function-name }}' + + versionId=$(aws lambda publish-version \ + --function-name '${{ inputs.function-name }}' | jq -r .Version) + + currentVersion=$(aws lambda get-alias \ + --function-name '${{ inputs.function-name }}' \ + --name DEPLOYED | jq -r .FunctionVersion) + + app_spec_content_string="{'version':0.0,'Resources':[{'${{ inputs.function-name }}':{'Type':'AWS::Lambda::Function','Properties':{'Name':'${{ inputs.function-name }}','Alias':'${{ inputs.function-alias }}','TargetVersion':'$versionId', 'CurrentVersion': '$currentVersion'}}}]}" + echo "$app_spec_content_string" + app_spec_content_sha256=$(echo -n "$app_spec_content_string" | shasum -a 256 | sed 's/ .*$//') + revision="revisionType=AppSpecContent,appSpecContent={content=\"$app_spec_content_string\",sha256=$app_spec_content_sha256}" + + aws lambda wait function-updated --function-name '${{ inputs.function-name }}' + + aws deploy create-deployment \ + --application-name="${{ inputs.codedeploy-app-name }}" \ + --deployment-group-name="${{ inputs.codedeploy-group-name }}" \ + --description="Triggered build ${{ github.sha }} from Github Actions" \ + --revision="$revision" \ No newline at end of file diff --git a/.github/actions/raw-terraform/action.yml b/.github/actions/raw-terraform/action.yml new file mode 100644 index 000000000..a69aea5ee --- /dev/null +++ b/.github/actions/raw-terraform/action.yml @@ -0,0 +1,96 @@ +name: 'Execute Raw Terraform' +description: 'Builds and either plans or applies a terraform environment' +inputs: + scope: + description: 'Turbo Repo scope to run the build for' + required: true + stack-output-path: + description: 'The path where CDKTF outputs the terraform json' + required: true + environment: + description: 'The node environment to build for' + required: true + default: 'development' + behavior: + description: The behavior that Terraform should use, either plan or apply + required: true + pagerduty-token: + description: Pagerduty Token to use in terraform + required: true + terraform-token: + description: Terraform Token to use in terraform + required: true + github-token: + description: Github Token to use for terraform comment + required: true + +runs: + using: 'composite' + steps: + - name: Install tfenv + shell: bash + run: | + git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv + echo "PATH=$HOME/.tfenv/bin:$PATH" >> $GITHUB_ENV + + # Setup Terraform Comment + - uses: shmokmt/actions-setup-tfcmt@v2 + + # Let's tell github actions we want to cache all the terraform verisons we install. + # We do this to speed up terraform installing, as the cache will cache the terraform versions we download. + - name: Cache tfenv installations + uses: actions/cache@v4 + with: + path: | + ~/.tfenv/versions + key: ${{ runner.os }}-tfenv-${{ hashFiles('**/.terraform-version') }} + restore-keys: | + ${{ runner.os }}-tfenv- + + - name: Copy Terraform Vars + shell: bash + run: | + cd ${{ inputs.stack-output-path }} + if [ "${{ inputs.environment }}" = "development" ]; then + echo "Development environment specified, copying development tf vars" + cp dev_backend.tfvars backend.tf + else + echo "Production environment specified, copying production tf vars" + cp prod_backend.tfvars backend.tf + fi + + - name: Init Terraform + shell: bash + run: | + cd ${{ inputs['stack-output-path'] }} + tfenv install + tfenv use + terraform init + - name: Save off terraform token + shell: bash + env: + TERRAFORM_TOKEN: ${{ inputs.terraform-token }} + run: | + rc="credentials \"app.terraform.io\" { " + rc="${rc} token=\"$TERRAFORM_TOKEN\" " + rc="${rc}}" + echo "$rc" > ~/.terraformrc + + # Once TFCMT supports no change applies, change terraform apply to + # tfcmt --var target:${{ inputs.scope }}-${{ inputs.environment }} apply -- terraform apply -auto-approve -lock-timeout=10m + # https://github.com/suzuki-shunsuke/tfcmt/issues/1184 + - name: Plan/Apply CDKTF + shell: bash + env: + TERRAFORM_TOKEN: ${{ inputs.pagerduty-token }} + GITHUB_TOKEN: ${{ inputs.github-token }} + PAGERDUTY_TOKEN: ${{ inputs.pagerduty-token }} + run: | + cd ${{ inputs.stack-output-path }} + if [ "${{ inputs.behavior }}" = "apply" ]; then + echo "Apply behavior specified, applying terraform configuration in ${{ inputs.environment }}." + terraform apply --auto-approve + else + echo "Plan behavior specified, planning terraform configuration in ${{ inputs.environment }}." + tfcmt --var target:${{ inputs.scope }}-${{ inputs.environment }} plan --skip-no-changes --patch -- terraform plan -lock-timeout=10m + fi diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 000000000..9b3b9ffe5 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,19 @@ +## Workflows + +This repository consists of the following workflows: + +* `pull-request.yml` - Ran on every single Pull Request and performs basic checks of the whole repo like Linting and Unit Tests +* `status-checks.yml` - Triggered on completion of other workflows and is used as the singluar Github Required Status check, since Github does not support Requiring Workflows that are skipped based on path filtering. Note: IF you add a new workflow it must be added to this array to be part of the Github Checks +* `.yml` - A workflow represnting a singluar service in the monorepo. + +There are also the following re-usable workflows: + +* `build-and-push-image.yml` - Used to either build & push a docker image to production/development or to just build on pull request +* `test-integrations.yml` - Used to run tests of a service against the `docker-compose.yml` environment. + +And then there are composite Github Actions: + +* `containerize` - Used to build a microservice into a docker image from our monorepo +* `install-pnpm-and-node` - Used to install PNPM and Node, and dependencies based on our `.nvmrc` and pnpm version in `package.json` + +All of the re-usable workflows and actions can be used by other repositories in the Pocket organization. diff --git a/.github/workflows/account-data-deleter.yml b/.github/workflows/account-data-deleter.yml new file mode 100644 index 000000000..ca711517a --- /dev/null +++ b/.github/workflows/account-data-deleter.yml @@ -0,0 +1,88 @@ +name: Account Data Deleter +on: + pull_request: + paths: + - 'infrastructure/account-data-deleter/**' + - 'packages/**' + - 'servers/account-data-deleter/**' + - 'lambdas/account-data-deleter-batch-delete/**' + - 'lambdas/account-data-deleter-events/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/account-data-deleter.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/account-data-deleter/**' + - 'packages/**' + - 'servers/account-data-deleter/**' + - 'lambdas/account-data-deleter-batch-delete/**' + - 'lambdas/account-data-deleter-events/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/account-data-deleter.yml' + - '.github/workflows/reuse-*.yml' +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: account-data-deleter + secrets: inherit + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: account-data-deleter-cdk + stack-output-path: infrastructure/account-data-deleter/cdktf.out/stacks/account-data-deleter + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: account-data-deleter + app-path: servers/account-data-deleter + app-port: 4015 + sentry-project: account-data-deleter + docker-repo-name-pattern: accountdatadeleter-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + events-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: account-data-deleter-events + sentry-project: account-data-deleter + s3-bucket-pattern: pocket-accountdatadeleter-{0}-sqs-event-consumer + codedeploy-app-name-pattern: AccountDataDeleter-{0}-Sqs-Event-Consumer-Lambda + codedeploy-group-name-pattern: AccountDataDeleter-{0}-Sqs-Event-Consumer-Lambda + function-name-pattern: AccountDataDeleter-{0}-Sqs-Event-Consumer-Function + secrets: inherit + + batch-delete-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: account-data-deleter-batch-delete + sentry-project: account-data-deleter + s3-bucket-pattern: pocket-accountdatadeleter-{0}-batchdeletelambda + codedeploy-app-name-pattern: AccountDataDeleter-{0}-BatchDeleteLambda-Lambda + codedeploy-group-name-pattern: AccountDataDeleter-{0}-BatchDeleteLambda-Lambda + function-name-pattern: AccountDataDeleter-{0}-BatchDeleteLambda-Function + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api, events-lambda, batch-delete-lambda] + with: + sentry-project: account-data-deleter + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit diff --git a/.github/workflows/account-delete-monitor.yml b/.github/workflows/account-delete-monitor.yml new file mode 100644 index 000000000..45d0a719d --- /dev/null +++ b/.github/workflows/account-delete-monitor.yml @@ -0,0 +1,60 @@ +name: Account Delete Monitor +on: + # Only run the tests for this service when any of the following file paths change + pull_request: + paths: + - 'infrastructure/account-delete-monitor/**' + - 'packages/**' + - 'lambdas/account-delete-monitor/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/account-delete-monitor.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/account-delete-monitor/**' + - 'packages/**' + - 'lambdas/account-delete-monitor/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/account-delete-monitor.yml' + - '.github/workflows/reuse-*.yml' +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: account-delete-monitor + secrets: inherit + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: account-delete-monitor-cdk + stack-output-path: infrastructure/account-delete-monitor/cdktf.out/stacks/account-delete-monitor + secrets: inherit + + + lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: account-delete-monitor + sentry-project: account-delete-monitor + s3-bucket-pattern: pocket-accountdeletemonitor-{0}-eventtracker + codedeploy-app-name-pattern: AccountDeleteMonitor-{0}-EventTracker-Lambda + codedeploy-group-name-pattern: AccountDeleteMonitor-{0}-EventTracker-Lambda + function-name-pattern: AccountDeleteMonitor-{0}-EventTracker-Function + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [lambda] + with: + sentry-project: account-delete-monitor + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit diff --git a/.github/workflows/annotations-api.yml b/.github/workflows/annotations-api.yml new file mode 100644 index 000000000..1ef03dfb0 --- /dev/null +++ b/.github/workflows/annotations-api.yml @@ -0,0 +1,87 @@ +name: Annotations API +on: + # Only run the tests for this service when any of the following file paths change + pull_request: + paths: + - 'infrastructure/annotations-api/**' + - 'packages/**' + - 'servers/annotations-api/**' + - 'lambdas/annotations-api-events/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/annotations-api.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/annotations-api/**' + - 'packages/**' + - 'servers/annotations-api/**' + - 'lambdas/annotations-api-events/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/annotations-api.yml' + - '.github/workflows/reuse-*.yml' +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: annotations-api + secrets: inherit + + apollo: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-client-api + graph-name: annotations-api + schema-file-path: servers/annotations-api/dist/schema-generated.graphql + prod-graph-url: https://annotations-api.readitlater.com + dev-graph-url: https://annotations-api.getpocket.dev + scope: annotations-api + secrets: + apollo-key: ${{ secrets.APOLLO_CLIENT_API_KEY }} + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: annotations-api-cdk + stack-output-path: infrastructure/annotations-api/cdktf.out/stacks/annotations-api + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: annotations-api + app-path: servers/annotations-api + app-port: 4008 + sentry-project: annotations-api + docker-repo-name-pattern: annotationsapi-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + events-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: annotations-api-events-lambda + sentry-project: annotations-api + s3-bucket-pattern: pocket-annotationsapi-{0}-sqs-event-consumer + codedeploy-app-name-pattern: AnnotationsAPI-{0}-Sqs-Event-Consumer-Lambda + codedeploy-group-name-pattern: AnnotationsAPI-{0}-Sqs-Event-Consumer-Lambda + function-name-pattern: AnnotationsAPI-{0}-Sqs-Event-Consumer-Function + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api, events-lambda] + with: + sentry-project: annotations-api + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit diff --git a/.github/workflows/braze-content-proxy.yml b/.github/workflows/braze-content-proxy.yml new file mode 100644 index 000000000..4d4e83887 --- /dev/null +++ b/.github/workflows/braze-content-proxy.yml @@ -0,0 +1,60 @@ +name: Braze Content Proxy +on: + pull_request: + paths: + - 'infrastructure/braze-content-proxy/**' + - 'packages/**' + - 'servers/braze-content-proxy/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/braze-content-proxy.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/braze-content-proxy/**' + - 'packages/**' + - 'servers/braze-content-proxy/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/braze-content-proxy.yml' + - '.github/workflows/reuse-*.yml' +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: braze-content-proxy + secrets: inherit + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: braze-content-proxy-cdk + stack-output-path: infrastructure/braze-content-proxy/cdktf.out/stacks/braze-content-proxy + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: braze-content-proxy + app-path: servers/braze-content-proxy + app-port: 4500 + sentry-project: braze-content-proxy + docker-repo-name-pattern: brazecontentproxy-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api] + with: + sentry-project: braze-content-proxy + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/braze.yml b/.github/workflows/braze.yml new file mode 100644 index 000000000..79d46c674 --- /dev/null +++ b/.github/workflows/braze.yml @@ -0,0 +1,29 @@ +name: Braze +on: + pull_request: + paths: + - 'infrastructure/braze/**' + - 'packages/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/braze.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/braze/**' + - 'packages/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/braze.yml' + - '.github/workflows/reuse-*.yml' +jobs: + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: braze-cdk + stack-output-path: infrastructure/braze/cdktf.out/stacks/braze + secrets: inherit diff --git a/.github/workflows/client-api.yml b/.github/workflows/client-api.yml new file mode 100644 index 000000000..6bd7b5905 --- /dev/null +++ b/.github/workflows/client-api.yml @@ -0,0 +1,42 @@ +name: Client API +on: + pull_request: + paths: + - 'infrastructure/client-api/**' + - 'packages/**' + - 'servers/client-api/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/client-api.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/client-api/**' + - 'packages/**' + - 'servers/client-api/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/client-api.yml' + - '.github/workflows/reuse-*.yml' +jobs: + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: client-api-cdk + stack-output-path: infrastructure/client-api/cdktf.out/stacks/client-api + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: client-api + docker-repo-name-pattern: clientapi-{0}-app + context: servers/client-api + app-path: servers/client-api + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/feature-flags.yml b/.github/workflows/feature-flags.yml new file mode 100644 index 000000000..4da0c136b --- /dev/null +++ b/.github/workflows/feature-flags.yml @@ -0,0 +1,64 @@ +name: Feature Flags +on: + pull_request: + paths: + - 'infrastructure/feature-flags/**' + - 'packages/**' + - 'servers/feature-flags/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/feature-flags.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/feature-flags/**' + - 'packages/**' + - 'servers/feature-flags/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/feature-flags.yml' + - '.github/workflows/reuse-*.yml' +jobs: + apollo: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-client-api + graph-name: featureflags + schema-file-path: servers/feature-flags/schema.graphql + prod-graph-url: https://featureflags.readitlater.com/graphql + dev-graph-url: https://featureflags.getpocket.dev/graphql + secrets: + apollo-key: ${{ secrets.APOLLO_CLIENT_API_KEY }} + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: feature-flags-cdk + stack-output-path: infrastructure/feature-flags/cdktf.out/stacks/feature-flags + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: feature-flags + app-path: servers/feature-flags + app-port: 4242 + sentry-project: feature-flags + docker-repo-name-pattern: featureflags-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api] + with: + sentry-project: feature-flags + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/fxa-webhook-proxy.yml b/.github/workflows/fxa-webhook-proxy.yml new file mode 100644 index 000000000..1dc62d1b5 --- /dev/null +++ b/.github/workflows/fxa-webhook-proxy.yml @@ -0,0 +1,67 @@ +name: FxA Webhook Proxy +on: + pull_request: + paths: + - 'infrastructure/fxa-webhook-proxy/**' + - 'packages/**' + - 'lambdas/fxa-webhook-proxy-gateway/**' + - 'lambdas/fxa-webhook-proxy-sqs/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/fxa-webhook-proxy.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/fxa-webhook-proxy/**' + - 'packages/**' + - 'lambdas/fxa-webhook-proxy-gateway/**' + - 'lambdas/fxa-webhook-proxy-sqs/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/fxa-webhook-proxy.yml' + - '.github/workflows/reuse-*.yml' +jobs: + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: fxa-webhook-proxy-cdk + stack-output-path: infrastructure/fxa-webhook-proxy/cdktf.out/stacks/fxa-webhook-proxy + secrets: inherit + + sqs-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: fxa-webhook-proxy-sqs + sentry-project: fxa-webhook-proxy + s3-bucket-pattern: pocket-fxawebhookproxy-{0}-sqs-fxa-events + codedeploy-app-name-pattern: FxAWebhookProxy-{0}-Sqs-FxA-Events-Lambda + codedeploy-group-name-pattern: FxAWebhookProxy-{0}-Sqs-FxA-Events-Lambda + function-name-pattern: FxAWebhookProxy-{0}-Sqs-FxA-Events-Function + secrets: inherit + + gateway-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: fxa-webhook-proxy-gateway + sentry-project: fxa-webhook-proxy + s3-bucket-pattern: pocket-fxawebhookproxy-{0}-apigateway-fxa-events + codedeploy-app-name-pattern: FxAWebhookProxy-{0}-ApiGateway-FxA-Events-Lambda + codedeploy-group-name-pattern: FxAWebhookProxy-{0}-ApiGateway-FxA-Events-Lambda + function-name-pattern: FxAWebhookProxy-{0}-ApiGateway-FxA-Events-Function + secrets: inherit + + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [sqs-lambda, gateway-lambda] + with: + sentry-project: annotations-api + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit diff --git a/.github/workflows/image-api.yml b/.github/workflows/image-api.yml new file mode 100644 index 000000000..a6eac16aa --- /dev/null +++ b/.github/workflows/image-api.yml @@ -0,0 +1,82 @@ +name: Image API +on: + pull_request: + paths: + - 'infrastructure/image-api/**' + - 'packages/**' + - 'servers/image-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/image-api.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/image-api/**' + - 'packages/**' + - 'servers/image-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/image-api.yml' + - '.github/workflows/reuse-*.yml' +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: image-api + secrets: inherit + + apollo: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-client-api + graph-name: image-api + schema-file-path: servers/image-api/schema.graphql + prod-graph-url: https://image-api.readitlater.com + dev-graph-url: https://image-api.getpocket.dev + secrets: + apollo-key: ${{ secrets.APOLLO_CLIENT_API_KEY }} + + apollo-admin: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-admin-api + graph-name: image-api + schema-file-path: servers/image-api/schema.graphql + prod-graph-url: https://image-api.readitlater.com + dev-graph-url: https://image-api.getpocket.dev + secrets: + apollo-key: ${{ secrets.APOLLO_ADMIN_API_KEY }} + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: image-api-cdk + stack-output-path: infrastructure/image-api/cdktf.out/stacks/image-api + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: image-api + app-path: servers/image-api + app-port: 4867 + sentry-project: image-api + docker-repo-name-pattern: imageapi-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api] + with: + sentry-project: image-api + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/instant-sync-events.yml b/.github/workflows/instant-sync-events.yml new file mode 100644 index 000000000..8accd7d56 --- /dev/null +++ b/.github/workflows/instant-sync-events.yml @@ -0,0 +1,52 @@ +name: Instant Sync Events +on: + pull_request: + paths: + - 'infrastructure/instant-sync-events/**' + - 'packages/**' + - 'lambdas/instant-sync-events/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/instant-sync-events.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/instant-sync-events/**' + - 'packages/**' + - 'lambdas/instant-sync-events/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/instant-sync-events.yml' + - '.github/workflows/reuse-*.yml' +jobs: + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: instant-sync-events-cdk + stack-output-path: infrastructure/instant-sync-events/cdktf.out/stacks/instant-sync-events + secrets: inherit + + lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: instant-sync-events + sentry-project: instant-sync-events + s3-bucket-pattern: pocket-instantsyncevents-{0}-eventtracker + codedeploy-app-name-pattern: InstantSyncEvents-{0}-EventTracker-Lambda + codedeploy-group-name-pattern: InstantSyncEvents-{0}-EventTracker-Lambda + function-name-pattern: InstantSyncEvents-{0}-EventTracker-Function + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [lambda] + with: + sentry-project: annotations-api + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit diff --git a/.github/workflows/list-api.yml b/.github/workflows/list-api.yml new file mode 100644 index 000000000..abf9022e7 --- /dev/null +++ b/.github/workflows/list-api.yml @@ -0,0 +1,74 @@ +name: List API +on: + pull_request: + paths: + - 'infrastructure/list-api/**' + - 'packages/**' + - 'servers/list-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/list-api.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/list-api/**' + - 'packages/**' + - 'servers/list-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/list-api.yml' + - '.github/workflows/reuse-*.yml' + + +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: list-api + secrets: inherit + + apollo: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-client-api + graph-name: list + schema-file-path: servers/list-api/dist/schema-generated.graphql + prod-graph-url: https://list-api.readitlater.com + dev-graph-url: https://list-api.getpocket.dev + scope: list-api + secrets: + apollo-key: ${{ secrets.APOLLO_CLIENT_API_KEY }} + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: list-api-cdk + stack-output-path: infrastructure/list-api/cdktf.out/stacks/list-api + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: list-api + app-path: servers/list-api + app-port: 4005 + sentry-project: list-api + docker-repo-name-pattern: listapi-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api] + with: + sentry-project: list-api + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/parser-graphql-wrapper.yml b/.github/workflows/parser-graphql-wrapper.yml new file mode 100644 index 000000000..21d8af51f --- /dev/null +++ b/.github/workflows/parser-graphql-wrapper.yml @@ -0,0 +1,82 @@ +name: Parser GraphQL Wrapper +on: + pull_request: + paths: + - 'infrastructure/parser-graphql-wrapper/**' + - 'packages/**' + - 'servers/parser-graphql-wrapper/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/parser-graphql-wrapper.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/parser-graphql-wrapper/**' + - 'packages/**' + - 'servers/parser-graphql-wrapper/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/parser-graphql-wrapper.yml' + - '.github/workflows/reuse-*.yml' +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: parser-graphql-wrapper + secrets: inherit + + apollo: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-client-api + graph-name: parser + schema-file-path: servers/parser-graphql-wrapper/schema.graphql + prod-graph-url: https://parser-graphql-wrapper.readitlater.com + dev-graph-url: https://parser-graphql-wrapper.getpocket.dev + secrets: + apollo-key: ${{ secrets.APOLLO_CLIENT_API_KEY }} + + apollo-admin: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-admin-api + graph-name: parser + schema-file-path: servers/parser-graphql-wrapper/schema-admin.graphql + prod-graph-url: https://parser-graphql-wrapper.readitlater.com + dev-graph-url: https://parser-graphql-wrapper.getpocket.dev + secrets: + apollo-key: ${{ secrets.APOLLO_ADMIN_API_KEY }} + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: parser-graphql-wrapper-cdk + stack-output-path: infrastructure/parser-graphql-wrapper/cdktf.out/stacks/parser-graphql-wrapper + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: parser-graphql-wrapper + app-path: servers/parser-graphql-wrapper + app-port: 4001 + sentry-project: parser-graphql-wrapper + docker-repo-name-pattern: parsergraphqlwrapper-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api] + with: + sentry-project: parser-graphql-wrapper + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/pocket-event-bridge.yml b/.github/workflows/pocket-event-bridge.yml new file mode 100644 index 000000000..8b0ac50f0 --- /dev/null +++ b/.github/workflows/pocket-event-bridge.yml @@ -0,0 +1,29 @@ +name: Pocket Event Bridge +on: + pull_request: + paths: + - 'infrastructure/pocket-event-bridge/**' + - 'packages/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/pocket-event-bridge.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/pocket-event-bridge/**' + - 'packages/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/pocket-event-bridge.yml' + - '.github/workflows/reuse-*.yml' +jobs: + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: pocket-event-bridge-cdk + stack-output-path: infrastructure/pocket-event-bridge/cdktf.out/stacks/pocket-event-bridge + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 91993fcf5..1417c5f3b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,6 +5,7 @@ on: pull_request: branches: ['main'] merge_group: + jobs: ## # Runs semantic release in a regular @@ -23,30 +24,18 @@ jobs: steps: - name: Check out code - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + uses: actions/checkout@v4 with: fetch-depth: 2 - - name: Setup Node.js environment - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4 - with: - node-version: 20.14 - registry-url: 'https://registry.npmjs.org' - - - name: PNPM Setup - uses: pnpm/action-setup@v4 - with: - version: 9.1.4 + - name: Install pnpm & node + uses: pocket/pocket-monorepo/.github/actions/install-pnpm-and-node@main - - name: Install dependencies - run: pnpm i - # Need to update sendgrid to enable this - # - name: Verify the integrity of provenance attestations and registry signatures for installed dependencies - # run: pnpm audit signatures - name: Semantic Release run: pnpm run semantic-release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{secrets.NPM_TOKEN}} # Need to update sendgrid to enable this # NPM_CONFIG_PROVENANCE: true diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 000000000..d64aeb07a --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,43 @@ +# A set of jobs that should always run no matter what on all Pull Requests in this repo +name: Pull Request +on: + pull_request: + +jobs: + check-packages: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install pnpm & node + uses: pocket/pocket-monorepo/.github/actions/install-pnpm-and-node@main + + - name: Check for mismatched dependencies + run: pnpm run list-mismatches + + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install pnpm & node + uses: pocket/pocket-monorepo/.github/actions/install-pnpm-and-node@main + + - name: Lint code + run: pnpm run lint + + unit-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install pnpm & node + uses: pocket/pocket-monorepo/.github/actions/install-pnpm-and-node@main + + - name: Unit tests + # Following uses a 2 concurrency because terraform modules seems to fail with an OOM error on CI if we do more. + run: pnpm run test --concurrency=2 \ No newline at end of file diff --git a/.github/workflows/push-server.yml b/.github/workflows/push-server.yml new file mode 100644 index 000000000..8910e1193 --- /dev/null +++ b/.github/workflows/push-server.yml @@ -0,0 +1,59 @@ +name: Push Server +on: + pull_request: + paths: + - 'infrastructure/push-server/**' + - 'packages/**' + - 'servers/push-server/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/push-server.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/push-server/**' + - 'packages/**' + - 'servers/push-server/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/push-server.yml' + - '.github/workflows/reuse-*.yml' +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: push-server + secrets: inherit + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: push-server-cdk + stack-output-path: infrastructure/push-server/cdktf.out/stacks/push-server + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: push-server + app-path: servers/push-server + sentry-project: push-server + docker-repo-name-pattern: push-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api] + with: + sentry-project: push-server + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/reuse-apollo-federation.yml b/.github/workflows/reuse-apollo-federation.yml new file mode 100644 index 000000000..63d8f83eb --- /dev/null +++ b/.github/workflows/reuse-apollo-federation.yml @@ -0,0 +1,79 @@ +# Runs Apollo rover schema check on the production graphql federated schema. +# If it is the production branch will deploy the subgraph to the production federated graph. +# If the branch is the development branch, will deploy the subgraph to the development federated graph. +name: 'Re-usable Apollo Studio Schema Workflow' +on: + workflow_call: + inputs: + federated-graph-name: + type: string + description: The name of federated graph to check + graph-name: + type: string + description: The name of this subgraph + schema-file-path: + type: string + description: The path to the schema file + default: ./schema.graphql + prod-graph-url: + type: string + description: The production subgraph url + dev-graph-url: + type: string + description: The development subgraph url + prod-graph-variant-name: + type: string + description: The production variant graph name + default: "current" + dev-graph-variant-name: + type: string + required: false + description: The development variant graph name + default: "development" + scope: + description: The pnpm scope to build for if we need to build before we push a schema + type: string + default: "" + secrets: + apollo-key: + description: The apollo studio key to use + required: true +jobs: + check-or-publish: + runs-on: ubuntu-latest + steps: + - name: Install rover + shell: bash + run: | + # download and install Rover + curl -sSL https://rover.apollo.dev/nix/latest | sh + + # This allows the PATH changes to persist to the next `run` step + echo "PATH=$HOME/.rover/bin:$PATH" >> "$GITHUB_ENV" + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install pnpm & node + if: ${{ inputs.scope != '' }} + uses: pocket/pocket-monorepo/.github/actions/install-pnpm-and-node@main + with: + scope: ${{ inputs['scope'] }} + - name: Build schema + if: ${{ inputs.scope != '' }} + shell: bash + run: pnpm run build --filter=${{ inputs.scope }}... + - name: Check Schema + if: github.event_name == 'pull_request' + shell: bash + run: | + rover subgraph check ${{ inputs.federated-graph-name }}@${{ inputs.prod-graph-variant-name }} --schema ${{ inputs.schema-file-path }} --name=${{ inputs.graph-name }} + env: + APOLLO_KEY: ${{ secrets.apollo-key }} + - name: Publish Schema + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + shell: bash + run: | + rover subgraph publish ${{ inputs.federated-graph-name }}@${{ github.ref == 'refs/heads/main' && inputs.prod-graph-variant-name || inputs.dev-graph-variant-name }} --schema ${{ inputs.schema-file-path }} --routing-url ${{ github.ref == 'refs/heads/main' && inputs.prod-graph-url || inputs.dev-graph-url }} --name=${{ inputs.graph-name }} + env: + APOLLO_KEY: ${{ secrets.apollo-key }} \ No newline at end of file diff --git a/.github/workflows/reuse-build-and-push-image.yml b/.github/workflows/reuse-build-and-push-image.yml new file mode 100644 index 000000000..c90deeef1 --- /dev/null +++ b/.github/workflows/reuse-build-and-push-image.yml @@ -0,0 +1,171 @@ +name: 'Re-usable Docker Build Flow' +on: + workflow_call: + inputs: + scope: + description: 'Turbo Repo scope to run the build for' + required: false + default: '' + type: string + docker-repo-name-pattern: + description: 'Docker name of the repo, usually: servicename-{0}-app. {0} is replaced with dev or prod' + required: true + type: string + development-aws-registry: + description: 'AWS Development Account Id' + type: string + default: 410318598490.dkr.ecr.us-east-1.amazonaws.com + production-aws-registry: + description: 'AWS Development Account Id' + type: string + default: 996905175585.dkr.ecr.us-east-1.amazonaws.com + context: + description: 'The path of where the application should be built from' + required: false + default: '.' + type: string + app-path: + description: 'The path of where the application is located in the monorepo ie servers/' + required: false + default: '' + type: string + app-port: + description: 'The port the application runs on ie 4006' + required: false + default: 80 + type: number + sentry-org: + description: 'The org name used in sentry. Used to upload source maps' + required: false + type: string + default: pocket + sentry-project: + description: 'The project name used in sentry. Used to upload source maps' + required: false + default: '' + type: string + terraform-output: + description: 'The terraform output which is used to get the ECS_Service and Task Defintion arns for codedeploy' + required: false + type: string + archive-download-name: + description: 'If specified, download this archive instead of checkout' + required: false + type: string + default: '' + +permissions: + contents: read # This is required for actions/checkout + id-token: write # Access the Github JWT for AWS access + deployments: write + +jobs: + # Let's build the image on every pull request just like we would on production + pull-request: + # Only run this job on a pull request event + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Checkout + if: inputs.archive-download-name == '' + uses: actions/checkout@v4 + - name: Archive download + if: inputs.archive-download-name != '' + uses: actions/download-artifact@v4 + with: + name: ${{inputs.archive-download-name}} + - name: Build Docker Image + uses: pocket/pocket-monorepo/.github/actions/containerize@main + with: + docker-repo-name: "${{inputs.development-aws-registry }}/${{ format(inputs.docker-repo-name-pattern, 'dev') }}" + app-path: ${{inputs.app-path}} + app-port: ${{inputs.app-port}} + context: ${{inputs.context}} + sentry-project: ${{inputs.sentry-project}} + sentry-org: ${{inputs.sentry-org}} + sentry-token: ${{secrets.SENTRY_BEARER}} + dockerhub-username: ${{secrets.DOCKERHUB_USERNAME}} + dockerhub-token: ${{secrets.DOCKERHUB_TOKEN}} + scope: ${{inputs.scope}} + + + development: + if: github.ref == 'refs/heads/dev' + runs-on: ubuntu-latest + steps: + - name: Checkout + if: inputs.archive-download-name == '' + uses: actions/checkout@v4 + - name: Archive download + if: inputs.archive-download-name != '' + uses: actions/download-artifact@v4 + with: + name: ${{inputs.archive-download-name}} + # Get the AWS credentials + - name: AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-east-1 + role-to-assume: arn:aws:iam::410318598490:role/PocketGHARole + - name: Build and Push Development Docker Image + id: dev-docker-build + uses: pocket/pocket-monorepo/.github/actions/containerize@main + with: + docker-repo-name: "${{inputs.development-aws-registry }}/${{ format(inputs.docker-repo-name-pattern, 'dev') }}" + app-path: ${{inputs.app-path}} + app-port: ${{inputs.app-port}} + context: ${{inputs.context}} + sentry-project: ${{inputs.sentry-project}} + sentry-org: ${{inputs.sentry-org}} + sentry-token: ${{secrets.SENTRY_BEARER}} + dockerhub-username: ${{secrets.DOCKERHUB_USERNAME}} + dockerhub-token: ${{secrets.DOCKERHUB_TOKEN}} + scope: ${{inputs.scope}} + push: true + - name: Code Deploy Docker Image + uses: pocket/pocket-monorepo/.github/actions/ecs-codedeploy@main + if: fromJSON(inputs.terraform-output).ecs-task-containerName.value != '' + with: + docker-image-name: ${{steps.dev-docker-build.outputs.docker-image-name}} + terraform-output: ${{ inputs.terraform-output }} + name: ${{inputs.scope}} + + production: + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - name: Checkout + if: inputs.archive-download-name == '' + uses: actions/checkout@v4 + - name: Archive download + if: inputs.archive-download-name != '' + uses: actions/download-artifact@v4 + with: + name: ${{inputs.archive-download-name}} + - name: AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-east-1 + role-to-assume: arn:aws:iam::996905175585:role/PocketGHARole + - name: Build and Push Production Docker Image + id: prod-docker-build + uses: pocket/pocket-monorepo/.github/actions/containerize@main + with: + docker-repo-name: "${{inputs.production-aws-registry }}/${{ format(inputs.docker-repo-name-pattern, 'prod') }}" + app-path: ${{inputs.app-path}} + app-port: ${{inputs.app-port}} + context: ${{inputs.context}} + sentry-project: ${{inputs.sentry-project}} + sentry-org: ${{inputs.sentry-org}} + sentry-token: ${{secrets.SENTRY_BEARER}} + dockerhub-username: ${{secrets.DOCKERHUB_USERNAME}} + dockerhub-token: ${{secrets.DOCKERHUB_TOKEN}} + scope: ${{inputs.scope}} + push: true + - name: Code Deploy Docker Image + uses: pocket/pocket-monorepo/.github/actions/ecs-codedeploy@main + if: fromJSON(inputs.terraform-output).ecs-task-containerName.value != '' + with: + docker-image-name: ${{steps.prod-docker-build.outputs.docker-image-name}} + terraform-output: ${{ inputs.terraform-output }} + name: ${{inputs.scope}} \ No newline at end of file diff --git a/.github/workflows/reuse-build-and-push-lambda.yml b/.github/workflows/reuse-build-and-push-lambda.yml new file mode 100644 index 000000000..8a3722cfb --- /dev/null +++ b/.github/workflows/reuse-build-and-push-lambda.yml @@ -0,0 +1,119 @@ +name: 'Re-usable Lambda Build Flow' +on: + workflow_call: + inputs: + scope: + description: 'Turbo Repo scope to run the build for' + required: true + type: string + s3-bucket-pattern: + description: 'Lambda S3 bucket pattern to use. {0} will be replaced with either dev or prod' + required: true + type: string + s3-key: + description: 'Lambda S3 key to use. Defaults to git sha' + required: false + default: '' + type: string + codedeploy-app-name-pattern: + description: CodeDeploy app name pattern to use. {0} will be replaced with either Dev or Prod' + required: true + type: string + codedeploy-group-name-pattern: + description: CodeDeploy group name pattern to use. {0} will be replaced with either Dev or Prod' + required: true + type: string + function-name-pattern: + description: The name pattern of the Lambda Function to deploy t. {0} will be replaced with either Dev or Prod' + required: true + type: string + sentry-org: + description: 'The org name used in sentry. Used to upload source maps' + required: false + type: string + default: pocket + sentry-project: + description: 'The project name used in sentry. Used to upload source maps' + required: true + type: string + +permissions: + contents: read # This is required for actions/checkout + id-token: write # Access the Github JWT for AWS access + + +jobs: + # Let's build the image on every pull request just like we would on production + pull-request: + # Only run this job on a pull request event + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build Lambda + uses: pocket/pocket-monorepo/.github/actions/build-lambda@main + with: + sentry-project: ${{inputs['sentry-project']}} + sentry-org: ${{inputs['sentry-org']}} + sentry-token: ${{secrets.SENTRY_BEARER}} + scope: ${{inputs['scope']}} + s3-key: ${{ inputs.s3-key }} + + development: + if: github.ref == 'refs/heads/dev' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-east-1 + role-to-assume: arn:aws:iam::410318598490:role/PocketGHARole + - name: Build Lambda + uses: pocket/pocket-monorepo/.github/actions/build-lambda@main + with: + sentry-project: ${{inputs['sentry-project']}} + sentry-org: ${{inputs['sentry-org']}} + sentry-token: ${{secrets.SENTRY_BEARER}} + scope: ${{inputs['scope']}} + s3-bucket: ${{ format(inputs.s3-bucket-pattern, 'dev') }} + s3-key: ${{ inputs.s3-key }} + - name: CodeDeploy Lambda + uses: pocket/pocket-monorepo/.github/actions/lambda-codedeploy@main + with: + s3-bucket: ${{ format(inputs.s3-bucket-pattern, 'dev') }} + s3-key: ${{ inputs.s3-key }} + codedeploy-app-name: ${{ format(inputs.codedeploy-app-name-pattern, 'Dev') }} + codedeploy-group-name: ${{ format(inputs.codedeploy-group-name-pattern, 'Dev') }} + function-name: ${{ format(inputs.function-name-pattern, 'Dev') }} + + production: + if: github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-east-1 + role-to-assume: arn:aws:iam::996905175585:role/PocketGHARole + - name: Build Lambda + uses: pocket/pocket-monorepo/.github/actions/build-lambda@main + with: + sentry-project: ${{inputs['sentry-project']}} + sentry-org: ${{inputs['sentry-org']}} + sentry-token: ${{secrets.SENTRY_BEARER}} + scope: ${{inputs['scope']}} + s3-bucket: ${{ format(inputs.s3-bucket-pattern, 'prod') }} + s3-key: ${{ inputs.s3-key }} + - name: CodeDeploy Lambda + uses: pocket/pocket-monorepo/.github/actions/lambda-codedeploy@main + with: + s3-bucket: ${{ format(inputs.s3-bucket-pattern, 'prod') }} + s3-key: ${{ inputs.s3-key }} + codedeploy-app-name: ${{ format(inputs.codedeploy-app-name-pattern, 'Prod') }} + codedeploy-group-name: ${{ format(inputs.codedeploy-group-name-pattern, 'Prod') }} + function-name: ${{ format(inputs.function-name-pattern, 'Prod') }} \ No newline at end of file diff --git a/.github/workflows/reuse-infrastructure.yml b/.github/workflows/reuse-infrastructure.yml new file mode 100644 index 000000000..8c3948417 --- /dev/null +++ b/.github/workflows/reuse-infrastructure.yml @@ -0,0 +1,142 @@ +name: 'Re-usable Infrastructure Workflow' +on: + workflow_call: + inputs: + scope: + description: 'Turbo Repo scope to run the build for' + required: false + type: string + stack-output-path: + description: 'The path where CDKTF outputs the terraform json' + required: false + type: string + raw-terraform: + description: 'Whether or not this service uses raw terraform' + required: false + default: false + type: boolean + outputs: + terraform-output: + description: "The output of terraform apply" + value: ${{ jobs.apply.outputs.terraform-output }} + +permissions: + pull-requests: write # Allow Terraform Comment to write to PRs + contents: read # This is required for actions/checkout + id-token: write # Access the Github JWT for AWS access + +jobs: + + plan: + # Only run this job on a pull request event + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Checkout Actions + uses: actions/checkout@v4 + # Get the AWS credentials + - name: AWS Credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-east-1 + role-to-assume: arn:aws:iam::996905175585:role/PocketGHARole + - name: Execute CDKTF + if: inputs.raw-terraform == false + uses: pocket/pocket-monorepo/.github/actions/cdktf@main + with: + stack-output-path: ${{inputs['stack-output-path']}} + scope: ${{inputs['scope']}} + environment: production + behavior: plan + github-token: ${{ secrets.GITHUB_TOKEN }} + pagerduty-token: ${{ secrets.PAGERDUTY_TOKEN }} + terraform-token: ${{ secrets.TERRAFORM_TOKEN }} + + - name: Execute Raw Terraform + if: inputs.raw-terraform == true + uses: pocket/pocket-monorepo/.github/actions/raw-terraform@main + with: + stack-output-path: ${{inputs['stack-output-path']}} + scope: ${{inputs['scope']}} + environment: production + behavior: plan + github-token: ${{ secrets.GITHUB_TOKEN }} + pagerduty-token: ${{ secrets.PAGERDUTY_TOKEN }} + terraform-token: ${{ secrets.TERRAFORM_TOKEN }} + + apply: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + outputs: + terraform-output: ${{ steps.set_output.outputs.terraform-output }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Development AWS Credentials + if: github.ref == 'refs/heads/dev' + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-east-1 + role-to-assume: arn:aws:iam::410318598490:role/PocketGHARole + - name: Production AWS Credentials + if: github.ref == 'refs/heads/main' + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-region: us-east-1 + role-to-assume: arn:aws:iam::996905175585:role/PocketGHARole + - name: Execute Development CDKTF + if: inputs.raw-terraform == false && github.ref == 'refs/heads/dev' + uses: pocket/pocket-monorepo/.github/actions/cdktf@main + with: + stack-output-path: ${{inputs['stack-output-path']}} + scope: ${{inputs['scope']}} + environment: development + behavior: apply + github-token: ${{ secrets.GITHUB_TOKEN }} + pagerduty-token: ${{ secrets.PAGERDUTY_TOKEN }} + terraform-token: ${{ secrets.TERRAFORM_TOKEN }} + - name: Execute Developement Raw Terraform + if: inputs.raw-terraform == true && github.ref == 'refs/heads/dev' + uses: pocket/pocket-monorepo/.github/actions/raw-terraform@main + with: + stack-output-path: ${{inputs['stack-output-path']}} + scope: ${{inputs['scope']}} + environment: development + behavior: apply + github-token: ${{ secrets.GITHUB_TOKEN }} + pagerduty-token: ${{ secrets.PAGERDUTY_TOKEN }} + terraform-token: ${{ secrets.TERRAFORM_TOKEN }} + + - name: Execute Production CDKTF + if: inputs.raw-terraform == false && github.ref == 'refs/heads/main' + uses: pocket/pocket-monorepo/.github/actions/cdktf@main + with: + stack-output-path: ${{inputs['stack-output-path']}} + scope: ${{inputs['scope']}} + environment: production + behavior: apply + github-token: ${{ secrets.GITHUB_TOKEN }} + pagerduty-token: ${{ secrets.PAGERDUTY_TOKEN }} + terraform-token: ${{ secrets.TERRAFORM_TOKEN }} + + - name: Execute Production Raw Terraform + if: inputs.raw-terraform == true && github.ref == 'refs/heads/main' + uses: pocket/pocket-monorepo/.github/actions/raw-terraform@main + with: + stack-output-path: ${{inputs['stack-output-path']}} + scope: ${{inputs['scope']}} + environment: production + behavior: apply + github-token: ${{ secrets.GITHUB_TOKEN }} + pagerduty-token: ${{ secrets.PAGERDUTY_TOKEN }} + terraform-token: ${{ secrets.TERRAFORM_TOKEN }} + + - name: Set terraform output + id: set_output + run: | + echo "Grabbing Terraform Output" + cd ${{inputs['stack-output-path']}} + echo "terraform-output=$(terraform output -json | jq -c)" >> $GITHUB_OUTPUT + \ No newline at end of file diff --git a/.github/workflows/reuse-sentry-release.yml b/.github/workflows/reuse-sentry-release.yml new file mode 100644 index 000000000..4447587c8 --- /dev/null +++ b/.github/workflows/reuse-sentry-release.yml @@ -0,0 +1,35 @@ +name: 'Re-usable Sentry Release Workflow' +on: + workflow_call: + inputs: + sentry-project: + description: 'The sentry project name' + required: true + type: string + sentry-organization: + description: 'The sentry organization' + required: false + default: pocket + type: string + sentry-environment: + description: 'The sentry environment to release on' + required: false + default: pocket + type: string +jobs: + + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Create Sentry Release + uses: getsentry/action-release@v1 + env: + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_BEARER }} + SENTRY_ORG: ${{ inputs.sentry-organization }} + SENTRY_PROJECT: ${{ inputs.sentry-project }} + with: + environment: ${{ inputs.sentry-environment }} \ No newline at end of file diff --git a/.github/workflows/reuse-test-integrations.yml b/.github/workflows/reuse-test-integrations.yml new file mode 100644 index 000000000..1e5090dd7 --- /dev/null +++ b/.github/workflows/reuse-test-integrations.yml @@ -0,0 +1,45 @@ +name: 'Re-usable Test Integrations' +on: + workflow_call: + inputs: + scope: + description: 'Turbo Repo scope to run tests for' + required: true + type: string + +jobs: + # naming this main, so that when this is called in Github Actions UI it shows up as: + # Service/test-integrations/main + main: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + # Log into Docker Hub so we bypass any rate limits and can pull our private Snowplow Micro Image + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + # Kick off starting docker compose first, since it can take a bit and can run in the background + - name: Start Docker Compose services + run: docker compose up -d + + # While we wait for docker compose to be healthy we install node and needed packages for this service + - name: Install pnpm & node + uses: pocket/pocket-monorepo/.github/actions/install-pnpm-and-node@main + with: + scope: ${{ inputs['scope'] }} + + # Wait for the docker services we started earlier to all be healthy + # TODO: In the future, we should figure out how to pass a scope to the Localstack startup routine via docker compose (perhaps a docker env..), + # because right now this will init and wait for all the localstack services in use in this repo. + # in circleci, we had to do it all manually so we passed it in then. + - name: Wait for services to be healthy + run: docker compose up --wait + + # Let's run those integration tests! + - name: Run service integration tests + run: pnpm run test-integrations --filter=${{ inputs['scope'] }} \ No newline at end of file diff --git a/.github/workflows/sendgrid-data.yml b/.github/workflows/sendgrid-data.yml new file mode 100644 index 000000000..98882acd1 --- /dev/null +++ b/.github/workflows/sendgrid-data.yml @@ -0,0 +1,53 @@ +name: Sendgrid Data +on: + pull_request: + paths: + - 'infrastructure/sendgrid-data/**' + - 'packages/**' + - 'lambdas/sendgrid-data/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/sendgrid-data.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/sendgrid-data/**' + - 'packages/**' + - 'lambdas/sendgrid-data/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/sendgrid-data.yml' + - '.github/workflows/reuse-*.yml' + +jobs: + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: sendgrid-data-cdk + stack-output-path: infrastructure/sendgrid-data/cdktf.out/stacks/sendgrid-data + secrets: inherit + + + lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: sendgrid-data + sentry-project: sendgrid-data + s3-bucket-pattern: pocket-sendgriddata-{0}-apigateway + codedeploy-app-name-pattern: SendGridData-{0}-ApiGateway-Lambda + codedeploy-group-name-pattern: SendGridData-{0}-ApiGateway-Lambda + function-name-pattern: SendGridData-{0}-ApiGateway-Function + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [lambda] + with: + sentry-project: sendgrid-data + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit diff --git a/.github/workflows/shareable-lists-api.yml b/.github/workflows/shareable-lists-api.yml new file mode 100644 index 000000000..e398fba30 --- /dev/null +++ b/.github/workflows/shareable-lists-api.yml @@ -0,0 +1,97 @@ +name: Shareable Lists API +on: + pull_request: + paths: + - 'infrastructure/shareable-lists-api/**' + - 'packages/**' + - 'servers/shareable-lists-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/shareable-lists-api.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/shareable-lists-api/**' + - 'packages/**' + - 'servers/shareable-lists-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/shareable-lists-api.yml' + - '.github/workflows/reuse-*.yml' +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: shareable-lists-api + secrets: inherit + + apollo: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-client-api + graph-name: shareable-lists-api + schema-file-path: servers/shareable-lists-api/schema-client-api.graphql + prod-graph-url: https://shareablelistsapi.readitlater.com + dev-graph-url: https://shareablelistsapi.getpocket.dev + scope: shareable-lists-api + secrets: + apollo-key: ${{ secrets.APOLLO_CLIENT_API_KEY }} + + apollo-admin: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-admin-api + graph-name: shareable-lists-api + schema-file-path: servers/shareable-lists-api/schema-admin-api.graphql + prod-graph-url: https://shareablelistsapi.readitlater.com/admin + dev-graph-url: https://shareablelistsapi.getpocket.dev/admin + scope: shareable-lists-api + secrets: + apollo-key: ${{ secrets.APOLLO_ADMIN_API_KEY }} + + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: shareable-lists-api-cdk + stack-output-path: infrastructure/shareable-lists-api/cdktf.out/stacks/shareable-lists-api + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: shareable-lists-api + app-path: servers/shareable-lists-api + app-port: 4029 + sentry-project: shareable-lists-api + docker-repo-name-pattern: shareablelistsapi-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + events-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: shareable-lists-api-events-lambda + sentry-project: shareable-lists-api + s3-bucket-pattern: pocket-shareablelistsapi-{0}-sqs-event-consumer + codedeploy-app-name-pattern: ShareableListsApi-{0}-Sqs-Event-Consumer-Lambda + codedeploy-group-name-pattern: ShareableListsApi-{0}-Sqs-Event-Consumer-Lambda + function-name-pattern: ShareableListsApi-{0}-Sqs-Event-Consumer-Function + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api, events-lambda] + with: + sentry-project: shareable-lists-api + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/shared-snowplow-consumer.yml b/.github/workflows/shared-snowplow-consumer.yml new file mode 100644 index 000000000..d01098e31 --- /dev/null +++ b/.github/workflows/shared-snowplow-consumer.yml @@ -0,0 +1,61 @@ +name: Shared Snowplow Consumer +on: + pull_request: + paths: + - 'infrastructure/shared-snowplow-consumer/**' + - 'packages/**' + - 'servers/shared-snowplow-consumer/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/shared-snowplow-consumer.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/shared-snowplow-consumer/**' + - 'packages/**' + - 'servers/shared-snowplow-consumer/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/shared-snowplow-consumer.yml' + - '.github/workflows/reuse-*.yml' + +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: shared-snowplow-consumer + secrets: inherit + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: shared-snowplow-consumer-cdk + stack-output-path: infrastructure/shared-snowplow-consumer/cdktf.out/stacks/shared-snowplow-consumer + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: shared-snowplow-consumer + app-path: servers/shared-snowplow-consumer + app-port: 4015 + sentry-project: shared-snowplow-consumer + docker-repo-name-pattern: sharedsnowplowconsumer-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api] + with: + sentry-project: shareable-lists-api + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/shares-api.yml b/.github/workflows/shares-api.yml new file mode 100644 index 000000000..873720697 --- /dev/null +++ b/.github/workflows/shares-api.yml @@ -0,0 +1,73 @@ +name: Shares API +on: + pull_request: + paths: + - 'infrastructure/shares-api/**' + - 'packages/**' + - 'servers/shares-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/shares-api.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/shares-api/**' + - 'packages/**' + - 'servers/shares-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/shares-api.yml' + - '.github/workflows/reuse-*.yml' + +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: shares-api + secrets: inherit + + apollo: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-client-api + graph-name: shares-api + schema-file-path: servers/shares-api/dist/schema-generated.graphql + prod-graph-url: https://shares-api.readitlater.com + dev-graph-url: https://shares-api.getpocket.dev + scope: shares-api + secrets: + apollo-key: ${{ secrets.APOLLO_CLIENT_API_KEY }} + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: shares-api-cdk + stack-output-path: infrastructure/shares-api/cdktf.out/stacks/shares-api + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: shares-api + app-path: servers/shares-api + app-port: 4031 + sentry-project: shares-api + docker-repo-name-pattern: sharesapi-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api] + with: + sentry-project: shares-api + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/status-checks.yml b/.github/workflows/status-checks.yml new file mode 100644 index 000000000..062cfabb6 --- /dev/null +++ b/.github/workflows/status-checks.yml @@ -0,0 +1,19 @@ +## Note that since this workflow uses Workflow Run changes will only be reflected once it is on the default branch + +# Because we use conditional path filtering on all our workflows, but want to Require status checks to pass on Github, +# we use a special status check job that we can require and will do the checking for us. +# We also use this because re-usable workflows can not be targeted for Github Required Status Checks as of 8/15/2024 +name: Status Checks +on: + pull_request: + +jobs: + enforce-all-checks: + runs-on: ubuntu-latest + permissions: + checks: read + steps: + - name: GitHub Checks + uses: poseidon/wait-for-status-checks@v0.4.1 + with: + token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/transactional-emails.yml b/.github/workflows/transactional-emails.yml new file mode 100644 index 000000000..b0d2173df --- /dev/null +++ b/.github/workflows/transactional-emails.yml @@ -0,0 +1,52 @@ +name: Transactional Emails +on: + pull_request: + paths: + - 'infrastructure/transactional-emails/**' + - 'packages/**' + - 'lambdas/transactional-emails/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/transactional-emails.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/transactional-emails/**' + - 'packages/**' + - 'lambdas/transactional-emails/**' + - 'pnpm-lock.yaml' + - '.github/actions/**' + - '.github/workflows/transactional-emails.yml' + - '.github/workflows/reuse-*.yml' + +jobs: + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: transactional-emails-cdk + stack-output-path: infrastructure/transactional-emails/cdktf.out/stacks/transactional-emails + secrets: inherit + + lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: transactional-emails + sentry-project: transactional-emails + s3-bucket-pattern: pocket-transactionalemails-{0}-sqs-event-consumer + codedeploy-app-name-pattern: TransactionalEmails-{0}-Sqs-Event-Consumer-Lambda + codedeploy-group-name-pattern: TransactionalEmails-{0}-Sqs-Event-Consumer-Lambda + function-name-pattern: TransactionalEmails-{0}-Sqs-Event-Consumer-Function + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [lambda] + with: + sentry-project: transactional-emails + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit diff --git a/.github/workflows/user-api.yml b/.github/workflows/user-api.yml new file mode 100644 index 000000000..d97a16c7f --- /dev/null +++ b/.github/workflows/user-api.yml @@ -0,0 +1,81 @@ +name: User API +on: + # Only run the tests for this service when any of the following file paths change + pull_request: + paths: + - 'infrastructure/user-api/**' + - 'packages/**' + - 'servers/user-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/user-api.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/user-api/**' + - 'packages/**' + - 'servers/user-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/user-api.yml' + - '.github/workflows/reuse-*.yml' +jobs: + # Let's test the service against some real life and mocked docker services. + test-integrations: + # Only run this job on a pull request event + if: github.event_name == 'pull_request' + # Use our re-usable test integrations workflow which will use our docker compose file + uses: ./.github/workflows/reuse-test-integrations.yml + with: + # Only run the tests for our service + scope: user-api + # Ensure the re-usable workflow is allowed to access the secrets + secrets: inherit + + apollo: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-client-api + graph-name: user + schema-file-path: servers/user-api/schema.graphql + prod-graph-url: https://user-api.readitlater.com + dev-graph-url: https://user-api.getpocket.dev + secrets: + apollo-key: ${{ secrets.APOLLO_CLIENT_API_KEY }} + + # It's infrastructure time, run the infrastructure update commands + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: user-api-cdk + stack-output-path: infrastructure/user-api/cdktf.out/stacks/user-api + # Ensure the re-usable workflow is allowed to access the secrets + secrets: inherit + + # Let's try building and conidtionally pushing our docker image to the necessary account. + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: user-api + app-path: servers/user-api + app-port: 4006 + sentry-project: user-api + docker-repo-name-pattern: userapi-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + # Ensure the re-usable workflow is allowed to access the secrets + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api] + with: + sentry-project: user-api + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/user-list-search.yml b/.github/workflows/user-list-search.yml new file mode 100644 index 000000000..13430e4df --- /dev/null +++ b/.github/workflows/user-list-search.yml @@ -0,0 +1,202 @@ +name: User List Search +on: + pull_request: + paths: + - 'infrastructure/user-list-search/**' + - 'packages/**' + - 'servers/user-list-search/**' + - 'lambdas/user-list-search-*/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/user-list-search.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/user-list-search/**' + - 'packages/**' + - 'servers/user-list-search/**' + - 'lambdas/user-list-search-*/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/user-list-search.yml' + - '.github/workflows/reuse-*.yml' +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: user-list-search + secrets: inherit + + apollo: + uses: ./.github/workflows/reuse-apollo-federation.yml + with: + federated-graph-name: pocket-client-api + graph-name: user-list-search + schema-file-path: servers/user-list-search/dist/schema-generated.graphql + prod-graph-url: https://user-list-search.readitlater.com/graphql + dev-graph-url: https://user-list-search.getpocket.dev/graphql + scope: user-list-search + secrets: + apollo-key: ${{ secrets.APOLLO_CLIENT_API_KEY }} + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + raw-terraform: true + stack-output-path: infrastructure/user-list-search + scope: user-list-search + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: user-list-search + app-path: servers/user-list-search + app-port: 4000 + sentry-project: user-list-search + docker-repo-name-pattern: userlistsearch-{0} + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + events-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: user-list-search-events + sentry-project: user-list-search + s3-bucket-pattern: pocket-userlistsearch-{0}-kinesis-consumer + s3-key: events-${{ github.sha }}.zip + codedeploy-app-name-pattern: UserListSearch-{0}-EventHandler + codedeploy-group-name-pattern: UserListSearch-{0}-EventHandler + function-name-pattern: UserListSearch-{0}-EventHandler + secrets: inherit + + kinesis-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: user-list-search-kinesis-to-sqs + sentry-project: user-list-search + s3-bucket-pattern: pocket-userlistsearch-{0}-kinesis-consumer + s3-key: kinesis-${{ github.sha }}.zip + codedeploy-app-name-pattern: UserListSearch-{0}-UnifiedEventsConsumer + codedeploy-group-name-pattern: UserListSearch-{0}-UnifiedEventsConsumer + function-name-pattern: UserListSearch-{0}-UnifiedEventsConsumer + secrets: inherit + + item-update-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: user-list-search-indexing + sentry-project: user-list-search + s3-bucket-pattern: pocket-userlistsearch-{0}-kinesis-consumer + s3-key: item-update-${{ github.sha }}.zip + codedeploy-app-name-pattern: UserListSearch-{0}-ItemUpdate + codedeploy-group-name-pattern: UserListSearch-{0}-ItemUpdate + function-name-pattern: UserListSearch-{0}-ItemUpdate + secrets: inherit + + item-delete-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: user-list-search-indexing + sentry-project: user-list-search + s3-bucket-pattern: pocket-userlistsearch-{0}-kinesis-consumer + s3-key: item-delete-${{ github.sha }}.zip + codedeploy-app-name-pattern: UserListSearch-{0}-ItemDelete + codedeploy-group-name-pattern: UserListSearch-{0}-ItemDelete + function-name-pattern: UserListSearch-{0}-ItemDelete + secrets: inherit + + item-update-backfill-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: user-list-search-indexing + sentry-project: user-list-search + s3-bucket-pattern: pocket-userlistsearch-{0}-kinesis-consumer + s3-key: item-update-backfill-${{ github.sha }}.zip + codedeploy-app-name-pattern: UserListSearch-{0}-ItemUpdateBackfill + codedeploy-group-name-pattern: UserListSearch-{0}-ItemUpdateBackfill + function-name-pattern: UserListSearch-{0}-ItemUpdateBackfill + secrets: inherit + + user-list-import-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: user-list-search-indexing + sentry-project: user-list-search + s3-bucket-pattern: pocket-userlistsearch-{0}-kinesis-consumer + s3-key: user-list-import-${{ github.sha }}.zip + codedeploy-app-name-pattern: UserListSearch-{0}-UserListImport + codedeploy-group-name-pattern: UserListSearch-{0}-UserListImport + function-name-pattern: UserListSearch-{0}-UserListImport + secrets: inherit + + user-list-import-backfill-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: user-list-search-indexing + sentry-project: user-list-search + s3-bucket-pattern: pocket-userlistsearch-{0}-kinesis-consumer + s3-key: user-list-import-backfill-${{ github.sha }}.zip + codedeploy-app-name-pattern: UserListSearch-{0}-UserListImportBackfill + codedeploy-group-name-pattern: UserListSearch-{0}-UserListImportBackfill + function-name-pattern: UserListSearch-{0}-UserListImportBackfill + secrets: inherit + + corpus-indexing-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: user-list-search-corpus-indexing + sentry-project: user-list-search + s3-bucket-pattern: pocket-userlistsearch-{0}-kinesis-consumer + s3-key: corpus-indexing-${{ github.sha }}.zip + codedeploy-app-name-pattern: UserListSearch-{0}-CorpusIndexer + codedeploy-group-name-pattern: UserListSearch-{0}-CorpusIndexer + function-name-pattern: UserListSearch-{0}-CorpusIndexer + secrets: inherit + + corpus-parser-hydration-lambda: + uses: ./.github/workflows/reuse-build-and-push-lambda.yml + needs: [infrastructure] + with: + scope: user-list-search-corpus-parser-hydration + sentry-project: user-list-search + s3-bucket-pattern: pocket-userlistsearch-{0}-kinesis-consumer + s3-key: corpus-parser-hydration-${{ github.sha }}.zip + codedeploy-app-name-pattern: UserListSearch-{0}-CorpusParserHydrator + codedeploy-group-name-pattern: UserListSearch-{0}-CorpusParserHydrator + function-name-pattern: UserListSearch-{0}-CorpusParserHydrator + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: + - api + - events-lambda + - kinesis-lambda + - item-update-lambda + - item-delete-lambda + - item-update-backfill-lambda + - user-list-import-lambda + - user-list-import-backfill-lambda + - corpus-indexing-lambda + - corpus-parser-hydration-lambda + with: + sentry-project: user-list-search + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit diff --git a/.github/workflows/v3-proxy-api.yml b/.github/workflows/v3-proxy-api.yml new file mode 100644 index 000000000..6f00daef9 --- /dev/null +++ b/.github/workflows/v3-proxy-api.yml @@ -0,0 +1,60 @@ +name: V3 Proxy API +on: + pull_request: + paths: + - 'infrastructure/v3-proxy-api/**' + - 'packages/**' + - 'servers/v3-proxy-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/v3-proxy-api.yml' + - '.github/workflows/reuse-*.yml' + push: + branches: + - main + - dev + paths: + - 'infrastructure/v3-proxy-api/**' + - 'packages/**' + - 'servers/v3-proxy-api/**' + - 'pnpm-lock.yaml' + - 'Dockerfile' + - '.github/actions/**' + - '.github/workflows/v3-proxy-api.yml' + - '.github/workflows/reuse-*.yml' +jobs: + test-integrations: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reuse-test-integrations.yml + with: + scope: v3-proxy-api + secrets: inherit + + infrastructure: + uses: ./.github/workflows/reuse-infrastructure.yml + with: + scope: v3-proxy-api-cdk + stack-output-path: infrastructure/v3-proxy-api/cdktf.out/stacks/v3-proxy-api + secrets: inherit + + api: + uses: ./.github/workflows/reuse-build-and-push-image.yml + needs: [infrastructure] + with: + scope: v3-proxy-api + app-path: servers/v3-proxy-api + app-port: 4030 + sentry-project: v3-proxy-api + docker-repo-name-pattern: v3proxyapi-{0}-app + terraform-output: ${{needs.infrastructure.outputs.terraform-output}} + secrets: inherit + + sentry: + if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' + uses: ./.github/workflows/reuse-sentry-release.yml + needs: [api] + with: + sentry-project: v3-proxy-api + sentry-environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'development' }} + secrets: inherit \ No newline at end of file diff --git a/.nvmrc b/.nvmrc index 24f544994..9bdb657cd 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.15 \ No newline at end of file +20.16 \ No newline at end of file diff --git a/.syncpackrc b/.syncpackrc index 150fd0f81..f6fcd301a 100644 --- a/.syncpackrc +++ b/.syncpackrc @@ -18,7 +18,7 @@ "@aws-sdk/client-s3", "@aws-sdk/**" ], - "pinVersion": "3.609.0", + "pinVersion": "3.632.0", "label": "AWS SDK Dependencies should all have the same version (uses a specifc package as the first one for Renovate to latch to)" }, { @@ -26,7 +26,7 @@ "@sentry/node", "@sentry/**" ], - "pinVersion": "8.18.0", + "pinVersion": "8.27.0", "label": "Sentry Dependencies should all have the same version (uses a specifc package as the first one for Renovate to latch to)" }, { diff --git a/Dockerfile b/Dockerfile index 0cd82b7c3..50180f55b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,13 +5,12 @@ # Docker build step that creates our # base image used in all steps #---------------------------------------- -FROM node:20.15-alpine@sha256:34b7aa411056c85dbf71d240d26516949b3f72b318d796c26b57caaa1df5639a AS base +FROM node:20.16-alpine@sha256:eb8101caae9ac02229bd64c024919fe3d4504ff7f329da79ca60a04db08cef52 AS base ARG SCOPE ARG APP_PATH ARG PORT ARG GIT_SHA -ARG SENTRY_AUTH_TOKEN ARG SENTRY_ORG ARG SENTRY_PROJECT @@ -20,12 +19,12 @@ RUN apk add --no-cache curl ## Add turbo and pnpm to all followup builder images # Dockerfile -RUN corepack enable && corepack prepare pnpm@9.1.4 --activate +RUN corepack enable && corepack prepare pnpm@9.9.0 --activate # Enable `pnpm add --global` on Alpine Linux by setting # home location environment variable to a location already in $PATH # https://github.com/pnpm/pnpm/issues/784#issuecomment-1518582235 ENV PNPM_HOME=/usr/local/bin -RUN pnpm add -g turbo@1.13.4 +RUN pnpm add -g turbo@2.1.0 #---------------------------------------- # Docker build step that prunes down to @@ -36,7 +35,6 @@ ARG SCOPE ARG APP_PATH ARG PORT ARG GIT_SHA -ARG SENTRY_AUTH_TOKEN ARG SENTRY_ORG ARG SENTRY_PROJECT @@ -60,7 +58,6 @@ ARG SCOPE ARG APP_PATH ARG PORT ARG GIT_SHA -ARG SENTRY_AUTH_TOKEN ARG SENTRY_ORG ARG SENTRY_PROJECT @@ -95,7 +92,8 @@ RUN pnpx @sentry/cli sourcemaps inject pruned/dist RUN mv ./.prisma.tmp pruned/node_modules/.prisma | true # If sentry project was passed, upload the source maps -RUN if [ -n "$SENTRY_PROJECT" ] ; then pnpx @sentry/cli sourcemaps upload pruned/dist --release ${GIT_SHA} --auth-token ${SENTRY_AUTH_TOKEN} --org ${SENTRY_ORG} --project ${SENTRY_PROJECT} ; fi +RUN --mount=type=secret,id=sentry_token \ + if [ -n "$SENTRY_PROJECT" ] ; then pnpx @sentry/cli sourcemaps upload pruned/dist --release ${GIT_SHA} --auth-token $(cat /run/secrets/sentry_token) --org ${SENTRY_ORG} --project ${SENTRY_PROJECT} ; fi #---------------------------------------- # Docker build step that: @@ -118,9 +116,9 @@ RUN chown -R nodejs:nodejs /app USER nodejs ENV NODE_ENV=production -ENV PORT $PORT +ENV PORT=${PORT} ENV GIT_SHA=${GIT_SHA} ENV RELEASE_SHA=${GIT_SHA} EXPOSE $PORT -CMD npm run start +CMD [ "npm", "run", "start" ] diff --git a/README.md b/README.md index 17c5049cb..d342a4af2 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,10 @@ pnpm build To develop all apps and packages, run the following commands: ```bash -cp .env.example .env cd pocket-monorepo +cp .env.example .env docker compose up --wait +pnpm install pnpm dev ``` @@ -60,9 +61,10 @@ This will bring up the docker shared services (MySQL, Memcached, Redis) and then To run a specific server, run the following: ```bash -cp .env.example .env cd pocket-monorepo +cp .env.example .env docker compose up --wait +pnpm install pnpm dev --filter=annotations-api... ``` @@ -125,3 +127,27 @@ Learn more about the power of Turborepo: - [Filtering](https://turbo.build/repo/docs/core-concepts/monorepos/filtering) - [Configuration Options](https://turbo.build/repo/docs/reference/configuration) - [CLI Usage](https://turbo.build/repo/docs/reference/command-line-reference) + +## Service CI Status + +[![Account Data Deleter](https://github.com/Pocket/pocket-monorepo/actions/workflows/account-data-deleter.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/account-data-deleter.yml) +[![Account Delete Monitor](https://github.com/Pocket/pocket-monorepo/actions/workflows/account-delete-monitor.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/account-delete-monitor.yml) +[![Annotations API](https://github.com/Pocket/pocket-monorepo/actions/workflows/annotations-api.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/annotations-api.yml) +[![Braze](https://github.com/Pocket/pocket-monorepo/actions/workflows/braze.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/braze.yml) +[![Client API](https://github.com/Pocket/pocket-monorepo/actions/workflows/client-api.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/client-api.yml) +[![Feature Flags](https://github.com/Pocket/pocket-monorepo/actions/workflows/feature-flags.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/feature-flags.yml) +[![FxA Webhook Proxy](https://github.com/Pocket/pocket-monorepo/actions/workflows/fxa-webhook-proxy.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/fxa-webhook-proxy.yml) +[![Image API](https://github.com/Pocket/pocket-monorepo/actions/workflows/image-api.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/image-api.yml) +[![Instant Sync Events](https://github.com/Pocket/pocket-monorepo/actions/workflows/instant-sync-events.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/instant-sync-events.yml) +[![List API](https://github.com/Pocket/pocket-monorepo/actions/workflows/list-api.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/list-api.yml) +[![Parser GraphQL Wrapper](https://github.com/Pocket/pocket-monorepo/actions/workflows/parser-graphql-wrapper.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/parser-graphql-wrapper.yml) +[![Pocket Event Bridge](https://github.com/Pocket/pocket-monorepo/actions/workflows/pocket-event-bridge.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/pocket-event-bridge.yml) +[![Push Server](https://github.com/Pocket/pocket-monorepo/actions/workflows/push-server.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/push-server.yml) +[![Sendgrid Data](https://github.com/Pocket/pocket-monorepo/actions/workflows/sendgrid-data.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/sendgrid-data.yml) +[![Shareable Lists API](https://github.com/Pocket/pocket-monorepo/actions/workflows/shareable-lists-api.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/shareable-lists-api.yml) +[![Shared Snowplow Consumer](https://github.com/Pocket/pocket-monorepo/actions/workflows/shared-snowplow-consumer.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/shared-snowplow-consumer.yml) +[![Shares API](https://github.com/Pocket/pocket-monorepo/actions/workflows/shares-api.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/shares-api.yml) +[![Transactional Emails](https://github.com/Pocket/pocket-monorepo/actions/workflows/transactional-emails.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/transactional-emails.yml) +[![User API](https://github.com/Pocket/pocket-monorepo/actions/workflows/user-api.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/user-api.yml) +[![User List Search](https://github.com/Pocket/pocket-monorepo/actions/workflows/user-list-search.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/user-list-search.yml) +[![V3 Proxy API](https://github.com/Pocket/pocket-monorepo/actions/workflows/v3-proxy-api.yml/badge.svg)](https://github.com/Pocket/pocket-monorepo/actions/workflows/v3-proxy-api.yml) diff --git a/docker-compose.yml b/docker-compose.yml index 3c689e609..3f96ef7ee 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,6 @@ -version: '3' services: ## Start Common Processes Config - # Note this is not the collector we use in Prod, but works for local testing - otlpcollector: - image: grafana/otel-lgtm - platform: linux/amd64 - environment: - OTEL_METRIC_EXPORT_INTERVAL: 1 - ports: - - 4317:4317 # OTLP gRPC receiver - - 4318:4318 # OTLP http receiver - - 3000:3000 # Grafana UI admin:admin, use localhost:3000 to view traces - + # Note this is not the collector we use in Prod, but works for local testing & github actions memcached: image: memcached:latest ports: @@ -90,10 +79,12 @@ services: - CMD - bash - -c - - curl --write-out '%{http_code}' --silent --output /dev/null http://localhost:4566/_localstack/health + # Wait for Localstack to have init'd all of our services: https://docs.localstack.cloud/references/init-hooks/ + - curl --silent --fail /dev/null http://localhost:4566/_localstack/init/ready | jq -e '.completed == true' > /dev/null || exit 1 interval: 5s timeout: 10s start_period: 10s + retries: 60 snowplow: image: pocket/snowplow-micro:dev diff --git a/infrastructure/account-data-deleter/package.json b/infrastructure/account-data-deleter/package.json index c4ebaa540..3458ed586 100644 --- a/infrastructure/account-data-deleter/package.json +++ b/infrastructure/account-data-deleter/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/account-data-deleter/src/dataDeleterApp.ts b/infrastructure/account-data-deleter/src/dataDeleterApp.ts index 1ede61781..def4b3ce7 100644 --- a/infrastructure/account-data-deleter/src/dataDeleterApp.ts +++ b/infrastructure/account-data-deleter/src/dataDeleterApp.ts @@ -87,14 +87,6 @@ export class DataDeleterApp extends Construct { { name: 'app', envVars: [ - { - name: 'AWS_XRAY_CONTEXT_MISSING', - value: 'IGNORE_ERROR', - }, - { - name: 'AWS_XRAY_LOG_LEVEL', - value: 'silent', - }, { name: 'DATABASE_READ_PORT', value: config.envVars.databasePort, diff --git a/infrastructure/account-delete-monitor/package.json b/infrastructure/account-delete-monitor/package.json index 268249ea2..580ad9046 100644 --- a/infrastructure/account-delete-monitor/package.json +++ b/infrastructure/account-delete-monitor/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/annotations-api/package.json b/infrastructure/annotations-api/package.json index b240aaa6a..e829df324 100644 --- a/infrastructure/annotations-api/package.json +++ b/infrastructure/annotations-api/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/annotations-api/src/main.ts b/infrastructure/annotations-api/src/main.ts index 235693f43..a38cb1ed7 100644 --- a/infrastructure/annotations-api/src/main.ts +++ b/infrastructure/annotations-api/src/main.ts @@ -210,10 +210,6 @@ class AnnotationsAPI extends TerraformStack { name: 'SQS_BATCH_DELETE_QUEUE_URL', value: `https://sqs.${region.name}.amazonaws.com/${caller.accountId}/${config.envVars.sqsBatchDeleteQueueName}`, }, - { - name: 'OTLP_COLLECTOR_HOST', - value: config.tracing.host, - }, ], logGroup: this.createCustomLogGroup('app'), logMultilinePattern: '^\\S.+', @@ -252,25 +248,6 @@ class AnnotationsAPI extends TerraformStack { }, ], }, - { - name: 'aws-otel-collector', - command: ['--config=/etc/ecs/ecs-xray.yaml'], - containerImage: 'amazon/aws-otel-collector', - essential: true, - logMultilinePattern: '^\\S.+', - logGroup: this.createCustomLogGroup('aws-otel-collector'), - portMappings: [ - { - hostPort: 4138, - containerPort: 4138, - }, - { - hostPort: 4137, - containerPort: 4137, - }, - ], - repositoryCredentialsParam: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/DockerHub`, - }, ], codeDeploy: { useCodeDeploy: true, diff --git a/infrastructure/braze-content-proxy/.terraform-version b/infrastructure/braze-content-proxy/.terraform-version new file mode 100644 index 000000000..fe4e75fb7 --- /dev/null +++ b/infrastructure/braze-content-proxy/.terraform-version @@ -0,0 +1 @@ +1.8.3 \ No newline at end of file diff --git a/infrastructure/braze-content-proxy/cdktf.json b/infrastructure/braze-content-proxy/cdktf.json new file mode 100644 index 000000000..c1d3f84a1 --- /dev/null +++ b/infrastructure/braze-content-proxy/cdktf.json @@ -0,0 +1,5 @@ +{ + "language": "typescript", + "app": "npm run --silent compile && node dist/main.js", + "projectId": "84da9c3f-9eea-4e71-890c-2c4d8f67d69e" +} \ No newline at end of file diff --git a/infrastructure/braze-content-proxy/eslint.config.mjs b/infrastructure/braze-content-proxy/eslint.config.mjs new file mode 100644 index 000000000..1f5684f1b --- /dev/null +++ b/infrastructure/braze-content-proxy/eslint.config.mjs @@ -0,0 +1,3 @@ +import cdktf from '@pocket-tools/eslint-config/cdktf'; +import tseslint from 'typescript-eslint'; +export default tseslint.config(...cdktf); diff --git a/infrastructure/braze-content-proxy/package.json b/infrastructure/braze-content-proxy/package.json new file mode 100644 index 000000000..9b4f0ff4c --- /dev/null +++ b/infrastructure/braze-content-proxy/package.json @@ -0,0 +1,33 @@ +{ + "name": "braze-content-proxy-cdk", + "version": "1.0.0", + "private": true, + "license": "MPL-2.0", + "main": "dist/main.js", + "types": "dist/main.ts", + "scripts": { + "build": "rm -rf dist && tsc", + "compile": "tsc --pretty", + "format": "eslint --fix", + "lint": "eslint --fix-dry-run", + "synth": "cdktf synth", + "watch": "tsc -w" + }, + "dependencies": { + "@cdktf/provider-aws": "19.31.0", + "@cdktf/provider-local": "10.1.0", + "@cdktf/provider-null": "10.0.0", + "@cdktf/provider-pagerduty": "13.11.4", + "@pocket-tools/terraform-modules": "workspace:*", + "cdktf": "0.20.8", + "cdktf-cli": "0.20.8", + "constructs": "10.3.0" + }, + "devDependencies": { + "@pocket-tools/eslint-config": "workspace:*", + "@types/node": "^20.16", + "ts-node": "10.9.2", + "tsconfig": "workspace:*", + "typescript": "5.5.4" + } +} diff --git a/infrastructure/braze-content-proxy/src/config/index.ts b/infrastructure/braze-content-proxy/src/config/index.ts new file mode 100644 index 000000000..65e463750 --- /dev/null +++ b/infrastructure/braze-content-proxy/src/config/index.ts @@ -0,0 +1,36 @@ +const name = 'BrazeContentProxy'; +const domainPrefix = 'braze-content-proxy'; +const isDev = process.env.NODE_ENV === 'development'; +const environment = isDev ? 'Dev' : 'Prod'; +const domain = isDev + ? `${domainPrefix}.getpocket.dev` + : `${domainPrefix}.getpocket.com`; + +export const config = { + name, + isDev, + prefix: `${name}-${environment}`, + circleCIPrefix: `/${name}/CircleCI/${environment}`, + shortName: 'BCP', + environment, + domain, + healthCheck: { + command: [ + 'CMD-SHELL', + 'curl -f http://localhost:4500/.well-known/server-health || exit 1', + ], + interval: 15, + retries: 3, + timeout: 5, + startPeriod: 0, + }, + tags: { + service: name, + environment, + owner: 'Pocket', + costCenter: 'Pocket', + app_code: 'pocket', + component_code: `pocket-${name.toLowerCase()}`, + env_code: isDev ? 'dev' : 'prod', + }, +}; diff --git a/infrastructure/braze-content-proxy/src/main.ts b/infrastructure/braze-content-proxy/src/main.ts new file mode 100644 index 000000000..3fec80059 --- /dev/null +++ b/infrastructure/braze-content-proxy/src/main.ts @@ -0,0 +1,198 @@ +import { Construct } from 'constructs'; +import { App, S3Backend, TerraformStack } from 'cdktf'; +import { + provider as awsProvider, + dataAwsCallerIdentity, + dataAwsRegion, + dataAwsKmsAlias, + dataAwsSnsTopic, +} from '@cdktf/provider-aws'; +import { config } from './config'; +import { PocketALBApplication } from '@pocket-tools/terraform-modules'; +import { provider as localProvider } from '@cdktf/provider-local'; +import { provider as nullProvider } from '@cdktf/provider-null'; +import { provider as pagerDutyProvider } from '@cdktf/provider-pagerduty'; +import * as fs from 'fs'; + +class BrazeContentProxy extends TerraformStack { + constructor(scope: Construct, name: string) { + super(scope, name); + + new awsProvider.AwsProvider(this, 'aws', { + region: 'us-east-1', + defaultTags: [{ tags: config.tags }], + }); + new pagerDutyProvider.PagerdutyProvider(this, 'pagerduty_provider', { + token: undefined, + }); + new localProvider.LocalProvider(this, 'local_provider'); + new nullProvider.NullProvider(this, 'null_provider'); + + new S3Backend(this, { + bucket: `mozilla-pocket-team-${config.environment.toLowerCase()}-terraform-state`, + dynamodbTable: `mozilla-pocket-team-${config.environment.toLowerCase()}-terraform-state`, + key: config.name, + region: 'us-east-1', + }); + + const region = new dataAwsRegion.DataAwsRegion(this, 'region'); + const caller = new dataAwsCallerIdentity.DataAwsCallerIdentity( + this, + 'caller', + ); + + this.createPocketAlbApplication({ + secretsManagerKmsAlias: this.getSecretsManagerKmsAlias(), + snsTopic: this.getCodeDeploySnsTopic(), + region, + caller, + }); + } + + /** + * Get the sns topic for code deploy + * @private + */ + private getCodeDeploySnsTopic() { + return new dataAwsSnsTopic.DataAwsSnsTopic(this, 'backend_notifications', { + name: `Backend-${config.environment}-ChatBot`, + }); + } + + /** + * Get secrets manager kms alias + * @private + */ + private getSecretsManagerKmsAlias() { + return new dataAwsKmsAlias.DataAwsKmsAlias(this, 'kms_alias', { + name: 'alias/aws/secretsmanager', + }); + } + + private createPocketAlbApplication(dependencies: { + region: dataAwsRegion.DataAwsRegion; + caller: dataAwsCallerIdentity.DataAwsCallerIdentity; + secretsManagerKmsAlias: dataAwsKmsAlias.DataAwsKmsAlias; + snsTopic: dataAwsSnsTopic.DataAwsSnsTopic; + }): PocketALBApplication { + const { region, caller, secretsManagerKmsAlias, snsTopic } = dependencies; + + return new PocketALBApplication(this, 'application', { + internal: false, + prefix: config.prefix, + alb6CharacterPrefix: config.shortName, + cdn: true, + domain: config.domain, + containerConfigs: [ + { + name: 'app', + portMappings: [ + { + hostPort: 4500, + containerPort: 4500, + }, + ], + healthCheck: config.healthCheck, + envVars: [ + { + name: 'NODE_ENV', + value: process.env.NODE_ENV, + }, + { + name: 'ENVIRONMENT', + value: process.env.NODE_ENV, // this gives us a nice lowercase production and development + }, + ], + secretEnvVars: [ + { + name: 'SENTRY_DSN', + valueFrom: `arn:aws:ssm:${region.name}:${caller.accountId}:parameter/${config.name}/${config.environment}/SENTRY_DSN`, + }, + { + name: 'BRAZE_API_KEY', + valueFrom: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:${config.name}/${config.environment}/BRAZE_API_KEY:key::`, + }, + ], + }, + ], + codeDeploy: { + useCodeDeploy: true, + useCodePipeline: false, + useTerraformBasedCodeDeploy: false, + generateAppSpec: false, + snsNotificationTopicArn: snsTopic.arn, + notifications: { + notifyOnFailed: true, + notifyOnSucceeded: false, + notifyOnStarted: false, + }, + }, + exposedContainer: { + name: 'app', + port: 4500, + healthCheckPath: '/.well-known/server-health', + }, + ecsIamConfig: { + prefix: config.prefix, + taskExecutionRolePolicyStatements: [ + //This policy could probably go in the shared module in the future. + { + actions: ['secretsmanager:GetSecretValue', 'kms:Decrypt'], + resources: [ + `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared`, + `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/*`, + secretsManagerKmsAlias.targetKeyArn, + `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:${config.name}/${config.environment}`, + `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:${config.name}/${config.environment}/*`, + `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:${config.prefix}`, + `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:${config.prefix}/*`, + ], + effect: 'Allow', + }, + //This policy could probably go in the shared module in the future. + { + actions: ['ssm:GetParameter*'], + resources: [ + `arn:aws:ssm:${region.name}:${caller.accountId}:parameter/${config.name}/${config.environment}`, + `arn:aws:ssm:${region.name}:${caller.accountId}:parameter/${config.name}/${config.environment}/*`, + ], + effect: 'Allow', + }, + ], + taskRolePolicyStatements: [ + { + actions: [ + 'xray:PutTraceSegments', + 'xray:PutTelemetryRecords', + 'xray:GetSamplingRules', + 'xray:GetSamplingTargets', + 'xray:GetSamplingStatisticSummaries', + ], + resources: ['*'], + effect: 'Allow', + }, + ], + taskExecutionDefaultAttachmentArn: + 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy', + }, + autoscalingConfig: { + targetMinCapacity: 2, + targetMaxCapacity: 10, + }, + alarms: { + http5xxErrorPercentage: { + threshold: 25, + evaluationPeriods: 4, + period: 300, + actions: config.isDev ? [] : [snsTopic.arn], + }, + }, + }); + } +} + +const app = new App(); +const stack = new BrazeContentProxy(app, 'braze-content-proxy'); +const tfEnvVersion = fs.readFileSync('.terraform-version', 'utf8'); +stack.addOverride('terraform.required_version', tfEnvVersion); +app.synth(); diff --git a/infrastructure/braze-content-proxy/tsconfig.json b/infrastructure/braze-content-proxy/tsconfig.json new file mode 100644 index 000000000..10c750597 --- /dev/null +++ b/infrastructure/braze-content-proxy/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "tsconfig/cdktf.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "exclude": [ + "node_modules/", + "dist/" + ], + "include": [ + "src/**/*.ts", + ] +} diff --git a/infrastructure/braze/package.json b/infrastructure/braze/package.json index 2f89a6e0c..3eaca256e 100644 --- a/infrastructure/braze/package.json +++ b/infrastructure/braze/package.json @@ -14,7 +14,7 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-aws": "19.31.0", "@pocket-tools/terraform-modules": "workspace:*", "cdktf": "0.20.8", "cdktf-cli": "0.20.8", @@ -22,9 +22,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/client-api/package.json b/infrastructure/client-api/package.json index c29080cb0..d2a992d07 100644 --- a/infrastructure/client-api/package.json +++ b/infrastructure/client-api/package.json @@ -13,10 +13,10 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", - "@cdktf/provider-pagerduty": "13.10.2", + "@cdktf/provider-pagerduty": "13.11.4", "@pocket-tools/terraform-modules": "workspace:*", "cdktf": "0.20.8", "cdktf-cli": "0.20.8", @@ -24,9 +24,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/client-api/src/main.ts b/infrastructure/client-api/src/main.ts index e4d299efa..c3bdd66a0 100644 --- a/infrastructure/client-api/src/main.ts +++ b/infrastructure/client-api/src/main.ts @@ -269,33 +269,6 @@ class ClientAPI extends TerraformStack { startPeriod: 0, }, }, - { - name: 'aws-otel-collector', - containerImage: 'amazon/aws-otel-collector', - essential: true, - repositoryCredentialsParam: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/DockerHub`, - //Used default config as stated here: - // Available configs here: - https://github.com/aws-observability/aws-otel-collector/tree/main/config - command: [ - '--config=/etc/ecs/ecs-xray.yaml', - //enable for debugging - //'--set=service.telemetry.logs.level=debug', - ], - logGroup: this.createCustomLogGroup('aws-otel-collector'), - logMultilinePattern: '^\\S.+', - portMappings: [ - { - //default http port - hostPort: 4138, - containerPort: 4138, - }, - { - //default grpc port - hostPort: 4137, - containerPort: 4137, - }, - ], - }, ], codeDeploy: { useCodeDeploy: true, diff --git a/infrastructure/feature-flags/package.json b/infrastructure/feature-flags/package.json index 74a6f7c2f..a4e454f1c 100644 --- a/infrastructure/feature-flags/package.json +++ b/infrastructure/feature-flags/package.json @@ -13,7 +13,7 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -23,9 +23,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/feature-flags/src/main.ts b/infrastructure/feature-flags/src/main.ts index e2e1c5b55..0d8cd7444 100644 --- a/infrastructure/feature-flags/src/main.ts +++ b/infrastructure/feature-flags/src/main.ts @@ -197,19 +197,6 @@ class FeatureFlags extends TerraformStack { }, ], }, - { - name: 'xray-daemon', - containerImage: 'amazon/aws-xray-daemon', - repositoryCredentialsParam: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/DockerHub`, - portMappings: [ - { - hostPort: 2000, - containerPort: 2000, - protocol: 'udp', - }, - ], - command: ['--region', 'us-east-1', '--local-mode'], - }, ], codeDeploy: { useCodeDeploy: true, diff --git a/infrastructure/fxa-webhook-proxy/package.json b/infrastructure/fxa-webhook-proxy/package.json index e8f637b5e..a8fc96ae9 100644 --- a/infrastructure/fxa-webhook-proxy/package.json +++ b/infrastructure/fxa-webhook-proxy/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/image-api/package.json b/infrastructure/image-api/package.json index cfb537dcd..793d9ad72 100644 --- a/infrastructure/image-api/package.json +++ b/infrastructure/image-api/package.json @@ -13,8 +13,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -24,9 +24,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/image-api/src/main.ts b/infrastructure/image-api/src/main.ts index 1f1831fe3..c5d46369e 100644 --- a/infrastructure/image-api/src/main.ts +++ b/infrastructure/image-api/src/main.ts @@ -151,10 +151,6 @@ class ImageAPI extends TerraformStack { name: 'REDIS_READER_ENDPOINT', value: readerEndpoint, }, - { - name: 'OTLP_COLLECTOR_HOST', - value: config.tracing.host, - }, { name: 'REDIS_IS_CLUSTER', value: 'true', @@ -177,31 +173,6 @@ class ImageAPI extends TerraformStack { logGroup: this.createCustomLogGroup('app'), logMultilinePattern: '^\\S.+', }, - { - name: 'aws-otel-collector', - containerImage: 'amazon/aws-otel-collector', - essential: true, - repositoryCredentialsParam: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/DockerHub`, - //Used default config as stated here: - // Available configs here: - https://github.com/aws-observability/aws-otel-collector/tree/main/config - command: [ - '--config=/etc/ecs/ecs-xray.yaml', - //enable for debugging - //'--set=service.telemetry.logs.level=debug', - ], - portMappings: [ - { - //default http port - hostPort: 4138, - containerPort: 4138, - }, - { - //default grpc port - hostPort: 4137, - containerPort: 4137, - }, - ], - }, ], codeDeploy: { useCodeDeploy: true, @@ -269,7 +240,7 @@ class ImageAPI extends TerraformStack { threshold: 25, evaluationPeriods: 4, period: 300, - actions: config.isProd ? [snsTopic.arn] : [], + actions: config.isProd ? [] : [], }, }, }); diff --git a/infrastructure/instant-sync-events/package.json b/infrastructure/instant-sync-events/package.json index 86a2f178e..3b4a535ab 100644 --- a/infrastructure/instant-sync-events/package.json +++ b/infrastructure/instant-sync-events/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/list-api/package.json b/infrastructure/list-api/package.json index a98af43f3..30bf8d900 100644 --- a/infrastructure/list-api/package.json +++ b/infrastructure/list-api/package.json @@ -13,8 +13,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -24,9 +24,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/list-api/src/config/index.ts b/infrastructure/list-api/src/config/index.ts index cef540f55..978cc9a05 100644 --- a/infrastructure/list-api/src/config/index.ts +++ b/infrastructure/list-api/src/config/index.ts @@ -50,7 +50,4 @@ export const config = { userEvents: `PocketEventBridge-${environment}-UserEventTopic`, }, }, - tracing: { - host: 'localhost', - }, }; diff --git a/infrastructure/list-api/src/main.ts b/infrastructure/list-api/src/main.ts index b44a34a41..fb81f4463 100644 --- a/infrastructure/list-api/src/main.ts +++ b/infrastructure/list-api/src/main.ts @@ -229,10 +229,6 @@ class ListAPI extends TerraformStack { name: 'EVENT_BUS_NAME', value: config.envVars.eventBusName, }, - { - name: 'OTLP_COLLECTOR_HOST', - value: config.tracing.host, - }, ], secretEnvVars: [ { @@ -307,31 +303,6 @@ class ListAPI extends TerraformStack { logGroup: this.createCustomLogGroup('app'), logMultilinePattern: '^\\S.+', }, - { - name: 'aws-otel-collector', - containerImage: 'amazon/aws-otel-collector', - essential: true, - repositoryCredentialsParam: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/DockerHub`, - //Used default config as stated here: - // Available configs here: - https://github.com/aws-observability/aws-otel-collector/tree/main/config - command: [ - '--config=/etc/ecs/ecs-xray.yaml', - //enable for debugging - //'--set=service.telemetry.logs.level=debug', - ], - portMappings: [ - { - //default http port - hostPort: 4138, - containerPort: 4138, - }, - { - //default grpc port - hostPort: 4137, - containerPort: 4137, - }, - ], - }, ], codeDeploy: { useCodeDeploy: true, diff --git a/infrastructure/parser-graphql-wrapper/package.json b/infrastructure/parser-graphql-wrapper/package.json index b3f914cb1..cf5d23c46 100644 --- a/infrastructure/parser-graphql-wrapper/package.json +++ b/infrastructure/parser-graphql-wrapper/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/parser-graphql-wrapper/src/config/index.ts b/infrastructure/parser-graphql-wrapper/src/config/index.ts index 07b3a745e..d1ace2df5 100644 --- a/infrastructure/parser-graphql-wrapper/src/config/index.ts +++ b/infrastructure/parser-graphql-wrapper/src/config/index.ts @@ -31,9 +31,6 @@ export const config = { component_code: `pocket-content-shared-${name.toLowerCase()}`, env_code: isDev ? 'dev' : 'prod', }, - tracing: { - host: 'localhost', - }, dynamodb: { itemSummaryTable: { key: 'urlHash', diff --git a/infrastructure/parser-graphql-wrapper/src/main.ts b/infrastructure/parser-graphql-wrapper/src/main.ts index 3d7b6987e..ac1c18c6f 100644 --- a/infrastructure/parser-graphql-wrapper/src/main.ts +++ b/infrastructure/parser-graphql-wrapper/src/main.ts @@ -152,10 +152,6 @@ class ParserGraphQLWrapper extends TerraformStack { name: 'ENVIRONMENT', value: process.env.NODE_ENV, }, - { - name: 'OTLP_COLLECTOR_HOST', - value: config.tracing.host, - }, { name: 'REDIS_PRIMARY_ENDPOINT', value: primaryEndpoint, @@ -282,25 +278,6 @@ class ParserGraphQLWrapper extends TerraformStack { }, ], }, - { - name: 'aws-otel-collector', - command: ['--config=/etc/ecs/ecs-xray.yaml'], - containerImage: 'amazon/aws-otel-collector', - essential: true, - logMultilinePattern: '^\\S.+', - logGroup: this.createCustomLogGroup('aws-otel-collector'), - portMappings: [ - { - hostPort: 4138, - containerPort: 4138, - }, - { - hostPort: 4137, - containerPort: 4137, - }, - ], - repositoryCredentialsParam: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/DockerHub`, - }, ], codeDeploy: { useCodeDeploy: true, diff --git a/infrastructure/pocket-event-bridge/package.json b/infrastructure/pocket-event-bridge/package.json index 165d29234..858138484 100644 --- a/infrastructure/pocket-event-bridge/package.json +++ b/infrastructure/pocket-event-bridge/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/push-server/package.json b/infrastructure/push-server/package.json index 9428d90a1..869daef2b 100644 --- a/infrastructure/push-server/package.json +++ b/infrastructure/push-server/package.json @@ -13,8 +13,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -24,9 +24,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/push-server/src/main.ts b/infrastructure/push-server/src/main.ts index 280479b69..6bc528322 100644 --- a/infrastructure/push-server/src/main.ts +++ b/infrastructure/push-server/src/main.ts @@ -170,25 +170,6 @@ class PushServer extends TerraformStack { }, ], }, - { - name: 'aws-otel-collector', - command: ['--config=/etc/ecs/ecs-xray.yaml'], - containerImage: 'amazon/aws-otel-collector', - essential: true, - logMultilinePattern: '^\\S.+', - logGroup: this.createCustomLogGroup('aws-otel-collector'), - portMappings: [ - { - hostPort: 4138, - containerPort: 4138, - }, - { - hostPort: 4137, - containerPort: 4137, - }, - ], - repositoryCredentialsParam: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/DockerHub`, - }, ], ecsIamConfig: { prefix: config.prefix, diff --git a/infrastructure/sendgrid-data/package.json b/infrastructure/sendgrid-data/package.json index b1749f65e..468d37978 100644 --- a/infrastructure/sendgrid-data/package.json +++ b/infrastructure/sendgrid-data/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/shareable-lists-api/package.json b/infrastructure/shareable-lists-api/package.json index 9dc6da593..b170bf41b 100644 --- a/infrastructure/shareable-lists-api/package.json +++ b/infrastructure/shareable-lists-api/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/shared-snowplow-consumer/package.json b/infrastructure/shared-snowplow-consumer/package.json index 50477fbba..506f38f13 100644 --- a/infrastructure/shared-snowplow-consumer/package.json +++ b/infrastructure/shared-snowplow-consumer/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/shared-snowplow-consumer/src/sharedSnowplowConsumerApp.ts b/infrastructure/shared-snowplow-consumer/src/sharedSnowplowConsumerApp.ts index 8fc790751..4b8a01622 100644 --- a/infrastructure/shared-snowplow-consumer/src/sharedSnowplowConsumerApp.ts +++ b/infrastructure/shared-snowplow-consumer/src/sharedSnowplowConsumerApp.ts @@ -91,10 +91,6 @@ export class SharedSnowplowConsumerApp extends Construct { name: 'SNOWPLOW_EVENTS_DLQ_URL', value: this.config.sqsDLQ.url, }, - { - name: 'OTLP_COLLECTOR_HOST', - value: config.tracing.host, - }, ], secretEnvVars: [ { @@ -103,25 +99,6 @@ export class SharedSnowplowConsumerApp extends Construct { }, ], }, - { - name: 'aws-otel-collector', - command: ['--config=/etc/ecs/ecs-xray.yaml'], - containerImage: 'amazon/aws-otel-collector', - essential: true, - logMultilinePattern: '^\\S.+', - logGroup: this.createCustomLogGroup('aws-otel-collector'), - portMappings: [ - { - hostPort: 4138, - containerPort: 4138, - }, - { - hostPort: 4137, - containerPort: 4137, - }, - ], - repositoryCredentialsParam: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/DockerHub`, - }, ], codeDeploy: { useCodeDeploy: true, diff --git a/infrastructure/shares-api/package.json b/infrastructure/shares-api/package.json index 77a801341..585fc3cdc 100644 --- a/infrastructure/shares-api/package.json +++ b/infrastructure/shares-api/package.json @@ -14,8 +14,8 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/shares-api/src/main.ts b/infrastructure/shares-api/src/main.ts index fa26d0c52..33878fabc 100644 --- a/infrastructure/shares-api/src/main.ts +++ b/infrastructure/shares-api/src/main.ts @@ -160,10 +160,6 @@ class SharesAPI extends TerraformStack { name: 'SQS_BATCH_DELETE_QUEUE_URL', value: `https://sqs.${region.name}.amazonaws.com/${caller.accountId}/${config.envVars.sqsBatchDeleteQueueName}`, }, - { - name: 'OTLP_COLLECTOR_HOST', - value: config.tracing.host, - }, { name: 'SHARE_URL', value: 'https://pocket.co/share', @@ -186,25 +182,6 @@ class SharesAPI extends TerraformStack { }, ], }, - { - name: 'aws-otel-collector', - command: ['--config=/etc/ecs/ecs-xray.yaml'], - containerImage: 'amazon/aws-otel-collector', - essential: true, - logMultilinePattern: '^\\S.+', - logGroup: this.createCustomLogGroup('aws-otel-collector'), - portMappings: [ - { - hostPort: 4138, - containerPort: 4138, - }, - { - hostPort: 4137, - containerPort: 4137, - }, - ], - repositoryCredentialsParam: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/DockerHub`, - }, ], codeDeploy: { useCodeDeploy: true, diff --git a/infrastructure/transactional-emails/package.json b/infrastructure/transactional-emails/package.json index 0d9034153..8dc1e9056 100644 --- a/infrastructure/transactional-emails/package.json +++ b/infrastructure/transactional-emails/package.json @@ -14,11 +14,11 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", - "@cdktf/provider-pagerduty": "13.10.2", + "@cdktf/provider-pagerduty": "13.11.4", "@pocket-tools/terraform-modules": "workspace:*", "cdktf": "0.20.8", "cdktf-cli": "0.20.8", @@ -26,9 +26,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/user-api/package.json b/infrastructure/user-api/package.json index b8dab7c76..91322ab3d 100644 --- a/infrastructure/user-api/package.json +++ b/infrastructure/user-api/package.json @@ -13,7 +13,7 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", "@pocket-tools/terraform-modules": "workspace:*", @@ -23,9 +23,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/user-api/src/main.ts b/infrastructure/user-api/src/main.ts index a6ae92aef..972e3b831 100644 --- a/infrastructure/user-api/src/main.ts +++ b/infrastructure/user-api/src/main.ts @@ -128,10 +128,6 @@ class UserAPI extends TerraformStack { name: 'EVENT_BUS_NAME', value: config.envVars.eventBusName, }, - { - name: 'OTLP_COLLECTOR_HOST', - value: config.tracing.host, - }, ], secretEnvVars: [ { @@ -194,29 +190,6 @@ class UserAPI extends TerraformStack { logGroup: this.createCustomLogGroup('app'), logMultilinePattern: '^\\S.+', }, - { - name: 'aws-otel-collector', - containerImage: 'amazon/aws-otel-collector', - essential: true, - repositoryCredentialsParam: `arn:aws:secretsmanager:${region.name}:${caller.accountId}:secret:Shared/DockerHub`, - //Used default config as stated here: - // Available configs here: - https://github.com/aws-observability/aws-otel-collector/tree/main/config - command: ['--config=/etc/ecs/ecs-xray.yaml'], - logGroup: this.createCustomLogGroup('aws-otel-collector'), - logMultilinePattern: '^\\S.+', - portMappings: [ - { - //default http port - hostPort: 4138, - containerPort: 4138, - }, - { - //default grpc port - hostPort: 4137, - containerPort: 4137, - }, - ], - }, ], codeDeploy: { useCodeDeploy: true, diff --git a/infrastructure/user-list-search/apollo_ecs.tf b/infrastructure/user-list-search/apollo_ecs.tf index bb07cd57a..137f48f7f 100644 --- a/infrastructure/user-list-search/apollo_ecs.tf +++ b/infrastructure/user-list-search/apollo_ecs.tf @@ -145,6 +145,20 @@ output "ecs-task-arn" { value = aws_ecs_task_definition.apollo.arn } +output "ecs-serviceName" { + description = "ECS Service Name" + value = aws_ecs_service.apollo.name +} +output "ecs-clusterName" { + description = "ECS Cluster Name" + value = aws_ecs_cluster.ecs_cluster.name +} + +output "ecs-application-url" { + description = "ECS Application URL" + value = local.workspace.domain +} + resource "aws_ecs_service" "apollo" { name = "Apollo" task_definition = aws_ecs_task_definition.apollo.arn diff --git a/infrastructure/v3-proxy-api/package.json b/infrastructure/v3-proxy-api/package.json index 85f20b7f2..0d5dc36ad 100644 --- a/infrastructure/v3-proxy-api/package.json +++ b/infrastructure/v3-proxy-api/package.json @@ -14,10 +14,10 @@ "watch": "tsc -w" }, "dependencies": { - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", "@cdktf/provider-null": "10.0.0", - "@cdktf/provider-pagerduty": "13.10.2", + "@cdktf/provider-pagerduty": "13.11.4", "@pocket-tools/terraform-modules": "workspace:*", "cdktf": "0.20.8", "cdktf-cli": "0.20.8", @@ -25,9 +25,9 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/infrastructure/v3-proxy-api/src/main.ts b/infrastructure/v3-proxy-api/src/main.ts index 2e6178813..087aaf2a8 100644 --- a/infrastructure/v3-proxy-api/src/main.ts +++ b/infrastructure/v3-proxy-api/src/main.ts @@ -8,10 +8,6 @@ import { } from '@cdktf/provider-aws'; import { provider as localProvider } from '@cdktf/provider-local'; import { provider as nullProvider } from '@cdktf/provider-null'; -import { - provider as pagerdutyProvider, - dataPagerdutyEscalationPolicy, -} from '@cdktf/provider-pagerduty'; import { PocketALBApplication, PocketPagerDuty, @@ -29,9 +25,6 @@ class Stack extends TerraformStack { region: 'us-east-1', defaultTags: [{ tags: config.tags }], }); - new pagerdutyProvider.PagerdutyProvider(this, 'pagerduty_provider', { - token: undefined, - }); new localProvider.LocalProvider(this, 'local_provider'); new nullProvider.NullProvider(this, 'null_provider'); @@ -87,23 +80,7 @@ class Stack extends TerraformStack { return undefined; } - const nonCriticalEscalationPolicyId = - new dataPagerdutyEscalationPolicy.DataPagerdutyEscalationPolicy( - this, - 'non_critical_escalation_policy', - { - name: 'Pocket On-Call: Default Non-Critical - Tier 2+ (Former Backend Temporary Holder)', - }, - ).id; - - return new PocketPagerDuty(this, 'pagerduty', { - prefix: config.prefix, - service: { - // This is a Tier 2 service and as such only raises non-critical alarms. - criticalEscalationPolicyId: nonCriticalEscalationPolicyId, - nonCriticalEscalationPolicyId: nonCriticalEscalationPolicyId, - }, - }); + return undefined; } /** diff --git a/lambdas/account-data-deleter-batch-delete/package.json b/lambdas/account-data-deleter-batch-delete/package.json index bcf5d1f1d..931903b77 100644 --- a/lambdas/account-data-deleter-batch-delete/package.json +++ b/lambdas/account-data-deleter-batch-delete/package.json @@ -17,24 +17,24 @@ "test-integrations": "jest \"\\.integration\\.ts\" --runInBand" }, "dependencies": { - "@aws-sdk/client-dynamodb": "3.609.0", - "@aws-sdk/lib-dynamodb": "3.609.0", - "@sentry/aws-serverless": "8.18.0", + "@aws-sdk/client-dynamodb": "3.632.0", + "@aws-sdk/lib-dynamodb": "3.632.0", + "@sentry/aws-serverless": "8.27.0", "exponential-backoff": "^3.1.1", "lodash": "4.17.21", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", "@types/lodash": "4.17.7", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "nock": "14.0.0-beta.6", - "ts-jest": "29.2.3", + "nock": "14.0.0-beta.11", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/account-data-deleter-batch-delete/src/externalCaller/deleteMutation.spec.ts b/lambdas/account-data-deleter-batch-delete/src/externalCaller/deleteMutation.spec.ts index de6f85224..ff47648e7 100644 --- a/lambdas/account-data-deleter-batch-delete/src/externalCaller/deleteMutation.spec.ts +++ b/lambdas/account-data-deleter-batch-delete/src/externalCaller/deleteMutation.spec.ts @@ -1,6 +1,6 @@ import { config } from '../config'; import { deleteUserMutationCaller, userApiCalls } from './deleteMutation'; -import nock = require('nock'); +import nock from 'nock'; describe('deleteUser mutation test', () => { const testUserId = '1001'; diff --git a/lambdas/account-data-deleter-batch-delete/src/index.ts b/lambdas/account-data-deleter-batch-delete/src/index.ts index b5254618d..9b55fb587 100644 --- a/lambdas/account-data-deleter-batch-delete/src/index.ts +++ b/lambdas/account-data-deleter-batch-delete/src/index.ts @@ -36,7 +36,7 @@ export async function deleteUsers(dynamoUtils: BatchDeleteDyanmoClient) { try { const deletedId = await deleteUserMutationCaller(userId.toString()); deletedUserIds.push(parseInt(deletedId)); - } catch (e) { + } catch { Sentry.captureException({ message: `unable to delete userId ${userId}` }); console.log(`unable to delete userId ${userId}`); } diff --git a/lambdas/account-data-deleter-events/package.json b/lambdas/account-data-deleter-events/package.json index 7bb7dfbfa..44cb3c799 100644 --- a/lambdas/account-data-deleter-events/package.json +++ b/lambdas/account-data-deleter-events/package.json @@ -17,22 +17,22 @@ "test-integrations": "jest \"\\.integration\\.ts\" --runInBand" }, "dependencies": { - "@aws-sdk/client-lambda": "3.609.0", - "@sentry/aws-serverless": "8.18.0", + "@aws-sdk/client-lambda": "3.632.0", + "@sentry/aws-serverless": "8.27.0", "fetch-retry": "^5.0.6", "stripe": "14.24.0", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "nock": "14.0.0-beta.6", - "ts-jest": "29.2.3", + "nock": "14.0.0-beta.11", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/account-delete-monitor/package.json b/lambdas/account-delete-monitor/package.json index f7345c042..c153e9440 100644 --- a/lambdas/account-delete-monitor/package.json +++ b/lambdas/account-delete-monitor/package.json @@ -17,22 +17,22 @@ "test-integrations": "jest \"\\.integration\\.ts\" --runInBand" }, "dependencies": { - "@aws-sdk/client-dynamodb": "3.609.0", - "@aws-sdk/lib-dynamodb": "3.609.0", - "@sentry/aws-serverless": "8.18.0", + "@aws-sdk/client-dynamodb": "3.632.0", + "@aws-sdk/lib-dynamodb": "3.632.0", + "@sentry/aws-serverless": "8.27.0", "exponential-backoff": "^3.1.1", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "nock": "14.0.0-beta.6", - "ts-jest": "29.2.3", + "nock": "14.0.0-beta.11", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/annotations-api-events/package.json b/lambdas/annotations-api-events/package.json index adc43a28f..206ab2159 100644 --- a/lambdas/annotations-api-events/package.json +++ b/lambdas/annotations-api-events/package.json @@ -17,19 +17,19 @@ "test-integrations": "jest \"\\.integration\\.ts\" --runInBand" }, "dependencies": { - "@sentry/aws-serverless": "8.18.0", + "@sentry/aws-serverless": "8.27.0", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "nock": "14.0.0-beta.6", - "ts-jest": "29.2.3", + "nock": "14.0.0-beta.11", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/fxa-webook-proxy-gateway/package.json b/lambdas/fxa-webook-proxy-gateway/package.json index ff3e730c4..861029c1e 100644 --- a/lambdas/fxa-webook-proxy-gateway/package.json +++ b/lambdas/fxa-webook-proxy-gateway/package.json @@ -18,8 +18,8 @@ "test-integrations": "jest \"\\.integration\\.ts\" --runInBand" }, "dependencies": { - "@aws-sdk/client-sqs": "3.609.0", - "@sentry/aws-serverless": "8.18.0", + "@aws-sdk/client-sqs": "3.632.0", + "@sentry/aws-serverless": "8.27.0", "jsonwebtoken": "^9.0.0", "jwk-to-pem": "^2.0.5", "jwks-rsa": "3.1.0", @@ -27,17 +27,17 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", "@types/jsonwebtoken": "^9.0.5", "@types/jwk-to-pem": "^2.0.1", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/fxa-webook-proxy-sqs/package.json b/lambdas/fxa-webook-proxy-sqs/package.json index 4348b8b5e..9a23a37d3 100644 --- a/lambdas/fxa-webook-proxy-sqs/package.json +++ b/lambdas/fxa-webook-proxy-sqs/package.json @@ -17,25 +17,25 @@ "test-integrations": "jest \"\\.integration\\.ts\" --runInBand" }, "dependencies": { - "@aws-sdk/client-secrets-manager": "3.609.0", - "@aws-sdk/client-sqs": "3.609.0", - "@sentry/aws-serverless": "8.18.0", + "@aws-sdk/client-secrets-manager": "3.632.0", + "@aws-sdk/client-sqs": "3.632.0", + "@sentry/aws-serverless": "8.27.0", "jsonwebtoken": "^9.0.0", "jwk-to-pem": "^2.0.5", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", "@types/jsonwebtoken": "^9.0.5", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/instant-sync-events/package.json b/lambdas/instant-sync-events/package.json index d33e7037b..18212ae11 100644 --- a/lambdas/instant-sync-events/package.json +++ b/lambdas/instant-sync-events/package.json @@ -16,22 +16,22 @@ }, "dependencies": { "@pocket-tools/lambda-secrets": "workspace:*", - "@sentry/aws-serverless": "8.18.0", + "@sentry/aws-serverless": "8.27.0", "knex": "3.1.0", "mysql2": "3.10.3", "nanoid": "3.3.7", "tslib": "2.6.3" }, "devDependencies": { - "@aws-sdk/client-sqs": "3.609.0", + "@aws-sdk/client-sqs": "3.632.0", "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/sendgrid-data/package.json b/lambdas/sendgrid-data/package.json index abc2a341a..30bb43bb6 100644 --- a/lambdas/sendgrid-data/package.json +++ b/lambdas/sendgrid-data/package.json @@ -14,21 +14,21 @@ "test": "jest \"\\.spec\\.ts\"" }, "dependencies": { - "@aws-sdk/client-cloudwatch": "3.609.0", - "@aws-sdk/client-firehose": "3.609.0", + "@aws-sdk/client-cloudwatch": "3.632.0", + "@aws-sdk/client-firehose": "3.632.0", "@sendgrid/client": "^8.0.0", - "@sentry/aws-serverless": "8.18.0", + "@sentry/aws-serverless": "8.27.0", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/shareable-lists-api-events/package.json b/lambdas/shareable-lists-api-events/package.json index 5f19a4226..48f005a63 100644 --- a/lambdas/shareable-lists-api-events/package.json +++ b/lambdas/shareable-lists-api-events/package.json @@ -17,21 +17,21 @@ "test-integrations": "jest \"\\.integration\\.ts\" --runInBand" }, "dependencies": { - "@sentry/aws-serverless": "8.18.0", + "@sentry/aws-serverless": "8.27.0", "fetch-retry": "^5.0.6", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "aws-lambda": "^1.0.7", "jest": "29.7.0", - "nock": "14.0.0-beta.6", - "ts-jest": "29.2.3", + "nock": "14.0.0-beta.11", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/transactional-emails/package.json b/lambdas/transactional-emails/package.json index b9418d83b..962c7dfb6 100644 --- a/lambdas/transactional-emails/package.json +++ b/lambdas/transactional-emails/package.json @@ -18,23 +18,23 @@ "test:watch": "npm test -- --watchAll" }, "dependencies": { - "@aws-sdk/client-ssm": "3.609.0", - "@sentry/aws-serverless": "8.18.0", + "@aws-sdk/client-ssm": "3.632.0", + "@sentry/aws-serverless": "8.27.0", "braze-api": "^2.9.1", "fetch-retry": "^5.0.6", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/user-list-search-corpus-indexing/package.json b/lambdas/user-list-search-corpus-indexing/package.json index 80532646b..b51db6c5a 100644 --- a/lambdas/user-list-search-corpus-indexing/package.json +++ b/lambdas/user-list-search-corpus-indexing/package.json @@ -18,22 +18,22 @@ }, "dependencies": { "@pocket-tools/ts-logger": "workspace:*", - "@sentry/aws-serverless": "8.18.0", + "@sentry/aws-serverless": "8.27.0", "fetch-retry": "^5.0.6", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/elasticsearch": "^5.0.37", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "aws-lambda": "^1.0.7", "jest": "29.7.0", - "nock": "14.0.0-beta.6", - "ts-jest": "29.2.3", + "nock": "14.0.0-beta.11", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/user-list-search-corpus-parser-hydration/package.json b/lambdas/user-list-search-corpus-parser-hydration/package.json index 3a4ca3df4..a8b56be99 100644 --- a/lambdas/user-list-search-corpus-parser-hydration/package.json +++ b/lambdas/user-list-search-corpus-parser-hydration/package.json @@ -18,22 +18,22 @@ }, "dependencies": { "@pocket-tools/ts-logger": "workspace:*", - "@sentry/aws-serverless": "8.18.0", + "@sentry/aws-serverless": "8.27.0", "fetch-retry": "^5.0.6", "string-strip-html": "8.4.0", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "aws-lambda": "^1.0.7", "jest": "29.7.0", - "nock": "14.0.0-beta.6", - "ts-jest": "29.2.3", + "nock": "14.0.0-beta.11", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/user-list-search-events/package.json b/lambdas/user-list-search-events/package.json index 6a8916f3d..71285f307 100644 --- a/lambdas/user-list-search-events/package.json +++ b/lambdas/user-list-search-events/package.json @@ -14,19 +14,19 @@ "test": "jest \"\\.spec\\.ts\" --runInBand --forceExit" }, "dependencies": { - "@sentry/aws-serverless": "8.18.0", + "@sentry/aws-serverless": "8.27.0", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "nock": "14.0.0-beta.6", - "ts-jest": "29.2.3", + "nock": "14.0.0-beta.11", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/user-list-search-indexing/package.json b/lambdas/user-list-search-indexing/package.json index 0b147f405..8ebe90742 100644 --- a/lambdas/user-list-search-indexing/package.json +++ b/lambdas/user-list-search-indexing/package.json @@ -14,21 +14,21 @@ "test": "jest \"\\.spec\\.ts\" --runInBand --forceExit" }, "dependencies": { - "@sentry/aws-serverless": "8.18.0", + "@sentry/aws-serverless": "8.27.0", "nanoid": "3.3.7", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", "jest-extended": "4.0.2", - "nock": "14.0.0-beta.6", - "ts-jest": "29.2.3", + "nock": "14.0.0-beta.11", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/lambdas/user-list-search-kinesis-to-sqs/package.json b/lambdas/user-list-search-kinesis-to-sqs/package.json index 3d929e6b8..c50093b94 100644 --- a/lambdas/user-list-search-kinesis-to-sqs/package.json +++ b/lambdas/user-list-search-kinesis-to-sqs/package.json @@ -14,24 +14,24 @@ "test": "jest \"\\.spec\\.ts\" --runInBand --forceExit" }, "dependencies": { - "@aws-sdk/client-sqs": "3.609.0", - "@sentry/aws-serverless": "8.18.0", + "@aws-sdk/client-sqs": "3.632.0", + "@sentry/aws-serverless": "8.27.0", "highland": "2.13.5", "tslib": "2.6.3", "uuid": "^9.0.1" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@types/aws-lambda": "8.10.141", + "@types/aws-lambda": "8.10.143", "@types/highland": "^2.12.11", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", "jest-extended": "4.0.2", - "nock": "14.0.0-beta.6", - "ts-jest": "29.2.3", + "nock": "14.0.0-beta.11", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/package.json b/package.json index 8eefddad9..ec614b39f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "name": "pocket-monorepo", "private": true, "scripts": { - "prebuild": "dotenv -- turbo run prebuild", "build": "dotenv -- turbo run build", "clean": "rm -rf .turbo node_modules packages/**/.turbo packages/**/dist packages/**/node_modules servers/**/logs servers/**/.turbo servers/**/dist servers/**/node_modules lambdas/**/logs lambdas/**/.turbo lambdas/**/dist lambdas/**/node_modules infrastructure/**/dist infrastructure/**/node_modules infrastructure/**/.turbo infrastructure/**/cdktf.out", "dev": "dotenv -- turbo run dev --concurrency 50", @@ -15,7 +14,6 @@ "prepare": "husky", "semantic-release": "dotenv -- turbo run semantic-release", "synth": "dotenv -- turbo run synth", - "pretest-integrations": "dotenv -- turbo run pretest-integrations", "test": "dotenv -- turbo run test", "test-integrations": "dotenv -- turbo run test-integrations" }, @@ -26,18 +24,18 @@ }, "dependencies": { "dotenv-cli": "latest", - "husky": "9.1.1" + "husky": "9.1.4" }, "devDependencies": { - "@commitlint/cli": "19.3.0", + "@commitlint/cli": "19.4.0", "@commitlint/config-conventional": "^19.2.2", "@pocket-tools/eslint-config": "workspace:*", - "syncpack": "^12.3.3", + "syncpack": "^12.4.0", "tsconfig": "workspace:*", - "turbo": "^1.13.4" + "turbo": "^2.1.0" }, - "packageManager": "pnpm@9.1.4", + "packageManager": "pnpm@9.9.0", "engines": { - "node": "^20.15" + "node": "^20.16" } } diff --git a/packages/apollo-utils/package.json b/packages/apollo-utils/package.json index 7de9725fc..bd9131734 100644 --- a/packages/apollo-utils/package.json +++ b/packages/apollo-utils/package.json @@ -25,6 +25,7 @@ "dev": "pnpm run build --watch", "format": "eslint --fix", "lint": "eslint --fix-dry-run", + "presemantic-release": "pnpm run build", "semantic-release": "semantic-release", "test": "jest", "test:watch": "pnpm run test -- --watch" @@ -75,11 +76,11 @@ "@apollo/cache-control-types": "1.0.3", "@apollo/server": "4.10.4", "@apollo/server-plugin-response-cache": "4.1.3", - "@apollo/subgraph": "2.8.3", + "@apollo/subgraph": "2.9.0", "@apollo/utils.keyvadapter": "3.1.0", "@apollo/utils.keyvaluecache": "3.1.0", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "express": "4.19.2", "graphql": "16.8.1", "graphql-tag": "2.12.6", @@ -92,25 +93,25 @@ "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", "@types/md5": "2.3.5", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ioredis-mock": "8.9.0", "jest": "29.7.0", "jest-extended": "4.0.2", - "semantic-release": "24.0.0", + "semantic-release": "24.1.0", "semantic-release-monorepo": "8.0.2", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "tsup": "8.1.2", - "typescript": "5.5.3" + "tsup": "8.2.4", + "typescript": "5.5.4" }, "peerDependencies": { "@apollo/server": "4.10.4", - "@apollo/subgraph": "2.8.3", + "@apollo/subgraph": "2.9.0", "@apollo/utils.keyvadapter": "3.1.0", "@apollo/utils.keyvaluecache": "3.1.0", "express": "4.19.2", "graphql": "16.8.1", "graphql-tag": "2.12.6" } -} +} \ No newline at end of file diff --git a/packages/apollo-utils/src/scalars/isoStringScalar.integration.spec.ts b/packages/apollo-utils/src/scalars/isoStringScalar.integration.spec.ts index 260a195ce..d9c3c6983 100644 --- a/packages/apollo-utils/src/scalars/isoStringScalar.integration.spec.ts +++ b/packages/apollo-utils/src/scalars/isoStringScalar.integration.spec.ts @@ -154,7 +154,7 @@ describe('isoStringScalar ApolloServer usage', () => { expect(result.data.somethingDeleted.deletedAt).toBe(isoUTCDateStr); expect(result.data.somethingDeleted.createdAt).toBe(isoUTCDateStr); expect(result.data.somethingDeleted.id).toBe('2'); - expect(result.errors).toBeUndefined; + expect(result.errors).toBeUndefined(); }); it('valid null in, valid response out', async () => { const response = await server.executeOperation({ @@ -165,7 +165,7 @@ describe('isoStringScalar ApolloServer usage', () => { expect(result.data.somethingDeleted.deletedAt).toBe(null); expect(result.data.somethingDeleted.createdAt).toBe(isoUTCDateStr); expect(result.data.somethingDeleted.id).toBe('1'); - expect(result.errors).toBeUndefined; + expect(result.errors).toBeUndefined(); }); it('invalid date format in, error out', async () => { const response = await server.executeOperation({ @@ -221,7 +221,7 @@ describe('isoStringScalar ApolloServer usage', () => { expect(result.data.somethingDeleted.deletedAt).toBe(isoUTCDateStr); expect(result.data.somethingDeleted.createdAt).toBe(isoUTCDateStr); expect(result.data.somethingDeleted.id).toBe('2'); - expect(result.errors).toBeUndefined; + expect(result.errors).toBeUndefined(); }); it('valid null in, valid response out', async () => { const response = await server.executeOperation({ @@ -239,7 +239,7 @@ describe('isoStringScalar ApolloServer usage', () => { expect(result.data.somethingDeleted.deletedAt).toBe(null); expect(result.data.somethingDeleted.createdAt).toBe(isoUTCDateStr); expect(result.data.somethingDeleted.id).toBe('1'); - expect(result.errors).toBeUndefined; + expect(result.errors).toBeUndefined(); }); it('invalid date format in, error out', async () => { const response = await server.executeOperation({ diff --git a/packages/backend-benchmarking/package.json b/packages/backend-benchmarking/package.json index 388bacbc8..dc80a5df3 100644 --- a/packages/backend-benchmarking/package.json +++ b/packages/backend-benchmarking/package.json @@ -25,18 +25,18 @@ "test:watch": "npm run test -- --watch" }, "dependencies": { - "chance": "1.1.11", + "chance": "1.1.12", "tslib": "2.6.3" }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "tsup": "8.1.2", - "typescript": "5.5.3" + "tsup": "8.2.4", + "typescript": "5.5.4" } } diff --git a/packages/eslint-config/base.js b/packages/eslint-config/base.js index 8c6b474bf..3083784cf 100644 --- a/packages/eslint-config/base.js +++ b/packages/eslint-config/base.js @@ -21,6 +21,8 @@ export default tseslint.config( ], // allows 'any' typehint '@typescript-eslint/no-explicit-any': 0, + // allows shorthands + '@typescript-eslint/no-unused-expressions': 0, }, }, { diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index 4141ca64b..bced3ffcf 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -41,7 +41,7 @@ "eslint-plugin-prettier": "^5.2.1", "jsonc-eslint-parser": "^2.4.0", "prettier": "^3.3.3", - "typescript": "5.5.3", - "typescript-eslint": "^7.16.1" + "typescript": "5.5.4", + "typescript-eslint": "^8.2.0" } } diff --git a/packages/feature-flags-client/package.json b/packages/feature-flags-client/package.json index 33aed7633..bdc1f979b 100644 --- a/packages/feature-flags-client/package.json +++ b/packages/feature-flags-client/package.json @@ -31,12 +31,12 @@ "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "tsup": "8.1.2", - "typescript": "5.5.3" + "tsup": "8.2.4", + "typescript": "5.5.4" } } diff --git a/packages/feature-flags-client/src/mockClient.ts b/packages/feature-flags-client/src/mockClient.ts index c84cfc85f..496758af5 100644 --- a/packages/feature-flags-client/src/mockClient.ts +++ b/packages/feature-flags-client/src/mockClient.ts @@ -40,12 +40,8 @@ export function mockUnleash( return compiled; }, {}); } - stop(): void { - true; - } - async start(): Promise { - true; - } + stop(): void {} + async start(): Promise {} getToggles(): FeatureInterface[] { return this.data; } diff --git a/packages/image-utils/.npmignore b/packages/image-utils/.npmignore new file mode 100644 index 000000000..e254b6528 --- /dev/null +++ b/packages/image-utils/.npmignore @@ -0,0 +1,8 @@ +src +.github +.idea +.prettier* +.eslintrc.js +.tsconfig.js +*.spec.ts +*.integration.ts \ No newline at end of file diff --git a/packages/image-utils/README.md b/packages/image-utils/README.md new file mode 100644 index 000000000..d916c026e --- /dev/null +++ b/packages/image-utils/README.md @@ -0,0 +1,3 @@ +# Image Utils + +We use this repository as a place to keep code we use across our backend services that implement anything to do with image urls diff --git a/packages/image-utils/eslint.config.mjs b/packages/image-utils/eslint.config.mjs new file mode 100644 index 000000000..638ac644e --- /dev/null +++ b/packages/image-utils/eslint.config.mjs @@ -0,0 +1,3 @@ +import packages from '@pocket-tools/eslint-config/packages'; +import tseslint from 'typescript-eslint'; +export default tseslint.config(...packages); diff --git a/packages/image-utils/jest.config.js b/packages/image-utils/jest.config.js new file mode 100644 index 000000000..3dc86cb25 --- /dev/null +++ b/packages/image-utils/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/?(*.)+(jest|spec).[jt]s?(x)'], + testPathIgnorePatterns: ['/dist/'], + setupFilesAfterEnv: ['jest-extended/all'], +}; diff --git a/packages/image-utils/package.json b/packages/image-utils/package.json new file mode 100644 index 000000000..51feb26ed --- /dev/null +++ b/packages/image-utils/package.json @@ -0,0 +1,91 @@ +{ + "name": "@pocket-tools/image-utils", + "version": "0.0.0-development", + "description": "Utilities for working with image urls", + "keywords": [ + "image" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/Pocket/pocket-monorepo.git" + }, + "license": "Apache-2.0", + "author": "", + "main": "dist/index.js", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "files": [ + "dist", + "package.json" + ], + "scripts": { + "build": "tsup src/index.ts --format cjs,esm --dts", + "dev": "pnpm run build --watch", + "format": "eslint --fix", + "lint": "eslint --fix-dry-run", + "semantic-release": "semantic-release", + "test": "jest", + "test:watch": "pnpm run test -- --watch" + }, + "release": { + "branches": [ + "main" + ], + "extends": "semantic-release-monorepo", + "plugins": [ + [ + "@semantic-release/commit-analyzer", + { + "preset": "conventionalcommits", + "parserOpts": { + "noteKeywords": [ + "BREAKING CHANGE", + "BREAKING CHANGES", + "BREAKING" + ] + } + } + ], + [ + "@semantic-release/release-notes-generator", + { + "preset": "conventionalcommits", + "parserOpts": { + "noteKeywords": [ + "BREAKING CHANGE", + "BREAKING CHANGES", + "BREAKING" + ] + }, + "writerOpts": { + "commitsSort": [ + "subject", + "scope" + ] + } + } + ], + "@semantic-release/npm", + "@semantic-release/github" + ] + }, + "dependencies": { + "parse-url": "9.2.0" + }, + "devDependencies": { + "@jest/globals": "29.7.0", + "@pocket-tools/eslint-config": "workspace:*", + "@types/jest": "29.5.12", + "@types/node": "^20.16", + "jest": "29.7.0", + "jest-extended": "4.0.2", + "semantic-release": "24.1.0", + "semantic-release-monorepo": "8.0.2", + "ts-jest": "29.2.4", + "ts-node": "10.9.2", + "tsconfig": "workspace:*", + "tsup": "8.2.4", + "typescript": "5.5.4" + }, + "peerDependencies": {} +} diff --git a/packages/image-utils/src/index.ts b/packages/image-utils/src/index.ts new file mode 100644 index 000000000..04bca77e0 --- /dev/null +++ b/packages/image-utils/src/index.ts @@ -0,0 +1 @@ +export * from './utils'; diff --git a/servers/image-api/src/pocketImageCache/utils.spec.ts b/packages/image-utils/src/utils.spec.ts similarity index 89% rename from servers/image-api/src/pocketImageCache/utils.spec.ts rename to packages/image-utils/src/utils.spec.ts index 5ed532ac5..ed8b50c64 100644 --- a/servers/image-api/src/pocketImageCache/utils.spec.ts +++ b/packages/image-utils/src/utils.spec.ts @@ -1,4 +1,3 @@ -import { NotFoundError } from '@pocket-tools/apollo-utils'; import { getOriginalUrlIfPocketImageCached } from './utils'; describe('getOriginalUrlIfPocketImageCached', () => { @@ -29,8 +28,6 @@ describe('getOriginalUrlIfPocketImageCached', () => { const url = 'https://pocket-image-cache.com/direct?resize=2000w'; expect(() => { getOriginalUrlIfPocketImageCached(url); - }).toThrowError( - new NotFoundError('Pocket image cache url is missing a source url'), - ); + }).toThrow(new Error('Source URL Missing')); }); }); diff --git a/servers/image-api/src/pocketImageCache/utils.ts b/packages/image-utils/src/utils.ts similarity index 93% rename from servers/image-api/src/pocketImageCache/utils.ts rename to packages/image-utils/src/utils.ts index 0265fe587..94125cd8b 100644 --- a/servers/image-api/src/pocketImageCache/utils.ts +++ b/packages/image-utils/src/utils.ts @@ -1,4 +1,3 @@ -import { NotFoundError } from '@pocket-tools/apollo-utils'; import parseUrl from 'parse-url'; //Functions on this page taken from Web Client. @@ -19,7 +18,7 @@ export const getOriginalUrlIfPocketImageCached = (url: string): string => { if (isEncoded) { const urlToUse = extractImageCacheUrl(url); if (!urlToUse) { - throw new NotFoundError('Pocket image cache url is missing a source url'); + throw new Error('Source URL Missing'); } return decodeURIComponent(urlToUse); } diff --git a/packages/image-utils/tsconfig.json b/packages/image-utils/tsconfig.json new file mode 100644 index 000000000..cc4df5007 --- /dev/null +++ b/packages/image-utils/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "tsconfig/library.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "exclude": ["node_modules", "dist"], + "include": ["src/**/*.ts", "src/config"] +} diff --git a/packages/int-mask/package.json b/packages/int-mask/package.json index 0bc907320..eb82f3794 100644 --- a/packages/int-mask/package.json +++ b/packages/int-mask/package.json @@ -25,12 +25,12 @@ "@jest/globals": "29.7.0", "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "tsup": "8.1.2", - "typescript": "5.5.3" + "tsup": "8.2.4", + "typescript": "5.5.4" } } diff --git a/packages/lambda-secrets/package.json b/packages/lambda-secrets/package.json index 9f90c6b01..e9852b42d 100644 --- a/packages/lambda-secrets/package.json +++ b/packages/lambda-secrets/package.json @@ -24,6 +24,7 @@ "dev": "pnpm run build --watch", "format": "eslint --fix", "lint": "eslint --fix-dry-run", + "presemantic-release": "pnpm run build", "semantic-release": "semantic-release" }, "release": { @@ -75,15 +76,15 @@ "@jest/globals": "29.7.0", "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "nock": "14.0.0-beta.6", - "semantic-release": "24.0.0", + "nock": "14.0.0-beta.11", + "semantic-release": "24.1.0", "semantic-release-monorepo": "8.0.2", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "tsup": "8.1.2", - "typescript": "5.5.3" + "tsup": "8.2.4", + "typescript": "5.5.4" } -} +} \ No newline at end of file diff --git a/packages/sentry/package.json b/packages/sentry/package.json index 6642e7122..df1308fc9 100644 --- a/packages/sentry/package.json +++ b/packages/sentry/package.json @@ -17,7 +17,7 @@ "lint": "eslint --fix-dry-run" }, "dependencies": { - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "tslib": "2.6.3" }, "devDependencies": { @@ -25,15 +25,15 @@ "@pocket-tools/eslint-config": "workspace:*", "@types/express": "4.17.21", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "tsup": "8.1.2", - "typescript": "5.5.3" + "tsup": "8.2.4", + "typescript": "5.5.4" }, "peerDependencies": { - "@sentry/node": "8.18.0" + "@sentry/node": "8.27.0" } } diff --git a/packages/terraform-modules/package.json b/packages/terraform-modules/package.json index 48677e50e..25fd240cd 100644 --- a/packages/terraform-modules/package.json +++ b/packages/terraform-modules/package.json @@ -20,6 +20,7 @@ "example:synth": "cdktf synth", "format": "eslint --fix", "lint": "eslint --fix-dry-run", + "presemantic-release": "pnpm run build", "semantic-release": "semantic-release", "test": "jest --ci --maxWorkers=4 --logHeapUsage", "test:watch": "npm test -- --watch --watch-extensions ts -R min --watch-files src" @@ -67,12 +68,12 @@ ] }, "dependencies": { - "@cdktf/provider-archive": "10.0.1", - "@cdktf/provider-aws": "19.26.0", + "@cdktf/provider-archive": "10.1.0", + "@cdktf/provider-aws": "19.31.0", "@cdktf/provider-local": "10.1.0", - "@cdktf/provider-newrelic": "12.10.3", + "@cdktf/provider-newrelic": "12.12.2", "@cdktf/provider-null": "10.0.0", - "@cdktf/provider-pagerduty": "13.10.2", + "@cdktf/provider-pagerduty": "13.11.4", "@cdktf/provider-time": "10.2.0", "cdktf": "0.20.8", "cdktf-cli": "0.20.8", @@ -83,15 +84,15 @@ "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "conventional-changelog-conventionalcommits": "8.0.0", "jest": "29.7.0", - "semantic-release": "24.0.0", + "semantic-release": "24.1.0", "semantic-release-monorepo": "8.0.2", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "tsup": "8.1.2", - "typescript": "5.5.3" + "tsup": "8.2.4", + "typescript": "5.5.4" } -} +} \ No newline at end of file diff --git a/packages/terraform-modules/src/base/ApplicationECSService.ts b/packages/terraform-modules/src/base/ApplicationECSService.ts index a6f1d4a2b..b2b499542 100644 --- a/packages/terraform-modules/src/base/ApplicationECSService.ts +++ b/packages/terraform-modules/src/base/ApplicationECSService.ts @@ -368,6 +368,18 @@ export class ApplicationECSService extends Construct { value: taskDef.family, staticId: true, }); + + new TerraformOutput(this, 'ecs-clusterName', { + description: 'ECS Cluster Name', + value: config.ecsClusterName, + staticId: true, + }); + + new TerraformOutput(this, 'ecs-serviceName', { + description: 'ECS Service Name', + value: this.service.name, + staticId: true, + }); } /** diff --git a/packages/terraform-modules/src/pocket/PocketALBApplication.ts b/packages/terraform-modules/src/pocket/PocketALBApplication.ts index 087b88016..b45dd61a1 100644 --- a/packages/terraform-modules/src/pocket/PocketALBApplication.ts +++ b/packages/terraform-modules/src/pocket/PocketALBApplication.ts @@ -8,7 +8,7 @@ import { route53Record, wafv2WebAclAssociation, } from '@cdktf/provider-aws'; -import { TerraformMetaArguments } from 'cdktf'; +import { TerraformMetaArguments, TerraformOutput } from 'cdktf'; import { Construct } from 'constructs'; import { ApplicationAutoscaling, @@ -276,6 +276,12 @@ export class PocketALBApplication extends Construct { ); this.createCloudwatchAlarms(); + + new TerraformOutput(this, 'ecs-application-url', { + description: 'ECS Application URL', + value: this.config.domain, + staticId: true, + }); } /** diff --git a/packages/terraform-modules/src/pocket/__snapshots__/PocketALBApplication.spec.ts.snap b/packages/terraform-modules/src/pocket/__snapshots__/PocketALBApplication.spec.ts.snap index 0bde784fc..07314a46f 100644 --- a/packages/terraform-modules/src/pocket/__snapshots__/PocketALBApplication.spec.ts.snap +++ b/packages/terraform-modules/src/pocket/__snapshots__/PocketALBApplication.spec.ts.snap @@ -130,6 +130,12 @@ exports[`PocketALBApplication renders a Pocket App with attached persistent stor } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -815,6 +821,12 @@ exports[`PocketALBApplication renders a Pocket App with attached waf 1`] = ` } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -1418,6 +1430,14 @@ exports[`PocketALBApplication renders an Pocket App with code deploy 1`] = ` } }, "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + }, + "ecs-clusterName": { + "description": "ECS Cluster Name", + "value": "\${aws_ecs_cluster.testPocketApp_ecs_cluster_C3960066.name}" + }, "ecs-codedeploy-app": { "description": "ECS Code Deploy App", "value": "\${aws_codedeploy_app.testPocketApp_ecs_service_ecs_codedeploy_ecs_code_deploy_480D0565.name}" @@ -1426,6 +1446,10 @@ exports[`PocketALBApplication renders an Pocket App with code deploy 1`] = ` "description": "ECS Code Deploy Group", "value": "\${aws_codedeploy_deployment_group.testPocketApp_ecs_service_ecs_codedeploy_ecs_codedeploy_deployment_group_44B006D1.deployment_group_name}" }, + "ecs-serviceName": { + "description": "ECS Service Name", + "value": "\${aws_ecs_service.testPocketApp_ecs_service_ecs-service_182DEA4C.name}" + }, "ecs-task-arn": { "description": "ECS Task Definition ARN", "value": "\${aws_ecs_task_definition.testPocketApp_ecs_service_ecs-task_A7E74E45.arn}" @@ -2152,6 +2176,14 @@ exports[`PocketALBApplication renders an Pocket App with code deploy and creates } }, "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + }, + "ecs-clusterName": { + "description": "ECS Cluster Name", + "value": "\${aws_ecs_cluster.testPocketApp_ecs_cluster_C3960066.name}" + }, "ecs-codedeploy-app": { "description": "ECS Code Deploy App", "value": "\${aws_codedeploy_app.testPocketApp_ecs_service_ecs_codedeploy_ecs_code_deploy_480D0565.name}" @@ -2160,6 +2192,10 @@ exports[`PocketALBApplication renders an Pocket App with code deploy and creates "description": "ECS Code Deploy Group", "value": "\${aws_codedeploy_deployment_group.testPocketApp_ecs_service_ecs_codedeploy_ecs_codedeploy_deployment_group_44B006D1.deployment_group_name}" }, + "ecs-serviceName": { + "description": "ECS Service Name", + "value": "\${aws_ecs_service.testPocketApp_ecs_service_ecs-service_182DEA4C.name}" + }, "ecs-task-arn": { "description": "ECS Task Definition ARN", "value": "\${aws_ecs_task_definition.testPocketApp_ecs_service_ecs-task_A7E74E45.arn}" @@ -2884,6 +2920,14 @@ exports[`PocketALBApplication renders an Pocket App with code deploy notificatio } }, "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + }, + "ecs-clusterName": { + "description": "ECS Cluster Name", + "value": "\${aws_ecs_cluster.testPocketApp_ecs_cluster_C3960066.name}" + }, "ecs-codedeploy-app": { "description": "ECS Code Deploy App", "value": "\${aws_codedeploy_app.testPocketApp_ecs_service_ecs_codedeploy_ecs_code_deploy_480D0565.name}" @@ -2892,6 +2936,10 @@ exports[`PocketALBApplication renders an Pocket App with code deploy notificatio "description": "ECS Code Deploy Group", "value": "\${aws_codedeploy_deployment_group.testPocketApp_ecs_service_ecs_codedeploy_ecs_codedeploy_deployment_group_44B006D1.deployment_group_name}" }, + "ecs-serviceName": { + "description": "ECS Service Name", + "value": "\${aws_ecs_service.testPocketApp_ecs_service_ecs-service_182DEA4C.name}" + }, "ecs-task-arn": { "description": "ECS Task Definition ARN", "value": "\${aws_ecs_task_definition.testPocketApp_ecs_service_ecs-task_A7E74E45.arn}" @@ -3599,6 +3647,12 @@ exports[`PocketALBApplication renders an Pocket App with custom Alarm Descriptio } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -4246,6 +4300,12 @@ exports[`PocketALBApplication renders an Pocket App with logs and dashboard in a } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -4824,6 +4884,12 @@ exports[`PocketALBApplication renders an application alarms 1`] = ` } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -5425,6 +5491,12 @@ exports[`PocketALBApplication renders an application custom default alarms 1`] = } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -6016,6 +6088,12 @@ exports[`PocketALBApplication renders an application with autoscaling group and } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -6654,6 +6732,12 @@ exports[`PocketALBApplication renders an application with custom task sizes 1`] } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -7232,6 +7316,12 @@ exports[`PocketALBApplication renders an application with default autoscaling gr } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -7870,6 +7960,12 @@ exports[`PocketALBApplication renders an application with minimal config 1`] = ` } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -8448,6 +8544,12 @@ exports[`PocketALBApplication renders an application with modified container def } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -9051,6 +9153,12 @@ exports[`PocketALBApplication renders an external application 1`] = ` } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -9745,6 +9853,12 @@ exports[`PocketALBApplication renders an internal application 1`] = ` } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { @@ -10323,6 +10437,12 @@ exports[`PocketALBApplication renders an internal application with tags 1`] = ` } } }, + "output": { + "ecs-application-url": { + "description": "ECS Application URL", + "value": "testing.bowling.gov" + } + }, "resource": { "aws_acm_certificate": { "testPocketApp_alb_certificate_417C14FF": { diff --git a/packages/tracing/package.json b/packages/tracing/package.json index 829dde6c6..ea6fea300 100644 --- a/packages/tracing/package.json +++ b/packages/tracing/package.json @@ -19,6 +19,7 @@ "dev": "pnpm run build --watch", "format": "eslint --fix", "lint": "eslint --fix-dry-run", + "presemantic-release": "pnpm run build", "semantic-release": "semantic-release" }, "release": { @@ -71,12 +72,12 @@ "@opentelemetry/exporter-trace-otlp-http": "0.52.1", "@opentelemetry/id-generator-aws-xray": "1.2.2", "@opentelemetry/instrumentation": "0.52.1", - "@opentelemetry/instrumentation-aws-sdk": "0.43.0", + "@opentelemetry/instrumentation-aws-sdk": "0.43.1", "@opentelemetry/instrumentation-dataloader": "0.11.0", - "@opentelemetry/instrumentation-express": "0.41.0", + "@opentelemetry/instrumentation-express": "0.41.1", "@opentelemetry/instrumentation-graphql": "0.42.0", "@opentelemetry/instrumentation-http": "0.52.1", - "@opentelemetry/instrumentation-knex": "0.38.0", + "@opentelemetry/instrumentation-knex": "0.39.0", "@opentelemetry/instrumentation-mysql2": "0.40.0", "@opentelemetry/instrumentation-net": "0.38.0", "@opentelemetry/propagator-aws-xray": "1.25.1", @@ -86,23 +87,23 @@ "@opentelemetry/sdk-trace-base": "1.25.1", "@opentelemetry/sdk-trace-node": "1.25.1", "@opentelemetry/semantic-conventions": "1.25.1", - "@prisma/instrumentation": "5.17.0", - "@sentry/node": "8.18.0", - "@sentry/opentelemetry": "8.18.0", + "@prisma/instrumentation": "5.18.0", + "@sentry/node": "8.27.0", + "@sentry/opentelemetry": "8.27.0", "tslib": "2.6.3" }, "devDependencies": { "@jest/globals": "29.7.0", "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "semantic-release": "24.0.0", + "semantic-release": "24.1.0", "semantic-release-monorepo": "8.0.2", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "tsup": "8.1.2", - "typescript": "5.5.3" + "tsup": "8.2.4", + "typescript": "5.5.4" } -} +} \ No newline at end of file diff --git a/packages/ts-logger/eslint.config.mjs b/packages/ts-logger/eslint.config.mjs index 638ac644e..a712c34d6 100644 --- a/packages/ts-logger/eslint.config.mjs +++ b/packages/ts-logger/eslint.config.mjs @@ -1,3 +1,7 @@ import packages from '@pocket-tools/eslint-config/packages'; import tseslint from 'typescript-eslint'; -export default tseslint.config(...packages); +export default tseslint.config(...packages, { + rules: { + '@typescript-eslint/no-require-imports': ['error', { allow: ['/logger$'] }], + }, +}); diff --git a/packages/ts-logger/package.json b/packages/ts-logger/package.json index 2469ff055..b659279df 100644 --- a/packages/ts-logger/package.json +++ b/packages/ts-logger/package.json @@ -21,6 +21,7 @@ "dev": "pnpm run build --watch", "format": "eslint --fix", "lint": "eslint --fix-dry-run", + "presemantic-release": "pnpm run build", "semantic-release": "semantic-release", "test": "jest", "test:watch": "pnpm run test -- --watch" @@ -76,14 +77,14 @@ "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", "@types/morgan": "1.9.9", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "semantic-release": "24.0.0", + "semantic-release": "24.1.0", "semantic-release-monorepo": "8.0.2", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "tsup": "8.1.2", - "typescript": "5.5.3" + "tsup": "8.2.4", + "typescript": "5.5.4" } -} +} \ No newline at end of file diff --git a/packages/ts-logger/src/logger.spec.ts b/packages/ts-logger/src/logger.spec.ts index eb2e0d48b..1021f810e 100644 --- a/packages/ts-logger/src/logger.spec.ts +++ b/packages/ts-logger/src/logger.spec.ts @@ -19,7 +19,7 @@ describe('createLogger', () => { it('Local environment does not write to file', async () => { process.env.NODE_ENV = 'development'; - // eslint-disable-next-line @typescript-eslint/no-var-requires + const createLogger = require('./logger').createLogger; const testLogger = createLogger(); @@ -28,7 +28,7 @@ describe('createLogger', () => { }); it('Test environment writes to files only', async () => { process.env.NODE_ENV = 'test'; - // eslint-disable-next-line @typescript-eslint/no-var-requires + const createLogger = require('./logger').createLogger; const testLogger = createLogger(); @@ -41,7 +41,7 @@ describe('createLogger', () => { it('Dev environment does not write to file', async () => { process.env.NODE_ENV = 'development'; - // eslint-disable-next-line @typescript-eslint/no-var-requires + const createLogger = require('./logger').createLogger; const testLogger = createLogger(); @@ -52,7 +52,7 @@ describe('createLogger', () => { describe('level', () => { it('level is LOG_LEVEL when LOG_LEVEL is defined', () => { process.env.LOG_LEVEL = 'debug'; - // eslint-disable-next-line @typescript-eslint/no-var-requires + const logger = require('./logger').createLogger(); expect(logger.level).toEqual('debug'); }); @@ -65,7 +65,7 @@ describe('createLogger', () => { it('level is debug when NODE_ENV is development', async () => { process.env.NODE_ENV = 'development'; - // eslint-disable-next-line @typescript-eslint/no-var-requires + const createLogger = require('./logger').createLogger; const testLogger = createLogger(); @@ -79,7 +79,7 @@ describe('createLogger', () => { it('level is debug when NODE_ENV is local ', async () => { process.env.NODE_ENV = 'local'; - // eslint-disable-next-line @typescript-eslint/no-var-requires + const createLogger = require('./logger').createLogger; const testLogger = createLogger(); @@ -90,7 +90,7 @@ describe('createLogger', () => { it('Non-dev and non-local do not write to file', async () => { process.env.NODE_ENV = 'production'; - // eslint-disable-next-line @typescript-eslint/no-var-requires + const createLogger = require('./logger').createLogger; const testLogger = createLogger(); @@ -105,7 +105,7 @@ describe('createLogger', () => { expect(logger.defaultMeta.releaseSha).toBeNull(); process.env.RELEASE_SHA = '12345678910'; - // eslint-disable-next-line @typescript-eslint/no-var-requires + const createLogger = require('./logger').createLogger; const testLogger = createLogger(); testLogger.info('test'); @@ -122,7 +122,7 @@ describe('createLogger', () => { it('has a release sha when RELEASE_SHA is not null', () => { process.env.RELEASE_SHA = '12345678910'; - // eslint-disable-next-line @typescript-eslint/no-var-requires + const createLogger = require('./logger').createLogger; const testLogger = createLogger(); testLogger.info('test'); diff --git a/packages/tsconfig/package.json b/packages/tsconfig/package.json index 0ad71ae55..e1dc39aab 100644 --- a/packages/tsconfig/package.json +++ b/packages/tsconfig/package.json @@ -5,14 +5,14 @@ "license": "MIT", "type": "module", "dependencies": { - "@types/node": "^20.14.11", + "@types/node": "^20.16", "ts-node": "10.9.2", "tslib": "2.6.3", - "tsup": "8.1.2", - "typescript": "5.5.3" + "tsup": "8.2.4", + "typescript": "5.5.4" }, "engines": { - "node": "^20.15" + "node": "^20.16" }, "publishConfig": { "access": "public" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae2484eb8..011675a70 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,12 +12,12 @@ importers: specifier: latest version: 7.4.2 husky: - specifier: 9.1.1 - version: 9.1.1 + specifier: 9.1.4 + version: 9.1.4 devDependencies: '@commitlint/cli': - specifier: 19.3.0 - version: 19.3.0(@types/node@20.14.11)(typescript@5.6.0-dev.20240805) + specifier: 19.4.0 + version: 19.4.0(@types/node@20.16.2)(typescript@5.7.0-dev.20240829) '@commitlint/config-conventional': specifier: ^19.2.2 version: 19.2.2 @@ -25,23 +25,23 @@ importers: specifier: workspace:* version: link:packages/eslint-config syncpack: - specifier: ^12.3.3 - version: 12.3.3(typescript@5.6.0-dev.20240805) + specifier: ^12.4.0 + version: 12.4.0(typescript@5.7.0-dev.20240829) tsconfig: specifier: workspace:* version: link:packages/tsconfig turbo: - specifier: ^1.13.4 - version: 1.13.4 + specifier: ^2.1.0 + version: 2.1.0 infrastructure/account-data-deleter: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -65,26 +65,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/account-delete-monitor: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -108,26 +108,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/annotations-api: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -151,23 +151,23 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/braze: dependencies: '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@pocket-tools/terraform-modules': specifier: workspace:* version: link:../../packages/terraform-modules @@ -185,23 +185,66 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 + + infrastructure/braze-content-proxy: + dependencies: + '@cdktf/provider-aws': + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + '@cdktf/provider-local': + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + '@cdktf/provider-null': + specifier: 10.0.0 + version: 10.0.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + '@cdktf/provider-pagerduty': + specifier: 13.11.4 + version: 13.11.4(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + '@pocket-tools/terraform-modules': + specifier: workspace:* + version: link:../../packages/terraform-modules + cdktf: + specifier: 0.20.8 + version: 0.20.8(constructs@10.3.0) + cdktf-cli: + specifier: 0.20.8 + version: 0.20.8(encoding@0.1.13)(ink@5.0.1(react-devtools-core@4.28.5)(react@18.3.1))(react@18.3.1) + constructs: + specifier: 10.3.0 + version: 10.3.0 + devDependencies: + '@pocket-tools/eslint-config': + specifier: workspace:* + version: link:../../packages/eslint-config + '@types/node': + specifier: ^20.16 + version: 20.16.2 + ts-node: + specifier: 10.9.2 + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) + tsconfig: + specifier: workspace:* + version: link:../../packages/tsconfig + typescript: + specifier: 5.5.4 + version: 5.5.4 infrastructure/client-api: dependencies: '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -209,8 +252,8 @@ importers: specifier: 10.0.0 version: 10.0.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-pagerduty': - specifier: 13.10.2 - version: 13.10.2(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 13.11.4 + version: 13.11.4(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@pocket-tools/terraform-modules': specifier: workspace:* version: link:../../packages/terraform-modules @@ -228,23 +271,23 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/feature-flags: dependencies: '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -268,26 +311,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/fxa-webhook-proxy: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -311,26 +354,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/image-api: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -354,26 +397,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/instant-sync-events: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -397,26 +440,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/list-api: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -440,26 +483,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/parser-graphql-wrapper: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -483,26 +526,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/pocket-event-bridge: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -526,26 +569,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/push-server: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -569,26 +612,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/sendgrid-data: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -612,26 +655,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/shareable-lists-api: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -655,26 +698,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/shared-snowplow-consumer: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -698,26 +741,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/shares-api: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -741,26 +784,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/transactional-emails: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -768,8 +811,8 @@ importers: specifier: 10.0.0 version: 10.0.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-pagerduty': - specifier: 13.10.2 - version: 13.10.2(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 13.11.4 + version: 13.11.4(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@pocket-tools/terraform-modules': specifier: workspace:* version: link:../../packages/terraform-modules @@ -787,23 +830,23 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/user-api: dependencies: '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -827,23 +870,23 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 infrastructure/v3-proxy-api: dependencies: '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -851,8 +894,8 @@ importers: specifier: 10.0.0 version: 10.0.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-pagerduty': - specifier: 13.10.2 - version: 13.10.2(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 13.11.4 + version: 13.11.4(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@pocket-tools/terraform-modules': specifier: workspace:* version: link:../../packages/terraform-modules @@ -870,29 +913,29 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/account-data-deleter-batch-delete: dependencies: '@aws-sdk/client-dynamodb': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/lib-dynamodb': - specifier: 3.609.0 - version: 3.609.0(@aws-sdk/client-dynamodb@3.609.0) + specifier: 3.632.0 + version: 3.632.0(@aws-sdk/client-dynamodb@3.632.0) '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) exponential-backoff: specifier: ^3.1.1 version: 3.1.1 @@ -907,8 +950,8 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 @@ -916,35 +959,35 @@ importers: specifier: 4.17.7 version: 4.17.7 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.5))(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.5))(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/account-data-deleter-events: dependencies: '@aws-sdk/client-lambda': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) fetch-retry: specifier: ^5.0.6 version: 5.0.6 @@ -959,44 +1002,44 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/account-delete-monitor: dependencies: '@aws-sdk/client-dynamodb': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/lib-dynamodb': - specifier: 3.609.0 - version: 3.609.0(@aws-sdk/client-dynamodb@3.609.0) + specifier: 3.632.0 + version: 3.632.0(@aws-sdk/client-dynamodb@3.632.0) '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) exponential-backoff: specifier: ^3.1.1 version: 3.1.1 @@ -1008,38 +1051,38 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/annotations-api-events: dependencies: '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) tslib: specifier: 2.6.3 version: 2.6.3 @@ -1048,32 +1091,32 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/corpus-embeddings-connector-creator: dependencies: @@ -1085,7 +1128,7 @@ importers: version: 8.18.0(@opentelemetry/api@1.9.0) aws-sigv4-fetch: specifier: ^4.0.0 - version: 4.0.0(@aws-sdk/client-sts@3.609.0) + version: 4.0.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) node-fetch: specifier: '2' version: 2.7.0(encoding@0.1.13) @@ -1116,7 +1159,7 @@ importers: version: 14.0.0-beta.6 ts-jest: specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) ts-node: specifier: 10.9.2 version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) @@ -1130,11 +1173,11 @@ importers: lambdas/fxa-webook-proxy-gateway: dependencies: '@aws-sdk/client-sqs': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) jsonwebtoken: specifier: ^9.0.0 version: 9.0.2 @@ -1152,8 +1195,8 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 @@ -1164,41 +1207,41 @@ importers: specifier: ^2.0.1 version: 2.0.3 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/fxa-webook-proxy-sqs: dependencies: '@aws-sdk/client-secrets-manager': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/client-sqs': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) jsonwebtoken: specifier: ^9.0.0 version: 9.0.2 @@ -1213,8 +1256,8 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 @@ -1222,29 +1265,29 @@ importers: specifier: ^9.0.5 version: 9.0.6 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/instant-sync-events: dependencies: @@ -1252,8 +1295,8 @@ importers: specifier: workspace:* version: link:../../packages/lambda-secrets '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) knex: specifier: 3.1.0 version: 3.1.0(mysql2@3.10.3) @@ -1268,50 +1311,50 @@ importers: version: 2.6.3 devDependencies: '@aws-sdk/client-sqs': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@pocket-tools/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/sendgrid-data: dependencies: '@aws-sdk/client-cloudwatch': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/client-firehose': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@sendgrid/client': specifier: ^8.0.0 version: 8.1.3 '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) tslib: specifier: 2.6.3 version: 2.6.3 @@ -1320,35 +1363,35 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/shareable-lists-api-events: dependencies: '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) fetch-retry: specifier: ^5.0.6 version: 5.0.6 @@ -1360,44 +1403,44 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 aws-lambda: specifier: ^1.0.7 version: 1.0.7 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/transactional-emails: dependencies: '@aws-sdk/client-ssm': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) braze-api: specifier: ^2.9.1 version: 2.9.1(encoding@0.1.13) @@ -1412,35 +1455,35 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/user-list-search-corpus-indexing: dependencies: @@ -1448,8 +1491,8 @@ importers: specifier: workspace:* version: link:../../packages/ts-logger '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) fetch-retry: specifier: ^5.0.6 version: 5.0.6 @@ -1461,8 +1504,8 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/elasticsearch': specifier: ^5.0.37 version: 5.0.43 @@ -1470,29 +1513,29 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 aws-lambda: specifier: ^1.0.7 version: 1.0.7 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/user-list-search-corpus-parser-hydration: dependencies: @@ -1500,8 +1543,8 @@ importers: specifier: workspace:* version: link:../../packages/ts-logger '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) fetch-retry: specifier: ^5.0.6 version: 5.0.6 @@ -1516,41 +1559,41 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 aws-lambda: specifier: ^1.0.7 version: 1.0.7 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/user-list-search-events: dependencies: '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) tslib: specifier: 2.6.3 version: 2.6.3 @@ -1559,38 +1602,38 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/user-list-search-indexing: dependencies: '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) nanoid: specifier: 3.3.7 version: 3.3.7 @@ -1602,44 +1645,44 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 lambdas/user-list-search-kinesis-to-sqs: dependencies: '@aws-sdk/client-sqs': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@sentry/aws-serverless': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0) highland: specifier: 2.13.5 version: 2.13.5 @@ -1654,8 +1697,8 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@types/aws-lambda': - specifier: 8.10.141 - version: 8.10.141 + specifier: 8.10.143 + version: 8.10.143 '@types/highland': specifier: ^2.12.11 version: 2.13.0 @@ -1663,29 +1706,29 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 packages/apollo-utils: dependencies: @@ -1699,8 +1742,8 @@ importers: specifier: 4.1.3 version: 4.1.3(@apollo/server@4.10.4(encoding@0.1.13)(graphql@16.8.1))(graphql@16.8.1) '@apollo/subgraph': - specifier: 2.8.3 - version: 2.8.3(graphql@16.8.1) + specifier: 2.9.0 + version: 2.9.0(graphql@16.8.1) '@apollo/utils.keyvadapter': specifier: 3.1.0 version: 3.1.0 @@ -1711,8 +1754,8 @@ importers: specifier: workspace:* version: link:../ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 express: specifier: 4.19.2 version: 4.19.2 @@ -1745,44 +1788,44 @@ importers: specifier: 2.3.5 version: 2.3.5 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ioredis-mock: specifier: 8.9.0 version: 8.9.0(@types/ioredis-mock@8.2.5)(ioredis@5.4.1) jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) semantic-release: - specifier: 24.0.0 - version: 24.0.0(typescript@5.5.3) + specifier: 24.1.0 + version: 24.1.0(typescript@5.5.4) semantic-release-monorepo: specifier: 8.0.2 - version: 8.0.2(semantic-release@24.0.0(typescript@5.5.3)) + version: 8.0.2(semantic-release@24.1.0(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../tsconfig tsup: - specifier: 8.1.2 - version: 8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2) + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 packages/backend-benchmarking: dependencies: chance: - specifier: 1.1.11 - version: 1.1.11 + specifier: 1.1.12 + version: 1.1.12 tslib: specifier: 2.6.3 version: 2.6.3 @@ -1794,26 +1837,26 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../tsconfig tsup: - specifier: 8.1.2 - version: 8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2) + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 packages/eslint-config: dependencies: @@ -1839,11 +1882,11 @@ importers: specifier: ^3.3.3 version: 3.3.3 typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 typescript-eslint: - specifier: ^7.16.1 - version: 7.16.1(eslint@9.7.0)(typescript@5.5.3) + specifier: ^8.2.0 + version: 8.3.0(eslint@9.7.0)(typescript@5.5.4) packages/feature-flags-client: dependencies: @@ -1864,26 +1907,72 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../tsconfig tsup: - specifier: 8.1.2 - version: 8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2) + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 + + packages/image-utils: + dependencies: + parse-url: + specifier: 9.2.0 + version: 9.2.0 + devDependencies: + '@jest/globals': + specifier: 29.7.0 + version: 29.7.0 + '@pocket-tools/eslint-config': + specifier: workspace:* + version: link:../eslint-config + '@types/jest': + specifier: 29.5.12 + version: 29.5.12 + '@types/node': + specifier: ^20.16 + version: 20.16.2 + jest: + specifier: 29.7.0 + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) + jest-extended: + specifier: 4.0.2 + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) + semantic-release: + specifier: 24.1.0 + version: 24.1.0(typescript@5.5.4) + semantic-release-monorepo: + specifier: 8.0.2 + version: 8.0.2(semantic-release@24.1.0(typescript@5.5.4)) + ts-jest: + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) + ts-node: + specifier: 10.9.2 + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) + tsconfig: + specifier: workspace:* + version: link:../tsconfig + tsup: + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) + typescript: + specifier: 5.5.4 + version: 5.5.4 packages/int-mask: dependencies: @@ -1907,26 +1996,26 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../tsconfig tsup: - specifier: 8.1.2 - version: 8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2) + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 packages/lambda-secrets: dependencies: @@ -1944,41 +2033,41 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 semantic-release: - specifier: 24.0.0 - version: 24.0.0(typescript@5.5.3) + specifier: 24.1.0 + version: 24.1.0(typescript@5.5.4) semantic-release-monorepo: specifier: 8.0.2 - version: 8.0.2(semantic-release@24.0.0(typescript@5.5.3)) + version: 8.0.2(semantic-release@24.1.0(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../tsconfig tsup: - specifier: 8.1.2 - version: 8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2) + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 packages/sentry: dependencies: '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 tslib: specifier: 2.6.3 version: 2.6.3 @@ -1996,47 +2085,47 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../tsconfig tsup: - specifier: 8.1.2 - version: 8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2) + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 packages/terraform-modules: dependencies: '@cdktf/provider-archive': - specifier: 10.0.1 - version: 10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 10.1.0 + version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-aws': - specifier: 19.26.0 - version: 19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 19.31.0 + version: 19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-local': specifier: 10.1.0 version: 10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-newrelic': - specifier: 12.10.3 - version: 12.10.3(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 12.12.2 + version: 12.12.2(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-null': specifier: 10.0.0 version: 10.0.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-pagerduty': - specifier: 13.10.2 - version: 13.10.2(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) + specifier: 13.11.4 + version: 13.11.4(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) '@cdktf/provider-time': specifier: 10.2.0 version: 10.2.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0) @@ -2063,35 +2152,35 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 conventional-changelog-conventionalcommits: specifier: 8.0.0 version: 8.0.0 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) semantic-release: - specifier: 24.0.0 - version: 24.0.0(typescript@5.5.3) + specifier: 24.1.0 + version: 24.1.0(typescript@5.5.4) semantic-release-monorepo: specifier: 8.0.2 - version: 8.0.2(semantic-release@24.0.0(typescript@5.5.3)) + version: 8.0.2(semantic-release@24.1.0(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../tsconfig tsup: - specifier: 8.1.2 - version: 8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2) + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 packages/tracing: dependencies: @@ -2117,14 +2206,14 @@ importers: specifier: 0.52.1 version: 0.52.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-aws-sdk': - specifier: 0.43.0 - version: 0.43.0(@opentelemetry/api@1.9.0) + specifier: 0.43.1 + version: 0.43.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-dataloader': specifier: 0.11.0 version: 0.11.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-express': - specifier: 0.41.0 - version: 0.41.0(@opentelemetry/api@1.9.0) + specifier: 0.41.1 + version: 0.41.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-graphql': specifier: 0.42.0 version: 0.42.0(@opentelemetry/api@1.9.0) @@ -2132,8 +2221,8 @@ importers: specifier: 0.52.1 version: 0.52.1(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-knex': - specifier: 0.38.0 - version: 0.38.0(@opentelemetry/api@1.9.0) + specifier: 0.39.0 + version: 0.39.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-mysql2': specifier: 0.40.0 version: 0.40.0(@opentelemetry/api@1.9.0) @@ -2162,14 +2251,14 @@ importers: specifier: 1.25.1 version: 1.25.1 '@prisma/instrumentation': - specifier: 5.17.0 - version: 5.17.0 + specifier: 5.18.0 + version: 5.18.0 '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 '@sentry/opentelemetry': - specifier: 8.18.0 - version: 8.18.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1) + specifier: 8.27.0 + version: 8.27.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1) tslib: specifier: 2.6.3 version: 2.6.3 @@ -2184,32 +2273,32 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) semantic-release: - specifier: 24.0.0 - version: 24.0.0(typescript@5.5.3) + specifier: 24.1.0 + version: 24.1.0(typescript@5.5.4) semantic-release-monorepo: specifier: 8.0.2 - version: 8.0.2(semantic-release@24.0.0(typescript@5.5.3)) + version: 8.0.2(semantic-release@24.1.0(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../tsconfig tsup: - specifier: 8.1.2 - version: 8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2) + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 packages/ts-logger: dependencies: @@ -2233,56 +2322,56 @@ importers: specifier: 1.9.9 version: 1.9.9 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) semantic-release: - specifier: 24.0.0 - version: 24.0.0(typescript@5.5.3) + specifier: 24.1.0 + version: 24.1.0(typescript@5.5.4) semantic-release-monorepo: specifier: 8.0.2 - version: 8.0.2(semantic-release@24.0.0(typescript@5.5.3)) + version: 8.0.2(semantic-release@24.1.0(typescript@5.5.4)) ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../tsconfig tsup: - specifier: 8.1.2 - version: 8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2) + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 packages/tsconfig: dependencies: '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tslib: specifier: 2.6.3 version: 2.6.3 tsup: - specifier: 8.1.2 - version: 8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2) + specifier: 8.2.4 + version: 8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2) typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/account-data-deleter: dependencies: '@aws-sdk/client-sqs': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@pocket-tools/apollo-utils': specifier: workspace:* version: link:../../packages/apollo-utils @@ -2296,8 +2385,8 @@ importers: specifier: workspace:* version: link:../../packages/ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 express: specifier: 4.19.2 version: 4.19.2 @@ -2324,23 +2413,23 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@sentry/types': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 @@ -2348,17 +2437,17 @@ importers: specifier: 7.0.0 version: 7.0.0 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 unleash-client: specifier: 5.6.1 version: 5.6.1 @@ -2375,32 +2464,29 @@ importers: specifier: 4.10.4 version: 4.10.4(encoding@0.1.13)(graphql@16.8.1) '@apollo/subgraph': - specifier: 2.8.3 - version: 2.8.3(graphql@16.8.1) + specifier: 2.9.0 + version: 2.9.0(graphql@16.8.1) '@aws-sdk/client-dynamodb': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/client-sqs': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/lib-dynamodb': - specifier: 3.609.0 - version: 3.609.0(@aws-sdk/client-dynamodb@3.609.0) + specifier: 3.632.0 + version: 3.632.0(@aws-sdk/client-dynamodb@3.632.0) '@pocket-tools/apollo-utils': specifier: workspace:* version: link:../../packages/apollo-utils '@pocket-tools/sentry': specifier: workspace:* version: link:../../packages/sentry - '@pocket-tools/tracing': - specifier: workspace:* - version: link:../../packages/tracing '@pocket-tools/ts-logger': specifier: workspace:* version: link:../../packages/ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 cors: specifier: 2.8.5 version: 2.8.5 @@ -2424,71 +2510,165 @@ importers: version: 5.4.2(graphql@16.8.1) graphql-tag: specifier: 2.12.6 - version: 2.12.6(graphql@16.8.1) - knex: - specifier: 3.1.0 - version: 3.1.0(mysql2@3.10.3) - luxon: - specifier: 3.4.4 - version: 3.4.4 - md5: - specifier: 2.3.0 - version: 2.3.0 - mysql2: - specifier: 3.10.3 - version: 3.10.3 - nanoid: - specifier: 3.3.7 - version: 3.3.7 + version: 2.12.6(graphql@16.8.1) + knex: + specifier: 3.1.0 + version: 3.1.0(mysql2@3.10.3) + luxon: + specifier: 3.4.4 + version: 3.4.4 + md5: + specifier: 2.3.0 + version: 2.3.0 + mysql2: + specifier: 3.10.3 + version: 3.10.3 + nanoid: + specifier: 3.3.7 + version: 3.3.7 + tslib: + specifier: 2.6.3 + version: 2.6.3 + uuid: + specifier: ^9.0.1 + version: 9.0.1 + devDependencies: + '@graphql-codegen/cli': + specifier: 5.0.2 + version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.16.2)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.8.1)(typescript@5.5.4) + '@graphql-codegen/typescript': + specifier: 4.0.9 + version: 4.0.9(encoding@0.1.13)(graphql@16.8.1) + '@graphql-codegen/typescript-resolvers': + specifier: ^4.1.0 + version: 4.2.1(encoding@0.1.13)(graphql@16.8.1) + '@pocket-tools/eslint-config': + specifier: workspace:* + version: link:../../packages/eslint-config + '@sentry/types': + specifier: 8.27.0 + version: 8.27.0 + '@types/chance': + specifier: 1.1.6 + version: 1.1.6 + '@types/jest': + specifier: 29.5.12 + version: 29.5.12 + '@types/md5': + specifier: 2.3.5 + version: 2.3.5 + '@types/node': + specifier: ^20.16 + version: 20.16.2 + '@types/uuid': + specifier: 9.0.8 + version: 9.0.8 + chance: + specifier: 1.1.12 + version: 1.1.12 + jest: + specifier: 29.7.0 + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) + jest-extended: + specifier: 4.0.2 + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) + nock: + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 + nodemon: + specifier: 3.1.4 + version: 3.1.4 + supertest: + specifier: 7.0.0 + version: 7.0.0 + ts-jest: + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) + ts-node: + specifier: 10.9.2 + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) + tsconfig: + specifier: workspace:* + version: link:../../packages/tsconfig + typescript: + specifier: 5.5.4 + version: 5.5.4 + + servers/braze-content-proxy: + dependencies: + '@apollo/client': + specifier: 3.7.17 + version: 3.7.17(graphql-ws@5.16.0(graphql@16.9.0))(graphql@16.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@graphql-typed-document-node/core': + specifier: 3.2.0 + version: 3.2.0(graphql@16.9.0) + '@pocket-tools/sentry': + specifier: workspace:* + version: link:../../packages/sentry + '@pocket-tools/ts-logger': + specifier: workspace:* + version: link:../../packages/ts-logger + '@sentry/node': + specifier: 8.27.0 + version: 8.27.0 + cross-fetch: + specifier: 4.0.0 + version: 4.0.0(encoding@0.1.13) + dataloader: + specifier: 2.2.2 + version: 2.2.2 + express: + specifier: 4.19.2 + version: 4.19.2 + graphql-tag: + specifier: 2.12.6 + version: 2.12.6(graphql@16.9.0) tslib: specifier: 2.6.3 version: 2.6.3 - uuid: - specifier: ^9.0.1 - version: 9.0.1 devDependencies: + '@graphql-codegen/add': + specifier: 5.0.3 + version: 5.0.3(graphql@16.9.0) '@graphql-codegen/cli': specifier: 5.0.2 - version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.14.11)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.8.1)(typescript@5.5.3) + version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.16.2)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.9.0)(typescript@5.5.4) + '@graphql-codegen/typed-document-node': + specifier: 5.0.9 + version: 5.0.9(encoding@0.1.13)(graphql@16.9.0) '@graphql-codegen/typescript': specifier: 4.0.9 - version: 4.0.9(encoding@0.1.13)(graphql@16.8.1) - '@graphql-codegen/typescript-resolvers': - specifier: ^4.1.0 - version: 4.2.1(encoding@0.1.13)(graphql@16.8.1) + version: 4.0.9(encoding@0.1.13)(graphql@16.9.0) + '@graphql-codegen/typescript-operations': + specifier: 4.2.3 + version: 4.2.3(encoding@0.1.13)(graphql@16.9.0) + '@jest/globals': + specifier: 29.7.0 + version: 29.7.0 '@pocket-tools/eslint-config': specifier: workspace:* version: link:../../packages/eslint-config - '@sentry/types': - specifier: 8.18.0 - version: 8.18.0 - '@types/chance': - specifier: 1.1.6 - version: 1.1.6 + '@types/express': + specifier: 4.17.21 + version: 4.17.21 '@types/jest': specifier: 29.5.12 version: 29.5.12 - '@types/md5': - specifier: 2.3.5 - version: 2.3.5 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 - '@types/uuid': - specifier: 9.0.8 - version: 9.0.8 - chance: - specifier: 1.1.11 - version: 1.1.11 + specifier: ^20.16 + version: 20.16.2 + '@types/supertest': + specifier: ^6.0.2 + version: 6.0.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 @@ -2496,17 +2676,17 @@ importers: specifier: 7.0.0 version: 7.0.0 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/feature-flags: dependencies: @@ -2514,8 +2694,8 @@ importers: specifier: 4.10.4 version: 4.10.4(encoding@0.1.13)(graphql@16.8.1) '@apollo/subgraph': - specifier: 2.8.3 - version: 2.8.3(graphql@16.8.1) + specifier: 2.9.0 + version: 2.9.0(graphql@16.8.1) '@govtechsg/passport-openidconnect': specifier: 1.0.2 version: 1.0.2 @@ -2526,8 +2706,8 @@ importers: specifier: workspace:* version: link:../../packages/sentry '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 body-parser: specifier: 1.20.2 version: 1.20.2 @@ -2587,8 +2767,8 @@ importers: specifier: ^9.0.5 version: 9.0.6 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 '@types/passport': specifier: 1.0.16 version: 1.0.16 @@ -2597,25 +2777,25 @@ importers: version: 4.0.1 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/image-api: dependencies: @@ -2623,8 +2803,8 @@ importers: specifier: 4.10.4 version: 4.10.4(encoding@0.1.13)(graphql@16.8.1) '@apollo/subgraph': - specifier: 2.8.3 - version: 2.8.3(graphql@16.8.1) + specifier: 2.9.0 + version: 2.9.0(graphql@16.8.1) '@apollo/utils.keyvadapter': specifier: 3.1.0 version: 3.1.0 @@ -2634,24 +2814,24 @@ importers: '@pocket-tools/apollo-utils': specifier: workspace:* version: link:../../packages/apollo-utils + '@pocket-tools/image-utils': + specifier: workspace:* + version: link:../../packages/image-utils '@pocket-tools/sentry': specifier: workspace:* version: link:../../packages/sentry - '@pocket-tools/tracing': - specifier: workspace:* - version: link:../../packages/tracing '@pocket-tools/ts-logger': specifier: workspace:* version: link:../../packages/ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 axios: - specifier: 1.7.2 - version: 1.7.2 + specifier: 1.7.4 + version: 1.7.4 axios-retry: specifier: 4.4.0 - version: 4.4.0(axios@1.7.2) + version: 4.4.0(axios@1.7.4) dataloader: specifier: 2.2.2 version: 2.2.2 @@ -2667,9 +2847,6 @@ importers: keyv: specifier: 4.5.4 version: 4.5.4 - parse-url: - specifier: 9.2.0 - version: 9.2.0 tslib: specifier: 2.6.3 version: 2.6.3 @@ -2684,17 +2861,17 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 @@ -2702,17 +2879,17 @@ importers: specifier: 7.0.0 version: 7.0.0 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/list-api: dependencies: @@ -2720,17 +2897,17 @@ importers: specifier: 4.10.4 version: 4.10.4(encoding@0.1.13)(graphql@16.8.1) '@apollo/subgraph': - specifier: 2.8.3 - version: 2.8.3(graphql@16.8.1) + specifier: 2.9.0 + version: 2.9.0(graphql@16.8.1) '@aws-sdk/client-eventbridge': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/client-kinesis': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/client-sqs': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@pocket-tools/apollo-cursor-pagination': specifier: 1.0.3 version: 1.0.3 @@ -2743,15 +2920,12 @@ importers: '@pocket-tools/sentry': specifier: workspace:* version: link:../../packages/sentry - '@pocket-tools/tracing': - specifier: workspace:* - version: link:../../packages/tracing '@pocket-tools/ts-logger': specifier: workspace:* version: link:../../packages/ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 '@snowplow/node-tracker': specifier: 3.23.1 version: 3.23.1 @@ -2832,23 +3006,23 @@ importers: specifier: 3.4.2 version: 3.4.2 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 '@types/supertest': specifier: ^6.0.2 version: 6.0.2 chance: - specifier: 1.1.11 - version: 1.1.11 + specifier: 1.1.12 + version: 1.1.12 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 @@ -2856,17 +3030,17 @@ importers: specifier: 7.0.0 version: 7.0.0 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/parser-graphql-wrapper: dependencies: @@ -2880,8 +3054,8 @@ importers: specifier: 4.10.4 version: 4.10.4(encoding@0.1.13)(graphql@16.8.1) '@apollo/subgraph': - specifier: 2.8.3 - version: 2.8.3(graphql@16.8.1) + specifier: 2.9.0 + version: 2.9.0(graphql@16.8.1) '@apollo/utils.keyvadapter': specifier: 3.1.0 version: 3.1.0 @@ -2889,11 +3063,11 @@ importers: specifier: 3.1.0 version: 3.1.0 '@aws-sdk/client-dynamodb': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/lib-dynamodb': - specifier: 3.609.0 - version: 3.609.0(@aws-sdk/client-dynamodb@3.609.0) + specifier: 3.632.0 + version: 3.632.0(@aws-sdk/client-dynamodb@3.632.0) '@extractus/oembed-extractor': specifier: ^3.2.1 version: 3.2.1(encoding@0.1.13) @@ -2906,21 +3080,21 @@ importers: '@pocket-tools/feature-flags-client': specifier: workspace:* version: link:../../packages/feature-flags-client + '@pocket-tools/image-utils': + specifier: workspace:* + version: link:../../packages/image-utils '@pocket-tools/int-mask': specifier: workspace:* version: link:../../packages/int-mask '@pocket-tools/sentry': specifier: workspace:* version: link:../../packages/sentry - '@pocket-tools/tracing': - specifier: workspace:* - version: link:../../packages/tracing '@pocket-tools/ts-logger': specifier: workspace:* version: link:../../packages/ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 cors: specifier: 2.8.5 version: 2.8.5 @@ -2960,6 +3134,9 @@ importers: luxon: specifier: 3.4.4 version: 3.4.4 + markdown-to-txt: + specifier: 2.0.1 + version: 2.0.1 md5: specifier: 2.3.0 version: 2.3.0 @@ -2990,7 +3167,7 @@ importers: version: 8.4.1 '@graphql-codegen/cli': specifier: 5.0.2 - version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.14.11)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.8.1)(typescript@5.5.3) + version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.16.2)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.8.1)(typescript@5.5.4) '@graphql-codegen/typescript': specifier: 4.0.9 version: 4.0.9(encoding@0.1.13)(graphql@16.8.1) @@ -3010,23 +3187,23 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 '@types/turndown': - specifier: 5.0.4 - version: 5.0.4 + specifier: 5.0.5 + version: 5.0.5 concurrently: specifier: ^8.2.2 version: 8.2.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) kysely-codegen: specifier: ^0.15.0 version: 0.15.0(kysely@0.27.3)(mysql2@3.10.3)(pg@8.12.0)(tarn@3.0.2) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 @@ -3034,26 +3211,26 @@ importers: specifier: 7.0.0 version: 7.0.0 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/push-server: dependencies: '@aws-sdk/client-sqs': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 apns2: specifier: 11.7.0 version: 11.7.0 @@ -3080,29 +3257,29 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 '@types/node-gcm': specifier: ^1.0.5 version: 1.0.5 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nodemon: specifier: 3.1.4 version: 3.1.4 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/shareable-lists-api: dependencies: @@ -3113,8 +3290,8 @@ importers: specifier: 4.1.3 version: 4.1.3(@apollo/server@4.10.4(encoding@0.1.13)(graphql@16.8.1))(graphql@16.8.1) '@apollo/subgraph': - specifier: 2.8.3 - version: 2.8.3(graphql@16.8.1) + specifier: 2.9.0 + version: 2.9.0(graphql@16.8.1) '@apollo/utils.keyvadapter': specifier: 3.1.0 version: 3.1.0 @@ -3122,8 +3299,8 @@ importers: specifier: 3.1.0 version: 3.1.0 '@aws-sdk/client-eventbridge': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@keyv/redis': specifier: 2.8.5 version: 2.8.5 @@ -3137,11 +3314,11 @@ importers: specifier: workspace:* version: link:../../packages/ts-logger '@prisma/client': - specifier: 5.14.0 - version: 5.14.0(prisma@5.14.0) + specifier: 5.18.0 + version: 5.18.0(prisma@5.18.0) '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 cors: specifier: 2.8.5 version: 2.8.5 @@ -3170,8 +3347,8 @@ importers: specifier: 3.10.3 version: 3.10.3 prisma: - specifier: 5.14.0 - version: 5.14.0 + specifier: 5.18.0 + version: 5.18.0 prisma-kysely: specifier: 1.8.0 version: 1.8.0(encoding@0.1.13) @@ -3198,17 +3375,17 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 dotenv: specifier: 16.4.5 version: 16.4.5 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) nodemon: specifier: 3.1.4 version: 3.1.4 @@ -3216,38 +3393,35 @@ importers: specifier: 7.0.0 version: 7.0.0 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/shared-snowplow-consumer: dependencies: '@aws-sdk/client-sqs': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@pocket-tools/apollo-utils': specifier: workspace:* version: link:../../packages/apollo-utils '@pocket-tools/sentry': specifier: workspace:* version: link:../../packages/sentry - '@pocket-tools/tracing': - specifier: workspace:* - version: link:../../packages/tracing '@pocket-tools/ts-logger': specifier: workspace:* version: link:../../packages/ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 '@snowplow/node-tracker': specifier: 3.23.1 version: 3.23.1 @@ -3271,35 +3445,35 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@snowplow/snowtype': - specifier: ^0.7.1 - version: 0.7.1(commander@12.1.0)(encoding@0.1.13) + specifier: ^0.8.2 + version: 0.8.2(commander@12.1.0)(encoding@0.1.13) '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/shares-api: dependencies: @@ -3307,32 +3481,29 @@ importers: specifier: 4.10.4 version: 4.10.4(encoding@0.1.13)(graphql@16.8.1) '@apollo/subgraph': - specifier: 2.8.3 - version: 2.8.3(graphql@16.8.1) + specifier: 2.9.0 + version: 2.9.0(graphql@16.8.1) '@aws-sdk/client-dynamodb': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/client-eventbridge': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/lib-dynamodb': - specifier: 3.609.0 - version: 3.609.0(@aws-sdk/client-dynamodb@3.609.0) + specifier: 3.632.0 + version: 3.632.0(@aws-sdk/client-dynamodb@3.632.0) '@pocket-tools/apollo-utils': specifier: workspace:* version: link:../../packages/apollo-utils '@pocket-tools/sentry': specifier: workspace:* version: link:../../packages/sentry - '@pocket-tools/tracing': - specifier: workspace:* - version: link:../../packages/tracing '@pocket-tools/ts-logger': specifier: workspace:* version: link:../../packages/ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 '@snowplow/tracker-core': specifier: 3.23.1 version: 3.23.1 @@ -3363,7 +3534,7 @@ importers: devDependencies: '@graphql-codegen/cli': specifier: 5.0.2 - version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.14.11)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.8.1)(typescript@5.5.3) + version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.16.2)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.8.1)(typescript@5.5.4) '@graphql-codegen/typescript': specifier: 4.0.9 version: 4.0.9(encoding@0.1.13)(graphql@16.8.1) @@ -3380,20 +3551,20 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 concurrently: specifier: ^8.2.2 version: 8.2.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 @@ -3401,17 +3572,17 @@ importers: specifier: 7.0.0 version: 7.0.0 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/user-api: dependencies: @@ -3419,11 +3590,11 @@ importers: specifier: 4.10.4 version: 4.10.4(encoding@0.1.13)(graphql@16.8.1) '@apollo/subgraph': - specifier: 2.8.3 - version: 2.8.3(graphql@16.8.1) + specifier: 2.9.0 + version: 2.9.0(graphql@16.8.1) '@aws-sdk/client-eventbridge': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@pocket-tools/apollo-utils': specifier: workspace:* version: link:../../packages/apollo-utils @@ -3433,15 +3604,12 @@ importers: '@pocket-tools/sentry': specifier: workspace:* version: link:../../packages/sentry - '@pocket-tools/tracing': - specifier: workspace:* - version: link:../../packages/tracing '@pocket-tools/ts-logger': specifier: workspace:* version: link:../../packages/ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 dataloader: specifier: 2.2.2 version: 2.2.2 @@ -3474,26 +3642,26 @@ importers: specifier: workspace:* version: link:../../packages/eslint-config '@sentry/types': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 '@types/jest': specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 '@types/supertest': specifier: ^6.0.2 version: 6.0.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-mock-req-res: specifier: 1.0.2 - version: 1.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 1.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 @@ -3501,17 +3669,17 @@ importers: specifier: 7.0.0 version: 7.0.0 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 servers/user-list-search: dependencies: @@ -3519,14 +3687,14 @@ importers: specifier: 4.10.4 version: 4.10.4(encoding@0.1.13)(graphql@16.8.1) '@apollo/subgraph': - specifier: 2.8.3 - version: 2.8.3(graphql@16.8.1) + specifier: 2.9.0 + version: 2.9.0(graphql@16.8.1) '@aws-sdk/client-eventbridge': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@aws-sdk/client-sqs': - specifier: 3.609.0 - version: 3.609.0 + specifier: 3.632.0 + version: 3.632.0 '@elastic/elasticsearch': specifier: ^8.14.0 version: 8.14.0 @@ -3545,15 +3713,12 @@ importers: '@pocket-tools/sentry': specifier: workspace:* version: link:../../packages/sentry - '@pocket-tools/tracing': - specifier: workspace:* - version: link:../../packages/tracing '@pocket-tools/ts-logger': specifier: workspace:* version: link:../../packages/ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 elastic-builder: specifier: ^2.29.0 version: 2.29.0 @@ -3599,7 +3764,7 @@ importers: version: 8.4.1 '@graphql-codegen/cli': specifier: 5.0.2 - version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.14.11)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.8.1)(typescript@5.5.3) + version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.16.2)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.8.1)(typescript@5.5.4) '@graphql-codegen/typescript': specifier: 4.0.9 version: 4.0.9(encoding@0.1.13)(graphql@16.8.1) @@ -3613,8 +3778,8 @@ importers: specifier: 3.23.1 version: 3.23.1 '@snowplow/snowtype': - specifier: ^0.7.1 - version: 0.7.1(commander@12.1.0)(encoding@0.1.13) + specifier: ^0.8.2 + version: 0.8.2(commander@12.1.0)(encoding@0.1.13) '@types/elasticsearch': specifier: ^5.0.37 version: 5.0.43 @@ -3630,6 +3795,9 @@ importers: '@types/mysql': specifier: 2.15.26 version: 2.15.26 + '@types/node': + specifier: ^20.16 + version: 20.16.2 '@types/supertest': specifier: ^6.0.2 version: 6.0.2 @@ -3641,13 +3809,13 @@ importers: version: 8.2.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-extended: specifier: 4.0.2 - version: 4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))) + version: 4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 @@ -3655,17 +3823,17 @@ importers: specifier: 7.0.0 version: 7.0.0 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 unleash-client: specifier: 5.6.1 version: 5.6.1 @@ -3681,15 +3849,12 @@ importers: '@pocket-tools/sentry': specifier: workspace:* version: link:../../packages/sentry - '@pocket-tools/tracing': - specifier: workspace:* - version: link:../../packages/tracing '@pocket-tools/ts-logger': specifier: workspace:* version: link:../../packages/ts-logger '@sentry/node': - specifier: 8.18.0 - version: 8.18.0 + specifier: 8.27.0 + version: 8.27.0 express: specifier: 4.19.2 version: 4.19.2 @@ -3711,7 +3876,7 @@ importers: version: 5.0.3(graphql@16.9.0) '@graphql-codegen/cli': specifier: 5.0.2 - version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.14.11)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.9.0)(typescript@5.5.3) + version: 5.0.2(@parcel/watcher@2.4.1)(@types/node@20.16.2)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.9.0)(typescript@5.5.4) '@graphql-codegen/typed-document-node': specifier: 5.0.9 version: 5.0.9(encoding@0.1.13)(graphql@16.9.0) @@ -3731,17 +3896,17 @@ importers: specifier: 29.5.12 version: 29.5.12 '@types/node': - specifier: ^20.14.11 - version: 20.14.11 + specifier: ^20.16 + version: 20.16.2 '@types/supertest': specifier: ^6.0.2 version: 6.0.2 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + version: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) nock: - specifier: 14.0.0-beta.6 - version: 14.0.0-beta.6 + specifier: 14.0.0-beta.11 + version: 14.0.0-beta.11 nodemon: specifier: 3.1.4 version: 3.1.4 @@ -3749,17 +3914,17 @@ importers: specifier: 7.0.0 version: 7.0.0 ts-jest: - specifier: 29.2.3 - version: 29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3) + specifier: 29.2.4 + version: 29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4) ts-node: specifier: 10.9.2 - version: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + version: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) tsconfig: specifier: workspace:* version: link:../../packages/tsconfig typescript: - specifier: 5.5.3 - version: 5.5.3 + specifier: 5.5.4 + version: 5.5.4 packages: @@ -3795,14 +3960,32 @@ packages: peerDependencies: graphql: 14.x || 15.x || 16.x + '@apollo/client@3.7.17': + resolution: {integrity: sha512-0EErSHEtKPNl5wgWikHJbKFAzJ/k11O0WO2QyqZSHpdxdAnw7UWHY4YiLbHCFG7lhrD+NTQ3Z/H9Jn4rcikoJA==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + graphql-ws: ^5.5.5 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + subscriptions-transport-ws: ^0.9.0 || ^0.11.0 + peerDependenciesMeta: + graphql-ws: + optional: true + react: + optional: true + react-dom: + optional: true + subscriptions-transport-ws: + optional: true + '@apollo/datasource-rest@6.3.0': resolution: {integrity: sha512-5YpAXY2VvkYySmaDl8G8Yt8qjOO89cqx7r+uchFjKGacS72L8nKxrLIzltjhQkLpyjwMLFLi2UDSCSMht+qGQA==} engines: {node: '>=16.14'} peerDependencies: graphql: ^16.5.0 - '@apollo/federation-internals@2.8.3': - resolution: {integrity: sha512-5GOeQ1I5C7uCU6ob/TbRGqWg2m+9qo8/8qlGhfaMUqN3ukSCmgkKUDdfg1M6sB3lDmIoL5tAoSkmJegKSaDR5A==} + '@apollo/federation-internals@2.9.0': + resolution: {integrity: sha512-zvz0nJpfblxAWzphlFtyqUswidIWOf7Vcj4YuPaUlXpOG7VZ0fWyTupPQsj0HeTkAAy3FzCItVHLzn4+I2H/YA==} engines: {node: '>=14.15.0'} peerDependencies: graphql: ^16.5.0 @@ -3829,8 +4012,8 @@ packages: peerDependencies: graphql: ^16.6.0 - '@apollo/subgraph@2.8.3': - resolution: {integrity: sha512-n00rjSstDEdD58Ug+9wCzOffrFcx6SAszKkYF/X1ugzBUruKNun+7S7wgd8m3KXImZwwQ5WTLiISBtTC8PRYsg==} + '@apollo/subgraph@2.9.0': + resolution: {integrity: sha512-FYAOMxMWbAQ/2U/+QYgznBdsyjPiH87wSSJqn6n1dQ80GWIWenZYd49iWy9/y/Z/RTYsA2o8ueAkgHH6AU4psA==} engines: {node: '>=14.15.0'} peerDependencies: graphql: ^16.5.0 @@ -3945,110 +4128,154 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-cloudwatch@3.609.0': - resolution: {integrity: sha512-nPKP38NHx559JhDCA7Df4RX1vkljeLrJycKkNLSZPrVBy3/rHxaRxh8sQBrlXBJdtjD3iY0urSthTEnxyyMcBQ==} + '@aws-sdk/client-cloudwatch@3.632.0': + resolution: {integrity: sha512-RIItCf874T8aiE17yikJ6VcARvRv/sn86WMpyJCN0+aUMSOB8X86OHe7KCUN72EkvFKeWXim808RPpS8fZLXKw==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-dynamodb@3.609.0': - resolution: {integrity: sha512-eu4JWHYzUukqMV+gfZLZbSPoC+KOLzhfGQn/HkSg8/utSiUEi4TjuNtVyWlBaSBDJ3T7rQQKRqTpDrkGS3ZWiQ==} + '@aws-sdk/client-dynamodb@3.632.0': + resolution: {integrity: sha512-Y7u/B/lyLdLZBrBSXjYZviyck0e3dZLL/Va6HIShNlDG8FyWuArefWr57/bu9Q8smdqpEduldprSRSWI7MPykg==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-eventbridge@3.609.0': - resolution: {integrity: sha512-wkVzHUmo/q1vOC+z+WL7WmXrd5TIVv9on0upxknqg5E8CvdVF8jis4GuDhy+dMltRNr0d2/zfRXDq4GcjHz3GQ==} + '@aws-sdk/client-eventbridge@3.632.0': + resolution: {integrity: sha512-G/0TXGgNFKcKLWI83w9v85ORrKpL3+5QKolruNA7qTX0XmMejO82+lkgZ7woEwP9PGMwS73mQli1ltrt5aqHTQ==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-firehose@3.609.0': - resolution: {integrity: sha512-02AIDsABJwT02dqjZmJPhcPATd5F+QY8gGEyH7dvhM+4UUWCiTZoq6JVAkLEFEJahGUfQZPtwzQLOQcJCNZ+8w==} + '@aws-sdk/client-firehose@3.632.0': + resolution: {integrity: sha512-akrXx3T+bVbnbkEuGnfK5nQEecys4vH20egkcI+4pN+qmfBlwkdxaC/LJVsroYdz+99Ownjkz0fV6OGfj2O3JA==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-kinesis@3.609.0': - resolution: {integrity: sha512-TmNPLf9+se/KiPBllC2mkyXrv+U/oU63Zqanfd8KPZRyMMGx1wwNWQCpAbjlgsorXo3m8pR51WKxxaPChAH15g==} + '@aws-sdk/client-kinesis@3.632.0': + resolution: {integrity: sha512-4CVhckeqvpWKATFwKdwysbnaJY9e9+zmJnnH8fQqqfOqijoH2KNkygPCFoiRKwYl+UHl99KDu1Vt8+/3M490Ug==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-lambda@3.609.0': - resolution: {integrity: sha512-+us5UQmuZu7Qd33l9xt2TZ2TAT4LWY7QfjSCUaaR8/LRNG6af1LvKfdxSC5iYU+jjb6Yrc1FITH/IoNxbjD6NQ==} + '@aws-sdk/client-lambda@3.632.0': + resolution: {integrity: sha512-vF4KRuHGr6EfW+dssm56S6b+jAa8dKqdWduHNms1TQFah0iOkjc9Dpo4p4j6bobZcuricGko/OZy9ynb1Dwldg==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-secrets-manager@3.609.0': - resolution: {integrity: sha512-1vDLUl0TuZx7TATsYkIaKj9etNzTpFVF95FpfFnJeyen397tYLot5sUNkcMCJvOLbdNVnJo1o5F8GNfU776EIQ==} + '@aws-sdk/client-secrets-manager@3.632.0': + resolution: {integrity: sha512-WsQhPHHK1yPfALcP1B7nBSGDzky6vFTUEXnUdfzb5Xy2cT+JTBTS6ChtQGqqOuGHDP/3t/9soqZ+L6rUCYBb/Q==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-sqs@3.609.0': - resolution: {integrity: sha512-0cJsOWp1AOt7MYNdpq8k0nDY5g2twXdnTcryljubIXJJMrORSd4p9YtH3X8auJaqb9vd2t/D8XhoJTNbTC/4lQ==} + '@aws-sdk/client-sqs@3.632.0': + resolution: {integrity: sha512-UK4JQ6nF6qDtc2rLdrYTgyZWTdUgfVHbVHQdHkrni2TNac3kEksgiDFxsm6zQjy1NoOg4YdPDeMOeHRvWImlPQ==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-ssm@3.609.0': - resolution: {integrity: sha512-65pwaO0rZs1sC6YrZ3cmZp6rvkIYkjhZt1TPCB5TpMvYeIpqRgoMc9edtsHWtO1MaEjda2v1uTpimQxuJ23Z/w==} + '@aws-sdk/client-ssm@3.632.0': + resolution: {integrity: sha512-p9QZguhC6NB6CQTFgLcYhU1yhGF7SN9kDMtFwtFBxTPO/SQJ/PJcEyL40yXPbuPUXFtT/YRhT9mIwQagfkXzAA==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-sso-oidc@3.609.0': - resolution: {integrity: sha512-0bNPAyPdkWkS9EGB2A9BZDkBNrnVCBzk5lYRezoT4K3/gi9w1DTYH5tuRdwaTZdxW19U1mq7CV0YJJARKO1L9Q==} + '@aws-sdk/client-sso-oidc@3.632.0': + resolution: {integrity: sha512-Oh1fIWaoZluihOCb/zDEpRTi+6an82fgJz7fyRBugyLhEtDjmvpCQ3oKjzaOhoN+4EvXAm1ZS/ZgpvXBlIRTgw==} engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-sts': ^3.609.0 + '@aws-sdk/client-sts': ^3.632.0 '@aws-sdk/client-sso@3.609.0': resolution: {integrity: sha512-gqXGFDkIpKHCKAbeJK4aIDt3tiwJ26Rf5Tqw9JS6BYXsdMeOB8FTzqD9R+Yc1epHd8s5L94sdqXT5PapgxFZrg==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-sts@3.609.0': - resolution: {integrity: sha512-A0B3sDKFoFlGo8RYRjDBWHXpbgirer2bZBkCIzhSPHc1vOFHt/m2NcUoE2xnBKXJFrptL1xDkvo1P+XYp/BfcQ==} + '@aws-sdk/client-sso@3.632.0': + resolution: {integrity: sha512-iYWHiKBz44m3chCFvtvHnvCpL2rALzyr1e6tOZV3dLlOKtQtDUlPy6OtnXDu4y+wyJCniy8ivG3+LAe4klzn1Q==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/client-sts@3.632.0': + resolution: {integrity: sha512-Ss5cBH09icpTvT+jtGGuQlRdwtO7RyE9BF4ZV/CEPATdd9whtJt4Qxdya8BUnkWR7h5HHTrQHqai3YVYjku41A==} engines: {node: '>=16.0.0'} '@aws-sdk/core@3.609.0': resolution: {integrity: sha512-ptqw+DTxLr01+pKjDUuo53SEDzI+7nFM3WfQaEo0yhDg8vWw8PER4sWj1Ysx67ksctnZesPUjqxd5SHbtdBxiA==} engines: {node: '>=16.0.0'} + '@aws-sdk/core@3.629.0': + resolution: {integrity: sha512-+/ShPU/tyIBM3oY1cnjgNA/tFyHtlWq+wXF9xEKRv19NOpYbWQ+xzNwVjGq8vR07cCRqy/sDQLWPhxjtuV/FiQ==} + engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-env@3.609.0': resolution: {integrity: sha512-v69ZCWcec2iuV9vLVJMa6fAb5xwkzN4jYIT8yjo2c4Ia/j976Q+TPf35Pnz5My48Xr94EFcaBazrWedF+kwfuQ==} engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-env@3.620.1': + resolution: {integrity: sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg==} + engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-http@3.609.0': resolution: {integrity: sha512-GQQfB9Mk4XUZwaPsk4V3w8MqleS6ApkZKVQn3vTLAKa8Y7B2Imcpe5zWbKYjDd8MPpMWjHcBGFTVlDRFP4zwSQ==} engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-http@3.622.0': + resolution: {integrity: sha512-VUHbr24Oll1RK3WR8XLUugLpgK9ZuxEm/NVeVqyFts1Ck9gsKpRg1x4eH7L7tW3SJ4TDEQNMbD7/7J+eoL2svg==} + engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-ini@3.609.0': resolution: {integrity: sha512-hwaBfXuBTv6/eAdEsDfGcteYUW6Km7lvvubbxEdxIuJNF3vswR7RMGIXaEC37hhPkTTgd3H0TONammhwZIfkog==} engines: {node: '>=16.0.0'} peerDependencies: '@aws-sdk/client-sts': ^3.609.0 + '@aws-sdk/credential-provider-ini@3.632.0': + resolution: {integrity: sha512-m6epoW41xa1ajU5OiHcmQHoGVtrbXBaRBOUhlCLZmcaqMLYsboM4iD/WZP8aatKEON5tTnVXh/4StV8D/+wemw==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sts': ^3.632.0 + '@aws-sdk/credential-provider-node@3.609.0': resolution: {integrity: sha512-4J8/JRuqfxJDGD9jTHVCBxCvYt7/Vgj2Stlhj930mrjFPO/yRw8ilAAZxBWe0JHPX3QwepCmh4ErZe53F5ysxQ==} engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-node@3.632.0': + resolution: {integrity: sha512-cL8fuJWm/xQBO4XJPkeuZzl3XinIn9EExWgzpG48NRMKR5us1RI/ucv7xFbBBaG+r/sDR2HpYBIA3lVIpm1H3Q==} + engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-process@3.609.0': resolution: {integrity: sha512-Ux35nGOSJKZWUIM3Ny0ROZ8cqPRUEkh+tR3X2o9ydEbFiLq3eMMyEnHJqx4EeUjLRchidlm4CCid9GxMe5/gdw==} engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-process@3.620.1': + resolution: {integrity: sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==} + engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-sso@3.609.0': resolution: {integrity: sha512-oQPGDKMMIxjvTcm86g07RPYeC7mCNk+29dPpY15ZAPRpAF7F0tircsC3wT9fHzNaKShEyK5LuI5Kg/uxsdy+Iw==} engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-sso@3.632.0': + resolution: {integrity: sha512-P/4wB6j7ym5QCPTL2xlMfvf2NcXSh+z0jmsZP4WW/tVwab4hvgabPPbLeEZDSWZ0BpgtxKGvRq0GSHuGeirQbA==} + engines: {node: '>=16.0.0'} + '@aws-sdk/credential-provider-web-identity@3.609.0': resolution: {integrity: sha512-U+PG8NhlYYF45zbr1km3ROtBMYqyyj/oK8NRp++UHHeuavgrP+4wJ4wQnlEaKvJBjevfo3+dlIBcaeQ7NYejWg==} engines: {node: '>=16.0.0'} peerDependencies: '@aws-sdk/client-sts': ^3.609.0 + '@aws-sdk/credential-provider-web-identity@3.621.0': + resolution: {integrity: sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sts': ^3.621.0 + '@aws-sdk/endpoint-cache@3.572.0': resolution: {integrity: sha512-CzuRWMj/xtN9p9eP915nlPmlyniTzke732Ow/M60++gGgB3W+RtZyFftw3TEx+NzNhd1tH54dEcGiWdiNaBz3Q==} engines: {node: '>=16.0.0'} - '@aws-sdk/lib-dynamodb@3.609.0': - resolution: {integrity: sha512-V7oWCktXvuZxcXhj3oKmSrkmIQg13yYpamgkAACUzuqUAG1ISPEUGTHYhSImkg4efHQkwHlfJgU5RL9Ya4wsLw==} + '@aws-sdk/lib-dynamodb@3.632.0': + resolution: {integrity: sha512-8QBjfCEKPOpU2stxCJ/DGDL7Gb1tzgwPwC1XLMzLW3rR94EcrlmJatEBXIHbGQypVvHVdwu3xILDrp4qn6P+Sg==} engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-dynamodb': ^3.609.0 + '@aws-sdk/client-dynamodb': ^3.632.0 - '@aws-sdk/middleware-endpoint-discovery@3.609.0': - resolution: {integrity: sha512-HnjoduqkbsU+x7V+SF/h0/fxBKzG9ABlYteR2yiZEVyY70o2Wtt7fh4mZoVvpyuDEFCsYnLk9Ve0+7mNo7+pWA==} + '@aws-sdk/middleware-endpoint-discovery@3.620.0': + resolution: {integrity: sha512-T6kuydHBF4BPP5CVH53Fze7c2b9rqxWP88XrGtmNMXXdY4sXur1v/itGdS2l3gqRjxKo0LsmjmuQm9zL4vGneQ==} engines: {node: '>=16.0.0'} '@aws-sdk/middleware-host-header@3.609.0': resolution: {integrity: sha512-iTKfo158lc4jLDfYeZmYMIBHsn8m6zX+XB6birCSNZ/rrlzAkPbGE43CNdKfvjyWdqgLMRXF+B+OcZRvqhMXPQ==} engines: {node: '>=16.0.0'} + '@aws-sdk/middleware-host-header@3.620.0': + resolution: {integrity: sha512-VMtPEZwqYrII/oUkffYsNWY9PZ9xpNJpMgmyU0rlDQ25O1c0Hk3fJmZRe6pEkAJ0omD7kLrqGl1DUjQVxpd/Rg==} + engines: {node: '>=16.0.0'} + '@aws-sdk/middleware-logger@3.609.0': resolution: {integrity: sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==} engines: {node: '>=16.0.0'} @@ -4057,28 +4284,36 @@ packages: resolution: {integrity: sha512-6sewsYB7/o/nbUfA99Aa/LokM+a/u4Wpm/X2o0RxOsDtSB795ObebLJe2BxY5UssbGaWkn7LswyfvrdZNXNj1w==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-sdk-s3@3.609.0': - resolution: {integrity: sha512-kvwjL6OJFhAGWoYaIWR7HmILjiVk6xVj6QEU6qZMA7FtGgvlKi4pLfs8Of+hQqo+2TEhUoxG/5t6WqwB8uxjsw==} + '@aws-sdk/middleware-recursion-detection@3.620.0': + resolution: {integrity: sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-sdk-sqs@3.609.0': - resolution: {integrity: sha512-0rbOiErKuKIc9fLyjiqtjgAcUt6yBBcXVwta/q+W7WLxJbNtkTfGKfKhxPtp0+5S8EyljMpg2rITBCJzNRXjiA==} + '@aws-sdk/middleware-sdk-s3@3.629.0': + resolution: {integrity: sha512-FRXLcnPWXBoq/T9mnGnrpqhrSKNSm22rqJ0L7P14KESmbGuwhF/7ELYYxXIpgnIpb/CIUVmIU5EE8lsW1VTe8A==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-signing@3.609.0': - resolution: {integrity: sha512-2w3dBLjQVKIajYzokO4hduq8/0hSMUYHHmIo1Kdl+MSY8uwRBt12bLL6pyreobTcRMxizvn2ph/CQ9I1ST/WGQ==} + '@aws-sdk/middleware-sdk-sqs@3.622.0': + resolution: {integrity: sha512-kOPX94jlVcvH7Wutzag99L+BSjT6LjXxW7Ntc02/oywYX6Gft4YdbeUYdcGYYHWDy/IT6jJ2wMJfFUEEh8U/9A==} engines: {node: '>=16.0.0'} '@aws-sdk/middleware-user-agent@3.609.0': resolution: {integrity: sha512-nbq7MXRmeXm4IDqh+sJRAxGPAq0OfGmGIwKvJcw66hLoG8CmhhVMZmIAEBDFr57S+YajGwnLLRt+eMI05MMeVA==} engines: {node: '>=16.0.0'} + '@aws-sdk/middleware-user-agent@3.632.0': + resolution: {integrity: sha512-yY/sFsHKwG9yzSf/DTclqWJaGPI2gPBJDCGBujSqTG1zlS7Ot4fqi91DZ6088BFWzbOorDzJFcAhAEFzc6LuQg==} + engines: {node: '>=16.0.0'} + '@aws-sdk/region-config-resolver@3.609.0': resolution: {integrity: sha512-lMHBG8zg9GWYBc9/XVPKyuAUd7iKqfPP7z04zGta2kGNOKbUTeqmAdc1gJGku75p4kglIPlGBorOxti8DhRmKw==} engines: {node: '>=16.0.0'} - '@aws-sdk/signature-v4-multi-region@3.609.0': - resolution: {integrity: sha512-FJs0BxVMyYOKNu7nzFI1kehfgWoYmdto5B8BSS29geUACF7jlOoeCfNZWVrnMjvAxVlSQ5O7Mr575932BnsycA==} + '@aws-sdk/region-config-resolver@3.614.0': + resolution: {integrity: sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==} + engines: {node: '>=16.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.629.0': + resolution: {integrity: sha512-GPX6dnmuLGDFp7CsGqGCzleEoNyr9ekgOzSBtcL5nKX++NruxO7f1QzJAbcYvz0gdKvz958UO0EKsGM6hnkTSg==} engines: {node: '>=16.0.0'} '@aws-sdk/token-providers@3.609.0': @@ -4087,6 +4322,12 @@ packages: peerDependencies: '@aws-sdk/client-sso-oidc': ^3.609.0 + '@aws-sdk/token-providers@3.614.0': + resolution: {integrity: sha512-okItqyY6L9IHdxqs+Z116y5/nda7rHxLvROxtAJdLavWTYDydxrZstImNgGWTeVdmc0xX2gJCI77UYUTQWnhRw==} + engines: {node: '>=16.0.0'} + peerDependencies: + '@aws-sdk/client-sso-oidc': ^3.614.0 + '@aws-sdk/types@3.609.0': resolution: {integrity: sha512-+Tqnh9w0h2LcrUsdXyT1F8mNhXz+tVYBtP19LpeEGntmvHwa2XzvLUCWpoIAIVsHp5+HdB2X9Sn0KAtmbFXc2Q==} engines: {node: '>=16.0.0'} @@ -4095,16 +4336,20 @@ packages: resolution: {integrity: sha512-XUKJWWo+KOB7fbnPP0+g/o5Ulku/X53t7i/h+sPHr5xxYTJJ9CYnbToo95mzxe7xWvkLrsNtJ8L+MnNn9INs2w==} engines: {node: '>=16.0.0'} - '@aws-sdk/util-dynamodb@3.609.0': - resolution: {integrity: sha512-FdXv4M/5Vee6zUuokpXpOPWK9hs6i4Bp4AZNWT2MTvOjUHP4BlP3b7h3Znb3pjjbA522VqDb674hrPXtS4sIWQ==} + '@aws-sdk/util-dynamodb@3.632.0': + resolution: {integrity: sha512-uvfHEk7y9JKLTOXPOQi+GhQLs0Eo09xNNMGk8ptZUeXS4u/Qs6lHKJK6i1khoeeQ6+ASSxmYmTbDhpPqUKGPEg==} engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-dynamodb': ^3.609.0 + '@aws-sdk/client-dynamodb': ^3.632.0 '@aws-sdk/util-endpoints@3.609.0': resolution: {integrity: sha512-Rh+3V8dOvEeE1aQmUy904DYWtLUEJ7Vf5XBPlQ6At3pBhp+zpXbsnpZzVL33c8lW1xfj6YPwtO6gOeEsl1juCQ==} engines: {node: '>=16.0.0'} + '@aws-sdk/util-endpoints@3.632.0': + resolution: {integrity: sha512-LlYMU8pAbcEQphOpE6xaNLJ8kPGhklZZTVzZVpVW477NaaGgoGTMYNXTABYHcxeF5E2lLrxql9OmVpvr8GWN8Q==} + engines: {node: '>=16.0.0'} + '@aws-sdk/util-locate-window@3.568.0': resolution: {integrity: sha512-3nh4TINkXYr+H41QaPelCceEB2FXP3fxp93YZXB/kqJvX0U9j0N0Uk45gvsjmEPzG8XxkPEeLIfT2I1M7A6Lig==} engines: {node: '>=16.0.0'} @@ -4121,6 +4366,15 @@ packages: aws-crt: optional: true + '@aws-sdk/util-user-agent-node@3.614.0': + resolution: {integrity: sha512-15ElZT88peoHnq5TEoEtZwoXTXRxNrk60TZNdpl/TUBJ5oNJ9Dqb5Z4ryb8ofN6nm9aFf59GVAerFDz8iUoHBA==} + engines: {node: '>=16.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + '@babel/code-frame@7.24.2': resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} engines: {node: '>=6.9.0'} @@ -4579,15 +4833,15 @@ packages: '@cdktf/node-pty-prebuilt-multiarch@0.10.1-pre.11': resolution: {integrity: sha512-qvga/nzEtdCJMu/6jJfDqpzbRejvXtNhWFnbubfuYyN5nMNORNXX+POT4j+mQSDQar5bIQ1a812szw/zr47cfw==} - '@cdktf/provider-archive@10.0.1': - resolution: {integrity: sha512-i0hXxK0fA+xkdvYILSAd5GsHilu/kxLl2G9pFuXQppDfXweiGvWYhmPy8FmXdsUPziDF8u+2O2dBuqkc2QdXVA==} + '@cdktf/provider-archive@10.1.0': + resolution: {integrity: sha512-CGRd60dYoAqWjMj9qEaKdWMDdj8fJE3eFYK0oXuhRzcagUdkvKwoqj4gGO+yLekq+x11ZWFwDgjo4cKL3c9j9A==} engines: {node: '>= 18.12.0'} peerDependencies: cdktf: ^0.20.0 constructs: ^10.3.0 - '@cdktf/provider-aws@19.26.0': - resolution: {integrity: sha512-f68ua90d33n7z//uX5FtrCV3kVW6oC/fMET3/cjEc+punuBg1X/a+9Hhn2z+Iu4ferknFhFZS3mwpjyyWH1DMQ==} + '@cdktf/provider-aws@19.31.0': + resolution: {integrity: sha512-zO1wgHsNc5u5VA0zDmGeaQH6PNjYt8Q7Bl4nCGnYR2OXD5gv5Iq/hV85PIirGIA2gmqWOqa+szQNMFEHS1tvow==} engines: {node: '>= 18.12.0'} peerDependencies: cdktf: ^0.20.0 @@ -4603,8 +4857,8 @@ packages: cdktf: ^0.20.0 constructs: ^10.3.0 - '@cdktf/provider-newrelic@12.10.3': - resolution: {integrity: sha512-Zs8dEEtf7UIpUuihdMB5gS4/biM+KOqyj8zwHS/tocMod0GqvNnHaDvl4i1YTsRKXMmBfM/86tv/nIM2RSuzYw==} + '@cdktf/provider-newrelic@12.12.2': + resolution: {integrity: sha512-sm5vn7pzhvpAMZm9VR+bnHzjh9yZQkrWmjJhpS1i+z6B1etbNCuWe/7pLxjAT8PPFNI/+/xTTYaGfMIEzjMWKg==} engines: {node: '>= 18.12.0'} peerDependencies: cdktf: ^0.20.0 @@ -4617,8 +4871,8 @@ packages: cdktf: ^0.20.0 constructs: ^10.3.0 - '@cdktf/provider-pagerduty@13.10.2': - resolution: {integrity: sha512-+X7OLnCC0r2zehPwUunPdtWRUu9OpW2EER6uzck9ZbyS6IP4jLWBR+YXf+vwsndKbFAd8t4wwHlLMi9RGTrMyQ==} + '@cdktf/provider-pagerduty@13.11.4': + resolution: {integrity: sha512-VlF2BTJt5m1Kgj/xNR62uvqwuXi25XOtBRt6OQlOULEF654r7lTiqRfZM6a12oUc4uJtKsS1rwuVxiO2i94X5A==} engines: {node: '>= 18.12.0'} peerDependencies: cdktf: ^0.20.0 @@ -4659,8 +4913,8 @@ packages: peerDependencies: commander: 11.1.x - '@commitlint/cli@19.3.0': - resolution: {integrity: sha512-LgYWOwuDR7BSTQ9OLZ12m7F/qhNY+NpAyPBgo4YNMkACE7lGuUnuQq1yi9hz1KA4+3VqpOYl8H1rY/LYK43v7g==} + '@commitlint/cli@19.4.0': + resolution: {integrity: sha512-sJX4J9UioVwZHq7JWM9tjT5bgWYaIN3rC4FP7YwfEwBYiIO+wMyRttRvQLNkow0vCdM0D67r9NEWU0Ui03I4Eg==} engines: {node: '>=v18'} hasBin: true @@ -4692,8 +4946,8 @@ packages: resolution: {integrity: sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==} engines: {node: '>=v18'} - '@commitlint/load@19.2.0': - resolution: {integrity: sha512-XvxxLJTKqZojCxaBQ7u92qQLFMMZc4+p9qrIq/9kJDy8DOrEa7P1yx7Tjdc2u2JxIalqT4KOGraVgCE7eCYJyQ==} + '@commitlint/load@19.4.0': + resolution: {integrity: sha512-I4lCWaEZYQJ1y+Y+gdvbGAx9pYPavqZAZ3/7/8BpWh+QjscAn8AjsUpLV2PycBsEx7gupq5gM4BViV9xwTIJuw==} engines: {node: '>=v18'} '@commitlint/message@19.0.0': @@ -4704,8 +4958,8 @@ packages: resolution: {integrity: sha512-Il+tNyOb8VDxN3P6XoBBwWJtKKGzHlitEuXA5BP6ir/3loWlsSqDr5aecl6hZcC/spjq4pHqNh0qPlfeWu38QA==} engines: {node: '>=v18'} - '@commitlint/read@19.2.1': - resolution: {integrity: sha512-qETc4+PL0EUv7Q36lJbPG+NJiBOGg7SSC7B5BsPWOmei+Dyif80ErfWQ0qXoW9oCh7GTpTNRoaVhiI8RbhuaNw==} + '@commitlint/read@19.4.0': + resolution: {integrity: sha512-r95jLOEZzKDakXtnQub+zR3xjdnrl2XzerPwm7ch1/cc5JGq04tyaNpa6ty0CRCWdVrk4CZHhqHozb8yZwy2+g==} engines: {node: '>=v18'} '@commitlint/resolve-extends@19.1.0': @@ -4735,11 +4989,10 @@ packages: '@dabh/diagnostics@2.0.3': resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} - '@effect/schema@0.66.5': - resolution: {integrity: sha512-xfu5161JyrfAS1Ruwv0RXd4QFiCALbm3iu9nlW9N9K+52wbS0WdO6XUekPZ9V/O7LN+XmlIh5Y9xhJaIWCZ/gw==} + '@effect/schema@0.69.0': + resolution: {integrity: sha512-dqVnriWqM8TT8d+5vgg1pH4ZOXfs7tQBVAY5N7PALzIOlZamsBKQCdwvMMqremjSkKITckF8/cIj1eQZHQeg7Q==} peerDependencies: - effect: ^3.0.3 - fast-check: ^3.13.2 + effect: ^3.5.7 '@elastic/elasticsearch@8.14.0': resolution: {integrity: sha512-MGrgCI4y+Ozssf5Q2IkVJlqt5bUMnKIICG2qxeOfrJNrVugMCBCAQypyesmSSocAtNm8IX3LxfJ3jQlFHmKe2w==} @@ -5046,10 +5299,6 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.10.0': - resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint-community/regexpp@4.11.0': resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -5602,6 +5851,10 @@ packages: resolution: {integrity: sha512-GTPkYf1meO2UXXIrz/SIDFWz+P4kXo2PTt36LYh/oNxV1PieYi7ZgenQk4IV0ut71Je3Z8ZoNZ8Tr7v2c1X1pg==} engines: {node: '>=16'} + '@mswjs/interceptors@0.34.3': + resolution: {integrity: sha512-UPi1V51c4+PVVG1lhVK2i29aOyBqXvBF8WBvlXIp2Q0vTVKrm20x2voLfunVC3N5wzocxEoHJyOwAXNdoMqy3Q==} + engines: {node: '>=18'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -5674,6 +5927,15 @@ packages: '@octokit/types@13.5.0': resolution: {integrity: sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==} + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@opensearch-project/opensearch@2.10.0': resolution: {integrity: sha512-I3Ko09HvA50zyDi92fgEZfFFaNHhpvXcYLImdKTSL6eEwKqQmszqkLF2g5NTgEyb4Jh9uD2RGX8EYr9PO9zenQ==} engines: {node: '>=10', yarn: ^1.22.10} @@ -5738,14 +6000,20 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-aws-lambda@0.43.0': + resolution: {integrity: sha512-pSxcWlsE/pCWQRIw92sV2C+LmKXelYkjkA7C5s39iPUi4pZ2lA1nIiw+1R/y2pDEhUHcaKkNyljQr3cx9ZpVlQ==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-aws-sdk@0.42.0': resolution: {integrity: sha512-6b4LQAeBSKU5RhKEP9rH+wMcKswlllIT9J65uREmnWQQJo5zogD6cWa2sJ814o9K25/aDi+zheVHDFDuA7iVCQ==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-aws-sdk@0.43.0': - resolution: {integrity: sha512-klfA48MT0uZY/mGw3cYdQeCXTyMhtY4FzHcZy9R7DdTcuCExgbxWrUlOSiqIJ5kBgsCZfBMEeA6UQKDBwa6X7Q==} + '@opentelemetry/instrumentation-aws-sdk@0.43.1': + resolution: {integrity: sha512-qLT2cCniJ5W+6PFzKbksnoIQuq9pS83nmgaExfUwXVvlwi0ILc50dea0tWBHZMkdIDa/zZdcuFrJ7+fUcSnRow==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -5768,12 +6036,24 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-express@0.41.1': + resolution: {integrity: sha512-uRx0V3LPGzjn2bxAnV8eUsDT82vT7NTwI0ezEuPMBOTOsnPpGhWdhcdNdhH80sM4TrWrOfXm9HGEdfWE3TRIww==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-fastify@0.38.0': resolution: {integrity: sha512-HBVLpTSYpkQZ87/Df3N0gAw7VzYZV3n28THIBrJWfuqw3Or7UqdhnjeuMIPQ04BKk3aZc0cWn2naSQObbh5vXw==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-fs@0.14.0': + resolution: {integrity: sha512-pVc8P5AgliC1DphyyBUgsxXlm2XaPH4BpYvt7rAZDMIqUpRk8gs19SioABtKqqxvFzg5jPtgJfJsdxq0Y+maLw==} + engines: {node: '>=14'} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + '@opentelemetry/instrumentation-graphql@0.42.0': resolution: {integrity: sha512-N8SOwoKL9KQSX7z3gOaw5UaTeVQcfDO1c21csVHnmnmGUoqsXbArK2B8VuwPWcv6/BC/i3io+xTo7QGRZ/z28Q==} engines: {node: '>=14'} @@ -5798,8 +6078,8 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-knex@0.38.0': - resolution: {integrity: sha512-EFef6Ss5ATsf5AxJOLE+pxkfupcWDaejkPH+2q7TNeG1UwsBFobfiWM+iHROZ1Cl/y3mTi60MW70FxsaX2/TjA==} + '@opentelemetry/instrumentation-knex@0.39.0': + resolution: {integrity: sha512-lRwTqIKQecPWDkH1KEcAUcFhCaNssbKSpxf4sxRTAROCwrCEnYkjOuqJHV+q1/CApjMTaKu0Er4LBv/6bDpoxA==} engines: {node: '>=14'} peerDependencies: '@opentelemetry/api': ^1.3.0 @@ -6078,8 +6358,8 @@ packages: '@pocket-tools/apollo-cursor-pagination@1.0.3': resolution: {integrity: sha512-6EHr3dmF55FQZ0i9IwiSK+8dREfSRdc9tMon7brXCwOQo44znwOQWMgu7066rewq+lzNNUgsQf+UBG3po6DKtA==} - '@prisma/client@5.14.0': - resolution: {integrity: sha512-akMSuyvLKeoU4LeyBAUdThP/uhVP3GuLygFE3MlYzaCb3/J8SfsYBE5PkaFuLuVpLyA6sFoW+16z/aPhNAESqg==} + '@prisma/client@5.18.0': + resolution: {integrity: sha512-BWivkLh+af1kqC89zCJYkHsRcyWsM8/JHpsDMM76DjP3ZdEquJhXa4IeX+HkWPnwJ5FanxEJFZZDTWiDs/Kvyw==} engines: {node: '>=16.13'} peerDependencies: prisma: '*' @@ -6087,23 +6367,23 @@ packages: prisma: optional: true - '@prisma/debug@5.14.0': - resolution: {integrity: sha512-iq56qBZuFfX3fCxoxT8gBX33lQzomBU0qIUaEj1RebsKVz1ob/BVH1XSBwwwvRVtZEV1b7Fxx2eVu34Ge/mg3w==} + '@prisma/debug@5.18.0': + resolution: {integrity: sha512-f+ZvpTLidSo3LMJxQPVgAxdAjzv5OpzAo/eF8qZqbwvgi2F5cTOI9XCpdRzJYA0iGfajjwjOKKrVq64vkxEfUw==} '@prisma/debug@5.3.1': resolution: {integrity: sha512-eYrxqslEKf+wpMFIIHgbcNYuZBXUdiJLA85Or3TwOhgPIN1ZoXT9CwJph3ynW8H1Xg0LkdYLwVmuULCwiMoU5A==} - '@prisma/engines-version@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48': - resolution: {integrity: sha512-ip6pNkRo1UxWv+6toxNcYvItNYaqQjXdFNGJ+Nuk2eYtRoEdoF13wxo7/jsClJFFenMPVNVqXQDV0oveXnR1cA==} + '@prisma/engines-version@5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169': + resolution: {integrity: sha512-a/+LpJj8vYU3nmtkg+N3X51ddbt35yYrRe8wqHTJtYQt7l1f8kjIBcCs6sHJvodW/EK5XGvboOiwm47fmNrbgg==} - '@prisma/engines@5.14.0': - resolution: {integrity: sha512-lgxkKZ6IEygVcw6IZZUlPIfLQ9hjSYAtHjZ5r64sCLDgVzsPFCi2XBBJgzPMkOQ5RHzUD4E/dVdpn9+ez8tk1A==} + '@prisma/engines@5.18.0': + resolution: {integrity: sha512-ofmpGLeJ2q2P0wa/XaEgTnX/IsLnvSp/gZts0zjgLNdBhfuj2lowOOPmDcfKljLQUXMvAek3lw5T01kHmCG8rg==} '@prisma/engines@5.3.1': resolution: {integrity: sha512-6QkILNyfeeN67BNEPEtkgh3Xo2tm6D7V+UhrkBbRHqKw9CTaz/vvTP/ROwYSP/3JT2MtIutZm/EnhxUiuOPVDA==} - '@prisma/fetch-engine@5.14.0': - resolution: {integrity: sha512-VrheA9y9DMURK5vu8OJoOgQpxOhas3qF0IBHJ8G/0X44k82kc8E0w98HCn2nhnbOOMwbWsJWXfLC2/F8n5u0gQ==} + '@prisma/fetch-engine@5.18.0': + resolution: {integrity: sha512-I/3u0x2n31rGaAuBRx2YK4eB7R/1zCuayo2DGwSpGyrJWsZesrV7QVw7ND0/Suxeo/vLkJ5OwuBqHoCxvTHpOg==} '@prisma/fetch-engine@5.3.1': resolution: {integrity: sha512-w1yk1YiK8N82Pobdq58b85l6e8akyrkxuzwV9DoiUTRf3gpsuhJJesHc4Yi0WzUC9/3znizl1UfCsI6dhkj3Vw==} @@ -6111,8 +6391,8 @@ packages: '@prisma/generator-helper@5.3.1': resolution: {integrity: sha512-zrYS0iHLgPlOJjYnd5KvVMMvSS+ktOL39EwooS5EnyvfzwfzxlKCeOUgxTfiKYs0WUWqzEvyNAYtramYgSknsQ==} - '@prisma/get-platform@5.14.0': - resolution: {integrity: sha512-/yAyBvcEjRv41ynZrhdrPtHgk47xLRRq/o5eWGcUpBJ1YrUZTYB8EoPiopnP7iQrMATK8stXQdPOoVlrzuTQZw==} + '@prisma/get-platform@5.18.0': + resolution: {integrity: sha512-Tk+m7+uhqcKDgnMnFN0lRiH7Ewea0OEsZZs9pqXa7i3+7svS3FSCqDBCaM9x5fmhhkufiG0BtunJVDka+46DlA==} '@prisma/get-platform@5.3.1': resolution: {integrity: sha512-3IiZY2BUjKnAuZ0569zppZE6/rZbVAM09//c2nvPbbkGG9MqrirA8fbhhF7tfVmhyVfdmVCHnf/ujWPHJ8B46Q==} @@ -6120,8 +6400,8 @@ packages: '@prisma/instrumentation@5.16.1': resolution: {integrity: sha512-4m5gRFWnQb8s/yTyGbMZkL7A5uJgqOWcWJxapwcAD0T0kh5sGPEVSQl/zTQvE9aduXhFAxOtC3gO+R8Hb5xO1Q==} - '@prisma/instrumentation@5.17.0': - resolution: {integrity: sha512-c1Sle4ji8aasMcYfBBHFM56We4ljfenVtRmS8aY06BllS7SoU6SmJBwG7vil+GHiR0Yrh+t9iBwt4AY0Jr4KNQ==} + '@prisma/instrumentation@5.18.0': + resolution: {integrity: sha512-r074avGkpPXItk+josQPhufZEmGhUCb16PQx4ITPS40vWTpTPET4VsgCBZB2alIN6SS7pRFod2vz2M2HHEEylQ==} '@prisma/internals@5.3.1': resolution: {integrity: sha512-zkW73hPHHNrMD21PeYgCTBfMu71vzJf+WtfydtJbS0JVJKyLfOel0iWSQg7wjNeQfccKp+NdHJ/5rTJ4NEUzgA==} @@ -6172,83 +6452,83 @@ packages: '@repeaterjs/repeater@3.0.5': resolution: {integrity: sha512-l3YHBLAol6d/IKnB9LhpD0cEZWAoe3eFKUyTYWmFmCO2Q/WOckxLQAUyMZWwZV2M/m3+4vgRoaolFqaII82/TA==} - '@rollup/rollup-android-arm-eabi@4.18.1': - resolution: {integrity: sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==} + '@rollup/rollup-android-arm-eabi@4.21.1': + resolution: {integrity: sha512-2thheikVEuU7ZxFXubPDOtspKn1x0yqaYQwvALVtEcvFhMifPADBrgRPyHV0TF3b+9BgvgjgagVyvA/UqPZHmg==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.18.1': - resolution: {integrity: sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==} + '@rollup/rollup-android-arm64@4.21.1': + resolution: {integrity: sha512-t1lLYn4V9WgnIFHXy1d2Di/7gyzBWS8G5pQSXdZqfrdCGTwi1VasRMSS81DTYb+avDs/Zz4A6dzERki5oRYz1g==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.18.1': - resolution: {integrity: sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==} + '@rollup/rollup-darwin-arm64@4.21.1': + resolution: {integrity: sha512-AH/wNWSEEHvs6t4iJ3RANxW5ZCK3fUnmf0gyMxWCesY1AlUj8jY7GC+rQE4wd3gwmZ9XDOpL0kcFnCjtN7FXlA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.18.1': - resolution: {integrity: sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==} + '@rollup/rollup-darwin-x64@4.21.1': + resolution: {integrity: sha512-dO0BIz/+5ZdkLZrVgQrDdW7m2RkrLwYTh2YMFG9IpBtlC1x1NPNSXkfczhZieOlOLEqgXOFH3wYHB7PmBtf+Bg==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.18.1': - resolution: {integrity: sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==} + '@rollup/rollup-linux-arm-gnueabihf@4.21.1': + resolution: {integrity: sha512-sWWgdQ1fq+XKrlda8PsMCfut8caFwZBmhYeoehJ05FdI0YZXk6ZyUjWLrIgbR/VgiGycrFKMMgp7eJ69HOF2pQ==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.18.1': - resolution: {integrity: sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==} + '@rollup/rollup-linux-arm-musleabihf@4.21.1': + resolution: {integrity: sha512-9OIiSuj5EsYQlmwhmFRA0LRO0dRRjdCVZA3hnmZe1rEwRk11Jy3ECGGq3a7RrVEZ0/pCsYWx8jG3IvcrJ6RCew==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.18.1': - resolution: {integrity: sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==} + '@rollup/rollup-linux-arm64-gnu@4.21.1': + resolution: {integrity: sha512-0kuAkRK4MeIUbzQYu63NrJmfoUVicajoRAL1bpwdYIYRcs57iyIV9NLcuyDyDXE2GiZCL4uhKSYAnyWpjZkWow==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.18.1': - resolution: {integrity: sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==} + '@rollup/rollup-linux-arm64-musl@4.21.1': + resolution: {integrity: sha512-/6dYC9fZtfEY0vozpc5bx1RP4VrtEOhNQGb0HwvYNwXD1BBbwQ5cKIbUVVU7G2d5WRE90NfB922elN8ASXAJEA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': - resolution: {integrity: sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==} + '@rollup/rollup-linux-powerpc64le-gnu@4.21.1': + resolution: {integrity: sha512-ltUWy+sHeAh3YZ91NUsV4Xg3uBXAlscQe8ZOXRCVAKLsivGuJsrkawYPUEyCV3DYa9urgJugMLn8Z3Z/6CeyRQ==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.18.1': - resolution: {integrity: sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==} + '@rollup/rollup-linux-riscv64-gnu@4.21.1': + resolution: {integrity: sha512-BggMndzI7Tlv4/abrgLwa/dxNEMn2gC61DCLrTzw8LkpSKel4o+O+gtjbnkevZ18SKkeN3ihRGPuBxjaetWzWg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.18.1': - resolution: {integrity: sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==} + '@rollup/rollup-linux-s390x-gnu@4.21.1': + resolution: {integrity: sha512-z/9rtlGd/OMv+gb1mNSjElasMf9yXusAxnRDrBaYB+eS1shFm6/4/xDH1SAISO5729fFKUkJ88TkGPRUh8WSAA==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.18.1': - resolution: {integrity: sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==} + '@rollup/rollup-linux-x64-gnu@4.21.1': + resolution: {integrity: sha512-kXQVcWqDcDKw0S2E0TmhlTLlUgAmMVqPrJZR+KpH/1ZaZhLSl23GZpQVmawBQGVhyP5WXIsIQ/zqbDBBYmxm5w==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.18.1': - resolution: {integrity: sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==} + '@rollup/rollup-linux-x64-musl@4.21.1': + resolution: {integrity: sha512-CbFv/WMQsSdl+bpX6rVbzR4kAjSSBuDgCqb1l4J68UYsQNalz5wOqLGYj4ZI0thGpyX5kc+LLZ9CL+kpqDovZA==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.18.1': - resolution: {integrity: sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==} + '@rollup/rollup-win32-arm64-msvc@4.21.1': + resolution: {integrity: sha512-3Q3brDgA86gHXWHklrwdREKIrIbxC0ZgU8lwpj0eEKGBQH+31uPqr0P2v11pn0tSIxHvcdOWxa4j+YvLNx1i6g==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.18.1': - resolution: {integrity: sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==} + '@rollup/rollup-win32-ia32-msvc@4.21.1': + resolution: {integrity: sha512-tNg+jJcKR3Uwe4L0/wY3Ro0H+u3nrb04+tcq1GSYzBEmKLeOQF2emk1whxlzNqb6MMrQ2JOcQEpuuiPLyRcSIw==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.18.1': - resolution: {integrity: sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==} + '@rollup/rollup-win32-x64-msvc@4.21.1': + resolution: {integrity: sha512-xGiIH95H1zU7naUyTKEyOA/I0aexNMUdO9qRv0bLKN3qu25bBdrxZHqA3PTJ24YNN/GdMzG4xkDcd/GvjuhfLg==} cpu: [x64] os: [win32] @@ -6299,6 +6579,10 @@ packages: resolution: {integrity: sha512-JlyFG/0uSAkFkEUPmrAoOzndHBF/9SPlnsQTJ2mie+b2f5wjjF/iRU5PoL8rQQ6r+Hw0LHvTpCkkj4+FxnFhlg==} engines: {node: '>=14.18'} + '@sentry/aws-serverless@8.27.0': + resolution: {integrity: sha512-VGiTzElQ0/9FasDiavHS/vpia+ZCjviiFjUii6GRdTi9CKkFqi/7zWxZi71w0hWg5Q0vndE27eatMbY3Tlah2Q==} + engines: {node: '>=14.18'} + '@sentry/core@7.116.0': resolution: {integrity: sha512-J6Wmjjx+o7RwST0weTU1KaKUAlzbc8MGkJV1rcHM9xjNTWTva+nrcCM3vFBagnk2Gm/zhwv3h0PvWEqVyp3U1Q==} engines: {node: '>=8'} @@ -6307,6 +6591,10 @@ packages: resolution: {integrity: sha512-8moEMC3gp4W6mH9w5amb/zrYk6bNW8WGgcLRMCs5rguxny8YP5i8ISOJ0T0LP9x/RxSK/6xix5D2bzI/5ECzlw==} engines: {node: '>=14.18'} + '@sentry/core@8.27.0': + resolution: {integrity: sha512-4frlXluHT3Du+Omw91K04jpvbfMtydvg4Bxj2+gt/DT19Swhm/fbEpzdUjgbAd3Jinj/n0qk/jFRXjr9JZKFjg==} + engines: {node: '>=14.18'} + '@sentry/integrations@7.116.0': resolution: {integrity: sha512-UZb60gaF+7veh1Yv79RiGvgGYOnU6xA97H+hI6tKgc1uT20YpItO4X56Vhp0lvyEyUGFZzBRRH1jpMDPNGPkqw==} engines: {node: '>=8'} @@ -6319,6 +6607,10 @@ packages: resolution: {integrity: sha512-a+W477bmt28I1DT51xJKmp4Y7hBAdEGqQ2K7gfOn3mRBHoihuhKl2Xe8BMwFH7+v4mAEZEwAZBUOLAC7h+Tjig==} engines: {node: '>=14.18'} + '@sentry/node@8.27.0': + resolution: {integrity: sha512-nE2VPSHOW/tzH/lB6CoBtYkmXqXncUuWMC56RLRiPyHEXDktZx8oFp364/3m117iKOjO0XHP57Kl5cdb90IM7g==} + engines: {node: '>=14.18'} + '@sentry/opentelemetry@8.18.0': resolution: {integrity: sha512-P2OoXXJcU2RiRZmpBqOkK+NLGkwQrYizlOHl1zckHI1nYmQgOD1tcJj4c1xOYzH+eGPLp/IViXHO6vaBr8BGGg==} engines: {node: '>=14.18'} @@ -6329,6 +6621,16 @@ packages: '@opentelemetry/sdk-trace-base': ^1.25.1 '@opentelemetry/semantic-conventions': ^1.25.1 + '@sentry/opentelemetry@8.27.0': + resolution: {integrity: sha512-FRz7ApnyZYDFmi2CWUhKBux2N/0WswRLHwHDZ31FYCajujw7vQKucgdsxDW2RIRPWDwcMxHY1kvt6EzM1hIsxQ==} + engines: {node: '>=14.18'} + peerDependencies: + '@opentelemetry/api': ^1.9.0 + '@opentelemetry/core': ^1.25.1 + '@opentelemetry/instrumentation': ^0.52.1 + '@opentelemetry/sdk-trace-base': ^1.25.1 + '@opentelemetry/semantic-conventions': ^1.25.1 + '@sentry/types@7.116.0': resolution: {integrity: sha512-QCCvG5QuQrwgKzV11lolNQPP2k67Q6HHD9vllZ/C4dkxkjoIym8Gy+1OgAN3wjsR0f/kG9o5iZyglgNpUVRapQ==} engines: {node: '>=8'} @@ -6337,6 +6639,10 @@ packages: resolution: {integrity: sha512-5J+uOqptnmAnW3Rk31AHIqW36Wzvlo3UOM+p2wjSYGrC/PgcE47Klzr+w4UcOhN6AZqefalGd3vaUXz9NaFdRg==} engines: {node: '>=14.18'} + '@sentry/types@8.27.0': + resolution: {integrity: sha512-B6lrP46+m2x0lfqWc9F4VcUbN893mVGnPEd7KIMRk95mPzkFJ3sNxggTQF5/ZfNO7lDQYQb22uysB5sj/BqFiw==} + engines: {node: '>=14.18'} + '@sentry/utils@7.116.0': resolution: {integrity: sha512-Vn9fcvwTq91wJvCd7WTMWozimqMi+dEZ3ie3EICELC2diONcN16ADFdzn65CQQbYwmUzRjN9EjDN2k41pKZWhQ==} engines: {node: '>=8'} @@ -6345,6 +6651,10 @@ packages: resolution: {integrity: sha512-7wq7cgaeSIGJncl9/2VMu81ZN5ep4lp4H1/+O8+xUxOmnPb/05ZZcbn9/VxVQvIoqZSZdwCLPeBz6PEVukvokA==} engines: {node: '>=14.18'} + '@sentry/utils@8.27.0': + resolution: {integrity: sha512-gyJM3SyLQe0A3mkQVVNdKYvk3ZoikkYgyA/D+5StFNLKdyUgEbJgXOGXrQSSYPF7BSX6Sc5b0KHCglPII0KuKw==} + engines: {node: '>=14.18'} + '@sideway/address@4.1.5': resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} @@ -6395,36 +6705,51 @@ packages: resolution: {integrity: sha512-VwiOk7TwXoE7NlNguV/aPq1hFH72tqkHCw8eWXbr2xHspRyyv9DLpLXhq+Ieje+NwoqXrY0xyQjPXdOE6cGcHA==} engines: {node: '>=16.0.0'} + '@smithy/config-resolver@3.0.5': + resolution: {integrity: sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==} + engines: {node: '>=16.0.0'} + '@smithy/core@2.2.4': resolution: {integrity: sha512-qdY3LpMOUyLM/gfjjMQZui+UTNS7kBRDWlvyIhVOql5dn2J3isk9qUTBtQ1CbDH8MTugHis1zu3h4rH+Qmmh4g==} engines: {node: '>=16.0.0'} + '@smithy/core@2.4.0': + resolution: {integrity: sha512-cHXq+FneIF/KJbt4q4pjN186+Jf4ZB0ZOqEaZMBhT79srEyGDDBV31NqBRBjazz8ppQ1bJbDJMY9ba5wKFV36w==} + engines: {node: '>=16.0.0'} + '@smithy/credential-provider-imds@3.1.3': resolution: {integrity: sha512-U1Yrv6hx/mRK6k8AncuI6jLUx9rn0VVSd9NPEX6pyYFBfkSkChOc/n4zUb8alHUVg83TbI4OdZVo1X0Zfj3ijA==} engines: {node: '>=16.0.0'} + '@smithy/credential-provider-imds@3.2.0': + resolution: {integrity: sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA==} + engines: {node: '>=16.0.0'} + '@smithy/eventstream-codec@3.1.2': resolution: {integrity: sha512-0mBcu49JWt4MXhrhRAlxASNy0IjDRFU+aWNDRal9OtUJvJNiwDuyKMUONSOjLjSCeGwZaE0wOErdqULer8r7yw==} - '@smithy/eventstream-serde-browser@3.0.4': - resolution: {integrity: sha512-Eo4anLZX6ltGJTZ5yJMc80gZPYYwBn44g0h7oFq6et+TYr5dUsTpIcDbz2evsOKIZhZ7zBoFWHtBXQ4QQeb5xA==} + '@smithy/eventstream-serde-browser@3.0.6': + resolution: {integrity: sha512-2hM54UWQUOrki4BtsUI1WzmD13/SeaqT/AB3EUJKbcver/WgKNaiJ5y5F5XXuVe6UekffVzuUDrBZVAA3AWRpQ==} engines: {node: '>=16.0.0'} '@smithy/eventstream-serde-config-resolver@3.0.3': resolution: {integrity: sha512-NVTYjOuYpGfrN/VbRQgn31x73KDLfCXCsFdad8DiIc3IcdxL+dYA9zEQPyOP7Fy2QL8CPy2WE4WCUD+ZsLNfaQ==} engines: {node: '>=16.0.0'} - '@smithy/eventstream-serde-node@3.0.4': - resolution: {integrity: sha512-mjlG0OzGAYuUpdUpflfb9zyLrBGgmQmrobNT8b42ZTsGv/J03+t24uhhtVEKG/b2jFtPIHF74Bq+VUtbzEKOKg==} + '@smithy/eventstream-serde-node@3.0.5': + resolution: {integrity: sha512-+upXvnHNyZP095s11jF5dhGw/Ihzqwl5G+/KtMnoQOpdfC3B5HYCcDVG9EmgkhJMXJlM64PyN5gjJl0uXFQehQ==} engines: {node: '>=16.0.0'} - '@smithy/eventstream-serde-universal@3.0.4': - resolution: {integrity: sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==} + '@smithy/eventstream-serde-universal@3.0.5': + resolution: {integrity: sha512-5u/nXbyoh1s4QxrvNre9V6vfyoLWuiVvvd5TlZjGThIikc3G+uNiG9uOTCWweSRjv1asdDIWK7nOmN7le4RYHQ==} engines: {node: '>=16.0.0'} '@smithy/fetch-http-handler@3.2.0': resolution: {integrity: sha512-vFvDxMrc6sO5Atec8PaISckMcAwsCrRhYxwUylg97bRT2KZoumOF7qk5+6EVUtuM1IG9AJV5aqXnHln9ZdXHpg==} + '@smithy/fetch-http-handler@3.2.4': + resolution: {integrity: sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==} + '@smithy/hash-node@3.0.3': resolution: {integrity: sha512-2ctBXpPMG+B3BtWSGNnKELJ7SH9e4TNefJS0cd2eSkOOROeBnnVBnAy9LtJ8tY4vUEoe55N4CNPxzbWvR39iBw==} engines: {node: '>=16.0.0'} @@ -6443,18 +6768,30 @@ packages: '@smithy/md5-js@3.0.3': resolution: {integrity: sha512-O/SAkGVwpWmelpj/8yDtsaVe6sINHLB1q8YE/+ZQbDxIw3SRLbTZuRaI10K12sVoENdnHqzPp5i3/H+BcZ3m3Q==} - '@smithy/middleware-compression@3.0.4': - resolution: {integrity: sha512-wxqn17tgnepjqmt0OyQA/cJnQYY2SpTx2kSKxMo71vVhomIUFPOVkwYSJY27OQWomPWy5E8va2kLfwi8Ap9wKQ==} + '@smithy/middleware-compression@3.0.7': + resolution: {integrity: sha512-ide8RSj0HWHq8uGryx1PuhI/0p+xgrrG+atDBgmv1ScIVIBrH7hqk2cfXyZ3+zQYeD2z95iDn75U1BHwlSwhag==} engines: {node: '>=16.0.0'} '@smithy/middleware-content-length@3.0.3': resolution: {integrity: sha512-Dbz2bzexReYIQDWMr+gZhpwBetNXzbhnEMhYKA6urqmojO14CsXjnsoPYO8UL/xxcawn8ZsuVU61ElkLSltIUQ==} engines: {node: '>=16.0.0'} + '@smithy/middleware-content-length@3.0.5': + resolution: {integrity: sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==} + engines: {node: '>=16.0.0'} + '@smithy/middleware-endpoint@3.0.4': resolution: {integrity: sha512-whUJMEPwl3ANIbXjBXZVdJNgfV2ZU8ayln7xUM47rXL2txuenI7jQ/VFFwCzy5lCmXScjp6zYtptW5Evud8e9g==} engines: {node: '>=16.0.0'} + '@smithy/middleware-endpoint@3.1.0': + resolution: {integrity: sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==} + engines: {node: '>=16.0.0'} + + '@smithy/middleware-retry@3.0.15': + resolution: {integrity: sha512-iTMedvNt1ApdvkaoE8aSDuwaoc+BhvHqttbA/FO4Ty+y/S5hW6Ci/CTScG7vam4RYJWZxdTElc3MEfHRVH6cgQ==} + engines: {node: '>=16.0.0'} + '@smithy/middleware-retry@3.0.7': resolution: {integrity: sha512-f5q7Y09G+2h5ivkSx5CHvlAT4qRR3jBFEsfXyQ9nFNiWQlr8c48blnu5cmbTQ+p1xmIO14UXzKoF8d7Tm0Gsjw==} engines: {node: '>=16.0.0'} @@ -6471,10 +6808,18 @@ packages: resolution: {integrity: sha512-rxdpAZczzholz6CYZxtqDu/aKTxATD5DAUDVj7HoEulq+pDSQVWzbg0btZDlxeFfa6bb2b5tUvgdX5+k8jUqcg==} engines: {node: '>=16.0.0'} + '@smithy/node-config-provider@3.1.4': + resolution: {integrity: sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==} + engines: {node: '>=16.0.0'} + '@smithy/node-http-handler@3.1.1': resolution: {integrity: sha512-L71NLyPeP450r2J/mfu1jMc//Z1YnqJt2eSNw7uhiItaONnBLDA68J5jgxq8+MBDsYnFwNAIc7dBG1ImiWBiwg==} engines: {node: '>=16.0.0'} + '@smithy/node-http-handler@3.1.4': + resolution: {integrity: sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==} + engines: {node: '>=16.0.0'} + '@smithy/property-provider@3.1.3': resolution: {integrity: sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==} engines: {node: '>=16.0.0'} @@ -6483,6 +6828,10 @@ packages: resolution: {integrity: sha512-x5jmrCWwQlx+Zv4jAtc33ijJ+vqqYN+c/ZkrnpvEe/uDas7AT7A/4Rc2CdfxgWv4WFGmEqODIrrUToPN6DDkGw==} engines: {node: '>=16.0.0'} + '@smithy/protocol-http@4.1.0': + resolution: {integrity: sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==} + engines: {node: '>=16.0.0'} + '@smithy/querystring-builder@3.0.3': resolution: {integrity: sha512-vyWckeUeesFKzCDaRwWLUA1Xym9McaA6XpFfAK5qI9DKJ4M33ooQGqvM4J+LalH4u/Dq9nFiC8U6Qn1qi0+9zw==} engines: {node: '>=16.0.0'} @@ -6499,14 +6848,26 @@ packages: resolution: {integrity: sha512-Z8Y3+08vgoDgl4HENqNnnzSISAaGrF2RoKupoC47u2wiMp+Z8P/8mDh1CL8+8ujfi2U5naNvopSBmP/BUj8b5w==} engines: {node: '>=16.0.0'} + '@smithy/shared-ini-file-loader@3.1.4': + resolution: {integrity: sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==} + engines: {node: '>=16.0.0'} + '@smithy/signature-v4@3.1.2': resolution: {integrity: sha512-3BcPylEsYtD0esM4Hoyml/+s7WP2LFhcM3J2AGdcL2vx9O60TtfpDOL72gjb4lU8NeRPeKAwR77YNyyGvMbuEA==} engines: {node: '>=16.0.0'} + '@smithy/signature-v4@4.1.0': + resolution: {integrity: sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==} + engines: {node: '>=16.0.0'} + '@smithy/smithy-client@3.1.5': resolution: {integrity: sha512-x9bL9Mx2CT2P1OiUlHM+ZNpbVU6TgT32f9CmTRzqIHA7M4vYrROCWEoC3o4xHNJASoGd4Opos3cXYPgh+/m4Ww==} engines: {node: '>=16.0.0'} + '@smithy/smithy-client@3.2.0': + resolution: {integrity: sha512-pDbtxs8WOhJLJSeaF/eAbPgXg4VVYFlRcL/zoNYA5WbG3wBL06CHtBSg53ppkttDpAJ/hdiede+xApip1CwSLw==} + engines: {node: '>=16.0.0'} + '@smithy/types@3.3.0': resolution: {integrity: sha512-IxvBBCTFDHbVoK7zIxqA1ZOdc4QfM5HM7rGleCuHi7L1wnKv5Pn69xXJQ9hgxH60ZVygH9/JG0jRgtUncE3QUA==} engines: {node: '>=16.0.0'} @@ -6537,10 +6898,18 @@ packages: resolution: {integrity: sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==} engines: {node: '>=16.0.0'} + '@smithy/util-defaults-mode-browser@3.0.15': + resolution: {integrity: sha512-FZ4Psa3vjp8kOXcd3HJOiDPBCWtiilLl57r0cnNtq/Ga9RSDrM5ERL6xt+tO43+2af6Pn5Yp92x2n5vPuduNfg==} + engines: {node: '>= 10.0.0'} + '@smithy/util-defaults-mode-browser@3.0.7': resolution: {integrity: sha512-Q2txLyvQyGfmjsaDbVV7Sg8psefpFcrnlGapDzXGFRPFKRBeEg6OvFK8FljqjeHSaCZ6/UuzQExUPqBR/2qlDA==} engines: {node: '>= 10.0.0'} + '@smithy/util-defaults-mode-node@3.0.15': + resolution: {integrity: sha512-KSyAAx2q6d0t6f/S4XB2+3+6aQacm3aLMhs9aLMqn18uYGUepbdssfogW5JQZpc6lXNBnp0tEnR5e9CEKmEd7A==} + engines: {node: '>= 10.0.0'} + '@smithy/util-defaults-mode-node@3.0.7': resolution: {integrity: sha512-F4Qcj1fG6MGi2BSWCslfsMSwllws/WzYONBGtLybyY+halAcXdWhcew+mej8M5SKd5hqPYp4f7b+ABQEaeytgg==} engines: {node: '>= 10.0.0'} @@ -6549,6 +6918,10 @@ packages: resolution: {integrity: sha512-ZAtNf+vXAsgzgRutDDiklU09ZzZiiV/nATyqde4Um4priTmasDH+eLpp3tspL0hS2dEootyFMhu1Y6Y+tzpWBQ==} engines: {node: '>=16.0.0'} + '@smithy/util-endpoints@2.0.5': + resolution: {integrity: sha512-ReQP0BWihIE68OAblC/WQmDD40Gx+QY1Ez8mTdFMXpmjfxSyz2fVQu3A4zXRfQU9sZXtewk3GmhfOHswvX+eNg==} + engines: {node: '>=16.0.0'} + '@smithy/util-hex-encoding@3.0.0': resolution: {integrity: sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==} engines: {node: '>=16.0.0'} @@ -6565,6 +6938,10 @@ packages: resolution: {integrity: sha512-xC3L5PKMAT/Bh8fmHNXP9sdQ4+4aKVUU3EEJ2CF/lLk7R+wtMJM+v/1B4en7jO++Wa5spGzFDBCl0QxgbUc5Ug==} engines: {node: '>=16.0.0'} + '@smithy/util-stream@3.1.3': + resolution: {integrity: sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==} + engines: {node: '>=16.0.0'} + '@smithy/util-uri-escape@3.0.0': resolution: {integrity: sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==} engines: {node: '>=16.0.0'} @@ -6584,12 +6961,12 @@ packages: '@snowplow/node-tracker@3.23.1': resolution: {integrity: sha512-MkmGdkKethmW2VBA1RXrC7OLeDWdZZXkUvmiGc0Z3fDKSoBFmburu69ocYFIkFMSBLzUdc1QXtrAACoiitaArA==} - '@snowplow/snowtype-core@0.7.1': - resolution: {integrity: sha512-9VYLeM/2V4CQOH0JcrO5GS9hLrnJxU3AKIIoS/hpSETfX+ZicgsTweFz0FwkhQv8rIQrAw/ok6YpENHEbgELrg==} + '@snowplow/snowtype-core@0.8.2': + resolution: {integrity: sha512-D9jag4WKXaHbxypGW3VF8+jwPAK94y6oFCyC6jWrNY3Exctr6y9OEq5zaG/fJImnkvK68BN6XZPJHV0zQ7846w==} engines: {node: '>=18'} - '@snowplow/snowtype@0.7.1': - resolution: {integrity: sha512-waYGYartZhf3tUFmg+GuWk1Wip356J/BxCvb0xxYkYEWhTFY9YcyMDDVmYXGLaiaJjxxWdp/d19N6XY7kLZ6Mw==} + '@snowplow/snowtype@0.8.2': + resolution: {integrity: sha512-tHB7mh8q1jK/eW3ibpbFGqXK3WUF7Xjt0p+sRZkkx81m8Qy0+rSmpF+vqqz26uMrxwHMWbGDtgXZBX7xgYF+qA==} engines: {node: '>=18'} hasBin: true @@ -6625,6 +7002,9 @@ packages: '@types/aws-lambda@8.10.141': resolution: {integrity: sha512-SMWlRBukG9KV8ZNjwemp2AzDibp/czIAeKKTw09nCPbWxVskIxactCJCGOp4y6I1hCMY7T7UGfySvBLXNeUbEw==} + '@types/aws-lambda@8.10.143': + resolution: {integrity: sha512-u5vzlcR14ge/4pMTTMDQr3MF0wEe38B2F9o84uC4F43vN5DGTy63npRrB6jQhyt+C0lGv4ZfiRcRkqJoZuPnmg==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -6821,6 +7201,9 @@ packages: '@types/node@20.14.11': resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==} + '@types/node@20.16.2': + resolution: {integrity: sha512-91s/n4qUPV/wg8eE9KHYW1kouTfDk2FPGjXbBMfRWP/2vg1rCXNQL1OCabwGs0XSdukuK+MwCDXE30QpSeMUhQ==} + '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -6887,8 +7270,8 @@ packages: '@types/triple-beam@1.3.5': resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} - '@types/turndown@5.0.4': - resolution: {integrity: sha512-28GI33lCCkU4SGH1GvjDhFgOVr+Tym4PXGBIU1buJUa6xQolniPArtUT+kv42RR2N9MsMLInkr904Aq+ESHBJg==} + '@types/turndown@5.0.5': + resolution: {integrity: sha512-TL2IgGgc7B5j78rIccBtlYAnkuv8nUQqhQc+DSYV5j9Be9XOcm/SKOVRuA47xAVI3680Tk9B1d8flK2GWT2+4w==} '@types/urijs@1.19.25': resolution: {integrity: sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==} @@ -6914,63 +7297,62 @@ packages: '@types/yoga-layout@1.9.2': resolution: {integrity: sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==} - '@typescript-eslint/eslint-plugin@7.16.1': - resolution: {integrity: sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/eslint-plugin@8.3.0': + resolution: {integrity: sha512-FLAIn63G5KH+adZosDYiutqkOkYEx0nvcwNNfJAf+c7Ae/H35qWwTYvPZUKFj5AS+WfHG/WJJfWnDnyNUlp8UA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^7.0.0 - eslint: ^8.56.0 + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/parser@7.16.1': - resolution: {integrity: sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/parser@8.3.0': + resolution: {integrity: sha512-h53RhVyLu6AtpUzVCYLPhZGL5jzTD9fZL+SYf/+hYOx2bDkyQXztXSc4tbvKYHzfMXExMLiL9CWqJmVz6+78IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/scope-manager@7.16.1': - resolution: {integrity: sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/scope-manager@8.3.0': + resolution: {integrity: sha512-mz2X8WcN2nVu5Hodku+IR8GgCOl4C0G/Z1ruaWN4dgec64kDBabuXyPAr+/RgJtumv8EEkqIzf3X2U5DUKB2eg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/type-utils@7.16.1': - resolution: {integrity: sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/type-utils@8.3.0': + resolution: {integrity: sha512-wrV6qh//nLbfXZQoj32EXKmwHf4b7L+xXLrP3FZ0GOUU72gSvLjeWUl5J5Ue5IwRxIV1TfF73j/eaBapxx99Lg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/types@7.16.1': - resolution: {integrity: sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/types@8.3.0': + resolution: {integrity: sha512-y6sSEeK+facMaAyixM36dQ5NVXTnKWunfD1Ft4xraYqxP0lC0POJmIaL/mw72CUMqjY9qfyVfXafMeaUj0noWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@7.16.1': - resolution: {integrity: sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/typescript-estree@8.3.0': + resolution: {integrity: sha512-Mq7FTHl0R36EmWlCJWojIC1qn/ZWo2YiWYc1XVtasJ7FIgjo0MVv9rZWXEE7IK2CGrtwe1dVOxWwqXUdNgfRCA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - '@typescript-eslint/utils@7.16.1': - resolution: {integrity: sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/utils@8.3.0': + resolution: {integrity: sha512-F77WwqxIi/qGkIGOGXNBLV7nykwfjLsdauRB/DOFPdv6LTF3BHHkBpq81/b5iMPSF055oO2BiivDJV4ChvNtXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 + eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/visitor-keys@7.16.1': - resolution: {integrity: sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==} - engines: {node: ^18.18.0 || >=20.0.0} + '@typescript-eslint/visitor-keys@8.3.0': + resolution: {integrity: sha512-RmZwrTbQ9QveF15m/Cl28n0LXD6ea2CjkhH5rQ55ewz3H24w+AMCJHPVYaZ8/0HoG8Z3cLLFFycRXxeO2tz9FA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@wesleytodd/openapi@0.3.0': resolution: {integrity: sha512-7vjiRFY4yW5aYTZzH4EINYpoClBZTahXWGbpaIl6SsL2XcikuvkgoHCA3t/Hu+3QibBT49W3BPXW3Bl8tr7Ddg==} @@ -6996,6 +7378,22 @@ packages: resolution: {integrity: sha512-LS8tSomZa3YHnntpWt3PP43iFEEl6YeIsvDakczHBKlay5LdkXFr8w7v8H6akpG5nRrzydyB0k1iE2eoL6aKIQ==} engines: {node: '>=16.0.0'} + '@wry/context@0.7.4': + resolution: {integrity: sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==} + engines: {node: '>=8'} + + '@wry/equality@0.5.7': + resolution: {integrity: sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==} + engines: {node: '>=8'} + + '@wry/trie@0.3.2': + resolution: {integrity: sha512-yRTyhWSls2OY/pYLfwff867r8ekooZ4UI+/gxot5Wj8EFwSf2rG+n+Mo/6LoLQm1TKA4GRj2+LCpbfS937dClQ==} + engines: {node: '>=8'} + + '@wry/trie@0.4.3': + resolution: {integrity: sha512-I6bHwH0fSf6RqQcnnXLJKhkSXG45MFral3GxPaY4uAl0LYDZM+YDVDAiU9bYwjTuysy1S0IeecWtmq1SZA3M1w==} + engines: {node: '>=8'} + '@xmldom/xmldom@0.8.10': resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} engines: {node: '>=10.0.0'} @@ -7290,8 +7688,8 @@ packages: axios@1.6.8: resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} - axios@1.7.2: - resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + axios@1.7.4: + resolution: {integrity: sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==} babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} @@ -7545,8 +7943,8 @@ packages: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - chance@1.1.11: - resolution: {integrity: sha512-kqTg3WWywappJPqtgrdvbA380VoXO2eu9VCV895JgbyHsaErXdyHK9LOZ911OvAk6L0obK7kDk9CGs8+oBawVA==} + chance@1.1.12: + resolution: {integrity: sha512-vVBIGQVnwtUG+SYe0ge+3MvF78cvSpuCOEUJr7sVEk2vSBuMW6OXNJjSzdtzrlxNUEaoqH2GBd5Y/+18BEB01Q==} change-case-all@1.0.15: resolution: {integrity: sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ==} @@ -7767,10 +8165,6 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} - commander@12.0.0: - resolution: {integrity: sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==} - engines: {node: '>=18'} - commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} @@ -8357,8 +8751,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - effect@3.0.3: - resolution: {integrity: sha512-mgG+FoWrM4sny8OxDFWCpq+6LwGf9cK/JztVhxZQeZM9ZMXY+lKbdMEQmemNYce0QVAz2+YqUKwhKzOidwbZzg==} + effect@3.5.7: + resolution: {integrity: sha512-PzEncc0R3ZZhqNTR+fXrSX+anF/4Ai6ftKie1ZrUUWY7WPE7d4KjB6wjpeWoGMOC7xWFPGSkBBUudyJN1mx3+g==} ejs@3.1.10: resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} @@ -8711,8 +9105,8 @@ packages: resolution: {integrity: sha512-XUizHanzlr/v7suBr/o85HSakOoWh6HKXZjFYl5C2+Gj0f0rkw+XTUZzrd9odDsgI9G5tRUcF4wSbKaX04T0DQ==} engines: {node: '>=10'} - fast-check@3.17.2: - resolution: {integrity: sha512-+3DPTxtxABLgmmVpYxrash3DHoq0cMa1jjLYNp3qqokKKhqVEaS4lbnaDKqWU5Dd6C2pEudPPBAEEQ9nUou9OQ==} + fast-check@3.20.0: + resolution: {integrity: sha512-pZIjqLpOZgdSLecec4GKC3Zq5702MZ34upMKxojnNVSWA0K64V3pXOBT1Wdsrc3AphLtzRBbsi8bRWF4TUGmUg==} engines: {node: '>=8.0.0'} fast-decode-uri-component@1.0.1: @@ -8758,6 +9152,10 @@ packages: resolution: {integrity: sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==} hasBin: true + fast-xml-parser@4.4.1: + resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==} + hasBin: true + fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} @@ -9133,6 +9531,10 @@ packages: resolution: {integrity: sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==} engines: {node: '>=18'} + globby@14.0.2: + resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==} + engines: {node: '>=18'} + google-auth-library@9.9.0: resolution: {integrity: sha512-9l+zO07h1tDJdIHN74SpnWIlNR+OuOemXlWJlLP9pXy6vFtizgpEzMuwJa4lqY9UAdiAv5DVd5ql0Am916I+aA==} engines: {node: '>=14'} @@ -9298,6 +9700,9 @@ packages: hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + hook-std@3.0.0: resolution: {integrity: sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -9386,8 +9791,8 @@ packages: humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - husky@9.1.1: - resolution: {integrity: sha512-fCqlqLXcBnXa/TJXmT93/A36tJsjdJkibQ1MuIiFyCCYUlpYpIaj2mv1w+3KR6Rzu1IC3slFTje5f6DUp2A2rg==} + husky@9.1.4: + resolution: {integrity: sha512-bho94YyReb4JV7LYWRWxZ/xr6TtOTt8cMfmQ39MQYJ7f/YE268s3GdghGwi+y4zAeqewE5zYLvuhV0M0ijsDEA==} engines: {node: '>=18'} hasBin: true @@ -9435,6 +9840,9 @@ packages: resolution: {integrity: sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ==} engines: {node: '>=12.2'} + import-in-the-middle@1.11.0: + resolution: {integrity: sha512-5DimNQGoe0pLUHbR9qK84iWaWjjbsxiqXnw6Qz64+azRgleqv9k2kTt5fw7QsOpmaGYtuxxursnPPsnTKEx10Q==} + import-in-the-middle@1.7.1: resolution: {integrity: sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==} @@ -9716,6 +10124,9 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} @@ -10460,6 +10871,9 @@ packages: lodash.difference@4.5.0: resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + lodash.escape@4.0.1: + resolution: {integrity: sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==} + lodash.escaperegexp@4.1.2: resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} @@ -10541,6 +10955,9 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + lodash.unescape@4.0.1: + resolution: {integrity: sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==} + lodash.union@4.6.0: resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} @@ -10610,10 +11027,6 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - lru-cache@7.18.3: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} @@ -10668,6 +11081,9 @@ packages: mark.js@8.11.1: resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + markdown-to-txt@2.0.1: + resolution: {integrity: sha512-Hsj7KTN8k1gutlLum3vosHwVZGnv8/cbYKWVkUyo/D1rzOYddbDesILebRfOsaVfjIBJank/AVOySBlHAYqfZw==} + marked-terminal@7.0.0: resolution: {integrity: sha512-sNEx8nn9Ktcm6pL0TnRz8tnXq/mSS0Q1FRSwJOAqw4lAB4l49UeDf85Gm1n9RPFm5qurCPjwi1StAQT2XExhZw==} engines: {node: '>=16.0.0'} @@ -10794,6 +11210,10 @@ packages: minimalistic-crypto-utils@1.0.1: resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + minimatch@10.0.1: + resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + engines: {node: 20 || >=22} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -10998,6 +11418,10 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + nock@14.0.0-beta.11: + resolution: {integrity: sha512-tmImk6btCUcCFHXkhqZnuSe4e/4M/YYs8qYaQGdjZSBloTXgQyuPrgjzn45zmFWpK2bDSEtIcF8olFdFxRaA1g==} + engines: {node: '>= 18'} + nock@14.0.0-beta.6: resolution: {integrity: sha512-b7lc7qvj1dQzxtbU7TqyTMnKbNKwGQd585xsRtcCZOv3I/yOK9Vwv4nOgnLFxFtX9m1yjhQDRbgqFCqNh9HuEw==} engines: {node: '>= 18'} @@ -11104,8 +11528,8 @@ packages: resolution: {integrity: sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - npm-package-arg@11.0.2: - resolution: {integrity: sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==} + npm-package-arg@11.0.3: + resolution: {integrity: sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==} engines: {node: ^16.14.0 || >=18.0.0} npm-packlist@5.1.3: @@ -11306,6 +11730,9 @@ packages: peerDependencies: '@opentelemetry/api': ^1.6.0 + optimism@0.16.2: + resolution: {integrity: sha512-zWNbgWj+3vLEjZNIh/okkY2EUfX+vB9TJopzIZwT1xxaMqC5hRLLraePod4c5n4He08xuXNH+zhKFFCu390wiQ==} + optimist@0.6.1: resolution: {integrity: sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==} @@ -11325,6 +11752,9 @@ packages: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + owasp-password-strength-test@1.3.0: resolution: {integrity: sha512-33/Z+vyjlFaVZsT7aAFe3SkQZdU6su59XNkYdU5o2Fssz0D9dt6uiFaMm62M7dFQSKogULq8UYvdKnHkeqNB2w==} @@ -11768,8 +12198,8 @@ packages: resolution: {integrity: sha512-VpNpolZ8RXRgfU+j4R+fPZmX8EE95w3vJ2tt7+FwuiQc0leNTfLK5QLf3KbbPDes2rfjh3g20AjDxefQIo5GIA==} hasBin: true - prisma@5.14.0: - resolution: {integrity: sha512-gCNZco7y5XtjrnQYeDJTiVZmT/ncqCr5RY1/Cf8X2wgLRmyh9ayPAGBNziI4qEE4S6SxCH5omQLVo9lmURaJ/Q==} + prisma@5.18.0: + resolution: {integrity: sha512-+TrSIxZsh64OPOmaSgVPH7ALL9dfU0jceYaMJXsNrTkFHO7/3RANi5K2ZiPB1De9+KDxCWn7jvRq8y8pvk+o9g==} engines: {node: '>=16.13'} hasBin: true @@ -12123,6 +12553,10 @@ packages: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true + response-iterator@0.2.6: + resolution: {integrity: sha512-pVzEEzrsg23Sh053rmDUvLSkGXluZio0qu8VT6ukrYuvtjVfCbDZH9d6PGXb8HZfzdNZt8feXv/jvUzlhRgLnw==} + engines: {node: '>=0.8'} + response-time@2.3.2: resolution: {integrity: sha512-MUIDaDQf+CVqflfTdQ5yam+aYCkXj1PY8fjlPDQ6ppxJlmgZb864pHtA750mayywNg8tx4rS7qH9JXd/OF+3gw==} engines: {node: '>= 0.8.0'} @@ -12166,8 +12600,8 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rollup@4.18.1: - resolution: {integrity: sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==} + rollup@4.21.1: + resolution: {integrity: sha512-ZnYyKvscThhgd3M5+Qt3pmhO4jIRR5RGzaSovB6Q7rGNrK5cUncrtLmcTTJVSdcKXyZjW8X8MB0JMSuH9bcAJg==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -12248,8 +12682,8 @@ packages: peerDependencies: semantic-release: '>20' - semantic-release@24.0.0: - resolution: {integrity: sha512-v46CRPw+9eI3ZuYGF2oAjqPqsfbnfFTwLBgQsv/lch4goD09ytwOTESMN4QIrx/wPLxUGey60/NMx+ANQtWRsA==} + semantic-release@24.1.0: + resolution: {integrity: sha512-FwaE2hKDHQn9G6GA7xmqsc9WnsjaFD/ppLM5PUg56Do9oKSCf+vH6cPeb3hEBV/m06n8Sh9vbVqPjHu/1onzQw==} engines: {node: '>=20.8.1'} hasBin: true @@ -12272,13 +12706,13 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} engines: {node: '>=10'} hasBin: true - semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} hasBin: true @@ -12594,6 +13028,9 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + string-env-interpolation@1.0.1: resolution: {integrity: sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==} @@ -12766,6 +13203,10 @@ packages: swap-case@2.0.2: resolution: {integrity: sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==} + symbol-observable@4.0.0: + resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} + engines: {node: '>=0.10'} + symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -12773,8 +13214,8 @@ packages: resolution: {integrity: sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==} engines: {node: ^14.18.0 || >=16.0.0} - syncpack@12.3.3: - resolution: {integrity: sha512-r154Rk8YtJA0My8Nu5v4e58n3y85atG4WlxekTQ/DT4toqiMtprqn5LrHuNVAhbpsOfUHPv6EFMj9k+FdDvgDA==} + syncpack@12.4.0: + resolution: {integrity: sha512-iVDbuxW1zpjC8IuGLLgTjfgnAjr1iTd+In//RGUi49nKT8f6BWYSEAt496fj4eGNmYeajUiGngBHl15Jb++RBg==} engines: {node: '>=16'} hasBin: true @@ -12936,6 +13377,10 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-invariant@0.10.3: + resolution: {integrity: sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==} + engines: {node: '>=8'} + ts-jest@29.2.3: resolution: {integrity: sha512-yCcfVdiBFngVz9/keHin9EnsrQtQtEu3nRykNy9RVp+FiPFFbPJ3Sg6Qg4+TkmH0vMP5qsTKgXSsk80HRwvdgQ==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} @@ -12960,6 +13405,30 @@ packages: esbuild: optional: true + ts-jest@29.2.4: + resolution: {integrity: sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + ts-log@2.2.5: resolution: {integrity: sha512-PGcnJoTBnVGy6yYNFxWVNkdcAuAMstvutN9MgDJIV6L0oG8fB+ZNNy1T+wJzah8RPGor1mZuPQkVfXNDpy9eHA==} @@ -12993,8 +13462,8 @@ packages: resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} engines: {node: '>=0.6.x'} - tsup@8.1.2: - resolution: {integrity: sha512-Gzw/PXSX/z0aYMNmkcI54bKKFVFJQbLne+EqTJZeQ3lNT3QpumjtMU4rl+ZwTTp8oRF3ahMbEAxT2sZPJLFSrg==} + tsup@8.2.4: + resolution: {integrity: sha512-akpCPePnBnC/CXgRrcy72ZSntgIEUa1jN0oJbbvpALWKNOz1B7aM+UVDWGRGIO/T/PZugAESWDJUAb5FD48o8Q==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -13023,38 +13492,38 @@ packages: tunnel-ssh@4.1.6: resolution: {integrity: sha512-y7+x+T3F3rkx2Zov5Tk9DGfeEBVAdWU3A/91E0Dk5rrZ/VFIlpV2uhhRuaISJUdyG0N+Lcp1fXZMXz+ovPt5vA==} - turbo-darwin-64@1.13.4: - resolution: {integrity: sha512-A0eKd73R7CGnRinTiS7txkMElg+R5rKFp9HV7baDiEL4xTG1FIg/56Vm7A5RVgg8UNgG2qNnrfatJtb+dRmNdw==} + turbo-darwin-64@2.1.0: + resolution: {integrity: sha512-gHwpDk2gyB7qZ57gUUwDIS/IkglqEjjVtPZCTxmCRg28Tiwjui0azsLVKrnHP9UZHllozwbi28x8HXLXLEFF1w==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@1.13.4: - resolution: {integrity: sha512-eG769Q0NF6/Vyjsr3mKCnkG/eW6dKMBZk6dxWOdrHfrg6QgfkBUk0WUUujzdtVPiUIvsh4l46vQrNVd9EOtbyA==} + turbo-darwin-arm64@2.1.0: + resolution: {integrity: sha512-GLaqGetNC6eS4eqXgsheLOHic/OcnGCGDi5boVf+TFZTXYH6YE15L4ugZha4xHXCr1KouCLILHh+f8EHEmWylg==} cpu: [arm64] os: [darwin] - turbo-linux-64@1.13.4: - resolution: {integrity: sha512-Bq0JphDeNw3XEi+Xb/e4xoKhs1DHN7OoLVUbTIQz+gazYjigVZvtwCvgrZI7eW9Xo1eOXM2zw2u1DGLLUfmGkQ==} + turbo-linux-64@2.1.0: + resolution: {integrity: sha512-VzBOsj7JyGoZtiNZZ6brjnY7UehRnClluw7pwznuLPzClkqOOPMd2jOcgkWxnP/xW4NBmOoFANXXrtvKBD4f2w==} cpu: [x64] os: [linux] - turbo-linux-arm64@1.13.4: - resolution: {integrity: sha512-BJcXw1DDiHO/okYbaNdcWN6szjXyHWx9d460v6fCHY65G8CyqGU3y2uUTPK89o8lq/b2C8NK0yZD+Vp0f9VoIg==} + turbo-linux-arm64@2.1.0: + resolution: {integrity: sha512-St7svJnOO5g4F6R7Z32e10I/0M3e6qpNjEYybXwPNul9NSfnUXeky4WoKaALwqNhyJ7nYemoFpZ1d+i8hFQTHg==} cpu: [arm64] os: [linux] - turbo-windows-64@1.13.4: - resolution: {integrity: sha512-OFFhXHOFLN7A78vD/dlVuuSSVEB3s9ZBj18Tm1hk3aW1HTWTuAw0ReN6ZNlVObZUHvGy8d57OAGGxf2bT3etQw==} + turbo-windows-64@2.1.0: + resolution: {integrity: sha512-iSobNud2MrJ1SZ1upVPlErT8xexsr0MQtKapdfq6z0M0rBnrDGEq5bUCSScWyGu+O4+glB4br9xkTAkGFqaxqQ==} cpu: [x64] os: [win32] - turbo-windows-arm64@1.13.4: - resolution: {integrity: sha512-u5A+VOKHswJJmJ8o8rcilBfU5U3Y1TTAfP9wX8bFh8teYF1ghP0EhtMRLjhtp6RPa+XCxHHVA2CiC3gbh5eg5g==} + turbo-windows-arm64@2.1.0: + resolution: {integrity: sha512-d61jN4rjE5PnUfF66GKrKoj8S8Ql4FGXzFFzZz4kjsHpZZzCTtqlzPZBmd1byzGYhDPTorTqG3G1USohbdyohA==} cpu: [arm64] os: [win32] - turbo@1.13.4: - resolution: {integrity: sha512-1q7+9UJABuBAHrcC4Sxp5lOqYS5mvxRrwa33wpIyM18hlOCpRD/fTJNxZ0vhbMcJmz15o9kkVm743mPn7p6jpQ==} + turbo@2.1.0: + resolution: {integrity: sha512-A969/LO/sPHKlapIarY2VVzqQ5JnnW2/1kksZlnMEpsRD6gwOELvVL+ozfMiO7av9RILt3UeN02L17efr6HUCA==} hasBin: true turndown@7.2.0: @@ -13099,10 +13568,6 @@ packages: resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} engines: {node: '>=12.20'} - type-fest@4.18.2: - resolution: {integrity: sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==} - engines: {node: '>=16'} - type-fest@4.21.0: resolution: {integrity: sha512-ADn2w7hVPcK6w1I0uWnM//y1rLXZhzB9mr0a3OirzclKF1Wp6VzevUmzz/NRAWunOT6E8HrnpGY7xOfc6K57fA==} engines: {node: '>=16'} @@ -13137,11 +13602,10 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@7.16.1: - resolution: {integrity: sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==} - engines: {node: ^18.18.0 || >=20.0.0} + typescript-eslint@8.3.0: + resolution: {integrity: sha512-EvWjwWLwwKDIJuBjk2I6UkV8KEQcwZ0VM10nR1rIunRDIP67QJTZAHBXTX0HW/oI1H10YESF8yWie8fRQxjvFA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.56.0 typescript: '*' peerDependenciesMeta: typescript: @@ -13157,8 +13621,13 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.6.0-dev.20240805: - resolution: {integrity: sha512-M+pWeLKA2huCTB2GLE0/0U/ezJh51Wdmm6J3BS1UxieKcnx1Kz2/NivXOnmCZY40gY6ItpMlLjnJIMXprNG9UQ==} + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.7.0-dev.20240829: + resolution: {integrity: sha512-F9kcFC/YWjYhecieA4GmXEu8IDrRtfONo3Pw61UZb9aQYDhbrfqpoz5ixfEt6O9rrSFvzdh1i0o1MRY2Bt/BLg==} engines: {node: '>=14.17'} hasBin: true @@ -13190,6 +13659,9 @@ packages: undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici@6.18.2: resolution: {integrity: sha512-o/MQLTwRm9IVhOqhZ0NQ9oXax1ygPjw6Vs+Vq/4QRjbOAC3B1GCHy7TYxxbExKlb7bzDRzt9vBWU6BDz0RFfYg==} engines: {node: '>=18.17'} @@ -13651,6 +14123,12 @@ packages: engines: {node: '>=8.0.0'} hasBin: true + zen-observable-ts@1.2.5: + resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==} + + zen-observable@0.8.15: + resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} + zip-stream@4.1.1: resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} engines: {node: '>= 10'} @@ -13700,6 +14178,27 @@ snapshots: dependencies: graphql: 16.8.1 + '@apollo/client@3.7.17(graphql-ws@5.16.0(graphql@16.9.0))(graphql@16.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.9.0) + '@wry/context': 0.7.4 + '@wry/equality': 0.5.7 + '@wry/trie': 0.4.3 + graphql: 16.9.0 + graphql-tag: 2.12.6(graphql@16.9.0) + hoist-non-react-statics: 3.3.2 + optimism: 0.16.2 + prop-types: 15.8.1 + response-iterator: 0.2.6 + symbol-observable: 4.0.0 + ts-invariant: 0.10.3 + tslib: 2.6.3 + zen-observable-ts: 1.2.5 + optionalDependencies: + graphql-ws: 5.16.0(graphql@16.9.0) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + '@apollo/datasource-rest@6.3.0(encoding@0.1.13)(graphql@16.8.1)': dependencies: '@apollo/utils.fetcher': 3.1.0 @@ -13715,7 +14214,7 @@ snapshots: transitivePeerDependencies: - encoding - '@apollo/federation-internals@2.8.3(graphql@16.8.1)': + '@apollo/federation-internals@2.9.0(graphql@16.8.1)': dependencies: '@types/uuid': 9.0.8 chalk: 4.1.2 @@ -13785,10 +14284,10 @@ snapshots: - encoding - supports-color - '@apollo/subgraph@2.8.3(graphql@16.8.1)': + '@apollo/subgraph@2.9.0(graphql@16.8.1)': dependencies: '@apollo/cache-control-types': 1.0.3(graphql@16.8.1) - '@apollo/federation-internals': 2.8.3(graphql@16.8.1) + '@apollo/federation-internals': 2.9.0(graphql@16.8.1) graphql: 16.8.1 '@apollo/usage-reporting-protobuf@4.1.1': @@ -13947,46 +14446,46 @@ snapshots: '@smithy/util-utf8': 2.3.0 tslib: 2.6.3 - '@aws-sdk/client-cloudwatch@3.609.0': + '@aws-sdk/client-cloudwatch@3.632.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/client-sts': 3.609.0 - '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/core': 2.2.4 - '@smithy/fetch-http-handler': 3.2.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-compression': 3.0.4 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-compression': 3.0.7 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 @@ -13995,46 +14494,46 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-dynamodb@3.609.0': + '@aws-sdk/client-dynamodb@3.632.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/client-sts': 3.609.0 - '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/middleware-endpoint-discovery': 3.609.0 - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-endpoint-discovery': 3.620.0 + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/core': 2.2.4 - '@smithy/fetch-http-handler': 3.2.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 @@ -14044,91 +14543,92 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-eventbridge@3.609.0': + '@aws-sdk/client-eventbridge@3.632.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/client-sts': 3.609.0 - '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-signing': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 - '@aws-sdk/signature-v4-multi-region': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 + '@aws-sdk/signature-v4-multi-region': 3.629.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/fetch-http-handler': 3.2.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 + '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-firehose@3.609.0': + '@aws-sdk/client-firehose@3.632.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/client-sts': 3.609.0 - '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/core': 2.2.4 - '@smithy/fetch-http-handler': 3.2.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 @@ -14136,257 +14636,300 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-kinesis@3.609.0': + '@aws-sdk/client-kinesis@3.632.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/client-sts': 3.609.0 - '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/core': 2.2.4 - '@smithy/eventstream-serde-browser': 3.0.4 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/eventstream-serde-browser': 3.0.6 '@smithy/eventstream-serde-config-resolver': 3.0.3 - '@smithy/eventstream-serde-node': 3.0.4 - '@smithy/fetch-http-handler': 3.2.0 + '@smithy/eventstream-serde-node': 3.0.5 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-base64': 3.0.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-body-length-node': 3.0.0 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + '@smithy/util-utf8': 3.0.0 + '@smithy/util-waiter': 3.1.2 + tslib: 2.6.3 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-lambda@3.632.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-host-header': 3.620.0 + '@aws-sdk/middleware-logger': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 + '@aws-sdk/types': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 + '@aws-sdk/util-user-agent-browser': 3.609.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/eventstream-serde-browser': 3.0.6 + '@smithy/eventstream-serde-config-resolver': 3.0.3 + '@smithy/eventstream-serde-node': 3.0.5 + '@smithy/fetch-http-handler': 3.2.4 + '@smithy/hash-node': 3.0.3 + '@smithy/invalid-dependency': 3.0.3 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 + '@smithy/middleware-serde': 3.0.3 + '@smithy/middleware-stack': 3.0.3 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 + '@smithy/util-stream': 3.1.3 '@smithy/util-utf8': 3.0.0 '@smithy/util-waiter': 3.1.2 tslib: 2.6.3 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-lambda@3.609.0': + '@aws-sdk/client-secrets-manager@3.632.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/client-sts': 3.609.0 - '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/core': 2.2.4 - '@smithy/eventstream-serde-browser': 3.0.4 - '@smithy/eventstream-serde-config-resolver': 3.0.3 - '@smithy/eventstream-serde-node': 3.0.4 - '@smithy/fetch-http-handler': 3.2.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 - '@smithy/util-stream': 3.0.5 '@smithy/util-utf8': 3.0.0 - '@smithy/util-waiter': 3.1.2 tslib: 2.6.3 + uuid: 9.0.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-secrets-manager@3.609.0': + '@aws-sdk/client-sqs@3.632.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/client-sts': 3.609.0 - '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-sdk-sqs': 3.622.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/core': 2.2.4 - '@smithy/fetch-http-handler': 3.2.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/md5-js': 3.0.3 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - uuid: 9.0.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sqs@3.609.0': + '@aws-sdk/client-ssm@3.632.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/client-sts': 3.609.0 - '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-sdk-sqs': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/core': 2.2.4 - '@smithy/fetch-http-handler': 3.2.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/md5-js': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 + '@smithy/util-waiter': 3.1.2 tslib: 2.6.3 + uuid: 9.0.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-ssm@3.609.0': + '@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0)': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/client-sts': 3.609.0 - '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/core': 2.2.4 - '@smithy/fetch-http-handler': 3.2.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 - '@smithy/util-waiter': 3.1.2 tslib: 2.6.3 - uuid: 9.0.1 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0)': + '@aws-sdk/client-sso@3.609.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sts': 3.609.0 '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) '@aws-sdk/middleware-host-header': 3.609.0 '@aws-sdk/middleware-logger': 3.609.0 '@aws-sdk/middleware-recursion-detection': 3.609.0 @@ -14425,42 +14968,42 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.609.0': + '@aws-sdk/client-sso@3.632.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.609.0 - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/core': 3.629.0 + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/core': 2.2.4 - '@smithy/fetch-http-handler': 3.2.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 @@ -14468,44 +15011,44 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sts@3.609.0': + '@aws-sdk/client-sts@3.632.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/core': 3.609.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) - '@aws-sdk/middleware-host-header': 3.609.0 + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/core': 3.629.0 + '@aws-sdk/credential-provider-node': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.609.0 - '@aws-sdk/region-config-resolver': 3.609.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.632.0 + '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 + '@aws-sdk/util-endpoints': 3.632.0 '@aws-sdk/util-user-agent-browser': 3.609.0 - '@aws-sdk/util-user-agent-node': 3.609.0 - '@smithy/config-resolver': 3.0.4 - '@smithy/core': 2.2.4 - '@smithy/fetch-http-handler': 3.2.0 + '@aws-sdk/util-user-agent-node': 3.614.0 + '@smithy/config-resolver': 3.0.5 + '@smithy/core': 2.4.0 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.3 - '@smithy/middleware-endpoint': 3.0.4 - '@smithy/middleware-retry': 3.0.7 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 - '@smithy/node-config-provider': 3.1.3 - '@smithy/node-http-handler': 3.1.1 - '@smithy/protocol-http': 4.0.3 - '@smithy/smithy-client': 3.1.5 + '@smithy/node-config-provider': 3.1.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.7 - '@smithy/util-defaults-mode-node': 3.0.7 - '@smithy/util-endpoints': 2.0.4 + '@smithy/util-defaults-mode-browser': 3.0.15 + '@smithy/util-defaults-mode-node': 3.0.15 + '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 '@smithy/util-utf8': 3.0.0 @@ -14523,6 +15066,19 @@ snapshots: fast-xml-parser: 4.2.5 tslib: 2.6.3 + '@aws-sdk/core@3.629.0': + dependencies: + '@smithy/core': 2.4.0 + '@smithy/node-config-provider': 3.1.4 + '@smithy/property-provider': 3.1.3 + '@smithy/protocol-http': 4.1.0 + '@smithy/signature-v4': 4.1.0 + '@smithy/smithy-client': 3.2.0 + '@smithy/types': 3.3.0 + '@smithy/util-middleware': 3.0.3 + fast-xml-parser: 4.4.1 + tslib: 2.6.3 + '@aws-sdk/credential-provider-env@3.609.0': dependencies: '@aws-sdk/types': 3.609.0 @@ -14530,6 +15086,13 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 + '@aws-sdk/credential-provider-env@3.620.1': + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@aws-sdk/credential-provider-http@3.609.0': dependencies: '@aws-sdk/types': 3.609.0 @@ -14542,14 +15105,26 @@ snapshots: '@smithy/util-stream': 3.0.5 tslib: 2.6.3 - '@aws-sdk/credential-provider-ini@3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0)': + '@aws-sdk/credential-provider-http@3.622.0': + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/fetch-http-handler': 3.2.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/property-provider': 3.1.3 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 + '@smithy/types': 3.3.0 + '@smithy/util-stream': 3.1.3 + tslib: 2.6.3 + + '@aws-sdk/credential-provider-ini@3.609.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0)': dependencies: - '@aws-sdk/client-sts': 3.609.0 + '@aws-sdk/client-sts': 3.632.0 '@aws-sdk/credential-provider-env': 3.609.0 '@aws-sdk/credential-provider-http': 3.609.0 '@aws-sdk/credential-provider-process': 3.609.0 - '@aws-sdk/credential-provider-sso': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0)) - '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.609.0) + '@aws-sdk/credential-provider-sso': 3.609.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0)) + '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.632.0) '@aws-sdk/types': 3.609.0 '@smithy/credential-provider-imds': 3.1.3 '@smithy/property-provider': 3.1.3 @@ -14560,14 +15135,32 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-node@3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0)': + '@aws-sdk/credential-provider-ini@3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0)': + dependencies: + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/credential-provider-env': 3.620.1 + '@aws-sdk/credential-provider-http': 3.622.0 + '@aws-sdk/credential-provider-process': 3.620.1 + '@aws-sdk/credential-provider-sso': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0)) + '@aws-sdk/credential-provider-web-identity': 3.621.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/types': 3.609.0 + '@smithy/credential-provider-imds': 3.2.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - aws-crt + + '@aws-sdk/credential-provider-node@3.609.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0)': dependencies: '@aws-sdk/credential-provider-env': 3.609.0 '@aws-sdk/credential-provider-http': 3.609.0 - '@aws-sdk/credential-provider-ini': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) + '@aws-sdk/credential-provider-ini': 3.609.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) '@aws-sdk/credential-provider-process': 3.609.0 - '@aws-sdk/credential-provider-sso': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0)) - '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.609.0) + '@aws-sdk/credential-provider-sso': 3.609.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0)) + '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.632.0) '@aws-sdk/types': 3.609.0 '@smithy/credential-provider-imds': 3.1.3 '@smithy/property-provider': 3.1.3 @@ -14579,6 +15172,25 @@ snapshots: - '@aws-sdk/client-sts' - aws-crt + '@aws-sdk/credential-provider-node@3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0)': + dependencies: + '@aws-sdk/credential-provider-env': 3.620.1 + '@aws-sdk/credential-provider-http': 3.622.0 + '@aws-sdk/credential-provider-ini': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/credential-provider-process': 3.620.1 + '@aws-sdk/credential-provider-sso': 3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0)) + '@aws-sdk/credential-provider-web-identity': 3.621.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/types': 3.609.0 + '@smithy/credential-provider-imds': 3.2.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - '@aws-sdk/client-sts' + - aws-crt + '@aws-sdk/credential-provider-process@3.609.0': dependencies: '@aws-sdk/types': 3.609.0 @@ -14587,10 +15199,18 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/credential-provider-sso@3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))': + '@aws-sdk/credential-provider-process@3.620.1': + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + + '@aws-sdk/credential-provider-sso@3.609.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))': dependencies: '@aws-sdk/client-sso': 3.609.0 - '@aws-sdk/token-providers': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0)) + '@aws-sdk/token-providers': 3.609.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0)) '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.3 @@ -14600,9 +15220,30 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-web-identity@3.609.0(@aws-sdk/client-sts@3.609.0)': + '@aws-sdk/credential-provider-sso@3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))': + dependencies: + '@aws-sdk/client-sso': 3.632.0 + '@aws-sdk/token-providers': 3.614.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0)) + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + transitivePeerDependencies: + - '@aws-sdk/client-sso-oidc' + - aws-crt + + '@aws-sdk/credential-provider-web-identity@3.609.0(@aws-sdk/client-sts@3.632.0)': + dependencies: + '@aws-sdk/client-sts': 3.632.0 + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + + '@aws-sdk/credential-provider-web-identity@3.621.0(@aws-sdk/client-sts@3.632.0)': dependencies: - '@aws-sdk/client-sts': 3.609.0 + '@aws-sdk/client-sts': 3.632.0 '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 '@smithy/types': 3.3.0 @@ -14613,20 +15254,21 @@ snapshots: mnemonist: 0.38.3 tslib: 2.6.3 - '@aws-sdk/lib-dynamodb@3.609.0(@aws-sdk/client-dynamodb@3.609.0)': + '@aws-sdk/lib-dynamodb@3.632.0(@aws-sdk/client-dynamodb@3.632.0)': dependencies: - '@aws-sdk/client-dynamodb': 3.609.0 - '@aws-sdk/util-dynamodb': 3.609.0(@aws-sdk/client-dynamodb@3.609.0) - '@smithy/smithy-client': 3.1.5 + '@aws-sdk/client-dynamodb': 3.632.0 + '@aws-sdk/util-dynamodb': 3.632.0(@aws-sdk/client-dynamodb@3.632.0) + '@smithy/core': 2.4.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/middleware-endpoint-discovery@3.609.0': + '@aws-sdk/middleware-endpoint-discovery@3.620.0': dependencies: '@aws-sdk/endpoint-cache': 3.572.0 '@aws-sdk/types': 3.609.0 - '@smithy/node-config-provider': 3.1.3 - '@smithy/protocol-http': 4.0.3 + '@smithy/node-config-provider': 3.1.4 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 tslib: 2.6.3 @@ -14637,6 +15279,13 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 + '@aws-sdk/middleware-host-header@3.620.0': + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/protocol-http': 4.1.0 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@aws-sdk/middleware-logger@3.609.0': dependencies: '@aws-sdk/types': 3.609.0 @@ -14650,42 +15299,52 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/middleware-sdk-s3@3.609.0': + '@aws-sdk/middleware-recursion-detection@3.620.0': + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/protocol-http': 4.1.0 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + + '@aws-sdk/middleware-sdk-s3@3.629.0': dependencies: + '@aws-sdk/core': 3.629.0 '@aws-sdk/types': 3.609.0 '@aws-sdk/util-arn-parser': 3.568.0 - '@smithy/node-config-provider': 3.1.3 - '@smithy/protocol-http': 4.0.3 - '@smithy/signature-v4': 3.1.2 - '@smithy/smithy-client': 3.1.5 + '@smithy/core': 2.4.0 + '@smithy/node-config-provider': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/signature-v4': 4.1.0 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-stream': 3.1.3 + '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@aws-sdk/middleware-sdk-sqs@3.609.0': + '@aws-sdk/middleware-sdk-sqs@3.622.0': dependencies: '@aws-sdk/types': 3.609.0 - '@smithy/smithy-client': 3.1.5 + '@smithy/smithy-client': 3.2.0 '@smithy/types': 3.3.0 '@smithy/util-hex-encoding': 3.0.0 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@aws-sdk/middleware-signing@3.609.0': + '@aws-sdk/middleware-user-agent@3.609.0': dependencies: '@aws-sdk/types': 3.609.0 - '@smithy/property-provider': 3.1.3 + '@aws-sdk/util-endpoints': 3.609.0 '@smithy/protocol-http': 4.0.3 - '@smithy/signature-v4': 3.1.2 '@smithy/types': 3.3.0 - '@smithy/util-middleware': 3.0.3 tslib: 2.6.3 - '@aws-sdk/middleware-user-agent@3.609.0': + '@aws-sdk/middleware-user-agent@3.632.0': dependencies: '@aws-sdk/types': 3.609.0 - '@aws-sdk/util-endpoints': 3.609.0 - '@smithy/protocol-http': 4.0.3 + '@aws-sdk/util-endpoints': 3.632.0 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 tslib: 2.6.3 @@ -14698,24 +15357,42 @@ snapshots: '@smithy/util-middleware': 3.0.3 tslib: 2.6.3 - '@aws-sdk/signature-v4-multi-region@3.609.0': + '@aws-sdk/region-config-resolver@3.614.0': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.609.0 '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.3 - '@smithy/signature-v4': 3.1.2 + '@smithy/node-config-provider': 3.1.4 + '@smithy/types': 3.3.0 + '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.3 + tslib: 2.6.3 + + '@aws-sdk/signature-v4-multi-region@3.629.0': + dependencies: + '@aws-sdk/middleware-sdk-s3': 3.629.0 + '@aws-sdk/types': 3.609.0 + '@smithy/protocol-http': 4.1.0 + '@smithy/signature-v4': 4.1.0 '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/token-providers@3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))': + '@aws-sdk/token-providers@3.609.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))': dependencies: - '@aws-sdk/client-sso-oidc': 3.609.0(@aws-sdk/client-sts@3.609.0) + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.3 '@smithy/types': 3.3.0 tslib: 2.6.3 + '@aws-sdk/token-providers@3.614.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))': + dependencies: + '@aws-sdk/client-sso-oidc': 3.632.0(@aws-sdk/client-sts@3.632.0) + '@aws-sdk/types': 3.609.0 + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@aws-sdk/types@3.609.0': dependencies: '@smithy/types': 3.3.0 @@ -14725,9 +15402,9 @@ snapshots: dependencies: tslib: 2.6.3 - '@aws-sdk/util-dynamodb@3.609.0(@aws-sdk/client-dynamodb@3.609.0)': + '@aws-sdk/util-dynamodb@3.632.0(@aws-sdk/client-dynamodb@3.632.0)': dependencies: - '@aws-sdk/client-dynamodb': 3.609.0 + '@aws-sdk/client-dynamodb': 3.632.0 tslib: 2.6.3 '@aws-sdk/util-endpoints@3.609.0': @@ -14737,6 +15414,13 @@ snapshots: '@smithy/util-endpoints': 2.0.4 tslib: 2.6.3 + '@aws-sdk/util-endpoints@3.632.0': + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/types': 3.3.0 + '@smithy/util-endpoints': 2.0.5 + tslib: 2.6.3 + '@aws-sdk/util-locate-window@3.568.0': dependencies: tslib: 2.6.3 @@ -14755,6 +15439,13 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 + '@aws-sdk/util-user-agent-node@3.614.0': + dependencies: + '@aws-sdk/types': 3.609.0 + '@smithy/node-config-provider': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@babel/code-frame@7.24.2': dependencies: '@babel/highlight': 7.24.5 @@ -15469,12 +16160,12 @@ snapshots: nan: 2.19.0 prebuild-install: 7.1.2 - '@cdktf/provider-archive@10.0.1(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0)': + '@cdktf/provider-archive@10.1.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0)': dependencies: cdktf: 0.20.8(constructs@10.3.0) constructs: 10.3.0 - '@cdktf/provider-aws@19.26.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0)': + '@cdktf/provider-aws@19.31.0(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0)': dependencies: cdktf: 0.20.8(constructs@10.3.0) constructs: 10.3.0 @@ -15497,7 +16188,7 @@ snapshots: cdktf: 0.20.8(constructs@10.3.0) constructs: 10.3.0 - '@cdktf/provider-newrelic@12.10.3(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0)': + '@cdktf/provider-newrelic@12.12.2(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0)': dependencies: cdktf: 0.20.8(constructs@10.3.0) constructs: 10.3.0 @@ -15507,7 +16198,7 @@ snapshots: cdktf: 0.20.8(constructs@10.3.0) constructs: 10.3.0 - '@cdktf/provider-pagerduty@13.10.2(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0)': + '@cdktf/provider-pagerduty@13.11.4(cdktf@0.20.8(constructs@10.3.0))(constructs@10.3.0)': dependencies: cdktf: 0.20.8(constructs@10.3.0) constructs: 10.3.0 @@ -15551,12 +16242,12 @@ snapshots: dependencies: commander: 12.1.0 - '@commitlint/cli@19.3.0(@types/node@20.14.11)(typescript@5.6.0-dev.20240805)': + '@commitlint/cli@19.4.0(@types/node@20.16.2)(typescript@5.7.0-dev.20240829)': dependencies: '@commitlint/format': 19.3.0 '@commitlint/lint': 19.2.2 - '@commitlint/load': 19.2.0(@types/node@20.14.11)(typescript@5.6.0-dev.20240805) - '@commitlint/read': 19.2.1 + '@commitlint/load': 19.4.0(@types/node@20.16.2)(typescript@5.7.0-dev.20240829) + '@commitlint/read': 19.4.0 '@commitlint/types': 19.0.3 execa: 8.0.1 yargs: 17.7.2 @@ -15602,15 +16293,15 @@ snapshots: '@commitlint/rules': 19.0.3 '@commitlint/types': 19.0.3 - '@commitlint/load@19.2.0(@types/node@20.14.11)(typescript@5.6.0-dev.20240805)': + '@commitlint/load@19.4.0(@types/node@20.16.2)(typescript@5.7.0-dev.20240829)': dependencies: '@commitlint/config-validator': 19.0.3 '@commitlint/execute-rule': 19.0.0 '@commitlint/resolve-extends': 19.1.0 '@commitlint/types': 19.0.3 chalk: 5.3.0 - cosmiconfig: 9.0.0(typescript@5.6.0-dev.20240805) - cosmiconfig-typescript-loader: 5.0.0(@types/node@20.14.11)(cosmiconfig@9.0.0(typescript@5.6.0-dev.20240805))(typescript@5.6.0-dev.20240805) + cosmiconfig: 9.0.0(typescript@5.7.0-dev.20240829) + cosmiconfig-typescript-loader: 5.0.0(@types/node@20.16.2)(cosmiconfig@9.0.0(typescript@5.7.0-dev.20240829))(typescript@5.7.0-dev.20240829) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -15626,7 +16317,7 @@ snapshots: conventional-changelog-angular: 7.0.0 conventional-commits-parser: 5.0.0 - '@commitlint/read@19.2.1': + '@commitlint/read@19.4.0': dependencies: '@commitlint/top-level': 19.0.0 '@commitlint/types': 19.0.3 @@ -15672,10 +16363,10 @@ snapshots: enabled: 2.0.0 kuler: 2.0.0 - '@effect/schema@0.66.5(effect@3.0.3)(fast-check@3.17.2)': + '@effect/schema@0.69.0(effect@3.5.7)': dependencies: - effect: 3.0.3 - fast-check: 3.17.2 + effect: 3.5.7 + fast-check: 3.20.0 '@elastic/elasticsearch@8.14.0': dependencies: @@ -15850,8 +16541,6 @@ snapshots: eslint: 9.7.0 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.10.0': {} - '@eslint-community/regexpp@4.11.0': {} '@eslint/config-array@0.17.0': @@ -16003,7 +16692,7 @@ snapshots: graphql: 16.9.0 tslib: 2.6.3 - '@graphql-codegen/cli@5.0.2(@parcel/watcher@2.4.1)(@types/node@20.14.11)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.8.1)(typescript@5.5.3)': + '@graphql-codegen/cli@5.0.2(@parcel/watcher@2.4.1)(@types/node@20.16.2)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.8.1)(typescript@5.5.4)': dependencies: '@babel/generator': 7.24.5 '@babel/template': 7.24.0 @@ -16014,20 +16703,20 @@ snapshots: '@graphql-tools/apollo-engine-loader': 8.0.1(encoding@0.1.13)(graphql@16.8.1) '@graphql-tools/code-file-loader': 8.1.1(graphql@16.8.1) '@graphql-tools/git-loader': 8.0.5(graphql@16.8.1) - '@graphql-tools/github-loader': 8.0.1(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.8.1) + '@graphql-tools/github-loader': 8.0.1(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.8.1) '@graphql-tools/graphql-file-loader': 8.0.1(graphql@16.8.1) '@graphql-tools/json-file-loader': 8.0.1(graphql@16.8.1) '@graphql-tools/load': 8.0.2(graphql@16.8.1) - '@graphql-tools/prisma-loader': 8.0.4(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.8.1) - '@graphql-tools/url-loader': 8.0.2(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.8.1) + '@graphql-tools/prisma-loader': 8.0.4(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.8.1) + '@graphql-tools/url-loader': 8.0.2(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.8.1) '@graphql-tools/utils': 10.2.0(graphql@16.8.1) '@whatwg-node/fetch': 0.8.8 chalk: 4.1.2 - cosmiconfig: 8.3.6(typescript@5.5.3) + cosmiconfig: 8.3.6(typescript@5.5.4) debounce: 1.2.1 detect-indent: 6.1.0 graphql: 16.8.1 - graphql-config: 5.0.3(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.8.1)(typescript@5.5.3) + graphql-config: 5.0.3(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.8.1)(typescript@5.5.4) inquirer: 8.2.6 is-glob: 4.0.3 jiti: 1.21.0 @@ -16053,7 +16742,7 @@ snapshots: - typescript - utf-8-validate - '@graphql-codegen/cli@5.0.2(@parcel/watcher@2.4.1)(@types/node@20.14.11)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.9.0)(typescript@5.5.3)': + '@graphql-codegen/cli@5.0.2(@parcel/watcher@2.4.1)(@types/node@20.16.2)(encoding@0.1.13)(enquirer@2.4.1)(graphql@16.9.0)(typescript@5.5.4)': dependencies: '@babel/generator': 7.24.5 '@babel/template': 7.24.0 @@ -16064,20 +16753,20 @@ snapshots: '@graphql-tools/apollo-engine-loader': 8.0.1(encoding@0.1.13)(graphql@16.9.0) '@graphql-tools/code-file-loader': 8.1.1(graphql@16.9.0) '@graphql-tools/git-loader': 8.0.5(graphql@16.9.0) - '@graphql-tools/github-loader': 8.0.1(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.9.0) + '@graphql-tools/github-loader': 8.0.1(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.9.0) '@graphql-tools/graphql-file-loader': 8.0.1(graphql@16.9.0) '@graphql-tools/json-file-loader': 8.0.1(graphql@16.9.0) '@graphql-tools/load': 8.0.2(graphql@16.9.0) - '@graphql-tools/prisma-loader': 8.0.4(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.9.0) - '@graphql-tools/url-loader': 8.0.2(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.9.0) + '@graphql-tools/prisma-loader': 8.0.4(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.9.0) + '@graphql-tools/url-loader': 8.0.2(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.9.0) '@graphql-tools/utils': 10.2.0(graphql@16.9.0) '@whatwg-node/fetch': 0.8.8 chalk: 4.1.2 - cosmiconfig: 8.3.6(typescript@5.5.3) + cosmiconfig: 8.3.6(typescript@5.5.4) debounce: 1.2.1 detect-indent: 6.1.0 graphql: 16.9.0 - graphql-config: 5.0.3(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.9.0)(typescript@5.5.3) + graphql-config: 5.0.3(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.9.0)(typescript@5.5.4) inquirer: 8.2.6 is-glob: 4.0.3 jiti: 1.21.0 @@ -16506,27 +17195,27 @@ snapshots: - bufferutil - utf-8-validate - '@graphql-tools/executor-http@1.0.9(@types/node@20.14.11)(graphql@16.8.1)': + '@graphql-tools/executor-http@1.0.9(@types/node@20.16.2)(graphql@16.8.1)': dependencies: '@graphql-tools/utils': 10.2.0(graphql@16.8.1) '@repeaterjs/repeater': 3.0.5 '@whatwg-node/fetch': 0.9.17 extract-files: 11.0.0 graphql: 16.8.1 - meros: 1.3.0(@types/node@20.14.11) + meros: 1.3.0(@types/node@20.16.2) tslib: 2.6.3 value-or-promise: 1.0.12 transitivePeerDependencies: - '@types/node' - '@graphql-tools/executor-http@1.0.9(@types/node@20.14.11)(graphql@16.9.0)': + '@graphql-tools/executor-http@1.0.9(@types/node@20.16.2)(graphql@16.9.0)': dependencies: '@graphql-tools/utils': 10.2.0(graphql@16.9.0) '@repeaterjs/repeater': 3.0.5 '@whatwg-node/fetch': 0.9.17 extract-files: 11.0.0 graphql: 16.9.0 - meros: 1.3.0(@types/node@20.14.11) + meros: 1.3.0(@types/node@20.16.2) tslib: 2.6.3 value-or-promise: 1.0.12 transitivePeerDependencies: @@ -16598,10 +17287,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@graphql-tools/github-loader@8.0.1(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.8.1)': + '@graphql-tools/github-loader@8.0.1(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.8.1)': dependencies: '@ardatan/sync-fetch': 0.0.1(encoding@0.1.13) - '@graphql-tools/executor-http': 1.0.9(@types/node@20.14.11)(graphql@16.8.1) + '@graphql-tools/executor-http': 1.0.9(@types/node@20.16.2)(graphql@16.8.1) '@graphql-tools/graphql-tag-pluck': 8.3.0(graphql@16.8.1) '@graphql-tools/utils': 10.2.0(graphql@16.8.1) '@whatwg-node/fetch': 0.9.17 @@ -16613,10 +17302,10 @@ snapshots: - encoding - supports-color - '@graphql-tools/github-loader@8.0.1(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.9.0)': + '@graphql-tools/github-loader@8.0.1(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.9.0)': dependencies: '@ardatan/sync-fetch': 0.0.1(encoding@0.1.13) - '@graphql-tools/executor-http': 1.0.9(@types/node@20.14.11)(graphql@16.9.0) + '@graphql-tools/executor-http': 1.0.9(@types/node@20.16.2)(graphql@16.9.0) '@graphql-tools/graphql-tag-pluck': 8.3.0(graphql@16.9.0) '@graphql-tools/utils': 10.2.0(graphql@16.9.0) '@whatwg-node/fetch': 0.9.17 @@ -16746,9 +17435,9 @@ snapshots: graphql: 16.9.0 tslib: 2.6.3 - '@graphql-tools/prisma-loader@8.0.4(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.8.1)': + '@graphql-tools/prisma-loader@8.0.4(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.8.1)': dependencies: - '@graphql-tools/url-loader': 8.0.2(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.8.1) + '@graphql-tools/url-loader': 8.0.2(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.8.1) '@graphql-tools/utils': 10.2.0(graphql@16.8.1) '@types/js-yaml': 4.0.9 '@whatwg-node/fetch': 0.9.17 @@ -16772,9 +17461,9 @@ snapshots: - supports-color - utf-8-validate - '@graphql-tools/prisma-loader@8.0.4(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.9.0)': + '@graphql-tools/prisma-loader@8.0.4(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.9.0)': dependencies: - '@graphql-tools/url-loader': 8.0.2(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.9.0) + '@graphql-tools/url-loader': 8.0.2(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.9.0) '@graphql-tools/utils': 10.2.0(graphql@16.9.0) '@types/js-yaml': 4.0.9 '@whatwg-node/fetch': 0.9.17 @@ -16842,12 +17531,12 @@ snapshots: tslib: 2.6.3 value-or-promise: 1.0.12 - '@graphql-tools/url-loader@8.0.2(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.8.1)': + '@graphql-tools/url-loader@8.0.2(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.8.1)': dependencies: '@ardatan/sync-fetch': 0.0.1(encoding@0.1.13) '@graphql-tools/delegate': 10.0.9(graphql@16.8.1) '@graphql-tools/executor-graphql-ws': 1.1.2(graphql@16.8.1) - '@graphql-tools/executor-http': 1.0.9(@types/node@20.14.11)(graphql@16.8.1) + '@graphql-tools/executor-http': 1.0.9(@types/node@20.16.2)(graphql@16.8.1) '@graphql-tools/executor-legacy-ws': 1.0.6(graphql@16.8.1) '@graphql-tools/utils': 10.2.0(graphql@16.8.1) '@graphql-tools/wrap': 10.0.5(graphql@16.8.1) @@ -16864,12 +17553,12 @@ snapshots: - encoding - utf-8-validate - '@graphql-tools/url-loader@8.0.2(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.9.0)': + '@graphql-tools/url-loader@8.0.2(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.9.0)': dependencies: '@ardatan/sync-fetch': 0.0.1(encoding@0.1.13) '@graphql-tools/delegate': 10.0.9(graphql@16.9.0) '@graphql-tools/executor-graphql-ws': 1.1.2(graphql@16.9.0) - '@graphql-tools/executor-http': 1.0.9(@types/node@20.14.11)(graphql@16.9.0) + '@graphql-tools/executor-http': 1.0.9(@types/node@20.16.2)(graphql@16.9.0) '@graphql-tools/executor-legacy-ws': 1.0.6(graphql@16.9.0) '@graphql-tools/utils': 10.2.0(graphql@16.9.0) '@graphql-tools/wrap': 10.0.5(graphql@16.9.0) @@ -16990,7 +17679,7 @@ snapshots: dependencies: '@inquirer/type': 1.3.1 '@types/mute-stream': 0.0.1 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/wrap-ansi': 3.0.0 ansi-escapes: 4.3.2 chalk: 4.1.2 @@ -17007,7 +17696,7 @@ snapshots: dependencies: '@inquirer/type': 1.3.1 '@types/mute-stream': 0.0.4 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/wrap-ansi': 3.0.0 ansi-escapes: 4.3.2 chalk: 4.1.2 @@ -17110,30 +17799,65 @@ snapshots: '@istanbuljs/schema@0.1.3': {} - '@jest/console@29.7.0': + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 20.16.2 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))': dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.16.2 + ansi-escapes: 4.3.2 chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + jest-haste-map: 29.7.0 jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.7 + pretty-format: 29.7.0 slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))': + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.16.2 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + jest-config: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -17158,7 +17882,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.16.2 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -17176,7 +17900,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.14.11 + '@types/node': 20.16.2 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -17198,7 +17922,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.14.11 + '@types/node': 20.16.2 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -17268,7 +17992,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/yargs': 17.0.32 chalk: 4.1.2 @@ -17326,6 +18050,15 @@ snapshots: chevrotain: 10.5.0 lilconfig: 2.1.0 + '@mswjs/interceptors@0.34.3': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -17415,6 +18148,15 @@ snapshots: dependencies: '@octokit/openapi-types': 22.2.0 + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + '@opensearch-project/opensearch@2.10.0': dependencies: aws4: 1.13.0 @@ -17495,6 +18237,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-aws-lambda@0.43.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-aws-xray': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + '@types/aws-lambda': 8.10.122 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-aws-sdk@0.42.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -17505,7 +18258,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-aws-sdk@0.43.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-aws-sdk@0.43.1(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) @@ -17541,6 +18294,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-express@0.41.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-fastify@0.38.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -17550,6 +18312,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@opentelemetry/instrumentation-fs@0.14.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + '@opentelemetry/instrumentation-graphql@0.42.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 @@ -17585,7 +18355,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-knex@0.38.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-knex@0.39.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) @@ -17907,11 +18677,11 @@ snapshots: '@pocket-tools/apollo-cursor-pagination@1.0.3': {} - '@prisma/client@5.14.0(prisma@5.14.0)': + '@prisma/client@5.18.0(prisma@5.18.0)': optionalDependencies: - prisma: 5.14.0 + prisma: 5.18.0 - '@prisma/debug@5.14.0': {} + '@prisma/debug@5.18.0': {} '@prisma/debug@5.3.1': dependencies: @@ -17921,22 +18691,22 @@ snapshots: transitivePeerDependencies: - supports-color - '@prisma/engines-version@5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48': {} + '@prisma/engines-version@5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169': {} - '@prisma/engines@5.14.0': + '@prisma/engines@5.18.0': dependencies: - '@prisma/debug': 5.14.0 - '@prisma/engines-version': 5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48 - '@prisma/fetch-engine': 5.14.0 - '@prisma/get-platform': 5.14.0 + '@prisma/debug': 5.18.0 + '@prisma/engines-version': 5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169 + '@prisma/fetch-engine': 5.18.0 + '@prisma/get-platform': 5.18.0 '@prisma/engines@5.3.1': {} - '@prisma/fetch-engine@5.14.0': + '@prisma/fetch-engine@5.18.0': dependencies: - '@prisma/debug': 5.14.0 - '@prisma/engines-version': 5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48 - '@prisma/get-platform': 5.14.0 + '@prisma/debug': 5.18.0 + '@prisma/engines-version': 5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169 + '@prisma/get-platform': 5.18.0 '@prisma/fetch-engine@5.3.1(encoding@0.1.13)': dependencies: @@ -17970,9 +18740,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@prisma/get-platform@5.14.0': + '@prisma/get-platform@5.18.0': dependencies: - '@prisma/debug': 5.14.0 + '@prisma/debug': 5.18.0 '@prisma/get-platform@5.3.1': dependencies: @@ -17997,7 +18767,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@prisma/instrumentation@5.17.0': + '@prisma/instrumentation@5.18.0': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) @@ -18104,73 +18874,73 @@ snapshots: '@repeaterjs/repeater@3.0.5': {} - '@rollup/rollup-android-arm-eabi@4.18.1': + '@rollup/rollup-android-arm-eabi@4.21.1': optional: true - '@rollup/rollup-android-arm64@4.18.1': + '@rollup/rollup-android-arm64@4.21.1': optional: true - '@rollup/rollup-darwin-arm64@4.18.1': + '@rollup/rollup-darwin-arm64@4.21.1': optional: true - '@rollup/rollup-darwin-x64@4.18.1': + '@rollup/rollup-darwin-x64@4.21.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.18.1': + '@rollup/rollup-linux-arm-gnueabihf@4.21.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.18.1': + '@rollup/rollup-linux-arm-musleabihf@4.21.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.18.1': + '@rollup/rollup-linux-arm64-gnu@4.21.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.18.1': + '@rollup/rollup-linux-arm64-musl@4.21.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.18.1': + '@rollup/rollup-linux-powerpc64le-gnu@4.21.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.18.1': + '@rollup/rollup-linux-riscv64-gnu@4.21.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.18.1': + '@rollup/rollup-linux-s390x-gnu@4.21.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.18.1': + '@rollup/rollup-linux-x64-gnu@4.21.1': optional: true - '@rollup/rollup-linux-x64-musl@4.18.1': + '@rollup/rollup-linux-x64-musl@4.21.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.18.1': + '@rollup/rollup-win32-arm64-msvc@4.21.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.18.1': + '@rollup/rollup-win32-ia32-msvc@4.21.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.18.1': + '@rollup/rollup-win32-x64-msvc@4.21.1': optional: true '@sec-ant/readable-stream@0.4.1': {} - '@semantic-release/commit-analyzer@13.0.0(semantic-release@24.0.0(typescript@5.5.3))': + '@semantic-release/commit-analyzer@13.0.0(semantic-release@24.1.0(typescript@5.5.4))': dependencies: conventional-changelog-angular: 8.0.0 conventional-changelog-writer: 8.0.0 conventional-commits-filter: 5.0.0 conventional-commits-parser: 6.0.0 - debug: 4.3.4 + debug: 4.3.5(supports-color@5.5.0) import-from-esm: 1.3.4 lodash-es: 4.17.21 - micromatch: 4.0.5 - semantic-release: 24.0.0(typescript@5.5.3) + micromatch: 4.0.7 + semantic-release: 24.1.0(typescript@5.5.4) transitivePeerDependencies: - supports-color '@semantic-release/error@4.0.0': {} - '@semantic-release/github@10.0.3(semantic-release@24.0.0(typescript@5.5.3))': + '@semantic-release/github@10.0.3(semantic-release@24.1.0(typescript@5.5.4))': dependencies: '@octokit/core': 6.1.2 '@octokit/plugin-paginate-rest': 11.3.0(@octokit/core@6.1.2) @@ -18178,21 +18948,21 @@ snapshots: '@octokit/plugin-throttling': 9.3.0(@octokit/core@6.1.2) '@semantic-release/error': 4.0.0 aggregate-error: 5.0.0 - debug: 4.3.4 + debug: 4.3.5(supports-color@5.5.0) dir-glob: 3.0.1 globby: 14.0.1 http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.4 + https-proxy-agent: 7.0.5 issue-parser: 7.0.0 lodash-es: 4.17.21 mime: 4.0.3 p-filter: 4.1.0 - semantic-release: 24.0.0(typescript@5.5.3) + semantic-release: 24.1.0(typescript@5.5.4) url-join: 5.0.0 transitivePeerDependencies: - supports-color - '@semantic-release/npm@12.0.0(semantic-release@24.0.0(typescript@5.5.3))': + '@semantic-release/npm@12.0.0(semantic-release@24.1.0(typescript@5.5.4))': dependencies: '@semantic-release/error': 4.0.0 aggregate-error: 5.0.0 @@ -18205,23 +18975,23 @@ snapshots: rc: 1.2.8 read-pkg: 9.0.1 registry-auth-token: 5.0.2 - semantic-release: 24.0.0(typescript@5.5.3) + semantic-release: 24.1.0(typescript@5.5.4) semver: 7.6.2 tempy: 3.1.0 - '@semantic-release/release-notes-generator@14.0.0(semantic-release@24.0.0(typescript@5.5.3))': + '@semantic-release/release-notes-generator@14.0.0(semantic-release@24.1.0(typescript@5.5.4))': dependencies: conventional-changelog-angular: 8.0.0 conventional-changelog-writer: 8.0.0 conventional-commits-filter: 5.0.0 conventional-commits-parser: 6.0.0 - debug: 4.3.4 + debug: 4.3.5(supports-color@5.5.0) get-stream: 7.0.1 import-from-esm: 1.3.4 into-stream: 7.0.0 lodash-es: 4.17.21 read-pkg-up: 11.0.0 - semantic-release: 24.0.0(typescript@5.5.3) + semantic-release: 24.1.0(typescript@5.5.4) transitivePeerDependencies: - supports-color @@ -18250,7 +19020,20 @@ snapshots: '@sentry/node': 8.18.0 '@sentry/types': 8.18.0 '@sentry/utils': 8.18.0 - '@types/aws-lambda': 8.10.141 + '@types/aws-lambda': 8.10.143 + transitivePeerDependencies: + - '@opentelemetry/api' + - supports-color + + '@sentry/aws-serverless@8.27.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/instrumentation-aws-lambda': 0.43.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-aws-sdk': 0.43.1(@opentelemetry/api@1.9.0) + '@sentry/core': 8.27.0 + '@sentry/node': 8.27.0 + '@sentry/types': 8.27.0 + '@sentry/utils': 8.27.0 + '@types/aws-lambda': 8.10.143 transitivePeerDependencies: - '@opentelemetry/api' - supports-color @@ -18265,6 +19048,11 @@ snapshots: '@sentry/types': 8.18.0 '@sentry/utils': 8.18.0 + '@sentry/core@8.27.0': + dependencies: + '@sentry/types': 8.27.0 + '@sentry/utils': 8.27.0 + '@sentry/integrations@7.116.0': dependencies: '@sentry/core': 7.116.0 @@ -18314,6 +19102,42 @@ snapshots: transitivePeerDependencies: - supports-color + '@sentry/node@8.27.0': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/context-async-hooks': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-connect': 0.38.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-express': 0.41.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-fastify': 0.38.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-fs': 0.14.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-graphql': 0.42.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-hapi': 0.40.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-http': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-ioredis': 0.42.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-koa': 0.42.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongodb': 0.46.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mongoose': 0.40.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql': 0.40.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-mysql2': 0.40.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-nestjs-core': 0.39.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-pg': 0.43.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-redis-4': 0.41.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + '@prisma/instrumentation': 5.18.0 + '@sentry/core': 8.27.0 + '@sentry/opentelemetry': 8.27.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1) + '@sentry/types': 8.27.0 + '@sentry/utils': 8.27.0 + import-in-the-middle: 1.11.0 + optionalDependencies: + opentelemetry-instrumentation-fetch-node: 1.2.3(@opentelemetry/api@1.9.0) + transitivePeerDependencies: + - supports-color + '@sentry/opentelemetry@8.18.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1)': dependencies: '@opentelemetry/api': 1.9.0 @@ -18325,10 +19149,23 @@ snapshots: '@sentry/types': 8.18.0 '@sentry/utils': 8.18.0 + '@sentry/opentelemetry@8.27.0(@opentelemetry/api@1.9.0)(@opentelemetry/core@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.52.1(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.25.1(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.25.1)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.52.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 1.25.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.25.1 + '@sentry/core': 8.27.0 + '@sentry/types': 8.27.0 + '@sentry/utils': 8.27.0 + '@sentry/types@7.116.0': {} '@sentry/types@8.18.0': {} + '@sentry/types@8.27.0': {} + '@sentry/utils@7.116.0': dependencies: '@sentry/types': 7.116.0 @@ -18337,6 +19174,10 @@ snapshots: dependencies: '@sentry/types': 8.18.0 + '@sentry/utils@8.27.0': + dependencies: + '@sentry/types': 8.27.0 + '@sideway/address@4.1.5': dependencies: '@hapi/hoek': 9.3.0 @@ -18363,7 +19204,7 @@ snapshots: '@slack/logger@3.0.0': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@slack/types@2.11.0': {} @@ -18372,8 +19213,8 @@ snapshots: '@slack/logger': 3.0.0 '@slack/types': 2.11.0 '@types/is-stream': 1.1.0 - '@types/node': 20.14.11 - axios: 1.7.2 + '@types/node': 20.16.2 + axios: 1.7.4 eventemitter3: 3.1.2 form-data: 2.5.1 is-electron: 2.2.2 @@ -18396,6 +19237,14 @@ snapshots: '@smithy/util-middleware': 3.0.3 tslib: 2.6.3 + '@smithy/config-resolver@3.0.5': + dependencies: + '@smithy/node-config-provider': 3.1.4 + '@smithy/types': 3.3.0 + '@smithy/util-config-provider': 3.0.0 + '@smithy/util-middleware': 3.0.3 + tslib: 2.6.3 + '@smithy/core@2.2.4': dependencies: '@smithy/middleware-endpoint': 3.0.4 @@ -18407,6 +19256,19 @@ snapshots: '@smithy/util-middleware': 3.0.3 tslib: 2.6.3 + '@smithy/core@2.4.0': + dependencies: + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.15 + '@smithy/middleware-serde': 3.0.3 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.2.0 + '@smithy/types': 3.3.0 + '@smithy/util-body-length-browser': 3.0.0 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + '@smithy/credential-provider-imds@3.1.3': dependencies: '@smithy/node-config-provider': 3.1.3 @@ -18415,6 +19277,14 @@ snapshots: '@smithy/url-parser': 3.0.3 tslib: 2.6.3 + '@smithy/credential-provider-imds@3.2.0': + dependencies: + '@smithy/node-config-provider': 3.1.4 + '@smithy/property-provider': 3.1.3 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + tslib: 2.6.3 + '@smithy/eventstream-codec@3.1.2': dependencies: '@aws-crypto/crc32': 5.2.0 @@ -18422,9 +19292,9 @@ snapshots: '@smithy/util-hex-encoding': 3.0.0 tslib: 2.6.3 - '@smithy/eventstream-serde-browser@3.0.4': + '@smithy/eventstream-serde-browser@3.0.6': dependencies: - '@smithy/eventstream-serde-universal': 3.0.4 + '@smithy/eventstream-serde-universal': 3.0.5 '@smithy/types': 3.3.0 tslib: 2.6.3 @@ -18433,13 +19303,13 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@smithy/eventstream-serde-node@3.0.4': + '@smithy/eventstream-serde-node@3.0.5': dependencies: - '@smithy/eventstream-serde-universal': 3.0.4 + '@smithy/eventstream-serde-universal': 3.0.5 '@smithy/types': 3.3.0 tslib: 2.6.3 - '@smithy/eventstream-serde-universal@3.0.4': + '@smithy/eventstream-serde-universal@3.0.5': dependencies: '@smithy/eventstream-codec': 3.1.2 '@smithy/types': 3.3.0 @@ -18453,6 +19323,14 @@ snapshots: '@smithy/util-base64': 3.0.0 tslib: 2.6.3 + '@smithy/fetch-http-handler@3.2.4': + dependencies: + '@smithy/protocol-http': 4.1.0 + '@smithy/querystring-builder': 3.0.3 + '@smithy/types': 3.3.0 + '@smithy/util-base64': 3.0.0 + tslib: 2.6.3 + '@smithy/hash-node@3.0.3': dependencies: '@smithy/types': 3.3.0 @@ -18479,11 +19357,11 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@smithy/middleware-compression@3.0.4': + '@smithy/middleware-compression@3.0.7': dependencies: '@smithy/is-array-buffer': 3.0.0 - '@smithy/node-config-provider': 3.1.3 - '@smithy/protocol-http': 4.0.3 + '@smithy/node-config-provider': 3.1.4 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 '@smithy/util-config-provider': 3.0.0 '@smithy/util-middleware': 3.0.3 @@ -18497,6 +19375,12 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 + '@smithy/middleware-content-length@3.0.5': + dependencies: + '@smithy/protocol-http': 4.1.0 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@smithy/middleware-endpoint@3.0.4': dependencies: '@smithy/middleware-serde': 3.0.3 @@ -18507,6 +19391,28 @@ snapshots: '@smithy/util-middleware': 3.0.3 tslib: 2.6.3 + '@smithy/middleware-endpoint@3.1.0': + dependencies: + '@smithy/middleware-serde': 3.0.3 + '@smithy/node-config-provider': 3.1.4 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + '@smithy/url-parser': 3.0.3 + '@smithy/util-middleware': 3.0.3 + tslib: 2.6.3 + + '@smithy/middleware-retry@3.0.15': + dependencies: + '@smithy/node-config-provider': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/service-error-classification': 3.0.3 + '@smithy/smithy-client': 3.2.0 + '@smithy/types': 3.3.0 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-retry': 3.0.3 + tslib: 2.6.3 + uuid: 9.0.1 + '@smithy/middleware-retry@3.0.7': dependencies: '@smithy/node-config-provider': 3.1.3 @@ -18536,6 +19442,13 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 + '@smithy/node-config-provider@3.1.4': + dependencies: + '@smithy/property-provider': 3.1.3 + '@smithy/shared-ini-file-loader': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@smithy/node-http-handler@3.1.1': dependencies: '@smithy/abort-controller': 3.1.1 @@ -18544,6 +19457,14 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 + '@smithy/node-http-handler@3.1.4': + dependencies: + '@smithy/abort-controller': 3.1.1 + '@smithy/protocol-http': 4.1.0 + '@smithy/querystring-builder': 3.0.3 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@smithy/property-provider@3.1.3': dependencies: '@smithy/types': 3.3.0 @@ -18554,6 +19475,11 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 + '@smithy/protocol-http@4.1.0': + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@smithy/querystring-builder@3.0.3': dependencies: '@smithy/types': 3.3.0 @@ -18574,6 +19500,11 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 + '@smithy/shared-ini-file-loader@3.1.4': + dependencies: + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@smithy/signature-v4@3.1.2': dependencies: '@smithy/is-array-buffer': 3.0.0 @@ -18584,6 +19515,17 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 + '@smithy/signature-v4@4.1.0': + dependencies: + '@smithy/is-array-buffer': 3.0.0 + '@smithy/protocol-http': 4.1.0 + '@smithy/types': 3.3.0 + '@smithy/util-hex-encoding': 3.0.0 + '@smithy/util-middleware': 3.0.3 + '@smithy/util-uri-escape': 3.0.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + '@smithy/smithy-client@3.1.5': dependencies: '@smithy/middleware-endpoint': 3.0.4 @@ -18593,6 +19535,15 @@ snapshots: '@smithy/util-stream': 3.0.5 tslib: 2.6.3 + '@smithy/smithy-client@3.2.0': + dependencies: + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-stack': 3.0.3 + '@smithy/protocol-http': 4.1.0 + '@smithy/types': 3.3.0 + '@smithy/util-stream': 3.1.3 + tslib: 2.6.3 + '@smithy/types@3.3.0': dependencies: tslib: 2.6.3 @@ -18631,6 +19582,14 @@ snapshots: dependencies: tslib: 2.6.3 + '@smithy/util-defaults-mode-browser@3.0.15': + dependencies: + '@smithy/property-provider': 3.1.3 + '@smithy/smithy-client': 3.2.0 + '@smithy/types': 3.3.0 + bowser: 2.11.0 + tslib: 2.6.3 + '@smithy/util-defaults-mode-browser@3.0.7': dependencies: '@smithy/property-provider': 3.1.3 @@ -18639,6 +19598,16 @@ snapshots: bowser: 2.11.0 tslib: 2.6.3 + '@smithy/util-defaults-mode-node@3.0.15': + dependencies: + '@smithy/config-resolver': 3.0.5 + '@smithy/credential-provider-imds': 3.2.0 + '@smithy/node-config-provider': 3.1.4 + '@smithy/property-provider': 3.1.3 + '@smithy/smithy-client': 3.2.0 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@smithy/util-defaults-mode-node@3.0.7': dependencies: '@smithy/config-resolver': 3.0.4 @@ -18655,6 +19624,12 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 + '@smithy/util-endpoints@2.0.5': + dependencies: + '@smithy/node-config-provider': 3.1.4 + '@smithy/types': 3.3.0 + tslib: 2.6.3 + '@smithy/util-hex-encoding@3.0.0': dependencies: tslib: 2.6.3 @@ -18681,6 +19656,17 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 + '@smithy/util-stream@3.1.3': + dependencies: + '@smithy/fetch-http-handler': 3.2.4 + '@smithy/node-http-handler': 3.1.4 + '@smithy/types': 3.3.0 + '@smithy/util-base64': 3.0.0 + '@smithy/util-buffer-from': 3.0.0 + '@smithy/util-hex-encoding': 3.0.0 + '@smithy/util-utf8': 3.0.0 + tslib: 2.6.3 + '@smithy/util-uri-escape@3.0.0': dependencies: tslib: 2.6.3 @@ -18707,7 +19693,7 @@ snapshots: got: 11.8.6 tslib: 2.6.3 - '@snowplow/snowtype-core@0.7.1(encoding@0.1.13)': + '@snowplow/snowtype-core@0.8.2(encoding@0.1.13)': dependencies: handlebars: 4.7.8 json-pointer: 0.6.2 @@ -18715,11 +19701,11 @@ snapshots: transitivePeerDependencies: - encoding - '@snowplow/snowtype@0.7.1(commander@12.1.0)(encoding@0.1.13)': + '@snowplow/snowtype@0.8.2(commander@12.1.0)(encoding@0.1.13)': dependencies: '@commander-js/extra-typings': 11.1.0(commander@12.1.0) '@inquirer/prompts': 3.3.2 - '@snowplow/snowtype-core': 0.7.1(encoding@0.1.13) + '@snowplow/snowtype-core': 0.8.2(encoding@0.1.13) chalk: 4.1.2 cli-spinner: 0.2.10 dotenv: 16.4.5 @@ -18727,8 +19713,10 @@ snapshots: got: 11.8.6 joi: 17.13.1 js-sha256: 0.10.1 + lodash: 4.17.21 mime-types: 2.1.35 mkdirp: 3.0.1 + semver: 7.6.3 tsx: 4.13.2 transitivePeerDependencies: - commander @@ -18755,12 +19743,14 @@ snapshots: '@types/accepts@1.3.7': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/aws-lambda@8.10.122': {} '@types/aws-lambda@8.10.141': {} + '@types/aws-lambda@8.10.143': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.24.8 @@ -18785,13 +19775,13 @@ snapshots: '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/responselike': 1.0.3 '@types/caseless@0.12.5': @@ -18801,17 +19791,17 @@ snapshots: '@types/connect@3.4.36': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/connect@3.4.38': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/content-disposition@0.5.8': {} '@types/conventional-commits-parser@5.0.0': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/cookiejar@2.1.5': {} @@ -18820,15 +19810,15 @@ snapshots: '@types/connect': 3.4.38 '@types/express': 4.17.21 '@types/keygrip': 1.0.6 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/cors@2.8.17': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/cross-spawn@6.0.2': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/debug@4.1.8': dependencies: @@ -18840,7 +19830,7 @@ snapshots: '@types/express-serve-static-core@4.19.0': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/qs': 6.9.15 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -18859,11 +19849,11 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/graphql-depth-limit@1.1.6': dependencies: @@ -18873,7 +19863,7 @@ snapshots: dependencies: '@types/express': 4.17.21 '@types/koa': 2.15.0 - '@types/node': 20.14.11 + '@types/node': 20.16.2 fs-capacitor: 8.0.0 graphql: 16.8.1 @@ -18883,7 +19873,7 @@ snapshots: '@types/highland@2.13.0': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/http-assert@1.5.5': {} @@ -18893,14 +19883,14 @@ snapshots: '@types/ioredis-mock@8.2.5': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 ioredis: 5.4.1 transitivePeerDependencies: - supports-color '@types/is-stream@1.1.0': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/istanbul-lib-coverage@2.0.6': {} @@ -18921,7 +19911,7 @@ snapshots: '@types/jsdom@20.0.1': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/tough-cookie': 4.0.5 parse5: 7.1.2 @@ -18929,7 +19919,7 @@ snapshots: '@types/jsonwebtoken@9.0.6': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/jwk-to-pem@2.0.3': {} @@ -18937,7 +19927,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/koa-compose@3.2.8': dependencies: @@ -18952,7 +19942,7 @@ snapshots: '@types/http-errors': 2.0.4 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.8 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/locutus@0.0.8': {} @@ -18972,34 +19962,34 @@ snapshots: '@types/morgan@1.9.9': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/ms@0.7.34': {} '@types/mute-stream@0.0.1': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/mute-stream@0.0.4': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/mysql@2.15.22': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/mysql@2.15.26': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/node-fetch@2.6.11': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 form-data: 4.0.0 '@types/node-fetch@2.6.6': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 form-data: 4.0.0 '@types/node-gcm@1.0.5': {} @@ -19012,6 +20002,10 @@ snapshots: dependencies: undici-types: 5.26.5 + '@types/node@20.16.2': + dependencies: + undici-types: 6.19.8 + '@types/normalize-package-data@2.4.4': {} '@types/parse-path@7.0.3': {} @@ -19036,7 +20030,7 @@ snapshots: '@types/pg@8.6.1': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 pg-protocol: 1.6.1 pg-types: 2.2.0 @@ -19047,14 +20041,14 @@ snapshots: '@types/request@2.48.12': dependencies: '@types/caseless': 0.12.5 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/tough-cookie': 4.0.5 form-data: 2.5.1 optional: true '@types/responselike@1.0.3': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/retry@0.12.0': {} @@ -19063,12 +20057,12 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/send': 0.17.4 '@types/shimmer@1.0.5': {} @@ -19081,7 +20075,7 @@ snapshots: dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/supertest@6.0.2': dependencies: @@ -19092,7 +20086,7 @@ snapshots: '@types/triple-beam@1.3.5': {} - '@types/turndown@5.0.4': {} + '@types/turndown@5.0.5': {} '@types/urijs@1.19.25': {} @@ -19102,7 +20096,7 @@ snapshots: '@types/ws@8.5.10': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 '@types/yargs-parser@21.0.3': {} @@ -19112,90 +20106,90 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 optional: true '@types/yoga-layout@1.9.2': {} - '@typescript-eslint/eslint-plugin@7.16.1(@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3))(eslint@9.7.0)(typescript@5.5.3)': + '@typescript-eslint/eslint-plugin@8.3.0(@typescript-eslint/parser@8.3.0(eslint@9.7.0)(typescript@5.5.4))(eslint@9.7.0)(typescript@5.5.4)': dependencies: - '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/scope-manager': 7.16.1 - '@typescript-eslint/type-utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/visitor-keys': 7.16.1 + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 8.3.0(eslint@9.7.0)(typescript@5.5.4) + '@typescript-eslint/scope-manager': 8.3.0 + '@typescript-eslint/type-utils': 8.3.0(eslint@9.7.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.3.0(eslint@9.7.0)(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 8.3.0 eslint: 9.7.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.5.3) + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3)': + '@typescript-eslint/parser@8.3.0(eslint@9.7.0)(typescript@5.5.4)': dependencies: - '@typescript-eslint/scope-manager': 7.16.1 - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3) - '@typescript-eslint/visitor-keys': 7.16.1 + '@typescript-eslint/scope-manager': 8.3.0 + '@typescript-eslint/types': 8.3.0 + '@typescript-eslint/typescript-estree': 8.3.0(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 8.3.0 debug: 4.3.5(supports-color@5.5.0) eslint: 9.7.0 optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@7.16.1': + '@typescript-eslint/scope-manager@8.3.0': dependencies: - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/visitor-keys': 7.16.1 + '@typescript-eslint/types': 8.3.0 + '@typescript-eslint/visitor-keys': 8.3.0 - '@typescript-eslint/type-utils@7.16.1(eslint@9.7.0)(typescript@5.5.3)': + '@typescript-eslint/type-utils@8.3.0(eslint@9.7.0)(typescript@5.5.4)': dependencies: - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3) - '@typescript-eslint/utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) + '@typescript-eslint/typescript-estree': 8.3.0(typescript@5.5.4) + '@typescript-eslint/utils': 8.3.0(eslint@9.7.0)(typescript@5.5.4) debug: 4.3.5(supports-color@5.5.0) - eslint: 9.7.0 - ts-api-utils: 1.3.0(typescript@5.5.3) + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: + - eslint - supports-color - '@typescript-eslint/types@7.16.1': {} + '@typescript-eslint/types@8.3.0': {} - '@typescript-eslint/typescript-estree@7.16.1(typescript@5.5.3)': + '@typescript-eslint/typescript-estree@8.3.0(typescript@5.5.4)': dependencies: - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/visitor-keys': 7.16.1 + '@typescript-eslint/types': 8.3.0 + '@typescript-eslint/visitor-keys': 8.3.0 debug: 4.3.5(supports-color@5.5.0) - globby: 11.1.0 + fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.4 semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.5.3) + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.16.1(eslint@9.7.0)(typescript@5.5.3)': + '@typescript-eslint/utils@8.3.0(eslint@9.7.0)(typescript@5.5.4)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@9.7.0) - '@typescript-eslint/scope-manager': 7.16.1 - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3) + '@typescript-eslint/scope-manager': 8.3.0 + '@typescript-eslint/types': 8.3.0 + '@typescript-eslint/typescript-estree': 8.3.0(typescript@5.5.4) eslint: 9.7.0 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@7.16.1': + '@typescript-eslint/visitor-keys@8.3.0': dependencies: - '@typescript-eslint/types': 7.16.1 + '@typescript-eslint/types': 8.3.0 eslint-visitor-keys: 3.4.3 '@wesleytodd/openapi@0.3.0(core-js@3.37.1)(encoding@0.1.13)(mobx@6.13.0)(openapi-types@12.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(styled-components@6.1.11(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': @@ -19258,6 +20252,22 @@ snapshots: fast-querystring: 1.1.2 tslib: 2.6.3 + '@wry/context@0.7.4': + dependencies: + tslib: 2.6.3 + + '@wry/equality@0.5.7': + dependencies: + tslib: 2.6.3 + + '@wry/trie@0.3.2': + dependencies: + tslib: 2.6.3 + + '@wry/trie@0.4.3': + dependencies: + tslib: 2.6.3 + '@xmldom/xmldom@0.8.10': {} JSONStream@1.3.5: @@ -19292,6 +20302,10 @@ snapshots: dependencies: acorn: 8.11.3 + acorn-import-attributes@1.9.5(acorn@8.12.1): + dependencies: + acorn: 8.12.1 + acorn-jsx@5.3.2(acorn@8.11.3): dependencies: acorn: 8.11.3 @@ -19546,10 +20560,10 @@ snapshots: uuid: 8.0.0 xml2js: 0.6.2 - aws-sigv4-fetch@4.0.0(@aws-sdk/client-sts@3.609.0): + aws-sigv4-fetch@4.0.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0): dependencies: '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.609.0(@aws-sdk/client-sts@3.609.0))(@aws-sdk/client-sts@3.609.0) + '@aws-sdk/credential-provider-node': 3.609.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0) '@aws-sdk/types': 3.609.0 '@smithy/protocol-http': 4.0.3 '@smithy/signature-v4': 3.1.2 @@ -19562,9 +20576,9 @@ snapshots: aws4@1.13.0: {} - axios-retry@4.4.0(axios@1.7.2): + axios-retry@4.4.0(axios@1.7.4): dependencies: - axios: 1.7.2 + axios: 1.7.4 is-retry-allowed: 2.2.0 axios@1.6.8: @@ -19575,7 +20589,7 @@ snapshots: transitivePeerDependencies: - debug - axios@1.7.2: + axios@1.7.4: dependencies: follow-redirects: 1.15.6 form-data: 4.0.0 @@ -20034,7 +21048,7 @@ snapshots: chalk@5.3.0: {} - chance@1.1.11: {} + chance@1.1.12: {} change-case-all@1.0.15: dependencies: @@ -20289,8 +21303,6 @@ snapshots: commander@10.0.1: {} - commander@12.0.0: {} - commander@12.1.0: {} commander@3.0.2: {} @@ -20489,39 +21501,39 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig-typescript-loader@5.0.0(@types/node@20.14.11)(cosmiconfig@9.0.0(typescript@5.6.0-dev.20240805))(typescript@5.6.0-dev.20240805): + cosmiconfig-typescript-loader@5.0.0(@types/node@20.16.2)(cosmiconfig@9.0.0(typescript@5.7.0-dev.20240829))(typescript@5.7.0-dev.20240829): dependencies: - '@types/node': 20.14.11 - cosmiconfig: 9.0.0(typescript@5.6.0-dev.20240805) + '@types/node': 20.16.2 + cosmiconfig: 9.0.0(typescript@5.7.0-dev.20240829) jiti: 1.21.0 - typescript: 5.6.0-dev.20240805 + typescript: 5.7.0-dev.20240829 - cosmiconfig@8.3.6(typescript@5.5.3): + cosmiconfig@8.3.6(typescript@5.5.4): dependencies: import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 - cosmiconfig@9.0.0(typescript@5.5.3): + cosmiconfig@9.0.0(typescript@5.5.4): dependencies: env-paths: 2.2.1 import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 - cosmiconfig@9.0.0(typescript@5.6.0-dev.20240805): + cosmiconfig@9.0.0(typescript@5.7.0-dev.20240829): dependencies: env-paths: 2.2.1 import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.6.0-dev.20240805 + typescript: 5.7.0-dev.20240829 cpu-features@0.0.2: dependencies: @@ -20550,6 +21562,21 @@ snapshots: - supports-color - ts-node + create-jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + create-require@1.1.1: {} cross-fetch@3.1.8(encoding@0.1.13): @@ -20882,7 +21909,7 @@ snapshots: dependencies: semver: 7.6.2 shelljs: 0.8.5 - typescript: 5.6.0-dev.20240805 + typescript: 5.7.0-dev.20240829 dreamopt@0.8.0: dependencies: @@ -20910,7 +21937,7 @@ snapshots: ee-first@1.1.1: {} - effect@3.0.3: {} + effect@3.5.7: {} ejs@3.1.10: dependencies: @@ -21454,7 +22481,7 @@ snapshots: node-addon-api: 5.1.0 prebuild-install: 7.1.2 - fast-check@3.17.2: + fast-check@3.20.0: dependencies: pure-rand: 6.1.0 @@ -21504,6 +22531,10 @@ snapshots: strnum: 1.0.5 optional: true + fast-xml-parser@4.4.1: + dependencies: + strnum: 1.0.5 + fastq@1.17.1: dependencies: reusify: 1.0.4 @@ -21641,7 +22672,7 @@ snapshots: '@fastify/busboy': 2.1.1 '@firebase/database-compat': 1.0.4 '@firebase/database-types': 1.0.2 - '@types/node': 20.14.11 + '@types/node': 20.16.2 farmhash: 3.3.1 jsonwebtoken: 9.0.2 jwks-rsa: 3.1.0 @@ -21778,7 +22809,7 @@ snapshots: gaxios@6.5.0(encoding@0.1.13): dependencies: extend: 3.0.2 - https-proxy-agent: 7.0.4 + https-proxy-agent: 7.0.5 is-stream: 2.0.1 node-fetch: 2.7.0(encoding@0.1.13) uuid: 9.0.1 @@ -21951,6 +22982,15 @@ snapshots: slash: 5.1.0 unicorn-magic: 0.1.0 + globby@14.0.2: + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.2 + ignore: 5.3.1 + path-type: 5.0.0 + slash: 5.1.0 + unicorn-magic: 0.1.0 + google-auth-library@9.9.0(encoding@0.1.13): dependencies: base64-js: 1.5.1 @@ -22015,15 +23055,15 @@ snapshots: graphology-types: 0.24.7 obliterator: 2.0.4 - graphql-config@5.0.3(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.8.1)(typescript@5.5.3): + graphql-config@5.0.3(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.8.1)(typescript@5.5.4): dependencies: '@graphql-tools/graphql-file-loader': 8.0.1(graphql@16.8.1) '@graphql-tools/json-file-loader': 8.0.1(graphql@16.8.1) '@graphql-tools/load': 8.0.2(graphql@16.8.1) '@graphql-tools/merge': 9.0.4(graphql@16.8.1) - '@graphql-tools/url-loader': 8.0.2(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.8.1) + '@graphql-tools/url-loader': 8.0.2(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.8.1) '@graphql-tools/utils': 10.2.0(graphql@16.8.1) - cosmiconfig: 8.3.6(typescript@5.5.3) + cosmiconfig: 8.3.6(typescript@5.5.4) graphql: 16.8.1 jiti: 1.21.0 minimatch: 4.2.3 @@ -22036,15 +23076,15 @@ snapshots: - typescript - utf-8-validate - graphql-config@5.0.3(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.9.0)(typescript@5.5.3): + graphql-config@5.0.3(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.9.0)(typescript@5.5.4): dependencies: '@graphql-tools/graphql-file-loader': 8.0.1(graphql@16.9.0) '@graphql-tools/json-file-loader': 8.0.1(graphql@16.9.0) '@graphql-tools/load': 8.0.2(graphql@16.9.0) '@graphql-tools/merge': 9.0.4(graphql@16.9.0) - '@graphql-tools/url-loader': 8.0.2(@types/node@20.14.11)(encoding@0.1.13)(graphql@16.9.0) + '@graphql-tools/url-loader': 8.0.2(@types/node@20.16.2)(encoding@0.1.13)(graphql@16.9.0) '@graphql-tools/utils': 10.2.0(graphql@16.9.0) - cosmiconfig: 8.3.6(typescript@5.5.3) + cosmiconfig: 8.3.6(typescript@5.5.4) graphql: 16.9.0 jiti: 1.21.0 minimatch: 4.2.3 @@ -22195,6 +23235,10 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + hook-std@3.0.0: {} hosted-git-info@2.8.9: {} @@ -22299,7 +23343,7 @@ snapshots: dependencies: ms: 2.1.3 - husky@9.1.1: {} + husky@9.1.4: {} iconv-lite@0.4.24: dependencies: @@ -22332,13 +23376,20 @@ snapshots: import-from-esm@1.3.4: dependencies: - debug: 4.3.4 + debug: 4.3.5(supports-color@5.5.0) import-meta-resolve: 4.1.0 transitivePeerDependencies: - supports-color import-from@4.0.0: {} + import-in-the-middle@1.11.0: + dependencies: + acorn: 8.12.1 + acorn-import-attributes: 1.9.5(acorn@8.12.1) + cjs-module-lexer: 1.3.1 + module-details-from-path: 1.0.3 + import-in-the-middle@1.7.1: dependencies: acorn: 8.12.1 @@ -22658,6 +23709,8 @@ snapshots: is-negative-zero@2.0.3: {} + is-node-process@1.2.0: {} + is-number-object@1.0.7: dependencies: has-tostringtag: 1.0.2 @@ -22854,7 +23907,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.16.2 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3 @@ -22893,6 +23946,25 @@ snapshots: - supports-color - ts-node + jest-cli@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest-config@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)): dependencies: '@babel/core': 7.24.8 @@ -22924,6 +23996,68 @@ snapshots: - babel-plugin-macros - supports-color + jest-config@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)): + dependencies: + '@babel/core': 7.24.8 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.24.8) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.7 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.16.2 + ts-node: 10.9.2(@types/node@20.14.11)(typescript@5.5.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-config@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)): + dependencies: + '@babel/core': 7.24.8 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.24.8) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.7 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.16.2 + ts-node: 10.9.2(@types/node@20.16.2)(typescript@5.5.4) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-diff@29.7.0: dependencies: chalk: 4.1.2 @@ -22949,7 +24083,7 @@ snapshots: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/jsdom': 20.0.1 - '@types/node': 20.14.11 + '@types/node': 20.16.2 jest-mock: 29.7.0 jest-util: 29.7.0 jsdom: 20.0.3 @@ -22963,16 +24097,16 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.16.2 jest-mock: 29.7.0 jest-util: 29.7.0 - jest-extended@4.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))): + jest-extended@4.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))): dependencies: jest-diff: 29.7.0 jest-get-type: 29.6.3 optionalDependencies: - jest: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + jest: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-get-type@29.6.3: {} @@ -22980,7 +24114,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.14.11 + '@types/node': 20.16.2 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -23016,14 +24150,14 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 - jest-mock-req-res@1.0.2(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3))): + jest-mock-req-res@1.0.2(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4))): dependencies: - jest: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + jest: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.16.2 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -23058,7 +24192,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.16.2 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -23086,7 +24220,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.16.2 chalk: 4.1.2 cjs-module-lexer: 1.3.1 collect-v8-coverage: 1.0.2 @@ -23132,7 +24266,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.16.2 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -23151,7 +24285,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.16.2 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -23160,7 +24294,7 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -23177,6 +24311,18 @@ snapshots: - supports-color - ts-node + jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jiti@1.21.0: {} jmespath@0.16.0: {} @@ -23604,6 +24750,8 @@ snapshots: lodash.difference@4.5.0: {} + lodash.escape@4.0.1: {} + lodash.escaperegexp@4.1.2: {} lodash.flatten@4.4.0: {} @@ -23658,6 +24806,8 @@ snapshots: lodash.startcase@4.4.0: {} + lodash.unescape@4.0.1: {} + lodash.union@4.6.0: {} lodash.uniq@4.5.0: {} @@ -23735,10 +24885,6 @@ snapshots: dependencies: yallist: 3.1.1 - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - lru-cache@7.18.3: {} lru-cache@8.0.5: {} @@ -23825,6 +24971,12 @@ snapshots: mark.js@8.11.1: {} + markdown-to-txt@2.0.1: + dependencies: + lodash.escape: 4.0.1 + lodash.unescape: 4.0.1 + marked: 4.3.0 + marked-terminal@7.0.0(marked@12.0.2): dependencies: ansi-escapes: 6.2.1 @@ -23876,9 +25028,9 @@ snapshots: merge2@1.4.1: {} - meros@1.3.0(@types/node@20.14.11): + meros@1.3.0(@types/node@20.16.2): optionalDependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 methods@1.1.2: {} @@ -23920,6 +25072,10 @@ snapshots: minimalistic-crypto-utils@1.0.1: {} + minimatch@10.0.1: + dependencies: + brace-expansion: 2.0.1 + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -24106,6 +25262,12 @@ snapshots: lower-case: 2.0.2 tslib: 2.6.3 + nock@14.0.0-beta.11: + dependencies: + '@mswjs/interceptors': 0.34.3 + json-stringify-safe: 5.0.1 + propagate: 2.0.1 + nock@14.0.0-beta.6: dependencies: json-stringify-safe: 5.0.1 @@ -24205,11 +25367,11 @@ snapshots: npm-normalize-package-bin@2.0.0: {} - npm-package-arg@11.0.2: + npm-package-arg@11.0.3: dependencies: hosted-git-info: 7.0.2 proc-log: 4.2.0 - semver: 7.6.2 + semver: 7.6.3 validate-npm-package-name: 5.0.1 npm-packlist@5.1.3: @@ -24354,6 +25516,11 @@ snapshots: - supports-color optional: true + optimism@0.16.2: + dependencies: + '@wry/context': 0.7.4 + '@wry/trie': 0.3.2 + optimist@0.6.1: dependencies: minimist: 0.0.10 @@ -24394,6 +25561,8 @@ snapshots: os-tmpdir@1.0.2: {} + outvariant@1.4.3: {} + owasp-password-strength-test@1.3.0: {} p-cancelable@2.1.1: {} @@ -24531,7 +25700,7 @@ snapshots: dependencies: '@babel/code-frame': 7.24.7 index-to-position: 0.1.2 - type-fest: 4.18.2 + type-fest: 4.21.0 parse-ms@4.0.0: {} @@ -24783,15 +25952,15 @@ snapshots: '@mrleebo/prisma-ast': 0.7.0 '@prisma/generator-helper': 5.3.1 '@prisma/internals': 5.3.1(encoding@0.1.13) - typescript: 5.5.3 + typescript: 5.5.4 zod: 3.23.6 transitivePeerDependencies: - encoding - supports-color - prisma@5.14.0: + prisma@5.18.0: dependencies: - '@prisma/engines': 5.14.0 + '@prisma/engines': 5.18.0 prismjs@1.29.0: {} @@ -24856,7 +26025,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.14.11 + '@types/node': 20.16.2 long: 5.2.3 protobufjs@7.3.2: @@ -24871,7 +26040,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.14.11 + '@types/node': 20.16.2 long: 5.2.3 protocols@2.0.1: {} @@ -25013,13 +26182,13 @@ snapshots: dependencies: find-up-simple: 1.0.0 read-pkg: 9.0.1 - type-fest: 4.18.2 + type-fest: 4.21.0 read-pkg-up@11.0.0: dependencies: find-up-simple: 1.0.0 read-pkg: 9.0.1 - type-fest: 4.18.2 + type-fest: 4.21.0 read-pkg-up@7.0.1: dependencies: @@ -25039,7 +26208,7 @@ snapshots: '@types/normalize-package-data': 2.4.4 normalize-package-data: 6.0.1 parse-json: 8.1.0 - type-fest: 4.18.2 + type-fest: 4.21.0 unicorn-magic: 0.1.0 read-yaml-file@2.1.0: @@ -25215,6 +26384,8 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + response-iterator@0.2.6: {} + response-time@2.3.2: dependencies: depd: 1.1.2 @@ -25258,26 +26429,26 @@ snapshots: dependencies: glob: 7.2.3 - rollup@4.18.1: + rollup@4.21.1: dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.18.1 - '@rollup/rollup-android-arm64': 4.18.1 - '@rollup/rollup-darwin-arm64': 4.18.1 - '@rollup/rollup-darwin-x64': 4.18.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.18.1 - '@rollup/rollup-linux-arm-musleabihf': 4.18.1 - '@rollup/rollup-linux-arm64-gnu': 4.18.1 - '@rollup/rollup-linux-arm64-musl': 4.18.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.18.1 - '@rollup/rollup-linux-riscv64-gnu': 4.18.1 - '@rollup/rollup-linux-s390x-gnu': 4.18.1 - '@rollup/rollup-linux-x64-gnu': 4.18.1 - '@rollup/rollup-linux-x64-musl': 4.18.1 - '@rollup/rollup-win32-arm64-msvc': 4.18.1 - '@rollup/rollup-win32-ia32-msvc': 4.18.1 - '@rollup/rollup-win32-x64-msvc': 4.18.1 + '@rollup/rollup-android-arm-eabi': 4.21.1 + '@rollup/rollup-android-arm64': 4.21.1 + '@rollup/rollup-darwin-arm64': 4.21.1 + '@rollup/rollup-darwin-x64': 4.21.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.21.1 + '@rollup/rollup-linux-arm-musleabihf': 4.21.1 + '@rollup/rollup-linux-arm64-gnu': 4.21.1 + '@rollup/rollup-linux-arm64-musl': 4.21.1 + '@rollup/rollup-linux-powerpc64le-gnu': 4.21.1 + '@rollup/rollup-linux-riscv64-gnu': 4.21.1 + '@rollup/rollup-linux-s390x-gnu': 4.21.1 + '@rollup/rollup-linux-x64-gnu': 4.21.1 + '@rollup/rollup-linux-x64-musl': 4.21.1 + '@rollup/rollup-win32-arm64-msvc': 4.21.1 + '@rollup/rollup-win32-ia32-msvc': 4.21.1 + '@rollup/rollup-win32-x64-msvc': 4.21.1 fsevents: 2.3.3 router@1.3.8: @@ -25352,7 +26523,7 @@ snapshots: secure-json-parse@2.7.0: {} - semantic-release-monorepo@8.0.2(semantic-release@24.0.0(typescript@5.5.3)): + semantic-release-monorepo@8.0.2(semantic-release@24.1.0(typescript@5.5.4)): dependencies: debug: 4.3.4 execa: 5.1.1 @@ -25365,26 +26536,26 @@ snapshots: pkg-up: 3.1.0 ramda: 0.27.2 read-pkg: 5.2.0 - semantic-release: 24.0.0(typescript@5.5.3) - semantic-release-plugin-decorators: 4.0.0(semantic-release@24.0.0(typescript@5.5.3)) + semantic-release: 24.1.0(typescript@5.5.4) + semantic-release-plugin-decorators: 4.0.0(semantic-release@24.1.0(typescript@5.5.4)) tempy: 1.0.1 transitivePeerDependencies: - supports-color - semantic-release-plugin-decorators@4.0.0(semantic-release@24.0.0(typescript@5.5.3)): + semantic-release-plugin-decorators@4.0.0(semantic-release@24.1.0(typescript@5.5.4)): dependencies: - semantic-release: 24.0.0(typescript@5.5.3) + semantic-release: 24.1.0(typescript@5.5.4) - semantic-release@24.0.0(typescript@5.5.3): + semantic-release@24.1.0(typescript@5.5.4): dependencies: - '@semantic-release/commit-analyzer': 13.0.0(semantic-release@24.0.0(typescript@5.5.3)) + '@semantic-release/commit-analyzer': 13.0.0(semantic-release@24.1.0(typescript@5.5.4)) '@semantic-release/error': 4.0.0 - '@semantic-release/github': 10.0.3(semantic-release@24.0.0(typescript@5.5.3)) - '@semantic-release/npm': 12.0.0(semantic-release@24.0.0(typescript@5.5.3)) - '@semantic-release/release-notes-generator': 14.0.0(semantic-release@24.0.0(typescript@5.5.3)) + '@semantic-release/github': 10.0.3(semantic-release@24.1.0(typescript@5.5.4)) + '@semantic-release/npm': 12.0.0(semantic-release@24.1.0(typescript@5.5.4)) + '@semantic-release/release-notes-generator': 14.0.0(semantic-release@24.1.0(typescript@5.5.4)) aggregate-error: 5.0.0 - cosmiconfig: 9.0.0(typescript@5.5.3) - debug: 4.3.4 + cosmiconfig: 9.0.0(typescript@5.5.4) + debug: 4.3.5(supports-color@5.5.0) env-ci: 11.0.0 execa: 9.2.0 figures: 6.1.0 @@ -25397,7 +26568,7 @@ snapshots: lodash-es: 4.17.21 marked: 12.0.2 marked-terminal: 7.0.0(marked@12.0.2) - micromatch: 4.0.5 + micromatch: 4.0.7 p-each-series: 3.0.0 p-reduce: 3.0.0 read-package-up: 11.0.0 @@ -25424,12 +26595,10 @@ snapshots: semver@6.3.1: {} - semver@7.6.0: - dependencies: - lru-cache: 6.0.0 - semver@7.6.2: {} + semver@7.6.3: {} + send@0.18.0: dependencies: debug: 2.6.9 @@ -25783,6 +26952,8 @@ snapshots: streamsearch@1.1.0: {} + strict-event-emitter@0.5.1: {} + string-env-interpolation@1.0.1: {} string-length@4.0.2: @@ -25876,7 +27047,7 @@ snapshots: stripe@14.24.0: dependencies: - '@types/node': 20.14.11 + '@types/node': 20.16.2 qs: 6.12.0 striptags@3.2.0: {} @@ -25992,6 +27163,8 @@ snapshots: dependencies: tslib: 2.6.3 + symbol-observable@4.0.0: {} + symbol-tree@3.2.4: {} synckit@0.9.1: @@ -25999,23 +27172,23 @@ snapshots: '@pkgr/core': 0.1.1 tslib: 2.6.3 - syncpack@12.3.3(typescript@5.6.0-dev.20240805): + syncpack@12.4.0(typescript@5.7.0-dev.20240829): dependencies: - '@effect/schema': 0.66.5(effect@3.0.3)(fast-check@3.17.2) + '@effect/schema': 0.69.0(effect@3.5.7) chalk: 5.3.0 chalk-template: 1.1.0 - commander: 12.0.0 - cosmiconfig: 9.0.0(typescript@5.6.0-dev.20240805) - effect: 3.0.3 + commander: 12.1.0 + cosmiconfig: 9.0.0(typescript@5.7.0-dev.20240829) + effect: 3.5.7 enquirer: 2.4.1 - fast-check: 3.17.2 - globby: 14.0.1 - minimatch: 9.0.4 - npm-package-arg: 11.0.2 + fast-check: 3.20.0 + globby: 14.0.2 + minimatch: 10.0.1 + npm-package-arg: 11.0.3 ora: 8.0.1 prompts: 2.4.2 read-yaml-file: 2.1.0 - semver: 7.6.0 + semver: 7.6.3 tightrope: 0.2.0 ts-toolbelt: 9.6.0 transitivePeerDependencies: @@ -26188,13 +27361,17 @@ snapshots: ts-algebra@1.2.2: {} - ts-api-utils@1.3.0(typescript@5.5.3): + ts-api-utils@1.3.0(typescript@5.5.4): dependencies: - typescript: 5.5.3 + typescript: 5.5.4 ts-interface-checker@0.1.13: {} - ts-jest@29.2.3(@babel/core@7.24.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.5))(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3): + ts-invariant@0.10.3: + dependencies: + tslib: 2.6.3 + + ts-jest@29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 @@ -26207,24 +27384,43 @@ snapshots: semver: 7.6.2 typescript: 5.5.3 yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.24.8 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.24.8) + + ts-jest@29.2.4(@babel/core@7.24.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.5))(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4): + dependencies: + bs-logger: 0.2.6 + ejs: 3.1.10 + fast-json-stable-stringify: 2.1.0 + jest: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) + jest-util: 29.7.0 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.6.2 + typescript: 5.5.4 + yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.24.5 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 babel-jest: 29.7.0(@babel/core@7.24.5) - ts-jest@29.2.3(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3): + ts-jest@29.2.4(@babel/core@7.24.8)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.8))(esbuild@0.23.0)(jest@29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)))(typescript@5.5.4): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.14.11)(ts-node@10.9.2(@types/node@20.14.11)(typescript@5.5.3)) + jest: 29.7.0(@types/node@20.16.2)(ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.6.2 - typescript: 5.5.3 + typescript: 5.5.4 yargs-parser: 21.1.1 optionalDependencies: '@babel/core': 7.24.8 @@ -26253,6 +27449,24 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + ts-node@10.9.2(@types/node@20.16.2)(typescript@5.5.4): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.16.2 + acorn: 8.12.1 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + ts-pattern@4.3.0: {} ts-toolbelt@9.6.0: {} @@ -26263,7 +27477,7 @@ snapshots: tsscmp@1.0.6: {} - tsup@8.1.2(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.3)(yaml@2.4.2): + tsup@8.2.4(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(typescript@5.5.4)(yaml@2.4.2): dependencies: bundle-require: 5.0.0(esbuild@0.23.0) cac: 6.7.14 @@ -26274,15 +27488,16 @@ snapshots: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 + picocolors: 1.0.1 postcss-load-config: 6.0.1(jiti@1.21.0)(postcss@8.4.39)(tsx@4.13.2)(yaml@2.4.2) resolve-from: 5.0.0 - rollup: 4.18.1 + rollup: 4.21.1 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 optionalDependencies: postcss: 8.4.39 - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - jiti - supports-color @@ -26308,32 +27523,32 @@ snapshots: transitivePeerDependencies: - supports-color - turbo-darwin-64@1.13.4: + turbo-darwin-64@2.1.0: optional: true - turbo-darwin-arm64@1.13.4: + turbo-darwin-arm64@2.1.0: optional: true - turbo-linux-64@1.13.4: + turbo-linux-64@2.1.0: optional: true - turbo-linux-arm64@1.13.4: + turbo-linux-arm64@2.1.0: optional: true - turbo-windows-64@1.13.4: + turbo-windows-64@2.1.0: optional: true - turbo-windows-arm64@1.13.4: + turbo-windows-arm64@2.1.0: optional: true - turbo@1.13.4: + turbo@2.1.0: optionalDependencies: - turbo-darwin-64: 1.13.4 - turbo-darwin-arm64: 1.13.4 - turbo-linux-64: 1.13.4 - turbo-linux-arm64: 1.13.4 - turbo-windows-64: 1.13.4 - turbo-windows-arm64: 1.13.4 + turbo-darwin-64: 2.1.0 + turbo-darwin-arm64: 2.1.0 + turbo-linux-64: 2.1.0 + turbo-linux-arm64: 2.1.0 + turbo-windows-64: 2.1.0 + turbo-windows-arm64: 2.1.0 turndown@7.2.0: dependencies: @@ -26361,8 +27576,6 @@ snapshots: type-fest@2.19.0: {} - type-fest@4.18.2: {} - type-fest@4.21.0: {} type-is@1.6.18: @@ -26415,22 +27628,24 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@7.16.1(eslint@9.7.0)(typescript@5.5.3): + typescript-eslint@8.3.0(eslint@9.7.0)(typescript@5.5.4): dependencies: - '@typescript-eslint/eslint-plugin': 7.16.1(@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3))(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/parser': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - eslint: 9.7.0 + '@typescript-eslint/eslint-plugin': 8.3.0(@typescript-eslint/parser@8.3.0(eslint@9.7.0)(typescript@5.5.4))(eslint@9.7.0)(typescript@5.5.4) + '@typescript-eslint/parser': 8.3.0(eslint@9.7.0)(typescript@5.5.4) + '@typescript-eslint/utils': 8.3.0(eslint@9.7.0)(typescript@5.5.4) optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: + - eslint - supports-color typescript@5.4.5: {} typescript@5.5.3: {} - typescript@5.6.0-dev.20240805: {} + typescript@5.5.4: {} + + typescript@5.7.0-dev.20240829: {} ua-parser-js@1.0.37: {} @@ -26459,6 +27674,8 @@ snapshots: undici-types@5.26.5: {} + undici-types@6.19.8: {} + undici@6.18.2: {} unicode-emoji-modifier-base@1.0.0: {} @@ -26979,6 +28196,12 @@ snapshots: optionalDependencies: commander: 9.5.0 + zen-observable-ts@1.2.5: + dependencies: + zen-observable: 0.8.15 + + zen-observable@0.8.15: {} + zip-stream@4.1.1: dependencies: archiver-utils: 3.0.4 diff --git a/renovate.json b/renovate.json index cc7eee589..95f3be33c 100644 --- a/renovate.json +++ b/renovate.json @@ -2,6 +2,10 @@ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["github>Pocket/renovate-config", "group:monorepos"], "packageRules": [ + { + "matchDepTypes": ["action"], + "pinDigests": false + }, { "managers": ["docker-compose"], "updateTypes": ["digest", "pinDigest"], diff --git a/servers/account-data-deleter/package.json b/servers/account-data-deleter/package.json index 5b6819e76..eca526a1e 100644 --- a/servers/account-data-deleter/package.json +++ b/servers/account-data-deleter/package.json @@ -21,12 +21,12 @@ "watch": "tsc -w --preserveWatchOutput & nodemon --config ../../nodemon.json" }, "dependencies": { - "@aws-sdk/client-sqs": "3.609.0", + "@aws-sdk/client-sqs": "3.632.0", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/feature-flags-client": "workspace:*", "@pocket-tools/sentry": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "express": "4.19.2", "express-validator": "^7.1.0", "knex": "3.1.0", @@ -37,18 +37,18 @@ }, "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", - "@sentry/types": "8.18.0", + "@sentry/types": "8.27.0", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", "jest-extended": "4.0.2", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", "supertest": "7.0.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3", + "typescript": "5.5.4", "unleash-client": "5.6.1" } } diff --git a/servers/account-data-deleter/src/routes/queueDelete.integration.ts b/servers/account-data-deleter/src/routes/queueDelete.integration.ts index 6c8efd34e..0aee832dd 100644 --- a/servers/account-data-deleter/src/routes/queueDelete.integration.ts +++ b/servers/account-data-deleter/src/routes/queueDelete.integration.ts @@ -150,7 +150,7 @@ describe('enqueueTablesForDeletion', () => { }); for (let i = 0; i < expectedMessages.length; i++) { expect(actualMessages[i]).toMatchObject(expectedMessages[i]); - expect(actualMessages[i].traceId).not.toBeNull; + expect(actualMessages[i].traceId).not.toBeNull(); } }); }); @@ -236,7 +236,7 @@ describe('enqueueTablesForDeletion', () => { }); for (let i = 0; i < expectedMessages.length; i++) { expect(actualMessages[i]).toMatchObject(expectedMessages[i]); - expect(actualMessages[i].traceId).not.toBeNull; + expect(actualMessages[i].traceId).not.toBeNull(); } }); }); @@ -376,7 +376,7 @@ describe('enqueueTablesForDeletion', () => { for (let i = 0; i < expectedMessages.length; i++) { // Stupid timezone expect(actualMessages[i]).toMatchObject(expectedMessages[i]); - expect(actualMessages[i].traceId).not.toBeNull; + expect(actualMessages[i].traceId).not.toBeNull(); } }); }); diff --git a/servers/annotations-api/package.json b/servers/annotations-api/package.json index c8ef43a70..3942aaf36 100644 --- a/servers/annotations-api/package.json +++ b/servers/annotations-api/package.json @@ -27,15 +27,14 @@ "@apollo/cache-control-types": "1.0.3", "@apollo/datasource-rest": "^6.2.2", "@apollo/server": "4.10.4", - "@apollo/subgraph": "2.8.3", - "@aws-sdk/client-dynamodb": "3.609.0", - "@aws-sdk/client-sqs": "3.609.0", - "@aws-sdk/lib-dynamodb": "3.609.0", + "@apollo/subgraph": "2.9.0", + "@aws-sdk/client-dynamodb": "3.632.0", + "@aws-sdk/client-sqs": "3.632.0", + "@aws-sdk/lib-dynamodb": "3.632.0", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/sentry": "workspace:*", - "@pocket-tools/tracing": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "cors": "2.8.5", "dataloader": "2.2.2", "exponential-backoff": "^3.1.1", @@ -57,21 +56,21 @@ "@graphql-codegen/typescript": "4.0.9", "@graphql-codegen/typescript-resolvers": "^4.1.0", "@pocket-tools/eslint-config": "workspace:*", - "@sentry/types": "8.18.0", + "@sentry/types": "8.27.0", "@types/chance": "1.1.6", "@types/jest": "29.5.12", "@types/md5": "2.3.5", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "@types/uuid": "9.0.8", - "chance": "1.1.11", + "chance": "1.1.12", "jest": "29.7.0", "jest-extended": "4.0.2", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", "supertest": "7.0.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/servers/annotations-api/src/main.ts b/servers/annotations-api/src/main.ts index 493cd9fb6..12b3a48fe 100644 --- a/servers/annotations-api/src/main.ts +++ b/servers/annotations-api/src/main.ts @@ -3,33 +3,17 @@ import { initSentry } from '@pocket-tools/sentry'; initSentry({ ...config.sentry, debug: config.sentry.environment == 'development', - skipOpenTelemetrySetup: true, }); -//this must run before all imports and server start but after sentry -//so open-telemetry can patch all libraries that we use -import { - nodeSDKBuilder, - AdditionalInstrumentation, -} from '@pocket-tools/tracing'; + import { serverLogger } from '@pocket-tools/ts-logger'; +import { startServer } from './server'; +import { EventEmitter } from 'events'; +import { BatchDeleteHandler } from './server/aws/batchDeleteHandler'; -nodeSDKBuilder({ - host: config.tracing.host, - serviceName: config.tracing.serviceName, - release: config.sentry.release, - logger: serverLogger, - additionalInstrumentations: [AdditionalInstrumentation.KNEX], - addSentry: true, -}).then(async () => { +startServer(config.app.port).then(async () => { // init BatchDeleteHandler, SQS queue is not // present in localstack for integration testing // Start BatchDelete queue polling new BatchDeleteHandler(new EventEmitter()); - - await startServer(config.app.port); serverLogger.info(`🚀 Server ready at http://localhost:${config.app.port}`); }); - -import { startServer } from './server'; -import { EventEmitter } from 'events'; -import { BatchDeleteHandler } from './server/aws/batchDeleteHandler'; diff --git a/servers/annotations-api/src/test/clearUserData/notes.integration.ts b/servers/annotations-api/src/test/clearUserData/notes.integration.ts index 88b7a77e8..5a32ec159 100644 --- a/servers/annotations-api/src/test/clearUserData/notes.integration.ts +++ b/servers/annotations-api/src/test/clearUserData/notes.integration.ts @@ -51,7 +51,7 @@ describe('clearUserData for Notes data', () => { expect(res['$metadata'].httpStatusCode).toEqual(200); expect(res.Count).toEqual(0); expect(res.Items.length).toEqual(0); - expect(res.LastEvaluatedKey).toBeUndefined; + expect(res.LastEvaluatedKey).toBeUndefined(); }); it('deletes multiple batches of records for a user id', async () => { const notesService = new NotesDataService(client, bigUser); @@ -60,7 +60,7 @@ describe('clearUserData for Notes data', () => { expect(res['$metadata'].httpStatusCode).toEqual(200); expect(res.Count).toEqual(0); expect(res.Items.length).toEqual(0); - expect(res.LastEvaluatedKey).toBeUndefined; + expect(res.LastEvaluatedKey).toBeUndefined(); }); it('does not throw an error if there are no records to delete', async () => { const notesService = new NotesDataService(client, noUser); @@ -69,6 +69,6 @@ describe('clearUserData for Notes data', () => { expect(res['$metadata'].httpStatusCode).toEqual(200); expect(res.Count).toEqual(0); expect(res.Items.length).toEqual(0); - expect(res.LastEvaluatedKey).toBeUndefined; + expect(res.LastEvaluatedKey).toBeUndefined(); }); }); diff --git a/servers/annotations-api/src/test/mutation/highlights-create.integration.ts b/servers/annotations-api/src/test/mutation/highlights-create.integration.ts index 4284bbca4..f64d74a4a 100644 --- a/servers/annotations-api/src/test/mutation/highlights-create.integration.ts +++ b/servers/annotations-api/src/test/mutation/highlights-create.integration.ts @@ -287,7 +287,7 @@ describe('Highlights creation', () => { .post(graphQLUrl) .set(headers) .send({ query: print(CREATE_HIGHLIGHTS), variables }); - expect(res.body.errors).not.toBeUndefined; + expect(res.body.errors).not.toBeUndefined(); expect(res.body.errors.length).toEqual(1); expect(res.body.errors[0].extensions?.code).toEqual('BAD_USER_INPUT'); expect(res.body.errors[0].message).toContain('Too many highlights'); @@ -313,7 +313,7 @@ describe('Highlights creation', () => { .post(graphQLUrl) .set(headers) .send({ query: print(CREATE_HIGHLIGHTS), variables }); - expect(res.body.errors).not.toBeUndefined; + expect(res.body.errors).not.toBeUndefined(); expect(res.body.errors.length).toEqual(1); expect(res.body.errors[0].extensions?.code).toEqual('BAD_USER_INPUT'); expect(res.body.errors[0].message).toContain('Too many highlights'); @@ -333,7 +333,7 @@ describe('Highlights creation', () => { .post(graphQLUrl) .set(headers) .send({ query: print(CREATE_HIGHLIGHTS), variables }); - expect(res.body.errors).toBeUndefined; + expect(res.body.errors).toBeUndefined(); expect(res.body.data).toBeTruthy(); expect(res.body.data?.createSavedItemHighlights.length).toEqual(1); }); diff --git a/servers/braze-content-proxy/README.md b/servers/braze-content-proxy/README.md new file mode 100644 index 000000000..d8af5ff21 --- /dev/null +++ b/servers/braze-content-proxy/README.md @@ -0,0 +1,73 @@ +# Braze Content Proxy API + +Provides Pocket Hits stories to be consumed by Connected Content blocks in Braze. + +## Application Overview + +- [Express](https://expressjs.com/) is the Node framework, +- [Apollo Client](https://www.apollographql.com/docs/react/) is used in Express to request data from +- [Client API](https://github.com/Pocket/client-api/). +- [Pocket Image Cache](https://pocket-image-cache.com/), a Pocket service, is also used to resize image thumbnails on the fly for use in emails. + +## Caching + +### API-side caching + +The API sets a two-minute cache on its output via a `Cache-Control` header. There is no caching of results from Client API, so any updates to curated stories and scheduling on Pocket Hits surfaces should be visible with a maximum of two-minute lag. + +### Braze-side caching + +Braze caches Connected Content for a minimum of five minutes (and recommends setting the value to 15 minutes): [Connected Content: Configurable Caching](https://www.braze.com/docs/user_guide/personalization_and_dynamic_content/connected_content/local_connected_content_variables/#configurable-caching). + +## Local Development + +- Clone the repository: + +```bash +git clone git@github.com:Pocket/braze-content-proxy.git + +cd braze-content-proxy +``` + +- Install the packages: + +```bash +npm install +``` + +- Start the app: + +```bash +npm run start:dev +``` + +- Load `http://localhost:4500` in your browser. Done! + +## Testing the proxy on Dev + +Note that it's often more convenient to work with test data curated on Dev, so the local setup is mainly useful for running tests and lint checks. + +- Push the branch you're working on to Dev: + +```bash +git push -f origin YOUR_BRANCH_HERE:dev +``` +and wait for the deployment to complete (~10 minutes). + +- to get scheduled items for a given day: +```bash +# params required +https://braze-content-proxy.getpocket.dev/scheduled-items/[SCHEDULED_SURFACE_GUID]/?date=[DATE_IN_YYYY-MM-DD_FORMAT]&apikey=[LOOK_UP_THE_KEY_IN_AWS] +# sample URL (don't forget to supply the API key) +https://braze-content-proxy.getpocket.dev/scheduled-items/POCKET_HITS_EN_US/?date=2022-05-27&apikey=[INSERT_API_KEY] +``` +- to get a collection by slug: +```bash +# params required +https://braze-content-proxy.getpocket.dev/collection/[COLLECTION_SLUG]/?apikey=[LOOK_UP_THE_KEY_IN_AWS] +# sample URL (don't forget to supply the API key) +https://braze-content-proxy.getpocket.dev/collection/halloween-history?apikey=[LOOK_UP_THE_KEY_IN_AWS] +``` + + +- Now you can do a sanity check for the data returned by the proxy. diff --git a/servers/braze-content-proxy/codegen.ts b/servers/braze-content-proxy/codegen.ts new file mode 100644 index 000000000..eb08ba8e1 --- /dev/null +++ b/servers/braze-content-proxy/codegen.ts @@ -0,0 +1,33 @@ +import { CodegenConfig } from '@graphql-codegen/cli'; + +const config: CodegenConfig = { + schema: 'https://client-api.getpocket.com', + documents: ['src/graphql/**/*.graphql'], + generates: { + './src/generated/graphql/types.ts': { + plugins: [ + //generated types do not conform to ts/lint rules, disable them for these files + { + add: { + content: '// THIS FILE IS GENERATED, DO NOT EDIT!', + }, + }, + { + add: { + content: '/* tslint:disable */', + }, + }, + { + add: { + content: '/* eslint-disable */', + }, + }, + 'typescript', + 'typescript-operations', + 'typed-document-node', + ], + }, + }, +}; + +export default config; diff --git a/servers/braze-content-proxy/eslint.config.mjs b/servers/braze-content-proxy/eslint.config.mjs new file mode 100644 index 000000000..3d0918aad --- /dev/null +++ b/servers/braze-content-proxy/eslint.config.mjs @@ -0,0 +1,5 @@ +import servers from '@pocket-tools/eslint-config/servers'; +import tseslint from 'typescript-eslint'; +export default tseslint.config(...servers, { + ignores: ['src/__generated__/*'], +}); diff --git a/servers/braze-content-proxy/jest.config.js b/servers/braze-content-proxy/jest.config.js new file mode 100644 index 000000000..bc244bf75 --- /dev/null +++ b/servers/braze-content-proxy/jest.config.js @@ -0,0 +1,9 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/src/**/?(*.)+(spec|integration).[jt]s?(x)'], + testPathIgnorePatterns: ['/dist/', '/lambda/'], + testTimeout: 10000, + displayName: 'braze-content-proxy', + setupFilesAfterEnv: ['jest-extended/all'], +}; diff --git a/servers/braze-content-proxy/package.json b/servers/braze-content-proxy/package.json new file mode 100644 index 000000000..c9ca20354 --- /dev/null +++ b/servers/braze-content-proxy/package.json @@ -0,0 +1,51 @@ +{ + "name": "braze-content-proxy", + "version": "1.0.0", + "main": "dist/main.js", + "scripts": { + "build": "rm -rf dist && tsc", + "dev": "npm run build && npm run watch", + "format": "eslint --fix", + "lint": "eslint --fix-dry-run", + "prebuild": "graphql-codegen", + "start": "node dist/main.js", + "test": "jest \"\\.spec\\.ts\"", + "test-integrations": "jest \"\\.integration\\.ts\" --runInBand", + "test:watch": "npm test -- --watchAll", + "watch": "tsc -w --preserveWatchOutput & nodemon --config ../../nodemon.json" + }, + "dependencies": { + "@apollo/client": "3.7.17", + "@graphql-typed-document-node/core": "3.2.0", + "@pocket-tools/sentry": "workspace:*", + "@pocket-tools/ts-logger": "workspace:*", + "@sentry/node": "8.27.0", + "cross-fetch": "4.0.0", + "dataloader": "2.2.2", + "express": "4.19.2", + "graphql-tag": "2.12.6", + "tslib": "2.6.3" + }, + "devDependencies": { + "@graphql-codegen/add": "5.0.3", + "@graphql-codegen/cli": "5.0.2", + "@graphql-codegen/typed-document-node": "5.0.9", + "@graphql-codegen/typescript": "4.0.9", + "@graphql-codegen/typescript-operations": "4.2.3", + "@jest/globals": "29.7.0", + "@pocket-tools/eslint-config": "workspace:*", + "@types/express": "4.17.21", + "@types/jest": "29.5.12", + "@types/node": "^20.16", + "@types/supertest": "^6.0.2", + "jest": "29.7.0", + "jest-extended": "4.0.2", + "nock": "14.0.0-beta.11", + "nodemon": "3.1.4", + "supertest": "7.0.0", + "ts-jest": "29.2.4", + "ts-node": "10.9.2", + "tsconfig": "workspace:*", + "typescript": "5.5.4" + } +} diff --git a/servers/braze-content-proxy/src/config/index.ts b/servers/braze-content-proxy/src/config/index.ts new file mode 100644 index 000000000..b94e09986 --- /dev/null +++ b/servers/braze-content-proxy/src/config/index.ts @@ -0,0 +1,33 @@ +export default { + app: { + environment: process.env.NODE_ENV || 'development', + apolloClientName: 'BrazeContentProxy', + version: `${process.env.GIT_SHA ?? 'local'}`, + port: 4500, + INVALID_API_KEY_ERROR_MESSAGE: 'Please provide a valid API key.', + }, + aws: { + region: process.env.REGION || 'us-east-1', + brazeApiKey: + process.env.BRAZE_API_KEY || 'BrazeContentProxy/Dev/BRAZE_API_KEY', + }, + // The URL to query data from. + clientApi: { + uri: `https://client-api.getpocket.${ + process.env.NODE_ENV === 'production' ? 'com' : 'dev' + }`, + }, + // Params we call Pocket Image Cache with to resize story thumbnails on the fly. + images: { + protocol: 'https', + host: 'pocket-image-cache.com', + width: 150, + height: 150, + filters: 'format(jpeg):quality(100):no_upscale():strip_exif()', + }, + sentry: { + dsn: process.env.SENTRY_DSN || '', + release: process.env.GIT_SHA || '', + environment: process.env.NODE_ENV || 'development', + }, +}; diff --git a/servers/braze-content-proxy/src/generated/graphql/types.ts b/servers/braze-content-proxy/src/generated/graphql/types.ts new file mode 100644 index 000000000..a7cfad378 --- /dev/null +++ b/servers/braze-content-proxy/src/generated/graphql/types.ts @@ -0,0 +1,3818 @@ +// THIS FILE IS GENERATED, DO NOT EDIT! +/* tslint:disable */ +/* eslint-disable */ +import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +/** All built-in and custom scalars, mapped to their actual values */ +export type Scalars = { + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } + Date: { input: any; output: any; } + DateString: { input: any; output: any; } + FunctionalBoostValue: { input: any; output: any; } + HtmlString: { input: any; output: any; } + ISOString: { input: any; output: any; } + Markdown: { input: any; output: any; } + Max300CharString: { input: any; output: any; } + NonNegativeInt: { input: any; output: any; } + Timestamp: { input: any; output: any; } + Url: { input: any; output: any; } + ValidUrl: { input: any; output: any; } +}; + +/** + * Input data for adding multiple items to a list. + * Appends to the end of the list. + */ +export type AddItemInput = { + authors?: InputMaybe; + excerpt?: InputMaybe; + imageUrl?: InputMaybe; + itemId: Scalars['ID']['input']; + note?: InputMaybe; + publisher?: InputMaybe; + title?: InputMaybe; + url: Scalars['Url']['input']; +}; + +export type AdvancedSearchFilters = { + contentType?: InputMaybe; + domain?: InputMaybe; + isFavorite?: InputMaybe; + status?: InputMaybe; + /** + * Include only items with the following tags (exact) + * in search results (OR combination) + */ + tags?: InputMaybe>; + title?: InputMaybe; +}; + +/** Valid grade values for CorpusItem (public graph) and ApprovedItem (admin graph) */ +export enum ApprovedItemGrade { + A = 'A', + B = 'B', + C = 'C' +} + +export type ArticleMarkdown = { + __typename?: 'ArticleMarkdown'; + images?: Maybe>; + text: Scalars['String']['output']; +}; + +/** + * The status of the syndicated article + * TODO: rename to SyndicatedArticle status and move to schema-shared.graphql + * (requires client changes) + */ +export enum ArticleStatus { + Active = 'ACTIVE', + Draft = 'DRAFT', + Expired = 'EXPIRED' +} + +/** Information about an Author of an article or some content */ +export type Author = { + __typename?: 'Author'; + /** Unique id for that Author */ + id: Scalars['ID']['output']; + /** Display name */ + name?: Maybe; + /** A url to that Author's site */ + url?: Maybe; +}; + +export type BaseError = { + message: Scalars['String']['output']; + path: Scalars['String']['output']; +}; + +/** Input object for creating and deleting highlights using bulk mutation. */ +export type BatchWriteHighlightsInput = { + create?: InputMaybe>; + delete?: InputMaybe>; +}; + +/** + * Result object for bulk create/delete highlights mutation. + * Mutation is atomic -- if there is a response, all operations + * were successful. + * + * The corresponding result array will be empty, but present, if there + * were no requests for created/deleted. + */ +export type BatchWriteHighlightsResult = { + __typename?: 'BatchWriteHighlightsResult'; + created: Array; + deleted: Array; +}; + +/** Row in a bulleted (unordered list) */ +export type BulletedListElement = ListElement & { + __typename?: 'BulletedListElement'; + /** Row in a list. */ + content: Scalars['Markdown']['output']; + /** Zero-indexed level, for handling nested lists. */ + level: Scalars['Int']['output']; +}; + +/** + * Apollo Server @cacheControl directive caching behavior either for a single field, or for all fields that + * return a particular type + */ +export enum CacheControlScope { + Private = 'PRIVATE', + Public = 'PUBLIC' +} + +/** A requested image that is cached and has the requested image parameters */ +export type CachedImage = { + __typename?: 'CachedImage'; + /** Height of the cached image */ + height?: Maybe; + /** Id of the image that matches the ID from the requested options */ + id: Scalars['ID']['output']; + /** URL of the cached image */ + url?: Maybe; + /** Width of the cached image */ + width?: Maybe; +}; + +/** Set of parameters that will be used to change an image */ +export type CachedImageInput = { + /** File type of the requested image */ + fileType?: InputMaybe; + /** Height of the image */ + height?: InputMaybe; + /** Id of the image in the returned result set */ + id: Scalars['ID']['input']; + /** Quality of the image in whole percentage, 100 = full, quality 50 = half quality */ + qualityPercentage?: InputMaybe; + /** Width of the image */ + width?: InputMaybe; +}; + +export type Collection = { + __typename?: 'Collection'; + IABChildCategory?: Maybe; + /** + * We will never return child categories in this type, so there's no need to + * specify `IABParentCategory` here. The basic `IABCategory` is sufficient. + */ + IABParentCategory?: Maybe; + authors: Array; + curationCategory?: Maybe; + excerpt?: Maybe; + externalId: Scalars['ID']['output']; + imageUrl?: Maybe; + intro?: Maybe; + labels?: Maybe>>; + /** + * note that language is *not* being used as locale - only to specify the + * language of the collection. + */ + language: CollectionLanguage; + partnership?: Maybe; + publishedAt?: Maybe; + /** + * Provides short url for the given_url in the format: https://pocket.co/. + * marked as beta because it's not ready yet for large client request. + */ + shortUrl?: Maybe; + slug: Scalars['String']['output']; + status: CollectionStatus; + stories: Array; + title: Scalars['String']['output']; +}; + +export type CollectionAuthor = { + __typename?: 'CollectionAuthor'; + active: Scalars['Boolean']['output']; + bio?: Maybe; + externalId: Scalars['ID']['output']; + imageUrl?: Maybe; + name: Scalars['String']['output']; + slug?: Maybe; +}; + +/** valid language codes for collections */ +export enum CollectionLanguage { + /** German */ + De = 'DE', + /** English */ + En = 'EN' +} + +/** + * If a collection was made in partnership with an external company, this + * entity will hold all required info about that partnership. + */ +export type CollectionPartnership = { + __typename?: 'CollectionPartnership'; + blurb: Scalars['Markdown']['output']; + externalId: Scalars['String']['output']; + imageUrl: Scalars['Url']['output']; + name: Scalars['String']['output']; + type: CollectionPartnershipType; + url: Scalars['Url']['output']; +}; + +/** Type and enums related to Collections made in partnership with a company. */ +export enum CollectionPartnershipType { + Partnered = 'PARTNERED', + Sponsored = 'SPONSORED' +} + +export enum CollectionStatus { + Archived = 'ARCHIVED', + Draft = 'DRAFT', + Published = 'PUBLISHED', + Review = 'REVIEW' +} + +export type CollectionStory = { + __typename?: 'CollectionStory'; + authors: Array; + excerpt: Scalars['Markdown']['output']; + externalId: Scalars['ID']['output']; + /** if True, the story is provided by a partner and should be displayed as such */ + fromPartner: Scalars['Boolean']['output']; + imageUrl?: Maybe; + item?: Maybe; + publisher?: Maybe; + sortOrder?: Maybe; + title: Scalars['String']['output']; + url: Scalars['Url']['output']; +}; + +export type CollectionStoryAuthor = { + __typename?: 'CollectionStoryAuthor'; + name: Scalars['String']['output']; + sortOrder: Scalars['Int']['output']; +}; + +export type CollectionsFiltersInput = { + /** If provided, will return all collections that match at least one of the labels. */ + labels?: InputMaybe>>; + /** If not provided, or if an unsupported language is requested, defaults to `en` */ + language?: InputMaybe; +}; + +export type CollectionsResult = { + __typename?: 'CollectionsResult'; + collections: Array; + pagination: Pagination; +}; + +/** Content type classification for a corpus item */ +export enum CorpusContentType { + Article = 'ARTICLE', + Collection = 'COLLECTION', + Video = 'VIDEO' +} + +/** + * Represents an item that is in the Corpus and its associated manually edited metadata. + * TODO: CorpusItem to implement PocketResource when it becomes available. + */ +export type CorpusItem = { + __typename?: 'CorpusItem'; + /** The author names and sort orders associated with this CorpusItem. */ + authors: Array; + /** The publication date for this story. */ + datePublished?: Maybe; + /** The excerpt of the Approved Item. */ + excerpt: Scalars['String']['output']; + /** The quality grade associated with this CorpusItem. */ + grade?: Maybe; + /** The GUID that is stored on an approved corpus item */ + id: Scalars['ID']['output']; + /** The image for this item's accompanying picture. */ + image: Image; + /** The image URL for this item's accompanying picture. */ + imageUrl: Scalars['Url']['output']; + /** What language this item is in. This is a two-letter code, for example, 'EN' for English. */ + language: CorpusLanguage; + /** The name of the online publication that published this story. */ + publisher: Scalars['String']['output']; + /** The user's saved item, from the Corpus Item, if the corpus item was saved to the user's saves */ + savedItem?: Maybe; + /** + * Provides short url for the given_url in the format: https://pocket.co/. + * marked as beta because it's not ready yet for large client request. + */ + shortUrl?: Maybe; + /** If the Corpus Item is pocket owned with a specific type, this is the associated object (Collection or SyndicatedArticle). */ + target?: Maybe; + /** Time to read in minutes. Is nullable. */ + timeToRead?: Maybe; + /** The title of the Approved Item. */ + title: Scalars['String']['output']; + /** The topic associated with this CorpusItem. */ + topic?: Maybe; + /** The URL of the Approved Item. */ + url: Scalars['Url']['output']; +}; + +/** An author associated with a CorpusItem. */ +export type CorpusItemAuthor = { + __typename?: 'CorpusItemAuthor'; + name: Scalars['String']['output']; + sortOrder: Scalars['Int']['output']; +}; + +/** Valid language codes for curated corpus items. */ +export enum CorpusLanguage { + /** German */ + De = 'DE', + /** English */ + En = 'EN', + /** Spanish */ + Es = 'ES', + /** French */ + Fr = 'FR', + /** Italian */ + It = 'IT' +} + +export type CorpusRecommendation = { + __typename?: 'CorpusRecommendation'; + /** Content meta data. */ + corpusItem: CorpusItem; + /** Clients should include this id in the `corpus_recommendation` Snowplow entity for impression, content_open, and engagement events related to this recommendation. This id is different across users, across requests, and across corpus items. The recommendation-api service associates metadata with this id to join and aggregate recommendations in our data warehouse. */ + id: Scalars['ID']['output']; + /** Reason why this CorpusItem is recommended to the user, or null if no reason is available. */ + reason?: Maybe; + /** + * Firefox clients require an integer id. Other clients should use `id` instead of this field. tileId uniquely identifies the ScheduledSurface, CorpusItem, and scheduled_date. tileId is greater than 0 and less than 2^53 to fit in a Javascript number (64-bit IEEE 754 float). The field type is a Float because a GraphQL Int is limited to 32 bit. + * @deprecated Only to be used by Firefox. Other clients should use `id`. We plan to also migrate Firefox New Tab to use CorpusRecommendation.id instead of tileId to track recommendation telemetry. + */ + tileId: Scalars['Float']['output']; +}; + +/** Paginated corpus search result connection */ +export type CorpusSearchConnection = { + __typename?: 'CorpusSearchConnection'; + edges: Array; + pageInfo: PageInfo; + totalCount: Scalars['Int']['output']; +}; + +/** An edge in a CorpusSearchConnection result */ +export type CorpusSearchEdge = { + __typename?: 'CorpusSearchEdge'; + cursor: Scalars['String']['output']; + node: CorpusSearchNode; +}; + +/** Fields that can be searched using query strings */ +export enum CorpusSearchFields { + /** Search all possible fields */ + All = 'ALL', + /** + * (Default) Search the fields which relate to the content + * of the resource (title, article, excerpt, extracted content) + * rather than the metadata (publisher). + */ + AllContentful = 'ALL_CONTENTFUL', + /** Search terms in excerpt fields */ + Excerpt = 'EXCERPT', + /** Search terms in parsed, extracted content fields */ + ExtractedContent = 'EXTRACTED_CONTENT', + /** Search terms in publisher fields */ + Publisher = 'PUBLISHER', + /** Search terms in title fields */ + Title = 'TITLE' +} + +/** Filters to refine corpus search results. */ +export type CorpusSearchFilters = { + /** When the content was added to Pocket's corpus */ + addedDateRange?: InputMaybe; + /** The author's name */ + author?: InputMaybe; + /** + * Filter to limit the result set to specific content types. + * Multiple types are combined with OR. + * Can use this to search collections only. + */ + contentType?: InputMaybe>; + /** Set to true to exclude collections from the results. */ + excludeCollections?: InputMaybe; + /** Set to true to exclude ML-generated recommendations from the results. */ + excludeML?: InputMaybe; + /** The language of the corpus to search (letter code) */ + language: CorpusLanguage; + /** + * Filter for when an article was published. Can provide + * upper/lower bounds with 'before' or 'after', or use both + * both to create a time range. + */ + publishedDateRange?: InputMaybe; + /** + * The publisher's name. This is an exact match for filtering. + * To use publisher in search, use the publisher field in the query + * string. + */ + publisher?: InputMaybe; + /** + * The topic (use getTopics query to retrieve valid topics). + * Multiple topics are combined with OR. + */ + topic?: InputMaybe>; +}; + +/** + * Highlighted snippets from fields in the search results + * so clients can show users where the query matches are. + * Each field, if available, contains an array of html text + * snippets that contain a match to the search term. + * The matching text is wrapped in tags, e.g. + * ["Hiss at vacuum cleaner if it fits i sits"] + */ +export type CorpusSearchHighlights = { + __typename?: 'CorpusSearchHighlights'; + excerpt?: Maybe>>; + fullText?: Maybe>>; + publisher?: Maybe>>; + title?: Maybe>>; +}; + +/** A node in a CorpusSearchConnection result */ +export type CorpusSearchNode = { + __typename?: 'CorpusSearchNode'; + /** The preview of the search result */ + preview: PocketMetadata; + /** Search highlights */ + searchHighlights?: Maybe; +}; + +/** A search query for the corpus */ +export type CorpusSearchQueryString = { + /** + * A specific field to search on (e.g. title), + * or ALL to search all available text content fields. + * If missing, defaults to 'ALL_CONTENTFUL' + */ + field?: InputMaybe; + /** The query string to search. */ + query: Scalars['String']['input']; +}; + +/** Sort scheme for Corpus Search. Defaults to showing most relevant results first. */ +export type CorpusSearchSort = { + sortBy: CorpusSearchSortBy; + sortOrder?: InputMaybe; +}; + +/** Sortable properties for Corpus Search */ +export enum CorpusSearchSortBy { + /** When the content was added to the corpus */ + DateAddedToCorpus = 'DATE_ADDED_TO_CORPUS', + /** + * When the content was originally published + * (Note: this data is sparse/nullable) + */ + DatePublished = 'DATE_PUBLISHED', + /** Relevance score computed by search algorithm */ + Relevance = 'RELEVANCE' +} + +/** This is the same as Slate but in this type all recommendations are backed by CorpusItems. This means that the editorial team has editorial control over the items served by this endpoint. */ +export type CorpusSlate = { + __typename?: 'CorpusSlate'; + /** The display headline for the slate. Surface context may be required to render determine what to display. This will depend on if we connect the copy to the Surface, SlateExperiment, or Slate. */ + headline: Scalars['String']['output']; + /** UUID */ + id: Scalars['ID']['output']; + /** Link to a page where the user can explore more recommendations similar to this slate, or null if no link is provided. */ + moreLink?: Maybe; + /** Indicates the main type of reason why recommendations are included in this slate, or null if none is available. */ + recommendationReasonType?: Maybe; + /** Recommendations for the current request context. */ + recommendations: Array; + /** A smaller, secondary headline that can be displayed to provide additional context on the slate. */ + subheadline?: Maybe; + /** utm_source value that can be set on the url by the caller to attribute the recommendations. */ + utmSource?: Maybe; +}; + + +/** This is the same as Slate but in this type all recommendations are backed by CorpusItems. This means that the editorial team has editorial control over the items served by this endpoint. */ +export type CorpusSlateRecommendationsArgs = { + count?: InputMaybe; +}; + +/** A collection of slates. */ +export type CorpusSlateLineup = { + __typename?: 'CorpusSlateLineup'; + /** UUID */ + id: Scalars['ID']['output']; + /** Slates. */ + slates: Array; +}; + + +/** A collection of slates. */ +export type CorpusSlateLineupSlatesArgs = { + count?: InputMaybe; +}; + +/** + * TODO: Make this type implement PocketResource when available. + * https://getpocket.atlassian.net/wiki/spaces/PE/pages/2771714049/The+Future+of+Item + */ +export type CorpusTarget = Collection | SyndicatedArticle; + +/** Input for creating a new User-highlighted passage on a SavedItem. */ +export type CreateHighlightByUrlInput = { + /** + * Optionally, a client-generated UUID to identify the highlight. + * If one is not passed, it will be created. Must be in UUID format, + * or will fail generation. Will not overwrite existing data if there + * is an ID collision. + */ + id?: InputMaybe; + /** Optional note generated by User */ + note?: InputMaybe; + /** + * Patch string generated by 'DiffMatchPatch' library, serialized + * into text via `patch_toText` method. + * Format is similar to UniDiff but is character-based. + * The patched text depends on version. For example, the version 2 + * patch surrounds the highlighted text portion with a pair of + * sentinel tags: '' + * Reference: https://github.com/google/diff-match-patch + */ + patch: Scalars['String']['input']; + /** + * The full text of the highlighted passage. Used as a fallback for + * rendering highlight if the patch fails. + */ + quote: Scalars['String']['input']; + /** The url of the Item that should be annotated in the User's list */ + url: Scalars['ValidUrl']['input']; + /** Annotation data version */ + version: Scalars['Int']['input']; +}; + +/** Input for creating a new User-highlighted passage on a SavedItem. */ +export type CreateHighlightInput = { + /** + * Optionally, a client-generated UUID to identify the highlight. + * If one is not passed, it will be created. Must be in UUID format, + * or will fail generation. Will not overwrite existing data if there + * is an ID collision. + */ + id?: InputMaybe; + /** The ID of the Item that should be annotated in the User's list */ + itemId: Scalars['ID']['input']; + /** Optional note generated by User */ + note?: InputMaybe; + /** + * Patch string generated by 'DiffMatchPatch' library, serialized + * into text via `patch_toText` method. + * Format is similar to UniDiff but is character-based. + * The patched text depends on version. For example, the version 2 + * patch surrounds the highlighted text portion with a pair of + * sentinel tags: '' + * Reference: https://github.com/google/diff-match-patch + */ + patch: Scalars['String']['input']; + /** + * The full text of the highlighted passage. Used as a fallback for + * rendering highlight if the patch fails. + */ + quote: Scalars['String']['input']; + /** Annotation data version */ + version: Scalars['Int']['input']; +}; + +/** Input data for creating a Shareable List. */ +export type CreateShareableListInput = { + description?: InputMaybe; + listItemNoteVisibility?: InputMaybe; + title: Scalars['String']['input']; +}; + +/** Input data for creating a Shareable List Item. */ +export type CreateShareableListItemInput = { + authors?: InputMaybe; + excerpt?: InputMaybe; + imageUrl?: InputMaybe; + itemId: Scalars['ID']['input']; + listExternalId: Scalars['ID']['input']; + note?: InputMaybe; + publisher?: InputMaybe; + sortOrder: Scalars['Int']['input']; + title?: InputMaybe; + url: Scalars['Url']['input']; +}; + +/** Input data for creating a Shareable List Item during Shareable List creation. */ +export type CreateShareableListItemWithList = { + authors?: InputMaybe; + excerpt?: InputMaybe; + imageUrl?: InputMaybe; + itemId: Scalars['ID']['input']; + note?: InputMaybe; + publisher?: InputMaybe; + sortOrder: Scalars['Int']['input']; + title?: InputMaybe; + url: Scalars['Url']['input']; +}; + +/** This type represents the information we need on a curated item. */ +export type CuratedInfo = { + __typename?: 'CuratedInfo'; + excerpt?: Maybe; + /** The image for this item's accompanying picture. */ + image?: Maybe; + imageSrc?: Maybe; + title?: Maybe; +}; + +export type CurationCategory = { + __typename?: 'CurationCategory'; + externalId: Scalars['ID']['output']; + name: Scalars['String']['output']; + slug: Scalars['String']['output']; +}; + +/** + * Filter to get documents added/published before or after a date, + * or provide both for a range of [after, before) + * Before is exclusive, after is inclusive. + */ +export type DateFilter = { + /** Inclusive date -- results must be at or after than this time. */ + after?: InputMaybe; + /** Exclusive date -- results must be exclusively before this time. */ + before?: InputMaybe; +}; + +export type DeleteSavedItemTagsInput = { + /** The id of the SavedItem from which to delete a Tag association */ + savedItemId: Scalars['ID']['input']; + /** The ids of the Tag to disassociate from the SavedItem */ + tagIds: Array; +}; + +/** Metadata from a domain, originally populated from ClearBit */ +export type DomainMetadata = { + __typename?: 'DomainMetadata'; + /** Url for the logo image */ + logo?: Maybe; + /** Url for the greyscale logo image */ + logoGreyscale?: Maybe; + /** The name of the domain (e.g., The New York Times) */ + name?: Maybe; +}; + +/** The reason a user web session is being expired. */ +export enum ExpireUserWebSessionReason { + /** Expire web session upon logging out. */ + Logout = 'LOGOUT', + /** Expire web session on account password change. */ + PasswordChanged = 'PASSWORD_CHANGED' +} + +/** Input field to boost the score of an elasticsearch document based on a specific field and value */ +export type FunctionalBoostField = { + /** A float number to boost the score by */ + factor: Scalars['Float']['input']; + /** Field to evaluate for boosting */ + field: Scalars['String']['input']; + /** The mathematical operation to use for boosting */ + operation: SearchFunctionalBoostOperation; + /** Field value to evaluate */ + value: Scalars['FunctionalBoostValue']['input']; +}; + +/** A User-highlighted passage on a SavedItem */ +export type Highlight = { + __typename?: 'Highlight'; + /** When the Highlight was created */ + _createdAt: Scalars['Timestamp']['output']; + /** When the highlight was last updated */ + _updatedAt: Scalars['Timestamp']['output']; + /** The ID for this Highlight annotation */ + id: Scalars['ID']['output']; + /** Highlight Note associated with this Highlight */ + note?: Maybe; + /** + * Patch string generated by 'DiffMatchPatch' library, serialized + * into text via `patch_toText` method. Use `patch_fromText` to + * deserialize into an object that can be used by the DiffMatchPatch + * library. Format is similar to UniDiff but is character-based. + * The patched text depends on version. For example, the version 2 + * patch surrounds the highlighted text portion with a pair of + * sentinel tags: '' + * Reference: https://github.com/google/diff-match-patch + */ + patch: Scalars['String']['output']; + /** + * The full text of the highlighted passage. Used as a fallback for + * rendering highlight if the patch fails. + */ + quote: Scalars['String']['output']; + /** Version number for highlight data specification */ + version: Scalars['Int']['output']; +}; + +export type HighlightNote = { + __typename?: 'HighlightNote'; + /** When the HighlightNote was created */ + _createdAt: Scalars['Timestamp']['output']; + /** When the HighlightNote was last updated */ + _updatedAt: Scalars['Timestamp']['output']; + /** User entered text */ + text: Scalars['String']['output']; +}; + +/** Interactive Advertising Bureau Category - these are used on clients to serve relevant ads */ +export type IabCategory = { + __typename?: 'IABCategory'; + externalId: Scalars['String']['output']; + name: Scalars['String']['output']; + slug: Scalars['String']['output']; +}; + +export type IabParentCategory = { + __typename?: 'IABParentCategory'; + children: Array; + externalId: Scalars['String']['output']; + name: Scalars['String']['output']; + slug: Scalars['String']['output']; +}; + +/** An image that is keyed on URL */ +export type Image = { + __typename?: 'Image'; + /** Query to get a cached and modified set of images based on the image from the original url, images will be matched by the client assigned id value */ + cachedImages?: Maybe>>; + /** A caption or description of the image */ + caption?: Maybe; + /** A credit for the image, typically who the image belongs to / created by */ + credit?: Maybe; + /** The determined height of the image at the url */ + height?: Maybe; + /** The id for placing within an Article View. Item.article will have placeholders of
where X is this id. Apps can download those images as needed and populate them in their article view. */ + imageId: Scalars['Int']['output']; + /** + * Absolute url to the image + * @deprecated use url property moving forward + */ + src: Scalars['String']['output']; + /** If the image is also a link, the destination url */ + targetUrl?: Maybe; + /** The url of the image */ + url: Scalars['Url']['output']; + /** The determined width of the image at the url */ + width?: Maybe; +}; + + +/** An image that is keyed on URL */ +export type ImageCachedImagesArgs = { + imageOptions: Array; +}; + +/** The image file type */ +export enum ImageFileType { + Jpeg = 'JPEG', + Png = 'PNG', + Webp = 'WEBP' +} + +export enum Imageness { + /** Contains images (v3 value is 1) */ + HasImages = 'HAS_IMAGES', + /** Is an image (v3 value is 2) */ + IsImage = 'IS_IMAGE', + /** No images (v3 value is 0) */ + NoImages = 'NO_IMAGES' +} + +/** + * The heart of Pocket + * A url and meta data related to it. + */ +export type Item = { + __typename?: 'Item'; + /** If available, the url to an AMP version of this article */ + ampUrl?: Maybe; + /** + * The pocket HTML string of the article. + * Note: Web and Android as of 3/4/2022 use the Article field, any improvements made + * within MArticle for parsing will not be reflected in the article field. + * When that happens, the clients will work to move to MArticle. + */ + article?: Maybe; + /** List of Authors involved with this article */ + authors?: Maybe>>; + /** If the item is a collection allow them to get the collection information */ + collection?: Maybe; + /** + * The length in bytes of the content + * @deprecated Clients should not use this + */ + contentLength?: Maybe; + /** If the item is in corpus allow the item to reference it. Exposing curated info for consistent UX */ + corpusItem?: Maybe; + /** The date the article was published */ + datePublished?: Maybe; + /** The date the parser resolved this item */ + dateResolved?: Maybe; + /** The domain, such as 'getpocket.com' of the resolved_url */ + domain?: Maybe; + /** + * The primary database id of the domain this article is from + * @deprecated Use a domain as the identifier instead + */ + domainId?: Maybe; + /** Additional information about the item domain, when present, use this for displaying the domain name */ + domainMetadata?: Maybe; + /** The string encoding code of this item's web page */ + encoding?: Maybe; + /** A snippet of text from the article */ + excerpt?: Maybe; + /** key field to identify the Item entity in the Parser service */ + givenUrl: Scalars['Url']['output']; + /** 0=no images, 1=contains images, 2=is an image */ + hasImage?: Maybe; + /** + * Indicates that the item was stored via a different search_hash (using the old method), we'll need to look up a different id + * @deprecated Most new items use a new hash + */ + hasOldDupes?: Maybe; + /** 0=no videos, 1=contains video, 2=is a video */ + hasVideo?: Maybe; + /** Keyword highlights from search */ + highlights?: Maybe; + /** A server generated unique id for this item based on itemId */ + id: Scalars['ID']['output']; + /** Array of images within an article */ + images?: Maybe>>; + /** + * Indicates if the text of the url is a redirect to another url + * @deprecated Clients should not use this + */ + innerDomainRedirect?: Maybe; + /** true if the item is an article */ + isArticle?: Maybe; + /** true if the item is an index / home page, rather than a specific single piece of content */ + isIndex?: Maybe; + /** + * The Item entity is owned by the Parser service. + * We only extend it in this service to make this service's schema valid. + * The key for this entity is the 'itemId' + */ + itemId: Scalars['String']['output']; + /** The detected language of the article */ + language?: Maybe; + /** Estimated time to listen to the article, in seconds */ + listenDuration?: Maybe; + /** + * Indicates if the url requires a login + * @deprecated Clients should not use this + */ + loginRequired?: Maybe; + /** The Marticle format of the article, used by clients for native article view. */ + marticle?: Maybe>; + /** The mime type of this item's web page */ + mimeType?: Maybe; + /** + * A normalized value of the givenUrl. + * It will look like a url but is not guaranteed to be a valid url, just a unique string that is used to eliminate common duplicates. + * Item's that share a normal_url should be considered the same item. For example https://getpocket.com and http://getpocket.com will be considered the same since they both normalize to http://getpocket.com + * This is technically the true identity of an item, since this is what the backend uses to tell if two items are the same. + * However, for the clients to use this, they would all have to ship an implementation of the normalization function that the backend has exactly. + * And even if it did that, some items, some of the earliest saves, use a legacy normalize function and the client would have no way to know when to use which normalizing function. + */ + normalUrl: Scalars['String']['output']; + /** + * If a the domainId is a subdomain this is the primary domain id + * @deprecated Use a domain as the identifier instead + */ + originDomainId?: Maybe; + /** The client preview/display logic for this url */ + preview?: Maybe; + /** A server generated unique reader slug for this item based on itemId */ + readerSlug: Scalars['String']['output']; + /** Recommend similar articles to show in the bottom of an article. */ + relatedAfterArticle: Array; + /** Recommend similar articles after saving. */ + relatedAfterCreate: Array; + /** The item id of the resolved_url */ + resolvedId?: Maybe; + /** + * The resolved url, but ran through the normalized function + * @deprecated Use the resolved url instead + */ + resolvedNormalUrl?: Maybe; + /** If the givenUrl redirects (once or many times), this is the final url. Otherwise, same as givenUrl */ + resolvedUrl?: Maybe; + /** + * The http response code of the given url + * @deprecated Clients should not use this + */ + responseCode?: Maybe; + /** Helper property to identify if the given item is in the user's list */ + savedItem?: Maybe; + /** + * Provides short url for the given_url in the format: https://pocket.co/. + * marked as beta because it's not ready yet for large client request. + */ + shortUrl?: Maybe; + /** If the url is an Article, the text in SSML format for speaking, i.e. Listen */ + ssml?: Maybe; + /** If the item has a syndicated counterpart the syndication information */ + syndicatedArticle?: Maybe; + /** + * Date this item was first parsed in Pocket + * @deprecated Clients should not use this + */ + timeFirstParsed?: Maybe; + /** How long it will take to read the article (TODO in what time unit? and by what calculation?) */ + timeToRead?: Maybe; + /** The title as determined by the parser. */ + title?: Maybe; + /** The page's / publisher's preferred thumbnail image */ + topImage?: Maybe; + /** + * The page's / publisher's preferred thumbnail image + * @deprecated use the topImage object + */ + topImageUrl?: Maybe; + /** + * Indicates if the parser used fallback methods + * @deprecated Clients should not use this + */ + usedFallback?: Maybe; + /** Array of videos within the item If the item is a video, this will likely just contain one video */ + videos?: Maybe>>; + /** Number of words in the article */ + wordCount?: Maybe; +}; + + +/** + * The heart of Pocket + * A url and meta data related to it. + */ +export type ItemRelatedAfterArticleArgs = { + count?: InputMaybe; +}; + + +/** + * The heart of Pocket + * A url and meta data related to it. + */ +export type ItemRelatedAfterCreateArgs = { + count?: InputMaybe; +}; + +/** Elasticsearch highlights */ +export type ItemHighlights = { + __typename?: 'ItemHighlights'; + full_text?: Maybe>>; + tags?: Maybe>>; + title?: Maybe>>; + url?: Maybe>>; +}; + +export type ItemNotFound = { + __typename?: 'ItemNotFound'; + message?: Maybe; +}; + +/** Union type for items that may or may not be processed */ +export type ItemResult = Item | PendingItem; + +export type ItemSummary = PocketMetadata & { + __typename?: 'ItemSummary'; + authors?: Maybe>; + datePublished?: Maybe; + domain?: Maybe; + excerpt?: Maybe; + id: Scalars['ID']['output']; + image?: Maybe; + item?: Maybe; + source: PocketMetadataSource; + title?: Maybe; + url: Scalars['Url']['output']; +}; + +/** A label used to mark and categorize an Entity (e.g. Collection). */ +export type Label = { + __typename?: 'Label'; + externalId: Scalars['ID']['output']; + name: Scalars['String']['output']; +}; + +/** Web link */ +export type Link = { + __typename?: 'Link'; + /** The link text displayed to the user. */ + text: Scalars['String']['output']; + /** The URL to send the user to when clicking on the link. */ + url: Scalars['Url']['output']; +}; + +export type ListElement = { + /** Row in a list. */ + content: Scalars['Markdown']['output']; + /** Zero-indexed level, for handling nested lists. */ + level: Scalars['Int']['output']; +}; + +/** The Connection type for ListItem */ +export type ListItemConnection = { + __typename?: 'ListItemConnection'; + /** A list of edges. */ + edges?: Maybe>; + /** Information to aid in pagination. */ + pageInfo: PageInfo; + /** Identifies the total count of SavedItems in the connection. */ + totalCount: Scalars['Int']['output']; +}; + +/** An Edge in a Connection */ +export type ListItemEdge = { + __typename?: 'ListItemEdge'; + /** A cursor for use in pagination. */ + cursor: Scalars['String']['output']; + /** The ListItem at the end of the edge. */ + node: ShareableListItem; +}; + +export type MarkdownImagePosition = { + __typename?: 'MarkdownImagePosition'; + index: Scalars['Int']['output']; + position: Scalars['Int']['output']; + /** Fallback is to use the images field in the Item entity */ + src?: Maybe; +}; + +/** Content of a blockquote */ +export type MarticleBlockquote = { + __typename?: 'MarticleBlockquote'; + /** Markdown text content. */ + content: Scalars['Markdown']['output']; +}; + +/** Content in a bulleted (unordered) list. */ +export type MarticleBulletedList = { + __typename?: 'MarticleBulletedList'; + rows: Array; +}; + +/** A pre formatted text in the HTML content. */ +export type MarticleCodeBlock = { + __typename?: 'MarticleCodeBlock'; + /** Assuming the codeblock was a programming language, this field is used to identify it. */ + language?: Maybe; + /** Content of a pre tag */ + text: Scalars['String']['output']; +}; + +export type MarticleComponent = Image | MarticleBlockquote | MarticleBulletedList | MarticleCodeBlock | MarticleDivider | MarticleHeading | MarticleNumberedList | MarticleTable | MarticleText | UnMarseable | Video; + +export type MarticleDivider = { + __typename?: 'MarticleDivider'; + /** Always '---'; provided for convenience if building a markdown string */ + content: Scalars['Markdown']['output']; +}; + +/** A heading in an article, with markdown formatting. */ +export type MarticleHeading = { + __typename?: 'MarticleHeading'; + /** Heading text, in markdown. */ + content: Scalars['Markdown']['output']; + /** Heading level. Restricted to values 1-6. */ + level: Scalars['Int']['output']; +}; + +/** Content in a bulleted (unordered) list. */ +export type MarticleNumberedList = { + __typename?: 'MarticleNumberedList'; + rows: Array; +}; + +/** Content in a table. */ +export type MarticleTable = { + __typename?: 'MarticleTable'; + /** Raw HTML representation of the table. */ + html: Scalars['String']['output']; +}; + +/** + * A section of the article's text content, in markdown. + * A subset of gfm is supported. See README.md for more information. + */ +export type MarticleText = { + __typename?: 'MarticleText'; + /** Markdown text content. Typically, a paragraph. */ + content: Scalars['Markdown']['output']; +}; + +/** Default Mutation Type */ +export type Mutation = { + __typename?: 'Mutation'; + /** + * Attach share context to a Pocket Share. If a context already exists + * on the Pocket Share, it will be overrwritten. Session ID via the `guid` + * field on the JWT is used to determine ownership of a share. + * That means users may only edit share links created in the same + * session (intended to be a post-share add, not something returned to + * later). It also lets us attribute ownership to anonymous/logged-out + * users. + * Null values in provided context will not overrwrite existing values + * if there are any, but but empty values will (e.g. empty string, empty array). + * Attempting to update a nonexistent share or a share that is not owned + * by the session user will return ShareNotFound. + */ + addShareContext?: Maybe; + /** Add a batch of items to an existing shareable list. */ + addToShareableList: ShareableList; + /** + * Make requests to create and delete highlights in a single batch. + * Mutation is atomic -- if there is a response, all operations were successful. + */ + batchWriteHighlights: BatchWriteHighlightsResult; + /** Remove all tags associated to a SavedItem (included for v3 proxy). */ + clearTags?: Maybe; + /** Add a batch of items to an existing shareable list. */ + createAndAddToShareableList?: Maybe; + /** Create new highlight annotation(s). Returns the data for the created Highlight object. */ + createHighlightByUrl: Highlight; + /** Create new highlight note. Returns the data for the created Highlight note. */ + createSavedItemHighlightNote?: Maybe; + /** Create new highlight annotation(s). Returns the data for the created Highlight object(s). */ + createSavedItemHighlights: Array; + /** + * Add tags to the savedItems + * Inputs a list of SavedItemTagsInput(ie. savedItemId and the list of tagName) + * Returns the list of `SavedItem` for which the tags were added + */ + createSavedItemTags: Array; + /** + * Create a Pocket Share for a provided target URL, optionally + * with additional share context. + */ + createShareLink?: Maybe; + /** + * Creates a Shareable List. Takes in an optional listItemData parameter to create a ShareableListItem + * along with a ShareableList. + */ + createShareableList?: Maybe; + /** Creates a Shareable List Item. */ + createShareableListItem?: Maybe; + /** + * Deletes a SavedItem from the users list. Returns ID of the + * deleted SavedItem + */ + deleteSavedItem: Scalars['ID']['output']; + /** Delete a highlight by its ID. */ + deleteSavedItemHighlight: Scalars['ID']['output']; + /** Delete a highlight note by the Highlight ID. */ + deleteSavedItemHighlightNote: Scalars['ID']['output']; + /** + * Delete one or more tags from one or more SavedItems. + * Note that if this operation results in a Tag having no associations + * to a SavedItem, the Tag object will be deleted. + */ + deleteSavedItemTags: Array; + /** Deletes a Shareable List. */ + deleteShareableList: ShareableList; + /** Deletes a Shareable List Item. HIDDEN Lists cannot have their items deleted. */ + deleteShareableListItem: ShareableListItem; + /** + * Deletes a Tag object. This is deletes the Tag and all SavedItem associations + * (removes the Tag from all SavedItems). Returns ID of the deleted Tag. + */ + deleteTag: Scalars['ID']['output']; + /** + * Delete a tag entity identified by name (rather than ID), to support v3 proxy. + * Disassociates this tag from all SavedItems. + */ + deleteTagByName?: Maybe; + /** Deletes user information and their pocket data for the given pocket userId. Returns pocket userId. */ + deleteUser: Scalars['ID']['output']; + /** + * Deletes user information and their pocket data for the given firefox account ID. + * Returns firefox account ID sent as the query parameter with the request. + */ + deleteUserByFxaId: Scalars['ID']['output']; + /** + * Expires a user's web session tokens by firefox account ID. + * Called by fxa-webhook proxy. Need to supply a reason why to expire user web session. + * Returns the user ID. + */ + expireUserWebSessionByFxaId: Scalars['ID']['output']; + /** + * temporary mutation for apple user migration. + * called by fxa-webhook proxy to update the fxaId and email of the user. + * Returns the pocket userId on success + * Note: requires `transfersub` to be set in the header. + */ + migrateAppleUser: Scalars['ID']['output']; + /** + * 'Re-add' a SavedItem by id. Unarchives and undeletes the SavedItem + * as applicable, and refreshes the "createdAt" timestamp. + */ + reAddById?: Maybe; + /** Refresh an Item's article content. */ + refreshItemArticle: Item; + /** + * Removes specific tags associated to a SavedItem, + * referenced by name, to support v3 proxy. + */ + removeTagsByName?: Maybe; + /** Rename a tag identified by name (rather than ID), to support v3 proxy. */ + renameTagByName?: Maybe; + /** + * Replaces the old tags associated with the savedItem to the new tag list + * given in the entry + * To remove all Tags from a SavedItem, use `updateSavedItemRemoveTags`. + * Note: if there is a new tag name in the SavedItemTagsInput, then the tag record will be created + * Inputs a list of SavedItemTagsInput(ie. savedItemId and list of tag names) + * Returns the SavedItem for which the tags have been modified. + * @deprecated use saveBatchUpdateTags + */ + replaceSavedItemTags: Array; + /** Replace specific tags associated to a SavedItem, to support v3 proxy. */ + replaceTags?: Maybe; + /** Archives PocketSaves */ + saveArchive?: Maybe; + /** + * Batch update the Tags associated with a Save + * by adding new tags and deleting existing tags. + * Maximum of 150 operations (adds/deletes) per request. + */ + saveBatchUpdateTags: SaveWriteMutationPayload; + /** + * Favorites PocketSaves + * Accepts a list of PocketSave Ids that we want to favorite. + */ + saveFavorite?: Maybe; + /** + * Save search to potentially appear in recentSearches response. + * Requires premium account (otherwise will send ForbiddenError). + */ + saveSearch?: Maybe; + /** Unarchives PocketSaves */ + saveUnArchive?: Maybe; + /** + * Unfavorites PocketSaves + * Accepts a list of PocketSave Ids that we want to unfavorite. + */ + saveUnFavorite?: Maybe; + /** + * Creates a new Save; if the Save already exists (either in List or Archive), "re-add" it. + * "Re-adding" unarchives and undeletes the Save as applicable, and refreshes the "createdAt" + * timestamp. + */ + saveUpsert: SaveWriteMutationPayload; + /** Archive a SavedItem (identified by URL) */ + savedItemArchive?: Maybe; + /** 'Soft-delete' a SavedItem (identified by URL) */ + savedItemDelete?: Maybe; + /** Favorite a SavedItem (identified by URL) */ + savedItemFavorite?: Maybe; + /** Associate Tag(s) with a Save */ + savedItemTag?: Maybe; + /** Unarchive a SavedItem (identified by URL) */ + savedItemUnArchive?: Maybe; + /** + * Undo the 'soft-delete' operation on a SavedItem (identified by URL). + * Does not restore tags. Does not restore SavedItems that have been + * 'hard-deleted' (record removed from the database entirely). + */ + savedItemUnDelete?: Maybe; + /** 'Unfavorite' a 'favorite' SavedItem (identified by URL) */ + savedItemUnFavorite?: Maybe; + /** + * Update the title display of a Saved Item, retrieved by URL. + * This is user-save specific (does not update the metadata saved by the parser) + * Clients should ensure the input fits in the utf8mb3 character set (BMP only, + * which means no emoji) to avoid being rejected by the database. + * In the future this will be more permissive. + */ + savedItemUpdateTitle?: Maybe; + /** + * Update an existing highlight annotation, by its ID. + * If the given highlight ID does not exist, will return error data + * and the highlight will not be created. + */ + updateHighlight: Highlight; + /** Archives a SavedItem */ + updateSavedItemArchive: SavedItem; + /** Favorites a SavedItem */ + updateSavedItemFavorite: SavedItem; + /** + * Update an existing highlight annotation, by its ID. + * If the given highlight ID does not exist, will return error data + * and the highlight will not be created. + * Note that if an ID is passed to the optional ID field in CreateHighlightInput, + * it will be ignored, as this mutation does not allow updating the ID. + * @deprecated use updateHighlight + */ + updateSavedItemHighlight: Highlight; + /** + * Update an existing highlight note, by its ID. + * If the given highlight ID does not exist, will return error data + * and the note will not be updated. + */ + updateSavedItemHighlightNote?: Maybe; + /** + * Removes all Tag associations from a SavedItem. Returns the + * SavedItem that had its Tag associations cleared. + * Note that if this operation results in a Tag having no associations + * to a SavedItem, the Tag object will be deleted. + * @deprecated use saveBatchUpdateTags + */ + updateSavedItemRemoveTags: SavedItem; + /** + * Set the Tags that are associated with a SavedItem. + * Will replace any existing Tag associations on the SavedItem. + * To remove all Tags from a SavedItem, use `updateSavedItemRemoveTags`. + * @deprecated use saveBatchUpdateTags + */ + updateSavedItemTags: SavedItem; + /** + * Update the title display of a Saved Item, retrieved by ID. + * This is user-save specific (does not update the metadata saved by the parser). + * Clients should ensure the input fits in the utf8mb3 character set (BMP only, + * which means no emoji) to avoid being rejected by the database. + * In the future this will be more permissive. + */ + updateSavedItemTitle?: Maybe; + /** Unarchives a SavedItem */ + updateSavedItemUnArchive: SavedItem; + /** Undo the delete operation for a SavedItem */ + updateSavedItemUnDelete: SavedItem; + /** Unfavorites a SavedItem */ + updateSavedItemUnFavorite: SavedItem; + /** Updates a Shareable List. Cannot make a list public. */ + updateShareableList: ShareableList; + /** Updates a single Shareable List Item. */ + updateShareableListItem: ShareableListItem; + /** Updates an array of Shareable List Items (sortOrder). */ + updateShareableListItems: Array; + /** + * Updates a Tag (renames the tag), and returns the updated Tag. + * If a Tag with the updated name already exists in the database, will + * associate that Tag to all relevant SavedItems rather than creating + * a duplicate Tag object. + */ + updateTag: Tag; + /** + * update the email of the user for the given pocket userId. Request is made by + * an authenticated user, and the userID is inferred from the request headers `userid`. + */ + updateUserEmail: User; + /** + * update the email of the user for the given firefox account ID. Request + * is made by a backend service. The `userid` in the headers should match + * the FxA ID or else an authentication error will be thrown. + */ + updateUserEmailByFxaId: User; + /** Updates user preferences for content recommendations across Pocket. */ + updateUserRecommendationPreferences: UserRecommendationPreferences; + /** + * Updates a SavedItem, undeletes and unarchives it, bringing it to the top of the user's list, if it exists + * and creates it if it doesn't. + */ + upsertSavedItem: SavedItem; +}; + + +/** Default Mutation Type */ +export type MutationAddShareContextArgs = { + context: ShareContextInput; + slug: Scalars['ID']['input']; +}; + + +/** Default Mutation Type */ +export type MutationAddToShareableListArgs = { + items: Array; + listExternalId: Scalars['ID']['input']; +}; + + +/** Default Mutation Type */ +export type MutationBatchWriteHighlightsArgs = { + input?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationClearTagsArgs = { + savedItem: SavedItemRef; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationCreateAndAddToShareableListArgs = { + itemData: Array; + listData: CreateShareableListInput; +}; + + +/** Default Mutation Type */ +export type MutationCreateHighlightByUrlArgs = { + input: CreateHighlightByUrlInput; +}; + + +/** Default Mutation Type */ +export type MutationCreateSavedItemHighlightNoteArgs = { + id: Scalars['ID']['input']; + input: Scalars['String']['input']; +}; + + +/** Default Mutation Type */ +export type MutationCreateSavedItemHighlightsArgs = { + input: Array; +}; + + +/** Default Mutation Type */ +export type MutationCreateSavedItemTagsArgs = { + input: Array; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationCreateShareLinkArgs = { + context?: InputMaybe; + target: Scalars['ValidUrl']['input']; +}; + + +/** Default Mutation Type */ +export type MutationCreateShareableListArgs = { + listData: CreateShareableListInput; + listItemData?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationCreateShareableListItemArgs = { + data: CreateShareableListItemInput; +}; + + +/** Default Mutation Type */ +export type MutationDeleteSavedItemArgs = { + id: Scalars['ID']['input']; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationDeleteSavedItemHighlightArgs = { + id: Scalars['ID']['input']; +}; + + +/** Default Mutation Type */ +export type MutationDeleteSavedItemHighlightNoteArgs = { + id: Scalars['ID']['input']; +}; + + +/** Default Mutation Type */ +export type MutationDeleteSavedItemTagsArgs = { + input: Array; +}; + + +/** Default Mutation Type */ +export type MutationDeleteShareableListArgs = { + externalId: Scalars['ID']['input']; +}; + + +/** Default Mutation Type */ +export type MutationDeleteShareableListItemArgs = { + externalId: Scalars['ID']['input']; +}; + + +/** Default Mutation Type */ +export type MutationDeleteTagArgs = { + id: Scalars['ID']['input']; +}; + + +/** Default Mutation Type */ +export type MutationDeleteTagByNameArgs = { + tagName: Scalars['String']['input']; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationDeleteUserByFxaIdArgs = { + id: Scalars['ID']['input']; +}; + + +/** Default Mutation Type */ +export type MutationExpireUserWebSessionByFxaIdArgs = { + id: Scalars['ID']['input']; + reason: ExpireUserWebSessionReason; +}; + + +/** Default Mutation Type */ +export type MutationMigrateAppleUserArgs = { + email: Scalars['String']['input']; + fxaId: Scalars['ID']['input']; +}; + + +/** Default Mutation Type */ +export type MutationReAddByIdArgs = { + id: Scalars['ID']['input']; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationRefreshItemArticleArgs = { + url: Scalars['String']['input']; +}; + + +/** Default Mutation Type */ +export type MutationRemoveTagsByNameArgs = { + savedItem: SavedItemRef; + tagNames: Array; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationRenameTagByNameArgs = { + newName: Scalars['String']['input']; + oldName: Scalars['String']['input']; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationReplaceSavedItemTagsArgs = { + input: Array; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationReplaceTagsArgs = { + savedItem: SavedItemRef; + tagNames: Array; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationSaveArchiveArgs = { + id: Array; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSaveBatchUpdateTagsArgs = { + input: Array; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSaveFavoriteArgs = { + id: Array; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSaveSearchArgs = { + search: RecentSearchInput; +}; + + +/** Default Mutation Type */ +export type MutationSaveUnArchiveArgs = { + id: Array; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSaveUnFavoriteArgs = { + id: Array; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSaveUpsertArgs = { + input: Array; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSavedItemArchiveArgs = { + givenUrl: Scalars['Url']['input']; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSavedItemDeleteArgs = { + givenUrl: Scalars['Url']['input']; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSavedItemFavoriteArgs = { + givenUrl: Scalars['Url']['input']; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSavedItemTagArgs = { + input: SavedItemTagInput; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSavedItemUnArchiveArgs = { + givenUrl: Scalars['Url']['input']; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSavedItemUnDeleteArgs = { + givenUrl: Scalars['Url']['input']; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSavedItemUnFavoriteArgs = { + givenUrl: Scalars['Url']['input']; + timestamp: Scalars['ISOString']['input']; +}; + + +/** Default Mutation Type */ +export type MutationSavedItemUpdateTitleArgs = { + givenUrl: Scalars['Url']['input']; + timestamp: Scalars['ISOString']['input']; + title: Scalars['String']['input']; +}; + + +/** Default Mutation Type */ +export type MutationUpdateHighlightArgs = { + id: Scalars['ID']['input']; + input: UpdateHighlightInput; +}; + + +/** Default Mutation Type */ +export type MutationUpdateSavedItemArchiveArgs = { + id: Scalars['ID']['input']; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationUpdateSavedItemFavoriteArgs = { + id: Scalars['ID']['input']; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationUpdateSavedItemHighlightArgs = { + id: Scalars['ID']['input']; + input: CreateHighlightInput; +}; + + +/** Default Mutation Type */ +export type MutationUpdateSavedItemHighlightNoteArgs = { + id: Scalars['ID']['input']; + input: Scalars['String']['input']; +}; + + +/** Default Mutation Type */ +export type MutationUpdateSavedItemRemoveTagsArgs = { + savedItemId?: InputMaybe; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationUpdateSavedItemTagsArgs = { + input: SavedItemTagUpdateInput; +}; + + +/** Default Mutation Type */ +export type MutationUpdateSavedItemTitleArgs = { + id: Scalars['ID']['input']; + timestamp: Scalars['ISOString']['input']; + title: Scalars['String']['input']; +}; + + +/** Default Mutation Type */ +export type MutationUpdateSavedItemUnArchiveArgs = { + id: Scalars['ID']['input']; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationUpdateSavedItemUnDeleteArgs = { + id: Scalars['ID']['input']; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationUpdateSavedItemUnFavoriteArgs = { + id: Scalars['ID']['input']; + timestamp?: InputMaybe; +}; + + +/** Default Mutation Type */ +export type MutationUpdateShareableListArgs = { + data: UpdateShareableListInput; +}; + + +/** Default Mutation Type */ +export type MutationUpdateShareableListItemArgs = { + data: UpdateShareableListItemInput; +}; + + +/** Default Mutation Type */ +export type MutationUpdateShareableListItemsArgs = { + data: Array; +}; + + +/** Default Mutation Type */ +export type MutationUpdateTagArgs = { + input: TagUpdateInput; +}; + + +/** Default Mutation Type */ +export type MutationUpdateUserEmailArgs = { + email: Scalars['String']['input']; +}; + + +/** Default Mutation Type */ +export type MutationUpdateUserEmailByFxaIdArgs = { + email: Scalars['String']['input']; + id: Scalars['ID']['input']; +}; + + +/** Default Mutation Type */ +export type MutationUpdateUserRecommendationPreferencesArgs = { + input: UpdateUserRecommendationPreferencesInput; +}; + + +/** Default Mutation Type */ +export type MutationUpsertSavedItemArgs = { + input: SavedItemUpsertInput; +}; + +export type NotFound = BaseError & { + __typename?: 'NotFound'; + key?: Maybe; + message: Scalars['String']['output']; + path: Scalars['String']['output']; + value?: Maybe; +}; + +export type NumberedListElement = ListElement & { + __typename?: 'NumberedListElement'; + /** Row in a list */ + content: Scalars['Markdown']['output']; + /** Numeric index. If a nested item, the index is zero-indexed from the first child. */ + index: Scalars['Int']['output']; + /** Zero-indexed level, for handling nested lists. */ + level: Scalars['Int']['output']; +}; + +export type OEmbed = PocketMetadata & { + __typename?: 'OEmbed'; + authors?: Maybe>; + datePublished?: Maybe; + domain?: Maybe; + excerpt?: Maybe; + htmlEmbed?: Maybe; + id: Scalars['ID']['output']; + image?: Maybe; + item?: Maybe; + source: PocketMetadataSource; + title?: Maybe; + type?: Maybe; + url: Scalars['Url']['output']; +}; + +export enum OEmbedType { + Link = 'LINK', + Photo = 'PHOTO', + Rich = 'RICH', + Video = 'VIDEO' +} + +/** Input for offset-pagination (internal backend use only). */ +export type OffsetPaginationInput = { + /** Defaults to 30 */ + limit?: InputMaybe; + /** Defaults to 0 */ + offset?: InputMaybe; +}; + +/** Information about pagination in a connection. */ +export type PageInfo = { + __typename?: 'PageInfo'; + /** When paginating forwards, the cursor to continue. */ + endCursor?: Maybe; + /** When paginating forwards, are there more items? */ + hasNextPage: Scalars['Boolean']['output']; + /** When paginating backwards, are there more items? */ + hasPreviousPage: Scalars['Boolean']['output']; + /** When paginating backwards, the cursor to continue. */ + startCursor?: Maybe; +}; + +/** + * Represents a type of page for /explore + * Deprecated for SlateLineups + */ +export enum PageType { + EditorialCollection = 'editorial_collection', + TopicPage = 'topic_page' +} + +export type Pagination = { + __typename?: 'Pagination'; + currentPage: Scalars['Int']['output']; + perPage: Scalars['Int']['output']; + totalPages: Scalars['Int']['output']; + totalResults: Scalars['Int']['output']; +}; + +/** + * Pagination request. To determine which edges to return, the connection + * evaluates the `before` and `after` cursors (if given) to filter the + * edges, then evaluates `first`/`last` to slice the edges (only include a + * value for either `first` or `last`, not both). If all fields are null, + * by default will return a page with the first 30 elements. + */ +export type PaginationInput = { + /** + * Returns the elements in the list that come after the specified cursor. + * The specified cursor is not included in the result. + */ + after?: InputMaybe; + /** + * Returns the elements in the list that come before the specified cursor. + * The specified cursor is not included in the result. + */ + before?: InputMaybe; + /** + * Returns the first _n_ elements from the list. Must be a non-negative integer. + * If `first` contains a value, `last` should be null/omitted in the input. + */ + first?: InputMaybe; + /** + * Returns the last _n_ elements from the list. Must be a non-negative integer. + * If `last` contains a value, `first` should be null/omitted in the input. + */ + last?: InputMaybe; +}; + +export type PendingItem = { + __typename?: 'PendingItem'; + /** + * URL of the item that the user gave for the SavedItem + * that is pending processing by parser + */ + itemId: Scalars['String']['output']; + status?: Maybe; + url: Scalars['Url']['output']; +}; + +export enum PendingItemStatus { + Resolved = 'RESOLVED', + Unresolved = 'UNRESOLVED' +} + +export type PocketMetadata = { + authors?: Maybe>; + datePublished?: Maybe; + domain?: Maybe; + excerpt?: Maybe; + id: Scalars['ID']['output']; + image?: Maybe; + item?: Maybe; + source: PocketMetadataSource; + title?: Maybe; + url: Scalars['Url']['output']; +}; + +export enum PocketMetadataSource { + Oembed = 'OEMBED', + Opengraph = 'OPENGRAPH', + PocketParser = 'POCKET_PARSER' +} + +/** + * New Pocket Save Type, replacing SavedItem. + * + * Represents a Pocket Item that a user has saved to their list. + * (Said otherways, indicates a saved url to a users list and associated user specific information.) + */ +export type PocketSave = { + __typename?: 'PocketSave'; + /** Indicates if the PocketSave is archived. */ + archived: Scalars['Boolean']['output']; + /** Timestamp that the PocketSave became archived, null if not archived. */ + archivedAt?: Maybe; + /** Unix timestamp of when the PocketSave was created. */ + createdAt: Scalars['ISOString']['output']; + /** Unix timestamp of when the entity was deleted. */ + deletedAt?: Maybe; + /** Indicates if the PocketSave is favorited. */ + favorite: Scalars['Boolean']['output']; + /** Timestamp that the PocketSave became favorited, null if not favorited. */ + favoritedAt?: Maybe; + /** The url the user gave (as opposed to normalized URLs). */ + givenUrl: Scalars['String']['output']; + /** Surrogate primary key. */ + id: Scalars['ID']['output']; + /** + * Link to the underlying Pocket Item for the URL. + * Temporary until resource field is added. Will hopefully + * make it easier for clients to adopt. + * @deprecated use resource + */ + item: ItemResult; + /** The status of this PocketSave; Marked for review for possible removal. */ + status?: Maybe; + /** The Suggested Tags associated with this PocketSave, if the user is not premium or there are none, this will be empty. */ + suggestedTags?: Maybe>; + /** The Tags associated with this PocketSave. */ + tags?: Maybe>; + /** The title of the Resource; defaults to the URL. */ + title: Scalars['String']['output']; + /** Unix timestamp of when the PocketSave was last updated, if any property on the PocketSave is modified this timestamp is set to the modified time. */ + updatedAt?: Maybe; +}; + +/** Enum to specify the PocketSave Status (mapped to integers in data store). */ +export enum PocketSaveStatus { + Archived = 'ARCHIVED', + Deleted = 'DELETED', + Hidden = 'HIDDEN', + Unread = 'UNREAD' +} + +export type PocketShare = { + __typename?: 'PocketShare'; + context?: Maybe; + createdAt: Scalars['ISOString']['output']; + preview?: Maybe; + shareUrl: Scalars['ValidUrl']['output']; + slug: Scalars['ID']['output']; + targetUrl: Scalars['ValidUrl']['output']; +}; + +export enum PremiumFeature { + /** Feature where you get an ad-free experience */ + AdFree = 'AD_FREE', + /** Feature where you can highlight articles */ + Annotations = 'ANNOTATIONS', + /** Feature where pocket saves permanent copies of all your saves */ + PermanentLibrary = 'PERMANENT_LIBRARY', + /** Feature where pocket's search is enhanced */ + PremiumSearch = 'PREMIUM_SEARCH', + /** Feature where pocket suggests tags */ + SuggestedTags = 'SUGGESTED_TAGS' +} + +export enum PremiumStatus { + /** + * User has premium and its active + * NOTE: User will still show as active if they turn off auto-renew or have otherwise canceled but the expiration date hasn't hit yet + */ + Active = 'ACTIVE', + /** User has had premium, but it is expired */ + Expired = 'EXPIRED', + /** User has never had premium */ + Never = 'NEVER' +} + +/** The publisher that the curation team set for the syndicated article */ +export type Publisher = { + __typename?: 'Publisher'; + /** Whether or not to show the article appeared on domain */ + appearedOnDomain: Scalars['Boolean']['output']; + /** The article call to action to show if selected */ + articleCta?: Maybe; + /** Whether or not to attribute the publisher to the article */ + attributeCanonicalToPublisher: Scalars['Boolean']['output']; + /** Square logo to use for the publisher */ + logo?: Maybe; + /** Wide logo to use for the publisher */ + logoWide?: Maybe; + /** Black wide based logo to use for the publisher */ + logoWideBlack?: Maybe; + /** Name of the publisher of the article */ + name?: Maybe; + /** The name to show to the article in recommendations */ + recommendationName?: Maybe; + /** Whether or not to show an article call to action */ + showArticleCta: Scalars['Boolean']['output']; + /** Whether or not to show the authors of the article */ + showAuthors: Scalars['Boolean']['output']; + /** Whether or not to show publisher recomendations */ + showPublisherRecommendations?: Maybe; + /** Url of the publisher */ + url?: Maybe; +}; + +/** + * The call to action to show on a SyndicatedArticle for a specific publisher + * TODO: rename to SyndicatedPublisherArticle and move to schema-shared.graphql + * (requires client changes) + */ +export type PublisherArticleCta = { + __typename?: 'PublisherArticleCta'; + /** The lead in text to show */ + leadIn?: Maybe; + /** The text to show */ + text?: Maybe; + /** The url to link to */ + url?: Maybe; +}; + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type Query = { + __typename?: 'Query'; + /** Retrieves a Collection by the given slug. The Collection must be published. */ + collectionBySlug?: Maybe; + /** + * Retrieves a Collection by the given slug. The Collection must be published. + * @deprecated Use collectionBySlug instead + */ + getCollectionBySlug?: Maybe; + /** Retrieves a paged set of published Collections. */ + getCollections: CollectionsResult; + /** + * Look up Item info by a url. + * @deprecated Use itemByUrl instead + */ + getItemByUrl?: Maybe; + /** + * Request a specific `Slate` by id + * @deprecated Please use queries specific to the surface ex. setMomentSlate. If a named query for your surface does not yet exit please reach out to the Data Products team and they will happily provide you with a named query. + */ + getSlate: Slate; + /** + * Request a specific `SlateLineup` by id + * @deprecated Please use queries specific to the surface ex. setMomentSlate. If a named query for your surface does not yet exit please reach out to the Data Products team and they will happily provide you with a named query. + */ + getSlateLineup: SlateLineup; + /** + * Look up SyndicatedArticle by a slug. + * @deprecated use syndicatedArticleBySlug instead + */ + getSyndicatedArticleBySlug?: Maybe; + /** + * Returns a list of unleash toggles that are enabled for a given context. + * + * For more details on this check out https://docs.google.com/document/d/1dYS81h-DbQEWNLtK-ajLTylw454S32llPXUyBmDd5mU/edit# and https://getpocket.atlassian.net/wiki/spaces/PE/pages/1191444582/Feature+Flags+-+Unleash + * + * ~ For each of the enabled unleash toggles (via https://featureflags.readitlater.com/api/client/features or an unleash sdk) + * ~ Check if the toggle is assigned/enabled for the provided {.context} + * ~ Add an {UnleashAssignment} representing it to this list + * ~ If no toggles are found, return an empty list + * @deprecated use unleashAssignments instead + */ + getUnleashAssignments?: Maybe; + /** Get ranked corpus slates and recommendations to deliver a unified Home experience. */ + homeSlateLineup: CorpusSlateLineup; + /** Look up Item info by a url. */ + itemByUrl?: Maybe; + /** + * List all available topics that we have recommendations for. + * @deprecated Use `getSlateLineup` with a specific SlateLineup instead. + */ + listTopics: Array; + /** Get a slate of ranked recommendations for the Firefox New Tab. Currently supports the Italy, France, and Spain markets. */ + newTabSlate: CorpusSlate; + /** + * Resolve Reader View links which might point to SavedItems that do not + * exist, aren't in the Pocket User's list, or are requested by a logged-out + * user (or user without a Pocket Account). + * Fetches data which clients can use to generate an appropriate fallback view + * that allows users to preview the content and access the original source site. + */ + readerSlug: ReaderViewResult; + /** List all topics that the user can express a preference for. */ + recommendationPreferenceTopics: Array; + scheduledSurface: ScheduledSurface; + /** Search Pocket's corpus of recommendations and collections. */ + searchCorpus?: Maybe; + /** + * Resolve data for a Shared link, or return a Not Found + * message if the share does not exist. + */ + shareSlug?: Maybe; + /** + * Looks up and returns a Shareable List with a given external ID for a given user. + * (the user ID will be coming through with the headers) + */ + shareableList?: Maybe; + /** Returns a publicly-shared Shareable List. Note: this query does not require user authentication. */ + shareableListPublic?: Maybe; + /** + * Looks up and returns an array of Shareable Lists for a given user ID for a given user. + * (the user ID will be coming through with the headers) + */ + shareableLists: Array; + /** Determines if the userid passed in the headers has access to the pilot program. */ + shareableListsPilotUser: Scalars['Boolean']['output']; + /** This is a future improvement, not needed now. */ + surface: Surface; + /** Look up the SyndicatedArticle by a slug */ + syndicatedArticleBySlug?: Maybe; + /** + * Returns a list of unleash toggles that are enabled for a given context. + * + * For more details on this check out https://docs.google.com/document/d/1dYS81h-DbQEWNLtK-ajLTylw454S32llPXUyBmDd5mU/edit# and https://getpocket.atlassian.net/wiki/spaces/PE/pages/1191444582/Feature+Flags+-+Unleash + * + * ~ For each of the enabled unleash toggles (via https://featureflags.readitlater.com/api/client/features or an unleash sdk) + * ~ Check if the toggle is assigned/enabled for the provided {.context} + * ~ Add an {UnleashAssignment} representing it to this list + * ~ If no toggles are found, return an empty list + */ + unleashAssignments?: Maybe; + /** Get a user entity for an authenticated client */ + user?: Maybe; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryCollectionBySlugArgs = { + slug: Scalars['String']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryGetCollectionBySlugArgs = { + slug: Scalars['String']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryGetCollectionsArgs = { + filters?: InputMaybe; + page?: InputMaybe; + perPage?: InputMaybe; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryGetItemByUrlArgs = { + url: Scalars['String']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryGetSlateArgs = { + recommendationCount?: InputMaybe; + slateId: Scalars['String']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryGetSlateLineupArgs = { + recommendationCount?: InputMaybe; + slateCount?: InputMaybe; + slateLineupId: Scalars['String']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryGetSyndicatedArticleBySlugArgs = { + slug: Scalars['String']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryGetUnleashAssignmentsArgs = { + context: UnleashContext; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryHomeSlateLineupArgs = { + locale?: Scalars['String']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryItemByUrlArgs = { + url: Scalars['String']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryNewTabSlateArgs = { + enableRankingByRegion?: InputMaybe; + locale: Scalars['String']['input']; + region?: InputMaybe; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryReaderSlugArgs = { + slug: Scalars['ID']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryScheduledSurfaceArgs = { + id: Scalars['ID']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QuerySearchCorpusArgs = { + filter: CorpusSearchFilters; + pagination?: InputMaybe; + search: CorpusSearchQueryString; + sort?: InputMaybe; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryShareSlugArgs = { + slug: Scalars['ID']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryShareableListArgs = { + externalId: Scalars['ID']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryShareableListPublicArgs = { + externalId: Scalars['ID']['input']; + slug: Scalars['String']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QuerySurfaceArgs = { + id: Scalars['ID']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QuerySyndicatedArticleBySlugArgs = { + slug: Scalars['String']['input']; +}; + + +/** + * Default root level query type. All authorization checks are done in these queries. + * TODO: These belong in a seperate User Service that provides a User object (the user settings will probably exist there too) + */ +export type QueryUnleashAssignmentsArgs = { + context: UnleashContext; +}; + +/** + * Metadata of an Item in Pocket for preview purposes, + * or an ItemNotFound result if the record does not exist. + */ +export type ReaderFallback = ItemNotFound | ReaderInterstitial; + +/** + * Card preview data for Items resolved from reader view + * (getpocket.com/read/) links. + * + * Should be used to create a view if Reader Mode cannot + * be rendered (e.g. the link is visited by an anonymous + * Pocket user, or a Pocket User that does not have the + * underlying Item in their Saves). Due to legal obligations + * we can only display Reader Mode for SavedItems. + */ +export type ReaderInterstitial = { + __typename?: 'ReaderInterstitial'; + itemCard?: Maybe; +}; + +/** Result for resolving a getpocket.com/read/ link. */ +export type ReaderViewResult = { + __typename?: 'ReaderViewResult'; + fallbackPage?: Maybe; + /** + * The SavedItem referenced by this reader view slug, if it + * is in the Pocket User's list. + */ + savedItem?: Maybe; + slug: Scalars['ID']['output']; +}; + +export type RecItUserProfile = { + userModels: Array; +}; + +export type RecentSearch = { + __typename?: 'RecentSearch'; + context?: Maybe; + sortId: Scalars['Int']['output']; + term: Scalars['String']['output']; +}; + +export type RecentSearchContext = { + __typename?: 'RecentSearchContext'; + key?: Maybe; + value?: Maybe; +}; + +export type RecentSearchInput = { + /** The term that was used for search */ + term: Scalars['String']['input']; + /** + * Optional, the time the search was performed. + * Defaults to current server time at time of request. + */ + timestamp?: InputMaybe; +}; + +/** Represents a Recommendation from Pocket */ +export type Recommendation = { + __typename?: 'Recommendation'; + curatedInfo?: Maybe; + /** The feed id from mysql that this item was curated from (if it was curated) */ + feedId?: Maybe; + /** + * A generated id from the Data and Learning team that represents the Recommendation - Deprecated + * @deprecated Use `id` + */ + feedItemId?: Maybe; + /** A generated id from the Data and Learning team that represents the Recommendation */ + id: Scalars['ID']['output']; + /** + * The Recommendation entity is owned by the Recommendation API service. + * We extend it in this service to add an extra field ('curationInfo') to the Recommendation entity. + * The key for this entity is the 'itemId' found within the Item entity which is owned by the Parser service. + */ + item: Item; + /** + * The ID of the item this recommendation represents + * TODO: Use apollo federation to turn this into an Item type. + */ + itemId: Scalars['ID']['output']; + /** The publisher of the item */ + publisher?: Maybe; + /** The source of the recommendation */ + recSrc: Scalars['String']['output']; +}; + +export type RecommendationReason = { + __typename?: 'RecommendationReason'; + /** A succinct name for the recommendation reason that can be displayed to the user. */ + name: Scalars['String']['output']; + /** The type of reason for why the recommendation is made. */ + type: RecommendationReasonType; +}; + +/** Reasons why recommendations are made. Focuses on client needs and is not exhaustive. */ +export enum RecommendationReasonType { + /** Recommendations are sourced from the Pocket Hits newsletter. */ + PocketHits = 'POCKET_HITS', + /** Recommendations that match the user's topic preferences are ranked higher. */ + PreferredTopics = 'PREFERRED_TOPICS' +} + +/** Interface that all state based entities must implement */ +export type RemoteEntity = { + /** Unix timestamp of when the entity was created */ + _createdAt?: Maybe; + /** Unix timestamp of when the entity was deleted, 30 days after this date this entity will be HARD deleted from the database and no longer exist */ + _deletedAt?: Maybe; + /** Unix timestamp of when the entity was last updated, if any property on the entity is modified this timestamp is set to the modified time */ + _updatedAt?: Maybe; + /** Version of the entity, this will increment with each modification of the entity's field */ + _version?: Maybe; + /** + * For tags entity, id denotes the unique tag Id. + * For savedItems, id denotes the itemId. + * Along with the userId provided in the header, we will use id to fetch savedItems/tags for the user. + */ + id: Scalars['ID']['output']; +}; + +/** Union type for saveById - retrieving either PocketSaves or NotFound errors */ +export type SaveByIdResult = NotFound | PocketSave; + +/** Payload for mutations that delete Saves */ +export type SaveDeleteMutationPayload = { + __typename?: 'SaveDeleteMutationPayload'; + /** Any errors associated with the mutation. Empty if the mutation was succesful. */ + errors: Array; + success: Scalars['Boolean']['output']; +}; + +/** + * Elasticsearch highlights. + * Highlighted snippets from the following fields in the search results + * so clients can show users where the query matches are. + * Each field, if available, contains an array of html text snippets + * that contain a match to the search term. + * The matching text is wrapped in `` tags, e.g. ["Hiss at vacuum cleaner if it fits i sits"] + */ +export type SaveItemSearchHighlights = { + __typename?: 'SaveItemSearchHighlights'; + fullText?: Maybe>>; + tags?: Maybe>>; + title?: Maybe>>; + url?: Maybe>>; +}; + +/** All types in this union should implement BaseError, for client fallback */ +export type SaveMutationError = NotFound | SyncConflict; + +export type SaveUpdateTagsInput = { + /** + * Tags to add, by name text; if a Tag + * with the given name does not exist, + * one will be created. + */ + addTagNames: Array; + /** Tags to remove, by ID */ + removeTagIds: Array; + saveId: Scalars['ID']['input']; +}; + +/** Input field for upserting a Save. Used by saveUpsert mutation */ +export type SaveUpsertInput = { + /** Optional, create/update the SavedItem as a favorited item */ + isFavorite?: InputMaybe; + /** Optional, title of the SavedItem */ + title?: InputMaybe; + /** + * The url to create/update the SavedItem with. (the url to save to the list) + * Must be at least a 4 character string which is the shortest url + */ + url: Scalars['String']['input']; +}; + +/** Payload for mutations that create or update Saves */ +export type SaveWriteMutationPayload = { + __typename?: 'SaveWriteMutationPayload'; + /** Any errors associated with the mutation. Empty if the mutation was succesful. */ + errors: Array; + /** The mutated Save objects; empty if the mutation did not succeed. */ + save: Array; +}; + +/** + * Represents a Pocket Item that a user has saved to their list. + * (Said otherways, indicates a saved url to a users list and associated user specific information.) + */ +export type SavedItem = RemoteEntity & { + __typename?: 'SavedItem'; + /** Unix timestamp of when the entity was created */ + _createdAt: Scalars['Int']['output']; + /** Unix timestamp of when the entity was deleted, 30 days after this date this entity will be HARD deleted from the database and no longer exist */ + _deletedAt?: Maybe; + /** Unix timestamp of when the entity was last updated, if any property on the entity is modified this timestamp is set to the modified time */ + _updatedAt?: Maybe; + /** Version of the entity, this will increment with each modification of the entity's field */ + _version?: Maybe; + /** Annotations associated to this SavedItem */ + annotations?: Maybe; + /** Timestamp that the SavedItem became archied, null if not archived */ + archivedAt?: Maybe; + /** If the item is in corpus allow the saved item to reference it. Exposing curated info for consistent UX */ + corpusItem?: Maybe; + /** Timestamp that the SavedItem became favorited, null if not favorited */ + favoritedAt?: Maybe; + /** Surrogate primary key. This is usually generated by clients, but will be generated by the server if not passed through creation */ + id: Scalars['ID']['output']; + /** Helper property to indicate if the SavedItem is archived */ + isArchived: Scalars['Boolean']['output']; + /** Helper property to indicate if the SavedItem is favorited */ + isFavorite: Scalars['Boolean']['output']; + /** Link to the underlying Pocket Item for the URL */ + item: ItemResult; + /** The status of this SavedItem */ + status?: Maybe; + /** The Suggested Tags associated with this SavedItem, if the user is not premium or there are none, this will be empty. */ + suggestedTags?: Maybe>; + /** The Tags associated with this SavedItem */ + tags?: Maybe>; + /** The title for user saved item. Set by the user and if not, set by the parser. */ + title?: Maybe; + /** The url the user saved to their list */ + url: Scalars['String']['output']; +}; + +/** + * Container for all annotations associated to a SavedItem. + * Can be extended when more types of annotations are added. + */ +export type SavedItemAnnotations = { + __typename?: 'SavedItemAnnotations'; + /** User-highlighted passages on a SavedItem */ + highlights?: Maybe>>; +}; + +/** The connection type for SavedItem. */ +export type SavedItemConnection = { + __typename?: 'SavedItemConnection'; + /** A list of edges. */ + edges?: Maybe>>; + /** Information to aid in pagination. */ + pageInfo: PageInfo; + /** Identifies the total count of SavedItems in the connection. */ + totalCount: Scalars['Int']['output']; +}; + +/** Payload for mutations that delete Saves */ +export type SavedItemDeleteMutationPayload = { + __typename?: 'SavedItemDeleteMutationPayload'; + /** Any errors associated with the mutation. Empty if the mutation was succesful. */ + errors: Array; + success: Scalars['Boolean']['output']; +}; + +/** An edge in a connection. */ +export type SavedItemEdge = { + __typename?: 'SavedItemEdge'; + /** A cursor for use in pagination. */ + cursor: Scalars['String']['output']; + /** The SavedItem at the end of the edge. */ + node?: Maybe; +}; + +/** All types in this union should implement BaseError, for client fallback */ +export type SavedItemMutationError = NotFound | SyncConflict; + +/** + * We don't have official oneOf support, but this will + * throw if both `id` and `url` are unset/null. + * Don't provide both... but if both are provided, it will + * default to using ID. + */ +export type SavedItemRef = { + id?: InputMaybe; + url?: InputMaybe; +}; + +export type SavedItemSearchResult = { + __typename?: 'SavedItemSearchResult'; + savedItem: SavedItem; + /** + * Highlighted snippets from fields in the search results + * searchHighlights is a premium user feature. Not available for free search. + */ + searchHighlights?: Maybe; +}; + +/** The connection type for SavedItem. */ +export type SavedItemSearchResultConnection = { + __typename?: 'SavedItemSearchResultConnection'; + /** A list of edges. */ + edges: Array; + /** Information to aid in pagination. */ + pageInfo: PageInfo; + /** Identifies the total count of items in the connection. */ + totalCount: Scalars['Int']['output']; +}; + +/** An edge in a connection. */ +export type SavedItemSearchResultEdge = { + __typename?: 'SavedItemSearchResultEdge'; + /** A cursor for use in pagination. */ + cursor: Scalars['String']['output']; + /** The item at the end of the edge. */ + node: SavedItemSearchResult; +}; + +/** A page of SavedItemSearchResult, retrieved by offset-based pagination. */ +export type SavedItemSearchResultPage = { + __typename?: 'SavedItemSearchResultPage'; + entries: Array; + limit: Scalars['Int']['output']; + offset: Scalars['Int']['output']; + totalCount: Scalars['Int']['output']; +}; + +export enum SavedItemStatus { + Archived = 'ARCHIVED', + Deleted = 'DELETED', + Hidden = 'HIDDEN', + Unread = 'UNREAD' +} + +/** Valid statuses a client may use to filter SavedItems */ +export enum SavedItemStatusFilter { + Archived = 'ARCHIVED', + Hidden = 'HIDDEN', + Unread = 'UNREAD' +} + +export type SavedItemTagAssociation = { + __typename?: 'SavedItemTagAssociation'; + /** The ID of the SavedItem associated with the Tag */ + savedItemId: Scalars['ID']['output']; + /** The ID of the Tag associated with the SavedItem */ + tagId: Scalars['ID']['output']; +}; + +/** Input field for adding Tag Associations to a SavedItem, by givenUrl */ +export type SavedItemTagInput = { + givenUrl: Scalars['Url']['input']; + tagNames: Array; +}; + +/** Input field for setting all Tag associations on a SavedItem. */ +export type SavedItemTagUpdateInput = { + /** The SavedItem ID to associate Tags to */ + savedItemId: Scalars['ID']['input']; + /** The set of Tag IDs to associate to the SavedItem */ + tagIds: Array; +}; + +/** Input field for setting all Tag associations on a SavedItem. */ +export type SavedItemTagsInput = { + /** The SavedItem ID to associate Tags to */ + savedItemId: Scalars['ID']['input']; + /** The set of Tag names to associate to the SavedItem */ + tags: Array; +}; + +/** Input field for upserting a SavedItem */ +export type SavedItemUpsertInput = { + /** Optional, create/update the SavedItem as a favorited item */ + isFavorite?: InputMaybe; + /** Optional, time that request was submitted by client epoch/unix time */ + timestamp?: InputMaybe; + /** Optional, title of the SavedItem */ + title?: InputMaybe; + /** + * The url to create/update the SavedItem with. (the url to save to the list) + * Must be at least a 4 character string which is the shortest url + */ + url: Scalars['String']['input']; +}; + +/** Payload for mutations that create or update SavedItems */ +export type SavedItemWriteMutationPayload = { + __typename?: 'SavedItemWriteMutationPayload'; + /** Any errors associated with the mutation. Empty if the mutation was succesful. */ + errors: Array; + /** The mutated SavedItem objects; empty if the mutation did not succeed. */ + savedItem: Array; +}; + +/** A SavedItem can be one of these content types */ +export enum SavedItemsContentType { + /** + * Item is a parsed page can be opened in reader view + * @deprecated Use `IS_READABLE`. + */ + Article = 'ARTICLE', + /** Item is a parsed article that contains videos */ + HasVideo = 'HAS_VIDEO', + /** Item is a video or a parsed article that contains videos */ + HasVideoInclusive = 'HAS_VIDEO_INCLUSIVE', + /** Item is an un-parsable page and will be opened externally */ + IsExternal = 'IS_EXTERNAL', + /** Item is an image */ + IsImage = 'IS_IMAGE', + /** Item is a parsed page can be opened in reader view */ + IsReadable = 'IS_READABLE', + /** Item is a video */ + IsVideo = 'IS_VIDEO', + /** + * Item is a parsed article that contains videos + * @deprecated Use `HAS_VIDEO`. + */ + Video = 'VIDEO' +} + +/** Input field for filtering a user's list */ +export type SavedItemsFilter = { + /** Optional, filter to get SavedItems based on content type */ + contentType?: InputMaybe; + /** + * Optional, filter to get SavedItems that have been archived. + * This field is deprecated. Use status instead. + * TODO: Add deprecate tag once input field deprecation is enabled. + * Ref: https://github.com/apollographql/federation/issues/912 + */ + isArchived?: InputMaybe; + /** Optional, filter to get SavedItems that have been favorited */ + isFavorite?: InputMaybe; + /** Optional, filter to get SavedItems with highlights */ + isHighlighted?: InputMaybe; + /** Optional, filter to get user items based on status. Deprecated: use statuses instead. */ + status?: InputMaybe; + /** Optional, filters to get user items based on multiple statuses (OR operator) */ + statuses?: InputMaybe>>; + /** Optional, filter to get SavedItems associated to the specified Tag. */ + tagIds?: InputMaybe>; + /** + * Optional, filter to get SavedItems associated to the specified Tag name. + * To get untagged items, include the string '_untagged_'. + */ + tagNames?: InputMaybe>; + /** + * Optional, filter to get SavedItems updated before a unix timestamp. + * Mutually exclusive with `updatedSince` option. + */ + updatedBefore?: InputMaybe; + /** + * Optional, filter to get SavedItems updated since a unix timestamp. + * Mutually exclusive with `updatedBefore` option. + */ + updatedSince?: InputMaybe; +}; + +/** A page of SavedItems, retrieved by offset-based pagination. */ +export type SavedItemsPage = { + __typename?: 'SavedItemsPage'; + entries: Array; + limit: Scalars['Int']['output']; + offset: Scalars['Int']['output']; + totalCount: Scalars['Int']['output']; +}; + +/** Input to sort fetched SavedItems. If unspecified, defaults to CREATED_AT, ASC. */ +export type SavedItemsSort = { + /** The field by which to sort SavedItems */ + sortBy: SavedItemsSortBy; + /** The order in which to sort SavedItems */ + sortOrder: SavedItemsSortOrder; +}; + +/** Enum to specify the sort by field (these are the current options, we could add more in the future) */ +export enum SavedItemsSortBy { + ArchivedAt = 'ARCHIVED_AT', + CreatedAt = 'CREATED_AT', + FavoritedAt = 'FAVORITED_AT', + UpdatedAt = 'UPDATED_AT' +} + +/** Enum to specify the sort order of SavedItems fetched */ +export enum SavedItemsSortOrder { + Asc = 'ASC', + Desc = 'DESC' +} + +/** Represents a surface that has scheduled items by day */ +export type ScheduledSurface = { + __typename?: 'ScheduledSurface'; + /** Agreed on GUID that is from our shared data pocket confluence */ + id: Scalars['ID']['output']; + /** Subquery to get the ScheduledSurfaceItems to display to a user for a given date */ + items: Array; + /** Internal name of the surface */ + name: Scalars['String']['output']; +}; + + +/** Represents a surface that has scheduled items by day */ +export type ScheduledSurfaceItemsArgs = { + date: Scalars['Date']['input']; +}; + +/** + * A scheduled entry for an CorpusItem to appear on a Scheduled Surface. + * For example, a story that is scheduled to appear on December 31st, 2021 on the Scheduled Surface in Firefox for the US audience. + */ +export type ScheduledSurfaceItem = { + __typename?: 'ScheduledSurfaceItem'; + /** The curated item that should run */ + corpusItem: CorpusItem; + /** A backend GUID that represents this scheduled run */ + id: Scalars['ID']['output']; + /** The date the item should run at */ + scheduledDate: Scalars['Date']['output']; + /** Agreed on GUID that is from our shared data pocket confluence */ + surfaceId: Scalars['ID']['output']; +}; + +/** Input filed for filtering items */ +export type SearchFilter = { + /** Optional filter to items of a specific content type */ + contentType?: InputMaybe; + /** + * Optional filter to get items that matches the domain + * domain should be in the url format, e.g getpocket.com (or) list.getpocket.com + */ + domain?: InputMaybe; + /** Optional filter to get items that are favorited */ + favorite?: InputMaybe; + /** Optional filter to get items in a specific state */ + status?: InputMaybe; + /** Optional fitler to get item with specific tags */ + tags?: InputMaybe>>; +}; + +export type SearchFilterInput = { + /** Optional, filter to get SavedItems based on content type */ + contentType?: InputMaybe; + /** + * Optional filter to get items that matches the domain + * domain should be in the url format, e.g getpocket.com (or) list.getpocket.com + */ + domain?: InputMaybe; + /** Optional, filter to get user items that have been favorited */ + isFavorite?: InputMaybe; + /** + * Optional, filter to get user items only based on title and url, ie Free Search + * Note, though that if this is selected and the user is premium, they will not get search highligthing. + */ + onlyTitleAndURL?: InputMaybe; + /** Optional, filter to get user items based on status. */ + status?: InputMaybe; +}; + +/** + * Used to detemermine whether to add or multiply a document's score by the + * functional boost factor + */ +export enum SearchFunctionalBoostOperation { + Add = 'ADD', + Multiply = 'MULTIPLY' +} + +/** Input field to get elasticsearch highlights of keywords */ +export type SearchHighlightField = { + /** Field to highlight */ + field: Scalars['String']['input']; + /** The number of characters to return in addition to the keyword */ + size: Scalars['Int']['input']; +}; + +/** A SavedItem can be one of these content types */ +export enum SearchItemsContentType { + Article = 'ARTICLE', + Video = 'VIDEO' +} + +/** Enum to specify the sort by field (these are the current options, we could add more in the future) */ +export enum SearchItemsSortBy { + /** Indicates when a SavedItem was created */ + CreatedAt = 'CREATED_AT', + /** + * Sort SavedItems based on a relevance score + * This is a feature of elasticsearch and current only available for premium search + */ + Relevance = 'RELEVANCE', + /** Estimated time to read a SavedItem */ + TimeToRead = 'TIME_TO_READ' +} + +/** Enum to specify the sort order of user items fetched */ +export enum SearchItemsSortOrder { + Asc = 'ASC', + Desc = 'DESC' +} + +/** Valid statuses a client may use to filter */ +export enum SearchItemsStatusFilter { + Archived = 'ARCHIVED', + Unread = 'UNREAD' +} + +/** Input field for search */ +export type SearchParams = { + /** Fields to search for the keyword in */ + fields: Array>; + /** Filters to be applied to the search */ + filters?: InputMaybe; + /** Offset for pagination */ + from?: InputMaybe; + /** Operation to boost the score of a document based */ + functionalBoosts?: InputMaybe>>; + /** Fields that should be highlighted if keywords are found within them */ + highlightFields?: InputMaybe>>; + /** Number of items to return */ + size?: InputMaybe; + /** Sorting for the search */ + sort?: InputMaybe; + /** The keyword to search for */ + term: Scalars['String']['input']; +}; + +/** The return type for the search query */ +export type SearchResult = { + __typename?: 'SearchResult'; + /** @deprecated Not required by implementing clients */ + page?: Maybe; + /** @deprecated Not required by implementing client */ + perPage?: Maybe; + /** Items found */ + results?: Maybe>>; + /** Number of items found */ + totalResults: Scalars['Int']['output']; +}; + +/** Input field for sorting items */ +export type SearchSort = { + /** Direction of the sort (ASC/DESC) */ + direction: SearchSortDirection; + /** Field in elasticsearch to sort by */ + field: Scalars['String']['input']; +}; + +/** Sort direction of the returned items. */ +export enum SearchSortDirection { + Asc = 'ASC', + Desc = 'DESC' +} + +export type SearchSortInput = { + /** The field by which to sort user items */ + sortBy: SearchItemsSortBy; + /** The order in which to sort user items */ + sortOrder?: InputMaybe; +}; + +/** + * An index item can be in one of these states + * QUEUED implies an item that has not been archived + */ +export enum SearchStatus { + Archived = 'ARCHIVED', + Queued = 'QUEUED' +} + +export type ShareContext = { + __typename?: 'ShareContext'; + /** User-provided highlights of the content */ + highlights?: Maybe>; + /** A user-provided comment/note on the shared content. */ + note?: Maybe; +}; + +/** Input for mutation which creates a new Pocket Share link. */ +export type ShareContextInput = { + /** Quoted content from the Share source */ + highlights?: InputMaybe; + /** A note/comment about the Share (up to 500 characters). */ + note?: InputMaybe; +}; + +export type ShareHighlight = { + __typename?: 'ShareHighlight'; + /** Highlighted text on a piece of shared content. */ + quote: Scalars['String']['output']; +}; + +export type ShareHighlightInput = { + /** + * Highlighted text on a piece of shared content. + * This is a permissive constraint but there needs + * to be _a_ constraint. + * This input is not required, but if present 'quotes' + * is required as it is the only field. + * Limited to 300 characters per quote (longer quotes + * will not be rejected, but will be truncated). + */ + quotes: Array; +}; + +export type ShareNotFound = { + __typename?: 'ShareNotFound'; + message?: Maybe; +}; + +export type ShareResult = PocketShare | ShareNotFound; + +/** A user-created list of Pocket saves that can be shared publicly. */ +export type ShareableList = { + __typename?: 'ShareableList'; + /** The timestamp of when the list was created by its owner. */ + createdAt: Scalars['ISOString']['output']; + /** Optional text description of a Shareable List. Provided by the Pocket user. */ + description?: Maybe; + /** A unique string identifier in UUID format. */ + externalId: Scalars['ID']['output']; + /** Pocket Saves that have been added to this list by the Pocket user. */ + items: ListItemConnection; + /** The visibility of notes added to list items for this list. */ + listItemNoteVisibility: ShareableListVisibility; + /** + * Pocket Saves that have been added to this list by the Pocket user. + * @deprecated use items + */ + listItems: Array; + /** The moderation status of the list. Defaults to VISIBLE. */ + moderationStatus: ShareableListModerationStatus; + /** + * A URL-ready identifier of the list. Generated from the title + * of the list when it's first made public. Unique per user. + */ + slug?: Maybe; + /** The status of the list. Defaults to PRIVATE. */ + status: ShareableListVisibility; + /** The title of the list. Provided by the Pocket user. */ + title: Scalars['String']['output']; + /** + * The timestamp of when the list was last updated by its owner + * or a member of the moderation team. + */ + updatedAt: Scalars['ISOString']['output']; + /** The user who created this shareable list. */ + user: User; +}; + + +/** A user-created list of Pocket saves that can be shared publicly. */ +export type ShareableListItemsArgs = { + pagination?: InputMaybe; +}; + +/** A Pocket Save (story) that has been added to a Shareable List. */ +export type ShareableListItem = { + __typename?: 'ShareableListItem'; + /** A comma-separated list of story authors. Supplied by the Parser. */ + authors?: Maybe; + /** The timestamp of when this story was added to the list by its owner. */ + createdAt: Scalars['ISOString']['output']; + /** The excerpt of the story. Supplied by the Parser. */ + excerpt?: Maybe; + /** A unique string identifier in UUID format. */ + externalId: Scalars['ID']['output']; + /** The URL of the thumbnail image illustrating the story. Supplied by the Parser. */ + imageUrl?: Maybe; + /** The Parser Item ID. */ + itemId: Scalars['ID']['output']; + /** User generated note to accompany this list item. */ + note?: Maybe; + /** The name of the publisher for this story. Supplied by the Parser. */ + publisher?: Maybe; + /** The custom sort order of stories within a list. Defaults to 1. */ + sortOrder: Scalars['Int']['output']; + /** + * The title of the story. Supplied by the Parser. + * May not be available for URLs that cannot be resolved. + * Not editable by the Pocket user, as are all the other + * Parser-supplied story properties below. + */ + title?: Maybe; + /** The timestamp of when the story was last updated. Not used for the MVP. */ + updatedAt: Scalars['ISOString']['output']; + /** The URL of the story saved to a list. */ + url: Scalars['Url']['output']; +}; + +/** The moderation status of a Shareable List. Defaults to VISIBLE. */ +export enum ShareableListModerationStatus { + /** + * The list and its contents have been removed from view and further editing + * by its owner as it violated the Pocket content moderation policy. + */ + Hidden = 'HIDDEN', + /** The list and its contents abide by the Pocket content moderation policy. */ + Visible = 'VISIBLE' +} + +/** + * A list that has been already shared publicly. + * This type is needed as it needs to be cached. + */ +export type ShareableListPublic = { + __typename?: 'ShareableListPublic'; + /** The timestamp of when the list was created by its owner. */ + createdAt: Scalars['ISOString']['output']; + /** Optional text description of a Shareable List. Provided by the Pocket user. */ + description?: Maybe; + /** A unique string identifier in UUID format. */ + externalId: Scalars['ID']['output']; + /** The visibility of notes added to list items for this list. */ + listItemNoteVisibility: ShareableListVisibility; + /** Pocket Saves that have been added to this list by the Pocket user. */ + listItems: Array; + /** The moderation status of the list. Defaults to VISIBLE. */ + moderationStatus: ShareableListModerationStatus; + /** + * A URL-ready identifier of the list. Generated from the title + * of the list when it's first made public. Unique per user. + */ + slug?: Maybe; + /** The status of the list. Defaults to PRIVATE. */ + status: ShareableListVisibility; + /** The title of the list. Provided by the Pocket user. */ + title: Scalars['String']['output']; + /** + * The timestamp of when the list was last updated by its owner + * or a member of the moderation team. + */ + updatedAt: Scalars['ISOString']['output']; + /** The user who created this shareable list. */ + user: User; +}; + +/** The visibility levels used (e.g. list, list item note) in the Shareable List API. Defaults to PRIVATE - visible only to its owner. */ +export enum ShareableListVisibility { + /** Only visible to its owner - the Pocket user who created it. */ + Private = 'PRIVATE', + /** Can be viewed by anyone in the world. */ + Public = 'PUBLIC' +} + +/** A grouping of item recommendations that relate to each other under a specific name and description */ +export type Slate = { + __typename?: 'Slate'; + /** The description of the the slate */ + description?: Maybe; + /** The name to show to the user for this set of recommendations */ + displayName?: Maybe; + /** A unique guid/slug, provided by the Data & Learning team that can identify a specific experiment. Production apps typically won't request a specific one, but can for QA or during a/b testing. */ + experimentId: Scalars['ID']['output']; + id: Scalars['String']['output']; + /** An ordered list of the recommendations to show to the user */ + recommendations: Array; + /** A guid that is unique to every API request that returned slates, such as `getSlateLineup` or `getSlate`. The API will provide a new request id every time apps hit the API. */ + requestId: Scalars['ID']['output']; +}; + +export type SlateLineup = { + __typename?: 'SlateLineup'; + /** A unique guid/slug, provided by the Data & Learning team that can identify a specific experiment. Production apps typically won't request a specific one, but can for QA or during a/b testing. */ + experimentId: Scalars['ID']['output']; + /** A unique slug/id that describes a SlateLineup. The Data & Learning team will provide apps what id to use here for specific cases. */ + id: Scalars['ID']['output']; + /** A guid that is unique to every API request that returned slates, such as `getRecommendationSlateLineup` or `getSlate`. The API will provide a new request id every time apps hit the API. */ + requestId: Scalars['ID']['output']; + /** An ordered list of slates for the client to display */ + slates: Array; +}; + +/** + * Union type to reference a surface + * This is a future improvement, not needed now. + */ +export type Surface = ScheduledSurface; + +export type SyncConflict = BaseError & { + __typename?: 'SyncConflict'; + message: Scalars['String']['output']; + path: Scalars['String']['output']; +}; + +/** An article that Pocket has syndicated and we also host on our own site */ +export type SyndicatedArticle = { + __typename?: 'SyndicatedArticle'; + /** Array of author names in string format */ + authorNames: Array>; + /** Content for the syndicated article */ + content?: Maybe; + /** + * The pocket curation category of the Article, maps to the Pocket Curation Topic lists + * @deprecated use topic instead + */ + curationCategory?: Maybe; + /** Excerpt */ + excerpt?: Maybe; + /** When does the contract for syndication expire */ + expiresAt?: Maybe; + /** The Sub IAB category of the article defined at https://support.aerserv.com/hc/en-us/articles/207148516-List-of-IAB-Categories */ + iabSubCategory?: Maybe; + /** The Main IAB category of the article defined at https://support.aerserv.com/hc/en-us/articles/207148516-List-of-IAB-Categories */ + iabTopCategory?: Maybe; + /** The item id of this Syndicated Article */ + itemId?: Maybe; + /** The locale country of the article */ + localeCountry?: Maybe; + /** The language of the article */ + localeLanguage?: Maybe; + /** Primary image to use in surfacing this content */ + mainImage?: Maybe; + /** The item id of the article we cloned */ + originalItemId: Scalars['ID']['output']; + /** AWSDateTime — Format: YYYY-MM-DDThh:mm:ss.sssZ */ + publishedAt: Scalars['String']['output']; + /** The manually set publisher information for this article */ + publisher?: Maybe; + publisherUrl: Scalars['String']['output']; + /** Recommend similar syndicated articles. */ + relatedEndOfArticle: Array; + /** Recommend similar articles from the same publisher. */ + relatedRightRail: Array; + /** Should ads be shown on this article or not */ + showAds: Scalars['Boolean']['output']; + /** Slug that pocket uses for this article in the url */ + slug?: Maybe; + /** + * DRAFT — Article is not meant to be available to the public + * EXPIRED — Article contract is up and should be redirected to original article + * ACTIVE — Article is clear to be shown in syndicated form + */ + status: ArticleStatus; + /** Title of syndicated article */ + title: Scalars['String']['output']; + /** The pocket topic of the Article, maps to the Pocket Curation Topic lists */ + topic?: Maybe; +}; + + +/** An article that Pocket has syndicated and we also host on our own site */ +export type SyndicatedArticleRelatedEndOfArticleArgs = { + count?: InputMaybe; +}; + + +/** An article that Pocket has syndicated and we also host on our own site */ +export type SyndicatedArticleRelatedRightRailArgs = { + count?: InputMaybe; +}; + +/** Represents a Tag that a User has created for their list */ +export type Tag = { + __typename?: 'Tag'; + /** Unix timestamp of when the entity was deleted, 30 days after this date this entity will be HARD deleted from the database and no longer exist */ + _deletedAt?: Maybe; + /** Version of the entity, this will increment with each modification of the entity's field */ + _version?: Maybe; + /** Surrogate primary key. This is usually generated by clients, but will be generated by the server if not passed through creation */ + id: Scalars['ID']['output']; + /** The actual tag string the user created for their list */ + name: Scalars['String']['output']; + /** paginated listing of all SavedItems associated with this Tag for the user */ + savedItems?: Maybe; +}; + + +/** Represents a Tag that a User has created for their list */ +export type TagSavedItemsArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + +/** The connection type for Tag. */ +export type TagConnection = { + __typename?: 'TagConnection'; + /** A list of edges. */ + edges?: Maybe>>; + /** Information to aid in pagination. */ + pageInfo: PageInfo; + /** Identifies the total count of Tags in the connection. */ + totalCount: Scalars['Int']['output']; +}; + +/** Input field for creating a Tag */ +export type TagCreateInput = { + /** The user provided tag string */ + name: Scalars['String']['input']; + /** ID of the SavedItem to associate with this Tag */ + savedItemId: Scalars['ID']['input']; +}; + +/** Payload for mutations that delete Tags */ +export type TagDeleteMutationPayload = { + __typename?: 'TagDeleteMutationPayload'; + /** Any errors associated with the mutation. Empty if the mutation was succesful. */ + errors: Array; + success: Scalars['Boolean']['output']; +}; + +/** An edge in a connection. */ +export type TagEdge = { + __typename?: 'TagEdge'; + /** A cursor for use in pagination. */ + cursor: Scalars['String']['output']; + /** The Tag at the end of the edge. */ + node?: Maybe; +}; + +/** All types in this union should implement BaseError, for client fallback */ +export type TagMutationError = NotFound | SyncConflict; + +/** Input field for updating a Tag */ +export type TagUpdateInput = { + /** Tag ID */ + id: Scalars['ID']['input']; + /** The updated tag string */ + name: Scalars['String']['input']; +}; + +/** Payload for mutations that create or update Tags */ +export type TagWriteMutationPayload = { + __typename?: 'TagWriteMutationPayload'; + /** Any errors associated with the mutation. Empty if the mutation was succesful. */ + errors: Array; + /** The mutated Tag objects; empty if the mutation did not succeed. */ + tag: Array; +}; + +/** + * Represents a topic for /explore + * Deprecated for SlateLineups + */ +export type Topic = { + __typename?: 'Topic'; + /** The label the curator uses internally to get items onto this topic */ + curatorLabel: Scalars['String']['output']; + /** The internal feed id that this topic will pull from if set */ + customFeedId?: Maybe; + /** + * The name of the topic to show to the user + * @deprecated displayName is deprecated. Use name instead. + */ + displayName: Scalars['String']['output']; + /** If returned a note to show to the user about the topic */ + displayNote?: Maybe; + /** The legacy UUID id of the topic */ + id: Scalars['ID']['output']; + /** Whether or not clients should show this topic ot users */ + isDisplayed: Scalars['Boolean']['output']; + /** Whether or not this topic should be visiblly promoted (prominent on the page) */ + isPromoted: Scalars['Boolean']['output']; + /** The name of the topic to show to the user */ + name: Scalars['String']['output']; + /** The type of page this topic represents used in generation */ + pageType: PageType; + /** The query that was used internally for elasticsearch to find items */ + query: Scalars['String']['output']; + /** The slug that should be used in the url to represent the topic */ + slug: Scalars['String']['output']; + /** The description to use in the HTML markup for SEO and social media sharing */ + socialDescription?: Maybe; + /** The image to use in the HTML markup for SEO and social media sharing */ + socialImage?: Maybe; + /** The title to use in the HTML markup for SEO and social media sharing */ + socialTitle?: Maybe; +}; + +export type TopicInput = { + /** The id of the topic */ + id: Scalars['ID']['input']; +}; + +/** Represents content that could not be parsed into a valid Marticle* component. */ +export type UnMarseable = { + __typename?: 'UnMarseable'; + /** The html that could not be parsed into a Marticle* component. */ + html: Scalars['String']['output']; +}; + +/** Details on the variant/status of this toggle for a given user/context */ +export type UnleashAssignment = { + __typename?: 'UnleashAssignment'; + /** Whether or not the provided context is assigned */ + assigned: Scalars['Boolean']['output']; + /** The unleash toggle name, the same name as it appears in the admin interface and feature api */ + name: Scalars['String']['output']; + /** If the variant has a payload, its payload value */ + payload?: Maybe; + /** If the toggle has variants, the variant name it is assigned to */ + variant?: Maybe; +}; + +/** Contains a list of all toggles. */ +export type UnleashAssignmentList = { + __typename?: 'UnleashAssignmentList'; + assignments: Array>; +}; + +/** + * Information about the user and device. Based on https://unleash.github.io/docs/unleash_context + * + * Used to calculate assignment values. + */ +export type UnleashContext = { + /** + * A unique name for one of our apps. Can be any string, but here are some known/expected values: + * + * - `android` + * - `ios` + * - `web-discover` + * - `web-app` + */ + appName?: InputMaybe; + /** + * The environment the device is running in: + * - `prod` + * - `beta` + * - `alpha` + */ + environment?: InputMaybe; + properties?: InputMaybe; + /** The device's IP address. If omitted, inferred from either request header `x-forwarded-for` or the origin IP of the request. */ + remoteAddress?: InputMaybe; + /** A device specific identifier that will be consistent across sessions, typically the encoded {guid} or some session token. */ + sessionId?: InputMaybe; + /** If logged in, the user's encoded user id (uid). The {Account.user_id}. */ + userId?: InputMaybe; +}; + +export enum UnleashEnvironment { + /** Internal team builds */ + Alpha = 'alpha', + /** User facing, beta level builds */ + Beta = 'beta', + /** User facing, production builds */ + Prod = 'prod' +} + +/** Extended properties that Unleash can use to assign users through a toggle's strategies. */ +export type UnleashProperties = { + /** Only required on activation strategies that are based on account age */ + accountCreatedAt?: InputMaybe; + /** If omitted, inferred from request header `accept-langauge`. */ + locale?: InputMaybe; + /** Only required on activation strategies that are based whether a user model exists */ + recItUserProfile?: InputMaybe; +}; + +export type UpdateHighlightInput = { + /** The ID of the Item that should be annotated in the User's list */ + itemId: Scalars['ID']['input']; + /** Optional note generated by User */ + note?: InputMaybe; + /** + * Patch string generated by 'DiffMatchPatch' library, serialized + * into text via `patch_toText` method. + * Format is similar to UniDiff but is character-based. + * The patched text depends on version. For example, the version 2 + * patch surrounds the highlighted text portion with a pair of + * sentinel tags: '' + * Reference: https://github.com/google/diff-match-patch + */ + patch: Scalars['String']['input']; + /** + * The full text of the highlighted passage. Used as a fallback for + * rendering highlight if the patch fails. + */ + quote: Scalars['String']['input']; + /** Annotation data version */ + version: Scalars['Int']['input']; +}; + +/** Input data for updating a Shareable List. */ +export type UpdateShareableListInput = { + description?: InputMaybe; + externalId: Scalars['ID']['input']; + listItemNoteVisibility?: InputMaybe; + status?: InputMaybe; + title?: InputMaybe; +}; + +/** Input data for updating a single Shareable List Item. */ +export type UpdateShareableListItemInput = { + externalId: Scalars['ID']['input']; + note?: InputMaybe; + sortOrder?: InputMaybe; +}; + +/** Input data for updating an array of Shareable List Items, targeting sortOrder. */ +export type UpdateShareableListItemsInput = { + externalId: Scalars['ID']['input']; + sortOrder: Scalars['Int']['input']; +}; + +export type UpdateUserRecommendationPreferencesInput = { + /** Topics that the user expressed interest in. */ + preferredTopics: Array; +}; + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type User = { + __typename?: 'User'; + /** Timestamp of the date when account was created */ + accountCreationDate?: Maybe; + advancedSearch?: Maybe; + advancedSearchByOffset?: Maybe; + /** The public avatar url for the user */ + avatarUrl?: Maybe; + /** A users bio for their profile */ + description?: Maybe; + /** Email address associated with the account. */ + email?: Maybe; + /** The users first name */ + firstName?: Maybe; + /** User id, provided by the user service. */ + id: Scalars['ID']['output']; + /** Indicates if a user is FxA or not */ + isFxa?: Maybe; + /** The user's premium status */ + isPremium?: Maybe; + /** The users last name */ + lastName?: Maybe; + /** The users first name and last name combined */ + name?: Maybe; + /** Premium features that a user has access to */ + premiumFeatures?: Maybe>>; + /** Current premium status of the user */ + premiumStatus?: Maybe; + recentSearches?: Maybe>; + /** Preferences for recommendations that the user has explicitly set. */ + recommendationPreferences?: Maybe; + /** Get a PocketSave(s) by its id(s) */ + saveById: Array; + /** + * Get a SavedItem by its id + * @deprecated Use saveById instead + */ + savedItemById?: Maybe; + /** Get a general paginated listing of all SavedItems for the user */ + savedItems?: Maybe; + /** Fetch SavedItems with offset pagination. Internal backend use only. */ + savedItemsByOffset?: Maybe; + /** + * Premium search query. Name will be updated after client input + * @deprecated Use searchSavedItems + */ + search: SearchResult; + /** Get a paginated list of user items that match a given term */ + searchSavedItems?: Maybe; + searchSavedItemsByOffset?: Maybe; + /** Get a paginated listing of all a user's Tags */ + tags?: Maybe; + /** + * Get all tag names for a user. + * If syncSince is passed, it will only return tags if changes + * to a user's tags have occurred after syncSince. It will return + * all of the user's tags (not just the changes). + * + * Yes, this is bad graphql design. It's serving a specific + * REST API which has unlimited SQL queries, and we do not want to + * make it possible to request every associated SavedItem + * node on a tag object. Just biting the bullet on this one. + */ + tagsList?: Maybe>; + /** The public username for the user */ + username?: Maybe; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserAdvancedSearchArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + queryString?: InputMaybe; + sort?: InputMaybe; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserAdvancedSearchByOffsetArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + queryString?: InputMaybe; + sort?: InputMaybe; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserSaveByIdArgs = { + ids: Array; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserSavedItemByIdArgs = { + id: Scalars['ID']['input']; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserSavedItemsArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserSavedItemsByOffsetArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserSearchArgs = { + params: SearchParams; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserSearchSavedItemsArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; + term: Scalars['String']['input']; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserSearchSavedItemsByOffsetArgs = { + filter?: InputMaybe; + pagination?: InputMaybe; + sort?: InputMaybe; + term: Scalars['String']['input']; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserTagsArgs = { + pagination?: InputMaybe; +}; + + +/** Resolve by reference the User entity in this graph to provide user data with public lists. */ +export type UserTagsListArgs = { + syncSince?: InputMaybe; +}; + +export type UserRecommendationPreferences = { + __typename?: 'UserRecommendationPreferences'; + /** Topics that the user expressed interest in. */ + preferredTopics?: Maybe>; +}; + +/** A Video, typically within an Article View of an Item or if the Item is a video itself. */ +export type Video = { + __typename?: 'Video'; + /** If known, the height of the video in px */ + height?: Maybe; + /** If known, the length of the video in seconds */ + length?: Maybe; + /** Absolute url to the video */ + src: Scalars['String']['output']; + /** The type of video */ + type: VideoType; + /** The video's id within the service defined by type */ + vid?: Maybe; + /** The id of the video within Article View. Item.article will have placeholders of
where X is this id. Apps can download those images as needed and populate them in their article view. */ + videoId: Scalars['Int']['output']; + /** If known, the width of the video in px */ + width?: Maybe; +}; + +export enum VideoType { + /** Brightcove (v3 value is 8) */ + Brightcove = 'BRIGHTCOVE', + /** Flash (v3 value is 6) */ + Flash = 'FLASH', + /** html5 (v3 value is 5) */ + Html5 = 'HTML5', + /** iframe (v3 value is 7) */ + Iframe = 'IFRAME', + /** video iframe (v3 value is 4) */ + VimeoIframe = 'VIMEO_IFRAME', + /** Vimeo Link (v3 value is 2) */ + VimeoLink = 'VIMEO_LINK', + /** Vimeo Moogaloop (v3 value is 3) */ + VimeoMoogaloop = 'VIMEO_MOOGALOOP', + /** Youtube (v3 value is 1) */ + Youtube = 'YOUTUBE' +} + +export enum Videoness { + /** Contains videos (v3 value is 1) */ + HasVideos = 'HAS_VIDEOS', + /** Is a video (v3 value is 2) */ + IsVideo = 'IS_VIDEO', + /** No videos (v3 value is 0) */ + NoVideos = 'NO_VIDEOS' +} + +export type PocketCollectionsQueryVariables = Exact<{ + slug: Scalars['String']['input']; +}>; + + +export type PocketCollectionsQuery = { __typename?: 'Query', getCollectionBySlug?: { __typename?: 'Collection', externalId: string, title: string, excerpt?: any | null, imageUrl?: any | null, intro?: any | null, publishedAt?: any | null, stories: Array<{ __typename?: 'CollectionStory', externalId: string, title: string, excerpt: any, imageUrl?: any | null, publisher?: string | null, url: any, authors: Array<{ __typename?: 'CollectionStoryAuthor', name: string }>, item?: { __typename?: 'Item', shortUrl?: any | null } | null }> } | null }; + +export type PocketHitsQueryVariables = Exact<{ + date: Scalars['Date']['input']; + scheduledSurfaceId: Scalars['ID']['input']; +}>; + + +export type PocketHitsQuery = { __typename?: 'Query', scheduledSurface: { __typename?: 'ScheduledSurface', items: Array<{ __typename?: 'ScheduledSurfaceItem', id: string, corpusItem: { __typename?: 'CorpusItem', url: any, shortUrl?: any | null, title: string, topic?: string | null, excerpt: string, imageUrl: any, publisher: string, authors: Array<{ __typename?: 'CorpusItemAuthor', name: string }> } }> } }; + + +export const PocketCollectionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"PocketCollections"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"slug"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"getCollectionBySlug"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"slug"},"value":{"kind":"Variable","name":{"kind":"Name","value":"slug"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"externalId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"imageUrl"}},{"kind":"Field","name":{"kind":"Name","value":"intro"}},{"kind":"Field","name":{"kind":"Name","value":"publishedAt"}},{"kind":"Field","name":{"kind":"Name","value":"stories"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"externalId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"imageUrl"}},{"kind":"Field","name":{"kind":"Name","value":"publisher"}},{"kind":"Field","name":{"kind":"Name","value":"authors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"shortUrl"}}]}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]}}]} as unknown as DocumentNode; +export const PocketHitsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"PocketHits"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"date"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Date"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"scheduledSurfaceId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"scheduledSurface"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"scheduledSurfaceId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"items"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"date"},"value":{"kind":"Variable","name":{"kind":"Name","value":"date"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"corpusItem"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"shortUrl"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"topic"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"imageUrl"}},{"kind":"Field","name":{"kind":"Name","value":"authors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"publisher"}}]}}]}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/servers/braze-content-proxy/src/graphql/client-api-proxy.ts b/servers/braze-content-proxy/src/graphql/client-api-proxy.ts new file mode 100644 index 000000000..4cf883296 --- /dev/null +++ b/servers/braze-content-proxy/src/graphql/client-api-proxy.ts @@ -0,0 +1,84 @@ +import { + ApolloClient, + ApolloQueryResult, + HttpLink, + InMemoryCache, +} from '@apollo/client/core'; +import fetch from 'cross-fetch'; +import config from '../config'; +import { + PocketCollectionsDocument, + PocketCollectionsQuery, + PocketCollectionsQueryVariables, + PocketHitsDocument, + PocketHitsQuery, +} from '../generated/graphql/types'; + +export const client = new ApolloClient({ + link: new HttpLink({ fetch, uri: config.clientApi.uri }), + cache: new InMemoryCache(), + name: config.app.apolloClientName, + version: config.app.version, + defaultOptions: { + watchQuery: { + fetchPolicy: 'no-cache', + }, + query: { + fetchPolicy: 'no-cache', + }, + }, +}); + +/** + * calls client API to get collections information + * @param slug slug identifier of the collction + * @returns collections and its story details required by braze + */ +export async function getCollectionsFromGraph( + slug: string, +): Promise> { + const response = await client.query< + PocketCollectionsQuery, + PocketCollectionsQueryVariables + >({ + query: PocketCollectionsDocument, + variables: { + slug: slug, + }, + }); + + if (!response.data?.getCollectionBySlug) { + throw new Error( + `server error: unable to fetch collections for slug: ${slug}.`, + ); + } + + return response; +} + +/** + * Calls Client API to get Pocket Hits stories for a given Pocket Hits surface + * and date (in "YYYY-MM-DD" format). + * @param date Date in "YYYY-MM-DD" format. + * @param scheduledSurfaceId Valid scheduled surface of the Pocket Hits surface. + * @returns Stories for the given Pocket Hits surface and date. + */ +export async function getScheduledSurfaceStories( + date: string, + scheduledSurfaceId: string, +): Promise> { + const data = await client.query({ + query: PocketHitsDocument, + variables: { + date, + scheduledSurfaceId, + }, + }); + + if (!data.data?.scheduledSurface?.items) { + throw new Error( + `No data returned for ${scheduledSurfaceId} scheduled on ${date}.`, + ); + } + return data; +} diff --git a/servers/braze-content-proxy/src/graphql/queries/collections.graphql b/servers/braze-content-proxy/src/graphql/queries/collections.graphql new file mode 100644 index 000000000..5cef20567 --- /dev/null +++ b/servers/braze-content-proxy/src/graphql/queries/collections.graphql @@ -0,0 +1,24 @@ +query PocketCollections($slug: String!) { + getCollectionBySlug(slug: $slug) { + externalId + title + excerpt + imageUrl + intro + publishedAt + stories { + externalId + title + excerpt + imageUrl + publisher + authors { + name + } + item { + shortUrl + } + url + } + } +} diff --git a/servers/braze-content-proxy/src/graphql/queries/scheduledSurface.graphql b/servers/braze-content-proxy/src/graphql/queries/scheduledSurface.graphql new file mode 100644 index 000000000..a0858b60f --- /dev/null +++ b/servers/braze-content-proxy/src/graphql/queries/scheduledSurface.graphql @@ -0,0 +1,19 @@ +query PocketHits($date: Date!, $scheduledSurfaceId: ID!) { + scheduledSurface(id: $scheduledSurfaceId) { + items(date: $date) { + id + corpusItem { + url + shortUrl + title + topic + excerpt + imageUrl + authors { + name + } + publisher + } + } + } +} diff --git a/servers/braze-content-proxy/src/main.integration.ts b/servers/braze-content-proxy/src/main.integration.ts new file mode 100644 index 000000000..e3fdea698 --- /dev/null +++ b/servers/braze-content-proxy/src/main.integration.ts @@ -0,0 +1,26 @@ +import request from 'supertest'; +import { startServer } from './server'; +import { Server } from 'http'; +import { Application } from 'express'; + +describe('main.integration.ts', () => { + let app: Application; + let server: Server; + + beforeAll(async () => { + ({ app, server } = await startServer(0)); + }); + afterAll(async () => { + server.close(); + }); + + describe('health endpoint', () => { + it('should return 200 OK', async () => { + const response = await request(app).get('/.well-known/server-health'); + + expect(response.statusCode).toBe(200); + expect(response.text).not.toBeNull(); + expect(response.text).toBe('ok'); + }); + }); +}); diff --git a/servers/braze-content-proxy/src/main.ts b/servers/braze-content-proxy/src/main.ts new file mode 100644 index 000000000..28454e3be --- /dev/null +++ b/servers/braze-content-proxy/src/main.ts @@ -0,0 +1,17 @@ +import config from './config'; + +import { initSentry } from '@pocket-tools/sentry'; +// Initialize sentry +initSentry({ + ...config.sentry, + debug: config.sentry.environment == 'development', +}); + +import { serverLogger } from '@pocket-tools/ts-logger'; +import { startServer } from './server'; + +startServer(config.app.port).then(() => { + serverLogger.info( + `🚀 Braze Content Proxy ready at http://localhost:${config.app.port}`, + ); +}); diff --git a/servers/braze-content-proxy/src/routes/collection.integration.ts b/servers/braze-content-proxy/src/routes/collection.integration.ts new file mode 100644 index 000000000..c0512c663 --- /dev/null +++ b/servers/braze-content-proxy/src/routes/collection.integration.ts @@ -0,0 +1,69 @@ +import config from '../config'; +import request from 'supertest'; +import { Server } from 'http'; +import { Application } from 'express'; +import { brazeCollectionsFixture, graphCollectionFixture } from './fixture'; +import { client } from '../graphql/client-api-proxy'; +import { startServer } from '../server'; + +describe(`get collection test`, () => { + let app: Application; + let server: Server; + + beforeAll(async () => { + ({ app, server } = await startServer(0)); + }); + afterAll(async () => { + server.close(); + }); + beforeEach(() => { + jest.clearAllMocks(); + }); + + it(`/get collection should return braze collection payload`, async () => { + const testSlug = 'the-world-as-explained-by-pop-culture'; + // spying on the getStories function to make it return a mock response + jest + .spyOn(client, 'query') + .mockResolvedValue(graphCollectionFixture as any); + const response = await request(app).get( + `/collection/${testSlug}?apikey=${config.aws.brazeApiKey}`, + ); + expect(response.statusCode).toBe(200); + expect(response.body).toEqual(brazeCollectionsFixture); + expect(response.headers['cache-control']).not.toBeUndefined(); + expect(response.headers['cache-control']).toBe('public, max-age=120'); + }); + + it('should return 500 if collection is not found', async () => { + const notFoundGraphError = { + errors: [ + { + message: 'Error - Not Found: not-found', + path: ['getCollectionBySlug'], + extensions: { + code: 'NOT_FOUND', + serviceName: 'collection', + }, + }, + ], + data: { + getCollectionBySlug: null, + }, + }; + jest.spyOn(client, 'query').mockResolvedValue(notFoundGraphError as any); + const response = await request(app).get( + `/collection/not-found-slug?apikey=${config.aws.brazeApiKey}`, + ); + expect(response.statusCode).toBe(500); + }); + + it('should return 500 if invalid api key is provided ', async () => { + const response = await request(app).get( + `/collection/this-is-test-slug?apikey=invalid-api-key`, + ); + expect(response.statusCode).toBe(500); + expect(response.body.error).not.toBeUndefined(); + expect(response.body.error).toBe(config.app.INVALID_API_KEY_ERROR_MESSAGE); + }); +}); diff --git a/servers/braze-content-proxy/src/routes/collection.ts b/servers/braze-content-proxy/src/routes/collection.ts new file mode 100644 index 000000000..4d964e05f --- /dev/null +++ b/servers/braze-content-proxy/src/routes/collection.ts @@ -0,0 +1,72 @@ +import { getCollectionsFromGraph } from '../graphql/client-api-proxy'; +import { getResizedImageUrl, validateApiKey } from '../utils'; +import { BrazeCollections, BrazeCollectionStory } from './types'; +import config from '../config'; +import { Router } from 'express'; +import { PocketCollectionsQuery } from '../generated/graphql/types'; +import type { ApolloQueryResult } from '@apollo/client/core/types'; + +const router: Router = Router(); + +/** + * GET endpoint to receive collection metadata and its stories information from client + * Note: will throw only 500 to prevent braze from sending the email if call fails. + */ +router.get('/:slug', async (req, res, next) => { + // Enable two minute cache when in AWS. + // The short-lived cache is to speed up the curators' workflow + // if they need to make last-minute updates. + if (config.app.environment !== 'development') { + res.set('Cache-control', 'public, max-age=120'); + } + + const slug = req.params.slug; + // Get the API key + const apiKey = req.query.apikey as string; + + try { + await validateApiKey(apiKey); + // Fetch data + return res.json(await getCollection(slug)); + } catch (err) { + // Let Express handle any errors + next(err); + } +}); + +/** + * fetch collections and transform them to braze payload + * @param slug + */ +export async function getCollection(slug: string) { + const response = await getCollectionsFromGraph(slug); + return transformToBrazePayload(response); +} + +function transformToBrazePayload( + response: ApolloQueryResult, +): BrazeCollections { + const collection = response.data.getCollectionBySlug; + const stories: BrazeCollectionStory[] = collection.stories.map((story) => { + return { + title: story.title, + url: story.url, + excerpt: story.excerpt, + imageUrl: getResizedImageUrl(story.imageUrl), + authors: story.authors.map((author) => author.name), + shortUrl: story.item.shortUrl, + publisher: story.publisher, + externalId: story.externalId, + }; + }); + return { + title: collection.title, + intro: collection.intro, + excerpt: collection.excerpt, + publishedAt: collection.publishedAt, + imageUrl: getResizedImageUrl(collection.imageUrl), + externalId: collection.externalId, + stories: stories, + }; +} +export default router; diff --git a/servers/braze-content-proxy/src/routes/fixture.ts b/servers/braze-content-proxy/src/routes/fixture.ts new file mode 100644 index 000000000..aca133183 --- /dev/null +++ b/servers/braze-content-proxy/src/routes/fixture.ts @@ -0,0 +1,80 @@ +import { BrazeCollections } from './types'; +import { getResizedImageUrl } from '../utils'; + +export const graphCollectionFixture = { + data: { + getCollectionBySlug: { + externalId: '75898157-b267-49f8-923a-7296ec44b9fe', + title: 'How Pop Culture Explains The World', + excerpt: + 'Breaking down the complexities of society with help from Michael Scott, Homer Simpson, and Neopets. ', + imageUrl: + 'https://s3.amazonaws.com/pocket-collectionapi-prod-images/aef6a1a8-3f6c-4281-b7fc-440e4a3ff8bc.jpeg', + intro: 'test introduction that has a lot of words', + publishedAt: '2022-08-03T16:54:22.000Z', + stories: [ + { + externalId: '0bc6487f-adad-4971-934b-85bae9852fbd', + item: { + shortUrl: 'https://pocket.co/x_JA', + __typename: 'Item', + }, + title: 'Labor Exploitation, Explained by Minions', + url: 'https://www.vox.com/the-goods/23177505/minions-2-rise-of-gru-explained-capitalism', + excerpt: + '**Lucy Blakiston**: “Even though I’m not a fan of Minions (this may be an unpopular opinion)', + imageUrl: + 'https://s3.amazonaws.com/pocket-collectionapi-prod-images/92631502-7403-4900-9bd6-6eb86398fdb9.jpeg', + publisher: 'Vox', + authors: [ + { + name: 'test author-1', + }, + { + name: 'test author-2', + }, + ], + }, + { + externalId: '994b8b75-6730-4758-b926-e05d5eea9867', + title: 'The Rise and Fall of the Pop Star Purity Ring', + url: 'https://jezebel.com/the-rise-and-fall-of-the-pop-star-purity-ring-1822170318', + item: { + shortUrl: 'https://pocket.co/x_AB', + __typename: 'Item', + }, + excerpt: 'this is a text with lot of words. and interesting story', + imageUrl: + 'https://s3.amazonaws.com/pocket-collectionapi-prod-images/609a0ffd-d9af-4cda-b911-9e40397611bc.jpeg', + publisher: 'Jezebel', + authors: [ + { + name: 'Chelsea Beck', + }, + ], + }, + ], + }, + }, +}; + +export const brazeCollectionsFixture: BrazeCollections = Object.freeze({ + ...graphCollectionFixture.data.getCollectionBySlug, + imageUrl: getResizedImageUrl( + graphCollectionFixture.data.getCollectionBySlug.imageUrl, + ), + stories: graphCollectionFixture.data.getCollectionBySlug.stories.map( + (story) => { + const res = { + ...story, + //this method is unit tested, so using it in fixture + imageUrl: getResizedImageUrl(story.imageUrl), + shortUrl: story.item.shortUrl, + authors: story.authors.map((author) => author.name), + }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { item: _, ...rest } = res; + return rest; + }, + ), +}); diff --git a/servers/braze-content-proxy/src/routes/scheduledItems.integration.ts b/servers/braze-content-proxy/src/routes/scheduledItems.integration.ts new file mode 100644 index 000000000..ba8bafa0b --- /dev/null +++ b/servers/braze-content-proxy/src/routes/scheduledItems.integration.ts @@ -0,0 +1,95 @@ +import request from 'supertest'; +import { Server } from 'http'; +import { Application } from 'express'; +import config from '../config'; +import { stories } from './scheduledItems'; +import { startServer } from '../server'; + +describe('/scheduled-items/:scheduledSurfaceID?date=date&apikey=apikey', () => { + let app: Application; + let server: Server; + beforeAll(async () => { + ({ app, server } = await startServer(0)); + }); + afterAll(async () => { + server.close(); + }); + + const testNewTab = 'POCKET_HITS_EN_US'; + const testDate = '2050-01-01'; + const validUrl = `/scheduled-items/${testNewTab}?date=${testDate}&apikey=${config.aws.brazeApiKey}`; + + const testStories = { + stories: [ + { + id: '123-abc', + url: 'www.test-url.com', + shortUrl: 'https://pocket.co/abc', + title: 'test-title', + excerpt: 'test-excerpt', + imageUrl: 'www.test-image-url.com', + authors: 'test-author', + publisher: 'test-publisher', + topic: 'health and fitness', + }, + { + id: '456-cde', + url: 'www.second-test-url.com', + shortUrl: 'https://pocket.co/cde', + title: 'second-test-title', + excerpt: 'second-test-excerpt', + imageUrl: 'www.second-test-image-url.com', + authors: 'second-test-author', + publisher: 'second-test-publisher', + topic: 'entertainment', + }, + ], + }; + + it('should return 200 OK and correct headers when valid query params are provided', async () => { + const response = await request(app).get(validUrl); + + expect(response.statusCode).toBe(200); + // checking if the cache-control header has been set correctly + expect(response.headers['cache-control']).not.toBeUndefined(); + expect(response.headers['cache-control']).toBe('public, max-age=120'); + }); + + it('should return correct data when valid query params are provided', async () => { + // spying on the getStories function to make it return a mock response + jest.spyOn(stories, 'getStories').mockResolvedValue(testStories as any); + + const response = await request(app).get(validUrl); + + expect(response.statusCode).toBe(200); + expect(response.body).toEqual(testStories); + }); + + it('should return 404 for non-existent url ', async () => { + const response = await request(app).get('/not-found'); + + expect(response.statusCode).toBe(404); + }); + + it('should return 500 if incorrect date format is provided ', async () => { + const response = await request(app).get( + `/scheduled-items/${testNewTab}?date=20220524`, + ); + + expect(response.statusCode).toBe(500); + expect(response.body.error).not.toBeUndefined(); + expect(response.body.error).toBe( + 'Not a valid date. Please provide a date in YYYY-MM-DD format.', + ); + }); + + it('should return 500 if invalid api key is provided ', async () => { + const response = await request(app).get( + `/scheduled-items/${testNewTab}?date=${testDate}&apikey=invalid-key`, + ); + + expect(response.statusCode).toBe(500); + expect(response.body.error).not.toBeUndefined(); + expect(response.body.error).toBe(config.app.INVALID_API_KEY_ERROR_MESSAGE); + }); +}); diff --git a/servers/braze-content-proxy/src/routes/scheduledItems.ts b/servers/braze-content-proxy/src/routes/scheduledItems.ts new file mode 100644 index 000000000..487ea2947 --- /dev/null +++ b/servers/braze-content-proxy/src/routes/scheduledItems.ts @@ -0,0 +1,77 @@ +import { BrazeContentProxyResponse, TransformedCorpusItem } from './types'; +import { getResizedImageUrl, validateApiKey, validateDate } from '../utils'; +import { getScheduledSurfaceStories } from '../graphql/client-api-proxy'; +import config from '../config'; +import { Router } from 'express'; + +const router: Router = Router(); + +router.get('/:scheduledSurfaceID', async (req, res, next) => { + // Enable two minute cache when in AWS. + // The short-lived cache is to speed up the curators' workflow + // if they need to make last-minute updates. + if (config.app.environment !== 'development') { + res.set('Cache-control', 'public, max-age=120'); + } + + // Get the scheduled surface GUID + const scheduledSurfaceID = req.params.scheduledSurfaceID; + // Get the date the stories are scheduled for + const date = req.query.date as string; + // Get the API key + const apiKey = req.query.apikey as string; + + try { + // Validate inputs + validateDate(date); + await validateApiKey(apiKey); + + // Fetch data + return res.json(await stories.getStories(date, scheduledSurfaceID)); + } catch (err) { + // Let Express handle any errors + next(err); + } +}); + +/** + * Entry point to this module. Retrieves data from Client API and transforms it + * to match expected schema. + * note: getStories is wrapped inside object to enable mocking testing. + */ +export const stories = { + getStories: async ( + date: string, + scheduledSurfaceId: string, + ): Promise => { + const data = await getScheduledSurfaceStories(date, scheduledSurfaceId); + + const stories = data ? data.data.scheduledSurface.items : []; + + const transformedStories: TransformedCorpusItem[] = stories.map((item) => { + return { + // The id of the Scheduled Surface Item + id: item.id, + url: item.corpusItem.url, + shortUrl: item.corpusItem.shortUrl, + title: item.corpusItem.title, + topic: item.corpusItem.topic, + excerpt: item.corpusItem.excerpt, + publisher: item.corpusItem.publisher, + // Resize images on the fly so that they don't distort emails when sent out. + imageUrl: getResizedImageUrl(item.corpusItem.imageUrl), + // Flatten the authors into a comma-separated string. + authors: item.corpusItem.authors + ?.map((author) => author.name) + .join(', '), + __typename: 'CorpusItem', + }; + }); + + return { + stories: transformedStories, + }; + }, +}; + +export default router; diff --git a/servers/braze-content-proxy/src/routes/types.ts b/servers/braze-content-proxy/src/routes/types.ts new file mode 100644 index 000000000..8eb4f65b2 --- /dev/null +++ b/servers/braze-content-proxy/src/routes/types.ts @@ -0,0 +1,57 @@ +/** + * A very lean Corpus Item type with just the data Pocket Hits emails need. + */ +export type TransformedCorpusItem = { + // Unlike in the Client API response, the Braze Content Proxy response contains + // a string that lists all the authors for each story, not an object. + authors: string; + // This value is the id of the Scheduled Surface Item, rather than the Corpus Item + id: string; + + url: string; + + shortUrl: string; + + title: string; + + topic: string; + + excerpt: string; + + publisher: string; + + imageUrl: string; + + __typename: string; +}; + +/** + * The response we serve from this proxy for Braze. + */ +export type BrazeContentProxyResponse = { + stories: TransformedCorpusItem[]; +}; + +/** + * response payload type for /GET collections call + */ +export type BrazeCollections = { + title: string; + excerpt: string; + imageUrl: string; + intro: string; + publishedAt: string; + externalId: string; + stories: BrazeCollectionStory[]; +}; + +export type BrazeCollectionStory = { + title: string; + url: string; + shortUrl: string; + excerpt: string; + imageUrl: string; + publisher: string; + authors: string[]; + externalId: string; +}; diff --git a/servers/braze-content-proxy/src/server.ts b/servers/braze-content-proxy/src/server.ts new file mode 100644 index 000000000..62b4f65f8 --- /dev/null +++ b/servers/braze-content-proxy/src/server.ts @@ -0,0 +1,50 @@ +import express, { Application, json } from 'express'; +import * as Sentry from '@sentry/node'; +import collectionRouter from './routes/collection'; +import scheduledStoriesRouter from './routes/scheduledItems'; +import { Server, createServer } from 'http'; +import { serverLogger } from '@pocket-tools/ts-logger'; + +export async function startServer(port: number) { + const app: Application = express(); + const httpServer: Server = createServer(app); + + app.use(json()); + app.get('/.well-known/server-health', (req, res) => { + res.status(200).send('ok'); + }); + + app.use('/collection/', collectionRouter); + app.use('/scheduled-items/', scheduledStoriesRouter); + + app.set('query parser', 'simple'); + app.get('/.well-known/server-health', (req, res) => { + res.status(200).send('ok'); + }); + + app.use((err, req, res, next) => { + if (res.headersSent) { + return next(err); + } + + // Log error to CloudWatch + serverLogger.error(err); + + // Send error to Sentry + Sentry.captureException(err); + + /** + * If Pocket Hits stories are unavailable for whatever reason, the emails + * should not be sent out. To achieve this, Braze needs to receive a 500 or 502 + * error if anything is amiss - if a 404 error is sent instead, Braze will + * render an empty string and proceed with sending out the email. + * + * See Braze docs on Connected Content: + * https://www.braze.com/docs/user_guide/personalization_and_dynamic_content/connected_content/making_an_api_call/ + */ + res.status(500).json({ error: err.message }); + }); + + await new Promise((resolve) => httpServer.listen({ port }, resolve)); + return { server: httpServer, app }; +} diff --git a/servers/braze-content-proxy/src/utils.spec.ts b/servers/braze-content-proxy/src/utils.spec.ts new file mode 100644 index 000000000..49e79b503 --- /dev/null +++ b/servers/braze-content-proxy/src/utils.spec.ts @@ -0,0 +1,78 @@ +import config from './config'; +import { validateDate, validateApiKey, getResizedImageUrl } from './utils'; + +describe('function validateDate', () => { + it('Allows a date in YYYY-MM-DD format', () => { + expect(() => { + validateDate('2050-01-01'); + }).not.toThrow(); + }); + + it('Disallows an empty date value', () => { + expect(() => { + validateDate(''); + }).toThrowError( + 'Not a valid date. Please provide a date in YYYY-MM-DD format.', + ); + }); + + it('Disallows a date in invalid format', () => { + expect(() => { + validateDate('29 Jan, 1900'); + }).toThrowError( + 'Not a valid date. Please provide a date in YYYY-MM-DD format.', + ); + }); +}); + +describe('function validateApiKey', () => { + it('should NOT throw an error when correct api key is provided', async () => { + await expect(validateApiKey(config.aws.brazeApiKey)).resolves.not.toThrow(); + }); + + it('should throw an error when an empty string is provided', async () => { + await expect(validateApiKey('')).rejects.toThrowError( + config.app.INVALID_API_KEY_ERROR_MESSAGE, + ); + }); + + it('should throw an error when provided key does not match braze api key', async () => { + await expect(validateApiKey('incorrect-api-key')).rejects.toThrowError( + config.app.INVALID_API_KEY_ERROR_MESSAGE, + ); + }); +}); + +describe('function getResizedImageUrl', () => { + it('should return resize image url with default filters when no filters are provided', () => { + const imageUrl = 'www.my-image-url.com'; + const resizedImageUrl = + `${config.images.protocol}://${config.images.host}/${config.images.width}x${config.images.height}/filters:${config.images.filters}/`.concat( + encodeURIComponent(imageUrl), + ); + + expect(getResizedImageUrl(imageUrl)).toEqual(resizedImageUrl); + }); + + it('should return resize image url with the correct filter values', () => { + const imageUrl = 'www.my-image-url.com'; + const customFilters = { + width: 200, + height: 200, + filters: 'format(jpeg):quality(90):no_upscale():strip_exif()', + }; + const resizedImageUrl = + `${config.images.protocol}://${config.images.host}/${customFilters.width}x${customFilters.height}/filters:${customFilters.filters}/`.concat( + encodeURIComponent(imageUrl), + ); + + expect( + getResizedImageUrl( + imageUrl, + customFilters.width, + customFilters.height, + customFilters.filters, + ), + ).toEqual(resizedImageUrl); + }); +}); diff --git a/servers/braze-content-proxy/src/utils.ts b/servers/braze-content-proxy/src/utils.ts new file mode 100644 index 000000000..87c1e9c4b --- /dev/null +++ b/servers/braze-content-proxy/src/utils.ts @@ -0,0 +1,68 @@ +/** + * Check if the scheduled surface GUID provided is on the list + * of surfaces needed by Braze. + * + * @param name + */ +import config from './config'; + +/** + * Check if the date string provided is in YYYY-MM-DD format. + * + * @param date + */ +export function validateDate(date: string): void { + const regEx = /^\d{4}-\d{2}-\d{2}$/; + + if (!date || date.match(regEx) === null) { + throw new Error( + 'Not a valid date. Please provide a date in YYYY-MM-DD format.', + ); + } + + return; +} + +/** + * Check if the API request is authorised. We store an API key in AWS Secrets Manager + * and provide it in Braze email templates so that API calls from Braze succeed. + * + * A rather simplistic way to ensure Pocket Hits data is not publicly available + * before it is sent out, but it is enough for our use case here. + * + * @param key + */ +export async function validateApiKey(key: string): Promise { + // Fail early on no key provided. + if (!key) { + throw new Error(config.app.INVALID_API_KEY_ERROR_MESSAGE); + } + + const storedKey = config.aws.brazeApiKey; + + // Compare the stored key to the one provided by the request to the API. + if (key !== storedKey) { + throw new Error(config.app.INVALID_API_KEY_ERROR_MESSAGE); + } + + return; +} + +/** + * + * @param imageUrl + * @param width + * @param height + * @param filters + * @returns image url with resize filters applied + */ +export function getResizedImageUrl( + imageUrl: string, + width: number = config.images.width, + height: number = config.images.height, + filters: string = config.images.filters, +): string { + return `${config.images.protocol}://${config.images.host}/${width}x${height}/filters:${filters}/`.concat( + encodeURIComponent(imageUrl), + ); +} diff --git a/servers/braze-content-proxy/tsconfig.json b/servers/braze-content-proxy/tsconfig.json new file mode 100644 index 000000000..753fd6667 --- /dev/null +++ b/servers/braze-content-proxy/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "tsconfig/graphql.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "exclude": ["node_modules", "dist", "**/.pnpm/*", "src/test"], + "include": ["src/**/*.ts", "src/config"] +} diff --git a/servers/client-api/.env.example b/servers/client-api/.env.example index 30fc17bc8..cafa86774 100644 --- a/servers/client-api/.env.example +++ b/servers/client-api/.env.example @@ -1,4 +1,7 @@ +REDIS_ENDPOINT=localhost:6379 +REDIS_PROTOCOL=redis +APP_ENVIRONMENT=local APOLLO_KEY=API_KEY_HERE -APOLLO_GRAPH_REF=pocket-client-api@development +APOLLO_GRAPH_REF=pocket-client-api@current PORT=4050 -OTLP_COLLECTOR_HOST=host.docker.internal \ No newline at end of file +OTLP_COLLECTOR_HOST=localhost \ No newline at end of file diff --git a/servers/client-api/Dockerfile b/servers/client-api/Dockerfile index bc165d188..f87cddf23 100644 --- a/servers/client-api/Dockerfile +++ b/servers/client-api/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/apollographql/router:v1.50.0@sha256:59aef3beaf6c8839c12ed5284ac20cdfb510f311d293a40d6fb373deec093cda +FROM ghcr.io/apollographql/router:v1.53.0@sha256:cfa48711d26bcc7b0320c990f6bf9d135914e1ce34c93d7f2d6ccc5f8314ee1f USER root diff --git a/servers/client-api/README.md b/servers/client-api/README.md index d8aece3cf..9d33c56ee 100644 --- a/servers/client-api/README.md +++ b/servers/client-api/README.md @@ -12,7 +12,8 @@ ## Commands - `docker build -t router .` builds the router image with the tag `router` for local testing. -- `rover dev --supergraph-config supergraph.yaml --router-config router.yaml` to run the Router locally without Docker (using [Rover]). You'll need to update the `supergraph.yaml` file to point at the local versions of your subgraphs. **Make sure to set the required environment variables ahead of time!** +- `dotenv rover dev --supergraph-config ./config/supergraph.yaml --router-config ./config/router.yaml` to run the Router locally without Docker (using [Rover]). You'll need to update the `supergraph.yaml` file to point at the local versions of your subgraphs. **Make sure to set the required environment variables ahead of time!** +- Alternatively you can use the prod or dev graph if you have an api key set like: `dotenv rover dev --graph-ref pocket-client-api@current --router-config ./config/router.yaml` and override it like `dotenv rover dev --graph-ref pocket-client-api@current --router-config ./config/router.yaml --name parser-graphql-wrapper --url http://localhost:4001`. `rover dev --name parser-graphql-wrapper --url http://localhost:4001` can also be ran in a seperate terminal window anytime after the first dev command is ran. - `docker run -it --env APOLLO_KEY --env APOLLO_GRAPH_REF -p4000:4000 router` runs the same router image you'll run in production. You can now query the router at `http://localhost:4000`. - Make sure to set the env vars `APOLLO_KEY` and `APOLLO_GRAPH_REF` first - You can alternatively create a file (e.g., `.env`) and run `docker run -it --env-file .env -v $(pwd)/config/router.yaml:/config/router.yaml -v $(pwd)/rhai:/dist/rhai -p4050:4050 router --dev --config /config/router.yaml`. **Make sure not to check the `.env` file into source control!** This will enable hot reloading and dev mode but use the production schemas. diff --git a/servers/client-api/config/router.yaml b/servers/client-api/config/router.yaml index 1930f12e3..4f78029ad 100644 --- a/servers/client-api/config/router.yaml +++ b/servers/client-api/config/router.yaml @@ -6,7 +6,7 @@ supergraph: query_planning: cache: redis: - urls: ['rediss-cluster://${env.REDIS_ENDPOINT}'] + urls: ['${env.REDIS_PROTOCOL:-rediss-cluster}://${env.REDIS_ENDPOINT}'] ttl: 48h # optional, by default no expiration include_subgraph_errors: all: true # Propagate errors from all subgraphs @@ -65,9 +65,6 @@ telemetry: - slug # collectionBySlug exporters: tracing: - otlp: - enabled: true - endpoint: 'http://${env.OTLP_COLLECTOR_HOST}:4317' common: resource: 'environment.name': '${env.APP_ENVIRONMENT}' @@ -83,5 +80,5 @@ apq: router: cache: redis: - urls: ['rediss-cluster://${env.REDIS_ENDPOINT}'] + urls: ['${env.REDIS_PROTOCOL:-rediss-cluster}://${env.REDIS_ENDPOINT}'] ttl: 24h # optional, by default no expiration diff --git a/servers/client-api/config/supergraph.yaml b/servers/client-api/config/supergraph.yaml index 0b073a840..6340b4894 100644 --- a/servers/client-api/config/supergraph.yaml +++ b/servers/client-api/config/supergraph.yaml @@ -1,10 +1,76 @@ -federation_version: =2.4.7 +federation_version: =2.7.0 subgraphs: - products: + # Pocket Monorepo + annotations-api: + routing_url: https://annotations-api.readitlater.com + # schema: + # subgraph_url: https://annotations-api.readitlater.com + schema: # Schema downloaded from GraphOS registry, does not poll for updates + graphref: pocket-client-api@current + subgraph: annotations-api + featureflags: + routing_url: https://featureflags.readitlater.com/graphql + schema: + subgraph_url: https://featureflags.readitlater.com/graphql + image-api: + routing_url: https://image-api.readitlater.com + schema: + subgraph_url: https://image-api.readitlater.com + list-api: + routing_url: https://list-api.readitlater.com + schema: + subgraph_url: https://list-api.readitlater.com + parser: + #routing_url: https://parser-graphql-wrapper.readitlater.com + #schema: + # subgraph_url: https://parser-graphql-wrapper.readitlater.com routing_url: http://localhost:4001 schema: subgraph_url: http://localhost:4001 - users: - routing_url: http://localhost:4002 + shareable-lists-api: + routing_url: https://shareablelistsapi.readitlater.com + schema: + subgraph_url: https://shareablelistsapi.readitlater.com + shares-api: + routing_url: https://shares-api.readitlater.com + schema: + subgraph_url: https://shares-api.readitlater.com + user: + routing_url: https://user-api.readitlater.com + schema: + subgraph_url: https://user-api.readitlater.com + user-list-search: + routing_url: https://user-list-search.readitlater.com/graphql + schema: + subgraph_url: https://user-list-search.readitlater.com/graphql + + # # Content Monorepo + collection: + routing_url: https://collection-api.readitlater.com + # schema: + # subgraph_url: https://collection-api.readitlater.com + schema: # Schema downloaded from GraphOS registry, does not poll for updates + graphref: pocket-client-api@current + subgraph: collection + curated-corpus: + routing_url: https://curated-corpus-api.readitlater.com + # schema: + # subgraph_url: https://curated-corpus-api.readitlater.com + schema: # Schema downloaded from GraphOS registry, does not poll for updates + graphref: pocket-client-api@current + subgraph: curated-corpus + # curation-tools: + # routing_url: https://curation-tools-api.readitlater.com + # schema: + # subgraph_url: https://curation-tools-api.readitlater.com + recommendation-api: + routing_url: https://recommendation-api.readitlater.com/ schema: - subgraph_url: http://localhost:4002 + subgraph_url: https://recommendation-api.readitlater.com/ + syndication: + routing_url: https://syndication-api-wrapper.readitlater.com/ + # schema: + # subgraph_url: https://syndication-api-wrapper.readitlater.com/ + schema: # Schema downloaded from GraphOS registry, does not poll for updates + graphref: pocket-client-api@current + subgraph: syndication \ No newline at end of file diff --git a/servers/feature-flags/package.json b/servers/feature-flags/package.json index 0cb1c8947..3f4240214 100644 --- a/servers/feature-flags/package.json +++ b/servers/feature-flags/package.json @@ -22,11 +22,11 @@ }, "dependencies": { "@apollo/server": "4.10.4", - "@apollo/subgraph": "2.8.3", + "@apollo/subgraph": "2.9.0", "@govtechsg/passport-openidconnect": "1.0.2", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/sentry": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "body-parser": "1.20.2", "cors": "2.8.5", "express": "4.19.2", @@ -48,15 +48,15 @@ "@types/express-session": "1.18.0", "@types/jest": "29.5.12", "@types/jsonwebtoken": "^9.0.5", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "@types/passport": "1.0.16", "@types/passport-jwt": "4.0.1", "jest": "29.7.0", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/servers/feature-flags/src/unleashClient/strategy/accountAge.ts b/servers/feature-flags/src/unleashClient/strategy/accountAge.ts index b90996893..82c2c6373 100644 --- a/servers/feature-flags/src/unleashClient/strategy/accountAge.ts +++ b/servers/feature-flags/src/unleashClient/strategy/accountAge.ts @@ -1,7 +1,7 @@ import { Strategy } from 'unleash-client'; import { UnleashContext } from '../../graphql/typeDefs'; import { normalizedStrategyValue } from 'unleash-client/lib/strategy/util'; -import { AccountAgeError, SessionIdError } from '../../utils/customErrors'; +import { AccountAgeError } from '../../utils/customErrors'; import * as Sentry from '@sentry/node'; const DAY_IN_MILLISECONDS = 86400000; @@ -15,12 +15,7 @@ export class AccountAgeStrategy extends Strategy { try { const groupId = parameters.groupId || context.featureToggle || ''; const percentage = Number(parameters.rollout); - const stickinessId = context.userId || context.sessionId; - - // If there is no sticky id - if (!stickinessId || !stickinessId?.length) { - throw new SessionIdError('No Stickiness ID Provided'); - } + const stickinessId = context.userId || context.sessionId || ''; // Check for valid start date const accountAge = parameters?.accountAge; diff --git a/servers/feature-flags/src/unleashClient/strategy/accountAgeAtStart.ts b/servers/feature-flags/src/unleashClient/strategy/accountAgeAtStart.ts index 858fc4de5..424996491 100644 --- a/servers/feature-flags/src/unleashClient/strategy/accountAgeAtStart.ts +++ b/servers/feature-flags/src/unleashClient/strategy/accountAgeAtStart.ts @@ -1,11 +1,7 @@ import { Strategy } from 'unleash-client'; import { UnleashContext } from '../../graphql/typeDefs'; import { normalizedStrategyValue } from 'unleash-client/lib/strategy/util'; -import { - StartDateError, - AccountAgeError, - SessionIdError, -} from '../../utils/customErrors'; +import { StartDateError, AccountAgeError } from '../../utils/customErrors'; import * as Sentry from '@sentry/node'; const DAY_IN_MILLISECONDS = 86400000; @@ -19,12 +15,7 @@ export class AccountAgeAtStartStrategy extends Strategy { try { const groupId = parameters.groupId || context.featureToggle || ''; const percentage = Number(parameters.rollout); - const stickinessId = context.userId || context.sessionId; - - // If there is no sticky id - if (!stickinessId || !stickinessId?.length) { - throw new SessionIdError('No Stickiness ID Provided'); - } + const stickinessId = context.userId || context.sessionId || ''; // Check for valid start date const startDate = Date.parse(parameters?.startDate); diff --git a/servers/feature-flags/src/unleashClient/strategy/hasUserModel.ts b/servers/feature-flags/src/unleashClient/strategy/hasUserModel.ts index 928d3ed11..edb0d4888 100644 --- a/servers/feature-flags/src/unleashClient/strategy/hasUserModel.ts +++ b/servers/feature-flags/src/unleashClient/strategy/hasUserModel.ts @@ -1,7 +1,6 @@ import { Strategy } from 'unleash-client'; import { UnleashContext, RecItUserProfile } from '../../graphql/typeDefs'; import { normalizedStrategyValue } from 'unleash-client/lib/strategy/util'; -import { SessionIdError } from '../../utils/customErrors'; import * as Sentry from '@sentry/node'; export class HasUserModel extends Strategy { @@ -13,12 +12,7 @@ export class HasUserModel extends Strategy { try { const groupId = parameters.groupId || context.featureToggle || ''; const percentage = Number(parameters.rollout); - const stickinessId = context.userId || context.sessionId; - - // If there is no sticky id - if (!stickinessId || !stickinessId?.length) { - throw new SessionIdError('No Stickiness ID Provided'); - } + const stickinessId = context.userId || context.sessionId || ''; // Users without a user profile are not eligible. const userProfileString = context?.properties?.recItUserProfile; diff --git a/servers/feature-flags/src/unleashClient/strategy/newUser.ts b/servers/feature-flags/src/unleashClient/strategy/newUser.ts index 458f0f9c7..ac98280b6 100644 --- a/servers/feature-flags/src/unleashClient/strategy/newUser.ts +++ b/servers/feature-flags/src/unleashClient/strategy/newUser.ts @@ -1,7 +1,7 @@ import { Strategy } from 'unleash-client'; import { UnleashContext } from '../../graphql/typeDefs'; import { normalizedStrategyValue } from 'unleash-client/lib/strategy/util'; -import { StartDateError, SessionIdError } from '../../utils/customErrors'; +import { StartDateError } from '../../utils/customErrors'; import * as Sentry from '@sentry/node'; export class NewUserStrategy extends Strategy { @@ -13,12 +13,7 @@ export class NewUserStrategy extends Strategy { try { const groupId = parameters.groupId || context.featureToggle || ''; const percentage = Number(parameters.rollout); - const stickinessId = context.userId || context.sessionId; - - // If there is no sticky id - if (!stickinessId || !stickinessId?.length) { - throw new SessionIdError('No Stickiness ID Provided'); - } + const stickinessId = context.userId || context.sessionId || ''; // Check for valid start date const startDate = Date.parse(parameters?.startDate); diff --git a/servers/feature-flags/src/unleashClient/strategy/newUserInLocale.ts b/servers/feature-flags/src/unleashClient/strategy/newUserInLocale.ts index 8fb3398c6..ecdc98907 100644 --- a/servers/feature-flags/src/unleashClient/strategy/newUserInLocale.ts +++ b/servers/feature-flags/src/unleashClient/strategy/newUserInLocale.ts @@ -2,7 +2,7 @@ import { Strategy } from 'unleash-client'; import { UnleashContext } from '../../graphql/typeDefs'; import { normalizedStrategyValue } from 'unleash-client/lib/strategy/util'; import { pocketSupportedLocales } from '../../utils/pocketSupportedLocales'; -import { StartDateError, SessionIdError } from '../../utils/customErrors'; +import { StartDateError } from '../../utils/customErrors'; import * as Sentry from '@sentry/node'; export class NewUserInLocaleStrategy extends Strategy { @@ -14,12 +14,7 @@ export class NewUserInLocaleStrategy extends Strategy { try { const groupId = parameters.groupId || context.featureToggle || ''; const percentage = Number(parameters.rollout); - const stickinessId = context.userId || context.sessionId; - - // If there is no sticky id - if (!stickinessId || !stickinessId?.length) { - throw new SessionIdError('No Stickiness ID Provided'); - } + const stickinessId = context.userId || context.sessionId || ''; // Check for language const passedLocale = context?.properties?.locale || 'en'; diff --git a/servers/feature-flags/src/unleashClient/strategy/userInLocale.ts b/servers/feature-flags/src/unleashClient/strategy/userInLocale.ts index 8a94c98ab..26cc3459e 100644 --- a/servers/feature-flags/src/unleashClient/strategy/userInLocale.ts +++ b/servers/feature-flags/src/unleashClient/strategy/userInLocale.ts @@ -1,7 +1,6 @@ import { Strategy } from 'unleash-client'; import { UnleashContext } from '../../graphql/typeDefs'; import { normalizedStrategyValue } from 'unleash-client/lib/strategy/util'; -import { SessionIdError } from '../../utils/customErrors'; import * as Sentry from '@sentry/node'; export class UserInLocaleStrategy extends Strategy { @@ -13,12 +12,7 @@ export class UserInLocaleStrategy extends Strategy { try { const groupId = parameters.groupId || context.featureToggle || ''; const percentage = Number(parameters.rollout); - const stickinessId = context.userId || context.sessionId; - - // If there is no sticky id - if (!stickinessId || !stickinessId?.length) { - throw new SessionIdError('No Stickiness ID Provided'); - } + const stickinessId = context.userId || context.sessionId || ''; // Check for locale const locale = context?.properties?.locale; diff --git a/servers/feature-flags/src/utils/customErrors.ts b/servers/feature-flags/src/utils/customErrors.ts index 12925bfc8..d3da68463 100644 --- a/servers/feature-flags/src/utils/customErrors.ts +++ b/servers/feature-flags/src/utils/customErrors.ts @@ -18,10 +18,3 @@ export class AccountCreatedAtError extends Error { this.name = 'AccountCreatedAtError'; } } - -export class SessionIdError extends Error { - constructor(message: string) { - super(message); - this.name = 'SessionIdError'; - } -} diff --git a/servers/image-api/package.json b/servers/image-api/package.json index b0a50ae33..1ff4ba250 100644 --- a/servers/image-api/package.json +++ b/servers/image-api/package.json @@ -23,37 +23,36 @@ }, "dependencies": { "@apollo/server": "4.10.4", - "@apollo/subgraph": "2.8.3", + "@apollo/subgraph": "2.9.0", "@apollo/utils.keyvadapter": "3.1.0", "@keyv/redis": "2.8.5", "@pocket-tools/apollo-utils": "workspace:*", + "@pocket-tools/image-utils": "workspace:*", "@pocket-tools/sentry": "workspace:*", - "@pocket-tools/tracing": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", - "axios": "1.7.2", + "@sentry/node": "8.27.0", + "axios": "1.7.4", "axios-retry": "4.4.0", "dataloader": "2.2.2", "express": "4.19.2", "graphql": "16.8.1", "graphql-tag": "2.12.6", "keyv": "4.5.4", - "parse-url": "9.2.0", "tslib": "2.6.3" }, "devDependencies": { "@jest/globals": "29.7.0", "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", "jest-extended": "4.0.2", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", "supertest": "7.0.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/servers/image-api/src/pocketImageCache/metadata.ts b/servers/image-api/src/pocketImageCache/metadata.ts index afb17cc2c..13f5fc792 100644 --- a/servers/image-api/src/pocketImageCache/metadata.ts +++ b/servers/image-api/src/pocketImageCache/metadata.ts @@ -25,7 +25,7 @@ export const getImageMetadata = async (url: string): Promise => { width: response.data.thumbor.source.width, height: response.data.thumbor.source.height, }; - } catch (error: any) { + } catch { console.log('Error requesting metadata', { metadata: metadataUrl }); throw new Error('Could not get image metadata'); } diff --git a/servers/image-api/src/resolvers/index.ts b/servers/image-api/src/resolvers/index.ts index 33974f2f1..14e6d1fce 100644 --- a/servers/image-api/src/resolvers/index.ts +++ b/servers/image-api/src/resolvers/index.ts @@ -1,6 +1,6 @@ import { IContext } from '../server/context'; import { Image, CachedImageInput, CachedImage } from '../types'; -import { getOriginalUrlIfPocketImageCached } from '../pocketImageCache/utils'; +import { getOriginalUrlIfPocketImageCached } from '@pocket-tools/image-utils'; import { getPocketImageCachePath } from '../pocketImageCache'; import config from '../config'; diff --git a/servers/image-api/src/server/main.ts b/servers/image-api/src/server/main.ts index 08d515fa0..d43fab6e7 100644 --- a/servers/image-api/src/server/main.ts +++ b/servers/image-api/src/server/main.ts @@ -4,24 +4,13 @@ import { initSentry } from '@pocket-tools/sentry'; initSentry({ ...config.sentry, debug: config.sentry.environment == 'development', - skipOpenTelemetrySetup: true, }); -//this must run before all imports and server start but after sentry -//so open-telemetry can patch all libraries that we use -import { nodeSDKBuilder } from '@pocket-tools/tracing'; + +import { startServer } from './apollo'; import { serverLogger } from '@pocket-tools/ts-logger'; -nodeSDKBuilder({ - host: config.tracing.host, - serviceName: config.tracing.serviceName, - release: config.sentry.release, - logger: serverLogger, - addSentry: true, -}).then(async () => { - await startServer(config.app.serverPort); +startServer(config.app.serverPort).then(() => { serverLogger.info( `🚀 Public server ready at http://localhost:${config.app.serverPort}`, ); }); - -import { startServer } from './apollo'; diff --git a/servers/list-api/package.json b/servers/list-api/package.json index c416a6999..6e02854f1 100644 --- a/servers/list-api/package.json +++ b/servers/list-api/package.json @@ -21,17 +21,16 @@ }, "dependencies": { "@apollo/server": "4.10.4", - "@apollo/subgraph": "2.8.3", - "@aws-sdk/client-eventbridge": "3.609.0", - "@aws-sdk/client-kinesis": "3.609.0", - "@aws-sdk/client-sqs": "3.609.0", + "@apollo/subgraph": "2.9.0", + "@aws-sdk/client-eventbridge": "3.632.0", + "@aws-sdk/client-kinesis": "3.632.0", + "@aws-sdk/client-sqs": "3.632.0", "@pocket-tools/apollo-cursor-pagination": "1.0.3", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/int-mask": "workspace:*", "@pocket-tools/sentry": "workspace:*", - "@pocket-tools/tracing": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "@snowplow/node-tracker": "3.23.1", "@snowplow/tracker-core": "3.23.1", "dataloader": "2.2.2", @@ -60,17 +59,17 @@ "@types/locutus": "0.0.8", "@types/lodash": "4.17.7", "@types/luxon": "3.4.2", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "@types/supertest": "^6.0.2", - "chance": "1.1.11", + "chance": "1.1.12", "jest": "29.7.0", "jest-extended": "4.0.2", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", "supertest": "7.0.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/servers/list-api/src/externalCaller/parserCaller.spec.ts b/servers/list-api/src/externalCaller/parserCaller.spec.ts index 38be67104..3fb6eda84 100644 --- a/servers/list-api/src/externalCaller/parserCaller.spec.ts +++ b/servers/list-api/src/externalCaller/parserCaller.spec.ts @@ -1,14 +1,19 @@ import { ParserCaller } from './parserCaller'; -import nock from 'nock'; import config from '../config'; import { mockParserGetItemRequest, mockParserGetItemIdRequest, } from '../test/utils/parserMocks'; +import nock, { cleanAll, restore } from 'nock'; describe('ParserCallerTest', function () { const urlToParse = 'https://igiveyou.a.test'; + afterAll(() => { + cleanAll(); + restore(); + }); + it('should retrieve item from parser service', async () => { mockParserGetItemRequest(urlToParse, { item: { diff --git a/servers/list-api/src/server/main.ts b/servers/list-api/src/server/main.ts index eb87f5009..ab77fb3f6 100644 --- a/servers/list-api/src/server/main.ts +++ b/servers/list-api/src/server/main.ts @@ -4,28 +4,13 @@ import { initSentry } from '@pocket-tools/sentry'; initSentry({ ...config.sentry, debug: config.sentry.environment == 'development', - skipOpenTelemetrySetup: true, }); -//this must run before all imports and server start but after sentry -//so open-telemetry can patch all libraries that we use -import { - AdditionalInstrumentation, - nodeSDKBuilder, -} from '@pocket-tools/tracing'; import { serverLogger } from '@pocket-tools/ts-logger'; -nodeSDKBuilder({ - host: config.tracing.host, - serviceName: config.tracing.serviceName, - release: config.sentry.release, - logger: serverLogger, - additionalInstrumentations: [AdditionalInstrumentation.KNEX], - addSentry: true, -}).then(async () => { - await startServer(config.app.port); +import { startServer } from './apollo'; + +startServer(config.app.port).then(() => { serverLogger.info( `🚀 Public server ready at http://localhost:${config.app.port}`, ); }); - -import { startServer } from './apollo'; diff --git a/servers/list-api/src/test/graphql/mutations/clearTags.integration.ts b/servers/list-api/src/test/graphql/mutations/clearTags.integration.ts index 495a12db1..65337273e 100644 --- a/servers/list-api/src/test/graphql/mutations/clearTags.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/clearTags.integration.ts @@ -5,6 +5,7 @@ import { Application } from 'express'; import { ApolloServer } from '@apollo/server'; import request from 'supertest'; import { mockParserGetItemIdRequest } from '../../utils/parserMocks'; +import { restore, cleanAll } from 'nock'; describe('clearTags mutation', () => { //using write client as mutation will use write client to read as well. @@ -93,6 +94,8 @@ describe('clearTags mutation', () => { await readDb.destroy(); jest.restoreAllMocks(); jest.useRealTimers(); + restore(); + cleanAll(); await server.stop(); }); afterEach(() => eventSpy.mockClear()); diff --git a/servers/list-api/src/test/graphql/mutations/replaceTags.integration.ts b/servers/list-api/src/test/graphql/mutations/replaceTags.integration.ts index e1c0932bb..3814e2b9e 100644 --- a/servers/list-api/src/test/graphql/mutations/replaceTags.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/replaceTags.integration.ts @@ -5,6 +5,7 @@ import { Application } from 'express'; import { ApolloServer } from '@apollo/server'; import request from 'supertest'; import { mockParserGetItemIdRequest } from '../../utils/parserMocks'; +import { restore, cleanAll } from 'nock'; describe('clearTags mutation', () => { //using write client as mutation will use write client to read as well. @@ -93,6 +94,8 @@ describe('clearTags mutation', () => { await readDb.destroy(); jest.restoreAllMocks(); jest.useRealTimers(); + restore(); + cleanAll(); await server.stop(); }); afterEach(() => eventSpy.mockClear()); diff --git a/servers/list-api/src/test/graphql/mutations/savedItemById/savedItemsMutationService-upsert.integration.ts b/servers/list-api/src/test/graphql/mutations/savedItemById/savedItemsMutationService-upsert.integration.ts index 279382825..e63d517a1 100644 --- a/servers/list-api/src/test/graphql/mutations/savedItemById/savedItemsMutationService-upsert.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/savedItemById/savedItemsMutationService-upsert.integration.ts @@ -1,5 +1,4 @@ import { readClient, writeClient } from '../../../../database/client'; -import nock, { cleanAll } from 'nock'; import config from '../../../../config'; import { EventType, @@ -23,6 +22,7 @@ import { Application } from 'express'; import { ApolloServer } from '@apollo/server'; import request from 'supertest'; import type { Knex } from 'knex'; +import nock, { cleanAll, restore } from 'nock'; function mockParserGetItemRequest(urlToParse: string, data: any) { nock(config.parserDomain) @@ -84,11 +84,12 @@ describe('UpsertSavedItem Mutation', () => { }); afterAll(async () => { + restore(); + cleanAll(); await writeDb.destroy(); await readDb.destroy(); jest.useRealTimers(); jest.restoreAllMocks(); - cleanAll(); await server.stop(); }); diff --git a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemArchive.integration.ts b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemArchive.integration.ts index ed636e2a6..c0510e3e5 100644 --- a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemArchive.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemArchive.integration.ts @@ -7,6 +7,7 @@ import { gql } from 'graphql-tag'; import { print } from 'graphql'; import request from 'supertest'; import { mockParserGetItemIdRequest } from '../../../utils/parserMocks'; +import { cleanAll, restore } from 'nock'; describe('savedItemArchive mutation', function () { const writeDb = writeClient(); @@ -64,6 +65,8 @@ describe('savedItemArchive mutation', function () { await server.stop(); await writeDb.destroy(); await readDb.destroy(); + restore(); + cleanAll(); jest.restoreAllMocks(); }); diff --git a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemDelete.integration.ts b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemDelete.integration.ts index 498e48f25..f61404814 100644 --- a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemDelete.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemDelete.integration.ts @@ -7,6 +7,7 @@ import { gql } from 'graphql-tag'; import { print } from 'graphql'; import request from 'supertest'; import { mockParserGetItemIdRequest } from '../../../utils/parserMocks'; +import { restore, cleanAll } from 'nock'; describe('savedItemDelete mutation', function () { const writeDb = writeClient(); @@ -101,6 +102,8 @@ describe('savedItemDelete mutation', function () { await server.stop(); await writeDb.destroy(); await readDb.destroy(); + restore(); + cleanAll(); jest.restoreAllMocks(); }); diff --git a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemFavorite.integration.ts b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemFavorite.integration.ts index 7b3afd0fe..cf66b8e86 100644 --- a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemFavorite.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemFavorite.integration.ts @@ -7,6 +7,7 @@ import { gql } from 'graphql-tag'; import { print } from 'graphql'; import request from 'supertest'; import { mockParserGetItemIdRequest } from '../../../utils/parserMocks'; +import { cleanAll, restore } from 'nock'; describe('savedItemFavorite mutation', function () { const writeDb = writeClient(); @@ -64,6 +65,8 @@ describe('savedItemFavorite mutation', function () { await server.stop(); await writeDb.destroy(); await readDb.destroy(); + restore(); + cleanAll(); jest.restoreAllMocks(); }); diff --git a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemTag.integration.ts b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemTag.integration.ts index a17c7065c..2b96e97b9 100644 --- a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemTag.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemTag.integration.ts @@ -8,6 +8,7 @@ import { gql } from 'graphql-tag'; import { print } from 'graphql'; import request from 'supertest'; import { EventType } from '../../../../businessEvents'; +import { restore, cleanAll } from 'nock'; describe('savedItemTag mutation', () => { const writeDb = writeClient(); @@ -92,6 +93,8 @@ describe('savedItemTag mutation', () => { await server.stop(); await writeDb.destroy(); await readDb.destroy(); + restore(); + cleanAll(); jest.restoreAllMocks(); }); it('should add tags to a SavedItem with no tags', async () => { diff --git a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnArchive.integration.ts b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnArchive.integration.ts index 19871aa60..83b20275f 100644 --- a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnArchive.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnArchive.integration.ts @@ -7,6 +7,7 @@ import { gql } from 'graphql-tag'; import { print } from 'graphql'; import request from 'supertest'; import { mockParserGetItemIdRequest } from '../../../utils/parserMocks'; +import { restore, cleanAll } from 'nock'; describe('savedItemUnArchive mutation', function () { const writeDb = writeClient(); @@ -63,6 +64,8 @@ describe('savedItemUnArchive mutation', function () { await server.stop(); await writeDb.destroy(); await readDb.destroy(); + restore(); + cleanAll(); jest.restoreAllMocks(); }); diff --git a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnDelete.integration.ts b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnDelete.integration.ts index 41b131e1f..00434692d 100644 --- a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnDelete.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnDelete.integration.ts @@ -7,6 +7,7 @@ import { gql } from 'graphql-tag'; import { print } from 'graphql'; import request from 'supertest'; import { mockParserGetItemIdRequest } from '../../../utils/parserMocks'; +import { restore, cleanAll } from 'nock'; describe('savedItemUnDelete mutation', function () { const writeDb = writeClient(); @@ -65,6 +66,8 @@ describe('savedItemUnDelete mutation', function () { await server.stop(); await writeDb.destroy(); await readDb.destroy(); + restore(); + cleanAll(); }); it('should "undelete" an "unread" savedItem', async () => { diff --git a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnFavorite.integration.ts b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnFavorite.integration.ts index e603d38d1..1fd1225c1 100644 --- a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnFavorite.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUnFavorite.integration.ts @@ -7,6 +7,7 @@ import { gql } from 'graphql-tag'; import { print } from 'graphql'; import request from 'supertest'; import { mockParserGetItemIdRequest } from '../../../utils/parserMocks'; +import { restore, cleanAll } from 'nock'; describe('savedItemUnFavorite mutation', function () { const writeDb = writeClient(); @@ -64,6 +65,8 @@ describe('savedItemUnFavorite mutation', function () { await server.stop(); await writeDb.destroy(); await readDb.destroy(); + restore(); + cleanAll(); jest.restoreAllMocks(); }); diff --git a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUpdateTitle.integration.ts b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUpdateTitle.integration.ts index 2f88e22ea..394495868 100644 --- a/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUpdateTitle.integration.ts +++ b/servers/list-api/src/test/graphql/mutations/savedItemByUrl/savedItemUpdateTitle.integration.ts @@ -7,6 +7,7 @@ import { gql } from 'graphql-tag'; import { print } from 'graphql'; import request from 'supertest'; import { mockParserGetItemIdRequest } from '../../../utils/parserMocks'; +import { restore, cleanAll } from 'nock'; describe('savedItemArchive mutation', function () { const writeDb = writeClient(); @@ -86,6 +87,8 @@ describe('savedItemArchive mutation', function () { await server.stop(); await writeDb.destroy(); await readDb.destroy(); + restore(); + cleanAll(); jest.restoreAllMocks(); }); diff --git a/servers/list-api/src/test/graphql/queries/item.integration.ts b/servers/list-api/src/test/graphql/queries/item.integration.ts index e7c0317ae..c7e58c459 100644 --- a/servers/list-api/src/test/graphql/queries/item.integration.ts +++ b/servers/list-api/src/test/graphql/queries/item.integration.ts @@ -143,8 +143,8 @@ describe('item', () => { query: GET_TWO_SAVED_ITEMS, variables, }); - expect(res.body.errors).toBeUndefined; - expect(res.body.data).not.toBeUndefined; + expect(res.body.errors).toBeUndefined(); + expect(res.body.data).not.toBeUndefined(); const entities = res.body.data._entities; expect(entities.length).toEqual(2); expect(entities).toEqual(expect.arrayContaining(expected)); @@ -169,8 +169,8 @@ describe('item', () => { variables, }); - expect(res.body.errors).toBeUndefined; - expect(res.body.data).not.toBeUndefined; + expect(res.body.errors).toBeUndefined(); + expect(res.body.data).not.toBeUndefined(); const entities = res.body.data._entities; expect(entities.length).toEqual(1); expect(entities[0]).toEqual(expected); @@ -185,13 +185,13 @@ describe('item', () => { query: GET_SAVED_ITEM, variables, }); - expect(res.body.data).not.toBeUndefined; - expect(res.body.errors).toBeUndefined; + expect(res.body.data).not.toBeUndefined(); + expect(res.body.errors).toBeUndefined(); const entities = res.body.data._entities; expect(entities.length).toEqual(1); expect(entities[0].givenUrl).toEqual( 'https://www.youtube.com/watch?v=Tpbo25iBvfU', ); - expect(entities[0].savedItem).toBeNull; + expect(entities[0].savedItem).toBeNull(); }); }); diff --git a/servers/parser-graphql-wrapper/package.json b/servers/parser-graphql-wrapper/package.json index 40ef0e20f..95fd9b0ad 100644 --- a/servers/parser-graphql-wrapper/package.json +++ b/servers/parser-graphql-wrapper/package.json @@ -22,20 +22,20 @@ "@apollo/cache-control-types": "1.0.3", "@apollo/datasource-rest": "^6.2.2", "@apollo/server": "4.10.4", - "@apollo/subgraph": "2.8.3", + "@apollo/subgraph": "2.9.0", "@apollo/utils.keyvadapter": "3.1.0", "@apollo/utils.keyvaluecache": "3.1.0", - "@aws-sdk/client-dynamodb": "3.609.0", - "@aws-sdk/lib-dynamodb": "3.609.0", + "@aws-sdk/client-dynamodb": "3.632.0", + "@aws-sdk/lib-dynamodb": "3.632.0", "@extractus/oembed-extractor": "^3.2.1", "@keyv/redis": "2.8.5", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/feature-flags-client": "workspace:*", + "@pocket-tools/image-utils": "workspace:*", "@pocket-tools/int-mask": "workspace:*", "@pocket-tools/sentry": "workspace:*", - "@pocket-tools/tracing": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "cors": "2.8.5", "dataloader": "2.2.2", "domino": "2.1.6", @@ -49,6 +49,7 @@ "kysely": "0.27.3", "lodash": "4.17.21", "luxon": "3.4.4", + "markdown-to-txt": "2.0.1", "md5": "2.3.0", "mysql2": "3.10.3", "open-graph-scraper": "6.5.2", @@ -67,17 +68,17 @@ "@types/cors": "^2.8.17", "@types/express": "4.17.21", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", - "@types/turndown": "5.0.4", + "@types/node": "^20.16", + "@types/turndown": "5.0.5", "concurrently": "^8.2.2", "jest": "29.7.0", "kysely-codegen": "^0.15.0", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", "supertest": "7.0.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } -} +} \ No newline at end of file diff --git a/servers/parser-graphql-wrapper/schema-admin.graphql b/servers/parser-graphql-wrapper/schema-admin.graphql new file mode 100644 index 000000000..49ec9020e --- /dev/null +++ b/servers/parser-graphql-wrapper/schema-admin.graphql @@ -0,0 +1,556 @@ +extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.0" + import: [ + "@key" + "@shareable" + "@requires" + "@external" + "@tag" + "@inaccessible" + ] + ) +"A String representing a date in the format of `yyyy-MM-dd HH:mm:ss`" +scalar DateString +""" +ISOString scalar - all datetimes fields are Typescript Date objects on this server & +returned as ISO-8601 encoded date strings (e.g. ISOString scalars) to GraphQL clients. +See Section 5.6 of the RFC 3339 profile of the ISO 8601 standard: https://www.ietf.org/rfc/rfc3339.txt. +""" +scalar ISOString + +""" +A string formatted with CommonMark markdown, +plus the strikethrough extension from GFM. +This Scalar is for documentation purposes; otherwise +not treated differently from String in the API. +""" +scalar Markdown + +"A String in the format of a url." +scalar Url +scalar ValidUrl + +enum CacheControlScope { + PUBLIC + PRIVATE +} + +""" +We need to manually implement cacheControl in the schema for now +https://stackoverflow.com/questions/52922080/how-to-implement-caching-on-apollo-server-hapi-graphql +https://github.com/apollographql/federation/issues/356 +""" +directive @cacheControl( + maxAge: Int + scope: CacheControlScope +) on FIELD_DEFINITION | OBJECT | INTERFACE + +""" +The heart of Pocket +A url and meta data related to it. +""" +type Item + @key(fields: "givenUrl") + @key(fields: "itemId") + @cacheControl(maxAge: 86400) { + "A server generated unique id for this item. Item's whose normalUrl are the same will have the same item_id. Most likely numeric, but to ensure future proofing this can be treated as a String in apps." + itemId: String! + "A server generated unique id for this item based on itemId" + id: ID! + "A server generated unique reader slug for this item based on itemId" + readerSlug: String! + """ + A normalized value of the givenUrl. + It will look like a url but is not guaranteed to be a valid url, just a unique string that is used to eliminate common duplicates. + Item's that share a normal_url should be considered the same item. For example https://getpocket.com and http://getpocket.com will be considered the same since they both normalize to http://getpocket.com + This is technically the true identity of an item, since this is what the backend uses to tell if two items are the same. + However, for the clients to use this, they would all have to ship an implementation of the normalization function that the backend has exactly. + And even if it did that, some items, some of the earliest saves, use a legacy normalize function and the client would have no way to know when to use which normalizing function. + """ + normalUrl: String! + "If available, the url to an AMP version of this article" + ampUrl: Url + """ + Provides short url for the given_url in the format: https://pocket.co/. + marked as beta because it's not ready yet for large client request. + """ + shortUrl: Url @tag(name: "beta") + "List of Authors involved with this article" + authors: [Author] + "The domain, such as 'getpocket.com' of the resolved_url" + domain: String + "Additional information about the item domain, when present, use this for displaying the domain name" + domainMetadata: DomainMetadata + "The string encoding code of this item's web page" + encoding: String + "A snippet of text from the article" + excerpt: String + "0=no images, 1=contains images, 2=is an image" + hasImage: Imageness + "0=no videos, 1=contains video, 2=is a video" + hasVideo: Videoness + "Array of images within an article" + images: [Image] + "true if the item is an article" + isArticle: Boolean + "true if the item is an index / home page, rather than a specific single piece of content" + isIndex: Boolean + "The mime type of this item's web page" + mimeType: String + "The item id of the resolved_url" + resolvedId: String + "If the givenUrl redirects (once or many times), this is the final url. Otherwise, same as givenUrl" + resolvedUrl: Url + "The title as determined by the parser." + title: String + "The page's / publisher's preferred thumbnail image" + topImageUrl: Url @deprecated(reason: "use the topImage object") + "The page's / publisher's preferred thumbnail image" + topImage: Image + "Array of videos within the item If the item is a video, this will likely just contain one video" + videos: [Video] + "Number of words in the article" + wordCount: Int + "The date the parser resolved this item" + dateResolved: DateString + "The date the article was published" + datePublished: DateString + "The detected language of the article" + language: String + "How long it will take to read the article (TODO in what time unit? and by what calculation?)" + timeToRead: Int + "Estimated time to listen to the article, in seconds" + listenDuration: Int + """ + The url as provided by the user when saving. Only http or https schemes allowed. + + CAUTION: this value will *likely* (but not always) change depending on which query is used. + itemByItemId will return the normalUrl value here (which is a bug?). itemByUrl will return + the URL value passed in to the query. As if that weren't complicated enough, sometimes + normalUrl and givenUrl are the same (but not usually). + """ + givenUrl: Url! + "Indicates that the item was stored via a different search_hash (using the old method), we'll need to look up a different id" + hasOldDupes: Boolean @deprecated(reason: "Most new items use a new hash") + "The primary database id of the domain this article is from" + domainId: String @deprecated(reason: "Use a domain as the identifier instead") + "If a the domainId is a subdomain this is the primary domain id" + originDomainId: String + @deprecated(reason: "Use a domain as the identifier instead") + "The http response code of the given url" + responseCode: Int @deprecated(reason: "Clients should not use this") + "The length in bytes of the content" + contentLength: Int @deprecated(reason: "Clients should not use this") + "Indicates if the text of the url is a redirect to another url" + innerDomainRedirect: Boolean + @deprecated(reason: "Clients should not use this") + "Indicates if the url requires a login" + loginRequired: Boolean @deprecated(reason: "Clients should not use this") + "Indicates if the parser used fallback methods" + usedFallback: Int @deprecated(reason: "Clients should not use this") + "Date this item was first parsed in Pocket" + timeFirstParsed: DateString @deprecated(reason: "Clients should not use this") + "The resolved url, but ran through the normalized function" + resolvedNormalUrl: Url @deprecated(reason: "Use the resolved url instead") + """ + The pocket HTML string of the article. + Note: Web and Android as of 3/4/2022 use the Article field, any improvements made + within MArticle for parsing will not be reflected in the article field. + When that happens, the clients will work to move to MArticle. + """ + article: String + + "If the url is an Article, the text in SSML format for speaking, i.e. Listen" + ssml: String @tag(name: "beta") + + "The Marticle format of the article, used by clients for native article view." + marticle: [MarticleComponent!] + + "The client preview/display logic for this url" + preview: PocketMetadata +} + +type ArticleMarkdown { + text: String! + images: [MarkdownImagePosition!] +} + +type MarkdownImagePosition { + index: Int! + position: Int! + """ + Fallback is to use the images field in the Item entity + """ + src: String +} + +""" +Metadata from a domain, originally populated from ClearBit +""" +type DomainMetadata @cacheControl(maxAge: 86400) { + "The name of the domain (e.g., The New York Times)" + name: String + "Url for the logo image" + logo: Url + "Url for the greyscale logo image" + logoGreyscale: Url +} + +""" +An image, typically a thumbnail or article view image for an Item +""" +type Image @cacheControl(maxAge: 86400) @key(fields: "url") { + "Absolute url to the image" + url: Url! + "A caption or description of the image" + caption: String + "A credit for the image, typically who the image belongs to / created by" + credit: String + "If known, the height of the image in px" + height: Int @shareable + "The id for placing within an Article View. Item.article will have placeholders of
where X is this id. Apps can download those images as needed and populate them in their article view." + imageId: Int! + "Absolute url to the image" + src: String! @deprecated(reason: "use url property moving forward") + "If known, the width of the image in px" + width: Int @shareable + "If the image is also a link, the destination url" + targetUrl: String +} + +enum Imageness { + "No images (v3 value is 0)" + NO_IMAGES + "Contains images (v3 value is 1)" + HAS_IMAGES + "Is an image (v3 value is 2)" + IS_IMAGE +} + +""" +A Video, typically within an Article View of an Item or if the Item is a video itself. +""" +type Video @cacheControl(maxAge: 86400) { + "If known, the height of the video in px" + height: Int + "Absolute url to the video" + src: String! + "The type of video" + type: VideoType! + "The video's id within the service defined by type" + vid: String + "The id of the video within Article View. Item.article will have placeholders of
where X is this id. Apps can download those images as needed and populate them in their article view." + videoId: Int! + "If known, the width of the video in px" + width: Int + "If known, the length of the video in seconds" + length: Int +} + +enum VideoType { + "Youtube (v3 value is 1)" + YOUTUBE + "Vimeo Link (v3 value is 2)" + VIMEO_LINK + "Vimeo Moogaloop (v3 value is 3)" + VIMEO_MOOGALOOP + "video iframe (v3 value is 4)" + VIMEO_IFRAME + "html5 (v3 value is 5)" + HTML5 + "Flash (v3 value is 6)" + FLASH + "iframe (v3 value is 7)" + IFRAME + "Brightcove (v3 value is 8)" + BRIGHTCOVE +} + +enum Videoness { + "No videos (v3 value is 0)" + NO_VIDEOS + "Contains videos (v3 value is 1)" + HAS_VIDEOS + "Is a video (v3 value is 2)" + IS_VIDEO +} + +union MarticleComponent = + | MarticleText + | Image + | MarticleDivider + | MarticleTable + | MarticleHeading + | MarticleCodeBlock + | Video + | MarticleBulletedList + | MarticleNumberedList + | MarticleBlockquote + | UnMarseable + +""" +Represents content that could not be parsed into a valid Marticle* component. +""" +type UnMarseable { + "The html that could not be parsed into a Marticle* component." + html: String! +} + +""" +A section of the article's text content, in markdown. +A subset of gfm is supported. See README.md for more information. +""" +type MarticleText { + "Markdown text content. Typically, a paragraph." + content: Markdown! +} + +type MarticleDivider { + "Always '---'; provided for convenience if building a markdown string" + content: Markdown! +} + +""" +Content in a table. +""" +type MarticleTable { + "Raw HTML representation of the table." + html: String! +} + +""" +A heading in an article, with markdown formatting. +""" +type MarticleHeading { + "Heading text, in markdown." + content: Markdown! + "Heading level. Restricted to values 1-6." + level: Int! +} + +""" +A pre formatted text in the HTML content. +""" +type MarticleCodeBlock { + "Content of a pre tag" + text: String! + "Assuming the codeblock was a programming language, this field is used to identify it." + language: Int +} + +interface ListElement { + "Row in a list." + content: Markdown! + "Zero-indexed level, for handling nested lists." + level: Int! +} + +""" +Row in a bulleted (unordered list) +""" +type BulletedListElement implements ListElement { + "Row in a list." + content: Markdown! + "Zero-indexed level, for handling nested lists." + level: Int! +} + +type NumberedListElement implements ListElement { + "Row in a list" + content: Markdown! + "Zero-indexed level, for handling nested lists." + level: Int! + "Numeric index. If a nested item, the index is zero-indexed from the first child." + index: Int! +} + +""" +Content in a bulleted (unordered) list. +""" +type MarticleBulletedList { + rows: [BulletedListElement!]! +} + +""" +Content in a bulleted (unordered) list. +""" +type MarticleNumberedList { + rows: [NumberedListElement!]! +} + +""" +Content of a blockquote +""" +type MarticleBlockquote { + "Markdown text content." + content: Markdown! +} + +""" +Information about an Author of an article or some content +""" +type Author @cacheControl(maxAge: 86400) { + "Unique id for that Author" + id: ID! + "Display name" + name: String + "A url to that Author's site" + url: String +} + +type Query { + """ + Look up Item info by a url. + """ + getItemByUrl(url: String!): Item + @cacheControl(maxAge: 86400) + @deprecated(reason: "Use itemByUrl instead") + + """ + Look up Item info by a url. + """ + itemByUrl(url: String!): Item @cacheControl(maxAge: 86400) + + """ + Resolve Reader View links which might point to SavedItems that do not + exist, aren't in the Pocket User's list, or are requested by a logged-out + user (or user without a Pocket Account). + Fetches data which clients can use to generate an appropriate fallback view + that allows users to preview the content and access the original source site. + """ + readerSlug(slug: ID!): ReaderViewResult! +} + +type Mutation { + """ + Refresh an Item's article content. + """ + refreshItemArticle(url: String!): Item! +} + +extend type CorpusItem @key(fields: "url") { + """ + Provides short url for the given_url in the format: https://pocket.co/. + marked as beta because it's not ready yet for large client request. + """ + shortUrl: Url @tag(name: "beta") + url: Url! @external + """ + Time to read in minutes. Is nullable. + """ + timeToRead: Int +} +extend type Collection @key(fields: "slug") { + """ + Provides short url for the given_url in the format: https://pocket.co/. + marked as beta because it's not ready yet for large client request. + """ + shortUrl: Url @tag(name: "beta") + slug: String! @external +} + +""" +Result for resolving a getpocket.com/read/ link. +""" +type ReaderViewResult @key(fields: "slug") { + slug: ID! + fallbackPage: ReaderFallback +} + +""" +Metadata of an Item in Pocket for preview purposes, +or an ItemNotFound result if the record does not exist. +""" +union ReaderFallback = ReaderInterstitial | ItemNotFound + +enum PocketMetadataSource { + POCKET_PARSER + OPENGRAPH + OEMBED +} + +interface PocketMetadata { + id: ID! + image: Image + excerpt: String + title: String + authors: [Author!] + domain: DomainMetadata + datePublished: ISOString + url: Url! + source: PocketMetadataSource! + item: Item +} + +type ItemSummary implements PocketMetadata { + id: ID! + image: Image + excerpt: String + title: String + authors: [Author!] + domain: DomainMetadata + datePublished: ISOString + url: Url! + source: PocketMetadataSource! + item: Item +} + +enum OEmbedType { + RICH + VIDEO + PHOTO + LINK +} + +type OEmbed implements PocketMetadata { + id: ID! + image: Image + excerpt: String + title: String + authors: [Author!] + domain: DomainMetadata + datePublished: ISOString + url: Url! + source: PocketMetadataSource! + item: Item + htmlEmbed: String + type: OEmbedType +} + +""" +Card preview data for Items resolved from reader view +(getpocket.com/read/) links. + +Should be used to create a view if Reader Mode cannot +be rendered (e.g. the link is visited by an anonymous +Pocket user, or a Pocket User that does not have the +underlying Item in their Saves). Due to legal obligations +we can only display Reader Mode for SavedItems. +""" +type ReaderInterstitial { + itemCard: PocketMetadata +} + +type ItemNotFound { + message: String +} + +type PocketShare @key(fields: "targetUrl") { + targetUrl: ValidUrl! + preview: PocketMetadata +} + +""" +A node in a CorpusSearchConnection result +""" +type CorpusSearchNode @key(fields: "url") { + """ + For federation only + """ + url: Url! @inaccessible + """ + The preview of the search result + """ + preview: PocketMetadata! +} diff --git a/servers/parser-graphql-wrapper/schema.graphql b/servers/parser-graphql-wrapper/schema.graphql index 4f4c38e6c..8fb79f361 100644 --- a/servers/parser-graphql-wrapper/schema.graphql +++ b/servers/parser-graphql-wrapper/schema.graphql @@ -19,6 +19,11 @@ See Section 5.6 of the RFC 3339 profile of the ISO 8601 standard: https://www.ie """ scalar ISOString +""" +A date in the YYYY-MM-DD format. +""" +scalar Date + """ A string formatted with CommonMark markdown, plus the strikethrough extension from GFM. @@ -167,8 +172,20 @@ type Item "The Marticle format of the article, used by clients for native article view." marticle: [MarticleComponent!] - "The client preview/display logic for this url" + "The client preview/display logic for this url. The requires for each object should be kept in sync with the sub objects requires field." preview: PocketMetadata + @requires( + fields: "syndicatedArticle { title excerpt mainImage publishedAt authorNames publisherUrl publisher { logo name } } collection { title excerpt publishedAt authors { name } imageUrl } corpusItem { title excerpt datePublished publisher image { url } }" + ) + + "If the item is a syndicated article, then the syndication information" + syndicatedArticle: SyndicatedArticle @external + + "If the item is a collection, then the collection information" + collection: Collection @external + + "If the item is in the Pocket Corpus, then the corpus information" + corpusItem: CorpusItem @external } type ArticleMarkdown { @@ -440,7 +457,50 @@ extend type CorpusItem @key(fields: "url") { Time to read in minutes. Is nullable. """ timeToRead: Int + + """ + The title of the Approved Item. + """ + title: String! @external + """ + The excerpt of the Approved Item. + """ + excerpt: String! @external + """ + The publication date for this story. + """ + datePublished: Date @external + """ + The name of the online publication that published this story. + """ + publisher: String! @external + """ + The image for this item's accompanying picture. + """ + image: Image! @external + + """ + The author names and sort orders associated with this CorpusItem. + """ + authors: [CorpusItemAuthor!]! @external + + """ + The preview of the search result + """ + preview: PocketMetadata! + @requires( + fields: "title excerpt datePublished publisher image { url } authors { name sortOrder }" + ) +} + +""" +An author associated with a CorpusItem. +""" +type CorpusItemAuthor @external { + name: String! + sortOrder: Int! } + extend type Collection @key(fields: "slug") { """ Provides short url for the given_url in the format: https://pocket.co/. @@ -448,6 +508,21 @@ extend type Collection @key(fields: "slug") { """ shortUrl: Url @tag(name: "beta") slug: String! @external + title: String! @external + authors: [CollectionAuthor!]! @external + excerpt: Markdown @external + publishedAt: DateString @external + imageUrl: Url @external + + """ + The preview of the collection + """ + preview: PocketMetadata! + @requires(fields: "title excerpt publishedAt authors { name } imageUrl") +} + +extend type CollectionAuthor @external { + name: String! } """ @@ -468,6 +543,9 @@ enum PocketMetadataSource { POCKET_PARSER OPENGRAPH OEMBED + CURATED_CORPUS + COLLECTION + SYNDICATION } interface PocketMetadata { @@ -524,7 +602,7 @@ Card preview data for Items resolved from reader view Should be used to create a view if Reader Mode cannot be rendered (e.g. the link is visited by an anonymous -Pocket user, or a Pocket User that does not have the +Pocket user, or a Pocket User that does not have the underlying Item in their Saves). Due to legal obligations we can only display Reader Mode for SavedItems. """ @@ -541,10 +619,57 @@ type PocketShare @key(fields: "targetUrl") { preview: PocketMetadata } -"""A node in a CorpusSearchConnection result""" -type CorpusSearchNode @key (fields: "url") { - """For federation only""" +""" +A node in a CorpusSearchConnection result +""" +type CorpusSearchNode @key(fields: "url") { + """ + For federation only + """ url: Url! @inaccessible - """The preview of the search result""" + """ + The preview of the search result + """ + preview: PocketMetadata! +} + +extend type SyndicatedArticle @key(fields: "slug") { + "Slug that pocket uses for this article in the url" + slug: String + + "Title of syndicated article" + title: String! @external + "Array of author names in string format" + authorNames: [String]! @external + + "AWSDateTime — Format: YYYY-MM-DDThh:mm:ss.sssZ" + publishedAt: String! @external + + "Primary image to use in surfacing this content" + mainImage: String @external + + "Excerpt " + excerpt: String @external + + "The canonical publisher URL. Automatically set at time of creation but can be changed by editor." + publisherUrl: String! @external + + "The manually set publisher information for this article" + publisher: Publisher @external + + """ + The preview of the syndicated article + """ preview: PocketMetadata! + @requires( + fields: "title excerpt mainImage publishedAt authorNames publisherUrl publisher { logo name }" + ) } + + +extend type Publisher @external { + "Square logo to use for the publisher" + logo: String + "Name of the publisher of the article" + name: String +} \ No newline at end of file diff --git a/servers/parser-graphql-wrapper/src/__generated__/resolvers-types.ts b/servers/parser-graphql-wrapper/src/__generated__/resolvers-types.ts index 0c55866a8..2cc12f427 100644 --- a/servers/parser-graphql-wrapper/src/__generated__/resolvers-types.ts +++ b/servers/parser-graphql-wrapper/src/__generated__/resolvers-types.ts @@ -20,6 +20,8 @@ export type Scalars = { Boolean: { input: boolean; output: boolean; } Int: { input: number; output: number; } Float: { input: number; output: number; } + /** A date in the YYYY-MM-DD format. */ + Date: { input: any; output: any; } /** A String representing a date in the format of `yyyy-MM-dd HH:mm:ss` */ DateString: { input: any; output: any; } /** @@ -74,16 +76,40 @@ export enum CacheControlScope { export type Collection = { __typename?: 'Collection'; + authors: Array; + excerpt?: Maybe; + imageUrl?: Maybe; + /** The preview of the collection */ + preview: PocketMetadata; + publishedAt?: Maybe; /** * Provides short url for the given_url in the format: https://pocket.co/. * marked as beta because it's not ready yet for large client request. */ shortUrl?: Maybe; slug: Scalars['String']['output']; + title: Scalars['String']['output']; +}; + +export type CollectionAuthor = { + __typename?: 'CollectionAuthor'; + name: Scalars['String']['output']; }; export type CorpusItem = { __typename?: 'CorpusItem'; + /** The author names and sort orders associated with this CorpusItem. */ + authors: Array; + /** The publication date for this story. */ + datePublished?: Maybe; + /** The excerpt of the Approved Item. */ + excerpt: Scalars['String']['output']; + /** The image for this item's accompanying picture. */ + image: Image; + /** The preview of the search result */ + preview: PocketMetadata; + /** The name of the online publication that published this story. */ + publisher: Scalars['String']['output']; /** * Provides short url for the given_url in the format: https://pocket.co/. * marked as beta because it's not ready yet for large client request. @@ -91,9 +117,18 @@ export type CorpusItem = { shortUrl?: Maybe; /** Time to read in minutes. Is nullable. */ timeToRead?: Maybe; + /** The title of the Approved Item. */ + title: Scalars['String']['output']; url: Scalars['Url']['output']; }; +/** An author associated with a CorpusItem. */ +export type CorpusItemAuthor = { + __typename?: 'CorpusItemAuthor'; + name: Scalars['String']['output']; + sortOrder: Scalars['Int']['output']; +}; + /** A node in a CorpusSearchConnection result */ export type CorpusSearchNode = { __typename?: 'CorpusSearchNode'; @@ -164,11 +199,15 @@ export type Item = { article?: Maybe; /** List of Authors involved with this article */ authors?: Maybe>>; + /** If the item is a collection, then the collection information */ + collection?: Maybe; /** * The length in bytes of the content * @deprecated Clients should not use this */ contentLength?: Maybe; + /** If the item is in the Pocket Corpus, then the corpus information */ + corpusItem?: Maybe; /** The date the article was published */ datePublished?: Maybe; /** The date the parser resolved this item */ @@ -246,7 +285,7 @@ export type Item = { * @deprecated Use a domain as the identifier instead */ originDomainId?: Maybe; - /** The client preview/display logic for this url */ + /** The client preview/display logic for this url. The requires for each object should be kept in sync with the sub objects requires field. */ preview?: Maybe; /** A server generated unique reader slug for this item based on itemId */ readerSlug: Scalars['String']['output']; @@ -271,6 +310,8 @@ export type Item = { shortUrl?: Maybe; /** If the url is an Article, the text in SSML format for speaking, i.e. Listen */ ssml?: Maybe; + /** If the item is a syndicated article, then the syndication information */ + syndicatedArticle?: Maybe; /** * Date this item was first parsed in Pocket * @deprecated Clients should not use this @@ -452,9 +493,12 @@ export type PocketMetadata = { }; export enum PocketMetadataSource { + Collection = 'COLLECTION', + CuratedCorpus = 'CURATED_CORPUS', Oembed = 'OEMBED', Opengraph = 'OPENGRAPH', - PocketParser = 'POCKET_PARSER' + PocketParser = 'POCKET_PARSER', + Syndication = 'SYNDICATION' } export type PocketShare = { @@ -463,6 +507,14 @@ export type PocketShare = { targetUrl: Scalars['ValidUrl']['output']; }; +export type Publisher = { + __typename?: 'Publisher'; + /** Square logo to use for the publisher */ + logo?: Maybe; + /** Name of the publisher of the article */ + name?: Maybe; +}; + export type Query = { __typename?: 'Query'; /** @@ -525,6 +577,28 @@ export type ReaderViewResult = { slug: Scalars['ID']['output']; }; +export type SyndicatedArticle = { + __typename?: 'SyndicatedArticle'; + /** Array of author names in string format */ + authorNames: Array>; + /** Excerpt */ + excerpt?: Maybe; + /** Primary image to use in surfacing this content */ + mainImage?: Maybe; + /** The preview of the syndicated article */ + preview: PocketMetadata; + /** AWSDateTime — Format: YYYY-MM-DDThh:mm:ss.sssZ */ + publishedAt: Scalars['String']['output']; + /** The manually set publisher information for this article */ + publisher?: Maybe; + /** The canonical publisher URL. Automatically set at time of creation but can be changed by editor. */ + publisherUrl: Scalars['String']['output']; + /** Slug that pocket uses for this article in the url */ + slug?: Maybe; + /** Title of syndicated article */ + title: Scalars['String']['output']; +}; + /** Represents content that could not be parsed into a valid Marticle* component. */ export type UnMarseable = { __typename?: 'UnMarseable'; @@ -679,15 +753,18 @@ export type ResolversTypes = ResolversObject<{ BulletedListElement: ResolverTypeWrapper; Int: ResolverTypeWrapper; CacheControlScope: CacheControlScope; - Collection: ResolverTypeWrapper; - CorpusItem: ResolverTypeWrapper; + Collection: ResolverTypeWrapper & { preview: ResolversTypes['PocketMetadata'] }>; + CollectionAuthor: ResolverTypeWrapper; + CorpusItem: ResolverTypeWrapper & { preview: ResolversTypes['PocketMetadata'] }>; + CorpusItemAuthor: ResolverTypeWrapper; CorpusSearchNode: ResolverTypeWrapper & { preview: ResolversTypes['PocketMetadata'] }>; + Date: ResolverTypeWrapper; DateString: ResolverTypeWrapper; DomainMetadata: ResolverTypeWrapper; ISOString: ResolverTypeWrapper; Image: ResolverTypeWrapper; Imageness: Imageness; - Item: ResolverTypeWrapper & { marticle?: Maybe>, preview?: Maybe }>; + Item: ResolverTypeWrapper & { collection?: Maybe, corpusItem?: Maybe, marticle?: Maybe>, preview?: Maybe, syndicatedArticle?: Maybe }>; Boolean: ResolverTypeWrapper; ItemNotFound: ResolverTypeWrapper; ItemSummary: ResolverTypeWrapper & { item?: Maybe }>; @@ -710,10 +787,12 @@ export type ResolversTypes = ResolversObject<{ PocketMetadata: ResolverTypeWrapper['PocketMetadata']>; PocketMetadataSource: PocketMetadataSource; PocketShare: ResolverTypeWrapper & { preview?: Maybe }>; + Publisher: ResolverTypeWrapper; Query: ResolverTypeWrapper<{}>; ReaderFallback: ResolverTypeWrapper['ReaderFallback']>; ReaderInterstitial: ResolverTypeWrapper & { itemCard?: Maybe }>; ReaderViewResult: ResolverTypeWrapper & { fallbackPage?: Maybe }>; + SyndicatedArticle: ResolverTypeWrapper & { preview: ResolversTypes['PocketMetadata'] }>; UnMarseable: ResolverTypeWrapper; Url: ResolverTypeWrapper; ValidUrl: ResolverTypeWrapper; @@ -730,14 +809,17 @@ export type ResolversParentTypes = ResolversObject<{ ID: Scalars['ID']['output']; BulletedListElement: BulletedListElement; Int: Scalars['Int']['output']; - Collection: Collection; - CorpusItem: CorpusItem; + Collection: Omit & { preview: ResolversParentTypes['PocketMetadata'] }; + CollectionAuthor: CollectionAuthor; + CorpusItem: Omit & { preview: ResolversParentTypes['PocketMetadata'] }; + CorpusItemAuthor: CorpusItemAuthor; CorpusSearchNode: Omit & { preview: ResolversParentTypes['PocketMetadata'] }; + Date: Scalars['Date']['output']; DateString: Scalars['DateString']['output']; DomainMetadata: DomainMetadata; ISOString: Scalars['ISOString']['output']; Image: Image; - Item: Omit & { marticle?: Maybe>, preview?: Maybe }; + Item: Omit & { collection?: Maybe, corpusItem?: Maybe, marticle?: Maybe>, preview?: Maybe, syndicatedArticle?: Maybe }; Boolean: Scalars['Boolean']['output']; ItemNotFound: ItemNotFound; ItemSummary: Omit & { item?: Maybe }; @@ -758,10 +840,12 @@ export type ResolversParentTypes = ResolversObject<{ OEmbed: Omit & { item?: Maybe }; PocketMetadata: ResolversInterfaceTypes['PocketMetadata']; PocketShare: Omit & { preview?: Maybe }; + Publisher: Publisher; Query: {}; ReaderFallback: ResolversUnionTypes['ReaderFallback']; ReaderInterstitial: Omit & { itemCard?: Maybe }; ReaderViewResult: Omit & { fallbackPage?: Maybe }; + SyndicatedArticle: Omit & { preview: ResolversParentTypes['PocketMetadata'] }; UnMarseable: UnMarseable; Url: Scalars['Url']['output']; ValidUrl: Scalars['ValidUrl']['output']; @@ -796,16 +880,40 @@ export type BulletedListElementResolvers = ResolversObject<{ __resolveReference?: ReferenceResolver, { __typename: 'Collection' } & GraphQLRecursivePick, ContextType>; + + + + preview?: Resolver & GraphQLRecursivePick, ContextType>; + shortUrl?: Resolver, { __typename: 'Collection' } & GraphQLRecursivePick, ContextType>; + + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type CollectionAuthorResolvers = ResolversObject<{ + name?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }>; export type CorpusItemResolvers = ResolversObject<{ __resolveReference?: ReferenceResolver, { __typename: 'CorpusItem' } & GraphQLRecursivePick, ContextType>; + + + + + preview?: Resolver & GraphQLRecursivePick, ContextType>; + shortUrl?: Resolver, { __typename: 'CorpusItem' } & GraphQLRecursivePick, ContextType>; timeToRead?: Resolver, { __typename: 'CorpusItem' } & GraphQLRecursivePick, ContextType>; + + __isTypeOf?: IsTypeOfResolverFn; +}>; + +export type CorpusItemAuthorResolvers = ResolversObject<{ + name?: Resolver; + sortOrder?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }>; @@ -816,6 +924,10 @@ export type CorpusSearchNodeResolvers; }>; +export interface DateScalarConfig extends GraphQLScalarTypeConfig { + name: 'Date'; +} + export interface DateStringScalarConfig extends GraphQLScalarTypeConfig { name: 'DateString'; } @@ -846,50 +958,53 @@ export type ImageResolvers = ResolversObject<{ __resolveReference?: ReferenceResolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; - ampUrl?: Resolver, ParentType, ContextType>; - article?: Resolver, ParentType, ContextType>; - authors?: Resolver>>, ParentType, ContextType>; - contentLength?: Resolver, ParentType, ContextType>; - datePublished?: Resolver, ParentType, ContextType>; - dateResolved?: Resolver, ParentType, ContextType>; - domain?: Resolver, ParentType, ContextType>; - domainId?: Resolver, ParentType, ContextType>; - domainMetadata?: Resolver, ParentType, ContextType>; - encoding?: Resolver, ParentType, ContextType>; - excerpt?: Resolver, ParentType, ContextType>; - givenUrl?: Resolver; - hasImage?: Resolver, ParentType, ContextType>; - hasOldDupes?: Resolver, ParentType, ContextType>; - hasVideo?: Resolver, ParentType, ContextType>; - id?: Resolver; - images?: Resolver>>, ParentType, ContextType>; - innerDomainRedirect?: Resolver, ParentType, ContextType>; - isArticle?: Resolver, ParentType, ContextType>; - isIndex?: Resolver, ParentType, ContextType>; - itemId?: Resolver; - language?: Resolver, ParentType, ContextType>; - listenDuration?: Resolver, ParentType, ContextType>; - loginRequired?: Resolver, ParentType, ContextType>; - marticle?: Resolver>, ParentType, ContextType>; - mimeType?: Resolver, ParentType, ContextType>; - normalUrl?: Resolver; - originDomainId?: Resolver, ParentType, ContextType>; - preview?: Resolver, ParentType, ContextType>; - readerSlug?: Resolver; - resolvedId?: Resolver, ParentType, ContextType>; - resolvedNormalUrl?: Resolver, ParentType, ContextType>; - resolvedUrl?: Resolver, ParentType, ContextType>; - responseCode?: Resolver, ParentType, ContextType>; - shortUrl?: Resolver, ParentType, ContextType>; - ssml?: Resolver, ParentType, ContextType>; - timeFirstParsed?: Resolver, ParentType, ContextType>; - timeToRead?: Resolver, ParentType, ContextType>; - title?: Resolver, ParentType, ContextType>; - topImage?: Resolver, ParentType, ContextType>; - topImageUrl?: Resolver, ParentType, ContextType>; - usedFallback?: Resolver, ParentType, ContextType>; - videos?: Resolver>>, ParentType, ContextType>; - wordCount?: Resolver, ParentType, ContextType>; + ampUrl?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + article?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + authors?: Resolver>>, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + + contentLength?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + + datePublished?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + dateResolved?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + domain?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + domainId?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + domainMetadata?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + encoding?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + excerpt?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + givenUrl?: Resolver | GraphQLRecursivePick), ContextType>; + hasImage?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + hasOldDupes?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + hasVideo?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + id?: Resolver | GraphQLRecursivePick), ContextType>; + images?: Resolver>>, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + innerDomainRedirect?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + isArticle?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + isIndex?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + itemId?: Resolver | GraphQLRecursivePick), ContextType>; + language?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + listenDuration?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + loginRequired?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + marticle?: Resolver>, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + mimeType?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + normalUrl?: Resolver | GraphQLRecursivePick), ContextType>; + originDomainId?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + preview?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick) & GraphQLRecursivePick, ContextType>; + readerSlug?: Resolver | GraphQLRecursivePick), ContextType>; + resolvedId?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + resolvedNormalUrl?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + resolvedUrl?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + responseCode?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + shortUrl?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + ssml?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + + timeFirstParsed?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + timeToRead?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + title?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + topImage?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + topImageUrl?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + usedFallback?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + videos?: Resolver>>, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; + wordCount?: Resolver, { __typename: 'Item' } & (GraphQLRecursivePick | GraphQLRecursivePick), ContextType>; __isTypeOf?: IsTypeOfResolverFn; }>; @@ -1023,6 +1138,12 @@ export type PocketShareResolvers; }>; +export type PublisherResolvers = ResolversObject<{ + logo?: Resolver, ParentType, ContextType>; + name?: Resolver, ParentType, ContextType>; + __isTypeOf?: IsTypeOfResolverFn; +}>; + export type QueryResolvers = ResolversObject<{ getItemByUrl?: Resolver, ParentType, ContextType, RequireFields>; itemByUrl?: Resolver, ParentType, ContextType, RequireFields>; @@ -1045,6 +1166,20 @@ export type ReaderViewResultResolvers; }>; +export type SyndicatedArticleResolvers = ResolversObject<{ + __resolveReference?: ReferenceResolver, { __typename: 'SyndicatedArticle' } & GraphQLRecursivePick, ContextType>; + + + + preview?: Resolver & GraphQLRecursivePick, ContextType>; + + + + slug?: Resolver, { __typename: 'SyndicatedArticle' } & GraphQLRecursivePick, ContextType>; + + __isTypeOf?: IsTypeOfResolverFn; +}>; + export type UnMarseableResolvers = ResolversObject<{ html?: Resolver; __isTypeOf?: IsTypeOfResolverFn; @@ -1074,8 +1209,11 @@ export type Resolvers = ResolversObject<{ Author?: AuthorResolvers; BulletedListElement?: BulletedListElementResolvers; Collection?: CollectionResolvers; + CollectionAuthor?: CollectionAuthorResolvers; CorpusItem?: CorpusItemResolvers; + CorpusItemAuthor?: CorpusItemAuthorResolvers; CorpusSearchNode?: CorpusSearchNodeResolvers; + Date?: GraphQLScalarType; DateString?: GraphQLScalarType; DomainMetadata?: DomainMetadataResolvers; ISOString?: GraphQLScalarType; @@ -1100,10 +1238,12 @@ export type Resolvers = ResolversObject<{ OEmbed?: OEmbedResolvers; PocketMetadata?: PocketMetadataResolvers; PocketShare?: PocketShareResolvers; + Publisher?: PublisherResolvers; Query?: QueryResolvers; ReaderFallback?: ReaderFallbackResolvers; ReaderInterstitial?: ReaderInterstitialResolvers; ReaderViewResult?: ReaderViewResultResolvers; + SyndicatedArticle?: SyndicatedArticleResolvers; UnMarseable?: UnMarseableResolvers; Url?: GraphQLScalarType; ValidUrl?: GraphQLScalarType; diff --git a/servers/parser-graphql-wrapper/src/apollo/resolvers.ts b/servers/parser-graphql-wrapper/src/apollo/resolvers.ts index 024169d0a..451dbfde9 100644 --- a/servers/parser-graphql-wrapper/src/apollo/resolvers.ts +++ b/servers/parser-graphql-wrapper/src/apollo/resolvers.ts @@ -8,7 +8,14 @@ import { import { SSMLModel } from '../models/SSMLModel'; import { fallbackPage } from '../readerView'; import { PocketDefaultScalars } from '@pocket-tools/apollo-utils'; -import { Item, Resolvers, Videoness } from '../__generated__/resolvers-types'; +import { + Collection, + CorpusItem, + Item, + Resolvers, + SyndicatedArticle, + Videoness, +} from '../__generated__/resolvers-types'; import { BoolStringParam, MediaTypeParam } from '../datasources/ParserAPI'; import { extractSlugFromReadUrl, @@ -27,6 +34,11 @@ export const resolvers: Resolvers = { item, context, false, + { + syndicatedArticle: item.syndicatedArticle, + collection: item.collection, + corpusItem: item.corpusItem, + }, ); return { url: representation.url, @@ -47,7 +59,7 @@ export const resolvers: Resolvers = { } if ('givenUrl' in item) { - return itemFromUrl(item.givenUrl, context); + return { ...item, ...(await itemFromUrl(item.givenUrl, context)) }; } else if ('itemId' in item) { const itemLoaderType = await context.dataLoaders.itemIdLoader.load( item.itemId, @@ -55,10 +67,11 @@ export const resolvers: Resolvers = { if (!itemLoaderType.url) { throw new Error(`No url found for itemId: ${item.itemId}`); } - return itemFromUrl(itemLoaderType.url, context); + return { ...item, ...(await itemFromUrl(itemLoaderType.url, context)) }; } }, - article: async (parent, args, { dataSources }, info) => { + article: async (uncastParent, args, { dataSources }, info) => { + const parent = uncastParent as Item; if (parent.article) { // Use the parent resolver for article content if available // (e.g. via refreshArticle mutation), otherwise load the article @@ -78,7 +91,8 @@ export const resolvers: Resolvers = { return item.article || null; }, - marticle: async (parent, args, { dataSources }, info) => { + marticle: async (uncastParent, args, { dataSources }, info) => { + const parent = uncastParent as Item; // Note: When the Web & Android teams switch to MArticle, make all the parser article call use // MediaTypeParam.AS_COMMENTS and add back this optimization: // @@ -106,12 +120,13 @@ export const resolvers: Resolvers = { : ([] as MarticleElement[]); }, ssml: async (parent, args, { dataSources }, info) => { - if (!parent.article && parent.isArticle) { + const castParent = parent as Item; + if (!castParent.article && castParent.isArticle) { // If the field was requested via refreshArticle we need to clear the cache before we request data const clearCache = isInResolverChain('refreshItemArticle', info.path); - parent.article = ( + castParent.article = ( await dataSources.parserAPI.getItemData( - parent.givenUrl, + castParent.givenUrl, { videos: MediaTypeParam.DIV_TAG, images: MediaTypeParam.DIV_TAG, @@ -121,12 +136,14 @@ export const resolvers: Resolvers = { ) ).article; } - if (!parent.article) { + if (!castParent.article) { return null; } - return SSMLModel.generateSSML(parent); + return SSMLModel.generateSSML(parent as Item); }, - shortUrl: async (parent, args, context) => { + shortUrl: async (uncastParent, args, context) => { + const parent = uncastParent as Item; + // If the givenUrl is already a short share url, or there is a // short url key on the parent from a previous step, return the // same value to avoid another db trip @@ -147,11 +164,16 @@ export const resolvers: Resolvers = { const clearCache = isInResolverChain('refreshItemArticle', info.path); const preview = await context.dataSources.pocketMetadataModel.derivePocketMetadata( - parent, + parent as Item, context, clearCache, + { + syndicatedArticle: parent.syndicatedArticle as SyndicatedArticle, + collection: parent.collection as Collection, + corpusItem: parent.corpusItem as CorpusItem, + }, ); - return { ...preview, item: parent }; + return { ...preview, item: parent as Item }; }, }, MarticleComponent: { @@ -206,10 +228,22 @@ export const resolvers: Resolvers = { try { const item = await dataSources.parserAPI.getItemData(url); return item.timeToRead || null; - } catch (e) { + } catch { return null; } }, + preview: async (parent, _, context) => { + const item = await context.dataSources.parserAPI.getItemData(parent.url); + + const preview = + await context.dataSources.pocketMetadataModel.derivePocketMetadata( + item, + context, + false, + { corpusItem: parent as CorpusItem }, + ); + return { ...preview, item }; + }, }, Collection: { shortUrl: async ({ slug }, args, { dataSources, dataLoaders }) => { @@ -227,6 +261,36 @@ export const resolvers: Resolvers = { givenUrl: item.givenUrl, }); }, + preview: async (parent, args, context) => { + const item = await context.dataSources.parserAPI.getItemData( + `${config.shortUrl.collectionUrl}/${parent.slug}`, + ); + + const preview = + await context.dataSources.pocketMetadataModel.derivePocketMetadata( + item, + context, + false, + { collection: parent as Collection }, + ); + return { ...preview, item }; + }, + }, + SyndicatedArticle: { + preview: async (parent, args, context) => { + const item = await context.dataSources.parserAPI.getItemData( + `${config.shortUrl.syndicationUrl}/${parent.slug}`, + ); + + const preview = + await context.dataSources.pocketMetadataModel.derivePocketMetadata( + item, + context, + false, + { syndicatedArticle: parent as SyndicatedArticle }, + ); + return { ...preview, item }; + }, }, PocketMetadata: { __resolveType(parent) { diff --git a/servers/parser-graphql-wrapper/src/config/index.ts b/servers/parser-graphql-wrapper/src/config/index.ts index c4ba041ba..014c0ea45 100644 --- a/servers/parser-graphql-wrapper/src/config/index.ts +++ b/servers/parser-graphql-wrapper/src/config/index.ts @@ -58,6 +58,8 @@ export default { 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ123456789_', collectionUrl: process.env.COLLECTIONS_URL || 'https://getpocket.com/collections', + syndicationUrl: + process.env.SYNDICATION_URL || 'https://getpocket.com/explore/item', }, mysql: { host: process.env.DB_HOST || 'localhost', diff --git a/servers/parser-graphql-wrapper/src/main.ts b/servers/parser-graphql-wrapper/src/main.ts index a5879b655..a1c16f0bb 100644 --- a/servers/parser-graphql-wrapper/src/main.ts +++ b/servers/parser-graphql-wrapper/src/main.ts @@ -7,22 +7,12 @@ import { initSentry } from '@pocket-tools/sentry'; initSentry({ ...config.sentry, debug: config.sentry.environment == 'development', - skipOpenTelemetrySetup: true, }); -import { nodeSDKBuilder } from '@pocket-tools/tracing'; import { serverLogger } from '@pocket-tools/ts-logger'; +import { startServer } from './apollo/server'; -nodeSDKBuilder({ - host: config.tracing.host, - serviceName: config.tracing.serviceName, - release: config.sentry.release, - logger: serverLogger, - addSentry: true, -}).then(async () => { - const { url } = await startServer(config.app.serverPort); +startServer(config.app.serverPort).then(({ url }) => { serverLogger.info( `🚀 Public server ready at http://localhost:${config.app.serverPort}${url}`, ); }); - -import { startServer } from './apollo/server'; diff --git a/servers/parser-graphql-wrapper/src/models/PocketMetadataModel.ts b/servers/parser-graphql-wrapper/src/models/PocketMetadataModel.ts index 21cd50db5..4aba10aba 100644 --- a/servers/parser-graphql-wrapper/src/models/PocketMetadataModel.ts +++ b/servers/parser-graphql-wrapper/src/models/PocketMetadataModel.ts @@ -3,6 +3,9 @@ import { PocketMetadataSource, PocketMetadata, ItemSummary, + SyndicatedArticle, + CorpusItem, + Collection, } from '../__generated__/resolvers-types'; import config from '../config'; import { DateTime } from 'luxon'; @@ -12,6 +15,8 @@ import { PocketMetadataEntity, } from '../databases/pocketMetadataStore'; import md5 from 'md5'; +import { getOriginalUrlIfPocketImageCached } from '@pocket-tools/image-utils'; +import markdownToTxt from 'markdown-to-txt'; export interface IPocketMetadataDataSource { matcher: RegExp; @@ -36,25 +41,34 @@ export class PocketMetadataModel { item: Item, context: IContext, refresh: boolean, + extraData: { + corpusItem?: CorpusItem; + syndicatedArticle?: SyndicatedArticle; + collection?: Collection; + } = {}, ): Promise { + const { syndicatedArticle, collection, corpusItem } = extraData; const url = item.givenUrl; // the url we are going to key everything on. - const fallbackParserPocketMetadata: ItemSummary = { - id: item.id, - image: item.topImage ?? item.images?.[0], - excerpt: item.excerpt, - title: item.title ?? item.givenUrl, - authors: item.authors, - domain: item.domainMetadata, - datePublished: item.datePublished - ? DateTime.fromSQL(item.datePublished, { - zone: config.mysql.tz, - }).toJSDate() - : null, - url: url, - source: PocketMetadataSource.PocketParser, - __typename: 'ItemSummary', - }; + const syndicatedArticlePocketMetadata = this.transformSyndicatedArticle( + item, + syndicatedArticle, + ); + if (syndicatedArticlePocketMetadata) { + return syndicatedArticlePocketMetadata; + } + + const collectionPocketMetadata = this.transformCollection(item, collection); + if (collectionPocketMetadata) { + return collectionPocketMetadata; + } + + const corpusItemMetadata = this.transformCorpusItem(item, corpusItem); + if (corpusItemMetadata) { + return corpusItemMetadata; + } + + const fallbackParserPocketMetadata = this.transformParserFallback(item); // First we filter to our sources. // We do this first because some sources could be behind a feature flag or not enabled // We also only store other data sources beyond our parser in the datastore, \ @@ -172,4 +186,173 @@ export class PocketMetadataModel { return res == null ? null : this.fromEntity(res); } + + /** + * + * @param item Item object from the Graph + * @param collection Collection object from the graph + * @returns ItemSummary data to be shown to the user + */ + transformCollection( + item: Item, + collection: Collection, + ): ItemSummary | undefined { + if (!collection) { + return; + } + const imageUrl = getOriginalUrlIfPocketImageCached(collection.imageUrl); + return { + id: item.id, + image: { + url: imageUrl, + imageId: 0, + src: imageUrl, + }, + excerpt: markdownToTxt(collection.excerpt), + title: collection.title, + authors: collection.authors.map((author, index) => { + return { + name: author.name, + id: index.toFixed(), + }; + }), + domain: { + logo: 'https://getpocket.com/favicon.ico', + name: 'Pocket', + }, + datePublished: collection.publishedAt + ? DateTime.fromISO(collection.publishedAt).toJSDate() + : item.datePublished + ? DateTime.fromSQL(item.datePublished, { + zone: config.mysql.tz, + }).toJSDate() + : null, + url: item.givenUrl, + source: PocketMetadataSource.Collection, + __typename: 'ItemSummary', + }; + } + + /** + * + * @param item Item object from the Graph + * @param syndicatedArticle Syndication object from the graph + * @returns ItemSummary data to be shown to the user + */ + transformSyndicatedArticle( + item: Item, + syndicatedArticle?: SyndicatedArticle, + ): ItemSummary | undefined { + if (!syndicatedArticle) { + return; + } + const imageUrl = getOriginalUrlIfPocketImageCached( + syndicatedArticle.mainImage, + ); + + return { + id: item.id, + image: { + url: imageUrl, + imageId: 0, + src: imageUrl, + }, + excerpt: syndicatedArticle.excerpt, + title: syndicatedArticle.title, + authors: syndicatedArticle.authorNames.map((author, index) => { + return { + name: author, + id: index.toFixed(), + }; + }), + domain: { + logo: syndicatedArticle.publisher.logo, + name: syndicatedArticle.publisher.name, + }, + datePublished: syndicatedArticle.publishedAt + ? DateTime.fromISO(syndicatedArticle.publishedAt).toJSDate() + : item.datePublished + ? DateTime.fromSQL(item.datePublished, { + zone: config.mysql.tz, + }).toJSDate() + : null, + url: item.givenUrl, + source: PocketMetadataSource.Syndication, + __typename: 'ItemSummary', + }; + } + + /** + * + * @param item Item object from the Graph + * @param syndicatedArticle Syndication object from the graph + * @returns ItemSummary data to be shown to the user + */ + transformCorpusItem( + item: Item, + corpusItem?: CorpusItem, + ): ItemSummary | undefined { + if (!corpusItem) { + return; + } + const imageUrl = getOriginalUrlIfPocketImageCached(corpusItem.image.url); + + return { + id: item.id, + image: { + url: imageUrl, + imageId: 0, + src: imageUrl, + }, + excerpt: corpusItem.excerpt, + title: corpusItem.title, + authors: corpusItem.authors + .map((author) => { + return { + name: author.name, + id: author.sortOrder.toFixed(), + }; + }) + .sort((author1, author2) => + author1.id < author2.id ? -1 : author1.id > author2.id ? 1 : 0, + ), + domain: { + name: corpusItem.publisher, + }, + datePublished: corpusItem.datePublished + ? DateTime.fromISO(corpusItem.datePublished).toJSDate() + : item.datePublished + ? DateTime.fromSQL(item.datePublished, { + zone: config.mysql.tz, + }).toJSDate() + : null, + url: item.givenUrl, + source: PocketMetadataSource.CuratedCorpus, + __typename: 'ItemSummary', + }; + } + + /** + * Transforms the item into ItemSummary + * @param item The item that we need to transform + * @returns + */ + transformParserFallback(item: Item): ItemSummary | undefined { + return { + id: item.id, + image: item.topImage ?? item.images?.[0], + excerpt: item.excerpt, + title: item.title ?? item.givenUrl, + authors: item.authors, + domain: item.domainMetadata, + datePublished: item.datePublished + ? DateTime.fromSQL(item.datePublished, { + zone: config.mysql.tz, + }).toJSDate() + : null, + url: item.givenUrl, + source: PocketMetadataSource.PocketParser, + __typename: 'ItemSummary', + }; + } } diff --git a/servers/parser-graphql-wrapper/src/test/mutations/refreshMutation.integration.ts b/servers/parser-graphql-wrapper/src/test/mutations/refreshMutation.integration.ts index c60cfa2a9..269affb14 100644 --- a/servers/parser-graphql-wrapper/src/test/mutations/refreshMutation.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/mutations/refreshMutation.integration.ts @@ -14,6 +14,7 @@ import { nockResponseForParser, nockThreeStandardParserResponses, } from '../utils/parserResponse'; +import { cleanAll, restore } from 'nock'; import { BoolStringParam } from '../../datasources/ParserAPI'; import Keyv from 'keyv'; import { conn as sharesInit } from '../../databases/readitlaShares'; @@ -35,6 +36,8 @@ describe('refresh mutation', () => { await readitlbInit().destroy(); await sharesInit().destroy(); cache.disconnect(); + restore(); + cleanAll(); }); beforeAll(async () => { diff --git a/servers/parser-graphql-wrapper/src/test/queries/marticleParser.integration.ts b/servers/parser-graphql-wrapper/src/test/queries/marticleParser.integration.ts index fc19e69c4..a824b737e 100644 --- a/servers/parser-graphql-wrapper/src/test/queries/marticleParser.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/queries/marticleParser.integration.ts @@ -6,7 +6,7 @@ * - CircleCI config - Create a job to the function test npm script from above */ -import nock, { cleanAll } from 'nock'; +import nock, { cleanAll, restore } from 'nock'; import { getRedis } from '../../cache'; import { VideoType, Videoness } from '../../__generated__/resolvers-types'; import { startServer } from '../../apollo/server'; @@ -104,6 +104,7 @@ describe('Marticle integration ', () => { await server.stop(); await getRedis().disconnect(); cleanAll(); + restore(); }); it('should return marticle text for the given url', async () => { @@ -148,7 +149,7 @@ describe('Marticle integration ', () => { }, ]; - expect(res.body.data).not.toBeUndefined; + expect(res.body.data).not.toBeUndefined(); const marticle = res.body.data.itemByUrl.marticle; expect(marticle.length).toBeGreaterThan(0); expect(marticle).toStrictEqual(expected); @@ -196,7 +197,7 @@ describe('Marticle integration ', () => { const res = await request(app) .post(graphQLUrl) .send({ query: print(GET_ITEMS_BY_URL), variables }); - expect(res.body.data).not.toBeUndefined; + expect(res.body.data).not.toBeUndefined(); const marticle = res.body.data.itemByUrl.marticle; expect(marticle.length).toBeGreaterThan(0); expect(marticle).toStrictEqual([ @@ -263,7 +264,7 @@ describe('Marticle integration ', () => { const res = await request(app) .post(graphQLUrl) .send({ query: print(GET_ITEMS_BY_URL), variables }); - expect(res.body.data).not.toBeUndefined; + expect(res.body.data).not.toBeUndefined(); const marticle = res.body.data.itemByUrl.marticle; expect(marticle.length).toBeGreaterThan(0); expect(marticle).toStrictEqual([ @@ -319,7 +320,7 @@ describe('Marticle integration ', () => { .post(graphQLUrl) .send({ query: print(GET_ITEMS_BY_URL), variables }); - expect(res.body.data).not.toBeUndefined; + expect(res.body.data).not.toBeUndefined(); const marticle = res.body.data.itemByUrl.marticle; expect(marticle).toStrictEqual([]); }); @@ -358,7 +359,7 @@ describe('Marticle integration ', () => { const res = await request(app) .post(graphQLUrl) .send({ query: print(GET_ITEMS_BY_URL), variables }); - expect(res.body.data).not.toBeUndefined; + expect(res.body.data).not.toBeUndefined(); const marticle = res.body.data.itemByUrl.marticle; expect(marticle.length).toBeGreaterThan(0); expect(marticle).toStrictEqual([ diff --git a/servers/parser-graphql-wrapper/src/test/queries/oembed.integration.ts b/servers/parser-graphql-wrapper/src/test/queries/oembed.integration.ts index 0ae485e60..bff190d7d 100644 --- a/servers/parser-graphql-wrapper/src/test/queries/oembed.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/queries/oembed.integration.ts @@ -1,4 +1,4 @@ -import { cleanAll } from 'nock'; +import { cleanAll, restore } from 'nock'; import { getRedis } from '../../cache'; import { startServer } from '../../apollo/server'; import { ApolloServer } from '@apollo/server'; @@ -117,6 +117,7 @@ describe('oembedPreview', () => { await server.stop(); await getRedis().disconnect(); cleanAll(); + restore(); await readitlabDB.destroy(); await sharesInit().destroy(); jest.restoreAllMocks(); diff --git a/servers/parser-graphql-wrapper/src/test/queries/opengraph.integration.ts b/servers/parser-graphql-wrapper/src/test/queries/opengraph.integration.ts index df777f433..15766cc72 100644 --- a/servers/parser-graphql-wrapper/src/test/queries/opengraph.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/queries/opengraph.integration.ts @@ -1,4 +1,4 @@ -import { cleanAll } from 'nock'; +import { cleanAll, restore } from 'nock'; import { getRedis } from '../../cache'; import { startServer } from '../../apollo/server'; import { ApolloServer } from '@apollo/server'; @@ -122,6 +122,7 @@ describe('preview', () => { await server.stop(); await getRedis().disconnect(); cleanAll(); + restore(); await readitlabDB.destroy(); await sharesInit().destroy(); jest.restoreAllMocks(); diff --git a/servers/parser-graphql-wrapper/src/test/queries/parserApi.integration.ts b/servers/parser-graphql-wrapper/src/test/queries/parserApi.integration.ts index 51a0a878f..b96754e26 100644 --- a/servers/parser-graphql-wrapper/src/test/queries/parserApi.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/queries/parserApi.integration.ts @@ -3,7 +3,7 @@ import { ApolloServer } from '@apollo/server'; import { gql } from 'graphql-tag'; import { print } from 'graphql'; import request from 'supertest'; -import { cleanAll } from 'nock'; +import { cleanAll, restore } from 'nock'; import { getRedis } from '../../cache'; import { IContext } from '../../apollo/context'; import Keyv from 'keyv'; @@ -46,6 +46,7 @@ describe('ParserAPI DataSource', () => { afterAll(async () => { await cache.disconnect(); await server.stop(); + restore(); }); it('should retrieve item from cache if it exists and is not expired', async () => { // Nock a new article to ensure no refreshing diff --git a/servers/parser-graphql-wrapper/src/test/queries/preview.integration.ts.bak b/servers/parser-graphql-wrapper/src/test/queries/preview.integration.ts.bak new file mode 100644 index 000000000..06451fa50 --- /dev/null +++ b/servers/parser-graphql-wrapper/src/test/queries/preview.integration.ts.bak @@ -0,0 +1,170 @@ +// import { cleanAll, restore } from 'nock'; +// import { getRedis } from '../../cache'; +// import { startServer } from '../../apollo/server'; +// import { ApolloServer } from '@apollo/server'; +// import request from 'supertest'; +// import { print } from 'graphql'; +// import { gql } from 'graphql-tag'; +// import { IContext } from '../../apollo/context'; +// import { Application } from 'express'; +// import { IntMask } from '@pocket-tools/int-mask'; +// import { nockResponseForParser } from '../utils/parserResponse'; +// import { Kysely } from 'kysely'; +// import { DB } from '../../__generated__/readitlab'; +// import { conn as readitlabInit } from '../../databases/readitlab'; +// import { conn as sharesInit } from '../../databases/readitlaShares'; +// import { clearDynamoDB, dynamoClient } from '../../datasources/dynamoClient'; +// import { PocketMetadataSource } from '../../__generated__/resolvers-types'; + +// //TODO: Sync with @kschelonka on how we can test this best. For now I manually tested locally and in dev. +// describe.skip('preview', () => { +// let app: Application; +// let server: ApolloServer; +// let graphQLUrl: string; +// let readitlabDB: Kysely; + +// const GET_PREVIEW = gql` +// query display($representations: [_Any!]!) { +// _entities(representations: $representations) { +// ... on Item { +// preview { +// ... on PocketMetadata { +// source +// id +// title +// image { +// url +// src +// } +// excerpt +// authors { +// id +// } +// domain { +// name +// logo +// } +// datePublished +// url +// item { +// id +// } +// } +// } +// } +// } +// } +// `; + +// const testUrl = 'https://getpocket.com/collections/testing'; + +// const item = { +// item_id: 123, +// search_hash: '123455sdf', +// normal_url: testUrl, +// resolved_id: 123, +// has_old_dupes: 0, +// }; + +// const parserItemId = '123'; + +// const defaultExpected = { +// id: 'encodedId_202cb962ac59075b964b07152d234b70', +// image: null, +// excerpt: null, +// authors: null, +// domain: { logo: null, name: 'getpocket.com' }, +// datePublished: '2022-06-29T20:14:49.000Z', +// url: testUrl, +// item: { +// id: 'encodedId_202cb962ac59075b964b07152d234b70', +// }, +// }; + +// beforeAll(async () => { +// ({ app, server, url: graphQLUrl } = await startServer(0)); +// readitlabDB = readitlabInit(); +// await readitlabDB.deleteFrom('items_resolver').execute(); + +// //Create a seed item +// await readitlabDB.insertInto('items_resolver').values([item]).execute(); +// }); + +// beforeEach(async () => { +// jest.resetAllMocks(); +// jest.restoreAllMocks(); +// jest.spyOn(IntMask, 'decode').mockReturnValueOnce(123); +// jest.spyOn(IntMask, 'encode').mockReturnValueOnce('encodedId'); +// // flush the redis cache +// await getRedis().clear(); +// await clearDynamoDB(dynamoClient()); +// }); + +// afterAll(async () => { +// await server.stop(); +// await getRedis().disconnect(); +// cleanAll(); +// restore(); +// await readitlabDB.destroy(); +// await sharesInit().destroy(); +// jest.restoreAllMocks(); +// }); + +// it.each([ +// { +// parserData: {}, +// collection: { +// __typename: 'Collection', +// title: 'Super cool collection', +// excerpt: 'The collection', +// publishedAt: '2028-01-01', +// authors: [{ name: 'Billy Joel' }], +// imageUrl: 'https://thecoolimage.com', +// }, +// syndicatedArticle: undefined, +// corpusItem: undefined, +// expected: { +// title: 'Super cool collection', +// source: PocketMetadataSource.Collection, +// }, +// }, +// ])( +// 'should return opengraph display data if enabled', +// async ({ +// parserData, +// collection, +// syndicatedArticle, +// corpusItem, +// expected, +// }) => { +// nockResponseForParser(testUrl, { +// data: { +// item_id: parserItemId, +// given_url: testUrl, +// normal_url: testUrl, +// title: 'parser test', +// authors: [], +// images: [], +// videos: [], +// resolved_id: '16822', +// excerpt: null, +// domainMetadata: null, +// topImageUrl: null, +// // override the default +// ...parserData, +// }, +// }); +// const variables = { +// representations: [ +// { __typename: 'Item', collection, syndicatedArticle, corpusItem }, +// ], +// }; +// const res = await request(app) +// .post(graphQLUrl) +// .send({ query: print(GET_PREVIEW), variables }); +// expect(res.body.data).toEqual({ +// itemByUrl: { preview: { ...defaultExpected, ...expected } }, +// }); +// }, +// ); +// }); diff --git a/servers/parser-graphql-wrapper/src/test/queries/readerUrl.integration.ts b/servers/parser-graphql-wrapper/src/test/queries/readerUrl.integration.ts index 369d30fb1..2e2059bad 100644 --- a/servers/parser-graphql-wrapper/src/test/queries/readerUrl.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/queries/readerUrl.integration.ts @@ -6,6 +6,7 @@ import { gql } from 'graphql-tag'; import request from 'supertest'; import { Application } from 'express'; import { nockResponseForParser } from '../utils/parserResponse'; +import { restore, cleanAll } from 'nock'; import { getRedis } from '../../cache'; import { ParserResponse } from '../../datasources/ParserAPITypes'; import { Kysely } from 'kysely'; @@ -56,6 +57,8 @@ describe('referenceResolver', () => { afterAll(async () => { await server.stop(); await readitlabDB.destroy(); + restore(); + cleanAll(); }); it('should return resolved item for reader url', async () => { diff --git a/servers/parser-graphql-wrapper/src/test/queries/readerViewResult.integration.ts b/servers/parser-graphql-wrapper/src/test/queries/readerViewResult.integration.ts index 8072ba9a7..537acec28 100644 --- a/servers/parser-graphql-wrapper/src/test/queries/readerViewResult.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/queries/readerViewResult.integration.ts @@ -1,4 +1,4 @@ -import { cleanAll } from 'nock'; +import { cleanAll, restore } from 'nock'; import { getRedis } from '../../cache'; import { startServer } from '../../apollo/server'; import { ApolloServer } from '@apollo/server'; @@ -111,6 +111,7 @@ describe('readerSlug', () => { await server.stop(); await getRedis().disconnect(); cleanAll(); + restore(); await readitlaDB.destroy(); await sharesInit().destroy(); jest.restoreAllMocks(); diff --git a/servers/parser-graphql-wrapper/src/test/queries/referenceResolver.integration.ts b/servers/parser-graphql-wrapper/src/test/queries/referenceResolver.integration.ts index 706aeb7c4..548d6be27 100644 --- a/servers/parser-graphql-wrapper/src/test/queries/referenceResolver.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/queries/referenceResolver.integration.ts @@ -1,3 +1,4 @@ +import { cleanAll, restore } from 'nock'; import { ApolloServer } from '@apollo/server'; import { IContext } from '../../apollo/context'; import { startServer } from '../../apollo/server'; @@ -55,6 +56,8 @@ describe('referenceResolver', () => { afterAll(async () => { await server.stop(); await readitlabDB.destroy(); + cleanAll(); + restore(); }); it('should return item for a single item id', async () => { diff --git a/servers/parser-graphql-wrapper/src/test/queries/shortUrl.integration.ts b/servers/parser-graphql-wrapper/src/test/queries/shortUrl.integration.ts index 99ae0266c..0c5eabd0b 100644 --- a/servers/parser-graphql-wrapper/src/test/queries/shortUrl.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/queries/shortUrl.integration.ts @@ -2,7 +2,7 @@ import { ApolloServer } from '@apollo/server'; import { IContext } from '../../apollo/context'; import { startServer } from '../../apollo/server'; import { getRedis } from '../../cache'; -import { cleanAll } from 'nock'; +import { cleanAll, restore } from 'nock'; import { print } from 'graphql/index'; import { gql } from 'graphql-tag'; import request from 'supertest'; @@ -36,6 +36,7 @@ describe('ShortUrl', () => { await sharesConnection.destroy(); await getRedis().disconnect(); cleanAll(); + restore(); }); afterEach(() => jest.clearAllMocks()); diff --git a/servers/parser-graphql-wrapper/src/test/queries/ssml.integration.ts b/servers/parser-graphql-wrapper/src/test/queries/ssml.integration.ts index bbf0629a4..c3cbd2635 100644 --- a/servers/parser-graphql-wrapper/src/test/queries/ssml.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/queries/ssml.integration.ts @@ -1,4 +1,4 @@ -import { cleanAll } from 'nock'; +import { cleanAll, restore } from 'nock'; import { getRedis } from '../../cache'; import { startServer } from '../../apollo/server'; import { ApolloServer } from '@apollo/server'; @@ -32,6 +32,7 @@ describe('SSML integration ', () => { await server.stop(); await getRedis().disconnect(); cleanAll(); + restore(); await readitlabConn().destroy(); await sharesConn().destroy(); jest.restoreAllMocks(); diff --git a/servers/parser-graphql-wrapper/src/test/queries/timeToRead.integration.ts b/servers/parser-graphql-wrapper/src/test/queries/timeToRead.integration.ts index 5ce5d51a4..0bd3988a3 100644 --- a/servers/parser-graphql-wrapper/src/test/queries/timeToRead.integration.ts +++ b/servers/parser-graphql-wrapper/src/test/queries/timeToRead.integration.ts @@ -8,6 +8,7 @@ import { Application } from 'express'; import { nockResponseForParser } from '../utils/parserResponse'; import { getRedis } from '../../cache'; import { ParserResponse } from '../../datasources/ParserAPITypes'; +import { cleanAll, restore } from 'nock'; describe('timeToRead', () => { const testUrl = 'https://someurl.com'; @@ -42,6 +43,8 @@ describe('timeToRead', () => { afterAll(async () => { await server.stop(); + cleanAll(); + restore(); }); it('should return timeToRead for a CorpusItem when parser item has time_to_read property', async () => { diff --git a/servers/push-server/package.json b/servers/push-server/package.json index 6d967a5eb..0fff75f27 100644 --- a/servers/push-server/package.json +++ b/servers/push-server/package.json @@ -25,8 +25,8 @@ "watch": "tsc -w --preserveWatchOutput & nodemon --config ../../nodemon.json" }, "dependencies": { - "@aws-sdk/client-sqs": "3.609.0", - "@sentry/node": "8.18.0", + "@aws-sdk/client-sqs": "3.632.0", + "@sentry/node": "8.27.0", "apns2": "11.7.0", "dotenv": "16.4.5", "firebase-admin": "^12.0.0", @@ -37,13 +37,13 @@ "devDependencies": { "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "@types/node-gcm": "^1.0.5", "jest": "29.7.0", "nodemon": "3.1.4", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/servers/shareable-lists-api/eslint.config.mjs b/servers/shareable-lists-api/eslint.config.mjs index be4ca205d..415e8f3ea 100644 --- a/servers/shareable-lists-api/eslint.config.mjs +++ b/servers/shareable-lists-api/eslint.config.mjs @@ -1,3 +1,8 @@ import servers from '@pocket-tools/eslint-config/servers'; import tseslint from 'typescript-eslint'; -export default tseslint.config(...servers); +export default tseslint.config(...servers, { + rules: { + '@typescript-eslint/no-unused-vars': 'warn', + '@typescript-eslint/no-require-imports': 'warn', + }, +}); diff --git a/servers/shareable-lists-api/package.json b/servers/shareable-lists-api/package.json index e6e7b020c..438e5a34a 100644 --- a/servers/shareable-lists-api/package.json +++ b/servers/shareable-lists-api/package.json @@ -24,6 +24,7 @@ "migrate:dev": "npm run export-env && prisma migrate dev", "migrate:reset": "prisma migrate reset", "prebuild": "dotenv -e .env.ci -- prisma generate", + "pretest": "dotenv -e .env.ci -- prisma generate", "pretest-integrations": "dotenv -e .env.ci -- prisma migrate reset --skip-seed --force", "start": "npm run migrate:deploy && node dist/main.js", "test": "jest \"\\.spec\\.ts\"", @@ -34,16 +35,16 @@ "dependencies": { "@apollo/server": "4.10.4", "@apollo/server-plugin-response-cache": "4.1.3", - "@apollo/subgraph": "2.8.3", + "@apollo/subgraph": "2.9.0", "@apollo/utils.keyvadapter": "3.1.0", "@apollo/utils.keyvaluecache": "3.1.0", - "@aws-sdk/client-eventbridge": "3.609.0", + "@aws-sdk/client-eventbridge": "3.632.0", "@keyv/redis": "2.8.5", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/sentry": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@prisma/client": "5.14.0", - "@sentry/node": "8.18.0", + "@prisma/client": "5.18.0", + "@sentry/node": "8.27.0", "cors": "2.8.5", "express": "4.19.2", "express-validator": "^7.1.0", @@ -53,7 +54,7 @@ "keyv": "4.5.4", "kysely": "0.27.3", "mysql2": "3.10.3", - "prisma": "5.14.0", + "prisma": "5.18.0", "prisma-kysely": "1.8.0", "slugify": "1.6.6", "tslib": "2.6.3", @@ -64,16 +65,16 @@ "@faker-js/faker": "8.4.1", "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "dotenv": "16.4.5", "jest": "29.7.0", "jest-extended": "4.0.2", "nodemon": "3.1.4", "supertest": "7.0.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" }, "prisma": { "seed": "ts-node --emit=false prisma/seed.ts" diff --git a/servers/shared-snowplow-consumer/package.json b/servers/shared-snowplow-consumer/package.json index ed381a6c7..dcdd7c448 100644 --- a/servers/shared-snowplow-consumer/package.json +++ b/servers/shared-snowplow-consumer/package.json @@ -22,12 +22,11 @@ "watch": "tsc -w --preserveWatchOutput & nodemon --config ../../nodemon.json" }, "dependencies": { - "@aws-sdk/client-sqs": "3.609.0", + "@aws-sdk/client-sqs": "3.632.0", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/sentry": "workspace:*", - "@pocket-tools/tracing": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "@snowplow/node-tracker": "3.23.1", "@snowplow/tracker-core": "3.23.1", "express": "4.19.2", @@ -37,15 +36,15 @@ "devDependencies": { "@faker-js/faker": "8.4.1", "@pocket-tools/eslint-config": "workspace:*", - "@snowplow/snowtype": "^0.7.1", + "@snowplow/snowtype": "^0.8.2", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "jest": "29.7.0", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/servers/shared-snowplow-consumer/src/main.ts b/servers/shared-snowplow-consumer/src/main.ts index 5fdded717..a62cd6121 100644 --- a/servers/shared-snowplow-consumer/src/main.ts +++ b/servers/shared-snowplow-consumer/src/main.ts @@ -3,24 +3,14 @@ import { initSentry } from '@pocket-tools/sentry'; initSentry({ ...config.sentry, debug: config.sentry.environment == 'development', - skipOpenTelemetrySetup: true, }); -import { nodeSDKBuilder } from '@pocket-tools/tracing'; import { serverLogger } from '@pocket-tools/ts-logger'; +import { startServer } from './server'; //this must run before all imports and server start but after sentry //so open-telemetry can patch all libraries that we use -nodeSDKBuilder({ - host: config.tracing.host, - serviceName: config.tracing.serviceName, - release: config.sentry.release, - logger: serverLogger, - addSentry: true, -}).then(async () => { - await startServer(config.app.port); +startServer(config.app.port).then(() => { serverLogger.info( `🚀 Public server ready at http://localhost:${config.app.port}`, ); }); - -import { startServer } from './server'; diff --git a/servers/shared-snowplow-consumer/src/snowplow/user/userEventHandler.ts b/servers/shared-snowplow-consumer/src/snowplow/user/userEventHandler.ts index 0a606b6c8..ec578cb2e 100644 --- a/servers/shared-snowplow-consumer/src/snowplow/user/userEventHandler.ts +++ b/servers/shared-snowplow-consumer/src/snowplow/user/userEventHandler.ts @@ -85,11 +85,14 @@ export class UserEventHandler extends EventHandler { UserEventHandler.generateApiUserContext(data.detail), ]; - data['detail-type'] == 'account-deletion' - ? context.push( - UserEventHandler.generateDeleteEventAccountContext(data.detail), - ) - : context.push(UserEventHandler.generateAccountContext(data.detail)); + if (data['detail-type'] == 'account-deletion') { + context.push( + UserEventHandler.generateDeleteEventAccountContext(data.detail), + ); + } else { + context.push(UserEventHandler.generateAccountContext(data.detail)); + } + return context; } diff --git a/servers/shares-api/package.json b/servers/shares-api/package.json index af4bebe61..6665460ce 100644 --- a/servers/shares-api/package.json +++ b/servers/shares-api/package.json @@ -25,15 +25,14 @@ }, "dependencies": { "@apollo/server": "4.10.4", - "@apollo/subgraph": "2.8.3", - "@aws-sdk/client-dynamodb": "3.609.0", - "@aws-sdk/client-eventbridge": "3.609.0", - "@aws-sdk/lib-dynamodb": "3.609.0", + "@apollo/subgraph": "2.9.0", + "@aws-sdk/client-dynamodb": "3.632.0", + "@aws-sdk/client-eventbridge": "3.632.0", + "@aws-sdk/lib-dynamodb": "3.632.0", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/sentry": "workspace:*", - "@pocket-tools/tracing": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "@snowplow/tracker-core": "3.23.1", "cors": "2.8.5", "express": "4.19.2", @@ -51,16 +50,16 @@ "@parcel/watcher": "^2.4.1", "@pocket-tools/eslint-config": "workspace:*", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "concurrently": "^8.2.2", "jest": "29.7.0", "jest-extended": "4.0.2", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", "supertest": "7.0.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/servers/shares-api/src/main.ts b/servers/shares-api/src/main.ts index 081d66480..e98e190f3 100644 --- a/servers/shares-api/src/main.ts +++ b/servers/shares-api/src/main.ts @@ -3,22 +3,10 @@ import { initSentry } from '@pocket-tools/sentry'; initSentry({ ...config.sentry, debug: config.sentry.environment == 'development', - skipOpenTelemetrySetup: true, }); -import { nodeSDKBuilder } from '@pocket-tools/tracing'; import { serverLogger } from '@pocket-tools/ts-logger'; +import { startServer } from './apollo/server'; -//this must run before all imports and server start but after sentry -//so open-telemetry can patch all libraries that we use -nodeSDKBuilder({ - host: config.tracing.host, - serviceName: config.tracing.serviceName, - release: config.sentry.release, - logger: serverLogger, - addSentry: true, -}).then(async () => { - await startServer(config.app.port); +startServer(config.app.port).then(() => { serverLogger.info(`🚀 Server ready at http://localhost:${config.app.port}`); }); - -import { startServer } from './apollo/server'; diff --git a/servers/user-api/package.json b/servers/user-api/package.json index 1df41b27f..f03eed02a 100644 --- a/servers/user-api/package.json +++ b/servers/user-api/package.json @@ -19,14 +19,13 @@ }, "dependencies": { "@apollo/server": "4.10.4", - "@apollo/subgraph": "2.8.3", - "@aws-sdk/client-eventbridge": "3.609.0", + "@apollo/subgraph": "2.9.0", + "@aws-sdk/client-eventbridge": "3.632.0", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/int-mask": "workspace:*", "@pocket-tools/sentry": "workspace:*", - "@pocket-tools/tracing": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "dataloader": "2.2.2", "express": "4.19.2", "graphql": "16.8.1", @@ -39,18 +38,18 @@ "devDependencies": { "@faker-js/faker": "8.4.1", "@pocket-tools/eslint-config": "workspace:*", - "@sentry/types": "8.18.0", + "@sentry/types": "8.27.0", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "@types/supertest": "^6.0.2", "jest": "29.7.0", "jest-mock-req-res": "1.0.2", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", "supertest": "7.0.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/servers/user-api/src/context.ts b/servers/user-api/src/context.ts index a903f4dba..278803ca0 100644 --- a/servers/user-api/src/context.ts +++ b/servers/user-api/src/context.ts @@ -130,7 +130,7 @@ class ContextManager implements IContext { this.fxaUserId, ); this._userId = userDataService.userId; - } catch (e) { + } catch { serverLogger.error('Could not find user with FxA userId', { fxaUserId: this.fxaUserId, }); diff --git a/servers/user-api/src/main.ts b/servers/user-api/src/main.ts index eb19298cc..f9abed30a 100644 --- a/servers/user-api/src/main.ts +++ b/servers/user-api/src/main.ts @@ -3,28 +3,13 @@ import { initSentry } from '@pocket-tools/sentry'; initSentry({ ...config.sentry, debug: config.sentry.environment == 'development', - skipOpenTelemetrySetup: true, }); -//this must run before all imports and server start but after sentry -//so open-telemetry can patch all libraries that we use -import { - AdditionalInstrumentation, - nodeSDKBuilder, -} from '@pocket-tools/tracing'; + import { serverLogger } from '@pocket-tools/ts-logger'; +import { startServer } from './apollo'; -nodeSDKBuilder({ - host: config.tracing.host, - serviceName: config.tracing.serviceName, - release: config.sentry.release, - logger: serverLogger, - additionalInstrumentations: [AdditionalInstrumentation.KNEX], - addSentry: true, -}).then(async () => { - const { url } = await startServer(config.app.port); +startServer(config.app.port).then(({ url }) => { serverLogger.info( `🚀 Public server ready at http://localhost:${config.app.port}${url}`, ); }); - -import { startServer } from './apollo'; diff --git a/servers/user-list-search/package.json b/servers/user-list-search/package.json index b38f2c1d1..de2e635ca 100644 --- a/servers/user-list-search/package.json +++ b/servers/user-list-search/package.json @@ -22,18 +22,17 @@ }, "dependencies": { "@apollo/server": "4.10.4", - "@apollo/subgraph": "2.8.3", - "@aws-sdk/client-eventbridge": "3.609.0", - "@aws-sdk/client-sqs": "3.609.0", + "@apollo/subgraph": "2.9.0", + "@aws-sdk/client-eventbridge": "3.632.0", + "@aws-sdk/client-sqs": "3.632.0", "@elastic/elasticsearch": "^8.14.0", "@opensearch-project/opensearch": "^2.10.0", "@pocket-tools/apollo-cursor-pagination": "1.0.3", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/feature-flags-client": "workspace:*", "@pocket-tools/sentry": "workspace:*", - "@pocket-tools/tracing": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "elastic-builder": "^2.29.0", "elasticsearch": "^16.7.3", "express": "4.19.2", @@ -55,24 +54,25 @@ "@graphql-codegen/typescript-resolvers": "^4.1.0", "@pocket-tools/eslint-config": "workspace:*", "@snowplow/node-tracker": "3.23.1", - "@snowplow/snowtype": "^0.7.1", + "@snowplow/snowtype": "^0.8.2", "@types/elasticsearch": "^5.0.37", "@types/express": "4.17.21", "@types/graphql": "^14.5.0", "@types/jest": "29.5.12", "@types/mysql": "2.15.26", + "@types/node": "^20.16", "@types/supertest": "^6.0.2", "@types/uuid": "9.0.8", "concurrently": "^8.2.2", "jest": "29.7.0", "jest-extended": "4.0.2", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", "supertest": "7.0.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3", + "typescript": "5.5.4", "unleash-client": "5.6.1" } } diff --git a/servers/user-list-search/src/datasource/elasticsearch/elasticsearchSearch.ts b/servers/user-list-search/src/datasource/elasticsearch/elasticsearchSearch.ts index 174c551ff..c0816576c 100644 --- a/servers/user-list-search/src/datasource/elasticsearch/elasticsearchSearch.ts +++ b/servers/user-list-search/src/datasource/elasticsearch/elasticsearchSearch.ts @@ -728,7 +728,7 @@ export const search = async ( results: searchResults, totalResults: total.value, }; - } catch (e) { + } catch { // query_string returns an error for invalid syntax, catch this error and return an empty result // replicate the same behavior as simple_query_string which is less strict on syntax return { diff --git a/servers/user-list-search/src/main.ts b/servers/user-list-search/src/main.ts index 13fe555ec..110fec797 100644 --- a/servers/user-list-search/src/main.ts +++ b/servers/user-list-search/src/main.ts @@ -3,30 +3,13 @@ import { initSentry } from '@pocket-tools/sentry'; initSentry({ ...config.sentry, debug: config.sentry.environment == 'development', - skipOpenTelemetrySetup: true, }); -//this must run before all imports and server start but before sentry -//so open-telemetry can patch all libraries that we use -import { - AdditionalInstrumentation, - nodeSDKBuilder, -} from '@pocket-tools/tracing'; - import { serverLogger } from '@pocket-tools/ts-logger'; +import { startServer } from './server/serverUtils'; -nodeSDKBuilder({ - host: config.tracing.host, - serviceName: config.serviceName, - release: config.sentry.release, - logger: serverLogger, - additionalInstrumentations: [AdditionalInstrumentation.KNEX], - addSentry: true, -}).then(async () => { - const { url } = await startServer(config.app.port); +startServer(config.app.port).then(({ url }) => { serverLogger.info( `🚀 Public server ready at http://localhost:${config.app.port}${url}`, ); }); - -import { startServer } from './server/serverUtils'; diff --git a/servers/user-list-search/src/shared/util.ts b/servers/user-list-search/src/shared/util.ts index 972bcf066..cd98f5bd6 100644 --- a/servers/user-list-search/src/shared/util.ts +++ b/servers/user-list-search/src/shared/util.ts @@ -25,7 +25,7 @@ export const normalizeDate = (date: Date): string | null => { // we are receiving a non-null Date object but it's still throwing an error, so we need to figure out what is wrong with this date try { return date.toISOString(); - } catch (err) { + } catch { // Date is likely '0000-00-00 00:00:00' because the database has invalid data. if (date.toString() !== 'Invalid Date') { Sentry.captureException('normalizeDate failed', { diff --git a/servers/v3-proxy-api/package.json b/servers/v3-proxy-api/package.json index 677966059..efa5a3fd5 100644 --- a/servers/v3-proxy-api/package.json +++ b/servers/v3-proxy-api/package.json @@ -18,9 +18,8 @@ "@graphql-typed-document-node/core": "3.2.0", "@pocket-tools/apollo-utils": "workspace:*", "@pocket-tools/sentry": "workspace:*", - "@pocket-tools/tracing": "workspace:*", "@pocket-tools/ts-logger": "workspace:*", - "@sentry/node": "8.18.0", + "@sentry/node": "8.27.0", "express": "4.19.2", "express-validator": "^7.1.0", "graphql-request": "^6.1.0", @@ -36,15 +35,15 @@ "@pocket-tools/eslint-config": "workspace:*", "@types/express": "4.17.21", "@types/jest": "29.5.12", - "@types/node": "^20.14.11", + "@types/node": "^20.16", "@types/supertest": "^6.0.2", "jest": "29.7.0", - "nock": "14.0.0-beta.6", + "nock": "14.0.0-beta.11", "nodemon": "3.1.4", "supertest": "7.0.0", - "ts-jest": "29.2.3", + "ts-jest": "29.2.4", "ts-node": "10.9.2", "tsconfig": "workspace:*", - "typescript": "5.5.3" + "typescript": "5.5.4" } } diff --git a/servers/v3-proxy-api/src/config/index.ts b/servers/v3-proxy-api/src/config/index.ts index 1f3b141e6..e34711848 100644 --- a/servers/v3-proxy-api/src/config/index.ts +++ b/servers/v3-proxy-api/src/config/index.ts @@ -6,6 +6,12 @@ export default { defaultMaxAge: 86400, port: 4030, }, + // IDs of native extensions which have special routing/handling + // (the response and request params are mutated after receiving request + // and differ from other client behavior) + extensionApiIds: [ + 9346, 7035, 15449, 22931, 23283, 53720, 60289, 70018, 73360, + ], tracing: { host: process.env.OTLP_COLLECTOR_HOST || 'localhost', serviceName: 'v3-api-proxy', diff --git a/servers/v3-proxy-api/src/generated/graphql/types.ts b/servers/v3-proxy-api/src/generated/graphql/types.ts index 4817cb25a..6c5a677b1 100644 --- a/servers/v3-proxy-api/src/generated/graphql/types.ts +++ b/servers/v3-proxy-api/src/generated/graphql/types.ts @@ -828,6 +828,8 @@ export type Item = { * @deprecated Clients should not use this */ contentLength?: Maybe; + /** If the item is in corpus allow the item to reference it. Exposing curated info for consistent UX */ + corpusItem?: Maybe; /** The date the article was published */ datePublished?: Maybe; /** The date the parser resolved this item */ @@ -3438,7 +3440,7 @@ export type Topic = { displayName: Scalars['String']['output']; /** If returned a note to show to the user about the topic */ displayNote?: Maybe; - /** The id of the topic */ + /** The legacy UUID id of the topic */ id: Scalars['ID']['output']; /** Whether or not clients should show this topic ot users */ isDisplayed: Scalars['Boolean']['output']; @@ -4004,7 +4006,7 @@ export type SavedItemsCompleteQueryVariables = Exact<{ withTagsList: Scalars['Boolean']['input']; withAccountData: Scalars['Boolean']['input']; withRecentSearches: Scalars['Boolean']['input']; - tagsListSince?: InputMaybe; + tagListSince?: InputMaybe; }>; @@ -4018,7 +4020,7 @@ export type SavedItemsSimpleQueryVariables = Exact<{ withTagsList: Scalars['Boolean']['input']; withAccountData: Scalars['Boolean']['input']; withRecentSearches: Scalars['Boolean']['input']; - tagsListSince?: InputMaybe; + tagListSince?: InputMaybe; }>; @@ -4033,7 +4035,7 @@ export type SearchSavedItemsCompleteQueryVariables = Exact<{ withTagsList: Scalars['Boolean']['input']; withAccountData: Scalars['Boolean']['input']; withRecentSearches: Scalars['Boolean']['input']; - tagsListSince?: InputMaybe; + tagListSince?: InputMaybe; }>; @@ -4048,12 +4050,20 @@ export type SearchSavedItemsSimpleQueryVariables = Exact<{ withTagsList: Scalars['Boolean']['input']; withAccountData: Scalars['Boolean']['input']; withRecentSearches: Scalars['Boolean']['input']; - tagsListSince?: InputMaybe; + tagListSince?: InputMaybe; }>; export type SearchSavedItemsSimpleQuery = { __typename?: 'Query', user?: { __typename?: 'User', tagsList?: Array | null, id: string, username?: string | null, email?: string | null, accountCreationDate?: any | null, name?: string | null, firstName?: string | null, lastName?: string | null, isPremium?: boolean | null, isFxa?: boolean | null, description?: string | null, avatarUrl?: string | null, premiumStatus?: PremiumStatus | null, premiumFeatures?: Array | null, searchSavedItemsByOffset?: { __typename?: 'SavedItemSearchResultPage', offset: number, limit: number, totalCount: number, entries: Array<{ __typename?: 'SavedItemSearchResult', savedItem: { __typename?: 'SavedItem', id: string, status?: SavedItemStatus | null, url: string, isFavorite: boolean, isArchived: boolean, _updatedAt?: number | null, _createdAt: number, favoritedAt?: number | null, archivedAt?: number | null, title?: string | null, tags?: Array<{ __typename?: 'Tag', name: string }> | null, item: { __typename: 'Item', itemId: string, resolvedId?: string | null, wordCount?: number | null, title?: string | null, timeToRead?: number | null, listenDuration?: number | null, resolvedUrl?: any | null, givenUrl: any, excerpt?: string | null, domain?: string | null, isArticle?: boolean | null, isIndex?: boolean | null, hasVideo?: Videoness | null, hasImage?: Imageness | null, language?: string | null, topImage?: { __typename?: 'Image', url: any } | null } | { __typename: 'PendingItem' }, annotations?: { __typename?: 'SavedItemAnnotations', highlights?: Array<{ __typename?: 'Highlight', id: string, patch: string, quote: string, version: number, _createdAt: any } | null> | null } | null }, searchHighlights?: { __typename?: 'SaveItemSearchHighlights', fullText?: Array | null, url?: Array | null, tags?: Array | null, title?: Array | null } | null }> } | null, recentSearches?: Array<{ __typename?: 'RecentSearch', term: string, sortId: number, context?: { __typename?: 'RecentSearchContext', key?: string | null, value?: string | null } | null }> | null } | null }; +export type TagsListQueryVariables = Exact<{ + withAccountData: Scalars['Boolean']['input']; + tagListSince?: InputMaybe; +}>; + + +export type TagsListQuery = { __typename?: 'Query', user?: { __typename?: 'User', tagsList?: Array | null, id: string, username?: string | null, email?: string | null, accountCreationDate?: any | null, name?: string | null, firstName?: string | null, lastName?: string | null, isPremium?: boolean | null, isFxa?: boolean | null, description?: string | null, avatarUrl?: string | null, premiumStatus?: PremiumStatus | null, premiumFeatures?: Array | null } | null }; + export const AccountFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"accountCreationDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"isPremium"}},{"kind":"Field","name":{"kind":"Name","value":"isFxa"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"premiumStatus"}},{"kind":"Field","name":{"kind":"Name","value":"premiumFeatures"}}]}}]} as unknown as DocumentNode; export const HighlightFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"HighlightFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"highlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"patch"}},{"kind":"Field","name":{"kind":"Name","value":"quote"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}}]}}]}}]}}]} as unknown as DocumentNode; export const RecentSearchFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RecentSearchFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentSearches"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"term"}},{"kind":"Field","name":{"kind":"Name","value":"context"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sortId"}}]}}]}}]} as unknown as DocumentNode; @@ -4087,7 +4097,8 @@ export const ReplaceTagsDocument = {"kind":"Document","definitions":[{"kind":"Op export const SaveSearchDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"SaveSearch"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"search"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"RecentSearchInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"saveSearch"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"search"},"value":{"kind":"Variable","name":{"kind":"Name","value":"search"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"term"}}]}}]}}]} as unknown as DocumentNode; export const UnFavoriteSavedItemByUrlDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UnFavoriteSavedItemByUrl"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"givenUrl"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Url"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"timestamp"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"savedItemUnFavorite"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"givenUrl"},"value":{"kind":"Variable","name":{"kind":"Name","value":"givenUrl"}}},{"kind":"Argument","name":{"kind":"Name","value":"timestamp"},"value":{"kind":"Variable","name":{"kind":"Name","value":"timestamp"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]} as unknown as DocumentNode; export const UnFavoriteSavedItemByIdDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UnFavoriteSavedItemById"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"updateSavedItemUnFavoriteId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"timestamp"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"updateSavedItemUnFavorite"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"updateSavedItemUnFavoriteId"}}},{"kind":"Argument","name":{"kind":"Name","value":"timestamp"},"value":{"kind":"Variable","name":{"kind":"Name","value":"timestamp"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode; -export const SavedItemsCompleteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"savedItemsComplete"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OffsetPaginationInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemsFilter"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemsSort"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"tagsListSince"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}}}]}]},{"kind":"FragmentSpread","name":{"kind":"Name","value":"RecentSearchFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"tagsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"syncSince"},"value":{"kind":"Variable","name":{"kind":"Name","value":"tagsListSince"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"savedItemsByOffset"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemComplete"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"HighlightFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}}}]}]}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"itemId"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedId"}},{"kind":"Field","name":{"kind":"Name","value":"wordCount"}},{"kind":"Field","name":{"kind":"Name","value":"topImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"timeToRead"}},{"kind":"Field","name":{"kind":"Name","value":"listenDuration"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedUrl"}},{"kind":"Field","name":{"kind":"Name","value":"givenUrl"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isArticle"}},{"kind":"Field","name":{"kind":"Name","value":"isIndex"}},{"kind":"Field","name":{"kind":"Name","value":"hasVideo"}},{"kind":"Field","name":{"kind":"Name","value":"hasImage"}},{"kind":"Field","name":{"kind":"Name","value":"language"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"isFavorite"}},{"kind":"Field","name":{"kind":"Name","value":"isArchived"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"favoritedAt"}},{"kind":"Field","name":{"kind":"Name","value":"archivedAt"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemComplete"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}},{"kind":"Field","name":{"kind":"Name","value":"authors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"domainMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"logoGreyscale"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"images"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"imageId"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"height"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"credit"}},{"kind":"Field","name":{"kind":"Name","value":"caption"}}]}},{"kind":"Field","name":{"kind":"Name","value":"videos"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"videoId"}},{"kind":"Field","name":{"kind":"Name","value":"src"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"vid"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"accountCreationDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"isPremium"}},{"kind":"Field","name":{"kind":"Name","value":"isFxa"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"premiumStatus"}},{"kind":"Field","name":{"kind":"Name","value":"premiumFeatures"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RecentSearchFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentSearches"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"term"}},{"kind":"Field","name":{"kind":"Name","value":"context"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sortId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemComplete"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemSimple"}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemComplete"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"HighlightFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"highlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"patch"}},{"kind":"Field","name":{"kind":"Name","value":"quote"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}}]}}]}}]}}]} as unknown as DocumentNode; -export const SavedItemsSimpleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"savedItemsSimple"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OffsetPaginationInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemsFilter"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemsSort"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"tagsListSince"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}}}]}]},{"kind":"FragmentSpread","name":{"kind":"Name","value":"RecentSearchFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"tagsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"syncSince"},"value":{"kind":"Variable","name":{"kind":"Name","value":"tagsListSince"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"savedItemsByOffset"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemSimple"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"HighlightFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}}}]}]}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"itemId"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedId"}},{"kind":"Field","name":{"kind":"Name","value":"wordCount"}},{"kind":"Field","name":{"kind":"Name","value":"topImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"timeToRead"}},{"kind":"Field","name":{"kind":"Name","value":"listenDuration"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedUrl"}},{"kind":"Field","name":{"kind":"Name","value":"givenUrl"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isArticle"}},{"kind":"Field","name":{"kind":"Name","value":"isIndex"}},{"kind":"Field","name":{"kind":"Name","value":"hasVideo"}},{"kind":"Field","name":{"kind":"Name","value":"hasImage"}},{"kind":"Field","name":{"kind":"Name","value":"language"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"accountCreationDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"isPremium"}},{"kind":"Field","name":{"kind":"Name","value":"isFxa"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"premiumStatus"}},{"kind":"Field","name":{"kind":"Name","value":"premiumFeatures"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RecentSearchFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentSearches"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"term"}},{"kind":"Field","name":{"kind":"Name","value":"context"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sortId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"isFavorite"}},{"kind":"Field","name":{"kind":"Name","value":"isArchived"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"favoritedAt"}},{"kind":"Field","name":{"kind":"Name","value":"archivedAt"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"HighlightFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"highlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"patch"}},{"kind":"Field","name":{"kind":"Name","value":"quote"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}}]}}]}}]}}]} as unknown as DocumentNode; -export const SearchSavedItemsCompleteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"searchSavedItemsComplete"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"term"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OffsetPaginationInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchSortInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"tagsListSince"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}}}]}]},{"kind":"FragmentSpread","name":{"kind":"Name","value":"RecentSearchFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"tagsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"syncSince"},"value":{"kind":"Variable","name":{"kind":"Name","value":"tagsListSince"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"searchSavedItemsByOffset"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"term"},"value":{"kind":"Variable","name":{"kind":"Name","value":"term"}}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"savedItem"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemComplete"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"HighlightFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}}}]}]}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"SearchResultHighlights"}}]}},{"kind":"Field","name":{"kind":"Name","value":"offset"}},{"kind":"Field","name":{"kind":"Name","value":"limit"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"itemId"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedId"}},{"kind":"Field","name":{"kind":"Name","value":"wordCount"}},{"kind":"Field","name":{"kind":"Name","value":"topImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"timeToRead"}},{"kind":"Field","name":{"kind":"Name","value":"listenDuration"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedUrl"}},{"kind":"Field","name":{"kind":"Name","value":"givenUrl"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isArticle"}},{"kind":"Field","name":{"kind":"Name","value":"isIndex"}},{"kind":"Field","name":{"kind":"Name","value":"hasVideo"}},{"kind":"Field","name":{"kind":"Name","value":"hasImage"}},{"kind":"Field","name":{"kind":"Name","value":"language"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"isFavorite"}},{"kind":"Field","name":{"kind":"Name","value":"isArchived"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"favoritedAt"}},{"kind":"Field","name":{"kind":"Name","value":"archivedAt"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemComplete"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}},{"kind":"Field","name":{"kind":"Name","value":"authors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"domainMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"logoGreyscale"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"images"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"imageId"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"height"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"credit"}},{"kind":"Field","name":{"kind":"Name","value":"caption"}}]}},{"kind":"Field","name":{"kind":"Name","value":"videos"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"videoId"}},{"kind":"Field","name":{"kind":"Name","value":"src"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"vid"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"accountCreationDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"isPremium"}},{"kind":"Field","name":{"kind":"Name","value":"isFxa"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"premiumStatus"}},{"kind":"Field","name":{"kind":"Name","value":"premiumFeatures"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RecentSearchFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentSearches"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"term"}},{"kind":"Field","name":{"kind":"Name","value":"context"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sortId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemComplete"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemSimple"}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemComplete"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"HighlightFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"highlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"patch"}},{"kind":"Field","name":{"kind":"Name","value":"quote"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SearchResultHighlights"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemSearchResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"searchHighlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fullText"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}},{"kind":"Field","name":{"kind":"Name","value":"title"}}]}}]}}]} as unknown as DocumentNode; -export const SearchSavedItemsSimpleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"searchSavedItemsSimple"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"term"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OffsetPaginationInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchSortInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"tagsListSince"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}}}]}]},{"kind":"FragmentSpread","name":{"kind":"Name","value":"RecentSearchFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"tagsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"syncSince"},"value":{"kind":"Variable","name":{"kind":"Name","value":"tagsListSince"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"searchSavedItemsByOffset"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"term"},"value":{"kind":"Variable","name":{"kind":"Name","value":"term"}}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"savedItem"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemSimple"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"HighlightFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}}}]}]}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"SearchResultHighlights"}}]}},{"kind":"Field","name":{"kind":"Name","value":"offset"}},{"kind":"Field","name":{"kind":"Name","value":"limit"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"itemId"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedId"}},{"kind":"Field","name":{"kind":"Name","value":"wordCount"}},{"kind":"Field","name":{"kind":"Name","value":"topImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"timeToRead"}},{"kind":"Field","name":{"kind":"Name","value":"listenDuration"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedUrl"}},{"kind":"Field","name":{"kind":"Name","value":"givenUrl"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isArticle"}},{"kind":"Field","name":{"kind":"Name","value":"isIndex"}},{"kind":"Field","name":{"kind":"Name","value":"hasVideo"}},{"kind":"Field","name":{"kind":"Name","value":"hasImage"}},{"kind":"Field","name":{"kind":"Name","value":"language"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"accountCreationDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"isPremium"}},{"kind":"Field","name":{"kind":"Name","value":"isFxa"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"premiumStatus"}},{"kind":"Field","name":{"kind":"Name","value":"premiumFeatures"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RecentSearchFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentSearches"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"term"}},{"kind":"Field","name":{"kind":"Name","value":"context"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sortId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"isFavorite"}},{"kind":"Field","name":{"kind":"Name","value":"isArchived"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"favoritedAt"}},{"kind":"Field","name":{"kind":"Name","value":"archivedAt"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"HighlightFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"highlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"patch"}},{"kind":"Field","name":{"kind":"Name","value":"quote"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SearchResultHighlights"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemSearchResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"searchHighlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fullText"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}},{"kind":"Field","name":{"kind":"Name","value":"title"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file +export const SavedItemsCompleteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"savedItemsComplete"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OffsetPaginationInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemsFilter"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemsSort"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"tagListSince"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}}}]}]},{"kind":"FragmentSpread","name":{"kind":"Name","value":"RecentSearchFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"tagsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"syncSince"},"value":{"kind":"Variable","name":{"kind":"Name","value":"tagListSince"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"savedItemsByOffset"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemComplete"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"HighlightFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}}}]}]}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"itemId"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedId"}},{"kind":"Field","name":{"kind":"Name","value":"wordCount"}},{"kind":"Field","name":{"kind":"Name","value":"topImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"timeToRead"}},{"kind":"Field","name":{"kind":"Name","value":"listenDuration"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedUrl"}},{"kind":"Field","name":{"kind":"Name","value":"givenUrl"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isArticle"}},{"kind":"Field","name":{"kind":"Name","value":"isIndex"}},{"kind":"Field","name":{"kind":"Name","value":"hasVideo"}},{"kind":"Field","name":{"kind":"Name","value":"hasImage"}},{"kind":"Field","name":{"kind":"Name","value":"language"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"isFavorite"}},{"kind":"Field","name":{"kind":"Name","value":"isArchived"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"favoritedAt"}},{"kind":"Field","name":{"kind":"Name","value":"archivedAt"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemComplete"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}},{"kind":"Field","name":{"kind":"Name","value":"authors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"domainMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"logoGreyscale"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"images"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"imageId"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"height"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"credit"}},{"kind":"Field","name":{"kind":"Name","value":"caption"}}]}},{"kind":"Field","name":{"kind":"Name","value":"videos"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"videoId"}},{"kind":"Field","name":{"kind":"Name","value":"src"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"vid"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"accountCreationDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"isPremium"}},{"kind":"Field","name":{"kind":"Name","value":"isFxa"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"premiumStatus"}},{"kind":"Field","name":{"kind":"Name","value":"premiumFeatures"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RecentSearchFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentSearches"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"term"}},{"kind":"Field","name":{"kind":"Name","value":"context"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sortId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemComplete"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemSimple"}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemComplete"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"HighlightFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"highlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"patch"}},{"kind":"Field","name":{"kind":"Name","value":"quote"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}}]}}]}}]}}]} as unknown as DocumentNode; +export const SavedItemsSimpleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"savedItemsSimple"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OffsetPaginationInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemsFilter"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemsSort"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"tagListSince"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}}}]}]},{"kind":"FragmentSpread","name":{"kind":"Name","value":"RecentSearchFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"tagsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"syncSince"},"value":{"kind":"Variable","name":{"kind":"Name","value":"tagListSince"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"savedItemsByOffset"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemSimple"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"HighlightFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}}}]}]}]}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"itemId"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedId"}},{"kind":"Field","name":{"kind":"Name","value":"wordCount"}},{"kind":"Field","name":{"kind":"Name","value":"topImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"timeToRead"}},{"kind":"Field","name":{"kind":"Name","value":"listenDuration"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedUrl"}},{"kind":"Field","name":{"kind":"Name","value":"givenUrl"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isArticle"}},{"kind":"Field","name":{"kind":"Name","value":"isIndex"}},{"kind":"Field","name":{"kind":"Name","value":"hasVideo"}},{"kind":"Field","name":{"kind":"Name","value":"hasImage"}},{"kind":"Field","name":{"kind":"Name","value":"language"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"accountCreationDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"isPremium"}},{"kind":"Field","name":{"kind":"Name","value":"isFxa"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"premiumStatus"}},{"kind":"Field","name":{"kind":"Name","value":"premiumFeatures"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RecentSearchFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentSearches"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"term"}},{"kind":"Field","name":{"kind":"Name","value":"context"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sortId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"isFavorite"}},{"kind":"Field","name":{"kind":"Name","value":"isArchived"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"favoritedAt"}},{"kind":"Field","name":{"kind":"Name","value":"archivedAt"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"HighlightFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"highlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"patch"}},{"kind":"Field","name":{"kind":"Name","value":"quote"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}}]}}]}}]}}]} as unknown as DocumentNode; +export const SearchSavedItemsCompleteDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"searchSavedItemsComplete"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"term"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OffsetPaginationInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchSortInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"tagListSince"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}}}]}]},{"kind":"FragmentSpread","name":{"kind":"Name","value":"RecentSearchFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"tagsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"syncSince"},"value":{"kind":"Variable","name":{"kind":"Name","value":"tagListSince"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"searchSavedItemsByOffset"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"term"},"value":{"kind":"Variable","name":{"kind":"Name","value":"term"}}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"savedItem"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemComplete"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"HighlightFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}}}]}]}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"SearchResultHighlights"}}]}},{"kind":"Field","name":{"kind":"Name","value":"offset"}},{"kind":"Field","name":{"kind":"Name","value":"limit"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"itemId"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedId"}},{"kind":"Field","name":{"kind":"Name","value":"wordCount"}},{"kind":"Field","name":{"kind":"Name","value":"topImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"timeToRead"}},{"kind":"Field","name":{"kind":"Name","value":"listenDuration"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedUrl"}},{"kind":"Field","name":{"kind":"Name","value":"givenUrl"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isArticle"}},{"kind":"Field","name":{"kind":"Name","value":"isIndex"}},{"kind":"Field","name":{"kind":"Name","value":"hasVideo"}},{"kind":"Field","name":{"kind":"Name","value":"hasImage"}},{"kind":"Field","name":{"kind":"Name","value":"language"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"isFavorite"}},{"kind":"Field","name":{"kind":"Name","value":"isArchived"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"favoritedAt"}},{"kind":"Field","name":{"kind":"Name","value":"archivedAt"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemComplete"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}},{"kind":"Field","name":{"kind":"Name","value":"authors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"domainMetadata"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"logoGreyscale"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"images"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"imageId"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"height"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"credit"}},{"kind":"Field","name":{"kind":"Name","value":"caption"}}]}},{"kind":"Field","name":{"kind":"Name","value":"videos"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"videoId"}},{"kind":"Field","name":{"kind":"Name","value":"src"}},{"kind":"Field","name":{"kind":"Name","value":"width"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"vid"}},{"kind":"Field","name":{"kind":"Name","value":"length"}},{"kind":"Field","name":{"kind":"Name","value":"height"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"accountCreationDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"isPremium"}},{"kind":"Field","name":{"kind":"Name","value":"isFxa"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"premiumStatus"}},{"kind":"Field","name":{"kind":"Name","value":"premiumFeatures"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RecentSearchFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentSearches"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"term"}},{"kind":"Field","name":{"kind":"Name","value":"context"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sortId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemComplete"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemSimple"}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemComplete"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"HighlightFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"highlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"patch"}},{"kind":"Field","name":{"kind":"Name","value":"quote"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SearchResultHighlights"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemSearchResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"searchHighlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fullText"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}},{"kind":"Field","name":{"kind":"Name","value":"title"}}]}}]}}]} as unknown as DocumentNode; +export const SearchSavedItemsSimpleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"searchSavedItemsSimple"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"term"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"OffsetPaginationInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"filter"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchFilterInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sort"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"SearchSortInput"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"tagListSince"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}}}]}]},{"kind":"FragmentSpread","name":{"kind":"Name","value":"RecentSearchFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withRecentSearches"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"tagsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"syncSince"},"value":{"kind":"Variable","name":{"kind":"Name","value":"tagListSince"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withTagsList"}}}]}]},{"kind":"Field","name":{"kind":"Name","value":"searchSavedItemsByOffset"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"term"},"value":{"kind":"Variable","name":{"kind":"Name","value":"term"}}},{"kind":"Argument","name":{"kind":"Name","value":"pagination"},"value":{"kind":"Variable","name":{"kind":"Name","value":"pagination"}}},{"kind":"Argument","name":{"kind":"Name","value":"filter"},"value":{"kind":"Variable","name":{"kind":"Name","value":"filter"}}},{"kind":"Argument","name":{"kind":"Name","value":"sort"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sort"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"entries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"savedItem"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"SavedItemSimple"}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"HighlightFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAnnotations"}}}]}]}]}},{"kind":"FragmentSpread","name":{"kind":"Name","value":"SearchResultHighlights"}}]}},{"kind":"Field","name":{"kind":"Name","value":"offset"}},{"kind":"Field","name":{"kind":"Name","value":"limit"}},{"kind":"Field","name":{"kind":"Name","value":"totalCount"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"ItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"Field","name":{"kind":"Name","value":"itemId"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedId"}},{"kind":"Field","name":{"kind":"Name","value":"wordCount"}},{"kind":"Field","name":{"kind":"Name","value":"topImage"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"timeToRead"}},{"kind":"Field","name":{"kind":"Name","value":"listenDuration"}},{"kind":"Field","name":{"kind":"Name","value":"resolvedUrl"}},{"kind":"Field","name":{"kind":"Name","value":"givenUrl"}},{"kind":"Field","name":{"kind":"Name","value":"excerpt"}},{"kind":"Field","name":{"kind":"Name","value":"domain"}},{"kind":"Field","name":{"kind":"Name","value":"isArticle"}},{"kind":"Field","name":{"kind":"Name","value":"isIndex"}},{"kind":"Field","name":{"kind":"Name","value":"hasVideo"}},{"kind":"Field","name":{"kind":"Name","value":"hasImage"}},{"kind":"Field","name":{"kind":"Name","value":"language"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"accountCreationDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"isPremium"}},{"kind":"Field","name":{"kind":"Name","value":"isFxa"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"premiumStatus"}},{"kind":"Field","name":{"kind":"Name","value":"premiumFeatures"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"RecentSearchFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recentSearches"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"term"}},{"kind":"Field","name":{"kind":"Name","value":"context"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"key"}},{"kind":"Field","name":{"kind":"Name","value":"value"}}]}},{"kind":"Field","name":{"kind":"Name","value":"sortId"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SavedItemSimple"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"isFavorite"}},{"kind":"Field","name":{"kind":"Name","value":"isArchived"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"favoritedAt"}},{"kind":"Field","name":{"kind":"Name","value":"archivedAt"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"tags"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}},{"kind":"Field","name":{"kind":"Name","value":"item"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"__typename"}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Item"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"ItemSimple"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"HighlightFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"annotations"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"highlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"patch"}},{"kind":"Field","name":{"kind":"Name","value":"quote"}},{"kind":"Field","name":{"kind":"Name","value":"version"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"SearchResultHighlights"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"SavedItemSearchResult"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"searchHighlights"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fullText"}},{"kind":"Field","name":{"kind":"Name","value":"url"}},{"kind":"Field","name":{"kind":"Name","value":"tags"}},{"kind":"Field","name":{"kind":"Name","value":"title"}}]}}]}}]} as unknown as DocumentNode; +export const TagsListDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"tagsList"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"tagListSince"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"ISOString"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"user"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"tagsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"syncSince"},"value":{"kind":"Variable","name":{"kind":"Name","value":"tagListSince"}}}]},{"kind":"FragmentSpread","name":{"kind":"Name","value":"AccountFields"},"directives":[{"kind":"Directive","name":{"kind":"Name","value":"include"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"if"},"value":{"kind":"Variable","name":{"kind":"Name","value":"withAccountData"}}}]}]}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"AccountFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"username"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"accountCreationDate"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"firstName"}},{"kind":"Field","name":{"kind":"Name","value":"lastName"}},{"kind":"Field","name":{"kind":"Name","value":"isPremium"}},{"kind":"Field","name":{"kind":"Name","value":"isFxa"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"avatarUrl"}},{"kind":"Field","name":{"kind":"Name","value":"premiumStatus"}},{"kind":"Field","name":{"kind":"Name","value":"premiumFeatures"}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/servers/v3-proxy-api/src/graph/get/toRest.spec.ts b/servers/v3-proxy-api/src/graph/get/toRest.spec.ts index 493618e5c..5e7464f9c 100644 --- a/servers/v3-proxy-api/src/graph/get/toRest.spec.ts +++ b/servers/v3-proxy-api/src/graph/get/toRest.spec.ts @@ -1,4 +1,5 @@ import { + SavedItemsCompleteQuery, SavedItemsSimpleQuery, SavedItemStatus, } from '../../generated/graphql'; @@ -137,6 +138,39 @@ describe('GraphQL <> Rest convesion', () => { expect(res['id3'].status).toEqual('2'); expect(res['id4'].status).toEqual('3'); }); + it('redacts metadata except item_id for deleted status', () => { + const entries = [ + { id: 'id1', status: SavedItemStatus.Unread }, + { id: 'id3', status: SavedItemStatus.Deleted }, + ].map((data) => ({ + __typename: 'SavedItem' as const, + ...testSavedItemFragment({ + ...mockSavedItemFragment, + ...data, + }), + item: { + ...testItemFragment({ + ...mockItemFragment, + itemId: data.id, + }), + }, + })); + const graphResponse: SavedItemsSimpleQuery = { + user: { + savedItemsByOffset: { + totalCount: 10, + entries, + }, + }, + }; + const res = savedItemsSimpleToRest(graphResponse).list; + expect(res['id3']).toEqual({ item_id: 'id3', status: '2' }); + expect(res['id1']).toMatchObject({ + item_id: 'id1', + given_title: 'given title', + given_url: 'https://test.com', + }); + }); it('should return defaults for pending items', () => { const graphResponse: SavedItemsSimpleQuery = { user: { @@ -232,6 +266,40 @@ describe('GraphQL <> Rest convesion', () => { }); expect(res).toEqual(expectedGetCompleteAnnotations); }); + it('redacts metadata except item_id for deleted status', () => { + const entries = [ + { id: 'id1', status: SavedItemStatus.Unread }, + { id: 'id3', status: SavedItemStatus.Deleted }, + ].map((data) => ({ + __typename: 'SavedItem' as const, + ...testSavedItemFragment({ + ...mockSavedItemFragment, + ...data, + }), + item: { + ...testItemFragment({ + ...mockItemFragment, + itemId: data.id, + }), + }, + })); + const graphResponse: SavedItemsCompleteQuery = { + user: { + savedItemsByOffset: { + totalCount: 10, + entries, + }, + }, + }; + const res = savedItemsCompleteToRest(graphResponse).list; + expect(res['id3']).toEqual({ item_id: 'id3', status: '2' }); + expect(res['id1']).toMatchObject({ + item_id: 'id1', + given_title: 'given title', + given_url: 'https://test.com', + domain_metadata: {}, + }); + }); }); describe('convertSearchSavedItemSimple', () => { it('works for search response with results (free tier, simple)', () => { diff --git a/servers/v3-proxy-api/src/graph/get/toRest.ts b/servers/v3-proxy-api/src/graph/get/toRest.ts index 8e8f26678..050bee855 100644 --- a/servers/v3-proxy-api/src/graph/get/toRest.ts +++ b/servers/v3-proxy-api/src/graph/get/toRest.ts @@ -9,6 +9,7 @@ import { RecentSearchFieldsFragment, SavedItemsCompleteQuery, SavedItemsSimpleQuery, + SavedItemStatus, SearchSavedItemsCompleteQuery, SearchSavedItemsSimpleQuery, } from '../../generated/graphql'; @@ -37,6 +38,7 @@ import { AccountResponse, PremiumFeatures, RecentSearchResponse, + DeletedItem, } from '../types'; import * as tx from '../shared/transforms'; import { DateTime } from 'luxon'; @@ -261,7 +263,10 @@ export function SearchResultTransformerSimple( index: number, ): ListItemWithSearchHighlights { return { - ...ListItemTransformerSimple(searchResult.savedItem, index), + ...(ListItemTransformerSimple( + searchResult.savedItem, + index, + ) as ListItemObject), // We do not search deleted items; simplify with type annotation for now ...HighlightsTransformer(searchResult.searchHighlights), }; } @@ -274,7 +279,10 @@ export function SearchResultTransformerComplete( index: number, ): ListItemCompleteWithSearchHighlights { return { - ...ListItemTransformerComplete(searchResult.savedItem, index), + ...(ListItemTransformerComplete( + searchResult.savedItem, + index, + ) as ListItemObjectComplete), // We do not search deleted items; simplify with type annotation for now ...HighlightsTransformer(searchResult.searchHighlights), }; } @@ -286,7 +294,7 @@ export function SearchResultTransformerComplete( export function ListItemTransformerSimple( savedItem: SavedItemSimple, index: number, -): ListItemObject { +): ListItemObject | DeletedItem { return ListItemTransformer(savedItem, index); } /** @@ -296,9 +304,13 @@ export function ListItemTransformerSimple( export function ListItemTransformerComplete( savedItem: SavedItemComplete, index: number, -): ListItemObjectComplete { +): ListItemObjectComplete | DeletedItem { const simple = ListItemTransformer(savedItem, index); - if (savedItem.item.__typename === 'PendingItem') { + // Don't need to continue processing if pending or deleted + if ( + savedItem.item.__typename === 'PendingItem' || + savedItem.status === SavedItemStatus.Deleted + ) { return simple; } const completeFieldMap = { @@ -336,7 +348,7 @@ export function ListItemTransformerComplete( function ListItemTransformer( savedItem: T, index: number, -): ListItemObject | ListItemObjectComplete { +): ListItemObject | ListItemObjectComplete | DeletedItem { const statusMap = { UNREAD: '0' as const, ARCHIVED: '1' as const, @@ -353,6 +365,14 @@ function ListItemTransformer( time_favorited: (savedItem.favoritedAt ?? '0').toString(), sort_id: index, }; + // Redact information from deleted items, and return early + // just need item_id and status + if (baseFields.status === statusMap['DELETED']) { + return { + item_id: baseFields.item_id, + status: baseFields.status, + }; + } const conditionalFields = {}; const tags = tx.TagsReducer(savedItem.tags, savedItem.id); tags != null && (conditionalFields['tags'] = tags); diff --git a/servers/v3-proxy-api/src/graph/graphQLClient.ts b/servers/v3-proxy-api/src/graph/graphQLClient.ts index 110dda8ac..5617ce6ae 100644 --- a/servers/v3-proxy-api/src/graph/graphQLClient.ts +++ b/servers/v3-proxy-api/src/graph/graphQLClient.ts @@ -34,6 +34,9 @@ import { SearchSavedItemsCompleteQuery, SearchSavedItemsCompleteDocument, SearchSavedItemsSimpleDocument, + TagsListQueryVariables, + TagsListQuery, + TagsListDocument, } from '../generated/graphql'; import config from '../config'; import * as Sentry from '@sentry/node'; @@ -157,7 +160,7 @@ export class GraphQLClientFactory { !( error.path && Array.isArray(error.path) && - error.path.indexOf('recentSearches') && + error.path.indexOf('recentSearches') >= 0 && error.extensions.code === 'FORBIDDEN' ), ); @@ -316,3 +319,25 @@ export async function addSavedItem( >(AddSavedItemCompleteDocument, variables); } } + +/** + * function call to get saves (detailType=simple) + * + * @param accessToken accessToken of the user + * @param consumerKey consumerKey associated with the user + * @param headers any headers received by proxy is just pass through to web graphQL proxy. + * @param variables input variables required for the query + */ +export async function getTagList( + accessToken: string, + consumerKey: string, + headers: any, + variables: TagsListQueryVariables, +): Promise { + Sentry.addBreadcrumb({ message: 'invoking getTagList' }); + const client = new GraphQLClientFactory(accessToken, consumerKey, headers); + return client.request( + TagsListDocument, + variables, + ); +} diff --git a/servers/v3-proxy-api/src/graph/shared/transforms.ts b/servers/v3-proxy-api/src/graph/shared/transforms.ts index 5425525a5..1e952ac9b 100644 --- a/servers/v3-proxy-api/src/graph/shared/transforms.ts +++ b/servers/v3-proxy-api/src/graph/shared/transforms.ts @@ -150,6 +150,7 @@ export function DomainMetadataTransformer( metadata: DomainMetadata | undefined, ): DomainMetadataItemObject { const metadataResponse = {} as DomainMetadataItemObject; + if (metadata == null) return metadataResponse; metadata.name && (metadataResponse['name'] = metadata.name); metadata.logo && (metadataResponse['logo'] = metadata.logo); metadata.logoGreyscale && diff --git a/servers/v3-proxy-api/src/graph/types.ts b/servers/v3-proxy-api/src/graph/types.ts index 622856fbf..61c58ef8d 100644 --- a/servers/v3-proxy-api/src/graph/types.ts +++ b/servers/v3-proxy-api/src/graph/types.ts @@ -22,7 +22,7 @@ export type ToStringParams = { export type GetResponseSimple = { //todo: add top level fields //e.g status, complete - as they are not mapped by developer portal docs - list: { [key: string]: ListItemObject }; + list: { [key: string]: ListItemObject | DeletedItem }; } & GetStaticResponse & GetTopLevelDefaultResponse & TagsList; @@ -137,7 +137,7 @@ export type GetTopLevelDefaultResponse = { export type GetResponseComplete = { // search_meta: { search_type: 'normal' }; - list: { [key: string]: ListItemObjectComplete }; + list: { [key: string]: ListItemObjectComplete | DeletedItem }; } & GetStaticResponse & GetTopLevelDefaultResponse & TagsList; @@ -156,7 +156,7 @@ export type PassthroughResponse = { }; export type FetchResponse = { - list: { [key: string]: ListItemObjectComplete }; + list: { [key: string]: ListItemObjectComplete | DeletedItem }; passthrough: PassthroughResponse; } & GetResponseCompleteTotal; @@ -348,6 +348,8 @@ export type ListItemObject = { listen_duration_estimate: number; }; +export type DeletedItem = { item_id: string; status: '2' }; + export type ListItemObjectComplete = ListItemObject & ListItemObjectAdditional; export type ListItemObjectAdditional = { diff --git a/servers/v3-proxy-api/src/graphql/queries/savedItemsComplete.graphql b/servers/v3-proxy-api/src/graphql/queries/savedItemsComplete.graphql index 34301391a..35253ab71 100644 --- a/servers/v3-proxy-api/src/graphql/queries/savedItemsComplete.graphql +++ b/servers/v3-proxy-api/src/graphql/queries/savedItemsComplete.graphql @@ -6,12 +6,12 @@ query savedItemsComplete( $withTagsList: Boolean! $withAccountData: Boolean! $withRecentSearches: Boolean! - $tagsListSince: ISOString + $tagListSince: ISOString ) { user { ...AccountFields @include(if: $withAccountData) ...RecentSearchFields @include(if: $withRecentSearches) - tagsList(syncSince: $tagsListSince) @include(if: $withTagsList) + tagsList(syncSince: $tagListSince) @include(if: $withTagsList) savedItemsByOffset(pagination: $pagination, filter: $filter, sort: $sort) { entries { ...SavedItemComplete diff --git a/servers/v3-proxy-api/src/graphql/queries/savedItemsSimple.graphql b/servers/v3-proxy-api/src/graphql/queries/savedItemsSimple.graphql index 7613e145f..7e7d67a4f 100644 --- a/servers/v3-proxy-api/src/graphql/queries/savedItemsSimple.graphql +++ b/servers/v3-proxy-api/src/graphql/queries/savedItemsSimple.graphql @@ -6,12 +6,12 @@ query savedItemsSimple( $withTagsList: Boolean! $withAccountData: Boolean! $withRecentSearches: Boolean! - $tagsListSince: ISOString + $tagListSince: ISOString ) { user { ...AccountFields @include(if: $withAccountData) ...RecentSearchFields @include(if: $withRecentSearches) - tagsList(syncSince: $tagsListSince) @include(if: $withTagsList) + tagsList(syncSince: $tagListSince) @include(if: $withTagsList) savedItemsByOffset(pagination: $pagination, filter: $filter, sort: $sort) { entries { ...SavedItemSimple diff --git a/servers/v3-proxy-api/src/graphql/queries/searchSavedItemsComplete.graphql b/servers/v3-proxy-api/src/graphql/queries/searchSavedItemsComplete.graphql index f1901a029..9d9771c92 100644 --- a/servers/v3-proxy-api/src/graphql/queries/searchSavedItemsComplete.graphql +++ b/servers/v3-proxy-api/src/graphql/queries/searchSavedItemsComplete.graphql @@ -7,12 +7,12 @@ query searchSavedItemsComplete( $withTagsList: Boolean! $withAccountData: Boolean! $withRecentSearches: Boolean! - $tagsListSince: ISOString + $tagListSince: ISOString ) { user { ...AccountFields @include(if: $withAccountData) ...RecentSearchFields @include(if: $withRecentSearches) - tagsList(syncSince: $tagsListSince) @include(if: $withTagsList) + tagsList(syncSince: $tagListSince) @include(if: $withTagsList) searchSavedItemsByOffset( term: $term pagination: $pagination diff --git a/servers/v3-proxy-api/src/graphql/queries/searchSavedItemsSimple.graphql b/servers/v3-proxy-api/src/graphql/queries/searchSavedItemsSimple.graphql index 6a747dc67..0ea22df8f 100644 --- a/servers/v3-proxy-api/src/graphql/queries/searchSavedItemsSimple.graphql +++ b/servers/v3-proxy-api/src/graphql/queries/searchSavedItemsSimple.graphql @@ -7,12 +7,12 @@ query searchSavedItemsSimple( $withTagsList: Boolean! $withAccountData: Boolean! $withRecentSearches: Boolean! - $tagsListSince: ISOString + $tagListSince: ISOString ) { user { ...AccountFields @include(if: $withAccountData) ...RecentSearchFields @include(if: $withRecentSearches) - tagsList(syncSince: $tagsListSince) @include(if: $withTagsList) + tagsList(syncSince: $tagListSince) @include(if: $withTagsList) searchSavedItemsByOffset( term: $term pagination: $pagination diff --git a/servers/v3-proxy-api/src/graphql/queries/tagsList.graphql b/servers/v3-proxy-api/src/graphql/queries/tagsList.graphql new file mode 100644 index 000000000..c7b88658d --- /dev/null +++ b/servers/v3-proxy-api/src/graphql/queries/tagsList.graphql @@ -0,0 +1,9 @@ +query tagsList( + $withAccountData: Boolean! + $tagListSince: ISOString +) { + user { + tagsList(syncSince: $tagListSince) + ...AccountFields @include(if: $withAccountData) + } +} diff --git a/servers/v3-proxy-api/src/main.ts b/servers/v3-proxy-api/src/main.ts index ab3704cc9..37f1111bd 100644 --- a/servers/v3-proxy-api/src/main.ts +++ b/servers/v3-proxy-api/src/main.ts @@ -3,25 +3,13 @@ import { initSentry } from '@pocket-tools/sentry'; initSentry({ ...config.sentry, debug: config.sentry.environment == 'development', - skipOpenTelemetrySetup: true, }); -//this must run before all imports and server start but before sentry -//so open-telemetry can patch all libraries that we use -import { nodeSDKBuilder } from '@pocket-tools/tracing'; import { serverLogger } from '@pocket-tools/ts-logger'; +import { startServer } from './server'; -nodeSDKBuilder({ - host: config.tracing.host, - serviceName: config.tracing.serviceName, - release: config.sentry.release, - logger: serverLogger, - addSentry: true, -}).then(async () => { - await startServer(config.app.port); +startServer(config.app.port).then(() => { serverLogger.info( `🚀 Public server ready at http://localhost:${config.app.port}`, ); }); - -import { startServer } from './server'; diff --git a/servers/v3-proxy-api/src/routes/ActionsRouter.ts b/servers/v3-proxy-api/src/routes/ActionsRouter.ts index f034911ac..21baa4ead 100644 --- a/servers/v3-proxy-api/src/routes/ActionsRouter.ts +++ b/servers/v3-proxy-api/src/routes/ActionsRouter.ts @@ -93,11 +93,13 @@ type SendActionError = { type SendActionResult = { status: 1; action_errors: Array; - action_results: Array; + action_results: Array< + AddResponse['item'] | PendingAddResponse['item'] | boolean + >; }; export class ActionsRouter { - private client: GraphQLClient; + protected client: GraphQLClient; constructor( accessToken: string, consumerKey: string, @@ -190,6 +192,7 @@ export class ActionsRouter { } return result; } + /** * Process the 'add' action from a batch of actions sent to /v3/send. * The actions should be validated and sanitized before this is invoked. @@ -197,7 +200,7 @@ export class ActionsRouter { */ public async add( input: ItemAddAction, - ): Promise { + ): Promise { if (input.url != null) { const addVars: { input: SavedItemUpsertInput; @@ -208,7 +211,8 @@ export class ActionsRouter { ...(input.title && { title: input.title }), }, }; - return await processV3Add(this.client, addVars, input.tags); + const result = await processV3Add(this.client, addVars, input.tags); + return result['item']; } this.invalidAction({ action: 'add (item_id only)' }); } @@ -219,7 +223,7 @@ export class ActionsRouter { */ public async readd( input: Omit & { action: 'readd' }, - ): Promise { + ): Promise { if (input.itemId != null) { const variables: ReAddByIdMutationVariables = { id: input.itemId.toString(), @@ -231,7 +235,8 @@ export class ActionsRouter { >(ReAddByIdDocument, variables); // TODO: Technically this is nullable, but is it ever // in the case that the client does not throw an error? - return AddItemTransformer(result['reAddById']!); + const added = AddItemTransformer(result['reAddById']!); + return added['item']; } else { const addVars: { input: SavedItemUpsertInput; @@ -241,7 +246,8 @@ export class ActionsRouter { timestamp: input.time, }, }; - return await processV3Add(this.client, addVars); + const added = await processV3Add(this.client, addVars); + return added['item']; } } /** @@ -299,7 +305,7 @@ export class ActionsRouter { * @returns true (operation is successful unless error is thrown) * @throws ClientError if operation fails */ - private async favorite( + public async favorite( input: Omit & { action: 'favorite' }, ): Promise { if (input.itemId) { diff --git a/servers/v3-proxy-api/src/routes/v3Add.ts b/servers/v3-proxy-api/src/routes/v3Add.ts index 1a63d0cb5..0ba065486 100644 --- a/servers/v3-proxy-api/src/routes/v3Add.ts +++ b/servers/v3-proxy-api/src/routes/v3Add.ts @@ -13,6 +13,7 @@ import { InputValidationError } from '../errors/InputValidationError'; import { AddItemTransformer } from '../graph/add/toRest'; import { GraphQLClient } from 'graphql-request'; import { asyncHandler } from '../middleware/asyncHandler'; +import { AddResponse, PendingAddResponse } from '../graph/types'; const router: Router = Router(); @@ -86,7 +87,7 @@ export async function processV3Add( | AddSavedItemCompleteMutationVariables // these are the same | AddSavedItemBeforeTagMutationVariables, tags?: string[], -) { +): Promise { if (tags == null) { const result = await addSavedItem(client, variables); return AddItemTransformer(result['upsertSavedItem']); diff --git a/servers/v3-proxy-api/src/routes/v3Get.integration.ts b/servers/v3-proxy-api/src/routes/v3Get.integration.ts index 8ec7bb90f..8e486e98f 100644 --- a/servers/v3-proxy-api/src/routes/v3Get.integration.ts +++ b/servers/v3-proxy-api/src/routes/v3Get.integration.ts @@ -1299,4 +1299,98 @@ describe('v3Get', () => { expect(response.headers['x-source']).toBe(expectedHeaders['X-Source']); }); }); + describe('for extensions', () => { + // Weird but intentional prod behavior: + // * search + taglist will discard search results + // * taglist + total does not return total field + // We won't bother faithfully replicating and testing this, + // since it's for extensions and really doesn't make sense; + // they shouldn't make requests like this (and we have control) + let clientSpy; + afterEach(() => clientSpy.mockRestore()); + it.each([ + { + requestData: { + detailType: 'simple', + }, + fixture: { + requestData: mockGraphGetSimpleTagsList, + }, + responseData: expectedGetSimpleTagslist, + }, + { + requestData: { + detailType: 'complete', + }, + fixture: { + requestData: mockGraphGetCompleteTagsList, + }, + responseData: expectedGetCompleteTagslist, + }, + ])( + "doesn't return list data if taglist is specified", + async ({ requestData, fixture, responseData }) => { + clientSpy = jest + .spyOn(GraphQLClient.prototype, 'request') + .mockResolvedValueOnce(fixture.requestData); + const response = await request(app) + .get('/v3/get') + .query({ + ...requestData, + consumer_key: '7035-test', + access_token: 'test', + taglist: '1', + since: 1712766000, + }); + delete responseData['list']; + expect(response.body).toEqual(responseData); + }, + ); + it.each([ + { + requestData: { + detailType: 'simple', + forcetaglist: '1', + }, + fixture: { + requestData: mockGraphGetSimple, + }, + responseData: expectedGetSimple, + }, + { + requestData: { + detailType: 'complete', + }, + fixture: { + requestData: mockGraphGetComplete, + }, + responseData: expectedGetComplete, + }, + { + requestData: { + detailType: 'simple', + forceaccount: '1', + }, + fixture: { + requestData: mockGraphGetSimpleFreeAccount, + }, + responseData: expectedGetSimpleFreeAccount, + }, + ])( + 'returns list data if taglist is not specified (including forcetaglist... yes...)', + async ({ requestData, fixture, responseData }) => { + clientSpy = jest + .spyOn(GraphQLClient.prototype, 'request') + .mockResolvedValueOnce(fixture.requestData); + const response = await request(app) + .get('/v3/get') + .query({ + ...requestData, + consumer_key: '7035-test', + access_token: 'test', + }); + expect(response.body).toEqual(responseData); + }, + ); + }); }); diff --git a/servers/v3-proxy-api/src/routes/v3Get.ts b/servers/v3-proxy-api/src/routes/v3Get.ts index 573259346..4a3e5a64d 100644 --- a/servers/v3-proxy-api/src/routes/v3Get.ts +++ b/servers/v3-proxy-api/src/routes/v3Get.ts @@ -8,6 +8,7 @@ import { callSavedItemsByOffsetComplete, callSearchByOffsetComplete, callSearchByOffsetSimple, + getTagList, } from '../graph/graphQLClient'; import { savedItemsSimpleToRest, @@ -23,6 +24,7 @@ import { checkSchema, validationResult, matchedData } from 'express-validator'; import { V3GetParams, V3GetSchema } from './validations'; import { InputValidationError } from '../errors/InputValidationError'; import { asyncHandler } from '../middleware/asyncHandler'; +import { isExtension, parseApiId } from '../utils'; const router: Router = Router(); @@ -97,6 +99,24 @@ export async function processV3call( ? new Date(data.since * 1000).toISOString() : undefined; if (tagListSince) options['tagListSince'] = tagListSince; + // First check if it's an extension... if it is, and the taglist field + // is passed, ignore everything else and just return the taglist query + // (eyy, I don't make the rules) + if (isExtension(parseApiId(consumerKey)) && data.taglist) { + const tagListVariables = { + withAccountData: options.withAccountData, + tagListSince, + }; + const response = await getTagList( + accessToken, + consumerKey, + headers, + tagListVariables, + ); + const result = savedItemsSimpleToRest(response); + delete result['list']; // empty array result + return result; + } // Search takes precedence -- if search term is passed, call search api if (data.search) { const variables = setSearchVariables(data); diff --git a/servers/v3-proxy-api/src/routes/v3Send.integration.ts b/servers/v3-proxy-api/src/routes/v3Send.integration.ts index 076df2556..960520238 100644 --- a/servers/v3-proxy-api/src/routes/v3Send.integration.ts +++ b/servers/v3-proxy-api/src/routes/v3Send.integration.ts @@ -258,7 +258,7 @@ describe('v3/send', () => { () => (addSpy = jest .spyOn(ActionsRouter.prototype, 'add') - .mockResolvedValueOnce(expectedAddResponses[0]) + .mockResolvedValueOnce(expectedAddResponses[0]['item']) .mockRejectedValueOnce( new ClientError( { @@ -273,7 +273,7 @@ describe('v3/send', () => { {} as any, ), ) - .mockResolvedValueOnce(expectedAddResponses[1])), + .mockResolvedValueOnce(expectedAddResponses[1]['item'])), ); afterEach(() => addSpy.mockRestore()); it('sends an array of responses and errors', async () => { @@ -291,9 +291,9 @@ describe('v3/send', () => { const expected = { status: 1, action_results: [ - expectedAddResponses[0], + expectedAddResponses[0]['item'], false, - expectedAddResponses[1], + expectedAddResponses[1]['item'], ], action_errors: [ null, @@ -322,7 +322,7 @@ describe('v3/send', () => { }); const expected = { status: 1, - action_results: [false, expectedAddResponses[0], false], + action_results: [false, expectedAddResponses[0]['item'], false], action_errors: [ { message: `Invalid Action: 'action_imposter'`, @@ -1019,7 +1019,7 @@ describe('v3/send', () => { expect(clientSpy.mock.calls[0][1]).toEqual(expectedCall); expect(res.body).toEqual({ status: 1, - action_results: [expectedAddResponses[0]], + action_results: [expectedAddResponses[0]['item']], action_errors: [null], }); }, diff --git a/servers/v3-proxy-api/src/routes/v3Send.ts b/servers/v3-proxy-api/src/routes/v3Send.ts index 0573f514a..dce55bc0d 100644 --- a/servers/v3-proxy-api/src/routes/v3Send.ts +++ b/servers/v3-proxy-api/src/routes/v3Send.ts @@ -7,8 +7,8 @@ import { V3SendSchemaPost, } from './validations'; import { InputValidationError } from '../errors/InputValidationError'; -import { ActionsRouter } from './ActionsRouter'; import { asyncHandler } from '../middleware/asyncHandler'; +import { ActionsRouter } from './ActionsRouter'; const router: Router = Router(); diff --git a/servers/v3-proxy-api/src/routes/validations/SendActionValidators.ts b/servers/v3-proxy-api/src/routes/validations/SendActionValidators.ts index 700ed1913..db823fe18 100644 --- a/servers/v3-proxy-api/src/routes/validations/SendActionValidators.ts +++ b/servers/v3-proxy-api/src/routes/validations/SendActionValidators.ts @@ -202,7 +202,7 @@ function HasItemIdOrUrl(Base: TBase) { try { new URL(this.input.url); this.url = this.input.url; - } catch (e) { + } catch { const error: ArrayFieldError = { type: 'array_field', path: 'url', diff --git a/servers/v3-proxy-api/src/utils.spec.ts b/servers/v3-proxy-api/src/utils.spec.ts new file mode 100644 index 000000000..f84cefe49 --- /dev/null +++ b/servers/v3-proxy-api/src/utils.spec.ts @@ -0,0 +1,26 @@ +import { isExtension, parseApiId } from './utils'; + +describe('utils', () => { + describe('parseApiId from consumer key', () => { + it.each(['123-test', '123-456', '123-a34df234'])( + 'works for expected keys', + (key) => { + expect(parseApiId(key)).toEqual(123); + }, + ); + it.each(['test', 'abc-1234', '1232', '123aa-test'])( + 'returns undefined for malformed/nonconforming keys', + (key) => { + expect(parseApiId(key)).toBeUndefined(); + }, + ); + }); + describe('isExtension', () => { + it.each([7035, 73360])('works for extensions', (key) => { + expect(isExtension(key)).toEqual(true); + }); + it.each([NaN, undefined, 9999999, 0])('works for non-extensions', (key) => { + expect(isExtension(key)).toEqual(false); + }); + }); +}); diff --git a/servers/v3-proxy-api/src/utils.ts b/servers/v3-proxy-api/src/utils.ts new file mode 100644 index 000000000..8c3af3198 --- /dev/null +++ b/servers/v3-proxy-api/src/utils.ts @@ -0,0 +1,20 @@ +import config from './config'; + +/** + * Parse the API ID (prefix) from the consumer key string. + * We don't need to do a ton of validation because this is + * just used to determine if the request comes from an extension + * and whether we need to return special responses; if people pass + * weird stuff in the consumer keys it will just be ignored. + * @param consumerKey consumer key provided to API by Pocket; + * format is prefixed by "-" + */ +export function parseApiId(consumerKey: string): number | undefined { + const re = new RegExp(/^(\d+)-[\w\d]+/); + const apiId = consumerKey.match(re)?.[0]; + return apiId != null ? parseInt(apiId) : undefined; +} + +export function isExtension(apiId: number | undefined) { + return config.extensionApiIds.indexOf(apiId) >= 0 ? true : false; +} diff --git a/turbo.json b/turbo.json index aca1570ee..2497965e2 100644 --- a/turbo.json +++ b/turbo.json @@ -1,13 +1,51 @@ { "$schema": "https://turbo.build/schema.json", - "globalDependencies": ["**/.env.*local", "packages/tsconfig/**"], - "globalEnv": ["NODE_ENV"], - "globalDotEnv": [".env", ".env.example"], - "pipeline": { + "globalDependencies": [ + "**/.env.*local", + "packages/tsconfig/**", + ".env", + ".env.example" + ], + "globalEnv": [ + "NODE_ENV", + "GITHUB_TOKEN", + "NPM_TOKEN", + "GH_TOKEN", + "PARSER_BASE_ENDPOINT", + "PARSER_DATA_PATH", + "LOG_LEVEL", + "CHARACTER_MAP", + "POSITION_MAP", + "MD5_RANDOMIZER", + "LETTER_INDEX", + "SALT_1", + "SALT_2", + "UNLEASH_ENDPOINT", + "UNLEASH_KEY" + ], + "tasks": { "build": { - "dependsOn": ["prebuild", "^build"], - "inputs": ["src/**/*", "tsconfig.json", "package.json"], - "outputs": ["dist/**"], + "dependsOn": ["^build"], + "inputs": [ + "src/**/*", + "tsconfig.json", + "package.json", + "schema-public.graphql", + "schema-shared.graphql", + "schema-admin.graphql", + "schema.graphql", + "prisma/schema.prisma", + "src/graphql/**/*.graphql", + "codegen.ts" + ], + "outputs": [ + "dist/**", + "schema-admin-api.graphql", + "schema-client-api.graphql", + "prisma/src/**/*", + "src/generated/**/*", + "src/__generated__/**/*" + ], "cache": true }, "synth": { @@ -27,42 +65,20 @@ "inputs": ["src/**/*", "eslint.config.js", "package.json"] }, "semantic-release": { - "dependsOn": ["^build", "build"] + "dependsOn": ["^build"] }, "test": { "inputs": ["src/**/*", "package.json", "jest.config.js", "jest.setup.js"], - "dependsOn": ["^build", "prebuild"], + "dependsOn": ["^build"], "cache": true }, "test-integrations": { - "dependsOn": ["^build", "prebuild", "pretest-integrations"], + "dependsOn": ["^build"], "cache": false }, "dev": { "cache": false, "persistent": true - }, - "prebuild": { - "inputs": [ - "schema-public.graphql", - "schema-shared.graphql", - "schema-admin.graphql", - "schema.graphql", - "prisma/schema.prisma", - "src/graphql/**/*.graphql", - "codegen.ts" - ], - "outputs": [ - "schema-admin-api.graphql", - "schema-client-api.graphql", - "prisma/src/**/*", - "src/generated/**/*", - "src/__generated__/**/*" - ], - "cache": true - }, - "pretest-integrations": { - "cache": false } } }