diff --git a/.cspell.json b/.cspell.json index b8ae9adfc23..e3b2e8a7dec 100644 --- a/.cspell.json +++ b/.cspell.json @@ -594,6 +594,7 @@ "Strobl", "stroeder", "Styleable", + "subfolders", "subjectsthum", "sublist", "subnetmask", diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9c3e8e3ee11..ac586cbe668 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -12,10 +12,7 @@ // Add the IDs of extensions you want installed when the container is created. "customizations": { "vscode": { - "extensions": [ - "dbaeumer.vscode-eslint", - "mongodb.mongodb-vscode" - ] + "extensions": ["dbaeumer.vscode-eslint", "mongodb.mongodb-vscode"] } }, // Use 'forwardPorts' to make a list of ports inside the container available locally. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index c5d73961ff2..f5bb4a98071 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,8 +1,9 @@ - **I'm submitting a...** - - [ ] bug report - - [ ] feature request - - [ ] question about the decisions made in the repository - - [ ] question about how to use this project + + - [ ] bug report + - [ ] feature request + - [ ] question about the decisions made in the repository + - [ ] question about how to use this project - **Summary** diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c0b29ba2813..298cca3eaf3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,7 +1,7 @@ -name: "🐛 Bug Report" -description: "Submit a bug report to help us improve" -title: "🐛 Bug Report: " -labels: ["type: bug"] +name: '🐛 Bug Report' +description: 'Submit a bug report to help us improve' +title: '🐛 Bug Report: ' +labels: ['type: bug'] body: - type: markdown attributes: @@ -11,36 +11,36 @@ body: validations: required: true attributes: - label: "📜 Description" - description: "A clear and concise description of what the bug is." - placeholder: "It bugs out when ..." + label: '📜 Description' + description: 'A clear and concise description of what the bug is.' + placeholder: 'It bugs out when ...' - type: textarea id: steps-to-reproduce validations: required: true attributes: - label: "👟 Reproduction steps" - description: "How do you trigger this bug? Please walk us through it step by step." + label: '👟 Reproduction steps' + description: 'How do you trigger this bug? Please walk us through it step by step.' placeholder: "1. Go to '...' - 2. Click on '....' - 3. Scroll down to '....' - 4. See the error" + 2. Click on '....' + 3. Scroll down to '....' + 4. See the error" - type: textarea id: expected-behavior validations: required: true attributes: - label: "👍 Expected behavior" - description: "What did you think should happen?" - placeholder: "It should ..." + label: '👍 Expected behavior' + description: 'What did you think should happen?' + placeholder: 'It should ...' - type: textarea id: actual-behavior validations: required: true attributes: - label: "👎 Actual Behavior with Screenshots" - description: "What did actually happen? Add screenshots, if applicable." - placeholder: "It actually ..." + label: '👎 Actual Behavior with Screenshots' + description: 'What did actually happen? Add screenshots, if applicable.' + placeholder: 'It actually ...' - type: input id: novu-version validations: @@ -70,26 +70,26 @@ body: validations: required: false attributes: - label: "📃 Provide any additional context for the Bug." - description: "Add any other context about the problem here." - placeholder: "It actually ..." + label: '📃 Provide any additional context for the Bug.' + description: 'Add any other context about the problem here.' + placeholder: 'It actually ...' - type: checkboxes id: no-duplicate-issues attributes: - label: "👀 Have you spent some time to check if this bug has been raised before?" + label: '👀 Have you spent some time to check if this bug has been raised before?' options: - label: "I checked and didn't find a similar issue" required: true - type: checkboxes id: read-code-of-conduct attributes: - label: "đŸĸ Have you read the Contributing Guidelines?" + label: 'đŸĸ Have you read the Contributing Guidelines?' options: - - label: "I have read the [Contributing Guidelines](https://github.com/novuhq/novu/blob/main/CONTRIBUTING.md)" + - label: 'I have read the [Contributing Guidelines](https://github.com/novuhq/novu/blob/main/CONTRIBUTING.md)' required: true - type: dropdown attributes: label: Are you willing to submit PR? description: This is absolutely not required, but we are happy to guide you in the contribution process. Find us in help-needed channel on [Discord](https://discord.gg/9wcGSf22PM)! options: - - "Yes I am willing to submit a PR!" + - 'Yes I am willing to submit a PR!' diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index b33d3f7dc26..2d350b2b2bf 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,6 +1,6 @@ name: 🚀 Feature -description: "Submit a proposal for a new feature" -title: "🚀 Feature: " +description: 'Submit a proposal for a new feature' +title: '🚀 Feature: ' labels: [feature] body: - type: markdown @@ -12,46 +12,46 @@ body: validations: required: true attributes: - label: "🔖 Feature description" - description: "A clear and concise description of what the feature is." - placeholder: "You should add ..." + label: '🔖 Feature description' + description: 'A clear and concise description of what the feature is.' + placeholder: 'You should add ...' - type: textarea id: pitch validations: required: true attributes: - label: "🎤 Why is this feature needed ?" - description: "Please explain why this feature should be implemented and how it would be used. Add examples, if applicable." - placeholder: "In my use-case, ..." + label: '🎤 Why is this feature needed ?' + description: 'Please explain why this feature should be implemented and how it would be used. Add examples, if applicable.' + placeholder: 'In my use-case, ...' - type: textarea id: solution validations: required: true attributes: - label: "✌ī¸ How do you aim to achieve this?" - description: "A clear and concise description of what you want to happen." - placeholder: "I want this feature to, ..." + label: '✌ī¸ How do you aim to achieve this?' + description: 'A clear and concise description of what you want to happen.' + placeholder: 'I want this feature to, ...' - type: textarea id: alternative validations: required: false attributes: - label: "🔄ī¸ Additional Information" + label: '🔄ī¸ Additional Information' description: "A clear and concise description of any alternative solutions or additional solutions you've considered." - placeholder: "I tried, ..." + placeholder: 'I tried, ...' - type: checkboxes id: no-duplicate-issues attributes: - label: "👀 Have you spent some time to check if this feature request has been raised before?" + label: '👀 Have you spent some time to check if this feature request has been raised before?' options: - label: "I checked and didn't find similar issue" required: true - type: checkboxes id: read-code-of-conduct attributes: - label: "đŸĸ Have you read the Code of Conduct?" + label: 'đŸĸ Have you read the Code of Conduct?' options: - - label: "I have read the [Contributing Guidelines](https://github.com/novuhq/novu/blob/main/CONTRIBUTING.md)" + - label: 'I have read the [Contributing Guidelines](https://github.com/novuhq/novu/blob/main/CONTRIBUTING.md)' required: true - type: dropdown id: willing-to-submit-pr @@ -59,4 +59,4 @@ body: label: Are you willing to submit PR? description: This is absolutely not required, but we are happy to guide you in the contribution process. Find us in help-needed channel on [Discord](https://discord.gg/9wcGSf22PM)! options: - - "Yes I am willing to submit a PR!" + - 'Yes I am willing to submit a PR!' diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 2cf10e5d3e3..f59b27dde17 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,16 +1,20 @@ ### What changed? Why was the change needed? + ### Screenshots +
Expand for optional sections ### Related enterprise PR + ### Special notes for your reviewer +
diff --git a/.github/actions/docker/build-api/action.yml b/.github/actions/docker/build-api/action.yml index 1014040be21..3a01326e53f 100644 --- a/.github/actions/docker/build-api/action.yml +++ b/.github/actions/docker/build-api/action.yml @@ -52,7 +52,7 @@ runs: aws-access-key-id: ${{ inputs.aws-access-key-id }} aws-secret-access-key: ${{ inputs.aws-secret-access-key }} aws-region: eu-west-2 - + - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 @@ -67,7 +67,7 @@ runs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/api + REPOSITORY: novu-dev/api IMAGE_TAG: ${{ github.sha }} DOCKER_BUILD_ARGUMENTS: > --platform=linux/amd64 --provenance=false @@ -81,7 +81,7 @@ runs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/api + REPOSITORY: novu-dev/api IMAGE_TAG: ${{ github.sha }} run: | echo "Built image" @@ -97,7 +97,7 @@ runs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/api + REPOSITORY: novu-dev/api IMAGE_TAG: ${{ github.sha }} run: | docker tag $REGISTRY/$REPOSITORY:$IMAGE_TAG $REGISTRY/$REPOSITORY:${{ inputs.tag }} @@ -107,7 +107,7 @@ runs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/api + REPOSITORY: novu-dev/api IMAGE_TAG: ${{ github.sha }} run: | docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG @@ -117,6 +117,6 @@ runs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/api + REPOSITORY: novu-dev/api run: | docker push $REGISTRY/$REPOSITORY:${{ inputs.tag }} diff --git a/.github/actions/docker/build-worker/action.yml b/.github/actions/docker/build-worker/action.yml index 6986429664d..1d94e8f3a02 100644 --- a/.github/actions/docker/build-worker/action.yml +++ b/.github/actions/docker/build-worker/action.yml @@ -52,7 +52,7 @@ runs: aws-access-key-id: ${{ inputs.aws-access-key-id }} aws-secret-access-key: ${{ inputs.aws-secret-access-key }} aws-region: eu-west-2 - + - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 @@ -67,7 +67,7 @@ runs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/worker + REPOSITORY: novu-dev/worker IMAGE_TAG: ${{ github.sha }} DOCKER_BUILD_ARGUMENTS: > --platform=linux/amd64 --provenance=false @@ -81,7 +81,7 @@ runs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/worker + REPOSITORY: novu-dev/worker IMAGE_TAG: ${{ github.sha }} run: | echo "Built image" @@ -97,7 +97,7 @@ runs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/worker + REPOSITORY: novu-dev/worker IMAGE_TAG: ${{ github.sha }} run: | docker tag $REGISTRY/$REPOSITORY:$IMAGE_TAG $REGISTRY/$REPOSITORY:${{ inputs.tag }} @@ -107,7 +107,7 @@ runs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/worker + REPOSITORY: novu-dev/worker IMAGE_TAG: ${{ github.sha }} run: | docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG @@ -117,6 +117,6 @@ runs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/worker + REPOSITORY: novu-dev/worker run: | docker push $REGISTRY/$REPOSITORY:${{ inputs.tag }} diff --git a/.github/actions/free-space/action.yml b/.github/actions/free-space/action.yml index 45805252eab..b7b4dfa7d3a 100644 --- a/.github/actions/free-space/action.yml +++ b/.github/actions/free-space/action.yml @@ -1,17 +1,17 @@ name: Extend Disk Space -description: This action removes some preinstalled tools in favor of opening space for our docker runs with QEMU +description: This action removes some preinstalled tools in favor of opening space for our docker runs with QEMU runs: using: composite steps: - name: Run script run: | set -eux - + df -h echo "::group::apt clean" sudo apt clean echo "::endgroup::" - + echo "::group::/usr/local/*" du -hsc /usr/local/* echo "::endgroup::" @@ -66,6 +66,6 @@ runs: sudo rm -rf /opt/hostedtoolcache/CodeQL || : # 1.4GB sudo rm -rf /opt/hostedtoolcache/go || : - + df -h shell: bash diff --git a/.github/actions/run-api/action.yml b/.github/actions/run-api/action.yml index e7d027a5a63..93eaedc7a4d 100644 --- a/.github/actions/run-api/action.yml +++ b/.github/actions/run-api/action.yml @@ -21,8 +21,8 @@ runs: shell: bash env: LAUNCH_DARKLY_SDK_KEY: ${{ inputs.launch_darkly_sdk_key }} - NODE_ENV: "test" - PORT: "1336" + NODE_ENV: 'test' + PORT: '1336' run: cd apps/api && pnpm start:prod & - name: Wait on API diff --git a/.github/actions/run-backend/action.yml b/.github/actions/run-backend/action.yml index bec045ebe83..14eb1c91e3a 100644 --- a/.github/actions/run-backend/action.yml +++ b/.github/actions/run-backend/action.yml @@ -27,9 +27,9 @@ runs: env: GITHUB_OAUTH_CLIENT_ID: ${{ inputs.cypress_github_oauth_client_id }} GITHUB_OAUTH_CLIENT_SECRET: ${{ inputs.cypress_github_oauth_client_secret }} - NODE_ENV: "test" - PORT: "1336" - GITHUB_OAUTH_REDIRECT: "http://127.0.0.1:1336/v1/auth/github/callback" + NODE_ENV: 'test' + PORT: '1336' + GITHUB_OAUTH_REDIRECT: 'http://127.0.0.1:1336/v1/auth/github/callback' LAUNCH_DARKLY_SDK_KEY: ${{ inputs.launch_darkly_sdk_key }} CI_EE_TEST: ${{ inputs.ci_ee_test }} run: cd apps/api && pnpm start:prod & @@ -37,8 +37,8 @@ runs: - name: Start Worker shell: bash env: - NODE_ENV: "test" - PORT: "1342" + NODE_ENV: 'test' + PORT: '1342' LAUNCH_DARKLY_SDK_KEY: ${{ inputs.launch_darkly_sdk_key }} CI_EE_TEST: ${{ inputs.ci_ee_test }} run: cd apps/worker && pnpm start:prod & diff --git a/.github/actions/run-worker/action.yml b/.github/actions/run-worker/action.yml index 4d139c010c3..0eeb5c43d5d 100644 --- a/.github/actions/run-worker/action.yml +++ b/.github/actions/run-worker/action.yml @@ -1,4 +1,3 @@ - name: Run Worker description: Sets up a Redis Cluster instance needed to run the tests diff --git a/.github/actions/setup-project/action.yml b/.github/actions/setup-project/action.yml index 01e4c10156d..5526929bae2 100644 --- a/.github/actions/setup-project/action.yml +++ b/.github/actions/setup-project/action.yml @@ -51,7 +51,7 @@ runs: shell: bash if: ${{ inputs.submodules == 'true' }} run: pnpm symlink:submodules - + - name: Install wait-on plugin shell: bash run: pnpm i -g wait-on diff --git a/.github/actions/setup-redis-cluster/action.yml b/.github/actions/setup-redis-cluster/action.yml index 9844a4a5a50..2d23fed6f03 100644 --- a/.github/actions/setup-redis-cluster/action.yml +++ b/.github/actions/setup-redis-cluster/action.yml @@ -1,6 +1,6 @@ name: Setup Novu Redis Cluster -description: Sets up a Redis Cluster instance needed to run the tests +description: Sets up a Redis Cluster instance needed to run the tests runs: using: composite diff --git a/.github/actions/slack-notify-on-failure/action.yml b/.github/actions/slack-notify-on-failure/action.yml index 5a51f187c83..e1f0bff33a8 100644 --- a/.github/actions/slack-notify-on-failure/action.yml +++ b/.github/actions/slack-notify-on-failure/action.yml @@ -6,16 +6,16 @@ inputs: type: string runs: - using: "composite" + using: 'composite' steps: - name: Notify Slack Action if: ${{ github.ref_name == 'next' || github.ref_name == 'main' || github.ref_name == 'prod' }} uses: ravsamhq/notify-slack-action@v2 with: footer: "Run: {run_url}\nCommit: {commit_url}" - message_format: "{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>" - notification_title: "{workflow} is now failing!" - notify_when: "failure" + message_format: '{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>' + notification_title: '{workflow} is now failing!' + notify_when: 'failure' status: ${{ job.status }} env: SLACK_WEBHOOK_URL: ${{ inputs.slackWebhookURL }} diff --git a/.github/actions/validate-openapi/action.yml b/.github/actions/validate-openapi/action.yml index 73b3f3444d5..e5726ea88b4 100644 --- a/.github/actions/validate-openapi/action.yml +++ b/.github/actions/validate-openapi/action.yml @@ -12,7 +12,7 @@ runs: with: targets: lint:openapi projects: '@novu/api' - + - name: Kill port for api 1336 for unit tests shell: bash run: sudo kill -9 $(sudo lsof -t -i:1336) diff --git a/.github/actions/validate-swagger/action.yml b/.github/actions/validate-swagger/action.yml deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 29281d9f972..f8837f7372d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -9,17 +9,17 @@ # the `language` matrix defined below to confirm you have the correct set of # supported CodeQL languages. # -name: "CodeQL" +name: 'CodeQL' concurrency: - group: "${{ github.workflow }}-${{ github.ref }}" + group: '${{ github.workflow }}-${{ github.ref }}' cancel-in-progress: true on: push: - branches: [ "main", "next" ] + branches: ['main', 'next'] pull_request: # The branches below must be a subset of the branches above - branches: [ "main", "next" ] + branches: ['main', 'next'] schedule: - cron: '25 2 * * 4' @@ -35,41 +35,40 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript', 'typescript' ] + language: ['javascript', 'typescript'] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/community-label.yml b/.github/workflows/community-label.yml index b57aea56e3a..3c92433f5b8 100644 --- a/.github/workflows/community-label.yml +++ b/.github/workflows/community-label.yml @@ -7,7 +7,7 @@ on: - '!prod' concurrency: - group: "${{ github.workflow }}-${{ github.ref }}" + group: '${{ github.workflow }}-${{ github.ref }}' cancel-in-progress: true jobs: diff --git a/.github/workflows/conventional-commit.yml b/.github/workflows/conventional-commit.yml index 047aa847d48..73f9703c787 100644 --- a/.github/workflows/conventional-commit.yml +++ b/.github/workflows/conventional-commit.yml @@ -1,4 +1,4 @@ -name: "Lint PR title" +name: 'Lint PR title' on: pull_request_target: @@ -45,7 +45,6 @@ jobs: scopes: | ${{ env.SCOPES }} - - uses: marocchino/sticky-pull-request-comment@v2 # When the previous steps fails, the workflow would stop. By adding this # condition you can continue the execution with the populated error message. diff --git a/.github/workflows/dev-deploy-api.yml b/.github/workflows/dev-deploy-api.yml index bd1a011fd1b..efdd5086659 100644 --- a/.github/workflows/dev-deploy-api.yml +++ b/.github/workflows/dev-deploy-api.yml @@ -17,6 +17,7 @@ on: - 'libs/application-generic/**' env: TF_WORKSPACE: novu-dev + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} jobs: test_api: @@ -130,7 +131,7 @@ jobs: sourcemaps: apps/api/dist ignore_empty: true ignore_missing: true - url_prefix: "~" + url_prefix: '~' newrelic: runs-on: ubuntu-latest @@ -147,6 +148,6 @@ jobs: with: region: EU apiKey: ${{ secrets.NEW_RELIC_API_KEY }} - guid: "MzgxMjQwOHxBUE18QVBQTElDQVRJT058NDk3NjQzODIy" - version: "${{ env.RELEASE_VERSION }}" - user: "${{ github.actor }}" + guid: 'MzgxMjQwOHxBUE18QVBQTElDQVRJT058NDk3NjQzODIy' + version: '${{ env.RELEASE_VERSION }}' + user: '${{ github.actor }}' diff --git a/.github/workflows/dev-deploy-dashboard.yml b/.github/workflows/dev-deploy-dashboard.yml index 3a65f97f4ee..cde607f82e2 100644 --- a/.github/workflows/dev-deploy-dashboard.yml +++ b/.github/workflows/dev-deploy-dashboard.yml @@ -1,5 +1,3 @@ -# This is a basic workflow to help you get started with Actions - name: Deploy DEV DASHBOARD # Controls when the action will run. Triggers the workflow on push or pull request @@ -14,6 +12,9 @@ on: - 'apps/web/**' - 'apps/dashboard/**' +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: test_dashboard: diff --git a/.github/workflows/dev-deploy-embed.yml b/.github/workflows/dev-deploy-embed.yml index a3351de3727..8352f70828a 100644 --- a/.github/workflows/dev-deploy-embed.yml +++ b/.github/workflows/dev-deploy-embed.yml @@ -1,5 +1,3 @@ -# This is a basic workflow to help you get started with Actions - name: Deploy DEV EMBED # Controls when the action will run. Triggers the workflow on push or pull request @@ -13,6 +11,9 @@ on: paths: - 'libs/embed/**' +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" diff --git a/.github/workflows/dev-deploy-inbound-mail.yml b/.github/workflows/dev-deploy-inbound-mail.yml index fbe4859bd96..130917b8217 100644 --- a/.github/workflows/dev-deploy-inbound-mail.yml +++ b/.github/workflows/dev-deploy-inbound-mail.yml @@ -1,5 +1,8 @@ name: Deploy DEV Inbound Mail +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: @@ -79,7 +82,7 @@ jobs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/inbound-mail + REPOSITORY: novu-dev/inbound-mail IMAGE_TAG: ${{ github.sha }} DOCKER_BUILD_ARGUMENTS: > --platform=linux/amd64 --provenance=false @@ -93,7 +96,7 @@ jobs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/inbound-mail + REPOSITORY: novu-dev/inbound-mail IMAGE_TAG: ${{ github.sha }} run: | echo "Built image" @@ -106,7 +109,7 @@ jobs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/inbound-mail + REPOSITORY: novu-dev/inbound-mail IMAGE_TAG: ${{ github.sha }} run: | docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG @@ -118,7 +121,6 @@ jobs: token: ${{ secrets.GH_PACKAGES }} path: cloud-infra - - name: Terraform setup uses: hashicorp/setup-terraform@v3 with: @@ -179,4 +181,4 @@ jobs: sourcemaps: apps/inbound-mail/dist ignore_empty: true ignore_missing: true - url_prefix: "~" + url_prefix: '~' diff --git a/.github/workflows/dev-deploy-web-component.yml b/.github/workflows/dev-deploy-web-component.yml index a691a2a552e..29605c9060d 100644 --- a/.github/workflows/dev-deploy-web-component.yml +++ b/.github/workflows/dev-deploy-web-component.yml @@ -1,5 +1,8 @@ name: Deploy DEV Notification Center Web Component +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + on: workflow_dispatch: push: diff --git a/.github/workflows/dev-deploy-web.yml b/.github/workflows/dev-deploy-web.yml index 092906d424a..5c0edf9dea5 100644 --- a/.github/workflows/dev-deploy-web.yml +++ b/.github/workflows/dev-deploy-web.yml @@ -1,5 +1,3 @@ -# This is a basic workflow to help you get started with Actions - name: Deploy DEV WEB # Controls when the action will run. Triggers the workflow on push or pull request @@ -14,6 +12,9 @@ on: - 'apps/web/**' - 'packages/shared/**' +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: test_web: diff --git a/.github/workflows/dev-deploy-webhook.yml b/.github/workflows/dev-deploy-webhook.yml index 6b4be494f52..42490c14ea3 100644 --- a/.github/workflows/dev-deploy-webhook.yml +++ b/.github/workflows/dev-deploy-webhook.yml @@ -15,6 +15,9 @@ on: - 'libs/dal/**' - 'packages/shared/**' +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + jobs: test_webhook: uses: ./.github/workflows/reusable-webhook-e2e.yml diff --git a/.github/workflows/dev-deploy-widget.yml b/.github/workflows/dev-deploy-widget.yml index 13dc1ae96bf..95fc3284813 100644 --- a/.github/workflows/dev-deploy-widget.yml +++ b/.github/workflows/dev-deploy-widget.yml @@ -1,5 +1,3 @@ -# This is a basic workflow to help you get started with Actions - name: Deploy DEV Widget # Controls when the action will run. Triggers the workflow on push or pull request @@ -15,6 +13,9 @@ on: - 'apps/ws/**' - 'packages/shared/**' +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: test_widget: diff --git a/.github/workflows/dev-deploy-worker.yml b/.github/workflows/dev-deploy-worker.yml index 54c4783d242..e818a148a04 100644 --- a/.github/workflows/dev-deploy-worker.yml +++ b/.github/workflows/dev-deploy-worker.yml @@ -18,8 +18,10 @@ on: - 'libs/application-generic/**' - 'packages/stateless/**' - 'packages/node/**' + env: TF_WORKSPACE: novu-dev + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} jobs: test_worker: @@ -85,6 +87,6 @@ jobs: with: region: EU apiKey: ${{ secrets.NEW_RELIC_API_KEY }} - guid: "MzgxMjQwOHxBUE18QVBQTElDQVRJT058NDk3NjQzODIy" - version: "${{ env.RELEASE_VERSION }}" - user: "${{ github.actor }}" + guid: 'MzgxMjQwOHxBUE18QVBQTElDQVRJT058NDk3NjQzODIy' + version: '${{ env.RELEASE_VERSION }}' + user: '${{ github.actor }}' diff --git a/.github/workflows/dev-deploy-ws.yml b/.github/workflows/dev-deploy-ws.yml index b54bf88aba0..b47739f1db1 100644 --- a/.github/workflows/dev-deploy-ws.yml +++ b/.github/workflows/dev-deploy-ws.yml @@ -12,6 +12,7 @@ on: - 'apps/ws/**' env: TF_WORKSPACE: novu-dev + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} jobs: test_ws: @@ -92,17 +93,16 @@ jobs: aws ecs describe-task-definition --task-definition ${{ env.ws_task_name }} \ --query taskDefinition > task-definition.json - - name: Set Bull MQ Env variable for EE shell: bash run: | echo "BULL_MQ_PRO_NPM_TOKEN=${{ secrets.BULL_MQ_PRO_NPM_TOKEN }}" >> $GITHUB_ENV - + - name: Build with Buildx, tag, and test shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/ws + REPOSITORY: novu-dev/ws IMAGE_TAG: ${{ github.sha }} DOCKER_BUILD_ARGUMENTS: > --platform=linux/amd64 --provenance=false @@ -116,7 +116,7 @@ jobs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/ws + REPOSITORY: novu-dev/ws IMAGE_TAG: ${{ github.sha }} run: | echo "Built image" @@ -130,7 +130,7 @@ jobs: shell: bash env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu-dev/ws + REPOSITORY: novu-dev/ws IMAGE_TAG: ${{ github.sha }} run: | docker push $REGISTRY/$REPOSITORY:$IMAGE_TAG diff --git a/.github/workflows/issue-label.yml b/.github/workflows/issue-label.yml index e313538befd..c8539b518f9 100644 --- a/.github/workflows/issue-label.yml +++ b/.github/workflows/issue-label.yml @@ -5,7 +5,7 @@ on: types: [opened] concurrency: - group: "${{ github.workflow }}-${{ github.ref }}" + group: '${{ github.workflow }}-${{ github.ref }}' cancel-in-progress: true jobs: diff --git a/.github/workflows/milestone-assign.yml b/.github/workflows/milestone-assign.yml index c6235cb8bd0..1baa7aeec7e 100644 --- a/.github/workflows/milestone-assign.yml +++ b/.github/workflows/milestone-assign.yml @@ -5,7 +5,7 @@ on: types: [submitted] concurrency: - group: "${{ github.workflow }}-${{ github.ref }}" + group: '${{ github.workflow }}-${{ github.ref }}' cancel-in-progress: true jobs: diff --git a/.github/workflows/on-pr.yml b/.github/workflows/on-pr.yml index 6be684d41e3..13a0bb0a328 100644 --- a/.github/workflows/on-pr.yml +++ b/.github/workflows/on-pr.yml @@ -1,8 +1,11 @@ name: Check pull request concurrency: - group: "${{ github.workflow }}-${{ github.ref }}" + group: '${{ github.workflow }}-${{ github.ref }}' cancel-in-progress: true +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + on: pull_request: workflow_dispatch: @@ -245,7 +248,7 @@ jobs: test-e2e-ee-affected: ${{ contains(fromJson(needs.get-affected.outputs.test-e2e-ee), '@novu/api') || contains(fromJson(needs.get-affected.outputs.test-e2e-ee), '@novu/worker') }} job-name: ${{ matrix.name }} test-unit: false - secrets: inherit + secrets: inherit test_e2e_web: name: E2E test Web app diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 6fca208686f..075256d17c6 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -1,4 +1,4 @@ -name: "Pull Request Labeler" +name: 'Pull Request Labeler' on: - pull_request_target diff --git a/.github/workflows/pr-manager.yml b/.github/workflows/pr-manager.yml index ef3cfd440df..9a229d88154 100644 --- a/.github/workflows/pr-manager.yml +++ b/.github/workflows/pr-manager.yml @@ -1,4 +1,4 @@ -name: "Pull Request Manager" +name: 'Pull Request Manager' on: schedule: - cron: '0 * * * *' @@ -25,6 +25,6 @@ jobs: days-before-pr-close: 31 # Delete the branch when closing PRs. GitHub's "restore branch" function works indefinitely, so no reason not to. delete-branch: true - stale-pr-message: "This PR is being marked as stale due to inactivity." - close-pr-message: "This PR is being closed due to inactivity. Please reopen if work is intended to be continued." + stale-pr-message: 'This PR is being marked as stale due to inactivity.' + close-pr-message: 'This PR is being closed due to inactivity. Please reopen if work is intended to be continued.' operations-per-run: 100 diff --git a/.github/workflows/prepare-cloud-release.yaml b/.github/workflows/prepare-cloud-release.yaml index 7898a1a12ea..8c800b040a2 100644 --- a/.github/workflows/prepare-cloud-release.yaml +++ b/.github/workflows/prepare-cloud-release.yaml @@ -1,11 +1,14 @@ -name: "Prepare Cloud Release" +name: 'Prepare Cloud Release' + +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} on: workflow_dispatch: # Triggers the workflow every work day at 8:00 UTC # The 3 hour offset should change when daylight savings change for GMT +3. schedule: - - cron: "0 8 * * 1,2,3,4,5" + - cron: '0 8 * * 1,2,3,4,5' jobs: prepare-cloud-release: diff --git a/.github/workflows/prepare-self-hosted-release.yml b/.github/workflows/prepare-self-hosted-release.yml index 5fe76966b21..4eed3dbec2b 100644 --- a/.github/workflows/prepare-self-hosted-release.yml +++ b/.github/workflows/prepare-self-hosted-release.yml @@ -1,5 +1,8 @@ name: Prepare Self-hosted Release +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + on: push: tags: @@ -13,16 +16,14 @@ permissions: id-token: write jobs: - build_docker: runs-on: ubuntu-latest timeout-minutes: 90 strategy: fail-fast: false matrix: - name: ['novu/api','novu/worker','novu/web','novu/webhook','novu/ws'] + name: ['novu/api', 'novu/worker', 'novu/web', 'novu/webhook', 'novu/ws'] steps: - - name: Git Checkout uses: actions/checkout@v4 @@ -38,7 +39,7 @@ jobs: echo "SERVICE_COMMON_NAME=$SERVICE_COMMON_NAME" >> $GITHUB_ENV echo "REGISTRY_OWNER=novuhq" >> $GITHUB_ENV echo "This is the service name: $SERVICE_NAME and release version: $LATEST_VERSION" - + - name: Install pnpm uses: pnpm/action-setup@v3 @@ -71,10 +72,10 @@ jobs: uses: docker/setup-buildx-action@v3 with: driver-opts: 'image=moby/buildkit:v0.13.1' - + - uses: ./.github/actions/free-space name: Extend space in Action Container - + - name: Login to GitHub Container Registry uses: docker/login-action@v3 with: @@ -92,16 +93,16 @@ jobs: --output=type=image,name=ghcr.io/${{ env.REGISTRY_OWNER }}/${{ env.SERVICE_NAME }},push-by-digest=true,name-canonical=true run: | cd apps/$SERVICE_COMMON_NAME - + if [ "${{ env.SERVICE_NAME }}" == "worker" ]; then cd src/ && echo -e "\nIS_SELF_HOSTED=true\nOS_TELEMETRY_URL=\"${{ secrets.OS_TELEMETRY_URL }}\"" >> .example.env && cd .. elif [ "${{ env.SERVICE_NAME }}" == "web" ]; then echo -e "\nIS_V2_ENABLED=true" >> .env.sample fi - + pnpm run docker:build docker images - + - name: Check for EE files id: check-ee-files run: | diff --git a/.github/workflows/preview-packages.yml b/.github/workflows/preview-packages.yml index 74428d9e9f1..06a0d6c0a70 100644 --- a/.github/workflows/preview-packages.yml +++ b/.github/workflows/preview-packages.yml @@ -1,5 +1,8 @@ name: Publish NPM Packages Previews +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + on: workflow_dispatch: push: @@ -21,7 +24,7 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 20 - cache: "pnpm" + cache: 'pnpm' - name: Install dependencies run: pnpm install @@ -31,7 +34,7 @@ jobs: - name: Build run: pnpm run preview:pkg:build - + - name: Release package previews to pkg.pr.new run: pnpm run preview:pkg:publish if: ${{ success() }} diff --git a/.github/workflows/prod-deploy-api.yml b/.github/workflows/prod-deploy-api.yml index 93a20d74802..0aca04406d7 100644 --- a/.github/workflows/prod-deploy-api.yml +++ b/.github/workflows/prod-deploy-api.yml @@ -1,5 +1,8 @@ name: Deploy PROD API +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: @@ -45,23 +48,23 @@ jobs: shell: bash run: | echo "BULL_MQ_PRO_NPM_TOKEN=${{ secrets.BULL_MQ_PRO_NPM_TOKEN }}" >> $GITHUB_ENV - + - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID}} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - + - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 - + - name: Build, tag, and push image to Amazon ECR id: build-image env: REGISTRY: ${{ steps.login-ecr.outputs.registry }} - REPOSITORY: novu/api + REPOSITORY: novu/api IMAGE_TAG: ${{ github.sha }} DOCKER_BUILD_ARGUMENTS: > --platform=linux/amd64 @@ -129,6 +132,6 @@ jobs: with: region: EU apiKey: ${{ secrets.NEW_RELIC_API_KEY }} - guid: "MzgxMjQwOHxBUE18QVBQTElDQVRJT058NDk3NzA2ODk2" - version: "${{ env.RELEASE_VERSION }}" - user: "${{ github.actor }}" + guid: 'MzgxMjQwOHxBUE18QVBQTElDQVRJT058NDk3NzA2ODk2' + version: '${{ env.RELEASE_VERSION }}' + user: '${{ github.actor }}' diff --git a/.github/workflows/prod-deploy-embed.yml b/.github/workflows/prod-deploy-embed.yml index d16bd8b3133..ddc7f78a8c1 100644 --- a/.github/workflows/prod-deploy-embed.yml +++ b/.github/workflows/prod-deploy-embed.yml @@ -1,5 +1,3 @@ -# This is a basic workflow to help you get started with Actions - name: Deploy PROD EMBED # Controls when the action will run. Triggers the workflow on push or pull request @@ -7,6 +5,9 @@ name: Deploy PROD EMBED on: workflow_dispatch: +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: deploy_embed_eu: @@ -21,15 +22,15 @@ jobs: secrets: inherit deploy_embed_us: - uses: ./.github/workflows/reusable-embed-deploy.yml - with: - environment: Production - widget_url: https://widget.novu.co - netlify_deploy_message: Production deployment - netlify_alias: prod - netlify_gh_env: Production - netlify_site_id: 0689c015-fca0-4940-a26d-3e33f561bc48 - secrets: inherit + uses: ./.github/workflows/reusable-embed-deploy.yml + with: + environment: Production + widget_url: https://widget.novu.co + netlify_deploy_message: Production deployment + netlify_alias: prod + netlify_gh_env: Production + netlify_site_id: 0689c015-fca0-4940-a26d-3e33f561bc48 + secrets: inherit publish_docker_image_embed: needs: diff --git a/.github/workflows/prod-deploy-inbound-mail.yml b/.github/workflows/prod-deploy-inbound-mail.yml index ca43debae4e..3e59135e0d0 100644 --- a/.github/workflows/prod-deploy-inbound-mail.yml +++ b/.github/workflows/prod-deploy-inbound-mail.yml @@ -5,6 +5,9 @@ name: Deploy PROD Inbound Mail on: workflow_dispatch: +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + jobs: test_inbound_mail: strategy: diff --git a/.github/workflows/prod-deploy-web-component.yml b/.github/workflows/prod-deploy-web-component.yml index 2ed532e3b93..490635dc51a 100644 --- a/.github/workflows/prod-deploy-web-component.yml +++ b/.github/workflows/prod-deploy-web-component.yml @@ -3,6 +3,9 @@ name: Deploy PROD Notification Center Web Component on: workflow_dispatch: +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + jobs: build: uses: ./.github/workflows/reusable-notification-center.yml diff --git a/.github/workflows/prod-deploy-web.yml b/.github/workflows/prod-deploy-web.yml index 7a8f317f4c2..54a5eedb56f 100644 --- a/.github/workflows/prod-deploy-web.yml +++ b/.github/workflows/prod-deploy-web.yml @@ -1,5 +1,3 @@ -# This is a basic workflow to help you get started with Actions - name: Deploy PROD WEB # Controls when the action will run. Triggers the workflow on push or pull request @@ -7,6 +5,9 @@ name: Deploy PROD WEB on: workflow_dispatch: +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: deploy_web_eu: diff --git a/.github/workflows/prod-deploy-webhook.yml b/.github/workflows/prod-deploy-webhook.yml index b9e192724b4..79ca5551847 100644 --- a/.github/workflows/prod-deploy-webhook.yml +++ b/.github/workflows/prod-deploy-webhook.yml @@ -5,6 +5,9 @@ name: Deploy PROD WEBHOOK on: workflow_dispatch: +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + jobs: publish_docker_image_webhook: uses: ./.github/workflows/reusable-docker.yml diff --git a/.github/workflows/prod-deploy-widget.yml b/.github/workflows/prod-deploy-widget.yml index 83a54e3a29a..7be6c05cde0 100644 --- a/.github/workflows/prod-deploy-widget.yml +++ b/.github/workflows/prod-deploy-widget.yml @@ -1,5 +1,3 @@ -# This is a basic workflow to help you get started with Actions - name: Deploy PROD Widget # Controls when the action will run. Triggers the workflow on push or pull request @@ -7,6 +5,9 @@ name: Deploy PROD Widget on: workflow_dispatch: +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + jobs: test_widget: uses: ./.github/workflows/reusable-widget-e2e.yml diff --git a/.github/workflows/prod-deploy-worker.yml b/.github/workflows/prod-deploy-worker.yml index b584bbe0936..31c93529fe0 100644 --- a/.github/workflows/prod-deploy-worker.yml +++ b/.github/workflows/prod-deploy-worker.yml @@ -5,6 +5,9 @@ name: Deploy PROD Worker on: workflow_dispatch: +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + jobs: build_prod_image: # The type of runner that the job will run on @@ -52,7 +55,7 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID}} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: us-east-1 - + - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 @@ -115,6 +118,6 @@ jobs: with: region: EU apiKey: ${{ secrets.NEW_RELIC_API_KEY }} - guid: "MzgxMjQwOHxBUE18QVBQTElDQVRJT058NDk3NzA2ODk2" - version: "${{ env.RELEASE_VERSION }}" - user: "${{ github.actor }}" + guid: 'MzgxMjQwOHxBUE18QVBQTElDQVRJT058NDk3NzA2ODk2' + version: '${{ env.RELEASE_VERSION }}' + user: '${{ github.actor }}' diff --git a/.github/workflows/prod-deploy-ws.yml b/.github/workflows/prod-deploy-ws.yml index ab737bb0b6d..99c8d872ce3 100644 --- a/.github/workflows/prod-deploy-ws.yml +++ b/.github/workflows/prod-deploy-ws.yml @@ -5,6 +5,9 @@ name: Deploy PROD WS on: workflow_dispatch: +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + jobs: # This workflow contains a single job called "build" build_prod_image: diff --git a/.github/workflows/reusable-api-e2e.yml b/.github/workflows/reusable-api-e2e.yml index dda2c7e5a96..8d5b399ec3a 100644 --- a/.github/workflows/reusable-api-e2e.yml +++ b/.github/workflows/reusable-api-e2e.yml @@ -1,5 +1,8 @@ name: E2E API Tests +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: @@ -83,7 +86,6 @@ jobs: - uses: ./.github/actions/start-localstack name: Start localstack - - uses: ./.github/actions/run-worker name: Run worker with: diff --git a/.github/workflows/reusable-dashboard-deploy.yml b/.github/workflows/reusable-dashboard-deploy.yml index 2cb0eeeb28f..b0cddb617fb 100644 --- a/.github/workflows/reusable-dashboard-deploy.yml +++ b/.github/workflows/reusable-dashboard-deploy.yml @@ -1,5 +1,8 @@ name: Deploy Dashboard to Netlify +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: diff --git a/.github/workflows/reusable-dashboard-e2e.yml b/.github/workflows/reusable-dashboard-e2e.yml index 01ccd9f0e2f..d0572ecb838 100644 --- a/.github/workflows/reusable-dashboard-e2e.yml +++ b/.github/workflows/reusable-dashboard-e2e.yml @@ -1,7 +1,8 @@ -# This is a basic workflow to help you get started with Actions - name: Test DASHBOARD +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_dispatch: @@ -57,7 +58,7 @@ jobs: with: submodules: true token: ${{ secrets.SUBMODULES_TOKEN }} - + - id: checkout-community-code name: Checkout community code uses: actions/checkout@v4 @@ -124,30 +125,30 @@ jobs: needs: [e2e_dashboard] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 20.8.1 - - - name: Download blob reports from GitHub Actions Artifacts - uses: actions/download-artifact@v4 - with: - path: dashboard-all-blob-reports - pattern: dashboard-blob-report-* - merge-multiple: true - - - name: Merge into HTML Report - run: npx playwright merge-reports --reporter html ./dashboard-all-blob-reports - - - name: Upload HTML report - uses: actions/upload-artifact@v4 - with: - name: dashboard-html-report--attempt-${{ github.run_attempt }} - path: playwright-report - retention-days: 14 - - - name: Send Slack notifications - uses: ./.github/actions/slack-notify-on-failure - if: failure() - with: - slackWebhookURL: ${{ secrets.SLACK_WEBHOOK_URL_ENG_FEED_GITHUB }} + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.8.1 + + - name: Download blob reports from GitHub Actions Artifacts + uses: actions/download-artifact@v4 + with: + path: dashboard-all-blob-reports + pattern: dashboard-blob-report-* + merge-multiple: true + + - name: Merge into HTML Report + run: npx playwright merge-reports --reporter html ./dashboard-all-blob-reports + + - name: Upload HTML report + uses: actions/upload-artifact@v4 + with: + name: dashboard-html-report--attempt-${{ github.run_attempt }} + path: playwright-report + retention-days: 14 + + - name: Send Slack notifications + uses: ./.github/actions/slack-notify-on-failure + if: failure() + with: + slackWebhookURL: ${{ secrets.SLACK_WEBHOOK_URL_ENG_FEED_GITHUB }} diff --git a/.github/workflows/reusable-docker.yml b/.github/workflows/reusable-docker.yml index 7da9ec7d7d4..0f83e5f773d 100644 --- a/.github/workflows/reusable-docker.yml +++ b/.github/workflows/reusable-docker.yml @@ -1,5 +1,8 @@ name: Build, tag and push docker image to ghcr.io +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: @@ -64,7 +67,7 @@ jobs: id-token: write strategy: matrix: - name: [ '${{ inputs.package_name }}-ee'] + name: ['${{ inputs.package_name }}-ee'] steps: - uses: actions/checkout@v4 with: @@ -87,14 +90,13 @@ jobs: with: driver-opts: 'image=moby/buildkit:v0.13.1' - - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ inputs.aws-region }} - + - name: Login to Amazon ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v2 diff --git a/.github/workflows/reusable-embed-deploy.yml b/.github/workflows/reusable-embed-deploy.yml index a28a2718ef0..5cce978fa92 100644 --- a/.github/workflows/reusable-embed-deploy.yml +++ b/.github/workflows/reusable-embed-deploy.yml @@ -1,5 +1,8 @@ name: Deploy Embed to Netlify +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: diff --git a/.github/workflows/reusable-inbound-mail-e2e.yml b/.github/workflows/reusable-inbound-mail-e2e.yml index c655735457e..6e10506e09f 100644 --- a/.github/workflows/reusable-inbound-mail-e2e.yml +++ b/.github/workflows/reusable-inbound-mail-e2e.yml @@ -1,5 +1,8 @@ name: E2E Inbound Mail Tests +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: diff --git a/.github/workflows/reusable-notification-center.yml b/.github/workflows/reusable-notification-center.yml index c67ea65c8e4..d25e0956581 100644 --- a/.github/workflows/reusable-notification-center.yml +++ b/.github/workflows/reusable-notification-center.yml @@ -1,5 +1,8 @@ name: Test and build @novu/notification-center +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + on: workflow_call: diff --git a/.github/workflows/reusable-web-deploy.yml b/.github/workflows/reusable-web-deploy.yml index d3b41e318d3..59ba8aff46a 100644 --- a/.github/workflows/reusable-web-deploy.yml +++ b/.github/workflows/reusable-web-deploy.yml @@ -1,5 +1,8 @@ name: Deploy Web to Netlify +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: diff --git a/.github/workflows/reusable-web-e2e.yml b/.github/workflows/reusable-web-e2e.yml index 6542f8afd20..b18a7557df2 100644 --- a/.github/workflows/reusable-web-e2e.yml +++ b/.github/workflows/reusable-web-e2e.yml @@ -1,7 +1,8 @@ -# This is a basic workflow to help you get started with Actions - name: Test WEB +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_dispatch: @@ -57,7 +58,7 @@ jobs: with: submodules: true token: ${{ secrets.SUBMODULES_TOKEN }} - + - id: checkout-community-code name: Checkout community code uses: actions/checkout@v4 @@ -126,30 +127,30 @@ jobs: needs: [e2e_web] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 20.8.1 - - - name: Download blob reports from GitHub Actions Artifacts - uses: actions/download-artifact@v4 - with: - path: all-blob-reports - pattern: blob-report-* - merge-multiple: true - - - name: Merge into HTML Report - run: npx playwright merge-reports --reporter html ./all-blob-reports - - - name: Upload HTML report - uses: actions/upload-artifact@v4 - with: - name: html-report--attempt-${{ github.run_attempt }} - path: playwright-report - retention-days: 14 - - - name: Send Slack notifications - uses: ./.github/actions/slack-notify-on-failure - if: failure() - with: - slackWebhookURL: ${{ secrets.SLACK_WEBHOOK_URL_ENG_FEED_GITHUB }} + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 20.8.1 + + - name: Download blob reports from GitHub Actions Artifacts + uses: actions/download-artifact@v4 + with: + path: all-blob-reports + pattern: blob-report-* + merge-multiple: true + + - name: Merge into HTML Report + run: npx playwright merge-reports --reporter html ./all-blob-reports + + - name: Upload HTML report + uses: actions/upload-artifact@v4 + with: + name: html-report--attempt-${{ github.run_attempt }} + path: playwright-report + retention-days: 14 + + - name: Send Slack notifications + uses: ./.github/actions/slack-notify-on-failure + if: failure() + with: + slackWebhookURL: ${{ secrets.SLACK_WEBHOOK_URL_ENG_FEED_GITHUB }} diff --git a/.github/workflows/reusable-webhook-e2e.yml b/.github/workflows/reusable-webhook-e2e.yml index 48d7a123800..24f15aa34e8 100644 --- a/.github/workflows/reusable-webhook-e2e.yml +++ b/.github/workflows/reusable-webhook-e2e.yml @@ -1,5 +1,8 @@ name: E2E WEBHOOK Tests +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: @@ -14,17 +17,17 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - uses: ./.github/actions/setup-project + - uses: ./.github/actions/setup-project - - uses: ./.github/actions/start-localstack + - uses: ./.github/actions/start-localstack - # Runs a single command using the runners shell - - name: Build Webhook - run: CI='' pnpm build:webhook + # Runs a single command using the runners shell + - name: Build Webhook + run: CI='' pnpm build:webhook - # Runs a set of commands using the runners shell - - name: Run a test - run: | - cd apps/webhook && pnpm test:e2e + # Runs a set of commands using the runners shell + - name: Run a test + run: | + cd apps/webhook && pnpm test:e2e diff --git a/.github/workflows/reusable-widget-deploy.yml b/.github/workflows/reusable-widget-deploy.yml index d4d1b4295b6..f446e10db95 100644 --- a/.github/workflows/reusable-widget-deploy.yml +++ b/.github/workflows/reusable-widget-deploy.yml @@ -1,5 +1,8 @@ name: Deploy Widget to Netlify +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: @@ -36,7 +39,6 @@ on: required: true type: string - # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: reusable_widget_deploy: diff --git a/.github/workflows/reusable-widget-e2e.yml b/.github/workflows/reusable-widget-e2e.yml index b635bac7def..16e004b2856 100644 --- a/.github/workflows/reusable-widget-e2e.yml +++ b/.github/workflows/reusable-widget-e2e.yml @@ -1,6 +1,8 @@ -# This is a basic workflow to help you get started with Actions name: Test E2E WIDGET +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: diff --git a/.github/workflows/reusable-worker-e2e.yml b/.github/workflows/reusable-worker-e2e.yml index 5407fc9570c..06546b975a5 100644 --- a/.github/workflows/reusable-worker-e2e.yml +++ b/.github/workflows/reusable-worker-e2e.yml @@ -1,5 +1,8 @@ name: E2E worker Tests +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: @@ -26,35 +29,35 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: - - id: setup - run: | - if ! [[ -z "${{ secrets.SUBMODULES_TOKEN }}" ]]; then - echo "has_token=true" >> $GITHUB_OUTPUT - else - echo "has_token=false" >> $GITHUB_OUTPUT - fi - # checkout with submodules if token is provided - - uses: actions/checkout@v4 - if: steps.setup.outputs.has_token == 'true' - with: - submodules: ${{ inputs.ee }} - token: ${{ secrets.SUBMODULES_TOKEN }} - # else checkout without submodules if the token is not provided - - uses: actions/checkout@v4 - if: steps.setup.outputs.has_token != 'true' - - - uses: ./.github/actions/setup-project - - - uses: ./.github/actions/setup-redis-cluster - - - uses: ./.github/actions/start-localstack - - # Runs a single command using the runners shell - - name: Build worker - run: CI='' pnpm build:worker - - # Runs a set of commands using the runners shell - - name: Run a test - run: | - cd apps/worker && pnpm test:e2e - pnpm test + - id: setup + run: | + if ! [[ -z "${{ secrets.SUBMODULES_TOKEN }}" ]]; then + echo "has_token=true" >> $GITHUB_OUTPUT + else + echo "has_token=false" >> $GITHUB_OUTPUT + fi + # checkout with submodules if token is provided + - uses: actions/checkout@v4 + if: steps.setup.outputs.has_token == 'true' + with: + submodules: ${{ inputs.ee }} + token: ${{ secrets.SUBMODULES_TOKEN }} + # else checkout without submodules if the token is not provided + - uses: actions/checkout@v4 + if: steps.setup.outputs.has_token != 'true' + + - uses: ./.github/actions/setup-project + + - uses: ./.github/actions/setup-redis-cluster + + - uses: ./.github/actions/start-localstack + + # Runs a single command using the runners shell + - name: Build worker + run: CI='' pnpm build:worker + + # Runs a set of commands using the runners shell + - name: Run a test + run: | + cd apps/worker && pnpm test:e2e + pnpm test diff --git a/.github/workflows/reusable-workers-service-deploy.yml b/.github/workflows/reusable-workers-service-deploy.yml index 15aaa38ef04..afb947952db 100644 --- a/.github/workflows/reusable-workers-service-deploy.yml +++ b/.github/workflows/reusable-workers-service-deploy.yml @@ -1,5 +1,8 @@ name: Deploy Workers Job +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: @@ -64,7 +67,6 @@ jobs: echo "ecs_cluster=$(terraform output -json worker_ecs_cluster | jq -r .)" >> $GITHUB_OUTPUT echo "aws_region=$(terraform output -json aws_region | jq -r .)" >> $GITHUB_OUTPUT - deploy_worker_queue: needs: infrastructure_data runs-on: ubuntu-latest diff --git a/.github/workflows/reusable-ws-e2e.yml b/.github/workflows/reusable-ws-e2e.yml index ea99d61fb44..f054c2c4906 100644 --- a/.github/workflows/reusable-ws-e2e.yml +++ b/.github/workflows/reusable-ws-e2e.yml @@ -1,5 +1,8 @@ name: E2E WebSocket Tests +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + # Controls when the action will run. Triggers the workflow on push or pull request on: workflow_call: diff --git a/.github/workflows/rollback.yml b/.github/workflows/rollback.yml index a6414c5ef4e..f504ad0b270 100644 --- a/.github/workflows/rollback.yml +++ b/.github/workflows/rollback.yml @@ -1,6 +1,9 @@ name: Rollback run-name: Rollback the ${{ inputs.service }} service in the ${{ inputs.environment }} environment +env: + NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} + on: workflow_dispatch: inputs: @@ -25,7 +28,7 @@ on: type: choice description: Select the environment region. Required only in production. options: - - [EU,US] + - [EU, US] - [EU] - [US] mode: @@ -121,11 +124,11 @@ jobs: echo "Retrieving current_task_definition_arn..." current_task_definition_arn=$(aws ecs describe-services --cluster ${{ env.ecs_cluster }} --services ${{ env.ecs_service }} --query 'services[0].taskDefinition' --output text) echo "current_task_definition_arn=$current_task_definition_arn" >> $GITHUB_ENV - + echo "Retrieving task_definition_family..." task_definition_family=$(aws ecs describe-task-definition --task-definition ${{ env.task_name }} --query 'taskDefinition.family' --output text) echo "task_definition_family=$task_definition_family" >> $GITHUB_ENV - + echo "Retrieving task_definition_list..." task_definition_list=$(aws ecs list-task-definitions --family-prefix "${task_definition_family}" --output text --sort DESC | grep 'TASKDEFINITIONARNS' | cut -f 2) task_definition_list_formatted=$(echo "$task_definition_list" | tr '\n' '|') # Replace newline with '|' @@ -178,7 +181,6 @@ jobs: echo "previous_task_definition_arn=$needed_arn" >> $GITHUB_ENV echo "Your task definition ARN is $needed_arn" - - name: Rollback a service to the previous task definition id: rollback env: @@ -191,7 +193,6 @@ jobs: echo "The previous task definition: $(echo $CURRENT_TASK | awk -F'task-definition/' '{print $2}')" echo "The current task definition: $(echo $PREVIOUS_TASK | awk -F'task-definition/' '{print $2}')" - netlify: if: contains(fromJson('["web", "widget"]'), github.event.inputs.service) runs-on: ubuntu-latest diff --git a/.github/workflows/tag-images.yml b/.github/workflows/tag-images.yml index daf317f65b8..44fae29177c 100644 --- a/.github/workflows/tag-images.yml +++ b/.github/workflows/tag-images.yml @@ -33,7 +33,7 @@ jobs: GH_ACTOR: ${{ github.actor }} GH_PASSWORD: ${{ secrets.GH_PACKAGES }} run: | - echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin + echo $GH_PASSWORD | docker login ghcr.io -u $GH_ACTOR --password-stdin - name: Tag API env: diff --git a/.gitpod.yml b/.gitpod.yml index bdb9f418eab..5ccafcfc062 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -2,7 +2,7 @@ image: file: .gitpod.dockerfile tasks: - init: npm_config_yes=true pnpm setup:project && gp sync-done setup - command: mkdir -p /workspace/data && mongod --dbpath /workspace/data + command: mkdir -p /workspace/data && mongod --dbpath /workspace/data - init: gp sync-await setup command: redis-server - name: Shared Library diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc index a1d8fea5b69..cd7fe879668 100644 --- a/.markdownlint.jsonc +++ b/.markdownlint.jsonc @@ -4,12 +4,12 @@ // MD024/no-duplicate-heading/no-duplicate-header - Multiple headings with the same content "MD024": { - "siblings_only": true + "siblings_only": true, }, // no-multiple-blanks "MD012": false, - + // MD032/blanks-around-lists - Lists should be surrounded by blank lines "MD032": false, @@ -33,22 +33,14 @@ // MD044/proper-names - Proper names should have the correct capitalization "MD044": { "code_blocks": false, - "names": [ - "Cake.Markdownlint", - "CommonMark", - "JavaScript", - "Markdown", - "markdown-it", - "markdownlint", - "Node.js" - ] + "names": ["Cake.Markdownlint", "CommonMark", "JavaScript", "Markdown", "markdown-it", "markdownlint", "Node.js"], }, // MD-46/code-block-style "MD046": { - "style": "fenced" + "style": "fenced", }, // MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines - "MD031": false + "MD031": false, } diff --git a/.vscode/launch.json b/.vscode/launch.json index af743d5a772..11075039d70 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,229 +1,148 @@ { "version": "0.2.0", "configurations": [ - { "name": "API - TEST ENV", "request": "launch", - "runtimeArgs": [ - "run-script", - "start:test" - ], + "runtimeArgs": ["run-script", "start:test"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/api", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "API", "request": "launch", - "runtimeArgs": [ - "run-script", - "start" - ], + "runtimeArgs": ["run-script", "start"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/api", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "worker", "request": "launch", - "runtimeArgs": [ - "run-script", - "start" - ], + "runtimeArgs": ["run-script", "start"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/worker", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "WEB", "request": "launch", - "runtimeArgs": [ - "run-script", - "start:dev" - ], + "runtimeArgs": ["run-script", "start:dev"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/web", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "WIDGET", "request": "launch", - "runtimeArgs": [ - "run-script", - "start:dev" - ], + "runtimeArgs": ["run-script", "start:dev"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/widget", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "WIDGET - test", "request": "launch", - "runtimeArgs": [ - "run-script", - "start:test" - ], + "runtimeArgs": ["run-script", "start:test"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/widget", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "WS", "request": "launch", - "runtimeArgs": [ - "run-script", - "start" - ], + "runtimeArgs": ["run-script", "start"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/ws", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "WS - TEST ENV", "request": "launch", - "runtimeArgs": [ - "run-script", - "start:test" - ], + "runtimeArgs": ["run-script", "start:test"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/ws", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "DAL", "request": "launch", - "runtimeArgs": [ - "run-script", - "start:dev" - ], + "runtimeArgs": ["run-script", "start:dev"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/libs/dal", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "TESTING LIB", "request": "launch", - "runtimeArgs": [ - "run-script", - "start:dev" - ], + "runtimeArgs": ["run-script", "start:dev"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/libs/testing", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "EMBED", "request": "launch", - "runtimeArgs": [ - "run-script", - "start:dev" - ], + "runtimeArgs": ["run-script", "start:dev"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/libs/embed", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "SHARED", "request": "launch", - "runtimeArgs": [ - "run-script", - "start:dev" - ], + "runtimeArgs": ["run-script", "start:dev"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/packages/shared", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "STORYBOOK", "request": "launch", - "runtimeArgs": [ - "run-script", - "storybook" - ], + "runtimeArgs": ["run-script", "storybook"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/web", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "CORE", "request": "launch", - "runtimeArgs": [ - "run-script", - "start:dev" - ], + "runtimeArgs": ["run-script", "start:dev"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/packages/node", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "Cypress open - web", "request": "launch", - "runtimeArgs": [ - "run-script", - "cypress:open" - ], + "runtimeArgs": ["run-script", "cypress:open"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/web", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" }, { "name": "Cypress open - widget", "request": "launch", - "runtimeArgs": [ - "run-script", - "cypress:open" - ], + "runtimeArgs": ["run-script", "cypress:open"], "runtimeExecutable": "npm", "cwd": "${workspaceFolder}/apps/widget", - "skipFiles": [ - "/**" - ], + "skipFiles": ["/**"], "type": "node" } ], diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 5918193398a..14df9002691 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -21,7 +21,7 @@ "endsPattern": "Started application in NODE_ENV" } } - }, + }, { "type": "npm", "script": "start", @@ -41,14 +41,7 @@ "id": "server", "color": "terminal.ansiGreen" }, - "dependsOn": [ - "SHARED", - "API", - "APPLICATION GENERIC", - "DAL", - "EE - TRANSLATION", - "EE - BILLING" - ] + "dependsOn": ["SHARED", "API", "APPLICATION GENERIC", "DAL", "EE - TRANSLATION", "EE - BILLING"] }, { "type": "npm", @@ -69,7 +62,8 @@ "endsPattern": "webpack compiled successfully" } } - }, { + }, + { "type": "npm", "script": "start", "isBackground": true, @@ -88,12 +82,7 @@ "endsPattern": "webpack compiled successfully" } }, - "dependsOn": [ - "SHARED", - "API", - "DESIGN SYSTEM", - "NOVUI" - ] + "dependsOn": ["SHARED", "API", "DESIGN SYSTEM", "NOVUI"] }, { "type": "npm", @@ -110,11 +99,7 @@ "label": "APPLICATION GENERIC", "path": "/libs/application-generic", "problemMatcher": "$tsc-watch", - "dependsOn": [ - "SHARED", - "TESTING", - "PROVIDERS" - ] + "dependsOn": ["SHARED", "TESTING", "PROVIDERS"] }, { "type": "npm", @@ -123,9 +108,7 @@ "label": "DAL", "path": "/libs/dal", "problemMatcher": "$tsc-watch", - "dependsOn": [ - "SHARED" - ] + "dependsOn": ["SHARED"] }, { "type": "npm", @@ -142,9 +125,7 @@ "label": "PROVIDERS", "path": "/packages/providers", "problemMatcher": "$tsc-watch", - "dependsOn": [ - "SHARED" - ] + "dependsOn": ["SHARED"] }, { "type": "npm", @@ -161,9 +142,7 @@ "label": "TESTING", "path": "/libs/testing", "problemMatcher": "$tsc-watch", - "dependsOn": [ - "SHARED" - ] + "dependsOn": ["SHARED"] }, { "type": "npm", @@ -221,10 +200,7 @@ "label": "NOTIFICATION CENTER", "path": "/packages/notification-center", "problemMatcher": "$tsc", - "dependsOn": [ - "NC CLIENT", - "SHARED" - ] + "dependsOn": ["NC CLIENT", "SHARED"] }, { "type": "npm", @@ -232,9 +208,7 @@ "label": "NC CLIENT", "path": "/packages/client", "problemMatcher": "$tsc", - "dependsOn": [ - "SHARED" - ] + "dependsOn": ["SHARED"] } ] } diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 14352a3718c..4338d6e7904 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -17,23 +17,23 @@ diverse, inclusive, and healthy community. Examples of behavior that contributes to a positive environment for our community includes: -* Demonstrating empathy and kindness toward other people -* Being respectful of differing opinions, viewpoints, and experiences -* Giving and gracefully accepting constructive feedback -* Accepting responsibility and apologizing to those affected by our mistakes, +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -* Focusing on what is best not just for us as individuals, but for the +- Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: -* The use of sexualized language or imagery, and sexual attention or +- The use of sexualized language or imagery, and sexual attention or advances of any kind -* Trolling, insulting or derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or email +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, without their explicit permission -* Other conduct that could reasonably be considered inappropriate in a +- Other conduct that could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities @@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an +standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within diff --git a/README.md b/README.md index 7569a559bad..09eca5a66cb 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ There are two ways to get started: ```bash npx novu@latest dev ``` + 2. [Create a free cloud account](https://dashboard.novu.co?utm_campaign=github-readme) ## 📚 Table of contents @@ -135,6 +136,7 @@ Using the Novu API and admin panel, you can easily add a real-time notification notification-center-912bb96e009fb3a69bafec23bcde00b0 Read more about how to add a [notification center Inbox](https://docs.novu.co/inbox/react/get-started?utm_campaign=github-readme) to your app. + ## Providers @@ -217,6 +219,7 @@ We are more than happy to help you. If you are getting any errors or facing prob Novu is a commercial open source company, which means some parts of this open source repository require a commercial license. The concept is called "Open Core," where the core technology is fully open source, licensed under MIT license, and the enterprise code is covered under a commercial license ("/enterprise" Enterprise Edition). Enterprise features are built by the core engineering team of Novu which is hired in full-time. The following modules and folders are licensed under the enterprise license: + - `enterprise` folder at the root of the project and all of their subfolders and modules - `apps/web/src/ee` folder and all of their subfolders and modules - `apps/dashboard/src/ee` folder and all of their subfolders and modules diff --git a/SECURITY.md b/SECURITY.md index 9b94c6ade88..4f7605572fb 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -46,7 +46,7 @@ If you come across a vulnerability, please inform us promptly so we can promptly 6. Please share enough details for us to understand and fix the issue as fast as we can. Typically, providing the IP address or the URL of the affected system along with a description of the problem should be enough, though more intricate issues might need additional clarification. -## What *We* Promise +## What _We_ Promise 1. We'll get back to you within 3 business days with our assessment of the report and an estimated date when we expect to resolve it. diff --git a/apps/api/.spectral.yaml b/apps/api/.spectral.yaml index 31d5ceb4c92..482288d25ed 100644 --- a/apps/api/.spectral.yaml +++ b/apps/api/.spectral.yaml @@ -14,9 +14,9 @@ extends: [[spectral:oas, all]] # https://meta.stoplight.io/docs/spectral/293426e270fac-overrides overrides: - files: - - "**#/paths/~1v1~1subscribers~1%7BsubscriberId%7D~1preferences~1%7BtemplateId%7D" - - "**#/paths/~1v1~1subscribers~1%7BsubscriberId%7D~1preferences~1%7Blevel%7D" - - "**#/paths/~1v1~1workflows~1%7BworkflowIdOrIdentifier%7D" - - "**#/paths/~1v1~1notification-templates~1%7BworkflowIdOrIdentifier%7D" + - '**#/paths/~1v1~1subscribers~1%7BsubscriberId%7D~1preferences~1%7BtemplateId%7D' + - '**#/paths/~1v1~1subscribers~1%7BsubscriberId%7D~1preferences~1%7Blevel%7D' + - '**#/paths/~1v1~1workflows~1%7BworkflowIdOrIdentifier%7D' + - '**#/paths/~1v1~1notification-templates~1%7BworkflowIdOrIdentifier%7D' rules: - path-params: "off" + path-params: 'off' diff --git a/apps/api/README.md b/apps/api/README.md index 477c6f02fd3..bee04293f68 100644 --- a/apps/api/README.md +++ b/apps/api/README.md @@ -11,7 +11,6 @@ A RESTful API for accessing the Novu platform, built using [NestJS](https://nestjs.com/). - ## Running the API See the docs for [Run in Local Machine](https://docs.novu.co/community/run-in-local-machine?utm_campaign=github-api-readme) to get setup. Then run: @@ -24,30 +23,37 @@ $ npm run start:api ## Test ### Unit Tests + ```bash # unit tests $ npm run test ``` ### E2E tests + See the docs for [Running on Local Machine - API Tests](https://docs.novu.co/community/run-in-local-machine#api?utm_campaign=github-api-readme). ## Adding a new Endpoint + ### Choose the right controller / new controller. + - If the endpoint is related to an existing entity, add the endpoint to the existing controller. + ### Add the correct decorators to the controller method. + - Use the `@Get`, `@Post`, `@Put`, `@Delete` decorators to define the HTTP method. - Use the `@Param`, `@Query`, `@Body` decorators to define the parameters. - Use the `@UserAuthentication()` decorator to define the guards as well as make it accessible to novu web app. - Use the @ExternalApiAccessible decorator to define the endpoint as accessible by external API (Users with Api-Key) & The official Novu SDK. -#### Naming conventions - - for the controller methods should be in the format `getEntityName`, `createEntityName`, `updateEntityName`, `deleteEntityName`. - - In Case of a getAll / List use the `list` prefix for the method name and don't forget to add pagination functionality. - - Use the `@SdkUsePagination` decorator to alert the sdk of a paginated endpoint (will improve DX with an async iterator) the pagination parameters. - - In case of a uniuqe usecase outside of the basic REST operations, attempt to use the regular naming conventions just for a sub-resource. - - `@SdkGroupName` - Use this decorator to group the endpoints in the SDK, use `.` separator to create a subresource (Ex' 'Subscribers.Notifications' getSubscriberNotifications), the original resource is defined as an openApi Tag . - - `@SdkMethodName` in case of a unique operation, use this decorator to define the method name in the SDK. +#### Naming conventions + +- for the controller methods should be in the format `getEntityName`, `createEntityName`, `updateEntityName`, `deleteEntityName`. +- In Case of a getAll / List use the `list` prefix for the method name and don't forget to add pagination functionality. + - Use the `@SdkUsePagination` decorator to alert the sdk of a paginated endpoint (will improve DX with an async iterator) the pagination parameters. +- In case of a uniuqe usecase outside of the basic REST operations, attempt to use the regular naming conventions just for a sub-resource. + - `@SdkGroupName` - Use this decorator to group the endpoints in the SDK, use `.` separator to create a subresource (Ex' 'Subscribers.Notifications' getSubscriberNotifications), the original resource is defined as an openApi Tag . + - `@SdkMethodName` in case of a unique operation, use this decorator to define the method name in the SDK. ## OpenAPI (formerly Swagger) @@ -63,8 +69,8 @@ $ npm run lint:openapi The command will return warnings and errors that must be fixed before the Github action will pass. These fixes are created by making changes through the `@nestjs/swagger` decorators. - ## Migrations + Database migrations are included for features that have a hard dependency on specific data being available on database entities. These migrations are run by both Novu Cloud and Novu Self-Hosted users to support new feature releases. ### How to Run diff --git a/apps/api/jarvis-api-intro.md b/apps/api/jarvis-api-intro.md index f5ef84776ef..5ec0272cb3b 100644 --- a/apps/api/jarvis-api-intro.md +++ b/apps/api/jarvis-api-intro.md @@ -1,6 +1,6 @@ Hi, I'm Jarvis 🤖 -I'm a bot built to help you with your contribution to Novu. +I'm a bot built to help you with your contribution to Novu. I will add instructions and guides on how to run the subset of the Novu platform associated to this issue and make your first contribution. This issue was tagged as related to `@novu/api` and the related code is located at the `apps/api` folder, here is how I can help you: @@ -8,19 +8,23 @@ This issue was tagged as related to `@novu/api` and the related code is located
First time contributing to Novu? - If that's the first time you want to contribute to Novu here are a few simple steps to get you started: - 1. Fork the repository and clone your fork to your local machine. - 2. Install the dependencies using `npm run setup:project`. - 3. Create a new branch with the number of the issue, for example: `1454-fix-something-cool` and start contributing based on the [Contributing Guide](https://docs.novu.co/community/run-in-local-machine?utm_campaign=github-jarvis) or the short guide in the section below. - 4. Create a Pull request and follow the template of creation +If that's the first time you want to contribute to Novu here are a few simple steps to get you started: + +1. Fork the repository and clone your fork to your local machine. +2. Install the dependencies using `npm run setup:project`. +3. Create a new branch with the number of the issue, for example: `1454-fix-something-cool` and start contributing based on the [Contributing Guide](https://docs.novu.co/community/run-in-local-machine?utm_campaign=github-jarvis) or the short guide in the section below. +4. Create a Pull request and follow the template of creation
Run and test `@novu/api` locally - ### Run API in watch mode - The easiest way to start the API is to run `npm run start:api` from the root of the repository +### Run API in watch mode + +The easiest way to start the API is to run `npm run start:api` from the root of the repository + +### Run API integration tests + +To validate your changes or simply to run the e2e tests run `npm run start:e2e:api`. All the e2e tests have the `.e2e.ts` suffix and usually are located near the controller files of each module. - ### Run API integration tests - To validate your changes or simply to run the e2e tests run `npm run start:e2e:api`. All the e2e tests have the `.e2e.ts` suffix and usually are located near the controller files of each module.
diff --git a/apps/dashboard/README.md b/apps/dashboard/README.md index 74872fd4af6..1e5a46b4e1c 100644 --- a/apps/dashboard/README.md +++ b/apps/dashboard/README.md @@ -22,7 +22,7 @@ export default tseslint.config({ tsconfigRootDir: import.meta.dirname, }, }, -}) +}); ``` - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` @@ -31,7 +31,7 @@ export default tseslint.config({ ```js // eslint.config.js -import react from 'eslint-plugin-react' +import react from 'eslint-plugin-react'; export default tseslint.config({ // Set the react version @@ -46,5 +46,5 @@ export default tseslint.config({ ...react.configs.recommended.rules, ...react.configs['jsx-runtime'].rules, }, -}) +}); ``` diff --git a/apps/dashboard/src/index.css b/apps/dashboard/src/index.css index ecfe13bbf6f..30fa7346b83 100644 --- a/apps/dashboard/src/index.css +++ b/apps/dashboard/src/index.css @@ -87,8 +87,9 @@ @apply bg-background text-foreground-950; } - body, html{ + body, + html { height: 100%; scroll-behavior: smooth; -} + } } diff --git a/apps/web/.storybook/Doc.container.tsx b/apps/web/.storybook/Doc.container.tsx index ae81e24715f..9a13aed2981 100644 --- a/apps/web/.storybook/Doc.container.tsx +++ b/apps/web/.storybook/Doc.container.tsx @@ -22,7 +22,8 @@ export const DocsContainer = ({ children, context }) => { }, }; }, - }}> + }} + > {children} ); diff --git a/apps/web/.storybook/main.js b/apps/web/.storybook/main.js index 8d24b5538aa..a1e2ad206ab 100644 --- a/apps/web/.storybook/main.js +++ b/apps/web/.storybook/main.js @@ -1,12 +1,17 @@ -import { dirname, join } from "path"; +import { dirname, join } from 'path'; module.exports = { stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], - addons: [getAbsolutePath("@storybook/addon-links"), getAbsolutePath("@storybook/addon-essentials"), getAbsolutePath("storybook-dark-mode"), getAbsolutePath("@storybook/addon-mdx-gfm")], + addons: [ + getAbsolutePath('@storybook/addon-links'), + getAbsolutePath('@storybook/addon-essentials'), + getAbsolutePath('storybook-dark-mode'), + getAbsolutePath('@storybook/addon-mdx-gfm'), + ], framework: { - name: getAbsolutePath("@storybook/react-webpack5"), - options: {} + name: getAbsolutePath('@storybook/react-webpack5'), + options: {}, }, features: { @@ -14,10 +19,10 @@ module.exports = { }, docs: { - autodocs: true - } + autodocs: true, + }, }; function getAbsolutePath(value) { - return dirname(require.resolve(join(value, "package.json"))); + return dirname(require.resolve(join(value, 'package.json'))); } diff --git a/apps/web/public/index.html b/apps/web/public/index.html index 0853c4758e6..406aae780ff 100644 --- a/apps/web/public/index.html +++ b/apps/web/public/index.html @@ -1,4 +1,4 @@ - + @@ -46,7 +46,11 @@ /* Critical CSS for the instant loader */ @layer critical { /* Override Mantine injected CSS layers to prevent minor jumps */ - *,::before,::after,::backdrop,::file-selector-button { + *, + ::before, + ::after, + ::backdrop, + ::file-selector-button { margin: 0px; padding: 0px; box-sizing: border-box; @@ -63,12 +67,12 @@ @media (prefers-color-scheme: light) { /* surface.page (light mode) */ - background-color: #EDF0F2; + background-color: #edf0f2; } @media (prefers-color-scheme: dark) { /* surface.page (dark mode) */ - background-color: #13131A ; + background-color: #13131a; } } @@ -104,24 +108,94 @@
- - + + - - + + - - + + - - + + - - + +
diff --git a/apps/web/src/components/docs/DocsButton.tsx b/apps/web/src/components/docs/DocsButton.tsx index 49a1db74787..837a7a5ffeb 100644 --- a/apps/web/src/components/docs/DocsButton.tsx +++ b/apps/web/src/components/docs/DocsButton.tsx @@ -36,7 +36,7 @@ const DefaultButton = ({ onClick }: { onClick: () => void }) => ( } onClick={onClick} diff --git a/apps/web/src/components/docs/Mdx.tsx b/apps/web/src/components/docs/Mdx.tsx index 8810f6f653a..2cec9b51ac5 100644 --- a/apps/web/src/components/docs/Mdx.tsx +++ b/apps/web/src/components/docs/Mdx.tsx @@ -302,7 +302,7 @@ export const Mdx = ({ code = '', mappings = {}, isChildDocs, children, isLoading listStyleType: 'decimal', listStylePosition: 'inside', '& p': { - display: 'inline !important', + display: '!important inline', }, })} {...props} @@ -317,7 +317,7 @@ export const Mdx = ({ code = '', mappings = {}, isChildDocs, children, isLoading listStyleType: 'disc', listStylePosition: 'inside', '& p': { - display: 'inline !important', + display: '!important inline', }, })} {...props} diff --git a/apps/web/src/components/nav/RootNavMenuFooter.tsx b/apps/web/src/components/nav/RootNavMenuFooter.tsx index ef869337fcd..d635525d9c8 100644 --- a/apps/web/src/components/nav/RootNavMenuFooter.tsx +++ b/apps/web/src/components/nav/RootNavMenuFooter.tsx @@ -9,7 +9,7 @@ export const RootNavMenuFooter: React.FC = () => { className={cx( hstack(), css({ - display: 'flex !important', + display: '!important flex', justifyContent: 'space-between', pt: '100', }) diff --git a/apps/web/src/pages/templates/components/CustomCodeEditor.css b/apps/web/src/pages/templates/components/CustomCodeEditor.css index d1d63267e89..e5afb986394 100644 --- a/apps/web/src/pages/templates/components/CustomCodeEditor.css +++ b/apps/web/src/pages/templates/components/CustomCodeEditor.css @@ -41,10 +41,7 @@ color: #fff !important; } - -.custom-code-editor - .monaco-editor - .overflow-guard { +.custom-code-editor .monaco-editor .overflow-guard { border-radius: 10px !important; } diff --git a/apps/web/src/stories/Introduction.stories.mdx b/apps/web/src/stories/Introduction.stories.mdx index a95c3c38220..4363e196737 100644 --- a/apps/web/src/stories/Introduction.stories.mdx +++ b/apps/web/src/stories/Introduction.stories.mdx @@ -128,33 +128,21 @@ We recommend building UIs with a [**component-driven**](https://componentdriven.
Configure
- TipEdit the Markdown in{' '} - src/stories/Introduction.stories.mdx + TipEdit the Markdown in src/stories/Introduction.stories.mdx
diff --git a/apps/web/src/studio/components/GetStartedPageV2/index.tsx b/apps/web/src/studio/components/GetStartedPageV2/index.tsx index 714267accb0..e55d5d99c45 100644 --- a/apps/web/src/studio/components/GetStartedPageV2/index.tsx +++ b/apps/web/src/studio/components/GetStartedPageV2/index.tsx @@ -174,7 +174,7 @@ export const GetStartedPageV2 = ({ location }: { location: 'onboarding' | 'get-s border: 'none !important', padding: '1px', borderRadius: '100', - boxShadow: 'dark !important', + boxShadow: '!important dark', })} onDoubleClick={() => { track('Command copied - [Get Started - V2]'); diff --git a/apps/widget/README.md b/apps/widget/README.md index 9516c111986..c60613a517f 100644 --- a/apps/widget/README.md +++ b/apps/widget/README.md @@ -1,9 +1,9 @@ # Widget - ## How to run e2e test in local? Run `npm run start:test` script in the following apps on separate terminals: + 1. apps/api 2. apps/ws 3. apps/widget diff --git a/apps/widget/config-overrides.js b/apps/widget/config-overrides.js index 404a228034a..1db88e6c840 100644 --- a/apps/widget/config-overrides.js +++ b/apps/widget/config-overrides.js @@ -2,8 +2,8 @@ const { useBabelRc, override } = require('customize-cra'); // const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; function overrideConfig(config, env) { - const plugins = [...config.plugins, /* new BundleAnalyzerPlugin() */]; - + const plugins = [...config.plugins /* new BundleAnalyzerPlugin() */]; + return { ...config, plugins }; } diff --git a/apps/widget/cypress/test-shell/example/test.html b/apps/widget/cypress/test-shell/example/test.html index 8b92cf1b1dc..c49c361a16d 100644 --- a/apps/widget/cypress/test-shell/example/test.html +++ b/apps/widget/cypress/test-shell/example/test.html @@ -1,10 +1,10 @@ - - - - - Title - - -This is a test page - + + + + + Title + + + This is a test page + diff --git a/apps/widget/cypress/test-shell/index.html b/apps/widget/cypress/test-shell/index.html index f21a0ca1126..b58c9ec8726 100644 --- a/apps/widget/cypress/test-shell/index.html +++ b/apps/widget/cypress/test-shell/index.html @@ -1,81 +1,115 @@ - - Getting Started - - - - - - - - -
- - Settings - - Sign - out +
+
+

Dashboard

-
+ +
+
+ +
+
+
+ +
+
- -
-
-

- Dashboard -

-
-
-
-
- -
-
-
- -
-
- - - - - + + diff --git a/apps/widget/index.html b/apps/widget/index.html index 7a617d81528..2f7d9e9f605 100644 --- a/apps/widget/index.html +++ b/apps/widget/index.html @@ -24,8 +24,8 @@
-
+

Dashboard

-
+
-
+
diff --git a/apps/widget/public/index.html b/apps/widget/public/index.html index 910c85e4792..e1d3e55cb13 100644 --- a/apps/widget/public/index.html +++ b/apps/widget/public/index.html @@ -1,19 +1,18 @@ - + - - - - - - - - - - - - React App - - + React App + + - - -
- - - - - \ No newline at end of file + + + diff --git a/apps/worker/README.md b/apps/worker/README.md index 18d4fc94215..04e006db03c 100644 --- a/apps/worker/README.md +++ b/apps/worker/README.md @@ -6,6 +6,7 @@ [travis-url]: https://travis-ci.org/nestjs/nest [linux-image]: https://img.shields.io/travis/nestjs/nest/master.svg?label=linux [linux-url]: https://travis-ci.org/nestjs/nest +

A progressive Node.js framework for building efficient and scalable server-side applications, heavily inspired by Angular.

NPM Version diff --git a/docker/community/docker-compose.yml b/docker/community/docker-compose.yml index 24377a78043..b15831ec23e 100644 --- a/docker/community/docker-compose.yml +++ b/docker/community/docker-compose.yml @@ -173,9 +173,9 @@ services: REACT_APP_WS_URL: ${REACT_APP_WS_URL} ports: - 4200:4200 - command: ["/bin/sh", "-c", "pnpm run envsetup:docker && pnpm run start:static:build"] + command: ['/bin/sh', '-c', 'pnpm run envsetup:docker && pnpm run start:static:build'] healthcheck: - test: ['CMD-SHELL', 'curl --silent --fail http://localhost:4200 || exit 1'] + test: ['CMD-SHELL', 'curl --silent --fail http://localhost:4200 || exit 1'] interval: 30s timeout: 10s retries: 3 diff --git a/docker/local/docker-compose.e2e.yml b/docker/local/docker-compose.e2e.yml index 5270656dbd9..313d14a0152 100644 --- a/docker/local/docker-compose.e2e.yml +++ b/docker/local/docker-compose.e2e.yml @@ -2,16 +2,16 @@ version: '3.1' services: localstack: - container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}" - image: "localstack/localstack:0.14.5" + container_name: '${LOCALSTACK_DOCKER_NAME-localstack_main}' + image: 'localstack/localstack:0.14.5' network_mode: bridge environment: - SERVICES=s3 ports: - - "${DOCKER_LOCALSTACK_PORT:-4566}:4566" + - '${DOCKER_LOCALSTACK_PORT:-4566}:4566' volumes: - - "${TMPDIR:-/tmp/localstack}:/tmp/localstack" - - "/var/run/docker.sock:/var/run/docker.sock" + - '${TMPDIR:-/tmp/localstack}:/tmp/localstack' + - '/var/run/docker.sock:/var/run/docker.sock' healthcheck: test: "bash -c 'AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test aws --endpoint-url=http://127.0.0.1:4566 s3 ls'" retries: 5 diff --git a/docker/local/docker-compose.local.yml b/docker/local/docker-compose.local.yml index e2c6aa7667a..cc37db1bb77 100644 --- a/docker/local/docker-compose.local.yml +++ b/docker/local/docker-compose.local.yml @@ -1,26 +1,25 @@ - services: api: build: - dockerfile: "./apps/api/Dockerfile" - context: "../../.." + dockerfile: './apps/api/Dockerfile' + context: '../../..' worker: build: - dockerfile: "./apps/worker/Dockerfile" - context: "../../.." + dockerfile: './apps/worker/Dockerfile' + context: '../../..' web: build: - dockerfile: "./apps/web/Dockerfile" - context: "../../.." + dockerfile: './apps/web/Dockerfile' + context: '../../..' ws: build: - dockerfile: "./apps/ws/Dockerfile" - context: "../../.." + dockerfile: './apps/ws/Dockerfile' + context: '../../..' widget: build: - dockerfile: "./apps/widget/Dockerfile" - context: "../../.." + dockerfile: './apps/widget/Dockerfile' + context: '../../..' embed: build: - dockerfile: "./libs/embed/Dockerfile" - context: "../../.." + dockerfile: './libs/embed/Dockerfile' + context: '../../..' diff --git a/docker/local/docker-compose.yml b/docker/local/docker-compose.yml index 1465a9c1ec5..b8027216012 100644 --- a/docker/local/docker-compose.yml +++ b/docker/local/docker-compose.yml @@ -1,37 +1,37 @@ services: localstack: - container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}" - image: "localstack/localstack:0.14.5" + container_name: '${LOCALSTACK_DOCKER_NAME-localstack_main}' + image: 'localstack/localstack:0.14.5' network_mode: bridge environment: - SERVICES=s3 ports: - - "${DOCKER_LOCALSTACK_PORT:-4566}:4566" + - '${DOCKER_LOCALSTACK_PORT:-4566}:4566' volumes: - - "${TMPDIR:-/tmp/localstack}:/tmp/localstack" - - "/var/run/docker.sock:/var/run/docker.sock" + - '${TMPDIR:-/tmp/localstack}:/tmp/localstack' + - '/var/run/docker.sock:/var/run/docker.sock' healthcheck: test: "bash -c 'AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test aws --endpoint-url=http://127.0.0.1:4566 s3 ls'" retries: 5 interval: 10s mongo: - container_name: "${MONGO_DOCKER_NAME-mongo_main}" + container_name: '${MONGO_DOCKER_NAME-mongo_main}' image: mongo network_mode: bridge ports: - - "${DOCKER_MONGO_PORT:-27017}:27017" + - '${DOCKER_MONGO_PORT:-27017}:27017' volumes: - - "${TMPDIR:-/tmp/mongo}:/db/data" + - '${TMPDIR:-/tmp/mongo}:/db/data' healthcheck: - test: "bash -c 'mongo --host 127.0.0.1:27017 --eval \"printjson(rs.status())\"'" + test: 'bash -c ''mongo --host 127.0.0.1:27017 --eval "printjson(rs.status())"''' retries: 5 interval: 10s redis: - container_name: "${REDIS_DOCKER_NAME-redis_main}" + container_name: '${REDIS_DOCKER_NAME-redis_main}' image: redis network_mode: bridge ports: - - "${DOCKER_REDIS_SERVICE_PORT:-6379}:6379" + - '${DOCKER_REDIS_SERVICE_PORT:-6379}:6379' healthcheck: test: "bash -c 'redis-cli ping'" retries: 5 @@ -39,6 +39,6 @@ services: pyroscope: image: grafana/pyroscope:latest ports: - - "4040:4040" + - '4040:4040' profiles: - optional diff --git a/enterprise/packages/dal/tsconfig.build.json b/enterprise/packages/dal/tsconfig.build.json index 6ef5124af0b..d4f964ab3ba 100644 --- a/enterprise/packages/dal/tsconfig.build.json +++ b/enterprise/packages/dal/tsconfig.build.json @@ -8,11 +8,7 @@ "esModuleInterop": false, "outDir": "./dist", "rootDir": "./src", - "types": [ - "node" - ] + "types": ["node"] }, - "include": [ - "src/**/*" - ] + "include": ["src/**/*"] } diff --git a/enterprise/packages/shared-services/tsconfig.json b/enterprise/packages/shared-services/tsconfig.json index baba9a9e4c0..1605d2a7119 100644 --- a/enterprise/packages/shared-services/tsconfig.json +++ b/enterprise/packages/shared-services/tsconfig.json @@ -9,7 +9,7 @@ "esModuleInterop": true, "rootDir": "src", "strict": true, - "types": ["node", "jest"], + "types": ["node", "jest"] }, "include": ["src/**/*.ts"], "exclude": ["node_modules/**"] diff --git a/eslint.config.mjs b/eslint.config.mjs index 56a09a4b1ef..6cd21b98a3b 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -46,7 +46,8 @@ const noRestrictedImportsMultiLevelNovuPattern = { // This flatMap logic ignores the path 1 below the root level and prevents deeper imports. ...['framework', 'js', 'novui'].flatMap((pkg) => [`!@novu/${pkg}/**/*`, `@novu/${pkg}/*/**/*`]), ], - message: "Please import only from the root package entry point. For example, use 'import { Client } from '@novu/node';' instead of 'import { Client } from '@novu/node/src';'", + message: + "Please import only from the root package entry point. For example, use 'import { Client } from '@novu/node';' instead of 'import { Client } from '@novu/node/src';'", }; export default tsEslint.config( @@ -116,8 +117,8 @@ export default tsEslint.config( 'unused-imports/no-unused-imports': 'off', '@typescript-eslint/space-before-blocks': 'off', '@typescript-eslint/lines-between-class-members': 'off', - "@typescript-eslint/no-throw-literal": "off", - "@typescript-eslint/only-throw-error": "error", + '@typescript-eslint/no-throw-literal': 'off', + '@typescript-eslint/only-throw-error': 'error', 'react/jsx-wrap-multilines': 'off', 'react/jsx-filename-extension': 'off', 'multiline-comment-style': ['warn', 'starred-block'], @@ -174,9 +175,7 @@ export default tsEslint.config( 'no-restricted-imports': [ 'error', { - patterns: [ - noRestrictedImportsMultiLevelNovuPattern, - ], + patterns: [noRestrictedImportsMultiLevelNovuPattern], }, ], diff --git a/jest.config.js b/jest.config.js index a93551fca25..4a5b465ecb5 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,4 @@ module.exports = { - preset: "ts-jest", - testEnvironment: "node", + preset: 'ts-jest', + testEnvironment: 'node', }; diff --git a/libs/application-generic/README.md b/libs/application-generic/README.md index abf86657ed8..3da45db8282 100644 --- a/libs/application-generic/README.md +++ b/libs/application-generic/README.md @@ -1,4 +1,3 @@ # Application generic Generic backend code used inside of Novu's different services - diff --git a/libs/application-generic/src/utils/deepmerge.ts b/libs/application-generic/src/utils/deepmerge.ts index 88c7f03ceea..f6a0ecc7c6f 100644 --- a/libs/application-generic/src/utils/deepmerge.ts +++ b/libs/application-generic/src/utils/deepmerge.ts @@ -24,7 +24,7 @@ function emptyTarget(val: unknown) { function cloneUnlessOtherwiseSpecified( value: Record, - options: IOptions + options: IOptions, ): Record | Record[] { return options.clone !== false && options.isMergeableObject(value) ? deepMergeObjects(emptyTarget(value), value, options) @@ -34,13 +34,13 @@ function cloneUnlessOtherwiseSpecified( function defaultArrayMerge( target: Record[], source: Record[], - options: IOptions + options: IOptions, ): Record[] { return target.concat(source).map(function (element) { - return cloneUnlessOtherwiseSpecified( - element, - options - ) as Record; + return cloneUnlessOtherwiseSpecified(element, options) as Record< + string, + unknown + >; }); } @@ -79,7 +79,7 @@ function propertyIsUnsafe(target: Record, key: string) { function mergeObject( target: Record, source: Record, - options: IOptions + options: IOptions, ): Record { const destination = {}; if (options.isMergeableObject(target)) { @@ -88,7 +88,7 @@ function mergeObject( getKeys(target).forEach((key: string) => { destination[key] = cloneUnlessOtherwiseSpecified( target[key] as Record, - options + options, ); }); } @@ -106,12 +106,12 @@ function mergeObject( destination[key] = getMergeFunction(key as string, options)( target[key] as Record, source[key] as Record, - options + options, ); } else { destination[key] = cloneUnlessOtherwiseSpecified( source[key] as Record, - options + options, ); } }); @@ -121,42 +121,42 @@ function mergeObject( interface IOptions { customMerge: ( - key: string + key: string, ) => ( target: Record, source: Record, - options: IOptions + options: IOptions, ) => Record; arrayMerge: ( target: Record[], source: Record[], - options: IOptions + options: IOptions, ) => Record[]; isMergeableObject: (value: unknown) => boolean; cloneUnlessOtherwiseSpecified: ( value: Record, - options: IOptions + options: IOptions, ) => Record | Record[]; clone?: boolean; } interface IDeepMergeOptions { customMerge?: ( - key: string + key: string, ) => ( target: Record, source: Record, - options: IOptions + options: IOptions, ) => Record; arrayMerge?: ( target: Record[], source: Record[], - options: IOptions + options: IOptions, ) => Record[]; isMergeableObject?: (value: unknown) => boolean; cloneUnlessOtherwiseSpecified?: ( value: Record, - options: IOptions + options: IOptions, ) => Record | Record[]; clone?: boolean; } @@ -170,11 +170,11 @@ interface IDeepMergeOptions { * @returns The merged object or array of objects. */ function deepMergeObjects< - T extends Record | Record[] + T extends Record | Record[], >( target: Record | Record[], source: Record | Record[], - options?: IDeepMergeOptions + options?: IDeepMergeOptions, ): T { options = options || {}; options.arrayMerge = options.arrayMerge || defaultArrayMerge; @@ -192,21 +192,21 @@ function deepMergeObjects< if (!sourceAndTargetTypesMatch) { return cloneUnlessOtherwiseSpecified( source as Record, - options as IOptions + options as IOptions, ) as T; } if (sourceIsArray) { return options.arrayMerge( target as Record[], source as Record[], - options as IOptions + options as IOptions, ) as T; } return mergeObject( target as Record, source, - options as IOptions + options as IOptions, ) as T; } @@ -220,7 +220,7 @@ function deepMergeObjects< */ export function deepMerge>( array: T[], - options?: IDeepMergeOptions + options?: IDeepMergeOptions, ): T { if (!Array.isArray(array)) { throw new Error('first argument should be an array'); diff --git a/libs/automation/nx.json b/libs/automation/nx.json index 832046d4958..a2b00adfb4e 100644 --- a/libs/automation/nx.json +++ b/libs/automation/nx.json @@ -26,12 +26,10 @@ }, "targetDefaults": { "@nx/js:tsc": { - "cache": true, "dependsOn": ["^build"], "inputs": ["production", "^production"] }, "@nx/eslint:lint": { - "cache": true, "inputs": [ "default", "{workspaceRoot}/.eslintrc.json", @@ -40,7 +38,6 @@ ] }, "@nx/jest:jest": { - "cache": true, "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"], "options": { "passWithNoTests": true diff --git a/libs/design-system/.storybook/Doc.container.tsx b/libs/design-system/.storybook/Doc.container.tsx index ae81e24715f..9a13aed2981 100644 --- a/libs/design-system/.storybook/Doc.container.tsx +++ b/libs/design-system/.storybook/Doc.container.tsx @@ -22,7 +22,8 @@ export const DocsContainer = ({ children, context }) => { }, }; }, - }}> + }} + > {children} ); diff --git a/libs/design-system/.storybook/NovuTheme.tsx b/libs/design-system/.storybook/NovuTheme.tsx index d8f509b6114..86a0b5aa71a 100644 --- a/libs/design-system/.storybook/NovuTheme.tsx +++ b/libs/design-system/.storybook/NovuTheme.tsx @@ -5,10 +5,10 @@ const themeBase: ThemeVarsPartial = { base: 'light', brandTitle: 'Novu Design System', brandTarget: '_self', -} +}; /** * Novu Design System theme for Storybook - * + * * @see https://storybook.js.org/docs/configure/theming */ export const lightTheme = create({ diff --git a/libs/design-system/.storybook/manager-head.html b/libs/design-system/.storybook/manager-head.html index 62499dd0581..fed14ea70bf 100644 --- a/libs/design-system/.storybook/manager-head.html +++ b/libs/design-system/.storybook/manager-head.html @@ -1 +1 @@ - + diff --git a/libs/design-system/src/Colors.stories.mdx b/libs/design-system/src/Colors.stories.mdx index ef039a7dea6..791bde7c5f1 100644 --- a/libs/design-system/src/Colors.stories.mdx +++ b/libs/design-system/src/Colors.stories.mdx @@ -1,4 +1,4 @@ -import { Meta, ColorPalette, ColorItem, } from '@storybook/addon-docs'; +import { Meta, ColorPalette, ColorItem } from '@storybook/addon-docs'; import { colors } from './config'; @@ -8,6 +8,28 @@ import { colors } from './config'; - - + + diff --git a/libs/design-system/src/icons/gradient/BellGradient.tsx b/libs/design-system/src/icons/gradient/BellGradient.tsx index 4d21f74338e..e515417ee30 100644 --- a/libs/design-system/src/icons/gradient/BellGradient.tsx +++ b/libs/design-system/src/icons/gradient/BellGradient.tsx @@ -17,7 +17,8 @@ export function BellGradient(props: React.ComponentPropsWithoutRef<'svg'>) { y1="26.4965" x2="15" y2="4.5" - gradientUnits="userSpaceOnUse"> + gradientUnits="userSpaceOnUse" + > diff --git a/libs/design-system/src/icons/gradient/CompassGradient.tsx b/libs/design-system/src/icons/gradient/CompassGradient.tsx index bc53cc30aad..c3b0708e660 100644 --- a/libs/design-system/src/icons/gradient/CompassGradient.tsx +++ b/libs/design-system/src/icons/gradient/CompassGradient.tsx @@ -28,7 +28,8 @@ export function CompassGradient(props: React.ComponentPropsWithoutRef<'svg'>) { y1="20.7999" x2="15.2502" y2="10.2" - gradientUnits="userSpaceOnUse"> + gradientUnits="userSpaceOnUse" + > diff --git a/libs/design-system/src/icons/gradient/GlobeGradient.tsx b/libs/design-system/src/icons/gradient/GlobeGradient.tsx index 6b24967e615..8cfcbd8498b 100644 --- a/libs/design-system/src/icons/gradient/GlobeGradient.tsx +++ b/libs/design-system/src/icons/gradient/GlobeGradient.tsx @@ -35,7 +35,8 @@ export function GlobeGradient(props: React.ComponentPropsWithoutRef<'svg'>) { y1="16.5" x2="15.75" y2="15.5" - gradientUnits="userSpaceOnUse"> + gradientUnits="userSpaceOnUse" + > diff --git a/libs/embed/src/embed.ts b/libs/embed/src/embed.ts index 789ee484437..da18c90171f 100644 --- a/libs/embed/src/embed.ts +++ b/libs/embed/src/embed.ts @@ -363,9 +363,8 @@ class Novu { wrapper.className = 'wrapper-novu-widget'; wrapper.style.display = 'none'; wrapper.id = WEASL_WRAPPER_ID; - ( - wrapper as any - ).style = `z-index: ${Number.MAX_SAFE_INTEGER}; width: 0; height: 0; position: relative; display: none;`; + (wrapper as any).style = + `z-index: ${Number.MAX_SAFE_INTEGER}; width: 0; height: 0; position: relative; display: none;`; wrapper.appendChild(this.iframe); document.body.appendChild(wrapper); } diff --git a/libs/embed/src/shared/helpers.js b/libs/embed/src/shared/helpers.js index 052670231ba..4810b2b95b5 100644 --- a/libs/embed/src/shared/helpers.js +++ b/libs/embed/src/shared/helpers.js @@ -1,8 +1,7 @@ const COOKIE_NAME = 'WEASL_AUTH'; - export const expireToken = (clientId) => { - document.cookie = `${COOKIE_NAME}-${clientId}=;expires=${(new Date()).toUTCString()};`; + document.cookie = `${COOKIE_NAME}-${clientId}=;expires=${new Date().toUTCString()};`; }; export const isMobile = () => window.innerWidth < 600; @@ -10,14 +9,14 @@ export const isTablet = () => window.innerWidth > 600 && window.innerWidth < 768 export const isDesktop = () => window.innerWidth > 768; export const isPortraitMode = () => window.innerHeight > window.innerWidth; -export const allowedAttrTypes = ['STRING', 'NUMBER', 'BOOLEAN', 'JSON'] +export const allowedAttrTypes = ['STRING', 'NUMBER', 'BOOLEAN', 'JSON']; // TODO: use a library for this export const makeDomainMatcher = (actualDomain) => { - const [ actualHost, actualPort ] = actualDomain.split(':'); + const [actualHost, actualPort] = actualDomain.split(':'); const actualDomainParts = actualHost.split('.'); return (allowedDomain) => { - const [ allowedHost, allowedPort ] = allowedDomain.split(':'); + const [allowedHost, allowedPort] = allowedDomain.split(':'); // check the ports first if both are there if (allowedPort && actualPort && allowedPort !== actualPort) { @@ -25,7 +24,12 @@ export const makeDomainMatcher = (actualDomain) => { } const allowedDomainParts = allowedHost.split('.'); - const matched = allowedDomainParts.length && allowedDomainParts.reduceRight((matchedSoFar, part, index) => matchedSoFar && part === actualDomainParts[index], true); + const matched = + allowedDomainParts.length && + allowedDomainParts.reduceRight( + (matchedSoFar, part, index) => matchedSoFar && part === actualDomainParts[index], + true + ); return matched; - } -} \ No newline at end of file + }; +}; diff --git a/libs/embed/src/shared/iframeClasses.js b/libs/embed/src/shared/iframeClasses.js index 947995719a7..7241787160e 100644 --- a/libs/embed/src/shared/iframeClasses.js +++ b/libs/embed/src/shared/iframeClasses.js @@ -1,2 +1,2 @@ export const TAKEOVER_CLASSNAME = 'weasl-iframe-takeover'; -export const INFO_MSG_CLASSNAME = 'weasl-iframe-info-msg'; \ No newline at end of file +export const INFO_MSG_CLASSNAME = 'weasl-iframe-info-msg'; diff --git a/libs/embed/test/index.html b/libs/embed/test/index.html index c88c4fe9b17..bfc04c67bd1 100644 --- a/libs/embed/test/index.html +++ b/libs/embed/test/index.html @@ -21,12 +21,12 @@ } - +

-
-

- Dashboard -

+
+

Dashboard

-
+
-
+
@@ -272,12 +270,12 @@