diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 0c7a9ab6489..00000000000 --- a/.eslintignore +++ /dev/null @@ -1,8 +0,0 @@ -node_modules -dist/ -build/ -coverage/ -bin/ -packages/server/nango-integrations/ -packages/node-client/tests -packages/cli/fixtures/ diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 39cbc9016a1..00000000000 --- a/.eslintrc +++ /dev/null @@ -1,293 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "sourceType": "module", - "ecmaFeatures": { - "impliedStrict": true, - "jsx": true - }, - "project": "tsconfig.json" - }, - "env": { - "es6": true, - "node": true - }, - "plugins": [ - "@typescript-eslint", - "unicorn" - ], - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:@typescript-eslint/recommended-type-checked", - "plugin:@typescript-eslint/strict", - "plugin:@typescript-eslint/strict-type-checked", - "plugin:@typescript-eslint/stylistic", - "plugin:prettier/recommended", - "plugin:import/errors", - "plugin:import/warnings", - "plugin:import/recommended" - ], - "rules": { - "no-console": "warn", - "prettier/prettier": "error", - "@typescript-eslint/no-inferrable-types": "off", - "@typescript-eslint/require-await": "error", - // Previously warn but now errors - "@typescript-eslint/no-non-null-assertion": "warn", - "@typescript-eslint/no-explicit-any": "warn", - // To reenable as error progressively - "@typescript-eslint/no-floating-promises": "warn", - "@typescript-eslint/no-unsafe-assignment": "warn", - "@typescript-eslint/no-unsafe-member-access": "warn", - "@typescript-eslint/no-unsafe-call": "warn", - "@typescript-eslint/no-unsafe-argument": "warn", - "@typescript-eslint/no-misused-promises": "warn", - "@typescript-eslint/no-unsafe-return": "warn", - "@typescript-eslint/no-empty-function": "warn", - "@typescript-eslint/no-unsafe-enum-comparison": "warn", - "@typescript-eslint/restrict-template-expressions": [ - "error", - { - "allowNumber": true, - "allowBoolean": true, - "allowNever": true - } - ], - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/no-invalid-void-type": "warn", - "@typescript-eslint/no-base-to-string": "warn", - "@typescript-eslint/restrict-plus-operands": "warn", - "@typescript-eslint/consistent-type-exports": "error", - "@typescript-eslint/no-unnecessary-condition": "off", // Our types are not good enough right now - "@typescript-eslint/only-throw-error": "warn", - "@typescript-eslint/no-unused-vars": [ - "error", - { - "args": "all", - "argsIgnorePattern": "^_", - "caughtErrors": "all", - "caughtErrorsIgnorePattern": "^_", - "destructuredArrayIgnorePattern": "^_", - "varsIgnorePattern": "^_", - "ignoreRestSiblings": true - } - ], - "@typescript-eslint/consistent-type-imports": [ - "error", - { - "prefer": "type-imports", - "fixStyle": "separate-type-imports" - } - ], - "@typescript-eslint/no-confusing-void-expression": [ - "warn", - { - "ignoreVoidOperator": true, - "ignoreArrowShorthand": true - } - ], - // Import - "import/extensions": [ - "error", - "always", - { - "json": "always", - "js": "always", - "ts": "never", - "ignorePackages": true - } - ], - "import/no-unresolved": "off", - "import/no-duplicates": "error", - "import/no-extraneous-dependencies": "error", - "import/no-empty-named-blocks": "error", - "import/no-absolute-path": "error", - "import/no-self-import": "error", - "import/newline-after-import": "error", - "import/consistent-type-specifier-style": [ - "error", - "prefer-top-level" - ], - "import/namespace": "off", // very slow - // Unicorn - "unicorn/catch-error-name": [ - "error", - { - "name": "err" - } - ] - }, - "overrides": [ - { - "files": [ - "integration-templates/**/*.ts" - ], - "rules": { - "no-constant-condition": "off", - "@typescript-eslint/no-dynamic-delete": "off", - "@typescript-eslint/no-redundant-type-constituents": "off" - } - }, - { - "files": [ - "packages/frontend/**/*.ts" - ], - "env": { - "browser": true, - "es6": true, - "node": false - }, - "parserOptions": { - "ecmaVersion": 2018, - "sourceType": "module", - "ecmaFeatures": { - "impliedStrict": true, - "jsx": false - }, - "project": "packages/frontend/tsconfig.json" - }, - "rules": { - "no-console": "off", - "@typescript-eslint/no-misused-promises": [ - "warn", - { - "checksVoidReturn": { - "arguments": false, - "attributes": false - } - } - ] - } - }, - { - "files": [ - "packages/webapp/**/*.tsx" - ], - "plugins": [ - "react", - "react-hooks" - ], - "extends": [ - "plugin:react-hooks/recommended", - "plugin:react/recommended", - "plugin:react/jsx-runtime", - ], - "env": { - "browser": true, - "es6": true, - "node": false - }, - "parserOptions": { - "ecmaVersion": 2018, - "sourceType": "module", - "ecmaFeatures": { - "impliedStrict": true, - "jsx": true - }, - "project": "packages/webapp/tsconfig.json" - }, - "rules": { - "no-console": "off", - "react/prop-types": "off", - "@typescript-eslint/no-misused-promises": [ - "warn", - { - "checksVoidReturn": { - "arguments": false, - "attributes": false - } - } - ], - // unnecessary when bundling - "import/extensions": "off" - } - }, - { - "files": [ - "packages/connect-ui/**/*.tsx", - "packages/connect-ui/**/*.ts" - ], - "plugins": [ - "react", - "react-hooks" - ], - "extends": [ - "plugin:react-hooks/recommended", - "plugin:react/recommended", - "plugin:react/jsx-runtime", - ], - "env": { - "browser": true, - "es6": true, - "node": false - }, - "parserOptions": { - "ecmaVersion": 2018, - "sourceType": "module", - "ecmaFeatures": { - "impliedStrict": true, - "jsx": true - }, - "project": "packages/connect-ui/tsconfig.json" - }, - "rules": { - // unnecessary when bundling - "import/extensions": "off", - "@typescript-eslint/member-ordering": "error", - "@typescript-eslint/no-non-null-assertion": "error", - "@typescript-eslint/no-explicit-any": "error", - "@typescript-eslint/only-throw-error": "error", - "react/prop-types": "off", - "react/jsx-sort-props": [ - "error", - { - "callbacksLast": true, - "shorthandFirst": true, - "reservedFirst": true - } - ], - "import/order": [ - "error", - { - "groups": [ - "builtin", - "external", - "unknown", - "internal", - "parent", - "sibling", - "type", - "index", - "object" - ], - "newlines-between": "always", - "alphabetize": { - "order": "asc" - }, - "warnOnUnassignedImports": true, - "pathGroups": [ - { - "pattern": "@/**", - "group": "parent" - }, - { - "pattern": "@nangohq/*", - "group": "internal", - "position": "after" - } - ] - } - ] - } - }, - { - "files": "**.test.ts", - "rules": { - "@typescript-eslint/no-unsafe-assignment": "off", - "@typescript-eslint/no-non-null-assertion": "off" - } - } - ] -} diff --git a/.github/workflows/build-image-reusable.yaml b/.github/workflows/build-image-reusable.yaml index 1141937bfb0..857253fb080 100644 --- a/.github/workflows/build-image-reusable.yaml +++ b/.github/workflows/build-image-reusable.yaml @@ -11,12 +11,6 @@ on: name: required: true type: string - key_for_sentry_secret: - required: false - type: string - key_for_posthog_secret: - required: false - type: string jobs: build-container: @@ -50,8 +44,6 @@ jobs: - name: Build image (${{ inputs.name }}) run: | - export SENTRY_KEY=${{ secrets[inputs.key_for_sentry_secret] }} - export POSTHOG_KEY=${{ secrets[inputs.key_for_posthog_secret] }} ./scripts/build_docker.sh build ${{ inputs.name }} ${{ env.SHA }} - name: Push image diff --git a/.github/workflows/build-image.yaml b/.github/workflows/build-image.yaml index 95017accffd..8470b962e35 100644 --- a/.github/workflows/build-image.yaml +++ b/.github/workflows/build-image.yaml @@ -10,26 +10,18 @@ on: jobs: build-image: + # TODO: remove this, it's only needed for the frontend strategy: matrix: group: - name: 'staging' if: true - sentry_key: SENTRY_KEY_staging - name: 'prod' if: ${{ github.ref == 'refs/heads/master' }} - sentry_key: SENTRY_KEY_prod - posthog_key: POSTHOG_KEY_prod - - # Commented for now - # - name: 'enterprise' - # if: ${{ github.ref == 'refs/heads/master' }} secrets: inherit uses: ./.github/workflows/build-image-reusable.yaml with: if: ${{ matrix.group.if }} name: ${{ matrix.group.name }} - key_for_sentry_secret: ${{ matrix.group.sentry_key }} - key_for_posthog_secret: ${{ matrix.group.posthog_key }} diff --git a/.github/workflows/build-images.yaml b/.github/workflows/build-images.yaml index 2f61d6059ee..ea0c0b63a88 100644 --- a/.github/workflows/build-images.yaml +++ b/.github/workflows/build-images.yaml @@ -24,9 +24,8 @@ jobs: secrets: inherit with: package: server - run-cmd: build:staging + run-cmd: build:prod tags: -t nangohq/nango-server:staging-${{ github.event.pull_request.head.sha || github.sha }} - nango-server-prod: if: github.ref == 'refs/heads/master' uses: ./.github/workflows/push-container.yaml @@ -49,5 +48,5 @@ jobs: secrets: inherit with: package: server - run-cmd: build:enterprise + run-cmd: build:prod tags: -t nangohq/nango-server:enterprise -t nangohq/nango-server:enterprise-${{ github.event.pull_request.head.sha || github.sha }} diff --git a/.github/workflows/tests-clients.yaml b/.github/workflows/tests-clients.yaml index 5da1e096c67..814b17eca8e 100644 --- a/.github/workflows/tests-clients.yaml +++ b/.github/workflows/tests-clients.yaml @@ -9,12 +9,26 @@ on: merge_group: jobs: + compute-matrix: + runs-on: ubuntu-latest + outputs: + os-matrix: ${{ steps.set-os-matrix.outputs.os-matrix }} + steps: + - name: Set OS Matrix + id: set-os-matrix + run: | + if [[ '${{ github.ref }}' == 'refs/heads/master' ]]; then + echo "os-matrix=[\"ubuntu-latest\",\"windows-latest\"]" >> $GITHUB_OUTPUT + else + echo "os-matrix=[\"ubuntu-latest\"]" >> $GITHUB_OUTPUT + fi tests: + needs: compute-matrix strategy: fail-fast: false matrix: node-version: [18.x, 20.x, 22.x] - os: [ubuntu-latest, windows-latest] + os: ${{ fromJson(needs.compute-matrix.outputs.os-matrix) }} runs-on: ${{ matrix.os }} diff --git a/Dockerfile b/Dockerfile index 08b593f8e62..6ff513db415 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,15 +54,6 @@ RUN true \ # /!\ Do not set NODE_ENV=production before building, it will break some modules # ENV NODE_ENV=production -ARG image_env -ARG posthog_key -ARG sentry_key - -# TODO: remove the need for this -ENV REACT_APP_ENV $image_env -ENV REACT_APP_PUBLIC_POSTHOG_HOST https://app.posthog.com -ENV REACT_APP_PUBLIC_POSTHOG_KEY $posthog_key -ENV REACT_APP_PUBLIC_SENTRY_KEY $sentry_key # Build the frontend RUN true \ @@ -104,12 +95,10 @@ WORKDIR /app/nango # COPY --from=build --chown=node:node /app/tmp /app/nango COPY --from=build /app/tmp /app/nango -ARG image_env ARG git_hash ENV PORT=8080 ENV NODE_ENV=production -ENV IMAGE_ENV $image_env ENV GIT_HASH $git_hash ENV SERVER_RUN_MODE=DOCKERIZED diff --git a/docker-compose.yaml b/docker-compose.yaml index 969c721bba3..ff422615e4b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -19,29 +19,29 @@ services: container_name: nango-server platform: linux/amd64 environment: - - NANGO_ENCRYPTION_KEY=${NANGO_ENCRYPTION_KEY} - - NANGO_DB_USER=${NANGO_DB_USER} - - NANGO_DB_PASSWORD=${NANGO_DB_PASSWORD} - - NANGO_DB_HOST=${NANGO_DB_HOST} - - NANGO_DB_NAME=${NANGO_DB_NAME} - - NANGO_DB_SSL=${NANGO_DB_SSL} - - NANGO_DB_ADDITIONAL_SCHEMAS=${NANGO_DB_ADDITIONAL_SCHEMAS} - - NANGO_DB_POOL_MIN=${NANGO_DB_POOL_MIN} - - NANGO_DB_POOL_MAX=${NANGO_DB_POOL_MAX} + - NANGO_ENCRYPTION_KEY + - NANGO_DB_USER + - NANGO_DB_PASSWORD + - NANGO_DB_HOST=${NANGO_DB_HOST:-nango-db} + - NANGO_DB_NAME + - NANGO_DB_SSL + - NANGO_DB_ADDITIONAL_SCHEMAS + - NANGO_DB_POOL_MIN + - NANGO_DB_POOL_MAX - RECORDS_DATABASE_URL=${RECORDS_DATABASE_URL:-postgresql://nango:nango@nango-db:5432/nango} - - SERVER_PORT=${SERVER_PORT} + - SERVER_PORT - CSP_REPORT_ONLY=true - NANGO_SERVER_URL=${NANGO_SERVER_URL:-http://localhost:3003} - - FLAG_AUTH_ENABLED=${FLAG_AUTH_ENABLED} - - NANGO_DASHBOARD_USERNAME=${NANGO_DASHBOARD_USERNAME} - - NANGO_DASHBOARD_PASSWORD=${NANGO_DASHBOARD_PASSWORD} + - FLAG_AUTH_ENABLED + - NANGO_DASHBOARD_USERNAME + - NANGO_DASHBOARD_PASSWORD - LOG_LEVEL=${LOG_LEVEL:-info} - - TELEMETRY=${TELEMETRY} - - NANGO_SERVER_WEBSOCKETS_PATH=${NANGO_SERVER_WEBSOCKETS_PATH} + - TELEMETRY + - NANGO_SERVER_WEBSOCKETS_PATH - NANGO_LOGS_ENABLED=${NANGO_LOGS_ENABLED:-false} - NANGO_LOGS_ES_URL=${NANGO_LOGS_ES_URL:-http://nango-elasticsearch:9200} - - NANGO_LOGS_ES_USER=${NANGO_LOGS_ES_USER} - - NANGO_LOGS_ES_PWD=${NANGO_LOGS_ES_PWD} + - NANGO_LOGS_ES_USER + - NANGO_LOGS_ES_PWD - FLAG_SERVE_CONNECT_UI=${FLAG_SERVE_CONNECT_UI:-true} volumes: - './packages/shared/providers.yaml:/usr/nango-server/src/packages/shared/providers.yaml' diff --git a/docs-v2/integrations/all/airtable.mdx b/docs-v2/integrations/all/airtable.mdx index 6558b56d90e..d06d3ae6e9b 100644 --- a/docs-v2/integrations/all/airtable.mdx +++ b/docs-v2/integrations/all/airtable.mdx @@ -35,6 +35,7 @@ _No setup guide yet._ ## Useful links - [Web API docs (their REST API)](https://airtable.com/developers/web/api/introduction) +- [SCIM API docs (their REST SCIM API)](https://airtable.com/developers/web/api/scim-overview) - [List of OAuth scopes](https://airtable.com/developers/web/api/scopes) - [Information on rate limits](https://airtable.com/developers/web/api/rate-limits) diff --git a/docs-v2/integrations/all/chorus.mdx b/docs-v2/integrations/all/chorus.mdx index 9f381f621d5..85f99d66b65 100644 --- a/docs-v2/integrations/all/chorus.mdx +++ b/docs-v2/integrations/all/chorus.mdx @@ -44,4 +44,10 @@ _No setup guide yet._ - Chorus uses `API_KEY` auth mode with `Authorization: Bearer ${apiKey}` in the request header to access different endpoints. - API tokens can be generated for each Chorus user, and is managed via the Personal Settings page within the Chorus application. -Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/chorus.mdx) \ No newline at end of file +Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/chorus.mdx) + +## Going further + + + Guide to connect to Chorus using Connect UI + diff --git a/docs-v2/integrations/all/chorus/connect.mdx b/docs-v2/integrations/all/chorus/connect.mdx new file mode 100644 index 00000000000..de8e8706642 --- /dev/null +++ b/docs-v2/integrations/all/chorus/connect.mdx @@ -0,0 +1,38 @@ +--- +title: Chorus - How do I link my account? +sidebarTitle: Chorus +--- + + +# Overview + +To authenticate with Chorus, you need: +1. **API Key** - Your Chorus API Key + + +This guide will walk you through generating the API Key within Chorus. + + +### Prerequisites: + +- You must have a **Chorus Admin account**. Only Chorus Admins can generate the **API key**. + + +#### Step 1: Generating Your Chorus API Key +1. Log in to your [Chorus account](https://hello.chorus.ai/login). +2. In the navigation menu, click the **Profile** icon, then select **Settings**. +3. In the **Personal Settings** page, scroll down to find **API Access**. +4. Click **Generate API Token**. + +#### Step 2: Enter credentials in the Connect UI + +Once you have the **API Key**: +1. Open the form where you need to authenticate with Chorus. +2. Enter the **API Key** in the designated field. +3. Submit the form, and you should be successfully authenticated. + + + + +You are now connected to Chorus. + \ No newline at end of file diff --git a/docs-v2/integrations/all/chorus/form.png b/docs-v2/integrations/all/chorus/form.png new file mode 100644 index 00000000000..55c168f0a89 Binary files /dev/null and b/docs-v2/integrations/all/chorus/form.png differ diff --git a/docs-v2/integrations/all/findymail.mdx b/docs-v2/integrations/all/findymail.mdx new file mode 100644 index 00000000000..bdb8d517401 --- /dev/null +++ b/docs-v2/integrations/all/findymail.mdx @@ -0,0 +1,47 @@ +--- +title: FindyMail +sidebarTitle: FindyMail +provider: findymail +--- + +import Overview from '/snippets/overview.mdx'; +import PreBuiltTooling from '/snippets/generated/findymail/PreBuiltTooling.mdx'; + +import PreBuiltUseCases from '/snippets/generated/findymail/PreBuiltUseCases.mdx'; + + + + + +## Access requirements + +| Pre-Requisites | Status | Comment | +| ----------------- | ------ | ------- | +| Paid dev account | ❓ | | +| Paid test account | ❓ | | +| Partnership | ❓ | | +| App review | ❓ | | +| Security audit | ❓ | | + +## Setup guide + +_No setup guide yet._ + +Need help getting started? Get help in the [community](https://nango.dev/slack). + + + Contribute improvements to the setup guide by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/findymail.mdx) + + +## Useful links + +- [Generate a FindyMail API key in your FindyMail account](https://findymail.com) +- [FindyMail API Docs](https://findymail.com/api-docs) + +Contribute useful links by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/findymail.mdx) + +## API gotchas + +_No API gotchas yet._ + +Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/findymail.mdx) diff --git a/docs-v2/integrations/all/findymail/connect.mdx b/docs-v2/integrations/all/findymail/connect.mdx new file mode 100644 index 00000000000..6eb61f6d354 --- /dev/null +++ b/docs-v2/integrations/all/findymail/connect.mdx @@ -0,0 +1,35 @@ +--- +title: FindyMail - How do I link my account? +sidebarTitle: FindyMail +--- + +# Overview + +To authenticate with FindyMail, you will need: + +1. **API Key** - A key that is used to identify your FindyMail account. + +This guide will walk you through finding these Keys within FindyMail. + +### Prerequisites: + +- You must have a registered FindyMail account. + +### Instructions: + +#### Step 1: Finding Your API Key + +1. **Log in** to your FindyMail dashboard. +2. Click **API** in the left sidebar. +3. Create a new API key. +4. You can also find your API key at [FindyMail API](https://app.findymail.com/user/api-tokens) + +#### Step 2: Enter API Key in the Connect UI + +Once you have your **API Key**: + +1. Open the form where you need to authenticate with FindyMail. +2. Enter your **API Key** in the designated field. +3. Submit the form, and you should be successfully authenticated. + +You are now connected to FindyMail. diff --git a/docs-v2/integrations/all/freshsales.mdx b/docs-v2/integrations/all/freshsales.mdx index 9f7561f101f..933691d559c 100644 --- a/docs-v2/integrations/all/freshsales.mdx +++ b/docs-v2/integrations/all/freshsales.mdx @@ -46,4 +46,10 @@ _No setup guide yet._ - When creating a connection, you need to add the subdomain as a connection configuration parameter, for example: `nango.auth('freshsales', 'test-connection-id', {params: {subdomain: ''}})`. - Freshsales enforces rate limit on the account level. For more details check [freshsales rate limit](https://support.freshsales.io/en/support/solutions/articles/223406-does-freshsales-have-api-request-limits-for-an-account-) -Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/freshsales.mdx) \ No newline at end of file +Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/freshsales.mdx) + +## Going further + + + Guide to connect to Freshsales using Connect UI + \ No newline at end of file diff --git a/docs-v2/integrations/all/freshsales/api_key.png b/docs-v2/integrations/all/freshsales/api_key.png new file mode 100644 index 00000000000..a73ebf8162f Binary files /dev/null and b/docs-v2/integrations/all/freshsales/api_key.png differ diff --git a/docs-v2/integrations/all/freshsales/connect.mdx b/docs-v2/integrations/all/freshsales/connect.mdx new file mode 100644 index 00000000000..c45263f5031 --- /dev/null +++ b/docs-v2/integrations/all/freshsales/connect.mdx @@ -0,0 +1,39 @@ +--- +title: Freshsales - How do I link my account? +sidebarTitle: Freshsales +--- + + +# Overview + +To authenticate with Freshsales, you need: +1. **API Key** - Your Freshsales API Key. +2. **Freshsales subdomain** - Your unique Freshsales subdomain (e.g., mycompany.freshsales.com). + +This guide will walk you through finding both your **API Key** and **Freshsales subdomain** within Freshsales. + +### Prerequisites: + +- You must have an account with Freshsales. + +#### Step 1: Finding Your Freshsales API Key +1. Login to your **Freshsales** account. Click on your **Profile picture** and select **Personal Settings**. + +2. Click on the **API** tab. Your **API Key** will be displayed in **Your API Key** field. + + + +#### Step 2: Finding Your Freshsales subdomain +1. Login to your **Freshsales** account. On you address bar, The URL will be similar to: `https://mycompany.myfreshworks.com/crm/sales/`. Your subdomain is the text between `https://` and `.myfreshworks.com`, which in this case would be `mycompany`. + +#### Step 3: Enter credentials in the Connect UI + +Once you have your **API Key** and **Freshsales Domain**: +1. Open the form where you need to authenticate with Freshsales. +2. Enter the **API Key** and **Freshsales subdomain** in their designated fields. +3. Submit the form, and you should be successfully authenticated. + + + + +You are now connected to Freshsales. diff --git a/docs-v2/integrations/all/freshsales/form.png b/docs-v2/integrations/all/freshsales/form.png new file mode 100644 index 00000000000..1b046e8eead Binary files /dev/null and b/docs-v2/integrations/all/freshsales/form.png differ diff --git a/docs-v2/integrations/all/freshsales/profile.png b/docs-v2/integrations/all/freshsales/profile.png new file mode 100644 index 00000000000..f3164049cf3 Binary files /dev/null and b/docs-v2/integrations/all/freshsales/profile.png differ diff --git a/docs-v2/integrations/all/freshservice.mdx b/docs-v2/integrations/all/freshservice.mdx index 895be879b25..7f5529eaacd 100644 --- a/docs-v2/integrations/all/freshservice.mdx +++ b/docs-v2/integrations/all/freshservice.mdx @@ -42,3 +42,8 @@ _No setup guide yet._ ## API gotchas Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/freshservice.mdx) + +## Going further + + Guide to connect to Freshservice using Nango Connect UI. + \ No newline at end of file diff --git a/docs-v2/integrations/all/freshservice/api_key.png b/docs-v2/integrations/all/freshservice/api_key.png new file mode 100644 index 00000000000..5600a57a056 Binary files /dev/null and b/docs-v2/integrations/all/freshservice/api_key.png differ diff --git a/docs-v2/integrations/all/freshservice/connect.mdx b/docs-v2/integrations/all/freshservice/connect.mdx new file mode 100644 index 00000000000..5681a650afe --- /dev/null +++ b/docs-v2/integrations/all/freshservice/connect.mdx @@ -0,0 +1,37 @@ +--- +title: Freshservice - How do I link my account? +sidebarTitle: Freshservice +--- + + +# Overview + +To authenticate with Freshservice, you need: +1. **API Key** - Your Freshservice API Key. +2. **Freshservice subdomain** - Your unique Freshservice subdomain (e.g., mycompany.freshservice.com). + +This guide will walk you through finding both your **API Key** and **Freshservice subdomain** within Freshservice. + +### Prerequisites: + +- You must have a Freshservice account with admin privileges. + +#### Step 1: Finding Your Freshservice API Key +1. Login to your **Freshservice** account. Click on your **Profile picture** and select **Personal Settings**. + +2. Your **API Key** will then be available below the **Delegate Approvals** section to your right. + + +#### Step 2: Finding Your Freshservice subdomain +1. Login to your **Freshservice** account. On you address bar, The URL will be similar to: `https://mycompany.freshservice.com`. Your subdomain is the text between `https://` and `.freshservice.com`, which in this case would be `mycompany`. + +#### Step 3: Enter credentials in the Connect UI + +Once you have your **API Key** and **Freshservice Domain**: +1. Open the form where you need to authenticate with Freshservice. +2. Enter the **API Key** and **Freshservice subdomain** in their designated fields. +3. Submit the form, and you should be successfully authenticated. + + + +You are now connected to Freshservice. diff --git a/docs-v2/integrations/all/freshservice/form.png b/docs-v2/integrations/all/freshservice/form.png new file mode 100644 index 00000000000..10b77180500 Binary files /dev/null and b/docs-v2/integrations/all/freshservice/form.png differ diff --git a/docs-v2/integrations/all/freshservice/profile.png b/docs-v2/integrations/all/freshservice/profile.png new file mode 100644 index 00000000000..daca82f0225 Binary files /dev/null and b/docs-v2/integrations/all/freshservice/profile.png differ diff --git a/docs-v2/integrations/all/gainsight-cc.mdx b/docs-v2/integrations/all/gainsight-cc.mdx index 19e54da306d..0bebabff936 100644 --- a/docs-v2/integrations/all/gainsight-cc.mdx +++ b/docs-v2/integrations/all/gainsight-cc.mdx @@ -45,3 +45,9 @@ _No setup guide yet._ - To view the list of scopes for a given endpoint, please refer to the Authorizations section of that endpoint. - When creating a new connection in Nango, please provide your `region`. You can find this under `API access information` in Control. Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/gainsight-cc.mdx) + +## Going further + + + Guide to connect to Gainsight CC using Connect UI + diff --git a/docs-v2/integrations/all/gainsight-cc/api-credentials.png b/docs-v2/integrations/all/gainsight-cc/api-credentials.png new file mode 100644 index 00000000000..a6c10ee6147 Binary files /dev/null and b/docs-v2/integrations/all/gainsight-cc/api-credentials.png differ diff --git a/docs-v2/integrations/all/gainsight-cc/connect.mdx b/docs-v2/integrations/all/gainsight-cc/connect.mdx new file mode 100644 index 00000000000..e96445e3a1e --- /dev/null +++ b/docs-v2/integrations/all/gainsight-cc/connect.mdx @@ -0,0 +1,43 @@ +--- +title: Gainsight CC - How do I link my account? +sidebarTitle: Gainsight CC +--- + + +# Overview + +To authenticate with Gainsight CC, you need: +1. **Client ID** - A unique identifier for your client. +2. **Client Secret** - A confidential key used to authenticate the identity of the application (client). +3. **Region** - The specific Gainsight CC region where your data resides. + +This guide will walk you through obtaining these credentials within Gainsight CC. + +### Prerequisites: + +- You must have an account with Gainsight CC. + +### Instructions: + +#### Step 1: Generating API credentials +1. Login to your Gainsight CC account. +2. Navigate to **Integrations** and select **API**. +3. In the **OAuth2** section, add a name in the **Label** field and click the **Create an OAuth2 client**. A pair of API credentials will be generated for you. + + +#### Step 2: Finding your region +1. Within the **API** section in the **Integrations** section, head to the **API access information** area. Your **Region** will be displayed there. + + +#### Step 3: Enter credentials in the Connect UI + +Once you have the **Client ID**, **Client Secret** and **Region**: +1. Open the form where you need to authenticate with Gainsight CC. +2. Enter the **Client ID**, **Client Secret** and **Region** in their designated fields. +3. Submit the form, and you should be successfully authenticated. + + + + +You are now connected to Gainsight CC. + \ No newline at end of file diff --git a/docs-v2/integrations/all/gainsight-cc/form.png b/docs-v2/integrations/all/gainsight-cc/form.png new file mode 100644 index 00000000000..0dd27a65d8a Binary files /dev/null and b/docs-v2/integrations/all/gainsight-cc/form.png differ diff --git a/docs-v2/integrations/all/gainsight-cc/region.png b/docs-v2/integrations/all/gainsight-cc/region.png new file mode 100644 index 00000000000..64c72465e23 Binary files /dev/null and b/docs-v2/integrations/all/gainsight-cc/region.png differ diff --git a/docs-v2/integrations/all/gong.mdx b/docs-v2/integrations/all/gong.mdx index 1eb0724951f..c8820db4077 100644 --- a/docs-v2/integrations/all/gong.mdx +++ b/docs-v2/integrations/all/gong.mdx @@ -41,6 +41,8 @@ Gong offers both Basic auth (API key) and OAuth as authentication. Nango impleme - [API Docs](https://app.gong.io/settings/api/documentation#overview) - [Oauth-related docs](https://help.gong.io/hc/en-us/articles/13944551222157-Create-an-app-for-Gong) - [API rate limiting](https://app.gong.io/settings/api/documentation#overview) +- [SCIM API Docs](https://help.gong.io/docs/provision-team-members-from-a-custom-source-scim) +- [Retrieve Access Key and Access Key Secret](https://help.gong.io/docs/receive-access-to-the-api) Contribute useful links by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/gong.mdx) @@ -54,6 +56,6 @@ Gong offers both Basic auth (API key) and OAuth as authentication. Nango impleme Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/gong.mdx) - + Guide to connect to Gong API using Nango Connect. diff --git a/docs-v2/integrations/all/gong/connect.mdx b/docs-v2/integrations/all/gong/connect.mdx index 779ff910555..8670f13f363 100644 --- a/docs-v2/integrations/all/gong/connect.mdx +++ b/docs-v2/integrations/all/gong/connect.mdx @@ -14,7 +14,7 @@ This guide will walk you through finding or creating those credentials within Go ### Prerequisites: -- You must set up an account with Gong. +- You must set up an administrator account with Gong. #### Step 1: Finding Gong API Key and API Key Secret 1. Log into your Gong account and navigate to `Company Settings` > `Ecosystem` > `API` and click `Create` to generate the access key and the access key secret. diff --git a/docs-v2/integrations/all/guru.mdx b/docs-v2/integrations/all/guru.mdx index 4f40a3a12e8..4b267106192 100644 --- a/docs-v2/integrations/all/guru.mdx +++ b/docs-v2/integrations/all/guru.mdx @@ -34,7 +34,7 @@ _No setup guide yet._ ## Useful links -- [Where can I find my API key?](https://help.getguru.com/articles/cj9Rrj7i/How-to-obtain-your-API-Credentials) +- [How to obtain your API credentials](https://help.getguru.com/docs/gurus-api#:~:text=Navigate%20to%20the%20Apps%20%26%20Integrations,Token%20and%20entering%20your%20name) - [Guru API Docs](https://developer.getguru.com/reference/authentication) Contribute useful links by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/guru.mdx) @@ -45,3 +45,10 @@ _No setup guide yet._ Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/guru.mdx) + +## Going further + + + Guide to connect to Guru using Connect UI + + diff --git a/docs-v2/integrations/all/guru/api_integrations.png b/docs-v2/integrations/all/guru/api_integrations.png new file mode 100644 index 00000000000..725a2208d8b Binary files /dev/null and b/docs-v2/integrations/all/guru/api_integrations.png differ diff --git a/docs-v2/integrations/all/guru/api_token.png b/docs-v2/integrations/all/guru/api_token.png new file mode 100644 index 00000000000..6e9fead95f2 Binary files /dev/null and b/docs-v2/integrations/all/guru/api_token.png differ diff --git a/docs-v2/integrations/all/guru/collection_token.png b/docs-v2/integrations/all/guru/collection_token.png new file mode 100644 index 00000000000..db639d3850c Binary files /dev/null and b/docs-v2/integrations/all/guru/collection_token.png differ diff --git a/docs-v2/integrations/all/guru/connect.mdx b/docs-v2/integrations/all/guru/connect.mdx new file mode 100644 index 00000000000..ee574600754 --- /dev/null +++ b/docs-v2/integrations/all/guru/connect.mdx @@ -0,0 +1,64 @@ +--- +title: Guru - How do I link my account? +sidebarTitle: Guru +--- + + +# Overview + +To authenticate with Guru, you will need: +1. **User/Collection ID** - The user or collection ID of your Guru account. +2. **User/Collection Token** - The user or collection token of your Guru account. + +This guide will walk you through finding the **User/Collection ID** and generating your **User/Collection Token** within Guru. + +### Prerequisites: + +- You must have an account with Guru. + +### Instructions: + +#### Step 1: Finding your User/Collection ID +a. Finding your User ID +- Your **User ID** is the username you use to sign in to your account. + +b. Finding your Collection ID +- You can obtain your **Collection ID** by perfoming a curl request with your **USER ID and Token** to get a [list of all collections](https://developer.getguru.com/reference/getv1collectionsgetcollections) on your team. + +``` +curl -u USER:TOKEN https://api.getguru.com/api/v1/collections -D - +``` + +- If your credentials are correct, you will receive a list of collections along with their IDs, which you can use as your Collection ID. + +#### Step 2: Generating Your User/Collection token +- There are two types of tokens for using the Guru API: a `Collection token` (read-only), and a `User token` (read/write). This guide will demonstrate how to obtain both. + +a. Generating your User token +1. Login to your [Guru](https://app.getguru.com/) account. +2. Navigate to the [Apps & Integrations](https://app.getguru.com/manage/integrations/apps) page under the **Manage** menu. + +3. Click on the [API Access](https://app.getguru.com/settings/integrations/api-access) tab to manage your tokens. +4. Generate an API token for yourself by selecting **Generate User Token** and entering your name. You can also generate API tokens for your teammates by selecting **Generate a new user token**. + + +4. You can reissue a token using the **circular arrow icon** on the right side of the dashboard next to the corresponding user. You can also revoke a user's token using the **trash can icon**. + +b. Generating your Collection token +1. You can also generate Collection-based read-only tokens by selecting **Generate a New Collection Token** and then selecting your desired Collection from the dropdown. + + + + + +#### Step 3: Enter credentials in the Connect UI + +Once you have your **User/Collection ID** and **User/Collection Token**: +1. Open the form where you need to authenticate with Guru. +2. Enter the **User/Collection ID** and **User/Collection Token** in their respective fields. +3. Submit the form, and you should be successfully authenticated. + + + + +You are now connected to Guru. diff --git a/docs-v2/integrations/all/guru/form.png b/docs-v2/integrations/all/guru/form.png new file mode 100644 index 00000000000..16bb3aa4555 Binary files /dev/null and b/docs-v2/integrations/all/guru/form.png differ diff --git a/docs-v2/integrations/all/guru/generate_collection_token.png b/docs-v2/integrations/all/guru/generate_collection_token.png new file mode 100644 index 00000000000..156ee6e590e Binary files /dev/null and b/docs-v2/integrations/all/guru/generate_collection_token.png differ diff --git a/docs-v2/integrations/all/guru/generate_user_token.png b/docs-v2/integrations/all/guru/generate_user_token.png new file mode 100644 index 00000000000..b7ce840c0af Binary files /dev/null and b/docs-v2/integrations/all/guru/generate_user_token.png differ diff --git a/docs-v2/integrations/all/lagrowthmachine.mdx b/docs-v2/integrations/all/lagrowthmachine.mdx new file mode 100644 index 00000000000..f29755e60d0 --- /dev/null +++ b/docs-v2/integrations/all/lagrowthmachine.mdx @@ -0,0 +1,47 @@ +--- +title: La Growth Machine +sidebarTitle: La Growth Machine +provider: lagrowthmachine +--- + +import Overview from '/snippets/overview.mdx'; +import PreBuiltTooling from '/snippets/generated/lagrowthmachine/PreBuiltTooling.mdx'; + +import PreBuiltUseCases from '/snippets/generated/lagrowthmachine/PreBuiltUseCases.mdx'; + + + + + +## Access requirements + +| Pre-Requisites | Status | Comment | +| ----------------- | ------ | ------- | +| Paid dev account | ❓ | | +| Paid test account | ❓ | | +| Partnership | ❓ | | +| App review | ❓ | | +| Security audit | ❓ | | + +## Setup guide + +_No setup guide yet._ + +Need help getting started? Get help in the [community](https://nango.dev/slack). + + + Contribute improvements to the setup guide by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/lagrowthmachine.mdx) + + +## Useful links + +- [Generate a La Growth Machine API key in your La Growth Machine account](https://lagrowthmachine.com/) +- [La Growth Machine API Docs](https://documenter.getpostman.com/view/2071164/TVCmSkH2) + +Contribute useful links by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/lagrowthmachine.mdx) + +## API gotchas + +_No API gotchas yet._ + +Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/lagrowthmachine.mdx) diff --git a/docs-v2/integrations/all/lagrowthmachine/connect.mdx b/docs-v2/integrations/all/lagrowthmachine/connect.mdx new file mode 100644 index 00000000000..1609eabc559 --- /dev/null +++ b/docs-v2/integrations/all/lagrowthmachine/connect.mdx @@ -0,0 +1,35 @@ +--- +title: La Growth Machine - How do I link my account? +sidebarTitle: La Growth Machine +--- + +# Overview + +To authenticate with La Growth Machine, you will need: + +1. **API Key** - A key that is used to identify your La Growth Machine account. + +This guide will walk you through finding these Keys within La Growth Machine. + +### Prerequisites: + +- You must have a registered La Growth Machine account. + +### Instructions: + +#### Step 1: Finding Your API Key + +1. **Log in** to your La Growth Machine dashboard. +2. Open the **Settings** menu and click **Integrations & API**. +3. You will see your API key in the **Your API Key** field. +4. You can also find your API key at [La Growth Machine API Settings](https://app.lagrowthmachine.com/settings/api) + +#### Step 2: Enter API Key in the Connect UI + +Once you have your **API Key**: + +1. Open the form where you need to authenticate with La Growth Machine. +2. Enter your **API Key** in the designated field. +3. Submit the form, and you should be successfully authenticated. + +You are now connected to La Growth Machine. diff --git a/docs-v2/integrations/all/sap-success-factors.mdx b/docs-v2/integrations/all/sap-success-factors.mdx index ec51cc5fde3..71f345a0b69 100644 --- a/docs-v2/integrations/all/sap-success-factors.mdx +++ b/docs-v2/integrations/all/sap-success-factors.mdx @@ -7,7 +7,7 @@ provider: sap-success-factors import Overview from "/snippets/overview.mdx"; import PreBuiltUseCases from "/snippets/generated/sap-success-factors/PreBuiltUseCases.mdx" -import PreBuiltUseCases from "/snippets/generated/sap-success-factors/PreBuiltTooling.mdx" +import PreBuiltTooling from "/snippets/generated/sap-success-factors/PreBuiltTooling.mdx" diff --git a/docs-v2/integrations/all/scrapedo.mdx b/docs-v2/integrations/all/scrapedo.mdx new file mode 100644 index 00000000000..f096d77e288 --- /dev/null +++ b/docs-v2/integrations/all/scrapedo.mdx @@ -0,0 +1,54 @@ +--- +title: Scrape.do +sidebarTitle: Scrape.do +provider: scrapedo +--- + +import Overview from "/snippets/overview.mdx"; +import PreBuiltTooling from "/snippets/generated/scrapedo/PreBuiltTooling.mdx"; + +import PreBuiltUseCases from "/snippets/generated/scrapedo/PreBuiltUseCases.mdx" + + + + + +## Access requirements +| Pre-Requisites | Status | Comment| +| - | - | - | +| Paid dev account | ❓ | | +| Paid test account | ❓ | | +| Partnership | ❓ | | +| App review | ❓ | | +| Security audit | ❓ | | + + +## Setup guide + +_No setup guide yet._ + +Need help getting started? Get help in the [community](https://nango.dev/slack). + +Contribute improvements to the setup guide by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/scrapedo.mdx) + + +## Useful links + +- [How to generate an API Token in your Scrape.do account](https://dashboard.scrape.do/signup) +- [Scrape.do API docs](https://scrape.do/documentation/#quick-start) +- [Scrape.do Authentication](https://scrape.do/documentation/#token) +- [Frequently Asked Technical Questions](https://scrape.do/documentation/#frequently-asked-technical-questions) + +Contribute useful links by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/scrapedo.mdx) + +## API gotchas + +_No API gotchas yet._ + +Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/scrapedo.mdx) + +## Going further + + + Guide to connect to Scrape.do using Connect UI + diff --git a/docs-v2/integrations/all/scrapedo/connect.mdx b/docs-v2/integrations/all/scrapedo/connect.mdx new file mode 100644 index 00000000000..8505bb8a206 --- /dev/null +++ b/docs-v2/integrations/all/scrapedo/connect.mdx @@ -0,0 +1,34 @@ +--- +title: Scrape.do - How do I link my account? +sidebarTitle: Scrape.do +--- + +# Overview + +To authenticate with Scrape.do, you will need: + +1. **API Token** - A key that is used to identify your Scrape.do account. + +This guide will walk you through finding these Keys within Scrape.do. + +### Prerequisites: + +- You must have a registered Scrape.do account. + +### Instructions: + +#### Step 1: Finding Your API Token + +1. **Log in** to your Scrape.do dashboard. +2. Open the **Dashboard** menu. +3. You will see your API Token in the **Quick Start** field. + +#### Step 2: Enter API Token in the Connect UI + +Once you have your **API Token**: + +1. Open the form where you need to authenticate with Scrape.do. +2. Enter your **API Token** in the designated field. +3. Submit the form, and you should be successfully authenticated. + +You are now connected to Scrape.do. diff --git a/docs-v2/integrations/all/sendgrid.mdx b/docs-v2/integrations/all/sendgrid.mdx index c34813eb3c8..50c95c5494b 100644 --- a/docs-v2/integrations/all/sendgrid.mdx +++ b/docs-v2/integrations/all/sendgrid.mdx @@ -1,6 +1,6 @@ --- -title: Sendgrid -sidebarTitle: Sendgrid +title: SendGrid +sidebarTitle: SendGrid provider: sendgrid --- @@ -34,7 +34,7 @@ _No setup guide yet._ ## Useful links -- [Generate an API key in your Sendgrid account](https://app.sendgrid.com/settings/api_keys) +- [Generate an API key in your SendGrid account](https://app.sendgrid.com/settings/api_keys) - [API docs](https://docs.sendgrid.com/api-reference/how-to-use-the-sendgrid-v3-api/authentication) - [Auth-related docs](https://docs.sendgrid.com/api-reference/how-to-use-the-sendgrid-v3-api/authentication#authorization-header) @@ -43,3 +43,8 @@ _No setup guide yet._ ## API gotchas Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/sendgrid.mdx) + +## Going further + + Guide to connect to SendGrid using Nango Connect UI. + diff --git a/docs-v2/integrations/all/sendgrid/connect.mdx b/docs-v2/integrations/all/sendgrid/connect.mdx new file mode 100644 index 00000000000..558cc4f06a8 --- /dev/null +++ b/docs-v2/integrations/all/sendgrid/connect.mdx @@ -0,0 +1,38 @@ +--- +title: SendGrid - How do I link my account? +sidebarTitle: SendGrid +--- + + +# Overview + +To authenticate with SendGrid, you need: +1. **API Key** - Your SendGrid API Key. + +This guide will walk you through finding your **API Key** within SendGrid. + +### Prerequisites: + +- You must have a verified SendGrid account. After signing up, the SendGrid team will manually review and activate your account. + + +#### Step 1: Generating Your SendGrid API Key +1. Login to your **SendGrid** account. Navigate to **Settings** on the left navigation bar, and then select **API Keys**. +2. Click **Create API Key**. +3. Give your API key a name. +4. Select **Full Access**, **Restricted Access**, or **Billing Access**. +5. If you're selecting **Restricted Access**, or **Billing Access**, select the specific permissions to give each category. For more information, see [API key permissions](https://www.twilio.com/docs/sendgrid/ui/account-and-settings/api-keys#api-key-permissions). +6. Click **Create & View**. Your **API Key** will be displayed. + +#### Step 2: Enter credentials in the Connect UI + +Once you have your **API Key**: +1. Open the form where you need to authenticate with SendGrid. +2. Enter the **API Key** in the designated field. +3. Submit the form, and you should be successfully authenticated. + + + + +You are now connected to SendGrid. + \ No newline at end of file diff --git a/docs-v2/integrations/all/sendgrid/form.png b/docs-v2/integrations/all/sendgrid/form.png new file mode 100644 index 00000000000..f5f81861608 Binary files /dev/null and b/docs-v2/integrations/all/sendgrid/form.png differ diff --git a/docs-v2/integrations/all/sharepoint-online-v1/add_cert.png b/docs-v2/integrations/all/sharepoint-online-v1/add_cert.png new file mode 100644 index 00000000000..508bf82667e Binary files /dev/null and b/docs-v2/integrations/all/sharepoint-online-v1/add_cert.png differ diff --git a/docs-v2/integrations/all/sharepoint-online-v1/app_registration.png b/docs-v2/integrations/all/sharepoint-online-v1/app_registration.png new file mode 100644 index 00000000000..46579825a36 Binary files /dev/null and b/docs-v2/integrations/all/sharepoint-online-v1/app_registration.png differ diff --git a/docs-v2/integrations/all/sharepoint-online-v1/client_id.png b/docs-v2/integrations/all/sharepoint-online-v1/client_id.png new file mode 100644 index 00000000000..47730e5f7f6 Binary files /dev/null and b/docs-v2/integrations/all/sharepoint-online-v1/client_id.png differ diff --git a/docs-v2/integrations/all/sharepoint-online-v1/connect.mdx b/docs-v2/integrations/all/sharepoint-online-v1/connect.mdx new file mode 100644 index 00000000000..a0caf7cdf6e --- /dev/null +++ b/docs-v2/integrations/all/sharepoint-online-v1/connect.mdx @@ -0,0 +1,172 @@ +--- +title: SharePoint Online (v1) - How do I link my account? +sidebarTitle: SharePoint Online (v1) +--- + + +# Overview + +To authenticate with SharePoint Online (v1), you need: +1. **Tenant ID** - The unique identifier for your organization that uses Microsoft services. +2. **Tenant Name** - The initial domain name for your Microsoft services tenant. +3. **Client ID** - The unique identifier that Azure assigns to your application when it's registered. +4. **Client Assertion** - A unique string that enables client applications to access Azure resources without requiring users to provide their credentials. + +This guide will walk you through generating and finding these credentials within Azure. + +### Prerequisites: + +- You must have an Azure account with an active SharePoint subscription. + +### Instructions: + +#### Step 1: Finding your Tenant ID +1. Your Tenant ID can be found in the **Tenant ID** field on the [Overview page](https://aad.portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/Overview). + + +#### Step 2: Finding your Tenant Name +1. Your Tenant Name can be found in the **Primary domain** field on the [Overview page](https://aad.portal.azure.com/#view/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/~/Overview). It is the text that appears before `onmicrosoft.com`. For example, if the primary domain is `mycompany.onmicrosoft.com`, the **Tenant Name** would be `mycompany`. + + +#### Step 3: Finding your Client ID +1. Navigate to the [Azure portal home page](https://portal.azure.com/#home) and sign in using the credentials of an administrator. +2. Select **App registrations**. + +3. Select **New registration**. + +4. In the **Register an application** section, enter a meaningful application name to display to users. Select who can use this application based on your environment and click **Register**. + +5. Once you have registered your application, your **Client ID** will be displayed in the **Application (client) ID** field within the **Essentials**. + + +#### Step 4: Generating your Client Assertion +- After successfully registering your application in [Step 3: Finding your Client ID](#step-3-finding-your-client-id), the next step is to generate a client assertion for the registered application. To do this, you must first create a private key and a certificate for your application. This guide will walk you through generating these locally. +1. Run the following command to generate a 2048-bit RSA private key: + +``` +openssl genpkey -algorithm RSA -out private.key -pkeyopt rsa_keygen_bits:2048 +``` +2. Run the following to create a CSR based on the private key generated above: +``` +openssl req -new -key private.key -out csr.csr +``` +- You will be prompted to enter information such as country, organization, and Common Name (CN). Make sure that the CN matches the identity of your application. +3. Use the CSR to create a self-signed certificate: +``` +openssl req -x509 -key private.key -in csr.csr -out certificate.crt -days 3650 +``` +- This will generate a **.crt** certificate that is valid for 10 years. +4. To convert the certificate and private key to **PEM** format: +``` +openssl pkcs12 -export -out certificate.pem -inkey private.key -in certificate.crt +``` +5. Once the above certificate is generated, navigate to **App registrations** and select your above registered application. +6. Under the **Client credentials** section, click **Add a certificate or Secret**. + + + +7. Choose the **.crt** certificate file you generated above and upload it. + + +- After uploading, the **thumbprint** and certificate details will appear in the portal. +8. Now that your certificate is registered with Microsoft, you need to generate a JWT **Client Assertion** using the private key and the certificate's thumbprint. You can use the code from the following script to generate the JWT. +``` +import { readFileSync } from 'fs'; +import { execSync } from 'child_process'; +import jwt from 'jsonwebtoken'; +import readlineSync from 'readline-sync'; + +const getUserInput = () => { + const tenantId = readlineSync.question('Please enter your tenant ID: '); + const clientId = readlineSync.question('Please enter your client ID: '); + return { tenantId, clientId }; +}; + +const readPrivateKey = (path) => { + try { + return readFileSync(path, 'utf8'); + } catch (error) { + console.error(`Error reading private key from ${path}:`, error); + throw error; + } +}; + +const getX5tThumbprint = (certPath) => { + const command = `echo $(openssl x509 -in ${certPath} -fingerprint -noout) | sed 's/SHA1 Fingerprint=//g' | sed 's/://g' | xxd -r -ps | base64`; + + try { + const thumbprint = execSync(command).toString().trim(); + return thumbprint; + } catch (error) { + console.error(`Error calculating x5t thumbprint for certificate ${certPath}:`, error); + throw error; + } +}; + +const TEN_YEARS_MS = 10 * 365 * 24 * 60 * 60 * 1000; + +// Microsoft Entra ID doesn't place restrictions on the exp time currently. +const createJwtClaims = (tenantId, clientId, expirationInSeconds = TEN_YEARS_MS) => ({ + aud: `https://login.microsoftonline.com/${tenantId}/oauth2/token`, + iss: clientId, + sub: clientId, + nbf: Math.floor(Date.now() / 1000), + exp: Math.floor(Date.now() / 1000) + expirationInSeconds, + jti: generateUniqueJti(), +}); + +const generateUniqueJti = () => `jti-${Math.random().toString(36).substr(2, 9)}`; + +const createJwt = (claims, privateKey, x5tThumbprint) => { + const header = { + alg: "PS256", + typ: "JWT", + x5t: x5tThumbprint, + }; + + try { + return jwt.sign(claims, privateKey, { + algorithm: 'RS256', + header: header, + }); + } catch (error) { + console.error('Error signing JWT:', error); + throw error; + } +}; + +const generateJwtAssertion = () => { + const { tenantId, clientId } = getUserInput(); + const certPath = 'certificate.pem'; + const privateKeyPath = 'private.key'; + + const privateKey = readPrivateKey(privateKeyPath); + const x5tThumbprint = getX5tThumbprint(certPath); + + console.log('Calculated x5t Thumbprint:', x5tThumbprint); + + const claims = createJwtClaims(tenantId, clientId); + + const token = createJwt(claims, privateKey, x5tThumbprint); + + console.log('JWT Assertion:', token); +}; + +generateJwtAssertion(); + + +``` +- Run the script above in the same directory where your certificates were generated. It will prompt you for your **Client ID**, **Tenant ID**, and the **Password** set during the certificate generation process. A JWT **Client Assertion** will then be generated. + +**Note**: The generated **Client Assertion** is valid for ten years. After this period, you will need to regenerate the assertion and reauthenticate. + +Once you have your credentials: +1. Open the form where you need to authenticate with SharePoint Online (v1). +2. Enter the **Tenant ID**, **Tenant Name**, **Client ID** and **Client Assertion** in their designated fields. +3. Submit the form, and you should be successfully authenticated. + + + + +You are now connected to SharePoint Online (v1). + \ No newline at end of file diff --git a/docs-v2/integrations/all/sharepoint-online-v1/form.png b/docs-v2/integrations/all/sharepoint-online-v1/form.png new file mode 100644 index 00000000000..da59d103417 Binary files /dev/null and b/docs-v2/integrations/all/sharepoint-online-v1/form.png differ diff --git a/docs-v2/integrations/all/sharepoint-online-v1/new_registration.png b/docs-v2/integrations/all/sharepoint-online-v1/new_registration.png new file mode 100644 index 00000000000..54e96e421b2 Binary files /dev/null and b/docs-v2/integrations/all/sharepoint-online-v1/new_registration.png differ diff --git a/docs-v2/integrations/all/sharepoint-online-v1/register_new_app.png b/docs-v2/integrations/all/sharepoint-online-v1/register_new_app.png new file mode 100644 index 00000000000..8dff5d9b145 Binary files /dev/null and b/docs-v2/integrations/all/sharepoint-online-v1/register_new_app.png differ diff --git a/docs-v2/integrations/all/sharepoint-online-v1/tenant_id.png b/docs-v2/integrations/all/sharepoint-online-v1/tenant_id.png new file mode 100644 index 00000000000..cda07c7d5ec Binary files /dev/null and b/docs-v2/integrations/all/sharepoint-online-v1/tenant_id.png differ diff --git a/docs-v2/integrations/all/sharepoint-online-v1/tenant_name.png b/docs-v2/integrations/all/sharepoint-online-v1/tenant_name.png new file mode 100644 index 00000000000..668f9a8c383 Binary files /dev/null and b/docs-v2/integrations/all/sharepoint-online-v1/tenant_name.png differ diff --git a/docs-v2/integrations/all/sharepoint-online-v1/upload_cert.png b/docs-v2/integrations/all/sharepoint-online-v1/upload_cert.png new file mode 100644 index 00000000000..a5ffde52468 Binary files /dev/null and b/docs-v2/integrations/all/sharepoint-online-v1/upload_cert.png differ diff --git a/docs-v2/integrations/all/sharepoint-online.mdx b/docs-v2/integrations/all/sharepoint-online.mdx index 1c69327fbd2..92789013c21 100644 --- a/docs-v2/integrations/all/sharepoint-online.mdx +++ b/docs-v2/integrations/all/sharepoint-online.mdx @@ -46,3 +46,8 @@ _No setup guide yet._ - You can find permissions required for each API call in their corresponding API methods section. Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/sharepoint-online.mdx) + +## Going further + + Guide to connect to SharePoint Online (v1) using Nango Connect UI. + \ No newline at end of file diff --git a/docs-v2/integrations/all/shopify-api-key/admin_api_access_token.png b/docs-v2/integrations/all/shopify-api-key/admin_api_access_token.png new file mode 100644 index 00000000000..7fe8b90b53d Binary files /dev/null and b/docs-v2/integrations/all/shopify-api-key/admin_api_access_token.png differ diff --git a/docs-v2/integrations/all/shopify-api-key/connect.mdx b/docs-v2/integrations/all/shopify-api-key/connect.mdx new file mode 100644 index 00000000000..c025cbe2ff0 --- /dev/null +++ b/docs-v2/integrations/all/shopify-api-key/connect.mdx @@ -0,0 +1,63 @@ +--- +title: Shopify (api key) - How do I link my account? +sidebarTitle: Shopify (api key) +--- + + +# Overview + +To authenticate with Shopify, you will need: +1. **Shopify Domain** - The domain associated with your Shopify account. +2. **API Access Token** - The API access token generated after installing an app in your Shopify store. + +This guide will walk you through finding your **Shopify Domain** and generating your **API Access Token** within Shopify. + +### Prerequisites: + +- You must have an account with Shopify. +- Custom app development must be activated in your Shopify admin account. + +### Instructions: + +#### Step 1: Finding your Shopify Domain +1. Sign in to your [Shopify](https://www.shopify.com/) account. +2. Your **Shopify Domain** is the text found after the URL of your store in the address bar. For example, in `https://admin.shopify.com/store/6nzh0y-y6`, the domain is `6nzh0y-y6`. +3. You can also click on your profile in the top right corner, then select **All Stores** to view the list of stores associated with your account. + +4. From the displayed list, your **Shopify Domain** is the value before `myshopify.com`. + + + + + +#### Step 2: Generating Your API Access Token +- After you've [activated custom app development](https://help.shopify.com/en/manual/apps/app-types/custom-apps#enable-custom-app-development), you can create and install a custom app in your Shopify admin. + +1. From your Shopify admin, go to **Settings** > [Apps and sales channels](https://admin.shopify.com/settings/apps). +2. Click **Develop apps**. + +3. Click **Create a custom app**. +4. In the modal window, enter the **App name** and select an **App developer**. The app developer can be the store owner, or any staff or collaborator account with the **Develop apps** permission. + +5. Click **Create app**. +- After you create a custom app, you can assign API scopes to it. A custom app can have **Admin API** scopes, **Storefront API** scopes, or both, depending on the requirements of the app. You need to select at least one scope before you install the app. +6. In the **Overview** tab, select at least a single scope from either **Admin** or **Storefront** API scopes, or both, depending on the app's requirements. + +7. Click **Install app**. +8. In the modal window, click **Install**. + +9. Once your custom app is installed, your **API Access Token** will be generated. + + + +#### Step 3: Enter credentials in the Connect UI + +Once you have your **Shopify Domain** and **API Access Token**: +1. Open the form where you need to authenticate with Shopify (api key). +2. Enter the **Shopify Domain** and **API Access Token** in their respective fields. +3. Submit the form, and you should be successfully authenticated. + + + + +You are now connected to Shopify (api key). diff --git a/docs-v2/integrations/all/shopify-api-key/create_app_modal.png b/docs-v2/integrations/all/shopify-api-key/create_app_modal.png new file mode 100644 index 00000000000..0dc73c86b18 Binary files /dev/null and b/docs-v2/integrations/all/shopify-api-key/create_app_modal.png differ diff --git a/docs-v2/integrations/all/shopify-api-key/develop_apps.png b/docs-v2/integrations/all/shopify-api-key/develop_apps.png new file mode 100644 index 00000000000..c490c19e5ce Binary files /dev/null and b/docs-v2/integrations/all/shopify-api-key/develop_apps.png differ diff --git a/docs-v2/integrations/all/shopify-api-key/form.png b/docs-v2/integrations/all/shopify-api-key/form.png new file mode 100644 index 00000000000..ed33c9a6fb3 Binary files /dev/null and b/docs-v2/integrations/all/shopify-api-key/form.png differ diff --git a/docs-v2/integrations/all/shopify-api-key/install_app.png b/docs-v2/integrations/all/shopify-api-key/install_app.png new file mode 100644 index 00000000000..1b748e678d0 Binary files /dev/null and b/docs-v2/integrations/all/shopify-api-key/install_app.png differ diff --git a/docs-v2/integrations/all/shopify-api-key/profile.png b/docs-v2/integrations/all/shopify-api-key/profile.png new file mode 100644 index 00000000000..31457721971 Binary files /dev/null and b/docs-v2/integrations/all/shopify-api-key/profile.png differ diff --git a/docs-v2/integrations/all/shopify-api-key/scopes.png b/docs-v2/integrations/all/shopify-api-key/scopes.png new file mode 100644 index 00000000000..1355e1a08d4 Binary files /dev/null and b/docs-v2/integrations/all/shopify-api-key/scopes.png differ diff --git a/docs-v2/integrations/all/shopify-api-key/stores.png b/docs-v2/integrations/all/shopify-api-key/stores.png new file mode 100644 index 00000000000..b3380444ac2 Binary files /dev/null and b/docs-v2/integrations/all/shopify-api-key/stores.png differ diff --git a/docs-v2/integrations/all/shopify.mdx b/docs-v2/integrations/all/shopify.mdx index a4c9a860cda..e0841bd3839 100644 --- a/docs-v2/integrations/all/shopify.mdx +++ b/docs-v2/integrations/all/shopify.mdx @@ -60,3 +60,13 @@ For more details, see the [docs here](/guides/getting-started/authorize-an-api-f _None yet, add yours!_ Contribute API gotchas by [editing this page](https://github.com/nangohq/nango/tree/master/docs-v2/integrations/all/shopify.mdx) + +## Going further + + + Guide to connect to Shopify using Connect UI + + + + Guide to connect to Shopify (api key) using Connect UI + diff --git a/docs-v2/integrations/all/shopify/connect.mdx b/docs-v2/integrations/all/shopify/connect.mdx new file mode 100644 index 00000000000..92d0b74d6c6 --- /dev/null +++ b/docs-v2/integrations/all/shopify/connect.mdx @@ -0,0 +1,39 @@ +--- +title: Shopify - How do I link my account? +sidebarTitle: Shopify +--- + + +# Overview + +To authenticate with Shopify, you will need: +1. **Shopify Domain** - The domain associated with your Shopify account. + +This guide will walk you through finding your **Shopify Domain** within Shopify. + +### Prerequisites: + +- You must have an account with Shopify. + +### Instructions: + +#### Step 1: Finding your Shopify Domain +1. Sign in to your [Shopify](https://www.shopify.com/) account. +2. Your **Shopify Domain** is the text found after the URL of your store in the address bar. For example, in `https://admin.shopify.com/store/6nzh0y-y6`, the domain is `6nzh0y-y6`. +3. You can also click on your profile in the top right corner, then select **All Stores** to view the list of stores associated with your account. + +4. From the displayed list, your **Shopify Domain** is the value before `myshopify.com`. + + + +#### Step 2: Enter credentials in the Connect UI + +Once you have your **Shopify Domain**: +1. Open the form where you need to authenticate with Shopify. +2. Enter the **Shopify Domain** in the respective field. +3. Submit the form, and you should be successfully authenticated. + + + + +You are now connected to Shopify. diff --git a/docs-v2/integrations/all/shopify/form.png b/docs-v2/integrations/all/shopify/form.png new file mode 100644 index 00000000000..22e92b0090b Binary files /dev/null and b/docs-v2/integrations/all/shopify/form.png differ diff --git a/docs-v2/mint.json b/docs-v2/mint.json index f04c02de280..d465906611d 100644 --- a/docs-v2/mint.json +++ b/docs-v2/mint.json @@ -266,6 +266,7 @@ "integrations/all/facebook", "integrations/all/factorial", "integrations/all/falai", + "integrations/all/findymail", "integrations/all/figjam", "integrations/all/figma", "integrations/all/firefish", @@ -320,6 +321,7 @@ "integrations/all/klaviyo", "integrations/all/klipfolio", "integrations/all/kustomer", + "integrations/all/lagrowthmachine", "integrations/all/lastpass", "integrations/all/lattice", "integrations/all/lessonly", @@ -394,6 +396,7 @@ "integrations/all/salesforce-experience-cloud", "integrations/all/salesloft", "integrations/all/sap-success-factors", + "integrations/all/scrapedo", "integrations/all/segment", "integrations/all/sendgrid", "integrations/all/servicem8", diff --git a/docs-v2/reference/sdks/node.mdx b/docs-v2/reference/sdks/node.mdx index ff0cf12c1c7..9532f43fdb2 100644 --- a/docs-v2/reference/sdks/node.mdx +++ b/docs-v2/reference/sdks/node.mdx @@ -1002,6 +1002,7 @@ await nango.syncStatus('', ['SYNC_NAME1', 'SYNC_NAME2'], '", + "connection_id": "", "name": "", "status": "RUNNING", "type": "INCREMENTAL", diff --git a/docs-v2/script.js b/docs-v2/script.js index 0aea15cf8c4..8cb72212059 100644 --- a/docs-v2/script.js +++ b/docs-v2/script.js @@ -1,11 +1,19 @@ -/* eslint-disable no-undef */ +/\* eslint-disable no-undef \*/ var script = document.createElement("script"); script.src = "https://widget.kapa.ai/kapa-widget.bundle.js"; script.setAttribute("data-website-id", "d4b1f0f4-ea6f-4dc7-80c9-393418474105"); script.setAttribute("data-project-name", "Nango"); script.setAttribute("data-project-color", "#020202"); script.setAttribute( - "data-project-logo", - "https://avatars.githubusercontent.com/u/106751793?v=4"); +"data-project-logo", +"https://avatars.githubusercontent.com/u/106751793?v=4"); script.setAttribute("data-modal-disclaimer", "This is a custom LLM for Nango.dev with access to all documentation, closed GitHub PRs and Issues and the API reference. Note that this is AI technology, so please use common sense."); document.body.appendChild(script); + + + +// Koala Start +window.koalaSettings = { host: 'https://bluegrass.nango.dev' }; + +!function(t){var k="ko",i=(window.globalKoalaKey=window.globalKoalaKey||k);if(window[i])return;var ko=(window[i]=[]);["identify","track","removeListeners","on","off","qualify","ready"].forEach(function(t){ko[t]=function(){var n=[].slice.call(arguments);return n.unshift(t),ko.push(n),ko}});var n=document.createElement("script");n.async=!0,n.setAttribute("src","https://shoegaze.nango.dev/v1/pk_799998f91877afef040206962ce1af164de9/sdk.js"),(document.body || document.head).appendChild(n)}(); +// Koala End \ No newline at end of file diff --git a/docs-v2/snippets/generated/chorus/PreBuiltTooling.mdx b/docs-v2/snippets/generated/chorus/PreBuiltTooling.mdx index f97bb511221..f8d5582d997 100644 --- a/docs-v2/snippets/generated/chorus/PreBuiltTooling.mdx +++ b/docs-v2/snippets/generated/chorus/PreBuiltTooling.mdx @@ -6,7 +6,7 @@ | Pre-built authorization (API Key) | ✅ | | Pre-built authorization UI | ✅ | | Custom authorization UI | ✅ | -| End-user authorization guide | 🚫 | +| End-user authorization guide | ✅ | | Expired credentials detection | ✅ | diff --git a/docs-v2/snippets/generated/findymail/PreBuiltTooling.mdx b/docs-v2/snippets/generated/findymail/PreBuiltTooling.mdx new file mode 100644 index 00000000000..f8d5582d997 --- /dev/null +++ b/docs-v2/snippets/generated/findymail/PreBuiltTooling.mdx @@ -0,0 +1,40 @@ +## Pre-built tooling + + +| Tools | Status | +| - | - | +| Pre-built authorization (API Key) | ✅ | +| Pre-built authorization UI | ✅ | +| Custom authorization UI | ✅ | +| End-user authorization guide | ✅ | +| Expired credentials detection | ✅ | + + +| Tools | Status | +| - | - | +| Pre-built use-cases | 🚫 (time to contribute: <48h) | +| API unification | ✅ | +| 2-way sync | ✅ | +| Webhooks from Nango on data modifications | ✅ | +| Real-time webhooks from 3rd-party API | 🚫 (time to contribute: <48h) | +| Proxy requests | ✅ | + + +| Tools | Status | +| - | - | +| HTTP request logging | ✅ | +| End-to-type type safety | ✅ | +| Data runtime validation | ✅ | +| OpenTelemetry export | ✅ | +| Slack alerts on errors | ✅ | +| Integration status API | ✅ | + + +| Tools | Status | +| - | - | +| Create or customize use-cases | ✅ | +| Pre-configured pagination | 🚫 (time to contribute: <48h) | +| Pre-configured rate-limit handling | 🚫 (time to contribute: <48h) | +| Per-customer configurations | ✅ | + + \ No newline at end of file diff --git a/docs-v2/snippets/generated/findymail/PreBuiltUseCases.mdx b/docs-v2/snippets/generated/findymail/PreBuiltUseCases.mdx new file mode 100644 index 00000000000..e29f9b230e4 --- /dev/null +++ b/docs-v2/snippets/generated/findymail/PreBuiltUseCases.mdx @@ -0,0 +1,5 @@ +## Pre-built use-cases + +_No pre-built use cases yet (time to contribute: <48h)_ + +Not seeing the use case you need? [Build your own](https://docs.nango.dev/guides/customize/setup) independently. diff --git a/docs-v2/snippets/generated/freshsales/PreBuiltTooling.mdx b/docs-v2/snippets/generated/freshsales/PreBuiltTooling.mdx index f97bb511221..f8d5582d997 100644 --- a/docs-v2/snippets/generated/freshsales/PreBuiltTooling.mdx +++ b/docs-v2/snippets/generated/freshsales/PreBuiltTooling.mdx @@ -6,7 +6,7 @@ | Pre-built authorization (API Key) | ✅ | | Pre-built authorization UI | ✅ | | Custom authorization UI | ✅ | -| End-user authorization guide | 🚫 | +| End-user authorization guide | ✅ | | Expired credentials detection | ✅ | diff --git a/docs-v2/snippets/generated/freshservice/PreBuiltTooling.mdx b/docs-v2/snippets/generated/freshservice/PreBuiltTooling.mdx index a57b8ab2438..7f8826df4a9 100644 --- a/docs-v2/snippets/generated/freshservice/PreBuiltTooling.mdx +++ b/docs-v2/snippets/generated/freshservice/PreBuiltTooling.mdx @@ -6,7 +6,7 @@ | Pre-built authorization (Basic) | ✅ | | Pre-built authorization UI | ✅ | | Custom authorization UI | ✅ | -| End-user authorization guide | 🚫 | +| End-user authorization guide | ✅ | | Expired credentials detection | ✅ | diff --git a/docs-v2/snippets/generated/gainsight-cc/PreBuiltTooling.mdx b/docs-v2/snippets/generated/gainsight-cc/PreBuiltTooling.mdx index 4dd2ba15dd6..22272b66479 100644 --- a/docs-v2/snippets/generated/gainsight-cc/PreBuiltTooling.mdx +++ b/docs-v2/snippets/generated/gainsight-cc/PreBuiltTooling.mdx @@ -7,6 +7,7 @@ | Credentials auto-refresh | ✅ | | Pre-built authorization UI | ✅ | | Custom authorization UI | ✅ | +| End-user authorization guide | ✅ | | Expired credentials detection | ✅ | diff --git a/docs-v2/snippets/generated/github/PreBuiltUseCases.mdx b/docs-v2/snippets/generated/github/PreBuiltUseCases.mdx index f227e02064b..4ede6f94b47 100644 --- a/docs-v2/snippets/generated/github/PreBuiltUseCases.mdx +++ b/docs-v2/snippets/generated/github/PreBuiltUseCases.mdx @@ -16,10 +16,8 @@ | Endpoint | Description | Readme | | - | - | - | | `GET /github/list-repos` | List github repos from an organization. | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/github/actions/list-repos.md) | -| `POST /github/create-demo-issue` | Create a GitHub issue in Nango's showcase repository. | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/github/actions/create-demo-issue.md) | | `GET /github/issues` | Fetches Github issues from all a user's repositories | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/github/syncs/issues.md) | | `GET /github/issues-lite` | Fetches Github issues but up to a maximum of 15 | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/github/syncs/issues-lite.md) | -| `GET /github/demo-issues` | Fetches GitHub issues from our showcase repository. | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/github/syncs/issues-demo.md) | diff --git a/docs-v2/snippets/generated/gong/PreBuiltTooling.mdx b/docs-v2/snippets/generated/gong/PreBuiltTooling.mdx index 7f8826df4a9..639f2c21a1f 100644 --- a/docs-v2/snippets/generated/gong/PreBuiltTooling.mdx +++ b/docs-v2/snippets/generated/gong/PreBuiltTooling.mdx @@ -12,7 +12,7 @@ | Tools | Status | | - | - | -| Pre-built use-cases | 🚫 (time to contribute: <48h) | +| Pre-built use-cases | ✅ | | API unification | ✅ | | 2-way sync | ✅ | | Webhooks from Nango on data modifications | ✅ | diff --git a/docs-v2/snippets/generated/gong/PreBuiltUseCases.mdx b/docs-v2/snippets/generated/gong/PreBuiltUseCases.mdx index e29f9b230e4..e0eb9d1ac92 100644 --- a/docs-v2/snippets/generated/gong/PreBuiltUseCases.mdx +++ b/docs-v2/snippets/generated/gong/PreBuiltUseCases.mdx @@ -1,5 +1,15 @@ -## Pre-built use-cases -_No pre-built use cases yet (time to contribute: <48h)_ +## Pre-built use cases + + + + + +| Endpoint | Description | Readme | +| - | - | - | +| `GET /users` | Fetches the list of gong users | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/gong/syncs/users.md) | + + + Not seeing the use case you need? [Build your own](https://docs.nango.dev/guides/customize/setup) independently. diff --git a/docs-v2/snippets/generated/guru/PreBuiltTooling.mdx b/docs-v2/snippets/generated/guru/PreBuiltTooling.mdx index a57b8ab2438..7f8826df4a9 100644 --- a/docs-v2/snippets/generated/guru/PreBuiltTooling.mdx +++ b/docs-v2/snippets/generated/guru/PreBuiltTooling.mdx @@ -6,7 +6,7 @@ | Pre-built authorization (Basic) | ✅ | | Pre-built authorization UI | ✅ | | Custom authorization UI | ✅ | -| End-user authorization guide | 🚫 | +| End-user authorization guide | ✅ | | Expired credentials detection | ✅ | diff --git a/docs-v2/snippets/generated/lagrowthmachine/PreBuiltTooling.mdx b/docs-v2/snippets/generated/lagrowthmachine/PreBuiltTooling.mdx new file mode 100644 index 00000000000..f8d5582d997 --- /dev/null +++ b/docs-v2/snippets/generated/lagrowthmachine/PreBuiltTooling.mdx @@ -0,0 +1,40 @@ +## Pre-built tooling + + +| Tools | Status | +| - | - | +| Pre-built authorization (API Key) | ✅ | +| Pre-built authorization UI | ✅ | +| Custom authorization UI | ✅ | +| End-user authorization guide | ✅ | +| Expired credentials detection | ✅ | + + +| Tools | Status | +| - | - | +| Pre-built use-cases | 🚫 (time to contribute: <48h) | +| API unification | ✅ | +| 2-way sync | ✅ | +| Webhooks from Nango on data modifications | ✅ | +| Real-time webhooks from 3rd-party API | 🚫 (time to contribute: <48h) | +| Proxy requests | ✅ | + + +| Tools | Status | +| - | - | +| HTTP request logging | ✅ | +| End-to-type type safety | ✅ | +| Data runtime validation | ✅ | +| OpenTelemetry export | ✅ | +| Slack alerts on errors | ✅ | +| Integration status API | ✅ | + + +| Tools | Status | +| - | - | +| Create or customize use-cases | ✅ | +| Pre-configured pagination | 🚫 (time to contribute: <48h) | +| Pre-configured rate-limit handling | 🚫 (time to contribute: <48h) | +| Per-customer configurations | ✅ | + + \ No newline at end of file diff --git a/docs-v2/snippets/generated/lagrowthmachine/PreBuiltUseCases.mdx b/docs-v2/snippets/generated/lagrowthmachine/PreBuiltUseCases.mdx new file mode 100644 index 00000000000..e29f9b230e4 --- /dev/null +++ b/docs-v2/snippets/generated/lagrowthmachine/PreBuiltUseCases.mdx @@ -0,0 +1,5 @@ +## Pre-built use-cases + +_No pre-built use cases yet (time to contribute: <48h)_ + +Not seeing the use case you need? [Build your own](https://docs.nango.dev/guides/customize/setup) independently. diff --git a/docs-v2/snippets/generated/quickbooks/PreBuiltUseCases.mdx b/docs-v2/snippets/generated/quickbooks/PreBuiltUseCases.mdx index 2a01c9566f8..7b353f43b8c 100644 --- a/docs-v2/snippets/generated/quickbooks/PreBuiltUseCases.mdx +++ b/docs-v2/snippets/generated/quickbooks/PreBuiltUseCases.mdx @@ -30,6 +30,13 @@ + +| Endpoint | Description | Readme | +| - | - | - | +| `GET /general-ledger` | Fetch all general ledger entries in QuickBooks | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/quickbooks/syncs/general-ledger.md) | + + + | Endpoint | Description | Readme | | - | - | - | diff --git a/docs-v2/snippets/generated/scrapedo/PreBuiltTooling.mdx b/docs-v2/snippets/generated/scrapedo/PreBuiltTooling.mdx new file mode 100644 index 00000000000..f8d5582d997 --- /dev/null +++ b/docs-v2/snippets/generated/scrapedo/PreBuiltTooling.mdx @@ -0,0 +1,40 @@ +## Pre-built tooling + + +| Tools | Status | +| - | - | +| Pre-built authorization (API Key) | ✅ | +| Pre-built authorization UI | ✅ | +| Custom authorization UI | ✅ | +| End-user authorization guide | ✅ | +| Expired credentials detection | ✅ | + + +| Tools | Status | +| - | - | +| Pre-built use-cases | 🚫 (time to contribute: <48h) | +| API unification | ✅ | +| 2-way sync | ✅ | +| Webhooks from Nango on data modifications | ✅ | +| Real-time webhooks from 3rd-party API | 🚫 (time to contribute: <48h) | +| Proxy requests | ✅ | + + +| Tools | Status | +| - | - | +| HTTP request logging | ✅ | +| End-to-type type safety | ✅ | +| Data runtime validation | ✅ | +| OpenTelemetry export | ✅ | +| Slack alerts on errors | ✅ | +| Integration status API | ✅ | + + +| Tools | Status | +| - | - | +| Create or customize use-cases | ✅ | +| Pre-configured pagination | 🚫 (time to contribute: <48h) | +| Pre-configured rate-limit handling | 🚫 (time to contribute: <48h) | +| Per-customer configurations | ✅ | + + \ No newline at end of file diff --git a/docs-v2/snippets/generated/scrapedo/PreBuiltUseCases.mdx b/docs-v2/snippets/generated/scrapedo/PreBuiltUseCases.mdx new file mode 100644 index 00000000000..e29f9b230e4 --- /dev/null +++ b/docs-v2/snippets/generated/scrapedo/PreBuiltUseCases.mdx @@ -0,0 +1,5 @@ +## Pre-built use-cases + +_No pre-built use cases yet (time to contribute: <48h)_ + +Not seeing the use case you need? [Build your own](https://docs.nango.dev/guides/customize/setup) independently. diff --git a/docs-v2/snippets/generated/sendgrid/PreBuiltTooling.mdx b/docs-v2/snippets/generated/sendgrid/PreBuiltTooling.mdx index f97bb511221..f8d5582d997 100644 --- a/docs-v2/snippets/generated/sendgrid/PreBuiltTooling.mdx +++ b/docs-v2/snippets/generated/sendgrid/PreBuiltTooling.mdx @@ -6,7 +6,7 @@ | Pre-built authorization (API Key) | ✅ | | Pre-built authorization UI | ✅ | | Custom authorization UI | ✅ | -| End-user authorization guide | 🚫 | +| End-user authorization guide | ✅ | | Expired credentials detection | ✅ | diff --git a/docs-v2/snippets/generated/shopify/PreBuiltTooling.mdx b/docs-v2/snippets/generated/shopify/PreBuiltTooling.mdx index 4dd2ba15dd6..22272b66479 100644 --- a/docs-v2/snippets/generated/shopify/PreBuiltTooling.mdx +++ b/docs-v2/snippets/generated/shopify/PreBuiltTooling.mdx @@ -7,6 +7,7 @@ | Credentials auto-refresh | ✅ | | Pre-built authorization UI | ✅ | | Custom authorization UI | ✅ | +| End-user authorization guide | ✅ | | Expired credentials detection | ✅ | diff --git a/docs-v2/snippets/generated/smartsheet/PreBuiltTooling.mdx b/docs-v2/snippets/generated/smartsheet/PreBuiltTooling.mdx index 9a2a6d57a87..d63f8f2e4cd 100644 --- a/docs-v2/snippets/generated/smartsheet/PreBuiltTooling.mdx +++ b/docs-v2/snippets/generated/smartsheet/PreBuiltTooling.mdx @@ -13,7 +13,7 @@ | Tools | Status | | - | - | -| Pre-built use-cases | 🚫 (time to contribute: <48h) | +| Pre-built use-cases | ✅ | | API unification | ✅ | | 2-way sync | ✅ | | Webhooks from Nango on data modifications | ✅ | diff --git a/docs-v2/snippets/generated/smartsheet/PreBuiltUseCases.mdx b/docs-v2/snippets/generated/smartsheet/PreBuiltUseCases.mdx index e29f9b230e4..ec0429b14ad 100644 --- a/docs-v2/snippets/generated/smartsheet/PreBuiltUseCases.mdx +++ b/docs-v2/snippets/generated/smartsheet/PreBuiltUseCases.mdx @@ -1,5 +1,18 @@ -## Pre-built use-cases -_No pre-built use cases yet (time to contribute: <48h)_ +## Pre-built use cases + + + + + +| Endpoint | Description | Readme | +| - | - | - | +| `POST /users` | Creates a user in Smartsheet | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/smartsheet/actions/create-user.md) | +| `DELETE /users` | Deletes a user from Smartsheet. User is transitioned to a free collaborator with read-only access to owned reports, sheets, Sights, workspaces, and any shared templates (unless those are optionally transferred to another user). | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/smartsheet/actions/delete-user.md) | +| `POST /users/disable` | Disables a user in an organization account. User will no longer be able to access Smartsheet in any way. User's assets will continue to be owned by this user until they are transferred to another user. | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/smartsheet/actions/disable-user.md) | +| `GET /users` | Fetches a list of users from Smartsheet | [🔗](https://github.com/NangoHQ/integration-templates/blob/main/integrations/smartsheet/syncs/users.md) | + + + Not seeing the use case you need? [Build your own](https://docs.nango.dev/guides/customize/setup) independently. diff --git a/docs-v2/spec.yaml b/docs-v2/spec.yaml index f7dd6590520..be6c36ebb75 100644 --- a/docs-v2/spec.yaml +++ b/docs-v2/spec.yaml @@ -1141,11 +1141,20 @@ paths: type: string full_resync: type: boolean - description: Clear the records and reset the "lastSyncDate" associated with the sync before triggering a new sync job. + description: Reset the "lastSyncDate" associated with the sync before triggering a new sync job. responses: '200': description: Successfully triggered the sync + content: + application/json: + schema: + type: object + required: + - success + properties: + success: + type: boolean '400': description: Invalid request content: @@ -1182,6 +1191,15 @@ paths: responses: '200': description: Successfully started the sync + content: + application/json: + schema: + type: object + required: + - success + properties: + success: + type: boolean '400': description: Invalid request content: @@ -1217,6 +1235,15 @@ paths: responses: '200': description: Successfully paused the sync + content: + application/json: + schema: + type: object + required: + - success + properties: + success: + type: boolean '400': description: Invalid request content: @@ -1265,6 +1292,9 @@ paths: id: type: string description: The unique identifier for the sync. + connection_id: + type: string + description: The ID of the connection name: type: string description: The name of the sync. diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000000..702cbf2c69f --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,358 @@ +import unicorn from 'eslint-plugin-unicorn'; +import globals from 'globals'; +import tsParser from '@typescript-eslint/parser'; +import react from 'eslint-plugin-react'; +import reactHooks from 'eslint-plugin-react-hooks'; +import * as tseslint from 'typescript-eslint'; +import prettier from 'eslint-config-prettier'; +import prettierRecommended from 'eslint-plugin-prettier/recommended'; +import eslint from '@eslint/js'; +import importPlugin from 'eslint-plugin-import'; + +export default tseslint.config( + { + ignores: [ + '**/node_modules', + '**/dist/', + '**/build/', + '**/coverage/', + '**/bin/', + 'packages/server/nango-integrations/', + 'packages/node-client/tests', + 'packages/cli/fixtures/', + 'docs-v2/script.js' + ] + }, + + prettier, + prettierRecommended, + + { + files: ['**/*.{js,mjs,cjs,ts,jsx,tsx,mts,mtsx}'], + plugins: { + unicorn, + import: importPlugin + }, + languageOptions: { + globals: { + ...globals.node + } + }, + rules: { + ...eslint.configs.recommended.rules, + ...importPlugin.flatConfigs.errors.rules, + ...importPlugin.flatConfigs.warnings.rules, + ...importPlugin.flatConfigs.recommended.rules, + 'no-console': 'warn', + 'prettier/prettier': 'error', + + 'import/extensions': [ + 'error', + 'always', + { + json: 'always', + js: 'always', + ts: 'never', + ignorePackages: true + } + ], + + 'import/no-unresolved': 'off', + 'import/no-duplicates': 'error', + 'import/no-extraneous-dependencies': 'error', + 'import/no-empty-named-blocks': 'error', + 'import/no-absolute-path': 'error', + 'import/no-self-import': 'error', + 'import/newline-after-import': 'error', + 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], + 'import/namespace': 'off', + + 'unicorn/catch-error-name': [ + 'error', + { + name: 'err' + } + ] + } + }, + { + files: ['**/*.{ts,tsx}'], + plugins: { + '@typescript-eslint': tseslint.plugin + }, + extends: [ + tseslint.configs.recommended, + tseslint.configs.recommendedTypeChecked, + tseslint.configs.strict, + tseslint.configs.stylistic, + tseslint.configs.strictTypeChecked + ], + + languageOptions: { + parser: tsParser, + ecmaVersion: 5, + sourceType: 'module', + + parserOptions: { + ecmaFeatures: { + impliedStrict: true, + jsx: true + }, + + project: './tsconfig.json' + } + }, + + rules: { + 'no-unused-vars': 'off', + '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/require-await': 'error', + '@typescript-eslint/no-non-null-assertion': 'warn', + '@typescript-eslint/no-explicit-any': 'warn', + + '@typescript-eslint/restrict-template-expressions': [ + 'error', + { + allowNumber: true, + allowBoolean: true, + allowNever: true + } + ], + + '@typescript-eslint/await-thenable': 'error', + '@typescript-eslint/no-invalid-void-type': 'warn', + '@typescript-eslint/no-base-to-string': 'warn', + '@typescript-eslint/restrict-plus-operands': 'warn', + '@typescript-eslint/consistent-type-exports': 'error', + '@typescript-eslint/no-unnecessary-condition': 'off', + '@typescript-eslint/only-throw-error': 'warn', + + '@typescript-eslint/no-unused-vars': [ + 'error', + { + args: 'all', + argsIgnorePattern: '^_', + caughtErrors: 'all', + caughtErrorsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + varsIgnorePattern: '^_', + ignoreRestSiblings: true + } + ], + + '@typescript-eslint/consistent-type-imports': [ + 'error', + { + prefer: 'type-imports', + fixStyle: 'separate-type-imports' + } + ], + + '@typescript-eslint/no-confusing-void-expression': [ + 'warn', + { + ignoreVoidOperator: true, + ignoreArrowShorthand: true + } + ], + + // To re-enable as error progressively + '@typescript-eslint/no-deprecated': 'warn', + '@typescript-eslint/no-floating-promises': 'warn', + '@typescript-eslint/no-unsafe-assignment': 'warn', + '@typescript-eslint/no-unsafe-member-access': 'warn', + '@typescript-eslint/no-unsafe-call': 'warn', + '@typescript-eslint/no-unsafe-argument': 'warn', + '@typescript-eslint/no-misused-promises': 'warn', + '@typescript-eslint/no-unsafe-return': 'warn', + '@typescript-eslint/no-empty-function': 'warn', + '@typescript-eslint/no-unsafe-enum-comparison': 'warn' + } + }, + { + files: ['integration-templates/**/*.ts'], + rules: { + 'no-constant-condition': 'off', + '@typescript-eslint/no-dynamic-delete': 'off', + '@typescript-eslint/no-redundant-type-constituents': 'off' + } + }, + { + files: ['packages/frontend/**/*.ts'], + languageOptions: { + globals: { + ...globals.browser, + ...Object.fromEntries(Object.entries(globals.node).map(([key]) => [key, 'off'])) + }, + + ecmaVersion: 2018, + sourceType: 'module', + + parserOptions: { + ecmaFeatures: { + impliedStrict: true, + jsx: false + }, + + project: 'packages/frontend/tsconfig.json' + } + }, + rules: { + 'no-console': 'off', + + '@typescript-eslint/no-misused-promises': [ + 'warn', + { + checksVoidReturn: { + arguments: false, + attributes: false + } + } + ] + } + }, + { + files: ['packages/webapp/src/**/*.{tsx,ts}'], + plugins: { + react: react, + 'react-hooks': reactHooks + }, + settings: { + react: { + version: 'detect' + } + }, + + languageOptions: { + globals: { + ...globals.browser, + ...Object.fromEntries(Object.entries(globals.node).map(([key]) => [key, 'off'])) + }, + + ecmaVersion: 2018, + sourceType: 'module', + + parserOptions: { + ecmaFeatures: { + impliedStrict: true, + jsx: true + }, + + project: 'packages/webapp/tsconfig.json' + } + }, + + rules: { + ...react.configs.flat.recommended.rules, + ...react.configs.flat['jsx-runtime'].rules, + ...reactHooks.configs.recommended.rules, + 'no-console': 'off', + 'react/prop-types': 'off', + + '@typescript-eslint/no-unused-expressions': 'off', // bugged + '@typescript-eslint/no-empty-function': 'off', + + '@typescript-eslint/no-misused-promises': [ + 'warn', + { + checksVoidReturn: { + arguments: false, + attributes: false + } + } + ], + + 'import/extensions': 'off' + } + }, + { + files: ['packages/connect-ui/src/**/*.{tsx,ts}'], + + plugins: { + react: react, + 'react-hooks': reactHooks + }, + + settings: { + react: { + version: 'detect' + } + }, + + languageOptions: { + globals: { + ...globals.browser, + ...Object.fromEntries(Object.entries(globals.node).map(([key]) => [key, 'off'])) + }, + + ecmaVersion: 2018, + sourceType: 'module', + + parserOptions: { + ecmaFeatures: { + impliedStrict: true, + jsx: true + }, + jsxPragma: null, + + project: 'packages/connect-ui/tsconfig.json' + } + }, + + rules: { + ...react.configs.flat.recommended.rules, + ...react.configs.flat['jsx-runtime'].rules, + ...reactHooks.configs.recommended.rules, + + 'import/extensions': 'off', + '@typescript-eslint/member-ordering': 'error', + '@typescript-eslint/no-non-null-assertion': 'error', + '@typescript-eslint/no-explicit-any': 'error', + '@typescript-eslint/only-throw-error': 'error', + 'react/prop-types': 'off', + + 'react/jsx-sort-props': [ + 'error', + { + callbacksLast: true, + shorthandFirst: true, + reservedFirst: true + } + ], + + 'import/order': [ + 'error', + { + groups: ['builtin', 'external', 'unknown', 'internal', 'parent', 'sibling', 'type', 'index', 'object'], + + 'newlines-between': 'always', + + alphabetize: { + order: 'asc' + }, + + warnOnUnassignedImports: true, + + pathGroups: [ + { + pattern: '@/**', + group: 'parent' + }, + { + pattern: '@nangohq/*', + group: 'internal', + position: 'after' + } + ] + } + ] + } + }, + { + files: ['**/**.test.ts'], + rules: { + '@typescript-eslint/no-unsafe-assignment': 'off', + '@typescript-eslint/no-non-null-assertion': 'off' + } + } +); diff --git a/package-lock.json b/package-lock.json index a9c49c84c9f..c6d5c54fad8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,28 +12,30 @@ "scripts" ], "devDependencies": { - "@tsconfig/node18-strictest-esm": "1.0.1", + "@eslint/js": "9.17.0", "@types/node": "20.12.2", - "@typescript-eslint/eslint-plugin": "7.18.0", - "@typescript-eslint/parser": "7.18.0", + "@typescript-eslint/eslint-plugin": "8.19.1", + "@typescript-eslint/parser": "8.19.1", "concurrently": "8.2.2", - "eslint": "8.56.0", + "eslint": "9.17.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-import": "2.31.0", "eslint-plugin-prettier": "5.2.1", - "eslint-plugin-react": "7.33.2", - "eslint-plugin-react-hooks": "4.6.0", + "eslint-plugin-react": "7.37.3", + "eslint-plugin-react-hooks": "5.1.0", "eslint-plugin-unicorn": "56.0.1", + "globals": "15.14.0", "husky": "8.0.3", - "js-yaml": "^4.1.0", - "lint-staged": "15.2.11", + "js-yaml": "4.1.0", + "lint-staged": "15.3.0", "onchange": "7.1.0", "prettier": "3.4.2", "rimraf": "6.0.1", "testcontainers": "9.12.0", - "tsx": "4.19.0", - "typescript": "5.3.3", - "vitest": "1.6.0" + "tsx": "4.19.2", + "typescript": "5.7.3", + "typescript-eslint": "8.19.1", + "vitest": "2.1.8" }, "engines": { "node": ">=18.0.0 || >=20.0.0" @@ -1837,9 +1839,10 @@ } }, "node_modules/@babel/eslint-parser": { - "version": "7.23.10", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.25.9.tgz", + "integrity": "sha512-5UXfgpK0j0Xr/xIdgdLEhOFxaDZ0bRPWJJchRpqOSur/3rZoPbqqki5mm0p4NE2cs28krBEiSM2MB7//afRSQQ==", "dev": true, - "license": "MIT", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", "eslint-visitor-keys": "^2.1.0", @@ -1850,21 +1853,23 @@ }, "peerDependencies": { "@babel/core": "^7.11.0", - "eslint": "^7.5.0 || ^8.0.0" + "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/@babel/eslint-parser/node_modules/eslint-visitor-keys": { "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=10" } }, "node_modules/@babel/eslint-parser/node_modules/semver": { "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -4228,85 +4233,6 @@ "node": ">=12.0.0" } }, - "node_modules/@datadog/native-appsec": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", - "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^3.9.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@datadog/native-iast-rewriter": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", - "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", - "dependencies": { - "lru-cache": "^7.14.0", - "node-gyp-build": "^4.5.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@datadog/native-iast-rewriter/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.2.tgz", - "integrity": "sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==", - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/@datadog/native-iast-taint-tracking": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", - "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", - "hasInstallScript": true, - "dependencies": { - "node-gyp-build": "^3.9.0" - } - }, - "node_modules/@datadog/native-metrics": { - "version": "2.0.0", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "node-addon-api": "^6.1.0", - "node-gyp-build": "^3.9.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@datadog/pprof": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", - "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", - "hasInstallScript": true, - "dependencies": { - "delay": "^5.0.0", - "node-gyp-build": "<4.0", - "p-limit": "^3.1.0", - "pprof-format": "^2.1.0", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/@datadog/sketches-js": { "version": "2.1.0", "license": "Apache-2.0" @@ -4857,22 +4783,50 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, - "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", + "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.5", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", + "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -4880,18 +4834,52 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@eslint/js": { - "version": "8.56.0", + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.17.0.tgz", + "integrity": "sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w==", "dev": true, - "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", + "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", + "dev": true, + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@fastify/busboy": { @@ -5106,12 +5094,49 @@ "react-hook-form": "^7.0.0" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", + "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", "minimatch": "^3.0.5" }, @@ -5119,11 +5144,6 @@ "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "dev": true, @@ -5136,6 +5156,26 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "license": "ISC", @@ -5543,17 +5583,6 @@ "node": ">=0.10.0" } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/@jest/source-map": { "version": "27.5.1", "dev": true, @@ -5730,7 +5759,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -5921,8 +5952,9 @@ }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { "version": "5.1.1-v1", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz", + "integrity": "sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==", "dev": true, - "license": "MIT", "dependencies": { "eslint-scope": "5.1.1" } @@ -10409,9 +10441,10 @@ "dev": true }, "node_modules/@rushstack/eslint-patch": { - "version": "1.7.2", - "dev": true, - "license": "MIT" + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz", + "integrity": "sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA==", + "dev": true }, "node_modules/@sentry-internal/browser-utils": { "version": "8.36.0", @@ -10607,19 +10640,6 @@ "node": ">=14.18" } }, - "node_modules/@sentry-internal/tracing": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.119.2.tgz", - "integrity": "sha512-V2W+STWrafyGJhQv3ulMFXYDwWHiU6wHQAQBShsHVACiFaDrJ2kPRet38FKv4dMLlLlP2xN+ss2e5zv3tYlTiQ==", - "dependencies": { - "@sentry/core": "7.119.2", - "@sentry/types": "7.119.2", - "@sentry/utils": "7.119.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@sentry/browser": { "version": "8.36.0", "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.36.0.tgz", @@ -10672,47 +10692,6 @@ "node": ">=14.18" } }, - "node_modules/@sentry/core": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.119.2.tgz", - "integrity": "sha512-hQr3d2yWq/2lMvoyBPOwXw1IHqTrCjOsU1vYKhAa6w9vGbJZFGhKGGE2KEi/92c3gqGn+gW/PC7cV6waCTDuVA==", - "dependencies": { - "@sentry/types": "7.119.2", - "@sentry/utils": "7.119.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/integrations": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.119.2.tgz", - "integrity": "sha512-dCuXKvbUE3gXVVa696SYMjlhSP6CxpMH/gl4Jk26naEB8Xjsn98z/hqEoXLg6Nab73rjR9c/9AdKqBbwVMHyrQ==", - "dependencies": { - "@sentry/core": "7.119.2", - "@sentry/types": "7.119.2", - "@sentry/utils": "7.119.2", - "localforage": "^1.8.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/node": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.119.2.tgz", - "integrity": "sha512-TPNnqxh+Myooe4jTyRiXrzrM2SH08R4+nrmBls4T7lKp2E5R/3mDSe/YTn5rRcUt1k1hPx1NgO/taG0DoS5cXA==", - "dependencies": { - "@sentry-internal/tracing": "7.119.2", - "@sentry/core": "7.119.2", - "@sentry/integrations": "7.119.2", - "@sentry/types": "7.119.2", - "@sentry/utils": "7.119.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@sentry/react": { "version": "8.36.0", "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.36.0.tgz", @@ -10766,25 +10745,6 @@ "node": ">=14.18" } }, - "node_modules/@sentry/types": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz", - "integrity": "sha512-ydq1tWsdG7QW+yFaTp0gFaowMLNVikIqM70wxWNK+u98QzKnVY/3XTixxNLsUtnAB4Y+isAzFhrc6Vb5GFdFeg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/@sentry/utils": { - "version": "7.119.2", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.119.2.tgz", - "integrity": "sha512-TLdUCvcNgzKP0r9YD7tgCL1PEUp42TObISridsPJ5rhpVGQJvpr+Six0zIkfDUxerLYWZoK8QMm9KgFlPLNQzA==", - "dependencies": { - "@sentry/types": "7.119.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@sideway/address": { "version": "4.1.4", "license": "BSD-3-Clause", @@ -10804,11 +10764,6 @@ "version": "2.0.0", "license": "BSD-3-Clause" }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "dev": true, - "license": "MIT" - }, "node_modules/@sinonjs/commons": { "version": "1.8.6", "dev": true, @@ -12115,11 +12070,6 @@ "version": "1.0.3", "license": "MIT" }, - "node_modules/@tsconfig/node18-strictest-esm": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, "node_modules/@types/archiver": { "version": "5.3.2", "dev": true, @@ -12728,8 +12678,9 @@ }, "node_modules/@types/semver": { "version": "7.5.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true }, "node_modules/@types/serve-index": { "version": "1.9.4", @@ -12845,281 +12796,138 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", - "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.19.1.tgz", + "integrity": "sha512-tJzcVyvvb9h/PB96g30MpxACd9IrunT7GF9wfA9/0TJ1LxGOJx1TdPzSbBBnNED7K9Ka8ybJsnEpiXPktolTLg==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/type-utils": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/scope-manager": "8.19.1", + "@typescript-eslint/type-utils": "8.19.1", + "@typescript-eslint/utils": "8.19.1", + "@typescript-eslint/visitor-keys": "8.19.1", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", - "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "node_modules/@typescript-eslint/parser": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.19.1.tgz", + "integrity": "sha512-67gbfv8rAwawjYx3fYArwldTQKoYfezNUT4D5ioWetr/xCrxXxvleo3uuiFuKfejipvq+og7mjz3b0G2bVyUCw==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0" + "@typescript-eslint/scope-manager": "8.19.1", + "@typescript-eslint/types": "8.19.1", + "@typescript-eslint/typescript-estree": "8.19.1", + "@typescript-eslint/visitor-keys": "8.19.1", + "debug": "^4.3.4" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.19.1.tgz", + "integrity": "sha512-60L9KIuN/xgmsINzonOcMDSB8p82h95hoBfSBtXuO4jlR1R9L1xSkmVZKgCPVfavDlXihh4ARNjXhh1gGnLC7Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.18.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.19.1", + "@typescript-eslint/visitor-keys": "8.19.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", - "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.19.1.tgz", + "integrity": "sha512-Rp7k9lhDKBMRJB/nM9Ksp1zs4796wVNyihG9/TU9R6KCJDNkQbc2EOKjrBtLYh3396ZdpXLtr/MkaSEmNMtykw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4" + "@typescript-eslint/typescript-estree": "8.19.1", + "@typescript-eslint/utils": "8.19.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "node_modules/@typescript-eslint/types": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.19.1.tgz", + "integrity": "sha512-JBVHMLj7B1K1v1051ZaMMgLW4Q/jre5qGK0Ew6UgXz1Rqh+/xPzV1aW581OM00X6iOfyr1be+QyW8LOUf19BbA==", "dev": true, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.19.1.tgz", + "integrity": "sha512-jk/TZwSMJlxlNnqhy0Eod1PNEvCkpY6MXOXE/WLlblZ6ibb32i2We4uByoKPv1d0OD2xebDv4hbs3fm11SMw8Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", + "@typescript-eslint/types": "8.19.1", + "@typescript-eslint/visitor-keys": "8.19.1", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/brace-expansion": { + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", @@ -13128,7 +12936,7 @@ "balanced-match": "^1.0.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/minimatch": { + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", @@ -13143,247 +12951,56 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", - "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", - "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "node_modules/@typescript-eslint/utils": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.1.tgz", + "integrity": "sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0" + "@typescript-eslint/scope-manager": "8.19.1", + "@typescript-eslint/types": "8.19.1", + "@typescript-eslint/typescript-estree": "8.19.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.1.tgz", + "integrity": "sha512-fzmjU8CHK853V/avYZAvuVut3ZTfwN5YtMaoi+X9Y9MA9keaWNHC3zEQ9zvyX/7Hj+5JkNyK1l7TOR2hevHB6Q==", "dev": true, - "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@typescript-eslint/types": "8.19.1", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/eslint" } }, "node_modules/@uidotdev/usehooks": { @@ -13400,9 +13017,10 @@ } }, "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "dev": true, - "license": "ISC" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz", + "integrity": "sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==", + "dev": true }, "node_modules/@vitejs/plugin-react-swc": { "version": "3.5.0", @@ -13417,100 +13035,126 @@ } }, "node_modules/@vitest/expect": { - "version": "1.6.0", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.8.tgz", + "integrity": "sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "chai": "^4.3.10" + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/runner": { - "version": "1.6.0", + "node_modules/@vitest/mocker": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.8.tgz", + "integrity": "sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "1.6.0", - "p-limit": "^5.0.0", - "pathe": "^1.1.1" + "@vitest/spy": "2.1.8", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" }, "funding": { "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } } }, - "node_modules/@vitest/runner/node_modules/p-limit": { - "version": "5.0.0", + "node_modules/@vitest/mocker/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, "license": "MIT", "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@types/estree": "^1.0.0" } }, - "node_modules/@vitest/runner/node_modules/yocto-queue": { - "version": "1.0.0", + "node_modules/@vitest/pretty-format": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", + "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=12.20" + "dependencies": { + "tinyrainbow": "^1.2.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/snapshot": { - "version": "1.6.0", + "node_modules/@vitest/runner": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.8.tgz", + "integrity": "sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==", "dev": true, "license": "MIT", "dependencies": { - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "pretty-format": "^29.7.0" + "@vitest/utils": "2.1.8", + "pathe": "^1.1.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/spy": { - "version": "1.6.0", + "node_modules/@vitest/snapshot": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.8.tgz", + "integrity": "sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==", "dev": true, "license": "MIT", "dependencies": { - "tinyspy": "^2.2.0" + "@vitest/pretty-format": "2.1.8", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/utils": { - "version": "1.6.0", + "node_modules/@vitest/spy": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.8.tgz", + "integrity": "sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==", "dev": true, "license": "MIT", "dependencies": { - "diff-sequences": "^29.6.3", - "estree-walker": "^3.0.3", - "loupe": "^2.3.7", - "pretty-format": "^29.7.0" + "tinyspy": "^3.0.2" }, "funding": { "url": "https://opencollective.com/vitest" } }, - "node_modules/@vitest/utils/node_modules/estree-walker": { - "version": "3.0.3", + "node_modules/@vitest/utils": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.8.tgz", + "integrity": "sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0" + "@vitest/pretty-format": "2.1.8", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, "node_modules/@webassemblyjs/ast": { @@ -13737,7 +13381,9 @@ } }, "node_modules/acorn": { - "version": "8.11.3", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -13784,8 +13430,9 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -14084,13 +13731,23 @@ "dev": true, "license": "0BSD" }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/array-buffer-byte-length": { - "version": "1.0.1", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { "node": ">= 0.4" @@ -14130,6 +13787,26 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.findlastindex": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", @@ -14168,14 +13845,15 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.2", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -14203,30 +13881,34 @@ } }, "node_modules/array.prototype.tosorted": { - "version": "1.1.3", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.7", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.1.0", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", "dev": true, - "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -14272,17 +13954,20 @@ "license": "MIT" }, "node_modules/assertion-error": { - "version": "1.1.0", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">=12" } }, "node_modules/ast-types-flow": { "version": "0.0.8", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true }, "node_modules/async": { "version": "3.2.4", @@ -14293,14 +13978,6 @@ "dev": true, "license": "MIT" }, - "node_modules/asynciterator.prototype": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - } - }, "node_modules/asynckit": { "version": "0.4.0", "license": "MIT" @@ -14373,9 +14050,10 @@ } }, "node_modules/axe-core": { - "version": "4.7.0", + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", "dev": true, - "license": "MPL-2.0", "engines": { "node": ">=4" } @@ -14402,11 +14080,12 @@ } }, "node_modules/axobject-query": { - "version": "3.2.1", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "dequal": "^2.0.3" + "engines": { + "node": ">= 0.4" } }, "node_modules/b4a": { @@ -15561,6 +15240,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", @@ -15586,6 +15266,21 @@ "node": ">= 0.4" } }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-me-maybe": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", @@ -15673,26 +15368,26 @@ } }, "node_modules/chai": { - "version": "4.4.1", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", "dev": true, "license": "MIT", "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">=4" + "node": ">=12" } }, "node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -15745,14 +15440,13 @@ } }, "node_modules/check-error": { - "version": "1.0.3", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.2" - }, "engines": { - "node": "*" + "node": ">= 16" } }, "node_modules/check-types": { @@ -16517,15 +16211,11 @@ "version": "1.0.0", "license": "MIT" }, - "node_modules/confbox": { - "version": "0.1.7", - "dev": true, - "license": "MIT" - }, "node_modules/confusing-browser-globals": { "version": "1.0.11", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", @@ -16899,9 +16589,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", - "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -17435,8 +17125,9 @@ }, "node_modules/damerau-levenshtein": { "version": "1.0.8", - "dev": true, - "license": "BSD-2-Clause" + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", @@ -17492,14 +17183,14 @@ } }, "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -17509,29 +17200,29 @@ } }, "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "is-data-view": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/inspect-js" } }, "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", "is-data-view": "^1.0.1" }, @@ -17581,69 +17272,6 @@ "node": ">=12.17" } }, - "node_modules/dd-trace": { - "version": "5.21.0", - "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", - "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", - "hasInstallScript": true, - "dependencies": { - "@datadog/native-appsec": "8.0.1", - "@datadog/native-iast-rewriter": "2.4.1", - "@datadog/native-iast-taint-tracking": "3.1.0", - "@datadog/native-metrics": "^2.0.0", - "@datadog/pprof": "5.3.0", - "@datadog/sketches-js": "^2.1.0", - "@opentelemetry/api": ">=1.0.0 <1.9.0", - "@opentelemetry/core": "^1.14.0", - "crypto-randomuuid": "^1.0.0", - "dc-polyfill": "^0.1.4", - "ignore": "^5.2.4", - "import-in-the-middle": "^1.8.1", - "int64-buffer": "^0.1.9", - "istanbul-lib-coverage": "3.2.0", - "jest-docblock": "^29.7.0", - "koalas": "^1.0.2", - "limiter": "1.1.5", - "lodash.sortby": "^4.7.0", - "lru-cache": "^7.14.0", - "module-details-from-path": "^1.0.3", - "msgpack-lite": "^0.1.26", - "opentracing": ">=0.12.1", - "path-to-regexp": "^0.1.2", - "pprof-format": "^2.1.0", - "protobufjs": "^7.2.5", - "retry": "^0.13.1", - "semver": "^7.5.4", - "shell-quote": "^1.8.1", - "tlhunter-sorted-set": "^0.1.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/dd-trace/node_modules/@opentelemetry/api": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", - "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/dd-trace/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/dd-trace/node_modules/retry": { - "version": "0.13.1", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/debounce-fn": { "version": "5.1.2", "license": "MIT", @@ -17707,12 +17335,11 @@ "license": "MIT" }, "node_modules/deep-eql": { - "version": "4.1.3", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", - "dependencies": { - "type-detect": "^4.0.0" - }, "engines": { "node": ">=6" } @@ -17753,6 +17380,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -17822,14 +17450,6 @@ "node": ">=4" } }, - "node_modules/dequal": { - "version": "2.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/des.js": { "version": "1.1.0", "license": "MIT", @@ -17916,14 +17536,6 @@ "node": ">=0.3.1" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -18017,14 +17629,15 @@ } }, "node_modules/doctrine": { - "version": "3.0.0", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, - "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, "engines": { - "node": ">=6.0.0" + "node": ">=0.10.0" } }, "node_modules/dom-converter": { @@ -18166,11 +17779,11 @@ "license": "BSD-2-Clause" }, "node_modules/dunder-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", - "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", + "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" }, @@ -18402,57 +18015,62 @@ } }, "node_modules/es-abstract": { - "version": "1.23.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz", - "integrity": "sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==", + "version": "1.23.9", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz", + "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==", "dev": true, "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.0", + "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", - "gopd": "^1.0.1", + "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", + "is-data-view": "^1.0.2", + "is-regex": "^1.2.1", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.0", + "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.5", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.3", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.18" }, "engines": { "node": ">= 0.4" @@ -18467,11 +18085,9 @@ "license": "MIT" }, "node_modules/es-define-property": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "engines": { "node": ">= 0.4" } @@ -18484,28 +18100,36 @@ } }, "node_modules/es-iterator-helpers": { - "version": "1.0.15", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", "dev": true, - "license": "MIT", "dependencies": { - "asynciterator.prototype": "^1.0.0", - "call-bind": "^1.0.2", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "es-abstract": "^1.22.1", - "es-set-tostringtag": "^2.0.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.2.1", - "globalthis": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "iterator.prototype": "^1.1.2", - "safe-array-concat": "^1.0.1" + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/es-module-lexer": { - "version": "1.2.1", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "dev": true, "license": "MIT" }, @@ -18513,7 +18137,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -18522,14 +18145,15 @@ } }, "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.4", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -18544,13 +18168,14 @@ } }, "node_modules/es-to-primitive": { - "version": "1.2.1", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", "dev": true, - "license": "MIT", "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" }, "engines": { "node": ">= 0.4" @@ -18997,205 +18622,73 @@ } }, "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "version": "9.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.17.0.tgz", + "integrity": "sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.9.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.17.0", + "@eslint/plugin-kit": "^0.2.3", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-config-react-app": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.16.0", - "@babel/eslint-parser": "^7.16.3", - "@rushstack/eslint-patch": "^1.1.0", - "@typescript-eslint/eslint-plugin": "^5.5.0", - "@typescript-eslint/parser": "^5.5.0", - "babel-preset-react-app": "^10.0.1", - "confusing-browser-globals": "^1.0.11", - "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-import": "^2.25.3", - "eslint-plugin-jest": "^25.3.0", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.27.1", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-testing-library": "^5.0.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "eslint": "^8.0.0" - } - }, - "node_modules/eslint-config-react-app/node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-config-react-app/node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-config-react-app/node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://eslint.org/donate" }, "peerDependencies": { - "eslint": "*" + "jiti": "*" }, "peerDependenciesMeta": { - "typescript": { + "jiti": { "optional": true } } }, - "node_modules/eslint-config-react-app/node_modules/eslint-plugin-jest": { - "version": "25.7.0", + "node_modules/eslint-config-prettier": { + "version": "9.1.0", "dev": true, "license": "MIT", - "dependencies": { - "@typescript-eslint/experimental-utils": "^5.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "bin": { + "eslint-config-prettier": "bin/cli.js" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } + "eslint": ">=7.0.0" } }, "node_modules/eslint-import-resolver-node": { @@ -19242,23 +18735,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-flowtype": { - "version": "8.0.3", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "lodash": "^4.17.21", - "string-natural-compare": "^3.0.1" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@babel/plugin-syntax-flow": "^7.14.5", - "@babel/plugin-transform-react-jsx": "^7.14.9", - "eslint": "^8.1.0" - } - }, "node_modules/eslint-plugin-import": { "version": "2.31.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", @@ -19300,17 +18776,6 @@ "ms": "^2.1.1" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/eslint-plugin-import/node_modules/semver": { "version": "6.3.1", "dev": true, @@ -19320,46 +18785,39 @@ } }, "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.8.0", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/runtime": "^7.23.2", - "aria-query": "^5.3.0", - "array-includes": "^3.1.7", + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", "array.prototype.flatmap": "^1.3.2", "ast-types-flow": "^0.0.8", - "axe-core": "=4.7.0", - "axobject-query": "^3.2.1", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", "damerau-levenshtein": "^1.0.8", "emoji-regex": "^9.2.2", - "es-iterator-helpers": "^1.0.15", - "hasown": "^2.0.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^3.3.5", "language-tags": "^1.0.9", "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7" + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" }, "engines": { "node": ">=4.0" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { - "version": "5.3.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "dequal": "^2.0.3" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { "version": "9.2.2", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true }, "node_modules/eslint-plugin-prettier": { "version": "5.2.1", @@ -19392,68 +18850,63 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.33.2", + "version": "7.37.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.3.tgz", + "integrity": "sha512-DomWuTQPFYZwF/7c9W2fkKkStqZmBd3uugfqBYLdkZ3Hii23WzZuOLUskGxB8qkSKqftxEeGL1TB2kMhrce0jA==", "dev": true, - "license": "MIT", "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.12", + "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", + "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.4", + "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.8" + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" }, "engines": { "node": ">=4" }, "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", + "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "node_modules/eslint-plugin-react/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "dev": true, - "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -19468,27 +18921,13 @@ }, "node_modules/eslint-plugin-react/node_modules/semver": { "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/eslint-plugin-testing-library": { - "version": "5.11.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^5.58.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0", - "npm": ">=6" - }, - "peerDependencies": { - "eslint": "^7.5.0 || ^8.0.0" - } - }, "node_modules/eslint-plugin-unicorn": { "version": "56.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-56.0.1.tgz", @@ -19537,18 +18976,6 @@ "node": ">=8" } }, - "node_modules/eslint-plugin-unicorn/node_modules/globals": { - "version": "15.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.13.0.tgz", - "integrity": "sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/eslint-plugin-unicorn/node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -19605,55 +19032,11 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-webpack-plugin": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "^7.29.0 || ^8.4.1", - "jest-worker": "^28.0.2", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0", - "webpack": "^5.0.0" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { - "version": "28.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } + "node_modules/eslint/node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true }, "node_modules/eslint/node_modules/chalk": { "version": "4.1.2", @@ -19672,15 +19055,28 @@ } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -19688,8 +19084,9 @@ }, "node_modules/eslint/node_modules/estraverse": { "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -19702,16 +19099,29 @@ } }, "node_modules/espree": { - "version": "9.6.1", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -19799,6 +19209,8 @@ }, "node_modules/event-lite": { "version": "0.1.3", + "resolved": "https://registry.npmjs.org/event-lite/-/event-lite-0.1.3.tgz", + "integrity": "sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw==", "license": "MIT" }, "node_modules/event-target-shim": { @@ -19875,6 +19287,16 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/exponential-backoff": { "version": "3.1.1", "license": "Apache-2.0" @@ -20045,8 +19467,7 @@ "node_modules/fast-uri": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", - "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", - "dev": true + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==" }, "node_modules/fast-xml-parser": { "version": "4.4.1", @@ -20150,14 +19571,15 @@ } }, "node_modules/file-entry-cache": { - "version": "6.0.1", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, - "license": "MIT", "dependencies": { - "flat-cache": "^3.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16.0.0" } }, "node_modules/file-loader": { @@ -20325,35 +19747,23 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, - "license": "MIT", "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.2.7", - "dev": true, - "license": "ISC" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true }, "node_modules/fn.name": { "version": "1.1.0", @@ -20647,14 +20057,17 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.6", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -20750,23 +20163,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { - "version": "1.2.4", - "license": "MIT", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -20818,6 +20229,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "license": "MIT", @@ -20829,14 +20252,14 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -20861,9 +20284,9 @@ "license": "MIT" }, "node_modules/git-cliff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/git-cliff/-/git-cliff-2.5.0.tgz", - "integrity": "sha512-HOWY+f5YyK3fYylYY7N8tdd+qPPK7cuInkyY1PVMRsU4c2JT8TM2rvxpVDa6p5uD5MlZ/4mZ7E8RLux99TapQQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/git-cliff/-/git-cliff-2.7.0.tgz", + "integrity": "sha512-gO4rb3VCAvzv+vWPPspxSCAeDAQbvknYioO43Wb+Dn0MWFC3zc89uwkxx36yAmCa7qui9TL2E3vSz6j9GbbzqA==", "dev": true, "dependencies": { "execa": "^8.0.1" @@ -20875,18 +20298,18 @@ "node": ">=18.19 || >=20.6 || >=21" }, "optionalDependencies": { - "git-cliff-darwin-arm64": "2.5.0", - "git-cliff-darwin-x64": "2.5.0", - "git-cliff-linux-arm64": "2.5.0", - "git-cliff-linux-x64": "2.5.0", - "git-cliff-windows-arm64": "2.5.0", - "git-cliff-windows-x64": "2.5.0" + "git-cliff-darwin-arm64": "2.7.0", + "git-cliff-darwin-x64": "2.7.0", + "git-cliff-linux-arm64": "2.7.0", + "git-cliff-linux-x64": "2.7.0", + "git-cliff-windows-arm64": "2.7.0", + "git-cliff-windows-x64": "2.7.0" } }, "node_modules/git-cliff-darwin-arm64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/git-cliff-darwin-arm64/-/git-cliff-darwin-arm64-2.5.0.tgz", - "integrity": "sha512-mIw8CZRRRVFB7HWLYESAlvLjXSoqMThyhbdCbVJYEZw2Qxx2UhldEkGv62+qLAhjYwG7GfoeByDqwXGS9rWe7Q==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/git-cliff-darwin-arm64/-/git-cliff-darwin-arm64-2.7.0.tgz", + "integrity": "sha512-8D6Zxk9onts9r16yzuJEUq4ixGMJYvUI47GujUbs3ifsXB7x8SCOX7QCwmylRkZKnRC95fZ3jwi+gy95SwVaPQ==", "cpu": [ "arm64" ], @@ -20897,9 +20320,9 @@ ] }, "node_modules/git-cliff-darwin-x64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/git-cliff-darwin-x64/-/git-cliff-darwin-x64-2.5.0.tgz", - "integrity": "sha512-YPoE+rAgdRea4apauK25yDqNDJYvZtoqE8FBKuKRo9AY+btqZMVgxN6UNf9Ea4jQtDQOTqhpYUpM0czk9z4GgQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/git-cliff-darwin-x64/-/git-cliff-darwin-x64-2.7.0.tgz", + "integrity": "sha512-CkADqy5hif6P6rrTIWkkSkrsQzbcTv1kr5dAIpRq9SkjWVpRHQftouhNyB2qfNe0SH73R9N9oCIocIA1bSnVeQ==", "cpu": [ "x64" ], @@ -20910,9 +20333,9 @@ ] }, "node_modules/git-cliff-linux-arm64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/git-cliff-linux-arm64/-/git-cliff-linux-arm64-2.5.0.tgz", - "integrity": "sha512-KJCD7tpH+LJw7XrKhi+jPWFxEGqsxUDUmNLeSjGGptkbXx+LXNFTqTdvQHCeFWSybKMuBnEcou8qEfYTDIcrIg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/git-cliff-linux-arm64/-/git-cliff-linux-arm64-2.7.0.tgz", + "integrity": "sha512-kuJz+hL+nDqmK2E3/uahufdAHKjn76F0rv/oZpaQgUSmdE8vy9x1J28YSoXTlXIr0BfuzZjxCKrrfr8b7wU/Xw==", "cpu": [ "arm64" ], @@ -20923,9 +20346,9 @@ ] }, "node_modules/git-cliff-linux-x64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/git-cliff-linux-x64/-/git-cliff-linux-x64-2.5.0.tgz", - "integrity": "sha512-jvyfCRy758iHRvbsM6VmGWqOm0OczQLDI/r6w/OdAoRIt5vQiZJbJFJaMLqzEJRtN8g4hTrEZ+5EYbFY1BMVDQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/git-cliff-linux-x64/-/git-cliff-linux-x64-2.7.0.tgz", + "integrity": "sha512-0qHHPEsAo9HQZpifM9wdnjot90yB7C+LIHSFfGhkTsmzr/Daxnekt0um6mb3yEA7YuFnE9+c8mvLDoXlgJ5eaA==", "cpu": [ "x64" ], @@ -20936,9 +20359,9 @@ ] }, "node_modules/git-cliff-windows-arm64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/git-cliff-windows-arm64/-/git-cliff-windows-arm64-2.5.0.tgz", - "integrity": "sha512-t+5ikWPEJuVbDfVWU/Ckbno9qKA6FOQuM9gnRi7tjnXXDoEwdgwZVvCHB3p3dmcgzzmRA1RRAhS27CNJMTB42Q==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/git-cliff-windows-arm64/-/git-cliff-windows-arm64-2.7.0.tgz", + "integrity": "sha512-uq5qGuWkO6YCEGg9nDk3butX0F80hfICsBh6LWicL9bfpyfEzdSbuv4AS1hJ2jTIjqRMOP2NRSii4pM9bqjfsw==", "cpu": [ "arm64" ], @@ -20949,9 +20372,9 @@ ] }, "node_modules/git-cliff-windows-x64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/git-cliff-windows-x64/-/git-cliff-windows-x64-2.5.0.tgz", - "integrity": "sha512-rKCowa6k79bdujEa9/s+PSk3M5ViNZISFp4NK+0Ac6yoCDN0ylgvhHRUhSoxLjJ73an40Rg+I83Q92HPKklVGw==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/git-cliff-windows-x64/-/git-cliff-windows-x64-2.7.0.tgz", + "integrity": "sha512-WOoKrlYvRMaWcEdQZD1I+Pg+W6yjztxzUkid7qqyum6J2e21kfw8asL5gDnTX9rZAKu+MV29/zG7RdFqKD2qsA==", "cpu": [ "x64" ], @@ -21156,14 +20579,12 @@ } }, "node_modules/globals": { - "version": "13.24.0", + "version": "15.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", + "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -21334,6 +20755,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -21345,6 +20767,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, "dependencies": { "dunder-proto": "^1.0.0" }, @@ -21356,8 +20779,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "license": "MIT", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "engines": { "node": ">= 0.4" }, @@ -21477,13 +20901,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "7.18.3", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/hpack.js": { "version": "2.1.6", "dev": true, @@ -21840,11 +21257,6 @@ "dev": true, "license": "ISC" }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" - }, "node_modules/immer": { "version": "9.0.21", "dev": true, @@ -21870,9 +21282,9 @@ } }, "node_modules/import-in-the-middle": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.11.0.tgz", - "integrity": "sha512-5DimNQGoe0pLUHbR9qK84iWaWjjbsxiqXnw6Qz64+azRgleqv9k2kTt5fw7QsOpmaGYtuxxursnPPsnTKEx10Q==", + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.11.2.tgz", + "integrity": "sha512-gK6Rr6EykBcc6cVWRSBR5TWf8nn6hZMYSRYqCcHa0l0d1fPK7JSYo6+Mlmck76jIX9aL/IZ71c06U2VpFwl1zA==", "dependencies": { "acorn": "^8.8.2", "acorn-import-attributes": "^1.9.5", @@ -21950,16 +21362,19 @@ }, "node_modules/int64-buffer": { "version": "0.1.10", + "resolved": "https://registry.npmjs.org/int64-buffer/-/int64-buffer-0.1.10.tgz", + "integrity": "sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==", "license": "MIT" }, "node_modules/internal-slot": { - "version": "1.0.7", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", "dev": true, - "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" + "hasown": "^2.0.2", + "side-channel": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -22003,12 +21418,14 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.4", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -22022,12 +21439,15 @@ "license": "MIT" }, "node_modules/is-async-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", - "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.0.tgz", + "integrity": "sha512-GExz9MtyhlZyXYLxzlJRj5WUCE661zhDa1Yna52CN57AJsymh+DvXXjyveSioqSRdxvUrdKdvqB1b5cVKsNpWQ==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -22037,11 +21457,15 @@ } }, "node_modules/is-bigint": { - "version": "1.0.4", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", "dev": true, - "license": "MIT", "dependencies": { - "has-bigints": "^1.0.1" + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -22058,12 +21482,13 @@ } }, "node_modules/is-boolean-object": { - "version": "1.1.2", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", + "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -22117,11 +21542,13 @@ } }, "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", "dev": true, "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", "is-typed-array": "^1.1.13" }, "engines": { @@ -22132,11 +21559,13 @@ } }, "node_modules/is-date-object": { - "version": "1.0.5", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", "dev": true, - "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -22166,12 +21595,12 @@ } }, "node_modules/is-finalizationregistry": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.0.tgz", - "integrity": "sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", "dev": true, "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -22196,12 +21625,15 @@ } }, "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -22237,18 +21669,6 @@ "dev": true, "license": "MIT" }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", "license": "MIT", @@ -22257,11 +21677,13 @@ } }, "node_modules/is-number-object": { - "version": "1.0.7", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", "dev": true, - "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -22280,8 +21702,9 @@ }, "node_modules/is-path-inside": { "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=8" } @@ -22314,12 +21737,15 @@ "license": "MIT" }, "node_modules/is-regex": { - "version": "1.1.4", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -22357,12 +21783,12 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", "dev": true, "dependencies": { - "call-bind": "^1.0.7" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -22382,11 +21808,13 @@ } }, "node_modules/is-string": { - "version": "1.0.7", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", "dev": true, - "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -22396,11 +21824,14 @@ } }, "node_modules/is-symbol": { - "version": "1.0.4", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", "dev": true, - "license": "MIT", "dependencies": { - "has-symbols": "^1.0.2" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -22410,12 +21841,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "dependencies": { - "which-typed-array": "^1.1.14" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -22442,24 +21873,28 @@ } }, "node_modules/is-weakref": { - "version": "1.0.2", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", + "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2" + "call-bound": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "engines": { "node": ">= 0.4" @@ -22587,15 +22022,20 @@ } }, "node_modules/iterator.prototype": { - "version": "1.1.2", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", "dev": true, - "license": "MIT", "dependencies": { - "define-properties": "^1.2.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "reflect.getprototypeof": "^1.0.4", - "set-function-name": "^2.0.1" + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/jackspeak": { @@ -24437,6 +23877,12 @@ "bignumber.js": "^9.0.0" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "dev": true, @@ -24561,6 +24007,15 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "dev": true, @@ -24653,14 +24108,16 @@ "license": "MIT" }, "node_modules/language-subtag-registry": { - "version": "0.3.22", - "dev": true, - "license": "CC0-1.0" + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true }, "node_modules/language-tags": { "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", "dev": true, - "license": "MIT", "dependencies": { "language-subtag-registry": "^0.3.20" }, @@ -24735,14 +24192,6 @@ "node": ">= 0.8.0" } }, - "node_modules/lie": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", - "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", - "dependencies": { - "immediate": "~3.0.5" - } - }, "node_modules/lilconfig": { "version": "2.1.0", "dev": true, @@ -24759,12 +24208,12 @@ "license": "MIT" }, "node_modules/lint-staged": { - "version": "15.2.11", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.11.tgz", - "integrity": "sha512-Ev6ivCTYRTGs9ychvpVw35m/bcNDuBN+mnTeObCL5h+boS5WzBEC6LHI4I9F/++sZm1m+J2LEiy0gxL/R9TBqQ==", + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.3.0.tgz", + "integrity": "sha512-vHFahytLoF2enJklgtOtCtIjZrKD/LoxlaUusd5nh7dWv/dkKQJY74ndFSzxCdv7g0ueGg1ORgTSt4Y9LPZn9A==", "dev": true, "dependencies": { - "chalk": "~5.3.0", + "chalk": "~5.4.1", "commander": "~12.1.0", "debug": "~4.4.0", "execa": "~8.0.1", @@ -25090,29 +24539,6 @@ "node": ">=8.9.0" } }, - "node_modules/local-pkg": { - "version": "0.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "mlly": "^1.4.2", - "pkg-types": "^1.0.3" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/localforage": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", - "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", - "dependencies": { - "lie": "3.1.1" - } - }, "node_modules/locate-path": { "version": "6.0.0", "dev": true, @@ -25393,12 +24819,11 @@ } }, "node_modules/loupe": { - "version": "2.3.7", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } + "license": "MIT" }, "node_modules/lower-case": { "version": "2.0.2", @@ -25413,19 +24838,24 @@ "dev": true, "license": "0BSD" }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, "node_modules/magic-string": { - "version": "0.30.10", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, - "node_modules/magic-string/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "dev": true, - "license": "MIT" - }, "node_modules/mailgun.js": { "version": "8.2.1", "license": "MIT", @@ -25469,6 +24899,14 @@ "tmpl": "1.0.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/md5": { "version": "2.3.0", "license": "BSD-3-Clause", @@ -25701,17 +25139,6 @@ "dev": true, "license": "MIT" }, - "node_modules/mlly": { - "version": "1.7.1", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.1.1", - "ufo": "^1.5.3" - } - }, "node_modules/module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", @@ -25723,6 +25150,8 @@ }, "node_modules/msgpack-lite": { "version": "0.1.26", + "resolved": "https://registry.npmjs.org/msgpack-lite/-/msgpack-lite-0.1.26.tgz", + "integrity": "sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==", "license": "MIT", "dependencies": { "event-lite": "^0.1.1", @@ -25736,6 +25165,8 @@ }, "node_modules/msgpack-lite/node_modules/isarray": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "license": "MIT" }, "node_modules/multer": { @@ -25819,12 +25250,6 @@ "react-dom": "*" } }, - "node_modules/nano-css/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true - }, "node_modules/nano-css/node_modules/css-tree": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", @@ -25883,8 +25308,9 @@ }, "node_modules/natural-compare-lite": { "version": "1.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true }, "node_modules/negotiator": { "version": "0.6.3", @@ -25914,7 +25340,8 @@ }, "node_modules/node-addon-api": { "version": "6.1.0", - "license": "MIT" + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" }, "node_modules/node-cron": { "version": "3.0.3", @@ -25979,7 +25406,8 @@ }, "node_modules/node-gyp-build": { "version": "3.9.0", - "license": "MIT", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.9.0.tgz", + "integrity": "sha512-zLcTg6P4AbcHPq465ZMFNXx7XpKKJh+7kkN699NiQWisR2uWYOWNWqRHAmbnmKiL4e9aLSlmy5U7rEMUXV59+A==", "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", @@ -25998,9 +25426,9 @@ "dev": true }, "node_modules/nodemon": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", - "integrity": "sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz", + "integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==", "dev": true, "dependencies": { "chokidar": "^3.5.2", @@ -26212,13 +25640,16 @@ } }, "node_modules/object.assign": { - "version": "4.1.5", + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.5", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", "object-keys": "^1.1.1" }, "engines": { @@ -26229,13 +25660,14 @@ } }, "node_modules/object.entries": { - "version": "1.1.7", + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz", + "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -26291,25 +25723,14 @@ "node": ">= 0.4" } }, - "node_modules/object.hasown": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, @@ -26437,6 +25858,23 @@ "node": ">= 0.8.0" } }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/p-limit": { "version": "3.1.0", "license": "MIT", @@ -26731,15 +26169,19 @@ }, "node_modules/pathe": { "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "dev": true, "license": "MIT" }, "node_modules/pathval": { - "version": "1.1.1", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">= 14.16" } }, "node_modules/pause": { @@ -26941,16 +26383,6 @@ "node": ">=8" } }, - "node_modules/pkg-types": { - "version": "1.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "confbox": "^0.1.7", - "mlly": "^1.7.0", - "pathe": "^1.1.2" - } - }, "node_modules/pkg-up": { "version": "3.1.0", "dev": true, @@ -28332,30 +27764,6 @@ "renderkid": "^3.0.0" } }, - "node_modules/pretty-format": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/prism-react-renderer": { "version": "1.3.5", "dev": true, @@ -29288,19 +28696,19 @@ } }, "node_modules/reflect.getprototypeof": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.8.tgz", - "integrity": "sha512-B5dj6usc5dkk8uFliwjwDHM8To5/QwdKz9JcBZ8Ic4G1f0YmeeJTtE/ZTdgRFPAfxZFiUaPhZ1Jcs4qeagItGQ==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "dev": true, "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", - "dunder-proto": "^1.0.0", - "es-abstract": "^1.23.5", + "es-abstract": "^1.23.9", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "gopd": "^1.2.0", - "which-builtin-type": "^1.2.0" + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -29871,14 +29279,15 @@ "license": "0BSD" }, "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, "engines": { @@ -29911,14 +29320,37 @@ ], "license": "MIT" }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/safe-regex-test": { - "version": "1.0.3", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.6", + "call-bound": "^1.0.2", "es-errors": "^1.3.0", - "is-regex": "^1.1.4" + "is-regex": "^1.2.1" }, "engines": { "node": ">= 0.4" @@ -30425,6 +29857,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -30460,6 +29893,20 @@ "node": ">=6.9" } }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "license": "ISC" @@ -30502,13 +29949,65 @@ } }, "node_modules/side-channel": { - "version": "1.0.6", - "license": "MIT", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dependencies": { - "call-bind": "^1.0.7", "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -30519,6 +30018,8 @@ }, "node_modules/siginfo": { "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, @@ -30895,6 +30396,8 @@ }, "node_modules/stackback": { "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, @@ -31025,7 +30528,9 @@ } }, "node_modules/std-env": { - "version": "3.7.0", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", "dev": true, "license": "MIT" }, @@ -31131,8 +30636,9 @@ }, "node_modules/string-natural-compare": { "version": "3.0.1", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/string-natural-compare/-/string-natural-compare-3.0.1.tgz", + "integrity": "sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw==", + "dev": true }, "node_modules/string-width": { "version": "4.2.3", @@ -31159,35 +30665,70 @@ "node": ">=8" } }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/string.prototype.matchall": { - "version": "4.0.10", + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "regexp.prototype.flags": "^1.5.0", - "set-function-name": "^2.0.0", - "side-channel": "^1.0.4" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -31197,15 +30738,19 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", "define-properties": "^1.2.1", "es-object-atoms": "^1.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -31307,22 +30852,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-literal": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "js-tokens": "^9.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/strip-literal/node_modules/js-tokens": { - "version": "9.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/strip-outer": { "version": "1.0.1", "license": "MIT", @@ -32198,12 +31727,33 @@ "dev": true }, "node_modules/tinybench": { - "version": "2.6.0", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", "dev": true, "license": "MIT" }, "node_modules/tinypool": { - "version": "0.8.4", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", "dev": true, "license": "MIT", "engines": { @@ -32211,7 +31761,9 @@ } }, "node_modules/tinyspy": { - "version": "2.2.1", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", "dev": true, "license": "MIT", "engines": { @@ -32343,14 +31895,15 @@ "license": "MIT" }, "node_modules/ts-api-utils": { - "version": "1.3.0", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz", + "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==", "dev": true, - "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/ts-easing": { @@ -32449,17 +32002,6 @@ "version": "2.6.3", "license": "0BSD" }, - "node_modules/ts-json-schema-generator/node_modules/typescript": { - "version": "5.4.5", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/ts-node": { "version": "10.9.1", "license": "MIT", @@ -32760,8 +32302,9 @@ }, "node_modules/tsutils": { "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, - "license": "MIT", "dependencies": { "tslib": "^1.8.1" }, @@ -32773,9 +32316,9 @@ } }, "node_modules/tsx": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.0.tgz", - "integrity": "sha512-bV30kM7bsLZKZIOCHeMNVMJ32/LuJzLVajkQI/qf92J2Qr08ueLQvW00PUZGiuLPP760UINwupgUj8qrSCPUKg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", + "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", "devOptional": true, "dependencies": { "esbuild": "~0.23.0", @@ -32880,11 +32423,12 @@ } }, "node_modules/type-fest": { - "version": "0.20.2", + "version": "4.32.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.32.0.tgz", + "integrity": "sha512-rfgpoi08xagF3JSdtJlCwMq9DGNDE0IMh3Mkpc1wUypg9vPi786AiqeBBKcqvIkq42azsBM85N490fyZjeUftw==", "dev": true, - "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=10" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -32902,30 +32446,30 @@ } }, "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" } }, "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -32935,18 +32479,18 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz", - "integrity": "sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "reflect.getprototypeof": "^1.0.6" + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" }, "engines": { "node": ">= 0.4" @@ -32988,8 +32532,9 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "license": "Apache-2.0", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -32998,10 +32543,27 @@ "node": ">=14.17" } }, - "node_modules/ufo": { - "version": "1.5.3", + "node_modules/typescript-eslint": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.19.1.tgz", + "integrity": "sha512-LKPUQpdEMVOeKluHi8md7rwLcoXHhwvWp3x+sJkMuq3gGm9yaYJtPo8sRZSblMFJ5pcOGCAak/scKf1mvZDlQw==", "dev": true, - "license": "MIT" + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.19.1", + "@typescript-eslint/parser": "8.19.1", + "@typescript-eslint/utils": "8.19.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } }, "node_modules/uid-safe": { "version": "2.1.5", @@ -33024,14 +32586,18 @@ } }, "node_modules/unbox-primitive": { - "version": "1.0.2", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", "dev": true, - "license": "MIT", "dependencies": { - "call-bind": "^1.0.2", + "call-bound": "^1.0.3", "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -33480,14 +33046,16 @@ } }, "node_modules/vite-node": { - "version": "1.6.0", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.8.tgz", + "integrity": "sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==", "dev": true, "license": "MIT", "dependencies": { "cac": "^6.7.14", - "debug": "^4.3.4", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", "vite": "^5.0.0" }, "bin": { @@ -33500,6 +33068,31 @@ "url": "https://opencollective.com/vitest" } }, + "node_modules/vite-node/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/vite-node/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, "node_modules/vite-plugin-svgr": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/vite-plugin-svgr/-/vite-plugin-svgr-4.2.0.tgz", @@ -34170,30 +33763,32 @@ } }, "node_modules/vitest": { - "version": "1.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "1.6.0", - "@vitest/runner": "1.6.0", - "@vitest/snapshot": "1.6.0", - "@vitest/spy": "1.6.0", - "@vitest/utils": "1.6.0", - "acorn-walk": "^8.3.2", - "chai": "^4.3.10", - "debug": "^4.3.4", - "execa": "^8.0.1", - "local-pkg": "^0.5.0", - "magic-string": "^0.30.5", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.5.0", - "strip-literal": "^2.0.0", - "tinybench": "^2.5.1", - "tinypool": "^0.8.3", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.8.tgz", + "integrity": "sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.8", + "@vitest/mocker": "2.1.8", + "@vitest/pretty-format": "^2.1.8", + "@vitest/runner": "2.1.8", + "@vitest/snapshot": "2.1.8", + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "1.6.0", - "why-is-node-running": "^2.2.2" + "vite-node": "2.1.8", + "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" @@ -34207,8 +33802,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.6.0", - "@vitest/ui": "1.6.0", + "@vitest/browser": "2.1.8", + "@vitest/ui": "2.1.8", "happy-dom": "*", "jsdom": "*" }, @@ -34233,129 +33828,30 @@ } } }, - "node_modules/vitest/node_modules/execa": { - "version": "8.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/vitest/node_modules/get-stream": { - "version": "8.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/human-signals": { - "version": "5.0.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/vitest/node_modules/is-stream": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/mimic-fn": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/npm-run-path": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/onetime": { - "version": "6.0.0", + "node_modules/vitest/node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, "license": "MIT", "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/path-key": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" + "ms": "^2.1.3" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vitest/node_modules/signal-exit": { - "version": "4.1.0", - "dev": true, - "license": "ISC", "engines": { - "node": ">=14" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/vitest/node_modules/strip-final-newline": { - "version": "3.0.0", + "node_modules/vitest/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, "node_modules/w3c-hr-time": { "version": "1.0.2", @@ -34753,39 +34249,43 @@ } }, "node_modules/which-boxed-primitive": { - "version": "1.0.2", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", "dev": true, - "license": "MIT", "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-builtin-type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.0.tgz", - "integrity": "sha512-I+qLGQ/vucCby4tf5HsLmGueEla4ZhwTBSqaooS+Y0BuxN4Cp+okmGuV+8mXZ84KDI9BA+oklo+RzKg0ONdSUA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.7", + "call-bound": "^1.0.2", "function.prototype.name": "^1.1.6", "has-tostringtag": "^1.0.2", "is-async-function": "^2.0.0", - "is-date-object": "^1.0.5", + "is-date-object": "^1.1.0", "is-finalizationregistry": "^1.1.0", "is-generator-function": "^1.0.10", - "is-regex": "^1.1.4", + "is-regex": "^1.2.1", "is-weakref": "^1.0.2", "isarray": "^2.0.5", - "which-boxed-primitive": "^1.0.2", + "which-boxed-primitive": "^1.1.0", "which-collection": "^1.0.2", - "which-typed-array": "^1.1.15" + "which-typed-array": "^1.1.16" }, "engines": { "node": ">= 0.4" @@ -34825,15 +34325,16 @@ "dev": true }, "node_modules/which-typed-array": { - "version": "1.1.16", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.16.tgz", - "integrity": "sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", "dev": true, "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", "for-each": "^0.3.3", - "gopd": "^1.0.1", + "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, "engines": { @@ -34844,7 +34345,9 @@ } }, "node_modules/why-is-node-running": { - "version": "2.2.2", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { @@ -35583,9 +35086,9 @@ } }, "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "version": "3.24.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz", + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==", "funding": { "url": "https://github.com/sponsors/colinhacks" } @@ -35619,9 +35122,9 @@ } }, "node_modules/zx": { - "version": "8.1.4", - "resolved": "https://registry.npmjs.org/zx/-/zx-8.1.4.tgz", - "integrity": "sha512-QFDYYpnzdpRiJ3dL2102Cw26FpXpWshW4QLTGxiYfIcwdAqg084jRCkK/kuP/NOSkxOjydRwNFG81qzA5r1a6w==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/zx/-/zx-8.3.0.tgz", + "integrity": "sha512-L8mY3yfJwo3a8ZDD6f9jZzAcRWJZYcV8GauZmBxLB/aSTwaMzMIEVpPp2Kyx+7yF0gdvuxKnMxAZRft9UCawiw==", "dev": true, "bin": { "zx": "build/cli.js" @@ -35654,9 +35157,9 @@ "@nangohq/nango-yaml": "0.48.1", "@nangohq/shared": "^0.48.1", "@swc/core": "^1.5.25", - "ajv": "^8.12.0", + "ajv": "^8.17.1", "ajv-errors": "^3.0.0", - "axios": "^1.7.4", + "axios": "^1.7.9", "chalk": "^5.3.0", "chokidar": "^3.5.3", "commander": "^10.0.1", @@ -35675,8 +35178,8 @@ "ts-json-schema-generator": "^2.3.0", "ts-node": "^10.9.1", "tsup": "^8.1.0", - "typescript": "^5.3.3", - "zod": "3.23.8" + "typescript": "5.7.3", + "zod": "3.24.1" }, "bin": { "nango": "dist/index.js" @@ -35700,20 +35203,21 @@ "esbuild": "^0.17.19", "json-schema": "0.4.0", "strip-ansi": "7.1.0", - "vitest": "1.6.0" + "vitest": "2.1.8" }, "engines": { "node": ">=18.0" } }, "packages/cli/node_modules/ajv": { - "version": "8.12.0", - "license": "MIT", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -35827,10 +35331,10 @@ "tailwind-merge": "2.5.4", "tailwindcss": "3.4.14", "tailwindcss-animate": "1.0.7", - "typescript": "5.5.3", + "typescript": "5.7.3", "vite": "5.4.6", "vite-plugin-svgr": "4.2.0", - "zod": "3.23.8", + "zod": "3.24.1", "zustand": "5.0.0-rc.2" } }, @@ -35898,19 +35402,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/connect-ui/node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "packages/connect-ui/node_modules/zustand": { "version": "5.0.0-rc.2", "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.0-rc.2.tgz", @@ -35961,8 +35452,8 @@ "tarn": "3.0.2" }, "devDependencies": { - "typescript": "5.3.3", - "vitest": "1.6.0" + "typescript": "5.7.3", + "vitest": "2.1.8" } }, "packages/fleet": { @@ -35975,7 +35466,144 @@ }, "devDependencies": { "@nangohq/types": "file:../types", - "vitest": "1.6.0" + "vitest": "2.1.8" + } + }, + "packages/fleet/node_modules/@datadog/native-appsec": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", + "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=16" + } + }, + "packages/fleet/node_modules/@datadog/native-iast-rewriter": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", + "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", + "license": "Apache-2.0", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">= 10" + } + }, + "packages/fleet/node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "packages/fleet/node_modules/@datadog/native-iast-taint-tracking": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", + "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "packages/fleet/node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "packages/fleet/node_modules/@datadog/pprof": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", + "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, + "packages/fleet/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "packages/fleet/node_modules/dd-trace": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", + "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/native-appsec": "8.0.1", + "@datadog/native-iast-rewriter": "2.4.1", + "@datadog/native-iast-taint-tracking": "3.1.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.3.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.8.1", + "int64-buffer": "^0.1.9", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "packages/fleet/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" } }, "packages/frontend": { @@ -36018,19 +35646,147 @@ "@nangohq/types": "file:../types", "@nangohq/utils": "file:../utils", "@nangohq/webhooks": "file:../webhooks", - "axios": "^1.7.4", + "axios": "^1.7.9", "dd-trace": "5.21.0", "express": "4.20.0", "get-port": "7.1.0", "node-cron": "3.0.3", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@types/node": "^20.12.2", - "nodemon": "3.1.7", - "type-fest": "4.26.1", - "typescript": "5.3.3", - "vitest": "1.6.0" + "nodemon": "3.1.9", + "type-fest": "4.32.0", + "typescript": "5.7.3", + "vitest": "2.1.8" + } + }, + "packages/jobs/node_modules/@datadog/native-appsec": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", + "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=16" + } + }, + "packages/jobs/node_modules/@datadog/native-iast-rewriter": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", + "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", + "license": "Apache-2.0", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">= 10" + } + }, + "packages/jobs/node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "packages/jobs/node_modules/@datadog/native-iast-taint-tracking": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", + "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "packages/jobs/node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "packages/jobs/node_modules/@datadog/pprof": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", + "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, + "packages/jobs/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "packages/jobs/node_modules/dd-trace": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", + "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/native-appsec": "8.0.1", + "@datadog/native-iast-rewriter": "2.4.1", + "@datadog/native-iast-taint-tracking": "3.1.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.3.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.8.1", + "int64-buffer": "^0.1.9", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" } }, "packages/jobs/node_modules/get-port": { @@ -36043,16 +35799,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/jobs/node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", - "dev": true, + "packages/jobs/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 4" } }, "packages/keystore": { @@ -36065,7 +35818,144 @@ }, "devDependencies": { "@nangohq/types": "file:../types", - "vitest": "1.6.0" + "vitest": "2.1.8" + } + }, + "packages/keystore/node_modules/@datadog/native-appsec": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", + "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=16" + } + }, + "packages/keystore/node_modules/@datadog/native-iast-rewriter": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", + "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", + "license": "Apache-2.0", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">= 10" + } + }, + "packages/keystore/node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "packages/keystore/node_modules/@datadog/native-iast-taint-tracking": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", + "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "packages/keystore/node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "packages/keystore/node_modules/@datadog/pprof": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", + "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, + "packages/keystore/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "packages/keystore/node_modules/dd-trace": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", + "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/native-appsec": "8.0.1", + "@datadog/native-iast-rewriter": "2.4.1", + "@datadog/native-iast-taint-tracking": "3.1.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.3.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.8.1", + "int64-buffer": "^0.1.9", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "packages/keystore/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" } }, "packages/kvstore": { @@ -36076,7 +35966,7 @@ "redis": "4.6.13" }, "devDependencies": { - "vitest": "1.6.0" + "vitest": "2.1.8" } }, "packages/logs": { @@ -36093,12 +35983,12 @@ "@opentelemetry/sdk-trace-base": "1.27.0", "@opentelemetry/sdk-trace-node": "1.27.0", "@opentelemetry/semantic-conventions": "1.27.0", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@nangohq/types": "file:../types", - "type-fest": "4.26.1", - "vitest": "1.6.0" + "type-fest": "4.32.0", + "vitest": "2.1.8" } }, "packages/logs/node_modules/@opentelemetry/api-logs": { @@ -36299,18 +36189,6 @@ "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "packages/logs/node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/nango-yaml": { "name": "@nangohq/nango-yaml", "version": "0.48.1", @@ -36320,7 +36198,7 @@ }, "devDependencies": { "@nangohq/types": "0.48.1", - "vitest": "1.6.0" + "vitest": "2.1.8" } }, "packages/nango-yaml/node_modules/ms": { @@ -36335,12 +36213,12 @@ "version": "0.48.1", "license": "SEE LICENSE IN LICENSE FILE IN GIT REPOSITORY", "dependencies": { - "axios": "^1.7.4" + "axios": "^1.7.9" }, "devDependencies": { "@nangohq/types": "0.48.1", "tsup": "^8.2.4", - "vitest": "1.6.0" + "vitest": "2.1.8" }, "engines": { "node": ">=18.0" @@ -36356,13 +36234,141 @@ "express": "4.20.0", "get-port": "7.1.0", "p-queue": "8.0.1", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@nangohq/types": "file:../types", "@types/node": "20.12.2", - "type-fest": "4.26.1", - "vitest": "1.6.0" + "type-fest": "4.32.0", + "vitest": "2.1.8" + } + }, + "packages/orchestrator/node_modules/@datadog/native-appsec": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", + "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=16" + } + }, + "packages/orchestrator/node_modules/@datadog/native-iast-rewriter": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", + "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", + "license": "Apache-2.0", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">= 10" + } + }, + "packages/orchestrator/node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "packages/orchestrator/node_modules/@datadog/native-iast-taint-tracking": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", + "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "packages/orchestrator/node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "packages/orchestrator/node_modules/@datadog/pprof": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", + "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, + "packages/orchestrator/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "packages/orchestrator/node_modules/dd-trace": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", + "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/native-appsec": "8.0.1", + "@datadog/native-iast-rewriter": "2.4.1", + "@datadog/native-iast-taint-tracking": "3.1.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.3.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.8.1", + "int64-buffer": "^0.1.9", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" } }, "packages/orchestrator/node_modules/get-port": { @@ -36375,16 +36381,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/orchestrator/node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", - "dev": true, + "packages/orchestrator/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 4" } }, "packages/persist": { @@ -36400,13 +36403,141 @@ "@nangohq/utils": "file:../utils", "dd-trace": "5.21.0", "express": "^4.20.0", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@types/node": "20.12.2", "node-fetch": "^3.3.2", - "typescript": "5.3.3", - "vitest": "1.6.0" + "typescript": "5.7.3", + "vitest": "2.1.8" + } + }, + "packages/persist/node_modules/@datadog/native-appsec": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", + "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=16" + } + }, + "packages/persist/node_modules/@datadog/native-iast-rewriter": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", + "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", + "license": "Apache-2.0", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">= 10" + } + }, + "packages/persist/node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "packages/persist/node_modules/@datadog/native-iast-taint-tracking": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", + "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "packages/persist/node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "packages/persist/node_modules/@datadog/pprof": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", + "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, + "packages/persist/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "packages/persist/node_modules/dd-trace": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", + "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/native-appsec": "8.0.1", + "@datadog/native-iast-rewriter": "2.4.1", + "@datadog/native-iast-taint-tracking": "3.1.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.3.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.8.1", + "int64-buffer": "^0.1.9", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" } }, "packages/persist/node_modules/node-fetch": { @@ -36426,6 +36557,15 @@ "url": "https://opencollective.com/node-fetch" } }, + "packages/persist/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "packages/records": { "name": "@nangohq/records", "version": "1.0.0", @@ -36439,7 +36579,7 @@ }, "devDependencies": { "@types/md5": "2.3.2", - "vitest": "1.6.0" + "vitest": "2.1.8" } }, "packages/runner": { @@ -36451,7 +36591,7 @@ "@nangohq/utils": "file:../utils", "@trpc/client": "^10.45.1", "@trpc/server": "^10.45.1", - "axios": "^1.7.4", + "axios": "^1.7.9", "botbuilder": "4.23.1", "connect-timeout": "1.9.0", "dd-trace": "5.21.0", @@ -36459,14 +36599,101 @@ "soap": "1.1.2", "superjson": "2.2.1", "undici": "6.12.0", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@nangohq/types": "file:../types", "@types/connect-timeout": "0.0.39", "@types/node": "20.12.2", - "typescript": "5.3.3", - "vitest": "1.6.0" + "typescript": "5.7.3", + "vitest": "2.1.8" + } + }, + "packages/runner/node_modules/@datadog/native-appsec": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", + "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=16" + } + }, + "packages/runner/node_modules/@datadog/native-iast-rewriter": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", + "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", + "license": "Apache-2.0", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">= 10" + } + }, + "packages/runner/node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "packages/runner/node_modules/@datadog/native-iast-taint-tracking": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", + "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "packages/runner/node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "packages/runner/node_modules/@datadog/pprof": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", + "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, + "packages/runner/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" } }, "packages/runner/node_modules/@trpc/client": { @@ -36486,6 +36713,56 @@ ], "license": "MIT" }, + "packages/runner/node_modules/dd-trace": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", + "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/native-appsec": "8.0.1", + "@datadog/native-iast-rewriter": "2.4.1", + "@datadog/native-iast-taint-tracking": "3.1.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.3.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.8.1", + "int64-buffer": "^0.1.9", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "packages/runner/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "packages/scheduler": { "name": "@nangohq/scheduler", "version": "1.0.0", @@ -36496,20 +36773,145 @@ "uuidv7": "0.6.3" }, "devDependencies": { - "type-fest": "4.26.1", - "vitest": "1.6.0" + "type-fest": "4.32.0", + "vitest": "2.1.8" } }, - "packages/scheduler/node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", - "dev": true, + "packages/scheduler/node_modules/@datadog/native-appsec": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", + "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + }, "engines": { "node": ">=16" + } + }, + "packages/scheduler/node_modules/@datadog/native-iast-rewriter": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", + "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", + "license": "Apache-2.0", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 10" + } + }, + "packages/scheduler/node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "packages/scheduler/node_modules/@datadog/native-iast-taint-tracking": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", + "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "packages/scheduler/node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "packages/scheduler/node_modules/@datadog/pprof": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", + "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, + "packages/scheduler/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "packages/scheduler/node_modules/dd-trace": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", + "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/native-appsec": "8.0.1", + "@datadog/native-iast-rewriter": "2.4.1", + "@datadog/native-iast-taint-tracking": "3.1.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.3.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.8.1", + "int64-buffer": "^0.1.9", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "packages/scheduler/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" } }, "packages/server": { @@ -36529,7 +36931,7 @@ "@nangohq/utils": "file:../utils", "@nangohq/webhooks": "file:../webhooks", "@workos-inc/node": "6.2.0", - "axios": "^1.7.4", + "axios": "^1.7.9", "body-parser": "1.20.3", "connect-session-knex": "4.0.0", "cookie-parser": "1.4.6", @@ -36556,7 +36958,7 @@ "simple-oauth2": "5.1.0", "uuid": "9.0.0", "ws": "8.18.0", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@types/cookie-parser": "1.4.3", @@ -36576,16 +36978,103 @@ "@types/uuid": "8.3.4", "@types/ws": "8.5.4", "get-port": "7.1.0", - "nodemon": "3.1.7", - "type-fest": "4.26.1", - "typescript": "5.3.3", - "vitest": "1.6.0" + "nodemon": "3.1.9", + "type-fest": "4.32.0", + "typescript": "5.7.3", + "vitest": "2.1.8" }, "engines": { "node": ">=18.0", "npm": ">=6.14.11" } }, + "packages/server/node_modules/@datadog/native-appsec": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", + "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=16" + } + }, + "packages/server/node_modules/@datadog/native-iast-rewriter": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", + "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", + "license": "Apache-2.0", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">= 10" + } + }, + "packages/server/node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "packages/server/node_modules/@datadog/native-iast-taint-tracking": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", + "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "packages/server/node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "packages/server/node_modules/@datadog/pprof": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", + "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, + "packages/server/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, "packages/server/node_modules/@types/express": { "version": "4.17.13", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", @@ -36607,6 +37096,47 @@ "@types/node": "*" } }, + "packages/server/node_modules/dd-trace": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", + "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/native-appsec": "8.0.1", + "@datadog/native-iast-rewriter": "2.4.1", + "@datadog/native-iast-taint-tracking": "3.1.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.3.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.8.1", + "int64-buffer": "^0.1.9", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" + } + }, "packages/server/node_modules/dotenv": { "version": "16.0.3", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", @@ -36645,16 +37175,13 @@ "uuid": "dist/bin/uuid" } }, - "packages/server/node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", - "dev": true, + "packages/server/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 4" } }, "packages/server/node_modules/uuid": { @@ -36681,11 +37208,10 @@ "@nangohq/nango-yaml": "0.48.1", "@nangohq/node": "^0.48.1", "@nangohq/utils": "file:../utils", - "@sentry/node": "^7.119.2", - "ajv": "^8.12.0", + "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "archiver": "^6.0.1", - "axios": "^1.7.4", + "axios": "^1.7.9", "braintree": "^3.15.0", "dd-trace": "5.21.0", "exponential-backoff": "^3.1.1", @@ -36708,7 +37234,6 @@ "@nangohq/logs": "file:../logs", "@nangohq/nango-orchestrator": "file:../orchestrator", "@nangohq/types": "0.48.1", - "@sentry/types": "7.112.2", "@types/braintree": "^3.3.12", "@types/js-yaml": "^4.0.5", "@types/json-schema": "7.0.15", @@ -36719,15 +37244,93 @@ "express": "^4.20.0", "json-schema": "0.4.0", "knex": "3.1.0", - "type-fest": "4.26.1", - "typescript": "^5.3.3", - "vitest": "1.6.0" + "type-fest": "4.32.0", + "typescript": "5.7.3", + "vitest": "2.1.8" }, "engines": { "node": ">=18.0", "npm": ">=6.14.11" } }, + "packages/shared/node_modules/@datadog/native-appsec": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", + "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=16" + } + }, + "packages/shared/node_modules/@datadog/native-iast-rewriter": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", + "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", + "license": "Apache-2.0", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">= 10" + } + }, + "packages/shared/node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "packages/shared/node_modules/@datadog/native-iast-taint-tracking": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", + "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "packages/shared/node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "packages/shared/node_modules/@datadog/pprof": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", + "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, "packages/shared/node_modules/@nangohq/database": { "version": "1.0.0", "resolved": "file:packages/shared/vendor/nangohq-database-1.0.0.tgz", @@ -39024,12 +39627,13 @@ "url": "https://github.com/sponsors/colinhacks" } }, - "packages/shared/node_modules/@sentry/types": { - "version": "7.112.2", - "dev": true, - "license": "MIT", + "packages/shared/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, "packages/shared/node_modules/@types/uuid": { @@ -39038,13 +39642,14 @@ "license": "MIT" }, "packages/shared/node_modules/ajv": { - "version": "8.16.0", - "license": "MIT", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -39155,6 +39760,47 @@ "node": ">= 12.0.0" } }, + "packages/shared/node_modules/dd-trace": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", + "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/native-appsec": "8.0.1", + "@datadog/native-iast-rewriter": "2.4.1", + "@datadog/native-iast-taint-tracking": "3.1.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.3.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.8.1", + "int64-buffer": "^0.1.9", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" + } + }, "packages/shared/node_modules/fast-xml-parser": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", @@ -39201,6 +39847,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "packages/shared/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "packages/shared/node_modules/tar-stream": { "version": "3.1.6", "license": "MIT", @@ -39210,18 +39865,6 @@ "streamx": "^2.15.0" } }, - "packages/shared/node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "packages/shared/node_modules/zip-stream": { "version": "5.0.1", "license": "MIT", @@ -39243,21 +39886,9 @@ "license": "SEE LICENSE IN LICENSE FILE IN GIT REPOSITORY", "devDependencies": { "@types/json-schema": "7.0.15", - "axios": "^1.7.4", + "axios": "^1.7.9", "json-schema": "0.4.0", - "type-fest": "4.26.1" - } - }, - "packages/types/node_modules/type-fest": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", - "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type-fest": "4.32.0" } }, "packages/utils": { @@ -39266,7 +39897,7 @@ "license": "SEE LICENSE IN LICENSE FILE IN GIT REPOSITORY", "dependencies": { "@colors/colors": "1.6.0", - "axios": "^1.7.4", + "axios": "^1.7.9", "dd-trace": "5.21.0", "exponential-backoff": "3.1.1", "fast-safe-stringify": "2.1.1", @@ -39276,13 +39907,100 @@ "serialize-error": "11.0.3", "truncate-json": "3.0.0", "winston": "3.13.0", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@nangohq/types": "file:../types", "express": "^4.20.0", "ms": "3.0.0-canary.1", - "vitest": "1.6.0" + "vitest": "2.1.8" + } + }, + "packages/utils/node_modules/@datadog/native-appsec": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@datadog/native-appsec/-/native-appsec-8.0.1.tgz", + "integrity": "sha512-SpWkoo7K4+pwxFze1ogRF1qBaKm8sZjWfZKnQ8Ex67f6L5odLjWOoiiIAs5rp01sLKGXjxU8IJf+X9j4PvI2zQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=16" + } + }, + "packages/utils/node_modules/@datadog/native-iast-rewriter": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-rewriter/-/native-iast-rewriter-2.4.1.tgz", + "integrity": "sha512-j3auTmyyn63e2y+SL28CGNy/l+jXQyh+pxqoGTacWaY5FW/dvo5nGQepAismgJ3qJ8VhQfVWRdxBSiT7wu9clw==", + "license": "Apache-2.0", + "dependencies": { + "lru-cache": "^7.14.0", + "node-gyp-build": "^4.5.0" + }, + "engines": { + "node": ">= 10" + } + }, + "packages/utils/node_modules/@datadog/native-iast-rewriter/node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "packages/utils/node_modules/@datadog/native-iast-taint-tracking": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@datadog/native-iast-taint-tracking/-/native-iast-taint-tracking-3.1.0.tgz", + "integrity": "sha512-rw6qSjmxmu1yFHVvZLXFt/rVq2tUZXocNogPLB8n7MPpA0jijNGb109WokWw5ITImiW91GcGDuBW6elJDVKouQ==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-gyp-build": "^3.9.0" + } + }, + "packages/utils/node_modules/@datadog/native-metrics": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@datadog/native-metrics/-/native-metrics-2.0.0.tgz", + "integrity": "sha512-YklGVwUtmKGYqFf1MNZuOHvTYdKuR4+Af1XkWcMD8BwOAjxmd9Z+97328rCOY8TFUJzlGUPaXzB8j2qgG/BMwA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "node-addon-api": "^6.1.0", + "node-gyp-build": "^3.9.0" + }, + "engines": { + "node": ">=12" + } + }, + "packages/utils/node_modules/@datadog/pprof": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.3.0.tgz", + "integrity": "sha512-53z2Q3K92T6Pf4vz4Ezh8kfkVEvLzbnVqacZGgcbkP//q0joFzO8q00Etw1S6NdnCX0XmX08ULaF4rUI5r14mw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "delay": "^5.0.0", + "node-gyp-build": "<4.0", + "p-limit": "^3.1.0", + "pprof-format": "^2.1.0", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=14" + } + }, + "packages/utils/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" } }, "packages/utils/node_modules/agent-base": { @@ -39295,6 +40013,47 @@ "node": ">= 14" } }, + "packages/utils/node_modules/dd-trace": { + "version": "5.21.0", + "resolved": "https://registry.npmjs.org/dd-trace/-/dd-trace-5.21.0.tgz", + "integrity": "sha512-3jgrYxifuYmSl3kuAxpTSOS7/kKK9DLbw4m85hS/Yn5IFCXer+uvG8sWwFIcBNXOidF/BcyeKC92WX4X87W4Iw==", + "hasInstallScript": true, + "license": "(Apache-2.0 OR BSD-3-Clause)", + "dependencies": { + "@datadog/native-appsec": "8.0.1", + "@datadog/native-iast-rewriter": "2.4.1", + "@datadog/native-iast-taint-tracking": "3.1.0", + "@datadog/native-metrics": "^2.0.0", + "@datadog/pprof": "5.3.0", + "@datadog/sketches-js": "^2.1.0", + "@opentelemetry/api": ">=1.0.0 <1.9.0", + "@opentelemetry/core": "^1.14.0", + "crypto-randomuuid": "^1.0.0", + "dc-polyfill": "^0.1.4", + "ignore": "^5.2.4", + "import-in-the-middle": "^1.8.1", + "int64-buffer": "^0.1.9", + "istanbul-lib-coverage": "3.2.0", + "jest-docblock": "^29.7.0", + "koalas": "^1.0.2", + "limiter": "1.1.5", + "lodash.sortby": "^4.7.0", + "lru-cache": "^7.14.0", + "module-details-from-path": "^1.0.3", + "msgpack-lite": "^0.1.26", + "opentracing": ">=0.12.1", + "path-to-regexp": "^0.1.2", + "pprof-format": "^2.1.0", + "protobufjs": "^7.2.5", + "retry": "^0.13.1", + "semver": "^7.5.4", + "shell-quote": "^1.8.1", + "tlhunter-sorted-set": "^0.1.0" + }, + "engines": { + "node": ">=18" + } + }, "packages/utils/node_modules/http-proxy-agent": { "version": "7.0.2", "license": "MIT", @@ -39325,6 +40084,15 @@ "node": ">=12.13" } }, + "packages/utils/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "packages/webapp": { "name": "@nangohq/webapp", "version": "1.0.0", @@ -39384,13 +40152,45 @@ "swr": "2.2.5", "tailwind-merge": "2.5.4", "tailwindcss": "3.4.14", - "typescript": "5.3.3", + "typescript": "5.7.3", "vaul": "0.9.1", "web-vitals": "2.1.4", "webpack": "5.94.0", "zustand": "4.5.5" } }, + "packages/webapp/node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/webapp/node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "packages/webapp/node_modules/@mantine/core": { "version": "7.12.1", "resolved": "https://registry.npmjs.org/@mantine/core/-/core-7.12.1.tgz", @@ -39972,104 +40772,324 @@ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { - "@types/react": { + "@types/react": { + "optional": true + } + } + }, + "packages/webapp/node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-presence": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", + "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", + "dev": true, + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "packages/webapp/node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "dev": true, + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "packages/webapp/node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "dev": true, + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "packages/webapp/node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "dev": true, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "packages/webapp/node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "dev": true, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "packages/webapp/node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "packages/webapp/node_modules/@typescript-eslint/experimental-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz", + "integrity": "sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "packages/webapp/node_modules/@typescript-eslint/parser": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { "optional": true } } }, - "packages/webapp/node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-presence": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", - "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", + "packages/webapp/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "packages/webapp/node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", - "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "packages/webapp/node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "dependencies": { - "@radix-ui/react-slot": "1.1.0" + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "eslint": "*" }, "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { + "typescript": { "optional": true } } }, - "packages/webapp/node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", - "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "packages/webapp/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "packages/webapp/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependenciesMeta": { - "@types/react": { + "typescript": { "optional": true } } }, - "packages/webapp/node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", - "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "packages/webapp/node_modules/@typescript-eslint/utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "packages/webapp/node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": ">=8.0.0" } }, - "packages/webapp/node_modules/@radix-ui/react-scroll-area/node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", - "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "packages/webapp/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "packages/webapp/node_modules/babel-loader": { @@ -40090,6 +41110,22 @@ "webpack": ">=2" } }, + "packages/webapp/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "packages/webapp/node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -40133,6 +41169,18 @@ "url": "https://github.com/sponsors/kossnocorp" } }, + "packages/webapp/node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, "packages/webapp/node_modules/dotenv": { "version": "10.0.0", "dev": true, @@ -40149,6 +41197,228 @@ "node": ">=6" } }, + "packages/webapp/node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/webapp/node_modules/eslint-config-react-app": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.1.tgz", + "integrity": "sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.16.0", + "@babel/eslint-parser": "^7.16.3", + "@rushstack/eslint-patch": "^1.1.0", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "babel-preset-react-app": "^10.0.1", + "confusing-browser-globals": "^1.0.11", + "eslint-plugin-flowtype": "^8.0.3", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jest": "^25.3.0", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.27.1", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-testing-library": "^5.0.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "eslint": "^8.0.0" + } + }, + "packages/webapp/node_modules/eslint-plugin-flowtype": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz", + "integrity": "sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21", + "string-natural-compare": "^3.0.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@babel/plugin-syntax-flow": "^7.14.5", + "@babel/plugin-transform-react-jsx": "^7.14.9", + "eslint": "^8.1.0" + } + }, + "packages/webapp/node_modules/eslint-plugin-jest": { + "version": "25.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-25.7.0.tgz", + "integrity": "sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.0.0 || ^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "packages/webapp/node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "packages/webapp/node_modules/eslint-plugin-testing-library": { + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.11.1.tgz", + "integrity": "sha512-5eX9e1Kc2PqVRed3taaLnAAqPZGEX75C+M/rXzUAI3wIg/ZxzUm1OVAwfe/O+vE+6YXOLetSe9g5GKD2ecXipw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^5.58.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0", + "npm": ">=6" + }, + "peerDependencies": { + "eslint": "^7.5.0 || ^8.0.0" + } + }, + "packages/webapp/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/webapp/node_modules/eslint-scope/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "packages/webapp/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/webapp/node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "packages/webapp/node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, "packages/webapp/node_modules/fs-extra": { "version": "10.1.0", "dev": true, @@ -40162,6 +41432,33 @@ "node": ">=12" } }, + "packages/webapp/node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/webapp/node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "packages/webapp/node_modules/iconv-lite": { "version": "0.6.3", "dev": true, @@ -40197,6 +41494,41 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "packages/webapp/node_modules/jest-worker": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "packages/webapp/node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "packages/webapp/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "packages/webapp/node_modules/postcss-loader": { "version": "8.1.1", "dev": true, @@ -40299,6 +41631,34 @@ } } }, + "packages/webapp/node_modules/react-scripts/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "packages/webapp/node_modules/react-scripts/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, "packages/webapp/node_modules/react-scripts/node_modules/cosmiconfig": { "version": "7.1.0", "dev": true, @@ -40314,6 +41674,30 @@ "node": ">=10" } }, + "packages/webapp/node_modules/react-scripts/node_modules/eslint-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-3.2.0.tgz", + "integrity": "sha512-avrKcGncpPbPSUHX6B3stNGzkKFto3eL+DKM4+VyMrVnhPc3vRczVlCq3uhuFOdRvDHTVXuzwk1ZKUrqDQHQ9w==", + "dev": true, + "dependencies": { + "@types/eslint": "^7.29.0 || ^8.4.1", + "jest-worker": "^28.0.2", + "micromatch": "^4.0.5", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0", + "webpack": "^5.0.0" + } + }, "packages/webapp/node_modules/react-scripts/node_modules/postcss-loader": { "version": "6.2.1", "dev": true, @@ -40335,6 +41719,25 @@ "webpack": "^5.0.0" } }, + "packages/webapp/node_modules/react-scripts/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "packages/webapp/node_modules/react-toastify": { "version": "9.1.1", "dev": true, @@ -40355,6 +41758,22 @@ "node": ">=6" } }, + "packages/webapp/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "packages/webapp/node_modules/schema-utils": { "version": "2.7.1", "dev": true, @@ -40414,29 +41833,6 @@ "dev": true, "license": "0BSD" }, - "packages/webapp/node_modules/type-fest": { - "version": "4.18.2", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "packages/webapp/node_modules/typescript": { - "version": "4.9.5", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "packages/webapp/node_modules/yaml": { "version": "1.10.2", "dev": true, @@ -40451,14 +41847,14 @@ "dependencies": { "@nangohq/logs": "file:../logs", "@nangohq/utils": "file:../utils", - "axios": "^1.7.4", + "axios": "^1.7.9", "dayjs": "1.11.7", "dayjs-plugin-utc": "0.1.2" }, "devDependencies": { "@nangohq/types": "file:../types", - "typescript": "5.3.3", - "vitest": "1.6.0" + "typescript": "5.7.3", + "vitest": "2.1.8" } }, "packages/webhooks/node_modules/dayjs": { @@ -40470,24 +41866,24 @@ "name": "@nangohq/scripts", "devDependencies": { "@apidevtools/swagger-cli": "4.0.4", - "ajv": "8.12.0", - "chalk": "5.3.0", - "git-cliff": "2.5.0", + "ajv": "8.17.1", + "chalk": "5.4.1", + "git-cliff": "2.7.0", "js-yaml": "4.1.0", "webflow-api": "3.0.1", - "zx": "8.1.4" + "zx": "8.3.0" } }, "scripts/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", diff --git a/package.json b/package.json index 881fe208e56..0aa79f5fbe6 100644 --- a/package.json +++ b/package.json @@ -11,27 +11,22 @@ "undo:migration": "cd packages/database/lib && knex migrate:rollback --esm --knexfile ./knexfile.cjs", "prettier-format": "prettier --config .prettierrc \"./**/*.{ts,tsx}\" --write", "prettier-watch": "onchange './**/*.{ts,tsx}' -- prettier --write {{changed}}", - "lint": "eslint . --ext .ts,.tsx", - "lint:fix": "eslint . --ext .ts,.tsx --fix", + "lint": "eslint . ", + "lint:fix": "eslint . --fix", "ts-build": "tsc -b tsconfig.build.json", "ts-build:docker": "tsc -b tsconfig.docker.json", "ts-clean": "npx rimraf packages/*/tsconfig.tsbuildinfo packages/*/dist", "docker-build": "docker build -f packages/server/Dockerfile -t nango-server:latest .", - "webapp-build:hosted": "cd ./packages/webapp && npm run build:hosted && cd ../..", - "webapp-build:staging": "cd ./packages/webapp && npm run build:staging && cd ../..", - "webapp-build:prod": "cd ./packages/webapp && npm run build:prod && cd ../..", - "webapp-build:enterprise": "cd ./packages/webapp && npm run build:enterprise && cd ../..", + "webapp-build": "cd ./packages/webapp && npm run build && cd ../..", "webapp-build:watch": "tsc -b -w packages/webapp/tsconfig.json", "docker-build:unified": "./scripts/build_docker.sh", - "build:hosted": "npm ci && npm run ts-build && npm run webapp-build:hosted && npm run connect-ui:build", - "build:staging": "npm ci && npm run ts-build && npm run webapp-build:staging", - "build:prod": "npm ci && npm run ts-build && npm run webapp-build:prod", - "build:enterprise": "npm ci && npm run ts-build && npm run webapp-build:enterprise", + "build:hosted": "npm ci && npm run ts-build && npm run webapp-build && npm run connect-ui:build", + "build:prod": "npm ci && npm run ts-build && npm run webapp-build", "server:dev:watch": "cd ./packages/server && npm run dev", "jobs:dev:watch": "npm run dev -w @nangohq/nango-jobs", "persist:dev:watch": "npm run dev -w @nangohq/nango-persist", "orchestrator:dev:watch": "npm run dev -w @nangohq/nango-orchestrator", - "webapp:dev:watch": "cd ./packages/webapp && npm run start:local", + "webapp:dev:watch": "cd ./packages/webapp && npm run start", "connect-ui:dev:watch": "cd ./packages/connect-ui && npm run dev", "connect-ui:build": "npm run -w @nangohq/connect-ui build", "prepare": "husky install", @@ -54,28 +49,30 @@ "dev:docker": "docker compose --file dev/docker-compose.dev.yaml up -d" }, "devDependencies": { - "@tsconfig/node18-strictest-esm": "1.0.1", + "@eslint/js": "9.17.0", "@types/node": "20.12.2", - "@typescript-eslint/eslint-plugin": "7.18.0", - "@typescript-eslint/parser": "7.18.0", + "@typescript-eslint/eslint-plugin": "8.19.1", + "@typescript-eslint/parser": "8.19.1", "concurrently": "8.2.2", - "eslint": "8.56.0", + "eslint": "9.17.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-import": "2.31.0", "eslint-plugin-prettier": "5.2.1", - "eslint-plugin-react": "7.33.2", - "eslint-plugin-react-hooks": "4.6.0", + "eslint-plugin-react": "7.37.3", + "eslint-plugin-react-hooks": "5.1.0", "eslint-plugin-unicorn": "56.0.1", + "globals": "15.14.0", "husky": "8.0.3", - "js-yaml": "^4.1.0", - "lint-staged": "15.2.11", + "js-yaml": "4.1.0", + "lint-staged": "15.3.0", "onchange": "7.1.0", "prettier": "3.4.2", "rimraf": "6.0.1", "testcontainers": "9.12.0", - "tsx": "4.19.0", - "typescript": "5.3.3", - "vitest": "1.6.0" + "tsx": "4.19.2", + "typescript": "5.7.3", + "typescript-eslint": "8.19.1", + "vitest": "2.1.8" }, "lint-staged": { "*.{js,jsx,ts,tsx,cjs}": [ diff --git a/packages/cli/.gitignore b/packages/cli/.gitignore deleted file mode 100644 index 2ea55edb2ed..00000000000 --- a/packages/cli/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -dist/* -tsconfig.tsbuildinfo -nango-integrations -node_modules -nango-data diff --git a/packages/cli/docker/docker-compose.yaml b/packages/cli/docker/docker-compose.yaml deleted file mode 100644 index 27a672eb753..00000000000 --- a/packages/cli/docker/docker-compose.yaml +++ /dev/null @@ -1,134 +0,0 @@ -version: '3.9' -services: - nango-db: - image: postgres:16.0-alpine - container_name: nango-db - environment: - POSTGRES_PASSWORD: nango - POSTGRES_USER: nango - POSTGRES_DB: nango - ports: - - '${NANGO_DB_PORT:-5432}:5432' - volumes: - - ./nango-data:/var/lib/postgresql/data - networks: - - nango - - nango-server: - image: nangohq/nango-server:hosted - container_name: nango-server - platform: linux/amd64 - environment: - - NANGO_ENCRYPTION_KEY=${NANGO_ENCRYPTION_KEY} - - NANGO_DB_USER=${NANGO_DB_USER} - - NANGO_DB_PASSWORD=${NANGO_DB_PASSWORD} - - NANGO_DB_HOST=${NANGO_DB_HOST} - - NANGO_DB_NAME=${NANGO_DB_NAME} - - NANGO_DB_SSL=${NANGO_DB_SSL} - - NANGO_DB_ADDITIONAL_SCHEMAS=${NANGO_DB_ADDITIONAL_SCHEMAS} - - NANGO_DB_POOL_MIN=${NANGO_DB_POOL_MIN} - - NANGO_DB_POOL_MAX=${NANGO_DB_POOL_MAX} - - NANGO_PORT=${NANGO_PORT:-3003} - - SERVER_PORT=${NANGO_PORT:-3003} - - NANGO_SERVER_URL=${NANGO_SERVER_URL:-http://localhost:3003} - - NANGO_DASHBOARD_USERNAME=${NANGO_DASHBOARD_USERNAME} - - NANGO_DASHBOARD_PASSWORD=${NANGO_DASHBOARD_PASSWORD} - - LOG_LEVEL=${LOG_LEVEL:-info} - - TELEMETRY=${TELEMETRY} - - NANGO_SERVER_WEBSOCKETS_PATH=${NANGO_SERVER_WEBSOCKETS_PATH} - - RECORDS_DATABASE_URL=${RECORDS_DATABASE_URL:-postgresql://nango:nango@nango-db:5432/nango} - - NANGO_LOGS_ENABLED=${NANGO_LOGS_ENABLED:-false} - - NANGO_LOGS_ES_URL=${NANGO_LOGS_ES_URL:-http://nango-elasticsearch:9200} - - NANGO_LOGS_ES_USER=${NANGO_LOGS_ES_USER} - - NANGO_LOGS_ES_PWD=${NANGO_LOGS_ES_PWD} - restart: always - ports: - - '${NANGO_PORT:-3003}:${NANGO_PORT:-3003}' - depends_on: - - nango-db - # - nango-elasticsearch - volumes: - - '${NANGO_INTEGRATIONS_LOCATION:-./}:/usr/nango-server/src/packages/shared/dist/nango-integrations' - networks: - - nango - - nango-jobs: - image: nangohq/nango-jobs:production - container_name: nango-jobs - platform: linux/amd64 - restart: always - ports: - - '${WORKER_PORT:-3004}:${WORKER_PORT:-3004}' - environment: - - NANGO_ENCRYPTION_KEY=${NANGO_ENCRYPTION_KEY} - - NANGO_DB_USER=${NANGO_DB_USER} - - NANGO_DB_PASSWORD=${NANGO_DB_PASSWORD} - - NANGO_DB_HOST=${NANGO_DB_HOST} - - NANGO_DB_NAME=${NANGO_DB_NAME} - - NANGO_DB_SSL=${NANGO_DB_SSL} - - RECORDS_DATABASE_URL=${RECORDS_DATABASE_URL:-postgresql://nango:nango@nango-db:5432/nango} - - NANGO_LOGS_ENABLED=${NANGO_LOGS_ENABLED:-false} - - NANGO_LOGS_ES_URL=${NANGO_LOGS_ES_URL:-http://nango-elasticsearch:9200} - - NANGO_LOGS_ES_USER=${NANGO_LOGS_ES_USER} - - NANGO_LOGS_ES_PWD=${NANGO_LOGS_ES_PWD} - - ORCHESTRATOR_SERVICE_URL=${ORCHESTRATOR_SERVICE_URL} - depends_on: - - nango-db - # - nango-elasticsearch - volumes: - - '${NANGO_INTEGRATIONS_LOCATION:-./}:/usr/nango-jobs/src/packages/shared/dist/nango-integrations' - networks: - - nango - - nango-persist: - image: nangohq/nango-persist:production - container_name: nango-persist - platform: linux/amd64 - restart: always - ports: - - '${PERSIST_PORT:-3007}:${PERSIST_PORT:-3007}' - environment: - - NANGO_ENCRYPTION_KEY=${NANGO_ENCRYPTION_KEY} - - NANGO_DB_USER=${NANGO_DB_USER} - - NANGO_DB_PASSWORD=${NANGO_DB_PASSWORD} - - NANGO_DB_HOST=${NANGO_DB_HOST} - - NANGO_DB_NAME=${NANGO_DB_NAME} - - NANGO_DB_SSL=${NANGO_DB_SSL} - - RECORDS_DATABASE_URL=${RECORDS_DATABASE_URL:-postgresql://nango:nango@nango-db:5432/nango} - - NANGO_LOGS_ENABLED=${NANGO_LOGS_ENABLED:-false} - - NANGO_LOGS_ES_URL=${NANGO_LOGS_ES_URL:-http://nango-elasticsearch:9200} - - NANGO_LOGS_ES_USER=${NANGO_LOGS_ES_USER} - - NANGO_LOGS_ES_PWD=${NANGO_LOGS_ES_PWD} - depends_on: - - nango-db - # - nango-elasticsearch - networks: - - nango - - # - # Optional dependency - # To load elasticsearch, set NANGO_LOGS_ENABLED=true in nango-server and uncomment this dependency - # nango-elasticsearch: - # image: elasticsearch:8.13.0 - # container_name: nango-elasticsearch - # ulimits: - # memlock: - # soft: -1 - # hard: -1 - # volumes: - # - elasticsearch-data1:/usr/share/elasticsearch/data - # ports: - # - 9500:9200 - # - 9600:9300 - # environment: - # - discovery.type=single-node - # - xpack.security.enabled=false - # networks: - # - nango - -networks: - nango: - -volumes: - elasticsearch-data1: - driver: local diff --git a/packages/cli/lib/cli.ts b/packages/cli/lib/cli.ts index 85e085408bf..330794986da 100644 --- a/packages/cli/lib/cli.ts +++ b/packages/cli/lib/cli.ts @@ -5,8 +5,6 @@ import chalk from 'chalk'; import chokidar from 'chokidar'; import ejs from 'ejs'; import * as dotenv from 'dotenv'; -import { spawn } from 'child_process'; -import type { ChildProcess } from 'node:child_process'; import { getNangoRootPath, printDebug } from './utils.js'; import { loadYamlAndGenerate } from './services/model.service.js'; @@ -292,50 +290,3 @@ export function configWatch({ fullPath, debug = false }: { fullPath: string; deb loadYamlAndGenerate({ fullPath, debug }); }); } - -let child: ChildProcess | undefined; -process.on('SIGINT', () => { - if (child) { - const dockerDown = spawn('docker', ['compose', '-f', path.join(getNangoRootPath(), 'docker/docker-compose.yaml'), '--project-directory', '.', 'down'], { - stdio: 'inherit' - }); - dockerDown.on('exit', () => { - process.exit(); - }); - } else { - process.exit(); - } -}); - -/** - * Docker Run - * @desc spawn a child process to run the docker compose located in the cli - * Look into https://www.npmjs.com/package/docker-compose to avoid dependency maybe? - */ -export const dockerRun = async (debug = false) => { - const cwd = process.cwd(); - - const args = ['compose', '-f', path.join(getNangoRootPath(), 'docker/docker-compose.yaml'), '--project-directory', '.', 'up', '--build']; - - if (debug) { - printDebug(`Running docker with args: ${args.join(' ')}`); - } - - child = spawn('docker', args, { - cwd, - detached: false, - stdio: 'inherit' - }); - - await new Promise((resolve, reject) => { - child?.on('exit', (code) => { - if (code !== 0) { - reject(new Error(`Error with the nango docker containers, please check your containers using 'docker ps''`)); - return; - } - resolve(true); - }); - - child?.on('error', reject); - }); -}; diff --git a/packages/cli/lib/index.ts b/packages/cli/lib/index.ts index e0de55e9407..54f391f8230 100644 --- a/packages/cli/lib/index.ts +++ b/packages/cli/lib/index.ts @@ -11,7 +11,7 @@ import figlet from 'figlet'; import path from 'path'; import * as dotenv from 'dotenv'; -import { init, generate, tscWatch, configWatch, dockerRun, version } from './cli.js'; +import { init, generate, tscWatch, configWatch, version } from './cli.js'; import deployService from './services/deploy.service.js'; import { compileAllFiles } from './services/compile.service.js'; import verificationService from './services/verification.service.js'; @@ -245,30 +245,6 @@ program } }); -program - .command('sync:dev', { hidden: true }) - .description('Work locally to develop integration code') - .option('--no-compile-interfaces', `Watch the ${nangoConfigFile} and recompile the interfaces on change`, true) - .action(async function (this: Command) { - const { compileInterfaces, autoConfirm, debug } = this.opts(); - const fullPath = process.cwd(); - await verificationService.necessaryFilesExist({ fullPath, autoConfirm, debug }); - if (compileInterfaces) { - configWatch({ fullPath, debug }); - } - - tscWatch({ fullPath, debug }); - await dockerRun(debug); - }); - -program - .command('sync:docker.run', { hidden: true }) - .description('Run the docker container locally') - .action(async function (this: Command) { - const { debug } = this.opts(); - await dockerRun(debug); - }); - program .command('sync:config.check', { hidden: true }) .alias('scc') diff --git a/packages/cli/lib/utils/result.ts b/packages/cli/lib/utils/result.ts index 58acd8982ff..d362d6f3297 100644 --- a/packages/cli/lib/utils/result.ts +++ b/packages/cli/lib/utils/result.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-type-parameters */ /* By convention Left represents a failed computation And Right represents a successful one @@ -26,8 +27,8 @@ export function Ok(value: T): Result { return { value, unwrap: () => value, - isErr: () => false, - isOk: () => true, + isErr: (): this is Left => false, + isOk: (): this is Right => true, map: (fn: (value: T) => U): Result => { try { return Ok(fn(value)); @@ -47,8 +48,8 @@ export function Err(error: E | string): Result { unwrap: () => { throw error as Error; }, - isErr: () => true, - isOk: () => false, + isErr: (): this is Left => true, + isOk: (): this is Right => false, map: (_fn: (value: T) => U): Result => { return Err(error); }, diff --git a/packages/cli/package.json b/packages/cli/package.json index 2ce337fbff3..9dfeb6b771b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -27,9 +27,9 @@ "@nangohq/nango-yaml": "0.48.1", "@nangohq/shared": "^0.48.1", "@swc/core": "^1.5.25", - "ajv": "^8.12.0", + "ajv": "^8.17.1", "ajv-errors": "^3.0.0", - "axios": "^1.7.4", + "axios": "^1.7.9", "chalk": "^5.3.0", "chokidar": "^3.5.3", "commander": "^10.0.1", @@ -48,8 +48,8 @@ "ts-json-schema-generator": "^2.3.0", "ts-node": "^10.9.1", "tsup": "^8.1.0", - "typescript": "^5.3.3", - "zod": "3.23.8" + "typescript": "5.7.3", + "zod": "3.24.1" }, "devDependencies": { "@babel/core": "^7.22.1", @@ -70,7 +70,7 @@ "esbuild": "^0.17.19", "json-schema": "0.4.0", "strip-ansi": "7.1.0", - "vitest": "1.6.0" + "vitest": "2.1.8" }, "engines": { "node": ">=18.0" diff --git a/packages/cli/scripts/v1-v2.js b/packages/cli/scripts/v1-v2.js index b9bca60e329..3e9cb8df3b6 100755 --- a/packages/cli/scripts/v1-v2.js +++ b/packages/cli/scripts/v1-v2.js @@ -54,7 +54,6 @@ function convertYAML(inputYAML) { } data.integrations[integration].actions[taskName] = task; - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete data.integrations[integration][taskName]; } else if (task.runs) { change.type = 'sync'; @@ -102,7 +101,6 @@ function convertYAML(inputYAML) { } data.integrations[integration].syncs[taskName] = task; - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete data.integrations[integration][taskName]; } if (change.changes.length > 0) { diff --git a/packages/connect-ui/package.json b/packages/connect-ui/package.json index 15e24324cae..c4c80d8db4d 100644 --- a/packages/connect-ui/package.json +++ b/packages/connect-ui/package.json @@ -37,10 +37,10 @@ "tailwind-merge": "2.5.4", "tailwindcss": "3.4.14", "tailwindcss-animate": "1.0.7", - "typescript": "5.5.3", + "typescript": "5.7.3", "vite": "5.4.6", "vite-plugin-svgr": "4.2.0", - "zod": "3.23.8", + "zod": "3.24.1", "zustand": "5.0.0-rc.2" } } diff --git a/packages/connect-ui/src/views/Go.tsx b/packages/connect-ui/src/views/Go.tsx index fc5f772c0cc..0548028d0a6 100644 --- a/packages/connect-ui/src/views/Go.tsx +++ b/packages/connect-ui/src/views/Go.tsx @@ -327,12 +327,12 @@ export const Go: React.FC = () => {
- + {orderedFields.length > 0 && (
{orderedFields.map(([name]) => { const [type, key] = name.split('.') as ['credentials' | 'params', string]; - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const definition = provider[type === 'credentials' ? 'credentials' : 'connection_config']?.[key]; // Not all fields have a definition in providers.yaml so we fallback to default const base = name in defaultConfiguration ? defaultConfiguration[name] : undefined; diff --git a/packages/database/lib/getConfig.ts b/packages/database/lib/getConfig.ts index 96206a9cec4..77567655f3e 100644 --- a/packages/database/lib/getConfig.ts +++ b/packages/database/lib/getConfig.ts @@ -15,7 +15,8 @@ export function getDbConfig({ timeoutMs }: { timeoutMs: number }): Knex.Config { database: process.env['NANGO_DB_NAME'] || 'nango', password: process.env['NANGO_DB_PASSWORD'] || 'nango', ssl: process.env['NANGO_DB_SSL'] != null && process.env['NANGO_DB_SSL'].toLowerCase() === 'true' ? { rejectUnauthorized: false } : undefined, - statement_timeout: timeoutMs + statement_timeout: timeoutMs, + application_name: process.env['NANGO_DB_APPLICATION_NAME'] || '[unknown]' }, pool: { min: parseInt(process.env['NANGO_DB_POOL_MIN'] || '0'), diff --git a/packages/database/lib/knexfile.cjs b/packages/database/lib/knexfile.cjs index fc5cab26182..b0333df9c97 100644 --- a/packages/database/lib/knexfile.cjs +++ b/packages/database/lib/knexfile.cjs @@ -1,6 +1,5 @@ // Knex CLI for migration needs this Knexfile but doesn't play well with ESM modules. // That's why the content of the Knex config is moved to ./config.ts to be imported by the app in ESM-fashion, and the Knexfile is only used for the Knex CLI in CommonJS-fashion. -// eslint-disable-next-line @typescript-eslint/no-var-requires const { config } = require('../dist/config.js'); module.exports = config; diff --git a/packages/database/lib/migrations/20221026075018_create_connection.cjs b/packages/database/lib/migrations/20221026075018_create_connection.cjs index a6e172e51e7..49dfa162191 100644 --- a/packages/database/lib/migrations/20221026075018_create_connection.cjs +++ b/packages/database/lib/migrations/20221026075018_create_connection.cjs @@ -1,4 +1,4 @@ -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable('_nango_connections', function (table) { table.increments('id').primary(); table.timestamps(true, true); @@ -9,6 +9,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable('_nango_connections'); }; diff --git a/packages/database/lib/migrations/20221026075019_create_config.cjs b/packages/database/lib/migrations/20221026075019_create_config.cjs index 8dfe0450e3a..fd25c56b143 100644 --- a/packages/database/lib/migrations/20221026075019_create_config.cjs +++ b/packages/database/lib/migrations/20221026075019_create_config.cjs @@ -1,4 +1,4 @@ -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable('_nango_configs', function (table) { table.increments('id').primary(); table.timestamps(true, true); @@ -11,6 +11,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable('_nango_configs'); }; diff --git a/packages/database/lib/migrations/20221223094334_add_connection_config.cjs b/packages/database/lib/migrations/20221223094334_add_connection_config.cjs index 5dc3801cf9d..3b69a8daefe 100644 --- a/packages/database/lib/migrations/20221223094334_add_connection_config.cjs +++ b/packages/database/lib/migrations/20221223094334_add_connection_config.cjs @@ -1,10 +1,10 @@ -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable('_nango_connections', function (table) { table.jsonb('connection_config'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_connections', function (table) { table.dropColumn('connection_config'); }); diff --git a/packages/database/lib/migrations/20230121211135_alter_scope_type_in_config.cjs b/packages/database/lib/migrations/20230121211135_alter_scope_type_in_config.cjs index 01d17177bfa..89da01b3373 100644 --- a/packages/database/lib/migrations/20230121211135_alter_scope_type_in_config.cjs +++ b/packages/database/lib/migrations/20230121211135_alter_scope_type_in_config.cjs @@ -1,10 +1,10 @@ -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable('_nango_configs', function (table) { table.text('oauth_scopes').alter({ alterType: true }); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_configs', function (table) { table.string('oauth_scopes').alter({ alterType: true }); }); diff --git a/packages/database/lib/migrations/20230208124114_create_account.cjs b/packages/database/lib/migrations/20230208124114_create_account.cjs index 3d0cd294bf4..5faaf060e02 100644 --- a/packages/database/lib/migrations/20230208124114_create_account.cjs +++ b/packages/database/lib/migrations/20230208124114_create_account.cjs @@ -1,4 +1,4 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.raw('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"'); return knex.schema.createTable('_nango_accounts', function (table) { table.increments('id').primary(); @@ -12,6 +12,6 @@ exports.up = async function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable('_nango_accounts'); }; diff --git a/packages/database/lib/migrations/20230208124526_add_account_id_to_config.cjs b/packages/database/lib/migrations/20230208124526_add_account_id_to_config.cjs index 1ab7574a349..dd7f9b84d9d 100644 --- a/packages/database/lib/migrations/20230208124526_add_account_id_to_config.cjs +++ b/packages/database/lib/migrations/20230208124526_add_account_id_to_config.cjs @@ -1,4 +1,4 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.from(`_nango_accounts`).insert({ email: 'self-hosted', id: 0 }).onConflict(['id']).merge(); return knex.schema.alterTable('_nango_configs', function (table) { table.integer('account_id').references('id').inTable('_nango_accounts').defaultTo(0).notNullable(); @@ -7,7 +7,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_configs', function (table) { table.dropUnique(['unique_key', 'account_id']); table.unique('unique_key'); diff --git a/packages/database/lib/migrations/20230208124533_add_account_id_to_connection.cjs b/packages/database/lib/migrations/20230208124533_add_account_id_to_connection.cjs index db7b5c0252b..2c1d0f4e46b 100644 --- a/packages/database/lib/migrations/20230208124533_add_account_id_to_connection.cjs +++ b/packages/database/lib/migrations/20230208124533_add_account_id_to_connection.cjs @@ -1,4 +1,4 @@ -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable('_nango_connections', function (table) { table.integer('account_id').references('id').inTable('_nango_accounts').defaultTo(0).notNullable(); table.dropUnique(['provider_config_key', 'connection_id']); @@ -6,7 +6,7 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_connections', function (table) { table.dropColumn('account_id'); table.dropUnique(['provider_config_key', 'connection_id', 'account_id']); diff --git a/packages/database/lib/migrations/20230213163753_add_callback_to_account.cjs b/packages/database/lib/migrations/20230213163753_add_callback_to_account.cjs index 5d2c42473b3..df8376fb5fd 100644 --- a/packages/database/lib/migrations/20230213163753_add_callback_to_account.cjs +++ b/packages/database/lib/migrations/20230213163753_add_callback_to_account.cjs @@ -1,10 +1,10 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable('_nango_accounts', function (table) { table.text('callback_url'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_accounts', function (table) { table.dropColumn('callback_url'); }); diff --git a/packages/database/lib/migrations/20230217123640_add_metadata_to_connection.cjs b/packages/database/lib/migrations/20230217123640_add_metadata_to_connection.cjs index d0fbfd33a56..7cc236aefe4 100644 --- a/packages/database/lib/migrations/20230217123640_add_metadata_to_connection.cjs +++ b/packages/database/lib/migrations/20230217123640_add_metadata_to_connection.cjs @@ -1,10 +1,10 @@ -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable('_nango_connections', function (table) { table.jsonb('metadata'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_connections', function (table) { table.dropColumn('metadata'); }); diff --git a/packages/database/lib/migrations/20230225211916_create_user.cjs b/packages/database/lib/migrations/20230225211916_create_user.cjs index 3b7a86b3b4e..e085f0a66d0 100644 --- a/packages/database/lib/migrations/20230225211916_create_user.cjs +++ b/packages/database/lib/migrations/20230225211916_create_user.cjs @@ -1,4 +1,4 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.createTable('_nango_users', function (table) { table.increments('id').primary(); table.timestamps(true, true); @@ -11,6 +11,6 @@ exports.up = async function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable('_nango_users'); }; diff --git a/packages/database/lib/migrations/20230225211941_add_name_and_owner_to_account.cjs b/packages/database/lib/migrations/20230225211941_add_name_and_owner_to_account.cjs index b787eda54dd..e768247ab81 100644 --- a/packages/database/lib/migrations/20230225211941_add_name_and_owner_to_account.cjs +++ b/packages/database/lib/migrations/20230225211941_add_name_and_owner_to_account.cjs @@ -1,4 +1,4 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex .from(`_nango_users`) .insert({ id: 0, name: 'unknown', email: 'unknown@example.com', hashed_password: 'unkown', salt: 'unknown', account_id: 0 }) @@ -11,7 +11,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_accounts', function (table) { table.dropColumn('owner_id'); table.dropColumn('name'); diff --git a/packages/database/lib/migrations/20230307152421_add_reset_link_to_users.cjs b/packages/database/lib/migrations/20230307152421_add_reset_link_to_users.cjs index 002eba07f22..918598b03b7 100644 --- a/packages/database/lib/migrations/20230307152421_add_reset_link_to_users.cjs +++ b/packages/database/lib/migrations/20230307152421_add_reset_link_to_users.cjs @@ -1,10 +1,10 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable('_nango_users', function (table) { table.string('reset_password_token'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_users', function (table) { table.dropColumn('reset_password_token'); }); diff --git a/packages/database/lib/migrations/20230322233031_add_encryption_to_config.cjs b/packages/database/lib/migrations/20230322233031_add_encryption_to_config.cjs index 314553dcc4f..81cf9618ebc 100644 --- a/packages/database/lib/migrations/20230322233031_add_encryption_to_config.cjs +++ b/packages/database/lib/migrations/20230322233031_add_encryption_to_config.cjs @@ -1,11 +1,11 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable('_nango_configs', function (table) { table.string('oauth_client_secret_iv'); table.string('oauth_client_secret_tag'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_configs', function (table) { table.dropColumn('oauth_client_secret_iv'); table.dropColumn('oauth_client_secret_tag'); diff --git a/packages/database/lib/migrations/20230322233042_add_encryption_to_connection.cjs b/packages/database/lib/migrations/20230322233042_add_encryption_to_connection.cjs index 4c0daab9e33..601605f8366 100644 --- a/packages/database/lib/migrations/20230322233042_add_encryption_to_connection.cjs +++ b/packages/database/lib/migrations/20230322233042_add_encryption_to_connection.cjs @@ -1,11 +1,11 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable('_nango_connections', function (table) { table.string('credentials_iv'); table.string('credentials_tag'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_connections', function (table) { table.dropColumn('credentials_iv'); table.dropColumn('credentials_tag'); diff --git a/packages/database/lib/migrations/20230322233049_add_encryption_to_account.cjs b/packages/database/lib/migrations/20230322233049_add_encryption_to_account.cjs index 62e1d3c8d2f..4e0993d6dd4 100644 --- a/packages/database/lib/migrations/20230322233049_add_encryption_to_account.cjs +++ b/packages/database/lib/migrations/20230322233049_add_encryption_to_account.cjs @@ -1,11 +1,11 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable('_nango_accounts', function (table) { table.string('secret_key_iv'); table.string('secret_key_tag'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_accounts', function (table) { table.dropColumn('secret_key_iv'); table.dropColumn('secret_key_tag'); diff --git a/packages/database/lib/migrations/20230323011937_create_db_config.cjs b/packages/database/lib/migrations/20230323011937_create_db_config.cjs index 444b0858039..994dd7ac4fb 100644 --- a/packages/database/lib/migrations/20230323011937_create_db_config.cjs +++ b/packages/database/lib/migrations/20230323011937_create_db_config.cjs @@ -1,10 +1,10 @@ -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable('_nango_db_config', function (table) { table.string('encryption_key_hash'); table.boolean('encryption_complete').defaultTo(false); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable('_nango_db_config'); }; diff --git a/packages/database/lib/migrations/20230324135032_alter_secret_from_account.cjs b/packages/database/lib/migrations/20230324135032_alter_secret_from_account.cjs index d98e23c7cc3..8c85a3c49d0 100644 --- a/packages/database/lib/migrations/20230324135032_alter_secret_from_account.cjs +++ b/packages/database/lib/migrations/20230324135032_alter_secret_from_account.cjs @@ -1,10 +1,10 @@ -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable('_nango_accounts', function (table) { table.string('secret_key').defaultTo(knex.raw('uuid_generate_v4()')).alter({ alterType: true }); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_accounts', function (table) { table.uuid('secret_key').defaultTo(knex.raw('uuid_generate_v4()')).alter({ alterType: true }); }); diff --git a/packages/database/lib/migrations/20230326083713_create_oauth_session.cjs b/packages/database/lib/migrations/20230326083713_create_oauth_session.cjs index eca03c1f9eb..efab102e3a0 100644 --- a/packages/database/lib/migrations/20230326083713_create_oauth_session.cjs +++ b/packages/database/lib/migrations/20230326083713_create_oauth_session.cjs @@ -1,4 +1,4 @@ -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable('_nango_oauth_sessions', function (table) { table.uuid('id').notNullable(); table.string('provider_config_key').notNullable(); @@ -17,6 +17,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable('_nango_oauth_sessions'); }; diff --git a/packages/database/lib/migrations/20230510083713_activity_logging_table.cjs b/packages/database/lib/migrations/20230510083713_activity_logging_table.cjs index 294dbdbf081..3964466706b 100644 --- a/packages/database/lib/migrations/20230510083713_activity_logging_table.cjs +++ b/packages/database/lib/migrations/20230510083713_activity_logging_table.cjs @@ -1,7 +1,7 @@ const tableName = '_nango_activity_logs'; const messagesTableName = '_nango_activity_log_messages'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema .createTable(tableName, function (table) { table.increments('id').primary(); @@ -40,7 +40,7 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable(messagesTableName).then(() => { return knex.schema.dropTable(tableName); }); diff --git a/packages/database/lib/migrations/20230511090816_tickets.cjs b/packages/database/lib/migrations/20230511090816_tickets.cjs index 472e61e2fa9..c6608e31fb2 100644 --- a/packages/database/lib/migrations/20230511090816_tickets.cjs +++ b/packages/database/lib/migrations/20230511090816_tickets.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_unified_tickets'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable(tableName, function (table) { table.uuid('id').notNullable(); table.string('external_id').notNullable(); @@ -25,6 +25,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable(tableName); }; diff --git a/packages/database/lib/migrations/20230512090816_add_sync.cjs b/packages/database/lib/migrations/20230512090816_add_sync.cjs index e70fe9b8fa7..ee4a14eb0ea 100644 --- a/packages/database/lib/migrations/20230512090816_add_sync.cjs +++ b/packages/database/lib/migrations/20230512090816_add_sync.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_sync_jobs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable(tableName, function (table) { table.increments('id').primary(); table.integer('nango_connection_id').unsigned().notNullable(); @@ -13,6 +13,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable(tableName); }; diff --git a/packages/database/lib/migrations/20230513090816_add_sync_schedule.cjs b/packages/database/lib/migrations/20230513090816_add_sync_schedule.cjs index 71340be8579..d6b8f0b5dbe 100644 --- a/packages/database/lib/migrations/20230513090816_add_sync_schedule.cjs +++ b/packages/database/lib/migrations/20230513090816_add_sync_schedule.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_sync_schedules'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable(tableName, function (table) { table.increments('id').primary(); table.integer('nango_connection_id').references('id').inTable('_nango_connections').defaultTo(0).notNullable().onDelete('CASCADE'); @@ -11,6 +11,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable(tableName); }; diff --git a/packages/database/lib/migrations/20230516090816_add_sync_config.cjs b/packages/database/lib/migrations/20230516090816_add_sync_config.cjs index b524abb28b7..361c3b3d4fe 100644 --- a/packages/database/lib/migrations/20230516090816_add_sync_config.cjs +++ b/packages/database/lib/migrations/20230516090816_add_sync_config.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_sync_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable(tableName, function (table) { table.increments('id').primary(); table.integer('account_id').references('id').inTable('_nango_accounts').defaultTo(0).notNullable(); @@ -11,6 +11,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable(tableName); }; diff --git a/packages/database/lib/migrations/20230519080408_add_sync_data.cjs b/packages/database/lib/migrations/20230519080408_add_sync_data.cjs index c7756f83d6c..55d6495c4b8 100644 --- a/packages/database/lib/migrations/20230519080408_add_sync_data.cjs +++ b/packages/database/lib/migrations/20230519080408_add_sync_data.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_sync_data_records'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable(tableName, function (table) { table.uuid('id').notNullable(); table.string('external_id').notNullable(); @@ -38,6 +38,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable(tableName); }; diff --git a/packages/database/lib/migrations/20230525185131_update_data_records_uniqueness.cjs b/packages/database/lib/migrations/20230525185131_update_data_records_uniqueness.cjs index 38144594608..1ce8dfa15c2 100644 --- a/packages/database/lib/migrations/20230525185131_update_data_records_uniqueness.cjs +++ b/packages/database/lib/migrations/20230525185131_update_data_records_uniqueness.cjs @@ -1,13 +1,13 @@ const tableName = '_nango_sync_data_records'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.table(tableName, function (table) { table.dropUnique(['nango_connection_id', 'external_id']); table.unique(['nango_connection_id', 'external_id', 'model']); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropUnique(['nango_connection_id', 'external_id', 'model']); table.unique(['nango_connection_id', 'external_id']); diff --git a/packages/database/lib/migrations/20230529080846_field_mappings_per_connection.cjs b/packages/database/lib/migrations/20230529080846_field_mappings_per_connection.cjs index 73ec8dca45e..e911adced62 100644 --- a/packages/database/lib/migrations/20230529080846_field_mappings_per_connection.cjs +++ b/packages/database/lib/migrations/20230529080846_field_mappings_per_connection.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_connections'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable(tableName, function (table) { table.jsonb('field_mappings').defaultTo('{}'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.dropColumn('field_mappings'); }); diff --git a/packages/database/lib/migrations/20230529110419_sync_config_and_schedule_adjustments.cjs b/packages/database/lib/migrations/20230529110419_sync_config_and_schedule_adjustments.cjs index 5b76458e98f..0cae98c6a2c 100644 --- a/packages/database/lib/migrations/20230529110419_sync_config_and_schedule_adjustments.cjs +++ b/packages/database/lib/migrations/20230529110419_sync_config_and_schedule_adjustments.cjs @@ -1,7 +1,7 @@ const syncJobs = '_nango_sync_jobs'; const syncSchedules = '_nango_sync_schedules'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(syncJobs, function (table) { table.specificType('models', 'text ARRAY'); table.string('frequency'); @@ -13,7 +13,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(syncJobs, function (table) { table.dropColumn('models'); table.dropColumn('frequency'); diff --git a/packages/database/lib/migrations/20230529110450_sync_changes.cjs b/packages/database/lib/migrations/20230529110450_sync_changes.cjs index e4ab5ee8f39..e230319d859 100644 --- a/packages/database/lib/migrations/20230529110450_sync_changes.cjs +++ b/packages/database/lib/migrations/20230529110450_sync_changes.cjs @@ -3,7 +3,7 @@ const syncJobs = '_nango_sync_jobs'; const syncSchedules = '_nango_sync_schedules'; const syncDataRecords = '_nango_sync_data_records'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.createTable(syncs, function (table) { table.uuid('id').primary().notNullable(); table.integer('nango_connection_id').unsigned().notNullable(); @@ -36,7 +36,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(syncJobs, function (table) { table.dropColumn('sync_id'); table.integer('nango_connection_id').unsigned().notNullable(); diff --git a/packages/database/lib/migrations/20230529164653_index_on_model_for_sync_data_records.cjs b/packages/database/lib/migrations/20230529164653_index_on_model_for_sync_data_records.cjs index 26bef9fc514..60fbae703a6 100644 --- a/packages/database/lib/migrations/20230529164653_index_on_model_for_sync_data_records.cjs +++ b/packages/database/lib/migrations/20230529164653_index_on_model_for_sync_data_records.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_sync_data_records'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.table(tableName, function (table) { table.index('model'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropIndex('model'); }); diff --git a/packages/database/lib/migrations/20230531185120_operation_name_for_activity_log.cjs b/packages/database/lib/migrations/20230531185120_operation_name_for_activity_log.cjs index 797b683387c..38878a2e64e 100644 --- a/packages/database/lib/migrations/20230531185120_operation_name_for_activity_log.cjs +++ b/packages/database/lib/migrations/20230531185120_operation_name_for_activity_log.cjs @@ -1,12 +1,12 @@ const TABLE_NAME = '_nango_activity_logs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(TABLE_NAME, function (table) { table.string('operation_name'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable(TABLE_NAME, function (table) { table.dropColumn('operation_name'); }); diff --git a/packages/database/lib/migrations/20230601081230_activity_log_id_for_sync_job.cjs b/packages/database/lib/migrations/20230601081230_activity_log_id_for_sync_job.cjs index b7d0c9f5d44..00f3c1acc07 100644 --- a/packages/database/lib/migrations/20230601081230_activity_log_id_for_sync_job.cjs +++ b/packages/database/lib/migrations/20230601081230_activity_log_id_for_sync_job.cjs @@ -1,12 +1,12 @@ const TABLE_NAME = '_nango_sync_jobs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(TABLE_NAME, function (table) { table.integer('activity_log_id').references('id').inTable('_nango_activity_logs').onDelete('SET NULL'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable(TABLE_NAME, function (table) { table.dropColumn('activity_log_id'); }); diff --git a/packages/database/lib/migrations/20230602172423_add_offset_to_schedule.cjs b/packages/database/lib/migrations/20230602172423_add_offset_to_schedule.cjs index 4b7a8c2d20b..8333fad3ca7 100644 --- a/packages/database/lib/migrations/20230602172423_add_offset_to_schedule.cjs +++ b/packages/database/lib/migrations/20230602172423_add_offset_to_schedule.cjs @@ -1,12 +1,12 @@ const TABLE_NAME = '_nango_sync_schedules'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(TABLE_NAME, function (table) { table.integer('offset').defaultTo(0); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable(TABLE_NAME, function (table) { table.dropColumn('offset'); }); diff --git a/packages/database/lib/migrations/20230605073948_store_webhook_url_in_accounts.cjs b/packages/database/lib/migrations/20230605073948_store_webhook_url_in_accounts.cjs index 9dba0728e49..d988bdf0500 100644 --- a/packages/database/lib/migrations/20230605073948_store_webhook_url_in_accounts.cjs +++ b/packages/database/lib/migrations/20230605073948_store_webhook_url_in_accounts.cjs @@ -1,10 +1,10 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable('_nango_accounts', function (table) { table.text('webhook_url'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_accounts', function (table) { table.dropColumn('webhook_url'); }); diff --git a/packages/database/lib/migrations/20230605101533_sync_cloud_updates.cjs b/packages/database/lib/migrations/20230605101533_sync_cloud_updates.cjs index cf3b5759414..1175e90ed81 100644 --- a/packages/database/lib/migrations/20230605101533_sync_cloud_updates.cjs +++ b/packages/database/lib/migrations/20230605101533_sync_cloud_updates.cjs @@ -1,6 +1,6 @@ const syncConfigs = '_nango_sync_configs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(syncConfigs, function (table) { table.dropColumn('provider'); table.dropColumn('snippet'); @@ -12,7 +12,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(syncConfigs, function (table) { table.string('provider'); table.text('snippet'); diff --git a/packages/database/lib/migrations/20230605161639_sync_cloud_model_and_version.cjs b/packages/database/lib/migrations/20230605161639_sync_cloud_model_and_version.cjs index 134f01cea7c..195963aa3b0 100644 --- a/packages/database/lib/migrations/20230605161639_sync_cloud_model_and_version.cjs +++ b/packages/database/lib/migrations/20230605161639_sync_cloud_model_and_version.cjs @@ -1,6 +1,6 @@ const TABLE = '_nango_sync_configs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(TABLE, function (table) { table.dropColumn('integration_name'); table.string('version').notNullable(); @@ -8,7 +8,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(TABLE, function (table) { table.string('integration_name'); table.dropColumn('version'); diff --git a/packages/database/lib/migrations/20230606103939_sync_cloud_is_active_and_metadata.cjs b/packages/database/lib/migrations/20230606103939_sync_cloud_is_active_and_metadata.cjs index a406ac47b3a..c16028ae3f2 100644 --- a/packages/database/lib/migrations/20230606103939_sync_cloud_is_active_and_metadata.cjs +++ b/packages/database/lib/migrations/20230606103939_sync_cloud_is_active_and_metadata.cjs @@ -1,13 +1,13 @@ const TABLE = '_nango_sync_configs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(TABLE, function (table) { table.boolean('active').defaultTo(false); table.string('runs'); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(TABLE, function (table) { table.dropColumn('active'); table.dropColumn('runs'); diff --git a/packages/database/lib/migrations/20230612060608_store_models_in_sync_configs.cjs b/packages/database/lib/migrations/20230612060608_store_models_in_sync_configs.cjs index c97e03bdb60..545164c870c 100644 --- a/packages/database/lib/migrations/20230612060608_store_models_in_sync_configs.cjs +++ b/packages/database/lib/migrations/20230612060608_store_models_in_sync_configs.cjs @@ -1,12 +1,12 @@ const TABLE = '_nango_sync_configs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(TABLE, function (table) { table.jsonb('model_schema').defaultTo('{}'); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(TABLE, function (table) { table.dropColumn('model_schema'); }); diff --git a/packages/database/lib/migrations/20230613080214_link_sync_configs.cjs b/packages/database/lib/migrations/20230613080214_link_sync_configs.cjs index 7bebfc6f0b8..73ae09e7deb 100644 --- a/packages/database/lib/migrations/20230613080214_link_sync_configs.cjs +++ b/packages/database/lib/migrations/20230613080214_link_sync_configs.cjs @@ -2,7 +2,7 @@ const JOBS_TABLE = '_nango_sync_jobs'; const RECORDS_TABLE = '_nango_sync_data_records'; const CONFIGS_TABLE = '_nango_sync_configs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(RECORDS_TABLE, function (table) { table.integer('sync_job_id').references('id').inTable(JOBS_TABLE).onDelete('CASCADE').index(); }); @@ -12,7 +12,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(RECORDS_TABLE, function (table) { table.dropColumn('sync_job_id'); }); diff --git a/packages/database/lib/migrations/20230614080012_drop_unified_tickets_table.cjs b/packages/database/lib/migrations/20230614080012_drop_unified_tickets_table.cjs index 0bd1ed6f38f..ba50636af2c 100644 --- a/packages/database/lib/migrations/20230614080012_drop_unified_tickets_table.cjs +++ b/packages/database/lib/migrations/20230614080012_drop_unified_tickets_table.cjs @@ -1,10 +1,10 @@ const tableName = '_nango_unified_tickets'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.dropTable(tableName); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.createTable(tableName, function (table) { table.uuid('id').notNullable(); table.string('external_id').notNullable(); diff --git a/packages/database/lib/migrations/20230614091738_link_sync_id_to_sync_config.cjs b/packages/database/lib/migrations/20230614091738_link_sync_id_to_sync_config.cjs index 0e7b868eb37..39d3e46ab7f 100644 --- a/packages/database/lib/migrations/20230614091738_link_sync_id_to_sync_config.cjs +++ b/packages/database/lib/migrations/20230614091738_link_sync_id_to_sync_config.cjs @@ -1,13 +1,13 @@ const tableName = '_nango_sync_configs'; const syncs = '_nango_syncs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.uuid('sync_id').references('id').inTable(syncs).onDelete('CASCADE'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.dropColumn('sync_id'); }); diff --git a/packages/database/lib/migrations/20230615183358_update_indices_on_data_records.cjs b/packages/database/lib/migrations/20230615183358_update_indices_on_data_records.cjs index 0b1f490f405..aa175f6b564 100644 --- a/packages/database/lib/migrations/20230615183358_update_indices_on_data_records.cjs +++ b/packages/database/lib/migrations/20230615183358_update_indices_on_data_records.cjs @@ -1,13 +1,13 @@ const tableName = '_nango_sync_data_records'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.table(tableName, function (table) { table.index('data_hash'); table.index('external_id'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropIndex('data_hash'); table.dropIndex('external_id'); diff --git a/packages/database/lib/migrations/20230629054518_add_sync_deploy_type.cjs b/packages/database/lib/migrations/20230629054518_add_sync_deploy_type.cjs index 1fd3e37a66b..ae43fb801d6 100644 --- a/packages/database/lib/migrations/20230629054518_add_sync_deploy_type.cjs +++ b/packages/database/lib/migrations/20230629054518_add_sync_deploy_type.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_activity_logs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema .alterTable(tableName, function (table) { table.string('action_new').defaultTo('oauth').notNullable(); @@ -22,7 +22,7 @@ exports.up = function (knex, _) { ); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema .alterTable(tableName, function (table) { table.enu('action_new', ['oauth', 'proxy', 'token', 'sync']).defaultTo('oauth').notNullable(); diff --git a/packages/database/lib/migrations/20230703041405_update_sync_models.cjs b/packages/database/lib/migrations/20230703041405_update_sync_models.cjs index 919335f008e..98ef5a05f93 100644 --- a/packages/database/lib/migrations/20230703041405_update_sync_models.cjs +++ b/packages/database/lib/migrations/20230703041405_update_sync_models.cjs @@ -1,7 +1,7 @@ const SYNC_TABLE = '_nango_syncs'; const SYNC_CONFIG = '_nango_sync_configs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(SYNC_TABLE, function (table) { table.dropColumn('models'); }); @@ -11,7 +11,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(SYNC_TABLE, function (table) { table.specificType('models', 'text ARRAY'); }); diff --git a/packages/database/lib/migrations/20230704175816_nango_environments.cjs b/packages/database/lib/migrations/20230704175816_nango_environments.cjs index 86345bd34d1..679e47cfc86 100644 --- a/packages/database/lib/migrations/20230704175816_nango_environments.cjs +++ b/packages/database/lib/migrations/20230704175816_nango_environments.cjs @@ -1,4 +1,4 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.createTable('_nango_environments', function (table) { table.increments('id').primary(); table.string('name').notNullable(); @@ -20,6 +20,6 @@ exports.up = async function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable('_nango_environments'); }; diff --git a/packages/database/lib/migrations/20230704175820_link_environment_accounts.cjs b/packages/database/lib/migrations/20230704175820_link_environment_accounts.cjs index d500286cf94..8be4c90021b 100644 --- a/packages/database/lib/migrations/20230704175820_link_environment_accounts.cjs +++ b/packages/database/lib/migrations/20230704175820_link_environment_accounts.cjs @@ -6,7 +6,7 @@ const ENVIRONMENTS_TABLE = '_nango_environments'; const ACCOUNTS_TABLE = '_nango_accounts'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { const existingAccounts = await knex.table(ACCOUNTS_TABLE).select('*'); for (const account of existingAccounts) { @@ -37,7 +37,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.table('_nango_environments').truncate(); return knex.schema.alterTable(ACCOUNTS_TABLE, function (table) { diff --git a/packages/database/lib/migrations/20230707103352_use_environment_id_instead_of_account_id.cjs b/packages/database/lib/migrations/20230707103352_use_environment_id_instead_of_account_id.cjs index 479b68e3ea5..a2eeafe3bd8 100644 --- a/packages/database/lib/migrations/20230707103352_use_environment_id_instead_of_account_id.cjs +++ b/packages/database/lib/migrations/20230707103352_use_environment_id_instead_of_account_id.cjs @@ -8,7 +8,7 @@ const ACCOUNTS_TABLE = '_nango_accounts'; const TABLE_PREFIX = '_nango_'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { const tablesToReplace = [ { name: `${TABLE_PREFIX}activity_logs`, dropForeign: true, truncate: true }, { name: `${TABLE_PREFIX}configs`, dropForeign: true, truncate: false }, @@ -50,7 +50,7 @@ exports.up = async function (knex, _) { } }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.alterTable(ACCOUNTS_TABLE, function (table) { table.uuid('secret_key').defaultTo(knex.raw('uuid_generate_v4()')).notNullable(); table.uuid('public_key').defaultTo(knex.raw('uuid_generate_v4()')).notNullable(); diff --git a/packages/database/lib/migrations/20230719102146_oauth_credentials_not_required.cjs b/packages/database/lib/migrations/20230719102146_oauth_credentials_not_required.cjs index 9f0e9e8a419..0a4a0efedab 100644 --- a/packages/database/lib/migrations/20230719102146_oauth_credentials_not_required.cjs +++ b/packages/database/lib/migrations/20230719102146_oauth_credentials_not_required.cjs @@ -1,6 +1,6 @@ const TABLE_NAME = '_nango_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(TABLE_NAME, function (table) { table.string('oauth_client_id').alter().nullable().defaultTo(null); table.string('oauth_client_secret').alter().nullable().defaultTo(null); @@ -8,7 +8,7 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable(TABLE_NAME, function (table) { table.string('oauth_client_id').alter().notNullable(); table.string('oauth_client_secret').alter().notNullable(); diff --git a/packages/database/lib/migrations/20230721105652_soft_deletes.cjs b/packages/database/lib/migrations/20230721105652_soft_deletes.cjs index 9a9b9d25323..e128d162b4e 100644 --- a/packages/database/lib/migrations/20230721105652_soft_deletes.cjs +++ b/packages/database/lib/migrations/20230721105652_soft_deletes.cjs @@ -7,7 +7,7 @@ const SYNC_SCHEDULES_TABLE = '_nango_sync_schedules'; const tables = [CONNECTIONS_TABLE, SYNCS_TABLE, SYNC_CONFIGS_TABLE, CONFIGS_TABLE, SYNC_JOBS_TABLE, SYNC_SCHEDULES_TABLE]; -exports.up = async function (knex, _) { +exports.up = async function (knex) { for (const nangoTable of tables) { await knex.schema.alterTable(nangoTable, function (table) { table.boolean('deleted').defaultTo(false); @@ -16,7 +16,7 @@ exports.up = async function (knex, _) { } }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { for (const nangoTable of tables) { await knex.schema.alterTable(nangoTable, function (table) { table.dropColumn('deleted'); diff --git a/packages/database/lib/migrations/20230721105849_additional_index_nango_connections.cjs b/packages/database/lib/migrations/20230721105849_additional_index_nango_connections.cjs index 54552eedfb3..d82aa33e686 100644 --- a/packages/database/lib/migrations/20230721105849_additional_index_nango_connections.cjs +++ b/packages/database/lib/migrations/20230721105849_additional_index_nango_connections.cjs @@ -1,13 +1,13 @@ const tableName = '_nango_connections'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.table(tableName, function (table) { table.index('provider_config_key'); table.index('connection_id'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropIndex('provider_config_key'); table.dropIndex('connection_id'); diff --git a/packages/database/lib/migrations/20230721115148_update_uniques.cjs b/packages/database/lib/migrations/20230721115148_update_uniques.cjs index b3f6764a6df..f76530b26c1 100644 --- a/packages/database/lib/migrations/20230721115148_update_uniques.cjs +++ b/packages/database/lib/migrations/20230721115148_update_uniques.cjs @@ -1,7 +1,7 @@ const CONNECTIONS_TABLE = '_nango_connections'; const CONFIGS_TABLE = '_nango_configs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(CONNECTIONS_TABLE, function (table) { table.dropUnique(['provider_config_key', 'connection_id', 'environment_id']); table.unique(['provider_config_key', 'connection_id', 'environment_id', 'deleted_at']); @@ -12,7 +12,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(CONNECTIONS_TABLE, function (table) { table.unique(['provider_config_key', 'connection_id', 'environment_id']); table.dropUnique(['provider_config_key', 'connection_id', 'environment_id', 'deleted_at']); diff --git a/packages/database/lib/migrations/20230724110746_add_connection_last_fetched_date.cjs b/packages/database/lib/migrations/20230724110746_add_connection_last_fetched_date.cjs index 78080364bf2..e4da09f5fa7 100644 --- a/packages/database/lib/migrations/20230724110746_add_connection_last_fetched_date.cjs +++ b/packages/database/lib/migrations/20230724110746_add_connection_last_fetched_date.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_connections'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.dateTime('last_fetched_at'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('last_fetched_at'); }); diff --git a/packages/database/lib/migrations/20230725102233_unique_sync_name_per_connection.cjs b/packages/database/lib/migrations/20230725102233_unique_sync_name_per_connection.cjs index 492e9db64af..b5dbb0fd182 100644 --- a/packages/database/lib/migrations/20230725102233_unique_sync_name_per_connection.cjs +++ b/packages/database/lib/migrations/20230725102233_unique_sync_name_per_connection.cjs @@ -1,12 +1,12 @@ const SYNCS_TABLE = '_nango_syncs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable(SYNCS_TABLE, function (table) { table.unique(['name', 'nango_connection_id', 'deleted_at']); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.alterTable(SYNCS_TABLE, function (table) { table.dropUnique(['name', 'nango_connection_id', 'deleted_at']); }); diff --git a/packages/database/lib/migrations/20230725103142_activity_indices.cjs b/packages/database/lib/migrations/20230725103142_activity_indices.cjs index f7574f91817..d824982814f 100644 --- a/packages/database/lib/migrations/20230725103142_activity_indices.cjs +++ b/packages/database/lib/migrations/20230725103142_activity_indices.cjs @@ -1,13 +1,13 @@ const LOG_MESSAGES_TABLE = '_nango_activity_log_messages'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable(LOG_MESSAGES_TABLE, function (table) { table.index('activity_log_id', 'activity_log_id_index'); table.index('created_at', 'created_at_index'); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.alterTable(LOG_MESSAGES_TABLE, function (table) { table.dropIndex('activity_log_id', 'activity_log_id_index'); table.dropIndex('created_at', 'created_at_index'); diff --git a/packages/database/lib/migrations/20230727075437_scopes_length.cjs b/packages/database/lib/migrations/20230727075437_scopes_length.cjs index 3f34d62396c..5d8ade65e82 100644 --- a/packages/database/lib/migrations/20230727075437_scopes_length.cjs +++ b/packages/database/lib/migrations/20230727075437_scopes_length.cjs @@ -1,12 +1,12 @@ const CONFIGS_TABLE = '_nango_configs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable(CONFIGS_TABLE, function (table) { table.text('oauth_scopes').alter({ alterType: true }); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.alterTable(CONFIGS_TABLE, function (table) { table.string('oauth_scopes').alter({ alterType: true }); }); diff --git a/packages/database/lib/migrations/20230728114040_last_sync_date.cjs b/packages/database/lib/migrations/20230728114040_last_sync_date.cjs index 559c0defdbf..6672bfac326 100644 --- a/packages/database/lib/migrations/20230728114040_last_sync_date.cjs +++ b/packages/database/lib/migrations/20230728114040_last_sync_date.cjs @@ -1,12 +1,12 @@ const SYNCS_TABLE = '_nango_syncs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable(SYNCS_TABLE, function (table) { table.dateTime('last_sync_date').nullable(); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.alterTable(SYNCS_TABLE, function (table) { table.dropColumn('last_sync_date'); }); diff --git a/packages/database/lib/migrations/20230803113912_remove_activity_log.cjs b/packages/database/lib/migrations/20230803113912_remove_activity_log.cjs index 5cfb480ca64..3bf6fe7b649 100644 --- a/packages/database/lib/migrations/20230803113912_remove_activity_log.cjs +++ b/packages/database/lib/migrations/20230803113912_remove_activity_log.cjs @@ -1,12 +1,12 @@ const JOBS_TABLE = '_nango_sync_jobs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable(JOBS_TABLE, function (table) { table.dropColumn('activity_log_id'); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.alterTable(JOBS_TABLE, function (table) { table.integer('activity_log_id').references('id').inTable('_nango_activity_logs').onDelete('SET NULL'); }); diff --git a/packages/database/lib/migrations/20230804082618_connection_metadata_consolidation.cjs b/packages/database/lib/migrations/20230804082618_connection_metadata_consolidation.cjs index 095f2bf955a..3e597bef4c3 100644 --- a/packages/database/lib/migrations/20230804082618_connection_metadata_consolidation.cjs +++ b/packages/database/lib/migrations/20230804082618_connection_metadata_consolidation.cjs @@ -5,7 +5,7 @@ */ const DB_TABLE = '_nango_connections'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { const existingMetaData = await knex.select('id', 'metadata', 'connection_config').from(DB_TABLE).whereNotNull('metadata').andWhere('metadata', '!=', '{}'); for (const record of existingMetaData) { @@ -33,7 +33,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.alterTable(DB_TABLE, function (table) { table.jsonb('field_mappings').defaultTo('{}'); }); diff --git a/packages/database/lib/migrations/20230804110506_remove_params_from_connection_config.cjs b/packages/database/lib/migrations/20230804110506_remove_params_from_connection_config.cjs index c54e9f7b01e..488c8f6a395 100644 --- a/packages/database/lib/migrations/20230804110506_remove_params_from_connection_config.cjs +++ b/packages/database/lib/migrations/20230804110506_remove_params_from_connection_config.cjs @@ -5,7 +5,7 @@ */ const DB_TABLE = '_nango_connections'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { const existingCC = await knex.select('id', 'connection_config').from(DB_TABLE).whereNotNull('connection_config').andWhere('connection_config', '!=', '{}'); for (const record of existingCC) { @@ -18,7 +18,6 @@ exports.up = async function (knex, _) { if (key.includes('connectionConfig.params.')) { const newKey = key.replace('connectionConfig.params.', ''); connection_config[newKey] = connection_config[key]; - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete connection_config[key]; await knex.update({ connection_config }).from(DB_TABLE).where({ id }); @@ -29,6 +28,6 @@ exports.up = async function (knex, _) { return Promise.resolve(); }; -exports.down = async function (_knex, _) { +exports.down = async function () { return Promise.resolve(); }; diff --git a/packages/database/lib/migrations/20230804132344_update_account_and_organization.cjs b/packages/database/lib/migrations/20230804132344_update_account_and_organization.cjs index 00511017077..6ee25a0a35e 100644 --- a/packages/database/lib/migrations/20230804132344_update_account_and_organization.cjs +++ b/packages/database/lib/migrations/20230804132344_update_account_and_organization.cjs @@ -1,7 +1,7 @@ const ACCOUNTS_TABLE = '_nango_accounts'; const USERS_TABLE = '_nango_users'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(USERS_TABLE, function (table) { table.boolean('suspended').defaultTo(false).notNullable(); table.dateTime('suspended_at').defaultTo(null); @@ -11,7 +11,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(USERS_TABLE, function (table) { table.dropColumn('suspended'); table.dropColumn('suspended_at'); diff --git a/packages/database/lib/migrations/20230804181955_invited_users.cjs b/packages/database/lib/migrations/20230804181955_invited_users.cjs index a268faa3715..e9799653c55 100644 --- a/packages/database/lib/migrations/20230804181955_invited_users.cjs +++ b/packages/database/lib/migrations/20230804181955_invited_users.cjs @@ -1,6 +1,6 @@ const DB_TABLE = '_nango_invited_users'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.createTable(DB_TABLE, function (table) { table.increments('id').primary(); table.string('name').notNullable(); @@ -14,6 +14,6 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.dropTable(DB_TABLE); }; diff --git a/packages/database/lib/migrations/20230810110751_data_records_deleted.cjs b/packages/database/lib/migrations/20230810110751_data_records_deleted.cjs index b87d91796eb..9d462e901d5 100644 --- a/packages/database/lib/migrations/20230810110751_data_records_deleted.cjs +++ b/packages/database/lib/migrations/20230810110751_data_records_deleted.cjs @@ -1,13 +1,13 @@ const tableName = '_nango_sync_data_records'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.boolean('external_is_deleted').defaultTo(false).index(); table.dateTime('external_deleted_at'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('external_is_deleted'); table.dropColumn('external_deleted_at'); diff --git a/packages/database/lib/migrations/20230811084146_deleted_records_index.cjs b/packages/database/lib/migrations/20230811084146_deleted_records_index.cjs index 175a8a50bb1..095dcc80d0d 100644 --- a/packages/database/lib/migrations/20230811084146_deleted_records_index.cjs +++ b/packages/database/lib/migrations/20230811084146_deleted_records_index.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_sync_data_records'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.index('created_at'); table.index('updated_at'); @@ -11,7 +11,7 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropIndex('created_at'); table.dropIndex('updated_at'); diff --git a/packages/database/lib/migrations/20230811085027_deleted_records_tracking.cjs b/packages/database/lib/migrations/20230811085027_deleted_records_tracking.cjs index e9fa2309c7b..7afc0e2d37c 100644 --- a/packages/database/lib/migrations/20230811085027_deleted_records_tracking.cjs +++ b/packages/database/lib/migrations/20230811085027_deleted_records_tracking.cjs @@ -2,7 +2,7 @@ const tableName = '_nango_sync_data_records_deletes'; const JOBS_TABLE = '_nango_sync_jobs'; const SYNC_TABLE = '_nango_syncs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable(tableName, function (table) { table.uuid('id').notNullable(); table.string('external_id').notNullable().index(); @@ -46,6 +46,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable(tableName); }; diff --git a/packages/database/lib/migrations/20230811093401_data_records_additional_index.cjs b/packages/database/lib/migrations/20230811093401_data_records_additional_index.cjs index 8c3eebf35d6..7bf5ac2c242 100644 --- a/packages/database/lib/migrations/20230811093401_data_records_additional_index.cjs +++ b/packages/database/lib/migrations/20230811093401_data_records_additional_index.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_sync_data_records'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.index('external_deleted_at'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropIndex('external_deleted_at'); }); diff --git a/packages/database/lib/migrations/20230811131558_track_deletes_in_nango_sync_configs.cjs b/packages/database/lib/migrations/20230811131558_track_deletes_in_nango_sync_configs.cjs index fa3f8e2d534..5b8cc861eb3 100644 --- a/packages/database/lib/migrations/20230811131558_track_deletes_in_nango_sync_configs.cjs +++ b/packages/database/lib/migrations/20230811131558_track_deletes_in_nango_sync_configs.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_sync_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.boolean('track_deletes').defaultTo(false); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('track_deletes'); }); diff --git a/packages/database/lib/migrations/20230904183820_add_action_type.cjs b/packages/database/lib/migrations/20230904183820_add_action_type.cjs index 39aa8fd0d82..221e806c124 100644 --- a/packages/database/lib/migrations/20230904183820_add_action_type.cjs +++ b/packages/database/lib/migrations/20230904183820_add_action_type.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_sync_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.string('type').defaultTo('sync'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('type'); }); diff --git a/packages/database/lib/migrations/20230911164150_environment_variables_in_project_settings.cjs b/packages/database/lib/migrations/20230911164150_environment_variables_in_project_settings.cjs index ab59abd90a7..426606293d7 100644 --- a/packages/database/lib/migrations/20230911164150_environment_variables_in_project_settings.cjs +++ b/packages/database/lib/migrations/20230911164150_environment_variables_in_project_settings.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_environment_variables'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable(tableName, function (table) { table.increments('id').primary(); table.integer('environment_id').unsigned().references('id').inTable(`_nango_environments`); @@ -10,6 +10,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable(tableName); }; diff --git a/packages/database/lib/migrations/20230912181226_add_encryption_to_tables.cjs b/packages/database/lib/migrations/20230912181226_add_encryption_to_tables.cjs index 124cb4f3661..c4b8c02820a 100644 --- a/packages/database/lib/migrations/20230912181226_add_encryption_to_tables.cjs +++ b/packages/database/lib/migrations/20230912181226_add_encryption_to_tables.cjs @@ -2,7 +2,7 @@ const SECRETS_TABLE = '_nango_environment_variables'; const RECORDS_TABLE = '_nango_sync_data_records'; const DELETED_RECORDS_TABLE = '_nango_sync_data_records_deletes'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(SECRETS_TABLE, function (table) { table.string('value_iv'); table.string('value_tag'); @@ -17,7 +17,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(RECORDS_TABLE, function (table) { table.dropColumn('json_iv'); table.dropColumn('json_tag'); diff --git a/packages/database/lib/migrations/20230914080128_add_run_in_to_job.cjs b/packages/database/lib/migrations/20230914080128_add_run_in_to_job.cjs index f5cb2d4bfb1..93040038336 100644 --- a/packages/database/lib/migrations/20230914080128_add_run_in_to_job.cjs +++ b/packages/database/lib/migrations/20230914080128_add_run_in_to_job.cjs @@ -1,12 +1,12 @@ const JOBS_TABLE = '_nango_sync_jobs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable(JOBS_TABLE, function (table) { table.string('run_id'); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.alterTable(JOBS_TABLE, function (table) { table.dropColumn('run_id'); }); diff --git a/packages/database/lib/migrations/20230914161744_add_auto_start_to_config.cjs b/packages/database/lib/migrations/20230914161744_add_auto_start_to_config.cjs index 6d5e5c96e3d..4ffe9a92a36 100644 --- a/packages/database/lib/migrations/20230914161744_add_auto_start_to_config.cjs +++ b/packages/database/lib/migrations/20230914161744_add_auto_start_to_config.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_sync_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.boolean('auto_start').defaultTo(true); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('auto_start'); }); diff --git a/packages/database/lib/migrations/20230918054535_sync_level_attributes.cjs b/packages/database/lib/migrations/20230918054535_sync_level_attributes.cjs index bd3ea6a05c1..8c3f9f58012 100644 --- a/packages/database/lib/migrations/20230918054535_sync_level_attributes.cjs +++ b/packages/database/lib/migrations/20230918054535_sync_level_attributes.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_sync_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.jsonb('attributes').defaultTo('{}'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('attributes'); }); diff --git a/packages/database/lib/migrations/20230920084353_add_prebuilt_and_public_flag_to_sync_config.cjs b/packages/database/lib/migrations/20230920084353_add_prebuilt_and_public_flag_to_sync_config.cjs index 32b5552e99e..7f849acd15c 100644 --- a/packages/database/lib/migrations/20230920084353_add_prebuilt_and_public_flag_to_sync_config.cjs +++ b/packages/database/lib/migrations/20230920084353_add_prebuilt_and_public_flag_to_sync_config.cjs @@ -1,13 +1,13 @@ const tableName = '_nango_sync_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.boolean('pre_built').defaultTo(false); table.boolean('is_public').defaultTo(false); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('pre_built'); table.dropColumn('is_public'); diff --git a/packages/database/lib/migrations/20230921104322_add_uuid_to_all_accounts.cjs b/packages/database/lib/migrations/20230921104322_add_uuid_to_all_accounts.cjs index 05127803cdc..032396caacb 100644 --- a/packages/database/lib/migrations/20230921104322_add_uuid_to_all_accounts.cjs +++ b/packages/database/lib/migrations/20230921104322_add_uuid_to_all_accounts.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_accounts'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(tableName, function (table) { table.uuid('uuid').defaultTo(knex.raw('uuid_generate_v4()')); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.table(tableName, function (table) { table.dropColumn('uuid'); }); diff --git a/packages/database/lib/migrations/20230928082622_rotate_and_activation_logic.cjs b/packages/database/lib/migrations/20230928082622_rotate_and_activation_logic.cjs index 3ba2bcb0dd6..c4a0a8ae114 100644 --- a/packages/database/lib/migrations/20230928082622_rotate_and_activation_logic.cjs +++ b/packages/database/lib/migrations/20230928082622_rotate_and_activation_logic.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_environments'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.string('pending_secret_key').nullable(); table.unique('pending_secret_key'); @@ -11,7 +11,7 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('pending_secret_key'); table.dropColumn('pending_secret_key_iv'); diff --git a/packages/database/lib/migrations/20230928133211_activity_log_session_id_index.cjs b/packages/database/lib/migrations/20230928133211_activity_log_session_id_index.cjs index 40a43cb252f..fcb2799e66d 100644 --- a/packages/database/lib/migrations/20230928133211_activity_log_session_id_index.cjs +++ b/packages/database/lib/migrations/20230928133211_activity_log_session_id_index.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_activity_logs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.table(tableName, function (table) { table.index('session_id'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropIndex('session_id'); }); diff --git a/packages/database/lib/migrations/20231004161359_remove_encryption_flags.cjs b/packages/database/lib/migrations/20231004161359_remove_encryption_flags.cjs index 34e908f3115..4166703b363 100644 --- a/packages/database/lib/migrations/20231004161359_remove_encryption_flags.cjs +++ b/packages/database/lib/migrations/20231004161359_remove_encryption_flags.cjs @@ -1,7 +1,7 @@ const RECORDS_TABLE = '_nango_sync_data_records'; const DELETED_RECORDS_TABLE = '_nango_sync_data_records_deletes'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { //await knex.schema.alterTable(RECORDS_TABLE, function (table) { //table.dropColumn('json_iv'); //table.dropColumn('json_tag'); @@ -12,7 +12,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(DELETED_RECORDS_TABLE, function (table) { table.string('json_iv'); table.string('json_tag'); diff --git a/packages/database/lib/migrations/20231004235347_config_app_updates.cjs b/packages/database/lib/migrations/20231004235347_config_app_updates.cjs index fb8538c4ef7..ac5f97a8f83 100644 --- a/packages/database/lib/migrations/20231004235347_config_app_updates.cjs +++ b/packages/database/lib/migrations/20231004235347_config_app_updates.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_configs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(tableName, function (table) { table.text('oauth_client_secret').alter(); }); @@ -9,7 +9,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.alterTable(tableName, function (table) { table.string('oauth_client_secret', 255).alter(); }); diff --git a/packages/database/lib/migrations/20231016111628_sync_metadata.cjs b/packages/database/lib/migrations/20231016111628_sync_metadata.cjs index e9f5aa92836..359a7dcf008 100644 --- a/packages/database/lib/migrations/20231016111628_sync_metadata.cjs +++ b/packages/database/lib/migrations/20231016111628_sync_metadata.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_sync_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.jsonb('metadata').defaultTo('{}'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('metadata'); }); diff --git a/packages/database/lib/migrations/20231018115215_add_pending_delete.cjs b/packages/database/lib/migrations/20231018115215_add_pending_delete.cjs index 3eb00525a12..97d437d7e1e 100644 --- a/packages/database/lib/migrations/20231018115215_add_pending_delete.cjs +++ b/packages/database/lib/migrations/20231018115215_add_pending_delete.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_sync_data_records'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.boolean('pending_delete').defaultTo(false).index(); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('pending_delete'); }); diff --git a/packages/database/lib/migrations/20231018132226_add_webhook_option.cjs b/packages/database/lib/migrations/20231018132226_add_webhook_option.cjs index 2040e944f49..fc1b9babec9 100644 --- a/packages/database/lib/migrations/20231018132226_add_webhook_option.cjs +++ b/packages/database/lib/migrations/20231018132226_add_webhook_option.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_environments'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.boolean('always_send_webhook').defaultTo(false); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('always_send_webhook'); }); diff --git a/packages/database/lib/migrations/20231019135320_add_environment_id_to_log_messages.cjs b/packages/database/lib/migrations/20231019135320_add_environment_id_to_log_messages.cjs index 7e4826fe5af..f9e9c235f33 100644 --- a/packages/database/lib/migrations/20231019135320_add_environment_id_to_log_messages.cjs +++ b/packages/database/lib/migrations/20231019135320_add_environment_id_to_log_messages.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_activity_log_messages'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.integer('environment_id').unsigned().references('id').inTable(`_nango_environments`).index(); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('environment_id'); }); diff --git a/packages/database/lib/migrations/20231020102155_sync_job_table_indexes.cjs b/packages/database/lib/migrations/20231020102155_sync_job_table_indexes.cjs index 6a4b88b3e14..7d9aa52cfdb 100644 --- a/packages/database/lib/migrations/20231020102155_sync_job_table_indexes.cjs +++ b/packages/database/lib/migrations/20231020102155_sync_job_table_indexes.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_sync_jobs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.index(['sync_id', 'deleted']); table.index('deleted'); @@ -10,7 +10,7 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropIndex(['sync_id', 'deleted']); table.dropIndex('deleted'); diff --git a/packages/database/lib/migrations/20231027135906_slack_notifications_option.cjs b/packages/database/lib/migrations/20231027135906_slack_notifications_option.cjs index f9f7946d690..40f8aed8d64 100644 --- a/packages/database/lib/migrations/20231027135906_slack_notifications_option.cjs +++ b/packages/database/lib/migrations/20231027135906_slack_notifications_option.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_environments'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.boolean('slack_notifications').defaultTo(false); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('slack_notifications'); }); diff --git a/packages/database/lib/migrations/20231030112937_slack_notifications_table.cjs b/packages/database/lib/migrations/20231030112937_slack_notifications_table.cjs index 0c7114d7377..c55371d1db1 100644 --- a/packages/database/lib/migrations/20231030112937_slack_notifications_table.cjs +++ b/packages/database/lib/migrations/20231030112937_slack_notifications_table.cjs @@ -1,6 +1,6 @@ const DB_TABLE = '_nango_slack_notifications'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.createTable(DB_TABLE, function (table) { table.increments('id').primary(); table.boolean('open').defaultTo(true).index(); @@ -14,6 +14,6 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.dropTable(DB_TABLE); }; diff --git a/packages/database/lib/migrations/20231030124201_add_endpoints_to_sync_configs.cjs b/packages/database/lib/migrations/20231030124201_add_endpoints_to_sync_configs.cjs index 2b7f04b42aa..843dee73914 100644 --- a/packages/database/lib/migrations/20231030124201_add_endpoints_to_sync_configs.cjs +++ b/packages/database/lib/migrations/20231030124201_add_endpoints_to_sync_configs.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_sync_endpoints'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable(tableName, function (table) { table.increments('id').primary(); table.string('method').notNullable().index(); @@ -11,6 +11,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable(tableName); }; diff --git a/packages/database/lib/migrations/20231102095648_create_onboarding_demo.cjs b/packages/database/lib/migrations/20231102095648_create_onboarding_demo.cjs index 99d90c7e235..481391f2365 100644 --- a/packages/database/lib/migrations/20231102095648_create_onboarding_demo.cjs +++ b/packages/database/lib/migrations/20231102095648_create_onboarding_demo.cjs @@ -1,6 +1,6 @@ const DB_TABLE = '_nango_onboarding_demo_progress'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.createTable(DB_TABLE, function (table) { table.increments('id').primary(); table.integer('user_id').unsigned().references('id').inTable(`_nango_users`).index(); @@ -10,6 +10,6 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.dropTable(DB_TABLE); }; diff --git a/packages/database/lib/migrations/20231106085744_add_sync_index.cjs b/packages/database/lib/migrations/20231106085744_add_sync_index.cjs index 5c0005205ca..91e7b18d0ab 100644 --- a/packages/database/lib/migrations/20231106085744_add_sync_index.cjs +++ b/packages/database/lib/migrations/20231106085744_add_sync_index.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_syncs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.index(['nango_connection_id', 'deleted'], 'nango_syncs_nango_connection_id_deleted_index'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropIndex('nango_syncs_nango_connection_id_deleted_index'); }); diff --git a/packages/database/lib/migrations/20231106121117_delete_connection_improvements.cjs b/packages/database/lib/migrations/20231106121117_delete_connection_improvements.cjs index 7479ea4e867..a564a59cabd 100644 --- a/packages/database/lib/migrations/20231106121117_delete_connection_improvements.cjs +++ b/packages/database/lib/migrations/20231106121117_delete_connection_improvements.cjs @@ -3,7 +3,7 @@ const SYNC_RECORDS_TABLE = '_nango_sync_data_records'; const SYNC_RECORDS_DELETE_TABLE = '_nango_sync_data_records_deletes'; const SYNC_SCHEDULE_TABLE = '_nango_sync_schedules'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(SYNC_RECORDS_DELETE_TABLE, function (table) { table.index('sync_id'); }); @@ -21,7 +21,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.table(SYNC_RECORDS_DELETE_TABLE, function (table) { table.dropIndex('sync_id'); }); diff --git a/packages/database/lib/migrations/20231108201904_nango_config_v2_updates.cjs b/packages/database/lib/migrations/20231108201904_nango_config_v2_updates.cjs index 69a9e6de738..8462e9d64fa 100644 --- a/packages/database/lib/migrations/20231108201904_nango_config_v2_updates.cjs +++ b/packages/database/lib/migrations/20231108201904_nango_config_v2_updates.cjs @@ -1,13 +1,13 @@ const tableName = '_nango_sync_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.string('input').nullable(); table.string('sync_type').nullable(); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('input'); table.dropColumn('sync_type'); diff --git a/packages/database/lib/migrations/20231204191116_add_webhooks_subscriptions_to_config.cjs b/packages/database/lib/migrations/20231204191116_add_webhooks_subscriptions_to_config.cjs index 27c8e46c3b5..78cae42df3a 100644 --- a/packages/database/lib/migrations/20231204191116_add_webhooks_subscriptions_to_config.cjs +++ b/packages/database/lib/migrations/20231204191116_add_webhooks_subscriptions_to_config.cjs @@ -1,12 +1,12 @@ const TABLE_NAME = '_nango_sync_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(TABLE_NAME, function (table) { table.specificType('webhook_subscriptions', 'text ARRAY'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable(TABLE_NAME, function (table) { table.dropColumn('webhook_subscriptions'); }); diff --git a/packages/database/lib/migrations/20231205151403_add_uuid_to_environment.cjs b/packages/database/lib/migrations/20231205151403_add_uuid_to_environment.cjs index 11a85f7c528..9ed674d8cd5 100644 --- a/packages/database/lib/migrations/20231205151403_add_uuid_to_environment.cjs +++ b/packages/database/lib/migrations/20231205151403_add_uuid_to_environment.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_environments'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(tableName, function (table) { table.uuid('uuid').defaultTo(knex.raw('uuid_generate_v4()')).index(); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.table(tableName, function (table) { table.dropColumn('uuid'); }); diff --git a/packages/database/lib/migrations/20231208181152_update_jobs_type_enum.cjs b/packages/database/lib/migrations/20231208181152_update_jobs_type_enum.cjs index 2b1183438e1..5b3e43910fe 100644 --- a/packages/database/lib/migrations/20231208181152_update_jobs_type_enum.cjs +++ b/packages/database/lib/migrations/20231208181152_update_jobs_type_enum.cjs @@ -1,6 +1,6 @@ const tableName = '_nango_sync_jobs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema .alterTable(tableName, function (table) { table.string('type_new').defaultsTo('initial').notNullable(); @@ -22,7 +22,7 @@ exports.up = function (knex, _) { ); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema .alterTable(tableName, function (table) { table.enu('type', ['INITIAL', 'INCREMENTAL']).defaultTo('initial').notNullable(); diff --git a/packages/database/lib/migrations/20231213124728_drop_sync_data_records_indexes.cjs b/packages/database/lib/migrations/20231213124728_drop_sync_data_records_indexes.cjs index 00b51322da4..b93ececddb7 100644 --- a/packages/database/lib/migrations/20231213124728_drop_sync_data_records_indexes.cjs +++ b/packages/database/lib/migrations/20231213124728_drop_sync_data_records_indexes.cjs @@ -1,6 +1,6 @@ exports.config = { transaction: false }; -exports.up = function (_knex) { +exports.up = function () { return Promise.resolve(); /* * Production only migration @@ -17,6 +17,6 @@ exports.up = function (_knex) { */ }; -exports.down = function (_knex) { +exports.down = function () { return Promise.resolve(); }; diff --git a/packages/database/lib/migrations/20240131121245_add_auth_webhook_option.cjs b/packages/database/lib/migrations/20240131121245_add_auth_webhook_option.cjs index d976972fef1..36d98153f76 100644 --- a/packages/database/lib/migrations/20240131121245_add_auth_webhook_option.cjs +++ b/packages/database/lib/migrations/20240131121245_add_auth_webhook_option.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_environments'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.boolean('send_auth_webhook').defaultTo(false); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('send_auth_webhook'); }); diff --git a/packages/database/lib/migrations/20240326141028_hash-key.cjs b/packages/database/lib/migrations/20240326141028_hash-key.cjs index ab5f0a16e2c..8c10d06376e 100644 --- a/packages/database/lib/migrations/20240326141028_hash-key.cjs +++ b/packages/database/lib/migrations/20240326141028_hash-key.cjs @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ const utils = require('node:util'); const crypto = require('node:crypto'); diff --git a/packages/database/lib/migrations/20240403100610_add_account_status_info.cjs b/packages/database/lib/migrations/20240403100610_add_account_status_info.cjs index 5743dd57a4f..17fbf8e0a20 100644 --- a/packages/database/lib/migrations/20240403100610_add_account_status_info.cjs +++ b/packages/database/lib/migrations/20240403100610_add_account_status_info.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_accounts'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.alterTable(tableName, function (table) { table.boolean('is_capped').defaultTo(true); }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.table(tableName, function (table) { table.dropColumn('is_capped'); }); diff --git a/packages/database/lib/migrations/20240404185301_add_sync_last_fetch_at.cjs b/packages/database/lib/migrations/20240404185301_add_sync_last_fetch_at.cjs index dc7e4ad43d4..85bf6ce3e61 100644 --- a/packages/database/lib/migrations/20240404185301_add_sync_last_fetch_at.cjs +++ b/packages/database/lib/migrations/20240404185301_add_sync_last_fetch_at.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_syncs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.dateTime('last_fetched_at'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('last_fetched_at'); }); diff --git a/packages/database/lib/migrations/20240405171723_add_enabled_flag_on_sync_config.cjs b/packages/database/lib/migrations/20240405171723_add_enabled_flag_on_sync_config.cjs index d1eb54b5bc3..33c8618ec69 100644 --- a/packages/database/lib/migrations/20240405171723_add_enabled_flag_on_sync_config.cjs +++ b/packages/database/lib/migrations/20240405171723_add_enabled_flag_on_sync_config.cjs @@ -1,12 +1,12 @@ const tableName = '_nango_sync_configs'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable(tableName, function (table) { table.boolean('enabled').defaultTo(true); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table(tableName, function (table) { table.dropColumn('enabled'); }); diff --git a/packages/database/lib/migrations/20240430171723_oauth_session_activity_log_id.cjs b/packages/database/lib/migrations/20240430171723_oauth_session_activity_log_id.cjs index c00f246c68c..a52dfd0a313 100644 --- a/packages/database/lib/migrations/20240430171723_oauth_session_activity_log_id.cjs +++ b/packages/database/lib/migrations/20240430171723_oauth_session_activity_log_id.cjs @@ -1,10 +1,10 @@ -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.alterTable('_nango_oauth_sessions', function (table) { table.string('activity_log_id'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.table('_nango_oauth_sessions', function (table) { table.dropColumn('activity_log_id'); }); diff --git a/packages/database/lib/migrations/20240502171723_index_syncs.cjs b/packages/database/lib/migrations/20240502171723_index_syncs.cjs index 088a9d735ca..0d001c90055 100644 --- a/packages/database/lib/migrations/20240502171723_index_syncs.cjs +++ b/packages/database/lib/migrations/20240502171723_index_syncs.cjs @@ -1,13 +1,13 @@ exports.config = { transaction: false }; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.raw( 'CREATE INDEX CONCURRENTLY "idx_connectionid_name_where_deleted" ON "_nango_syncs" USING BTREE ("nango_connection_id", "name") WHERE deleted = false' ); await knex.schema.raw('CREATE INDEX CONCURRENTLY "idx_id_where_deleted" ON "_nango_syncs" USING BTREE ("id") WHERE deleted = false'); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.raw('DROP INDEX CONCURRENTLY idx_connectionid_name_where_deleted'); await knex.schema.raw('DROP INDEX CONCURRENTLY idx_id_where_deleted'); }; diff --git a/packages/database/lib/migrations/20240506171723_index_environments.cjs b/packages/database/lib/migrations/20240506171723_index_environments.cjs index b91b37ae30b..e9e598546ca 100644 --- a/packages/database/lib/migrations/20240506171723_index_environments.cjs +++ b/packages/database/lib/migrations/20240506171723_index_environments.cjs @@ -1,6 +1,6 @@ exports.config = { transaction: false }; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.raw( 'CREATE INDEX CONCURRENTLY IF NOT EXISTS "idx_environments_accountid_name" ON "_nango_environments" USING BTREE ("account_id","name")' ); @@ -9,7 +9,7 @@ exports.up = async function (knex, _) { ); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.raw('DROP INDEX CONCURRENTLY idx_environments_accountid_name'); await knex.schema.raw('DROP INDEX CONCURRENTLY idx_environments_secretkeyhashed'); }; diff --git a/packages/database/lib/migrations/20240508141028_hash-key-backfill.cjs b/packages/database/lib/migrations/20240508141028_hash-key-backfill.cjs index defc939debb..26d1575a595 100644 --- a/packages/database/lib/migrations/20240508141028_hash-key-backfill.cjs +++ b/packages/database/lib/migrations/20240508141028_hash-key-backfill.cjs @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ exports.config = { transaction: false }; const utils = require('node:util'); diff --git a/packages/database/lib/migrations/20240509171724_add_webhook_secondary.cjs b/packages/database/lib/migrations/20240509171724_add_webhook_secondary.cjs index 24c8553495b..ca224104b94 100644 --- a/packages/database/lib/migrations/20240509171724_add_webhook_secondary.cjs +++ b/packages/database/lib/migrations/20240509171724_add_webhook_secondary.cjs @@ -1,10 +1,10 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable('_nango_environments', function (table) { table.text('webhook_url_secondary'); }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_environments', function (table) { table.dropColumn('webhook_url_secondary'); }); diff --git a/packages/database/lib/migrations/20240517171724_verified_flag.cjs b/packages/database/lib/migrations/20240517171724_verified_flag.cjs index d6c40cdf100..aeec76d8c75 100644 --- a/packages/database/lib/migrations/20240517171724_verified_flag.cjs +++ b/packages/database/lib/migrations/20240517171724_verified_flag.cjs @@ -1,4 +1,4 @@ -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.alterTable('_nango_users', function (table) { table.boolean('email_verified').defaultTo(true); table.string('email_verification_token').nullable(); @@ -7,7 +7,7 @@ exports.up = async function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.alterTable('_nango_users', function (table) { table.dropColumn('email_verified'); table.dropColumn('email_verification_token'); diff --git a/packages/database/lib/migrations/20240527094039_add_notifications_table.cjs b/packages/database/lib/migrations/20240527094039_add_notifications_table.cjs index 2a906cfaedd..7ab2c520fd6 100644 --- a/packages/database/lib/migrations/20240527094039_add_notifications_table.cjs +++ b/packages/database/lib/migrations/20240527094039_add_notifications_table.cjs @@ -1,6 +1,6 @@ const DB_TABLE = '_nango_active_logs'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.createTable(DB_TABLE, function (table) { table.increments('id').primary(); table.string('type', 'varchar(255)').notNullable(); @@ -17,6 +17,6 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.dropTable(DB_TABLE); }; diff --git a/packages/database/lib/migrations/20240529171723_add_post_connection_script.cjs b/packages/database/lib/migrations/20240529171723_add_post_connection_script.cjs index 65242736e95..35d5abb16cf 100644 --- a/packages/database/lib/migrations/20240529171723_add_post_connection_script.cjs +++ b/packages/database/lib/migrations/20240529171723_add_post_connection_script.cjs @@ -1,6 +1,6 @@ const TABLE_NAME = '_nango_post_connection_scripts'; -exports.up = function (knex, _) { +exports.up = function (knex) { return knex.schema.createTable(TABLE_NAME, function (table) { table.increments('id').primary(); table.integer('config_id').unsigned().notNullable(); @@ -13,6 +13,6 @@ exports.up = function (knex, _) { }); }; -exports.down = function (knex, _) { +exports.down = function (knex) { return knex.schema.dropTable(TABLE_NAME); }; diff --git a/packages/database/lib/migrations/20240529180658_add_notifications_table_index.cjs b/packages/database/lib/migrations/20240529180658_add_notifications_table_index.cjs index 71501ac418c..c06c32f01a4 100644 --- a/packages/database/lib/migrations/20240529180658_add_notifications_table_index.cjs +++ b/packages/database/lib/migrations/20240529180658_add_notifications_table_index.cjs @@ -1,9 +1,9 @@ exports.config = { transaction: false }; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.raw('CREATE INDEX CONCURRENTLY "idx_sync_id_active_true" ON "_nango_active_logs" USING BTREE ("sync_id") WHERE active = true'); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.raw('DROP INDEX CONCURRENTLY idx_sync_id_active_true'); }; diff --git a/packages/database/lib/migrations/20240531122550_add_webhooks_table.cjs b/packages/database/lib/migrations/20240531122550_add_webhooks_table.cjs index da711839253..dddccb29cf3 100644 --- a/packages/database/lib/migrations/20240531122550_add_webhooks_table.cjs +++ b/packages/database/lib/migrations/20240531122550_add_webhooks_table.cjs @@ -1,6 +1,6 @@ const DB_TABLE = '_nango_external_webhooks'; -exports.up = async function (knex, _) { +exports.up = async function (knex) { return knex.schema.createTable(DB_TABLE, function (table) { table.increments('id').primary(); table.integer('environment_id').unsigned().notNullable(); @@ -15,6 +15,6 @@ exports.up = async function (knex, _) { }); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { return knex.schema.dropTable(DB_TABLE); }; diff --git a/packages/database/lib/migrations/20240603083808_post_connection_scripts_index.cjs b/packages/database/lib/migrations/20240603083808_post_connection_scripts_index.cjs index a5d37bdd31c..ff1ac2ee723 100644 --- a/packages/database/lib/migrations/20240603083808_post_connection_scripts_index.cjs +++ b/packages/database/lib/migrations/20240603083808_post_connection_scripts_index.cjs @@ -1,11 +1,11 @@ exports.config = { transaction: false }; -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.raw( 'CREATE INDEX CONCURRENTLY "idx_active_config_id_name" ON "_nango_post_connection_scripts" USING BTREE ("config_id", "name") WHERE active = true' ); }; -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.raw('DROP INDEX CONCURRENTLY idx_active_config_id_name'); }; diff --git a/packages/database/lib/migrations/20240708161616_index_sync_configs.cjs b/packages/database/lib/migrations/20240708161616_index_sync_configs.cjs index 257cdf2f208..c3561c21d60 100644 --- a/packages/database/lib/migrations/20240708161616_index_sync_configs.cjs +++ b/packages/database/lib/migrations/20240708161616_index_sync_configs.cjs @@ -3,7 +3,7 @@ exports.config = { transaction: false }; /** * @param {import('knex').Knex} knex */ -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.raw( `CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_nango_sync_configs_active ON _nango_sync_configs USING BTREE (type, sync_name, nango_config_id) @@ -13,6 +13,6 @@ exports.up = async function (knex, _) { /** * @param {import('knex').Knex} knex */ -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.raw('DROP INDEX CONCURRENTLY IF EXISTS idx_nango_sync_configs_active'); }; diff --git a/packages/database/lib/migrations/20240912210952_index_sync_config_id_sync.cjs b/packages/database/lib/migrations/20240912210952_index_sync_config_id_sync.cjs index 5cc5eb16100..d0433bcf5b8 100644 --- a/packages/database/lib/migrations/20240912210952_index_sync_config_id_sync.cjs +++ b/packages/database/lib/migrations/20240912210952_index_sync_config_id_sync.cjs @@ -3,7 +3,7 @@ exports.config = { transaction: false }; /** * @param {import('knex').Knex} knex */ -exports.up = async function (knex, _) { +exports.up = async function (knex) { await knex.schema.raw( `CREATE INDEX CONCURRENTLY IF NOT EXISTS "idx_sync_config_id_where_deleted" ON "_nango_syncs" USING BTREE ("sync_config_id") @@ -13,6 +13,6 @@ exports.up = async function (knex, _) { /** * @param {import('knex').Knex} knex */ -exports.down = async function (knex, _) { +exports.down = async function (knex) { await knex.schema.raw('DROP INDEX CONCURRENTLY IF EXISTS idx_sync_config_id_where_deleted'); }; diff --git a/packages/database/lib/migrations/20241122212401_integration_backfill_missing_fields.cjs b/packages/database/lib/migrations/20241122212401_integration_backfill_missing_fields.cjs index 6191f13eb78..cb76a1ebfef 100644 --- a/packages/database/lib/migrations/20241122212401_integration_backfill_missing_fields.cjs +++ b/packages/database/lib/migrations/20241122212401_integration_backfill_missing_fields.cjs @@ -1,7 +1,3 @@ -/* eslint-disable @typescript-eslint/no-unsafe-assignment */ -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -/* eslint-disable @typescript-eslint/no-unsafe-call */ -/* eslint-disable @typescript-eslint/no-var-requires */ const path = require('node:path'); const fs = require('node:fs'); const yaml = require('js-yaml'); @@ -23,7 +19,7 @@ exports.up = async function (knex) { const needsClientId = ['OAUTH1', 'OAUTH2', 'TBA', 'APP']; const clientIdProviders = Object.entries(providers) - .filter(([_, config]) => needsClientId.includes(config.auth_mode)) + .filter(([, config]) => needsClientId.includes(config.auth_mode)) .map(([name]) => name); await knex .queryBuilder() @@ -35,7 +31,7 @@ exports.up = async function (knex) { const needsClientSecret = ['OAUTH1', 'OAUTH2', 'TBA', 'APP']; const clientSecretProviders = Object.entries(providers) - .filter(([_, config]) => needsClientSecret.includes(config.auth_mode)) + .filter(([, config]) => needsClientSecret.includes(config.auth_mode)) .map(([name]) => name); await knex .queryBuilder() @@ -47,7 +43,7 @@ exports.up = async function (knex) { const needsAppLink = ['APP']; const appLinkProviders = Object.entries(providers) - .filter(([_, config]) => needsAppLink.includes(config.auth_mode)) + .filter(([, config]) => needsAppLink.includes(config.auth_mode)) .map(([name]) => name); await knex .queryBuilder() diff --git a/packages/database/package.json b/packages/database/package.json index f2886dbac8e..66133d4fb17 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -22,8 +22,8 @@ "tarn": "3.0.2" }, "devDependencies": { - "typescript": "5.3.3", - "vitest": "1.6.0" + "typescript": "5.7.3", + "vitest": "2.1.8" }, "files": [ "dist/**/*" diff --git a/packages/fleet/lib/db/client.ts b/packages/fleet/lib/db/client.ts index 550a1b89e5c..9676d6d6df8 100644 --- a/packages/fleet/lib/db/client.ts +++ b/packages/fleet/lib/db/client.ts @@ -13,7 +13,7 @@ export class DatabaseClient { public url: string; private config: knex.Knex.Config; - constructor({ url, schema, poolMax = 50 }: { url: string; schema: string; poolMax?: number }) { + constructor({ url, schema, poolMax = 15 }: { url: string; schema: string; poolMax?: number }) { this.url = url; this.schema = schema; this.config = { diff --git a/packages/fleet/lib/db/migrations/20241222195951_create_node_config_overrides.ts b/packages/fleet/lib/db/migrations/20241222195951_create_node_config_overrides.ts index cb670bfe769..fd8224b12f3 100644 --- a/packages/fleet/lib/db/migrations/20241222195951_create_node_config_overrides.ts +++ b/packages/fleet/lib/db/migrations/20241222195951_create_node_config_overrides.ts @@ -16,4 +16,6 @@ export async function up(knex: Knex): Promise { `); } -export async function down(_knex: Knex): Promise {} +export async function down(): Promise { + // +} diff --git a/packages/fleet/lib/fleet.ts b/packages/fleet/lib/fleet.ts index 1dc0550edb2..928075065d6 100644 --- a/packages/fleet/lib/fleet.ts +++ b/packages/fleet/lib/fleet.ts @@ -17,7 +17,7 @@ import { noopNodeProvider } from './node-providers/noop.js'; const defaultDbUrl = envs.NANGO_DATABASE_URL || - `postgres://${encodeURIComponent(envs.NANGO_DB_USER)}:${encodeURIComponent(envs.NANGO_DB_PASSWORD)}@${envs.NANGO_DB_HOST}:${envs.NANGO_DB_PORT}/${envs.NANGO_DB_NAME}${envs.NANGO_DB_SSL ? '?sslmode=no-verify' : ''}`; + `postgres://${encodeURIComponent(envs.NANGO_DB_USER)}:${encodeURIComponent(envs.NANGO_DB_PASSWORD)}@${envs.NANGO_DB_HOST}:${envs.NANGO_DB_PORT}/${envs.NANGO_DB_NAME}?application_name=${envs.NANGO_DB_APPLICATION_NAME}${envs.NANGO_DB_SSL ? '&sslmode=no-verify' : ''}`; export class Fleet { public fleetId: string; diff --git a/packages/fleet/lib/index.ts b/packages/fleet/lib/index.ts index 9589ad499f4..06fe30c65e3 100644 --- a/packages/fleet/lib/index.ts +++ b/packages/fleet/lib/index.ts @@ -1,4 +1,4 @@ export * from './fleet.js'; export * from './types.js'; -export * from './node-providers/node_provider.js'; +export type * from './node-providers/node_provider.js'; export * from './models/helpers.js'; diff --git a/packages/fleet/lib/models/deployments.ts b/packages/fleet/lib/models/deployments.ts index 5c61ea471c2..73f8d9e1a47 100644 --- a/packages/fleet/lib/models/deployments.ts +++ b/packages/fleet/lib/models/deployments.ts @@ -34,7 +34,7 @@ const DBDeployment = { export async function create(db: knex.Knex, commitId: CommitHash): Promise> { try { - return db.transaction(async (trx) => { + return await db.transaction(async (trx) => { // do nothing if commitId is already active deployment const active = await getActive(db); if (active.isErr()) { diff --git a/packages/fleet/lib/models/nodes.ts b/packages/fleet/lib/models/nodes.ts index b4e736f868f..dbcf1b4225e 100644 --- a/packages/fleet/lib/models/nodes.ts +++ b/packages/fleet/lib/models/nodes.ts @@ -204,7 +204,7 @@ export async function transitionTo( } ): Promise> { try { - return db.transaction(async (trx) => { + return await db.transaction(async (trx) => { const getNode = await get(trx, props.nodeId, { forUpdate: true }); if (getNode.isErr()) { return getNode; diff --git a/packages/fleet/package.json b/packages/fleet/package.json index 13b751595c0..eb5146cb919 100644 --- a/packages/fleet/package.json +++ b/packages/fleet/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "@nangohq/types": "file:../types", - "vitest": "1.6.0" + "vitest": "2.1.8" } } diff --git a/packages/frontend/lib/connectUI.ts b/packages/frontend/lib/connectUI.ts index 7df2e90b8d3..0c27830293b 100644 --- a/packages/frontend/lib/connectUI.ts +++ b/packages/frontend/lib/connectUI.ts @@ -125,6 +125,8 @@ export class ConnectUI { if (this.iframe) { document.body.removeChild(this.iframe); this.iframe = null; + + document.body.style.overflow = ''; } } diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 3bfd3578e3e..6526b3ee3df 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -20,6 +20,7 @@ "files": [ "dist/**/*.js", "dist/**/*.d.ts", + "dist/**/*.map", "!**/*.json", "README.md" ] diff --git a/packages/frontend/tsconfig.json b/packages/frontend/tsconfig.json index 7d31f7ff63b..008e8d94d72 100644 --- a/packages/frontend/tsconfig.json +++ b/packages/frontend/tsconfig.json @@ -3,7 +3,10 @@ "compilerOptions": { "lib": ["es2015", "dom"], "rootDir": "lib", - "outDir": "dist" + "outDir": "dist", + "declaration": true, + "declarationMap": true, + "sourceMap": true }, "references": [ { diff --git a/packages/jobs/.gitignore b/packages/jobs/.gitignore deleted file mode 100644 index 8c3aba0aad2..00000000000 --- a/packages/jobs/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -tsconfig.tsbuildinfo -dist/* -node_modules diff --git a/packages/jobs/lib/crons/deleteSyncsData.ts b/packages/jobs/lib/crons/deleteSyncsData.ts index 733ee85ed6d..722bd7e15e4 100644 --- a/packages/jobs/lib/crons/deleteSyncsData.ts +++ b/packages/jobs/lib/crons/deleteSyncsData.ts @@ -3,7 +3,6 @@ import db from '@nangohq/database'; import { errorManager, ErrorSourceEnum, hardDeleteJobs, findRecentlyDeletedSync, Orchestrator } from '@nangohq/shared'; import { records } from '@nangohq/records'; import { getLogger, metrics } from '@nangohq/utils'; -import tracer from 'dd-trace'; import { orchestratorClient } from '../clients.js'; const logger = getLogger('Jobs'); @@ -24,7 +23,7 @@ export function deleteSyncsData(): void { logger.info('[deleteSyncs] ✅ done'); } catch (err) { const e = new Error('failed_to_hard_delete_syncs_data', { cause: err instanceof Error ? err.message : err }); - errorManager.report(e, { source: ErrorSourceEnum.PLATFORM }, tracer); + errorManager.report(e, { source: ErrorSourceEnum.PLATFORM }); } metrics.duration(metrics.Types.JOBS_DELETE_SYNCS_DATA, Date.now() - start); }); diff --git a/packages/jobs/lib/crons/timeoutLogsOperations.ts b/packages/jobs/lib/crons/timeoutLogsOperations.ts index f6a4a160304..96e3afbfc2a 100644 --- a/packages/jobs/lib/crons/timeoutLogsOperations.ts +++ b/packages/jobs/lib/crons/timeoutLogsOperations.ts @@ -1,6 +1,5 @@ import * as cron from 'node-cron'; import { errorManager, ErrorSourceEnum } from '@nangohq/shared'; -import tracer from 'dd-trace'; import { envs, model } from '@nangohq/logs'; import { getLogger } from '@nangohq/utils'; @@ -20,7 +19,7 @@ export function timeoutLogsOperations(): void { await model.setTimeoutForAll(); logger.info(`✅ Timeouted`); } catch (err) { - errorManager.report(err, { source: ErrorSourceEnum.PLATFORM }, tracer); + errorManager.report(err, { source: ErrorSourceEnum.PLATFORM }); } } ); diff --git a/packages/jobs/lib/execution/sync.integration.test.ts b/packages/jobs/lib/execution/sync.integration.test.ts index fe050abe22d..3e838ac2c19 100644 --- a/packages/jobs/lib/execution/sync.integration.test.ts +++ b/packages/jobs/lib/execution/sync.integration.test.ts @@ -3,7 +3,7 @@ import { multipleMigrations } from '@nangohq/database'; import type { UnencryptedRecordData, ReturnedRecord } from '@nangohq/records'; import { records as recordsService, format as recordsFormatter, migrate as migrateRecords, clearDbTestsOnly as clearRecordsDb } from '@nangohq/records'; import { handleSyncSuccess, startSync } from './sync.js'; -import type { TaskSync } from '@nangohq/nango-orchestrator'; +import type { TaskAction, TaskOnEvent, TaskSync, TaskSyncAbort, TaskWebhook } from '@nangohq/nango-orchestrator'; import type { Connection, Sync, SyncResult, Job as SyncJob, SyncConfig } from '@nangohq/shared'; import { isSyncJobRunning, seeders, getLatestSyncJob, updateSyncJobResult } from '@nangohq/shared'; import { Ok, stringifyError } from '@nangohq/utils'; @@ -191,11 +191,11 @@ const runJob = async ( provider_config_key: connection.provider_config_key, connection_id: connection.connection_id }, - isSync: () => true, - isAction: () => false, - isOnEvent: () => false, - isSyncAbort: () => false, - isWebhook: () => false + isSync: (): this is TaskSync => true, + isWebhook: (): this is TaskWebhook => false, + isAction: (): this is TaskAction => false, + isOnEvent: (): this is TaskOnEvent => false, + isSyncAbort: (): this is TaskSyncAbort => false }; const nangoProps = await startSync(task, mockStartScript); if (nangoProps.isErr()) { @@ -324,7 +324,7 @@ async function seeds(records: UnencryptedRecordData[], trackDeletes: boolean) { const { env } = await seeders.seedAccountEnvAndUser(); const model = 'GithubIssue'; - const connection = await seeders.createConnectionSeed(env, 'github'); + const connection = await seeders.createConnectionSeed({ env, provider: 'github' }); if (!connection.id) { throw new Error('Failed to create connection'); diff --git a/packages/jobs/lib/execution/sync.ts b/packages/jobs/lib/execution/sync.ts index 1a474c7b174..46e9ede9394 100644 --- a/packages/jobs/lib/execution/sync.ts +++ b/packages/jobs/lib/execution/sync.ts @@ -224,7 +224,7 @@ export async function handleSyncSuccess({ nangoProps }: { nangoProps: NangoProps for (const model of nangoProps.syncConfig.models) { let deletedKeys: string[] = []; if (nangoProps.syncConfig.track_deletes) { - deletedKeys = await records.markNonCurrentGenerationRecordsAsDeleted({ + deletedKeys = await records.markPreviousGenerationRecordsAsDeleted({ connectionId: nangoProps.nangoConnectionId, model, syncId: nangoProps.syncId, diff --git a/packages/jobs/lib/routes/postIdle.ts b/packages/jobs/lib/routes/postIdle.ts index c6721b5a9bc..c76830dc661 100644 --- a/packages/jobs/lib/routes/postIdle.ts +++ b/packages/jobs/lib/routes/postIdle.ts @@ -31,9 +31,11 @@ const handler = async (req: EndpointRequest, res: EndpointResponse, res: EndpointResponse, res: EndpointResponse if (register.isErr()) { throw register.error; } - return res.status(200).json({ status: 'ok' }); + res.status(200).json({ status: 'ok' }); + return; } catch (err) { - return res.status(500).json({ error: { code: 'register_failed', message: err instanceof Error ? err.message : 'failed to register runner' } }); + res.status(500).json({ error: { code: 'register_failed', message: err instanceof Error ? err.message : 'failed to register runner' } }); + return; } }; diff --git a/packages/jobs/lib/runner/local.runner.ts b/packages/jobs/lib/runner/local.runner.ts index 5b8111cea5d..00df93312d3 100644 --- a/packages/jobs/lib/runner/local.runner.ts +++ b/packages/jobs/lib/runner/local.runner.ts @@ -83,7 +83,7 @@ export class LocalRunner implements Runner { }); } - return Promise.resolve(new LocalRunner(runnerId, `http://localhost:${port}`, childProcess.pid)); + return await Promise.resolve(new LocalRunner(runnerId, `http://localhost:${port}`, childProcess.pid)); } catch (err) { throw new Error(`Unable to get runner ${runnerId}: ${stringifyError(err)}`); } diff --git a/packages/jobs/package.json b/packages/jobs/package.json index b30153e1919..7230ef18421 100644 --- a/packages/jobs/package.json +++ b/packages/jobs/package.json @@ -27,18 +27,18 @@ "@nangohq/utils": "file:../utils", "@nangohq/webhooks": "file:../webhooks", "@nangohq/fleet": "file:../fleet", - "axios": "^1.7.4", + "axios": "^1.7.9", "dd-trace": "5.21.0", "get-port": "7.1.0", "express": "4.20.0", "node-cron": "3.0.3", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@types/node": "^20.12.2", - "nodemon": "3.1.7", - "typescript": "5.3.3", - "type-fest": "4.26.1", - "vitest": "1.6.0" + "nodemon": "3.1.9", + "typescript": "5.7.3", + "type-fest": "4.32.0", + "vitest": "2.1.8" } } diff --git a/packages/keystore/package.json b/packages/keystore/package.json index 1f5d97d2dd7..30acf23123b 100644 --- a/packages/keystore/package.json +++ b/packages/keystore/package.json @@ -23,6 +23,6 @@ }, "devDependencies": { "@nangohq/types": "file:../types", - "vitest": "1.6.0" + "vitest": "2.1.8" } } diff --git a/packages/kvstore/package.json b/packages/kvstore/package.json index 07b97bf8e5c..22d22c0c197 100644 --- a/packages/kvstore/package.json +++ b/packages/kvstore/package.json @@ -18,7 +18,7 @@ "redis": "4.6.13" }, "devDependencies": { - "vitest": "1.6.0" + "vitest": "2.1.8" }, "files": [ "dist/**/*" diff --git a/packages/logs/package.json b/packages/logs/package.json index 243d46dfe16..e57c0b9ac0d 100644 --- a/packages/logs/package.json +++ b/packages/logs/package.json @@ -24,12 +24,12 @@ "@opentelemetry/sdk-trace-base": "1.27.0", "@opentelemetry/sdk-trace-node": "1.27.0", "@opentelemetry/semantic-conventions": "1.27.0", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@nangohq/types": "file:../types", - "type-fest": "4.26.1", - "vitest": "1.6.0" + "type-fest": "4.32.0", + "vitest": "2.1.8" }, "files": [ "dist/**/*" diff --git a/packages/nango-yaml/lib/modelsParser.ts b/packages/nango-yaml/lib/modelsParser.ts index c14891147e7..51cda70f3be 100644 --- a/packages/nango-yaml/lib/modelsParser.ts +++ b/packages/nango-yaml/lib/modelsParser.ts @@ -70,7 +70,7 @@ export class ModelsParser { // At this point we are sure it's a Model stack.add(name); - this.parseOne({ name, fields: this.raw[name]!, stack }); + this.parseOne({ name, fields: this.raw[name], stack }); return true; } diff --git a/packages/nango-yaml/package.json b/packages/nango-yaml/package.json index 92f31c934d7..4f2742dbdf6 100644 --- a/packages/nango-yaml/package.json +++ b/packages/nango-yaml/package.json @@ -18,7 +18,7 @@ }, "devDependencies": { "@nangohq/types": "0.48.1", - "vitest": "1.6.0" + "vitest": "2.1.8" }, "files": [ "dist/**/*" diff --git a/packages/node-client/lib/index.ts b/packages/node-client/lib/index.ts index 6572c4b0ba3..b03c47496ea 100644 --- a/packages/node-client/lib/index.ts +++ b/packages/node-client/lib/index.ts @@ -745,6 +745,7 @@ export class Nango { * @param input - An optional input data for the action * @returns A promise that resolves with an object containing the response data from the triggered action */ + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters public async triggerAction(providerConfigKey: string, connectionId: string, actionName: string, input?: In): Promise { const url = `${this.serverUrl}/action/trigger`; diff --git a/packages/node-client/lib/utils.ts b/packages/node-client/lib/utils.ts index 3f169e8c797..8961d06db64 100644 --- a/packages/node-client/lib/utils.ts +++ b/packages/node-client/lib/utils.ts @@ -41,7 +41,7 @@ export function getUserAgent(userAgent?: string): string { return `nango-node-client/${NANGO_VERSION} (${osName}/${osVersion}; node.js/${nodeVersion})${userAgent ? `; ${userAgent}` : ''}`; } -export function addQueryParams(url: URL, queries?: Record | undefined) { +export function addQueryParams(url: URL, queries?: Record) { if (!queries) { return; } diff --git a/packages/node-client/package.json b/packages/node-client/package.json index 9f2b66348a8..1748b3650ec 100644 --- a/packages/node-client/package.json +++ b/packages/node-client/package.json @@ -25,7 +25,7 @@ }, "license": "SEE LICENSE IN LICENSE FILE IN GIT REPOSITORY", "dependencies": { - "axios": "^1.7.4" + "axios": "^1.7.9" }, "engines": { "node": ">=18.0" @@ -38,6 +38,6 @@ "devDependencies": { "@nangohq/types": "0.48.1", "tsup": "^8.2.4", - "vitest": "1.6.0" + "vitest": "2.1.8" } } diff --git a/packages/orchestrator/lib/clients/types.ts b/packages/orchestrator/lib/clients/types.ts index b950473d393..2f49bab4f38 100644 --- a/packages/orchestrator/lib/clients/types.ts +++ b/packages/orchestrator/lib/clients/types.ts @@ -108,11 +108,11 @@ export function TaskSync(props: TaskCommonFields & SyncArgs): TaskSync { debug: props.debug, connection: props.connection, groupKey: props.groupKey, - isSync: () => true, - isWebhook: () => false, - isAction: () => false, - isOnEvent: () => false, - isSyncAbort: () => false + isSync: (): this is TaskSync => true, + isWebhook: (): this is TaskWebhook => false, + isAction: (): this is TaskAction => false, + isOnEvent: (): this is TaskOnEvent => false, + isSyncAbort: (): this is TaskSyncAbort => false }; } @@ -130,11 +130,11 @@ export function TaskSyncAbort(props: TaskCommonFields & SyncArgs & AbortArgs): T connection: props.connection, groupKey: props.groupKey, reason: props.reason, - isSync: () => false, - isWebhook: () => false, - isAction: () => false, - isOnEvent: () => false, - isSyncAbort: () => true + isSync: (): this is TaskSync => false, + isWebhook: (): this is TaskWebhook => false, + isAction: (): this is TaskAction => false, + isOnEvent: (): this is TaskOnEvent => false, + isSyncAbort: (): this is TaskSyncAbort => true }; } @@ -150,11 +150,11 @@ export function TaskAction(props: TaskCommonFields & ActionArgs): TaskAction { activityLogId: props.activityLogId, input: props.input, groupKey: props.groupKey, - isSync: () => false, - isWebhook: () => false, - isAction: () => true, - isOnEvent: () => false, - isSyncAbort: () => false + isSync: (): this is TaskSync => false, + isWebhook: (): this is TaskWebhook => false, + isAction: (): this is TaskAction => true, + isOnEvent: (): this is TaskOnEvent => false, + isSyncAbort: (): this is TaskSyncAbort => false }; } @@ -171,11 +171,11 @@ export function TaskWebhook(props: TaskCommonFields & WebhookArgs): TaskWebhook activityLogId: props.activityLogId, input: props.input, groupKey: props.groupKey, - isSync: () => false, - isWebhook: () => true, - isAction: () => false, - isOnEvent: () => false, - isSyncAbort: () => false + isSync: (): this is TaskSync => false, + isWebhook: (): this is TaskWebhook => true, + isAction: (): this is TaskAction => false, + isOnEvent: (): this is TaskOnEvent => false, + isSyncAbort: (): this is TaskSyncAbort => false }; } @@ -192,11 +192,11 @@ export function TaskOnEvent(props: TaskCommonFields & OnEventArgs): TaskOnEvent fileLocation: props.fileLocation, activityLogId: props.activityLogId, groupKey: props.groupKey, - isSync: () => false, - isWebhook: () => false, - isAction: () => false, - isOnEvent: () => true, - isSyncAbort: () => false + isSync: (): this is TaskSync => false, + isWebhook: (): this is TaskWebhook => false, + isAction: (): this is TaskAction => false, + isOnEvent: (): this is TaskOnEvent => true, + isSyncAbort: (): this is TaskSyncAbort => false }; } diff --git a/packages/orchestrator/lib/routes/getHealth.ts b/packages/orchestrator/lib/routes/getHealth.ts index a179c9bf2b8..4d5dc8c30e7 100644 --- a/packages/orchestrator/lib/routes/getHealth.ts +++ b/packages/orchestrator/lib/routes/getHealth.ts @@ -14,5 +14,7 @@ export const routeHandler: RouteHandler = { path, method, validate: (_req, _res, next) => next(), // No extra validation needed - handler: (_req, res) => res.status(200).json({ status: 'ok' }) + handler: (_req, res) => { + res.status(200).json({ status: 'ok' }); + } }; diff --git a/packages/orchestrator/lib/routes/v1/postImmediate.ts b/packages/orchestrator/lib/routes/v1/postImmediate.ts index d63be164a84..c7b01cc6293 100644 --- a/packages/orchestrator/lib/routes/v1/postImmediate.ts +++ b/packages/orchestrator/lib/routes/v1/postImmediate.ts @@ -88,9 +88,11 @@ const handler = (scheduler: Scheduler) => { heartbeatTimeoutSecs: req.body.timeoutSettingsInSecs.heartbeat }); if (task.isErr()) { - return res.status(500).json({ error: { code: 'immediate_failed', message: task.error.message } }); + res.status(500).json({ error: { code: 'immediate_failed', message: task.error.message } }); + return; } - return res.status(200).json({ taskId: task.value.id }); + res.status(200).json({ taskId: task.value.id }); + return; }; }; diff --git a/packages/orchestrator/lib/routes/v1/postRecurring.ts b/packages/orchestrator/lib/routes/v1/postRecurring.ts index 6c806a78fc0..270a3f6025e 100644 --- a/packages/orchestrator/lib/routes/v1/postRecurring.ts +++ b/packages/orchestrator/lib/routes/v1/postRecurring.ts @@ -73,9 +73,11 @@ const handler = (scheduler: Scheduler) => { lastScheduledTaskId: null }); if (schedule.isErr()) { - return res.status(500).json({ error: { code: 'recurring_failed', message: schedule.error.message } }); + res.status(500).json({ error: { code: 'recurring_failed', message: schedule.error.message } }); + return; } - return res.status(200).json({ scheduleId: schedule.value.id }); + res.status(200).json({ scheduleId: schedule.value.id }); + return; }; }; diff --git a/packages/orchestrator/lib/routes/v1/putRecurring.ts b/packages/orchestrator/lib/routes/v1/putRecurring.ts index 311317afef2..283b92bbb0e 100644 --- a/packages/orchestrator/lib/routes/v1/putRecurring.ts +++ b/packages/orchestrator/lib/routes/v1/putRecurring.ts @@ -48,12 +48,15 @@ const handler = (scheduler: Scheduler) => { updatedSchedule = await scheduler.setScheduleFrequency({ scheduleName: schedule.name, frequencyMs: schedule.frequencyMs }); } if (!updatedSchedule) { - return res.status(400).json({ error: { code: 'put_recurring_failed', message: `invalid parameters: ${JSON.stringify(schedule)}` } }); + res.status(400).json({ error: { code: 'put_recurring_failed', message: `invalid parameters: ${JSON.stringify(schedule)}` } }); + return; } if (updatedSchedule.isErr()) { - return res.status(500).json({ error: { code: 'put_recurring_failed', message: updatedSchedule.error.message } }); + res.status(500).json({ error: { code: 'put_recurring_failed', message: updatedSchedule.error.message } }); + return; } - return res.status(200).json({ scheduleId: updatedSchedule.value.id }); + res.status(200).json({ scheduleId: updatedSchedule.value.id }); + return; }; }; diff --git a/packages/orchestrator/lib/routes/v1/schedules/postRun.ts b/packages/orchestrator/lib/routes/v1/schedules/postRun.ts index 1bbaa20dd0e..305d778925d 100644 --- a/packages/orchestrator/lib/routes/v1/schedules/postRun.ts +++ b/packages/orchestrator/lib/routes/v1/schedules/postRun.ts @@ -32,9 +32,11 @@ const handler = (scheduler: Scheduler) => { scheduleName: req.body.scheduleName }); if (schedule.isErr()) { - return res.status(500).json({ error: { code: 'recurring_run_failed', message: schedule.error.message } }); + res.status(500).json({ error: { code: 'recurring_run_failed', message: schedule.error.message } }); + return; } - return res.status(200).json({ scheduleId: schedule.value.id }); + res.status(200).json({ scheduleId: schedule.value.id }); + return; }; }; diff --git a/packages/orchestrator/lib/routes/v1/schedules/postSearch.ts b/packages/orchestrator/lib/routes/v1/schedules/postSearch.ts index 9a852194d66..bb784faec74 100644 --- a/packages/orchestrator/lib/routes/v1/schedules/postSearch.ts +++ b/packages/orchestrator/lib/routes/v1/schedules/postSearch.ts @@ -37,9 +37,11 @@ const handler = (scheduler: Scheduler) => { ...(names ? { names } : {}) }); if (getSchedules.isErr()) { - return res.status(500).json({ error: { code: 'search_failed', message: getSchedules.error.message } }); + res.status(500).json({ error: { code: 'search_failed', message: getSchedules.error.message } }); + return; } - return res.status(200).json(getSchedules.value); + res.status(200).json(getSchedules.value); + return; }; }; diff --git a/packages/orchestrator/lib/routes/v1/tasks/postSearch.ts b/packages/orchestrator/lib/routes/v1/tasks/postSearch.ts index 3480553ce88..c5b04f2a195 100644 --- a/packages/orchestrator/lib/routes/v1/tasks/postSearch.ts +++ b/packages/orchestrator/lib/routes/v1/tasks/postSearch.ts @@ -40,9 +40,11 @@ const handler = (scheduler: Scheduler) => { ...(limit ? { limit } : {}) }); if (getTasks.isErr()) { - return res.status(500).json({ error: { code: 'search_failed', message: getTasks.error.message } }); + res.status(500).json({ error: { code: 'search_failed', message: getTasks.error.message } }); + return; } - return res.status(200).json(getTasks.value); + res.status(200).json(getTasks.value); + return; }; }; diff --git a/packages/orchestrator/package.json b/packages/orchestrator/package.json index 435ff52e28e..b32d27c230c 100644 --- a/packages/orchestrator/package.json +++ b/packages/orchestrator/package.json @@ -20,12 +20,12 @@ "express": "4.20.0", "get-port": "7.1.0", "p-queue": "8.0.1", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@nangohq/types": "file:../types", - "type-fest": "4.26.1", + "type-fest": "4.32.0", "@types/node": "20.12.2", - "vitest": "1.6.0" + "vitest": "2.1.8" } } diff --git a/packages/persist/lib/routes/getHealth.ts b/packages/persist/lib/routes/getHealth.ts index f6cb7b8aa7c..bacea1bdf02 100644 --- a/packages/persist/lib/routes/getHealth.ts +++ b/packages/persist/lib/routes/getHealth.ts @@ -14,5 +14,7 @@ export const routeHandler: RouteHandler = { path, method, validate: (_req, _res, next) => next(), - handler: (_req, res) => res.status(200).json({ status: 'ok' }) + handler: (_req, res) => { + res.status(200).json({ status: 'ok' }); + } }; diff --git a/packages/persist/package.json b/packages/persist/package.json index f9e0e4c7b62..6625d16222c 100644 --- a/packages/persist/package.json +++ b/packages/persist/package.json @@ -26,12 +26,12 @@ "@nangohq/utils": "file:../utils", "dd-trace": "5.21.0", "express": "^4.20.0", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@types/node": "20.12.2", "node-fetch": "^3.3.2", - "typescript": "5.3.3", - "vitest": "1.6.0" + "typescript": "5.7.3", + "vitest": "2.1.8" } } diff --git a/packages/records/lib/db/config.ts b/packages/records/lib/db/config.ts index 65afe86ff01..ea12f4d5533 100644 --- a/packages/records/lib/db/config.ts +++ b/packages/records/lib/db/config.ts @@ -5,7 +5,7 @@ export const schema = envs.RECORDS_DATABASE_SCHEMA; const databaseUrl = envs.RECORDS_DATABASE_URL || envs.NANGO_DATABASE_URL || - `postgres://${encodeURIComponent(envs.NANGO_DB_USER)}:${encodeURIComponent(envs.NANGO_DB_PASSWORD)}@${envs.NANGO_DB_HOST}:${envs.NANGO_DB_PORT}/${envs.NANGO_DB_NAME}`; + `postgres://${encodeURIComponent(envs.NANGO_DB_USER)}:${encodeURIComponent(envs.NANGO_DB_PASSWORD)}@${envs.NANGO_DB_HOST}:${envs.NANGO_DB_PORT}/${envs.NANGO_DB_NAME}?application_name=${envs.NANGO_DB_APPLICATION_NAME}`; const runningMigrationOnly = process.argv.some((v) => v === 'migrate:latest'); const isJS = !runningMigrationOnly; diff --git a/packages/records/lib/index.ts b/packages/records/lib/index.ts index 91ab31040e5..6b92acb2a4f 100644 --- a/packages/records/lib/index.ts +++ b/packages/records/lib/index.ts @@ -1,5 +1,5 @@ export * from './db/migrate.js'; export * as records from './models/records.js'; export * as format from './helpers/format.js'; -export * from './types.js'; +export type * from './types.js'; export { clearDb as clearDbTestsOnly } from './db/test.helpers.js'; diff --git a/packages/records/lib/models/records.integration.test.ts b/packages/records/lib/models/records.integration.test.ts index ff5acfad7aa..c35b3a98c1f 100644 --- a/packages/records/lib/models/records.integration.test.ts +++ b/packages/records/lib/models/records.integration.test.ts @@ -1,4 +1,4 @@ -import { expect, describe, it, beforeAll, afterEach } from 'vitest'; +import { expect, describe, it, beforeAll, afterAll } from 'vitest'; import dayjs from 'dayjs'; import * as uuid from 'uuid'; import { migrate } from '../db/migrate.js'; @@ -13,13 +13,13 @@ describe('Records service', () => { await migrate(); }); - afterEach(async () => { + afterAll(async () => { await db(RECORDS_TABLE).truncate(); }); it('Should write records', async () => { - const connectionId = 1; - const environmentId = 2; + const connectionId = Math.floor(Math.random() * 1000000); + const environmentId = Math.floor(Math.random() * 1000000); const model = 'my-model'; const syncId = '00000000-0000-0000-0000-000000000000'; const records = [ @@ -50,8 +50,8 @@ describe('Records service', () => { }); it('Should be able to encrypt and insert 2000 records under 2 seconds', async () => { - const connectionId = 1; - const environmentId = 2; + const connectionId = Math.floor(Math.random() * 1000000); + const environmentId = Math.floor(Math.random() * 1000000); const model = 'my-model'; const syncId = '00000000-0000-0000-0000-000000000000'; const records = Array.from({ length: 2000 }, (_, i) => ({ @@ -76,8 +76,8 @@ describe('Records service', () => { }); it('Should delete records', async () => { - const connectionId = 1; - const environmentId = 2; + const connectionId = Math.floor(Math.random() * 1000000); + const environmentId = Math.floor(Math.random() * 1000000); const model = 'my-model'; const syncId = '00000000-0000-0000-0000-000000000000'; const records = [ @@ -196,8 +196,8 @@ describe('Records service', () => { }); it('Should return correct added records count when upserting concurrently', async () => { - const connectionId = 1; - const environmentId = 2; + const connectionId = Math.floor(Math.random() * 1000000); + const environmentId = Math.floor(Math.random() * 1000000); const model = 'my-model'; const syncId = '00000000-0000-0000-0000-000000000000'; const syncJobId = 1; diff --git a/packages/records/lib/models/records.ts b/packages/records/lib/models/records.ts index be21cb9a2f4..995a1b0e656 100644 --- a/packages/records/lib/models/records.ts +++ b/packages/records/lib/models/records.ts @@ -447,9 +447,9 @@ export async function deleteRecordCount({ connectionId, environmentId, model }: await db.from(RECORD_COUNTS_TABLE).where({ connection_id: connectionId, environment_id: environmentId, model }).del(); } -// Mark all non-deleted records that don't belong to currentGeneration as deleted +// Mark all non-deleted records from previous generations as deleted // returns the ids of records being deleted -export async function markNonCurrentGenerationRecordsAsDeleted({ +export async function markPreviousGenerationRecordsAsDeleted({ connectionId, model, syncId, @@ -471,9 +471,7 @@ export async function markNonCurrentGenerationRecordsAsDeleted({ sync_id: syncId, deleted_at: null }) - .whereNot({ - sync_job_id: generation - }) + .where('sync_job_id', '<', generation) .update({ deleted_at: now, updated_at: now, diff --git a/packages/records/package.json b/packages/records/package.json index 524ca08022a..6afe6d663fd 100644 --- a/packages/records/package.json +++ b/packages/records/package.json @@ -26,6 +26,6 @@ }, "devDependencies": { "@types/md5": "2.3.2", - "vitest": "1.6.0" + "vitest": "2.1.8" } } diff --git a/packages/runner/.gitignore b/packages/runner/.gitignore deleted file mode 100644 index 8c3aba0aad2..00000000000 --- a/packages/runner/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -tsconfig.tsbuildinfo -dist/* -node_modules diff --git a/packages/runner/package.json b/packages/runner/package.json index c999b7177a6..6d5ed9739e0 100644 --- a/packages/runner/package.json +++ b/packages/runner/package.json @@ -22,7 +22,7 @@ "@nangohq/utils": "file:../utils", "@trpc/client": "^10.45.1", "@trpc/server": "^10.45.1", - "axios": "^1.7.4", + "axios": "^1.7.9", "botbuilder": "4.23.1", "connect-timeout": "1.9.0", "dd-trace": "5.21.0", @@ -30,13 +30,13 @@ "soap": "1.1.2", "superjson": "2.2.1", "undici": "6.12.0", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@nangohq/types": "file:../types", "@types/connect-timeout": "0.0.39", "@types/node": "20.12.2", - "typescript": "5.3.3", - "vitest": "1.6.0" + "typescript": "5.7.3", + "vitest": "2.1.8" } } diff --git a/packages/scheduler/lib/types.ts b/packages/scheduler/lib/types.ts index 2edb4063158..a215d9f6cea 100644 --- a/packages/scheduler/lib/types.ts +++ b/packages/scheduler/lib/types.ts @@ -30,6 +30,7 @@ export interface Task { export type ImmediateProps = Omit; export type { ScheduleProps }; +// eslint-disable-next-line @typescript-eslint/no-unused-vars const scheduleStates = ['PAUSED', 'STARTED', 'DELETED'] as const; export type ScheduleState = (typeof scheduleStates)[number]; diff --git a/packages/scheduler/package.json b/packages/scheduler/package.json index 65442761262..a47f419421c 100644 --- a/packages/scheduler/package.json +++ b/packages/scheduler/package.json @@ -23,7 +23,7 @@ "uuidv7": "0.6.3" }, "devDependencies": { - "type-fest": "4.26.1", - "vitest": "1.6.0" + "type-fest": "4.32.0", + "vitest": "2.1.8" } } diff --git a/packages/server/lib/controllers/appAuth.controller.ts b/packages/server/lib/controllers/appAuth.controller.ts index 9c0312da66b..9f2758d1316 100644 --- a/packages/server/lib/controllers/appAuth.controller.ts +++ b/packages/server/lib/controllers/appAuth.controller.ts @@ -127,7 +127,8 @@ class AppAuthController { await logCtx.error(error.message, { connectionConfig, url: req.originalUrl }); await logCtx.failed(); - return publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error); + return; } if (!installation_id) { @@ -171,7 +172,8 @@ class AppAuthController { logCtx ); - return publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error as NangoError); + await publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error as NangoError); + return; } const [updatedConnection] = await connectionService.upsertConnection({ @@ -186,7 +188,8 @@ class AppAuthController { if (!updatedConnection) { await logCtx.error('Failed to create connection'); await logCtx.failed(); - return publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, WSErrBuilder.UnknownError('failed to create connection')); + await publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, WSErrBuilder.UnknownError('failed to create connection')); + return; } let connectSession: ConnectSessionAndEndUser | undefined; @@ -199,7 +202,8 @@ class AppAuthController { if (connectSessionRes.isErr()) { await logCtx.error('Failed to get session'); await logCtx.failed(); - return publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, WSErrBuilder.UnknownError('failed to get session')); + await publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, WSErrBuilder.UnknownError('failed to get session')); + return; } connectSession = connectSessionRes.value; @@ -233,7 +237,8 @@ class AppAuthController { authMode: String(provider.auth_mode) }); - return publisher.notifySuccess(res, wsClientId, providerConfigKey, connectionId); + await publisher.notifySuccess(res, wsClientId, providerConfigKey, connectionId); + return; } catch (err) { const prettyError = stringifyError(err, { pretty: true }); diff --git a/packages/server/lib/controllers/connect/postReconnect.integration.test.ts b/packages/server/lib/controllers/connect/postReconnect.integration.test.ts index dfbf8acc59e..2d4f7edaca7 100644 --- a/packages/server/lib/controllers/connect/postReconnect.integration.test.ts +++ b/packages/server/lib/controllers/connect/postReconnect.integration.test.ts @@ -55,7 +55,7 @@ describe(`POST ${endpoint}`, () => { // Create an initial connection await seeders.createConfigSeed(env, 'github', 'github'); - const connection = await seeders.createConnectionSeed(env, 'github'); + const connection = await seeders.createConnectionSeed({ env, provider: 'github' }); await linkConnection(db.knex, { endUserId: endUser.id, connection }); const res = await api.fetch(endpoint, { @@ -84,7 +84,7 @@ describe(`POST ${endpoint}`, () => { // Create an initial connection await seeders.createConfigSeed(env, 'github', 'github'); - const connection = await seeders.createConnectionSeed(env, 'github'); + const connection = await seeders.createConnectionSeed({ env, provider: 'github' }); const res = await api.fetch(endpoint, { method: 'POST', @@ -108,7 +108,7 @@ describe(`POST ${endpoint}`, () => { // Create an initial connection await seeders.createConfigSeed(env, 'github', 'github'); - const connection = await seeders.createConnectionSeed(env, 'github'); + const connection = await seeders.createConnectionSeed({ env, provider: 'github' }); const res = await api.fetch(endpoint, { method: 'POST', diff --git a/packages/server/lib/controllers/connection/connectionId/getConnection.integration.test.ts b/packages/server/lib/controllers/connection/connectionId/getConnection.integration.test.ts index e2613575263..a61013c5688 100644 --- a/packages/server/lib/controllers/connection/connectionId/getConnection.integration.test.ts +++ b/packages/server/lib/controllers/connection/connectionId/getConnection.integration.test.ts @@ -61,7 +61,10 @@ describe(`GET ${endpoint}`, () => { const { env, account } = await seeders.seedAccountEnvAndUser(); await seeders.createConfigSeed(env, 'algolia', 'algolia'); const endUser = await seeders.createEndUser({ environment: env, account }); - const conn = await seeders.createConnectionSeed(env, 'algolia', endUser, { + const conn = await seeders.createConnectionSeed({ + env, + provider: 'algolia', + endUser, rawCredentials: { type: 'API_KEY', apiKey: 'test_api_key' }, connectionConfig: { APP_ID: 'TEST' } }); @@ -83,11 +86,11 @@ describe(`GET ${endpoint}`, () => { }, connection_config: { APP_ID: 'TEST' }, end_user: { - displayName: null, + display_name: null, email: endUser.email, id: endUser.endUserId, organization: { - displayName: null, + display_name: null, id: endUser.organization!.organizationId } }, @@ -106,13 +109,19 @@ describe(`GET ${endpoint}`, () => { await seeders.createConfigSeed(env, 'algolia', 'algolia'); const endUser = await seeders.createEndUser({ environment: env, account }); - const conn = await seeders.createConnectionSeed(env, 'algolia', endUser, { + const conn = await seeders.createConnectionSeed({ + env, + provider: 'algolia', + endUser, rawCredentials: { type: 'API_KEY', apiKey: 'test_api_key' }, connectionConfig: { APP_ID: 'TEST' } }); await seeders.createConfigSeed(env, 'google', 'google'); - await seeders.createConnectionSeed(env, 'google', endUser, { + await seeders.createConnectionSeed({ + env, + provider: 'google', + endUser, connectionId: conn.connection_id, rawCredentials: { type: 'API_KEY', apiKey: 'test_api_key' }, connectionConfig: { APP_ID: 'TEST' } @@ -135,11 +144,11 @@ describe(`GET ${endpoint}`, () => { }, connection_config: { APP_ID: 'TEST' }, end_user: { - displayName: null, + display_name: null, email: endUser.email, id: endUser.endUserId, organization: { - displayName: null, + display_name: null, id: endUser.organization!.organizationId } }, diff --git a/packages/server/lib/controllers/connection/connectionId/metadata/patchMetadata.integration.test.ts b/packages/server/lib/controllers/connection/connectionId/metadata/patchMetadata.integration.test.ts index f403be9dbdf..4e4635c5b93 100644 --- a/packages/server/lib/controllers/connection/connectionId/metadata/patchMetadata.integration.test.ts +++ b/packages/server/lib/controllers/connection/connectionId/metadata/patchMetadata.integration.test.ts @@ -136,7 +136,7 @@ describe(`PATCH ${endpoint}`, () => { const env = await seeders.createEnvironmentSeed(); const unique_key = 'test-update'; await seeders.createConfigSeed(env, unique_key, 'google'); - const connections = await seeders.createConnectionSeed(env, unique_key); + const connections = await seeders.createConnectionSeed({ env, provider: unique_key }); const { connection_id, provider_config_key } = connections; diff --git a/packages/server/lib/controllers/connection/connectionId/metadata/postMetadata.integration.test.ts b/packages/server/lib/controllers/connection/connectionId/metadata/postMetadata.integration.test.ts index 8e0f665a9c6..ba7cbdbdeac 100644 --- a/packages/server/lib/controllers/connection/connectionId/metadata/postMetadata.integration.test.ts +++ b/packages/server/lib/controllers/connection/connectionId/metadata/postMetadata.integration.test.ts @@ -136,7 +136,7 @@ describe(`POST ${endpoint}`, () => { it('Should replace existing metadata, overwriting anything existing', async () => { const env = await seeders.createEnvironmentSeed(); await seeders.createConfigSeed(env, 'test-replace', 'google'); - const connections = await seeders.createConnectionSeed(env, 'test-replace'); + const connections = await seeders.createConnectionSeed({ env, provider: 'test-replace' }); const { connection_id, provider_config_key } = connections; diff --git a/packages/server/lib/controllers/connection/getConnections.integration.test.ts b/packages/server/lib/controllers/connection/getConnections.integration.test.ts index f99f0378be6..9e4720dddea 100644 --- a/packages/server/lib/controllers/connection/getConnections.integration.test.ts +++ b/packages/server/lib/controllers/connection/getConnections.integration.test.ts @@ -41,7 +41,7 @@ describe(`GET ${endpoint}`, () => { it('should list one connection', async () => { const { env } = await seeders.seedAccountEnvAndUser(); await seeders.createConfigSeed(env, 'github', 'github'); - const conn = await seeders.createConnectionSeed(env, 'github'); + const conn = await seeders.createConnectionSeed({ env, provider: 'github' }); const res = await api.fetch(endpoint, { method: 'GET', @@ -69,8 +69,8 @@ describe(`GET ${endpoint}`, () => { it('should search connections', async () => { const { env } = await seeders.seedAccountEnvAndUser(); await seeders.createConfigSeed(env, 'github', 'github'); - await seeders.createConnectionSeed(env, 'github'); - const conn2 = await seeders.createConnectionSeed(env, 'github'); + await seeders.createConnectionSeed({ env, provider: 'github' }); + const conn2 = await seeders.createConnectionSeed({ env, provider: 'github' }); const res = await api.fetch(endpoint, { method: 'GET', @@ -91,7 +91,7 @@ describe(`GET ${endpoint}`, () => { const { env, account } = await seeders.seedAccountEnvAndUser(); await seeders.createConfigSeed(env, 'github', 'github'); const endUser = await seeders.createEndUser({ environment: env, account }); - const conn = await seeders.createConnectionSeed(env, 'github', endUser); + const conn = await seeders.createConnectionSeed({ env, provider: 'github', endUser }); const res = await api.fetch(endpoint, { method: 'GET', @@ -103,12 +103,14 @@ describe(`GET ${endpoint}`, () => { expect(res.json).toMatchObject({ connections: [ { + id: conn.id!, + provider_config_key: 'github', connection_id: conn.connection_id, end_user: { id: endUser.endUserId, - displayName: null, + display_name: null, email: endUser.email, - organization: { id: endUser.organization!.organizationId, displayName: endUser.organization!.displayName! } + organization: { id: endUser.organization!.organizationId, display_name: endUser.organization!.displayName! } } } ] @@ -120,7 +122,7 @@ describe(`GET ${endpoint}`, () => { const { env, account } = await seeders.seedAccountEnvAndUser(); await seeders.createConfigSeed(env, 'github', 'github'); const endUser = await seeders.createEndUser({ environment: env, account }); - await seeders.createConnectionSeed(env, 'github', endUser); + await seeders.createConnectionSeed({ env, provider: 'github', endUser }); const res = await api.fetch(endpoint, { method: 'GET', @@ -140,7 +142,7 @@ describe(`GET ${endpoint}`, () => { const { env, account } = await seeders.seedAccountEnvAndUser(); await seeders.createConfigSeed(env, 'github', 'github'); const endUser = await seeders.createEndUser({ environment: env, account }); - const conn = await seeders.createConnectionSeed(env, 'github', endUser); + const conn = await seeders.createConnectionSeed({ env, provider: 'github', endUser }); const res = await api.fetch(endpoint, { method: 'GET', @@ -160,7 +162,7 @@ describe(`GET ${endpoint}`, () => { const { env, account } = await seeders.seedAccountEnvAndUser(); await seeders.createConfigSeed(env, 'github', 'github'); const endUser = await seeders.createEndUser({ environment: env, account }); - const conn = await seeders.createConnectionSeed(env, 'github', endUser); + const conn = await seeders.createConnectionSeed({ env, provider: 'github', endUser }); const res = await api.fetch(endpoint, { method: 'GET', diff --git a/packages/server/lib/controllers/oauth.controller.ts b/packages/server/lib/controllers/oauth.controller.ts index 7653a3df3d7..c77b5ca2d9b 100644 --- a/packages/server/lib/controllers/oauth.controller.ts +++ b/packages/server/lib/controllers/oauth.controller.ts @@ -102,7 +102,8 @@ class OAuthController { await logCtx.error(error.message); await logCtx.failed(); - return publisher.notifyErr(res, wsClientId, providerConfigKey, receivedConnectionId, error); + await publisher.notifyErr(res, wsClientId, providerConfigKey, receivedConnectionId, error); + return; } if (environment.hmac_enabled && !isConnectSession) { @@ -112,7 +113,8 @@ class OAuthController { await logCtx.error(error.message); await logCtx.failed(); - return publisher.notifyErr(res, wsClientId, providerConfigKey, receivedConnectionId, error); + await publisher.notifyErr(res, wsClientId, providerConfigKey, receivedConnectionId, error); + return; } const verified = hmacService.verify({ receivedDigest: hmac, environment, values: [providerConfigKey, receivedConnectionId] }); @@ -121,7 +123,8 @@ class OAuthController { await logCtx.error(error.message); await logCtx.failed(); - return publisher.notifyErr(res, wsClientId, providerConfigKey, receivedConnectionId, error); + await publisher.notifyErr(res, wsClientId, providerConfigKey, receivedConnectionId, error); + return; } } @@ -134,7 +137,8 @@ class OAuthController { await logCtx.error(error.message); await logCtx.failed(); - return publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error); + return; } await logCtx.enrichOperation({ integrationId: config.id!, integrationName: config.unique_key, providerName: config.provider }); @@ -145,7 +149,8 @@ class OAuthController { await logCtx.error(error.message); await logCtx.failed(); - return publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error); + return; } if (!(await isIntegrationAllowed({ config, res, logCtx }))) { @@ -230,11 +235,12 @@ class OAuthController { await logCtx.error(error.message); await logCtx.failed(); - return publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error); + return; } if (provider.auth_mode === 'OAUTH2') { - return this.oauth2Request({ + await this.oauth2Request({ provider: provider as ProviderOAuth2, providerConfig: config, session, @@ -246,17 +252,21 @@ class OAuthController { userScope, logCtx }); + return; } else if (provider.auth_mode === 'APP' || provider.auth_mode === 'CUSTOM') { - return this.appRequest(provider, config, session, res, authorizationParams, logCtx); + await this.appRequest(provider, config, session, res, authorizationParams, logCtx); + return; } else if (provider.auth_mode === 'OAUTH1') { - return this.oauth1Request(provider, config, session, res, callbackUrl, environmentId, logCtx); + await this.oauth1Request(provider, config, session, res, callbackUrl, environmentId, logCtx); + return; } const error = WSErrBuilder.UnknownAuthMode(provider.auth_mode); await logCtx.error(error.message); await logCtx.failed(); - return publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, wsClientId, providerConfigKey, connectionId, error); + return; } catch (err) { const prettyError = stringifyError(err, { pretty: true }); const error = WSErrBuilder.UnknownError(); @@ -515,7 +525,8 @@ class OAuthController { await logCtx.error(error.message, { connectionConfig }); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + return; } if (missesInterpolationParam(tokenUrl, connectionConfig)) { @@ -523,7 +534,8 @@ class OAuthController { await logCtx.error(error.message, { connectionConfig }); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + return; } if (provider.authorization_params && missesInterpolationParamInObject(provider.authorization_params, connectionConfig)) { @@ -531,7 +543,8 @@ class OAuthController { await logCtx.error(error.message, { connectionConfig }); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + return; } if (provider.token_params && missesInterpolationParamInObject(provider.token_params, connectionConfig)) { @@ -539,7 +552,8 @@ class OAuthController { await logCtx.error(error.message, { connectionConfig }); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + return; } if ( provider.token_params == undefined || @@ -648,7 +662,8 @@ class OAuthController { }); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + return; } } catch (err) { const prettyError = stringifyError(err, { pretty: true }); @@ -697,7 +712,8 @@ class OAuthController { await logCtx.error(error.message, { ...connectionConfig }); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + return; } await oAuthSessionService.create(session); @@ -809,24 +825,23 @@ class OAuthController { const errorMessage = 'No state found in callback'; const e = new Error(errorMessage); - errorManager.report(e, { - source: ErrorSourceEnum.PLATFORM, - operation: LogActionEnum.AUTH, - metadata: errorManager.getExpressRequestContext(req) - }); + errorManager.report(e, { source: ErrorSourceEnum.PLATFORM, operation: LogActionEnum.AUTH }); return; } - const session = await oAuthSessionService.findById(state as string); + let session; + try { + session = await oAuthSessionService.findById(state as string); + } catch (err) { + errorManager.report(err, { source: ErrorSourceEnum.PLATFORM, operation: LogActionEnum.AUTH }); + errorManager.errRes(res, 'invalid_oauth_state'); + return; + } if (session == null) { const e = new Error(`No session found for state: ${JSON.stringify(state)}`); - errorManager.report(e, { - source: ErrorSourceEnum.PLATFORM, - operation: LogActionEnum.AUTH, - metadata: errorManager.getExpressRequestContext(req) - }); + errorManager.report(e, { source: ErrorSourceEnum.PLATFORM, operation: LogActionEnum.AUTH }); return; } else { await oAuthSessionService.delete(state as string); @@ -846,7 +861,8 @@ class OAuthController { const error = WSErrBuilder.UnknownProviderTemplate(session.provider); await logCtx.error(error.message); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + return; } const config = (await configService.getProviderConfig(session.providerConfigKey, session.environmentId))!; @@ -860,29 +876,28 @@ class OAuthController { await logCtx.error(error.message); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + return; } if (session.authMode === 'OAUTH2' || session.authMode === 'CUSTOM') { - return this.oauth2Callback(provider as ProviderOAuth2, config, session, req, res, environment, account, logCtx); + await this.oauth2Callback(provider as ProviderOAuth2, config, session, req, res, environment, account, logCtx); + return; } else if (session.authMode === 'OAUTH1') { - return this.oauth1Callback(provider, config, session, req, res, environment, account, logCtx); + await this.oauth1Callback(provider, config, session, req, res, environment, account, logCtx); + return; } const error = WSErrBuilder.UnknownAuthMode(session.authMode); await logCtx.error(error.message, { url: req.originalUrl }); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, error); + return; } catch (err) { const prettyError = stringifyError(err, { pretty: true }); - errorManager.report(err, { - source: ErrorSourceEnum.PLATFORM, - operation: LogActionEnum.AUTH, - environmentId: session.environmentId, - metadata: errorManager.getExpressRequestContext(req) - }); + errorManager.report(err, { source: ErrorSourceEnum.PLATFORM, operation: LogActionEnum.AUTH, environmentId: session.environmentId }); await logCtx.error('Unknown error', { error: err, url: req.originalUrl }); await logCtx.failed(); @@ -958,7 +973,8 @@ class OAuthController { await logCtx.info('Update request has been made', { provider: session.provider, providerConfigKey, connectionId }); await logCtx.success(); - return publisher.notifySuccess(res, channel, providerConfigKey, connectionId); + await publisher.notifySuccess(res, channel, providerConfigKey, connectionId); + return; } // check for oauth overrides in the connection config @@ -1069,7 +1085,8 @@ class OAuthController { logCtx ); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, WSErrBuilder.UnknownError()); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, WSErrBuilder.UnknownError()); + return; } let connectionConfig = { @@ -1159,7 +1176,8 @@ class OAuthController { if (!updatedConnection) { await logCtx.error('Failed to create connection'); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, WSErrBuilder.UnknownError('failed to create connection')); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, WSErrBuilder.UnknownError('failed to create connection')); + return; } let connectSession: ConnectSessionAndEndUser | undefined; @@ -1172,7 +1190,8 @@ class OAuthController { if (connectSessionRes.isErr()) { await logCtx.error('Failed to get session'); await logCtx.failed(); - return publisher.notifyErr(res, channel, providerConfigKey, connectionId, WSErrBuilder.UnknownError('failed to get session')); + await publisher.notifyErr(res, channel, providerConfigKey, connectionId, WSErrBuilder.UnknownError('failed to get session')); + return; } connectSession = connectSessionRes.value; @@ -1247,7 +1266,8 @@ class OAuthController { await logCtx.success(); - return publisher.notifySuccess(res, channel, providerConfigKey, connectionId, pending); + await publisher.notifySuccess(res, channel, providerConfigKey, connectionId, pending); + return; } catch (err) { const prettyError = stringifyError(err, { pretty: true }); errorManager.report(err, { diff --git a/packages/server/lib/controllers/proxy.controller.ts b/packages/server/lib/controllers/proxy.controller.ts index 72c2ed25376..730bed620b2 100644 --- a/packages/server/lib/controllers/proxy.controller.ts +++ b/packages/server/lib/controllers/proxy.controller.ts @@ -45,8 +45,8 @@ class ProxyController { let logCtx: LogContext | undefined; try { - const connectionId = req.get('Connection-Id') as string; - const providerConfigKey = req.get('Provider-Config-Key') as string; + const connectionId = req.get('Connection-Id') || ''; + const providerConfigKey = req.get('Provider-Config-Key') || ''; const retries = req.get('Retries') as string; const baseUrlOverride = req.get('Base-Url-Override') as string; const decompress = req.get('Decompress') as string; diff --git a/packages/server/lib/controllers/sync.controller.ts b/packages/server/lib/controllers/sync.controller.ts index b4eea5ef707..825ee0d185e 100644 --- a/packages/server/lib/controllers/sync.controller.ts +++ b/packages/server/lib/controllers/sync.controller.ts @@ -201,7 +201,7 @@ class SyncController { return; } - res.sendStatus(200); + res.status(200).send({ success: true }); } catch (err) { next(err); } @@ -422,7 +422,7 @@ class SyncController { initiator: 'API call' }); - res.sendStatus(200); + res.status(200).send({ success: true }); } catch (err) { next(err); } @@ -464,7 +464,7 @@ class SyncController { initiator: 'API call' }); - res.sendStatus(200); + res.status(200).send({ success: true }); } catch (err) { next(err); } @@ -596,7 +596,7 @@ class SyncController { }); if (result.isErr()) { - errorManager.handleGenericError(result.error, req, res, tracer); + errorManager.handleGenericError(result.error, req, res); await logCtx.failed(); return; } diff --git a/packages/server/lib/controllers/v1/account/managed/getCallback.ts b/packages/server/lib/controllers/v1/account/managed/getCallback.ts index dfdb2a310a4..c6c447959ce 100644 --- a/packages/server/lib/controllers/v1/account/managed/getCallback.ts +++ b/packages/server/lib/controllers/v1/account/managed/getCallback.ts @@ -123,7 +123,7 @@ export const getManagedCallback = asyncWrapper(async (req, r if (invitation) { // If we came from an invitation we need to accept it and transfer the team await acceptInvitation(invitation.token); - const updated = await userService.update({ id: user!.id, account_id: invitation.account_id }); + const updated = await userService.update({ id: user.id, account_id: invitation.account_id }); if (!updated) { res.status(500).send({ error: { code: 'server_error', message: 'failed to update user team' } }); return; diff --git a/packages/server/lib/controllers/v1/environment/postEnvironment.integration.test.ts b/packages/server/lib/controllers/v1/environment/postEnvironment.integration.test.ts new file mode 100644 index 00000000000..f7d917df60c --- /dev/null +++ b/packages/server/lib/controllers/v1/environment/postEnvironment.integration.test.ts @@ -0,0 +1,39 @@ +import { afterAll, beforeAll, describe, it } from 'vitest'; +import { runServer, shouldBeProtected } from '../../../utils/tests.js'; + +let api: Awaited>; + +const endpoint = '/api/v1/environments'; + +describe(`POST ${endpoint}`, () => { + beforeAll(async () => { + api = await runServer(); + }); + afterAll(() => { + api.server.close(); + }); + + it('should be protected', async () => { + const res = await api.fetch(endpoint, { + method: 'POST', + body: { name: 'test' } + }); + + shouldBeProtected(res); + }); + + // Does not work because we only have env secret key for authentication but we actually want to create an env + // it('should create an environment', async () => { + // const { account } = await seeders.seedAccountEnvAndUser(); + + // const res = await api.fetch(endpoint, { + // method: 'POST', + // body: { name: 'test', accountId: account.id } + // }); + + // isSuccess(res.json); + // expect(res.json).toStrictEqual({ + // data: { id: expect.any(Number), name: 'test' } + // }); + // }); +}); diff --git a/packages/server/lib/controllers/v1/environment/postEnvironment.ts b/packages/server/lib/controllers/v1/environment/postEnvironment.ts new file mode 100644 index 00000000000..817846fc972 --- /dev/null +++ b/packages/server/lib/controllers/v1/environment/postEnvironment.ts @@ -0,0 +1,63 @@ +import { z } from 'zod'; +import { requireEmptyQuery, zodErrorToHTTP } from '@nangohq/utils'; +import { asyncWrapper } from '../../../utils/asyncWrapper.js'; +import type { PostEnvironment } from '@nangohq/types'; +import { accountService, environmentService, externalWebhookService } from '@nangohq/shared'; +import { envSchema } from '../../../helpers/validation.js'; + +const validationBody = z + .object({ + name: envSchema + }) + .strict(); + +export const postEnvironment = asyncWrapper(async (req, res) => { + const emptyQuery = requireEmptyQuery(req); + if (emptyQuery) { + res.status(400).send({ error: { code: 'invalid_query_params', errors: zodErrorToHTTP(emptyQuery.error) } }); + return; + } + + const valBody = validationBody.safeParse(req.body); + if (!valBody.success) { + res.status(400).send({ error: { code: 'invalid_body', errors: zodErrorToHTTP(valBody.error) } }); + return; + } + + const body: PostEnvironment['Body'] = valBody.data; + + const accountId = res.locals.user.account_id; + + const account = await accountService.getAccountById(accountId); + if (account?.is_capped) { + res.status(400).send({ error: { code: 'feature_disabled', message: 'Creating environment is only available for paying customer' } }); + return; + } + + const environments = await environmentService.getEnvironmentsByAccountId(accountId); + if (environments.length >= 10) { + res.status(400).send({ error: { code: 'resource_capped', message: "Can't create more environments" } }); + return; + } + + const exists = environments.some((env) => env.name === body.name); + if (exists) { + res.status(409).send({ error: { code: 'conflict', message: 'Environment already exists' } }); + return; + } + + const created = await environmentService.createEnvironment(accountId, body.name); + if (!created) { + res.status(500).send({ error: { code: 'server_error', message: 'Failed to create environment' } }); + return; + } + + await externalWebhookService.update(created.id, { + alwaysSendWebhook: true, + sendAuthWebhook: true, + sendRefreshFailedWebhook: true, + sendSyncFailedWebhook: true + }); + + res.status(200).send({ data: { id: created.id, name: created.name } }); +}); diff --git a/packages/server/lib/controllers/v1/flows/id/patchDisable.ts b/packages/server/lib/controllers/v1/flows/id/patchDisable.ts index a4320a18018..55aff572906 100644 --- a/packages/server/lib/controllers/v1/flows/id/patchDisable.ts +++ b/packages/server/lib/controllers/v1/flows/id/patchDisable.ts @@ -3,7 +3,7 @@ import { asyncWrapper } from '../../../../utils/asyncWrapper.js'; import type { PatchFlowDisable } from '@nangohq/types'; import { requireEmptyQuery, zodErrorToHTTP } from '@nangohq/utils'; import { flowConfig } from '../../../sync/deploy/validation.js'; -import { configService, disableScriptConfig } from '@nangohq/shared'; +import { configService, disableScriptConfig, errorNotificationService } from '@nangohq/shared'; import { providerConfigKeySchema, providerSchema, scriptNameSchema } from '../../../../helpers/validation.js'; export const validationBody = z @@ -53,6 +53,7 @@ export const patchFlowDisable = asyncWrapper(async (req, res) } const updated = await disableScriptConfig({ id: valParams.data.id, environmentId: environment.id }); + await errorNotificationService.sync.clearBySyncConfig({ sync_config_id: valParams.data.id }); if (updated > 0) { res.status(200).send({ data: { success: true } }); diff --git a/packages/server/lib/controllers/v1/getEnvJs.ts b/packages/server/lib/controllers/v1/getEnvJs.ts index daa6a1562c5..9ad1f85bb4e 100644 --- a/packages/server/lib/controllers/v1/getEnvJs.ts +++ b/packages/server/lib/controllers/v1/getEnvJs.ts @@ -1,4 +1,4 @@ -import { basePublicUrl, baseUrl, connectUrl, flagHasAuth, flagHasManagedAuth, flagHasScripts, isCloud } from '@nangohq/utils'; +import { basePublicUrl, baseUrl, connectUrl, flagHasAuth, flagHasManagedAuth, flagHasScripts, flagHasSlack, isCloud } from '@nangohq/utils'; import { asyncWrapper } from '../../utils/asyncWrapper.js'; import type { WindowEnv } from '@nangohq/types'; import { envs } from '@nangohq/logs'; @@ -12,14 +12,16 @@ export const getEnvJs = asyncWrapper((_, res) => { publicPosthogKey: process.env['PUBLIC_POSTHOG_KEY'] || '', publicPosthogHost: process.env['PUBLIC_POSTHOG_HOST'] || '', publicLogoDevKey: process.env['PUBLIC_LOGODEV_KEY'] || '', - publicKoalaKey: process.env['PUBLIC_KOALA_KEY'] || '', + publicKoalaApiUrl: process.env['PUBLIC_KOALA_API_URL'] || '', + publicKoalaCdnUrl: process.env['PUBLIC_KOALA_CDN_URL'] || '', isCloud, features: { logs: envs.NANGO_LOGS_ENABLED, scripts: flagHasScripts, auth: flagHasAuth, managedAuth: flagHasManagedAuth, - gettingStarted: true + gettingStarted: true, + slack: flagHasSlack } }; res.setHeader('content-type', 'text/javascript'); diff --git a/packages/server/lib/controllers/v1/integrations/providerConfigKey/flows/getFlows.integration.test.ts b/packages/server/lib/controllers/v1/integrations/providerConfigKey/flows/getFlows.integration.test.ts index bff76ea875b..70c33148576 100644 --- a/packages/server/lib/controllers/v1/integrations/providerConfigKey/flows/getFlows.integration.test.ts +++ b/packages/server/lib/controllers/v1/integrations/providerConfigKey/flows/getFlows.integration.test.ts @@ -84,7 +84,7 @@ describe(`GET ${route}`, () => { it('should create same template and deduplicate correctly', async () => { const { env } = await seeders.seedAccountEnvAndUser(); const config = await seeders.createConfigSeed(env, 'github', 'github'); - const connection = await seeders.createConnectionSeed(env, 'github'); + const connection = await seeders.createConnectionSeed({ env, provider: 'github' }); await seeders.createSyncSeeds({ connectionId: connection.id!, diff --git a/packages/server/lib/controllers/v1/logs/postInsights.integration.test.ts b/packages/server/lib/controllers/v1/logs/postInsights.integration.test.ts index 5f268b7c84b..2f3083c6487 100644 --- a/packages/server/lib/controllers/v1/logs/postInsights.integration.test.ts +++ b/packages/server/lib/controllers/v1/logs/postInsights.integration.test.ts @@ -69,7 +69,7 @@ describe('POST /logs/insights', () => { method: 'POST', query: { env: 'dev' }, token: env.secret_key, - body: { type: 'sync' } + body: { type: 'sync:run' } }); isSuccess(res.json); diff --git a/packages/server/lib/controllers/v1/logs/postInsights.ts b/packages/server/lib/controllers/v1/logs/postInsights.ts index 6d6e5731c52..c1b0c4628f9 100644 --- a/packages/server/lib/controllers/v1/logs/postInsights.ts +++ b/packages/server/lib/controllers/v1/logs/postInsights.ts @@ -6,7 +6,7 @@ import { envs, modelOperations } from '@nangohq/logs'; const validation = z .object({ - type: z.enum(['sync', 'action', 'proxy', 'webhook:incoming']) + type: z.enum(['sync:run', 'action', 'proxy', 'webhook:incoming']) }) .strict(); diff --git a/packages/server/lib/formatters/connection.ts b/packages/server/lib/formatters/connection.ts index d2590c77148..eccb6204aaf 100644 --- a/packages/server/lib/formatters/connection.ts +++ b/packages/server/lib/formatters/connection.ts @@ -7,6 +7,7 @@ import type { DBConnection, DBEndUser } from '@nangohq/types'; +import { endUserToApi } from './endUser.js'; export function connectionSimpleToApi({ data, @@ -25,14 +26,7 @@ export function connectionSimpleToApi({ provider_config_key: data.provider_config_key, provider, errors: activeLog, - endUser: endUser - ? { - id: endUser.end_user_id, - displayName: endUser.display_name || null, - email: endUser.email, - organization: endUser.organization_id ? { id: endUser.organization_id, displayName: endUser.organization_display_name || null } : null - } - : null, + endUser: endUser ? endUserToApi(endUser) : null, created_at: String(data.created_at), updated_at: String(data.updated_at) }; @@ -64,14 +58,7 @@ export function connectionSimpleToPublicApi({ provider_config_key: data.provider_config_key, provider, errors: activeLog, - end_user: endUser - ? { - id: endUser.end_user_id, - displayName: endUser.display_name || null, - email: endUser.email, - organization: endUser.organization_id ? { id: endUser.organization_id, displayName: endUser.organization_display_name || null } : null - } - : null, + end_user: endUser ? endUserToApi(endUser) : null, metadata: data.metadata || null, created: String(data.created_at) }; @@ -94,14 +81,7 @@ export function connectionFullToPublicApi({ provider_config_key: data.provider_config_key, provider, errors: activeLog, - end_user: endUser - ? { - id: endUser.end_user_id, - displayName: endUser.display_name || null, - email: endUser.email, - organization: endUser.organization_id ? { id: endUser.organization_id, displayName: endUser.organization_display_name || null } : null - } - : null, + end_user: endUser ? endUserToApi(endUser) : null, metadata: data.metadata || null, connection_config: data.connection_config || {}, created_at: String(data.created_at), diff --git a/packages/server/lib/formatters/endUser.ts b/packages/server/lib/formatters/endUser.ts index e26bd32280d..cea19c03310 100644 --- a/packages/server/lib/formatters/endUser.ts +++ b/packages/server/lib/formatters/endUser.ts @@ -7,8 +7,8 @@ export function endUserToApi(endUser: DBEndUser | null): ApiEndUser | null { return { id: endUser.end_user_id, - displayName: endUser.display_name || null, + display_name: endUser.display_name || null, email: endUser.email, - organization: endUser.organization_id ? { id: endUser.organization_id, displayName: endUser.organization_display_name || null } : null + organization: endUser.organization_id ? { id: endUser.organization_id, display_name: endUser.organization_display_name || null } : null }; } diff --git a/packages/server/lib/helpers/validation.ts b/packages/server/lib/helpers/validation.ts index c17d17c5b62..7a4e9090826 100644 --- a/packages/server/lib/helpers/validation.ts +++ b/packages/server/lib/helpers/validation.ts @@ -22,7 +22,7 @@ export const connectionIdSchema = z .max(255); export const envSchema = z .string() - .regex(/^[a-zA-Z0-9_-]+$/) + .regex(/^[a-z0-9_-]+$/) .max(255); export const connectSessionTokenPrefix = 'nango_connect_session_'; export const connectSessionTokenSchema = z.string().regex(new RegExp(`^${connectSessionTokenPrefix}[a-f0-9]{64}$`)); diff --git a/packages/server/lib/middleware/access.middleware.ts b/packages/server/lib/middleware/access.middleware.ts index 3fe6b7f5c2c..72376d998d8 100644 --- a/packages/server/lib/middleware/access.middleware.ts +++ b/packages/server/lib/middleware/access.middleware.ts @@ -14,7 +14,7 @@ import { envs } from '../env.js'; const logger = getLogger('AccessMiddleware'); const keyRegex = /^[0-9A-F]{8}-[0-9A-F]{4}-[4][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i; -const ignoreEnvPaths = ['/api/v1/meta', '/api/v1/user', '/api/v1/user/name', '/api/v1/signin', '/api/v1/invite/:id']; +const ignoreEnvPaths = ['/api/v1/environments', '/api/v1/meta', '/api/v1/user', '/api/v1/user/name', '/api/v1/signin', '/api/v1/invite/:id']; export class AccessMiddleware { private async validateSecretKey(secret: string): Promise< diff --git a/packages/server/lib/middleware/security.ts b/packages/server/lib/middleware/security.ts index d636fae89b4..2331ff2f72a 100644 --- a/packages/server/lib/middleware/security.ts +++ b/packages/server/lib/middleware/security.ts @@ -9,6 +9,9 @@ export function securityMiddlewares(): RequestHandler[] { hostWs.protocol = hostApi.startsWith('https') ? 'wss' : 'ws'; const reportOnly = process.env['CSP_REPORT_ONLY']; + const additionalConnectSources = [process.env['PUBLIC_KOALA_API_URL'] ? new URL(process.env['PUBLIC_KOALA_API_URL']).origin : '']; + const additionalScriptSources = [process.env['PUBLIC_KOALA_CDN_URL'] ? new URL(process.env['PUBLIC_KOALA_CDN_URL']).origin : '']; + return [ helmet.xssFilter(), helmet.noSniff(), @@ -24,7 +27,16 @@ export function securityMiddlewares(): RequestHandler[] { directives: { defaultSrc: ["'self'", hostPublic, hostApi], childSrc: "'self'", - connectSrc: ["'self'", 'https://*.google-analytics.com', 'https://*.sentry.io', hostPublic, hostApi, hostWs.href, 'https://*.posthog.com'], + connectSrc: [ + "'self'", + 'https://*.google-analytics.com', + 'https://*.sentry.io', + hostPublic, + hostApi, + hostWs.href, + 'https://*.posthog.com', + ...additionalConnectSources + ], fontSrc: ["'self'", 'https://*.googleapis.com', 'https://*.gstatic.com'], frameSrc: ["'self'", 'https://accounts.google.com', hostPublic, hostApi, connectUrl, 'https://www.youtube.com'], imgSrc: [ @@ -51,7 +63,8 @@ export function securityMiddlewares(): RequestHandler[] { 'https://*.googleapis.com', 'https://apis.google.com', 'https://*.posthog.com', - 'https://www.youtube.com' + 'https://www.youtube.com', + ...additionalScriptSources ], styleSrc: ['blob:', "'self'", "'unsafe-inline'", 'https://*.googleapis.com', hostPublic, hostApi], workerSrc: ['blob:', "'self'", hostPublic, hostApi, 'https://*.googleapis.com', 'https://*.posthog.com'] diff --git a/packages/server/lib/refreshConnections.ts b/packages/server/lib/refreshConnections.ts index 6ee25c5b6c3..a8264c43eb7 100644 --- a/packages/server/lib/refreshConnections.ts +++ b/packages/server/lib/refreshConnections.ts @@ -24,7 +24,7 @@ export function refreshConnectionsCron(): void { const e = new Error('failed_to_refresh_connections', { cause: err instanceof Error ? err.message : String(err) }); - errorManager.report(e, { source: ErrorSourceEnum.PLATFORM }, tracer); + errorManager.report(e, { source: ErrorSourceEnum.PLATFORM }); } finally { metrics.duration(metrics.Types.REFRESH_CONNECTIONS, Date.now() - start); } diff --git a/packages/server/lib/routes.ts b/packages/server/lib/routes.ts index 333b11c20dc..b34758b38d7 100644 --- a/packages/server/lib/routes.ts +++ b/packages/server/lib/routes.ts @@ -24,7 +24,6 @@ import accountController from './controllers/account.controller.js'; import type { Response, Request, RequestHandler } from 'express'; import { isCloud, isEnterprise, isBasicAuthEnabled, isTest, isLocal, basePublicUrl, baseUrl, flagHasAuth, flagHasManagedAuth } from '@nangohq/utils'; import { errorManager } from '@nangohq/shared'; -import tracer from 'dd-trace'; import { getConnection as getConnectionWeb } from './controllers/v1/connections/connectionId/getConnection.js'; import { searchOperations } from './controllers/v1/logs/searchOperations.js'; import { getOperation } from './controllers/v1/logs/getOperation.js'; @@ -110,6 +109,7 @@ import { postPublicAppStoreAuthorization } from './controllers/auth/postAppStore import { postRollout } from './controllers/fleet/postRollout.js'; import { getPublicConnection } from './controllers/connection/connectionId/getConnection.js'; import { postWebhook } from './controllers/webhook/environmentUuid/postWebhook.js'; +import { postEnvironment } from './controllers/v1/environment/postEnvironment.js'; export const router = express.Router(); @@ -169,7 +169,7 @@ const publicAPICorsHandler = cors({ maxAge: 600, exposedHeaders: 'Authorization, Etag, Content-Type, Content-Length, X-Nango-Signature, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset', allowedHeaders: - 'Authorization, Content-Type, Accept, Origin, X-Requested-With, Nango-Activity-Log-Id, Nango-Is-Dry-Run, Nango-Is-Sync, Provider-Config-Key, Connection-Id', + 'Authorization, Content-Type, Accept, Origin, X-Requested-With, Nango-Activity-Log-Id, Nango-Is-Dry-Run, Nango-Is-Sync, Provider-Config-Key, Connection-Id, Sentry-Trace, Baggage', origin: '*' }); publicAPI.use(publicAPICorsHandler); @@ -311,6 +311,7 @@ web.route('/api/v1/invite/:id').delete(webAuth, declineInvite); web.route('/api/v1/account/admin/switch').post(webAuth, accountController.switchAccount.bind(accountController)); web.route('/api/v1/environment').get(webAuth, environmentController.getEnvironment.bind(environmentController)); +web.route('/api/v1/environments').post(webAuth, postEnvironment); web.route('/api/v1/environment/callback').post(webAuth, environmentController.updateCallback.bind(environmentController)); web.route('/api/v1/environment/webhook/primary-url').patch(webAuth, updatePrimaryUrl); web.route('/api/v1/environment/webhook/secondary-url').patch(webAuth, updateSecondaryUrl); @@ -404,5 +405,5 @@ router.use((err: any, req: Request, res: Response>, _: return; } - errorManager.handleGenericError(err, req, res, tracer); + errorManager.handleGenericError(err, req, res); }); diff --git a/packages/server/lib/utils/utils.ts b/packages/server/lib/utils/utils.ts index 499c55d365a..d5020af7c45 100644 --- a/packages/server/lib/utils/utils.ts +++ b/packages/server/lib/utils/utils.ts @@ -218,7 +218,8 @@ export function parseCredentialParamsFromTemplate(provider: ProviderTwoStep): st * This can be used to convert the keys of a Json to snake case * @param payload This the json we want to convert from a camelCase a snake_case */ -export function convertJsonKeysToSnakeCase(payload: Record): R | null { +// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters +export function convertJsonKeysToSnakeCase(payload: Record): TReturn | null { if (payload == null) { return null; } @@ -234,7 +235,8 @@ export function convertJsonKeysToSnakeCase(payload: Record): R | * * @param payload The json we want to convert its keys to camelCase */ -export function convertJsonKeysToCamelCase(payload: Record): R | null { +// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters +export function convertJsonKeysToCamelCase(payload: Record): TReturn | null { if (payload == null) { return null; } diff --git a/packages/server/lib/webhook/hubspot-webhook-routing.unit.test.ts b/packages/server/lib/webhook/hubspot-webhook-routing.unit.test.ts index e0b314bf03a..cb830672e0d 100644 --- a/packages/server/lib/webhook/hubspot-webhook-routing.unit.test.ts +++ b/packages/server/lib/webhook/hubspot-webhook-routing.unit.test.ts @@ -100,7 +100,7 @@ describe('Webhook route unit tests', () => { expect(nangoMock.executeScriptForWebhooks).toHaveBeenCalledTimes(body.length); - const firstCallFirstArgument = nangoMock.executeScriptForWebhooks.mock.calls[0][1]; + const firstCallFirstArgument = nangoMock.executeScriptForWebhooks.mock.calls[0]?.[1]; expect(firstCallFirstArgument.eventId).toBe(4023112300); }); @@ -153,9 +153,9 @@ describe('Webhook route unit tests', () => { expect(nangoMock.executeScriptForWebhooks).toHaveBeenCalledTimes(body.length); - const firstCallFirstArgument = nangoMock.executeScriptForWebhooks.mock.calls[0][1]; + const firstCallFirstArgument = nangoMock.executeScriptForWebhooks.mock.calls[0]?.[1]; expect(firstCallFirstArgument.eventId).toBe(1234); - const secondCallFirstArgument = nangoMock.executeScriptForWebhooks.mock.calls[1][1]; + const secondCallFirstArgument = nangoMock.executeScriptForWebhooks.mock.calls[1]?.[1]; expect(secondCallFirstArgument.eventId).toBe(123); }); }); diff --git a/packages/server/lib/webhook/index.ts b/packages/server/lib/webhook/index.ts index 358eb766731..0e6173dbf3d 100644 --- a/packages/server/lib/webhook/index.ts +++ b/packages/server/lib/webhook/index.ts @@ -9,4 +9,4 @@ export { default as checkrWebhookRouting } from './checkr-webhook-routing.js'; export { default as microsoftTeamsWebhookRouting } from './microsoft-teams-webhook-routing.js'; export { default as unauthenticatedWebhookRouting } from './unauthenticated-webhook-routing.js'; export { default as airtableWebhookRouting } from './airtable-webhook-routing.js'; -export * from './types.js'; +export type * from './types.js'; diff --git a/packages/server/package.json b/packages/server/package.json index ba0292e229a..13c267e8869 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -35,7 +35,7 @@ "@nangohq/keystore": "file:../keystore", "@nangohq/fleet": "file:../fleet", "@workos-inc/node": "6.2.0", - "axios": "^1.7.4", + "axios": "^1.7.9", "body-parser": "1.20.3", "connect-session-knex": "4.0.0", "cookie-parser": "1.4.6", @@ -62,7 +62,7 @@ "simple-oauth2": "5.1.0", "uuid": "9.0.0", "ws": "8.18.0", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@types/cookie-parser": "1.4.3", @@ -82,9 +82,9 @@ "@types/uuid": "8.3.4", "@types/ws": "8.5.4", "get-port": "7.1.0", - "nodemon": "3.1.7", - "type-fest": "4.26.1", - "typescript": "5.3.3", - "vitest": "1.6.0" + "nodemon": "3.1.9", + "type-fest": "4.32.0", + "typescript": "5.7.3", + "vitest": "2.1.8" } } diff --git a/packages/shared/flows.yaml b/packages/shared/flows.yaml index 43cfcdc7ebb..6fb3833dfae 100644 --- a/packages/shared/flows.yaml +++ b/packages/shared/flows.yaml @@ -3804,17 +3804,6 @@ integrations: group: Files scopes: repo version: 1.0.0 - issues-demo: - runs: every 5 minutes - auto_start: false - sync_type: full - output: GithubIssueDemo - scopes: public_repo - description: | - Fetches GitHub issues from our showcase repository. - endpoint: - method: GET - path: /github/demo-issues actions: write-file: scopes: repo @@ -3836,14 +3825,6 @@ integrations: output: GithubRepo description: | List github repos from an organization. - create-demo-issue: - endpoint: - method: POST - path: /github/create-demo-issue - input: GithubCreateIssueInput - output: GithubCreateIssueResult - description: | - Create a GitHub issue in Nango's showcase repository. models: Issue: id: integer @@ -3898,15 +3879,6 @@ integrations: url: string status: string sha: string - GithubIssueDemo: - id: integer - title: string - url: string - GithubCreateIssueInput: - title: string - GithubCreateIssueResult: - url: string | undefined - status: number github-app: actions: repositories: @@ -4023,6 +3995,46 @@ integrations: watchers: number watchers_count: number web_commit_signoff_required: boolean + gong: + syncs: + users: + description: | + Fetches the list of gong users + endpoint: + method: GET + path: /users + group: Users + sync_type: incremental + runs: every day + output: User + scopes: + - api:users:read + models: + User: + id: string + firstName: string + lastName: string + email: string + gong-oauth: + syncs: + users: + description: | + Fetches the list of gong users + endpoint: + method: GET + path: /users + group: Users + sync_type: incremental + runs: every day + output: User + scopes: + - api:users:read + models: + User: + id: string + firstName: string + lastName: string + email: string google: syncs: workspace-org-units: @@ -6371,6 +6383,15 @@ integrations: group: Users output: SuccessResponse input: IdEntity + fetch-teams: + description: | + Fetch teams in an organisation in Jira + output: Teams + input: IdEntity + endpoint: + method: GET + path: /teams-list + group: Teams syncs: users: runs: every day @@ -6404,6 +6425,11 @@ integrations: lastName: string email: string products?: string[] + Teams: + teams: Team[] + Team: + id: string + name: string keeper-scim: actions: create-user: @@ -11023,6 +11049,18 @@ integrations: method: GET path: /invoices group: Invoices + general-ledger: + description: | + Fetch all general ledger entries in QuickBooks + runs: every hour + output: GeneralLedger + sync_type: incremental + endpoint: + method: GET + path: /general-ledger + group: General Ledger + scopes: + - com.intuit.quickbooks.accounting actions: create-customer: description: | @@ -11346,6 +11384,22 @@ integrations: customer_ref: Reference currency_ref?: Reference project_ref?: Reference + GeneralLedger: + id: string + date: string + createdDate: string + updatedDate: string + currency: string + note: string + lines: LedgerLine[] + LedgerLine: + journalLineId: string + type: string + accountId: string + accountName: string + netAmount: number + postingType: Debit | Credit + description: string quickbooks-sandbox: syncs: customers: @@ -11408,6 +11462,18 @@ integrations: method: GET path: /invoices group: Invoices + general-ledger: + description: | + Fetch all general ledger entries in QuickBooks + runs: every hour + output: GeneralLedger + sync_type: incremental + endpoint: + method: GET + path: /general-ledger + group: General Ledger + scopes: + - com.intuit.quickbooks.accounting actions: create-customer: description: | @@ -11731,6 +11797,22 @@ integrations: customer_ref: Reference currency_ref?: Reference project_ref?: Reference + GeneralLedger: + id: string + date: string + createdDate: string + updatedDate: string + currency: string + note: string + lines: LedgerLine[] + LedgerLine: + journalLineId: string + type: string + accountId: string + accountName: string + netAmount: number + postingType: Debit | Credit + description: string ramp: syncs: users: @@ -13307,6 +13389,71 @@ integrations: warning?: string | undefined error?: string | undefined raw_json: string + smartsheet: + syncs: + users: + runs: every 6 hours + description: Fetches a list of users from Smartsheet + output: User + sync_type: incremental + endpoint: + method: GET + path: /users + group: Users + scopes: + - READ_USERS + actions: + create-user: + description: Creates a user in Smartsheet + output: User + endpoint: + method: POST + path: /users + group: Users + input: CreateUser + scopes: + - ADMIN_USERS + delete-user: + description: > + Deletes a user from Smartsheet. User is transitioned to a free + collaborator with read-only access to owned reports, sheets, Sights, + workspaces, and any shared templates (unless those are optionally + transferred to another user). + endpoint: + method: DELETE + path: /users + group: Users + output: SuccessResponse + input: IdEntity + scopes: + - ADMIN_USERS + disable-user: + description: > + Disables a user in an organization account. User will no longer be + able to access Smartsheet in any way. User's assets will continue to + be owned by this user until they are transferred to another user. + endpoint: + method: POST + path: /users/disable + group: Users + output: SuccessResponse + input: IdEntity + scopes: + - ADMIN_USERS + models: + IdEntity: + id: string + SuccessResponse: + success: boolean + User: + id: string + email: string + firstName: string + lastName: string + CreateUser: + firstName: string + lastName: string + email: string stripe-app: syncs: subscriptions: diff --git a/packages/shared/lib/models/Sync.ts b/packages/shared/lib/models/Sync.ts index 79b6b114494..ac61a31f6de 100644 --- a/packages/shared/lib/models/Sync.ts +++ b/packages/shared/lib/models/Sync.ts @@ -26,6 +26,8 @@ export interface SyncResult { export type SyncResultByModel = Record; +export type SyncWithConnectionId = Sync & { connection_id: string }; + export interface Sync extends TimestampsAndDeleted { id: string; nango_connection_id: number; @@ -60,6 +62,7 @@ export interface ReportedSyncJobStatus { id?: string; type: SyncType | 'INITIAL'; name?: string; + connection_id?: string; status: SyncStatus; latestResult?: SyncResultByModel | undefined; jobStatus?: SyncStatus; diff --git a/packages/shared/lib/models/index.ts b/packages/shared/lib/models/index.ts index 7be37057e8e..48cba49298c 100644 --- a/packages/shared/lib/models/index.ts +++ b/packages/shared/lib/models/index.ts @@ -1,9 +1,9 @@ export * from './Telemetry.js'; -export * from './Connection.js'; -export * from './Generic.js'; -export * from './Provider.js'; +export type * from './Connection.js'; +export type * from './Generic.js'; +export type * from './Provider.js'; export * from './Auth.js'; export * from './Sync.js'; -export * from './Flow.js'; -export * from './NangoConfig.js'; +export type * from './Flow.js'; +export type * from './NangoConfig.js'; export * from './Proxy.js'; diff --git a/packages/shared/lib/sdk/sync.ts b/packages/shared/lib/sdk/sync.ts index 4b22571b21d..5be6576f5f3 100644 --- a/packages/shared/lib/sdk/sync.ts +++ b/packages/shared/lib/sdk/sync.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-type-parameters */ import https from 'node:https'; import { Nango, getUserAgent } from '@nangohq/node'; import type { AdminAxiosProps } from '@nangohq/node'; @@ -1290,7 +1291,6 @@ const TELEMETRY_ALLOWED_METHODS: (keyof NangoSync)[] = [ 'triggerSync' ]; -/* eslint-disable no-inner-declarations */ /** * @internal * @@ -1309,5 +1309,3 @@ export function instrumentSDK(rawNango: NangoAction | NangoSync) { } }); } - -/* eslint-enable no-inner-declarations */ diff --git a/packages/shared/lib/seeders/account.seeder.ts b/packages/shared/lib/seeders/account.seeder.ts index 867d18aa503..38dcbcec4f9 100644 --- a/packages/shared/lib/seeders/account.seeder.ts +++ b/packages/shared/lib/seeders/account.seeder.ts @@ -3,7 +3,7 @@ import accountService from '../services/account.service.js'; import type { DBTeam } from '@nangohq/types'; export async function createAccount(): Promise { - const acc = await accountService.getOrCreateAccount(uuid()); + const acc = await accountService.createAccountWithoutEnvironments(uuid()); if (!acc) { throw new Error('failed_to_create_account'); } diff --git a/packages/shared/lib/seeders/connection.seeder.ts b/packages/shared/lib/seeders/connection.seeder.ts index c91d812d80c..68f07448ce5 100644 --- a/packages/shared/lib/seeders/connection.seeder.ts +++ b/packages/shared/lib/seeders/connection.seeder.ts @@ -2,7 +2,7 @@ import db from '@nangohq/database'; import connectionService from '../services/connection.service.js'; import type { NangoConnection } from '../models/Connection.js'; import type { AuthCredentials } from '../models/Auth.js'; -import type { DBEnvironment, EndUser } from '@nangohq/types'; +import type { ConnectionConfig, DBEnvironment, EndUser } from '@nangohq/types'; import { linkConnection } from '../services/endUser.service.js'; export const createConnectionSeeds = async (env: DBEnvironment): Promise => { @@ -19,40 +19,52 @@ export const createConnectionSeeds = async (env: DBEnvironment): Promise res.connection.id!)); + + for (const res of result) { + if (!res.connection.id) { + throw new Error('Could not create connection seed'); + } + + connectionIds.push(res.connection.id); + } } return connectionIds; }; -export const createConnectionSeed = async ( - env: DBEnvironment, - provider: string, - endUser?: EndUser, - rest?: { - connectionId?: string; - rawCredentials?: AuthCredentials; - connectionConfig?: any; - } -): Promise => { - const name = rest?.connectionId ? rest.connectionId : Math.random().toString(36).substring(7); +export const createConnectionSeed = async ({ + env, + provider, + endUser, + connectionId, + rawCredentials, + connectionConfig +}: { + env: DBEnvironment; + provider: string; + endUser?: EndUser; + connectionId?: string; + rawCredentials?: AuthCredentials; + connectionConfig?: ConnectionConfig; +}): Promise => { + const name = connectionId ? connectionId : Math.random().toString(36).substring(7); const result = await connectionService.upsertConnection({ connectionId: name, providerConfigKey: provider, provider: provider, - parsedRawCredentials: rest?.rawCredentials || ({} as AuthCredentials), - connectionConfig: rest?.connectionConfig || {}, + parsedRawCredentials: rawCredentials || ({} as AuthCredentials), + connectionConfig: connectionConfig || {}, environmentId: env.id, accountId: 0 }); - if (!result || result[0] === undefined) { + if (!result || result[0] === undefined || !result[0].connection.id) { throw new Error('Could not create connection seed'); } if (endUser) { await linkConnection(db.knex, { endUserId: endUser.id, connection: result[0].connection }); } - return { id: result[0].connection.id!, connection_id: name, provider_config_key: provider, environment_id: env.id }; + return { id: result[0].connection.id, connection_id: name, provider_config_key: provider, environment_id: env.id }; }; export const deleteAllConnectionSeeds = async (): Promise => { diff --git a/packages/shared/lib/services/account.service.ts b/packages/shared/lib/services/account.service.ts index 78b2543959a..e38f2c8b9fd 100644 --- a/packages/shared/lib/services/account.service.ts +++ b/packages/shared/lib/services/account.service.ts @@ -70,6 +70,7 @@ class AccountService { if (!newAccount || newAccount.length == 0 || !newAccount[0]) { throw new Error('Failed to create account'); } + await environmentService.createDefaultEnvironments(newAccount[0]['id']); return newAccount[0]; @@ -94,6 +95,15 @@ class AccountService { return null; } + /** + * Create Account without default environments + * @desc create a new account and assign to the default environments + */ + async createAccountWithoutEnvironments(name: string): Promise { + const result = await db.knex.from(`_nango_accounts`).insert({ name }).returning('*'); + return result[0] || null; + } + async editCustomer(is_capped: boolean, accountId: number): Promise { await db.knex.update({ is_capped }).from(`_nango_accounts`).where({ id: accountId }); } diff --git a/packages/shared/lib/services/connection.service.integration.test.ts b/packages/shared/lib/services/connection.service.integration.test.ts index b90b39c314b..0df0fffe3c3 100644 --- a/packages/shared/lib/services/connection.service.integration.test.ts +++ b/packages/shared/lib/services/connection.service.integration.test.ts @@ -79,8 +79,8 @@ describe('Connection service integration tests', () => { await createConfigSeed(env, 'google', 'google'); await createConfigSeed(env, 'notion', 'notion'); - const google = await createConnectionSeed(env, 'google'); - const notion = await createConnectionSeed(env, 'notion'); + const google = await createConnectionSeed({ env, provider: 'google' }); + const notion = await createConnectionSeed({ env, provider: 'notion' }); const dbConnections = await connectionService.listConnections({ environmentId: env.id @@ -96,10 +96,10 @@ describe('Connection service integration tests', () => { await createConfigSeed(env, 'google', 'google'); await createConfigSeed(env, 'notion', 'notion'); - const google = await createConnectionSeed(env, 'google'); - const notion = await createConnectionSeed(env, 'notion'); - await createConnectionSeed(env, 'notion'); - await createConnectionSeed(env, 'notion'); + const google = await createConnectionSeed({ env, provider: 'google' }); + const notion = await createConnectionSeed({ env, provider: 'notion' }); + await createConnectionSeed({ env, provider: 'notion' }); + await createConnectionSeed({ env, provider: 'notion' }); const dbConnections = await connectionService.listConnections({ environmentId: env.id, @@ -116,8 +116,8 @@ describe('Connection service integration tests', () => { await createConfigSeed(env, 'google', 'google'); await createConfigSeed(env, 'notion', 'notion'); - const google = await createConnectionSeed(env, 'google'); - await createConnectionSeed(env, 'notion'); + const google = await createConnectionSeed({ env, provider: 'google' }); + await createConnectionSeed({ env, provider: 'notion' }); const dbConnections = await connectionService.listConnections({ environmentId: env.id, @@ -133,8 +133,8 @@ describe('Connection service integration tests', () => { await createConfigSeed(env, 'notion', 'notion'); - const notion = await createConnectionSeed(env, 'notion'); - await createConnectionSeed(env, 'notion'); + const notion = await createConnectionSeed({ env, provider: 'notion' }); + await createConnectionSeed({ env, provider: 'notion' }); const dbConnections = await connectionService.listConnections({ environmentId: env.id, @@ -150,8 +150,8 @@ describe('Connection service integration tests', () => { await createConfigSeed(env, 'notion', 'notion'); - const notion = await createConnectionSeed(env, 'notion'); - await createConnectionSeed(env, 'notion'); + const notion = await createConnectionSeed({ env, provider: 'notion' }); + await createConnectionSeed({ env, provider: 'notion' }); const dbConnections = await connectionService.listConnections({ environmentId: env.id, @@ -167,7 +167,7 @@ describe('Connection service integration tests', () => { await createConfigSeed(env, 'notion', 'notion'); - const notionError = await createConnectionSeed(env, 'notion'); + const notionError = await createConnectionSeed({ env, provider: 'notion' }); await errorNotificationService.auth.create({ type: 'auth', action: 'connection_test', @@ -175,7 +175,7 @@ describe('Connection service integration tests', () => { log_id: Math.random().toString(36).substring(7), active: true }); - await createConnectionSeed(env, 'notion'); + await createConnectionSeed({ env, provider: 'notion' }); const dbConnections = await connectionService.listConnections({ environmentId: env.id, @@ -191,7 +191,7 @@ describe('Connection service integration tests', () => { await createConfigSeed(env, 'notion', 'notion'); - const notionError = await createConnectionSeed(env, 'notion'); + const notionError = await createConnectionSeed({ env, provider: 'notion' }); await errorNotificationService.auth.create({ type: 'auth', action: 'connection_test', @@ -199,7 +199,7 @@ describe('Connection service integration tests', () => { log_id: Math.random().toString(36).substring(7), active: true }); - const notionOK = await createConnectionSeed(env, 'notion'); + const notionOK = await createConnectionSeed({ env, provider: 'notion' }); const dbConnections = await connectionService.listConnections({ environmentId: env.id, @@ -217,9 +217,9 @@ describe('Connection service integration tests', () => { const config = await createConfigSeed(env, 'notion', 'notion'); - await createConnectionSeed(env, 'notion'); + await createConnectionSeed({ env, provider: 'notion' }); - const notionAuthError = await createConnectionSeed(env, 'notion'); + const notionAuthError = await createConnectionSeed({ env, provider: 'notion' }); await errorNotificationService.auth.create({ type: 'auth', action: 'connection_test', @@ -228,7 +228,7 @@ describe('Connection service integration tests', () => { active: true }); - const notionSyncError = await createConnectionSeed(env, 'notion'); + const notionSyncError = await createConnectionSeed({ env, provider: 'notion' }); const sync = await createSyncSeeds({ connectionId: notionSyncError.id!, environment_id: env.id, diff --git a/packages/shared/lib/services/connection.service.ts b/packages/shared/lib/services/connection.service.ts index 9dce601fc0b..381a5f40e70 100644 --- a/packages/shared/lib/services/connection.service.ts +++ b/packages/shared/lib/services/connection.service.ts @@ -57,7 +57,8 @@ import { parseTableauTokenExpirationDate, interpolateObject, extractValueByPath, - stripCredential + stripCredential, + interpolateObjectValues } from '../utils/utils.js'; import type { LogContext, LogContextGetter } from '@nangohq/logs'; import { CONNECTIONS_WITH_SCRIPTS_CAP_LIMIT } from '../constants.js'; @@ -1698,7 +1699,7 @@ class ConnectionService { const bodyFormat = provider.body_format || 'json'; - const postBody: Record | string = {}; + let postBody: Record | string = {}; if (provider.token_params) { for (const [key, value] of Object.entries(provider.token_params)) { @@ -1712,6 +1713,7 @@ class ConnectionService { postBody[key] = strippedValue; } } + postBody = interpolateObjectValues(postBody, connectionConfig); } const headers: Record = {}; @@ -1733,7 +1735,9 @@ class ConnectionService { attributeNamePrefix: '$', ignoreAttributes: false }).build(postBody) - : JSON.stringify(postBody); + : bodyFormat === 'form' + ? new URLSearchParams(postBody).toString() + : JSON.stringify(postBody); const response = await axios.post(url.toString(), bodyContent, requestOptions); diff --git a/packages/shared/lib/services/environment.service.ts b/packages/shared/lib/services/environment.service.ts index dfc41a020b2..fa5d9230672 100644 --- a/packages/shared/lib/services/environment.service.ts +++ b/packages/shared/lib/services/environment.service.ts @@ -224,27 +224,21 @@ class EnvironmentService { return encryptionManager.decryptEnvironment(result[0]); } - async createEnvironment(accountId: number, environment: string): Promise { - const result = await db.knex.from(TABLE).insert({ account_id: accountId, name: environment }).returning('id'); + async createEnvironment(accountId: number, name: string): Promise { + const [environment] = await db.knex.from(TABLE).insert({ account_id: accountId, name }).returning('*'); - if (Array.isArray(result) && result.length === 1 && result[0] && 'id' in result[0]) { - const environmentId = result[0]['id']; - const environment = await this.getById(environmentId); - if (!environment) { - return null; - } - - const encryptedEnvironment = await encryptionManager.encryptEnvironment({ - ...environment, - secret_key_hashed: await hashSecretKey(environment.secret_key) - }); - await db.knex.from(TABLE).where({ id: environmentId }).update(encryptedEnvironment); - - const env = encryptionManager.decryptEnvironment(encryptedEnvironment); - return env; + if (!environment) { + return null; } - return null; + const encryptedEnvironment = await encryptionManager.encryptEnvironment({ + ...environment, + secret_key_hashed: await hashSecretKey(environment.secret_key) + }); + await db.knex.from(TABLE).where({ id: environment.id }).update(encryptedEnvironment); + + const env = encryptionManager.decryptEnvironment(encryptedEnvironment); + return env; } async createDefaultEnvironments(accountId: number): Promise { diff --git a/packages/shared/lib/services/file/remote.service.ts b/packages/shared/lib/services/file/remote.service.ts index 0e5eb8bfd3b..6998b4871cc 100644 --- a/packages/shared/lib/services/file/remote.service.ts +++ b/packages/shared/lib/services/file/remote.service.ts @@ -117,6 +117,10 @@ class RemoteFileService { } } + async getPublicTemplateJsonSchemaFile(integrationName: string, environmentId: number): Promise { + return this.getFile(`${this.publicRoute}/${integrationName}/.nango/schema.json`, environmentId); + } + getFile(fileName: string, environmentId: number): Promise { return new Promise((resolve, reject) => { const getObjectCommand = new GetObjectCommand({ diff --git a/packages/shared/lib/services/notification/error.service.ts b/packages/shared/lib/services/notification/error.service.ts index 0a64a793821..6e9258ff21a 100644 --- a/packages/shared/lib/services/notification/error.service.ts +++ b/packages/shared/lib/services/notification/error.service.ts @@ -6,6 +6,7 @@ import type { Result } from '@nangohq/utils'; import db from '@nangohq/database'; const DB_TABLE = '_nango_active_logs'; +const SYNC_TABLE = '_nango_syncs'; type ErrorNotification = Required>; type SyncErrorNotification = ErrorNotification & Required>; @@ -76,6 +77,21 @@ export const errorNotificationService = { }, clearBySyncId: async ({ sync_id }: Pick): Promise => { await db.knex.from(DB_TABLE).where({ type: 'sync', sync_id }).delete(); + }, + /** + * Clear By Sync Config Id + * @description Clear all sync notifications by sync config id. This is used + * when disabling a sync at the integration level. Any active logs are + * no longer relevant because the sync is disabled. + */ + clearBySyncConfig: async ({ sync_config_id }: { sync_config_id: number }): Promise => { + const query = db.knex + .from(DB_TABLE) + .join(SYNC_TABLE, `${SYNC_TABLE}.id`, '=', `${DB_TABLE}.sync_id`) + .where({ type: 'sync', active: true }) + .andWhere({ [`${SYNC_TABLE}.sync_config_id`]: sync_config_id, [`${SYNC_TABLE}.deleted`]: false }); + + await query.delete(); } } }; diff --git a/packages/shared/lib/services/paginate.service.ts b/packages/shared/lib/services/paginate.service.ts index 8d8e9fea8ae..263c402ad83 100644 --- a/packages/shared/lib/services/paginate.service.ts +++ b/packages/shared/lib/services/paginate.service.ts @@ -170,7 +170,11 @@ class PaginationService { } private updateConfigBodyOrParams(passPaginationParamsInBody: boolean, config: UserProvidedProxyConfiguration, updatedBodyOrParams: Record) { - passPaginationParamsInBody ? (config.data = updatedBodyOrParams) : (config.params = updatedBodyOrParams); + if (passPaginationParamsInBody) { + config.data = updatedBodyOrParams; + } else { + config.params = updatedBodyOrParams; + } } private getNextPageLinkFromBodyOrHeaders(linkPagination: LinkPagination, response: AxiosResponse, paginationConfig: Pagination) { diff --git a/packages/shared/lib/services/sync/config/deploy.service.ts b/packages/shared/lib/services/sync/config/deploy.service.ts index b82cb80507a..1465fc1e86f 100644 --- a/packages/shared/lib/services/sync/config/deploy.service.ts +++ b/packages/shared/lib/services/sync/config/deploy.service.ts @@ -416,6 +416,8 @@ export async function deployPreBuilt({ let provider_config_key: string; // this is a public template so copy it from the public location + // We might not want to do this as it just overrides the root nango.yaml + // which means we overwrite any custom nango.yaml that the user has await remoteFileService.copy( firstConfig.public_route, nangoConfigFile, @@ -522,6 +524,12 @@ export async function deployPreBuilt({ throw new NangoError('file_upload_error'); } + const flowJsonSchema: JSONSchema7 = { + definitions: {} + }; + + const flowModels = Array.isArray(models) ? models : [models]; + if (is_public) { await remoteFileService.copy( config.public_route, @@ -530,6 +538,21 @@ export async function deployPreBuilt({ environment.id, `${sync_name}.ts` ); + // fetch the json schema so we have type checking + const jsonSchema = await remoteFileService.getPublicTemplateJsonSchemaFile(firstConfig.public_route, environment.id); + + if (jsonSchema) { + const parsedJsonSchema = JSON.parse(jsonSchema); + for (const model of flowModels) { + const schema = parsedJsonSchema.definitions![model]; + if (!schema) { + const error = new NangoError('deploy_missing_json_schema_model', `json_schema doesn't contain model "${model}"`); + + return { success: false, error, response: null }; + } + flowJsonSchema.definitions![model] = schema; + } + } } else { if (typeof config.fileBody === 'object' && config.fileBody.ts) { await remoteFileService.upload( @@ -565,7 +588,7 @@ export async function deployPreBuilt({ nango_config_id, file_location, version, - models: Array.isArray(models) ? models : [models], + models: flowModels, active: true, runs, input: input && typeof input !== 'string' ? String(input.name) : input, @@ -581,6 +604,7 @@ export async function deployPreBuilt({ is_public, enabled: true, webhook_subscriptions: null, + models_json_schema: flowJsonSchema, updated_at: new Date() }; diff --git a/packages/shared/lib/services/sync/config/deploy.service.unit.test.ts b/packages/shared/lib/services/sync/config/deploy.service.unit.test.ts index db2b96da2b1..87b7faa5573 100644 --- a/packages/shared/lib/services/sync/config/deploy.service.unit.test.ts +++ b/packages/shared/lib/services/sync/config/deploy.service.unit.test.ts @@ -11,6 +11,7 @@ import { Orchestrator } from '../../../clients/orchestrator.js'; import type { OrchestratorClientInterface } from '../../../clients/orchestrator.js'; import type { DBTeam, DBEnvironment, CleanedIncomingFlowConfig } from '@nangohq/types'; import type { SyncConfig } from '../../../models/Sync.js'; +import db from '@nangohq/database'; const orchestratorClientNoop: OrchestratorClientInterface = { recurring: () => Promise.resolve({}) as any, @@ -207,6 +208,8 @@ describe('Sync config create', () => { return Promise.resolve([]); }); + vi.spyOn(db.knex, 'from').mockRejectedValue(new Error()); + await expect( DeployConfigService.deploy({ environment, diff --git a/packages/shared/lib/services/sync/manager.service.ts b/packages/shared/lib/services/sync/manager.service.ts index c1f07c6d4ed..a05a49995c0 100644 --- a/packages/shared/lib/services/sync/manager.service.ts +++ b/packages/shared/lib/services/sync/manager.service.ts @@ -13,7 +13,7 @@ import { import { errorNotificationService } from '../notification/error.service.js'; import configService from '../config.service.js'; import type { Connection, NangoConnection } from '../../models/Connection.js'; -import type { Sync, ReportedSyncJobStatus, SyncCommand } from '../../models/Sync.js'; +import type { SyncWithConnectionId, ReportedSyncJobStatus, SyncCommand } from '../../models/Sync.js'; import { SyncType, SyncStatus } from '../../models/Sync.js'; import { NangoError } from '../../utils/error.js'; import type { Config as ProviderConfig } from '../../models/Provider.js'; @@ -334,12 +334,24 @@ export class SyncManagerService { continue; } - const reportedStatus = await this.syncStatus({ sync, environmentId, providerConfigKey, includeJobStatus, orchestrator, recordsService }); + const syncWithConnectionId: SyncWithConnectionId = { + ...sync, + connection_id: connection.connection_id + }; + + const reportedStatus = await this.syncStatus({ + sync: syncWithConnectionId, + environmentId, + providerConfigKey, + includeJobStatus, + orchestrator, + recordsService + }); syncsWithStatus.push(reportedStatus); } } else { - const syncs = + const syncs: SyncWithConnectionId[] = syncNames.length > 0 ? await getSyncsByProviderConfigAndSyncNames(environmentId, providerConfigKey, syncNames) : await getSyncsByProviderConfigKey(environmentId, providerConfigKey); @@ -421,7 +433,7 @@ export class SyncManagerService { orchestrator, recordsService }: { - sync: Sync; + sync: SyncWithConnectionId; environmentId: number; providerConfigKey: string; includeJobStatus: boolean; @@ -458,6 +470,7 @@ export class SyncManagerService { return { id: sync.id, + connection_id: sync.connection_id, type: latestJob?.type === SyncType.INCREMENTAL ? latestJob.type : 'INITIAL', finishedAt: latestJob?.updated_at, nextScheduledSyncAt: schedule.nextDueDate, diff --git a/packages/shared/lib/services/sync/sync.service.ts b/packages/shared/lib/services/sync/sync.service.ts index e8434f80b1e..7241ff72f76 100644 --- a/packages/shared/lib/services/sync/sync.service.ts +++ b/packages/shared/lib/services/sync/sync.service.ts @@ -1,6 +1,6 @@ import { v4 as uuidv4 } from 'uuid'; import db, { schema, dbNamespace } from '@nangohq/database'; -import type { Sync, SyncConfig, Job as SyncJob } from '../../models/Sync.js'; +import type { Sync, SyncWithConnectionId, SyncConfig, Job as SyncJob } from '../../models/Sync.js'; import { SyncStatus } from '../../models/Sync.js'; import type { Connection, NangoConnection } from '../../models/Connection.js'; import type { ActiveLog, IncomingFlowConfig, SlimAction, SlimSync, SyncAndActionDifferences, SyncTypeLiteral } from '@nangohq/types'; @@ -197,7 +197,8 @@ export const getSyncs = async ( this.on(`${SYNC_CONFIG_TABLE}.sync_name`, `${TABLE}.name`) .andOn(`${SYNC_CONFIG_TABLE}.deleted`, '=', db.knex.raw('FALSE')) .andOn(`${SYNC_CONFIG_TABLE}.active`, '=', db.knex.raw('TRUE')) - .andOn(`${SYNC_CONFIG_TABLE}.type`, '=', db.knex.raw('?', 'sync')); + .andOn(`${SYNC_CONFIG_TABLE}.type`, '=', db.knex.raw('?', 'sync')) + .andOn(`${SYNC_CONFIG_TABLE}.enabled`, '=', db.knex.raw('?', 'TRUE')); }) .where({ nango_connection_id: nangoConnection.id, @@ -241,8 +242,6 @@ export const getSyncsByConnectionId = async (nangoConnectionId: number): Promise return null; }; -type SyncWithConnectionId = Sync & { connection_id: string }; - export const getSyncsByProviderConfigKey = async (environment_id: number, providerConfigKey: string): Promise => { const results = await db.knex .select(`${TABLE}.*`, `${TABLE}.name`, `_nango_connections.connection_id`, `${TABLE}.created_at`, `${TABLE}.updated_at`, `${TABLE}.last_sync_date`) @@ -284,9 +283,13 @@ export const getSyncNamesByConnectionId = async (nangoConnectionId: number): Pro return []; }; -export const getSyncsByProviderConfigAndSyncNames = async (environment_id: number, providerConfigKey: string, syncNames: string[]): Promise => { +export const getSyncsByProviderConfigAndSyncNames = async ( + environment_id: number, + providerConfigKey: string, + syncNames: string[] +): Promise => { const results = await db.knex - .select(`${TABLE}.*`) + .select(`${TABLE}.*`, '_nango_connections.connection_id') .from(TABLE) .join('_nango_connections', '_nango_connections.id', `${TABLE}.nango_connection_id`) .where({ diff --git a/packages/shared/lib/utils/analytics.ts b/packages/shared/lib/utils/analytics.ts index 62396d9093c..4a41dd17ad5 100644 --- a/packages/shared/lib/utils/analytics.ts +++ b/packages/shared/lib/utils/analytics.ts @@ -1,5 +1,5 @@ import { PostHog } from 'posthog-node'; -import { localhostUrl, isCloud, isStaging, baseUrl } from '@nangohq/utils'; +import { localhostUrl, isCloud, isStaging, baseUrl, getLogger } from '@nangohq/utils'; import { UserType } from '../utils/utils.js'; import errorManager, { ErrorSourceEnum } from './error.manager.js'; import accountService from '../services/account.service.js'; @@ -8,6 +8,8 @@ import userService from '../services/user.service.js'; import { LogActionEnum } from '../models/Telemetry.js'; import { NANGO_VERSION } from '../version.js'; +const logger = getLogger('analytics'); + export enum AnalyticsTypes { ACCOUNT_CREATED = 'server:account_created', ACCOUNT_JOINED = 'server:account_joined', @@ -99,12 +101,22 @@ class Analytics { packageVersion: string | undefined; constructor() { + const hasTelemetry = process.env['TELEMETRY'] !== 'false' && !isStaging; + if (!hasTelemetry) { + return; + } + + // hardcoded for OSS telemetry + const key = process.env['PUBLIC_POSTHOG_KEY'] || 'phc_4S2pWFTyPYT1i7zwC8YYQqABvGgSAzNHubUkdEFvcTl'; + if (!key) { + logger.error('No PostHog key'); + return; + } + try { - if (process.env['TELEMETRY']?.toLowerCase() !== 'false' && !isStaging) { - this.client = new PostHog('phc_4S2pWFTyPYT1i7zwC8YYQqABvGgSAzNHubUkdEFvcTl'); - this.client.enable(); - this.packageVersion = NANGO_VERSION; - } + this.client = new PostHog(key); + this.client.enable(); + this.packageVersion = NANGO_VERSION; } catch (err) { errorManager.report(err, { source: ErrorSourceEnum.PLATFORM, diff --git a/packages/shared/lib/utils/error.manager.ts b/packages/shared/lib/utils/error.manager.ts index 70ef3d403d3..2cc9902ac71 100644 --- a/packages/shared/lib/utils/error.manager.ts +++ b/packages/shared/lib/utils/error.manager.ts @@ -1,15 +1,8 @@ import * as uuid from 'uuid'; -import type { EventHint } from '@sentry/node'; -import sentry from '@sentry/node'; -import type { Tracer } from 'dd-trace'; -import type { ErrorEvent } from '@sentry/types'; +import tracer from 'dd-trace'; import { NangoError } from './error.js'; import type { Response, Request } from 'express'; -import { errorToObject, getLogger, isCloud } from '@nangohq/utils'; -import environmentService from '../services/environment.service.js'; -import accountService from '../services/account.service.js'; -import userService from '../services/user.service.js'; -import { NANGO_VERSION } from '../version.js'; +import { errorToObject, getLogger } from '@nangohq/utils'; const logger = getLogger('ErrorManager'); @@ -30,95 +23,19 @@ interface ErrorOptionalConfig { } class ErrorManager { - constructor() { - try { - if (isCloud && process.env['SENTRY_DNS']) { - const packageVersion = NANGO_VERSION; - sentry.init({ - dsn: process.env['SENTRY_DNS'], - beforeSend(event: ErrorEvent, _: EventHint) { - return event.user?.id === 'account-78' ? null : event; - }, - environment: process.env['NODE_ENV'] as string, - release: 'nango@' + packageVersion - }); - } - } catch (_) { - return; - } - } - /** * TODO: reuse information in res.locals when possible */ - public report(e: unknown, config: ErrorOptionalConfig = { source: ErrorSourceEnum.PLATFORM }, tracer?: Tracer): void { - void sentry.withScope(async function (scope) { - if (config.environmentId || config.accountId) { - let accountId: number | undefined; - if (config.environmentId) { - const environmentName = await environmentService.getEnvironmentName(config.environmentId); - accountId = (await environmentService.getAccountIdFromEnvironment(config.environmentId)) as number; - sentry.setTag('environmentName', environmentName); - } - - if (config.accountId && !config.environmentId) { - accountId = config.accountId; - } - const account = await accountService.getAccountById(accountId as number); - - if (!config.userId) { - const users = await userService.getUsersByAccountId(accountId as number); - sentry.setUser({ - id: `account-${accountId}`, - organization: account?.name || '', - emails: users.map((user) => user.email).join(','), - userIds: users.map((user) => user.id).join(',') - }); - } - } + public report(err: unknown, config: ErrorOptionalConfig = { source: ErrorSourceEnum.PLATFORM }): void { + logger.error('Exception caught', errorToObject(err)); - if (config.userId) { - const user = await userService.getUserById(config.userId); - sentry.setUser({ - id: `user-${config.userId}`, - email: user?.email || '', - userId: user?.id - }); - } - - sentry.setTag('source', config.source); - - if (config.operation) { - sentry.setTag('operation', config.operation); - } - - if (config.metadata) { - const metadata = Object.entries(config.metadata).reduce>((acc, [key, value]) => { - if (typeof value === 'object') { - acc[key] = JSON.stringify(value); - } else { - acc[key] = value; - } - return acc; - }, {}); - scope.setContext('metadata', metadata); - } - - if (typeof e === 'string') { - sentry.captureException(new Error(e)); - } else { - sentry.captureException(e); - } - }); - - logger.error('Exception caught', errorToObject(e)); - - if (e instanceof Error && tracer) { + if (err instanceof Error) { // Log to datadog manually // https://github.com/DataDog/dd-trace-js/issues/1944 const span = tracer.scope().active(); if (span) { - span.setTag('error', e); + span.addTags(config); + span.setTag('error', err); } } } @@ -141,41 +58,14 @@ class ErrorManager { this.errResFromNangoErr(res, err); } - public handleGenericError(err: any, _: Request, res: Response, tracer?: Tracer): void { + public handleGenericError(err: any, _: Request, res: Response): void { const errorId = uuid.v4(); - let nangoErr: NangoError; - if (!(err instanceof Error)) { - nangoErr = new NangoError('generic_error_malformed', errorId); - } else if (!(err instanceof NangoError)) { - nangoErr = new NangoError(err.message, errorId); - } else { - nangoErr = err; - } - - let environmentId: number | undefined; - if ('environment' in res.locals) { - environmentId = res.locals['environment'].id; - } - this.report(err, { source: ErrorSourceEnum.PLATFORM, environmentId, metadata: nangoErr.payload }, tracer); + this.report(err); const supportError = new NangoError('generic_error_support', errorId); this.errResFromNangoErr(res, supportError); } - - public getExpressRequestContext(req: Request): Record { - const metadata: Record = {}; - metadata['baseUrl'] = req.baseUrl; - metadata['originalUrl'] = req.originalUrl; - metadata['subdomains'] = req.subdomains; - metadata['body'] = req.body; - metadata['hostname'] = req.hostname; - metadata['method'] = req.method; - metadata['params'] = req.params; - metadata['query'] = req.query; - - return metadata; - } } export default new ErrorManager(); diff --git a/packages/shared/lib/utils/featureflags.ts b/packages/shared/lib/utils/featureflags.ts index 8d9070bcfa9..3c74d749c95 100644 --- a/packages/shared/lib/utils/featureflags.ts +++ b/packages/shared/lib/utils/featureflags.ts @@ -23,7 +23,7 @@ export class FeatureFlags { (r) => { return isExcludingFlag ? !r : r; }, - (_) => { + () => { return fallback; } ); diff --git a/packages/shared/package.json b/packages/shared/package.json index f52158f3d54..a2fedc54dbe 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -25,11 +25,10 @@ "@nangohq/nango-yaml": "0.48.1", "@nangohq/node": "^0.48.1", "@nangohq/utils": "file:../utils", - "@sentry/node": "^7.119.2", - "ajv": "^8.12.0", + "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "archiver": "^6.0.1", - "axios": "^1.7.4", + "axios": "^1.7.9", "braintree": "^3.15.0", "dd-trace": "5.21.0", "exponential-backoff": "^3.1.1", @@ -56,7 +55,6 @@ "@nangohq/logs": "file:../logs", "@nangohq/nango-orchestrator": "file:../orchestrator", "@nangohq/types": "0.48.1", - "@sentry/types": "7.112.2", "@types/braintree": "^3.3.12", "@types/js-yaml": "^4.0.5", "@types/json-schema": "7.0.15", @@ -67,9 +65,9 @@ "express": "^4.20.0", "json-schema": "0.4.0", "knex": "3.1.0", - "type-fest": "4.26.1", - "typescript": "^5.3.3", - "vitest": "1.6.0" + "type-fest": "4.32.0", + "typescript": "5.7.3", + "vitest": "2.1.8" }, "files": [ "dist/**/*", diff --git a/packages/shared/providers.yaml b/packages/shared/providers.yaml index 4bb257f6131..89d7647ab3d 100644 --- a/packages/shared/providers.yaml +++ b/packages/shared/providers.yaml @@ -176,6 +176,10 @@ aircall-basic: verification: method: GET endpoint: /v1/ping + paginate: + type: link + link_path_in_response_body: meta.next_page_link + response_path: results docs_connect: https://docs.nango.dev/integrations/all/aircall-basic/connect docs: https://docs.nango.dev/integrations/all/aircall @@ -1602,11 +1606,13 @@ chorus: headers: authorization: Bearer ${apiKey} docs: https://docs.nango.dev/integrations/all/chorus + docs_connect: https://docs.nango.dev/integrations/all/chorus/connect credentials: apiKey: type: string title: API Key description: The API key for your Chorus account + doc_section: '#step-1-generating-your-chorus-api-key' circle-so: display_name: Circle.so @@ -2046,7 +2052,7 @@ datadog: - dev-tools auth_mode: API_KEY proxy: - base_url: https://${connectionConfig.siteParameter}/api + base_url: https://api.${connectionConfig.siteParameter}/api headers: dd-api-key: ${apiKey} dd-application-key: ${connectionConfig.applicationKey} @@ -2689,6 +2695,24 @@ falai: title: API Key description: The API key for your fal.ai account +findymail: + display_name: FindyMail + categories: + - marketing + - crm + auth_mode: API_KEY + proxy: + base_url: https://app.findymail.com + headers: + authorization: Bearer ${apiKey} + docs: https://docs.nango.dev/integrations/all/findymail + docs_connect: https://docs.nango.dev/integrations/all/findymail/connect + credentials: + apiKey: + type: string + title: API Key + description: The API key for your FindyMail account + firefish: display_name: Firefish scope_separator: ' ' @@ -2844,7 +2868,7 @@ freshdesk: doc_section: '#step-2-finding-your-freshdesk-domain' freshsales: - display_name: FreshSales + display_name: Freshsales categories: - crm auth_mode: API_KEY @@ -2858,23 +2882,28 @@ freshsales: retry: after: 'retry-after' docs: https://docs.nango.dev/integrations/all/freshsales + docs_connect: https://docs.nango.dev/integrations/all/freshsales/connect connection_config: subdomain: type: string - title: FreshSales Domain - description: The subdomain of your FreshSales account + title: Freshsales subdomain + description: The subdomain of your Freshsales account pattern: '^[a-z0-9_-]+$' - example: domain + example: subdomain suffix: .freshsales.io prefix: https:// + doc_section: '#step-2-finding-your-freshsales-subdomain' credentials: apiKey: type: string title: API Key - description: The API key for your FreshSales account + description: The API key for your Freshsales account + example: 4oBqA_AzM_G3xbW3TJGvrA + pattern: '[A-Za-z0-9_]{22}' + doc_section: '#step-1-finding-your-freshsales-api-key' freshservice: - display_name: FreshService + display_name: Freshservice categories: - support auth_mode: BASIC @@ -2886,21 +2915,24 @@ freshservice: retry: after: 'retry-after' docs: https://docs.nango.dev/integrations/all/freshservice + docs_connect: https://docs.nango.dev/integrations/all/freshservice/connect connection_config: subdomain: type: string - title: FreshService Domain - description: The subdomain of your FreshService account + title: Freshservice subdomain + description: The subdomain of your Freshservice account pattern: '^[a-z0-9_-]+$' - example: domain + example: subdomain suffix: .freshservice.com prefix: https:// + doc_section: '#step-2-finding-your-freshservice-subdomain' credentials: username: type: string title: API key description: The API Key of your Freshservice account secret: true + doc_section: '#step-1-finding-your-freshservice-api-key' password: type: string title: '' @@ -2961,7 +2993,7 @@ front: docs: https://docs.nango.dev/integrations/all/front gainsight-cc: - display_name: Gainsight + display_name: Gainsight CC categories: - support - crm @@ -2973,13 +3005,15 @@ gainsight-cc: proxy: base_url: https://api2-${connectionConfig.region}.insided.com docs: https://docs.nango.dev/integrations/all/gainsight-cc + docs_connect: https://docs.nango.dev/integrations/all/gainsight-cc/connect connection_config: region: type: string title: Region description: The region of your Gainsight account - example: eu - pattern: '^[a-z]+$' + example: eu-west-1 + pattern: '^[a-z]{2}-[a-z]+-[1-9]$' + doc_section: '#step-2-finding-your-region' garmin: display_name: Garmin @@ -3027,16 +3061,21 @@ guru: method: GET endpoint: /whoami docs: https://docs.nango.dev/integrations/all/guru + docs_connect: https://docs.nango.dev/integrations/all/guru/connect credentials: username: type: string title: User/Collection ID description: The user or collection ID of your Guru account + doc_section: '#step-1-finding-your-user-collection-id' password: type: string title: User/Collection Token description: The user or collection token of your Guru account secret: true + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 + doc_section: '#step-2-generating-your-user-collection-token' github: display_name: GitHub @@ -4101,6 +4140,26 @@ kustomer: title: API Key description: The API key for your Kustomer account +lagrowthmachine: + display_name: La Growth Machine + categories: + - marketing + auth_mode: API_KEY + proxy: + base_url: https://apiv2.lagrowthmachine.com + query: + KEY: ${apiKey} + docs: https://docs.nango.dev/integrations/all/lagrowthmachine + docs_connect: https://docs.nango.dev/integrations/all/lagrowthmachine/connect + credentials: + apiKey: + type: string + title: API Key + description: The API key for your La Growth Machine account + example: 1bc32cba-a5d6-438a-bbcc-af312f560a3c + format: uuid + doc_section: '#step-1-finding-your-api-key' + lastpass: display_name: LastPass categories: @@ -6022,6 +6081,26 @@ sap-success-factors: secret: true doc_section: '#step-4-generating-your-saml-assertion' +scrapedo: + display_name: Scrape.do + categories: + - other + auth_mode: API_KEY + proxy: + base_url: https://api.scrape.do + query: + token: ${apiKey} + docs: https://docs.nango.dev/integrations/all/scrapedo + docs_connect: https://docs.nango.dev/integrations/all/scrapedo/connect + credentials: + apiKey: + type: string + title: API Token + description: The API Token for your Scrape.do account + example: 3c12d71308a346c41d10b19a2b2ac1ea5cacb53588d + pattern: '^[a-zA-Z0-9]+$' + doc_section: '#step-1-finding-your-api-key' + salesloft: display_name: Salesloft categories: @@ -6034,7 +6113,7 @@ salesloft: docs: https://docs.nango.dev/integrations/all/salesloft sendgrid: - display_name: Sendgrid + display_name: SendGrid categories: - marketing auth_mode: API_KEY @@ -6043,11 +6122,13 @@ sendgrid: authorization: Bearer ${apiKey} base_url: https://api.sendgrid.com docs: https://docs.nango.dev/integrations/all/sendgrid + docs_connect: https://docs.nango.dev/integrations/all/sendgrid/connect credentials: apiKey: type: string title: API Key description: The API key for your Sendgrid account + doc_section: '#step-1-generating-your-sendgrid-api-key' sedna: display_name: Sedna (Oauth2) @@ -6171,6 +6252,63 @@ sharepoint-online: alias: microsoft docs: https://docs.nango.dev/integrations/all/sharepoint-online +sharepoint-online-v1: + display_name: SharePoint Online (v1) + categories: + - storage + - communication + auth_mode: TWO_STEP + token_url: https://login.microsoftonline.com/${connectionConfig.tenantId}/oauth2/token + body_format: form + token_params: + client_id: ${credential.clientId} + grant_type: client_credentials + resource: https://${connectionConfig.tenantId}.sharepoint.com + client_assertion_type: urn:ietf:params:oauth:client-assertion-type:jwt-bearer + client_assertion: ${credential.assertion} + token_headers: + content-type: application/x-www-form-urlencoded + proxy: + base_url: https://${connectionConfig.tenantName}.sharepoint.com + headers: + accept: application/json;odata=verbose + token_response: + token: access_token + token_expiration: expires_in + token_expiration_strategy: expireIn + docs: https://docs.nango.dev/integrations/all/sharepoint-online + docs_connect: https://docs.nango.dev/integrations/all/sharepoint-online-v1/connect + connection_config: + tenantId: + type: string + title: Tenant ID + description: The unique identifier for your organization that uses Microsoft services + format: uuid + example: a1b2c3d4-e5f6-47a8-9b0c-d1234567890f + doc_section: '#step-1-finding-your-tenant-id' + order: 1 + tenantName: + type: string + title: Tenant Name + description: The initial domain name for your Microsoft services tenant + example: mycompany + pattern: '^[a-zA-Z0-9]+$' + doc_section: '#step-2-finding-your-tenant-name' + order: 2 + credentials: + clientId: + type: string + title: Client ID + description: Your application Client ID + secret: true + doc_section: '#step-3-finding-your-client-id' + assertion: + type: string + title: Client Assertion + description: Your generated client assertion + secret: true + doc_section: '#step-4-generating-your-client-assertion' + shipstation: display_name: Shipstation categories: @@ -6211,6 +6349,33 @@ shopify: headers: x-shopify-access-token: ${accessToken} docs: https://docs.nango.dev/integrations/all/shopify + docs_connect: https://docs.nango.dev/integrations/all/shopify/connect + connection_config: + subdomain: + type: string + title: Shopify Domain + description: The subdomain of your Shopify account + pattern: '^[a-z0-9_-]+$' + example: domain + suffix: .myshopify.com + prefix: https:// + doc_section: '#step-1-finding-your-shopify-domain' + +shopify-api-key: + display_name: Shopify (api key) + categories: + - e-commerce + auth_mode: API_KEY + proxy: + base_url: https://${connectionConfig.subdomain}.myshopify.com + headers: + x-shopify-access-token: ${apiKey} + content-type: application/json + verification: + method: POST + endpoint: /admin/api/2024-10/graphql.json?query=%7B__schema%7Btypes%7Bname%2Ckind%2Cfields%7Bname%7D%7D%7D%7D + docs: https://docs.nango.dev/integrations/all/shopify + docs_connect: https://docs.nango.dev/integrations/all/shopify-api-key/connect connection_config: subdomain: type: string @@ -6220,6 +6385,16 @@ shopify: example: domain suffix: .myshopify.com prefix: https:// + doc_section: '#step-1-finding-your-shopify-domain' + order: 1 + credentials: + apiKey: + type: string + title: API Access Token + description: The API access token generated + example: shpat_***************c03266f + pattern: '^shpat_[a-f0-9]{32}$' + doc_section: '#step-2-generating-your-api-access-token' shortcut: display_name: Shortcut diff --git a/packages/types/lib/api.endpoints.ts b/packages/types/lib/api.endpoints.ts index b1940d96eeb..0b1ecd3a6ce 100644 --- a/packages/types/lib/api.endpoints.ts +++ b/packages/types/lib/api.endpoints.ts @@ -59,6 +59,7 @@ import type { import type { GetMeta } from './meta/api'; import type { PatchFlowDisable, PatchFlowEnable, PatchFlowFrequency, PostPreBuiltDeploy, PutUpgradePreBuiltFlow } from './flow/http.api'; import type { PostPublicWebhook } from './webhooks/http.api'; +import type { PostEnvironment } from './environment/api'; export type PublicApiEndpoints = | SetMetadata @@ -128,7 +129,8 @@ export type PrivateApiEndpoints = | PutUpgradePreBuiltFlow | PostConnectionRefresh | PostManagedSignup - | PostPreBuiltDeploy; + | PostPreBuiltDeploy + | PostEnvironment; export type APIEndpoints = PrivateApiEndpoints | PublicApiEndpoints; /** diff --git a/packages/types/lib/api.ts b/packages/types/lib/api.ts index 93b4824938b..9922c89013f 100644 --- a/packages/types/lib/api.ts +++ b/packages/types/lib/api.ts @@ -14,6 +14,7 @@ export interface ValidationError { export type ResDefaultErrors = | ApiError<'not_found'> + | ApiError<'conflict'> | ApiError<'invalid_query_params', ValidationError[]> | ApiError<'invalid_body', ValidationError[]> | ApiError<'invalid_uri_params', ValidationError[]> diff --git a/packages/types/lib/endUser/index.ts b/packages/types/lib/endUser/index.ts index 3dc4a1799a5..04214d6ba12 100644 --- a/packages/types/lib/endUser/index.ts +++ b/packages/types/lib/endUser/index.ts @@ -29,10 +29,10 @@ export type DBInsertEndUser = Omit; + }; +}>; diff --git a/packages/types/lib/index.ts b/packages/types/lib/index.ts index 82e89f5d5f6..21d65fcae3d 100644 --- a/packages/types/lib/index.ts +++ b/packages/types/lib/index.ts @@ -25,7 +25,6 @@ export type * from './team/db.js'; export type * from './providers/api.js'; export type * from './proxy/api.js'; -export type * from './environment/db.js'; export type * from './scripts/on-events/db.js'; export type * from './scripts/on-events/api.js'; export type * from './scripts/syncs/api.js'; @@ -50,6 +49,7 @@ export type * from './runner/index.js'; export type * from './nangoYaml/index.js'; export type * from './environment/db.js'; +export type * from './environment/api/index.js'; export type * from './environment/api/webhook.js'; export type * from './environment/api/otlp.js'; export type * from './webhooks/api.js'; diff --git a/packages/types/lib/logs/api.ts b/packages/types/lib/logs/api.ts index 9bfbbb1eeab..b0181d262bc 100644 --- a/packages/types/lib/logs/api.ts +++ b/packages/types/lib/logs/api.ts @@ -82,7 +82,7 @@ export type PostInsights = Endpoint<{ Path: '/api/v1/logs/insights'; Querystring: { env: string }; Body: { - type: PickFromUnion; + type: PickFromUnion; }; Success: { data: { diff --git a/packages/types/lib/nangoYaml/index.ts b/packages/types/lib/nangoYaml/index.ts index d0d3b2b48a6..dcbc989cdf2 100644 --- a/packages/types/lib/nangoYaml/index.ts +++ b/packages/types/lib/nangoYaml/index.ts @@ -72,7 +72,7 @@ export interface NangoYamlV2IntegrationAction { export interface NangoYamlModel { [key: string]: NangoYamlModelFields; } -// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style + export interface NangoYamlModelFields { [key: string]: NangoYamlModelField; } @@ -144,9 +144,7 @@ export interface NangoModelField { optional?: boolean | undefined; } -export type NangoSyncEndpointOld = { - [key in HTTP_METHOD]?: string | undefined; -}; +export type NangoSyncEndpointOld = Partial>; export interface NangoSyncEndpointV2 { method: HTTP_METHOD; diff --git a/packages/types/lib/providers/provider.ts b/packages/types/lib/providers/provider.ts index 0e98e456af4..4ba776e8045 100644 --- a/packages/types/lib/providers/provider.ts +++ b/packages/types/lib/providers/provider.ts @@ -137,7 +137,7 @@ export interface ProviderTwoStep extends Omit { }; token_expires_in_ms?: number; proxy_header_authorization?: string; - body_format?: 'xml' | 'json'; + body_format?: 'xml' | 'json' | 'form'; } export interface ProviderSignature extends BaseProvider { signature: { diff --git a/packages/types/lib/web/env.ts b/packages/types/lib/web/env.ts index 23ee29bb4ec..ba8ce8c603f 100644 --- a/packages/types/lib/web/env.ts +++ b/packages/types/lib/web/env.ts @@ -6,7 +6,8 @@ export interface WindowEnv { publicPosthogKey: string; publicPosthogHost: string; publicLogoDevKey: string; - publicKoalaKey: string; + publicKoalaApiUrl: string; + publicKoalaCdnUrl: string; isCloud: boolean; features: { logs: boolean; @@ -14,5 +15,6 @@ export interface WindowEnv { auth: boolean; managedAuth: boolean; gettingStarted: boolean; + slack: boolean; }; } diff --git a/packages/types/package.json b/packages/types/package.json index 7d6da92a699..8ebcea44f44 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -13,9 +13,9 @@ }, "devDependencies": { "@types/json-schema": "7.0.15", - "axios": "^1.7.4", + "axios": "^1.7.9", "json-schema": "0.4.0", - "type-fest": "4.26.1" + "type-fest": "4.32.0" }, "license": "SEE LICENSE IN LICENSE FILE IN GIT REPOSITORY", "files": [ diff --git a/packages/utils/lib/environment/detection.ts b/packages/utils/lib/environment/detection.ts index e47553384c3..fe3e6d063ba 100644 --- a/packages/utils/lib/environment/detection.ts +++ b/packages/utils/lib/environment/detection.ts @@ -25,3 +25,4 @@ export const flagHasManagedAuth = process.env['FLAG_MANAGED_AUTH_ENABLED'] === 'true' && Boolean(process.env['WORKOS_API_KEY'] && process.env['WORKOS_CLIENT_ID']); export const flagHasAPIRateLimit = process.env['FLAG_API_RATE_LIMIT_ENABLED'] !== 'false'; export const flagHasBigQuery = process.env['FLAG_BIG_QUERY_EXPORT_ENABLED'] === 'true'; +export const flagHasSlack = !isHosted; diff --git a/packages/utils/lib/environment/parse.ts b/packages/utils/lib/environment/parse.ts index d7cd24107df..d52b3308154 100644 --- a/packages/utils/lib/environment/parse.ts +++ b/packages/utils/lib/environment/parse.ts @@ -144,6 +144,11 @@ export const ENVS = z.object({ .optional(), NANGO_DB_SCHEMA: z.string().optional().default('nango'), NANGO_DB_ADDITIONAL_SCHEMAS: z.string().optional(), + NANGO_DB_APPLICATION_NAME: z.string().optional().default('[unknown]'), + + // PostHog + PUBLIC_POSTHOG_KEY: z.string().optional(), + PUBLIC_POSTHOG_HOST: z.string().optional(), // Records RECORDS_DATABASE_URL: z.string().url().optional(), @@ -156,14 +161,14 @@ export const ENVS = z.object({ RENDER_API_KEY: z.string().optional(), IS_RENDER: bool, + // Sentry + PUBLIC_SENTRY_KEY: z.string().optional(), + // Slack NANGO_ADMIN_CONNECTION_ID: z.string().optional(), NANGO_SLACK_INTEGRATION_KEY: z.string().optional(), NANGO_ADMIN_UUID: z.string().uuid().optional(), - // Sentry - SENTRY_DNS: z.string().url().optional(), - // Internal API NANGO_INTERNAL_API_KEY: z.string().optional(), diff --git a/packages/utils/lib/express/route.ts b/packages/utils/lib/express/route.ts index a26b748361d..4627511ba0d 100644 --- a/packages/utils/lib/express/route.ts +++ b/packages/utils/lib/express/route.ts @@ -12,7 +12,7 @@ export interface Route> { export interface RouteHandler> extends Route { validate: (req: EndpointRequest, res: EndpointResponse, next: NextFunction) => void; - handler: (req: EndpointRequest, res: EndpointResponse, next: NextFunction) => void; + handler: (req: EndpointRequest, res: EndpointResponse, next: NextFunction) => void | Promise; } export const createRoute = >(server: Express, rh: RouteHandler): void => { diff --git a/packages/utils/lib/result.ts b/packages/utils/lib/result.ts index 58acd8982ff..d362d6f3297 100644 --- a/packages/utils/lib/result.ts +++ b/packages/utils/lib/result.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unnecessary-type-parameters */ /* By convention Left represents a failed computation And Right represents a successful one @@ -26,8 +27,8 @@ export function Ok(value: T): Result { return { value, unwrap: () => value, - isErr: () => false, - isOk: () => true, + isErr: (): this is Left => false, + isOk: (): this is Right => true, map: (fn: (value: T) => U): Result => { try { return Ok(fn(value)); @@ -47,8 +48,8 @@ export function Err(error: E | string): Result { unwrap: () => { throw error as Error; }, - isErr: () => true, - isOk: () => false, + isErr: (): this is Left => true, + isOk: (): this is Right => false, map: (_fn: (value: T) => U): Result => { return Err(error); }, diff --git a/packages/utils/lib/telemetry/metrics.ts b/packages/utils/lib/telemetry/metrics.ts index 17cec816e05..ebef0100d11 100644 --- a/packages/utils/lib/telemetry/metrics.ts +++ b/packages/utils/lib/telemetry/metrics.ts @@ -97,7 +97,7 @@ export function time Promise>(metricName: T computeDuration(start); return v; }, - (err) => { + (err: unknown) => { computeDuration(start); throw err; } diff --git a/packages/utils/lib/vitest.d.ts b/packages/utils/lib/vitest.d.ts index d20460f8eb6..cd1b85ae631 100644 --- a/packages/utils/lib/vitest.d.ts +++ b/packages/utils/lib/vitest.d.ts @@ -1,6 +1,6 @@ +/* eslint-disable @typescript-eslint/no-empty-object-type */ export * from 'vitest'; -/* eslint-disable @typescript-eslint/no-empty-interface */ interface CustomMatchers { toBeIsoDate: () => string; toBeIsoDateTimezone: () => string; diff --git a/packages/utils/package.json b/packages/utils/package.json index 23db45da268..4280b2c1f17 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -16,7 +16,7 @@ "license": "SEE LICENSE IN LICENSE FILE IN GIT REPOSITORY", "dependencies": { "@colors/colors": "1.6.0", - "axios": "^1.7.4", + "axios": "^1.7.9", "dd-trace": "5.21.0", "exponential-backoff": "3.1.1", "fast-safe-stringify": "2.1.1", @@ -26,13 +26,13 @@ "serialize-error": "11.0.3", "truncate-json": "3.0.0", "winston": "3.13.0", - "zod": "3.23.8" + "zod": "3.24.1" }, "devDependencies": { "@nangohq/types": "file:../types", "express": "^4.20.0", "ms": "3.0.0-canary.1", - "vitest": "1.6.0" + "vitest": "2.1.8" }, "files": [ "dist/**/*" diff --git a/packages/webapp/.env.enterprise b/packages/webapp/.env.enterprise deleted file mode 100644 index a6d9e96c690..00000000000 --- a/packages/webapp/.env.enterprise +++ /dev/null @@ -1,2 +0,0 @@ -REACT_APP_ENV=enterprise - diff --git a/packages/webapp/.env.hosted b/packages/webapp/.env.hosted deleted file mode 100644 index 620eefa84c1..00000000000 --- a/packages/webapp/.env.hosted +++ /dev/null @@ -1 +0,0 @@ -REACT_APP_ENV=hosted \ No newline at end of file diff --git a/packages/webapp/.env.local b/packages/webapp/.env.local deleted file mode 100644 index 42da5216624..00000000000 --- a/packages/webapp/.env.local +++ /dev/null @@ -1 +0,0 @@ -REACT_APP_ENV=local diff --git a/packages/webapp/.env.prod b/packages/webapp/.env.prod deleted file mode 100644 index 64526475ba2..00000000000 --- a/packages/webapp/.env.prod +++ /dev/null @@ -1,4 +0,0 @@ -REACT_APP_ENV=production -REACT_APP_PUBLIC_POSTHOG_KEY=phc_4S2pWFTyPYT1i7zwC8YYQqABvGgSAzNHubUkdEFvcTl -REACT_APP_PUBLIC_POSTHOG_HOST=https://app.posthog.com -REACT_APP_PUBLIC_SENTRY_KEY=https://4b9ac52fc05cdba175ed93c515f1cbc6@o4504688952606720.ingest.sentry.io/4506314548510721 diff --git a/packages/webapp/.env.staging b/packages/webapp/.env.staging deleted file mode 100644 index d2879444390..00000000000 --- a/packages/webapp/.env.staging +++ /dev/null @@ -1,2 +0,0 @@ -REACT_APP_ENV=staging -REACT_APP_PUBLIC_SENTRY_KEY=https://4b9ac52fc05cdba175ed93c515f1cbc6@o4504688952606720.ingest.sentry.io/4506314548510721 diff --git a/packages/webapp/.gitignore b/packages/webapp/.gitignore deleted file mode 100644 index e40b2c6a732..00000000000 --- a/packages/webapp/.gitignore +++ /dev/null @@ -1,22 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/packages/webapp/package.json b/packages/webapp/package.json index 0efe7ab4ba8..1f42957562e 100644 --- a/packages/webapp/package.json +++ b/packages/webapp/package.json @@ -6,16 +6,7 @@ "start": "DISABLE_ESLINT_PLUGIN=true react-scripts start", "build": "DISABLE_ESLINT_PLUGIN=true react-scripts build", "test": "DISABLE_ESLINT_PLUGIN=true react-scripts test", - "eject": "DISABLE_ESLINT_PLUGIN=true react-scripts eject", - "start:hosted": "env-cmd -f .env.hosted npm run start", - "start:local": "env-cmd -f .env.local npm run start", - "start:staging": "env-cmd -f .env.staging npm run start", - "start:prod": "env-cmd -f .env.prod npm run start", - "build:hosted": "env-cmd -f .env.hosted npm run build", - "build:local": "env-cmd -f .env.local npm run build", - "build:enterprise": "env-cmd -f .env.enterprise npm run build", - "build:staging": "env-cmd -f .env.staging npm run build", - "build:prod": "env-cmd -f .env.prod npm run build" + "eject": "DISABLE_ESLINT_PLUGIN=true react-scripts eject" }, "browserslist": { "production": [ @@ -85,7 +76,7 @@ "swr": "2.2.5", "tailwind-merge": "2.5.4", "tailwindcss": "3.4.14", - "typescript": "5.3.3", + "typescript": "5.7.3", "vaul": "0.9.1", "web-vitals": "2.1.4", "webpack": "5.94.0", diff --git a/packages/webapp/public/images/template-logos/findymail.svg b/packages/webapp/public/images/template-logos/findymail.svg new file mode 100644 index 00000000000..c8082aadfd7 --- /dev/null +++ b/packages/webapp/public/images/template-logos/findymail.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/webapp/public/images/template-logos/lagrowthmachine.svg b/packages/webapp/public/images/template-logos/lagrowthmachine.svg new file mode 100644 index 00000000000..ffcba56798d --- /dev/null +++ b/packages/webapp/public/images/template-logos/lagrowthmachine.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/webapp/public/images/template-logos/scrapedo.svg b/packages/webapp/public/images/template-logos/scrapedo.svg new file mode 100644 index 00000000000..1f6fd246343 --- /dev/null +++ b/packages/webapp/public/images/template-logos/scrapedo.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/packages/webapp/public/images/template-logos/sharepoint-online-v1.svg b/packages/webapp/public/images/template-logos/sharepoint-online-v1.svg new file mode 120000 index 00000000000..fac4fe65ca9 --- /dev/null +++ b/packages/webapp/public/images/template-logos/sharepoint-online-v1.svg @@ -0,0 +1 @@ +sharepoint-online.svg \ No newline at end of file diff --git a/packages/webapp/public/images/template-logos/shopify-api-key.svg b/packages/webapp/public/images/template-logos/shopify-api-key.svg new file mode 120000 index 00000000000..6216c3753cd --- /dev/null +++ b/packages/webapp/public/images/template-logos/shopify-api-key.svg @@ -0,0 +1 @@ +shopify.svg \ No newline at end of file diff --git a/packages/webapp/src/App.tsx b/packages/webapp/src/App.tsx index 1c0fb957bce..74b7088cca8 100644 --- a/packages/webapp/src/App.tsx +++ b/packages/webapp/src/App.tsx @@ -54,12 +54,15 @@ const App = () => { return ( - {globalEnv.publicKoalaKey && ( + {globalEnv.publicKoalaApiUrl && globalEnv.publicKoalaCdnUrl && ( @@ -106,7 +109,7 @@ const App = () => { } /> } /> - {true && } />} + {} />} {globalEnv.features.auth && ( <> } /> diff --git a/packages/webapp/src/components/EnvironmentPicker.tsx b/packages/webapp/src/components/EnvironmentPicker.tsx new file mode 100644 index 00000000000..09672c2bdd1 --- /dev/null +++ b/packages/webapp/src/components/EnvironmentPicker.tsx @@ -0,0 +1,163 @@ +import { Popover, PopoverContent, PopoverTrigger } from '../components/ui/Popover'; +import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '../components/ui/Command'; +import { useMeta } from '../hooks/useMeta'; +import { useNavigate } from 'react-router-dom'; +import { useState } from 'react'; +import { IconCheck, IconChevronDown } from '@tabler/icons-react'; +import { Button } from './ui/button/Button'; +import { useStore } from '../store'; +import { cn } from '../utils/utils'; +import { apiPostEnvironment } from '../hooks/useEnvironment'; +import { Dialog, DialogContent, DialogFooter, DialogTitle, DialogTrigger, DialogClose } from '../components/ui/Dialog'; +import { Input } from './ui/input/Input'; +import { Info } from './Info'; +import { useToast } from '../hooks/useToast'; + +export const EnvironmentPicker: React.FC = () => { + const navigate = useNavigate(); + const { toast } = useToast(); + + const env = useStore((state) => state.env); + const setEnv = useStore((state) => state.setEnv); + + const { meta, mutate } = useMeta(); + const [open, setOpen] = useState(false); + + const [openDialog, setOpenDialog] = useState(false); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(false); + const [name, setName] = useState(''); + + const onSelect = (selected: string) => { + if (selected === env) { + return; + } + + setEnv(selected); + + const pathSegments = window.location.pathname.split('/').filter(Boolean); + + pathSegments[0] = selected; + + let newPath = `/${pathSegments.join('/')}`; + + // If on 'integration' or 'connections' subpages beyond the second level, redirect to their parent page + if (pathSegments[1] === 'integrations' && pathSegments.length > 2) { + newPath = `/${selected}/integrations`; + } else if (pathSegments[1] === 'connections' && pathSegments.length > 2) { + newPath = `/${selected}/connections`; + } + + navigate(newPath); + }; + + const onCreate = async () => { + setLoading(true); + + const res = await apiPostEnvironment({ name }); + if ('error' in res.json) { + const err = res.json.error; + if (err.code === 'conflict') { + toast({ title: 'Environment name already exists', variant: 'error' }); + } else if (err.code === 'invalid_body') { + setError(true); + } else if (err.code === 'feature_disabled' || err.code === 'resource_capped') { + toast({ title: err.message, variant: 'error' }); + } else { + toast({ title: 'Failed to create environment', variant: 'error' }); + } + } else { + navigate(`/${res.json.data.name}`); + setOpen(false); + setOpenDialog(false); + setError(false); + setName(''); + void mutate(); + } + + setLoading(false); + }; + + if (!meta) { + return; + } + + return ( + + + + + + + {meta.environments.length > 5 && ( + + )} + + No environment found. + + {meta.environments.map((item) => ( + +
{item.name}
+ +
+ ))} +
+ +
+ + + + + + Environment Name +
+ setName(e.target.value)} + variant={'black'} + onKeyUp={(e) => e.code === 'Enter' && onCreate()} + /> +
+ *Must be lowercase letters, numbers, underscores and dashes. +
+
+ + Only the Prod environment is billed. Other environments are free, with restrictions making them unsuitable for + production. + + + + + + + +
+
+
+
+
+
+
+ ); +}; diff --git a/packages/webapp/src/components/LeftNavBar.tsx b/packages/webapp/src/components/LeftNavBar.tsx index bc0dabb3a63..fc7c998a8e2 100644 --- a/packages/webapp/src/components/LeftNavBar.tsx +++ b/packages/webapp/src/components/LeftNavBar.tsx @@ -15,13 +15,13 @@ import { useStore } from '../store'; import { useMeta } from '../hooks/useMeta'; import { useSignout } from '../utils/user'; import { HomeIcon, RocketIcon } from '@radix-ui/react-icons'; -import { useEnvironment } from '../hooks/useEnvironment'; import { useConnectionsCount } from '../hooks/useConnections'; import { useUser } from '../hooks/useUser'; import { globalEnv } from '../utils/env'; import { IconX } from '@tabler/icons-react'; import type { MaybePromise } from '@nangohq/types'; import { apiPatchOnboarding } from '../hooks/useOnboarding'; +import { EnvironmentPicker } from './EnvironmentPicker'; export enum LeftNavBarItems { Homepage, @@ -58,8 +58,6 @@ export default function LeftNavBar(props: LeftNavBarProps) { const { user: me } = useUser(); const env = useStore((state) => state.env); const { data } = useConnectionsCount(env); - const setEnv = useStore((state) => state.setEnv); - const { mutate } = useEnvironment(env); const showGettingStarted = useStore((state) => state.showGettingStarted); useEffect(() => { @@ -105,63 +103,25 @@ export default function LeftNavBar(props: LeftNavBarProps) { return list; }, [env, showGettingStarted, meta]); - const handleEnvChange = (e: React.ChangeEvent) => { - const newEnv = e.target.value; - setEnv(newEnv); - void mutate(); - - const pathSegments = window.location.pathname.split('/').filter(Boolean); - - pathSegments[0] = newEnv; - - let newPath = `/${pathSegments.join('/')}`; - - // If on 'integration' or 'connections' subpages beyond the second level, redirect to their parent page - if (pathSegments[1] === 'integrations' && pathSegments.length > 2) { - newPath = `/${newEnv}/integrations`; - } else if (pathSegments[1] === 'connections' && pathSegments.length > 2) { - newPath = `/${newEnv}/connections`; - } - - navigate(newPath); - }; - if (!meta || !me) { return null; } return (
-
+
-
+
Nango Nango {meta.version}
- {meta.environments.length === 0 && ( -
- -
- )} - {meta.environments.length > 0 && ( -
- -
- )} -
+ +
+ +
+ +
{items.map((item) => { const Icon = item.icon; return ( @@ -189,7 +149,7 @@ export default function LeftNavBar(props: LeftNavBarProps) { })}
-
+
setShowUserSettings(!showUserSettings)} diff --git a/packages/webapp/src/components/ui/Chart.tsx b/packages/webapp/src/components/ui/Chart.tsx index 8a40fa71d32..3d218074a1c 100644 --- a/packages/webapp/src/components/ui/Chart.tsx +++ b/packages/webapp/src/components/ui/Chart.tsx @@ -6,12 +6,13 @@ import { cn } from '../../utils/utils'; // Format: { THEME_NAME: CSS_SELECTOR } const THEMES = { light: '', dark: '.dark' } as const; -export type ChartConfig = { - [k in string]: { +export type ChartConfig = Record< + string, + { label?: React.ReactNode; icon?: React.ComponentType; - } & ({ color?: string; theme?: never } | { color?: never; theme: Record }); -}; + } & ({ color?: string; theme?: never } | { color?: never; theme: Record }) +>; interface ChartContextProps { config: ChartConfig; diff --git a/packages/webapp/src/components/ui/Command.tsx b/packages/webapp/src/components/ui/Command.tsx index 42ebbbb145d..8aaf2c1b18e 100644 --- a/packages/webapp/src/components/ui/Command.tsx +++ b/packages/webapp/src/components/ui/Command.tsx @@ -38,7 +38,7 @@ const CommandInput = React.forwardRef, React.ComponentPropsWithoutRef>( - (props, ref) => + (props, ref) => ); CommandEmpty.displayName = CommandPrimitive.Empty.displayName; diff --git a/packages/webapp/src/components/ui/button/Button.tsx b/packages/webapp/src/components/ui/button/Button.tsx index 1fadec6fb1b..d51c1496a8f 100644 --- a/packages/webapp/src/components/ui/button/Button.tsx +++ b/packages/webapp/src/components/ui/button/Button.tsx @@ -31,7 +31,8 @@ export const buttonStyles = cva( link: 'text-grayscale-400 hover:text-white focus:text-white', select: 'bg-grayscale-900 text-grayscale-400 border border-grayscale-900 hover:text-white focus:text-white hover:border-grayscale-600', popoverItem: 'w-full rounded hover:bg-grayscale-900 text-grayscale-300 focus:bg-grayscale-900', - secondary: 'bg-grayscale-900 text-grayscale-400 border border-grayscale-700 hover:text-white focus:text-white hover:border-grayscale-600' + secondary: 'bg-grayscale-900 text-grayscale-400 border border-grayscale-700 hover:text-white focus:text-white hover:border-grayscale-600', + tertiary: 'bg-grayscale-800 text-grayscale-100 border border-transparent hover:text-white focus:text-white hover:border-grayscale-600' }, size: { auto: '', diff --git a/packages/webapp/src/env.d.ts b/packages/webapp/src/env.d.ts index 8ccdb5b96d9..d6b405de728 100644 --- a/packages/webapp/src/env.d.ts +++ b/packages/webapp/src/env.d.ts @@ -6,9 +6,6 @@ declare global { namespace NodeJS { interface ProcessEnv { PORT: string; - REACT_APP_ENV: 'development' | 'staging' | 'production' | 'hosted' | 'enterprise'; - REACT_APP_PUBLIC_POSTHOG_KEY: string; - REACT_APP_PUBLIC_POSTHOG_HOST: string; } } } diff --git a/packages/webapp/src/hooks/useEnvironment.tsx b/packages/webapp/src/hooks/useEnvironment.tsx index 671336acae6..20fc4b0ef49 100644 --- a/packages/webapp/src/hooks/useEnvironment.tsx +++ b/packages/webapp/src/hooks/useEnvironment.tsx @@ -1,6 +1,7 @@ import useSWR from 'swr'; import type { EnvironmentAndAccount } from '@nangohq/server'; -import { swrFetcher } from '../utils/api'; +import { apiFetch, swrFetcher } from '../utils/api'; +import type { PostEnvironment } from '@nangohq/types'; export function useEnvironment(env: string) { const { data, error, mutate } = useSWR<{ environmentAndAccount: EnvironmentAndAccount }>(`/api/v1/environment?env=${env}`, swrFetcher, {}); @@ -14,3 +15,15 @@ export function useEnvironment(env: string) { mutate }; } + +export async function apiPostEnvironment(body: PostEnvironment['Body']) { + const res = await apiFetch('/api/v1/environments', { + method: 'POST', + body: JSON.stringify(body) + }); + + return { + res, + json: (await res.json()) as PostEnvironment['Reply'] + }; +} diff --git a/packages/webapp/src/hooks/useToast.tsx b/packages/webapp/src/hooks/useToast.tsx index 234849c98a2..2a83a5d1065 100644 --- a/packages/webapp/src/hooks/useToast.tsx +++ b/packages/webapp/src/hooks/useToast.tsx @@ -13,7 +13,7 @@ type ToasterToast = ToastProps & { action?: ToastActionElement; }; -const actionTypes = { +export const actionTypes = { ADD_TOAST: 'ADD_TOAST', UPDATE_TOAST: 'UPDATE_TOAST', DISMISS_TOAST: 'DISMISS_TOAST', diff --git a/packages/webapp/src/index.tsx b/packages/webapp/src/index.tsx index fe753829dcb..f796fd37235 100644 --- a/packages/webapp/src/index.tsx +++ b/packages/webapp/src/index.tsx @@ -1,6 +1,6 @@ import { SentryErrorBoundary } from './utils/sentry'; -import './utils/env'; +import { globalEnv } from './utils/env'; import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; @@ -11,7 +11,7 @@ import { PostHogProvider } from 'posthog-js/react'; import { ErrorBoundary } from './components/ErrorBoundary'; const options = { - api_host: process.env.REACT_APP_PUBLIC_POSTHOG_HOST, + api_host: globalEnv.publicPosthogHost, maskAllInputs: true }; @@ -19,7 +19,7 @@ const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement) root.render( }> - + diff --git a/packages/webapp/src/pages/Connection/Authorization.tsx b/packages/webapp/src/pages/Connection/Authorization.tsx index b71af4ea561..5d7020b22b3 100644 --- a/packages/webapp/src/pages/Connection/Authorization.tsx +++ b/packages/webapp/src/pages/Connection/Authorization.tsx @@ -71,10 +71,10 @@ export const Authorization: React.FC = ({ connection, errorL {endUser.id}
)} - {endUser?.displayName && ( + {endUser?.display_name && (
User Display Name - {endUser.displayName} + {endUser.display_name}
)} {endUser?.email && ( @@ -89,10 +89,10 @@ export const Authorization: React.FC = ({ connection, errorL {endUser.organization.id}
)} - {endUser?.organization?.displayName && ( + {endUser?.organization?.display_name && (
Organization Name - {endUser.organization.displayName} + {endUser.organization.display_name}
)} {connection.created_at && ( diff --git a/packages/webapp/src/pages/Connection/Create.tsx b/packages/webapp/src/pages/Connection/Create.tsx index 905430d4681..6835e231835 100644 --- a/packages/webapp/src/pages/Connection/Create.tsx +++ b/packages/webapp/src/pages/Connection/Create.tsx @@ -177,7 +177,7 @@ export const ConnectionCreate: React.FC = () => { className="text-white ring-0 focus:ring-0 focus-visible:outline-none" > - No framework found. + No integrations found. {listIntegration?.integrations.map((item) => { const checked = integration && item.uniqueKey === integration.uniqueKey; diff --git a/packages/webapp/src/pages/Connection/CreateLegacy.tsx b/packages/webapp/src/pages/Connection/CreateLegacy.tsx index 39d67436419..2afd965a36a 100644 --- a/packages/webapp/src/pages/Connection/CreateLegacy.tsx +++ b/packages/webapp/src/pages/Connection/CreateLegacy.tsx @@ -9,7 +9,7 @@ import { Tooltip } from '@geist-ui/core'; import type { Integration } from '@nangohq/server'; import useSet from '../../hooks/useSet'; -import { isHosted, isStaging, baseUrl } from '../../utils/utils'; +import { isCloudProd } from '../../utils/utils'; import { useGetIntegrationListAPI, useGetHmacAPI } from '../../utils/api'; import { useAnalyticsTrack } from '../../utils/analytics'; import DashboardLayout from '../../layout/DashboardLayout'; @@ -22,6 +22,7 @@ import type { AuthModeType } from '@nangohq/types'; import { useEnvironment } from '../../hooks/useEnvironment'; import { Helmet } from 'react-helmet'; import { useSearchParam } from 'react-use'; +import { globalEnv } from '../../utils/env'; export const ConnectionCreateLegacy: React.FC = () => { const { mutate } = useSWRConfig(); @@ -108,7 +109,7 @@ export const ConnectionCreateLegacy: React.FC = () => { if (environmentAndAccount) { const { environment, host } = environmentAndAccount; setPublicKey(environment.public_key); - setHostUrl(host || baseUrl()); + setHostUrl(host || globalEnv.apiUrl); setWebsocketsPath(environment.websockets_path || ''); setIsHmacEnabled(Boolean(environment.hmac_key)); } @@ -336,7 +337,7 @@ export const ConnectionCreateLegacy: React.FC = () => { const snippet = () => { const args = []; - if (isStaging() || isHosted()) { + if (!isCloudProd()) { args.push(`host: '${hostUrl}'`); if (websocketsPath && websocketsPath !== '/') { args.push(`websocketsPath: '${websocketsPath}'`); diff --git a/packages/webapp/src/pages/Connection/Show.tsx b/packages/webapp/src/pages/Connection/Show.tsx index 7963e7df815..08f9b434aa2 100644 --- a/packages/webapp/src/pages/Connection/Show.tsx +++ b/packages/webapp/src/pages/Connection/Show.tsx @@ -14,7 +14,6 @@ import { Button } from '../../components/ui/button/Button'; import { useEnvironment } from '../../hooks/useEnvironment'; import { Syncs } from './Syncs'; import { Authorization } from './Authorization'; -import { isHosted } from '../../utils/utils'; import { connectSlack } from '../../utils/slack-connection'; import { useStore } from '../../store'; @@ -29,6 +28,7 @@ import { useToast } from '../../hooks/useToast'; import { useListIntegration } from '../../hooks/useIntegration'; import { EndUserProfile } from './components/EndUserProfile'; import { getConnectionDisplayName } from '../../utils/endUser'; +import { globalEnv } from '../../utils/env'; export enum Tabs { Syncs, @@ -68,7 +68,7 @@ export const ConnectionShow: React.FC = () => { if (location.hash === '#models' || location.hash === '#syncs') { setActiveTab(Tabs.Syncs); } - if (location.hash === '#authorization' || isHosted()) { + if (location.hash === '#authorization' || !globalEnv.features.scripts) { setActiveTab(Tabs.Authorization); } }, [location]); @@ -94,7 +94,7 @@ export const ConnectionShow: React.FC = () => { undefined, { revalidate: false } ); - for await (const key of cache.keys()) { + for (const key of cache.keys()) { if (key.startsWith('/api/v1/connections')) { cache.delete(key); } @@ -237,7 +237,7 @@ export const ConnectionShow: React.FC = () => { - {!slackIsConnected && !isHosted() && showSlackBanner && ( + {!slackIsConnected && globalEnv.features.slack && showSlackBanner && ( setShowSlackBanner(false)} diff --git a/packages/webapp/src/pages/Connection/components/EndUserProfile.tsx b/packages/webapp/src/pages/Connection/components/EndUserProfile.tsx index 25631365f5d..a29237355ba 100644 --- a/packages/webapp/src/pages/Connection/components/EndUserProfile.tsx +++ b/packages/webapp/src/pages/Connection/components/EndUserProfile.tsx @@ -3,12 +3,12 @@ import type { ApiEndUser } from '@nangohq/types'; export const EndUserProfile: React.FC<{ endUser: ApiEndUser; connectionId: string }> = ({ endUser, connectionId }) => { return (
-
{endUser.email ?? endUser.displayName ?? connectionId}
+
{endUser.email ?? endUser.display_name ?? connectionId}
- {endUser.email && endUser.displayName && {endUser.displayName}} - {!endUser.email && endUser.displayName && {connectionId}} - {endUser.organization?.displayName && ({endUser.organization?.displayName})} + {endUser.email && endUser.display_name && {endUser.display_name}} + {!endUser.email && endUser.display_name && {connectionId}} + {endUser.organization?.display_name && ({endUser.organization?.display_name})}
); diff --git a/packages/webapp/src/pages/Environment/Settings.tsx b/packages/webapp/src/pages/Environment/Settings.tsx index 9603935b29e..1b1ac57d290 100644 --- a/packages/webapp/src/pages/Environment/Settings.tsx +++ b/packages/webapp/src/pages/Environment/Settings.tsx @@ -16,7 +16,7 @@ import { apiFetch } from '../../utils/api'; import IntegrationLogo from '../../components/ui/IntegrationLogo'; -import { isHosted, defaultCallback } from '../../utils/utils'; +import { defaultCallback } from '../../utils/utils'; import DashboardLayout from '../../layout/DashboardLayout'; import { LeftNavBarItems } from '../../components/LeftNavBar'; import SecretInput from '../../components/ui/input/SecretInput'; @@ -691,10 +691,10 @@ export const EnvironmentSettings: React.FC = () => { )}
- {!isHosted() && ( + {globalEnv.features.slack && (
-
-
Last 14 days
+
+ Last 14 days (UTC) +
{globalEnv.features.scripts && ( diff --git a/packages/webapp/src/pages/Homepage/components/InsightChart.tsx b/packages/webapp/src/pages/Homepage/components/InsightChart.tsx index 3b1d68a2a7d..792e6a0a29b 100644 --- a/packages/webapp/src/pages/Homepage/components/InsightChart.tsx +++ b/packages/webapp/src/pages/Homepage/components/InsightChart.tsx @@ -7,7 +7,7 @@ import type { InsightsHistogramEntry, PostInsights } from '@nangohq/types'; import { Skeleton } from '../../../components/ui/Skeleton'; import { useMemo } from 'react'; import { formatQuantity } from '../../../utils/utils'; -import { addDays, format } from 'date-fns'; +import { addDays, addMinutes, format } from 'date-fns'; import { useNavigate } from 'react-router-dom'; import { getLogsUrl } from '../../../utils/logs'; @@ -84,8 +84,14 @@ export const InsightChart: React.FC<{ title: string; desc: string; type: PostIns for (const date of dates) { const entry = map.get(date); total += entry?.total || 0; + + // JS always transform date to local time but we receive UTC from the backend + // Ideally we would get the raw data points and display dates based on local TZ but we group by day so it's too late to change the timezone + // It fixes a display issues when you are a day in the past or in the future + const utc = addMinutes(new Date(date), endDate.getTimezoneOffset()); + tmp.push({ - date: new Date(date), + date: utc, total: entry?.total || 0, success: entry?.success || 0, failure: entry?.failure || 0 @@ -137,6 +143,7 @@ export const InsightChart: React.FC<{ title: string; desc: string; type: PostIns -

- {message}{' '} - - ({operation.type} - {'action' in operation && <>:{operation.action}}) - -

+

{message}

); diff --git a/packages/webapp/src/pages/Team/components/Actions.tsx b/packages/webapp/src/pages/Team/components/Actions.tsx index ff52347ccec..e2a79125b37 100644 --- a/packages/webapp/src/pages/Team/components/Actions.tsx +++ b/packages/webapp/src/pages/Team/components/Actions.tsx @@ -26,7 +26,7 @@ export const UserAction: React.FC<{ user: ApiUser }> = ({ user }) => { setLoading(true); const updated = await apiDeleteTeamUser(env, { id: user.id }); - if ('error' in updated) { + if ('error' in updated.json) { toast({ title: 'An unexpected error occurred', variant: 'error' }); } else { if (user.id === me!.id) { @@ -89,7 +89,7 @@ export const InvitationAction: React.FC<{ invitation: ApiInvitation }> = ({ invi setLoading(true); const deleted = await apiDeleteInvite(env, { email: invitation.email }); - if ('error' in deleted) { + if ('error' in deleted.json) { toast({ title: 'An unexpected error occurred', variant: 'error' }); } else { toast({ title: `${invitation.email}'s invitation has been revoked`, variant: 'success' }); diff --git a/packages/webapp/src/pages/Team/components/Info.tsx b/packages/webapp/src/pages/Team/components/Info.tsx index b559202de17..fc9f0545cd9 100644 --- a/packages/webapp/src/pages/Team/components/Info.tsx +++ b/packages/webapp/src/pages/Team/components/Info.tsx @@ -19,7 +19,7 @@ export const TeamInfo: React.FC = () => { const onSave = async () => { const updated = await apiPutTeam(env, { name }); - if ('error' in updated) { + if ('error' in updated.json) { toast({ title: 'An unexpected error occurred', variant: 'error' }); } else { toast({ title: 'Team updated successfully', variant: 'success' }); diff --git a/packages/webapp/src/utils/api.tsx b/packages/webapp/src/utils/api.tsx index 9b1a0fe1274..169f059c243 100644 --- a/packages/webapp/src/utils/api.tsx +++ b/packages/webapp/src/utils/api.tsx @@ -1,9 +1,9 @@ import { toast } from 'react-toastify'; import { useSignout } from './user'; -import type { PostSignup } from '@nangohq/types'; +import type { ApiError, PostSignup } from '@nangohq/types'; -export async function apiFetch(input: string | URL | Request, init?: RequestInit | undefined) { +export async function apiFetch(input: string | URL | Request, init?: RequestInit) { return await fetch(input, { ...init, headers: { 'Content-Type': 'application/json', ...(init?.headers || {}) }, @@ -23,7 +23,7 @@ export interface SWRError { /** * Default SWR fetcher does not throw on HTTP error */ -export async function swrFetcher(url: string, req?: RequestInit | undefined): Promise { +export async function swrFetcher(url: string, req?: RequestInit): Promise { const res = await apiFetch(url, req); if (!res.ok) { @@ -59,7 +59,7 @@ export function useSignupAPI() { body: JSON.stringify(body) }; - return apiFetch('/api/v1/account/signup', options); + return await apiFetch('/api/v1/account/signup', options); } catch { requestErrorToast(); } @@ -77,7 +77,8 @@ export function useSigninAPI() { const res = await apiFetch('/api/v1/account/signin', options); if (res.status !== 200 && res.status !== 401 && res.status !== 400) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -93,7 +94,8 @@ export function useHostedSigninAPI() { const res = await apiFetch('/api/v1/basic'); if (res.status !== 200 && res.status !== 401) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -116,11 +118,13 @@ export function useEditCallbackUrlAPI(env: string) { const res = await apiFetch(`/api/v1/environment/callback?env=${env}`, options); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -143,11 +147,13 @@ export function useEditHmacEnabledAPI(env: string) { const res = await apiFetch(`/api/v1/environment/hmac-enabled?env=${env}`, options); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -170,11 +176,13 @@ export function useEditAlwaysSendWebhookAPI(env: string) { const res = await apiFetch(`/api/v1/environment/webhook-send?env=${env}`, options); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -197,11 +205,13 @@ export function useEditSendAuthWebhookAPI(env: string) { const res = await apiFetch(`/api/v1/environment/webhook-auth-send?env=${env}`, options); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -224,11 +234,13 @@ export function useEditHmacKeyAPI(env: string) { const res = await apiFetch(`/api/v1/environment/hmac-key?env=${env}`, options); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -251,11 +263,13 @@ export function useEditEnvVariablesAPI(env: string) { const res = await apiFetch(`/api/v1/environment/environment-variables?env=${env}`, options); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -278,11 +292,13 @@ export function useEditWebhookUrlAPI(env: string) { const res = await apiFetch(`/api/v1/environment/webhook/primary-url?env=${env}`, options); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -305,11 +321,13 @@ export function useEditWebhookSecondaryUrlAPI(env: string) { const res = await apiFetch(`/api/v1/environment/webhook/secondary-url?env=${env}`, options); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -332,18 +350,20 @@ export function useEditOtlpSettingsAPI(env: string) { const res = await apiFetch(`/api/v1/environment/otlp/settings?env=${env}`, options); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status === 403) { const { error } = await res.json(); - const msg = 'message' in error ? error.message : 'Forbidden'; + const msg = 'message' in error ? (error as ApiError['error']).message : 'Forbidden'; toast.error(msg, { position: toast.POSITION.BOTTOM_CENTER }); return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -361,11 +381,13 @@ export function useGetIntegrationListAPI(env: string) { const res = await apiFetch(`/api/v1/integrations?env=${env}`); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); + return; } return res; @@ -383,11 +405,12 @@ export function useGetProvidersAPI(env: string) { const res = await apiFetch(`/api/v1/provider?env=${env}`); if (res.status === 401) { - return signout(); + await signout(); + return; } if (res.status !== 200) { - return serverErrorToast(); + serverErrorToast(); } return res; diff --git a/packages/webapp/src/utils/endUser.ts b/packages/webapp/src/utils/endUser.ts index d1e90e806ff..3c7f66880ad 100644 --- a/packages/webapp/src/utils/endUser.ts +++ b/packages/webapp/src/utils/endUser.ts @@ -1,5 +1,5 @@ import type { ApiEndUser } from '@nangohq/types'; export function getConnectionDisplayName({ endUser, connectionId }: { endUser?: ApiEndUser | null; connectionId: string }): string { - return endUser?.displayName || endUser?.email || connectionId; + return endUser?.display_name || endUser?.email || connectionId; } diff --git a/packages/webapp/src/utils/language-snippets.tsx b/packages/webapp/src/utils/language-snippets.tsx index 2790b002100..e6314c9f5b5 100644 --- a/packages/webapp/src/utils/language-snippets.tsx +++ b/packages/webapp/src/utils/language-snippets.tsx @@ -2,10 +2,11 @@ import type { NangoModel, NangoSyncEndpointV2 } from '@nangohq/types'; import type { TargetId } from 'httpsnippet-lite'; import { HTTPSnippet } from 'httpsnippet-lite'; import type { NangoSyncModel } from '../types'; -import { isProd } from './utils'; import { modelToString } from './scripts'; -const maskedKey = ''; +function maskSecret(secret: string): string { + return `${secret.substring(0, 4)}${'*'.repeat(secret.length - 4)}`; +} export function nodeSyncSnippet({ modelName, @@ -18,10 +19,8 @@ export function nodeSyncSnippet({ connectionId: string; providerConfigKey: string; }) { - const secretKeyDisplay = isProd() ? maskedKey : secretKey; - return `import { Nango } from '@nangohq/node'; -const nango = new Nango({ secretKey: '${secretKeyDisplay}' }); +const nango = new Nango({ secretKey: '${maskSecret(secretKey)}' }); const records = await nango.listRecords({ providerConfigKey: '${providerConfigKey}', @@ -44,10 +43,8 @@ export function nodeActionSnippet({ providerConfigKey: string; input?: NangoModel | NangoSyncModel; }) { - const secretKeyDisplay = isProd() ? maskedKey : secretKey; - let snippet = `import Nango from '@nangohq/node'; -const nango = new Nango({ secretKey: '${secretKeyDisplay}' }); +const nango = new Nango({ secretKey: '${maskSecret(secretKey)}' }); const response = await nango.triggerAction( '${providerConfigKey}', @@ -80,13 +77,11 @@ export async function httpSnippet({ language: TargetId; input?: NangoModel | NangoSyncModel | undefined; }) { - const secretKeyDisplay = isProd() ? maskedKey : secretKey; - const snippet = new HTTPSnippet({ method: endpoint.method, url: `${baseUrl}/v1${endpoint.path}`, headers: [ - { name: 'Authorization', value: `Bearer ${secretKeyDisplay}` }, + { name: 'Authorization', value: `Bearer ${maskSecret(secretKey)}` }, { name: 'Content-Type', value: 'application/json' }, { name: 'Connection-Id', value: connectionId }, { name: 'Provider-Config-Key', value: providerConfigKey } diff --git a/packages/webapp/src/utils/sentry.tsx b/packages/webapp/src/utils/sentry.tsx index c8e4ad61322..5cc08a04c6d 100644 --- a/packages/webapp/src/utils/sentry.tsx +++ b/packages/webapp/src/utils/sentry.tsx @@ -1,9 +1,10 @@ import * as Sentry from '@sentry/react'; import { useEffect } from 'react'; import { Routes, createRoutesFromChildren, matchRoutes, useLocation, useNavigationType } from 'react-router-dom'; +import { globalEnv } from './env'; Sentry.init({ - dsn: process.env.REACT_APP_PUBLIC_SENTRY_KEY, + dsn: globalEnv.publicSentryKey, integrations: [ Sentry.reactRouterV6BrowserTracingIntegration({ useEffect, @@ -14,7 +15,7 @@ Sentry.init({ }), Sentry.replayIntegration() ], - tracePropagationTargets: [/^https:\/\/app.nango\.dev\/api/], + tracePropagationTargets: [/^https:\/\/api.nango\.dev/], tracesSampleRate: 0.1, replaysSessionSampleRate: 0.1, replaysOnErrorSampleRate: 0.3, diff --git a/packages/webapp/src/utils/utils.tsx b/packages/webapp/src/utils/utils.tsx index bae0d5d70cd..fb0a9e4286b 100644 --- a/packages/webapp/src/utils/utils.tsx +++ b/packages/webapp/src/utils/utils.tsx @@ -3,42 +3,17 @@ import type { ClassValue } from 'clsx'; import { format } from 'date-fns'; import { twMerge } from 'tailwind-merge'; import type { SyncResult } from '../types'; +import { globalEnv } from './env'; -export const localhostUrl: string = 'http://localhost:3003'; -export const stagingUrl: string = 'https://api-staging.nango.dev'; -export const prodUrl: string = 'https://api.nango.dev'; - -export const syncDocs = 'https://docs.nango.dev/guides/getting-started/read-from-an-api'; export const githubRepo = 'https://github.com/NangoHQ/integration-templates'; export const githubIntegrationTemplates = `${githubRepo}/tree/main/integrations`; -export function isHosted() { - return process.env.REACT_APP_ENV === 'hosted'; -} - -export function isStaging() { - return process.env.REACT_APP_ENV === 'staging'; -} - -export function isProd() { - return process.env.REACT_APP_ENV === 'production'; -} - -export function baseUrl() { - switch (process.env.REACT_APP_ENV) { - case 'hosted': - return localhostUrl; - case 'staging': - return stagingUrl; - case 'production': - return prodUrl; - default: - return localhostUrl; - } +export function isCloudProd() { + return window.location.origin === 'https://app.nango.dev'; } export function defaultCallback() { - return baseUrl() + '/oauth/callback'; + return globalEnv.apiUrl + '/oauth/callback'; } export function elapsedTime(start: Date | number, end: Date | number): string { diff --git a/packages/webhooks/lib/forward.ts b/packages/webhooks/lib/forward.ts index 88e56a3e45c..e06e65133f7 100644 --- a/packages/webhooks/lib/forward.ts +++ b/packages/webhooks/lib/forward.ts @@ -60,7 +60,11 @@ export const forwardWebhook = async ({ incomingHeaders: webhookOriginalHeaders }); - result.isOk() ? await logCtx.success() : await logCtx.failed(); + if (result.isOk()) { + await logCtx.success(); + } else { + await logCtx.failed(); + } return; } @@ -84,5 +88,9 @@ export const forwardWebhook = async ({ } } - success ? await logCtx.success() : await logCtx.failed(); + if (success) { + await logCtx.success(); + } else { + await logCtx.failed(); + } }; diff --git a/packages/webhooks/lib/utils.ts b/packages/webhooks/lib/utils.ts index a1117efcddf..ea131b8adcc 100644 --- a/packages/webhooks/lib/utils.ts +++ b/packages/webhooks/lib/utils.ts @@ -25,7 +25,7 @@ export const NON_FORWARDABLE_HEADERS = [ 'server' ]; -export const retry = async (logCtx?: LogContext | null | undefined, error?: AxiosError, attemptNumber?: number): Promise => { +export const retry = async (logCtx?: LogContext | null, error?: AxiosError, attemptNumber?: number): Promise => { if (error?.response && (error?.response?.status < 200 || error?.response?.status >= 300)) { const content = `Webhook response received an ${ error?.response?.status || error?.code diff --git a/packages/webhooks/package.json b/packages/webhooks/package.json index 53a0219bb0b..b8605057981 100644 --- a/packages/webhooks/package.json +++ b/packages/webhooks/package.json @@ -17,14 +17,14 @@ "dependencies": { "@nangohq/logs": "file:../logs", "@nangohq/utils": "file:../utils", - "axios": "^1.7.4", + "axios": "^1.7.9", "dayjs": "1.11.7", "dayjs-plugin-utc": "0.1.2" }, "devDependencies": { "@nangohq/types": "file:../types", - "typescript": "5.3.3", - "vitest": "1.6.0" + "typescript": "5.7.3", + "vitest": "2.1.8" }, "files": [ "dist/**/*" diff --git a/scripts/build_docker.sh b/scripts/build_docker.sh index 0de483022f0..b24327cd98a 100755 --- a/scripts/build_docker.sh +++ b/scripts/build_docker.sh @@ -3,7 +3,7 @@ set -e ACTION=$1 -ENV=$2 # enterprise | hosted | prod | staging +ENV=$2 # enterprise | hosted | prod | staging \\ TODO: remove this, it's only needed for the frontend GIT_HASH=$3 USAGE="./build_docker.sh GIT_HASH" @@ -28,13 +28,6 @@ if [ -z $GIT_HASH ]; then exit fi -if [ -z $SENTRY_KEY ]; then - echo -e "${YELLOW}SENTRY_KEY is empty${NC}" -fi -if [ -z $POSTHOG_KEY ]; then - echo -e "${YELLOW}POSTHOG_KEY is empty${NC}" -fi - # Move to here no matter where the file was executed cd "$(dirname "$0")" @@ -51,10 +44,7 @@ echo -e "Building nangohq/nango:$ENV\n" docker buildx build \ --platform linux/amd64 \ - --build-arg image_env="$ENV" \ --build-arg git_hash="$GIT_HASH" \ - --build-arg posthog_key="$SENTRY_KEY" \ - --build-arg sentry_key="$POSTHOG_KEY" \ --cache-from type=gha \ --cache-to type=gha,mode=max \ --file ../Dockerfile \ diff --git a/scripts/one-off/schedules-migration/migrate.ts b/scripts/one-off/schedules-migration/migrate.ts index e0b926fc36f..d79f3760fd0 100755 --- a/scripts/one-off/schedules-migration/migrate.ts +++ b/scripts/one-off/schedules-migration/migrate.ts @@ -45,6 +45,7 @@ interface SourceSchedule { environment_id: string; } +// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style type JsonObject = { [Key in string]: JsonValue } & { [Key in string]?: JsonValue | undefined }; type JsonArray = JsonValue[] | readonly JsonValue[]; type JsonPrimitive = string | number | boolean | null; diff --git a/scripts/one-off/schedules-migration/package-lock.json b/scripts/one-off/schedules-migration/package-lock.json index 4831d504840..df0a92a4cca 100644 --- a/scripts/one-off/schedules-migration/package-lock.json +++ b/scripts/one-off/schedules-migration/package-lock.json @@ -1,11 +1,11 @@ { - "name": "records-migration", + "name": "schedules-migration", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "records-migration", + "name": "schedules-migration", "version": "1.0.0", "dependencies": { "knex": "^3.1.0", diff --git a/scripts/package.json b/scripts/package.json index faeeded655c..db6a25d4f29 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -3,11 +3,11 @@ "type": "module", "devDependencies": { "@apidevtools/swagger-cli": "4.0.4", - "ajv": "8.12.0", - "chalk": "5.3.0", - "git-cliff": "2.5.0", + "ajv": "8.17.1", + "chalk": "5.4.1", + "git-cliff": "2.7.0", "js-yaml": "4.1.0", - "zx": "8.1.4", + "zx": "8.3.0", "webflow-api": "3.0.1" } } diff --git a/tsconfig.json b/tsconfig.json index b0885d9b776..2b9fe4f0e59 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,28 @@ { - "extends": "@tsconfig/node18-strictest-esm/tsconfig.json", - "compilerOptions": { - "ignoreDeprecations": "5.0", - "declaration": true, - "sourceMap": true, - "composite": true, - "checkJs": false - } + "compilerOptions": { + "lib": ["es2023"], + "module": "ES2022", + "target": "es2022", + "ignoreDeprecations": "5.0", + "declaration": true, + "sourceMap": true, + "composite": true, + "checkJs": false, + "importsNotUsedAsValues": "remove", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "allowUnusedLabels": false, + "allowUnreachableCode": false, + "exactOptionalPropertyTypes": true, + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedIndexedAccess": true, + "noUnusedLocals": true, + "noUnusedParameters": true + } } diff --git a/vite.config.ts b/vite.config.ts index eac1fd44891..7e26ce7e7d2 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -13,7 +13,8 @@ export default defineConfig({ NANGO_LOGS_ES_URL: 'http://fake.com', NANGO_LOGS_ES_USER: '', NANGO_LOGS_ES_PWD: '', - NANGO_LOGS_ENABLED: 'false' + NANGO_LOGS_ENABLED: 'false', + NANGO_DB_NAME: 'nango_test' }, chaiConfig: { truncateThreshold: 10000 diff --git a/vite.integration.config.ts b/vite.integration.config.ts index c33e9943e3c..197569cf12d 100644 --- a/vite.integration.config.ts +++ b/vite.integration.config.ts @@ -17,6 +17,12 @@ export default defineConfig({ ORCHESTRATOR_SERVICE_URL: 'http://orchestrator' }, fileParallelism: false, - pool: 'forks' + pool: 'forks', + + poolOptions: { + forks: { + singleFork: true + } + } } });